add permission support
refactoring
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
*/target
|
*/target
|
||||||
assist.toml
|
assist.toml
|
||||||
|
mcp_server_collection/server.toml
|
||||||
Generated
+364
@@ -2,6 +2,15 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@@ -206,6 +215,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "displaydoc"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dyn-clone"
|
name = "dyn-clone"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
@@ -476,6 +496,88 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_collections"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"potential_utf",
|
||||||
|
"utf8_iter",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_locale_core"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"litemap",
|
||||||
|
"tinystr",
|
||||||
|
"writeable",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_normalizer"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
|
||||||
|
dependencies = [
|
||||||
|
"icu_collections",
|
||||||
|
"icu_normalizer_data",
|
||||||
|
"icu_properties",
|
||||||
|
"icu_provider",
|
||||||
|
"smallvec",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_normalizer_data"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_properties"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
|
||||||
|
dependencies = [
|
||||||
|
"icu_collections",
|
||||||
|
"icu_locale_core",
|
||||||
|
"icu_properties_data",
|
||||||
|
"icu_provider",
|
||||||
|
"zerotrie",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_properties_data"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_provider"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_locale_core",
|
||||||
|
"writeable",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerotrie",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "id-arena"
|
name = "id-arena"
|
||||||
version = "2.3.0"
|
version = "2.3.0"
|
||||||
@@ -488,6 +590,27 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
|
||||||
|
dependencies = [
|
||||||
|
"idna_adapter",
|
||||||
|
"smallvec",
|
||||||
|
"utf8_iter",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna_adapter"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
|
||||||
|
dependencies = [
|
||||||
|
"icu_normalizer",
|
||||||
|
"icu_properties",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.13.1"
|
version = "2.13.1"
|
||||||
@@ -516,6 +639,12 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leb128fmt"
|
name = "leb128fmt"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -528,6 +657,12 @@ version = "0.2.184"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
|
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "litemap"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.14"
|
version = "0.4.14"
|
||||||
@@ -543,6 +678,15 @@ version = "0.4.29"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchit"
|
name = "matchit"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
@@ -560,6 +704,8 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -585,6 +731,15 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.50.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
@@ -650,6 +805,15 @@ version = "0.2.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "potential_utf"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
|
||||||
|
dependencies = [
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prettyplease"
|
name = "prettyplease"
|
||||||
version = "0.2.37"
|
version = "0.2.37"
|
||||||
@@ -730,6 +894,23 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmcp"
|
name = "rmcp"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -910,6 +1091,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -961,6 +1151,12 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@@ -984,6 +1180,17 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "synstructure"
|
||||||
|
version = "0.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.18"
|
version = "2.0.18"
|
||||||
@@ -1004,6 +1211,25 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinystr"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.51.0"
|
version = "1.51.0"
|
||||||
@@ -1153,6 +1379,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
|
||||||
|
dependencies = [
|
||||||
|
"matchers",
|
||||||
|
"nu-ansi-term",
|
||||||
|
"once_cell",
|
||||||
|
"regex-automata",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1167,6 +1423,25 @@ version = "0.2.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8_iter"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.23.0"
|
version = "1.23.0"
|
||||||
@@ -1178,6 +1453,12 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.1+wasi-snapshot-preview1"
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
@@ -1443,6 +1724,89 @@ dependencies = [
|
|||||||
"wasmparser",
|
"wasmparser",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "writeable"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
|
||||||
|
dependencies = [
|
||||||
|
"stable_deref_trait",
|
||||||
|
"yoke-derive",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke-derive"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerofrom"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
|
||||||
|
dependencies = [
|
||||||
|
"zerofrom-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerofrom-derive"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerotrie"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec"
|
||||||
|
version = "0.11.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
|
||||||
|
dependencies = [
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec-derive"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zmij"
|
name = "zmij"
|
||||||
version = "1.0.21"
|
version = "1.0.21"
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ serde = { version = "1.0.228", features = ["derive"] }
|
|||||||
tokio = { version = "1.51.0", features = ["full"] }
|
tokio = { version = "1.51.0", features = ["full"] }
|
||||||
own_assist_common = {path="../common"}
|
own_assist_common = {path="../common"}
|
||||||
tokio-util = "0.7.18"
|
tokio-util = "0.7.18"
|
||||||
|
tracing-subscriber = {version = "0.3.23", features = ["env-filter"]}
|
||||||
|
url = {version = "2.5.8", features = ["serde"]}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
default = ["datetime"]
|
||||||
datetime = []
|
datetime = []
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use own_assist_common::config_from_file;
|
use own_assist_common::config_from_file;
|
||||||
use own_assist_common::config_loader::ConfigLoadingError;
|
use own_assist_common::config_loader::ConfigLoadingError;
|
||||||
use crate::McpServiceType;
|
use crate::McpServiceType;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub(crate) struct Config {
|
pub(crate) struct Config {
|
||||||
|
#[serde(rename = "bind-address")]
|
||||||
|
pub(crate) bind_address: Option<url::Url>,
|
||||||
pub(crate) servers: Vec<ServerConfig>,
|
pub(crate) servers: Vec<ServerConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub(crate) struct ServerConfig {
|
pub(crate) struct ServerConfig {
|
||||||
pub(crate) path: String,
|
pub(crate) path: String,
|
||||||
pub(crate) r#type: McpServiceType
|
pub(crate) r#type: McpServiceType
|
||||||
@@ -16,6 +18,6 @@ pub(crate) struct ServerConfig {
|
|||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn from_file() -> Result<Self, ConfigLoadingError> {
|
pub fn from_file() -> Result<Self, ConfigLoadingError> {
|
||||||
config_from_file("servers.toml")
|
config_from_file("server.toml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,13 +2,16 @@
|
|||||||
pub mod datetime;
|
pub mod datetime;
|
||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
|
use axum::response::Json;
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use rmcp::transport::{
|
use rmcp::transport::{
|
||||||
StreamableHttpServerConfig,
|
StreamableHttpServerConfig,
|
||||||
streamable_http_server::{session::local::LocalSessionManager, tower::StreamableHttpService},
|
streamable_http_server::{session::local::LocalSessionManager, tower::StreamableHttpService},
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::main;
|
use tokio::main;
|
||||||
|
use tracing_subscriber::layer::SubscriberExt;
|
||||||
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
use crate::config::{Config, ServerConfig};
|
use crate::config::{Config, ServerConfig};
|
||||||
#[cfg(feature = "datetime")]
|
#[cfg(feature = "datetime")]
|
||||||
use crate::datetime::DateTimeHandler;
|
use crate::datetime::DateTimeHandler;
|
||||||
@@ -21,16 +24,16 @@ pub trait McpServerHandler: rmcp::ServerHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum McpServiceType {
|
pub enum McpServiceType {
|
||||||
DateTime
|
DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mcp_router(server_configs: Vec<ServerConfig>) -> Router {
|
pub(crate) fn mcp_router(server_configs: &Vec<ServerConfig>) -> Router {
|
||||||
let mut router = Router::new();
|
let mut router = Router::new();
|
||||||
|
|
||||||
for config in &server_configs {
|
for config in server_configs {
|
||||||
router = match config.r#type {
|
router = match config.r#type {
|
||||||
McpServiceType::DateTime => {
|
McpServiceType::DateTime => {
|
||||||
router.route_service(config.path.as_str(), DateTimeHandler::mcp_service())
|
router.route_service(config.path.as_str(), DateTimeHandler::mcp_service())
|
||||||
@@ -41,16 +44,36 @@ pub(crate) fn mcp_router(server_configs: Vec<ServerConfig>) -> Router {
|
|||||||
router
|
router
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bind_address_format(url: url::Url) -> String {
|
||||||
|
format!("{}:{}", url.host_str().expect("No host specified"), url.port().unwrap_or(8000))
|
||||||
|
}
|
||||||
|
|
||||||
#[main]
|
#[main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
tracing_subscriber::registry()
|
||||||
|
.with(
|
||||||
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
.unwrap_or_else(|_| "debug".to_string().into()),
|
||||||
|
)
|
||||||
|
.with(tracing_subscriber::fmt::layer())
|
||||||
|
.init();
|
||||||
|
|
||||||
let config = Config::from_file().inspect_err(|e|{
|
let config = Config::from_file().inspect_err(|e|{
|
||||||
eprintln!("Error loading config: {}", e); // FIXME: use actual logger instead
|
eprintln!("Error loading config: {e}");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
|
|
||||||
let router = mcp_router(config.servers);
|
println!("config: {config:#?}");
|
||||||
|
|
||||||
let tcp_listener = tokio::net::TcpListener::bind("127.0.0.1:8000").await.unwrap(); // use toml config
|
let router = mcp_router(&config.servers).route("/", axum::routing::get(|| async { Json(config.servers) }));
|
||||||
|
|
||||||
|
let bind_address = config.bind_address.unwrap_or(url::Url::parse("localhost:8000").unwrap());
|
||||||
|
println!("binding address at {bind_address}");
|
||||||
|
|
||||||
|
let tcp_listener = tokio::net::TcpListener::bind(bind_address_format(bind_address)).await.inspect_err(|e|{
|
||||||
|
eprintln!("Error bind tcp listener: {e:#?}");
|
||||||
|
std::process::exit(1);
|
||||||
|
}).unwrap();
|
||||||
|
|
||||||
let ct = tokio_util::sync::CancellationToken::new();
|
let ct = tokio_util::sync::CancellationToken::new();
|
||||||
|
|
||||||
|
|||||||
+147
-44
@@ -5,9 +5,9 @@ use ollama_rs::generation::chat::ChatMessage;
|
|||||||
use ollama_rs::generation::chat::request::ChatMessageRequest;
|
use ollama_rs::generation::chat::request::ChatMessageRequest;
|
||||||
use ollama_rs::generation::tools::ToolInfo;
|
use ollama_rs::generation::tools::ToolInfo;
|
||||||
use rmcp::ServiceError;
|
use rmcp::ServiceError;
|
||||||
use rmcp::model::{CallToolRequestParams, CallToolResult, };
|
use rmcp::model::{CallToolRequestParams, CallToolResult};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::ops::Index;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Default)]
|
#[derive(Debug, Copy, Clone, Default)]
|
||||||
@@ -18,9 +18,15 @@ pub enum ToolPermission {
|
|||||||
Denied,
|
Denied,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum PermissionAnswer {
|
||||||
|
Granted,
|
||||||
|
Denied,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RestrictedTool {
|
pub struct RestrictedTool {
|
||||||
permission: ToolPermission, // TODO: USE PERMISSION
|
permission: ToolPermission,
|
||||||
tool_info: ToolInfo,
|
tool_info: ToolInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +34,7 @@ pub struct RestrictedTool {
|
|||||||
pub struct MCPServerData {
|
pub struct MCPServerData {
|
||||||
name: String,
|
name: String,
|
||||||
client: MCPClient,
|
client: MCPClient,
|
||||||
/// tools in the ollama format. mcp resources are also translated into tools
|
/// tools in the ollama format. mcp resources are also translated into tools (not yet)
|
||||||
translated_tools: Vec<RestrictedTool>,
|
translated_tools: Vec<RestrictedTool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,6 +49,8 @@ impl MCPServerData {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resource into tool translation commented out, since resource reading is not yet solved. `AgentChat` would instead try to call tool with the resource name.
|
||||||
|
/*
|
||||||
match crate::mcp::translation::get_server_resource_tool_info(&client, &name).await {
|
match crate::mcp::translation::get_server_resource_tool_info(&client, &name).await {
|
||||||
Ok(resources_as_tool_infos) => {
|
Ok(resources_as_tool_infos) => {
|
||||||
for tool_info in resources_as_tool_infos {
|
for tool_info in resources_as_tool_infos {
|
||||||
@@ -56,6 +64,7 @@ impl MCPServerData {
|
|||||||
log::warn!("Server `{name}` does not support resources");
|
log::warn!("Server `{name}` does not support resources");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
Ok(MCPServerData {
|
Ok(MCPServerData {
|
||||||
name,
|
name,
|
||||||
@@ -85,6 +94,8 @@ pub enum ChatError {
|
|||||||
ArgumentParsingError,
|
ArgumentParsingError,
|
||||||
#[error("service could not be found")]
|
#[error("service could not be found")]
|
||||||
ServiceNotFoundError(String),
|
ServiceNotFoundError(String),
|
||||||
|
#[error("tool could not be found")]
|
||||||
|
ToolNotFoundError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AgentChat {
|
impl AgentChat {
|
||||||
@@ -92,7 +103,7 @@ impl AgentChat {
|
|||||||
ollama_client: Ollama,
|
ollama_client: Ollama,
|
||||||
model: String,
|
model: String,
|
||||||
mcp_clients: HashMap<String, MCPClient>,
|
mcp_clients: HashMap<String, MCPClient>,
|
||||||
system_prompt: String
|
system_prompt: String,
|
||||||
) -> Result<Self, ServiceError> {
|
) -> Result<Self, ServiceError> {
|
||||||
let history = vec![ChatMessage::system(system_prompt)];
|
let history = vec![ChatMessage::system(system_prompt)];
|
||||||
|
|
||||||
@@ -111,22 +122,74 @@ impl AgentChat {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_tools(&self) -> Vec<ToolInfo> {
|
pub fn get_all_tools(&self) -> impl Iterator<Item = &RestrictedTool> {
|
||||||
let mut all_tools: Vec<ToolInfo> = Vec::new();
|
self.mcp_servers
|
||||||
|
.values()
|
||||||
for server in self.mcp_servers.values() {
|
.map(|server| server.translated_tools.iter())
|
||||||
for tool in server.translated_tools.iter() {
|
.flatten()
|
||||||
all_tools.push(tool.tool_info.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
all_tools
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn message(&mut self, user_message: String) -> Result<ChatMessage, ChatError> {
|
///
|
||||||
let all_tools = self.get_all_tools();
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `name`: must be in the format "mcp_server_name::tool_or_resource_name".
|
||||||
|
///
|
||||||
|
/// returns:
|
||||||
|
/// Ok(tuple) => tuple of the server name and the tool or resource name
|
||||||
|
/// Err(error) => ChatError::FunctionParseError(name)
|
||||||
|
fn parse_tool_name(name: String) -> Result<(String, String), ChatError> {
|
||||||
|
let (mcp_server_name, tool_name) = name
|
||||||
|
.split_once("::")
|
||||||
|
.ok_or(ChatError::FunctionParseError(name.clone()))?;
|
||||||
|
|
||||||
log::debug!("all tools: {:#?}", all_tools);
|
Ok((mcp_server_name.to_string(), tool_name.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mcp_server_by_name(&self, name: String) -> Option<&MCPServerData> {
|
||||||
|
self.mcp_servers.get(&name)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `mpc_server_data`:
|
||||||
|
/// * `name`: must be in the format "mcp_server_name::tool_or_resource_name".
|
||||||
|
///
|
||||||
|
/// returns: Option<&RestrictedTool>
|
||||||
|
pub fn get_tool<'a>(
|
||||||
|
&self,
|
||||||
|
mpc_server_data: &'a MCPServerData,
|
||||||
|
name: String,
|
||||||
|
) -> Option<&'a RestrictedTool> {
|
||||||
|
mpc_server_data
|
||||||
|
.translated_tools
|
||||||
|
.iter()
|
||||||
|
.find(|tool| tool.tool_info.function.name == name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_permission(&mut self, full_tool_name: String, permission: ToolPermission) -> Result<(), ChatError> {
|
||||||
|
let (mcp_server_name, tool_name) = Self::parse_tool_name(full_tool_name.clone())?;
|
||||||
|
|
||||||
|
let mcp_server_data: &mut MCPServerData = self.mcp_servers.get_mut(&mcp_server_name.clone()).ok_or(ChatError::ServiceNotFoundError(mcp_server_name.clone()))?;
|
||||||
|
let tool_index = mcp_server_data.translated_tools.iter().position(|tool| tool.tool_info.function.name == full_tool_name).ok_or(ChatError::ToolNotFoundError(tool_name))?;
|
||||||
|
mcp_server_data.translated_tools[tool_index].permission = permission;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn message<C: Future<Output = PermissionAnswer>>(
|
||||||
|
&mut self,
|
||||||
|
user_message: String,
|
||||||
|
permission_request_callback: fn(mcp_server_name: String, tool_name: String) -> C,
|
||||||
|
) -> Result<ChatMessage, ChatError>
|
||||||
|
{
|
||||||
|
let all_tools: Vec<ToolInfo> = self
|
||||||
|
.get_all_tools()
|
||||||
|
.map(|restricted_tool| restricted_tool.tool_info.clone())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
log::debug!("all tools: {all_tools:#?}");
|
||||||
|
|
||||||
let mut response = self
|
let mut response = self
|
||||||
.ollama_client
|
.ollama_client
|
||||||
@@ -145,13 +208,16 @@ impl AgentChat {
|
|||||||
|
|
||||||
for tool_call in &response.message.tool_calls {
|
for tool_call in &response.message.tool_calls {
|
||||||
log::debug!("calling tool {}", tool_call.function.name);
|
log::debug!("calling tool {}", tool_call.function.name);
|
||||||
let result = self.call_tool(tool_call).await?;
|
let result = self.call_tool(tool_call, permission_request_callback).await?;
|
||||||
let contents = result
|
|
||||||
.content
|
let contents = match result {
|
||||||
.iter()
|
Some(result) => result.content
|
||||||
.filter_map(|content| content.as_text())
|
.iter()
|
||||||
.map(|text_content| text_content.text.clone())
|
.filter_map(|content| content.as_text())
|
||||||
.collect::<Vec<_>>();
|
.map(|text_content| text_content.text.clone())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
None => vec![String::from("Tool Permission Denied by the user")],
|
||||||
|
};
|
||||||
|
|
||||||
log::debug!("contents: {:#?}", contents);
|
log::debug!("contents: {:#?}", contents);
|
||||||
|
|
||||||
@@ -163,7 +229,8 @@ impl AgentChat {
|
|||||||
.ollama_client
|
.ollama_client
|
||||||
.send_chat_messages_with_history(
|
.send_chat_messages_with_history(
|
||||||
&mut self.message_history,
|
&mut self.message_history,
|
||||||
ChatMessageRequest::new(self.model.clone(), Vec::new()).tools(all_tools.clone()),
|
ChatMessageRequest::new(self.model.clone(), Vec::new())
|
||||||
|
.tools(all_tools.clone()),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
log::debug!("received message: {:#?}", response.message);
|
log::debug!("received message: {:#?}", response.message);
|
||||||
@@ -172,10 +239,25 @@ impl AgentChat {
|
|||||||
Ok(response.message)
|
Ok(response.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn call_tool(
|
///
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `tool_call`:
|
||||||
|
/// * `permission_request_callback`:
|
||||||
|
///
|
||||||
|
/// returns: Result<Option<CallToolResult>, ChatError>
|
||||||
|
/// if permission was denied: Ok(None)
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
async fn call_tool<C: Future<Output = PermissionAnswer>>(
|
||||||
&self,
|
&self,
|
||||||
tool_call: &ollama_rs::generation::tools::ToolCall,
|
tool_call: &ollama_rs::generation::tools::ToolCall,
|
||||||
) -> Result<CallToolResult, ChatError> {
|
permission_request_callback: fn(mcp_server_name: String, tool_name: String) -> C,
|
||||||
|
) -> Result<Option<CallToolResult>, ChatError> {
|
||||||
let arguments_json_object = tool_call
|
let arguments_json_object = tool_call
|
||||||
.function
|
.function
|
||||||
.arguments
|
.arguments
|
||||||
@@ -184,18 +266,44 @@ impl AgentChat {
|
|||||||
.inspect_err(|_| log::error!("arguments are not of type object"))?;
|
.inspect_err(|_| log::error!("arguments are not of type object"))?;
|
||||||
log::trace!("arguments_json_object: {:?}", arguments_json_object);
|
log::trace!("arguments_json_object: {:?}", arguments_json_object);
|
||||||
|
|
||||||
let (mcp_name, function_name) =
|
let full_unparsed_tool_name = &tool_call.function.name; // "mcp_server_name::tool_name"
|
||||||
tool_call
|
|
||||||
.function
|
let (mcp_server_name, tool_name) = Self::parse_tool_name(full_unparsed_tool_name.clone())?;
|
||||||
.name
|
|
||||||
.split_once("::")
|
let mcp_server_data = self
|
||||||
.ok_or(ChatError::FunctionParseError(
|
.get_mcp_server_by_name(mcp_server_name.clone())
|
||||||
tool_call.function.name.clone(),
|
.ok_or(ChatError::ServiceNotFoundError(mcp_server_name.clone()))?;
|
||||||
))?;
|
let restricted_tool = self
|
||||||
let (mcp_name, function_name) = (mcp_name.to_string(), function_name.to_string());
|
.get_tool(&mcp_server_data, full_unparsed_tool_name.clone())
|
||||||
|
.ok_or(ChatError::ToolNotFoundError(
|
||||||
|
full_unparsed_tool_name.clone(),
|
||||||
|
))?;
|
||||||
|
|
||||||
|
match restricted_tool.permission {
|
||||||
|
ToolPermission::Allowed => {
|
||||||
|
log::trace!("allowed restricted tool: {:?}", restricted_tool.tool_info);
|
||||||
|
}
|
||||||
|
ToolPermission::Denied => {
|
||||||
|
log::info!("denied restricted tool: {:?}", restricted_tool);
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
ToolPermission::Ask => {
|
||||||
|
log::trace!("ask restricted tool: {:?}", restricted_tool);
|
||||||
|
let response = permission_request_callback(mcp_server_name, tool_name.clone()).await;
|
||||||
|
match response {
|
||||||
|
PermissionAnswer::Granted => {
|
||||||
|
log::trace!("granted restricted tool: {:?}", restricted_tool);
|
||||||
|
}
|
||||||
|
PermissionAnswer::Denied => {
|
||||||
|
log::info!("denied restricted tool: {:?}", restricted_tool);
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let request_params =
|
let request_params =
|
||||||
CallToolRequestParams::new(function_name).with_arguments(arguments_json_object.clone());
|
CallToolRequestParams::new(tool_name).with_arguments(arguments_json_object.clone());
|
||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"calling tool {} with request_params: {:#?}",
|
"calling tool {} with request_params: {:#?}",
|
||||||
@@ -203,11 +311,6 @@ impl AgentChat {
|
|||||||
request_params
|
request_params
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(self
|
Ok(Some(mcp_server_data.client.call_tool(request_params).await?))
|
||||||
.mcp_servers
|
|
||||||
.get(&mcp_name)
|
|
||||||
.ok_or(ChatError::ServiceNotFoundError(mcp_name))?
|
|
||||||
.client.call_tool(request_params)
|
|
||||||
.await?)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -26,14 +26,13 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn ollama_instance(&self) -> Ollama {
|
pub fn ollama_instance(&self) -> Ollama {
|
||||||
let ollama_default_url = Url::parse("http://127.0.0.1:11434").unwrap();
|
|
||||||
|
|
||||||
let mut ollama_headers = HeaderMap::new();
|
let mut ollama_headers = HeaderMap::new();
|
||||||
|
|
||||||
if let Some(authorization_header) = &self.ollama.authorization {
|
if let Some(authorization_header) = &self.ollama.authorization {
|
||||||
ollama_headers.append("Authorization", HeaderValue::from_str(&authorization_header).unwrap());
|
ollama_headers.append("Authorization", HeaderValue::from_str(&authorization_header).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let ollama_default_url = Url::parse("http://127.0.0.1:11434").unwrap();
|
||||||
let mut ollama = Ollama::from_url(self.ollama.url.clone().unwrap_or(ollama_default_url));
|
let mut ollama = Ollama::from_url(self.ollama.url.clone().unwrap_or(ollama_default_url));
|
||||||
ollama.set_headers(Some(ollama_headers));
|
ollama.set_headers(Some(ollama_headers));
|
||||||
|
|
||||||
@@ -64,7 +63,7 @@ impl Config {
|
|||||||
pub struct OllamaConfig {
|
pub struct OllamaConfig {
|
||||||
pub url: Option<Url>,
|
pub url: Option<Url>,
|
||||||
pub model: OllamaModelConfig,
|
pub model: OllamaModelConfig,
|
||||||
pub authorization: Option<String>, // TODO: implement
|
pub authorization: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
|||||||
+12
-4
@@ -1,9 +1,14 @@
|
|||||||
mod config;
|
mod config;
|
||||||
mod model;
|
mod model;
|
||||||
|
|
||||||
|
use own_mcp::mcp::chat::{PermissionAnswer, ToolPermission};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::model::create_model_from_config;
|
use crate::model::create_model_from_config;
|
||||||
|
|
||||||
|
async fn permission_callback(mcp_server_name: String, tool_name:String) -> PermissionAnswer {
|
||||||
|
PermissionAnswer::Denied // TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
@@ -27,7 +32,8 @@ async fn main() {
|
|||||||
let system_prompt = "Du bist ein Assistent, der per Sprache bedient wird. Du erhälst die Transkription. \
|
let system_prompt = "Du bist ein Assistent, der per Sprache bedient wird. Du erhälst die Transkription. \
|
||||||
Wichtiger als deine Antworten sind deine Aktionen.\
|
Wichtiger als deine Antworten sind deine Aktionen.\
|
||||||
Nutze bitte die tools, falls du sie brauchst um Informationen zu bekommen (z.B: über das aktuelle Datum oder den aktuellen Wochentag). \
|
Nutze bitte die tools, falls du sie brauchst um Informationen zu bekommen (z.B: über das aktuelle Datum oder den aktuellen Wochentag). \
|
||||||
Du bist in einem Agent Loop und kannst mehrere Tools hintereinander nutzen.".to_string();
|
Du bist in einem Agent Loop und kannst mehrere Tools hintereinander nutzen. \
|
||||||
|
Falls der Nutzer das Nutzen eines Tools ablehnt, sag ihm bescheid, dass du es brauchst.".to_string();
|
||||||
|
|
||||||
let mut agent_chat = own_mcp::AgentChat::new(ollama, model_name.clone(), mcp_clients, system_prompt).await.inspect_err(
|
let mut agent_chat = own_mcp::AgentChat::new(ollama, model_name.clone(), mcp_clients, system_prompt).await.inspect_err(
|
||||||
|e| {
|
|e| {
|
||||||
@@ -36,10 +42,12 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
log::info!("all tools: {:#?}", agent_chat.get_all_tools());
|
log::info!("all tools: {:#?}", agent_chat.get_all_tools().collect::<Vec<_>>());
|
||||||
|
|
||||||
let answer = agent_chat.message("Welche Tools kannst du benutzten?".to_string()).await;
|
agent_chat.set_permission("mcp-playground-echo-server::echo".to_string(), ToolPermission::Allowed).unwrap();
|
||||||
let answer = agent_chat.message("Teste beide Server aus. Nutze bei fetch https://example.com/. Melde mir die Ergebnisse zurück.".to_string()).await;
|
|
||||||
|
let answer = agent_chat.message("Welche Tools kannst du benutzten?".to_string(), permission_callback).await;
|
||||||
|
let answer = agent_chat.message("Teste beide Server aus. Nutze bei fetch https://example.com/. Melde mir die Ergebnisse zurück.".to_string(), permission_callback).await;
|
||||||
|
|
||||||
dbg!(answer);
|
dbg!(answer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user