diff --git a/Cargo.lock b/Cargo.lock index 6adb81fda2..18c4e2273b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + [[package]] name = "adler2" version = "2.0.1" @@ -27,7 +36,7 @@ checksum = "5a871245e59daecd6abf45f516d35445466294ae987dc685106e1676685bfdce" dependencies = [ "anyhow", "derive_more", - "schemars", + "schemars 1.2.1", "serde", "serde_json", "strum", @@ -56,15 +65,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "aligned-vec" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" -dependencies = [ - "equator", -] - [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -187,6 +187,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "ascii" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" + [[package]] name = "assert-json-diff" version = "2.0.2" @@ -197,6 +203,17 @@ dependencies = [ "serde_json", ] +[[package]] +name = "ast_node" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb025ef00a6da925cf40870b9c8d008526b6004ece399cb0974209720f0b194" +dependencies = [ + "quote", + "swc_macros_common", + "syn 2.0.114", +] + [[package]] name = "async-compression" version = "0.4.37" @@ -209,6 +226,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-once-cell" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a" + [[package]] name = "async-stream" version = "0.3.6" @@ -321,7 +344,7 @@ version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" dependencies = [ - "bindgen", + "bindgen 0.69.5", "cc", "cmake", "dunce", @@ -679,7 +702,7 @@ dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", - "rustc_version 0.4.1", + "rustc_version", "tracing", ] @@ -797,6 +820,33 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "az" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link 0.2.1", +] + +[[package]] +name = "base32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" + [[package]] name = "base64" version = "0.13.1" @@ -860,7 +910,7 @@ dependencies = [ "path_abs", "plist", "regex", - "semver 1.0.27", + "semver", "serde", "serde_derive", "serde_with", @@ -875,6 +925,15 @@ dependencies = [ "wild", ] +[[package]] +name = "better_scoped_tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd228125315b132eed175bf47619ac79b945b26e56b848ba203ae4ea8603609" +dependencies = [ + "scoped-tls", +] + [[package]] name = "bincode" version = "1.3.3" @@ -907,6 +966,300 @@ dependencies = [ "which 4.4.2", ] +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.10.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.1", + "shlex", + "syn 2.0.114", +] + +[[package]] +name = "bindgen_cuda" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be55fb326843bb67cccceeeaf21c961ef303f60018f9a2ab69494dad8eaf9" +dependencies = [ + "glob", + "num_cpus", + "rayon", +] + +[[package]] +name = "biome_console" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bff6dcd31afe7872430d10b3b79d66ba01e090c3a000ba826e91830bca95d0c" +dependencies = [ + "biome_markup", + "biome_text_size", + "schemars 0.8.22", + "serde", + "termcolor", + "unicode-segmentation", + "unicode-width 0.1.14", +] + +[[package]] +name = "biome_deserialize" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9969c2b032155b05dc837c71337149800bdc56b07ecc3cfd7c2d963db07f049" +dependencies = [ + "biome_console", + "biome_diagnostics", + "biome_json_parser", + "biome_json_syntax", + "biome_rowan", + "bitflags 2.10.0", + "indexmap 1.9.3", + "serde", + "serde_json", + "tracing", +] + +[[package]] +name = "biome_diagnostics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92eeba94d7926178e59511b85cdcd0398ba1cc54a9f658ec261184e20028dd0e" +dependencies = [ + "backtrace", + "biome_console", + "biome_diagnostics_categories", + "biome_diagnostics_macros", + "biome_rowan", + "biome_text_edit", + "biome_text_size", + "bitflags 2.10.0", + "bpaf", + "serde", + "termcolor", + "unicode-width 0.1.14", +] + +[[package]] +name = "biome_diagnostics_categories" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e8ef1f8a683438b2c6e68c996d66ceeb4764c3672e1eb20c9e6b404056a3d4" +dependencies = [ + "quote", + "serde", +] + +[[package]] +name = "biome_diagnostics_macros" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9a4eeb40457bd8ed3ea91d2b48ad12e80dc92eb083f909a8b5ad1d1b71d5c4" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "biome_formatter" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd09e51dc9b0b6e52017ef6dacea26c3291181b42a3dbbccc61d47b8f9330d1" +dependencies = [ + "biome_console", + "biome_deserialize", + "biome_diagnostics", + "biome_rowan", + "cfg-if", + "countme", + "drop_bomb", + "indexmap 1.9.3", + "rustc-hash 1.1.0", + "tracing", + "unicode-width 0.1.14", +] + +[[package]] +name = "biome_js_factory" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1ed97002c53c737b765e2dc8f25da2f91ecec03385d2280afa5ab94456972a" +dependencies = [ + "biome_js_syntax", + "biome_rowan", +] + +[[package]] +name = "biome_js_formatter" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e010bc8836e38c7168a9bfbec9391efa3bd6b5e9b321e05d613fc511d1e5db51" +dependencies = [ + "biome_console", + "biome_deserialize", + "biome_diagnostics_categories", + "biome_formatter", + "biome_js_factory", + "biome_js_syntax", + "biome_js_unicode_table", + "biome_json_syntax", + "biome_rowan", + "biome_text_size", + "cfg-if", + "smallvec", + "tracing", + "unicode-width 0.1.14", +] + +[[package]] +name = "biome_js_parser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cef3036cef3632c72c83cc1197c3af868ae440ec2576a494ea812fafe5ee18e" +dependencies = [ + "biome_console", + "biome_diagnostics", + "biome_js_factory", + "biome_js_syntax", + "biome_js_unicode_table", + "biome_parser", + "biome_rowan", + "bitflags 2.10.0", + "cfg-if", + "drop_bomb", + "indexmap 1.9.3", + "rustc-hash 1.1.0", + "serde", + "serde_json", + "smallvec", + "tracing", + "unicode-bom", +] + +[[package]] +name = "biome_js_syntax" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874ff2a6f691d231195a02b85243c5e2ba820973f7ba71e29f320aaabe1a749e" +dependencies = [ + "biome_console", + "biome_diagnostics", + "biome_rowan", +] + +[[package]] +name = "biome_js_unicode_table" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b174dd2a0e5d74e1763045a9eb021bf89c38e3bf48f5852653635688a8675b9" + +[[package]] +name = "biome_json_factory" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ec30f94381f11b6c4f2cb49492cf02b34dec74fd8cf01b7b1b10138d2f6b41e" +dependencies = [ + "biome_json_syntax", + "biome_rowan", +] + +[[package]] +name = "biome_json_parser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baddbd7fee954d8b20b6db922e77c70db8d73fadeb43bae254e7fb2e0364a553" +dependencies = [ + "biome_console", + "biome_diagnostics", + "biome_js_unicode_table", + "biome_json_factory", + "biome_json_syntax", + "biome_parser", + "biome_rowan", + "tracing", + "unicode-bom", +] + +[[package]] +name = "biome_json_syntax" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97bb81952034ac0a4e5100d939c4286862193361a687c21aa0c15da388b29b32" +dependencies = [ + "biome_rowan", +] + +[[package]] +name = "biome_markup" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b75b241c9346a7a55968398e51502333c18e200bec5d72b08d448084045e02" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", +] + +[[package]] +name = "biome_parser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33531b8a29ce80cfd320f3278a167ec41985d9b4701013184d95aef9642bf761" +dependencies = [ + "biome_console", + "biome_diagnostics", + "biome_rowan", + "bitflags 2.10.0", + "drop_bomb", +] + +[[package]] +name = "biome_rowan" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e46e82f8245181cdf45794f3025db1daa4865e8730214345e540eae570957aa" +dependencies = [ + "biome_text_edit", + "biome_text_size", + "countme", + "hashbrown 0.12.3", + "memoffset", + "rustc-hash 1.1.0", + "tracing", +] + +[[package]] +name = "biome_text_edit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81ff84924f11cc4d9a5ee2a3b59630aa9f2c2c359f7623ac541b1ff82390d80b" +dependencies = [ + "biome_text_size", + "serde", + "similar", +] + +[[package]] +name = "biome_text_size" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e945f7da7f14dd66563ca6be0133014e6a1cbe935247f7b5ee8e28b2b8282f6" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -958,6 +1311,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake3" version = "1.5.3" @@ -1004,159 +1369,48 @@ dependencies = [ "objc2", ] -[[package]] -name = "boa_ast" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc119a5ad34c3f459062a96907f53358989b173d104258891bb74f95d93747e8" -dependencies = [ - "bitflags 2.10.0", - "boa_interner", - "boa_macros", - "boa_string", - "indexmap 2.13.0", - "num-bigint", - "rustc-hash 2.1.1", -] - -[[package]] -name = "boa_engine" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e637ec52ea66d76b0ca86180c259d6c7bb6e6a6e14b2f36b85099306d8b00cc3" -dependencies = [ - "aligned-vec", - "arrayvec", - "bitflags 2.10.0", - "boa_ast", - "boa_gc", - "boa_interner", - "boa_macros", - "boa_parser", - "boa_string", - "bytemuck", - "cfg-if", - "cow-utils", - "dashmap", - "dynify", - "fast-float2", - "float16", - "futures-channel", - "futures-concurrency", - "futures-lite", - "hashbrown 0.16.1", - "icu_normalizer", - "indexmap 2.13.0", - "intrusive-collections", - "itertools 0.14.0", - "num-bigint", - "num-integer", - "num-traits", - "num_enum", - "paste", - "portable-atomic", - "rand 0.9.2", - "regress", - "rustc-hash 2.1.1", - "ryu-js", - "serde", - "serde_json", - "small_btree", - "static_assertions", - "tag_ptr", - "tap", - "thin-vec", - "thiserror 2.0.18", - "time", - "xsum", -] - -[[package]] -name = "boa_gc" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1179f690cbfcbe5364cceee5f1cb577265bb6f07b0be6f210aabe270adcf9da" -dependencies = [ - "boa_macros", - "boa_string", - "hashbrown 0.16.1", - "thin-vec", -] - -[[package]] -name = "boa_interner" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9626505d33dc63d349662437297df1d3afd9d5fc4a2b3ad34e5e1ce879a78848" -dependencies = [ - "boa_gc", - "boa_macros", - "hashbrown 0.16.1", - "indexmap 2.13.0", - "once_cell", - "phf", - "rustc-hash 2.1.1", - "static_assertions", -] - -[[package]] -name = "boa_macros" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f36418a46544b152632c141b0a0b7a453cd69ca150caeef83aee9e2f4b48b7d" -dependencies = [ - "cfg-if", - "cow-utils", - "proc-macro2", - "quote", - "syn 2.0.114", - "synstructure", -] - -[[package]] -name = "boa_parser" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f99bf5b684f0de946378fcfe5f38c3a0fbd51cbf83a0f39ff773a0e218541f" -dependencies = [ - "bitflags 2.10.0", - "boa_ast", - "boa_interner", - "boa_macros", - "fast-float2", - "icu_properties", - "num-bigint", - "num-traits", - "regress", - "rustc-hash 2.1.1", -] - -[[package]] -name = "boa_string" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ce9d7aa5563a2e14eab111e2ae1a06a69a812f6c0c3d843196c9d03fbef440" -dependencies = [ - "fast-float2", - "itoa", - "paste", - "rustc-hash 2.1.1", - "ryu-js", - "static_assertions", -] - [[package]] name = "borrow-or-share" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc0b364ead1874514c8c2855ab558056ebfeb775653e7ae45ff72f28f8f3166c" +[[package]] +name = "boxed_error" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d4f95e880cfd28c4ca5a006cf7f6af52b4bcb7b5866f573b2faa126fb7affb" +dependencies = [ + "quote", + "syn 2.0.114", +] + [[package]] name = "boxfnonce" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426" +[[package]] +name = "bpaf" +version = "0.9.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a59e5c2bac9ccb280150ef4b58e07e4169d8c5c6ce0f70170e3c0b7c7b6124" +dependencies = [ + "bpaf_derive", +] + +[[package]] +name = "bpaf_derive" +version = "0.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "549ca9c364fdc06f9f36d1356980193d930abc80db848193c2dd4d0e9a83de1b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "brotli" version = "8.0.2" @@ -1205,6 +1459,9 @@ name = "bumpalo" version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +dependencies = [ + "allocator-api2", +] [[package]] name = "bytecount" @@ -1246,9 +1503,19 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "bytes-str" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c60b5ce37e0b883c37eb89f79a1e26fbe9c1081945d024eee93e8d91a7e18b3" +dependencies = [ + "bytes", + "serde", +] [[package]] name = "bytes-utils" @@ -1286,6 +1553,31 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "cache_control" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf2a5fb3207c12b5d208ebc145f967fea5cac41a021c37417ccc31ba40f39ee" + +[[package]] +name = "calendrical_calculations" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a0b39595c6ee54a8d0900204ba4c401d0ab4eb45adaf07178e8d017541529e7" +dependencies = [ + "core_maths", + "displaydoc", +] + +[[package]] +name = "camino" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +dependencies = [ + "serde_core", +] + [[package]] name = "candle-core" version = "0.9.2" @@ -1293,9 +1585,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c15b675b80d994b2eadb20a4bbe434eabeb454eac3ee5e2b4cf6f147ee9be091" dependencies = [ "byteorder", + "candle-kernels", "candle-metal-kernels", "candle-ug", - "float8", + "cudarc 0.19.0", + "float8 0.6.1", "gemm 0.19.0", "half", "libm", @@ -1313,6 +1607,15 @@ dependencies = [ "zip 7.2.0", ] +[[package]] +name = "candle-kernels" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8455f84bd810047c7c41216683c1020c915a9f8a740b3b0eabdd4fb2fbaa660" +dependencies = [ + "bindgen_cuda", +] + [[package]] name = "candle-metal-kernels" version = "0.9.2" @@ -1372,9 +1675,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c22d62be69068bf58987a45f690612739d8d2ea1bf508c1b87dc6815a019575d" dependencies = [ "ug", + "ug-cuda", "ug-metal", ] +[[package]] +name = "capacity_builder" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2d24a6dcf0cd402a21b65d35340f3a49ff3475dc5fdac91d22d2733e6641c6" +dependencies = [ + "capacity_builder_macros", + "ecow", + "hipstr", + "itoa", +] + +[[package]] +name = "capacity_builder_macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b4a6cae9efc04cc6cbb8faf338d2c497c165c83e74509cf4dbedea948bbf6e5" +dependencies = [ + "quote", + "syn 2.0.114", +] + [[package]] name = "castaway" version = "0.2.4" @@ -1479,9 +1805,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.56" +version = "4.5.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75ca66430e33a14957acc24c5077b503e7d374151b2b4b3a10c83b4ceb4be0e" +checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" dependencies = [ "clap_builder", "clap_derive", @@ -1489,9 +1815,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.56" +version = "4.5.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793207c7fa6300a0608d1080b858e5fdbe713cdc1c8db9fb17777d8a13e63df0" +checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" dependencies = [ "anstream", "anstyle", @@ -1601,6 +1927,19 @@ dependencies = [ "memchr", ] +[[package]] +name = "compact_str" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "ryu", + "static_assertions", +] + [[package]] name = "compact_str" version = "0.9.0" @@ -1756,6 +2095,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "cooked-waker" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147be55d677052dabc6b22252d5dd0fd4c29c8c27aa4f2fbef0f94aa003b406f" + [[package]] name = "cookie" version = "0.18.1" @@ -1823,10 +2168,19 @@ dependencies = [ ] [[package]] -name = "cow-utils" -version = "0.1.3" +name = "core_maths" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" +dependencies = [ + "libm", +] + +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" [[package]] name = "cpufeatures" @@ -1939,6 +2293,27 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "cudarc" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf99ab37ee7072d64d906aa2dada9a3422f1d975cdf8c8055a573bc84897ed8" +dependencies = [ + "half", + "libloading", +] + +[[package]] +name = "cudarc" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d5be1e9776a20360ca270df637b391c85d48ea57508140f30a4e8f6da91884a" +dependencies = [ + "float8 0.3.0", + "half", + "libloading", +] + [[package]] name = "darling" version = "0.20.11" @@ -2052,6 +2427,19 @@ dependencies = [ "serde", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "dashmap" version = "6.1.0" @@ -2072,6 +2460,12 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +[[package]] +name = "data-url" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" + [[package]] name = "dbus" version = "0.9.10" @@ -2112,6 +2506,366 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid", +] + +[[package]] +name = "deno_ast" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c2f6f65154faed61e45d6578566f9fab9d2a330c35c87366706883701cce51" +dependencies = [ + "base64 0.22.1", + "capacity_builder", + "deno_error", + "deno_media_type", + "deno_terminal", + "dprint-swc-ext", + "percent-encoding", + "serde", + "swc_atoms", + "swc_common", + "swc_config", + "swc_config_macro", + "swc_ecma_ast", + "swc_ecma_codegen", + "swc_ecma_codegen_macros", + "swc_ecma_lexer", + "swc_ecma_loader", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_transforms_classes", + "swc_ecma_transforms_macros", + "swc_ecma_transforms_proposal", + "swc_ecma_transforms_react", + "swc_ecma_transforms_typescript", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_eq_ignore_macros", + "swc_macros_common", + "swc_sourcemap", + "swc_visit", + "text_lines", + "thiserror 2.0.18", + "unicode-width 0.2.2", + "url", +] + +[[package]] +name = "deno_cache_dir" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7862aa4b7aad895ee979a3078bd25da192a1810b30cb5a7e764fed38d065eba9" +dependencies = [ + "async-trait", + "base32", + "base64 0.21.7", + "boxed_error", + "cache_control", + "chrono", + "data-url", + "deno_error", + "deno_media_type", + "deno_path_util", + "http 1.4.0", + "indexmap 2.13.0", + "log", + "once_cell", + "parking_lot", + "serde", + "serde_json", + "sha2", + "sys_traits", + "thiserror 2.0.18", + "url", +] + +[[package]] +name = "deno_config" +version = "0.77.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba166cbf37d43fb2d34d9a1dce8ce2c0f9b84727a99db0ed12564c05a46886b4" +dependencies = [ + "boxed_error", + "capacity_builder", + "chrono", + "deno_error", + "deno_maybe_sync", + "deno_package_json", + "deno_path_util", + "deno_semver", + "glob", + "ignore", + "import_map", + "indexmap 2.13.0", + "jsonc-parser", + "log", + "serde", + "serde_json", + "sys_traits", + "thiserror 2.0.18", + "url", +] + +[[package]] +name = "deno_core" +version = "0.381.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77660b04f5368bcd69a42e0fdd6343e325eb781ec7d79bbf49ff2548ae4f17b6" +dependencies = [ + "anyhow", + "az", + "bincode", + "bit-set 0.8.0", + "bit-vec 0.8.0", + "boxed_error", + "bytes", + "capacity_builder", + "cooked-waker", + "deno_core_icudata", + "deno_error", + "deno_ops", + "deno_path_util", + "deno_unsync", + "futures", + "indexmap 2.13.0", + "libc", + "parking_lot", + "percent-encoding", + "pin-project", + "serde", + "serde_json", + "serde_v8", + "smallvec", + "sourcemap", + "static_assertions", + "thiserror 2.0.18", + "tokio", + "url", + "v8", + "wasm_dep_analyzer", +] + +[[package]] +name = "deno_core_icudata" +version = "0.77.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9efff8990a82c1ae664292507e1a5c6749ddd2312898cdf9cd7cb1fd4bc64c6" + +[[package]] +name = "deno_error" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfafd2219b29886a71aecbb3449e462deed1b2c474dc5b12f855f0e58c478931" +dependencies = [ + "deno_error_macro", + "libc", + "serde", + "serde_json", + "tokio", + "url", +] + +[[package]] +name = "deno_error_macro" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c28ede88783f14cd8aae46ca89f230c226b40e4a81ab06fa52ed72af84beb2f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "deno_lockfile" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d71c0df1464034be21a9472e7ec8f9a21958418d203fa2c40507fb5cafe799d" +dependencies = [ + "async-trait", + "deno_semver", + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "deno_maybe_sync" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "042601bdeb305f3accea03d005ab106305960bbfc1b9649fe14d8ee29decf8dc" + +[[package]] +name = "deno_media_type" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac0109d26ff08a089642a79b45c65f91a849404c1ef3ec78c837a412956d8808" +dependencies = [ + "data-url", + "serde", + "url", +] + +[[package]] +name = "deno_npm" +version = "0.42.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ff75f741a6ead7e13ed60151071d886310d75942845fff8b523423115772e3f" +dependencies = [ + "async-trait", + "capacity_builder", + "chrono", + "deno_error", + "deno_lockfile", + "deno_semver", + "futures", + "indexmap 2.13.0", + "log", + "monch", + "serde", + "serde_json", + "thiserror 2.0.18", + "url", +] + +[[package]] +name = "deno_ops" +version = "0.257.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd9aa20a48be11c922d9451a524afecde323a22d5defacc1dd79f8deac728fb" +dependencies = [ + "indexmap 2.13.0", + "proc-macro2", + "quote", + "stringcase", + "strum", + "strum_macros", + "syn 2.0.114", + "syn-match", + "thiserror 2.0.18", +] + +[[package]] +name = "deno_package_json" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52308462288a304df2d659a8c3aa71426bee546843d23820605666e7c99b91e9" +dependencies = [ + "boxed_error", + "deno_error", + "deno_maybe_sync", + "deno_path_util", + "deno_semver", + "indexmap 2.13.0", + "serde", + "serde_json", + "sys_traits", + "thiserror 2.0.18", + "url", +] + +[[package]] +name = "deno_path_util" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c7e98943f0d068928906db0c7bde89de684fa32c6a8018caacc4cee2cdd72b" +dependencies = [ + "deno_error", + "percent-encoding", + "sys_traits", + "thiserror 2.0.18", + "url", +] + +[[package]] +name = "deno_resolver" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbc1abe929b6f3719871c4075154c6334d516b88c046b5c2ba7d7998ae62301" +dependencies = [ + "anyhow", + "async-once-cell", + "async-trait", + "base32", + "boxed_error", + "capacity_builder", + "chrono", + "deno_cache_dir", + "deno_config", + "deno_error", + "deno_lockfile", + "deno_maybe_sync", + "deno_media_type", + "deno_npm", + "deno_package_json", + "deno_path_util", + "deno_semver", + "deno_terminal", + "deno_unsync", + "dissimilar", + "futures", + "import_map", + "indexmap 2.13.0", + "jsonc-parser", + "log", + "node_resolver", + "once_cell", + "parking_lot", + "phf", + "serde", + "serde_json", + "sys_traits", + "thiserror 2.0.18", + "twox-hash", + "url", +] + +[[package]] +name = "deno_semver" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d46d2fd6959170a6e9f6607a6f79683868fa82ceac56ca520ab014e4fa5b21" +dependencies = [ + "capacity_builder", + "deno_error", + "ecow", + "hipstr", + "monch", + "once_cell", + "serde", + "thiserror 2.0.18", + "url", +] + +[[package]] +name = "deno_terminal" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ba8041ae7319b3ca6a64c399df4112badcbbe0868b4517637647614bede4be" +dependencies = [ + "once_cell", + "termcolor", +] + +[[package]] +name = "deno_unsync" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6742a724e8becb372a74c650a1aefb8924a5b8107f7d75b3848763ea24b27a87" +dependencies = [ + "futures-util", + "parking_lot", + "tokio", +] + [[package]] name = "der" version = "0.7.10" @@ -2192,7 +2946,7 @@ dependencies = [ "convert_case 0.10.0", "proc-macro2", "quote", - "rustc_version 0.4.1", + "rustc_version", "syn 2.0.114", "unicode-xid", ] @@ -2207,6 +2961,12 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.10.7" @@ -2219,6 +2979,38 @@ dependencies = [ "subtle", ] +[[package]] +name = "diplomat" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9adb46b05e2f53dcf6a7dfc242e4ce9eb60c369b6b6eb10826a01e93167f59c6" +dependencies = [ + "diplomat_core", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "diplomat-runtime" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0569bd3caaf13829da7ee4e83dbf9197a0e1ecd72772da6d08f0b4c9285c8d29" + +[[package]] +name = "diplomat_core" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51731530ed7f2d4495019abc7df3744f53338e69e2863a6a64ae91821c763df1" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "smallvec", + "strck", + "syn 2.0.114", +] + [[package]] name = "dirs" version = "5.0.1" @@ -2295,6 +3087,12 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "dissimilar" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" + [[package]] name = "dlv-list" version = "0.5.2" @@ -2346,6 +3144,28 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" +[[package]] +name = "dprint-swc-ext" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33175ddb7a6d418589cab2966bd14a710b3b1139459d3d5ca9edf783c4833f4c" +dependencies = [ + "num-bigint", + "rustc-hash 2.1.1", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_lexer", + "swc_ecma_parser", + "text_lines", +] + +[[package]] +name = "drop_bomb" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" + [[package]] name = "dunce" version = "1.0.5" @@ -2374,26 +3194,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d926b4d407d372f141f93bb444696142c29d32962ccbd3531117cf3aa0bfa9" -[[package]] -name = "dynify" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81acb15628a3e22358bf73de5e7e62360b8a777dbcb5fc9ac7dfa9ae73723747" -dependencies = [ - "dynify-macros", -] - -[[package]] -name = "dynify-macros" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec431cd708430d5029356535259c5d645d60edd3d39c54e5eea9782d46caa7d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - [[package]] name = "ecb" version = "0.1.2" @@ -2403,6 +3203,15 @@ dependencies = [ "cipher", ] +[[package]] +name = "ecow" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78e4f79b296fbaab6ce2e22d52cb4c7f010fe0ebe7a32e34fa25885fd797bd02" +dependencies = [ + "serde", +] + [[package]] name = "either" version = "1.15.0" @@ -2489,26 +3298,6 @@ dependencies = [ "log", ] -[[package]] -name = "equator" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" -dependencies = [ - "equator-macro", -] - -[[package]] -name = "equator-macro" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -2637,12 +3426,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "fast-float2" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8eb564c5c7423d25c886fb561d1e4ee69f72354d16918afa32c08811f6b6a55" - [[package]] name = "fastrand" version = "2.3.0" @@ -2697,21 +3480,21 @@ dependencies = [ ] [[package]] -name = "float16" -version = "0.1.5" +name = "float8" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bffafbd079d520191c7c2779ae9cf757601266cf4167d3f659ff09617ff8483" +checksum = "0f498aec3b227cd892ce18967f4033d9d397d28a80a7ab67e9f6b0176a79654e" dependencies = [ - "cfg-if", - "rustc_version 0.2.3", + "half", ] [[package]] name = "float8" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f463a8a37ede13dac13316d1a1eeafa992300906a0c4c7fa1177f366d10bcbf" +checksum = "719a903cc23e4a89e87962c2a80fdb45cdaad0983a89bd150bb57b4c8571a7d5" dependencies = [ + "cudarc 0.19.0", "half", "num-traits", "rand 0.9.2", @@ -2825,6 +3608,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" +[[package]] +name = "from_variant" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ff35a391aef949120a0340d690269b3d9f63460a6106e99bd07b961f345ea9" +dependencies = [ + "swc_macros_common", + "syn 2.0.114", +] + [[package]] name = "fs-err" version = "3.2.2" @@ -2850,6 +3643,22 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "fslock" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04412b8935272e3a9bae6f48c7bfff74c2911f60525404edfdd28e49884c3bfb" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" version = "0.3.31" @@ -3270,6 +4079,12 @@ dependencies = [ "weezl", ] +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + [[package]] name = "git-version" version = "0.3.9" @@ -3324,7 +4139,7 @@ dependencies = [ [[package]] name = "goose" -version = "1.22.0" +version = "1.23.0" dependencies = [ "ahash", "anyhow", @@ -3337,7 +4152,6 @@ dependencies = [ "axum 0.8.8", "base64 0.22.1", "blake3", - "boa_engine", "byteorder", "candle-core", "candle-nn", @@ -3345,7 +4159,7 @@ dependencies = [ "chrono", "clap", "ctor", - "dashmap", + "dashmap 6.1.0", "dirs 5.0.1", "dotenvy", "env-lock", @@ -3368,18 +4182,19 @@ dependencies = [ "mockall", "nanoid", "once_cell", - "opentelemetry", + "opentelemetry 0.27.1", "opentelemetry-appender-tracing", - "opentelemetry-otlp", - "opentelemetry_sdk", + "opentelemetry-otlp 0.27.0", + "opentelemetry_sdk 0.27.1", "paste", + "pctx_code_mode", "posthog-rs", "rand 0.8.5", "regex", "reqwest 0.12.28", "rmcp 0.14.0", "rubato", - "schemars", + "schemars 1.2.1", "serde", "serde_json", "serde_urlencoded", @@ -3406,7 +4221,7 @@ dependencies = [ "unicode-normalization", "url", "urlencoding", - "utoipa", + "utoipa 4.2.3", "uuid", "v_htmlescape", "webbrowser", @@ -3418,7 +4233,7 @@ dependencies = [ [[package]] name = "goose-acp" -version = "1.22.0" +version = "1.23.0" dependencies = [ "anyhow", "assert-json-diff", @@ -3451,7 +4266,7 @@ dependencies = [ [[package]] name = "goose-bench" -version = "1.22.0" +version = "1.23.0" dependencies = [ "anyhow", "async-trait", @@ -3474,7 +4289,7 @@ dependencies = [ [[package]] name = "goose-cli" -version = "1.22.0" +version = "1.23.0" dependencies = [ "anstream", "anyhow", @@ -3521,7 +4336,7 @@ dependencies = [ [[package]] name = "goose-mcp" -version = "1.22.0" +version = "1.23.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -3542,7 +4357,7 @@ dependencies = [ "regex", "reqwest 0.12.28", "rmcp 0.14.0", - "schemars", + "schemars 1.2.1", "serde", "serde_json", "serial_test", @@ -3570,7 +4385,7 @@ dependencies = [ [[package]] name = "goose-server" -version = "1.22.0" +version = "1.23.0" dependencies = [ "anyhow", "axum 0.8.8", @@ -3608,7 +4423,7 @@ dependencies = [ "tracing-appender", "tracing-subscriber", "url", - "utoipa", + "utoipa 4.2.3", "uuid", "winreg 0.55.0", "wiremock", @@ -3616,7 +4431,7 @@ dependencies = [ [[package]] name = "goose-test" -version = "1.22.0" +version = "1.23.0" dependencies = [ "clap", "serde_json", @@ -3636,6 +4451,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "gzip-header" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95cc527b92e6029a62960ad99aa8a6660faa4555fe5f731aab13aa6a921795a2" +dependencies = [ + "crc32fast", +] + [[package]] name = "h2" version = "0.3.27" @@ -3689,6 +4513,22 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "handlebars" +version = "6.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3f9296c208515b87bd915a2f5d1163d4b3f863ba83337d7713cf478055948e" +dependencies = [ + "derive_builder", + "log", + "num-order", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror 2.0.18", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -3784,6 +4624,17 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "hipstr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97971ffc85d4c98de12e2608e992a43f5294ebb625fdb045b27c731b64c4c6d6" +dependencies = [ + "serde", + "serde_bytes", + "sptr", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -3811,6 +4662,20 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "hstr" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa57007c3c9dab34df2fa4c1fb52fe9c34ec5a27ed9d8edea53254b50cd7887" +dependencies = [ + "hashbrown 0.14.5", + "new_debug_unreachable", + "once_cell", + "rustc-hash 2.1.1", + "serde", + "triomphe", +] + [[package]] name = "html_parser" version = "0.7.0" @@ -3976,7 +4841,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.4", "tower-service", - "webpki-roots 1.0.5", + "webpki-roots 1.0.6", ] [[package]] @@ -4042,10 +4907,32 @@ dependencies = [ ] [[package]] -name = "icu_collections" -version = "2.0.0" +name = "icu_calendar" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "d6f0e52e009b6b16ba9c0693578796f2dd4aaa59a7f8f920423706714a89ac4e" +dependencies = [ + "calendrical_calculations", + "displaydoc", + "icu_calendar_data", + "icu_locale", + "icu_locale_core", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_calendar_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527f04223b17edfe0bd43baf14a0cb1b017830db65f3950dc00224860a9a446d" + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -4054,6 +4941,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "icu_locale" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532b11722e350ab6bf916ba6eb0efe3ee54b932666afec989465f9243fe6dd60" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_locale_data", + "icu_provider", + "potential_utf", + "tinystr", + "zerovec", +] + [[package]] name = "icu_locale_core" version = "2.1.1" @@ -4069,49 +4971,50 @@ dependencies = [ ] [[package]] -name = "icu_normalizer" -version = "2.0.1" +name = "icu_locale_data" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b24a59706036ba941c9476a55cd57b82b77f38a3c667d637ee7cabbc85eaedc" +checksum = "1c5f1d16b4c3a2642d3a719f18f6b06070ab0aef246a6418130c955ae08aa831" + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.2" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5a97b8ac6235e69506e8dacfb2adf38461d2ce6d3e9bd9c94c4cbc3cd4400a4" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -4157,6 +5060,12 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "if_chain" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" + [[package]] name = "ignore" version = "0.4.25" @@ -4210,6 +5119,23 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c" +[[package]] +name = "import_map" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83a4958a41489355816028239fee373797435384d162f4908e7980c83c3bb1b" +dependencies = [ + "boxed_error", + "deno_error", + "indexmap 2.13.0", + "log", + "percent-encoding", + "serde", + "serde_json", + "thiserror 2.0.18", + "url", +] + [[package]] name = "include_dir" version = "0.7.4" @@ -4237,6 +5163,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] @@ -4308,15 +5235,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "intrusive-collections" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86" -dependencies = [ - "memoffset", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -4342,6 +5260,18 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is-macro" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57a3e447e24c22647738e4607f1df1e0ec6f72e16182c4cd199f647cdfb0e4" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "is-wsl" version = "0.4.0" @@ -4391,6 +5321,12 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +[[package]] +name = "ixdtf" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84de9d95a6d2547d9b77ee3f25fa0ee32e3c3a6484d47a55adebc0439c077992" + [[package]] name = "jiff" version = "0.2.18" @@ -4494,6 +5430,15 @@ dependencies = [ "serde", ] +[[package]] +name = "jsonc-parser" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01958dcb05b69d9612853b47df8f7881810e4f61b5cedd8894be04291f28ccb9" +dependencies = [ + "serde_json", +] + [[package]] name = "jsonrpcmsg" version = "0.1.2" @@ -4554,6 +5499,7 @@ checksum = "eebcc3aff044e5944a8fbaf69eb277d11986064cba30c468730e8b9909fb551c" dependencies = [ "byteorder", "dbus-secret-service", + "linux-keyutils", "log", "openssl", "security-framework 2.11.1", @@ -4562,6 +5508,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "lazy-regex" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5c13b6857ade4c8ee05c3c3dc97d2ab5415d691213825b90d3211c425c1f907" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a95c68db5d41694cea563c86a4ba4dc02141c16ef64814108cb23def4d5438" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.114", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -4667,6 +5636,16 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-keyutils" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" +dependencies = [ + "bitflags 2.10.0", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -4831,9 +5810,9 @@ checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b" [[package]] name = "memoffset" -version = "0.9.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] @@ -4933,6 +5912,12 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "monch" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b52c1b33ff98142aecea13138bd399b68aa7ab5d9546c300988c345004001eea" + [[package]] name = "monostate" version = "0.1.18" @@ -4995,6 +5980,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nibble_vec" version = "0.1.0" @@ -5028,6 +6019,37 @@ dependencies = [ "libc", ] +[[package]] +name = "node_resolver" +version = "0.65.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01957d40d64724eb35d92ac2ccd5b4be660072639c82c3bf831a24ba325a15f8" +dependencies = [ + "anyhow", + "async-trait", + "boxed_error", + "capacity_builder", + "dashmap 5.5.3", + "deno_error", + "deno_maybe_sync", + "deno_media_type", + "deno_package_json", + "deno_path_util", + "deno_semver", + "futures", + "lazy-regex", + "log", + "once_cell", + "path-clean", + "pretty_assertions", + "regex", + "serde", + "serde_json", + "sys_traits", + "thiserror 2.0.18", + "url", +] + [[package]] name = "nom" version = "7.1.3" @@ -5098,6 +6120,7 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "rand 0.8.5", "serde", ] @@ -5170,6 +6193,21 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + [[package]] name = "num-rational" version = "0.4.2" @@ -5201,37 +6239,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" -dependencies = [ - "num_enum_derive", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - [[package]] name = "number_prefix" version = "0.4.0" @@ -5533,6 +6540,15 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -5646,13 +6662,27 @@ dependencies = [ "tracing", ] +[[package]] +name = "opentelemetry" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 2.0.18", + "tracing", +] + [[package]] name = "opentelemetry-appender-tracing" version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5feffc321035ad94088a7e5333abb4d84a8726e54a802e736ce9dd7237e85b" dependencies = [ - "opentelemetry", + "opentelemetry 0.27.1", "tracing", "tracing-core", "tracing-subscriber", @@ -5667,7 +6697,20 @@ dependencies = [ "async-trait", "bytes", "http 1.4.0", - "opentelemetry", + "opentelemetry 0.27.1", + "reqwest 0.12.28", +] + +[[package]] +name = "opentelemetry-http" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +dependencies = [ + "async-trait", + "bytes", + "http 1.4.0", + "opentelemetry 0.31.0", "reqwest 0.12.28", ] @@ -5680,15 +6723,34 @@ dependencies = [ "async-trait", "futures-core", "http 1.4.0", - "opentelemetry", - "opentelemetry-http", - "opentelemetry-proto", - "opentelemetry_sdk", - "prost", + "opentelemetry 0.27.1", + "opentelemetry-http 0.27.0", + "opentelemetry-proto 0.27.0", + "opentelemetry_sdk 0.27.1", + "prost 0.13.5", "reqwest 0.12.28", "thiserror 1.0.69", "tokio", - "tonic", + "tonic 0.12.3", + "tracing", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" +dependencies = [ + "http 1.4.0", + "opentelemetry 0.31.0", + "opentelemetry-http 0.31.0", + "opentelemetry-proto 0.31.0", + "opentelemetry_sdk 0.31.0", + "prost 0.14.3", + "reqwest 0.12.28", + "thiserror 2.0.18", + "tokio", + "tonic 0.14.3", "tracing", ] @@ -5698,10 +6760,23 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6e05acbfada5ec79023c85368af14abd0b307c015e9064d249b2a950ef459a6" dependencies = [ - "opentelemetry", - "opentelemetry_sdk", - "prost", - "tonic", + "opentelemetry 0.27.1", + "opentelemetry_sdk 0.27.1", + "prost 0.13.5", + "tonic 0.12.3", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +dependencies = [ + "opentelemetry 0.31.0", + "opentelemetry_sdk 0.31.0", + "prost 0.14.3", + "tonic 0.14.3", + "tonic-prost", ] [[package]] @@ -5715,7 +6790,7 @@ dependencies = [ "futures-executor", "futures-util", "glob", - "opentelemetry", + "opentelemetry 0.27.1", "percent-encoding", "rand 0.8.5", "serde_json", @@ -5725,6 +6800,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "opentelemetry_sdk" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "opentelemetry 0.31.0", + "percent-encoding", + "rand 0.9.2", + "thiserror 2.0.18", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -5747,6 +6837,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" +[[package]] +name = "par-core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96cbd21255b7fb29a5d51ef38a779b517a91abd59e2756c039583f43ef4c90f" +dependencies = [ + "once_cell", +] + [[package]] name = "parking" version = "2.2.1" @@ -5799,6 +6898,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b867cad97c0791bbd3aaa6472142568c6c9e8f71937e98379f584cfb0cf35bec" +[[package]] +name = "path-clean" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd" + [[package]] name = "path_abs" version = "0.5.1" @@ -5826,6 +6931,141 @@ dependencies = [ "sha2", ] +[[package]] +name = "pctx_code_execution_runtime" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9180fee1264bed9613b65e8702b2bd4ba404a4606d802ac237808e032d476e84" +dependencies = [ + "anyhow", + "deno_core", + "deno_error", + "pctx_config", + "rmcp 0.14.0", + "serde", + "serde_json", + "thiserror 2.0.18", + "tracing", + "url", +] + +[[package]] +name = "pctx_code_mode" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5788a3f1aaa7bc0fdcbae6d9ff24a080a6cc0d202d8affa8f1c29097e40a504a" +dependencies = [ + "futures", + "pctx_code_execution_runtime", + "pctx_codegen", + "pctx_config", + "pctx_executor", + "schemars 1.2.1", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tracing", + "utoipa 5.4.0", +] + +[[package]] +name = "pctx_codegen" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebab01af80ced5df67e44d85c6caa9ccc5d0c6e07e0881e7d573447f1ee0f13" +dependencies = [ + "biome_formatter", + "biome_js_formatter", + "biome_js_parser", + "biome_js_syntax", + "handlebars", + "heck", + "indexmap 2.13.0", + "regex", + "schemars 0.8.22", + "serde", + "serde_json", + "thiserror 2.0.18", + "tracing", + "unicode-ident", +] + +[[package]] +name = "pctx_config" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f5d3440e3936b1e06f168ce1657dbb0f05e2be63972ddb51050f81a12e771fb" +dependencies = [ + "anyhow", + "base64 0.22.1", + "camino", + "http 1.4.0", + "indexmap 2.13.0", + "keyring", + "opentelemetry-otlp 0.31.0", + "opentelemetry_sdk 0.31.0", + "reqwest 0.12.28", + "rmcp 0.14.0", + "serde", + "serde_json", + "shlex", + "thiserror 2.0.18", + "tokio", + "tonic 0.14.3", + "tracing", + "url", +] + +[[package]] +name = "pctx_deno_transpiler" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0569477b4b06a749da9d37ddc3f9876444bd532f06bac0709010f0c85efc2d" +dependencies = [ + "deno_ast", + "thiserror 2.0.18", +] + +[[package]] +name = "pctx_executor" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5377dedd1b2f8dd5eed9baed09ae8efe46d131ed4eb1669a579e2588e91386" +dependencies = [ + "deno_core", + "deno_resolver", + "futures", + "node_resolver", + "pctx_code_execution_runtime", + "pctx_config", + "pctx_deno_transpiler", + "pctx_type_check_runtime", + "regex", + "serde", + "serde_json", + "sys_traits", + "tempfile", + "thiserror 2.0.18", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "pctx_type_check_runtime" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71b3e2fa9831b26e71f86d714c08a4b2cb052b594bfae8528efbc6ccd3b0b1ce" +dependencies = [ + "deno_ast", + "deno_core", + "futures", + "once_cell", + "serde", + "serde_json", + "thiserror 2.0.18", +] + [[package]] name = "pem" version = "3.0.6" @@ -5896,9 +7136,9 @@ dependencies = [ [[package]] name = "phf" -version = "0.13.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", "phf_shared", @@ -5906,19 +7146,19 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.13.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ - "fastrand", "phf_shared", + "rand 0.8.5", ] [[package]] name = "phf_macros" -version = "0.13.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ "phf_generator", "phf_shared", @@ -5929,11 +7169,11 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.13.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher", + "siphasher 1.0.2", ] [[package]] @@ -6058,7 +7298,7 @@ dependencies = [ "chrono", "derive_builder", "reqwest 0.11.27", - "semver 1.0.27", + "semver", "serde", "serde_json", "uuid", @@ -6070,6 +7310,8 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ + "serde_core", + "writeable", "zerovec", ] @@ -6114,6 +7356,16 @@ dependencies = [ "termtree", ] +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -6133,15 +7385,6 @@ dependencies = [ "num-integer", ] -[[package]] -name = "proc-macro-crate" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" -dependencies = [ - "toml_edit 0.23.10+spec-1.0.0", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -6196,7 +7439,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.13.5", +] + +[[package]] +name = "prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +dependencies = [ + "bytes", + "prost-derive 0.14.3", ] [[package]] @@ -6212,12 +7465,34 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "psl-types" version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" +[[package]] +name = "psm" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205" +dependencies = [ + "cc", +] + [[package]] name = "publicsuffix" version = "2.3.0" @@ -6381,6 +7656,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "radix_trie" version = "0.2.1" @@ -6597,9 +7878,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -6609,9 +7890,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -6620,25 +7901,15 @@ dependencies = [ [[package]] name = "regex-lite" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d942b98df5e658f56f20d592c7f868833fe38115e65c33003d8cd224b0155da" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - -[[package]] -name = "regress" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2057b2325e68a893284d1538021ab90279adac1139957ca2a74426c6f118fb48" -dependencies = [ - "hashbrown 0.16.1", - "memchr", -] +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "reqwest" @@ -6727,7 +7998,17 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.5", + "webpki-roots 1.0.6", +] + +[[package]] +name = "resb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a067ab3b5ca3b4dc307d0de9cf75f9f5e6ca9717b192b2f28a36c83e5de9e76" +dependencies = [ + "potential_utf", + "serde_core", ] [[package]] @@ -6766,7 +8047,7 @@ dependencies = [ "pastey", "pin-project-lite", "rmcp-macros 0.12.0", - "schemars", + "schemars 1.2.1", "serde", "serde_json", "thiserror 2.0.18", @@ -6797,7 +8078,7 @@ dependencies = [ "rand 0.9.2", "reqwest 0.12.28", "rmcp-macros 0.14.0", - "schemars", + "schemars 1.2.1", "serde", "serde_json", "sse-stream", @@ -6893,6 +8174,12 @@ dependencies = [ "ordered-multimap", ] +[[package]] +name = "rustc-demangle" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -6905,22 +8192,13 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.27", + "semver", ] [[package]] @@ -7099,7 +8377,7 @@ dependencies = [ "jsonrpcmsg", "rmcp 0.12.0", "sacp-derive", - "schemars", + "schemars 1.2.1", "serde", "serde_json", "thiserror 2.0.18", @@ -7168,6 +8446,19 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive 0.8.22", + "serde", + "serde_json", +] + [[package]] name = "schemars" version = "1.2.1" @@ -7177,11 +8468,23 @@ dependencies = [ "chrono", "dyn-clone", "ref-cast", - "schemars_derive", + "schemars_derive 1.2.1", "serde", "serde_json", ] +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.114", +] + [[package]] name = "schemars_derive" version = "1.2.1" @@ -7194,6 +8497,12 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -7258,27 +8567,12 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "seq-macro" version = "0.3.6" @@ -7307,6 +8601,16 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -7402,6 +8706,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_v8" +version = "0.290.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a52aca5a5661aea9c2ccf8c2f985f2381266d7aab03a0d02beadb4ae1190ea" +dependencies = [ + "deno_error", + "num-bigint", + "serde", + "smallvec", + "thiserror 2.0.18", + "v8", +] + [[package]] name = "serde_with" version = "3.16.1" @@ -7552,6 +8870,10 @@ name = "similar" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +dependencies = [ + "bstr", + "unicode-segmentation", +] [[package]] name = "simple_asn1" @@ -7565,6 +8887,12 @@ dependencies = [ "time", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "siphasher" version = "1.0.2" @@ -7577,15 +8905,6 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" -[[package]] -name = "small_btree" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba60d2df92ba73864714808ca68c059734853e6ab722b40e1cf543ebb3a057a" -dependencies = [ - "arrayvec", -] - [[package]] name = "smallvec" version = "1.15.1" @@ -7595,6 +8914,17 @@ dependencies = [ "serde", ] +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + [[package]] name = "smawk" version = "0.3.2" @@ -7621,6 +8951,24 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "sourcemap" +version = "9.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "314d62a489431668f719ada776ca1d49b924db951b7450f8974c9ae51ab05ad7" +dependencies = [ + "base64-simd", + "bitvec", + "data-encoding", + "debugid", + "if_chain", + "rustc-hash 2.1.1", + "serde", + "serde_json", + "unicode-id-start", + "url", +] + [[package]] name = "spin" version = "0.9.8" @@ -7652,6 +9000,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + [[package]] name = "sqlformat" version = "0.2.6" @@ -7882,6 +9236,19 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "stacker" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.59.0", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -7894,12 +9261,38 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8207e78455ffdf55661170876f88daf85356e4edd54e0a3dbc79586ca1e50cbe" +[[package]] +name = "strck" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42316e70da376f3d113a68d138a60d8a9883c604fe97942721ec2068dab13a9f" +dependencies = [ + "unicode-ident", +] + [[package]] name = "strength_reduce" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" +[[package]] +name = "string_enum" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae36a4951ca7bd1cfd991c241584a9824a70f6aff1e7d4f693fb3f2465e4030e" +dependencies = [ + "quote", + "swc_macros_common", + "syn 2.0.114", +] + +[[package]] +name = "stringcase" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72abeda133c49d7bddece6c154728f83eec8172380c80ab7096da9487e20d27c" + [[package]] name = "stringprep" version = "0.1.5" @@ -7944,6 +9337,387 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "swc_allocator" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d7eefd2c8b228a8c73056482b2ae4b3a1071fbe07638e3b55ceca8570cc48bb" +dependencies = [ + "allocator-api2", + "bumpalo", + "hashbrown 0.14.5", + "rustc-hash 2.1.1", +] + +[[package]] +name = "swc_atoms" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4ccbe2ecad10ad7432100f878a107b1d972a8aee83ca53184d00c23a078bb8a" +dependencies = [ + "hstr", + "once_cell", + "serde", +] + +[[package]] +name = "swc_common" +version = "17.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "259b675d633a26d24efe3802a9d88858c918e6e8f062d3222d3aa02d56a2cf4c" +dependencies = [ + "anyhow", + "ast_node", + "better_scoped_tls", + "bytes-str", + "either", + "from_variant", + "new_debug_unreachable", + "num-bigint", + "once_cell", + "rustc-hash 2.1.1", + "serde", + "siphasher 0.3.11", + "swc_atoms", + "swc_eq_ignore_macros", + "swc_sourcemap", + "swc_visit", + "tracing", + "unicode-width 0.2.2", + "url", +] + +[[package]] +name = "swc_config" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e90b52ee734ded867104612218101722ad87ff4cf74fe30383bd244a533f97" +dependencies = [ + "anyhow", + "bytes-str", + "indexmap 2.13.0", + "serde", + "serde_json", + "swc_config_macro", +] + +[[package]] +name = "swc_config_macro" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b416e8ce6de17dc5ea496e10c7012b35bbc0e3fef38d2e065eed936490db0b3" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.114", +] + +[[package]] +name = "swc_ecma_ast" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a573a0c72850dec8d4d8085f152d5778af35a2520c3093b242d2d1d50776da7c" +dependencies = [ + "bitflags 2.10.0", + "is-macro", + "num-bigint", + "once_cell", + "phf", + "rustc-hash 2.1.1", + "serde", + "string_enum", + "swc_atoms", + "swc_common", + "swc_visit", + "unicode-id-start", +] + +[[package]] +name = "swc_ecma_codegen" +version = "20.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2a6ee1ec49dda8dedeac54e4147b4e8b3f278d9bb34ab28983257a393d34ed" +dependencies = [ + "ascii", + "compact_str 0.7.1", + "memchr", + "num-bigint", + "once_cell", + "regex", + "rustc-hash 2.1.1", + "ryu-js", + "serde", + "swc_allocator", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_codegen_macros", + "swc_sourcemap", + "tracing", +] + +[[package]] +name = "swc_ecma_codegen_macros" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e276dc62c0a2625a560397827989c82a93fd545fcf6f7faec0935a82cc4ddbb8" +dependencies = [ + "proc-macro2", + "swc_macros_common", + "syn 2.0.114", +] + +[[package]] +name = "swc_ecma_lexer" +version = "26.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e82f7747e052c6ff6e111fa4adeb14e33b46ee6e94fe5ef717601f651db48fc" +dependencies = [ + "bitflags 2.10.0", + "either", + "num-bigint", + "rustc-hash 2.1.1", + "seq-macro", + "serde", + "smallvec", + "smartstring", + "stacker", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_parser", + "tracing", +] + +[[package]] +name = "swc_ecma_loader" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcababb48f0d46587a0a854b2c577eb3a56fa99687de558338021e93cd2c8f5" +dependencies = [ + "anyhow", + "pathdiff", + "rustc-hash 2.1.1", + "serde", + "swc_atoms", + "swc_common", + "tracing", +] + +[[package]] +name = "swc_ecma_parser" +version = "27.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f1a51af1a92cd4904c073b293e491bbc0918400a45d58227b34c961dd6f52d7" +dependencies = [ + "bitflags 2.10.0", + "either", + "num-bigint", + "phf", + "rustc-hash 2.1.1", + "seq-macro", + "serde", + "smartstring", + "stacker", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "tracing", +] + +[[package]] +name = "swc_ecma_transforms_base" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f6f165578ca4fee47bd57585c1b9597c94bf4ea6591df47f2b5fa5b1883fe" +dependencies = [ + "better_scoped_tls", + "indexmap 2.13.0", + "once_cell", + "par-core", + "phf", + "rustc-hash 2.1.1", + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_utils", + "swc_ecma_visit", + "tracing", +] + +[[package]] +name = "swc_ecma_transforms_classes" +version = "30.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3ab35eff4a980e02d708798ae4c35bc017612292adbffe7b7b554df772fdf5" +dependencies = [ + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_transforms_macros" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc777288799bf6786e5200325a56e4fbabba590264a4a48a0c70b16ad0cf5cd8" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.114", +] + +[[package]] +name = "swc_ecma_transforms_proposal" +version = "30.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d7748d4112c87ce1885260035e4a43cebfe7661a40174b7d77a0a04760a257" +dependencies = [ + "either", + "rustc-hash 2.1.1", + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_transforms_classes", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_transforms_react" +version = "33.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03de12e38e47ac1c96ac576f793ad37a9d7b16fbf4f2203881f89152f2498682" +dependencies = [ + "base64 0.22.1", + "bytes-str", + "indexmap 2.13.0", + "once_cell", + "rustc-hash 2.1.1", + "serde", + "sha1", + "string_enum", + "swc_atoms", + "swc_common", + "swc_config", + "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_transforms_typescript" +version = "33.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4408800fdeb541fabf3659db622189a0aeb386f57b6103f9294ff19dfde4f7b0" +dependencies = [ + "bytes-str", + "rustc-hash 2.1.1", + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_transforms_react", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_utils" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fb99e179988cabd473779a4452ab942bcb777176983ca3cbaf22a8f056a65b0" +dependencies = [ + "indexmap 2.13.0", + "num_cpus", + "once_cell", + "par-core", + "rustc-hash 2.1.1", + "ryu-js", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_visit", + "tracing", +] + +[[package]] +name = "swc_ecma_visit" +version = "18.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9611a72a4008d62608547a394e5d72a5245413104db096d95a52368a8cc1d63" +dependencies = [ + "new_debug_unreachable", + "num-bigint", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_visit", + "tracing", +] + +[[package]] +name = "swc_eq_ignore_macros" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c16ce73424a6316e95e09065ba6a207eba7765496fed113702278b7711d4b632" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "swc_macros_common" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1efbaa74943dc5ad2a2fb16cbd78b77d7e4d63188f3c5b4df2b4dcd2faaae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "swc_sourcemap" +version = "9.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de08ef00f816acdd1a58ee8a81c0e1a59eefef2093aefe5611f256fa6b64c4d7" +dependencies = [ + "base64-simd", + "bitvec", + "bytes-str", + "data-encoding", + "debugid", + "if_chain", + "rustc-hash 2.1.1", + "serde", + "serde_json", + "unicode-id-start", + "url", +] + +[[package]] +name = "swc_visit" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62fb71484b486c185e34d2172f0eabe7f4722742aad700f426a494bb2de232a2" +dependencies = [ + "either", + "new_debug_unreachable", +] + [[package]] name = "symphonia" version = "0.5.5" @@ -8146,6 +9920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", + "quote", "unicode-ident", ] @@ -8160,6 +9935,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-match" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "783c4140d7ed89f37116e865b49e5a9fdd28608b9071a9dd1e158b50fc0a31fc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -8217,6 +10003,26 @@ dependencies = [ "libc", ] +[[package]] +name = "sys_traits" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f74a2c95f72e36fa6bd04a40d15623a9904bab1cc2fa6c6135b09d774a65088" +dependencies = [ + "sys_traits_macros", +] + +[[package]] +name = "sys_traits_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "181f22127402abcf8ee5c83ccd5b408933fec36a6095cf82cda545634692657e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "sysctl" version = "0.6.0" @@ -8287,12 +10093,6 @@ dependencies = [ "libc", ] -[[package]] -name = "tag_ptr" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0e973b34477b7823833469eb0f5a3a60370fef7a453e02d751b59180d0a5a05" - [[package]] name = "tap" version = "1.0.1" @@ -8323,6 +10123,39 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "temporal_capi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a151e402c2bdb6a3a2a2f3f225eddaead2e7ce7dd5d3fa2090deb11b17aa4ed8" +dependencies = [ + "diplomat", + "diplomat-runtime", + "icu_calendar", + "icu_locale", + "num-traits", + "temporal_rs", + "timezone_provider", + "writeable", + "zoneinfo64", +] + +[[package]] +name = "temporal_rs" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88afde3bd75d2fc68d77a914bece426aa08aa7649ffd0cdd4a11c3d4d33474d1" +dependencies = [ + "core_maths", + "icu_calendar", + "icu_locale", + "ixdtf", + "num-traits", + "timezone_provider", + "tinystr", + "writeable", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -8407,6 +10240,15 @@ dependencies = [ "test-case-core", ] +[[package]] +name = "text_lines" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd5828de7deaa782e1dd713006ae96b3bee32d3279b79eb67ecf8072c059bcf" +dependencies = [ + "serde", +] + [[package]] name = "textwrap" version = "0.16.2" @@ -8514,10 +10356,7 @@ checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5" dependencies = [ "deranged", "itoa", - "js-sys", - "libc", "num-conv", - "num_threads", "powerfmt", "serde_core", "time-core", @@ -8540,6 +10379,18 @@ dependencies = [ "time-core", ] +[[package]] +name = "timezone_provider" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9ba0000e9e73862f3e7ca1ff159e2ddf915c9d8bb11e38a7874760f445d993" +dependencies = [ + "tinystr", + "zerotrie", + "zerovec", + "zoneinfo64", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -8583,7 +10434,7 @@ checksum = "a620b996116a59e184c2fa2dfd8251ea34a36d0a514758c6f966386bd2e03476" dependencies = [ "ahash", "aho-corasick", - "compact_str", + "compact_str 0.9.0", "dary_heap", "derive_builder", "esaxx-rs", @@ -8724,7 +10575,7 @@ dependencies = [ "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", - "toml_edit 0.22.27", + "toml_edit", ] [[package]] @@ -8772,18 +10623,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "toml_edit" -version = "0.23.10+spec-1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" -dependencies = [ - "indexmap 2.13.0", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "winnow", -] - [[package]] name = "toml_parser" version = "1.0.6+spec-1.1.0" @@ -8819,7 +10658,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "prost", + "prost 0.13.5", "socket2 0.5.10", "tokio", "tokio-stream", @@ -8829,6 +10668,46 @@ dependencies = [ "tracing", ] +[[package]] +name = "tonic" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a286e33f82f8a1ee2df63f4fa35c0becf4a85a0cb03091a15fd7bf0b402dc94a" +dependencies = [ + "async-trait", + "axum 0.8.8", + "base64 0.22.1", + "bytes", + "h2 0.4.13", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "socket2 0.6.2", + "sync_wrapper 1.0.2", + "tokio", + "tokio-stream", + "tower 0.5.3", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c55a2d6a14174563de34409c9f92ff981d006f56da9c6ecd40d9d4a31500b0" +dependencies = [ + "bytes", + "prost 0.14.3", + "tonic 0.14.3", +] + [[package]] name = "tower" version = "0.4.13" @@ -8857,9 +10736,12 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", + "indexmap 2.13.0", "pin-project-lite", + "slab", "sync_wrapper 1.0.2", "tokio", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -8971,8 +10853,8 @@ checksum = "97a971f6058498b5c0f1affa23e7ea202057a7301dbff68e968b2d578bcbd053" dependencies = [ "js-sys", "once_cell", - "opentelemetry", - "opentelemetry_sdk", + "opentelemetry 0.27.1", + "opentelemetry_sdk 0.27.1", "smallvec", "tracing", "tracing-core", @@ -9103,6 +10985,16 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "triomphe" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" +dependencies = [ + "serde", + "stable_deref_trait", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -9128,6 +11020,12 @@ dependencies = [ "utf-8", ] +[[package]] +name = "twox-hash" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7b17f197b3050ba473acf9181f7b1d3b66d1cf7356c6cc57886662276e65908" + [[package]] name = "typed-path" version = "0.12.2" @@ -9173,6 +11071,19 @@ dependencies = [ "yoke 0.7.5", ] +[[package]] +name = "ug-cuda" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f0a1fa748f26166778c33b8498255ebb7c6bffb472bcc0a72839e07ebb1d9b5" +dependencies = [ + "cudarc 0.17.8", + "half", + "serde", + "thiserror 1.0.69", + "ug", +] + [[package]] name = "ug-metal" version = "0.5.0" @@ -9240,6 +11151,18 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" +[[package]] +name = "unicode-bom" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" + +[[package]] +name = "unicode-id-start" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b79ad29b5e19de4260020f8919b443b2ef0277d242ce532ec7b7a2cc8b6007" + [[package]] name = "unicode-ident" version = "1.0.22" @@ -9349,12 +11272,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -9376,7 +11293,19 @@ dependencies = [ "indexmap 2.13.0", "serde", "serde_json", - "utoipa-gen", + "utoipa-gen 4.3.1", +] + +[[package]] +name = "utoipa" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" +dependencies = [ + "indexmap 2.13.0", + "serde", + "serde_json", + "utoipa-gen 5.4.0", ] [[package]] @@ -9392,6 +11321,17 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "utoipa-gen" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "uuid" version = "1.20.0" @@ -9415,6 +11355,23 @@ dependencies = [ "vsimd", ] +[[package]] +name = "v8" +version = "145.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61d9a107e16bae35a0be2bb0096ac1d2318aac352c82edd796ab2b9cac66d8f0" +dependencies = [ + "bindgen 0.72.1", + "bitflags 2.10.0", + "fslock", + "gzip-header", + "home", + "miniz_oxide", + "paste", + "temporal_capi", + "which 6.0.3", +] + [[package]] name = "v_htmlescape" version = "0.15.8" @@ -9557,6 +11514,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasm_dep_analyzer" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a10e6b67c951a84de7029487e0e0a496860dae49f6699edd279d5ff35b8fbf54" +dependencies = [ + "deno_error", + "thiserror 2.0.18", +] + [[package]] name = "web-sys" version = "0.3.85" @@ -9601,9 +11568,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" dependencies = [ "rustls-pki-types", ] @@ -9626,6 +11593,18 @@ dependencies = [ "rustix 0.38.44", ] +[[package]] +name = "which" +version = "6.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" +dependencies = [ + "either", + "home", + "rustix 0.38.44", + "winsafe", +] + [[package]] name = "which" version = "8.0.0" @@ -10330,18 +12309,21 @@ version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "xattr" version = "1.6.1" @@ -10402,12 +12384,6 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" -[[package]] -name = "xsum" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0637d3a5566a82fa5214bae89087bc8c9fb94cd8e8a3c07feb691bb8d9c632db" - [[package]] name = "xterm-color" version = "1.0.2" @@ -10434,6 +12410,12 @@ dependencies = [ "hashlink 0.10.0", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yoke" version = "0.7.5" @@ -10483,18 +12465,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.37" +version = "0.8.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7456cf00f0685ad319c5b1693f291a650eaf345e941d082fc4e03df8a03996ac" +checksum = "57cf3aa6855b23711ee9852dfc97dfaa51c45feaba5b645d0c777414d494a961" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.37" +version = "0.8.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1328722bbf2115db7e19d69ebcc15e795719e2d66b60827c6a69a117365e37a0" +checksum = "8a616990af1a287837c4fe6596ad77ef57948f787e46ce28e166facc0cc1cb75" dependencies = [ "proc-macro2", "quote", @@ -10631,6 +12613,19 @@ version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" +[[package]] +name = "zoneinfo64" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2e5597efbe7c421da8a7fd396b20b571704e787c21a272eecf35dfe9d386f0" +dependencies = [ + "calendrical_calculations", + "icu_locale_core", + "potential_utf", + "resb", + "serde", +] + [[package]] name = "zopfli" version = "0.8.3" diff --git a/Cargo.toml b/Cargo.toml index 6ee2d01e6f..881cbf0139 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ resolver = "2" [workspace.package] edition = "2021" -version = "1.22.0" +version = "1.23.0" authors = ["Block "] license = "Apache-2.0" repository = "https://github.com/block/goose" @@ -36,3 +36,7 @@ reqwest = { version = "0.12.28", default-features = false, features = ["multipar tower = "0.5.2" tower-http = "0.6.8" url = "2.5.8" + +[profile.release] +codegen-units = 1 +lto = true diff --git a/crates/goose-acp/tests/common_tests/mod.rs b/crates/goose-acp/tests/common_tests/mod.rs index 2917e22d1b..73e1122695 100644 --- a/crates/goose-acp/tests/common_tests/mod.rs +++ b/crates/goose-acp/tests/common_tests/mod.rs @@ -72,7 +72,7 @@ pub async fn run_mcp_http_server() { pub async fn run_builtin_and_mcp() { let expected_session_id = ExpectedSessionId::default(); let prompt = - "Search for get_code and text_editor tools. Use them to save the code to /tmp/result.txt."; + "Search for getCode and textEditor tools. Use them to save the code to /tmp/result.txt."; let mcp = McpFixture::new(expected_session_id.clone()).await; let openai = OpenAiFixture::new( vec![ @@ -81,15 +81,11 @@ pub async fn run_builtin_and_mcp() { include_str!("../test_data/openai_builtin_search.txt"), ), ( - r#"lookup/get_code: Get the code"#.into(), - include_str!("../test_data/openai_builtin_read_modules.txt"), - ), - ( - r#"lookup[\"get_code\"]({}): string - Get the code"#.into(), + r#"export async function getCode"#.into(), include_str!("../test_data/openai_builtin_execute.txt"), ), ( - r#"Successfully wrote to /tmp/result.txt"#.into(), + r#""writeResult": "Successfully wrote to /tmp/result.txt"#.into(), include_str!("../test_data/openai_builtin_final.txt"), ), ], diff --git a/crates/goose-acp/tests/test_data/openai_builtin_execute.txt b/crates/goose-acp/tests/test_data/openai_builtin_execute.txt index 49d8b4992c..1e1eefda5f 100644 --- a/crates/goose-acp/tests/test_data/openai_builtin_execute.txt +++ b/crates/goose-acp/tests/test_data/openai_builtin_execute.txt @@ -1,227 +1,435 @@ -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_hcC9QZSyxfjpHmJdtEWe18ay","type":"function","function":{"name":"code_execution__execute_code","arguments":""}}],"refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"b19o47w5ougEAzn"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_UBLtxrNOFHnLNHCInjjeVLzP","type":"function","function":{"name":"code_execution__execute","arguments":""}}],"refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"WDLD"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"rdSrkQ1Cz6"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"yJBJJfdldX"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Osxenpc4x"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"EYtPIkyWy"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"DTBcfoOJ"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"kLCKi4W0"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"import"}}]},"finish_reason":null}],"usage":null,"obfuscation":"sqbC9nK"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"async"}}]},"finish_reason":null}],"usage":null,"obfuscation":"0pB1gVsj"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" {"}}]},"finish_reason":null}],"usage":null,"obfuscation":"7A3BEIL77xh"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" function"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Quyw"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"AsczaKDd7"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" run"}}]},"finish_reason":null}],"usage":null,"obfuscation":"C47A3bchK"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"UjJwIZXo"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"()"}}]},"finish_reason":null}],"usage":null,"obfuscation":"GnzOrhzYZew"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" }"}}]},"finish_reason":null}],"usage":null,"obfuscation":"spOTdMkMdlp"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" {\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"sMmX7plrr"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" from"}}]},"finish_reason":null}],"usage":null,"obfuscation":"n2UHITYZ"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"wqLsTgMRSxtN"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" \\\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"am1f6FmN"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"5MHvUdIfJ0qJ"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"lookup"}}]},"finish_reason":null}],"usage":null,"obfuscation":"7smqbS0"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" console"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Uv1zV"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"punuQk0H6"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".log"}}]},"finish_reason":null}],"usage":null,"obfuscation":"JAPWfZ8vW"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":";\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"0MlZhMM3Wb"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"(\\\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"r2howfHn"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"qNe4Y7heibZN"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Fetching"}}]},"finish_reason":null}],"usage":null,"obfuscation":"3uEtb"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"import"}}]},"finish_reason":null}],"usage":null,"obfuscation":"jAg7bgI"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"73EB8Vfy"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" {"}}]},"finish_reason":null}],"usage":null,"obfuscation":"7GtakYXk4U1"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" using"}}]},"finish_reason":null}],"usage":null,"obfuscation":"bj5YgoP"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" text"}}]},"finish_reason":null}],"usage":null,"obfuscation":"iABvoSVl"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"a0nSxyCLV"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_editor"}}]},"finish_reason":null}],"usage":null,"obfuscation":"WGyvWz"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"sE6BzCdcA"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" }"}}]},"finish_reason":null}],"usage":null,"obfuscation":"kXeb0jURGpD"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"...\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"piPx4wDk"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" from"}}]},"finish_reason":null}],"usage":null,"obfuscation":"daxDWT2G"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\");"}}]},"finish_reason":null}],"usage":null,"obfuscation":"8dYsX5mrP"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" \\\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"p1uq4MMs"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"5VbIZPEA6ix"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"developer"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ZZJ0"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"01RMMD23GQkr"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"2pjhI3CHm"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"Ig3VtqefZFcI"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":";\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"BGPB0Y92qx"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" const"}}]},"finish_reason":null}],"usage":null,"obfuscation":"227PgWF"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"sPtg1aux9Q7t"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zYLjrdtw"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"uzSwsf36Eq"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"85j33BB"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"const"}}]},"finish_reason":null}],"usage":null,"obfuscation":"q36eyCe4"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ="}}]},"finish_reason":null}],"usage":null,"obfuscation":"m9B1dsMaGtk"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Yv253z8V"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" await"}}]},"finish_reason":null}],"usage":null,"obfuscation":"y1QKhVE"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Content"}}]},"finish_reason":null}],"usage":null,"obfuscation":"dbtiH2"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Lookup"}}]},"finish_reason":null}],"usage":null,"obfuscation":"tyu2C3"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ="}}]},"finish_reason":null}],"usage":null,"obfuscation":"V0BBzDO4BnO"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"mSnyOOHWO"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"eV7Z0MBJk"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zKEttDzEa"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"qODA1iJ3"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"({"}}]},"finish_reason":null}],"usage":null,"obfuscation":"KevY7aP3ryh"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"({"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ZLHVDfQXZIT"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"});"}}]},"finish_reason":null}],"usage":null,"obfuscation":"EgG4bzRSW8"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"});"}}]},"finish_reason":null}],"usage":null,"obfuscation":"xkfrxJ0vqN"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"x0sZLH8SbhL"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Ri1sVVmThdE"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"IHuyUXshht2C"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"EaMfvD5zX3O4"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"zv2aVS40gP6A"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"const"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Ktj0iLMG"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" let"}}]},"finish_reason":null}],"usage":null,"obfuscation":"q2RPbnzIm"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"BuVITia"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"RpPYIgMc"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Res"}}]},"finish_reason":null}],"usage":null,"obfuscation":"b9iRJbneyy"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ="}}]},"finish_reason":null}],"usage":null,"obfuscation":"hthkNEp3btP"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ="}}]},"finish_reason":null}],"usage":null,"obfuscation":"gCMQmiR8LDN"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ''"}}]},"finish_reason":null}],"usage":null,"obfuscation":"czifZEqaPz"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" text"}}]},"finish_reason":null}],"usage":null,"obfuscation":"WywYQ1Wq"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":";\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Z94iEsTOFM"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_editor"}}]},"finish_reason":null}],"usage":null,"obfuscation":"APkX6z"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"YmsDuM4CGmAm"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"({"}}]},"finish_reason":null}],"usage":null,"obfuscation":"O04vBMryw3h"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"F9VDjITdevyZ"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" command"}}]},"finish_reason":null}],"usage":null,"obfuscation":"5jIuc"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" if"}}]},"finish_reason":null}],"usage":null,"obfuscation":"3mTNWX7Ccs"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":"}}]},"finish_reason":null}],"usage":null,"obfuscation":"WmdqnCOKVLwM"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ("}}]},"finish_reason":null}],"usage":null,"obfuscation":"VPSM2U9ztaj"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" \\\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"tV8pBGp7"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"typeof"}}]},"finish_reason":null}],"usage":null,"obfuscation":"EjlBDWl"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"rdlyfaq1"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"waNmvkMf"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\\","}}]},"finish_reason":null}],"usage":null,"obfuscation":"SxWxNrDR"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"MtFriQX"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" path"}}]},"finish_reason":null}],"usage":null,"obfuscation":"PeHPMaR6"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ==="}}]},"finish_reason":null}],"usage":null,"obfuscation":"6lERzMmdv"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":"}}]},"finish_reason":null}],"usage":null,"obfuscation":"d0y267V7PORM"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" '"}}]},"finish_reason":null}],"usage":null,"obfuscation":"tFFzpFq7XNp"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" \\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ywEAhNkA9w"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"string"}}]},"finish_reason":null}],"usage":null,"obfuscation":"R3I84RZ"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"/"}}]},"finish_reason":null}],"usage":null,"obfuscation":"m9RiqrrR4d"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"')"}}]},"finish_reason":null}],"usage":null,"obfuscation":"BSnvZ4pAb76"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tmp"}}]},"finish_reason":null}],"usage":null,"obfuscation":"KdkE9OEMbk"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" {\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"cvK3wmQAp"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"/result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"wdawSE"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"9U4NG1zW1hpA"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".txt"}}]},"finish_reason":null}],"usage":null,"obfuscation":"oz5CFKhsF"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"TMZWFdPIGt"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\\","}}]},"finish_reason":null}],"usage":null,"obfuscation":"FLJEYU3Z"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"J6lbPQxv"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" file"}}]},"finish_reason":null}],"usage":null,"obfuscation":"jV9qDKjG"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ="}}]},"finish_reason":null}],"usage":null,"obfuscation":"qRU6bhPit7h"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_text"}}]},"finish_reason":null}],"usage":null,"obfuscation":"UtOfNMdx"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"IouQzhkX"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":"}}]},"finish_reason":null}],"usage":null,"obfuscation":"aQLvI4PhcN71"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"cyJEbKZ"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"cRS5SnPZ"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":";\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"d0mgOWJ4BI"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Content"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ymts0B"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"DT5fUSwF4rag"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" });"}}]},"finish_reason":null}],"usage":null,"obfuscation":"HIKXwLPsU"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"qxuu5io6tf3v"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"IyYG9VM0ay9"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" }"}}]},"finish_reason":null}],"usage":null,"obfuscation":"uivHQEB1MHf"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"FcZzRbewbWzs"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" else"}}]},"finish_reason":null}],"usage":null,"obfuscation":"mXjbTfS9"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"record_result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"yJ0heSJY"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" if"}}]},"finish_reason":null}],"usage":null,"obfuscation":"X6y8tpzr6O"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"(writeRes)"}}]},"finish_reason":null}],"usage":null,"obfuscation":"VCJyV87lb5"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ("}}]},"finish_reason":null}],"usage":null,"obfuscation":"Y1nBNR2nfBu"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\\n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"LniNHGfSN9"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"t6taDGZWE"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"KrXbglgQ"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"S4uVyIz"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tool"}}]},"finish_reason":null}],"usage":null,"obfuscation":"KoY7VbKmk"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" &&"}}]},"finish_reason":null}],"usage":null,"obfuscation":"sf0ZWdiu4N"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_graph"}}]},"finish_reason":null}],"usage":null,"obfuscation":"stocohw"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" typeof"}}]},"finish_reason":null}],"usage":null,"obfuscation":"TpYZWc"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":["}}]},"finish_reason":null}],"usage":null,"obfuscation":"GVtr3ESEB"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zbilqttA"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"Lickb1U7Hl"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zqGeQHW"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tool"}}]},"finish_reason":null}],"usage":null,"obfuscation":"okyVlrEIz"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ==="}}]},"finish_reason":null}],"usage":null,"obfuscation":"F8hxhZoBg"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"eOvg0xdJ"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" '"}}]},"finish_reason":null}],"usage":null,"obfuscation":"0QWhjOXxfMI"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"lookup"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ioz46mm"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"object"}}]},"finish_reason":null}],"usage":null,"obfuscation":"TkPlD4R"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"/get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"lqkgCSvsu"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"')"}}]},"finish_reason":null}],"usage":null,"obfuscation":"NR4MUn0RRS4"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"JhuyiKVe"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" {\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"saoY11LYc"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"Q3aHiaKq"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"eh3OiAfwS3Jl"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"description"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Ck"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"g5iOHn9zDZ"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"AEyKl8NF"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"8W6TSAMM"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"lJJbh0p7Dg"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ="}}]},"finish_reason":null}],"usage":null,"obfuscation":"VRzyVssdYN3"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" the"}}]},"finish_reason":null}],"usage":null,"obfuscation":"uFXa4PzBq"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Aql9R8g6"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"fxpxTVDG"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"N1FHNi9"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"ajR2a1Ju"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"sYqbc9to"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"depends"}}]},"finish_reason":null}],"usage":null,"obfuscation":"qNa3u6"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ??"}}]},"finish_reason":null}],"usage":null,"obfuscation":"hGQnicL3wo"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_on"}}]},"finish_reason":null}],"usage":null,"obfuscation":"PfZBUzLwEU"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"g4KW2tFJ"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":[]"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Kpm5Dl6W"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ifEWkT9"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"},{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"L8cOSVuZ"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".content"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Qsv00"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tool"}}]},"finish_reason":null}],"usage":null,"obfuscation":"KAZ6a6RFX"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ??"}}]},"finish_reason":null}],"usage":null,"obfuscation":"eThY8OKgQM"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"bJFlPCmV"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ''"}}]},"finish_reason":null}],"usage":null,"obfuscation":"0x03TQmZKV"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"developer"}}]},"finish_reason":null}],"usage":null,"obfuscation":"KE9I"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":";\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"vX8rRtILap"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"/text"}}]},"finish_reason":null}],"usage":null,"obfuscation":"BMnv2YIo"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zAqdH8JPBibe"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_editor"}}]},"finish_reason":null}],"usage":null,"obfuscation":"HH3wHg"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"ov9HisKNyUac"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"1BSk9J00"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" }\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"I4APrZWxY"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"description"}}]},"finish_reason":null}],"usage":null,"obfuscation":"y0"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"5ImlnX0Dttf5"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"j0kTAnXy"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"YXKxHGHDxIMx"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"9IGJB175"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" console"}}]},"finish_reason":null}],"usage":null,"obfuscation":"4czSy"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"qc9bKCEs"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".log"}}]},"finish_reason":null}],"usage":null,"obfuscation":"BzoIKE2IQ"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" to"}}]},"finish_reason":null}],"usage":null,"obfuscation":"a0mpsleQne"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"(\\\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"RFDi14O6"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" /"}}]},"finish_reason":null}],"usage":null,"obfuscation":"qu1SPcDdrND"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"kBQ5JuRLo"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tmp"}}]},"finish_reason":null}],"usage":null,"obfuscation":"iL5qu5xkSZ"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" length"}}]},"finish_reason":null}],"usage":null,"obfuscation":"uLKt9b"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"/result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Pw9vab"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"AernamVDYj"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".txt"}}]},"finish_reason":null}],"usage":null,"obfuscation":"4s3fq3kik"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\","}}]},"finish_reason":null}],"usage":null,"obfuscation":"W2G1ODBPI7"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"WBE2nHWv"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ClK2v6Co"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"depends"}}]},"finish_reason":null}],"usage":null,"obfuscation":"SndKuC"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".length"}}]},"finish_reason":null}],"usage":null,"obfuscation":"5QREcu"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_on"}}]},"finish_reason":null}],"usage":null,"obfuscation":"bqH02zHaqe"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":");\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"vYkJXePbp"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":["}}]},"finish_reason":null}],"usage":null,"obfuscation":"JQbX8vhhz"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"eYwcfwGza6SP"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"0"}}]},"finish_reason":null}],"usage":null,"obfuscation":"dZPvLddnRhi4"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"WD8XfCubj9Fi"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"]}"}}]},"finish_reason":null}],"usage":null,"obfuscation":"H6ruWXUkroP"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" const"}}]},"finish_reason":null}],"usage":null,"obfuscation":"GRx06ti"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"]}"}}]},"finish_reason":null}],"usage":null,"obfuscation":"oo1NmN82Wer"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"GARHMD7"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"KHl52jcbk6U"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Input"}}]},"finish_reason":null}],"usage":null,"obfuscation":"0ViQAnum"} -data: {"id":"chatcmpl-Cqnxk0p34ZkYNestA1fcahFGuLiRR","object":"chat.completion.chunk","created":1766701148,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":2823,"completion_tokens":1347,"total_tokens":4170,"prompt_tokens_details":{"cached_tokens":2176,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":1216,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"iENdGioMW9"} +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ="}}]},"finish_reason":null}],"usage":null,"obfuscation":"pH7owHzrw2r"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" {"}}]},"finish_reason":null}],"usage":null,"obfuscation":"g1NLPYzOctR"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" path"}}]},"finish_reason":null}],"usage":null,"obfuscation":"D8RncX3Y"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":"}}]},"finish_reason":null}],"usage":null,"obfuscation":"9WvQILV05SIi"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" '/"}}]},"finish_reason":null}],"usage":null,"obfuscation":"HqB41Bt0gL"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tmp"}}]},"finish_reason":null}],"usage":null,"obfuscation":"vDKGLeU1TF"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"/result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"3AdXIE"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".txt"}}]},"finish_reason":null}],"usage":null,"obfuscation":"uRa25ZT1p"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"',"}}]},"finish_reason":null}],"usage":null,"obfuscation":"vSHWogAiBbD"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" command"}}]},"finish_reason":null}],"usage":null,"obfuscation":"rZzDM"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":"}}]},"finish_reason":null}],"usage":null,"obfuscation":"pSUTKKwDCn8p"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" '"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Qjt96EnsRAm"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"09rNMlnR"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"',"}}]},"finish_reason":null}],"usage":null,"obfuscation":"itKwh0SX1ga"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" file"}}]},"finish_reason":null}],"usage":null,"obfuscation":"du3kCfTn"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_text"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ngVnMudT"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ybJSbaU82SiV"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"FRFx9RKj"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" }"}}]},"finish_reason":null}],"usage":null,"obfuscation":"LoFsPXu5IT5"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":";\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"K1VJOHAdow"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"79UQqyjivA2x"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"Wdhzy4D1tN5x"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" const"}}]},"finish_reason":null}],"usage":null,"obfuscation":"MMQBCgU"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"GXQxXyP"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"aHn6RNH"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" ="}}]},"finish_reason":null}],"usage":null,"obfuscation":"JhpeUQraTS4"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" await"}}]},"finish_reason":null}],"usage":null,"obfuscation":"QsGqq3h"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" Developer"}}]},"finish_reason":null}],"usage":null,"obfuscation":"nFR"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".text"}}]},"finish_reason":null}],"usage":null,"obfuscation":"k75EY8l0"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Editor"}}]},"finish_reason":null}],"usage":null,"obfuscation":"yfopeoz"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"(write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"NUMmKyB"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Input"}}]},"finish_reason":null}],"usage":null,"obfuscation":"tlqNVNVr"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":");\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"R9nTDEH8s"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"NfNK8HdqJSKv"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" "}}]},"finish_reason":null}],"usage":null,"obfuscation":"QVPXEN5xQ1Ze"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" return"}}]},"finish_reason":null}],"usage":null,"obfuscation":"7MTQ6U"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" {"}}]},"finish_reason":null}],"usage":null,"obfuscation":"K2FMAiCIujD"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"EE9Ru0tD"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Length"}}]},"finish_reason":null}],"usage":null,"obfuscation":"0SZhPwa"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":"}}]},"finish_reason":null}],"usage":null,"obfuscation":"IlyrcjFrNtf1"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"nIffRVq6"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".length"}}]},"finish_reason":null}],"usage":null,"obfuscation":"MJrhKV"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]},"finish_reason":null}],"usage":null,"obfuscation":"b0bPSjPStgSB"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"jZ1s48d"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"FnJBVR0"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":","}}]},"finish_reason":null}],"usage":null,"obfuscation":"sGoSb5moV3lU"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" path"}}]},"finish_reason":null}],"usage":null,"obfuscation":"lEDGAUW7"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":":"}}]},"finish_reason":null}],"usage":null,"obfuscation":"L33XZS2eVjP8"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" '/"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Mc6352ovqh"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tmp"}}]},"finish_reason":null}],"usage":null,"obfuscation":"WVf7tUa4MO"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"/result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"dgLoNl"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".txt"}}]},"finish_reason":null}],"usage":null,"obfuscation":"peo3oJpMf"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"'"}}]},"finish_reason":null}],"usage":null,"obfuscation":"CUBYBaa76JLc"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" }"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Mn0H2SyFIfj"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":";\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"auORHaAgoa"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"OUGiUCfKmJSM"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"}\\"}}]},"finish_reason":null}],"usage":null,"obfuscation":"dF6Q4oq7L7"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zkI9TnUUs3ch"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"2GBDJdx9"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tool"}}]},"finish_reason":null}],"usage":null,"obfuscation":"IR9AsAJLS"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_graph"}}]},"finish_reason":null}],"usage":null,"obfuscation":"LZdBnmQ"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":["}}]},"finish_reason":null}],"usage":null,"obfuscation":"LrdA4JMPl"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"hoFr6PdSxy"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tool"}}]},"finish_reason":null}],"usage":null,"obfuscation":"09voS71xG"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"OnQsbjgO"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Lookup"}}]},"finish_reason":null}],"usage":null,"obfuscation":"txA3kTV"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"bBPWLAWjf"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"MN2cF3bAO"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"4J9xpizI"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"description"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zF"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"cwNVXSPt"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"lVybj8jkPg"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"j9AE0p2w"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" to"}}]},"finish_reason":null}],"usage":null,"obfuscation":"PsKLkrCQru"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" save"}}]},"finish_reason":null}],"usage":null,"obfuscation":"LaBz90vK"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"ZM1ykOP4"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"depends"}}]},"finish_reason":null}],"usage":null,"obfuscation":"1EQhvi"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_on"}}]},"finish_reason":null}],"usage":null,"obfuscation":"dfaEmUGSEN"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":[]"}}]},"finish_reason":null}],"usage":null,"obfuscation":"z5Aw0q4K"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"},{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"41s45OYD"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tool"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zL7J4Y5rW"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"96Kod7bM"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Developer"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Qnr0"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".text"}}]},"finish_reason":null}],"usage":null,"obfuscation":"J3Fq0V0e"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Editor"}}]},"finish_reason":null}],"usage":null,"obfuscation":"7OJJNS2"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"p0Um8MwA"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"description"}}]},"finish_reason":null}],"usage":null,"obfuscation":"ZR"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"wIKGLRH8"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"Write"}}]},"finish_reason":null}],"usage":null,"obfuscation":"zbApOiBy"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"M1PXb440"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" to"}}]},"finish_reason":null}],"usage":null,"obfuscation":"En0BC1zcqo"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" /"}}]},"finish_reason":null}],"usage":null,"obfuscation":"5VoEIKXk92K"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tmp"}}]},"finish_reason":null}],"usage":null,"obfuscation":"6WSWQwr75c"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"/result"}}]},"finish_reason":null}],"usage":null,"obfuscation":"z0OIp4"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":".txt"}}]},"finish_reason":null}],"usage":null,"obfuscation":"yiZKDyLLD"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"wQnmcE1I"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"depends"}}]},"finish_reason":null}],"usage":null,"obfuscation":"Im97QG"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_on"}}]},"finish_reason":null}],"usage":null,"obfuscation":"YX0ERDmjVw"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":["}}]},"finish_reason":null}],"usage":null,"obfuscation":"bmrLkX68c"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"0"}}]},"finish_reason":null}],"usage":null,"obfuscation":"E6kFZ2NkKqDW"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"]}"}}]},"finish_reason":null}],"usage":null,"obfuscation":"GpL2fucX06l"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"]}"}}]},"finish_reason":null}],"usage":null,"obfuscation":"QcijSKPB34X"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"38W18dvZIF7"} + +data: {"id":"chatcmpl-D52mhi3yQh0ZVyJeuHwBBdtr5PZ2L","object":"chat.completion.chunk","created":1770094715,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":5612,"completion_tokens":1193,"total_tokens":6805,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":960,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Ikcn1RF9DqIck8"} data: [DONE] + + diff --git a/crates/goose-acp/tests/test_data/openai_builtin_final.txt b/crates/goose-acp/tests/test_data/openai_builtin_final.txt index 1551dbee37..d3f43dff24 100644 --- a/crates/goose-acp/tests/test_data/openai_builtin_final.txt +++ b/crates/goose-acp/tests/test_data/openai_builtin_final.txt @@ -1,173 +1,355 @@ -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"O7AAt"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"DBl2H"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"I've"},"finish_reason":null}],"usage":null,"obfuscation":"cVL"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"##"},"finish_reason":null}],"usage":null,"obfuscation":"QftPU"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" retrieved"},"finish_reason":null}],"usage":null,"obfuscation":"F0LyC2nMxaBxl"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Operation"},"finish_reason":null}],"usage":null,"obfuscation":"J5Sw3zVEkPvfW"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"D0e"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" completed"},"finish_reason":null}],"usage":null,"obfuscation":"1ueJsqoOUutou"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" code"},"finish_reason":null}],"usage":null,"obfuscation":"Fa"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n\n"},"finish_reason":null}],"usage":null,"obfuscation":"4IS"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" and"},"finish_reason":null}],"usage":null,"obfuscation":"SVR"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"I"},"finish_reason":null}],"usage":null,"obfuscation":"sZdBrx"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" saved"},"finish_reason":null}],"usage":null,"obfuscation":"Z"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" followed"},"finish_reason":null}],"usage":null,"obfuscation":"XdPAY5Vz3cjYwj"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" it"},"finish_reason":null}],"usage":null,"obfuscation":"1wEo"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" your"},"finish_reason":null}],"usage":null,"obfuscation":"PI"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"DXcu"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" instruction"},"finish_reason":null}],"usage":null,"obfuscation":"UH9S7jMuejM"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" /"},"finish_reason":null}],"usage":null,"obfuscation":"FaGyP"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"QWA3"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"tmp"},"finish_reason":null}],"usage":null,"obfuscation":"GZ4i"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" batch"},"finish_reason":null}],"usage":null,"obfuscation":"m"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"/result"},"finish_reason":null}],"usage":null,"obfuscation":""} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" get"},"finish_reason":null}],"usage":null,"obfuscation":"RzC"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".txt"},"finish_reason":null}],"usage":null,"obfuscation":"ph6"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Code"},"finish_reason":null}],"usage":null,"obfuscation":"hR9"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".\n\n"},"finish_reason":null}],"usage":null,"obfuscation":"tu"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" and"},"finish_reason":null}],"usage":null,"obfuscation":"LzV"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Details"},"finish_reason":null}],"usage":null,"obfuscation":""} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" text"},"finish_reason":null}],"usage":null,"obfuscation":"Rh"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":\n"},"finish_reason":null}],"usage":null,"obfuscation":"EvwW"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Editor"},"finish_reason":null}],"usage":null,"obfuscation":"T"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"4593mu"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" into"},"finish_reason":null}],"usage":null,"obfuscation":"Bw"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Retrieved"},"finish_reason":null}],"usage":null,"obfuscation":"VKOlyvL1zhIEw"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"finish_reason":null}],"usage":null,"obfuscation":"j39H7"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" code"},"finish_reason":null}],"usage":null,"obfuscation":"rc"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" single"},"finish_reason":null}],"usage":null,"obfuscation":""} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"finish_reason":null}],"usage":null,"obfuscation":"27XGKW"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" execute"},"finish_reason":null}],"usage":null,"obfuscation":"tzHiE8zaYekvXrP"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" via"},"finish_reason":null}],"usage":null,"obfuscation":"0di"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" call"},"finish_reason":null}],"usage":null,"obfuscation":"vw"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" lookup"},"finish_reason":null}],"usage":null,"obfuscation":""} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" and"},"finish_reason":null}],"usage":null,"obfuscation":"F7m"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"/get"},"finish_reason":null}],"usage":null,"obfuscation":"olP"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" saved"},"finish_reason":null}],"usage":null,"obfuscation":"H"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"_code"},"finish_reason":null}],"usage":null,"obfuscation":"Sa"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"KV0"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"finish_reason":null}],"usage":null,"obfuscation":"lsb3w"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" result"},"finish_reason":null}],"usage":null,"obfuscation":""} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"ognYvV"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"ifZo"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Saved"},"finish_reason":null}],"usage":null,"obfuscation":"W"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" /"},"finish_reason":null}],"usage":null,"obfuscation":"zvEML"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"hYDy"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"tmp"},"finish_reason":null}],"usage":null,"obfuscation":"m67x"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"finish_reason":null}],"usage":null,"obfuscation":"1jWh7T"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"/result"},"finish_reason":null}],"usage":null,"obfuscation":""} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" /"},"finish_reason":null}],"usage":null,"obfuscation":"ZlVNQ"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".txt"},"finish_reason":null}],"usage":null,"obfuscation":"z8K"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"tmp"},"finish_reason":null}],"usage":null,"obfuscation":"I7Jf"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".\n\n"},"finish_reason":null}],"usage":null,"obfuscation":"EP"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"/result"},"finish_reason":null}],"usage":null,"obfuscation":""} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"dDhAJx"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".txt"},"finish_reason":null}],"usage":null,"obfuscation":"sy2"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Path"},"finish_reason":null}],"usage":null,"obfuscation":"ti"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"finish_reason":null}],"usage":null,"obfuscation":"Q5DAw"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" written"},"finish_reason":null}],"usage":null,"obfuscation":"Fmz6IdQRRVrbcG3"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"UXGt7Q"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"finish_reason":null}],"usage":null,"obfuscation":"uAsSWL"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" File"},"finish_reason":null}],"usage":null,"obfuscation":"ca"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" /"},"finish_reason":null}],"usage":null,"obfuscation":"l25Gw"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" content"},"finish_reason":null}],"usage":null,"obfuscation":"HUApvDcMsMAuxrY"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"tmp"},"finish_reason":null}],"usage":null,"obfuscation":"eEjT"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ("},"finish_reason":null}],"usage":null,"obfuscation":"PU6QY"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"/result"},"finish_reason":null}],"usage":null,"obfuscation":""} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"excerpt"},"finish_reason":null}],"usage":null,"obfuscation":""} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".txt"},"finish_reason":null}],"usage":null,"obfuscation":"LoC"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"):\n"},"finish_reason":null}],"usage":null,"obfuscation":"YyY"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"finish_reason":null}],"usage":null,"obfuscation":"Ao85V"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"9CPGc5"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"YZVZ8Y"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ```\n"},"finish_reason":null}],"usage":null,"obfuscation":"N"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Code"},"finish_reason":null}],"usage":null,"obfuscation":"2M"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"7w1FAS"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" length"},"finish_reason":null}],"usage":null,"obfuscation":""} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"finish_reason":null}],"usage":null,"obfuscation":"4m"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" fetched"},"finish_reason":null}],"usage":null,"obfuscation":"wLn3x2DncUr9KZN"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"SRFQJN"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"finish_reason":null}],"usage":null,"obfuscation":"CwhQ2N"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"uuid"},"finish_reason":null}],"usage":null,"obfuscation":"DhC"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"jX7HKQ"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"dUQSSl"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"21"},"finish_reason":null}],"usage":null,"obfuscation":"v2Q3e"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"123"},"finish_reason":null}],"usage":null,"obfuscation":"O56B"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" characters"},"finish_reason":null}],"usage":null,"obfuscation":"rzLUIdvybCee"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"45"},"finish_reason":null}],"usage":null,"obfuscation":"7QbIj"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"finish_reason":null}],"usage":null,"obfuscation":"x3pWt"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"cZFPqS"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"FiaGDY"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"678"},"finish_reason":null}],"usage":null,"obfuscation":"ANzY"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Written"},"finish_reason":null}],"usage":null,"obfuscation":"Uv5i4hNfDvCKOKo"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"90"},"finish_reason":null}],"usage":null,"obfuscation":"d9Bgs"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" content"},"finish_reason":null}],"usage":null,"obfuscation":"IwipJnjOAgQbsM3"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n\n"},"finish_reason":null}],"usage":null,"obfuscation":"no1"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" in"},"finish_reason":null}],"usage":null,"obfuscation":"1xjY"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"PlkSe6"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"EtX"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ```\n"},"finish_reason":null}],"usage":null,"obfuscation":"P"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" file"},"finish_reason":null}],"usage":null,"obfuscation":"Ki"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"If"},"finish_reason":null}],"usage":null,"obfuscation":"qse2x"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":\n"},"finish_reason":null}],"usage":null,"obfuscation":"bsYW"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" you"},"finish_reason":null}],"usage":null,"obfuscation":"Fx3"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" "},"finish_reason":null}],"usage":null,"obfuscation":"HuTiM1"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" want"},"finish_reason":null}],"usage":null,"obfuscation":"jp"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" -"},"finish_reason":null}],"usage":null,"obfuscation":"Djq3E"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" me"},"finish_reason":null}],"usage":null,"obfuscation":"DeeA"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" The"},"finish_reason":null}],"usage":null,"obfuscation":"tKO"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"oKYZ"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" file"},"finish_reason":null}],"usage":null,"obfuscation":"08"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" view"},"finish_reason":null}],"usage":null,"obfuscation":"f1"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" contains"},"finish_reason":null}],"usage":null,"obfuscation":"3zNgk3SNozv6QX"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"Kay"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"finish_reason":null}],"usage":null,"obfuscation":"eIdHo"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" saved"},"finish_reason":null}],"usage":null,"obfuscation":"w"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" fenced"},"finish_reason":null}],"usage":null,"obfuscation":""} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" file"},"finish_reason":null}],"usage":null,"obfuscation":"nV"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" code"},"finish_reason":null}],"usage":null,"obfuscation":"Vz"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"U6ECJT"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" block"},"finish_reason":null}],"usage":null,"obfuscation":"Z"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" modify"},"finish_reason":null}],"usage":null,"obfuscation":""} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" with"},"finish_reason":null}],"usage":null,"obfuscation":"P9"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"2lX"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"wV6"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" content"},"finish_reason":null}],"usage":null,"obfuscation":"EWuNap9Z0N6SUaV"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" string"},"finish_reason":null}],"usage":null,"obfuscation":""} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"di1ZTP"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":\n"},"finish_reason":null}],"usage":null,"obfuscation":"ZiUL"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" or"},"finish_reason":null}],"usage":null,"obfuscation":"cHi4"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" \n"},"finish_reason":null}],"usage":null,"obfuscation":"Nas"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" save"},"finish_reason":null}],"usage":null,"obfuscation":"8Y"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"``"},"finish_reason":null}],"usage":null,"obfuscation":"P8Nhe"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"ill7"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"`\n"},"finish_reason":null}],"usage":null,"obfuscation":"yMUI"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"finish_reason":null}],"usage":null,"obfuscation":"WrWJM"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"test"},"finish_reason":null}],"usage":null,"obfuscation":"Wis"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" different"},"finish_reason":null}],"usage":null,"obfuscation":"M3jGyb9FytIMe"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"yZQWve"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" path"},"finish_reason":null}],"usage":null,"obfuscation":"3a"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"uuid"},"finish_reason":null}],"usage":null,"obfuscation":"pTW"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"PAdG3e"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"ZjldwU"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" tell"},"finish_reason":null}],"usage":null,"obfuscation":"Z6"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"123"},"finish_reason":null}],"usage":null,"obfuscation":"lCI7"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" me"},"finish_reason":null}],"usage":null,"obfuscation":"TWlE"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"45"},"finish_reason":null}],"usage":null,"obfuscation":"mfWAg"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" what"},"finish_reason":null}],"usage":null,"obfuscation":"IS"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"5vmLQg"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" you"},"finish_reason":null}],"usage":null,"obfuscation":"xrI"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"678"},"finish_reason":null}],"usage":null,"obfuscation":"g43k"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"’d"},"finish_reason":null}],"usage":null,"obfuscation":"nYYvw"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"90"},"finish_reason":null}],"usage":null,"obfuscation":"X2qMT"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" like"},"finish_reason":null}],"usage":null,"obfuscation":"ss"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n\n"},"finish_reason":null}],"usage":null,"obfuscation":"kgT"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" next"},"finish_reason":null}],"usage":null,"obfuscation":"Ko"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"``"},"finish_reason":null}],"usage":null,"obfuscation":"IENwg"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"finish_reason":null}],"usage":null,"obfuscation":"yM8hiD"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"`\n\n"},"finish_reason":null}],"usage":null,"obfuscation":"4U"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"x"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Notes"},"finish_reason":null}],"usage":null,"obfuscation":"mb"} -data: {"id":"chatcmpl-CqnxsizuiyMRFitx0QgzLwSExvKmX","object":"chat.completion.chunk","created":1766701156,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":2997,"completion_tokens":86,"total_tokens":3083,"prompt_tokens_details":{"cached_tokens":2432,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"z42f4eInXrYh3SS"} +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":\n"},"finish_reason":null}],"usage":null,"obfuscation":"eWI4"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"vNyV5I"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" The"},"finish_reason":null}],"usage":null,"obfuscation":"nXZ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" content"},"finish_reason":null}],"usage":null,"obfuscation":"10M7xKE1b67hafu"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" written"},"finish_reason":null}],"usage":null,"obfuscation":"cuhhj4CeigD1UgE"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"0IQ6"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"ZoQ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" file"},"finish_reason":null}],"usage":null,"obfuscation":"bs"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" was"},"finish_reason":null}],"usage":null,"obfuscation":"wS5"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" exactly"},"finish_reason":null}],"usage":null,"obfuscation":"sMx2WDna3NDQYwZ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"0hb"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" string"},"finish_reason":null}],"usage":null,"obfuscation":""} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" returned"},"finish_reason":null}],"usage":null,"obfuscation":"BEj8YwjVinkJVB"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" by"},"finish_reason":null}],"usage":null,"obfuscation":"3Dsy"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" get"},"finish_reason":null}],"usage":null,"obfuscation":"gtf"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Code"},"finish_reason":null}],"usage":null,"obfuscation":"WED"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" ("},"finish_reason":null}],"usage":null,"obfuscation":"bNdxf"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"21"},"finish_reason":null}],"usage":null,"obfuscation":"1CR1E"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" chars"},"finish_reason":null}],"usage":null,"obfuscation":"w"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"),"},"finish_reason":null}],"usage":null,"obfuscation":"W8r0d"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" wrapped"},"finish_reason":null}],"usage":null,"obfuscation":"aHhICEmcTUnhmMq"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" in"},"finish_reason":null}],"usage":null,"obfuscation":"rSUh"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"finish_reason":null}],"usage":null,"obfuscation":"OtFXr"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" markdown"},"finish_reason":null}],"usage":null,"obfuscation":"B7UAyjBDFJr4y2"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" code"},"finish_reason":null}],"usage":null,"obfuscation":"Av"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" block"},"finish_reason":null}],"usage":null,"obfuscation":"p"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" by"},"finish_reason":null}],"usage":null,"obfuscation":"YA3y"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"zD5"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" editor"},"finish_reason":null}],"usage":null,"obfuscation":""} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" output"},"finish_reason":null}],"usage":null,"obfuscation":""} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".\n\n"},"finish_reason":null}],"usage":null,"obfuscation":"A1"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"If"},"finish_reason":null}],"usage":null,"obfuscation":"RAGoS"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" you"},"finish_reason":null}],"usage":null,"obfuscation":"Raw"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"’d"},"finish_reason":null}],"usage":null,"obfuscation":"9RwEx"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" like"},"finish_reason":null}],"usage":null,"obfuscation":"yz"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"finish_reason":null}],"usage":null,"obfuscation":"kDeUAF"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" I"},"finish_reason":null}],"usage":null,"obfuscation":"BLTGS"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" can"},"finish_reason":null}],"usage":null,"obfuscation":"tYP"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":\n"},"finish_reason":null}],"usage":null,"obfuscation":"A5Jv"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"vxcFhK"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Verify"},"finish_reason":null}],"usage":null,"obfuscation":""} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"qQC"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" file"},"finish_reason":null}],"usage":null,"obfuscation":"Pz"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" contents"},"finish_reason":null}],"usage":null,"obfuscation":"AggSHo905WFTWo"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" by"},"finish_reason":null}],"usage":null,"obfuscation":"BpXh"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" reading"},"finish_reason":null}],"usage":null,"obfuscation":"7BlAGfq2LLaX94N"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" /"},"finish_reason":null}],"usage":null,"obfuscation":"4LzeE"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"tmp"},"finish_reason":null}],"usage":null,"obfuscation":"MczH"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"/result"},"finish_reason":null}],"usage":null,"obfuscation":""} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".txt"},"finish_reason":null}],"usage":null,"obfuscation":"KdZ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"finish_reason":null}],"usage":null,"obfuscation":"HtPvQ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"EbFCqJ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" View"},"finish_reason":null}],"usage":null,"obfuscation":"OV"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"tLL"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" raw"},"finish_reason":null}],"usage":null,"obfuscation":"ZqV"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" content"},"finish_reason":null}],"usage":null,"obfuscation":"bh4g1ZuIXjzIVon"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" without"},"finish_reason":null}],"usage":null,"obfuscation":"KqotEsJnw7202zj"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"AU4"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" code"},"finish_reason":null}],"usage":null,"obfuscation":"pw"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" block"},"finish_reason":null}],"usage":null,"obfuscation":"J"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" wrapper"},"finish_reason":null}],"usage":null,"obfuscation":"1sIrx9kpy3y1Qmp"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"finish_reason":null}],"usage":null,"obfuscation":"ns5tM"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"-"},"finish_reason":null}],"usage":null,"obfuscation":"3UgsGR"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" Save"},"finish_reason":null}],"usage":null,"obfuscation":"h1"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"finish_reason":null}],"usage":null,"obfuscation":"SFtKX"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" different"},"finish_reason":null}],"usage":null,"obfuscation":"cHVjmh5Hx4PLB"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" piece"},"finish_reason":null}],"usage":null,"obfuscation":"4"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" of"},"finish_reason":null}],"usage":null,"obfuscation":"rRb5"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" code"},"finish_reason":null}],"usage":null,"obfuscation":"kG"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" or"},"finish_reason":null}],"usage":null,"obfuscation":"9Ydy"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" text"},"finish_reason":null}],"usage":null,"obfuscation":"68"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"UPpM"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" another"},"finish_reason":null}],"usage":null,"obfuscation":"9y3pEwWtjcVhmFZ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" path"},"finish_reason":null}],"usage":null,"obfuscation":"xZ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n\n"},"finish_reason":null}],"usage":null,"obfuscation":"Flg"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Would"},"finish_reason":null}],"usage":null,"obfuscation":"ZK"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" you"},"finish_reason":null}],"usage":null,"obfuscation":"Nlc"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" like"},"finish_reason":null}],"usage":null,"obfuscation":"xZ"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" me"},"finish_reason":null}],"usage":null,"obfuscation":"38pk"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" to"},"finish_reason":null}],"usage":null,"obfuscation":"V0Lb"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" read"},"finish_reason":null}],"usage":null,"obfuscation":"Hq"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" back"},"finish_reason":null}],"usage":null,"obfuscation":"JP"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" the"},"finish_reason":null}],"usage":null,"obfuscation":"748"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" file"},"finish_reason":null}],"usage":null,"obfuscation":"9G"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" or"},"finish_reason":null}],"usage":null,"obfuscation":"Hdsm"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" make"},"finish_reason":null}],"usage":null,"obfuscation":"Y2"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" any"},"finish_reason":null}],"usage":null,"obfuscation":"6s2"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" adjustments"},"finish_reason":null}],"usage":null,"obfuscation":"pnlQHSO9oRP"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"?"},"finish_reason":null}],"usage":null,"obfuscation":"up8aas"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":null,"obfuscation":"F"} + +data: {"id":"chatcmpl-D52mrPdEJMNMRiu3YPcMWgAkrBN3L","object":"chat.completion.chunk","created":1770094725,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":5944,"completion_tokens":1591,"total_tokens":7535,"prompt_tokens_details":{"cached_tokens":4736,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":1408,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"R5KQcpHZ74"} data: [DONE] + + diff --git a/crates/goose-acp/tests/test_data/openai_builtin_read_modules.txt b/crates/goose-acp/tests/test_data/openai_builtin_read_modules.txt deleted file mode 100644 index 114f762cff..0000000000 --- a/crates/goose-acp/tests/test_data/openai_builtin_read_modules.txt +++ /dev/null @@ -1,43 +0,0 @@ -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"finish_reason":null}],"obfuscation":"v7"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_rS0QksngU4yYIDHrnDJy2EZM","type":"function","function":{"name":"code_execution__read_module","arguments":""}}]},"finish_reason":null}],"obfuscation":"T"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"mo"}}]},"finish_reason":null}],"obfuscation":"nXIpECrF"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"dule_"}}]},"finish_reason":null}],"obfuscation":"B9XWBe6c"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"path\":"}}]},"finish_reason":null}],"obfuscation":"tOSmhh"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":" \"lo"}}]},"finish_reason":null}],"obfuscation":"Zz3wgAww"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"okup/"}}]},"finish_reason":null}],"obfuscation":"pOpLxr8X"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"get_co"}}]},"finish_reason":null}],"obfuscation":"gCCacjW"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"de\"}"}}]},"finish_reason":null}],"obfuscation":"KY6NDanu"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_U0ieDPzZODuxxEWjHgi6s37G","type":"function","function":{"name":"code_execution__read_module","arguments":""}}]},"finish_reason":null}],"obfuscation":"l"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"mo"}}]},"finish_reason":null}],"obfuscation":"cKKL6hIz"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"dule_"}}]},"finish_reason":null}],"obfuscation":"zXnRkr9q"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"path\":"}}]},"finish_reason":null}],"obfuscation":"O17aod"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":" \"de"}}]},"finish_reason":null}],"obfuscation":"Hdkjwpwp"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"velop"}}]},"finish_reason":null}],"obfuscation":"31elhAol"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"er/tex"}}]},"finish_reason":null}],"obfuscation":"JsV3mVA"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"t_ed"}}]},"finish_reason":null}],"obfuscation":"8ZyjkFliU"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"itor\""}}]},"finish_reason":null}],"obfuscation":"waD7mnr"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"}"}}]},"finish_reason":null}],"obfuscation":"ohhnGgMcoCKQ"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"d6Rww4PaZYY"} - -data: {"id":"chatcmpl-CqnxaQj6rMqu4L24cNKWvWdMJRtaW","object":"chat.completion.chunk","created":1766701138,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":2586,"completion_tokens":1665,"total_tokens":4251,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":1600,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"0ofYwl6eisGBK"} - -data: [DONE] diff --git a/crates/goose-acp/tests/test_data/openai_builtin_search.txt b/crates/goose-acp/tests/test_data/openai_builtin_search.txt index a9139959a0..07130f8e41 100644 --- a/crates/goose-acp/tests/test_data/openai_builtin_search.txt +++ b/crates/goose-acp/tests/test_data/openai_builtin_search.txt @@ -1,27 +1,39 @@ -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null,"tool_calls":[{"index":0,"id":"call_dINW7AmExfpt2yitCRgIgnDk","type":"function","function":{"name":"code_execution__search_modules","arguments":""}}],"refusal":null},"finish_reason":null}],"usage":null,"obfuscation":"xjFTVJsrOLFKC"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"finish_reason":null}],"obfuscation":"Yd"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"OXXTjGoceY"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_zzoNiRL9fhMwZmopcrhgnzit","type":"function","function":{"name":"code_execution__list_functions","arguments":""}}]},"finish_reason":null}],"obfuscation":"RajKpGwjZtWueM"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"terms"}}]},"finish_reason":null}],"usage":null,"obfuscation":"MhlBIuai"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{}"}}]},"finish_reason":null}],"obfuscation":"6NOrpOsiDjm"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\":[\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"Q7ZAiod"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_oOGp9vL5SW3ATazwQsqMGVUF","type":"function","function":{"name":"code_execution__get_function_details","arguments":""}}]},"finish_reason":null}],"obfuscation":"XzNL5prg"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"get"}}]},"finish_reason":null}],"usage":null,"obfuscation":"QRDc1u5Ps1"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"fu"}}]},"finish_reason":null}],"obfuscation":"pXtaOUk0"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_code"}}]},"finish_reason":null}],"usage":null,"obfuscation":"1A5TssiT"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"nctio"}}]},"finish_reason":null}],"obfuscation":"3vnwaaJz"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\",\""}}]},"finish_reason":null}],"usage":null,"obfuscation":"IdoT3Umt"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ns\": ["}}]},"finish_reason":null}],"obfuscation":"DOwx5E"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"text"}}]},"finish_reason":null}],"usage":null,"obfuscation":"B2kd2ESuG"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"\"Loo"}}]},"finish_reason":null}],"obfuscation":"R0vj7yxw"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"_editor"}}]},"finish_reason":null}],"usage":null,"obfuscation":"rq0SWi"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"kup.g"}}]},"finish_reason":null}],"obfuscation":"ONm67mnw"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"]"}}]},"finish_reason":null}],"usage":null,"obfuscation":"y2zYEl2xLX"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"etCode"}}]},"finish_reason":null}],"obfuscation":"WKRbEGk"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"}"}}]},"finish_reason":null}],"usage":null,"obfuscation":"uSVgtytSzxV7"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"\", \""}}]},"finish_reason":null}],"obfuscation":"PUSV6OA"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"dKRdDeNi7Ag"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"Devel"}}]},"finish_reason":null}],"obfuscation":"iE40CeHf"} -data: {"id":"chatcmpl-CqnxO9QA2SYzqUg3j2vOBDv47NlNx","object":"chat.completion.chunk","created":1766701126,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":2476,"completion_tokens":1887,"total_tokens":4363,"prompt_tokens_details":{"cached_tokens":2176,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":1856,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"ZHkygmUrjh"} +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"oper.t"}}]},"finish_reason":null}],"obfuscation":"H6OirmC"} + +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"extE"}}]},"finish_reason":null}],"obfuscation":"kDbaE6CEl"} + +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ditor"}}]},"finish_reason":null}],"obfuscation":"y0gYF9yy"} + +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"\"]}"}}]},"finish_reason":null}],"obfuscation":"YrrS1cRX8"} + +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":null,"obfuscation":"HVEjNhyKZ9f"} + +data: {"id":"chatcmpl-D52mYBQiVJoVI837twEG5vpPRxo3F","object":"chat.completion.chunk","created":1770094706,"model":"gpt-5-nano-2025-08-07","service_tier":"default","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":2911,"completion_tokens":1088,"total_tokens":3999,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":1024,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"7gsIC3BJ8WITa"} data: [DONE] + + diff --git a/crates/goose-cli/src/scenario_tests/mock_client.rs b/crates/goose-cli/src/scenario_tests/mock_client.rs index 149e79eb0e..5331186a3a 100644 --- a/crates/goose-cli/src/scenario_tests/mock_client.rs +++ b/crates/goose-cli/src/scenario_tests/mock_client.rs @@ -98,6 +98,7 @@ impl McpClientTrait for MockClient { _session_id: &str, name: &str, arguments: Option>, + _working_dir: Option<&str>, _cancel_token: CancellationToken, ) -> Result { if let Some(handler) = self.handlers.get(name) { diff --git a/crates/goose-cli/src/session/mod.rs b/crates/goose-cli/src/session/mod.rs index 7d49aed5d4..3b3dcd314f 100644 --- a/crates/goose-cli/src/session/mod.rs +++ b/crates/goose-cli/src/session/mod.rs @@ -22,6 +22,7 @@ pub use self::export::message_to_markdown; pub use builder::{build_session, SessionBuilderConfig}; use console::Color; use goose::agents::AgentEvent; +use goose::agents::SUBAGENT_TOOL_REQUEST_TYPE; use goose::permission::permission_confirmation::PrincipalType; use goose::permission::Permission; use goose::permission::PermissionConfirmation; @@ -1537,6 +1538,49 @@ fn handle_mcp_notification( ) { match notification { ServerNotification::LoggingMessageNotification(log_notif) => { + if let Some(obj) = log_notif.params.data.as_object() { + if obj.get("type").and_then(|v| v.as_str()) == Some(SUBAGENT_TOOL_REQUEST_TYPE) { + if let (Some(subagent_id), Some(tool_call)) = ( + obj.get("subagent_id").and_then(|v| v.as_str()), + obj.get("tool_call").and_then(|v| v.as_object()), + ) { + let tool_name = tool_call + .get("name") + .and_then(|v| v.as_str()) + .unwrap_or("unknown"); + let arguments = tool_call + .get("arguments") + .and_then(|v| v.as_object()) + .cloned(); + + if interactive { + let _ = progress_bars.hide(); + } + if is_stream_json_mode { + emit_stream_event(&StreamEvent::Notification { + extension_id: extension_id.to_string(), + data: NotificationData::Log { + message: output::format_subagent_tool_call_message( + subagent_id, + tool_name, + ), + }, + }); + return; + } + if !is_json_mode { + output::render_subagent_tool_call( + subagent_id, + tool_name, + arguments.as_ref(), + debug, + ); + return; + } + } + } + } + let (formatted, subagent_id, notif_type) = format_logging_notification(&log_notif.params.data, debug); diff --git a/crates/goose-cli/src/session/output.rs b/crates/goose-cli/src/session/output.rs index c05387e56e..d7875377e3 100644 --- a/crates/goose-cli/src/session/output.rs +++ b/crates/goose-cli/src/session/output.rs @@ -314,8 +314,9 @@ fn render_tool_request(req: &ToolRequest, theme: Theme, debug: bool) { Ok(call) => match call.name.to_string().as_str() { "developer__text_editor" => render_text_editor_request(call, debug), "developer__shell" => render_shell_request(call, debug), - "execute_code" => render_execute_code_request(call, debug), + "execute" | "execute_code" => render_execute_code_request(call, debug), "delegate" => render_delegate_request(call, debug), + "subagent" => render_delegate_request(call, debug), "todo__write" => render_todo_request(call, debug), _ => render_default_request(call, debug), }, @@ -508,7 +509,7 @@ fn render_execute_code_request(call: &CallToolRequestParams, debug: bool) { "─── {} tool call{} | {} ──────────────────────────", style(count).cyan(), plural, - style("execute_code").magenta().dim() + style("execute").magenta().dim() ); for (i, node) in tool_graph.iter().filter_map(Value::as_object).enumerate() { @@ -541,6 +542,17 @@ fn render_execute_code_request(call: &CallToolRequestParams, debug: bool) { style(deps_str).dim() ); } + + let code = call + .arguments + .as_ref() + .and_then(|args| args.get("code")) + .and_then(Value::as_str) + .filter(|c| !c.is_empty()); + if code.is_some_and(|_| debug) { + println!("{}", style(code.unwrap_or_default()).green()); + } + println!(); } @@ -602,21 +614,108 @@ fn render_default_request(call: &CallToolRequestParams, debug: bool) { println!(); } +fn split_tool_name(tool_name: &str) -> (String, String) { + let parts: Vec<_> = tool_name.rsplit("__").collect(); + let tool = parts.first().copied().unwrap_or("unknown"); + let extension = parts + .split_first() + .map(|(_, s)| s.iter().rev().copied().collect::>().join("__")) + .unwrap_or_default(); + (tool.to_string(), extension) +} + +pub fn format_subagent_tool_call_message(subagent_id: &str, tool_name: &str) -> String { + let short_id = subagent_id.rsplit('_').next().unwrap_or(subagent_id); + let (tool, extension) = split_tool_name(tool_name); + + if extension.is_empty() { + format!("[subagent:{}] {}", short_id, tool) + } else { + format!("[subagent:{}] {} | {}", short_id, tool, extension) + } +} + +pub fn render_subagent_tool_call( + subagent_id: &str, + tool_name: &str, + arguments: Option<&JsonObject>, + debug: bool, +) { + if tool_name == "code_execution__execute_code" { + let tool_graph = arguments + .and_then(|args| args.get("tool_graph")) + .and_then(Value::as_array) + .filter(|arr| !arr.is_empty()); + if let Some(tool_graph) = tool_graph { + return render_subagent_tool_graph(subagent_id, tool_graph); + } + } + let tool_header = format!( + "─── {} ──────────────────────────", + style(format_subagent_tool_call_message(subagent_id, tool_name)) + .magenta() + .dim() + ); + println!(); + println!("{}", tool_header); + print_params(&arguments.cloned(), 0, debug); + println!(); +} + +fn render_subagent_tool_graph(subagent_id: &str, tool_graph: &[Value]) { + let short_id = subagent_id.rsplit('_').next().unwrap_or(subagent_id); + let count = tool_graph.len(); + let plural = if count == 1 { "" } else { "s" }; + println!(); + println!( + "─── {} {} tool call{} | {} ──────────────────────────", + style(format!("[subagent:{}]", short_id)).cyan(), + style(count).cyan(), + plural, + style("execute_code").magenta().dim() + ); + + for (i, node) in tool_graph.iter().filter_map(Value::as_object).enumerate() { + let tool = node + .get("tool") + .and_then(Value::as_str) + .unwrap_or("unknown"); + let desc = node + .get("description") + .and_then(Value::as_str) + .unwrap_or(""); + let deps: Vec<_> = node + .get("depends_on") + .and_then(Value::as_array) + .into_iter() + .flatten() + .filter_map(Value::as_u64) + .map(|d| (d + 1).to_string()) + .collect(); + let deps_str = if deps.is_empty() { + String::new() + } else { + format!(" (uses {})", deps.join(", ")) + }; + println!( + " {}. {}: {}{}", + style(i + 1).dim(), + style(tool).cyan(), + style(desc).green(), + style(deps_str).dim() + ); + } + println!(); +} + // Helper functions fn print_tool_header(call: &CallToolRequestParams) { - let parts: Vec<_> = call.name.rsplit("__").collect(); + let (tool, extension) = split_tool_name(&call.name); let tool_header = format!( "─── {} | {} ──────────────────────────", - style(parts.first().unwrap_or(&"unknown")), - style( - parts - .split_first() - .map(|(_, s)| s.iter().rev().copied().collect::>().join("__")) - .unwrap_or_else(|| "unknown".to_string()) - ) - .magenta() - .dim(), + style(tool), + style(extension).magenta().dim(), ); println!(); println!("{}", tool_header); diff --git a/crates/goose-mcp/src/developer/rmcp_developer.rs b/crates/goose-mcp/src/developer/rmcp_developer.rs index cdcdd3e905..0cb224dacd 100644 --- a/crates/goose-mcp/src/developer/rmcp_developer.rs +++ b/crates/goose-mcp/src/developer/rmcp_developer.rs @@ -10,13 +10,26 @@ use rmcp::{ model::{ CallToolResult, CancelledNotificationParam, Content, ErrorCode, ErrorData, GetPromptRequestParams, GetPromptResult, Implementation, ListPromptsResult, LoggingLevel, - LoggingMessageNotificationParam, PaginatedRequestParams, Prompt, PromptArgument, + LoggingMessageNotificationParam, Meta, PaginatedRequestParams, Prompt, PromptArgument, PromptMessage, PromptMessageRole, Role, ServerCapabilities, ServerInfo, }, schemars::JsonSchema, service::{NotificationContext, RequestContext}, tool, tool_handler, tool_router, RoleServer, ServerHandler, }; + +/// Header name for passing working directory through MCP request metadata +const WORKING_DIR_HEADER: &str = "agent-working-dir"; + +/// Extract working directory from MCP request metadata +fn extract_working_dir_from_meta(meta: &Meta) -> Option { + meta.0 + .get(WORKING_DIR_HEADER) + .and_then(|v| v.as_str()) + .filter(|s| !s.is_empty()) + .map(PathBuf::from) +} + use serde::{Deserialize, Serialize}; use std::{ collections::HashMap, @@ -873,6 +886,8 @@ impl DeveloperServer { let peer = context.peer; let request_id = context.id; + let working_dir = extract_working_dir_from_meta(&context.meta); + // Validate the shell command self.validate_shell_command(command)?; @@ -886,7 +901,7 @@ impl DeveloperServer { // Execute the command and capture output let output_result = self - .execute_shell_command(command, &peer, cancellation_token.clone()) + .execute_shell_command(command, &peer, cancellation_token.clone(), working_dir) .await; // Clean up the process from tracking @@ -970,6 +985,7 @@ impl DeveloperServer { command: &str, peer: &rmcp::service::Peer, cancellation_token: CancellationToken, + working_dir: Option, ) -> Result { let mut shell_config = ShellConfig::default(); let shell_name = std::path::Path::new(&shell_config.executable) @@ -977,10 +993,6 @@ impl DeveloperServer { .and_then(|s| s.to_str()) .unwrap_or("bash"); - let working_dir = std::env::var("GOOSE_WORKING_DIR") - .ok() - .map(std::path::PathBuf::from); - if let Some(ref env_file) = self.bash_env_file { if shell_name == "bash" { shell_config.envs.push(( diff --git a/crates/goose-mcp/src/developer/shell.rs b/crates/goose-mcp/src/developer/shell.rs index a05242833d..2e0a56b80a 100644 --- a/crates/goose-mcp/src/developer/shell.rs +++ b/crates/goose-mcp/src/developer/shell.rs @@ -8,7 +8,6 @@ use std::os::unix::process::CommandExt; pub struct ShellConfig { pub executable: String, pub args: Vec, - #[allow(dead_code)] pub envs: Vec<(OsString, OsString)>, } @@ -129,8 +128,13 @@ pub fn configure_shell_command( .env("EDITOR", "sh -c 'echo \"Interactive editor not available in this environment.\" >&2; exit 1'") .env("GIT_TERMINAL_PROMPT", "0") .env("GIT_PAGER", "cat") - .args(&shell_config.args) - .arg(command); + .args(&shell_config.args); + + for (key, value) in &shell_config.envs { + command_builder.env(key, value); + } + + command_builder.arg(command); // On Unix systems, create a new process group so we can kill child processes #[cfg(unix)] diff --git a/crates/goose-server/Cargo.toml b/crates/goose-server/Cargo.toml index 5a8d132a03..9a159d29cc 100644 --- a/crates/goose-server/Cargo.toml +++ b/crates/goose-server/Cargo.toml @@ -10,6 +10,10 @@ description.workspace = true [lints] workspace = true +[features] +default = [] +cuda = ["goose/cuda"] + [dependencies] goose = { path = "../goose" } goose-mcp = { path = "../goose-mcp" } diff --git a/crates/goose-server/src/openapi.rs b/crates/goose-server/src/openapi.rs index 597fb12124..61917905c7 100644 --- a/crates/goose-server/src/openapi.rs +++ b/crates/goose-server/src/openapi.rs @@ -576,6 +576,7 @@ derive_utoipa!(Icon as IconSchema); goose::goose_apps::WindowProps, goose::goose_apps::McpAppResource, goose::goose_apps::CspMetadata, + goose::goose_apps::PermissionsMetadata, goose::goose_apps::UiMetadata, goose::goose_apps::ResourceMetadata, super::routes::dictation::TranscribeRequest, diff --git a/crates/goose-server/src/routes/agent.rs b/crates/goose-server/src/routes/agent.rs index 17061cf684..e36bfd6c35 100644 --- a/crates/goose-server/src/routes/agent.rs +++ b/crates/goose-server/src/routes/agent.rs @@ -947,7 +947,12 @@ async fn call_tool( let tool_result = agent .extension_manager - .dispatch_tool_call(&payload.session_id, tool_call, CancellationToken::default()) + .dispatch_tool_call( + &payload.session_id, + tool_call, + None, + CancellationToken::default(), + ) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; diff --git a/crates/goose-server/src/routes/templates/mcp_app_proxy.html b/crates/goose-server/src/routes/templates/mcp_app_proxy.html index 805ec02659..07d91505c1 100644 --- a/crates/goose-server/src/routes/templates/mcp_app_proxy.html +++ b/crates/goose-server/src/routes/templates/mcp_app_proxy.html @@ -33,7 +33,7 @@ let guestIframe = null; - function createGuestIframe(html) { + function createGuestIframe(html, permissions) { if (guestIframe) { guestIframe.remove(); } @@ -46,6 +46,17 @@ // allow-forms: needed if the app has forms guestIframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms'); + // Build Permission Policy allow attribute from requested permissions + // These control access to sensitive browser APIs like camera, microphone, etc. + var allowList = []; + if (permissions && permissions.camera) allowList.push('camera'); + if (permissions && permissions.microphone) allowList.push('microphone'); + if (permissions && permissions.geolocation) allowList.push('geolocation'); + if (permissions && permissions.clipboardWrite) allowList.push('clipboard-write'); + if (allowList.length > 0) { + guestIframe.setAttribute('allow', allowList.join('; ')); + } + guestIframe.srcdoc = html; guestIframe.style.cssText = 'width:100%; height:100%; border:none;'; @@ -73,8 +84,9 @@ if (method === 'ui/notifications/sandbox-resource-ready') { var params = data.params || {}; var html = params.html || ''; + var permissions = params.permissions || null; - createGuestIframe(html); + createGuestIframe(html, permissions); return; } @@ -132,4 +144,4 @@ })(); - \ No newline at end of file + diff --git a/crates/goose/Cargo.toml b/crates/goose/Cargo.toml index a5d9396b51..584a7a70ad 100644 --- a/crates/goose/Cargo.toml +++ b/crates/goose/Cargo.toml @@ -9,13 +9,17 @@ description.workspace = true [features] default = [] +cuda = ["candle-core/cuda", "candle-nn/cuda"] [lints] workspace = true [build-dependencies] tokio = { workspace = true } -reqwest = { workspace = true, features = ["json", "rustls-tls-native-roots"], default-features = false } +reqwest = { workspace = true, features = [ + "json", + "rustls-tls-native-roots", +], default-features = false } [dependencies] lru = "0.16" @@ -51,7 +55,7 @@ sha2 = "0.10" base64 = { workspace = true } url = { workspace = true } axum = "0.8.1" -webbrowser = {workspace = true} +webbrowser = { workspace = true } lazy_static = "1.5.0" tracing = { workspace = true } tracing-subscriber = "0.3" @@ -59,8 +63,16 @@ tracing-opentelemetry = "0.28" opentelemetry = "0.27" opentelemetry-appender-tracing = "0.27" opentelemetry_sdk = { version = "0.27", features = ["rt-tokio", "metrics"] } -opentelemetry-otlp = { version = "0.27", features = ["http-proto", "reqwest-client"] } -keyring = { version = "3.6.2", features = ["apple-native", "windows-native", "sync-secret-service", "vendored"] } +opentelemetry-otlp = { version = "0.27", features = [ + "http-proto", + "reqwest-client", +] } +keyring = { version = "3.6.2", features = [ + "apple-native", + "windows-native", + "sync-secret-service", + "vendored", +] } serde_yaml = "0.9.34" once_cell = "1.20.2" etcetera = { workspace = true } @@ -69,7 +81,12 @@ utoipa = { version = "4.1", features = ["chrono"] } tokio-cron-scheduler = "0.14.0" urlencoding = "2.1" v_htmlescape = "0.15" -sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "sqlite", "chrono", "json"] } +sqlx = { version = "0.8", features = [ + "runtime-tokio-rustls", + "sqlite", + "chrono", + "json", +] } # For Bedrock provider aws-config = { version = "=1.8.12", features = ["behavior-version-latest"] } @@ -104,15 +121,17 @@ rubato = "0.16" zip = "0.6" sys-info = "0.9" -schemars = { version = "1.0.4", default-features = false, features = ["derive"] } +schemars = { version = "1.0.4", default-features = false, features = [ + "derive", +] } insta = "1.43.2" paste = "1.0.0" posthog-rs = "0.3.7" shellexpand = "3.1.1" indexmap = "2.12.0" ignore = { workspace = true } -which = { workspace = true} -boa_engine = "0.21.0" +which = { workspace = true } +pctx_code_mode = "^0.2.2" unbinder = "0.1.7" [target.'cfg(target_os = "windows")'.dependencies] diff --git a/crates/goose/src/agents/agent.rs b/crates/goose/src/agents/agent.rs index 2a3ecc8e33..e6d7bde384 100644 --- a/crates/goose/src/agents/agent.rs +++ b/crates/goose/src/agents/agent.rs @@ -509,6 +509,7 @@ impl Agent { .dispatch_tool_call( &session.id, tool_call.clone(), + Some(session.working_dir.as_path()), cancellation_token.unwrap_or_default(), ) .await; diff --git a/crates/goose/src/agents/apps_extension.rs b/crates/goose/src/agents/apps_extension.rs index 4c7dbdaf4f..69bfa9807a 100644 --- a/crates/goose/src/agents/apps_extension.rs +++ b/crates/goose/src/agents/apps_extension.rs @@ -531,6 +531,7 @@ impl McpClientTrait for AppsManagerClient { session_id: &str, name: &str, arguments: Option, + _working_dir: Option<&str>, _cancel_token: CancellationToken, ) -> Result { let result = match name { diff --git a/crates/goose/src/agents/chatrecall_extension.rs b/crates/goose/src/agents/chatrecall_extension.rs index e946d5407b..fb3c895b59 100644 --- a/crates/goose/src/agents/chatrecall_extension.rs +++ b/crates/goose/src/agents/chatrecall_extension.rs @@ -297,6 +297,7 @@ impl McpClientTrait for ChatRecallClient { session_id: &str, name: &str, arguments: Option, + _working_dir: Option<&str>, _cancellation_token: CancellationToken, ) -> Result { let content = match name { diff --git a/crates/goose/src/agents/code_execution_extension.rs b/crates/goose/src/agents/code_execution_extension.rs index d39184dfcc..535851d025 100644 --- a/crates/goose/src/agents/code_execution_extension.rs +++ b/crates/goose/src/agents/code_execution_extension.rs @@ -1,13 +1,10 @@ use crate::agents::extension::PlatformExtensionContext; -use crate::agents::extension_manager::get_parameter_names; use crate::agents::mcp_client::{Error, McpClientTrait}; use anyhow::Result; use async_trait::async_trait; -use boa_engine::builtins::promise::PromiseState; -use boa_engine::module::{MapModuleLoader, Module, SyntheticModuleInitializer}; -use boa_engine::{js_string, Context, JsNativeError, JsString, JsValue, NativeFunction, Source}; use indoc::indoc; -use regex::Regex; +use pctx_code_mode::model::{CallbackConfig, ExecuteInput, GetFunctionDetailsInput}; +use pctx_code_mode::{CallbackRegistry, CodeMode}; use rmcp::model::{ CallToolRequestParams, CallToolResult, Content, Implementation, InitializeResult, JsonObject, ListToolsResult, ProtocolVersion, RawContent, ServerCapabilities, Tool as McpTool, @@ -15,19 +12,22 @@ use rmcp::model::{ }; use schemars::{schema_for, JsonSchema}; use serde::{Deserialize, Serialize}; -use serde_json::Value; -use std::collections::{BTreeMap, BTreeSet}; -use std::rc::Rc; -use tokio::sync::mpsc; +use serde_json::{json, Value}; +use std::collections::hash_map::DefaultHasher; +use std::future::Future; +use std::hash::{Hash, Hasher}; +use std::pin::Pin; +use std::sync::Arc; +use tokio::sync::RwLock; use tokio_util::sync::CancellationToken; pub static EXTENSION_NAME: &str = "code_execution"; -type ToolCallRequest = ( - String, - String, - tokio::sync::oneshot::Sender>, -); +pub struct CodeExecutionClient { + info: InitializeResult, + context: PlatformExtensionContext, + state: RwLock>, +} #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] struct ToolGraphNode { @@ -41,382 +41,15 @@ struct ToolGraphNode { } #[derive(Debug, Serialize, Deserialize, JsonSchema)] -struct ExecuteCodeParams { - /// JavaScript code with ES6 imports for MCP tools. - code: String, +pub struct ExecuteWithToolGraph { + #[serde(flatten)] + input: ExecuteInput, /// DAG of tool calls showing execution flow. Each node represents a tool call. /// Use depends_on to show data flow (e.g., node 1 uses output from node 0). #[serde(default)] tool_graph: Vec, } -#[derive(Debug, Serialize, Deserialize, JsonSchema)] -struct ReadModuleParams { - /// Module path format: - /// - For entire server: "server_name" - /// - For specific tool: "server_name/tool_name" - module_path: String, -} - -#[derive(Debug, Serialize, Deserialize, JsonSchema)] -struct SearchModulesParams { - /// Search terms to find servers/tools (case-insensitive). Can be a single string or array of strings. - terms: SearchTerms, - /// If true, treat search terms as regex patterns - #[serde(default)] - regex: bool, -} - -#[derive(Debug, Serialize, Deserialize, JsonSchema)] -#[serde(untagged)] -enum SearchTerms { - Single(String), - Multiple(Vec), -} - -#[derive(Debug, Default, Deserialize)] -struct InputSchema { - #[serde(default)] - properties: BTreeMap, - #[serde(default)] - required: Vec, -} - -fn quote_join(vals: &[&str]) -> String { - format!("\"{}\"", vals.join("\" | \"")) -} - -fn infer_type(schema: &Value) -> Option { - if schema.get("properties").is_some() { - Some("object".to_string()) - } else if schema.get("items").is_some() { - Some("array".to_string()) - } else { - None - } -} - -fn extract_type_from_schema(schema: &Value) -> Option { - // enum array (github-mcp style) - if let Some(arr) = schema.get("enum").and_then(|e| e.as_array()) { - let vals: Vec<_> = arr.iter().filter_map(|v| v.as_str()).collect(); - if !vals.is_empty() { - return Some(quote_join(&vals)); - } - } - - // oneOf with const (schemars enums) - if let Some(arr) = schema.get("oneOf").and_then(|o| o.as_array()) { - let vals: Vec<_> = arr - .iter() - .filter_map(|v| v.get("const")?.as_str()) - .collect(); - if !vals.is_empty() { - return Some(quote_join(&vals)); - } - } - - // anyOf (Option or unions) - if let Some(arr) = schema.get("anyOf").and_then(|o| o.as_array()) { - let non_null: Vec<_> = arr - .iter() - .filter(|v| v.get("type").and_then(|t| t.as_str()) != Some("null")) - .collect(); - if non_null.len() == 1 { - return extract_type_from_schema(non_null[0]).or_else(|| infer_type(non_null[0])); - } - if non_null.len() > 1 { - let types: Vec<_> = non_null - .iter() - .filter_map(|v| extract_type_from_schema(v).or_else(|| infer_type(v))) - .collect(); - if !types.is_empty() { - return Some(types.join(" | ")); - } - } - } - - // type field (string or array) - match schema.get("type") { - Some(Value::String(s)) if s == "array" => { - let item_type = schema - .get("items") - .and_then(extract_type_from_schema) - .unwrap_or_else(|| "any".to_string()); - Some(if item_type == "any" { - "array".into() - } else { - format!("{item_type}[]") - }) - } - Some(Value::String(s)) if s == "object" => { - let Some(props) = schema.get("properties").and_then(|p| p.as_object()) else { - return Some("object".to_string()); - }; - let required: Vec<_> = schema - .get("required") - .and_then(|r| r.as_array()) - .map(|arr| arr.iter().filter_map(|v| v.as_str()).collect()) - .unwrap_or_default(); - let mut fields: Vec<_> = props - .iter() - .map(|(name, schema)| { - let ty = extract_type_from_schema(schema).unwrap_or_else(|| "any".into()); - let opt = if required.contains(&name.as_str()) { - "" - } else { - "?" - }; - format!("{name}{opt}: {ty}") - }) - .collect(); - fields.sort(); - Some(format!("{{ {} }}", fields.join(", "))) - } - Some(Value::String(s)) => Some(s.clone()), - Some(Value::Array(arr)) => { - let non_null: Vec<_> = arr - .iter() - .filter_map(|v| v.as_str()) - .filter(|s| *s != "null") - .collect(); - match non_null.len() { - 0 => None, - 1 => Some(non_null[0].to_string()), - _ => Some(non_null.join(" | ")), - } - } - _ => None, - } -} - -struct ToolInfo { - server_name: String, - tool_name: String, - full_name: String, - description: String, - params: Vec<(String, String, bool)>, - return_type: String, -} - -impl ToolInfo { - fn from_mcp_tool(tool: &McpTool) -> Option { - let (server_name, tool_name) = tool.name.split_once("__")?; - let param_names = get_parameter_names(tool); - - let mut schema_value = Value::Object(tool.input_schema.as_ref().clone()); - let _ = unbinder::dereference_schema(&mut schema_value, unbinder::Options::default()); - let schema: InputSchema = serde_json::from_value(schema_value).unwrap_or_default(); - - let params = param_names - .iter() - .map(|name| { - let ty = schema - .properties - .get(name) - .and_then(extract_type_from_schema) - .unwrap_or_else(|| "any".to_string()); - let required = schema.required.contains(name); - (name.clone(), ty, required) - }) - .collect(); - - let return_type = tool - .output_schema - .as_ref() - .and_then(|schema| { - let mut schema_value = Value::Object(schema.as_ref().clone()); - let _ = - unbinder::dereference_schema(&mut schema_value, unbinder::Options::default()); - extract_type_from_schema(&schema_value) - }) - .unwrap_or_else(|| "string".to_string()); - - Some(Self { - server_name: server_name.to_string(), - tool_name: tool_name.to_string(), - full_name: tool.name.to_string(), - description: tool - .description - .as_ref() - .map(|d| d.to_string()) - .unwrap_or_default(), - params, - return_type, - }) - } - - fn to_signature(&self) -> String { - let params = self - .params - .iter() - .map(|(name, ty, req)| format!("{name}{}: {ty}", if *req { "" } else { "?" })) - .collect::>() - .join(", "); - let desc = self.description.lines().next().unwrap_or(""); - format!( - "{}[\"{}\"]({{{params}}}): {} - {desc}", - self.server_name, self.tool_name, self.return_type - ) - } -} - -thread_local! { - static CALL_TX: std::cell::RefCell>> = - const { std::cell::RefCell::new(None) }; - static RESULT_CELL: std::cell::RefCell> = - const { std::cell::RefCell::new(None) }; -} - -fn create_server_module( - server_name: &str, - server_tools: &[&ToolInfo], - ctx: &mut Context, -) -> Module { - let tool_data: Vec<(String, String)> = server_tools - .iter() - .map(|t| (t.tool_name.clone(), t.full_name.clone())) - .collect(); - - let mut export_names: Vec = server_tools - .iter() - .map(|t| js_string!(t.tool_name.as_str())) - .collect(); - export_names.push(js_string!(server_name)); - - let server_name_owned = server_name.to_string(); - - Module::synthetic( - &export_names, - SyntheticModuleInitializer::from_copy_closure_with_captures( - |module, (tools, server_name), context| { - let namespace_obj = boa_engine::JsObject::with_null_proto(); - - for (tool_name, full_name) in tools.iter() { - let func = create_tool_function(full_name.clone()); - let js_func = func.to_js_function(context.realm()); - module.set_export(&js_string!(tool_name.as_str()), js_func.clone().into())?; - namespace_obj - .set(js_string!(tool_name.as_str()), js_func, false, context) - .map_err(|e| { - JsNativeError::error().with_message(format!("Failed to set prop: {e}")) - })?; - } - module.set_export(&js_string!(server_name.as_str()), namespace_obj.into())?; - - Ok(()) - }, - (tool_data, server_name_owned), - ), - None, - None, - ctx, - ) -} - -fn parse_result_to_js(result: &str, ctx: &mut Context) -> JsValue { - serde_json::from_str::(result) - .ok() - .and_then(|v| JsValue::from_json(&v, ctx).ok()) - .unwrap_or_else(|| JsValue::from(js_string!(result))) -} - -fn create_tool_function(full_tool_name: String) -> NativeFunction { - NativeFunction::from_copy_closure_with_captures( - |_this, args, full_name: &String, ctx| { - let args_json = args - .first() - .cloned() - .unwrap_or(JsValue::undefined()) - .to_json(ctx) - .map_err(|e| JsNativeError::error().with_message(e.to_string()))? - .unwrap_or(Value::Object(serde_json::Map::new())); - - let args_str = serde_json::to_string(&args_json).unwrap_or_else(|_| "{}".to_string()); - let (tx, rx) = tokio::sync::oneshot::channel(); - - CALL_TX - .with(|call_tx| { - call_tx - .borrow() - .as_ref() - .and_then(|sender| sender.send((full_name.clone(), args_str, tx)).ok()) - }) - .ok_or_else(|| JsNativeError::error().with_message("Channel unavailable"))?; - - rx.blocking_recv() - .map_err(|e| e.to_string()) - .and_then(|r| r) - .map(|result| parse_result_to_js(&result, ctx)) - .map_err(|e| JsNativeError::error().with_message(e).into()) - }, - full_tool_name, - ) -} - -fn run_js_module( - code: &str, - tools: &[ToolInfo], - call_tx: mpsc::UnboundedSender, -) -> Result { - CALL_TX.with(|tx| *tx.borrow_mut() = Some(call_tx)); - RESULT_CELL.with(|cell| *cell.borrow_mut() = None); - - let loader = Rc::new(MapModuleLoader::new()); - let mut ctx = Context::builder() - .module_loader(loader.clone()) - .build() - .map_err(|e| format!("Failed to create JS context: {e}"))?; - - let record_result = NativeFunction::from_copy_closure(|_this, args, ctx| { - let value = args.first().cloned().unwrap_or(JsValue::undefined()); - let fallback = || value.display().to_string(); - let result_str = value - .to_json(ctx) - .ok() - .flatten() - .map(|v| serde_json::to_string_pretty(&v).unwrap_or_else(|_| fallback())) - .unwrap_or_else(fallback); - RESULT_CELL.with(|cell| *cell.borrow_mut() = Some(result_str)); - Ok(value) - }); - - ctx.register_global_callable(js_string!("record_result"), 1, record_result) - .map_err(|e| format!("Failed to register record_result: {e}"))?; - - let mut by_server: BTreeMap<&str, Vec<&ToolInfo>> = BTreeMap::new(); - for tool in tools { - by_server.entry(&tool.server_name).or_default().push(tool); - } - - for (server_name, server_tools) in &by_server { - let module = create_server_module(server_name, server_tools, &mut ctx); - loader.insert(*server_name, module); - } - - let user_module = Module::parse(Source::from_bytes(code), None, &mut ctx) - .map_err(|e| format!("Parse error: {e}"))?; - loader.insert("__main__", user_module.clone()); - - let promise = user_module.load_link_evaluate(&mut ctx); - ctx.run_jobs() - .map_err(|e| format!("Job execution error: {e}"))?; - - match promise.state() { - PromiseState::Fulfilled(_) => { - let result = RESULT_CELL.with(|cell| cell.borrow().clone()); - Ok(result.unwrap_or_else(|| "undefined".to_string())) - } - PromiseState::Rejected(err) => Err(format!("Module error: {}", err.display())), - PromiseState::Pending => Err("Module evaluation did not complete".to_string()), - } -} - -pub struct CodeExecutionClient { - info: InitializeResult, - context: PlatformExtensionContext, -} - impl CodeExecutionClient { pub fn new(context: PlatformExtensionContext) -> Result { let info = InitializeResult { @@ -440,272 +73,222 @@ impl CodeExecutionClient { website_url: None, }, instructions: Some(indoc! {r#" - BATCH MULTIPLE TOOL CALLS INTO ONE execute_code CALL. + BATCH MULTIPLE TOOL CALLS INTO ONE execute CALL. This extension exists to reduce round-trips. When a task requires multiple tool calls: - - WRONG: Multiple execute_code calls, each with one tool - - RIGHT: One execute_code call with a script that calls all needed tools + - WRONG: Multiple execute calls, each with one tool + - RIGHT: One execute call with a script that calls all needed tools - IMPORTANT: All tool calls are SYNCHRONOUS. Do NOT use async/await. + IMPORTANT: All tool calls are ASYNC. Use await for each call. Workflow: - 1. Use the read_module tool to discover tools and signatures - 2. Write ONE script that imports and calls ALL tools needed for the task + 1. Use the list_functions and get_function_details tools to discover tools and signatures + 2. Write ONE script that calls ALL tools needed for the task, no need to import anything, + all the namespaces returned by list_functions and get_function_details will be available 3. Chain results: use output from one tool as input to the next + 4. Only return and console.log data you need, tools could have very large responses. "#}.to_string()), }; - Ok(Self { info, context }) + Ok(Self { + info, + context, + state: RwLock::new(None), + }) } - async fn get_tool_infos(&self, session_id: &str) -> Vec { - let Some(manager) = self + async fn load_callback_configs(&self, session_id: &str) -> Option> { + let manager = self + .context + .extension_manager + .as_ref() + .and_then(|w| w.upgrade())?; + + let tools = manager + .get_prefixed_tools_excluding(session_id, EXTENSION_NAME) + .await + .ok()?; + let mut cfgs = vec![]; + for tool in tools { + let full_name = tool.name.to_string(); + let (server_name, tool_name) = full_name.split_once("__")?; + cfgs.push(CallbackConfig { + name: tool_name.into(), + namespace: server_name.into(), + description: tool.description.as_ref().map(|d| d.to_string()), + input_schema: Some(json!(tool.input_schema)), + output_schema: tool.output_schema.as_ref().map(|s| json!(s)), + }) + } + Some(cfgs) + } + + /// Get the cached CodeMode, rebuilding if callback configs have changed + async fn get_code_mode(&self, session_id: &str) -> Result { + let cfgs = self + .load_callback_configs(session_id) + .await + .ok_or("Failed to load callback configs")?; + let current_hash = CodeModeState::hash(&cfgs); + + // Use cache if no state change + { + let guard = self.state.read().await; + if let Some(state) = guard.as_ref() { + if state.hash == current_hash { + return Ok(state.code_mode.clone()); + } + } + } + + // Rebuild CodeMode & cache + let mut guard = self.state.write().await; + // Double-check after acquiring write lock + if let Some(state) = guard.as_ref() { + if state.hash == current_hash { + return Ok(state.code_mode.clone()); + } + } + + let state = CodeModeState::new(cfgs)?; + let code_mode = state.code_mode.clone(); + *guard = Some(state); + Ok(code_mode) + } + + /// Build a CallbackRegistry with all tool callbacks registered + fn build_callback_registry( + &self, + session_id: &str, + code_mode: &CodeMode, + ) -> Result { + let manager = self .context .extension_manager .as_ref() .and_then(|w| w.upgrade()) - else { - return Vec::new(); - }; + .ok_or("Extension manager not available")?; - match manager - .get_prefixed_tools_excluding(session_id, EXTENSION_NAME) - .await - { - Ok(tools) if !tools.is_empty() => { - tools.iter().filter_map(ToolInfo::from_mcp_tool).collect() - } - _ => Vec::new(), + let registry = CallbackRegistry::default(); + for cfg in code_mode.callbacks() { + let full_name = format!("{}__{}", &cfg.namespace, &cfg.name); + let callback = create_tool_callback(session_id.to_string(), full_name, manager.clone()); + registry + .add(&cfg.id(), callback) + .map_err(|e| format!("Failed to register callback: {e}"))?; } + + Ok(registry) } - async fn handle_execute_code( + /// Handle the list_functions tool call + async fn handle_list_functions(&self, session_id: &str) -> Result, String> { + let code_mode = self.get_code_mode(session_id).await?; + let output = code_mode.list_functions(); + + Ok(vec![Content::text(output.code)]) + } + + /// Handle the get_function_details tool call + async fn handle_get_function_details( &self, session_id: &str, arguments: Option, ) -> Result, String> { - let code = arguments - .as_ref() - .and_then(|a| a.get("code")) - .and_then(|v| v.as_str()) - .ok_or("Missing required parameter: code")? - .to_string(); + let input: GetFunctionDetailsInput = arguments + .map(|args| serde_json::from_value(Value::Object(args))) + .transpose() + .map_err(|e| format!("Failed to parse arguments: {e}"))? + .ok_or("Missing arguments for get_function_details")?; - let tools = self.get_tool_infos(session_id).await; - let (call_tx, call_rx) = mpsc::unbounded_channel(); - let tool_handler = tokio::spawn(Self::run_tool_handler( - session_id.to_string(), - call_rx, - self.context.extension_manager.clone(), - )); + let code_mode = self.get_code_mode(session_id).await?; + let output = code_mode.get_function_details(input); - let js_result = tokio::task::spawn_blocking(move || run_js_module(&code, &tools, call_tx)) - .await - .map_err(|e| format!("JS execution task failed: {e}"))?; - - tool_handler.abort(); - js_result.map(|r| vec![Content::text(format!("Result: {r}"))]) + Ok(vec![Content::text(output.code)]) } - async fn handle_read_module( + /// Handle the execute tool call + async fn handle_execute( &self, session_id: &str, arguments: Option, ) -> Result, String> { - let path = arguments - .as_ref() - .and_then(|a| a.get("module_path")) - .and_then(|v| v.as_str()) - .ok_or("Missing required parameter: module_path")?; + let args: ExecuteWithToolGraph = arguments + .map(|args| serde_json::from_value(Value::Object(args))) + .transpose() + .map_err(|e| format!("Failed to parse arguments: {e}"))? + .ok_or("Missing arguments for execute")?; - let tools = self.get_tool_infos(session_id).await; - let parts: Vec<&str> = path.trim_start_matches('/').split('/').collect(); + let code_mode = self.get_code_mode(session_id).await?; + let registry = self.build_callback_registry(session_id, &code_mode)?; + let code = args.input.code.clone(); - match parts.as_slice() { - [server] => { - let server_tools: Vec<_> = - tools.iter().filter(|t| t.server_name == *server).collect(); - if server_tools.is_empty() { - return Err(format!("Module not found: {server}")); - } - let sigs: Vec<_> = server_tools.iter().map(|t| t.to_signature()).collect(); - Ok(vec![Content::text(format!( - "// import * as {server} from \"{server}\";\n\n{}", - sigs.join("\n") - ))]) - } - [server, tool] => { - let t = tools - .iter() - .find(|t| t.server_name == *server && t.tool_name == *tool) - .ok_or_else(|| format!("Tool not found: {server}/{tool}"))?; - Ok(vec![Content::text(format!( - "// import * as {server} from \"{server}\";\n\n{}\n\n{}", - t.to_signature(), - t.description - ))]) - } - _ => Err(format!( - "Invalid path: {path}. Use 'server' or 'server/tool'" - )), - } + // Deno runtime is not Send, so we need to run it in a blocking task + // with its own tokio runtime + let output = tokio::task::spawn_blocking(move || { + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .map_err(|e| format!("Failed to create runtime: {e}"))?; + + rt.block_on(async move { + code_mode + .execute(&code, Some(registry)) + .await + .map_err(|e| format!("Execution error: {e}")) + }) + }) + .await + .map_err(|e| format!("Execution task failed: {e}"))??; + + Ok(vec![Content::text(output.markdown())]) } +} - async fn handle_search_modules( - &self, - session_id: &str, - arguments: Option, - ) -> Result, String> { - let terms = arguments - .as_ref() - .and_then(|a| a.get("terms")) - .ok_or("Missing required parameter: terms")?; - - let terms_vec = if let Some(arr) = terms.as_array() { - arr.iter() - .filter_map(|v| v.as_str().map(String::from)) - .collect() - } else if let Some(s) = terms.as_str() { - if s.starts_with('[') && s.ends_with(']') { - serde_json::from_str::>(s).unwrap_or_else(|_| vec![s.to_string()]) - } else { - vec![s.to_string()] - } - } else { - return Err("Parameter 'terms' must be a string or array of strings".to_string()); - }; - - if terms_vec.is_empty() { - return Err("Search terms cannot be empty".to_string()); - } - - let use_regex = arguments - .as_ref() - .and_then(|a| a.get("regex")) - .and_then(|v| v.as_bool()) - .unwrap_or(false); - - let tools = self.get_tool_infos(session_id).await; - Self::handle_search(&tools, &terms_vec, use_regex) - } - - fn handle_search( - tools: &[ToolInfo], - terms: &[String], - use_regex: bool, - ) -> Result, String> { - enum Matcher { - Regex(Vec), - Plain(Vec), - } - - let matcher = if use_regex { - let patterns: Result, _> = terms - .iter() - .map(|t| { - Regex::new(&format!("(?i){t}")).map_err(|e| format!("Invalid regex '{t}': {e}")) - }) - .collect(); - Matcher::Regex(patterns?) - } else { - Matcher::Plain(terms.iter().map(|t| t.to_lowercase()).collect()) - }; - - let matches_any = |text: &str| -> bool { - match &matcher { - Matcher::Regex(patterns) => patterns.iter().any(|p| p.is_match(text)), - Matcher::Plain(terms) => { - let lower = text.to_lowercase(); - terms.iter().any(|t| lower.contains(t)) - } - } - }; - - let mut matching_servers: BTreeSet<&str> = BTreeSet::new(); - let mut matching_tools: Vec<&ToolInfo> = Vec::new(); - - for tool in tools { - if matches_any(&tool.server_name) { - matching_servers.insert(&tool.server_name); - } - if matches_any(&tool.tool_name) || matches_any(&tool.description) { - matching_tools.push(tool); - } - } - - if matching_servers.is_empty() && matching_tools.is_empty() { - return Err(format!("No matches found for: {}", terms.join(", "))); - } - - let mut output = String::new(); - - if !matching_servers.is_empty() { - output.push_str("## Matching Servers\n"); - for server in &matching_servers { - let count = tools.iter().filter(|t| t.server_name == *server).count(); - output.push_str(&format!("- {server} ({count} tools)\n")); - } - output.push('\n'); - } - - if !matching_tools.is_empty() { - output.push_str("## Matching Tools\n"); - output.push_str("Use the read_module tool for full signature and import syntax\n\n"); - for tool in &matching_tools { - output.push_str(&format!( - "- {}/{}: {}\n", - tool.server_name, - tool.tool_name, - tool.description.lines().next().unwrap_or("") - )); - } - } - - Ok(vec![Content::text(output)]) - } - - async fn run_tool_handler( - session_id: String, - mut call_rx: mpsc::UnboundedReceiver, - extension_manager: Option>, - ) { - while let Some((tool_name, arguments, response_tx)) = call_rx.recv().await { - let result = match extension_manager.as_ref().and_then(|w| w.upgrade()) { - Some(manager) => { - let tool_call = CallToolRequestParams { - meta: None, - task: None, - name: tool_name.into(), - arguments: serde_json::from_str(&arguments).ok(), - }; - match manager - .dispatch_tool_call(&session_id, tool_call, CancellationToken::new()) - .await - { - Ok(dispatch_result) => match dispatch_result.result.await { - Ok(result) => Ok(if let Some(sc) = &result.structured_content { - serde_json::to_string(sc).unwrap_or_default() - } else { - result - .content - .iter() - .filter_map(|c| match &c.raw { - RawContent::Text(t) => Some(t.text.clone()), - _ => None, - }) - .collect::>() - .join("\n") - }), - Err(e) => Err(format!("Tool error: {}", e.message)), - }, - Err(e) => Err(format!("Dispatch error: {e}")), - } - } - None => Err("Extension manager not available".to_string()), +fn create_tool_callback( + session_id: String, + full_name: String, + manager: Arc, +) -> pctx_code_mode::CallbackFn { + Arc::new(move |args: Option| { + let session_id = session_id.clone(); + let full_name = full_name.clone(); + let manager = manager.clone(); + Box::pin(async move { + let tool_call = CallToolRequestParams { + task: None, + meta: None, + name: full_name.into(), + arguments: args.and_then(|v| v.as_object().cloned()), }; - let _ = response_tx.send(result); - } - } + match manager + .dispatch_tool_call(&session_id, tool_call, None, CancellationToken::new()) + .await + { + Ok(dispatch_result) => match dispatch_result.result.await { + Ok(result) => { + if let Some(sc) = &result.structured_content { + Ok(serde_json::to_value(sc).unwrap_or(Value::Null)) + } else { + let text: String = result + .content + .iter() + .filter_map(|c| match &c.raw { + RawContent::Text(t) => Some(t.text.clone()), + _ => None, + }) + .collect::>() + .join("\n"); + // Try to parse as JSON, otherwise return as string + Ok(serde_json::from_str(&text).unwrap_or(Value::String(text))) + } + } + Err(e) => Err(format!("Tool error: {}", e.message)), + }, + Err(e) => Err(format!("Dispatch error: {e}")), + } + }) as Pin> + Send>> + }) } #[async_trait] @@ -723,113 +306,111 @@ impl McpClientTrait for CodeExecutionClient { .expect("valid schema") } + // Empty schema for list_functions (no parameters) + let empty_schema: JsonObject = serde_json::from_value(json!({ + "type": "object", + "properties": {}, + "required": [] + })) + .expect("valid schema"); + Ok(ListToolsResult { tools: vec![ McpTool::new( - "execute_code".to_string(), + "list_functions".to_string(), indoc! {r#" - Batch multiple MCP tool calls into ONE execution. This is the primary purpose of this tool. - - CRITICAL: Always combine related operations into a single execute_code call. - - WRONG: execute_code to read → execute_code to write (2 calls) - - RIGHT: execute_code that reads AND writes in one script (1 call) - - EXAMPLE - Read file and write to another (ONE call): - ```javascript - import { text_editor } from "developer"; - const content = text_editor({ path: "/path/to/source.md", command: "view" }); - text_editor({ path: "/path/to/dest.md", command: "write", file_text: content }); - record_result({ copied: true }); - ``` - - EXAMPLE - Multiple operations chained: - ```javascript - import { shell, text_editor } from "developer"; - const files = shell({ command: "ls -la" }); - const readme = text_editor({ path: "./README.md", command: "view" }); - const status = shell({ command: "git status" }); - record_result({ files, readme, status }); - ``` - - SYNTAX: - - Import: import { tool1, tool2 } from "serverName"; - - Call: toolName({ param1: value, param2: value }) - - Result: record_result(value) - call this to return a value from the script - - All calls are synchronous, return strings - - TOOL_GRAPH: Always provide tool_graph to describe the execution flow for the UI. - Each node has: tool (server/name), description (what it does), depends_on (indices of dependencies). - Example for chained operations: - [ - {"tool": "developer/shell", "description": "list files", "depends_on": []}, - {"tool": "developer/text_editor", "description": "read README.md", "depends_on": []}, - {"tool": "developer/text_editor", "description": "write output.txt", "depends_on": [0, 1]} - ] - - BEFORE CALLING: Use the read_module tool to check required parameters. + List all available functions across all namespaces. + + This will not return function input and output types. + After determining which functions are needed use + get_function_details to get input and output type + information about specific functions. "#} .to_string(), - schema::(), + empty_schema, ) .annotate(ToolAnnotations { - title: Some("Execute JavaScript".to_string()), + title: Some("List functions".to_string()), + read_only_hint: Some(true), + destructive_hint: Some(false), + idempotent_hint: Some(true), + open_world_hint: Some(false), + }), + McpTool::new( + "get_function_details".to_string(), + indoc! {r#" + Get detailed type information for specific functions. + + Provide a list of function identifiers in the format "Namespace.functionName" + (e.g., "Developer.shell", "Github.create_issue"). + + Returns full TypeScript interface definitions with parameter types, + return types, and descriptions for the requested functions. + "#} + .to_string(), + schema::(), + ) + .annotate(ToolAnnotations { + title: Some("Get function details".to_string()), + read_only_hint: Some(true), + destructive_hint: Some(false), + idempotent_hint: Some(true), + open_world_hint: Some(false), + }), + McpTool::new( + "execute".to_string(), + indoc! {r#" + Execute TypeScript code that calls available functions. + + SYNTAX - TypeScript with async run() function: + ```typescript + async function run() { + // Access functions via Namespace.functionName({ params }) + const files = await Developer.shell({ command: "ls -la" }); + const readme = await Developer.text_editor({ path: "./README.md", command: "view" }); + return { files, readme }; + } + ``` + + TOOL_GRAPH: Always provide tool_graph to describe the execution flow for the UI. + Each node has: tool (Namespace.functionName), description (what it does), depends_on (indices of dependencies). + Example for chained operations: + [ + {"tool": "Developer.shell", "description": "list files", "depends_on": []}, + {"tool": "Developer.textEditor", "description": "read README.md", "depends_on": []}, + {"tool": "Developer.textEditor", "description": "write output.txt", "depends_on": [0, 1]} + ] + + KEY RULES: + - Code MUST define an async function named `run()` + - All function calls are async - use `await` + - Access functions as Namespace.functionName() (e.g., Developer.shell, Github.create_issue) + - Return value from `run()` is the result, all `console.log()` output will be returned as well. + - Only functions from `list_functions()` are available - no `fetch()`, fs, or other Node/Deno APIs + - Variables don't persist between `execute()` calls - return or log anything you need later + - Add console.log() statements between API calls to track progress if errors occur + - Code runs in an isolated Deno sandbox with restricted network access + - If a function returns `any` do not assume it has any particular fields + + TOKEN USAGE WARNING: This tool could return LARGE responses if your code returns big objects. + To minimize tokens: + - Filter/map/reduce data IN YOUR CODE before returning + - Only return specific fields you need (e.g., return {id: result.id, count: items.length}) + - Use console.log() for intermediate results instead of returning everything + - Avoid returning full API responses - extract just what you need + + BEFORE CALLING: Use list_functions or get_function_details to check available functions and their parameters. + "#} + .to_string(), + schema::(), + ) + .annotate(ToolAnnotations { + title: Some("Execute TypeScript".to_string()), read_only_hint: Some(false), destructive_hint: Some(true), idempotent_hint: Some(false), open_world_hint: Some(true), }), - McpTool::new( - "read_module".to_string(), - indoc! {r#" - Read tool definitions to understand how to call them correctly. - - PATHS: - - "serverName" → lists all tools with signatures (shows required vs optional params) - - "serverName/toolName" → full details for one tool including description - - USE THIS BEFORE execute_code when: - - You haven't used a tool before - - You're unsure of parameter names or which are required - - A previous call failed due to missing/wrong parameters - - The signature format is: toolName({ param1: type, param2?: type }): string - Parameters with ? are optional; others are required. - "#} - .to_string(), - schema::(), - ) - .annotate(ToolAnnotations { - title: Some("Read module".to_string()), - read_only_hint: Some(true), - destructive_hint: Some(false), - idempotent_hint: Some(true), - open_world_hint: Some(false), - }), - McpTool::new( - "search_modules".to_string(), - indoc! {r#" - Search for tools by name or description across all available modules. - - USAGE: - - Single term: terms="github" (just a plain string) - - Multiple terms: terms=["git", "shell"] (a JSON array, NOT a string) - - Regex patterns: terms="sh.*", regex=true - - IMPORTANT: Do NOT stringify arrays. Use terms=["a","b"] not terms="[\"a\",\"b\"]" - - Returns matching servers and tools with descriptions. - Use this when you don't know which module contains the tool you need. - "#} - .to_string(), - schema::(), - ) - .annotate(ToolAnnotations { - title: Some("Search modules".to_string()), - read_only_hint: Some(true), - destructive_hint: Some(false), - idempotent_hint: Some(true), - open_world_hint: Some(false), - }), ], next_cursor: None, meta: None, @@ -841,16 +422,20 @@ impl McpClientTrait for CodeExecutionClient { session_id: &str, name: &str, arguments: Option, + _working_dir: Option<&str>, _cancellation_token: CancellationToken, ) -> Result { - let content = match name { - "execute_code" => self.handle_execute_code(session_id, arguments).await, - "read_module" => self.handle_read_module(session_id, arguments).await, - "search_modules" => self.handle_search_modules(session_id, arguments).await, + let result = match name { + "list_functions" => self.handle_list_functions(session_id).await, + "get_function_details" => { + self.handle_get_function_details(session_id, arguments) + .await + } + "execute" => self.handle_execute(session_id, arguments).await, _ => Err(format!("Unknown tool: {name}")), }; - match content { + match result { Ok(content) => Ok(CallToolResult::success(content)), Err(error) => Ok(CallToolResult::error(vec![Content::text(format!( "Error: {error}" @@ -863,431 +448,57 @@ impl McpClientTrait for CodeExecutionClient { } async fn get_moim(&self, session_id: &str) -> Option { - let tools = self.get_tool_infos(session_id).await; - if tools.is_empty() { - return None; - } - - let mut servers: BTreeSet<&str> = BTreeSet::new(); - for tool in &tools { - servers.insert(&tool.server_name); - } - - let server_list: Vec<_> = servers.into_iter().collect(); + let code_mode = self.get_code_mode(session_id).await.ok()?; + let available: Vec<_> = code_mode + .list_functions() + .functions + .iter() + .map(|f| format!("{}.{}", &f.namespace, &f.name)) + .collect(); Some(format!( indoc::indoc! {r#" - ALWAYS batch multiple tool operations into ONE execute_code call. - - WRONG: Separate execute_code calls for read file, then write file - - RIGHT: One execute_code with a script that reads AND writes + ALWAYS batch multiple tool operations into ONE execute call. + - WRONG: Separate execute calls for read file, then write file + - RIGHT: One execute with an async run() function that reads AND writes - Modules: {} + Available namespaces: {} - Use the read_module tool to see signatures before calling unfamiliar tools. + Use the list_functions & get_function_details tools to see tool signatures and input/output types before calling unfamiliar tools. "#}, - server_list.join(", ") + available.join(", ") )) } } -#[cfg(test)] -mod tests { - use super::*; - use std::sync::Arc; - use test_case::test_case; +struct CodeModeState { + code_mode: CodeMode, + hash: u64, +} - #[tokio::test] - async fn test_execute_code_simple() { - let temp_dir = tempfile::tempdir().unwrap(); - let session_manager = Arc::new(crate::session::SessionManager::new( - temp_dir.path().to_path_buf(), - )); - let context = PlatformExtensionContext { - extension_manager: None, - session_manager, - }; - let client = CodeExecutionClient::new(context).unwrap(); +impl CodeModeState { + fn new(cfgs: Vec) -> Result { + let hash = Self::hash(&cfgs); - let mut args = JsonObject::new(); - args.insert( - "code".to_string(), - Value::String("record_result(2 + 2)".to_string()), - ); + let code_mode = CodeMode::default() + .with_callbacks(&cfgs) + .map_err(|e| format!("failed adding callback configs to CodeMode: {e}"))?; - let result = client - .call_tool( - "test-session-id", - "execute_code", - Some(args), - CancellationToken::new(), - ) - .await - .unwrap(); + Ok(Self { code_mode, hash }) + } - assert!(!result.is_error.unwrap_or(false)); - if let RawContent::Text(text) = &result.content[0].raw { - assert_eq!(text.text, "Result: 4"); - } else { - panic!("Expected text content"); + /// Compute order-independent hash of callback configs + fn hash(cfgs: &[CallbackConfig]) -> u64 { + let mut cfg_strings: Vec<_> = cfgs + .iter() + .filter_map(|c| serde_json::to_string(c).ok()) + .collect(); + cfg_strings.sort(); + + let mut hasher = DefaultHasher::new(); + for s in cfg_strings { + s.hash(&mut hasher); } - } - - #[tokio::test] - async fn test_record_result_outputs_valid_json() { - let temp_dir = tempfile::tempdir().unwrap(); - let session_manager = Arc::new(crate::session::SessionManager::new( - temp_dir.path().to_path_buf(), - )); - let context = PlatformExtensionContext { - extension_manager: None, - session_manager, - }; - let client = CodeExecutionClient::new(context).unwrap(); - - // Nested array in object - this triggers truncation with display() (e.g., "items: Array(3)") - let mut args = JsonObject::new(); - args.insert( - "code".to_string(), - Value::String("record_result({items: [1, 2, 3], count: 3})".to_string()), - ); - - let result = client - .call_tool( - "test-session-id", - "execute_code", - Some(args), - CancellationToken::new(), - ) - .await - .unwrap(); - - assert!(!result.is_error.unwrap_or(false)); - if let RawContent::Text(text) = &result.content[0].raw { - let json_str = text.text.strip_prefix("Result: ").unwrap_or(&text.text); - let parsed: serde_json::Value = serde_json::from_str(json_str) - .unwrap_or_else(|_| panic!("Output should be valid JSON, got: {}", text.text)); - assert_eq!(parsed["items"].as_array().unwrap().len(), 3); - assert_eq!(parsed["count"], 3); - } else { - panic!("Expected text content"); - } - } - - #[tokio::test] - async fn test_read_module_not_found() { - let temp_dir = tempfile::tempdir().unwrap(); - let session_manager = Arc::new(crate::session::SessionManager::new( - temp_dir.path().to_path_buf(), - )); - let context = PlatformExtensionContext { - extension_manager: None, - session_manager, - }; - let client = CodeExecutionClient::new(context).unwrap(); - - let mut args = JsonObject::new(); - args.insert( - "module_path".to_string(), - Value::String("nonexistent".to_string()), - ); - - let result = client - .handle_read_module("test-session-id", Some(args)) - .await; - assert!(result.is_err()); - } - - #[test] - fn test_search_plain_text() { - let tools = vec![ - ToolInfo { - server_name: "developer".to_string(), - tool_name: "shell".to_string(), - full_name: "developer__shell".to_string(), - description: "Execute shell commands".to_string(), - params: vec![("command".to_string(), "string".to_string(), true)], - return_type: "string".to_string(), - }, - ToolInfo { - server_name: "developer".to_string(), - tool_name: "text_editor".to_string(), - full_name: "developer__text_editor".to_string(), - description: "Edit text files".to_string(), - params: vec![("path".to_string(), "string".to_string(), true)], - return_type: "string".to_string(), - }, - ToolInfo { - server_name: "git".to_string(), - tool_name: "commit".to_string(), - full_name: "git__commit".to_string(), - description: "Commit changes to git".to_string(), - params: vec![("message".to_string(), "string".to_string(), true)], - return_type: "string".to_string(), - }, - ]; - - // Search for "shell" - should match tool name - let result = - CodeExecutionClient::handle_search(&tools, &["shell".to_string()], false).unwrap(); - let text = match &result[0].raw { - RawContent::Text(t) => &t.text, - _ => panic!("Expected text"), - }; - assert!(text.contains("developer/shell")); - assert!(!text.contains("git/commit")); - - // Search for "developer" - should match server name - let result = - CodeExecutionClient::handle_search(&tools, &["developer".to_string()], false).unwrap(); - let text = match &result[0].raw { - RawContent::Text(t) => &t.text, - _ => panic!("Expected text"), - }; - assert!(text.contains("developer (2 tools)")); - - // Search for "edit" - should match description - let result = - CodeExecutionClient::handle_search(&tools, &["edit".to_string()], false).unwrap(); - let text = match &result[0].raw { - RawContent::Text(t) => &t.text, - _ => panic!("Expected text"), - }; - assert!(text.contains("developer/text_editor")); - - // Search for multiple terms - let result = CodeExecutionClient::handle_search( - &tools, - &["shell".to_string(), "git".to_string()], - false, - ) - .unwrap(); - let text = match &result[0].raw { - RawContent::Text(t) => &t.text, - _ => panic!("Expected text"), - }; - assert!(text.contains("developer/shell")); - assert!(text.contains("git/commit")); - - // Search with no matches - let result = - CodeExecutionClient::handle_search(&tools, &["nonexistent".to_string()], false); - assert!(result.is_err()); - } - - #[test] - fn test_search_regex() { - let tools = vec![ - ToolInfo { - server_name: "developer".to_string(), - tool_name: "shell".to_string(), - full_name: "developer__shell".to_string(), - description: "Execute shell commands".to_string(), - params: vec![], - return_type: "string".to_string(), - }, - ToolInfo { - server_name: "developer".to_string(), - tool_name: "text_editor".to_string(), - full_name: "developer__text_editor".to_string(), - description: "Edit text files".to_string(), - params: vec![], - return_type: "string".to_string(), - }, - ]; - - // Regex search for "sh.*" - should match shell - let result = - CodeExecutionClient::handle_search(&tools, &["sh.*".to_string()], true).unwrap(); - let text = match &result[0].raw { - RawContent::Text(t) => &t.text, - _ => panic!("Expected text"), - }; - assert!(text.contains("developer/shell")); - - // Regex search for "^text" - should match text_editor - let result = - CodeExecutionClient::handle_search(&tools, &["^text".to_string()], true).unwrap(); - let text = match &result[0].raw { - RawContent::Text(t) => &t.text, - _ => panic!("Expected text"), - }; - assert!(text.contains("developer/text_editor")); - - // Invalid regex should error - let result = CodeExecutionClient::handle_search(&tools, &["[invalid".to_string()], true); - assert!(result.is_err()); - assert!(result.unwrap_err().contains("Invalid regex")); - } - - #[test_case( - "github__get_me", - serde_json::json!({"type": "object", "properties": {}}), - None, - "github[\"get_me\"]({}): string - Get details of the authenticated user"; - "no params, no output schema" - )] - #[test_case( - "filesystem__read_text_file", - serde_json::json!({"type": "object", "properties": {"path": {"type": "string"}, "tail": {"type": "number"}, "head": {"type": "number"}}, "required": ["path"]}), - Some(serde_json::json!({"type": "object", "properties": {"content": {"type": "string"}}, "required": ["content"]})), - "filesystem[\"read_text_file\"]({head?: number, path: string, tail?: number}): { content: string } - Read the complete contents of a file"; - "optional number params, object output" - )] - #[test_case( - "memory__create_entities", - serde_json::json!({"type": "object", "properties": {"entities": {"type": "array", "items": {"type": "object", "properties": {"name": {"type": "string"}, "entityType": {"type": "string"}, "observations": {"type": "array", "items": {"type": "string"}}}, "required": ["name", "entityType", "observations"]}}}, "required": ["entities"]}), - Some(serde_json::json!({"type": "object", "properties": {"entities": {"type": "array", "items": {"type": "object", "properties": {"name": {"type": "string"}, "entityType": {"type": "string"}, "observations": {"type": "array", "items": {"type": "string"}}}, "required": ["name", "entityType", "observations"]}}}, "required": ["entities"]})), - "memory[\"create_entities\"]({entities: { entityType: string, name: string, observations: string[] }[]}): { entities: { entityType: string, name: string, observations: string[] }[] } - Create multiple new entities"; - "nested object array with typed props" - )] - #[test_case( - "github__dismiss_notification", - serde_json::json!({"type": "object", "properties": { - "threadID": {"type": "string"}, - "state": {"type": "string", "enum": ["read", "done"]} - }, "required": ["threadID", "state"]}), - None, - "github[\"dismiss_notification\"]({state: \"read\" | \"done\", threadID: string}): string - Dismiss a notification"; - "enum param, no output schema" - )] - #[test_case( - "computercontroller__web_scrape", - serde_json::json!({"type": "object", "properties": { - "url": {"type": "string"}, - "save_as": {"oneOf": [{"const": "text"}, {"const": "json"}, {"const": "binary"}]} - }, "required": ["url"]}), - None, - "computercontroller[\"web_scrape\"]({save_as?: \"text\" | \"json\" | \"binary\", url: string}): string - Scrape content from URL"; - "oneOf const param (schemars), no output schema" - )] - #[test_case( - "kiwitravel__search-flight", - serde_json::json!({"type": "object", "properties": { - "flyFrom": {"type": "string"}, - "flyTo": {"type": "string"}, - "departureDate": {"type": "string"} - }, "required": ["flyFrom", "flyTo", "departureDate"]}), - None, - "kiwitravel[\"search-flight\"]({departureDate: string, flyFrom: string, flyTo: string}): string - Search for flights"; - "hyphenated tool name uses bracket notation" - )] - fn test_mcp_tool_signature( - name: &str, - input: serde_json::Value, - output: Option, - expected: &str, - ) { - let input_schema: serde_json::Map = - serde_json::from_value(input).unwrap(); - let output_schema = output.map(|v| { - Arc::new( - serde_json::from_value::>(v).unwrap(), - ) - }); - let desc = expected.split(" - ").nth(1).unwrap_or("").to_string(); - let tool = McpTool { - name: name.to_string().into(), - title: None, - description: Some(desc.into()), - input_schema: Arc::new(input_schema), - output_schema, - annotations: None, - icons: None, - meta: None, - }; - let info = ToolInfo::from_mcp_tool(&tool).unwrap(); - assert_eq!(info.to_signature(), expected); - } - - #[test_case(serde_json::json!({"type": "string"}), "string"; "string")] - #[test_case(serde_json::json!({"type": "number"}), "number"; "number")] - #[test_case(serde_json::json!({"type": "boolean"}), "boolean"; "boolean")] - #[test_case(serde_json::json!({"type": "array"}), "array"; "array bare")] - #[test_case(serde_json::json!({"type": "array", "items": {"type": "string"}}), "string[]"; "array with items")] - #[test_case(serde_json::json!({"type": "object"}), "object"; "object bare")] - #[test_case(serde_json::json!({"type": "object", "properties": {"a": {"type": "string"}}, "required": ["a"]}), "{ a: string }"; "object with prop")] - #[test_case(serde_json::json!({"type": "object", "properties": {"a": {"type": "string"}}}), "{ a?: string }"; "object optional prop")] - #[test_case(serde_json::json!({"type": "object", "properties": {"a": {"type": "array", "items": {"type": "string"}}}, "required": ["a"]}), "{ a: string[] }"; "object with array prop")] - #[test_case(serde_json::json!({"enum": ["a", "b"]}), "\"a\" | \"b\""; "enum array")] - #[test_case(serde_json::json!({"oneOf": [{"const": "x"}, {"const": "y"}]}), "\"x\" | \"y\""; "oneOf const")] - fn test_extract_type_from_schema(schema: serde_json::Value, expected: &str) { - assert_eq!( - extract_type_from_schema(&schema), - Some(expected.to_string()) - ); - } - - fn eval_with_tools(code: &str, tools: &[(&str, &str)]) -> String { - let mut ctx = Context::default(); - for &(name, response) in tools { - let resp = response.to_string(); - let func = NativeFunction::from_copy_closure_with_captures( - |_this, _args, resp: &String, ctx| Ok(parse_result_to_js(resp, ctx)), - resp, - ); - ctx.register_global_callable(js_string!(name), 0, func) - .unwrap(); - } - ctx.eval(Source::from_bytes(code)) - .unwrap() - .display() - .to_string() - } - - #[test_case("2 + 2", &[], "4"; "pure_js")] - #[test_case("get_data({}).content", &[("get_data", r#"{"content":"hello"}"#)], "\"hello\""; "structured_property_access")] - #[test_case("typeof shell({})", &[("shell", "plain text")], "\"string\""; "plain_text_is_string")] - #[test_case("shell({}).content", &[("shell", "plain text")], "undefined"; "plain_text_no_property")] - fn test_tool_result(code: &str, tools: &[(&str, &str)], expected: &str) { - assert_eq!(eval_with_tools(code, tools), expected); - } - - #[test] - fn test_namespace_import_with_synthetic_module() { - let tools = vec![ToolInfo { - server_name: "testserver".to_string(), - tool_name: "get_value".to_string(), - full_name: "testserver__get_value".to_string(), - description: "Get a value".to_string(), - params: vec![], - return_type: "string".to_string(), - }]; - - let (tx, _rx) = mpsc::unbounded_channel(); - - let code_named = r#"import { get_value } from "testserver"; typeof get_value"#; - let result = run_js_module(code_named, &tools, tx.clone()); - assert!( - result.is_ok(), - "Named import should work: {:?}", - result.err() - ); - - let code_namespace = - r#"import * as testserver from "testserver"; typeof testserver.get_value"#; - let result = run_js_module(code_namespace, &tools, tx.clone()); - assert!( - result.is_ok(), - "Namespace import should work: {:?}", - result.err() - ); - - let code_server_named = - r#"import { testserver } from "testserver"; typeof testserver.get_value"#; - let result = run_js_module(code_server_named, &tools, tx.clone()); - assert!( - result.is_ok(), - "Server-named import should work: {:?}", - result.err() - ); - - let code_bracket = - r#"import { testserver } from "testserver"; typeof testserver["get_value"]"#; - let result = run_js_module(code_bracket, &tools, tx); - assert!( - result.is_ok(), - "Bracket notation should work: {:?}", - result.err() - ); + hasher.finish() } } diff --git a/crates/goose/src/agents/extension_manager.rs b/crates/goose/src/agents/extension_manager.rs index 060134d753..5a1fb799c1 100644 --- a/crates/goose/src/agents/extension_manager.rs +++ b/crates/goose/src/agents/extension_manager.rs @@ -624,16 +624,6 @@ impl ExtensionManager { .await?; Box::new(client) } else { - // Set GOOSE_WORKING_DIR in the current process for builtin extensions - // since they run in-process and read from std::env::var - if effective_working_dir.exists() && effective_working_dir.is_dir() { - std::env::set_var("GOOSE_WORKING_DIR", &effective_working_dir); - tracing::info!( - "Set GOOSE_WORKING_DIR for builtin extension: {:?}", - effective_working_dir - ); - } - let (server_read, client_write) = tokio::io::duplex(65536); let (client_read, server_write) = tokio::io::duplex(65536); extension_fn(server_read, server_write); @@ -1297,6 +1287,7 @@ impl ExtensionManager { &self, session_id: &str, tool_call: CallToolRequestParams, + working_dir: Option<&std::path::Path>, cancellation_token: CancellationToken, ) -> Result { let tool_name_str = tool_call.name.to_string(); @@ -1324,12 +1315,14 @@ impl ExtensionManager { let notifications_receiver = client.lock().await.subscribe().await; let session_id = session_id.to_string(); let actual_tool_name = resolved.actual_tool_name; + let working_dir_str = working_dir.map(|p| p.to_string_lossy().to_string()); let fut = async move { tracing::debug!( - "dispatch_tool_call: calling client.call_tool tool={} session_id={}", + "dispatch_tool_call: calling client.call_tool tool={} session_id={} working_dir={:?}", actual_tool_name, - session_id + session_id, + working_dir_str ); let client_guard = client.lock().await; client_guard @@ -1337,6 +1330,7 @@ impl ExtensionManager { &session_id, &actual_tool_name, arguments, + working_dir_str.as_deref(), cancellation_token, ) .await @@ -1672,6 +1666,7 @@ mod tests { _session_id: &str, name: &str, _arguments: Option, + _working_dir: Option<&str>, _cancellation_token: CancellationToken, ) -> Result { match name { @@ -1745,7 +1740,12 @@ mod tests { }; let result = extension_manager - .dispatch_tool_call("test-session-id", tool_call, CancellationToken::default()) + .dispatch_tool_call( + "test-session-id", + tool_call, + None, + CancellationToken::default(), + ) .await; assert!(result.is_ok()); @@ -1757,7 +1757,12 @@ mod tests { }; let result = extension_manager - .dispatch_tool_call("test-session-id", tool_call, CancellationToken::default()) + .dispatch_tool_call( + "test-session-id", + tool_call, + None, + CancellationToken::default(), + ) .await; assert!(result.is_ok()); @@ -1769,7 +1774,12 @@ mod tests { }; let result = extension_manager - .dispatch_tool_call("test-session-id", tool_call, CancellationToken::default()) + .dispatch_tool_call( + "test-session-id", + tool_call, + None, + CancellationToken::default(), + ) .await; assert!(result.is_ok()); @@ -1781,7 +1791,12 @@ mod tests { }; let result = extension_manager - .dispatch_tool_call("test-session-id", tool_call, CancellationToken::default()) + .dispatch_tool_call( + "test-session-id", + tool_call, + None, + CancellationToken::default(), + ) .await; assert!(result.is_ok()); @@ -1796,6 +1811,7 @@ mod tests { .dispatch_tool_call( "test-session-id", invalid_tool_call, + None, CancellationToken::default(), ) .await; @@ -1817,6 +1833,7 @@ mod tests { .dispatch_tool_call( "test-session-id", invalid_tool_call, + None, CancellationToken::default(), ) .await; @@ -1918,6 +1935,7 @@ mod tests { .dispatch_tool_call( "test-session-id", unavailable_tool_call, + None, CancellationToken::default(), ) .await; @@ -1941,6 +1959,7 @@ mod tests { .dispatch_tool_call( "test-session-id", available_tool_call, + None, CancellationToken::default(), ) .await; diff --git a/crates/goose/src/agents/extension_manager_extension.rs b/crates/goose/src/agents/extension_manager_extension.rs index cf163e4d8c..e3bf0e59cd 100644 --- a/crates/goose/src/agents/extension_manager_extension.rs +++ b/crates/goose/src/agents/extension_manager_extension.rs @@ -435,6 +435,7 @@ impl McpClientTrait for ExtensionManagerClient { session_id: &str, name: &str, arguments: Option, + _working_dir: Option<&str>, _cancellation_token: CancellationToken, ) -> Result { let result = match name { diff --git a/crates/goose/src/agents/mcp_client.rs b/crates/goose/src/agents/mcp_client.rs index a1dfed242e..19ec157992 100644 --- a/crates/goose/src/agents/mcp_client.rs +++ b/crates/goose/src/agents/mcp_client.rs @@ -1,6 +1,6 @@ use crate::action_required_manager::ActionRequiredManager; use crate::agents::types::SharedProvider; -use crate::session_context::SESSION_ID_HEADER; +use crate::session_context::{SESSION_ID_HEADER, WORKING_DIR_HEADER}; use rmcp::model::{ Content, CreateElicitationRequestParams, CreateElicitationResult, ElicitationAction, ErrorCode, Extensions, JsonObject, Meta, @@ -51,6 +51,7 @@ pub trait McpClientTrait: Send + Sync { session_id: &str, name: &str, arguments: Option, + working_dir: Option<&str>, cancel_token: CancellationToken, ) -> Result; @@ -105,7 +106,7 @@ pub trait McpClientTrait: Send + Sync { pub struct GooseClient { notification_handlers: Arc>>>, provider: SharedProvider, - // Single-slot because calls are serialized per MCP client; see send_request_with_session. + // Single-slot because calls are serialized per MCP client. current_session_id: Arc>>, } @@ -386,13 +387,14 @@ impl McpClient { self.docker_container.as_deref() } - async fn send_request_with_session( + async fn send_request_with_context( &self, session_id: &str, + working_dir: Option<&str>, request: ClientRequest, cancel_token: CancellationToken, ) -> Result { - let request = inject_session_id_into_request(request, Some(session_id)); + let request = inject_session_context_into_request(request, Some(session_id), working_dir); // ExtensionManager serializes calls per MCP connection, so one current_session_id slot // is sufficient for mapping callbacks to the active request session. let handle = { @@ -473,8 +475,9 @@ impl McpClientTrait for McpClient { cancel_token: CancellationToken, ) -> Result { let res = self - .send_request_with_session( + .send_request_with_context( session_id, + None, ClientRequest::ListResourcesRequest(ListResourcesRequest { params: Some(PaginatedRequestParams { meta: None, cursor }), method: Default::default(), @@ -497,8 +500,9 @@ impl McpClientTrait for McpClient { cancel_token: CancellationToken, ) -> Result { let res = self - .send_request_with_session( + .send_request_with_context( session_id, + None, ClientRequest::ReadResourceRequest(ReadResourceRequest { params: ReadResourceRequestParams { meta: None, @@ -524,8 +528,9 @@ impl McpClientTrait for McpClient { cancel_token: CancellationToken, ) -> Result { let res = self - .send_request_with_session( + .send_request_with_context( session_id, + None, ClientRequest::ListToolsRequest(ListToolsRequest { params: Some(PaginatedRequestParams { meta: None, cursor }), method: Default::default(), @@ -546,6 +551,7 @@ impl McpClientTrait for McpClient { session_id: &str, name: &str, arguments: Option, + working_dir: Option<&str>, cancel_token: CancellationToken, ) -> Result { let request = ClientRequest::CallToolRequest(CallToolRequest { @@ -560,7 +566,7 @@ impl McpClientTrait for McpClient { }); let result = self - .send_request_with_session(session_id, request, cancel_token) + .send_request_with_context(session_id, working_dir, request, cancel_token) .await; match result? { @@ -576,8 +582,9 @@ impl McpClientTrait for McpClient { cancel_token: CancellationToken, ) -> Result { let res = self - .send_request_with_session( + .send_request_with_context( session_id, + None, ClientRequest::ListPromptsRequest(ListPromptsRequest { params: Some(PaginatedRequestParams { meta: None, cursor }), method: Default::default(), @@ -605,8 +612,9 @@ impl McpClientTrait for McpClient { _ => None, }; let res = self - .send_request_with_session( + .send_request_with_context( session_id, + None, ClientRequest::GetPromptRequest(GetPromptRequest { params: GetPromptRequestParams { meta: None, @@ -633,20 +641,24 @@ impl McpClientTrait for McpClient { } } -/// Injects the given session_id into Extensions._meta. -/// None (or empty) removes any existing session id. -fn inject_session_id_into_extensions( +/// Injects the given session_id and working_dir into Extensions._meta. +/// None (or empty) removes any existing values. +fn inject_session_context_into_extensions( mut extensions: Extensions, session_id: Option<&str>, + working_dir: Option<&str>, ) -> Extensions { let session_id = session_id.filter(|id| !id.is_empty()); + let working_dir = working_dir.filter(|dir| !dir.is_empty()); let mut meta_map = extensions .get::() .map(|meta| meta.0.clone()) .unwrap_or_default(); // JsonObject is case-sensitive, so we use retain for case-insensitive removal - meta_map.retain(|k, _| !k.eq_ignore_ascii_case(SESSION_ID_HEADER)); + meta_map.retain(|k, _| { + !k.eq_ignore_ascii_case(SESSION_ID_HEADER) && !k.eq_ignore_ascii_case(WORKING_DIR_HEADER) + }); if let Some(session_id) = session_id { meta_map.insert( @@ -655,37 +667,51 @@ fn inject_session_id_into_extensions( ); } + if let Some(working_dir) = working_dir { + meta_map.insert( + WORKING_DIR_HEADER.to_string(), + Value::String(working_dir.to_string()), + ); + } + extensions.insert(Meta(meta_map)); extensions } -fn inject_session_id_into_request( +fn inject_session_context_into_request( request: ClientRequest, session_id: Option<&str>, + working_dir: Option<&str>, ) -> ClientRequest { match request { ClientRequest::ListResourcesRequest(mut req) => { - req.extensions = inject_session_id_into_extensions(req.extensions, session_id); + req.extensions = + inject_session_context_into_extensions(req.extensions, session_id, working_dir); ClientRequest::ListResourcesRequest(req) } ClientRequest::ReadResourceRequest(mut req) => { - req.extensions = inject_session_id_into_extensions(req.extensions, session_id); + req.extensions = + inject_session_context_into_extensions(req.extensions, session_id, working_dir); ClientRequest::ReadResourceRequest(req) } ClientRequest::ListToolsRequest(mut req) => { - req.extensions = inject_session_id_into_extensions(req.extensions, session_id); + req.extensions = + inject_session_context_into_extensions(req.extensions, session_id, working_dir); ClientRequest::ListToolsRequest(req) } ClientRequest::CallToolRequest(mut req) => { - req.extensions = inject_session_id_into_extensions(req.extensions, session_id); + req.extensions = + inject_session_context_into_extensions(req.extensions, session_id, working_dir); ClientRequest::CallToolRequest(req) } ClientRequest::ListPromptsRequest(mut req) => { - req.extensions = inject_session_id_into_extensions(req.extensions, session_id); + req.extensions = + inject_session_context_into_extensions(req.extensions, session_id, working_dir); ClientRequest::ListPromptsRequest(req) } ClientRequest::GetPromptRequest(mut req) => { - req.extensions = inject_session_id_into_extensions(req.extensions, session_id); + req.extensions = + inject_session_context_into_extensions(req.extensions, session_id, working_dir); ClientRequest::GetPromptRequest(req) } other => other, @@ -814,7 +840,8 @@ mod tests { *slot = Some(session_id.to_string()); } - let extensions = inject_session_id_into_extensions(Extensions::new(), ext_session); + let extensions = + inject_session_context_into_extensions(Extensions::new(), ext_session, None); let resolved = client.resolve_session_id(&extensions).await; @@ -830,8 +857,6 @@ mod tests { #[test_case(list_prompts_request; "list_prompts")] #[test_case(get_prompt_request; "get_prompt")] fn test_request_injects_session(request_builder: fn(Extensions) -> ClientRequest) { - use serde_json::json; - let session_id = "test-session-id"; let mut extensions = Extensions::new(); extensions.insert( @@ -843,7 +868,7 @@ mod tests { ); let request = request_builder(extensions); - let request = inject_session_id_into_request(request, Some(session_id)); + let request = inject_session_context_into_request(request, Some(session_id), None); let extensions = request_extensions(&request).expect("request should have extensions"); let meta = extensions .get::() @@ -861,10 +886,9 @@ mod tests { #[test] fn test_session_id_in_mcp_meta() { - use serde_json::json; - let session_id = "test-session-789"; - let extensions = inject_session_id_into_extensions(Default::default(), Some(session_id)); + let extensions = + inject_session_context_into_extensions(Default::default(), Some(session_id), None); let mcp_meta = extensions.get::().unwrap(); assert_eq!( @@ -904,7 +928,7 @@ mod tests { expected_meta: serde_json::Value, ) { use rmcp::model::Extensions; - use serde_json::{from_value, json}; + use serde_json::from_value; let mut extensions = Extensions::new(); extensions.insert( @@ -916,7 +940,7 @@ mod tests { .unwrap(), ); - let extensions = inject_session_id_into_extensions(extensions, session_id); + let extensions = inject_session_context_into_extensions(extensions, session_id, None); let mcp_meta = extensions.get::().unwrap(); assert_eq!(&mcp_meta.0, expected_meta.as_object().unwrap()); diff --git a/crates/goose/src/agents/mod.rs b/crates/goose/src/agents/mod.rs index c5ec4f5802..7ff0407a2a 100644 --- a/crates/goose/src/agents/mod.rs +++ b/crates/goose/src/agents/mod.rs @@ -32,5 +32,6 @@ pub use execute_commands::COMPACT_TRIGGERS; pub use extension::ExtensionConfig; pub use extension_manager::ExtensionManager; pub use prompt_manager::PromptManager; +pub use subagent_handler::SUBAGENT_TOOL_REQUEST_TYPE; pub use subagent_task_config::TaskConfig; pub use types::{FrontendTool, RetryConfig, SessionConfig, SuccessCheck}; diff --git a/crates/goose/src/agents/subagent_handler.rs b/crates/goose/src/agents/subagent_handler.rs index e81186149a..fd23d20d0a 100644 --- a/crates/goose/src/agents/subagent_handler.rs +++ b/crates/goose/src/agents/subagent_handler.rs @@ -1,12 +1,18 @@ use crate::{ agents::{subagent_task_config::TaskConfig, Agent, AgentConfig, AgentEvent, SessionConfig}, - conversation::{message::Message, Conversation}, + conversation::{ + message::{Message, MessageContent}, + Conversation, + }, prompt_template::render_template, recipe::Recipe, }; use anyhow::{anyhow, Result}; use futures::StreamExt; -use rmcp::model::{ErrorCode, ErrorData}; +use rmcp::model::{ + ErrorCode, ErrorData, LoggingLevel, LoggingMessageNotification, + LoggingMessageNotificationMethod, LoggingMessageNotificationParam, ServerNotification, +}; use serde::Serialize; use std::future::Future; use std::pin::Pin; @@ -17,7 +23,7 @@ use tracing::{debug, info}; pub type OnMessageCallback = Arc; #[derive(Serialize)] -pub(crate) struct SubagentPromptContext { +pub struct SubagentPromptContext { pub max_turns: usize, pub subagent_id: String, pub task_instructions: String, @@ -36,7 +42,7 @@ pub async fn run_complete_subagent_task( session_id: String, cancellation_token: Option, ) -> Result { - run_subagent_task_with_callback( + run_complete_subagent_task_with_notifications( config, recipe, task_config, @@ -57,7 +63,7 @@ pub async fn run_subagent_task_with_callback( cancellation_token: Option, on_message: Option, ) -> Result { - let (messages, final_output) = get_agent_messages( + let (messages, final_output) = get_agent_messages_with_callback( config, recipe, task_config, @@ -78,7 +84,44 @@ pub async fn run_subagent_task_with_callback( return Ok(output); } - let response_text = if return_last_only { + Ok(extract_response_text(&messages, return_last_only)) +} + +pub async fn run_complete_subagent_task_with_notifications( + config: AgentConfig, + recipe: Recipe, + task_config: TaskConfig, + return_last_only: bool, + session_id: String, + cancellation_token: Option, + notification_tx: Option>, +) -> Result { + let (messages, final_output) = get_agent_messages_with_notifications( + config, + recipe, + task_config, + session_id, + cancellation_token, + notification_tx, + ) + .await + .map_err(|e| { + ErrorData::new( + ErrorCode::INTERNAL_ERROR, + format!("Failed to execute task: {}", e), + None, + ) + })?; + + if let Some(output) = final_output { + return Ok(output); + } + + Ok(extract_response_text(&messages, return_last_only)) +} + +fn extract_response_text(messages: &Conversation, return_last_only: bool) -> String { + if return_last_only { messages .messages() .last() @@ -129,12 +172,12 @@ pub async fn run_subagent_task_with_callback( .collect(); all_text_content.join("\n") - }; - - Ok(response_text) + } } -fn get_agent_messages( +pub const SUBAGENT_TOOL_REQUEST_TYPE: &str = "subagent_tool_request"; + +fn get_agent_messages_with_callback( config: AgentConfig, recipe: Recipe, task_config: TaskConfig, @@ -152,11 +195,11 @@ fn get_agent_messages( let agent = Arc::new(Agent::with_config(config)); agent - .update_provider(task_config.provider, &session_id) + .update_provider(task_config.provider.clone(), &session_id) .await .map_err(|e| anyhow!("Failed to set provider on sub agent: {}", e))?; - for extension in task_config.extensions { + for extension in &task_config.extensions { if let Err(e) = agent.add_extension(extension.clone(), &session_id).await { debug!( "Failed to add extension '{}' to subagent: {}", @@ -171,24 +214,8 @@ fn get_agent_messages( .apply_recipe_components(recipe.response.clone(), true) .await; - let tools = agent.list_tools(&session_id, None).await; - let subagent_prompt = render_template( - "subagent_system.md", - &SubagentPromptContext { - max_turns: task_config - .max_turns - .expect("TaskConfig always sets max_turns"), - subagent_id: session_id.clone(), - task_instructions: system_instructions, - tool_count: tools.len(), - available_tools: tools - .iter() - .map(|t| t.name.to_string()) - .collect::>() - .join(", "), - }, - ) - .map_err(|e| anyhow!("Failed to render subagent system prompt: {}", e))?; + let subagent_prompt = + build_subagent_prompt(&agent, &task_config, &session_id, system_instructions).await?; agent.override_system_prompt(subagent_prompt).await; let user_message = Message::user().with_text(user_task); @@ -206,10 +233,15 @@ fn get_agent_messages( retry_config: recipe.retry, }; - let mut stream = agent - .reply(user_message, session_config, cancellation_token) + let mut stream = + crate::session_context::with_session_id(Some(session_id.to_string()), async { + agent + .reply(user_message, session_config, cancellation_token) + .await + }) .await .map_err(|e| anyhow!("Failed to get reply from agent: {}", e))?; + while let Some(message_result) = stream.next().await { match message_result { Ok(AgentEvent::Message(msg)) => { @@ -229,17 +261,248 @@ fn get_agent_messages( } } - let final_output = if has_response_schema { - agent - .final_output_tool - .lock() - .await - .as_ref() - .and_then(|tool| tool.final_output.clone()) - } else { - None - }; + let final_output = get_final_output(&agent, has_response_schema).await; Ok((conversation, final_output)) }) } + +fn get_agent_messages_with_notifications( + config: AgentConfig, + recipe: Recipe, + task_config: TaskConfig, + session_id: String, + cancellation_token: Option, + notification_tx: Option>, +) -> AgentMessagesFuture { + Box::pin(async move { + let system_instructions = recipe.instructions.clone().unwrap_or_default(); + let user_task = recipe + .prompt + .clone() + .unwrap_or_else(|| "Begin.".to_string()); + + let agent = Arc::new(Agent::with_config(config)); + + agent + .update_provider(task_config.provider.clone(), &session_id) + .await + .map_err(|e| anyhow!("Failed to set provider on sub agent: {}", e))?; + + for extension in &task_config.extensions { + if let Err(e) = agent.add_extension(extension.clone(), &session_id).await { + debug!( + "Failed to add extension '{}' to subagent: {}", + extension.name(), + e + ); + } + } + + let has_response_schema = recipe.response.is_some(); + agent + .apply_recipe_components(recipe.response.clone(), true) + .await; + + let subagent_prompt = + build_subagent_prompt(&agent, &task_config, &session_id, system_instructions).await?; + agent.override_system_prompt(subagent_prompt).await; + + let user_message = Message::user().with_text(user_task); + let mut conversation = Conversation::new_unvalidated(vec![user_message.clone()]); + + if let Some(activities) = recipe.activities { + for activity in activities { + info!("Recipe activity: {}", activity); + } + } + let session_config = SessionConfig { + id: session_id.clone(), + schedule_id: None, + max_turns: task_config.max_turns.map(|v| v as u32), + retry_config: recipe.retry, + }; + + conversation = run_subagent_stream( + agent.clone(), + user_message, + session_config, + cancellation_token, + &session_id, + ¬ification_tx, + conversation, + ) + .await?; + + let final_output = get_final_output(&agent, has_response_schema).await; + + Ok((conversation, final_output)) + }) +} + +async fn build_subagent_prompt( + agent: &Agent, + task_config: &TaskConfig, + session_id: &str, + system_instructions: String, +) -> Result { + let tools = agent.list_tools(session_id, None).await; + render_template( + "subagent_system.md", + &SubagentPromptContext { + max_turns: task_config + .max_turns + .expect("TaskConfig always sets max_turns"), + subagent_id: session_id.to_string(), + task_instructions: system_instructions, + tool_count: tools.len(), + available_tools: tools + .iter() + .map(|t| t.name.to_string()) + .collect::>() + .join(", "), + }, + ) + .map_err(|e| anyhow!("Failed to render subagent system prompt: {}", e)) +} + +async fn run_subagent_stream( + agent: Arc, + user_message: Message, + session_config: SessionConfig, + cancellation_token: Option, + session_id: &str, + notification_tx: &Option>, + mut conversation: Conversation, +) -> Result { + let mut stream = crate::session_context::with_session_id(Some(session_id.to_string()), async { + agent + .reply(user_message, session_config, cancellation_token) + .await + }) + .await + .map_err(|e| anyhow!("Failed to get reply from agent: {}", e))?; + + while let Some(message_result) = stream.next().await { + match message_result { + Ok(AgentEvent::Message(msg)) => { + if let Some(ref tx) = notification_tx { + for content in &msg.content { + if let Some(notif) = create_tool_notification(content, session_id) { + if tx.send(notif).is_err() { + debug!("Notification receiver dropped for subagent {}", session_id); + } + } + } + } + conversation.push(msg); + } + Ok(AgentEvent::McpNotification(_)) => {} + Ok(AgentEvent::ModelChange { .. }) => {} + Ok(AgentEvent::HistoryReplaced(updated_conversation)) => { + conversation = updated_conversation; + } + Err(e) => { + tracing::error!("Error receiving message from subagent: {}", e); + break; + } + } + } + + Ok(conversation) +} + +async fn get_final_output(agent: &Agent, has_response_schema: bool) -> Option { + if has_response_schema { + agent + .final_output_tool + .lock() + .await + .as_ref() + .and_then(|tool| tool.final_output.clone()) + } else { + None + } +} + +fn create_tool_notification( + content: &MessageContent, + subagent_id: &str, +) -> Option { + if let MessageContent::ToolRequest(req) = content { + let tool_call = req.tool_call.as_ref().ok()?; + + Some(ServerNotification::LoggingMessageNotification( + LoggingMessageNotification { + method: LoggingMessageNotificationMethod, + params: LoggingMessageNotificationParam { + level: LoggingLevel::Info, + logger: Some(format!("subagent:{}", subagent_id)), + data: serde_json::json!({ + "type": SUBAGENT_TOOL_REQUEST_TYPE, + "subagent_id": subagent_id, + "tool_call": { + "name": tool_call.name, + "arguments": tool_call.arguments + } + }), + }, + extensions: Default::default(), + }, + )) + } else { + None + } +} + +#[cfg(test)] +mod tests { + use super::{create_tool_notification, SUBAGENT_TOOL_REQUEST_TYPE}; + use crate::conversation::message::MessageContent; + use rmcp::model::{CallToolRequestParams, ServerNotification}; + use serde_json::json; + + #[test] + fn create_tool_notification_for_tool_request() { + let tool_call = CallToolRequestParams { + meta: None, + task: None, + name: "developer__shell".to_string().into(), + arguments: Some(json!({"command": "ls"}).as_object().unwrap().clone()), + }; + let content = MessageContent::tool_request("req1", Ok(tool_call)); + let notification = + create_tool_notification(&content, "session_1").expect("expected notification"); + + let ServerNotification::LoggingMessageNotification(log_notif) = notification else { + panic!("expected logging notification"); + }; + let data = log_notif + .params + .data + .as_object() + .expect("expected object data"); + assert_eq!( + data.get("type").and_then(|v| v.as_str()), + Some(SUBAGENT_TOOL_REQUEST_TYPE) + ); + assert_eq!( + data.get("subagent_id").and_then(|v| v.as_str()), + Some("session_1") + ); + let tool_call = data + .get("tool_call") + .and_then(|v| v.as_object()) + .expect("expected tool_call object"); + assert_eq!( + tool_call.get("name").and_then(|v| v.as_str()), + Some("developer__shell") + ); + } + + #[test] + fn create_tool_notification_ignores_non_tool_request() { + let content = MessageContent::text("hello"); + assert!(create_tool_notification(&content, "session_1").is_none()); + } +} diff --git a/crates/goose/src/agents/summon_extension.rs b/crates/goose/src/agents/summon_extension.rs index 4c3605cdf4..ca6924cbe9 100644 --- a/crates/goose/src/agents/summon_extension.rs +++ b/crates/goose/src/agents/summon_extension.rs @@ -1463,6 +1463,7 @@ impl McpClientTrait for SummonClient { session_id: &str, name: &str, arguments: Option, + _working_dir: Option<&str>, cancellation_token: CancellationToken, ) -> Result { let content = match name { @@ -1647,7 +1648,7 @@ You review code."#; assert!(names.contains(&"load") && names.contains(&"delegate")); let result = client - .call_tool("test", "unknown", None, CancellationToken::new()) + .call_tool("test", "unknown", None, None, CancellationToken::new()) .await .unwrap(); assert!(result.is_error.unwrap_or(false)); diff --git a/crates/goose/src/agents/todo_extension.rs b/crates/goose/src/agents/todo_extension.rs index 7aa3ccb492..39df8ab9fc 100644 --- a/crates/goose/src/agents/todo_extension.rs +++ b/crates/goose/src/agents/todo_extension.rs @@ -174,6 +174,7 @@ impl McpClientTrait for TodoClient { session_id: &str, name: &str, arguments: Option, + _working_dir: Option<&str>, _cancellation_token: CancellationToken, ) -> Result { let content = match name { diff --git a/crates/goose/src/goose_apps/mod.rs b/crates/goose/src/goose_apps/mod.rs index 327b0e1bf9..11c0d8450e 100644 --- a/crates/goose/src/goose_apps/mod.rs +++ b/crates/goose/src/goose_apps/mod.rs @@ -4,4 +4,6 @@ pub mod resource; pub use app::{fetch_mcp_apps, GooseApp, WindowProps}; pub use cache::McpAppCache; -pub use resource::{CspMetadata, McpAppResource, ResourceMetadata, UiMetadata}; +pub use resource::{ + CspMetadata, McpAppResource, PermissionsMetadata, ResourceMetadata, UiMetadata, +}; diff --git a/crates/goose/src/goose_apps/resource.rs b/crates/goose/src/goose_apps/resource.rs index a6ea769c74..6afbdcc4b1 100644 --- a/crates/goose/src/goose_apps/resource.rs +++ b/crates/goose/src/goose_apps/resource.rs @@ -14,6 +14,30 @@ pub struct CspMetadata { pub resource_domains: Option>, } +/// Sandbox permissions for MCP Apps +/// Specifies which browser capabilities the UI needs access to. +/// Maps to the iframe Permission Policy `allow` attribute. +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, PartialEq, Eq, Default)] +#[serde(rename_all = "camelCase")] +pub struct PermissionsMetadata { + /// Request camera access (maps to Permission Policy `camera` feature) + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub camera: bool, + /// Request microphone access (maps to Permission Policy `microphone` feature) + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub microphone: bool, + /// Request geolocation access (maps to Permission Policy `geolocation` feature) + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub geolocation: bool, + /// Request clipboard write access (maps to Permission Policy `clipboard-write` feature) + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub clipboard_write: bool, +} + +fn is_default_permissions(p: &PermissionsMetadata) -> bool { + *p == PermissionsMetadata::default() +} + /// UI-specific metadata for MCP resources #[derive(Debug, Clone, Serialize, Deserialize, ToSchema, PartialEq, Eq)] #[serde(rename_all = "camelCase")] @@ -21,6 +45,9 @@ pub struct UiMetadata { /// Content Security Policy configuration #[serde(skip_serializing_if = "Option::is_none")] pub csp: Option, + /// Sandbox permissions requested by the UI + #[serde(default, skip_serializing_if = "is_default_permissions")] + pub permissions: PermissionsMetadata, /// Preferred domain for the app (used for CORS) #[serde(skip_serializing_if = "Option::is_none")] pub domain: Option, @@ -87,6 +114,7 @@ impl McpAppResource { meta: Some(ResourceMetadata { ui: Some(UiMetadata { csp: Some(csp), + permissions: PermissionsMetadata::default(), domain: None, prefers_border: None, }), diff --git a/crates/goose/src/providers/canonical/data/canonical_mapping_report.json b/crates/goose/src/providers/canonical/data/canonical_mapping_report.json index 4ff9dd97e3..381405467f 100644 --- a/crates/goose/src/providers/canonical/data/canonical_mapping_report.json +++ b/crates/goose/src/providers/canonical/data/canonical_mapping_report.json @@ -1,278 +1,6 @@ { - "timestamp": "2026-01-27T17:42:42.278162+00:00", + "timestamp": "2026-02-03T00:38:43.150867902+00:00", "unmapped_models": [ - { - "provider": "databricks", - "model": "baxen-migration-demo" - }, - { - "provider": "databricks", - "model": "big-hack" - }, - { - "provider": "databricks", - "model": "case-history-checker" - }, - { - "provider": "databricks", - "model": "case_history_hackweek" - }, - { - "provider": "databricks", - "model": "claude-3-5-sonnet-2" - }, - { - "provider": "databricks", - "model": "claude-4" - }, - { - "provider": "databricks", - "model": "claude-haiku" - }, - { - "provider": "databricks", - "model": "claude-opus" - }, - { - "provider": "databricks", - "model": "claude-sonnet" - }, - { - "provider": "databricks", - "model": "cmg-test-iris" - }, - { - "provider": "databricks", - "model": "codellama-7b-hf-ift" - }, - { - "provider": "databricks", - "model": "column-mapping-model-endpoint" - }, - { - "provider": "databricks", - "model": "column-mapping-model-endpoint-v2" - }, - { - "provider": "databricks", - "model": "databricks-bge-large-en" - }, - { - "provider": "databricks", - "model": "databricks-gemini-3-flash" - }, - { - "provider": "databricks", - "model": "databricks-gemini-3-pro" - }, - { - "provider": "databricks", - "model": "databricks-gemma-3-12b" - }, - { - "provider": "databricks", - "model": "databricks-gpt-oss-120b" - }, - { - "provider": "databricks", - "model": "databricks-gpt-oss-20b" - }, - { - "provider": "databricks", - "model": "databricks-gte-large-en" - }, - { - "provider": "databricks", - "model": "databricks-llama-4-maverick" - }, - { - "provider": "databricks", - "model": "databricks-meta-llama-3-1-405b-instruct" - }, - { - "provider": "databricks", - "model": "databricks-meta-llama-3-1-8b-instruct" - }, - { - "provider": "databricks", - "model": "dummy-model-ml-gp-endpoint" - }, - { - "provider": "databricks", - "model": "e5-large-v2" - }, - { - "provider": "databricks", - "model": "gemini-2-5-pro-exp" - }, - { - "provider": "databricks", - "model": "gemini-pro" - }, - { - "provider": "databricks", - "model": "goose" - }, - { - "provider": "databricks", - "model": "goose-cerebras-glm-4-6" - }, - { - "provider": "databricks", - "model": "goose-gemini-3-pro" - }, - { - "provider": "databricks", - "model": "goose-gpt-oss" - }, - { - "provider": "databricks", - "model": "gpt-3-5-turbo-16k" - }, - { - "provider": "databricks", - "model": "gpt-3-5-turbo-instruct" - }, - { - "provider": "databricks", - "model": "gpt-4-0125-preview" - }, - { - "provider": "databricks", - "model": "gpt-4-vision-preview" - }, - { - "provider": "databricks", - "model": "gpt-5-mini-high" - }, - { - "provider": "databricks", - "model": "gpt-vision" - }, - { - "provider": "databricks", - "model": "hackweek-snowflake-gpt-query-generator" - }, - { - "provider": "databricks", - "model": "headless-goose" - }, - { - "provider": "databricks", - "model": "icg-poc" - }, - { - "provider": "databricks", - "model": "invoice_parser_test" - }, - { - "provider": "databricks", - "model": "jina-reranker-v1-turbo-en" - }, - { - "provider": "databricks", - "model": "korhan-openai-test" - }, - { - "provider": "databricks", - "model": "korhan-openai-wrapper" - }, - { - "provider": "databricks", - "model": "lfc_mml_er_bge_m3" - }, - { - "provider": "databricks", - "model": "moderation" - }, - { - "provider": "databricks", - "model": "o3-cdd-autopilot" - }, - { - "provider": "databricks", - "model": "optimized-llama2-7b" - }, - { - "provider": "databricks", - "model": "opus-mt-en-es" - }, - { - "provider": "databricks", - "model": "opus-mt-en-fr" - }, - { - "provider": "databricks", - "model": "opus-mt-en-ja" - }, - { - "provider": "databricks", - "model": "opus-mt-es-en" - }, - { - "provider": "databricks", - "model": "opus-mt-fr-en" - }, - { - "provider": "databricks", - "model": "opus-mt-ja-en" - }, - { - "provider": "databricks", - "model": "p2p-device-recovery-classify" - }, - { - "provider": "databricks", - "model": "picasso_embeddings" - }, - { - "provider": "databricks", - "model": "pii-redactor" - }, - { - "provider": "databricks", - "model": "pii-redactor-prod" - }, - { - "provider": "databricks", - "model": "prime_model" - }, - { - "provider": "databricks", - "model": "reportiq_selector_1" - }, - { - "provider": "databricks", - "model": "reportiq_selector_md_file" - }, - { - "provider": "databricks", - "model": "snowflake-gpt-query-generator-v3" - }, - { - "provider": "databricks", - "model": "sq-bank-statement-classifier" - }, - { - "provider": "databricks", - "model": "sq-bank-statement-parser" - }, - { - "provider": "databricks", - "model": "support-article-intent-mapping" - }, - { - "provider": "databricks", - "model": "text-embedding-3-large" - }, - { - "provider": "databricks", - "model": "text-embedding-3-small" - }, - { - "provider": "databricks", - "model": "text-embedding-ada-002" - }, { "provider": "google", "model": "aqa" @@ -285,18 +13,10 @@ "provider": "google", "model": "embedding-001" }, - { - "provider": "google", - "model": "embedding-gecko-001" - }, { "provider": "google", "model": "gemini-2.0-flash-001" }, - { - "provider": "google", - "model": "gemini-2.0-flash-exp" - }, { "provider": "google", "model": "gemini-2.0-flash-exp-image-generation" @@ -305,30 +25,26 @@ "provider": "google", "model": "gemini-2.0-flash-lite-001" }, - { - "provider": "google", - "model": "gemini-2.0-flash-lite-preview" - }, - { - "provider": "google", - "model": "gemini-2.0-flash-lite-preview-02-05" - }, { "provider": "google", "model": "gemini-2.5-computer-use-preview-10-2025" }, + { + "provider": "google", + "model": "gemini-2.5-flash-native-audio-latest" + }, + { + "provider": "google", + "model": "gemini-2.5-flash-native-audio-preview-09-2025" + }, + { + "provider": "google", + "model": "gemini-2.5-flash-native-audio-preview-12-2025" + }, { "provider": "google", "model": "gemini-3-pro-image-preview" }, - { - "provider": "google", - "model": "gemini-embedding-exp" - }, - { - "provider": "google", - "model": "gemini-embedding-exp-03-07" - }, { "provider": "google", "model": "gemini-exp-1206" @@ -2829,10 +2545,6 @@ "provider": "openrouter", "model": "arcee-ai/trinity-mini" }, - { - "provider": "openrouter", - "model": "arcee-ai/trinity-mini:free" - }, { "provider": "openrouter", "model": "arcee-ai/virtuoso-large" @@ -2897,10 +2609,6 @@ "provider": "openrouter", "model": "google/gemini-2.5-pro-preview" }, - { - "provider": "openrouter", - "model": "google/gemma-3-27b-it:free" - }, { "provider": "openrouter", "model": "inception/mercury" @@ -3021,10 +2729,6 @@ "provider": "openrouter", "model": "mistralai/voxtral-small-24b-2507" }, - { - "provider": "openrouter", - "model": "moonshotai/kimi-k2.5" - }, { "provider": "openrouter", "model": "nex-agi/deepseek-v3.1-nex-n1" @@ -3161,6 +2865,14 @@ "provider": "openrouter", "model": "openai/o4-mini-high" }, + { + "provider": "openrouter", + "model": "openrouter/auto" + }, + { + "provider": "openrouter", + "model": "openrouter/free" + }, { "provider": "openrouter", "model": "prime-intellect/intellect-3" @@ -3277,6 +2989,10 @@ "provider": "openrouter", "model": "stepfun-ai/step3" }, + { + "provider": "openrouter", + "model": "stepfun/step-3.5-flash:free" + }, { "provider": "openrouter", "model": "thedrummer/rocinante-12b" @@ -3320,6 +3036,14 @@ { "provider": "xai", "model": "grok-2-image-1212" + }, + { + "provider": "xai", + "model": "grok-imagine-image" + }, + { + "provider": "xai", + "model": "grok-imagine-video" } ], "all_mappings": { @@ -3363,376 +3087,7 @@ ], "aws_bedrock": [], "azure_openai": [], - "databricks": [ - { - "provider_model": "claude-3-5-haiku", - "canonical_model": "anthropic/claude-3.5-haiku" - }, - { - "provider_model": "claude-3-5-sonnet", - "canonical_model": "anthropic/claude-3.5-sonnet" - }, - { - "provider_model": "claude-3-7-sonnet", - "canonical_model": "anthropic/claude-3.7-sonnet" - }, - { - "provider_model": "claude-4-opus", - "canonical_model": "anthropic/claude-opus-4" - }, - { - "provider_model": "code-review-gpt-5", - "canonical_model": "openai/gpt-5" - }, - { - "provider_model": "code-review-gpt-5-mini", - "canonical_model": "openai/gpt-5-mini" - }, - { - "provider_model": "databricks-claude-3-7-sonnet", - "canonical_model": "anthropic/claude-3.7-sonnet" - }, - { - "provider_model": "databricks-claude-haiku-4-5", - "canonical_model": "anthropic/claude-haiku-4.5" - }, - { - "provider_model": "databricks-claude-opus-4-1", - "canonical_model": "anthropic/claude-opus-4.1" - }, - { - "provider_model": "databricks-claude-opus-4-5", - "canonical_model": "anthropic/claude-opus-4.5" - }, - { - "provider_model": "databricks-claude-sonnet-4", - "canonical_model": "anthropic/claude-sonnet-4" - }, - { - "provider_model": "databricks-claude-sonnet-4-5", - "canonical_model": "anthropic/claude-sonnet-4.5" - }, - { - "provider_model": "databricks-gemini-2-5-flash", - "canonical_model": "google/gemini-2.5-flash" - }, - { - "provider_model": "databricks-gemini-2-5-pro", - "canonical_model": "google/gemini-2.5-pro" - }, - { - "provider_model": "databricks-gpt-5", - "canonical_model": "openai/gpt-5" - }, - { - "provider_model": "databricks-gpt-5-1", - "canonical_model": "openai/gpt-5.1" - }, - { - "provider_model": "databricks-gpt-5-1-codex-max", - "canonical_model": "openai/gpt-5.1-codex-max" - }, - { - "provider_model": "databricks-gpt-5-1-codex-mini", - "canonical_model": "openai/gpt-5.1-codex-mini" - }, - { - "provider_model": "databricks-gpt-5-2", - "canonical_model": "openai/gpt-5.2" - }, - { - "provider_model": "databricks-gpt-5-mini", - "canonical_model": "openai/gpt-5-mini" - }, - { - "provider_model": "databricks-gpt-5-nano", - "canonical_model": "openai/gpt-5-nano" - }, - { - "provider_model": "databricks-meta-llama-3-3-70b-instruct", - "canonical_model": "meta-llama/llama-3.3-70b-instruct" - }, - { - "provider_model": "gemini-1-5-flash", - "canonical_model": "google/gemini-1.5-flash" - }, - { - "provider_model": "gemini-1-5-pro", - "canonical_model": "google/gemini-1.5-pro" - }, - { - "provider_model": "gemini-2-0-flash", - "canonical_model": "google/gemini-2.0-flash" - }, - { - "provider_model": "gemini-2-5-flash", - "canonical_model": "google/gemini-2.5-flash" - }, - { - "provider_model": "gemini-2-5-flash-latest", - "canonical_model": "google/gemini-2.5-flash" - }, - { - "provider_model": "gemini-2-5-pro", - "canonical_model": "google/gemini-2.5-pro" - }, - { - "provider_model": "gemini-flash-lite-latest", - "canonical_model": "google/gemini-flash-lite" - }, - { - "provider_model": "goose-claude-3-5-sonnet", - "canonical_model": "anthropic/claude-3.5-sonnet" - }, - { - "provider_model": "goose-claude-3-7-sonnet", - "canonical_model": "anthropic/claude-3.7-sonnet" - }, - { - "provider_model": "goose-claude-4-5-haiku", - "canonical_model": "anthropic/claude-haiku-4.5" - }, - { - "provider_model": "goose-claude-4-5-opus", - "canonical_model": "anthropic/claude-opus-4.5" - }, - { - "provider_model": "goose-claude-4-5-sonnet", - "canonical_model": "anthropic/claude-sonnet-4.5" - }, - { - "provider_model": "goose-claude-4-opus", - "canonical_model": "anthropic/claude-opus-4" - }, - { - "provider_model": "goose-claude-4-sonnet", - "canonical_model": "anthropic/claude-sonnet-4" - }, - { - "provider_model": "goose-claude-4-sonnet-bedrock", - "canonical_model": "anthropic/claude-sonnet-4" - }, - { - "provider_model": "goose-gemini-2-5-pro", - "canonical_model": "google/gemini-2.5-pro" - }, - { - "provider_model": "goose-gpt-4-1", - "canonical_model": "openai/gpt-4.1" - }, - { - "provider_model": "goose-gpt-4o", - "canonical_model": "openai/gpt-4o" - }, - { - "provider_model": "goose-gpt-5", - "canonical_model": "openai/gpt-5" - }, - { - "provider_model": "goose-gpt-5-2", - "canonical_model": "openai/gpt-5.2" - }, - { - "provider_model": "goose-o1", - "canonical_model": "openai/o1" - }, - { - "provider_model": "goose-o3", - "canonical_model": "openai/o3" - }, - { - "provider_model": "goose-o4-mini", - "canonical_model": "openai/o4-mini" - }, - { - "provider_model": "gpt-3-5-turbo", - "canonical_model": "openai/gpt-3.5-turbo" - }, - { - "provider_model": "gpt-3-5-turbo-0125", - "canonical_model": "openai/gpt-3.5-turbo" - }, - { - "provider_model": "gpt-4", - "canonical_model": "openai/gpt-4" - }, - { - "provider_model": "gpt-4-1-2025-04-14", - "canonical_model": "openai/gpt-4.1" - }, - { - "provider_model": "gpt-4-1-mini", - "canonical_model": "openai/gpt-4.1-mini" - }, - { - "provider_model": "gpt-4-1-nano", - "canonical_model": "openai/gpt-4.1-nano" - }, - { - "provider_model": "gpt-4-turbo", - "canonical_model": "openai/gpt-4-turbo" - }, - { - "provider_model": "gpt-4-turbo-2024-04-09", - "canonical_model": "openai/gpt-4-turbo" - }, - { - "provider_model": "gpt-4o", - "canonical_model": "openai/gpt-4o" - }, - { - "provider_model": "gpt-4o-2024-05-13", - "canonical_model": "openai/gpt-4o" - }, - { - "provider_model": "gpt-4o-2024-11-20", - "canonical_model": "openai/gpt-4o" - }, - { - "provider_model": "gpt-4o-mini", - "canonical_model": "openai/gpt-4o-mini" - }, - { - "provider_model": "gpt-4o-mini-2024-07-18", - "canonical_model": "openai/gpt-4o-mini" - }, - { - "provider_model": "gpt-5", - "canonical_model": "openai/gpt-5" - }, - { - "provider_model": "gpt-5-nano", - "canonical_model": "openai/gpt-5-nano" - }, - { - "provider_model": "headless-goose-claude-4-sonnet", - "canonical_model": "anthropic/claude-sonnet-4" - }, - { - "provider_model": "headless-goose-o3-mini", - "canonical_model": "openai/o3-mini" - }, - { - "provider_model": "kgoose-cashapp-claude-4-sonnet", - "canonical_model": "anthropic/claude-sonnet-4" - }, - { - "provider_model": "kgoose-cashapp-claude-sonnet-4-5", - "canonical_model": "anthropic/claude-sonnet-4.5" - }, - { - "provider_model": "kgoose-claude-4-sonnet", - "canonical_model": "anthropic/claude-sonnet-4" - }, - { - "provider_model": "kgoose-claude-haiku-4-5", - "canonical_model": "anthropic/claude-haiku-4.5" - }, - { - "provider_model": "kgoose-claude-sonnet-4-5", - "canonical_model": "anthropic/claude-sonnet-4.5" - }, - { - "provider_model": "kgoose-gemini-2-5-flash", - "canonical_model": "google/gemini-2.5-flash" - }, - { - "provider_model": "kgoose-gpt-4-1", - "canonical_model": "openai/gpt-4.1" - }, - { - "provider_model": "kgoose-gpt-4-1-mini", - "canonical_model": "openai/gpt-4.1-mini" - }, - { - "provider_model": "kgoose-gpt-4-1-nano", - "canonical_model": "openai/gpt-4.1-nano" - }, - { - "provider_model": "kgoose-gpt-4o", - "canonical_model": "openai/gpt-4o" - }, - { - "provider_model": "kgoose-gpt-5", - "canonical_model": "openai/gpt-5" - }, - { - "provider_model": "kgoose-gpt-5-mini", - "canonical_model": "openai/gpt-5-mini" - }, - { - "provider_model": "kgoose-gpt-5-nano", - "canonical_model": "openai/gpt-5-nano" - }, - { - "provider_model": "kgoose-o3", - "canonical_model": "openai/o3" - }, - { - "provider_model": "kgoose-o4-mini", - "canonical_model": "openai/o4-mini" - }, - { - "provider_model": "ng-tools-claude-haiku-3-5", - "canonical_model": "anthropic/claude-3.5-haiku" - }, - { - "provider_model": "ng-tools-claude-opus-4", - "canonical_model": "anthropic/claude-opus-4" - }, - { - "provider_model": "ng-tools-claude-opus-4-1", - "canonical_model": "anthropic/claude-opus-4.1" - }, - { - "provider_model": "ng-tools-claude-sonnet-3-7", - "canonical_model": "anthropic/claude-3.7-sonnet" - }, - { - "provider_model": "ng-tools-claude-sonnet-4", - "canonical_model": "anthropic/claude-sonnet-4" - }, - { - "provider_model": "ng-tools-gpt-5-nano", - "canonical_model": "openai/gpt-5-nano" - }, - { - "provider_model": "ng-tools-int-claude-sonnet-4-5", - "canonical_model": "anthropic/claude-sonnet-4.5" - }, - { - "provider_model": "o1", - "canonical_model": "openai/o1" - }, - { - "provider_model": "o1-2024-12-17", - "canonical_model": "openai/o1" - }, - { - "provider_model": "o1-mini", - "canonical_model": "openai/o1-mini" - }, - { - "provider_model": "o1-preview", - "canonical_model": "openai/o1-preview" - }, - { - "provider_model": "o3", - "canonical_model": "openai/o3" - }, - { - "provider_model": "o3-mini", - "canonical_model": "openai/o3-mini" - }, - { - "provider_model": "raml-claude-opus-4-5", - "canonical_model": "anthropic/claude-opus-4.5" - }, - { - "provider_model": "raml-claude-sonnet-4-5", - "canonical_model": "anthropic/claude-sonnet-4.5" - } - ], + "databricks": [], "gcp_vertex_ai": [], "google": [ { @@ -4079,6 +3434,14 @@ "provider_model": "anthropic/claude-sonnet-4.5", "canonical_model": "openrouter/anthropic/claude-sonnet-4.5" }, + { + "provider_model": "arcee-ai/trinity-large-preview:free", + "canonical_model": "openrouter/arcee-ai/trinity-large-preview:free" + }, + { + "provider_model": "arcee-ai/trinity-mini:free", + "canonical_model": "openrouter/arcee-ai/trinity-mini:free" + }, { "provider_model": "deepseek/deepseek-chat-v3-0324", "canonical_model": "openrouter/deepseek/deepseek-chat-v3" @@ -4087,10 +3450,6 @@ "provider_model": "deepseek/deepseek-chat-v3.1", "canonical_model": "openrouter/deepseek/deepseek-chat-v3.1" }, - { - "provider_model": "deepseek/deepseek-r1-distill-llama-70b", - "canonical_model": "openrouter/deepseek/deepseek-r1-distill-llama-70b" - }, { "provider_model": "deepseek/deepseek-v3.1-terminus", "canonical_model": "openrouter/deepseek/deepseek-v3.1-terminus" @@ -4107,10 +3466,6 @@ "provider_model": "google/gemini-2.0-flash-001", "canonical_model": "openrouter/google/gemini-2.0-flash-001" }, - { - "provider_model": "google/gemini-2.0-flash-exp:free", - "canonical_model": "openrouter/google/gemini-2.0-flash-exp:free" - }, { "provider_model": "google/gemini-2.5-flash", "canonical_model": "openrouter/google/gemini-2.5-flash" @@ -4147,6 +3502,10 @@ "provider_model": "google/gemma-3-27b-it", "canonical_model": "openrouter/google/gemma-3-27b-it" }, + { + "provider_model": "google/gemma-3-27b-it:free", + "canonical_model": "openrouter/google/gemma-3-27b-it:free" + }, { "provider_model": "meta-llama/llama-3.3-70b-instruct:free", "canonical_model": "openrouter/meta-llama/llama-3.3-70b-instruct:free" @@ -4211,6 +3570,10 @@ "provider_model": "moonshotai/kimi-k2-thinking", "canonical_model": "openrouter/moonshotai/kimi-k2-thinking" }, + { + "provider_model": "moonshotai/kimi-k2.5", + "canonical_model": "openrouter/moonshotai/kimi-k2.5" + }, { "provider_model": "nousresearch/hermes-4-70b", "canonical_model": "openrouter/nousresearch/hermes-4-70b" @@ -4516,558 +3879,6 @@ "canonical": "anthropic/claude-sonnet-4.5", "recommended": true }, - { - "provider": "databricks", - "model": "claude-3-5-haiku", - "canonical": "anthropic/claude-3.5-haiku", - "recommended": true - }, - { - "provider": "databricks", - "model": "claude-3-5-sonnet", - "canonical": "anthropic/claude-3.5-sonnet", - "recommended": true - }, - { - "provider": "databricks", - "model": "claude-3-7-sonnet", - "canonical": "anthropic/claude-3.7-sonnet", - "recommended": true - }, - { - "provider": "databricks", - "model": "claude-4-opus", - "canonical": "anthropic/claude-opus-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "code-review-gpt-5", - "canonical": "openai/gpt-5", - "recommended": true - }, - { - "provider": "databricks", - "model": "code-review-gpt-5-mini", - "canonical": "openai/gpt-5-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-claude-3-7-sonnet", - "canonical": "anthropic/claude-3.7-sonnet", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-claude-haiku-4-5", - "canonical": "anthropic/claude-haiku-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-claude-opus-4-1", - "canonical": "anthropic/claude-opus-4.1", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-claude-opus-4-5", - "canonical": "anthropic/claude-opus-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-claude-sonnet-4", - "canonical": "anthropic/claude-sonnet-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-claude-sonnet-4-5", - "canonical": "anthropic/claude-sonnet-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gemini-2-5-flash", - "canonical": "google/gemini-2.5-flash", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gemini-2-5-pro", - "canonical": "google/gemini-2.5-pro", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gpt-5", - "canonical": "openai/gpt-5", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gpt-5-1", - "canonical": "openai/gpt-5.1", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gpt-5-1-codex-max", - "canonical": "openai/gpt-5.1-codex-max", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gpt-5-1-codex-mini", - "canonical": "openai/gpt-5.1-codex-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gpt-5-2", - "canonical": "openai/gpt-5.2", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gpt-5-mini", - "canonical": "openai/gpt-5-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-gpt-5-nano", - "canonical": "openai/gpt-5-nano", - "recommended": true - }, - { - "provider": "databricks", - "model": "databricks-meta-llama-3-3-70b-instruct", - "canonical": "meta-llama/llama-3.3-70b-instruct", - "recommended": true - }, - { - "provider": "databricks", - "model": "gemini-1-5-flash", - "canonical": "google/gemini-1.5-flash", - "recommended": true - }, - { - "provider": "databricks", - "model": "gemini-1-5-pro", - "canonical": "google/gemini-1.5-pro", - "recommended": true - }, - { - "provider": "databricks", - "model": "gemini-2-0-flash", - "canonical": "google/gemini-2.0-flash", - "recommended": true - }, - { - "provider": "databricks", - "model": "gemini-2-5-flash", - "canonical": "google/gemini-2.5-flash", - "recommended": true - }, - { - "provider": "databricks", - "model": "gemini-2-5-flash-latest", - "canonical": "google/gemini-2.5-flash", - "recommended": true - }, - { - "provider": "databricks", - "model": "gemini-2-5-pro", - "canonical": "google/gemini-2.5-pro", - "recommended": true - }, - { - "provider": "databricks", - "model": "gemini-flash-lite-latest", - "canonical": "google/gemini-flash-lite", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-claude-3-5-sonnet", - "canonical": "anthropic/claude-3.5-sonnet", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-claude-3-7-sonnet", - "canonical": "anthropic/claude-3.7-sonnet", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-claude-4-5-haiku", - "canonical": "anthropic/claude-haiku-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-claude-4-5-opus", - "canonical": "anthropic/claude-opus-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-claude-4-5-sonnet", - "canonical": "anthropic/claude-sonnet-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-claude-4-opus", - "canonical": "anthropic/claude-opus-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-claude-4-sonnet", - "canonical": "anthropic/claude-sonnet-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-claude-4-sonnet-bedrock", - "canonical": "anthropic/claude-sonnet-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-gemini-2-5-pro", - "canonical": "google/gemini-2.5-pro", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-gpt-4-1", - "canonical": "openai/gpt-4.1", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-gpt-4o", - "canonical": "openai/gpt-4o", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-gpt-5", - "canonical": "openai/gpt-5", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-gpt-5-2", - "canonical": "openai/gpt-5.2", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-o1", - "canonical": "openai/o1", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-o3", - "canonical": "openai/o3", - "recommended": true - }, - { - "provider": "databricks", - "model": "goose-o4-mini", - "canonical": "openai/o4-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-3-5-turbo", - "canonical": "openai/gpt-3.5-turbo", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-3-5-turbo-0125", - "canonical": "openai/gpt-3.5-turbo", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4", - "canonical": "openai/gpt-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4-1-2025-04-14", - "canonical": "openai/gpt-4.1", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4-1-mini", - "canonical": "openai/gpt-4.1-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4-1-nano", - "canonical": "openai/gpt-4.1-nano", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4-turbo", - "canonical": "openai/gpt-4-turbo", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4-turbo-2024-04-09", - "canonical": "openai/gpt-4-turbo", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4o", - "canonical": "openai/gpt-4o", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4o-2024-05-13", - "canonical": "openai/gpt-4o", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4o-2024-11-20", - "canonical": "openai/gpt-4o", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4o-mini", - "canonical": "openai/gpt-4o-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-4o-mini-2024-07-18", - "canonical": "openai/gpt-4o-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-5", - "canonical": "openai/gpt-5", - "recommended": true - }, - { - "provider": "databricks", - "model": "gpt-5-nano", - "canonical": "openai/gpt-5-nano", - "recommended": true - }, - { - "provider": "databricks", - "model": "headless-goose-claude-4-sonnet", - "canonical": "anthropic/claude-sonnet-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "headless-goose-o3-mini", - "canonical": "openai/o3-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-cashapp-claude-4-sonnet", - "canonical": "anthropic/claude-sonnet-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-cashapp-claude-sonnet-4-5", - "canonical": "anthropic/claude-sonnet-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-claude-4-sonnet", - "canonical": "anthropic/claude-sonnet-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-claude-haiku-4-5", - "canonical": "anthropic/claude-haiku-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-claude-sonnet-4-5", - "canonical": "anthropic/claude-sonnet-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-gemini-2-5-flash", - "canonical": "google/gemini-2.5-flash", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-gpt-4-1", - "canonical": "openai/gpt-4.1", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-gpt-4-1-mini", - "canonical": "openai/gpt-4.1-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-gpt-4-1-nano", - "canonical": "openai/gpt-4.1-nano", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-gpt-4o", - "canonical": "openai/gpt-4o", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-gpt-5", - "canonical": "openai/gpt-5", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-gpt-5-mini", - "canonical": "openai/gpt-5-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-gpt-5-nano", - "canonical": "openai/gpt-5-nano", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-o3", - "canonical": "openai/o3", - "recommended": true - }, - { - "provider": "databricks", - "model": "kgoose-o4-mini", - "canonical": "openai/o4-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "ng-tools-claude-haiku-3-5", - "canonical": "anthropic/claude-3.5-haiku", - "recommended": true - }, - { - "provider": "databricks", - "model": "ng-tools-claude-opus-4", - "canonical": "anthropic/claude-opus-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "ng-tools-claude-opus-4-1", - "canonical": "anthropic/claude-opus-4.1", - "recommended": true - }, - { - "provider": "databricks", - "model": "ng-tools-claude-sonnet-3-7", - "canonical": "anthropic/claude-3.7-sonnet", - "recommended": true - }, - { - "provider": "databricks", - "model": "ng-tools-claude-sonnet-4", - "canonical": "anthropic/claude-sonnet-4", - "recommended": true - }, - { - "provider": "databricks", - "model": "ng-tools-gpt-5-nano", - "canonical": "openai/gpt-5-nano", - "recommended": true - }, - { - "provider": "databricks", - "model": "ng-tools-int-claude-sonnet-4-5", - "canonical": "anthropic/claude-sonnet-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "o1", - "canonical": "openai/o1", - "recommended": true - }, - { - "provider": "databricks", - "model": "o1-2024-12-17", - "canonical": "openai/o1", - "recommended": true - }, - { - "provider": "databricks", - "model": "o1-mini", - "canonical": "openai/o1-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "o1-preview", - "canonical": "openai/o1-preview", - "recommended": true - }, - { - "provider": "databricks", - "model": "o3", - "canonical": "openai/o3", - "recommended": true - }, - { - "provider": "databricks", - "model": "o3-mini", - "canonical": "openai/o3-mini", - "recommended": true - }, - { - "provider": "databricks", - "model": "raml-claude-opus-4-5", - "canonical": "anthropic/claude-opus-4.5", - "recommended": true - }, - { - "provider": "databricks", - "model": "raml-claude-sonnet-4-5", - "canonical": "anthropic/claude-sonnet-4.5", - "recommended": true - }, { "provider": "google", "model": "gemini-2.0-flash", @@ -5578,6 +4389,18 @@ "canonical": "openrouter/anthropic/claude-sonnet-4.5", "recommended": true }, + { + "provider": "openrouter", + "model": "arcee-ai/trinity-large-preview:free", + "canonical": "openrouter/arcee-ai/trinity-large-preview:free", + "recommended": true + }, + { + "provider": "openrouter", + "model": "arcee-ai/trinity-mini:free", + "canonical": "openrouter/arcee-ai/trinity-mini:free", + "recommended": true + }, { "provider": "openrouter", "model": "deepseek/deepseek-chat-v3-0324", @@ -5590,12 +4413,6 @@ "canonical": "openrouter/deepseek/deepseek-chat-v3.1", "recommended": true }, - { - "provider": "openrouter", - "model": "deepseek/deepseek-r1-distill-llama-70b", - "canonical": "openrouter/deepseek/deepseek-r1-distill-llama-70b", - "recommended": true - }, { "provider": "openrouter", "model": "deepseek/deepseek-v3.1-terminus", @@ -5620,12 +4437,6 @@ "canonical": "openrouter/google/gemini-2.0-flash-001", "recommended": true }, - { - "provider": "openrouter", - "model": "google/gemini-2.0-flash-exp:free", - "canonical": "openrouter/google/gemini-2.0-flash-exp:free", - "recommended": true - }, { "provider": "openrouter", "model": "google/gemini-2.5-flash", @@ -5680,6 +4491,12 @@ "canonical": "openrouter/google/gemma-3-27b-it", "recommended": true }, + { + "provider": "openrouter", + "model": "google/gemma-3-27b-it:free", + "canonical": "openrouter/google/gemma-3-27b-it:free", + "recommended": true + }, { "provider": "openrouter", "model": "meta-llama/llama-3.3-70b-instruct:free", @@ -5776,6 +4593,12 @@ "canonical": "openrouter/moonshotai/kimi-k2-thinking", "recommended": true }, + { + "provider": "openrouter", + "model": "moonshotai/kimi-k2.5", + "canonical": "openrouter/moonshotai/kimi-k2.5", + "recommended": true + }, { "provider": "openrouter", "model": "nousresearch/hermes-4-70b", @@ -6147,19 +4970,18 @@ "anthropic": 9, "aws_bedrock": 0, "azure_openai": 0, - "databricks": 160, + "databricks": 0, "gcp_vertex_ai": 0, - "google": 50, + "google": 47, "openai": 653, - "openrouter": 228, + "openrouter": 230, "tetrate": 0, "venice": 0, - "xai": 10 + "xai": 12 }, "canonical_models_used": [ "anthropic/claude-3-haiku", "anthropic/claude-3.5-haiku", - "anthropic/claude-3.5-sonnet", "anthropic/claude-3.7-sonnet", "anthropic/claude-haiku-4.5", "anthropic/claude-opus-4", @@ -6167,8 +4989,6 @@ "anthropic/claude-opus-4.5", "anthropic/claude-sonnet-4", "anthropic/claude-sonnet-4.5", - "google/gemini-1.5-flash", - "google/gemini-1.5-pro", "google/gemini-2.0-flash", "google/gemini-2.0-flash-lite", "google/gemini-2.5-flash", @@ -6184,7 +5004,6 @@ "google/gemini-embedding-001", "google/gemini-flash", "google/gemini-flash-lite", - "meta-llama/llama-3.3-70b-instruct", "openai/codex-mini", "openai/gpt-3.5-turbo", "openai/gpt-4", @@ -6210,8 +5029,6 @@ "openai/gpt-5.2-codex", "openai/gpt-5.2-pro", "openai/o1", - "openai/o1-mini", - "openai/o1-preview", "openai/o1-pro", "openai/o3", "openai/o3-deep-research", @@ -6230,14 +5047,14 @@ "openrouter/anthropic/claude-opus-4.5", "openrouter/anthropic/claude-sonnet-4", "openrouter/anthropic/claude-sonnet-4.5", + "openrouter/arcee-ai/trinity-large-preview:free", + "openrouter/arcee-ai/trinity-mini:free", "openrouter/deepseek/deepseek-chat-v3", "openrouter/deepseek/deepseek-chat-v3.1", - "openrouter/deepseek/deepseek-r1-distill-llama-70b", "openrouter/deepseek/deepseek-v3.1-terminus", "openrouter/deepseek/deepseek-v3.1-terminus:exacto", "openrouter/deepseek/deepseek-v3.2", "openrouter/google/gemini-2.0-flash-001", - "openrouter/google/gemini-2.0-flash-exp:free", "openrouter/google/gemini-2.5-flash", "openrouter/google/gemini-2.5-flash-lite", "openrouter/google/gemini-2.5-flash-lite-preview-09", @@ -6247,6 +5064,7 @@ "openrouter/google/gemini-3-flash-preview", "openrouter/google/gemini-3-pro-preview", "openrouter/google/gemma-3-27b-it", + "openrouter/google/gemma-3-27b-it:free", "openrouter/meta-llama/llama-3.3-70b-instruct:free", "openrouter/minimax/minimax-m1", "openrouter/minimax/minimax-m2", @@ -6262,6 +5080,7 @@ "openrouter/moonshotai/kimi-k2", "openrouter/moonshotai/kimi-k2-0905:exacto", "openrouter/moonshotai/kimi-k2-thinking", + "openrouter/moonshotai/kimi-k2.5", "openrouter/nousresearch/hermes-4-70b", "openrouter/nvidia/nemotron-nano-9b-v2", "openrouter/openai/gpt-4.1", diff --git a/crates/goose/src/providers/canonical/data/canonical_models.json b/crates/goose/src/providers/canonical/data/canonical_models.json index ea4911be76..f99c6a9b8a 100644 --- a/crates/goose/src/providers/canonical/data/canonical_models.json +++ b/crates/goose/src/providers/canonical/data/canonical_models.json @@ -952,6 +952,171 @@ "output": 81920 } }, + { + "id": "amazon-bedrock/eu.anthropic.claude-haiku-4.5-20251001-v1:0", + "name": "Claude Haiku 4.5 (EU)", + "family": "claude-haiku", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-02-28", + "release_date": "2025-10-15", + "last_updated": "2025-10-15", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 1.0, + "output": 5.0, + "cache_read": 0.1, + "cache_write": 1.25 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, + { + "id": "amazon-bedrock/eu.anthropic.claude-opus-4.5-20251101-v1:0", + "name": "Claude Opus 4.5 (EU)", + "family": "claude-opus", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-03-31", + "release_date": "2025-11-24", + "last_updated": "2025-08-01", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 5.0, + "output": 25.0, + "cache_read": 1.5, + "cache_write": 18.75 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, + { + "id": "amazon-bedrock/eu.anthropic.claude-sonnet-4-20250514-v1:0", + "name": "Claude Sonnet 4 (EU)", + "family": "claude-sonnet", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2024-04", + "release_date": "2025-05-22", + "last_updated": "2025-05-22", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 3.0, + "output": 15.0, + "cache_read": 0.3, + "cache_write": 3.75 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, + { + "id": "amazon-bedrock/eu.anthropic.claude-sonnet-4.5-20250929-v1:0", + "name": "Claude Sonnet 4.5 (EU)", + "family": "claude-sonnet", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-07-31", + "release_date": "2025-09-29", + "last_updated": "2025-09-29", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 3.0, + "output": 15.0, + "cache_read": 0.3, + "cache_write": 3.75 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, + { + "id": "amazon-bedrock/global.anthropic.claude-haiku-4.5-20251001-v1:0", + "name": "Claude Haiku 4.5 (Global)", + "family": "claude-haiku", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-02-28", + "release_date": "2025-10-15", + "last_updated": "2025-10-15", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 1.0, + "output": 5.0, + "cache_read": 0.1, + "cache_write": 1.25 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, { "id": "amazon-bedrock/global.anthropic.claude-opus-4.5-20251101-v1:0", "name": "Claude Opus 4.5 (Global)", @@ -985,6 +1150,72 @@ "output": 64000 } }, + { + "id": "amazon-bedrock/global.anthropic.claude-sonnet-4-20250514-v1:0", + "name": "Claude Sonnet 4 (Global)", + "family": "claude-sonnet", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2024-04", + "release_date": "2025-05-22", + "last_updated": "2025-05-22", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 3.0, + "output": 15.0, + "cache_read": 0.3, + "cache_write": 3.75 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, + { + "id": "amazon-bedrock/global.anthropic.claude-sonnet-4.5-20250929-v1:0", + "name": "Claude Sonnet 4.5 (Global)", + "family": "claude-sonnet", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-07-31", + "release_date": "2025-09-29", + "last_updated": "2025-09-29", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 3.0, + "output": 15.0, + "cache_read": 0.3, + "cache_write": 3.75 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, { "id": "amazon-bedrock/google.gemma-3-12b-it", "name": "Google Gemma 3 12B", @@ -1992,6 +2223,204 @@ "output": 262000 } }, + { + "id": "amazon-bedrock/us.anthropic.claude-haiku-4.5-20251001-v1:0", + "name": "Claude Haiku 4.5 (US)", + "family": "claude-haiku", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-02-28", + "release_date": "2025-10-15", + "last_updated": "2025-10-15", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 1.0, + "output": 5.0, + "cache_read": 0.1, + "cache_write": 1.25 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, + { + "id": "amazon-bedrock/us.anthropic.claude-opus-4-20250514-v1:0", + "name": "Claude Opus 4 (US)", + "family": "claude-opus", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2024-04", + "release_date": "2025-05-22", + "last_updated": "2025-05-22", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 15.0, + "output": 75.0, + "cache_read": 1.5, + "cache_write": 18.75 + }, + "limit": { + "context": 200000, + "output": 32000 + } + }, + { + "id": "amazon-bedrock/us.anthropic.claude-opus-4.1-20250805-v1:0", + "name": "Claude Opus 4.1 (US)", + "family": "claude-opus", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-03-31", + "release_date": "2025-08-05", + "last_updated": "2025-08-05", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 15.0, + "output": 75.0, + "cache_read": 1.5, + "cache_write": 18.75 + }, + "limit": { + "context": 200000, + "output": 32000 + } + }, + { + "id": "amazon-bedrock/us.anthropic.claude-opus-4.5-20251101-v1:0", + "name": "Claude Opus 4.5 (US)", + "family": "claude-opus", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-03-31", + "release_date": "2025-11-24", + "last_updated": "2025-08-01", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 5.0, + "output": 25.0, + "cache_read": 1.5, + "cache_write": 18.75 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, + { + "id": "amazon-bedrock/us.anthropic.claude-sonnet-4-20250514-v1:0", + "name": "Claude Sonnet 4 (US)", + "family": "claude-sonnet", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2024-04", + "release_date": "2025-05-22", + "last_updated": "2025-05-22", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 3.0, + "output": 15.0, + "cache_read": 0.3, + "cache_write": 3.75 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, + { + "id": "amazon-bedrock/us.anthropic.claude-sonnet-4.5-20250929-v1:0", + "name": "Claude Sonnet 4.5 (US)", + "family": "claude-sonnet", + "attachment": true, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-07-31", + "release_date": "2025-09-29", + "last_updated": "2025-09-29", + "modalities": { + "input": [ + "text", + "image", + "pdf" + ], + "output": [ + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 3.0, + "output": 15.0, + "cache_read": 0.3, + "cache_write": 3.75 + }, + "limit": { + "context": 200000, + "output": 64000 + } + }, { "id": "anthropic/claude-3-haiku", "name": "Claude Haiku 3", @@ -8730,6 +9159,37 @@ "output": 1536 } }, + { + "id": "openrouter/allenai/molmo-2-8b:free", + "name": "Molmo2 8B (free)", + "family": "allenai", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2026-01-09", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "text", + "image", + "video" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 36864, + "output": 36864 + } + }, { "id": "openrouter/anthropic/claude-3.5-haiku", "name": "Claude Haiku 3.5", @@ -9052,6 +9512,190 @@ "output": 131072 } }, + { + "id": "openrouter/black-forest-labs/flux.2-flex", + "name": "FLUX.2 Flex", + "family": "flux", + "attachment": false, + "reasoning": false, + "tool_call": false, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2025-11-25", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "image", + "text" + ], + "output": [ + "image", + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 67344, + "output": 67344 + } + }, + { + "id": "openrouter/black-forest-labs/flux.2-klein-4b", + "name": "FLUX.2 Klein 4B", + "family": "flux", + "attachment": false, + "reasoning": false, + "tool_call": false, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2026-01-14", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "image", + "text" + ], + "output": [ + "image", + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 40960, + "output": 40960 + } + }, + { + "id": "openrouter/black-forest-labs/flux.2-max", + "name": "FLUX.2 Max", + "family": "flux", + "attachment": false, + "reasoning": false, + "tool_call": false, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2025-12-16", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "image", + "text" + ], + "output": [ + "image", + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 46864, + "output": 46864 + } + }, + { + "id": "openrouter/black-forest-labs/flux.2-pro", + "name": "FLUX.2 Pro", + "family": "flux", + "attachment": false, + "reasoning": false, + "tool_call": false, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2025-11-25", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "image", + "text" + ], + "output": [ + "image", + "text" + ] + }, + "open_weights": false, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 46864, + "output": 46864 + } + }, + { + "id": "openrouter/bytedance-seed/seedream-4.5", + "name": "Seedream 4.5", + "family": "seed", + "attachment": false, + "reasoning": false, + "tool_call": false, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2025-12-23", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "image", + "text" + ], + "output": [ + "image", + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 4096, + "output": 4096 + } + }, + { + "id": "openrouter/cognitivecomputations/dolphin-mistral-24b-venice-edition:free", + "name": "Uncensored (free)", + "family": "mistral", + "attachment": false, + "reasoning": false, + "tool_call": true, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2025-07-09", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 32768, + "output": 32768 + } + }, { "id": "openrouter/cognitivecomputations/dolphin3.0-mistral-24b", "name": "Dolphin3.0 Mistral 24B", @@ -9203,7 +9847,7 @@ "family": "deepseek", "attachment": false, "reasoning": true, - "tool_call": true, + "tool_call": false, "temperature": true, "knowledge": "2025-05", "release_date": "2025-05-28", @@ -10181,6 +10825,93 @@ "output": 65536 } }, + { + "id": "openrouter/liquid/lfm-2.5-1.2b-instruct:free", + "name": "LFM2.5-1.2B-Instruct (free)", + "family": "liquid", + "attachment": false, + "reasoning": false, + "tool_call": true, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2026-01-20", + "last_updated": "2026-01-28", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 131072, + "output": 32768 + } + }, + { + "id": "openrouter/liquid/lfm-2.5-1.2b-thinking:free", + "name": "LFM2.5-1.2B-Thinking (free)", + "family": "liquid", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2026-01-20", + "last_updated": "2026-01-28", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 131072, + "output": 32768 + } + }, + { + "id": "openrouter/meta-llama/llama-3.1-405b-instruct:free", + "name": "Llama 3.1 405B Instruct (free)", + "family": "llama", + "attachment": true, + "reasoning": false, + "tool_call": true, + "temperature": true, + "knowledge": "2024-08", + "release_date": "2024-07-23", + "last_updated": "2025-04-05", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 131072, + "output": 131072 + } + }, { "id": "openrouter/meta-llama/llama-3.2-11b-vision-instruct", "name": "Llama 3.2 11B Vision Instruct", @@ -10211,6 +10942,36 @@ "output": 8192 } }, + { + "id": "openrouter/meta-llama/llama-3.2-3b-instruct:free", + "name": "Llama 3.2 3B Instruct (free)", + "family": "llama", + "attachment": true, + "reasoning": false, + "tool_call": true, + "temperature": true, + "knowledge": "2023-12", + "release_date": "2024-09-25", + "last_updated": "2024-09-25", + "modalities": { + "input": [ + "text", + "image" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 131072, + "output": 131072 + } + }, { "id": "openrouter/meta-llama/llama-3.3-70b-instruct:free", "name": "Llama 3.3 70B Instruct (free)", @@ -10236,8 +10997,8 @@ "output": 0.0 }, "limit": { - "context": 65536, - "output": 65536 + "context": 131072, + "output": 131072 } }, { @@ -11003,6 +11764,35 @@ "output": 8192 } }, + { + "id": "openrouter/nousresearch/hermes-3-llama-3.1-405b:free", + "name": "Hermes 3 405B Instruct (free)", + "family": "hermes", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2023-12", + "release_date": "2024-08-16", + "last_updated": "2024-08-16", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 131072, + "output": 131072 + } + }, { "id": "openrouter/nousresearch/hermes-4-405b", "name": "Hermes 4 405B", @@ -11061,6 +11851,65 @@ "output": 131072 } }, + { + "id": "openrouter/nvidia/nemotron-3-nano-30b-a3b:free", + "name": "Nemotron 3 Nano 30B A3B (free)", + "family": "nemotron", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-11", + "release_date": "2025-12-14", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 256000, + "output": 256000 + } + }, + { + "id": "openrouter/nvidia/nemotron-nano-12b-v2-vl:free", + "name": "Nemotron Nano 12B 2 VL (free)", + "family": "nemotron", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-11", + "release_date": "2025-10-28", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "text", + "image" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 128000, + "output": 128000 + } + }, { "id": "openrouter/nvidia/nemotron-nano-9b-v2", "name": "nvidia-nemotron-nano-9b-v2", @@ -11090,6 +11939,35 @@ "output": 131072 } }, + { + "id": "openrouter/nvidia/nemotron-nano-9b-v2:free", + "name": "Nemotron Nano 9B V2 (free)", + "family": "nemotron", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2024-09", + "release_date": "2025-09-05", + "last_updated": "2025-08-18", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 128000, + "output": 128000 + } + }, { "id": "openrouter/openai/gpt-4.1", "name": "GPT-4.1", @@ -11731,6 +12609,34 @@ "output": 32768 } }, + { + "id": "openrouter/openai/gpt-oss-120b:free", + "name": "gpt-oss-120b (free)", + "family": "gpt-oss", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "release_date": "2025-08-05", + "last_updated": "2025-08-05", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 131072, + "output": 32768 + } + }, { "id": "openrouter/openai/gpt-oss-20b", "name": "GPT OSS 20B", @@ -11759,6 +12665,34 @@ "output": 32768 } }, + { + "id": "openrouter/openai/gpt-oss-20b:free", + "name": "gpt-oss-20b (free)", + "family": "gpt-oss", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "release_date": "2025-08-05", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 131072, + "output": 32768 + } + }, { "id": "openrouter/openai/gpt-oss-safeguard-20b", "name": "GPT OSS Safeguard 20B", @@ -11907,6 +12841,36 @@ "output": 8192 } }, + { + "id": "openrouter/qwen/qwen-2.5-vl-7b-instruct:free", + "name": "Qwen2.5-VL 7B Instruct (free)", + "family": "qwen", + "attachment": true, + "reasoning": false, + "tool_call": true, + "temperature": true, + "knowledge": "2025-02", + "release_date": "2024-08-28", + "last_updated": "2024-08-28", + "modalities": { + "input": [ + "text", + "image" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 32768, + "output": 32768 + } + }, { "id": "openrouter/qwen/qwen2.5-vl-32b-instruct:free", "name": "Qwen2.5 VL 32B Instruct (free)", @@ -12259,6 +13223,35 @@ "output": 40960 } }, + { + "id": "openrouter/qwen/qwen3-4b:free", + "name": "Qwen3 4B (free)", + "family": "qwen", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "knowledge": "2025-04", + "release_date": "2025-04-30", + "last_updated": "2025-07-23", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 40960, + "output": 40960 + } + }, { "id": "openrouter/qwen/qwen3-8b:free", "name": "Qwen3 8B (free)", @@ -12490,6 +13483,35 @@ "output": 262144 } }, + { + "id": "openrouter/qwen/qwen3-next-80b-a3b-instruct:free", + "name": "Qwen3 Next 80B A3B Instruct (free)", + "family": "qwen", + "attachment": false, + "reasoning": false, + "tool_call": true, + "temperature": true, + "knowledge": "2025-04", + "release_date": "2025-09-11", + "last_updated": "2025-09-11", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 262144, + "output": 262144 + } + }, { "id": "openrouter/qwen/qwen3-next-80b-a3b-thinking", "name": "Qwen3 Next 80B A3B Thinking", @@ -12606,6 +13628,96 @@ "output": 32768 } }, + { + "id": "openrouter/sourceful/riverflow-v2-fast-preview", + "name": "Riverflow V2 Fast Preview", + "family": "sourceful", + "attachment": false, + "reasoning": false, + "tool_call": false, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2025-12-08", + "last_updated": "2026-01-28", + "modalities": { + "input": [ + "text", + "image" + ], + "output": [ + "image" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 8192, + "output": 8192 + } + }, + { + "id": "openrouter/sourceful/riverflow-v2-max-preview", + "name": "Riverflow V2 Max Preview", + "family": "sourceful", + "attachment": false, + "reasoning": false, + "tool_call": false, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2025-12-08", + "last_updated": "2026-01-28", + "modalities": { + "input": [ + "text", + "image" + ], + "output": [ + "image" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 8192, + "output": 8192 + } + }, + { + "id": "openrouter/sourceful/riverflow-v2-standard-preview", + "name": "Riverflow V2 Standard Preview", + "family": "sourceful", + "attachment": false, + "reasoning": false, + "tool_call": false, + "temperature": true, + "knowledge": "2025-06", + "release_date": "2025-12-08", + "last_updated": "2026-01-28", + "modalities": { + "input": [ + "text", + "image" + ], + "output": [ + "image" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 8192, + "output": 8192 + } + }, { "id": "openrouter/thudm/glm-z1-32b:free", "name": "GLM Z1 32B (free)", @@ -12664,6 +13776,35 @@ "output": 163840 } }, + { + "id": "openrouter/tngtech/tng-r1t-chimera:free", + "name": "R1T Chimera (free)", + "family": "tngtech", + "attachment": false, + "reasoning": true, + "tool_call": false, + "temperature": true, + "knowledge": "2025-07", + "release_date": "2025-11-26", + "last_updated": "2026-01-31", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.0, + "output": 0.0 + }, + "limit": { + "context": 163840, + "output": 163840 + } + }, { "id": "openrouter/x-ai/grok-3", "name": "Grok 3", @@ -13121,6 +14262,34 @@ "output": 131072 } }, + { + "id": "openrouter/z-ai/glm-4.7-flash", + "name": "GLM-4.7", + "family": "glm", + "attachment": false, + "reasoning": true, + "tool_call": true, + "temperature": true, + "release_date": "2026-01-19", + "last_updated": "2026-01-19", + "modalities": { + "input": [ + "text" + ], + "output": [ + "text" + ] + }, + "open_weights": true, + "cost": { + "input": 0.07, + "output": 0.4 + }, + "limit": { + "context": 200000, + "output": 65535 + } + }, { "id": "venice/claude-opus-45", "name": "Claude Opus 4.5", diff --git a/crates/goose/src/providers/databricks.rs b/crates/goose/src/providers/databricks.rs index 16fced6ac2..b1b2edc669 100644 --- a/crates/goose/src/providers/databricks.rs +++ b/crates/goose/src/providers/databricks.rs @@ -36,7 +36,7 @@ const DEFAULT_TIMEOUT_SECS: u64 = 600; const DATABRICKS_PROVIDER_NAME: &str = "databricks"; pub const DATABRICKS_DEFAULT_MODEL: &str = "databricks-claude-sonnet-4"; -const DATABRICKS_DEFAULT_FAST_MODEL: &str = "gemini-2-5-flash"; +const DATABRICKS_DEFAULT_FAST_MODEL: &str = "databricks-claude-haiku-4-5"; pub const DATABRICKS_KNOWN_MODELS: &[&str] = &[ "databricks-claude-sonnet-4-5", "databricks-claude-3-7-sonnet", diff --git a/crates/goose/src/session_context.rs b/crates/goose/src/session_context.rs index 8443b2e374..a7126ede09 100644 --- a/crates/goose/src/session_context.rs +++ b/crates/goose/src/session_context.rs @@ -1,6 +1,7 @@ use tokio::task_local; pub const SESSION_ID_HEADER: &str = "agent-session-id"; +pub const WORKING_DIR_HEADER: &str = "agent-working-dir"; task_local! { pub static SESSION_ID: Option; diff --git a/crates/goose/tests/mcp_integration_test.rs b/crates/goose/tests/mcp_integration_test.rs index 22a279305e..c6e339e8d6 100644 --- a/crates/goose/tests/mcp_integration_test.rs +++ b/crates/goose/tests/mcp_integration_test.rs @@ -267,7 +267,12 @@ async fn test_replayed_session( arguments: tool_call.arguments, }; let result = extension_manager - .dispatch_tool_call("test-session-id", tool_call, CancellationToken::default()) + .dispatch_tool_call( + "test-session-id", + tool_call, + None, + CancellationToken::default(), + ) .await; let tool_result = result?; diff --git a/documentation/docs/getting-started/providers.md b/documentation/docs/getting-started/providers.md index aa3a990d67..ff2a4e7776 100644 --- a/documentation/docs/getting-started/providers.md +++ b/documentation/docs/getting-started/providers.md @@ -34,9 +34,10 @@ goose is compatible with a wide range of LLM providers, allowing you to choose a | [LiteLLM](https://docs.litellm.ai/docs/) | LiteLLM proxy supporting multiple models with automatic prompt caching and unified API access. | `LITELLM_HOST`, `LITELLM_BASE_PATH` (optional), `LITELLM_API_KEY` (optional), `LITELLM_CUSTOM_HEADERS` (optional), `LITELLM_TIMEOUT` (optional) | | [Mistral AI](https://mistral.ai/) | Provides access to Mistral models including general-purpose models, specialized coding models (Codestral), and multimodal models (Pixtral). | `MISTRAL_API_KEY` | | [Ollama](https://ollama.com/) | Local model runner supporting Qwen, Llama, DeepSeek, and other open-source models. **Because this provider runs locally, you must first [download and run a model](#local-llms).** | `OLLAMA_HOST` | -| [Ramalama](https://ramalama.ai/) | Local model using native [OCI](https://opencontainers.org/) container runtimes, [CNCF](https://www.cncf.io/) tools, and supporting models as OCI artifacts. Ramalama API an compatible alternative to Ollama and can be used with the goose Ollama provider. Supports Qwen, Llama, DeepSeek, and other open-source models. **Because this provider runs locally, you must first [download and run a model](#local-llms).** | `OLLAMA_HOST` | | [OpenAI](https://platform.openai.com/api-keys) | Provides gpt-4o, o1, and other advanced language models. Also supports OpenAI-compatible endpoints (e.g., self-hosted LLaMA, vLLM, KServe). **o1-mini and o1-preview are not supported because goose uses tool calling.** | `OPENAI_API_KEY`, `OPENAI_HOST` (optional), `OPENAI_ORGANIZATION` (optional), `OPENAI_PROJECT` (optional), `OPENAI_CUSTOM_HEADERS` (optional) | | [OpenRouter](https://openrouter.ai/) | API gateway for unified access to various models with features like rate-limiting management. | `OPENROUTER_API_KEY` | +| [OVHcloud AI](https://www.ovhcloud.com/en/public-cloud/ai-endpoints/) | Provides access to open-source models including Qwen, Llama, Mistral, and DeepSeek through AI Endpoints service. | `OVHCLOUD_API_KEY` | +| [Ramalama](https://ramalama.ai/) | Local model using native [OCI](https://opencontainers.org/) container runtimes, [CNCF](https://www.cncf.io/) tools, and supporting models as OCI artifacts. Ramalama API is a compatible alternative to Ollama and can be used with the goose Ollama provider. Supports Qwen, Llama, DeepSeek, and other open-source models. **Because this provider runs locally, you must first [download and run a model](#local-llms).** | `OLLAMA_HOST` | | [Snowflake](https://docs.snowflake.com/user-guide/snowflake-cortex/aisql#choosing-a-model) | Access the latest models using Snowflake Cortex services, including Claude models. **Requires a Snowflake account and programmatic access token (PAT)**. | `SNOWFLAKE_HOST`, `SNOWFLAKE_TOKEN` | | [Tetrate Agent Router Service](https://router.tetrate.ai) | Unified API gateway for AI models including Claude, Gemini, GPT, open-weight models, and others. Supports PKCE authentication flow for secure API key generation. | `TETRATE_API_KEY`, `TETRATE_HOST` (optional) | | [Venice AI](https://venice.ai/home) | Provides access to open source models like Llama, Mistral, and Qwen while prioritizing user privacy. **Requires an account and an [API key](https://docs.venice.ai/overview/guides/generating-api-key)**. | `VENICE_API_KEY`, `VENICE_HOST` (optional), `VENICE_BASE_PATH` (optional), `VENICE_MODELS_PATH` (optional) | diff --git a/documentation/docs/guides/config-files.md b/documentation/docs/guides/config-files.md index 30d07fb1c0..b1faf2822d 100644 --- a/documentation/docs/guides/config-files.md +++ b/documentation/docs/guides/config-files.md @@ -19,6 +19,7 @@ The configuration files allow you to set default behaviors, configure language m - **permission.yaml** - Tool permission levels configured via `goose configure` - **secrets.yaml** - API keys and secrets (only when keyring is disabled) - **permissions/tool_permissions.json** - Runtime permission decisions (auto-managed) +- **prompts/** - Customized [prompt templates](/docs/guides/prompt-templates) In addition to editing configuration files directly, many settings can be managed from goose Desktop and goose CLI: - **goose Desktop**: From the `Settings` page and the bottom toolbar diff --git a/documentation/docs/guides/creating-plans.md b/documentation/docs/guides/creating-plans.md index 9dce591a6c..141c7767e2 100644 --- a/documentation/docs/guides/creating-plans.md +++ b/documentation/docs/guides/creating-plans.md @@ -38,6 +38,10 @@ The goose CLI plan mode uses two configuration values: goose also supports automatic model switching with [Lead/Worker mode](/docs/guides/environment-variables#leadworker-model-configuration), which provides turn-based switching between two models to help balance model capabilities with cost and speed. ::: +:::tip Customize Plan Format +You can also customize how goose creates plans by editing the `plan.md` [prompt template](/docs/guides/prompt-templates). +::: + ### Set goose planner environment variables You might add these lines to your bash shell config file (.bashrc) to add the planner environment variables: ```bash @@ -318,13 +322,27 @@ To enter planning mode, type `/plan`. Optionally, you can append your plan desc ( O)> /endplan ``` -
-

📚 Featured Tutorial

-
- -
-
+## Additional Resources + +import ContentCardCarousel from '@site/src/components/ContentCardCarousel'; +import blogBanner from '@site/blog/2025-12-19-does-your-ai-agent-need-a-plan/blog-banner.png'; + + \ No newline at end of file diff --git a/documentation/docs/guides/environment-variables.md b/documentation/docs/guides/environment-variables.md index c2cd7196d2..9b9f4bee3f 100644 --- a/documentation/docs/guides/environment-variables.md +++ b/documentation/docs/guides/environment-variables.md @@ -55,6 +55,71 @@ export GOOSE_PROVIDER__HOST="https://api.anthropic.com" export GOOSE_PROVIDER__API_KEY="your-api-key-here" ``` +### Custom Model Definitions + +Define custom model configurations with provider-specific parameters and context limits. This is useful for enabling provider beta features (like extended context windows) or configuring models with specific settings. + +| Variable | Purpose | Values | Default | +|----------|---------|---------|---------| +| `GOOSE_PREDEFINED_MODELS` | Define custom model configurations | JSON array of model objects | None | + +**Model Configuration Fields:** + +| Field | Required | Type | Description | +|-------|----------|------|-------------| +| `id` | No | number | Optional numeric identifier | +| `name` | Yes | string | Model name used to reference this configuration | +| `provider` | Yes | string | Provider name (e.g., "databricks", "openai", "anthropic") | +| `alias` | No | string | Display name for the model | +| `subtext` | No | string | Additional descriptive text | +| `context_limit` | No | number | Override the default context window size in tokens | +| `request_params` | No | object | Provider-specific parameters included in API requests | + +:::info +The `id`, `alias`, and `subtext` fields are currently not used. +::: + +When a custom model's `context_limit` is specified, it takes precedence over pattern-matching but can still be overridden by explicit environment variables like [`GOOSE_CONTEXT_LIMIT`](#model-context-limit-overrides). + +**Examples** + +```bash +# Enable Anthropic's 1M context window with beta header +export GOOSE_PREDEFINED_MODELS='[ + { + "id": 1, + "name": "claude-sonnet-4-1m", + "provider": "anthropic", + "alias": "Claude Sonnet 4 (1M context)", + "subtext": "Anthropic", + "context_limit": 1000000, + "request_params": { + "anthropic_beta": ["context-1m-2025-08-07"] + } + } +]' + +# Define multiple custom models +export GOOSE_PREDEFINED_MODELS='[ + { + "id": 1, + "name": "gpt-4-custom", + "provider": "openai", + "alias": "GPT-4 (200k)", + "context_limit": 200000 + }, + { + "id": 2, + "name": "internal-model", + "provider": "databricks", + "alias": "Internal Model (500k)", + "context_limit": 500000 + } +]' +``` + +Custom context limits and request parameters are applied when the model is used. Custom context limits are displayed in goose CLI's [token usage indicator](/docs/guides/sessions/smart-context-management#token-usage). + ### Lead/Worker Model Configuration These variables configure a [lead/worker model pattern](/docs/tutorials/lead-worker) where a powerful lead model handles initial planning and complex reasoning, then switches to a faster/cheaper worker model for execution. The switch happens automatically based on your settings. @@ -157,6 +222,7 @@ These variables control how goose manages conversation sessions and context. | `GOOSE_MAX_TURNS` | [Maximum number of turns](/docs/guides/sessions/smart-context-management#maximum-turns) allowed without user input | Integer (e.g., 10, 50, 100) | 1000 | | `GOOSE_SUBAGENT_MAX_TURNS` | Sets the maximum turns allowed for a [subagent](/docs/guides/subagents) to complete before timeout | Integer (e.g., 25) | 25 | | `CONTEXT_FILE_NAMES` | Specifies custom filenames for [hint/context files](/docs/guides/context-engineering/using-goosehints#custom-context-files) | JSON array of strings (e.g., `["CLAUDE.md", ".goosehints"]`) | `[".goosehints"]` | +| `GOOSE_PROMPT_EDITOR` | [External editor](/docs/guides/goose-cli-commands#external-editor-mode) to use for composing prompts instead of CLI input | Editor command (e.g., "vim", "code --wait") | Unset (uses CLI input) | | `GOOSE_CLI_THEME` | [Theme](/docs/guides/goose-cli-commands#themes) for CLI response markdown | "light", "dark", "ansi" | "dark" | | `GOOSE_CLI_NEWLINE_KEY` | Customize the keyboard shortcut for [inserting newlines in CLI input](/docs/guides/goose-cli-commands#keyboard-shortcuts) | Single character (e.g., "n", "m") | "j" (Ctrl+J) | | `GOOSE_RANDOM_THINKING_MESSAGES` | Controls whether to show amusing random messages during processing | "true", "false" | "true" | @@ -187,6 +253,9 @@ export GOOSE_SUBAGENT_MAX_TURNS=50 # Use multiple context files export CONTEXT_FILE_NAMES='["CLAUDE.md", ".goosehints", ".cursorrules", "project_rules.txt"]' +# Use vim for composing prompts +export GOOSE_PROMPT_EDITOR=vim + # Set the ANSI theme for the session export GOOSE_CLI_THEME=ansi diff --git a/documentation/docs/guides/goose-cli-commands.md b/documentation/docs/guides/goose-cli-commands.md index ace3687f41..29fdb5153a 100644 --- a/documentation/docs/guides/goose-cli-commands.md +++ b/documentation/docs/guides/goose-cli-commands.md @@ -187,6 +187,7 @@ Start or resume interactive chat sessions. - **`-n, --name `**: Give the session a name - **`--path `**: Legacy parameter for specifying session by file path - **`-r, --resume`**: Resume a previous session +- **`--fork`**: Create a new duplicate session with copied history. Must be used with `--resume`. Provide `--name` or `--session-id` to fork a specific session. Otherwise forks the most recent session. - **`--history`**: Show previous messages when resuming a session - **`--debug`**: Enable debug mode to output complete tool responses, detailed parameter values, and full file paths - **`--max-tool-repetitions `**: Set the maximum number of times the same tool can be called consecutively with identical parameters. Helps prevent infinite loops. @@ -208,6 +209,12 @@ goose session --resume --session-id 20251108_2 goose session --resume --path ./session.json # exported session goose session --resume --path ./session.jsonl # legacy session storage +# Fork a specific session by name +goose session --resume --fork --name my-project + +# Fork the most recent session and show message history +goose session --resume --fork --history + # Start with extensions goose session --with-extension "npx -y @modelcontextprotocol/server-memory" goose session --with-builtin developer @@ -740,6 +747,59 @@ goose session --name use-custom-theme --- +### External Editor Mode + +For composing longer prompts or working with complex code snippets, you can configure goose to use your preferred text editor instead of CLI input. This replaces the standard CLI input and keyboard shortcuts for the entire session. + +**How it works:** +1. goose opens your configured editor with a template file +2. Type your prompt after the `# Your prompt:` heading (conversation history is shown below for context) +3. Save the file and close/exit the editor to send your prompt to goose +4. goose processes your prompt and reopens the editor with the response added to the conversation history +5. Repeat steps 2-4 for each message in the conversation + +You can use any editor that accepts a file path argument, such as vim, nano, emacs, and VS Code. + +**Configuration:** + + + + + Applies to the current session only. + + ```bash + # For terminal editors like vim or nano + export GOOSE_PROMPT_EDITOR=vim + + # Or for GUI editors like VS Code (use --wait flag) + export GOOSE_PROMPT_EDITOR="code --wait" + ``` + + + + + Persists across all sessions unless overridden by the environment variable. + + 1. Navigate to the goose [configuration file](/docs/guides/config-files). For example, navigate to `~/.config/goose/config.yaml` on macOS. + 2. Add `GOOSE_PROMPT_EDITOR` and set it to your preferred editor: + + ```yaml + # For terminal editors like vim or nano + GOOSE_PROMPT_EDITOR: vim + + # Or for GUI editors like VS Code (use --wait flag) + GOOSE_PROMPT_EDITOR: code --wait + ``` + + + + +**Using GUI Editors:** + +GUI editors require a `--wait` or equivalent flag to ensure goose waits for you to finish editing before continuing. Without this flag, the editor opens but goose immediately proceeds as if you're done. Terminal editors like vim and nano don't need this flag. + +--- + ### Command History Search The `Ctrl+R` shortcut provides interactive search through your stored CLI [command history](/docs/guides/logs#command-history). This feature makes it easy to find and reuse recent commands without retyping them. When you type a search term, goose searches backwards through your history for matches. diff --git a/documentation/docs/guides/managing-tools/code-mode.md b/documentation/docs/guides/managing-tools/code-mode.md index 9562f0c75e..4db2c26415 100644 --- a/documentation/docs/guides/managing-tools/code-mode.md +++ b/documentation/docs/guides/managing-tools/code-mode.md @@ -32,7 +32,7 @@ Traditional MCP tool calling and Code Mode are two different approaches to the s | Aspect | Traditional | Code Mode | |--------|------------------|-----------| -| **Tool Discovery** | All tools from enabled extensions, for example:
• `developer.shell`
• `developer.text_editor`
• `github.list_issues`
• `github.get_pull_request`
• `slack.send_message`
• ... *potentially many more* | Code Execution extension's meta-tools:
• `search_modules`
• `read_module`
• `execute_code`

The LLM uses these tools to discover tools from other enabled extensions as needed | +| **Tool Discovery** | All tools from enabled extensions, for example:
• `developer.shell`
• `developer.text_editor`
• `github.list_issues`
• `github.get_pull_request`
• `slack.send_message`
• ... *potentially many more* | Code Execution extension's meta-tools:
• `list_functions`
• `get_function_details`
• `execute`

The LLM uses these tools to discover tools from other enabled extensions as needed | | **Tool Calling** | • Sequential tool calls
• Each result sent to the LLM before the next call | • May require tool discovery calls
• Multiple tool calls batched in one execution
• Intermediate results are chained and processed locally | | **Context Window** | Every LLM call includes all tool definitions from enabled extensions | Every LLM call includes the 3 meta-tool definitions, plus any tool definitions previously discovered in the session | | **Best For** | • 1-3 enabled extensions
• Simple tasks using 1-2 tools | • 5+ extensions
• Well-defined multi-step workflows | diff --git a/documentation/docs/guides/prompt-templates.md b/documentation/docs/guides/prompt-templates.md new file mode 100644 index 0000000000..596b5b299d --- /dev/null +++ b/documentation/docs/guides/prompt-templates.md @@ -0,0 +1,137 @@ +--- +sidebar_position: 86 +title: Customizing Prompt Templates +sidebar_label: Prompt Templates +description: Learn how to customize the prompt templates that define goose's behavior in different situations +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import { PanelLeft } from 'lucide-react'; + +goose comes with built-in prompt templates that guide its behavior in different situations. You can edit these templates to customize how goose responds, creates plans, decides what to save during compaction, and more. + +## How It Works + +goose's default prompt templates are defined in the codebase and embedded in the application. You can override any default by creating a custom version in your local config directory (either directly or via goose Desktop). + +When you customize a template: + +- Your customizations persist across goose updates +- Changes to defaults in the codebase don't affect your customized templates +- You can reset to default templates at any time +- Changes take effect in new sessions + +Your changes can range from major updates to minor adjustments such as: +- Edit `system.md` to have goose respond in Dutch by adding an instruction to "Reply in Dutch" +- Edit `plan.md` to add time estimates by adding instructions to "Include an estimated time for each step (e.g., "~5 min", "~30 min", "~2 hours")." + +See [Template Variable Syntax](#template-variable-syntax) for important information about modifying template variables. + +:::info Related Configuration +Other goose settings and features can also affect behavior or provide context, such as [config files](/docs/guides/config-files), [.goosehints](/docs/guides/context-engineering/using-goosehints), and [skills](/docs/guides/context-engineering/using-skills). +::: + +## Managing Prompt Templates + + + + + goose Desktop users can manage templates from the `Settings` page. + + **To customize a template:** + + 1. Click the button in the top-left to open the sidebar + 2. Click `Settings` in the sidebar + 3. Click the `Prompts` tab + 4. Click `Edit` next to the template you want to change + 5. Make your changes in the editor. You can click `Restore Default` to start over from the default template at any time. + 6. Click `Save` to apply your customization + + Customized prompt templates display a `Customized` badge. + + **To reset a template to its default:** + + 1. Click the button in the top-left to open the sidebar + 2. Click `Settings` in the sidebar + 3. Click the `Prompts` tab + 4. Click `Edit` next to the template you want to reset + 5. Click `Reset to Default` to delete your local template file + + Or click `Reset All` at the top of the tab to delete all of your local template files. + + + + + goose CLI users can edit template files directly in the file system. + + Custom templates are stored in: + + - **macOS/Linux:** `~/.config/goose/prompts/` + - **Windows:** `%APPDATA%\Block\goose\config\prompts\` + + **To customize a template:** + + 1. Create the `prompts` directory if it doesn't exist + 2. Copy the template file name from the table above (e.g., `system.md`) + 3. Create a file with that name in your prompts directory + 4. Add your custom content and save your changes. We recommend that you start by reviewing or copying the default template (linked in the [table](#available-prompt-templates) above). + + **To reset a template to its default:** + + 1. Delete the template file from your `prompts` directory + + + + +### Available Prompt Templates + +The following default templates can be customized. + +| Template | Description | Applies To | +|----------|-------------|------------| +| [system.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/system.md) | General system prompt defining goose's role, capabilities, and response format | Desktop and CLI | +| [apps_create.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/apps_create.md) | Prompt for generating new standalone apps (in development) | Desktop only | +| [apps_iterate.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/apps_iterate.md) | Prompt for updating existing standalone apps (in development) | Desktop only | +| [compaction.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/compaction.md) | Prompt for summarizing conversation history when context limits are reached | Desktop and CLI | +| [desktop_prompt.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/desktop_prompt.md) | Context about the user interface and available features | Desktop only | +| [desktop_recipe_instruction.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/desktop_recipe_instruction.md) | Instructions for executing recipes | Desktop only | +| [permission_judge.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/permission_judge.md) | Prompt for analyzing tool operations for read-only detection | Desktop and CLI | +| [plan.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/plan.md) | Instructions for creating detailed, actionable plans with clarifying questions | CLI only | +| [recipe.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/recipe.md) | Prompt for generating recipe files from conversations | Desktop and CLI | +| [subagent_system.md](https://github.com/block/goose/blob/main/crates/goose/src/prompts/subagent_system.md) | System prompt for subagents spawned to handle specific tasks | Desktop and CLI | + +Customizable templates are enumerated in the `TEMPLATE_REGISTRY` array in [`prompt_template.rs`](https://github.com/block/goose/blob/main/crates/goose/src/prompt_template.rs). + +### Template Variable Syntax + +Templates use [Jinja2](https://jinja.palletsprojects.com/) syntax for dynamic content: + +- `{{ variable }}` - Inserts a value (e.g., `{{ extensions }}` lists enabled extensions) +- `{% if condition %}...{% endif %}` - Conditional sections +- `{% for item in list %}...{% endfor %}` - Loops over items + +Check out the default templates (linked to from the [table](#available-prompt-templates) above) to find common variables, such as `{{ extensions }}` and `{{ hints }}`. + +:::warning +Be careful when modifying template variables, as incorrect changes can break functionality. Test your changes in a new session to ensure they work as expected. +::: + +## Additional Resources + +import ContentCardCarousel from '@site/src/components/ContentCardCarousel'; +import promptBanner from '@site/blog/2025-03-19-better-ai-prompting/prompt.png'; + + diff --git a/documentation/docs/guides/recipes/session-recipes.md b/documentation/docs/guides/recipes/session-recipes.md index f2c857e260..369914892b 100644 --- a/documentation/docs/guides/recipes/session-recipes.md +++ b/documentation/docs/guides/recipes/session-recipes.md @@ -180,6 +180,10 @@ You can turn your current goose session into a reusable recipe that includes the +:::tip Customize Recipe Generation +You can customize how goose generates recipes by editing the `recipe.md` [prompt template](/docs/guides/prompt-templates). +::: + ## Edit Recipe diff --git a/documentation/docs/guides/sessions/in-session-actions.md b/documentation/docs/guides/sessions/in-session-actions.md index 45776ea0a5..07538ce158 100644 --- a/documentation/docs/guides/sessions/in-session-actions.md +++ b/documentation/docs/guides/sessions/in-session-actions.md @@ -73,16 +73,20 @@ Forking sessions is useful to: - 1. Hover over any of your previous messages 2. Click the `Edit` button that appears 3. Make your changes in the inline editor 4. Click `Fork Session` to save your changes and start a new session (or use `Cmd+Enter` (macOS) or `Ctrl+Enter` (Windows/Linux)) - goose copies the conversation history from the original session to the new session. The new session is named "(edited)" and the original session is unchanged. - + goose creates a new session with conversation history up to and including your edited message. The new session is named "(edited)" and the original session remains unchanged. + + :::tip Fork vs Duplicate + - **Fork Session** (Edit button on a message): Creates a new session with history up to a specific edited message. Use this to explore different approaches from a particular point in the conversation. + - **[Duplicate Session](/docs/guides/sessions/session-management#duplicate-sessions)** (Copy button in session list): Creates a complete copy of the entire session. Use this to preserve a working session or reuse its configuration. + ::: + - Message editing options are not available in the goose CLI. + Message editing is not available in the goose CLI, but you can [duplicate entire sessions](/docs/guides/sessions/session-management#duplicate-sessions) using the `--fork` flag. diff --git a/documentation/docs/guides/sessions/session-management.md b/documentation/docs/guides/sessions/session-management.md index 4389482435..11afad6957 100644 --- a/documentation/docs/guides/sessions/session-management.md +++ b/documentation/docs/guides/sessions/session-management.md @@ -53,7 +53,15 @@ In your first session, goose prompts you to [set up an LLM (Large Language Model | Focus goose Window | `Cmd+Option+G` | `Ctrl+Alt+G` | | Keep goose Window Always on Top | `Cmd+Shift+T` | `Ctrl+Shift+T` | -
+ #### Customize Keyboard Shortcuts + + You can customize these keyboard shortcuts in the **Settings** menu: + 1. Click the button in the top-left to open the sidebar + 2. Click `Settings` + 3. Click the `Keyboard` tab + + Changes to global shortcuts (Focus Window, Quick Launcher) take effect immediately. Changes to application shortcuts (New Chat, Settings, etc.) require restarting goose. + #### Quick Launcher Start a new session by typing your prompt into a popup: 1. Press `Cmd+Option+Shift+G` (macOS) or `Ctrl+Alt+Shift+G` (Windows/Linux) to open the popup @@ -143,6 +151,10 @@ Search allows you to find specific content within sessions or find specific sess | Toggle Case-Sensitivity | `Aa` | `Aa` | | Close Search | `Esc` or `X` | `Esc` or `X` | + :::tip Customize Search Shortcuts + You can [customize](#keyboard-shortcuts) the Find, Find Next, and Find Previous keyboard shortcuts in **Settings** → **Keyboard** tab. + ::: + :::info No Regex or operator support Using regular expressions or search operators in search text isn't supported. ::: @@ -328,6 +340,63 @@ While you can resume sessions, we recommend creating new sessions for new tasks +## Duplicate Sessions + +Create a complete copy of any session to reuse configurations, experiment with variations, or preserve important work. + + + + + Duplicate a session from the session list: + + 1. Click the button in the top-left to open the sidebar + 2. Click `View All` at the bottom of the `Chat` section + 3. Find the session you want to duplicate + 4. Hover over the session card to reveal the action buttons + 5. Click the button that appears in the top-right corner + + The duplicated session includes: + - Complete conversation history + - All session metadata and settings + - Provider and model configuration + - Extension data and configurations + - Recipe information (if applicable) + + The new session is named the same as the original and appears at the top of your session list. + + :::tip Duplicate vs Fork Session + - **Duplicate** (Copy button in session list): Creates a complete copy of the entire session. Use this to preserve a working session or reuse its configuration. + - **[Fork Session](/docs/guides/sessions/in-session-actions#fork-session)** (Edit button on a message): Creates a new session with conversation history up to a specific edited message. Use this when editing a message to explore different approaches from that point. + ::: + + + + + Create a new session by copying all messages from a previous session using the `--fork` flag along with `--resume`. + + ```bash + # Fork the most recent session + goose session --resume --fork + + # Fork a specific session by name + goose session --resume --fork --name my-project + + # Fork a specific session by ID + goose session --resume --fork --session-id 20251108_3 + + # Fork and show message history + goose session --resume --fork --history + ``` + + The forked session includes: + - Complete conversation history from the original session + - All session metadata and settings + - Provider and model configuration + - Extension data and configurations + - Recipe information (if applicable) + + + ## Delete Sessions diff --git a/documentation/docs/guides/sessions/smart-context-management.md b/documentation/docs/guides/sessions/smart-context-management.md index df6b3e4159..c1bff50bc9 100644 --- a/documentation/docs/guides/sessions/smart-context-management.md +++ b/documentation/docs/guides/sessions/smart-context-management.md @@ -41,6 +41,10 @@ When you reach the auto-compaction threshold: 2. Once complete, you'll see a confirmation message that the conversation was compacted and summarized. 3. Continue the session. Your previous conversation remains visible, but only the compacted conversion is included in the active context for goose. +:::tip Customize Compaction +You can customize how goose summarizes conversations during compaction by editing the `compaction.md` [prompt template](/docs/guides/prompt-templates). +::: + ### Manual Compaction You can also trigger compaction manually before reaching context or token limits: diff --git a/documentation/docs/guides/subagents.mdx b/documentation/docs/guides/subagents.mdx index 0b5da174f2..7fbd41302d 100644 --- a/documentation/docs/guides/subagents.mdx +++ b/documentation/docs/guides/subagents.mdx @@ -248,6 +248,10 @@ Subagents use the following pre-configured settings, but you can override any de | **Extensions** | Inherited from parent | Specify which extensions to use in your prompt | | **Return Mode** | All subagent information provided in main session | Specify how much detail you want in your prompt | +:::tip Advanced Customization +You can also customize subagent behavior by editing the `subagent_system.md` [prompt template](/docs/guides/prompt-templates). +::: + ### Customizing Settings in Prompts You can override any default by including the setting in your natural language request: diff --git a/documentation/docs/guides/using-gooseignore.md b/documentation/docs/guides/using-gooseignore.md index 704a290f8e..6423828269 100644 --- a/documentation/docs/guides/using-gooseignore.md +++ b/documentation/docs/guides/using-gooseignore.md @@ -20,7 +20,7 @@ goose supports two types of `.gooseignore` files: - **Local ignore file** - Create a `.gooseignore` file at the root of the directory you'd like it applied to. These restrictions will only apply when working in a specific directory. :::tip -You can use both global and local `.gooseignore` files simultaneously. When both exist, goose will combine the restrictions from both files to determine which paths are restricted. +You can use both global and local `.gooseignore` files simultaneously. When both exist, goose will apply patterns from both files, with local patterns able to override global ones using negation. ::: ## Example `.gooseignore` file @@ -41,46 +41,91 @@ downloads/ # Ignore everything in the "downloads" directory # Ignore all files with this name in any directory **/credentials.json # Ignore all files named "credentials.json" in any directory - -# Complex patterns -*.log # Ignore all .log files -!error.log # Except for error.log file ``` +## Negation Patterns + +Use the `!` prefix to exclude files from ignore rules. This allows you to ignore broad patterns while allowing specific exceptions. + +Within each `.gooseignore` file, patterns are processed in order from top to bottom, so later patterns can override earlier ones. Negation patterns also work across files - you can use negation in your local `.gooseignore` to allow access to files blocked by your global `.gooseignore`. + +```plaintext +# Ignore all environment files +**/.env* + +# But allow the example file +!.env.example + +# Ignore all log files +*.log + +# But allow error logs +!error.log + +# Ignore all JSON files in the config directory +config/*.json + +# But allow the template +!config/template.json +``` + +:::tip Pattern Order Matters +Negation patterns must come after the patterns they're negating. The `!` pattern re-includes files that were previously ignored. +::: + ## Ignore File Types and Priority -goose respects ignore rules from global `.gooseignore` and local `.gooseignore` files. It uses a priority system to determine which files should be ignored. -### 1. Global `.gooseignore` -- Highest priority and always applied first -- Located at `~/.config/goose/.gooseignore` -- Affects all projects on your machine +goose respects ignore rules from global and local `.gooseignore` files, using a priority system where later patterns can override earlier ones. + +### When You Have Ignore Files + +When `.gooseignore` files exist, patterns are applied in this order: + +1. **Global `.gooseignore`** (applied first) + - Located at `~/.config/goose/.gooseignore` + - Affects all projects on your machine + +2. **Local `.gooseignore`** (applied second, can override global) + - Located in the current working directory (the root of the directory you want these rules applied to) + - Project-specific rules that can override global patterns ``` ~/.config/goose/ -└── .gooseignore ← Applied to all projects -``` - -### 2. Local `.gooseignore` -- Project-specific rules -- Located in your project root directory - -``` -~/.config/goose/ -└── .gooseignore ← Global rules applied first +└── .gooseignore ← Global patterns applied first Project/ -├── .gooseignore ← Local rules applied second +├── .gooseignore ← Local patterns applied second (can override global) └── src/ ``` -### 3. Default Patterns -By default, if you haven't created any .gooseignore files, goose will not modify files matching these patterns: +Because patterns are processed in order, you can use negation patterns in your local `.gooseignore` to allow access to files that were blocked by global patterns. + +**Example: Override global restrictions in a specific project** + +```plaintext +# In ~/.config/goose/.gooseignore (global) +**/.env* # Block all .env files everywhere + +# In your-project/.gooseignore (local) +!.env.example # Allow .env.example in this project only +``` + +In this example, `.env` and `.env.local` remain blocked, but `.env.example` is accessible in this specific project. + +### Default Patterns (No Ignore Files) + +If you haven't created any `.gooseignore` files (neither global nor local), goose automatically protects these sensitive files: + ```plaintext **/.env **/.env.* **/secrets.* ``` +:::info +These default patterns are only active when **no** `.gooseignore` files exist. Once you create either a global or local `.gooseignore` file, you'll need to add these patterns yourself if you want to keep them. +::: + ## Common use cases Here are some typical scenarios where `.gooseignore` is helpful: @@ -89,4 +134,4 @@ Here are some typical scenarios where `.gooseignore` is helpful: - **Third-Party Code**: Keep goose from changing external libraries or dependencies - **Important Configurations**: Protect critical configuration files from accidental modifications - **Version Control**: Prevent changes to version control files like `.git` directory -- **Custom Restrictions**: Create `.gooseignore` files to define which files goose should not access \ No newline at end of file +- **Custom Restrictions**: Create `.gooseignore` files to define which files goose should not access diff --git a/scripts/diagnostics-viewer.py b/scripts/diagnostics-viewer.py index 95aec894a1..049685a64b 100755 --- a/scripts/diagnostics-viewer.py +++ b/scripts/diagnostics-viewer.py @@ -1,6 +1,6 @@ #!/usr/bin/env -S uv run --quiet --script # /// script -# dependencies = ["textual>=0.87.0"] +# dependencies = ["textual>=0.87.0", "pyperclip"] # /// """ WARNING: entirely vibe coded. use as a throwaway tool @@ -17,6 +17,8 @@ import zipfile from pathlib import Path from typing import Optional, Any +import pyperclip + from textual.app import App, ComposeResult from textual.widgets import Header, Footer, Static, Tree, ListView, ListItem, Label, Input from textual.containers import Horizontal, Vertical, VerticalScroll, Container @@ -145,6 +147,7 @@ class TextViewerModal(ModalScreen): BINDINGS = [ Binding("escape,q,enter", "dismiss", "Close", show=True), + Binding("c", "copy", "Copy", show=True), ] def __init__(self, title: str, text: str): @@ -158,12 +161,17 @@ class TextViewerModal(ModalScreen): yield Static(f"[bold]{self.title}[/bold]", id="modal-title") with VerticalScroll(id="modal-scroll"): yield Static(self.text, id="modal-text") - yield Static("[dim]Press Escape, Q, or Enter to close[/dim]", id="modal-footer") + yield Static("[dim]Press C to copy, Escape/Q/Enter to close[/dim]", id="modal-footer") def action_dismiss(self): """Dismiss the modal.""" self.app.pop_screen() + def action_copy(self): + """Copy the text to clipboard.""" + pyperclip.copy(self.text) + self.notify("Copied to clipboard") + class SearchOverlay(Container): """Search overlay widget.""" diff --git a/scripts/test_compaction.sh b/scripts/test_compaction.sh index baa3b7ca96..876ee51421 100755 --- a/scripts/test_compaction.sh +++ b/scripts/test_compaction.sh @@ -2,6 +2,11 @@ # Compaction smoke test script # Tests both manual (trigger prompt) and auto compaction (threshold-based) +# +# Environment variable overrides: +# COMPACTION_PROVIDER - Override the provider for tests 1 & 2 (default: use system default) +# COMPACTION_MODEL - Override the model for tests 1 & 2 (default: use system default) +# SKIP_BUILD - Skip cargo build if set if [ -f .env ]; then export $(grep -v '^#' .env | xargs) @@ -19,6 +24,19 @@ fi SCRIPT_DIR=$(pwd) GOOSE_BIN="$SCRIPT_DIR/target/release/goose" +# Apply provider/model overrides if set +if [ -n "$COMPACTION_PROVIDER" ]; then + echo "Using override provider: $COMPACTION_PROVIDER" + export GOOSE_PROVIDER="$COMPACTION_PROVIDER" +fi +if [ -n "$COMPACTION_MODEL" ]; then + echo "Using override model: $COMPACTION_MODEL" + export GOOSE_MODEL="$COMPACTION_MODEL" +fi +if [ -n "$COMPACTION_PROVIDER" ] || [ -n "$COMPACTION_MODEL" ]; then + echo "" +fi + # Validation function to check compaction structure in session JSON validate_compaction() { local session_id=$1 diff --git a/scripts/test_providers.sh b/scripts/test_providers.sh index 60bc4c3fb8..024560f734 100755 --- a/scripts/test_providers.sh +++ b/scripts/test_providers.sh @@ -182,9 +182,9 @@ if [ "$CODE_EXEC_MODE" = true ]; then echo "Mode: code_execution (JS batching)" BUILTINS="developer,code_execution" # Match code_execution tool usage: - # - "execute_code | code_execution" or "read_module | code_execution" (fallback format) - # - "tool call | execute_code" or "tool calls | execute_code" (new format with tool_graph) - SUCCESS_PATTERN="(execute_code \| code_execution)|(read_module \| code_execution)|(tool calls? \| execute_code)" + # - "execute | code_execution" or "get_function_details | code_execution" (fallback format) + # - "tool call | execute" or "tool calls | execute" (new format with tool_graph) + SUCCESS_PATTERN="(execute \| code_execution)|(get_function_details \| code_execution)|(tool calls? \| execute)" SUCCESS_MSG="code_execution tool called" FAILURE_MSG="no code_execution tools called" else diff --git a/ui/desktop/openapi.json b/ui/desktop/openapi.json index c77adf7659..cda0170459 100644 --- a/ui/desktop/openapi.json +++ b/ui/desktop/openapi.json @@ -10,7 +10,7 @@ "license": { "name": "Apache-2.0" }, - "version": "1.22.0" + "version": "1.23.0" }, "paths": { "/action-required/tool-confirmation": { @@ -5249,6 +5249,28 @@ "never_allow" ] }, + "PermissionsMetadata": { + "type": "object", + "description": "Sandbox permissions for MCP Apps\nSpecifies which browser capabilities the UI needs access to.\nMaps to the iframe Permission Policy `allow` attribute.", + "properties": { + "camera": { + "type": "boolean", + "description": "Request camera access (maps to Permission Policy `camera` feature)" + }, + "clipboardWrite": { + "type": "boolean", + "description": "Request clipboard write access (maps to Permission Policy `clipboard-write` feature)" + }, + "geolocation": { + "type": "boolean", + "description": "Request geolocation access (maps to Permission Policy `geolocation` feature)" + }, + "microphone": { + "type": "boolean", + "description": "Request microphone access (maps to Permission Policy `microphone` feature)" + } + } + }, "PricingData": { "type": "object", "required": [ @@ -7021,6 +7043,9 @@ "description": "Preferred domain for the app (used for CORS)", "nullable": true }, + "permissions": { + "$ref": "#/components/schemas/PermissionsMetadata" + }, "prefersBorder": { "type": "boolean", "description": "Whether the app prefers to have a border around it", diff --git a/ui/desktop/package-lock.json b/ui/desktop/package-lock.json index 5f31d41e7c..8531e6a1f8 100644 --- a/ui/desktop/package-lock.json +++ b/ui/desktop/package-lock.json @@ -1,12 +1,12 @@ { "name": "goose-app", - "version": "1.22.0", + "version": "1.23.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "goose-app", - "version": "1.22.0", + "version": "1.23.0", "license": "Apache-2.0", "dependencies": { "@mcp-ui/client": "^5.17.3", diff --git a/ui/desktop/package.json b/ui/desktop/package.json index 4f4fa73472..3166488f49 100644 --- a/ui/desktop/package.json +++ b/ui/desktop/package.json @@ -1,7 +1,7 @@ { "name": "goose-app", "productName": "Goose", - "version": "1.22.0", + "version": "1.23.0", "description": "Goose App", "engines": { "node": "^24.10.0", diff --git a/ui/desktop/src/api/index.ts b/ui/desktop/src/api/index.ts index 0ceb269478..feba78d3e4 100644 --- a/ui/desktop/src/api/index.ts +++ b/ui/desktop/src/api/index.ts @@ -1,4 +1,4 @@ // This file is auto-generated by @hey-api/openapi-ts export { addExtension, agentAddExtension, agentRemoveExtension, backupConfig, callTool, cancelDownload, checkProvider, configureProviderOauth, confirmToolAction, createCustomProvider, createRecipe, createSchedule, decodeRecipe, deleteModel, deleteRecipe, deleteSchedule, deleteSession, detectProvider, diagnostics, downloadModel, encodeRecipe, exportApp, exportSession, forkSession, getCustomProvider, getDictationConfig, getDownloadProgress, getExtensions, getPricing, getPrompt, getPrompts, getProviderModels, getSession, getSessionExtensions, getSessionInsights, getSlashCommands, getTools, getTunnelStatus, importApp, importSession, initConfig, inspectRunningJob, killRunningJob, listApps, listModels, listRecipes, listSchedules, listSessions, mcpUiProxy, type Options, parseRecipe, pauseSchedule, providers, readAllConfig, readConfig, readResource, recipeToYaml, recoverConfig, removeConfig, removeCustomProvider, removeExtension, reply, resetPrompt, restartAgent, resumeAgent, runNowHandler, savePrompt, saveRecipe, scanRecipe, scheduleRecipe, sendTelemetryEvent, sessionsHandler, setConfigProvider, setRecipeSlashCommand, startAgent, startOpenrouterSetup, startTetrateSetup, startTunnel, status, stopAgent, stopTunnel, systemInfo, transcribeDictation, unpauseSchedule, updateAgentProvider, updateCustomProvider, updateFromSession, updateSchedule, updateSessionName, updateSessionUserRecipeValues, updateWorkingDir, upsertConfig, upsertPermissions, validateConfig } from './sdk.gen'; -export type { ActionRequired, ActionRequiredData, AddExtensionData, AddExtensionErrors, AddExtensionRequest, AddExtensionResponse, AddExtensionResponses, AgentAddExtensionData, AgentAddExtensionErrors, AgentAddExtensionResponse, AgentAddExtensionResponses, AgentRemoveExtensionData, AgentRemoveExtensionErrors, AgentRemoveExtensionResponse, AgentRemoveExtensionResponses, Annotations, Author, AuthorRequest, BackupConfigData, BackupConfigErrors, BackupConfigResponse, BackupConfigResponses, CallToolData, CallToolErrors, CallToolRequest, CallToolResponse, CallToolResponse2, CallToolResponses, CancelDownloadData, CancelDownloadErrors, CancelDownloadResponses, ChatRequest, CheckProviderData, CheckProviderRequest, ClientOptions, CommandType, ConfigKey, ConfigKeyQuery, ConfigResponse, ConfigureProviderOauthData, ConfigureProviderOauthErrors, ConfigureProviderOauthResponses, ConfirmToolActionData, ConfirmToolActionErrors, ConfirmToolActionRequest, ConfirmToolActionResponses, Content, Conversation, CreateCustomProviderData, CreateCustomProviderErrors, CreateCustomProviderResponse, CreateCustomProviderResponses, CreateRecipeData, CreateRecipeErrors, CreateRecipeRequest, CreateRecipeResponse, CreateRecipeResponse2, CreateRecipeResponses, CreateScheduleData, CreateScheduleErrors, CreateScheduleRequest, CreateScheduleResponse, CreateScheduleResponses, CspMetadata, DeclarativeProviderConfig, DecodeRecipeData, DecodeRecipeErrors, DecodeRecipeRequest, DecodeRecipeResponse, DecodeRecipeResponse2, DecodeRecipeResponses, DeleteModelData, DeleteModelErrors, DeleteModelResponses, DeleteRecipeData, DeleteRecipeErrors, DeleteRecipeRequest, DeleteRecipeResponse, DeleteRecipeResponses, DeleteScheduleData, DeleteScheduleErrors, DeleteScheduleResponse, DeleteScheduleResponses, DeleteSessionData, DeleteSessionErrors, DeleteSessionResponses, DetectProviderData, DetectProviderErrors, DetectProviderRequest, DetectProviderResponse, DetectProviderResponse2, DetectProviderResponses, DiagnosticsData, DiagnosticsErrors, DiagnosticsResponse, DiagnosticsResponses, DictationProvider, DictationProviderStatus, DownloadModelData, DownloadModelErrors, DownloadModelResponses, DownloadProgress, DownloadStatus, EmbeddedResource, EncodeRecipeData, EncodeRecipeErrors, EncodeRecipeRequest, EncodeRecipeResponse, EncodeRecipeResponse2, EncodeRecipeResponses, Envs, ErrorResponse, ExportAppData, ExportAppError, ExportAppErrors, ExportAppResponse, ExportAppResponses, ExportSessionData, ExportSessionErrors, ExportSessionResponse, ExportSessionResponses, ExtensionConfig, ExtensionData, ExtensionEntry, ExtensionLoadResult, ExtensionQuery, ExtensionResponse, ForkRequest, ForkResponse, ForkSessionData, ForkSessionErrors, ForkSessionResponse, ForkSessionResponses, FrontendToolRequest, GetCustomProviderData, GetCustomProviderErrors, GetCustomProviderResponse, GetCustomProviderResponses, GetDictationConfigData, GetDictationConfigResponse, GetDictationConfigResponses, GetDownloadProgressData, GetDownloadProgressErrors, GetDownloadProgressResponse, GetDownloadProgressResponses, GetExtensionsData, GetExtensionsErrors, GetExtensionsResponse, GetExtensionsResponses, GetPricingData, GetPricingResponse, GetPricingResponses, GetPromptData, GetPromptErrors, GetPromptResponse, GetPromptResponses, GetPromptsData, GetPromptsResponse, GetPromptsResponses, GetProviderModelsData, GetProviderModelsErrors, GetProviderModelsResponse, GetProviderModelsResponses, GetSessionData, GetSessionErrors, GetSessionExtensionsData, GetSessionExtensionsErrors, GetSessionExtensionsResponse, GetSessionExtensionsResponses, GetSessionInsightsData, GetSessionInsightsErrors, GetSessionInsightsResponse, GetSessionInsightsResponses, GetSessionResponse, GetSessionResponses, GetSlashCommandsData, GetSlashCommandsResponse, GetSlashCommandsResponses, GetToolsData, GetToolsErrors, GetToolsQuery, GetToolsResponse, GetToolsResponses, GetTunnelStatusData, GetTunnelStatusResponse, GetTunnelStatusResponses, GooseApp, Icon, ImageContent, ImportAppData, ImportAppError, ImportAppErrors, ImportAppRequest, ImportAppResponse, ImportAppResponse2, ImportAppResponses, ImportSessionData, ImportSessionErrors, ImportSessionRequest, ImportSessionResponse, ImportSessionResponses, InitConfigData, InitConfigErrors, InitConfigResponse, InitConfigResponses, InspectJobResponse, InspectRunningJobData, InspectRunningJobErrors, InspectRunningJobResponse, InspectRunningJobResponses, JsonObject, KillJobResponse, KillRunningJobData, KillRunningJobResponses, ListAppsData, ListAppsError, ListAppsErrors, ListAppsRequest, ListAppsResponse, ListAppsResponse2, ListAppsResponses, ListModelsData, ListModelsResponse, ListModelsResponses, ListRecipeResponse, ListRecipesData, ListRecipesErrors, ListRecipesResponse, ListRecipesResponses, ListSchedulesData, ListSchedulesErrors, ListSchedulesResponse, ListSchedulesResponse2, ListSchedulesResponses, ListSessionsData, ListSessionsErrors, ListSessionsResponse, ListSessionsResponses, LoadedProvider, McpAppResource, McpUiProxyData, McpUiProxyErrors, McpUiProxyResponses, Message, MessageContent, MessageEvent, MessageMetadata, ModelConfig, ModelInfo, ParseRecipeData, ParseRecipeError, ParseRecipeErrors, ParseRecipeRequest, ParseRecipeResponse, ParseRecipeResponse2, ParseRecipeResponses, PauseScheduleData, PauseScheduleErrors, PauseScheduleResponse, PauseScheduleResponses, PermissionLevel, PricingData, PricingQuery, PricingResponse, PrincipalType, PromptContentResponse, PromptsListResponse, ProviderDetails, ProviderEngine, ProviderMetadata, ProvidersData, ProvidersResponse, ProvidersResponse2, ProvidersResponses, ProviderType, RawAudioContent, RawEmbeddedResource, RawImageContent, RawResource, RawTextContent, ReadAllConfigData, ReadAllConfigResponse, ReadAllConfigResponses, ReadConfigData, ReadConfigErrors, ReadConfigResponses, ReadResourceData, ReadResourceErrors, ReadResourceRequest, ReadResourceResponse, ReadResourceResponse2, ReadResourceResponses, Recipe, RecipeManifest, RecipeParameter, RecipeParameterInputType, RecipeParameterRequirement, RecipeToYamlData, RecipeToYamlError, RecipeToYamlErrors, RecipeToYamlRequest, RecipeToYamlResponse, RecipeToYamlResponse2, RecipeToYamlResponses, RecoverConfigData, RecoverConfigErrors, RecoverConfigResponse, RecoverConfigResponses, RedactedThinkingContent, RemoveConfigData, RemoveConfigErrors, RemoveConfigResponse, RemoveConfigResponses, RemoveCustomProviderData, RemoveCustomProviderErrors, RemoveCustomProviderResponse, RemoveCustomProviderResponses, RemoveExtensionData, RemoveExtensionErrors, RemoveExtensionRequest, RemoveExtensionResponse, RemoveExtensionResponses, ReplyData, ReplyErrors, ReplyResponse, ReplyResponses, ResetPromptData, ResetPromptErrors, ResetPromptResponse, ResetPromptResponses, ResourceContents, ResourceMetadata, Response, RestartAgentData, RestartAgentErrors, RestartAgentRequest, RestartAgentResponse, RestartAgentResponse2, RestartAgentResponses, ResumeAgentData, ResumeAgentErrors, ResumeAgentRequest, ResumeAgentResponse, ResumeAgentResponse2, ResumeAgentResponses, RetryConfig, Role, RunNowHandlerData, RunNowHandlerErrors, RunNowHandlerResponse, RunNowHandlerResponses, RunNowResponse, SavePromptData, SavePromptErrors, SavePromptRequest, SavePromptResponse, SavePromptResponses, SaveRecipeData, SaveRecipeError, SaveRecipeErrors, SaveRecipeRequest, SaveRecipeResponse, SaveRecipeResponse2, SaveRecipeResponses, ScanRecipeData, ScanRecipeRequest, ScanRecipeResponse, ScanRecipeResponse2, ScanRecipeResponses, ScheduledJob, ScheduleRecipeData, ScheduleRecipeErrors, ScheduleRecipeRequest, ScheduleRecipeResponses, SendTelemetryEventData, SendTelemetryEventResponses, Session, SessionDisplayInfo, SessionExtensionsResponse, SessionInsights, SessionListResponse, SessionsHandlerData, SessionsHandlerErrors, SessionsHandlerResponse, SessionsHandlerResponses, SessionsQuery, SessionType, SetConfigProviderData, SetProviderRequest, SetRecipeSlashCommandData, SetRecipeSlashCommandErrors, SetRecipeSlashCommandResponses, SetSlashCommandRequest, Settings, SetupResponse, SlashCommand, SlashCommandsResponse, StartAgentData, StartAgentError, StartAgentErrors, StartAgentRequest, StartAgentResponse, StartAgentResponses, StartOpenrouterSetupData, StartOpenrouterSetupResponse, StartOpenrouterSetupResponses, StartTetrateSetupData, StartTetrateSetupResponse, StartTetrateSetupResponses, StartTunnelData, StartTunnelError, StartTunnelErrors, StartTunnelResponse, StartTunnelResponses, StatusData, StatusResponse, StatusResponses, StopAgentData, StopAgentErrors, StopAgentRequest, StopAgentResponse, StopAgentResponses, StopTunnelData, StopTunnelError, StopTunnelErrors, StopTunnelResponses, SubRecipe, SuccessCheck, SystemInfo, SystemInfoData, SystemInfoResponse, SystemInfoResponses, SystemNotificationContent, SystemNotificationType, TelemetryEventRequest, Template, TextContent, ThinkingContent, TokenState, Tool, ToolAnnotations, ToolConfirmationRequest, ToolInfo, ToolPermission, ToolRequest, ToolResponse, TranscribeDictationData, TranscribeDictationErrors, TranscribeDictationResponse, TranscribeDictationResponses, TranscribeRequest, TranscribeResponse, TunnelInfo, TunnelState, UiMetadata, UnpauseScheduleData, UnpauseScheduleErrors, UnpauseScheduleResponse, UnpauseScheduleResponses, UpdateAgentProviderData, UpdateAgentProviderErrors, UpdateAgentProviderResponses, UpdateCustomProviderData, UpdateCustomProviderErrors, UpdateCustomProviderRequest, UpdateCustomProviderResponse, UpdateCustomProviderResponses, UpdateFromSessionData, UpdateFromSessionErrors, UpdateFromSessionRequest, UpdateFromSessionResponses, UpdateProviderRequest, UpdateScheduleData, UpdateScheduleErrors, UpdateScheduleRequest, UpdateScheduleResponse, UpdateScheduleResponses, UpdateSessionNameData, UpdateSessionNameErrors, UpdateSessionNameRequest, UpdateSessionNameResponses, UpdateSessionUserRecipeValuesData, UpdateSessionUserRecipeValuesError, UpdateSessionUserRecipeValuesErrors, UpdateSessionUserRecipeValuesRequest, UpdateSessionUserRecipeValuesResponse, UpdateSessionUserRecipeValuesResponse2, UpdateSessionUserRecipeValuesResponses, UpdateWorkingDirData, UpdateWorkingDirErrors, UpdateWorkingDirRequest, UpdateWorkingDirResponses, UpsertConfigData, UpsertConfigErrors, UpsertConfigQuery, UpsertConfigResponse, UpsertConfigResponses, UpsertPermissionsData, UpsertPermissionsErrors, UpsertPermissionsQuery, UpsertPermissionsResponse, UpsertPermissionsResponses, ValidateConfigData, ValidateConfigErrors, ValidateConfigResponse, ValidateConfigResponses, WhisperModelResponse, WindowProps } from './types.gen'; +export type { ActionRequired, ActionRequiredData, AddExtensionData, AddExtensionErrors, AddExtensionRequest, AddExtensionResponse, AddExtensionResponses, AgentAddExtensionData, AgentAddExtensionErrors, AgentAddExtensionResponse, AgentAddExtensionResponses, AgentRemoveExtensionData, AgentRemoveExtensionErrors, AgentRemoveExtensionResponse, AgentRemoveExtensionResponses, Annotations, Author, AuthorRequest, BackupConfigData, BackupConfigErrors, BackupConfigResponse, BackupConfigResponses, CallToolData, CallToolErrors, CallToolRequest, CallToolResponse, CallToolResponse2, CallToolResponses, CancelDownloadData, CancelDownloadErrors, CancelDownloadResponses, ChatRequest, CheckProviderData, CheckProviderRequest, ClientOptions, CommandType, ConfigKey, ConfigKeyQuery, ConfigResponse, ConfigureProviderOauthData, ConfigureProviderOauthErrors, ConfigureProviderOauthResponses, ConfirmToolActionData, ConfirmToolActionErrors, ConfirmToolActionRequest, ConfirmToolActionResponses, Content, Conversation, CreateCustomProviderData, CreateCustomProviderErrors, CreateCustomProviderResponse, CreateCustomProviderResponses, CreateRecipeData, CreateRecipeErrors, CreateRecipeRequest, CreateRecipeResponse, CreateRecipeResponse2, CreateRecipeResponses, CreateScheduleData, CreateScheduleErrors, CreateScheduleRequest, CreateScheduleResponse, CreateScheduleResponses, CspMetadata, DeclarativeProviderConfig, DecodeRecipeData, DecodeRecipeErrors, DecodeRecipeRequest, DecodeRecipeResponse, DecodeRecipeResponse2, DecodeRecipeResponses, DeleteModelData, DeleteModelErrors, DeleteModelResponses, DeleteRecipeData, DeleteRecipeErrors, DeleteRecipeRequest, DeleteRecipeResponse, DeleteRecipeResponses, DeleteScheduleData, DeleteScheduleErrors, DeleteScheduleResponse, DeleteScheduleResponses, DeleteSessionData, DeleteSessionErrors, DeleteSessionResponses, DetectProviderData, DetectProviderErrors, DetectProviderRequest, DetectProviderResponse, DetectProviderResponse2, DetectProviderResponses, DiagnosticsData, DiagnosticsErrors, DiagnosticsResponse, DiagnosticsResponses, DictationProvider, DictationProviderStatus, DownloadModelData, DownloadModelErrors, DownloadModelResponses, DownloadProgress, DownloadStatus, EmbeddedResource, EncodeRecipeData, EncodeRecipeErrors, EncodeRecipeRequest, EncodeRecipeResponse, EncodeRecipeResponse2, EncodeRecipeResponses, Envs, ErrorResponse, ExportAppData, ExportAppError, ExportAppErrors, ExportAppResponse, ExportAppResponses, ExportSessionData, ExportSessionErrors, ExportSessionResponse, ExportSessionResponses, ExtensionConfig, ExtensionData, ExtensionEntry, ExtensionLoadResult, ExtensionQuery, ExtensionResponse, ForkRequest, ForkResponse, ForkSessionData, ForkSessionErrors, ForkSessionResponse, ForkSessionResponses, FrontendToolRequest, GetCustomProviderData, GetCustomProviderErrors, GetCustomProviderResponse, GetCustomProviderResponses, GetDictationConfigData, GetDictationConfigResponse, GetDictationConfigResponses, GetDownloadProgressData, GetDownloadProgressErrors, GetDownloadProgressResponse, GetDownloadProgressResponses, GetExtensionsData, GetExtensionsErrors, GetExtensionsResponse, GetExtensionsResponses, GetPricingData, GetPricingResponse, GetPricingResponses, GetPromptData, GetPromptErrors, GetPromptResponse, GetPromptResponses, GetPromptsData, GetPromptsResponse, GetPromptsResponses, GetProviderModelsData, GetProviderModelsErrors, GetProviderModelsResponse, GetProviderModelsResponses, GetSessionData, GetSessionErrors, GetSessionExtensionsData, GetSessionExtensionsErrors, GetSessionExtensionsResponse, GetSessionExtensionsResponses, GetSessionInsightsData, GetSessionInsightsErrors, GetSessionInsightsResponse, GetSessionInsightsResponses, GetSessionResponse, GetSessionResponses, GetSlashCommandsData, GetSlashCommandsResponse, GetSlashCommandsResponses, GetToolsData, GetToolsErrors, GetToolsQuery, GetToolsResponse, GetToolsResponses, GetTunnelStatusData, GetTunnelStatusResponse, GetTunnelStatusResponses, GooseApp, Icon, ImageContent, ImportAppData, ImportAppError, ImportAppErrors, ImportAppRequest, ImportAppResponse, ImportAppResponse2, ImportAppResponses, ImportSessionData, ImportSessionErrors, ImportSessionRequest, ImportSessionResponse, ImportSessionResponses, InitConfigData, InitConfigErrors, InitConfigResponse, InitConfigResponses, InspectJobResponse, InspectRunningJobData, InspectRunningJobErrors, InspectRunningJobResponse, InspectRunningJobResponses, JsonObject, KillJobResponse, KillRunningJobData, KillRunningJobResponses, ListAppsData, ListAppsError, ListAppsErrors, ListAppsRequest, ListAppsResponse, ListAppsResponse2, ListAppsResponses, ListModelsData, ListModelsResponse, ListModelsResponses, ListRecipeResponse, ListRecipesData, ListRecipesErrors, ListRecipesResponse, ListRecipesResponses, ListSchedulesData, ListSchedulesErrors, ListSchedulesResponse, ListSchedulesResponse2, ListSchedulesResponses, ListSessionsData, ListSessionsErrors, ListSessionsResponse, ListSessionsResponses, LoadedProvider, McpAppResource, McpUiProxyData, McpUiProxyErrors, McpUiProxyResponses, Message, MessageContent, MessageEvent, MessageMetadata, ModelConfig, ModelInfo, ParseRecipeData, ParseRecipeError, ParseRecipeErrors, ParseRecipeRequest, ParseRecipeResponse, ParseRecipeResponse2, ParseRecipeResponses, PauseScheduleData, PauseScheduleErrors, PauseScheduleResponse, PauseScheduleResponses, PermissionLevel, PermissionsMetadata, PricingData, PricingQuery, PricingResponse, PrincipalType, PromptContentResponse, PromptsListResponse, ProviderDetails, ProviderEngine, ProviderMetadata, ProvidersData, ProvidersResponse, ProvidersResponse2, ProvidersResponses, ProviderType, RawAudioContent, RawEmbeddedResource, RawImageContent, RawResource, RawTextContent, ReadAllConfigData, ReadAllConfigResponse, ReadAllConfigResponses, ReadConfigData, ReadConfigErrors, ReadConfigResponses, ReadResourceData, ReadResourceErrors, ReadResourceRequest, ReadResourceResponse, ReadResourceResponse2, ReadResourceResponses, Recipe, RecipeManifest, RecipeParameter, RecipeParameterInputType, RecipeParameterRequirement, RecipeToYamlData, RecipeToYamlError, RecipeToYamlErrors, RecipeToYamlRequest, RecipeToYamlResponse, RecipeToYamlResponse2, RecipeToYamlResponses, RecoverConfigData, RecoverConfigErrors, RecoverConfigResponse, RecoverConfigResponses, RedactedThinkingContent, RemoveConfigData, RemoveConfigErrors, RemoveConfigResponse, RemoveConfigResponses, RemoveCustomProviderData, RemoveCustomProviderErrors, RemoveCustomProviderResponse, RemoveCustomProviderResponses, RemoveExtensionData, RemoveExtensionErrors, RemoveExtensionRequest, RemoveExtensionResponse, RemoveExtensionResponses, ReplyData, ReplyErrors, ReplyResponse, ReplyResponses, ResetPromptData, ResetPromptErrors, ResetPromptResponse, ResetPromptResponses, ResourceContents, ResourceMetadata, Response, RestartAgentData, RestartAgentErrors, RestartAgentRequest, RestartAgentResponse, RestartAgentResponse2, RestartAgentResponses, ResumeAgentData, ResumeAgentErrors, ResumeAgentRequest, ResumeAgentResponse, ResumeAgentResponse2, ResumeAgentResponses, RetryConfig, Role, RunNowHandlerData, RunNowHandlerErrors, RunNowHandlerResponse, RunNowHandlerResponses, RunNowResponse, SavePromptData, SavePromptErrors, SavePromptRequest, SavePromptResponse, SavePromptResponses, SaveRecipeData, SaveRecipeError, SaveRecipeErrors, SaveRecipeRequest, SaveRecipeResponse, SaveRecipeResponse2, SaveRecipeResponses, ScanRecipeData, ScanRecipeRequest, ScanRecipeResponse, ScanRecipeResponse2, ScanRecipeResponses, ScheduledJob, ScheduleRecipeData, ScheduleRecipeErrors, ScheduleRecipeRequest, ScheduleRecipeResponses, SendTelemetryEventData, SendTelemetryEventResponses, Session, SessionDisplayInfo, SessionExtensionsResponse, SessionInsights, SessionListResponse, SessionsHandlerData, SessionsHandlerErrors, SessionsHandlerResponse, SessionsHandlerResponses, SessionsQuery, SessionType, SetConfigProviderData, SetProviderRequest, SetRecipeSlashCommandData, SetRecipeSlashCommandErrors, SetRecipeSlashCommandResponses, SetSlashCommandRequest, Settings, SetupResponse, SlashCommand, SlashCommandsResponse, StartAgentData, StartAgentError, StartAgentErrors, StartAgentRequest, StartAgentResponse, StartAgentResponses, StartOpenrouterSetupData, StartOpenrouterSetupResponse, StartOpenrouterSetupResponses, StartTetrateSetupData, StartTetrateSetupResponse, StartTetrateSetupResponses, StartTunnelData, StartTunnelError, StartTunnelErrors, StartTunnelResponse, StartTunnelResponses, StatusData, StatusResponse, StatusResponses, StopAgentData, StopAgentErrors, StopAgentRequest, StopAgentResponse, StopAgentResponses, StopTunnelData, StopTunnelError, StopTunnelErrors, StopTunnelResponses, SubRecipe, SuccessCheck, SystemInfo, SystemInfoData, SystemInfoResponse, SystemInfoResponses, SystemNotificationContent, SystemNotificationType, TelemetryEventRequest, Template, TextContent, ThinkingContent, TokenState, Tool, ToolAnnotations, ToolConfirmationRequest, ToolInfo, ToolPermission, ToolRequest, ToolResponse, TranscribeDictationData, TranscribeDictationErrors, TranscribeDictationResponse, TranscribeDictationResponses, TranscribeRequest, TranscribeResponse, TunnelInfo, TunnelState, UiMetadata, UnpauseScheduleData, UnpauseScheduleErrors, UnpauseScheduleResponse, UnpauseScheduleResponses, UpdateAgentProviderData, UpdateAgentProviderErrors, UpdateAgentProviderResponses, UpdateCustomProviderData, UpdateCustomProviderErrors, UpdateCustomProviderRequest, UpdateCustomProviderResponse, UpdateCustomProviderResponses, UpdateFromSessionData, UpdateFromSessionErrors, UpdateFromSessionRequest, UpdateFromSessionResponses, UpdateProviderRequest, UpdateScheduleData, UpdateScheduleErrors, UpdateScheduleRequest, UpdateScheduleResponse, UpdateScheduleResponses, UpdateSessionNameData, UpdateSessionNameErrors, UpdateSessionNameRequest, UpdateSessionNameResponses, UpdateSessionUserRecipeValuesData, UpdateSessionUserRecipeValuesError, UpdateSessionUserRecipeValuesErrors, UpdateSessionUserRecipeValuesRequest, UpdateSessionUserRecipeValuesResponse, UpdateSessionUserRecipeValuesResponse2, UpdateSessionUserRecipeValuesResponses, UpdateWorkingDirData, UpdateWorkingDirErrors, UpdateWorkingDirRequest, UpdateWorkingDirResponses, UpsertConfigData, UpsertConfigErrors, UpsertConfigQuery, UpsertConfigResponse, UpsertConfigResponses, UpsertPermissionsData, UpsertPermissionsErrors, UpsertPermissionsQuery, UpsertPermissionsResponse, UpsertPermissionsResponses, ValidateConfigData, ValidateConfigErrors, ValidateConfigResponse, ValidateConfigResponses, WhisperModelResponse, WindowProps } from './types.gen'; diff --git a/ui/desktop/src/api/types.gen.ts b/ui/desktop/src/api/types.gen.ts index d40b90a0dd..eca80ef670 100644 --- a/ui/desktop/src/api/types.gen.ts +++ b/ui/desktop/src/api/types.gen.ts @@ -667,6 +667,30 @@ export type ParseRecipeResponse = { */ export type PermissionLevel = 'always_allow' | 'ask_before' | 'never_allow'; +/** + * Sandbox permissions for MCP Apps + * Specifies which browser capabilities the UI needs access to. + * Maps to the iframe Permission Policy `allow` attribute. + */ +export type PermissionsMetadata = { + /** + * Request camera access (maps to Permission Policy `camera` feature) + */ + camera?: boolean; + /** + * Request clipboard write access (maps to Permission Policy `clipboard-write` feature) + */ + clipboardWrite?: boolean; + /** + * Request geolocation access (maps to Permission Policy `geolocation` feature) + */ + geolocation?: boolean; + /** + * Request microphone access (maps to Permission Policy `microphone` feature) + */ + microphone?: boolean; +}; + export type PricingData = { context_length?: number | null; currency: string; @@ -1273,6 +1297,7 @@ export type UiMetadata = { * Preferred domain for the app (used for CORS) */ domain?: string | null; + permissions?: PermissionsMetadata; /** * Whether the app prefers to have a border around it */ diff --git a/ui/desktop/src/components/GooseSidebar/AppSidebar.tsx b/ui/desktop/src/components/GooseSidebar/AppSidebar.tsx index 13327af6de..baefdc5c68 100644 --- a/ui/desktop/src/components/GooseSidebar/AppSidebar.tsx +++ b/ui/desktop/src/components/GooseSidebar/AppSidebar.tsx @@ -95,13 +95,14 @@ const menuItems: NavigationEntry[] = [ ]; const getSessionDisplayName = (session: Session): string => { - if (!shouldShowNewChatTitle(session)) { - return session.name; - } if (session.recipe?.title) { return session.recipe.title; } - return DEFAULT_CHAT_TITLE; + + if (shouldShowNewChatTitle(session)) { + return DEFAULT_CHAT_TITLE; + } + return session.name; }; const SessionList = React.memo<{ diff --git a/ui/desktop/src/components/McpApps/McpAppRenderer.tsx b/ui/desktop/src/components/McpApps/McpAppRenderer.tsx index 5607895b2c..6e562462ca 100644 --- a/ui/desktop/src/components/McpApps/McpAppRenderer.tsx +++ b/ui/desktop/src/components/McpApps/McpAppRenderer.tsx @@ -15,6 +15,7 @@ import { ToolResult, ToolCancelled, CspMetadata, + PermissionsMetadata, McpMethodParams, McpMethodResponse, } from './types'; @@ -40,6 +41,7 @@ interface McpAppRendererProps { interface ResourceData { html: string | null; csp: CspMetadata | null; + permissions: PermissionsMetadata | null; prefersBorder: boolean; } @@ -58,6 +60,7 @@ export default function McpAppRenderer({ const [resource, setResource] = useState({ html: cachedHtml || null, csp: null, + permissions: null, prefersBorder: true, }); const [error, setError] = useState(null); @@ -82,13 +85,20 @@ export default function McpAppRenderer({ if (response.data) { const content = response.data; const meta = content._meta as - | { ui?: { csp?: CspMetadata; prefersBorder?: boolean } } + | { + ui?: { + csp?: CspMetadata; + permissions?: PermissionsMetadata; + prefersBorder?: boolean; + }; + } | undefined; if (content.text !== cachedHtml) { setResource({ html: content.text, csp: meta?.ui?.csp || null, + permissions: meta?.ui?.permissions || null, prefersBorder: meta?.ui?.prefersBorder ?? true, }); } @@ -241,6 +251,7 @@ export default function McpAppRenderer({ const { iframeRef, proxyUrl } = useSandboxBridge({ resourceHtml: resource.html || '', resourceCsp: resource.csp, + resourcePermissions: resource.permissions, resourceUri, toolInput, toolInputPartial, diff --git a/ui/desktop/src/components/McpApps/types.ts b/ui/desktop/src/components/McpApps/types.ts index c24c7ae80f..28a397038c 100644 --- a/ui/desktop/src/components/McpApps/types.ts +++ b/ui/desktop/src/components/McpApps/types.ts @@ -1,4 +1,8 @@ -export type { CspMetadata, CallToolResponse as ToolResult } from '../../api/types.gen'; +export type { + CspMetadata, + PermissionsMetadata, + CallToolResponse as ToolResult, +} from '../../api/types.gen'; export type ContentBlock = | { type: 'text'; text: string } diff --git a/ui/desktop/src/components/McpApps/useSandboxBridge.ts b/ui/desktop/src/components/McpApps/useSandboxBridge.ts index f519f50bbe..2089cacf9d 100644 --- a/ui/desktop/src/components/McpApps/useSandboxBridge.ts +++ b/ui/desktop/src/components/McpApps/useSandboxBridge.ts @@ -9,6 +9,7 @@ import type { ToolCancelled, HostContext, CspMetadata, + PermissionsMetadata, } from './types'; import { fetchMcpAppProxyUrl } from './utils'; import { useTheme } from '../../contexts/ThemeContext'; @@ -18,6 +19,7 @@ import { errorMessage } from '../../utils/conversionUtils'; interface SandboxBridgeOptions { resourceHtml: string; resourceCsp: CspMetadata | null; + resourcePermissions: PermissionsMetadata | null; resourceUri: string; toolInput?: ToolInput; toolInputPartial?: ToolInputPartial; @@ -40,6 +42,7 @@ export function useSandboxBridge(options: SandboxBridgeOptions): SandboxBridgeRe const { resourceHtml, resourceCsp, + resourcePermissions, resourceUri, toolInput, toolInputPartial, @@ -80,7 +83,7 @@ export function useSandboxBridge(options: SandboxBridgeOptions): SandboxBridgeRe sendToSandbox({ jsonrpc: '2.0', method: 'ui/notifications/sandbox-resource-ready', - params: { html: resourceHtml, csp: resourceCsp }, + params: { html: resourceHtml, csp: resourceCsp, permissions: resourcePermissions }, }); break; @@ -181,6 +184,7 @@ export function useSandboxBridge(options: SandboxBridgeOptions): SandboxBridgeRe [ resourceHtml, resourceCsp, + resourcePermissions, resolvedTheme, sendToSandbox, onMcpRequest, diff --git a/ui/desktop/src/components/ToolCallWithResponse.tsx b/ui/desktop/src/components/ToolCallWithResponse.tsx index 1d91fd4a29..2fcca040bb 100644 --- a/ui/desktop/src/components/ToolCallWithResponse.tsx +++ b/ui/desktop/src/components/ToolCallWithResponse.tsx @@ -291,10 +291,79 @@ interface Progress { message?: string; } +interface SubagentToolRequestData { + type: 'subagent_tool_request'; + subagent_id: string; + tool_call: { + name: string; + arguments?: { tool_graph?: ToolGraphNode[] }; + }; +} + +const isSubagentToolRequestData = (data: unknown): data is SubagentToolRequestData => { + if (!data || typeof data !== 'object') { + return false; + } + const record = data as Record; + if (record.type !== 'subagent_tool_request') { + return false; + } + if (typeof record.subagent_id !== 'string') { + return false; + } + if (!record.tool_call || typeof record.tool_call !== 'object') { + return false; + } + const toolCall = record.tool_call as Record; + return typeof toolCall.name === 'string'; +}; + +const formatSubagentToolCall = (data: SubagentToolRequestData): string => { + const subagentId = data.subagent_id; + const toolCall = data.tool_call; + const toolCallName = toolCall.name; + + const shortId = subagentId?.split('_').pop() || subagentId; + + const parts = toolCallName.split('__').reverse(); + const toolName = parts[0] || 'unknown'; + const extensionName = parts.slice(1).reverse().join('__') || ''; + const toolGraph = toolCall.arguments?.tool_graph; + + if (toolName === 'execute_code' && toolGraph && toolGraph.length > 0) { + const plural = toolGraph.length === 1 ? '' : 's'; + const header = `[subagent:${shortId}] ${toolGraph.length} tool call${plural} | execute_code`; + const lines = toolGraph.map((node, idx) => { + const deps = + node.depends_on && node.depends_on.length > 0 + ? ` (uses ${node.depends_on.map((d) => d + 1).join(', ')})` + : ''; + return ` ${idx + 1}. ${node.tool}: ${node.description}${deps}`; + }); + return [header, ...lines].join('\n'); + } + + return extensionName + ? `[subagent:${shortId}] ${toolName} | ${extensionName}` + : `[subagent:${shortId}] ${toolName}`; +}; + const logToString = (logMessage: NotificationEvent) => { const message = logMessage.message as { method: string; params: unknown }; const params = message.params as Record; + if ( + params && + params.data && + typeof params.data === 'object' && + 'type' in params.data && + params.data.type === 'subagent_tool_request' + ) { + if (isSubagentToolRequestData(params.data)) { + return formatSubagentToolCall(params.data); + } + } + // Special case for the developer system shell logs if ( params && @@ -545,7 +614,7 @@ function ToolCallView({ case 'computer_control': return `poking around...`; - case 'execute_code': { + case 'execute': { const toolGraph = args.tool_graph as unknown as ToolGraphNode[] | undefined; if (toolGraph && Array.isArray(toolGraph) && toolGraph.length > 0) { if (toolGraph.length === 1) { @@ -639,19 +708,16 @@ function ToolCallView({ } > {(() => { - const toolName = toolCall.name.substring(toolCall.name.lastIndexOf('__') + 2); - const toolGraph = toolCall.arguments?.tool_graph as unknown as ToolGraphNode[] | undefined; const code = toolCall.arguments?.code as unknown as string | undefined; - const hasToolGraph = - toolName === 'execute_code' && - toolGraph && - Array.isArray(toolGraph) && - toolGraph.length > 0; + const toolGraph = toolCall.arguments?.tool_graph as unknown as ToolGraphNode[] | undefined; - if (hasToolGraph) { + if ( + toolCall.name === 'code_execution__execute' && + (typeof code === 'string' || Array.isArray(toolGraph)) + ) { return (
- +
); } @@ -692,7 +758,7 @@ function ToolCallView({ <> {toolResults.map((result, index) => (
- +
))} @@ -724,18 +790,19 @@ function ToolDetailsView({ toolCall, isStartExpanded }: ToolDetailsViewProps) { ); } -interface ToolGraphViewProps { - toolGraph: ToolGraphNode[]; +interface CodeModeViewProps { + toolGraph?: ToolGraphNode[]; code?: string; } -function ToolGraphView({ toolGraph, code }: ToolGraphViewProps) { +function CodeModeView({ toolGraph, code }: CodeModeViewProps) { const renderGraph = () => { - if (toolGraph.length === 0) return null; + const graph = toolGraph ?? []; + if (graph.length === 0) return null; const lines: string[] = []; - toolGraph.forEach((node, index) => { + graph.forEach((node, index) => { const deps = node.depends_on.length > 0 ? ` (uses ${node.depends_on.map((d) => d + 1).join(', ')})` : ''; lines.push(`${index + 1}. ${node.tool}: ${node.description}${deps}`); @@ -746,16 +813,19 @@ function ToolGraphView({ toolGraph, code }: ToolGraphViewProps) { return (
-
{renderGraph()}
+ {toolGraph && ( +
{renderGraph()}
+ )} {code && (
Code} isStartExpanded={false} > -
-              {code}
-            
+
)} @@ -764,11 +834,15 @@ function ToolGraphView({ toolGraph, code }: ToolGraphViewProps) { } interface ToolResultViewProps { + toolCall: { + name: string; + arguments: Record; + }; result: Content; isStartExpanded: boolean; } -function ToolResultView({ result, isStartExpanded }: ToolResultViewProps) { +function ToolResultView({ toolCall, result, isStartExpanded }: ToolResultViewProps) { const hasText = (c: Content): c is Content & { text: string } => 'text' in c && typeof (c as Record).text === 'string'; @@ -780,6 +854,18 @@ function ToolResultView({ result, isStartExpanded }: ToolResultViewProps) { const hasResource = (c: Content): c is Content & { resource: unknown } => 'resource' in c; + const wrapMarkdown = (text: string): string => { + if ( + ['code_execution__list_functions', 'code_execution__get_function_details'].includes( + toolCall.name + ) + ) { + return '```typescript\n' + text + '\n```'; + } else { + return text; + } + }; + return ( Output} @@ -788,7 +874,7 @@ function ToolResultView({ result, isStartExpanded }: ToolResultViewProps) {
{hasText(result) && ( )} diff --git a/ui/desktop/src/components/bottom_menu/DirSwitcher.tsx b/ui/desktop/src/components/bottom_menu/DirSwitcher.tsx index 481141b13a..26c8dc399e 100644 --- a/ui/desktop/src/components/bottom_menu/DirSwitcher.tsx +++ b/ui/desktop/src/components/bottom_menu/DirSwitcher.tsx @@ -3,7 +3,6 @@ import { FolderDot } from 'lucide-react'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/Tooltip'; import { updateWorkingDir } from '../../api'; import { toast } from 'react-toastify'; -import { setCurrentWorkingDir } from '../../utils/workingDir'; interface DirSwitcherProps { className: string; @@ -43,7 +42,6 @@ export const DirSwitcher: React.FC = ({ const newDir = result.filePaths[0]; window.electron.addRecentDir(newDir); - setCurrentWorkingDir(newDir); if (sessionId) { onWorkingDirChange?.(newDir); diff --git a/ui/desktop/src/components/recipes/RecipesView.tsx b/ui/desktop/src/components/recipes/RecipesView.tsx index 905efd17bc..5390c5984e 100644 --- a/ui/desktop/src/components/recipes/RecipesView.tsx +++ b/ui/desktop/src/components/recipes/RecipesView.tsx @@ -58,6 +58,7 @@ import { } from '../ui/dropdown-menu'; import { getSearchShortcutText } from '../../utils/keyboardShortcuts'; import { errorMessage } from '../../utils/conversionUtils'; +import { AppEvents } from '../../constants/events'; export default function RecipesView() { const setView = useNavigation(); @@ -149,6 +150,9 @@ export default function RecipesView() { }); const session = newAgent.data; trackRecipeStarted(true, undefined, false); + + window.dispatchEvent(new CustomEvent(AppEvents.SESSION_CREATED, { detail: { session } })); + setView('pair', { disableAnimation: true, resumeSessionId: session.id, diff --git a/ui/desktop/src/components/sessions/SessionHistoryView.tsx b/ui/desktop/src/components/sessions/SessionHistoryView.tsx index 95d781c94e..f90e706b7c 100644 --- a/ui/desktop/src/components/sessions/SessionHistoryView.tsx +++ b/ui/desktop/src/components/sessions/SessionHistoryView.tsx @@ -38,7 +38,9 @@ const isUserMessage = (message: Message): boolean => { if (message.role === 'assistant') { return false; } - return !message.content.every((c) => c.type === 'toolConfirmationRequest'); + return !message.content.every( + (c) => c.type === 'actionRequired' && c.data.actionType === 'toolConfirmation' + ); }; const filterMessagesForDisplay = (messages: Message[]): Message[] => { diff --git a/ui/desktop/src/components/settings/permission/PermissionModal.tsx b/ui/desktop/src/components/settings/permission/PermissionModal.tsx index 2ac07593a6..58fcd9229b 100644 --- a/ui/desktop/src/components/settings/permission/PermissionModal.tsx +++ b/ui/desktop/src/components/settings/permission/PermissionModal.tsx @@ -1,6 +1,6 @@ import { useEffect, useMemo, useState } from 'react'; import { Button } from '../../ui/button'; -import { ChevronDownIcon, SlidersHorizontal } from 'lucide-react'; +import { ChevronDownIcon, SlidersHorizontal, AlertCircle } from 'lucide-react'; import { getTools, PermissionLevel, ToolInfo, upsertPermissions } from '../../../api'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '../../ui/dialog'; import { @@ -33,6 +33,8 @@ export default function PermissionModal({ extensionName, onClose }: PermissionMo const [tools, setTools] = useState([]); const [updatedPermissions, setUpdatedPermissions] = useState>({}); + const [isLoading, setIsLoading] = useState(true); + const [loadError, setLoadError] = useState(null); const hasChanges = useMemo(() => { return Object.keys(updatedPermissions).some( @@ -43,12 +45,22 @@ export default function PermissionModal({ extensionName, onClose }: PermissionMo useEffect(() => { const fetchTools = async () => { + if (!sessionId) { + setIsLoading(false); + setLoadError('no_session'); + return; + } + + setIsLoading(true); + setLoadError(null); + try { const response = await getTools({ query: { extension_name: extensionName, session_id: sessionId }, }); if (response.error) { - console.error('Failed to get tools'); + console.error('Failed to get tools:', response.error); + setLoadError('fetch_failed'); } else { const filteredTools = (response.data || []).filter( (tool: ToolInfo) => @@ -58,6 +70,9 @@ export default function PermissionModal({ extensionName, onClose }: PermissionMo } } catch (err) { console.error('Error fetching tools:', err); + setLoadError('fetch_failed'); + } finally { + setIsLoading(false); } }; @@ -121,9 +136,8 @@ export default function PermissionModal({ extensionName, onClose }: PermissionMo
- {tools.length === 0 ? ( -
- {/* Loading spinner */} + {isLoading ? ( +
+ ) : loadError === 'no_session' ? ( +
+ +

No active session

+

+ Start a chat session first to configure tool permissions for this extension. Tool + permissions are loaded from the active session's extensions. +

+
+ ) : loadError === 'fetch_failed' ? ( +
+ +

Failed to load tools

+

+ Could not load tools for this extension. The extension may not be loaded in the + current session. +

+
+ ) : tools.length === 0 ? ( +
+

No tools available for this extension.

+
) : (
{tools.map((tool) => ( @@ -187,11 +223,13 @@ export default function PermissionModal({ extensionName, onClose }: PermissionMo - + {!loadError && ( + + )} diff --git a/ui/desktop/src/hooks/useChatStream.ts b/ui/desktop/src/hooks/useChatStream.ts index 8cf0fe6bf8..efbccdbdd2 100644 --- a/ui/desktop/src/hooks/useChatStream.ts +++ b/ui/desktop/src/hooks/useChatStream.ts @@ -257,7 +257,8 @@ async function streamFromResponse( currentMessages = pushMessage(currentMessages, msg); const hasToolConfirmation = msg.content.some( - (content) => content.type === 'toolConfirmationRequest' + (content) => + content.type === 'actionRequired' && content.data.actionType === 'toolConfirmation' ); const hasElicitation = msg.content.some( diff --git a/ui/desktop/src/sessions.ts b/ui/desktop/src/sessions.ts index d3e87967ba..0ab2a45e94 100644 --- a/ui/desktop/src/sessions.ts +++ b/ui/desktop/src/sessions.ts @@ -9,6 +9,9 @@ import type { FixedExtensionEntry } from './components/ConfigContext'; import { AppEvents } from './constants/events'; export function shouldShowNewChatTitle(session: Session): boolean { + if (session.recipe) { + return false; + } return !session.user_set_name && session.message_count === 0; } diff --git a/ui/desktop/src/utils/workingDir.ts b/ui/desktop/src/utils/workingDir.ts index d99c448fe9..905de021bc 100644 --- a/ui/desktop/src/utils/workingDir.ts +++ b/ui/desktop/src/utils/workingDir.ts @@ -1,11 +1,4 @@ -// Track the current working dir for this window (updated when user changes it) -let currentWorkingDir: string | null = null; - -export const setCurrentWorkingDir = (dir: string): void => { - currentWorkingDir = dir; -}; - export const getInitialWorkingDir = (): string => { - // Use the current dir if set, otherwise fall back to initial config - return currentWorkingDir ?? (window.appConfig?.get('GOOSE_WORKING_DIR') as string) ?? ''; + // Fall back to initial config from app startup + return (window.appConfig?.get('GOOSE_WORKING_DIR') as string) ?? ''; };