Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e593f3f25 | ||
|
|
3425da5688 | ||
|
|
df6010ab38 | ||
|
|
236ef036ec | ||
|
|
a6bd1a8d5f | ||
|
|
673aac34a8 | ||
|
|
5a4bf4ec8a | ||
|
|
199d4080cb |
@@ -5,3 +5,4 @@ server.toml
|
|||||||
temporary_audio
|
temporary_audio
|
||||||
cli/src/human_interface/.AUTH_HEADER
|
cli/src/human_interface/.AUTH_HEADER
|
||||||
.idea
|
.idea
|
||||||
|
/own_mcp/src/mcp/llmclient/mistral/.MISTRAL_API_KEY
|
||||||
|
|||||||
Generated
+93
-46
@@ -653,13 +653,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "displaydoc"
|
name = "displaydoc"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
|
checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.119",
|
"syn 3.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -987,9 +987,9 @@ checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.4.2"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
|
checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"itoa",
|
"itoa",
|
||||||
@@ -1137,9 +1137,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icalendar"
|
name = "icalendar"
|
||||||
version = "0.17.12"
|
version = "0.17.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3478c3b7a2411366daf20457373174bff6cfbc1089333038b1f95594d23d985"
|
checksum = "8fda1b791865374063fa57e84adfe3823c2d5cd5968d721533be4556a24cffd8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
@@ -1542,6 +1542,8 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "mcp_server_collection"
|
name = "mcp_server_collection"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
source = "sparse+https://git.mboemer.de/api/packages/milan/cargo/"
|
||||||
|
checksum = "875dadf54b4c4ddb6c11d724c41991011c8d24a5fde23c69d7c1e91aff913acf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -1551,7 +1553,7 @@ dependencies = [
|
|||||||
"icalendar",
|
"icalendar",
|
||||||
"libdav",
|
"libdav",
|
||||||
"own_assist_common 0.3.0",
|
"own_assist_common 0.3.0",
|
||||||
"rmcp",
|
"rmcp 2.2.0",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1565,9 +1567,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mcp_server_collection"
|
name = "mcp_server_collection"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
source = "sparse+https://git.mboemer.de/api/packages/milan/cargo/"
|
|
||||||
checksum = "875dadf54b4c4ddb6c11d724c41991011c8d24a5fde23c69d7c1e91aff913acf"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -1577,7 +1577,7 @@ dependencies = [
|
|||||||
"icalendar",
|
"icalendar",
|
||||||
"libdav",
|
"libdav",
|
||||||
"own_assist_common 0.3.0",
|
"own_assist_common 0.3.0",
|
||||||
"rmcp",
|
"rmcp 3.0.1",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1987,7 +1987,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "own_assist_cli"
|
name = "own_assist_cli"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.23.0",
|
"base64 0.23.0",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -1996,11 +1996,10 @@ dependencies = [
|
|||||||
"dialoguer",
|
"dialoguer",
|
||||||
"indicatif",
|
"indicatif",
|
||||||
"log",
|
"log",
|
||||||
"mcp_server_collection 0.2.2 (sparse+https://git.mboemer.de/api/packages/milan/cargo/)",
|
"mcp_server_collection 0.2.2",
|
||||||
"ollama-rs",
|
"own_assist_common 0.4.2",
|
||||||
"own_assist_common 0.4.1",
|
"own_mcp 0.2.0",
|
||||||
"own_mcp 0.1.1 (sparse+https://git.mboemer.de/api/packages/milan/cargo/)",
|
"rmcp 3.0.1",
|
||||||
"rmcp",
|
|
||||||
"rodio",
|
"rodio",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
@@ -2024,9 +2023,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "own_assist_common"
|
name = "own_assist_common"
|
||||||
version = "0.4.1"
|
version = "0.4.2"
|
||||||
source = "sparse+https://git.mboemer.de/api/packages/milan/cargo/"
|
source = "sparse+https://git.mboemer.de/api/packages/milan/cargo/"
|
||||||
checksum = "324156da8ebc00f6d5b6bd7709ffdf4dfe56bb0bb274315c133060d59ac8212b"
|
checksum = "fa329dcbbc05984ff2f2cc8cad5d8ea09939e3cb04ae4c1d41bfa402faa27c70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ollama-rs",
|
"ollama-rs",
|
||||||
@@ -2039,10 +2038,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "own_assist_common"
|
name = "own_assist_common"
|
||||||
version = "0.4.2"
|
version = "0.4.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ollama-rs",
|
"ollama-rs",
|
||||||
|
"own_mcp 0.2.0",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
"toml",
|
"toml",
|
||||||
@@ -2052,9 +2052,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "own_mcp"
|
name = "own_mcp"
|
||||||
version = "0.1.1"
|
version = "0.2.0"
|
||||||
|
source = "sparse+https://git.mboemer.de/api/packages/milan/cargo/"
|
||||||
|
checksum = "427641dafd06874e48a145761005779421db27710698fe0ac8fdfd27b0e3b46e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"cpal 0.18.1",
|
"cpal 0.18.1",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"hound",
|
"hound",
|
||||||
@@ -2062,7 +2066,7 @@ dependencies = [
|
|||||||
"ollama-rs",
|
"ollama-rs",
|
||||||
"rand 0.10.2",
|
"rand 0.10.2",
|
||||||
"reqwest 0.13.4",
|
"reqwest 0.13.4",
|
||||||
"rmcp",
|
"rmcp 3.0.1",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -2071,19 +2075,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "own_mcp"
|
name = "own_mcp"
|
||||||
version = "0.1.1"
|
version = "0.2.4"
|
||||||
source = "sparse+https://git.mboemer.de/api/packages/milan/cargo/"
|
|
||||||
checksum = "25d29e333d7fdd062f351598ed9761a10b7bb3c941259a66ce81cc12f484ecbe"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"cpal 0.18.1",
|
"cpal 0.18.1",
|
||||||
"env_logger",
|
|
||||||
"hound",
|
"hound",
|
||||||
"log",
|
"log",
|
||||||
"ollama-rs",
|
"ollama-rs",
|
||||||
"rand 0.10.2",
|
"rand 0.10.2",
|
||||||
"reqwest 0.13.4",
|
"reqwest 0.13.4",
|
||||||
"rmcp",
|
"rmcp 3.0.1",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.19",
|
"thiserror 2.0.19",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -2525,13 +2528,44 @@ dependencies = [
|
|||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
|
"pastey",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rand 0.10.2",
|
||||||
|
"rmcp-macros 2.2.0",
|
||||||
|
"schemars",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sse-stream",
|
||||||
|
"thiserror 2.0.19",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tokio-util",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rmcp"
|
||||||
|
version = "3.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3797d226787327b35b0b6f9e878fe55f3af2bb4daf916c0411079885454042f0"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"base64 0.23.0",
|
||||||
|
"bytes",
|
||||||
|
"chrono",
|
||||||
|
"futures",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"http-body-util",
|
||||||
"oauth2",
|
"oauth2",
|
||||||
"pastey",
|
"pastey",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"process-wrap",
|
"process-wrap",
|
||||||
"rand 0.10.2",
|
"rand 0.10.2",
|
||||||
"reqwest 0.13.4",
|
"reqwest 0.13.4",
|
||||||
"rmcp-macros",
|
"rmcp-macros 3.0.1",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -2559,6 +2593,19 @@ dependencies = [
|
|||||||
"syn 2.0.119",
|
"syn 2.0.119",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rmcp-macros"
|
||||||
|
version = "3.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8f5bc0c6851a20cd627ef4b90defb79f39a261c467de52af5d38000d7979c52"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde_json",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rodio"
|
name = "rodio"
|
||||||
version = "0.22.2"
|
version = "0.22.2"
|
||||||
@@ -2633,9 +2680,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.42"
|
version = "0.23.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138"
|
checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aws-lc-rs",
|
"aws-lc-rs",
|
||||||
"log",
|
"log",
|
||||||
@@ -2739,9 +2786,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schemars"
|
name = "schemars"
|
||||||
version = "1.2.1"
|
version = "1.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
|
checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
@@ -2753,14 +2800,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schemars_derive"
|
name = "schemars_derive"
|
||||||
version = "1.2.1"
|
version = "1.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f"
|
checksum = "d98c67716b46af2f0b8cf752abc930f6f9aecfbf671ecfb531db8a31dbe4e2ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"serde_derive_internals",
|
"serde_derive_internals",
|
||||||
"syn 2.0.119",
|
"syn 3.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2830,13 +2877,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive_internals"
|
name = "serde_derive_internals"
|
||||||
version = "0.29.1"
|
version = "0.30.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.119",
|
"syn 3.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3324,13 +3371,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.7.1"
|
version = "2.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
|
checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.119",
|
"syn 3.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3380,9 +3427,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "1.1.3+spec-1.1.0"
|
version = "1.1.4+spec-1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c"
|
checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
@@ -3416,9 +3463,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_parser"
|
name = "toml_parser"
|
||||||
version = "1.1.2+spec-1.1.0"
|
version = "1.1.3+spec-1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|||||||
+4
-5
@@ -1,17 +1,15 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "own_assist_cli"
|
name = "own_assist_cli"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ollama-rs = { version = "0.3.4", features = ["macros", "headers"] }
|
|
||||||
tokio = { version = "1.50.0", features = ["rt", "rt-multi-thread", "macros", "io-std"] }
|
tokio = { version = "1.50.0", features = ["rt", "rt-multi-thread", "macros", "io-std"] }
|
||||||
rmcp = { version = "2.2.0", features = ["client"] }
|
rmcp = { version = "3.0.1", features = ["client"] }
|
||||||
log = { version = "0.4.29" }
|
log = { version = "0.4.29" }
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
url = "2.5.8"
|
own_mcp = { version = "0.2.0", registry = "gitea" }
|
||||||
own_mcp = { version = "0.1.1", registry = "gitea" }
|
|
||||||
own_assist_common = { version = "0.4.1", registry = "gitea" }
|
own_assist_common = { version = "0.4.1", registry = "gitea" }
|
||||||
mcp_server_collection = { version = "0.2.0", registry = "gitea", optional = true}
|
mcp_server_collection = { version = "0.2.0", registry = "gitea", optional = true}
|
||||||
thiserror = "2.0.18"
|
thiserror = "2.0.18"
|
||||||
@@ -23,6 +21,7 @@ base64 = "0.23.0"
|
|||||||
cpal = "0.18.1"
|
cpal = "0.18.1"
|
||||||
rodio = "0.22.2"
|
rodio = "0.22.2"
|
||||||
tokio-util = { version = "0.7.18", optional = true }
|
tokio-util = { version = "0.7.18", optional = true }
|
||||||
|
url = "2.5.8"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["built-in-mcp-collection"]
|
default = ["built-in-mcp-collection"]
|
||||||
|
|||||||
+5
-3
@@ -102,19 +102,21 @@ async fn main() {
|
|||||||
let ollama = ollama_config.ollama();
|
let ollama = ollama_config.ollama();
|
||||||
let model_name = &ollama_config.model_config.name;
|
let model_name = &ollama_config.model_config.name;
|
||||||
|
|
||||||
ollama_config.create_model(Some(tlt!("model_download_needed"))).await.inspect_err(exit_msg!(format!(
|
ollama_config
|
||||||
|
.create_model(Some(tlt!("model_download_needed")))
|
||||||
|
.await
|
||||||
|
.inspect_err(exit_msg!(format!(
|
||||||
"failed creating ollama model `{model_name}`"
|
"failed creating ollama model `{model_name}`"
|
||||||
)))
|
)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
||||||
let mcp_clients = config
|
let mcp_clients = config
|
||||||
.mcp_clients()
|
.mcp_clients()
|
||||||
.await
|
.await
|
||||||
.inspect_err(exit_msg!("failed creating MCP clients"))
|
.inspect_err(exit_msg!("failed creating MCP clients"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut agent_chat = AgentChat::new(ollama, model_name.clone(), mcp_clients)
|
let mut agent_chat = AgentChat::new(Box::new(ollama), model_name.clone(), mcp_clients)
|
||||||
.await
|
.await
|
||||||
.inspect_err(exit_msg!("failed to create agent"))
|
.inspect_err(exit_msg!("failed to create agent"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "own_assist_common"
|
name = "own_assist_common"
|
||||||
version = "0.4.2"
|
version = "0.4.4"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
|
||||||
@@ -11,4 +11,5 @@ serde = { version = "1.0.228", features = ["derive"] }
|
|||||||
log = "0.4.29"
|
log = "0.4.29"
|
||||||
tracing-subscriber = { version = "0.3.23", features = ["env-filter"]}
|
tracing-subscriber = { version = "0.3.23", features = ["env-filter"]}
|
||||||
url = { version = "2.5.8", features = ["serde"] }
|
url = { version = "2.5.8", features = ["serde"] }
|
||||||
ollama-rs = { version = "0.3.6", features = ["headers"]}
|
ollama-rs = { version = "0.3.6", features = ["headers"]}
|
||||||
|
own_mcp = { version = "0.2.0", registry = "gitea" }
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
use ollama_rs::error::OllamaError;
|
use ollama_rs::error::OllamaError;
|
||||||
use ollama_rs::models::ModelOptions;
|
use ollama_rs::models::ModelOptions;
|
||||||
use ollama_rs::models::create::{CreateModelRequest, CreateModelStatus};
|
use ollama_rs::models::create::{CreateModelRequest, CreateModelStatus};
|
||||||
|
use own_mcp::mcp::Mistral;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
@@ -82,6 +83,21 @@ pub struct OllamaModelConfig {
|
|||||||
pub temperature: Option<f32>,
|
pub temperature: Option<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct MistralConfig {
|
||||||
|
#[serde(rename = "api-key")]
|
||||||
|
pub api_key: String,
|
||||||
|
pub model: String,
|
||||||
|
#[serde(rename = "system-prompt")]
|
||||||
|
pub system_prompt: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MistralConfig {
|
||||||
|
pub fn mistral(self) -> Mistral {
|
||||||
|
Mistral::new(self.api_key).with_system_prompt(self.system_prompt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct MCPClientConfig {
|
pub struct MCPClientConfig {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mcp_server_collection"
|
name = "mcp_server_collection"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rmcp = { version = "2.2.0", features = ["server", "transport-streamable-http-server-session", "transport-streamable-http-server"] }
|
rmcp = { version = "3.0.1", features = ["server", "transport-streamable-http-server-session", "transport-streamable-http-server"] }
|
||||||
chrono = "0.4.44"
|
chrono = "0.4.44"
|
||||||
axum = "0.8.9"
|
axum = "0.8.9"
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
|
|||||||
+9
-8
@@ -1,20 +1,21 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "own_mcp"
|
name = "own_mcp"
|
||||||
version = "0.1.1"
|
version = "0.2.4"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ollama-rs = {version = "0.3.4", features = ["macros", "headers"]}
|
ollama-rs = {version = "0.3.6", features = ["macros", "headers"]}
|
||||||
reqwest = { version = "0.13.2", features = ["stream", "multipart", "form"] }
|
reqwest = { version = "0.13.2", features = ["stream", "multipart", "form"] }
|
||||||
tokio = { version = "1.50.0", features = ["rt", "rt-multi-thread", "macros"] }
|
tokio = { version = "1.50.0", features = ["rt", "rt-multi-thread", "macros"] }
|
||||||
rmcp = {version="2.2.0", features = ["transport-streamable-http-client-reqwest", "reqwest", "client", "auth", "transport-child-process"]}
|
rmcp = {version="3.0.1", features = ["transport-streamable-http-client-reqwest", "reqwest", "client", "auth", "transport-child-process"]}
|
||||||
log = {version = "0.4.29"}
|
log = {version = "0.4.29"}
|
||||||
env_logger = "0.11.10"
|
serde = { version = "1.0.229", features = ["derive"] }
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
thiserror = "2.0.19"
|
||||||
thiserror = "2.0.17"
|
|
||||||
url = "2.5.8"
|
url = "2.5.8"
|
||||||
rand = "0.10.0"
|
rand = "0.10.2"
|
||||||
cpal = "0.18.1"
|
cpal = "0.18.1"
|
||||||
hound = "3.5.1"
|
hound = "3.5.1"
|
||||||
bytes = "1.11.1"
|
bytes = "1.11.1"
|
||||||
|
async-trait = "0.1.91"
|
||||||
|
chrono = "0.4.45"
|
||||||
@@ -2,6 +2,7 @@ pub mod audio;
|
|||||||
pub mod mcp;
|
pub mod mcp;
|
||||||
|
|
||||||
pub use mcp::chat::AgentChat;
|
pub use mcp::chat::AgentChat;
|
||||||
|
pub use mcp::llmclient::LLMClient;
|
||||||
|
|
||||||
pub use ollama_rs;
|
pub use ollama_rs;
|
||||||
pub use rmcp;
|
pub use rmcp;
|
||||||
|
|||||||
+17
-23
@@ -1,9 +1,7 @@
|
|||||||
use crate::mcp::MCPClient;
|
use crate::mcp::MCPClient;
|
||||||
use ollama_rs::Ollama;
|
use crate::mcp::llmclient::{LLMClient, LLMError};
|
||||||
use ollama_rs::error::OllamaError;
|
|
||||||
use ollama_rs::generation::chat::ChatMessage;
|
use ollama_rs::generation::chat::ChatMessage;
|
||||||
use ollama_rs::generation::chat::request::ChatMessageRequest;
|
use ollama_rs::generation::chat::request::ChatMessageRequest;
|
||||||
use ollama_rs::generation::completion::request::GenerationRequest;
|
|
||||||
use ollama_rs::generation::tools::{ToolCall, ToolInfo};
|
use ollama_rs::generation::tools::{ToolCall, ToolInfo};
|
||||||
use rmcp::ServiceError;
|
use rmcp::ServiceError;
|
||||||
use rmcp::model::{CallToolRequestParams, CallToolResult};
|
use rmcp::model::{CallToolRequestParams, CallToolResult};
|
||||||
@@ -77,16 +75,16 @@ impl MCPServerData {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AgentChat {
|
pub struct AgentChat {
|
||||||
ollama_client: Ollama,
|
llm_client: Box<dyn LLMClient>,
|
||||||
model: String,
|
model: String,
|
||||||
mcp_servers: HashMap<String, MCPServerData>,
|
mcp_servers: HashMap<String, MCPServerData>,
|
||||||
message_history: Vec<ChatMessage>,
|
pub message_history: Vec<ChatMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ChatError {
|
pub enum ChatError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
OllamaError(#[from] OllamaError),
|
LLMError(#[from] LLMError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ServiceError(#[from] ServiceError),
|
ServiceError(#[from] ServiceError),
|
||||||
#[error("the function name could not be parsed")]
|
#[error("the function name could not be parsed")]
|
||||||
@@ -113,7 +111,7 @@ pub struct ToolUsage {
|
|||||||
|
|
||||||
impl AgentChat {
|
impl AgentChat {
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
ollama_client: Ollama,
|
llm_client: Box<dyn LLMClient>,
|
||||||
model: String,
|
model: String,
|
||||||
mcp_clients: HashMap<String, MCPClient>,
|
mcp_clients: HashMap<String, MCPClient>,
|
||||||
) -> Result<Self, ServiceError> {
|
) -> Result<Self, ServiceError> {
|
||||||
@@ -126,17 +124,8 @@ impl AgentChat {
|
|||||||
servers.insert(server.name.clone(), server);
|
servers.insert(server.name.clone(), server);
|
||||||
}
|
}
|
||||||
|
|
||||||
// lets the ollama server load the model
|
|
||||||
let ollama_client_clone = ollama_client.clone();
|
|
||||||
let model_clone = model.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let _ = ollama_client_clone
|
|
||||||
.generate(GenerationRequest::new(model_clone, ""))
|
|
||||||
.await;
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ollama_client,
|
llm_client,
|
||||||
model,
|
model,
|
||||||
mcp_servers: servers,
|
mcp_servers: servers,
|
||||||
message_history: history,
|
message_history: history,
|
||||||
@@ -232,7 +221,7 @@ impl AgentChat {
|
|||||||
log::debug!("all tools: {all_tools:#?}");
|
log::debug!("all tools: {all_tools:#?}");
|
||||||
|
|
||||||
let mut response = self
|
let mut response = self
|
||||||
.ollama_client
|
.llm_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![ChatMessage::user(user_message)])
|
ChatMessageRequest::new(self.model.clone(), vec![ChatMessage::user(user_message)])
|
||||||
@@ -288,7 +277,7 @@ impl AgentChat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
response = self
|
response = self
|
||||||
.ollama_client
|
.llm_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())
|
ChatMessageRequest::new(self.model.clone(), Vec::new())
|
||||||
@@ -375,7 +364,7 @@ impl AgentChat {
|
|||||||
|
|
||||||
pub fn without_history(self) -> Self {
|
pub fn without_history(self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ollama_client: self.ollama_client,
|
llm_client: self.llm_client,
|
||||||
model: self.model,
|
model: self.model,
|
||||||
mcp_servers: self.mcp_servers,
|
mcp_servers: self.mcp_servers,
|
||||||
message_history: vec![],
|
message_history: vec![],
|
||||||
@@ -392,6 +381,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::mcp::chat::RestrictedTool;
|
use crate::mcp::chat::RestrictedTool;
|
||||||
use crate::mcp::get_client;
|
use crate::mcp::get_client;
|
||||||
|
use ollama_rs::Ollama;
|
||||||
use rmcp::model::Implementation;
|
use rmcp::model::Implementation;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -421,9 +411,13 @@ mod tests {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
)]);
|
)]);
|
||||||
|
|
||||||
let mut chat = AgentChat::new(ollama, "lfm2.5-thinking:1.2b".to_string(), mcp_clients)
|
let mut chat = AgentChat::new(
|
||||||
.await
|
Box::new(ollama),
|
||||||
.unwrap();
|
"lfm2.5-thinking:1.2b".to_string(),
|
||||||
|
mcp_clients,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let tools: Vec<RestrictedTool> = chat.get_all_tools().cloned().collect();
|
let tools: Vec<RestrictedTool> = chat.get_all_tools().cloned().collect();
|
||||||
assert_eq!(tools.len(), 1);
|
assert_eq!(tools.len(), 1);
|
||||||
|
|||||||
@@ -0,0 +1,216 @@
|
|||||||
|
use crate::mcp::llmclient::{LLMClient, LLMError};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use ollama_rs::generation::chat::ChatMessage as OllamaChatMessage;
|
||||||
|
use ollama_rs::generation::chat::request::ChatMessageRequest as OllamaChatMessageRequest;
|
||||||
|
use ollama_rs::generation::chat::{ChatMessageResponse, MessageRole};
|
||||||
|
use ollama_rs::generation::tools::{ToolCall, ToolInfo};
|
||||||
|
use ollama_rs::history::ChatHistory;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Mistral {
|
||||||
|
api_key: String,
|
||||||
|
system_prompt: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mistral {
|
||||||
|
pub fn new(api_key: String) -> Mistral {
|
||||||
|
Mistral {
|
||||||
|
api_key,
|
||||||
|
system_prompt: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_system_prompt(mut self, system_prompt: Option<String>) -> Mistral {
|
||||||
|
self.system_prompt = system_prompt;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct Message {
|
||||||
|
content: String,
|
||||||
|
role: MessageRole,
|
||||||
|
#[serde(
|
||||||
|
skip_serializing_if = "Vec::is_empty",
|
||||||
|
default = "Vec::new",
|
||||||
|
deserialize_with = "parse_tool_calls"
|
||||||
|
)]
|
||||||
|
tool_calls: Vec<ToolCall>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_tool_calls<'de, D>(d: D) -> Result<Vec<ToolCall>, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Deserialize::deserialize(d).map(|x: Option<_>| x.unwrap_or(Vec::new()))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OllamaChatMessage> for Message {
|
||||||
|
fn from(message: OllamaChatMessage) -> Message {
|
||||||
|
Message {
|
||||||
|
content: message.content,
|
||||||
|
role: message.role,
|
||||||
|
tool_calls: message.tool_calls,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Message> for OllamaChatMessage {
|
||||||
|
fn from(message: Message) -> OllamaChatMessage {
|
||||||
|
OllamaChatMessage {
|
||||||
|
role: message.role,
|
||||||
|
content: message.content,
|
||||||
|
tool_calls: message.tool_calls,
|
||||||
|
images: None,
|
||||||
|
thinking: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct ChatCompletionRequest {
|
||||||
|
messages: Vec<Message>,
|
||||||
|
model: String,
|
||||||
|
tools: Vec<ToolInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OllamaChatMessageRequest> for ChatCompletionRequest {
|
||||||
|
fn from(request: OllamaChatMessageRequest) -> ChatCompletionRequest {
|
||||||
|
ChatCompletionRequest {
|
||||||
|
messages: request.messages.into_iter().map(|m| m.into()).collect(),
|
||||||
|
model: request.model_name,
|
||||||
|
tools: request.tools,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
struct ChatCompletionChoice {
|
||||||
|
message: Message,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
struct ChatCompletionResponse {
|
||||||
|
choices: Vec<ChatCompletionChoice>,
|
||||||
|
model: String,
|
||||||
|
#[serde(rename = "created")]
|
||||||
|
created_unix_seconds: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<ChatCompletionResponse> for ChatMessageResponse {
|
||||||
|
type Error = LLMError;
|
||||||
|
|
||||||
|
fn try_from(value: ChatCompletionResponse) -> Result<ChatMessageResponse, LLMError> {
|
||||||
|
let created = chrono::DateTime::from_timestamp(value.created_unix_seconds, 0)
|
||||||
|
.ok_or(LLMError::Other("failed converting timestamp".to_string()))?;
|
||||||
|
|
||||||
|
Ok(ChatMessageResponse {
|
||||||
|
model: value.model,
|
||||||
|
created_at: created.to_rfc3339(),
|
||||||
|
message: value
|
||||||
|
.choices
|
||||||
|
.first()
|
||||||
|
.ok_or(LLMError::Other("answer does not exist".to_string()))?
|
||||||
|
.message
|
||||||
|
.clone()
|
||||||
|
.into(),
|
||||||
|
logprobs: None,
|
||||||
|
done: false,
|
||||||
|
final_data: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl LLMClient for Mistral {
|
||||||
|
async fn send_chat_messages_with_history(
|
||||||
|
&self,
|
||||||
|
history: &mut Vec<OllamaChatMessage>,
|
||||||
|
mut request: ollama_rs::generation::chat::request::ChatMessageRequest,
|
||||||
|
) -> Result<ChatMessageResponse, LLMError> {
|
||||||
|
if let Some(first_message) = history.first() // add system prompt as first message
|
||||||
|
&& first_message.role != MessageRole::System
|
||||||
|
&& let Some(system_prompt) = self.system_prompt.clone()
|
||||||
|
{
|
||||||
|
history.insert(
|
||||||
|
0,
|
||||||
|
OllamaChatMessage::new(MessageRole::System, system_prompt),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
history.append(&mut request.messages);
|
||||||
|
|
||||||
|
request.messages = history.messages().to_vec();
|
||||||
|
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let chat_completion_request: ChatCompletionRequest = request.into();
|
||||||
|
let response = client
|
||||||
|
.post("https://api.mistral.ai/v1/chat/completions")
|
||||||
|
.header("Authorization", format!("Bearer {}", self.api_key))
|
||||||
|
.json(&chat_completion_request)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|e| LLMError::NetworkError(e.to_string()))?;
|
||||||
|
|
||||||
|
let response = response
|
||||||
|
.error_for_status()
|
||||||
|
.map_err(|e| LLMError::Other(e.to_string()))?;
|
||||||
|
|
||||||
|
let completion_response: ChatCompletionResponse = response
|
||||||
|
.json()
|
||||||
|
.await
|
||||||
|
.map_err(|e| LLMError::Other(e.to_string()))?;
|
||||||
|
let chat_message_response: ChatMessageResponse = completion_response.try_into()?;
|
||||||
|
|
||||||
|
Ok(chat_message_response)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn preload_model(&self, _model: &str) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use ollama_rs::generation::chat::request::ChatMessageRequest;
|
||||||
|
use ollama_rs::generation::chat::{ChatMessage, MessageRole};
|
||||||
|
use rmcp::schemars;
|
||||||
|
|
||||||
|
#[derive(schemars::JsonSchema)]
|
||||||
|
struct BeepToolParameters {
|
||||||
|
location: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn sending_message() {
|
||||||
|
let client = Mistral::new(include_str!(".MISTRAL_API_KEY").to_string());
|
||||||
|
|
||||||
|
let mut history = vec![];
|
||||||
|
|
||||||
|
dbg!(
|
||||||
|
client
|
||||||
|
.send_chat_messages_with_history(
|
||||||
|
&mut history,
|
||||||
|
ChatMessageRequest::new(
|
||||||
|
"mistral-medium-3-5".to_string(),
|
||||||
|
vec![ChatMessage::new(
|
||||||
|
MessageRole::User,
|
||||||
|
"Mach ein Geräusch in der Küche".to_string()
|
||||||
|
)],
|
||||||
|
)
|
||||||
|
.tools(vec![ToolInfo {
|
||||||
|
tool_type: ollama_rs::generation::tools::ToolType::Function,
|
||||||
|
function: ollama_rs::generation::tools::ToolFunctionInfo {
|
||||||
|
name: "make_sound".to_string(),
|
||||||
|
description: "alerts the user with a beep".to_string(),
|
||||||
|
parameters: schemars::schema_for!(BeepToolParameters),
|
||||||
|
}
|
||||||
|
}]),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
pub mod mistral;
|
||||||
|
pub mod ollama;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use ollama_rs::generation::chat::request::ChatMessageRequest;
|
||||||
|
use ollama_rs::generation::chat::{ChatMessage, ChatMessageResponse};
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum LLMError {
|
||||||
|
#[error("network error: {0}")]
|
||||||
|
NetworkError(String),
|
||||||
|
#[error("llm error: {0}")]
|
||||||
|
Other(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait LLMClient: Debug + Send + Sync {
|
||||||
|
async fn send_chat_messages_with_history(
|
||||||
|
&self,
|
||||||
|
history: &mut Vec<ChatMessage>,
|
||||||
|
request: ChatMessageRequest,
|
||||||
|
) -> Result<ChatMessageResponse, LLMError>;
|
||||||
|
|
||||||
|
async fn preload_model(&self, model: &str);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
use crate::mcp::llmclient::{LLMClient, LLMError};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use ollama_rs::Ollama;
|
||||||
|
use ollama_rs::error::OllamaError;
|
||||||
|
use ollama_rs::generation::chat::request::ChatMessageRequest;
|
||||||
|
use ollama_rs::generation::chat::{ChatMessage, ChatMessageResponse};
|
||||||
|
use ollama_rs::generation::completion::request::GenerationRequest;
|
||||||
|
|
||||||
|
impl From<OllamaError> for LLMError {
|
||||||
|
fn from(err: OllamaError) -> LLMError {
|
||||||
|
match err {
|
||||||
|
OllamaError::ToolCallError(e) => LLMError::Other(e.to_string()),
|
||||||
|
OllamaError::JsonError(e) => LLMError::Other(e.to_string()),
|
||||||
|
OllamaError::ReqwestError(e) => LLMError::NetworkError(e.to_string()),
|
||||||
|
OllamaError::InternalError(e) => LLMError::Other(e.message),
|
||||||
|
OllamaError::Other(e) => LLMError::Other(e.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl LLMClient for Ollama {
|
||||||
|
async fn send_chat_messages_with_history(
|
||||||
|
&self,
|
||||||
|
history: &mut Vec<ChatMessage>,
|
||||||
|
request: ChatMessageRequest,
|
||||||
|
) -> Result<ChatMessageResponse, LLMError> {
|
||||||
|
Ok(self
|
||||||
|
.send_chat_messages_with_history(history, request)
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn preload_model(&self, model: &str) {
|
||||||
|
let _ = self
|
||||||
|
.generate(GenerationRequest::new(model.to_string(), ""))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
pub mod chat;
|
pub mod chat;
|
||||||
|
pub mod llmclient;
|
||||||
mod translation;
|
mod translation;
|
||||||
|
|
||||||
|
pub use llmclient::mistral::Mistral;
|
||||||
|
|
||||||
use rmcp::model::InitializeRequestParams;
|
use rmcp::model::InitializeRequestParams;
|
||||||
use rmcp::service::{ClientInitializeError, RunningService};
|
use rmcp::service::{ClientInitializeError, RunningService};
|
||||||
use rmcp::transport::streamable_http_client::StreamableHttpClientTransportConfig;
|
use rmcp::transport::streamable_http_client::StreamableHttpClientTransportConfig;
|
||||||
@@ -48,8 +51,10 @@ pub fn guaranteed_mcp_server_name(
|
|||||||
) -> String {
|
) -> String {
|
||||||
if let Some(user_specified_name) = user_specified_name {
|
if let Some(user_specified_name) = user_specified_name {
|
||||||
user_specified_name
|
user_specified_name
|
||||||
} else if let Some(peer_info) = client.peer_info() {
|
} else if let Some(peer_info) = client.peer_info()
|
||||||
peer_info.server_info.name.clone()
|
&& let Some(server_info) = &peer_info.server_info
|
||||||
|
{
|
||||||
|
server_info.name.clone()
|
||||||
} else {
|
} else {
|
||||||
let random_name = generate_random_mcp_server_name();
|
let random_name = generate_random_mcp_server_name();
|
||||||
log::warn!(
|
log::warn!(
|
||||||
|
|||||||
Reference in New Issue
Block a user