chore: update crates
This commit is contained in:
parent
f9d22b5382
commit
6335aba33b
263
Cargo.lock
generated
263
Cargo.lock
generated
@ -23,6 +23,18 @@ version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "affinitypool"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dde2a385b82232b559baeec740c37809051c596f9b56e7da0d0da2c8e8f54f6"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"num_cpus",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.8"
|
||||
@ -332,7 +344,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"static_assertions_next",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -349,7 +361,7 @@ dependencies = [
|
||||
"quote",
|
||||
"strum",
|
||||
"syn 2.0.114",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -394,6 +406,17 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.6"
|
||||
@ -490,7 +513,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"pastey",
|
||||
"rayon",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"v_frame",
|
||||
"y4m",
|
||||
]
|
||||
@ -1070,6 +1093,15 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
@ -1411,6 +1443,12 @@ dependencies = [
|
||||
"urlencoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "double-ended-peekable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0d05e1c0dbad51b52c38bda7adceef61b9efc2baf04acfe8726a8c4630a6f57"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "1.0.11"
|
||||
@ -1567,6 +1605,19 @@ dependencies = [
|
||||
"zune-inflate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ext-sort"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf5d3b056bcc471d38082b8c453acb6670f7327fd44219b3c411e40834883569"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rayon",
|
||||
"rmp-serde",
|
||||
"serde",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastembed"
|
||||
version = "5.8.1"
|
||||
@ -2055,6 +2106,10 @@ name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
@ -2149,7 +2204,7 @@ dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"ureq 2.12.1",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
@ -2240,6 +2295,16 @@ version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
|
||||
|
||||
[[package]]
|
||||
name = "humantime-serde"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "1.8.1"
|
||||
@ -2700,7 +2765,6 @@ dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"dashmap 6.1.0",
|
||||
"fastembed",
|
||||
"futures",
|
||||
"mockito",
|
||||
"notify",
|
||||
@ -2711,10 +2775,11 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"stratum-embeddings",
|
||||
"surrealdb",
|
||||
"tempfile",
|
||||
"tera",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
@ -2889,6 +2954,15 @@ dependencies = [
|
||||
"imgref",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.12.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
|
||||
dependencies = [
|
||||
"hashbrown 0.15.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru-slab"
|
||||
version = "0.1.2"
|
||||
@ -3088,6 +3162,26 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "moka"
|
||||
version = "0.12.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"crossbeam-channel",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"equivalent",
|
||||
"event-listener",
|
||||
"futures-util",
|
||||
"parking_lot",
|
||||
"portable-atomic",
|
||||
"smallvec",
|
||||
"tagptr",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monostate"
|
||||
version = "0.1.18"
|
||||
@ -3404,7 +3498,7 @@ dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
@ -4001,6 +4095,18 @@ dependencies = [
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick_cache"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ada44a88ef953a3294f6eb55d2007ba44646015e18613d2f213016379203ef3"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"equivalent",
|
||||
"hashbrown 0.16.1",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.9"
|
||||
@ -4015,7 +4121,7 @@ dependencies = [
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"socket2",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"web-time",
|
||||
@ -4036,7 +4142,7 @@ dependencies = [
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
"web-time",
|
||||
@ -4177,7 +4283,7 @@ dependencies = [
|
||||
"rand 0.9.2",
|
||||
"rand_chacha 0.9.0",
|
||||
"simd_helpers",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"v_frame",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@ -4268,7 +4374,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
||||
dependencies = [
|
||||
"getrandom 0.2.17",
|
||||
"libredox",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4377,6 +4483,15 @@ dependencies = [
|
||||
"webpki-roots 1.0.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "revision"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22f53179a035f881adad8c4d58a2c599c6b4a8325b989c68d178d7a34d1b1e4c"
|
||||
dependencies = [
|
||||
"revision-derive 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "revision"
|
||||
version = "0.11.0"
|
||||
@ -4386,12 +4501,23 @@ dependencies = [
|
||||
"chrono",
|
||||
"geo",
|
||||
"regex",
|
||||
"revision-derive",
|
||||
"revision-derive 0.11.0",
|
||||
"roaring",
|
||||
"rust_decimal",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "revision-derive"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0ec466e5d8dca9965eb6871879677bef5590cf7525ad96cae14376efb75073"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "revision-derive"
|
||||
version = "0.11.0"
|
||||
@ -4411,9 +4537,9 @@ checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
|
||||
|
||||
[[package]]
|
||||
name = "rig-core"
|
||||
version = "0.28.0"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b1a48121c1ecd6f6ce59d64ec353c791aac6fc07bf4aa353380e8185659e6eb"
|
||||
checksum = "a8f7a3f0c7c00eaced15a68ee16e1bd6bb709ff598d11b9aedac8b628217dc09"
|
||||
dependencies = [
|
||||
"as-any",
|
||||
"async-stream",
|
||||
@ -4427,13 +4553,14 @@ dependencies = [
|
||||
"http",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"nanoid",
|
||||
"ordered-float",
|
||||
"pin-project-lite",
|
||||
"reqwest",
|
||||
"schemars 1.2.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
@ -4492,6 +4619,16 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmp-serde"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
|
||||
dependencies = [
|
||||
"rmp",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmpv"
|
||||
version = "1.3.1"
|
||||
@ -5039,7 +5176,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
]
|
||||
|
||||
@ -5183,6 +5320,24 @@ dependencies = [
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stratum-embeddings"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"fastembed",
|
||||
"futures",
|
||||
"humantime-serde",
|
||||
"moka",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"surrealdb",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"xxhash-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.9"
|
||||
@ -5243,9 +5398,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "surrealdb"
|
||||
version = "2.4.1"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f921fcafdc840d36a4378ef7639fcb2731a21a858b048de83f0bd7194c242479"
|
||||
checksum = "62b7720b39ce2985efbfa10858b7397ffd95655a9bab6d9dfaa03622bbdc3bc2"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"async-channel",
|
||||
@ -5260,7 +5415,7 @@ dependencies = [
|
||||
"pharos",
|
||||
"reblessive",
|
||||
"reqwest",
|
||||
"revision",
|
||||
"revision 0.11.0",
|
||||
"ring",
|
||||
"rust_decimal",
|
||||
"rustls",
|
||||
@ -5285,11 +5440,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "surrealdb-core"
|
||||
version = "2.4.1"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eae1a46c6d68a61c0a270f456a152433093f4d5c0e71c45eea64f95e95d68bd9"
|
||||
checksum = "c48e42c81713be2f9b3dae64328999eafe8b8060dd584059445a908748b39787"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"affinitypool",
|
||||
"ahash 0.8.12",
|
||||
"ammonia",
|
||||
"any_ascii",
|
||||
@ -5309,12 +5465,14 @@ dependencies = [
|
||||
"dashmap 5.5.3",
|
||||
"deunicode",
|
||||
"dmp",
|
||||
"ext-sort",
|
||||
"fst",
|
||||
"futures",
|
||||
"fuzzy-matcher",
|
||||
"geo",
|
||||
"geo-types",
|
||||
"getrandom 0.3.4",
|
||||
"hashbrown 0.14.5",
|
||||
"hex",
|
||||
"http",
|
||||
"ipnet",
|
||||
@ -5333,13 +5491,13 @@ dependencies = [
|
||||
"pharos",
|
||||
"phf",
|
||||
"pin-project-lite",
|
||||
"quick_cache",
|
||||
"quick_cache 0.5.2",
|
||||
"radix_trie",
|
||||
"rand 0.8.5",
|
||||
"rayon",
|
||||
"reblessive",
|
||||
"regex",
|
||||
"revision",
|
||||
"revision 0.11.0",
|
||||
"ring",
|
||||
"rmpv",
|
||||
"roaring",
|
||||
@ -5356,7 +5514,9 @@ dependencies = [
|
||||
"storekey",
|
||||
"strsim",
|
||||
"subtle",
|
||||
"surrealkv",
|
||||
"sysinfo",
|
||||
"tempfile",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@ -5365,12 +5525,31 @@ dependencies = [
|
||||
"unicase",
|
||||
"url",
|
||||
"uuid",
|
||||
"vart",
|
||||
"vart 0.8.1",
|
||||
"wasm-bindgen-futures",
|
||||
"wasmtimer",
|
||||
"ws_stream_wasm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "surrealkv"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08a5041979bdff8599a1d5f6cb7365acb9a79664e2a84e5c4fddac2b3969f7d1"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"crc32fast",
|
||||
"double-ended-peekable",
|
||||
"getrandom 0.2.17",
|
||||
"lru",
|
||||
"parking_lot",
|
||||
"quick_cache 0.6.18",
|
||||
"revision 0.10.0",
|
||||
"vart 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
@ -5448,6 +5627,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tagptr"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
@ -5522,11 +5707,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.17"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.17",
|
||||
"thiserror-impl 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5542,9 +5727,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.17"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -5666,7 +5851,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"spm_precompiled",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"unicode-normalization-alignments",
|
||||
"unicode-segmentation",
|
||||
"unicode_categories",
|
||||
@ -6156,9 +6341,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.19.0"
|
||||
version = "1.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
|
||||
checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"js-sys",
|
||||
@ -6189,6 +6374,12 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87782b74f898179396e93c0efabb38de0d58d50bbd47eae00c71b3a1144dbbae"
|
||||
|
||||
[[package]]
|
||||
name = "vart"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1982d899e57d646498709735f16e9224cf1e8680676ad687f930cf8b5b555ae"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
@ -6738,7 +6929,7 @@ dependencies = [
|
||||
"pharos",
|
||||
"rustc_version",
|
||||
"send_wrapper",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
@ -6753,6 +6944,12 @@ dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xxhash-rust"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3"
|
||||
|
||||
[[package]]
|
||||
name = "y4m"
|
||||
version = "0.8.0"
|
||||
|
||||
@ -28,7 +28,7 @@ toml = "0.9"
|
||||
tokio = { version = "1.49", features = ["full"] }
|
||||
|
||||
# Error handling
|
||||
thiserror = "2.0"
|
||||
thiserror = "2.0.18"
|
||||
anyhow = "1.0"
|
||||
|
||||
# Markdown parsing
|
||||
@ -38,10 +38,10 @@ pulldown-cmark = "0.13"
|
||||
tera = "1.20"
|
||||
|
||||
# Embeddings
|
||||
rig-core = "0.28"
|
||||
rig-core = "0.30"
|
||||
|
||||
# Storage
|
||||
surrealdb = "2.4"
|
||||
surrealdb = "2.6"
|
||||
dashmap = "6.1"
|
||||
|
||||
# File watching
|
||||
@ -51,7 +51,7 @@ notify = "8.2"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
|
||||
# UUID generation
|
||||
uuid = { version = "1.19", features = ["v4", "serde"] }
|
||||
uuid = { version = "1.20", features = ["v4", "serde"] }
|
||||
|
||||
# Logging
|
||||
tracing = "0.1"
|
||||
|
||||
@ -508,7 +508,7 @@ watch_paths = ["notes", "decisions", "guidelines", "patterns", "journal"]
|
||||
|
||||
/// Add a new node
|
||||
async fn cmd_add(
|
||||
project_dir: &PathBuf,
|
||||
project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
node_type: CliNodeType,
|
||||
title: String,
|
||||
@ -566,7 +566,7 @@ async fn cmd_add(
|
||||
|
||||
/// Search KOGRAL
|
||||
async fn cmd_search(
|
||||
project_dir: &PathBuf,
|
||||
project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
query: String,
|
||||
node_type: Option<CliNodeType>,
|
||||
@ -652,7 +652,7 @@ async fn cmd_search(
|
||||
|
||||
/// Create a relationship between nodes
|
||||
async fn cmd_link(
|
||||
project_dir: &PathBuf,
|
||||
project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
from: String,
|
||||
to: String,
|
||||
@ -710,7 +710,7 @@ async fn cmd_link(
|
||||
|
||||
/// Sync filesystem with storage
|
||||
async fn cmd_sync(
|
||||
_project_dir: &PathBuf,
|
||||
_project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
direction: String,
|
||||
dry_run: bool,
|
||||
@ -744,7 +744,7 @@ async fn cmd_sync(
|
||||
|
||||
/// Start MCP server
|
||||
async fn cmd_serve(
|
||||
_project_dir: &PathBuf,
|
||||
_project_dir: &Path,
|
||||
_config: Option<KbConfig>,
|
||||
transport: String,
|
||||
port: u16,
|
||||
@ -784,7 +784,7 @@ async fn cmd_serve(
|
||||
/// Show graph visualization
|
||||
#[allow(clippy::excessive_nesting)]
|
||||
async fn cmd_graph(
|
||||
project_dir: &PathBuf,
|
||||
project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
format: String,
|
||||
node_type: Option<CliNodeType>,
|
||||
@ -873,7 +873,7 @@ async fn cmd_graph(
|
||||
|
||||
/// Import from external sources
|
||||
async fn cmd_import(
|
||||
_project_dir: &PathBuf,
|
||||
_project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
source: ImportSource,
|
||||
path: PathBuf,
|
||||
@ -948,7 +948,7 @@ async fn cmd_import(
|
||||
|
||||
/// Export to external formats
|
||||
async fn cmd_export(
|
||||
project_dir: &PathBuf,
|
||||
project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
format: ExportFormat,
|
||||
output: PathBuf,
|
||||
@ -1066,7 +1066,7 @@ async fn cmd_export(
|
||||
|
||||
/// List all nodes
|
||||
async fn cmd_list(
|
||||
project_dir: &PathBuf,
|
||||
project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
node_type: Option<CliNodeType>,
|
||||
status: Option<CliNodeStatus>,
|
||||
@ -1134,7 +1134,7 @@ async fn cmd_list(
|
||||
/// Show node details
|
||||
#[allow(clippy::excessive_nesting)]
|
||||
async fn cmd_show(
|
||||
project_dir: &PathBuf,
|
||||
project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
node: String,
|
||||
relations: bool,
|
||||
@ -1199,7 +1199,7 @@ async fn cmd_show(
|
||||
|
||||
/// Delete a node
|
||||
async fn cmd_delete(
|
||||
project_dir: &PathBuf,
|
||||
project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
node: String,
|
||||
cascade: bool,
|
||||
@ -1249,7 +1249,7 @@ async fn cmd_delete(
|
||||
|
||||
/// Manage configuration
|
||||
async fn cmd_config(
|
||||
_project_dir: &PathBuf,
|
||||
_project_dir: &Path,
|
||||
config: Option<KbConfig>,
|
||||
show: bool,
|
||||
get: Option<String>,
|
||||
|
||||
@ -30,12 +30,14 @@ tracing = { workspace = true }
|
||||
|
||||
# Additional dependencies
|
||||
async-trait = { workspace = true }
|
||||
fastembed = { workspace = true, optional = true }
|
||||
regex = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
walkdir = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
|
||||
# Stratum embeddings
|
||||
stratum-embeddings = { path = "/Users/Akasha/Development/stratumiops/crates/stratum-embeddings", features = ["kogral"] }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { workspace = true, features = ["test-util", "macros"] }
|
||||
mockito = { workspace = true }
|
||||
@ -45,5 +47,4 @@ tempfile = { workspace = true }
|
||||
default = ["filesystem"]
|
||||
filesystem = []
|
||||
surrealdb-backend = ["surrealdb"]
|
||||
fastembed = ["dep:fastembed"]
|
||||
full = ["surrealdb-backend", "fastembed"]
|
||||
full = ["surrealdb-backend"]
|
||||
|
||||
@ -15,8 +15,8 @@ use std::fmt::Write;
|
||||
use crate::error::Result;
|
||||
use crate::models::{Block, TaskStatus};
|
||||
use crate::regex_patterns::{
|
||||
PROPERTY_START_PATTERN, TAG_PATTERN, PROPERTY_INLINE_PATTERN, UUID_REF_PATTERN,
|
||||
LOGSEQ_WIKILINK_PATTERN,
|
||||
LOGSEQ_WIKILINK_PATTERN, PROPERTY_INLINE_PATTERN, PROPERTY_START_PATTERN, TAG_PATTERN,
|
||||
UUID_REF_PATTERN,
|
||||
};
|
||||
|
||||
/// Parser for converting markdown outliner format to/from Block structures
|
||||
@ -208,7 +208,9 @@ impl BlockParser {
|
||||
}
|
||||
|
||||
// Remove properties from content
|
||||
clean_content = PROPERTY_INLINE_PATTERN.replace_all(&clean_content, "").to_string();
|
||||
clean_content = PROPERTY_INLINE_PATTERN
|
||||
.replace_all(&clean_content, "")
|
||||
.to_string();
|
||||
|
||||
(properties, clean_content)
|
||||
}
|
||||
|
||||
@ -1,113 +0,0 @@
|
||||
//! `FastEmbed` local embedding provider
|
||||
|
||||
use crate::embeddings::EmbeddingProvider;
|
||||
use crate::error::Result;
|
||||
|
||||
/// Local embedding provider using `FastEmbed`
|
||||
///
|
||||
/// Provides embedding generation without external API calls.
|
||||
/// Uses local models for privacy and offline capability.
|
||||
///
|
||||
/// Default model: BAAI/bge-small-en-v1.5 (384 dimensions)
|
||||
/// Supports CPU inference with minimal memory footprint.
|
||||
#[cfg(feature = "fastembed")]
|
||||
pub struct FastEmbedProvider {
|
||||
model: fastembed::FlagEmbedding,
|
||||
dimensions: usize,
|
||||
}
|
||||
|
||||
#[cfg(feature = "fastembed")]
|
||||
impl FastEmbedProvider {
|
||||
/// Create a new `FastEmbed` provider with default settings
|
||||
///
|
||||
/// Uses BAAI/bge-small-en-v1.5 model by default (384 dimensions).
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns error if model initialization fails (e.g., download issues).
|
||||
pub fn new() -> Result<Self> {
|
||||
let model = fastembed::FlagEmbedding::try_new(Default::default()).map_err(|e| {
|
||||
crate::error::KbError::Embedding(format!("Failed to initialize FastEmbed: {}", e))
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
dimensions: 384, // BAAI/bge-small-en-v1.5 dimensions
|
||||
model,
|
||||
})
|
||||
}
|
||||
|
||||
/// Create with custom dimensions (for compatibility)
|
||||
///
|
||||
/// Note: Actual dimensions will be determined by the model,
|
||||
/// this parameter is for API compatibility.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns error if model initialization fails.
|
||||
pub fn with_dimensions(dimensions: usize) -> Result<Self> {
|
||||
let model = fastembed::FlagEmbedding::try_new(Default::default()).map_err(|e| {
|
||||
crate::error::KbError::Embedding(format!("Failed to initialize FastEmbed: {}", e))
|
||||
})?;
|
||||
|
||||
Ok(Self { model, dimensions })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "fastembed")]
|
||||
impl EmbeddingProvider for FastEmbedProvider {
|
||||
fn embed(&self, text: &str) -> Result<Vec<f32>> {
|
||||
let embeddings = self
|
||||
.model
|
||||
.embed(vec![text], None)
|
||||
.map_err(|e| crate::error::KbError::Embedding(format!("Embedding error: {}", e)))?;
|
||||
|
||||
Ok(embeddings
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or_else(|| crate::error::KbError::Embedding("No embedding returned".to_string()))?)
|
||||
}
|
||||
|
||||
fn dimensions(&self) -> usize {
|
||||
self.dimensions
|
||||
}
|
||||
}
|
||||
|
||||
/// Fallback for when feature is not enabled
|
||||
#[cfg(not(feature = "fastembed"))]
|
||||
pub struct FastEmbedProvider {
|
||||
dimensions: usize,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "fastembed"))]
|
||||
impl FastEmbedProvider {
|
||||
/// Create a new `FastEmbed` provider (stub when feature not enabled)
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Always returns error since fastembed feature is not enabled
|
||||
pub fn new() -> Result<Self> {
|
||||
Err(crate::error::KbError::Embedding(
|
||||
"fastembed feature not enabled. Enable with: cargo build --features fastembed"
|
||||
.to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Create with custom dimensions (stub when feature not enabled)
|
||||
#[must_use]
|
||||
pub fn with_dimensions(dimensions: usize) -> Self {
|
||||
Self { dimensions }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "fastembed"))]
|
||||
impl EmbeddingProvider for FastEmbedProvider {
|
||||
fn embed(&self, _text: &str) -> Result<Vec<f32>> {
|
||||
Err(crate::error::KbError::Embedding(
|
||||
"fastembed feature not enabled".to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
fn dimensions(&self) -> usize {
|
||||
self.dimensions
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,10 @@
|
||||
//! Embedding generation for semantic search
|
||||
//! Embedding generation for semantic search using stratum-embeddings
|
||||
|
||||
use crate::error::Result;
|
||||
pub use stratum_embeddings::{
|
||||
cosine_similarity, euclidean_distance, normalize_embedding, Embedding, EmbeddingError,
|
||||
EmbeddingOptions, EmbeddingProvider, EmbeddingResult, FastEmbedProvider, MemoryCache,
|
||||
ProviderInfo,
|
||||
};
|
||||
|
||||
/// Embedding provider trait
|
||||
pub trait EmbeddingProvider: Send + Sync {
|
||||
/// Generate embeddings for text
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if embedding generation fails
|
||||
fn embed(&self, text: &str) -> Result<Vec<f32>>;
|
||||
|
||||
/// Get embedding dimensions
|
||||
fn dimensions(&self) -> usize;
|
||||
}
|
||||
|
||||
// Module stubs
|
||||
pub mod fastembed;
|
||||
pub mod rig;
|
||||
/// Re-export for backward compatibility
|
||||
pub type Result<T> = std::result::Result<T, EmbeddingError>;
|
||||
|
||||
@ -1,109 +0,0 @@
|
||||
//! rig-core embedding provider integration
|
||||
|
||||
use crate::embeddings::EmbeddingProvider;
|
||||
use crate::error::Result;
|
||||
|
||||
/// Embedding provider using rig-core
|
||||
///
|
||||
/// Integrates with cloud embedding APIs (`OpenAI`, Claude, Ollama, etc.)
|
||||
/// via the rig-core library for production semantic search.
|
||||
///
|
||||
/// Supports multiple embedding services via rig-core abstraction.
|
||||
/// API key should be set in environment variables (e.g., `OPENAI_API_KEY`).
|
||||
pub struct RigEmbeddingProvider {
|
||||
#[allow(dead_code)]
|
||||
model: String,
|
||||
dimensions: usize,
|
||||
}
|
||||
|
||||
impl RigEmbeddingProvider {
|
||||
/// Create a new rig-core embedding provider
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `model` - Model identifier (e.g., "text-embedding-3-small",
|
||||
/// "openai/text-embedding-3-small")
|
||||
/// * `dimensions` - Expected embedding dimensions
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns error if required API keys are not configured.
|
||||
#[must_use]
|
||||
pub fn new(model: String, dimensions: usize) -> Self {
|
||||
Self { model, dimensions }
|
||||
}
|
||||
|
||||
/// Create provider for `OpenAI`'s `text-embedding-3-small`
|
||||
///
|
||||
/// Requires `OPENAI_API_KEY` environment variable.
|
||||
#[must_use]
|
||||
pub fn openai_small() -> Self {
|
||||
Self {
|
||||
model: "text-embedding-3-small".to_string(),
|
||||
dimensions: 1536,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create provider for `OpenAI`'s `text-embedding-3-large`
|
||||
///
|
||||
/// Requires `OPENAI_API_KEY` environment variable.
|
||||
#[must_use]
|
||||
pub fn openai_large() -> Self {
|
||||
Self {
|
||||
model: "text-embedding-3-large".to_string(),
|
||||
dimensions: 3072,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create provider for Ollama embeddings (local inference)
|
||||
///
|
||||
/// Requires Ollama running locally on default port 11434.
|
||||
#[must_use]
|
||||
pub fn ollama(model: String, dimensions: usize) -> Self {
|
||||
Self { model, dimensions }
|
||||
}
|
||||
}
|
||||
|
||||
impl EmbeddingProvider for RigEmbeddingProvider {
|
||||
fn embed(&self, _text: &str) -> Result<Vec<f32>> {
|
||||
// Note: Full rig-core integration requires async context.
|
||||
// For now, return error with helpful message about API keys.
|
||||
// In production, this would use rig-core's embedding client.
|
||||
|
||||
// Check for API key availability
|
||||
let has_openai_key = std::env::var("OPENAI_API_KEY").is_ok();
|
||||
let has_anthropic_key = std::env::var("ANTHROPIC_API_KEY").is_ok();
|
||||
|
||||
if !has_openai_key && !has_anthropic_key {
|
||||
return Err(crate::error::KbError::Embedding(
|
||||
"No embedding service configured. Set OPENAI_API_KEY or ANTHROPIC_API_KEY"
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
// Return placeholder embeddings with correct dimensions
|
||||
// In actual implementation, this would call rig-core's embedding service
|
||||
Ok(vec![0.0; self.dimensions])
|
||||
}
|
||||
|
||||
fn dimensions(&self) -> usize {
|
||||
self.dimensions
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_openai_small_dimensions() {
|
||||
let provider = RigEmbeddingProvider::openai_small();
|
||||
assert_eq!(provider.dimensions(), 1536);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_openai_large_dimensions() {
|
||||
let provider = RigEmbeddingProvider::openai_large();
|
||||
assert_eq!(provider.dimensions(), 3072);
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,7 @@ use serde_yaml;
|
||||
|
||||
use crate::error::{KbError, Result};
|
||||
use crate::models::{Node, NodeStatus, NodeType};
|
||||
use crate::regex_patterns::{WIKILINK_PATTERN, CODE_REF_PATTERN};
|
||||
use crate::regex_patterns::{CODE_REF_PATTERN, WIKILINK_PATTERN};
|
||||
|
||||
/// Extract frontmatter as a map of key-value strings
|
||||
///
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
//! Lazy-compiled regex patterns for the KOGRAL knowledge base engine
|
||||
//!
|
||||
//! All regex patterns are compiled once at startup using `once_cell::sync::Lazy`
|
||||
//! to avoid recompilation overhead during normal operation.
|
||||
//! All regex patterns are compiled once at startup using
|
||||
//! `once_cell::sync::Lazy` to avoid recompilation overhead during normal
|
||||
//! operation.
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
@ -11,8 +12,7 @@ pub static WIKILINK_PATTERN: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"\[\[([^\]|]+)(?:\|[^\]]+)?\]\]").unwrap());
|
||||
|
||||
/// Code reference pattern: `@path/to/file.rs:42`
|
||||
pub static CODE_REF_PATTERN: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"@([\w/.-]+:\d+)").unwrap());
|
||||
pub static CODE_REF_PATTERN: Lazy<Regex> = Lazy::new(|| Regex::new(r"@([\w/.-]+:\d+)").unwrap());
|
||||
|
||||
/// Tag pattern: `#tagname`
|
||||
pub static TAG_PATTERN: Lazy<Regex> = Lazy::new(|| Regex::new(r"#(\w+)").unwrap());
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
//! Integration tests for Nickel configuration loading
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use kogral_core::config::nickel;
|
||||
use kogral_core::config::schema::{EmbeddingProvider, KbConfig, StorageType};
|
||||
|
||||
@ -29,7 +29,8 @@ impl AuthConfig {
|
||||
/// Verify a request token against the configured token
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `request_token` - Token provided in the request (can be from params or header)
|
||||
/// * `request_token` - Token provided in the request (can be from params or
|
||||
/// header)
|
||||
///
|
||||
/// # Returns
|
||||
/// * Ok(()) if authentication succeeds
|
||||
|
||||
@ -7,7 +7,7 @@ use serde_json::{json, Value};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
use crate::{
|
||||
auth::{AuthConfig, extract_token_from_params},
|
||||
auth::{extract_token_from_params, AuthConfig},
|
||||
prompts, resources, tools,
|
||||
types::{
|
||||
JsonRpcRequest, JsonRpcResponse, PromptsCapability, ResourcesCapability,
|
||||
@ -31,7 +31,11 @@ impl McpServer {
|
||||
} else {
|
||||
info!("MCP server running without authentication");
|
||||
}
|
||||
Self { name, version, auth }
|
||||
Self {
|
||||
name,
|
||||
version,
|
||||
auth,
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the MCP server with stdio transport
|
||||
@ -96,7 +100,8 @@ impl McpServer {
|
||||
debug!("Handling method: {}", request.method);
|
||||
|
||||
// Verify authentication for protected methods
|
||||
// Initialize is allowed without auth for initial setup, ping can be used for health checks
|
||||
// Initialize is allowed without auth for initial setup, ping can be used for
|
||||
// health checks
|
||||
if !matches!(request.method.as_str(), "initialize" | "ping") {
|
||||
if let Err(e) = self.authenticate(&request.params) {
|
||||
debug!("Authentication failed: {}", e);
|
||||
|
||||
@ -358,7 +358,12 @@ async fn tool_add_note(args: Value) -> Result<ToolResult> {
|
||||
let mut node = Node::new(NodeType::Note, title);
|
||||
node.content = content;
|
||||
|
||||
let tags = validate_string_array(args["tags"].as_array(), "tags", MAX_ARRAY_ITEMS, MAX_SHORT_LENGTH)?;
|
||||
let tags = validate_string_array(
|
||||
args["tags"].as_array(),
|
||||
"tags",
|
||||
MAX_ARRAY_ITEMS,
|
||||
MAX_SHORT_LENGTH,
|
||||
)?;
|
||||
node.tags = tags;
|
||||
|
||||
let relates_to = validate_string_array(
|
||||
@ -369,7 +374,9 @@ async fn tool_add_note(args: Value) -> Result<ToolResult> {
|
||||
)?;
|
||||
node.relates_to = relates_to;
|
||||
|
||||
if let Some(project) = validate_optional_string(args["project"].as_str(), "project", MAX_SHORT_LENGTH)? {
|
||||
if let Some(project) =
|
||||
validate_optional_string(args["project"].as_str(), "project", MAX_SHORT_LENGTH)?
|
||||
{
|
||||
node.project = Some(project);
|
||||
}
|
||||
|
||||
@ -393,14 +400,17 @@ async fn tool_add_note(args: Value) -> Result<ToolResult> {
|
||||
/// Add an ADR
|
||||
async fn tool_add_decision(args: Value) -> Result<ToolResult> {
|
||||
let title = validate_required_string(args["title"].as_str(), "title", MAX_STRING_LENGTH)?;
|
||||
let decision = validate_required_string(args["decision"].as_str(), "decision", MAX_STRING_LENGTH)?;
|
||||
let decision =
|
||||
validate_required_string(args["decision"].as_str(), "decision", MAX_STRING_LENGTH)?;
|
||||
|
||||
let mut node = Node::new(NodeType::Decision, title);
|
||||
node.content = decision.clone();
|
||||
|
||||
// Store decision-specific data in metadata
|
||||
let mut metadata = serde_json::Map::new();
|
||||
if let Some(context) = validate_optional_string(args["context"].as_str(), "context", MAX_STRING_LENGTH)? {
|
||||
if let Some(context) =
|
||||
validate_optional_string(args["context"].as_str(), "context", MAX_STRING_LENGTH)?
|
||||
{
|
||||
metadata.insert("context".to_string(), json!(context));
|
||||
}
|
||||
metadata.insert("decision".to_string(), json!(decision));
|
||||
@ -417,10 +427,17 @@ async fn tool_add_decision(args: Value) -> Result<ToolResult> {
|
||||
|
||||
node.metadata = metadata.into_iter().collect();
|
||||
|
||||
let tags = validate_string_array(args["tags"].as_array(), "tags", MAX_ARRAY_ITEMS, MAX_SHORT_LENGTH)?;
|
||||
let tags = validate_string_array(
|
||||
args["tags"].as_array(),
|
||||
"tags",
|
||||
MAX_ARRAY_ITEMS,
|
||||
MAX_SHORT_LENGTH,
|
||||
)?;
|
||||
node.tags = tags;
|
||||
|
||||
if let Some(project) = validate_optional_string(args["project"].as_str(), "project", MAX_SHORT_LENGTH)? {
|
||||
if let Some(project) =
|
||||
validate_optional_string(args["project"].as_str(), "project", MAX_SHORT_LENGTH)?
|
||||
{
|
||||
node.project = Some(project);
|
||||
}
|
||||
|
||||
@ -448,7 +465,14 @@ async fn tool_link(args: Value) -> Result<ToolResult> {
|
||||
let relation_str = validate_enum(
|
||||
args["relation"].as_str(),
|
||||
"relation",
|
||||
&["relates_to", "depends_on", "implements", "extends", "supersedes", "explains"],
|
||||
&[
|
||||
"relates_to",
|
||||
"depends_on",
|
||||
"implements",
|
||||
"extends",
|
||||
"supersedes",
|
||||
"explains",
|
||||
],
|
||||
)?;
|
||||
let strength = validate_strength(args["strength"].as_f64())?;
|
||||
|
||||
@ -479,8 +503,10 @@ async fn tool_link(args: Value) -> Result<ToolResult> {
|
||||
|
||||
/// Get guidelines
|
||||
async fn tool_get_guidelines(args: Value) -> Result<ToolResult> {
|
||||
let language = validate_optional_string(args["language"].as_str(), "language", MAX_SHORT_LENGTH)?;
|
||||
let category = validate_optional_string(args["category"].as_str(), "category", MAX_SHORT_LENGTH)?;
|
||||
let language =
|
||||
validate_optional_string(args["language"].as_str(), "language", MAX_SHORT_LENGTH)?;
|
||||
let category =
|
||||
validate_optional_string(args["category"].as_str(), "category", MAX_SHORT_LENGTH)?;
|
||||
|
||||
let storage = FilesystemStorage::new(std::path::PathBuf::from(".kogral"));
|
||||
let graph = storage.load_graph("default").await?;
|
||||
@ -584,8 +610,16 @@ async fn tool_export(args: Value) -> Result<ToolResult> {
|
||||
async fn tool_find_blocks(args: Value) -> Result<ToolResult> {
|
||||
let tag = validate_optional_string(args["tag"].as_str(), "tag", MAX_SHORT_LENGTH)?;
|
||||
let status = validate_optional_string(args["status"].as_str(), "status", MAX_SHORT_LENGTH)?;
|
||||
let property_key = validate_optional_string(args["property_key"].as_str(), "property_key", MAX_SHORT_LENGTH)?;
|
||||
let property_value = validate_optional_string(args["property_value"].as_str(), "property_value", MAX_STRING_LENGTH)?;
|
||||
let property_key = validate_optional_string(
|
||||
args["property_key"].as_str(),
|
||||
"property_key",
|
||||
MAX_SHORT_LENGTH,
|
||||
)?;
|
||||
let property_value = validate_optional_string(
|
||||
args["property_value"].as_str(),
|
||||
"property_value",
|
||||
MAX_STRING_LENGTH,
|
||||
)?;
|
||||
let limit = validate_limit(args["limit"].as_u64(), 20)?;
|
||||
|
||||
let storage = FilesystemStorage::new(std::path::PathBuf::from(".kogral"));
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
//! Input validation for MCP tools
|
||||
//!
|
||||
//! Enforces safe limits on user inputs to prevent abuse and resource exhaustion.
|
||||
//! Enforces safe limits on user inputs to prevent abuse and resource
|
||||
//! exhaustion.
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use serde_json::Value;
|
||||
@ -41,7 +42,11 @@ pub fn validate_required_string(
|
||||
}
|
||||
|
||||
/// Validates an optional string field
|
||||
pub fn validate_optional_string(value: Option<&str>, field_name: &str, max_length: usize) -> Result<Option<String>> {
|
||||
pub fn validate_optional_string(
|
||||
value: Option<&str>,
|
||||
field_name: &str,
|
||||
max_length: usize,
|
||||
) -> Result<Option<String>> {
|
||||
match value {
|
||||
Some(s) => {
|
||||
if s.is_empty() {
|
||||
@ -82,7 +87,10 @@ pub fn validate_limit(value: Option<u64>, default: usize) -> Result<usize> {
|
||||
pub fn validate_strength(value: Option<f64>) -> Result<f32> {
|
||||
let strength = value.unwrap_or(1.0);
|
||||
if !(0.0..=1.0).contains(&strength) {
|
||||
return Err(anyhow!("Strength must be between 0 and 1, got {}", strength));
|
||||
return Err(anyhow!(
|
||||
"Strength must be between 0 and 1, got {}",
|
||||
strength
|
||||
));
|
||||
}
|
||||
Ok(strength as f32)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user