mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
feat(acp): Honor MCP servers from clients like Zed (stdio + http) (#6230)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Generated
+148
-179
@@ -2,15 +2,6 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
@@ -28,35 +19,17 @@ dependencies = [
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "agent-client-protocol"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3e527d7dfe0f334313d42d1d9318f0a79665f6f21c440d0798f230a77a7ed6c"
|
||||
dependencies = [
|
||||
"agent-client-protocol-schema",
|
||||
"anyhow",
|
||||
"async-broadcast",
|
||||
"async-trait",
|
||||
"derive_more",
|
||||
"futures",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "agent-client-protocol-schema"
|
||||
version = "0.10.5"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6903a00e8ac822f9bacac59a1932754d7387c72ebb7c9c7439ad021505591da4"
|
||||
checksum = "16d08d095e8069115774caa50392e9c818e3fb1c482ef4f3153d26b4595482f2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"derive_more",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -252,18 +225,6 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-broadcast"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.20"
|
||||
@@ -914,21 +875,6 @@ dependencies = [
|
||||
"syn 2.0.111",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
@@ -1274,6 +1220,12 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3eeab4423108c5d7c744f4d234de88d18d636100093ae04caf4825134b9c3a32"
|
||||
|
||||
[[package]]
|
||||
name = "boxfnonce"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "7.0.0"
|
||||
@@ -2573,16 +2525,6 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener-strategy"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exr"
|
||||
version = "1.73.0"
|
||||
@@ -2954,6 +2896,15 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generator"
|
||||
version = "0.8.7"
|
||||
@@ -2965,7 +2916,7 @@ dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows 0.59.0",
|
||||
"windows 0.61.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3013,12 +2964,6 @@ dependencies = [
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "git-version"
|
||||
version = "0.3.9"
|
||||
@@ -3075,7 +3020,6 @@ dependencies = [
|
||||
name = "goose"
|
||||
version = "1.17.0"
|
||||
dependencies = [
|
||||
"agent-client-protocol",
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@@ -3124,7 +3068,8 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
"reqwest 0.12.12",
|
||||
"rmcp 0.9.1",
|
||||
"rmcp",
|
||||
"sacp",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3175,7 +3120,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"paste",
|
||||
"regex",
|
||||
"rmcp 0.9.1",
|
||||
"rmcp",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
@@ -3188,7 +3133,6 @@ dependencies = [
|
||||
name = "goose-cli"
|
||||
version = "1.17.0"
|
||||
dependencies = [
|
||||
"agent-client-protocol",
|
||||
"anstream",
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -3214,8 +3158,9 @@ dependencies = [
|
||||
"open",
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
"rmcp 0.9.1",
|
||||
"rmcp",
|
||||
"rustyline",
|
||||
"sacp",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
@@ -3269,7 +3214,7 @@ dependencies = [
|
||||
"rayon",
|
||||
"regex",
|
||||
"reqwest 0.11.27",
|
||||
"rmcp 0.8.5",
|
||||
"rmcp",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3324,7 +3269,7 @@ dependencies = [
|
||||
"http 1.2.0",
|
||||
"rand 0.9.2",
|
||||
"reqwest 0.12.12",
|
||||
"rmcp 0.9.1",
|
||||
"rmcp",
|
||||
"rustls 0.23.31",
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -4362,6 +4307,16 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpcmsg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d833a15225c779251e13929203518c2ff26e2fe0f322d584b213f4f4dad37bd"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonschema"
|
||||
version = "0.30.0"
|
||||
@@ -5119,15 +5074,6 @@ dependencies = [
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
@@ -5774,16 +5720,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "process-wrap"
|
||||
version = "8.2.0"
|
||||
version = "8.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d35f4dc9988d1326b065b4def5e950c3ed727aa03e3151b86cc9e2aec6b03f54"
|
||||
checksum = "a3ef4f2f0422f23a82ec9f628ea2acd12871c81a9362b02c43c1aa86acfc3ba1"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"indexmap 2.12.0",
|
||||
"nix 0.29.0",
|
||||
"nix 0.30.1",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"windows 0.59.0",
|
||||
"windows 0.61.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6321,28 +6267,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmcp"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5947688160b56fb6c827e3c20a72c90392a1d7e9dec74749197aa1780ac42ca"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"futures",
|
||||
"paste",
|
||||
"pin-project-lite",
|
||||
"rmcp-macros 0.8.5",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.17",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmcp"
|
||||
version = "0.9.1"
|
||||
@@ -6351,15 +6275,19 @@ checksum = "eaa07b85b779d1e1df52dd79f6c6bffbe005b191f07290136cc42a142da3409a"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"futures",
|
||||
"http 1.2.0",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"oauth2",
|
||||
"paste",
|
||||
"pin-project-lite",
|
||||
"process-wrap",
|
||||
"rand 0.9.2",
|
||||
"reqwest 0.12.12",
|
||||
"rmcp-macros 0.9.1",
|
||||
"rmcp-macros",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -6368,21 +6296,10 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmcp-macros"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01263441d3f8635c628e33856c468b96ebbce1af2d3699ea712ca71432d4ee7a"
|
||||
dependencies = [
|
||||
"darling 0.21.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_json",
|
||||
"syn 2.0.111",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6442,12 +6359,6 @@ dependencies = [
|
||||
"ordered-multimap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
@@ -6646,6 +6557,42 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd29631678d6fb0903b69223673e122c32e9ae559d0960a38d574695ebc0ea15"
|
||||
|
||||
[[package]]
|
||||
name = "sacp"
|
||||
version = "9.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7679525f5c2f4e1cb4b07e3684c4b050b34bafa0f908852879b7411522ff6626"
|
||||
dependencies = [
|
||||
"agent-client-protocol-schema",
|
||||
"anyhow",
|
||||
"boxfnonce",
|
||||
"futures",
|
||||
"futures-concurrency",
|
||||
"fxhash",
|
||||
"jsonrpcmsg",
|
||||
"rmcp",
|
||||
"sacp-derive",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.17",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sacp-derive"
|
||||
version = "9.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70a36c27381224c2fc970935c887b26f48ff78105003d9abfa04c2e808569d3b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
@@ -7425,27 +7372,6 @@ version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.111",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
@@ -7921,20 +7847,19 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.43.1"
|
||||
version = "1.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "492a604e2fd7f814268a378409e6c92b5525d747d10db9a229723f55a417958c"
|
||||
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2 0.5.8",
|
||||
"socket2 0.6.1",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7954,9 +7879,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -8662,12 +8587,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.15.1"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
|
||||
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
|
||||
dependencies = [
|
||||
"getrandom 0.3.1",
|
||||
"serde",
|
||||
"js-sys",
|
||||
"serde_core",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9009,12 +8936,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.59.0"
|
||||
version = "0.61.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1"
|
||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||
dependencies = [
|
||||
"windows-core 0.59.0",
|
||||
"windows-targets 0.53.3",
|
||||
"windows-collections",
|
||||
"windows-core 0.61.2",
|
||||
"windows-future",
|
||||
"windows-link 0.1.3",
|
||||
"windows-numerics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9065,15 +9004,26 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.59.0"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce"
|
||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||
dependencies = [
|
||||
"windows-implement 0.59.0",
|
||||
"windows-implement 0.60.2",
|
||||
"windows-interface 0.59.1",
|
||||
"windows-link 0.1.3",
|
||||
"windows-result 0.3.4",
|
||||
"windows-strings 0.3.1",
|
||||
"windows-targets 0.53.3",
|
||||
"windows-strings 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-link 0.1.3",
|
||||
"windows-threading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9111,9 +9061,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.59.0"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
|
||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -9176,6 +9126,16 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.2.0"
|
||||
@@ -9226,9 +9186,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.3.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
|
||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
@@ -9350,6 +9310,15 @@ dependencies = [
|
||||
"windows_x86_64_msvc 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
||||
@@ -19,7 +19,7 @@ goose = { path = "../goose" }
|
||||
goose-bench = { path = "../goose-bench" }
|
||||
goose-mcp = { path = "../goose-mcp" }
|
||||
rmcp = { workspace = true }
|
||||
agent-client-protocol = "0.9.0"
|
||||
sacp = "9.0.0"
|
||||
clap = { version = "4.4", features = ["derive"] }
|
||||
cliclack = "0.3.5"
|
||||
console = "0.16.1"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@ description.workspace = true
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
rmcp = { version = "0.8.1", features = ["server", "client", "transport-io", "macros"] }
|
||||
rmcp = { workspace = true, features = ["server", "client", "transport-io", "macros"] }
|
||||
anyhow = "1.0.94"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-stream = { version = "0.1", features = ["io-util"] }
|
||||
|
||||
@@ -121,7 +121,7 @@ unbinder = "0.1.7"
|
||||
winapi = { version = "0.3", features = ["wincred"] }
|
||||
|
||||
[dev-dependencies]
|
||||
agent-client-protocol = "0.9.2"
|
||||
sacp = "9.0.0"
|
||||
criterion = "0.5"
|
||||
serial_test = "3.2.0"
|
||||
mockall = "0.13.1"
|
||||
@@ -133,6 +133,7 @@ dotenvy = "0.15.7"
|
||||
ctor = "0.2.9"
|
||||
test-case = "3.3"
|
||||
env-lock = "1.0.1"
|
||||
rmcp = { workspace = true, features = ["transport-streamable-http-server"] }
|
||||
|
||||
[[example]]
|
||||
name = "agent"
|
||||
|
||||
@@ -140,7 +140,7 @@ pub enum ExtensionError {
|
||||
|
||||
pub type ExtensionResult<T> = Result<T, ExtensionError>;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, ToSchema)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, ToSchema, PartialEq)]
|
||||
pub struct Envs {
|
||||
/// A map of environment variables to set, e.g. API_KEY -> some_secret, HOST -> host
|
||||
#[serde(default)]
|
||||
@@ -230,7 +230,7 @@ impl Envs {
|
||||
}
|
||||
|
||||
/// Represents the different types of MCP extensions that can be added to the manager
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema, PartialEq)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum ExtensionConfig {
|
||||
/// Server-sent events client with a URI endpoint
|
||||
|
||||
@@ -15,7 +15,7 @@ pub enum PrincipalType {
|
||||
Tool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||
pub struct PermissionConfirmation {
|
||||
pub principal_type: PrincipalType,
|
||||
pub permission: Permission,
|
||||
|
||||
@@ -1,44 +1,102 @@
|
||||
use agent_client_protocol::{
|
||||
self as acp, Agent, Client, ClientSideConnection, ContentBlock, InitializeRequest,
|
||||
NewSessionRequest, PromptRequest, ProtocolVersion, SessionNotification, SessionUpdate,
|
||||
TextContent,
|
||||
mod common;
|
||||
|
||||
use rmcp::transport::streamable_http_server::{
|
||||
session::local::LocalSessionManager, StreamableHttpServerConfig, StreamableHttpService,
|
||||
};
|
||||
use std::path::Path;
|
||||
use rmcp::{
|
||||
handler::server::router::tool::ToolRouter, model::*, tool, tool_handler, tool_router,
|
||||
ErrorData as McpError, ServerHandler,
|
||||
};
|
||||
use sacp::schema::{
|
||||
ContentBlock, ContentChunk, InitializeRequest, McpServer, NewSessionRequest, PromptRequest,
|
||||
RequestPermissionOutcome, RequestPermissionRequest, RequestPermissionResponse,
|
||||
SessionNotification, SessionUpdate, StopReason, TextContent, VERSION as PROTOCOL_VERSION,
|
||||
};
|
||||
use sacp::{ClientToAgent, JrConnectionCx};
|
||||
use std::collections::VecDeque;
|
||||
use std::process::Stdio;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use tokio::process::{Child, Command};
|
||||
use tokio::task::JoinHandle;
|
||||
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
|
||||
use wiremock::matchers::{method, path};
|
||||
use wiremock::{Mock, MockServer, ResponseTemplate};
|
||||
|
||||
const BASIC_RESPONSE: &str = include_str!("./test_data/openai_chat_completion_streaming.txt");
|
||||
const BASIC_TEXT: &str = "Hello! How can I assist you today? 🌍";
|
||||
/// Fake code returned by the MCP server - an LLM couldn't know this from memory
|
||||
const FAKE_CODE: &str = "test-uuid-12345-67890";
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_acp_basic_completion() {
|
||||
let mock_server = setup_mock_openai(BASIC_RESPONSE).await;
|
||||
let work_dir = tempfile::tempdir().unwrap();
|
||||
let prompt = "what is 1+1";
|
||||
let mock_server = setup_mock_openai(vec![(
|
||||
format!(r#"</info-msg>\n{prompt}","role":"user""#),
|
||||
include_str!("./test_data/openai_basic_response.txt"),
|
||||
)])
|
||||
.await;
|
||||
|
||||
let (client, updates) = TestClient::new();
|
||||
let child = spawn_goose_acp(&mock_server).await;
|
||||
run_acp_session(&mock_server, vec![], |cx, session_id, updates| async move {
|
||||
let response = cx
|
||||
.send_request(PromptRequest {
|
||||
session_id,
|
||||
prompt: vec![ContentBlock::Text(TextContent {
|
||||
text: prompt.to_string(),
|
||||
annotations: None,
|
||||
meta: None,
|
||||
})],
|
||||
meta: None,
|
||||
})
|
||||
.block_task()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(response.stop_reason, StopReason::EndTurn);
|
||||
wait_for_text(&updates, "2", Duration::from_secs(5)).await;
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_acp_with_mcp_http_server() {
|
||||
let prompt = "Use the get_code tool and output only its result.";
|
||||
let (mcp_url, _handle) = spawn_mcp_http_server().await;
|
||||
|
||||
let mock_server = setup_mock_openai(vec![
|
||||
(
|
||||
format!(r#"</info-msg>\n{prompt}","role":"user""#),
|
||||
include_str!("./test_data/openai_tool_call_response.txt"),
|
||||
),
|
||||
(
|
||||
format!(r#""content":"{FAKE_CODE}","role":"tool""#),
|
||||
include_str!("./test_data/openai_tool_result_response.txt"),
|
||||
),
|
||||
])
|
||||
.await;
|
||||
|
||||
run_acp_session(
|
||||
client,
|
||||
child,
|
||||
work_dir.path(),
|
||||
|conn, session_id| async move {
|
||||
let response = conn
|
||||
.prompt(PromptRequest::new(
|
||||
&mock_server,
|
||||
vec![McpServer::Http {
|
||||
name: "lookup".into(),
|
||||
url: mcp_url,
|
||||
headers: vec![],
|
||||
}],
|
||||
|cx, session_id, updates| async move {
|
||||
let response = cx
|
||||
.send_request(PromptRequest {
|
||||
session_id,
|
||||
vec![ContentBlock::Text(TextContent::new("test message"))],
|
||||
))
|
||||
prompt: vec![ContentBlock::Text(TextContent {
|
||||
text: prompt.to_string(),
|
||||
annotations: None,
|
||||
meta: None,
|
||||
})],
|
||||
meta: None,
|
||||
})
|
||||
.block_task()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(response.stop_reason, acp::StopReason::EndTurn);
|
||||
|
||||
wait_for_text(&updates, BASIC_TEXT, Duration::from_secs(5)).await;
|
||||
assert_eq!(response.stop_reason, StopReason::EndTurn);
|
||||
wait_for_text(&updates, FAKE_CODE, Duration::from_secs(5)).await;
|
||||
},
|
||||
)
|
||||
.await;
|
||||
@@ -63,16 +121,50 @@ async fn wait_for_text(
|
||||
}
|
||||
}
|
||||
|
||||
async fn setup_mock_openai(streaming_response: &str) -> MockServer {
|
||||
/// Each entry is (expected_body_substring, response_body).
|
||||
/// Session description requests are handled automatically.
|
||||
async fn setup_mock_openai(exchanges: Vec<(String, &'static str)>) -> MockServer {
|
||||
let mock_server = MockServer::start().await;
|
||||
let queue: VecDeque<(String, &'static str)> = exchanges.into_iter().collect();
|
||||
let queue = Arc::new(Mutex::new(queue));
|
||||
|
||||
Mock::given(method("POST"))
|
||||
.and(path("/v1/chat/completions"))
|
||||
.respond_with(
|
||||
ResponseTemplate::new(200)
|
||||
.insert_header("content-type", "text/event-stream")
|
||||
.set_body_string(streaming_response),
|
||||
)
|
||||
.respond_with({
|
||||
let queue = queue.clone();
|
||||
move |req: &wiremock::Request| {
|
||||
let body = String::from_utf8_lossy(&req.body);
|
||||
|
||||
if body.contains("Reply with only a description in four words or less") {
|
||||
return ResponseTemplate::new(200)
|
||||
.insert_header("content-type", "application/json")
|
||||
.set_body_string(include_str!(
|
||||
"./test_data/openai_session_description.json"
|
||||
));
|
||||
}
|
||||
|
||||
let (expected, response) = {
|
||||
let mut q = queue.lock().unwrap();
|
||||
match q.pop_front() {
|
||||
Some(item) => item,
|
||||
None => {
|
||||
return ResponseTemplate::new(500)
|
||||
.set_body_string(format!("unexpected request: {body}"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if !body.contains(&expected) {
|
||||
return ResponseTemplate::new(500).set_body_string(format!(
|
||||
"expected body to contain: {expected}\nactual: {body}"
|
||||
));
|
||||
}
|
||||
|
||||
ResponseTemplate::new(200)
|
||||
.insert_header("content-type", "text/event-stream")
|
||||
.set_body_string(response)
|
||||
}
|
||||
})
|
||||
.mount(&mock_server)
|
||||
.await;
|
||||
|
||||
@@ -83,88 +175,156 @@ fn extract_text(updates: &[SessionNotification]) -> String {
|
||||
updates
|
||||
.iter()
|
||||
.filter_map(|n| match &n.update {
|
||||
SessionUpdate::AgentMessageChunk(chunk) => match &chunk.content {
|
||||
ContentBlock::Text(t) => Some(t.text.clone()),
|
||||
_ => None,
|
||||
},
|
||||
SessionUpdate::AgentMessageChunk(ContentChunk {
|
||||
content: ContentBlock::Text(t),
|
||||
..
|
||||
}) => Some(t.text.clone()),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
struct TestClient {
|
||||
updates: Arc<Mutex<Vec<SessionNotification>>>,
|
||||
}
|
||||
|
||||
impl TestClient {
|
||||
fn new() -> (Self, Arc<Mutex<Vec<SessionNotification>>>) {
|
||||
let updates = Arc::new(Mutex::new(Vec::new()));
|
||||
(
|
||||
Self {
|
||||
updates: updates.clone(),
|
||||
},
|
||||
updates,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl Client for TestClient {
|
||||
async fn request_permission(
|
||||
&self,
|
||||
_args: acp::RequestPermissionRequest,
|
||||
) -> acp::Result<acp::RequestPermissionResponse> {
|
||||
Err(acp::Error::method_not_found())
|
||||
}
|
||||
|
||||
async fn session_notification(&self, args: SessionNotification) -> acp::Result<()> {
|
||||
self.updates.lock().unwrap().push(args);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn spawn_goose_acp(mock_server: &MockServer) -> Child {
|
||||
Command::new("cargo")
|
||||
.args(["run", "-p", "goose-cli", "--", "acp"])
|
||||
Command::new(&*common::GOOSE_BINARY)
|
||||
.args(["acp"])
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.env("GOOSE_PROVIDER", "openai")
|
||||
.env("GOOSE_MODEL", "gpt-5-nano")
|
||||
.env("GOOSE_MODE", "approve")
|
||||
.env("OPENAI_HOST", mock_server.uri())
|
||||
.env("OPENAI_API_KEY", "test-key")
|
||||
.env(
|
||||
"RUST_LOG",
|
||||
std::env::var("RUST_LOG").unwrap_or_else(|_| "info".into()),
|
||||
)
|
||||
.kill_on_drop(true)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn run_acp_session<F, Fut>(client: TestClient, mut child: Child, work_dir: &Path, test_fn: F)
|
||||
async fn run_acp_session<F, Fut>(mock_server: &MockServer, mcp_servers: Vec<McpServer>, test_fn: F)
|
||||
where
|
||||
F: FnOnce(ClientSideConnection, acp::SessionId) -> Fut,
|
||||
F: FnOnce(
|
||||
JrConnectionCx<ClientToAgent>,
|
||||
sacp::schema::SessionId,
|
||||
Arc<Mutex<Vec<SessionNotification>>>,
|
||||
) -> Fut,
|
||||
Fut: std::future::Future<Output = ()>,
|
||||
{
|
||||
let mut child = spawn_goose_acp(mock_server).await;
|
||||
let work_dir = tempfile::tempdir().unwrap();
|
||||
let updates = Arc::new(Mutex::new(Vec::new()));
|
||||
let outgoing = child.stdin.take().unwrap().compat_write();
|
||||
let incoming = child.stdout.take().unwrap().compat();
|
||||
|
||||
let work_dir = work_dir.to_path_buf();
|
||||
let local_set = tokio::task::LocalSet::new();
|
||||
local_set
|
||||
.run_until(async move {
|
||||
let (conn, handle_io) = ClientSideConnection::new(client, outgoing, incoming, |fut| {
|
||||
tokio::task::spawn_local(fut);
|
||||
});
|
||||
tokio::task::spawn_local(handle_io);
|
||||
let transport = sacp::ByteStreams::new(outgoing, incoming);
|
||||
|
||||
conn.initialize(InitializeRequest::new(ProtocolVersion::V1))
|
||||
ClientToAgent::builder()
|
||||
.on_receive_notification(
|
||||
{
|
||||
let updates = updates.clone();
|
||||
async move |notification: SessionNotification, _cx| {
|
||||
updates.lock().unwrap().push(notification);
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
sacp::on_receive_notification!(),
|
||||
)
|
||||
.on_receive_request(
|
||||
async move |request: RequestPermissionRequest, request_cx, _connection_cx| {
|
||||
let option_id = request.options.first().map(|opt| opt.id.clone());
|
||||
match option_id {
|
||||
Some(id) => request_cx.respond(RequestPermissionResponse {
|
||||
outcome: RequestPermissionOutcome::Selected { option_id: id },
|
||||
meta: None,
|
||||
}),
|
||||
None => request_cx.respond(RequestPermissionResponse {
|
||||
outcome: RequestPermissionOutcome::Cancelled,
|
||||
meta: None,
|
||||
}),
|
||||
}
|
||||
},
|
||||
sacp::on_receive_request!(),
|
||||
)
|
||||
.with_client(
|
||||
transport,
|
||||
move |cx: JrConnectionCx<ClientToAgent>| async move {
|
||||
cx.send_request(InitializeRequest {
|
||||
protocol_version: PROTOCOL_VERSION,
|
||||
client_capabilities: Default::default(),
|
||||
client_info: Default::default(),
|
||||
meta: None,
|
||||
})
|
||||
.block_task()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let session = conn
|
||||
.new_session(NewSessionRequest::new(&work_dir))
|
||||
.await
|
||||
.unwrap();
|
||||
let session = cx
|
||||
.send_request(NewSessionRequest {
|
||||
mcp_servers,
|
||||
cwd: work_dir.path().to_path_buf(),
|
||||
meta: None,
|
||||
})
|
||||
.block_task()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
test_fn(conn, session.session_id).await;
|
||||
})
|
||||
.await;
|
||||
test_fn(cx.clone(), session.session_id, updates).await;
|
||||
Ok(())
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Lookup {
|
||||
tool_router: ToolRouter<Lookup>,
|
||||
}
|
||||
|
||||
#[tool_router]
|
||||
impl Lookup {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
tool_router: Self::tool_router(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a fake code that an LLM couldn't know from memory
|
||||
#[tool(description = "Get the code")]
|
||||
fn get_code(&self) -> Result<CallToolResult, McpError> {
|
||||
Ok(CallToolResult::success(vec![Content::text(FAKE_CODE)]))
|
||||
}
|
||||
}
|
||||
|
||||
#[tool_handler]
|
||||
impl ServerHandler for Lookup {
|
||||
fn get_info(&self) -> ServerInfo {
|
||||
ServerInfo {
|
||||
protocol_version: ProtocolVersion::V_2025_03_26,
|
||||
capabilities: ServerCapabilities::builder().enable_tools().build(),
|
||||
server_info: Implementation::from_build_env(),
|
||||
instructions: Some("Lookup server with get_code tool.".into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn spawn_mcp_http_server() -> (String, JoinHandle<()>) {
|
||||
let service = StreamableHttpService::new(
|
||||
|| Ok(Lookup::new()),
|
||||
LocalSessionManager::default().into(),
|
||||
StreamableHttpServerConfig::default(),
|
||||
);
|
||||
let router = axum::Router::new().nest_service("/mcp", service);
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
let url = format!("http://{addr}/mcp");
|
||||
|
||||
let handle = tokio::spawn(async move {
|
||||
axum::serve(listener, router).await.unwrap();
|
||||
});
|
||||
|
||||
(url, handle)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
/// Build a binary from a package and return its path.
|
||||
pub fn build_binary(package: &str, bin_name: &str) -> PathBuf {
|
||||
let output = Command::new("cargo")
|
||||
.args([
|
||||
"build",
|
||||
"-p",
|
||||
package,
|
||||
"--bin",
|
||||
bin_name,
|
||||
"--message-format=json",
|
||||
])
|
||||
.output()
|
||||
.expect("failed to build binary");
|
||||
|
||||
if !output.status.success() {
|
||||
panic!("build failed: {}", String::from_utf8_lossy(&output.stderr));
|
||||
}
|
||||
|
||||
String::from_utf8_lossy(&output.stdout)
|
||||
.lines()
|
||||
.filter_map(|line| serde_json::from_str::<serde_json::Value>(line).ok())
|
||||
.filter(|msg| msg["reason"] == "compiler-artifact")
|
||||
.filter(|msg| msg["target"]["name"] == bin_name)
|
||||
.filter(|msg| {
|
||||
msg["target"]["kind"]
|
||||
.as_array()
|
||||
.map(|k| k.iter().any(|v| v == "bin"))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.filter_map(|msg| msg["executable"].as_str().map(PathBuf::from))
|
||||
.next()
|
||||
.expect("failed to find binary path in cargo output")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub static GOOSE_BINARY: LazyLock<PathBuf> = LazyLock::new(|| build_binary("goose-cli", "goose"));
|
||||
#[allow(dead_code)]
|
||||
pub static CAPTURE_BINARY: LazyLock<PathBuf> =
|
||||
LazyLock::new(|| build_binary("goose-test", "capture"));
|
||||
@@ -1,4 +1,4 @@
|
||||
use serde::Deserialize;
|
||||
mod common;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
@@ -20,21 +20,6 @@ use async_trait::async_trait;
|
||||
use goose::conversation::message::Message;
|
||||
use goose::providers::base::{Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use goose::providers::errors::ProviderError;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::process::Command;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct CargoBuildMessage {
|
||||
reason: String,
|
||||
target: Target,
|
||||
executable: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Target {
|
||||
name: String,
|
||||
kind: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MockProvider {
|
||||
@@ -75,44 +60,6 @@ impl Provider for MockProvider {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_and_get_binary_path() -> PathBuf {
|
||||
let output = Command::new("cargo")
|
||||
.args([
|
||||
"build",
|
||||
"--frozen",
|
||||
"-p",
|
||||
"goose-test",
|
||||
"--bin",
|
||||
"capture",
|
||||
"--message-format=json",
|
||||
])
|
||||
.output()
|
||||
.expect("failed to build binary");
|
||||
|
||||
if !output.status.success() {
|
||||
panic!("build failed: {}", String::from_utf8_lossy(&output.stderr));
|
||||
}
|
||||
|
||||
String::from_utf8_lossy(&output.stdout)
|
||||
.lines()
|
||||
.map(serde_json::from_str::<CargoBuildMessage>)
|
||||
.filter_map(Result::ok)
|
||||
.filter(|message| message.reason == "compiler-artifact")
|
||||
.filter_map(|message| {
|
||||
if message.target.name == "capture"
|
||||
&& message.target.kind.contains(&String::from("bin"))
|
||||
{
|
||||
Some(PathBuf::from(message.executable))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.next()
|
||||
.expect("failed to parse binary path")
|
||||
}
|
||||
|
||||
static REPLAY_BINARY_PATH: Lazy<PathBuf> = Lazy::new(build_and_get_binary_path);
|
||||
|
||||
enum TestMode {
|
||||
Record,
|
||||
Playback,
|
||||
@@ -214,7 +161,7 @@ async fn test_replayed_session(
|
||||
TestMode::Record => "record",
|
||||
TestMode::Playback => "playback",
|
||||
};
|
||||
let cmd = REPLAY_BINARY_PATH.to_string_lossy().to_string();
|
||||
let cmd = common::CAPTURE_BINARY.to_string_lossy().to_string();
|
||||
let mut args = vec!["stdio", mode_arg]
|
||||
.into_iter()
|
||||
.map(str::to_string)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
data: {"id":"chatcmpl-test","object":"chat.completion.chunk","created":1766229303,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
|
||||
|
||||
data: {"id":"chatcmpl-test","object":"chat.completion.chunk","created":1766229303,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":"2"},"finish_reason":null}]}
|
||||
|
||||
data: {"id":"chatcmpl-test","object":"chat.completion.chunk","created":1766229303,"model":"gpt-5-nano","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
|
||||
|
||||
data: {"id":"chatcmpl-test","object":"chat.completion.chunk","created":1766229303,"model":"gpt-5-nano","choices":[],"usage":{"prompt_tokens":100,"completion_tokens":10,"total_tokens":110}}
|
||||
|
||||
data: [DONE]
|
||||
@@ -1,27 +0,0 @@
|
||||
data: {"choices":[],"created":0,"id":"","prompt_filter_results":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"prompt_index":0}]}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"","role":"assistant"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"Hello"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"!"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" How"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" can"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" I"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" assist"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" you"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" today"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"?"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" 🌍"}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: {"choices":[{"finish_reason":"stop","index":0,"content_filter_offsets":{"check_offset":3458,"start_offset":3458,"end_offset":3494},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":null}}],"created":1747592466,"id":"chatcmpl-BYcvCkaKJjQIM7e2j6vg08RIcY8qp","usage":{"completion_tokens":13,"completion_tokens_details":{"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":1675,"prompt_tokens_details":{"cached_tokens":1536},"total_tokens":1688},"model":"gpt-4o-2024-11-20","system_fingerprint":"fp_ee1d74bde0"}
|
||||
|
||||
data: [DONE]
|
||||
@@ -0,0 +1 @@
|
||||
{"id":"chatcmpl-test","object":"chat.completion","created":1766229622,"model":"gpt-5-nano","choices":[{"index":0,"message":{"role":"assistant","content":"Test session"},"finish_reason":"stop"}],"usage":{"prompt_tokens":79,"completion_tokens":10,"total_tokens":89}}
|
||||
@@ -0,0 +1,9 @@
|
||||
data: {"id":"chatcmpl-test1","object":"chat.completion.chunk","created":1766309803,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_abc123","type":"function","function":{"name":"lookup__get_code","arguments":""}}],"refusal":null},"finish_reason":null}]}
|
||||
|
||||
data: {"id":"chatcmpl-test1","object":"chat.completion.chunk","created":1766309803,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{}"}}]},"finish_reason":null}]}
|
||||
|
||||
data: {"id":"chatcmpl-test1","object":"chat.completion.chunk","created":1766309803,"model":"gpt-5-nano","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}]}
|
||||
|
||||
data: {"id":"chatcmpl-test1","object":"chat.completion.chunk","created":1766309803,"model":"gpt-5-nano","choices":[],"usage":{"prompt_tokens":100,"completion_tokens":50,"total_tokens":150}}
|
||||
|
||||
data: [DONE]
|
||||
@@ -0,0 +1,9 @@
|
||||
data: {"id":"chatcmpl-test2","object":"chat.completion.chunk","created":1766309809,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
|
||||
|
||||
data: {"id":"chatcmpl-test2","object":"chat.completion.chunk","created":1766309809,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":"test-uuid-12345-67890"},"finish_reason":null}]}
|
||||
|
||||
data: {"id":"chatcmpl-test2","object":"chat.completion.chunk","created":1766309809,"model":"gpt-5-nano","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
|
||||
|
||||
data: {"id":"chatcmpl-test2","object":"chat.completion.chunk","created":1766309809,"model":"gpt-5-nano","choices":[],"usage":{"prompt_tokens":200,"completion_tokens":10,"total_tokens":210}}
|
||||
|
||||
data: [DONE]
|
||||
Reference in New Issue
Block a user