diff --git a/.gitignore b/.gitignore
index 2a91a65b6eaef906681bf3f6e315de07b094c4b1..ccf4f471d5a7b70be0dc8d619ac64050dd6681ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,6 @@ xcuserdata/
# Don't commit any secrets to the repo.
.env
.env.secret.toml
+
+# `nix build` output
+/result
diff --git a/Cargo.lock b/Cargo.lock
index 9bb6a3322e613d717d0b3b2755c43fba0f7f3941..da60b0b2318f630b2f64f03d535c09d11bd4938d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -211,14 +211,14 @@ dependencies = [
"worktree",
"zed_env_vars",
"zlog",
- "zstd 0.11.2+zstd.1.5.2",
+ "zstd",
]
[[package]]
name = "agent-client-protocol"
-version = "0.8.0"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e639d6b544ad39f5b4e05802db5eb04e1518284eb05fda1839931003e0244c8"
+checksum = "c2ffe7d502c1e451aafc5aff655000f84d09c9af681354ac0012527009b1af13"
dependencies = [
"agent-client-protocol-schema",
"anyhow",
@@ -233,15 +233,16 @@ dependencies = [
[[package]]
name = "agent-client-protocol-schema"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f182f5e14bef8232b239719bd99166bb11e986c08fc211f28e392f880d3093ba"
+checksum = "8af81cc2d5c3f9c04f73db452efd058333735ba9d51c2cf7ef33c9fee038e7e6"
dependencies = [
"anyhow",
"derive_more 2.0.1",
"schemars",
"serde",
"serde_json",
+ "strum 0.27.2",
]
[[package]]
@@ -680,21 +681,6 @@ dependencies = [
"syn 2.0.106",
]
-[[package]]
-name = "argminmax"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70f13d10a41ac8d2ec79ee34178d61e6f47a29c2edfe7ef1721c7383b0359e65"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "array-init-cursor"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed51fe0f224d1d4ea768be38c51f9f831dee9d05c163c11fba0b8c44387b1fc3"
-
[[package]]
name = "arraydeque"
version = "0.5.1"
@@ -1278,15 +1264,6 @@ dependencies = [
"num-traits",
]
-[[package]]
-name = "atoi_simd"
-version = "0.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2a49e05797ca52e312a0c658938b7d00693ef037799ef7187678f212d7684cf"
-dependencies = [
- "debug_unsafe",
-]
-
[[package]]
name = "atomic"
version = "0.5.3"
@@ -2070,26 +2047,6 @@ dependencies = [
"serde",
]
-[[package]]
-name = "bincode"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740"
-dependencies = [
- "bincode_derive",
- "serde",
- "unty",
-]
-
-[[package]]
-name = "bincode_derive"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09"
-dependencies = [
- "virtue",
-]
-
[[package]]
name = "bindgen"
version = "0.71.1"
@@ -2242,19 +2199,6 @@ dependencies = [
"profiling",
]
-[[package]]
-name = "blake3"
-version = "1.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0"
-dependencies = [
- "arrayref",
- "arrayvec",
- "cc",
- "cfg-if",
- "constant_time_eq 0.3.1",
-]
-
[[package]]
name = "block"
version = "0.1.6"
@@ -2344,12 +2288,6 @@ dependencies = [
"syn 2.0.106",
]
-[[package]]
-name = "boxcar"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36f64beae40a84da1b4b26ff2761a5b895c12adc41dc25aaee1c4f2bbfe97a6e"
-
[[package]]
name = "breadcrumbs"
version = "0.1.0"
@@ -2516,9 +2454,6 @@ name = "bytes"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
-dependencies = [
- "serde",
-]
[[package]]
name = "bytes-utils"
@@ -2805,15 +2740,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
-[[package]]
-name = "castaway"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
-dependencies = [
- "rustversion",
-]
-
[[package]]
name = "cbc"
version = "0.1.2"
@@ -2942,16 +2868,6 @@ dependencies = [
"windows-link 0.2.1",
]
-[[package]]
-name = "chrono-tz"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3"
-dependencies = [
- "chrono",
- "phf 0.12.1",
-]
-
[[package]]
name = "chunked_transfer"
version = "1.5.0"
@@ -3201,12 +3117,7 @@ dependencies = [
"anyhow",
"cloud_llm_client",
"indoc",
- "ordered-float 2.10.1",
- "rustc-hash 2.1.1",
- "schemars",
"serde",
- "serde_json",
- "strum 0.27.2",
]
[[package]]
@@ -3314,8 +3225,8 @@ name = "codestral"
version = "0.1.0"
dependencies = [
"anyhow",
- "edit_prediction",
"edit_prediction_context",
+ "edit_prediction_types",
"futures 0.3.31",
"gpui",
"http_client",
@@ -3505,17 +3416,6 @@ dependencies = [
"memchr",
]
-[[package]]
-name = "comfy-table"
-version = "7.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b03b7db8e0b4b2fdad6c551e634134e99ec000e5c8c3b6856c65e8bbaded7a3b"
-dependencies = [
- "crossterm",
- "unicode-segmentation",
- "unicode-width",
-]
-
[[package]]
name = "command-fds"
version = "0.3.2"
@@ -3569,21 +3469,6 @@ dependencies = [
"workspace",
]
-[[package]]
-name = "compact_str"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a"
-dependencies = [
- "castaway",
- "cfg-if",
- "itoa",
- "rustversion",
- "ryu",
- "serde",
- "static_assertions",
-]
-
[[package]]
name = "component"
version = "0.1.0"
@@ -3689,12 +3574,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
-[[package]]
-name = "constant_time_eq"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
-
[[package]]
name = "context_server"
version = "0.1.0"
@@ -3747,7 +3626,7 @@ dependencies = [
"command_palette_hooks",
"ctor",
"dirs 4.0.0",
- "edit_prediction",
+ "edit_prediction_types",
"editor",
"fs",
"futures 0.3.31",
@@ -4160,7 +4039,7 @@ dependencies = [
name = "crashes"
version = "0.1.0"
dependencies = [
- "bincode 1.3.3",
+ "bincode",
"cfg-if",
"crash-handler",
"extension_host",
@@ -4174,7 +4053,7 @@ dependencies = [
"smol",
"system_specs",
"windows 0.61.3",
- "zstd 0.11.2+zstd.1.5.2",
+ "zstd",
]
[[package]]
@@ -4319,29 +4198,6 @@ version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
-[[package]]
-name = "crossterm"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
-dependencies = [
- "bitflags 2.9.4",
- "crossterm_winapi",
- "document-features",
- "parking_lot",
- "rustix 1.1.2",
- "winapi",
-]
-
-[[package]]
-name = "crossterm_winapi"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
-dependencies = [
- "winapi",
-]
-
[[package]]
name = "crunchy"
version = "0.2.4"
@@ -4696,12 +4552,6 @@ dependencies = [
"util",
]
-[[package]]
-name = "debug_unsafe"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85d3cef41d236720ed453e102153a53e4cc3d2fde848c0078a50cf249e8e3e5b"
-
[[package]]
name = "debugger_tools"
version = "0.1.0"
@@ -4734,6 +4584,7 @@ dependencies = [
"db",
"debugger_tools",
"editor",
+ "feature_flags",
"file_icons",
"futures 0.3.31",
"fuzzy",
@@ -5109,15 +4960,6 @@ dependencies = [
"zlog",
]
-[[package]]
-name = "document-features"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
-dependencies = [
- "litrs",
-]
-
[[package]]
name = "documented"
version = "0.9.2"
@@ -5267,144 +5109,252 @@ dependencies = [
name = "edit_prediction"
version = "0.1.0"
dependencies = [
- "client",
- "gpui",
- "language",
-]
-
-[[package]]
-name = "edit_prediction_button"
-version = "0.1.0"
-dependencies = [
+ "ai_onboarding",
"anyhow",
+ "arrayvec",
+ "brotli",
"client",
+ "clock",
+ "cloud_api_types",
"cloud_llm_client",
- "codestral",
+ "cloud_zeta2_prompt",
+ "collections",
"copilot",
- "edit_prediction",
- "editor",
+ "credentials_provider",
+ "ctor",
+ "db",
+ "edit_prediction_context",
+ "edit_prediction_types",
"feature_flags",
"fs",
"futures 0.3.31",
"gpui",
"indoc",
+ "itertools 0.14.0",
"language",
+ "language_model",
+ "log",
"lsp",
"menu",
- "paths",
+ "open_ai",
+ "parking_lot",
+ "postage",
+ "pretty_assertions",
"project",
+ "rand 0.9.2",
"regex",
+ "release_channel",
+ "semver",
+ "serde",
"serde_json",
"settings",
- "supermaven",
+ "smol",
+ "strsim",
+ "strum 0.27.2",
"telemetry",
- "theme",
+ "telemetry_events",
+ "thiserror 2.0.17",
"ui",
- "ui_input",
"util",
+ "uuid",
"workspace",
+ "worktree",
"zed_actions",
- "zeta",
+ "zlog",
]
[[package]]
-name = "edit_prediction_context"
+name = "edit_prediction_cli"
version = "0.1.0"
dependencies = [
+ "anthropic",
"anyhow",
- "arrayvec",
+ "chrono",
"clap",
+ "client",
"cloud_llm_client",
+ "cloud_zeta2_prompt",
"collections",
+ "debug_adapter_extension",
+ "edit_prediction",
+ "edit_prediction_context",
+ "extension",
+ "fs",
"futures 0.3.31",
"gpui",
- "hashbrown 0.15.5",
+ "gpui_tokio",
+ "http_client",
"indoc",
- "itertools 0.14.0",
"language",
+ "language_extension",
+ "language_model",
+ "language_models",
+ "languages",
"log",
- "ordered-float 2.10.1",
- "postage",
+ "node_runtime",
+ "paths",
"pretty_assertions",
"project",
- "regex",
+ "prompt_store",
+ "pulldown-cmark 0.12.2",
+ "release_channel",
+ "reqwest_client",
"serde",
"serde_json",
"settings",
- "slotmap",
- "strum 0.27.2",
- "text",
- "tree-sitter",
- "tree-sitter-c",
- "tree-sitter-cpp",
- "tree-sitter-go",
+ "shellexpand 2.1.2",
+ "smol",
+ "sqlez",
+ "sqlez_macros",
+ "terminal_view",
+ "toml 0.8.23",
"util",
+ "watch",
"zlog",
]
[[package]]
-name = "editor"
+name = "edit_prediction_context"
version = "0.1.0"
dependencies = [
- "aho-corasick",
"anyhow",
- "assets",
- "buffer_diff",
- "client",
- "clock",
+ "cloud_llm_client",
"collections",
- "convert_case 0.8.0",
- "criterion",
- "ctor",
- "dap",
- "db",
- "edit_prediction",
- "emojis",
- "feature_flags",
- "file_icons",
- "fs",
+ "env_logger 0.11.8",
"futures 0.3.31",
- "fuzzy",
- "git",
"gpui",
- "http_client",
"indoc",
- "itertools 0.14.0",
"language",
- "languages",
- "linkify",
"log",
"lsp",
- "markdown",
- "menu",
- "multi_buffer",
- "ordered-float 2.10.1",
"parking_lot",
"pretty_assertions",
"project",
- "rand 0.9.2",
- "regex",
- "release_channel",
- "rope",
- "rpc",
- "schemars",
- "semver",
"serde",
"serde_json",
"settings",
"smallvec",
- "smol",
- "snippet",
- "sum_tree",
- "task",
- "telemetry",
- "tempfile",
+ "text",
+ "tree-sitter",
+ "util",
+ "zlog",
+]
+
+[[package]]
+name = "edit_prediction_types"
+version = "0.1.0"
+dependencies = [
+ "client",
+ "gpui",
+ "language",
+]
+
+[[package]]
+name = "edit_prediction_ui"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "buffer_diff",
+ "client",
+ "cloud_llm_client",
+ "cloud_zeta2_prompt",
+ "codestral",
+ "command_palette_hooks",
+ "copilot",
+ "edit_prediction",
+ "edit_prediction_types",
+ "editor",
+ "feature_flags",
+ "fs",
+ "futures 0.3.31",
+ "gpui",
+ "indoc",
+ "language",
+ "lsp",
+ "markdown",
+ "menu",
+ "multi_buffer",
+ "paths",
+ "project",
+ "regex",
+ "serde_json",
+ "settings",
+ "supermaven",
+ "telemetry",
+ "text",
+ "theme",
+ "ui",
+ "ui_input",
+ "util",
+ "workspace",
+ "zed_actions",
+]
+
+[[package]]
+name = "editor"
+version = "0.1.0"
+dependencies = [
+ "aho-corasick",
+ "anyhow",
+ "assets",
+ "buffer_diff",
+ "client",
+ "clock",
+ "collections",
+ "convert_case 0.8.0",
+ "criterion",
+ "ctor",
+ "dap",
+ "db",
+ "edit_prediction_types",
+ "emojis",
+ "feature_flags",
+ "file_icons",
+ "fs",
+ "futures 0.3.31",
+ "fuzzy",
+ "git",
+ "gpui",
+ "http_client",
+ "indoc",
+ "itertools 0.14.0",
+ "language",
+ "languages",
+ "linkify",
+ "log",
+ "lsp",
+ "markdown",
+ "menu",
+ "multi_buffer",
+ "ordered-float 2.10.1",
+ "parking_lot",
+ "pretty_assertions",
+ "project",
+ "rand 0.9.2",
+ "regex",
+ "release_channel",
+ "rope",
+ "rpc",
+ "schemars",
+ "semver",
+ "serde",
+ "serde_json",
+ "settings",
+ "smallvec",
+ "smol",
+ "snippet",
+ "sum_tree",
+ "task",
+ "telemetry",
+ "tempfile",
"text",
"theme",
"time",
+ "tracing",
"tree-sitter-bash",
"tree-sitter-c",
"tree-sitter-html",
+ "tree-sitter-md",
"tree-sitter-python",
"tree-sitter-rust",
"tree-sitter-typescript",
@@ -5420,6 +5370,7 @@ dependencies = [
"workspace",
"zed_actions",
"zlog",
+ "ztracing",
]
[[package]]
@@ -5695,12 +5646,6 @@ dependencies = [
"windows-sys 0.48.0",
]
-[[package]]
-name = "ethnum"
-version = "1.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b"
-
[[package]]
name = "euclid"
version = "0.22.11"
@@ -5864,6 +5809,7 @@ dependencies = [
"serde",
"serde_json",
"task",
+ "tempfile",
"toml 0.8.23",
"url",
"util",
@@ -5993,12 +5939,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
-[[package]]
-name = "fallible-streaming-iterator"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
-
[[package]]
name = "fancy-regex"
version = "0.16.2"
@@ -6010,12 +5950,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 = "fast-srgb8"
version = "1.0.0"
@@ -6191,7 +6125,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9"
dependencies = [
"crc32fast",
- "libz-rs-sys",
"miniz_oxide",
]
@@ -6448,16 +6381,6 @@ dependencies = [
"winapi",
]
-[[package]]
-name = "fs4"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8640e34b88f7652208ce9e88b1a37a2ae95227d84abec377ccd3c5cfeb141ed4"
-dependencies = [
- "rustix 1.1.2",
- "windows-sys 0.59.0",
-]
-
[[package]]
name = "fs_benchmarks"
version = "0.1.0"
@@ -6918,6 +6841,20 @@ dependencies = [
"seq-macro",
]
+[[package]]
+name = "generator"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "libc",
+ "log",
+ "rustversion",
+ "windows 0.61.3",
+]
+
[[package]]
name = "generic-array"
version = "0.14.7"
@@ -7079,6 +7016,7 @@ dependencies = [
"gpui",
"http_client",
"indoc",
+ "itertools 0.14.0",
"pretty_assertions",
"regex",
"serde",
@@ -7136,6 +7074,7 @@ dependencies = [
"theme",
"time",
"time_format",
+ "tracing",
"ui",
"unindent",
"util",
@@ -7145,6 +7084,7 @@ dependencies = [
"zed_actions",
"zeroize",
"zlog",
+ "ztracing",
]
[[package]]
@@ -7521,7 +7461,6 @@ dependencies = [
"allocator-api2",
"equivalent",
"foldhash 0.1.5",
- "rayon",
"serde",
]
@@ -7633,7 +7572,7 @@ version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c255bdf46e07fb840d120a36dcc81f385140d7191c76a7391672675c01a55d"
dependencies = [
- "bincode 1.3.3",
+ "bincode",
"byteorder",
"heed-traits",
"serde",
@@ -8223,7 +8162,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
- "hashbrown 0.15.5",
+ "hashbrown 0.16.1",
"serde",
"serde_core",
]
@@ -8393,7 +8332,7 @@ version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8251fb7bcd9ccd3725ed8deae9fe7db8e586495c9eb5b0c52e6233e5e75ea"
dependencies = [
- "bincode 1.3.3",
+ "bincode",
"crossbeam-channel",
"fnv",
"lazy_static",
@@ -9234,15 +9173,6 @@ dependencies = [
"webrtc-sys",
]
-[[package]]
-name = "libz-rs-sys"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "840db8cf39d9ec4dd794376f38acc40d0fc65eec2a8f484f7fd375b84602becd"
-dependencies = [
- "zlib-rs",
-]
-
[[package]]
name = "libz-sys"
version = "1.1.22"
@@ -9305,12 +9235,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
-[[package]]
-name = "litrs"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed"
-
[[package]]
name = "livekit"
version = "0.7.8"
@@ -9480,6 +9404,19 @@ dependencies = [
"value-bag",
]
+[[package]]
+name = "loom"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca"
+dependencies = [
+ "cfg-if",
+ "generator",
+ "scoped-tls",
+ "tracing",
+ "tracing-subscriber",
+]
+
[[package]]
name = "loop9"
version = "0.1.5"
@@ -9602,25 +9539,6 @@ dependencies = [
"num-traits",
]
-[[package]]
-name = "lz4"
-version = "1.28.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4"
-dependencies = [
- "lz4-sys",
-]
-
-[[package]]
-name = "lz4-sys"
-version = "1.11.1+lz4-1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6"
-dependencies = [
- "cc",
- "libc",
-]
-
[[package]]
name = "mac"
version = "0.1.1"
@@ -10169,9 +10087,11 @@ dependencies = [
"sum_tree",
"text",
"theme",
+ "tracing",
"tree-sitter",
"util",
"zlog",
+ "ztracing",
]
[[package]]
@@ -10483,15 +10403,6 @@ name = "notify-types"
version = "2.0.0"
source = "git+https://github.com/zed-industries/notify.git?rev=b4588b2e5aee68f4c0e100f140e808cbce7b1419#b4588b2e5aee68f4c0e100f140e808cbce7b1419"
-[[package]]
-name = "now"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d89e9874397a1f0a52fc1f197a8effd9735223cb2390e9dcc83ac6cd02923d0"
-dependencies = [
- "chrono",
-]
-
[[package]]
name = "ntapi"
version = "0.4.1"
@@ -10887,41 +10798,6 @@ dependencies = [
"memchr",
]
-[[package]]
-name = "object_store"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c1be0c6c22ec0817cdc77d3842f721a17fd30ab6965001415b5402a74e6b740"
-dependencies = [
- "async-trait",
- "base64 0.22.1",
- "bytes 1.10.1",
- "chrono",
- "form_urlencoded",
- "futures 0.3.31",
- "http 1.3.1",
- "http-body-util",
- "humantime",
- "hyper 1.7.0",
- "itertools 0.14.0",
- "parking_lot",
- "percent-encoding",
- "quick-xml 0.38.3",
- "rand 0.9.2",
- "reqwest 0.12.24",
- "ring",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "thiserror 2.0.17",
- "tokio",
- "tracing",
- "url",
- "walkdir",
- "wasm-bindgen-futures",
- "web-time",
-]
-
[[package]]
name = "ollama"
version = "0.1.0"
@@ -12156,16 +12032,6 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
-[[package]]
-name = "planus"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3daf8e3d4b712abe1d690838f6e29fb76b76ea19589c4afa39ec30e12f62af71"
-dependencies = [
- "array-init-cursor",
- "hashbrown 0.15.5",
-]
-
[[package]]
name = "plist"
version = "1.8.0"
@@ -12234,544 +12100,30 @@ dependencies = [
]
[[package]]
-name = "polars"
-version = "0.51.0"
+name = "polling"
+version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5f7feb5d56b954e691dff22a8b2d78d77433dcc93c35fe21c3777fdc121b697"
+checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
dependencies = [
- "getrandom 0.2.16",
- "getrandom 0.3.4",
- "polars-arrow",
- "polars-core",
- "polars-error",
- "polars-io",
- "polars-lazy",
- "polars-ops",
- "polars-parquet",
- "polars-sql",
- "polars-time",
- "polars-utils",
- "version_check",
+ "cfg-if",
+ "concurrent-queue",
+ "hermit-abi",
+ "pin-project-lite",
+ "rustix 1.1.2",
+ "windows-sys 0.61.2",
]
[[package]]
-name = "polars-arrow"
-version = "0.51.0"
+name = "pollster"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7"
+
+[[package]]
+name = "pori"
+version = "0.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32b4fed2343961b3eea3db2cee165540c3e1ad9d5782350cc55a9e76cf440148"
-dependencies = [
- "atoi_simd",
- "bitflags 2.9.4",
- "bytemuck",
- "chrono",
- "chrono-tz",
- "dyn-clone",
- "either",
- "ethnum",
- "getrandom 0.2.16",
- "getrandom 0.3.4",
- "hashbrown 0.15.5",
- "itoa",
- "lz4",
- "num-traits",
- "polars-arrow-format",
- "polars-error",
- "polars-schema",
- "polars-utils",
- "serde",
- "simdutf8",
- "streaming-iterator",
- "strum_macros 0.27.2",
- "version_check",
- "zstd 0.13.3",
-]
-
-[[package]]
-name = "polars-arrow-format"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a556ac0ee744e61e167f34c1eb0013ce740e0ee6cd8c158b2ec0b518f10e6675"
-dependencies = [
- "planus",
- "serde",
-]
-
-[[package]]
-name = "polars-compute"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "138785beda4e4a90a025219f09d0d15a671b2be9091513ede58e05db6ad4413f"
-dependencies = [
- "atoi_simd",
- "bytemuck",
- "chrono",
- "either",
- "fast-float2",
- "hashbrown 0.15.5",
- "itoa",
- "num-traits",
- "polars-arrow",
- "polars-error",
- "polars-utils",
- "rand 0.9.2",
- "ryu",
- "serde",
- "skiplist",
- "strength_reduce",
- "strum_macros 0.27.2",
- "version_check",
-]
-
-[[package]]
-name = "polars-core"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e77b1f08ef6dbb032bb1d0d3365464be950df9905f6827a95b24c4ca5518901d"
-dependencies = [
- "bitflags 2.9.4",
- "boxcar",
- "bytemuck",
- "chrono",
- "chrono-tz",
- "comfy-table",
- "either",
- "hashbrown 0.15.5",
- "indexmap",
- "itoa",
- "num-traits",
- "polars-arrow",
- "polars-compute",
- "polars-dtype",
- "polars-error",
- "polars-row",
- "polars-schema",
- "polars-utils",
- "rand 0.9.2",
- "rand_distr",
- "rayon",
- "regex",
- "serde",
- "serde_json",
- "strum_macros 0.27.2",
- "uuid",
- "version_check",
- "xxhash-rust",
-]
-
-[[package]]
-name = "polars-dtype"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89c43d0ea57168be4546c4d8064479ed8b29a9c79c31a0c7c367ee734b9b7158"
-dependencies = [
- "boxcar",
- "hashbrown 0.15.5",
- "polars-arrow",
- "polars-error",
- "polars-utils",
- "serde",
- "uuid",
-]
-
-[[package]]
-name = "polars-error"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9cb5d98f59f8b94673ee391840440ad9f0d2170afced95fc98aa86f895563c0"
-dependencies = [
- "object_store",
- "parking_lot",
- "polars-arrow-format",
- "regex",
- "signal-hook",
- "simdutf8",
-]
-
-[[package]]
-name = "polars-expr"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "343931b818cf136349135ba11dbc18c27683b52c3477b1ba8ca606cf5ab1965c"
-dependencies = [
- "bitflags 2.9.4",
- "hashbrown 0.15.5",
- "num-traits",
- "polars-arrow",
- "polars-compute",
- "polars-core",
- "polars-io",
- "polars-ops",
- "polars-plan",
- "polars-row",
- "polars-time",
- "polars-utils",
- "rand 0.9.2",
- "rayon",
- "recursive",
-]
-
-[[package]]
-name = "polars-io"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10388c64b8155122488229a881d1c6f4fdc393bc988e764ab51b182fcb2307e4"
-dependencies = [
- "async-trait",
- "atoi_simd",
- "blake3",
- "bytes 1.10.1",
- "chrono",
- "fast-float2",
- "fs4",
- "futures 0.3.31",
- "glob",
- "hashbrown 0.15.5",
- "home",
- "itoa",
- "memchr",
- "memmap2",
- "num-traits",
- "object_store",
- "percent-encoding",
- "polars-arrow",
- "polars-core",
- "polars-error",
- "polars-parquet",
- "polars-schema",
- "polars-time",
- "polars-utils",
- "rayon",
- "regex",
- "reqwest 0.12.24",
- "ryu",
- "serde",
- "serde_json",
- "simdutf8",
- "tokio",
- "tokio-util",
- "url",
-]
-
-[[package]]
-name = "polars-lazy"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fb6e2c6c2fa4ea0c660df1c06cf56960c81e7c2683877995bae3d4e3d408147"
-dependencies = [
- "bitflags 2.9.4",
- "chrono",
- "either",
- "memchr",
- "polars-arrow",
- "polars-compute",
- "polars-core",
- "polars-expr",
- "polars-io",
- "polars-mem-engine",
- "polars-ops",
- "polars-plan",
- "polars-stream",
- "polars-time",
- "polars-utils",
- "rayon",
- "version_check",
-]
-
-[[package]]
-name = "polars-mem-engine"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20a856e98e253587c28d8132a5e7e5a75cb2c44731ca090f1481d45f1d123771"
-dependencies = [
- "futures 0.3.31",
- "memmap2",
- "polars-arrow",
- "polars-core",
- "polars-error",
- "polars-expr",
- "polars-io",
- "polars-ops",
- "polars-plan",
- "polars-time",
- "polars-utils",
- "rayon",
- "recursive",
- "tokio",
-]
-
-[[package]]
-name = "polars-ops"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acf6062173fdc9ba05775548beb66e76643a148d9aeadc9984ed712bc4babd76"
-dependencies = [
- "argminmax",
- "base64 0.22.1",
- "bytemuck",
- "chrono",
- "chrono-tz",
- "either",
- "hashbrown 0.15.5",
- "hex",
- "indexmap",
- "libm",
- "memchr",
- "num-traits",
- "polars-arrow",
- "polars-compute",
- "polars-core",
- "polars-error",
- "polars-schema",
- "polars-utils",
- "rayon",
- "regex",
- "regex-syntax",
- "strum_macros 0.27.2",
- "unicode-normalization",
- "unicode-reverse",
- "version_check",
-]
-
-[[package]]
-name = "polars-parquet"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc1d769180dec070df0dc4b89299b364bf2cfe32b218ecc4ddd8f1a49ae60669"
-dependencies = [
- "async-stream",
- "base64 0.22.1",
- "brotli",
- "bytemuck",
- "ethnum",
- "flate2",
- "futures 0.3.31",
- "hashbrown 0.15.5",
- "lz4",
- "num-traits",
- "polars-arrow",
- "polars-compute",
- "polars-error",
- "polars-parquet-format",
- "polars-utils",
- "serde",
- "simdutf8",
- "snap",
- "streaming-decompression",
- "zstd 0.13.3",
-]
-
-[[package]]
-name = "polars-parquet-format"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c025243dcfe8dbc57e94d9f82eb3bef10b565ab180d5b99bed87fd8aea319ce1"
-dependencies = [
- "async-trait",
- "futures 0.3.31",
-]
-
-[[package]]
-name = "polars-plan"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd3a2e33ae4484fe407ab2d2ba5684f0889d1ccf3ad6b844103c03638e6d0a0"
-dependencies = [
- "bitflags 2.9.4",
- "bytemuck",
- "bytes 1.10.1",
- "chrono",
- "chrono-tz",
- "either",
- "futures 0.3.31",
- "hashbrown 0.15.5",
- "memmap2",
- "num-traits",
- "percent-encoding",
- "polars-arrow",
- "polars-compute",
- "polars-core",
- "polars-error",
- "polars-io",
- "polars-ops",
- "polars-parquet",
- "polars-time",
- "polars-utils",
- "rayon",
- "recursive",
- "regex",
- "sha2",
- "strum_macros 0.27.2",
- "version_check",
-]
-
-[[package]]
-name = "polars-row"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18734f17e0e348724df3ae65f3ee744c681117c04b041cac969dfceb05edabc0"
-dependencies = [
- "bitflags 2.9.4",
- "bytemuck",
- "polars-arrow",
- "polars-compute",
- "polars-dtype",
- "polars-error",
- "polars-utils",
-]
-
-[[package]]
-name = "polars-schema"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e6c1ab13e04d5167661a9854ed1ea0482b2ed9b8a0f1118dabed7cd994a85e3"
-dependencies = [
- "indexmap",
- "polars-error",
- "polars-utils",
- "serde",
- "version_check",
-]
-
-[[package]]
-name = "polars-sql"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4e7766da02cc1d464994404d3e88a7a0ccd4933df3627c325480fbd9bbc0a11"
-dependencies = [
- "bitflags 2.9.4",
- "hex",
- "polars-core",
- "polars-error",
- "polars-lazy",
- "polars-ops",
- "polars-plan",
- "polars-time",
- "polars-utils",
- "rand 0.9.2",
- "regex",
- "serde",
- "sqlparser",
-]
-
-[[package]]
-name = "polars-stream"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31f6c6ca1ea01f9dea424d167e4f33f5ec44cd67fbfac9efd40575ed20521f14"
-dependencies = [
- "async-channel 2.5.0",
- "async-trait",
- "atomic-waker",
- "bitflags 2.9.4",
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-queue",
- "crossbeam-utils",
- "futures 0.3.31",
- "memmap2",
- "parking_lot",
- "percent-encoding",
- "pin-project-lite",
- "polars-arrow",
- "polars-core",
- "polars-error",
- "polars-expr",
- "polars-io",
- "polars-mem-engine",
- "polars-ops",
- "polars-parquet",
- "polars-plan",
- "polars-utils",
- "rand 0.9.2",
- "rayon",
- "recursive",
- "slotmap",
- "tokio",
- "tokio-util",
- "version_check",
-]
-
-[[package]]
-name = "polars-time"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6a3a6e279a7a984a0b83715660f9e880590c6129ec2104396bfa710bcd76dee"
-dependencies = [
- "atoi_simd",
- "bytemuck",
- "chrono",
- "chrono-tz",
- "now",
- "num-traits",
- "polars-arrow",
- "polars-compute",
- "polars-core",
- "polars-error",
- "polars-ops",
- "polars-utils",
- "rayon",
- "regex",
- "strum_macros 0.27.2",
-]
-
-[[package]]
-name = "polars-utils"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57b267021b0e5422d7fbc70fd79e51b9f9a8466c585779373a18b0199e973f29"
-dependencies = [
- "bincode 2.0.1",
- "bytemuck",
- "bytes 1.10.1",
- "compact_str",
- "either",
- "flate2",
- "foldhash 0.1.5",
- "hashbrown 0.15.5",
- "indexmap",
- "libc",
- "memmap2",
- "num-traits",
- "polars-error",
- "rand 0.9.2",
- "raw-cpuid 11.6.0",
- "rayon",
- "regex",
- "rmp-serde",
- "serde",
- "serde_json",
- "serde_stacker",
- "slotmap",
- "stacker",
- "uuid",
- "version_check",
-]
-
-[[package]]
-name = "polling"
-version = "3.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
-dependencies = [
- "cfg-if",
- "concurrent-queue",
- "hermit-abi",
- "pin-project-lite",
- "rustix 1.1.2",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "pollster"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7"
-
-[[package]]
-name = "pori"
-version = "0.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4a63d338dec139f56dacc692ca63ad35a6be6a797442479b55acd611d79e906"
+checksum = "a4a63d338dec139f56dacc692ca63ad35a6be6a797442479b55acd611d79e906"
dependencies = [
"nom 7.1.3",
]
@@ -13088,6 +12440,7 @@ dependencies = [
"terminal",
"text",
"toml 0.8.23",
+ "tracing",
"unindent",
"url",
"util",
@@ -13097,6 +12450,7 @@ dependencies = [
"worktree",
"zeroize",
"zlog",
+ "ztracing",
]
[[package]]
@@ -13498,7 +12852,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89"
dependencies = [
"memchr",
- "serde",
]
[[package]]
@@ -13832,26 +13185,6 @@ dependencies = [
"zed_actions",
]
-[[package]]
-name = "recursive"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0786a43debb760f491b1bc0269fe5e84155353c67482b9e60d0cfb596054b43e"
-dependencies = [
- "recursive-proc-macro-impl",
- "stacker",
-]
-
-[[package]]
-name = "recursive-proc-macro-impl"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76009fbe0614077fc1a2ce255e3a1881a2e3a3527097d5dc6d8212c585e7e38b"
-dependencies = [
- "quote",
- "syn 2.0.106",
-]
-
[[package]]
name = "redox_syscall"
version = "0.2.16"
@@ -14208,35 +13541,26 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-util",
- "h2 0.4.12",
"http 1.3.1",
"http-body 1.0.1",
"http-body-util",
"hyper 1.7.0",
- "hyper-rustls 0.27.7",
"hyper-util",
"js-sys",
"log",
"percent-encoding",
"pin-project-lite",
- "quinn",
- "rustls 0.23.33",
- "rustls-native-certs 0.8.2",
- "rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 1.0.2",
"tokio",
- "tokio-rustls 0.26.2",
- "tokio-util",
"tower 0.5.2",
"tower-http 0.6.6",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
- "wasm-streams",
"web-sys",
]
@@ -14359,17 +13683,6 @@ dependencies = [
"paste",
]
-[[package]]
-name = "rmp-serde"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
-dependencies = [
- "byteorder",
- "rmp",
- "serde",
-]
-
[[package]]
name = "rmpv"
version = "1.3.0"
@@ -14406,9 +13719,11 @@ dependencies = [
"rand 0.9.2",
"rayon",
"sum_tree",
+ "tracing",
"unicode-segmentation",
"util",
"zlog",
+ "ztracing",
]
[[package]]
@@ -14439,7 +13754,7 @@ dependencies = [
"tracing",
"util",
"zlog",
- "zstd 0.11.2+zstd.1.5.2",
+ "zstd",
]
[[package]]
@@ -15323,23 +14638,12 @@ dependencies = [
]
[[package]]
-name = "serde_spanned"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "serde_stacker"
-version = "0.1.14"
+name = "serde_spanned"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4936375d50c4be7eff22293a9344f8e46f323ed2b3c243e52f89138d9bb0f4a"
+checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
dependencies = [
- "serde",
"serde_core",
- "stacker",
]
[[package]]
@@ -15683,16 +14987,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
-[[package]]
-name = "skiplist"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f354fd282d3177c2951004953e2fdc4cb342fa159bbee8b829852b6a081c8ea1"
-dependencies = [
- "rand 0.9.2",
- "thiserror 2.0.17",
-]
-
[[package]]
name = "skrifa"
version = "0.37.0"
@@ -15768,12 +15062,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
-[[package]]
-name = "snap"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b"
-
[[package]]
name = "snippet"
version = "0.1.0"
@@ -15820,26 +15108,6 @@ dependencies = [
"workspace",
]
-[[package]]
-name = "soa-rs"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b75ae4668062b095fda87ba54118697bed601f07f6c68bf50289a25ca0c8c935"
-dependencies = [
- "soa-rs-derive",
-]
-
-[[package]]
-name = "soa-rs-derive"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c09121507da587d3434e5929ce3321162f36bd3eff403873cb163c06b176913"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.106",
-]
-
[[package]]
name = "socket2"
version = "0.5.10"
@@ -15959,15 +15227,6 @@ dependencies = [
"unicode_categories",
]
-[[package]]
-name = "sqlparser"
-version = "0.53.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05a528114c392209b3264855ad491fcce534b94a38771b0a0b97a79379275ce8"
-dependencies = [
- "log",
-]
-
[[package]]
name = "sqlx"
version = "0.8.6"
@@ -16269,15 +15528,6 @@ dependencies = [
"ui",
]
-[[package]]
-name = "streaming-decompression"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf6cc3b19bfb128a8ad11026086e31d3ce9ad23f8ea37354b31383a187c44cf3"
-dependencies = [
- "fallible-streaming-iterator",
-]
-
[[package]]
name = "streaming-iterator"
version = "0.1.9"
@@ -16409,7 +15659,9 @@ dependencies = [
"log",
"rand 0.9.2",
"rayon",
+ "tracing",
"zlog",
+ "ztracing",
]
[[package]]
@@ -16419,7 +15671,7 @@ dependencies = [
"anyhow",
"client",
"collections",
- "edit_prediction",
+ "edit_prediction_types",
"editor",
"env_logger 0.11.8",
"futures 0.3.31",
@@ -17663,7 +16915,6 @@ dependencies = [
"futures-core",
"futures-io",
"futures-sink",
- "futures-util",
"pin-project-lite",
"tokio",
]
@@ -17895,9 +17146,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
-version = "0.1.41"
+version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
dependencies = [
"log",
"pin-project-lite",
@@ -17907,9 +17158,9 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.30"
+version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
+checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
@@ -17918,9 +17169,9 @@ dependencies = [
[[package]]
name = "tracing-core"
-version = "0.1.34"
+version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
+checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
dependencies = [
"once_cell",
"valuable",
@@ -17949,9 +17200,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
-version = "0.3.20"
+version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
+checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
dependencies = [
"matchers",
"nu-ansi-term",
@@ -17968,6 +17219,38 @@ dependencies = [
"tracing-serde",
]
+[[package]]
+name = "tracing-tracy"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eaa1852afa96e0fe9e44caa53dc0bd2d9d05e0f2611ce09f97f8677af56e4ba"
+dependencies = [
+ "tracing-core",
+ "tracing-subscriber",
+ "tracy-client",
+]
+
+[[package]]
+name = "tracy-client"
+version = "0.18.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91d722a05fe49b31fef971c4732a7d4aa6a18283d9ba46abddab35f484872947"
+dependencies = [
+ "loom",
+ "once_cell",
+ "tracy-client-sys",
+]
+
+[[package]]
+name = "tracy-client-sys"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fb391ac70462b3097a755618fbf9c8f95ecc1eb379a414f7b46f202ed10db1f"
+dependencies = [
+ "cc",
+ "windows-targets 0.52.6",
+]
+
[[package]]
name = "trait-variant"
version = "0.1.2"
@@ -18519,15 +17802,6 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
-[[package]]
-name = "unicode-reverse"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b6f4888ebc23094adfb574fdca9fdc891826287a6397d2cd28802ffd6f20c76"
-dependencies = [
- "unicode-segmentation",
-]
-
[[package]]
name = "unicode-script"
version = "0.5.7"
@@ -18588,12 +17862,6 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
-[[package]]
-name = "unty"
-version = "0.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae"
-
[[package]]
name = "url"
version = "2.5.7"
@@ -18869,12 +18137,6 @@ dependencies = [
"settings",
]
-[[package]]
-name = "virtue"
-version = "0.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1"
-
[[package]]
name = "vscode_theme"
version = "0.2.0"
@@ -21030,12 +20292,6 @@ dependencies = [
"toml_edit 0.22.27",
]
-[[package]]
-name = "xxhash-rust"
-version = "0.8.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3"
-
[[package]]
name = "yaml-rust2"
version = "0.8.1"
@@ -21223,7 +20479,7 @@ dependencies = [
"audio",
"auto_update",
"auto_update_ui",
- "bincode 1.3.3",
+ "bincode",
"breadcrumbs",
"call",
"channel",
@@ -21245,7 +20501,8 @@ dependencies = [
"debugger_tools",
"debugger_ui",
"diagnostics",
- "edit_prediction_button",
+ "edit_prediction",
+ "edit_prediction_ui",
"editor",
"env_logger 0.11.8",
"extension",
@@ -21336,6 +20593,7 @@ dependencies = [
"time",
"title_bar",
"toolchain_selector",
+ "tracing",
"tree-sitter-md",
"tree-sitter-rust",
"ui",
@@ -21356,10 +20614,9 @@ dependencies = [
"zed-reqwest",
"zed_actions",
"zed_env_vars",
- "zeta",
- "zeta2_tools",
"zlog",
"zlog_settings",
+ "ztracing",
]
[[package]]
@@ -21669,151 +20926,6 @@ dependencies = [
"syn 2.0.106",
]
-[[package]]
-name = "zeta"
-version = "0.1.0"
-dependencies = [
- "ai_onboarding",
- "anyhow",
- "arrayvec",
- "brotli",
- "buffer_diff",
- "client",
- "clock",
- "cloud_api_types",
- "cloud_llm_client",
- "cloud_zeta2_prompt",
- "collections",
- "command_palette_hooks",
- "copilot",
- "credentials_provider",
- "ctor",
- "db",
- "edit_prediction",
- "edit_prediction_context",
- "editor",
- "feature_flags",
- "fs",
- "futures 0.3.31",
- "gpui",
- "indoc",
- "itertools 0.14.0",
- "language",
- "language_model",
- "log",
- "lsp",
- "markdown",
- "menu",
- "open_ai",
- "parking_lot",
- "postage",
- "pretty_assertions",
- "project",
- "rand 0.9.2",
- "regex",
- "release_channel",
- "semver",
- "serde",
- "serde_json",
- "settings",
- "smol",
- "strsim",
- "strum 0.27.2",
- "telemetry",
- "telemetry_events",
- "theme",
- "thiserror 2.0.17",
- "ui",
- "util",
- "uuid",
- "workspace",
- "worktree",
- "zed_actions",
- "zlog",
-]
-
-[[package]]
-name = "zeta2_tools"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "clap",
- "client",
- "cloud_llm_client",
- "cloud_zeta2_prompt",
- "collections",
- "edit_prediction_context",
- "editor",
- "feature_flags",
- "futures 0.3.31",
- "gpui",
- "indoc",
- "language",
- "multi_buffer",
- "pretty_assertions",
- "project",
- "serde",
- "serde_json",
- "settings",
- "telemetry",
- "text",
- "ui",
- "ui_input",
- "util",
- "workspace",
- "zeta",
- "zlog",
-]
-
-[[package]]
-name = "zeta_cli"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "chrono",
- "clap",
- "client",
- "cloud_llm_client",
- "cloud_zeta2_prompt",
- "collections",
- "debug_adapter_extension",
- "edit_prediction_context",
- "extension",
- "fs",
- "futures 0.3.31",
- "gpui",
- "gpui_tokio",
- "indoc",
- "language",
- "language_extension",
- "language_model",
- "language_models",
- "languages",
- "log",
- "node_runtime",
- "ordered-float 2.10.1",
- "paths",
- "polars",
- "pretty_assertions",
- "project",
- "prompt_store",
- "pulldown-cmark 0.12.2",
- "release_channel",
- "reqwest_client",
- "serde",
- "serde_json",
- "settings",
- "shellexpand 2.1.2",
- "smol",
- "soa-rs",
- "terminal_view",
- "toml 0.8.23",
- "util",
- "watch",
- "zeta",
- "zlog",
-]
-
[[package]]
name = "zip"
version = "0.6.6"
@@ -21823,7 +20935,7 @@ dependencies = [
"aes",
"byteorder",
"bzip2",
- "constant_time_eq 0.1.5",
+ "constant_time_eq",
"crc32fast",
"crossbeam-utils",
"flate2",
@@ -21831,7 +20943,7 @@ dependencies = [
"pbkdf2 0.11.0",
"sha1",
"time",
- "zstd 0.11.2+zstd.1.5.2",
+ "zstd",
]
[[package]]
@@ -21849,12 +20961,6 @@ dependencies = [
"thiserror 1.0.69",
]
-[[package]]
-name = "zlib-rs"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2"
-
[[package]]
name = "zlog"
version = "0.1.0"
@@ -21882,16 +20988,7 @@ version = "0.11.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
dependencies = [
- "zstd-safe 5.0.2+zstd.1.5.2",
-]
-
-[[package]]
-name = "zstd"
-version = "0.13.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
-dependencies = [
- "zstd-safe 7.2.4",
+ "zstd-safe",
]
[[package]]
@@ -21904,15 +21001,6 @@ dependencies = [
"zstd-sys",
]
-[[package]]
-name = "zstd-safe"
-version = "7.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
-dependencies = [
- "zstd-sys",
-]
-
[[package]]
name = "zstd-sys"
version = "2.0.16+zstd.1.5.7"
@@ -21923,6 +21011,20 @@ dependencies = [
"pkg-config",
]
+[[package]]
+name = "ztracing"
+version = "0.1.0"
+dependencies = [
+ "tracing",
+ "tracing-subscriber",
+ "tracing-tracy",
+ "ztracing_macro",
+]
+
+[[package]]
+name = "ztracing_macro"
+version = "0.1.0"
+
[[package]]
name = "zune-core"
version = "0.4.12"
diff --git a/Cargo.toml b/Cargo.toml
index 59b9a53d4a60b28582625fb90b64b934079cdc40..0ad4d2b14523988aa0dd6e3bfc935f84bcd0d8d9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -54,9 +54,9 @@ members = [
"crates/diagnostics",
"crates/docs_preprocessor",
"crates/edit_prediction",
- "crates/edit_prediction_button",
+ "crates/edit_prediction_types",
+ "crates/edit_prediction_ui",
"crates/edit_prediction_context",
- "crates/zeta2_tools",
"crates/editor",
"crates/eval",
"crates/eval_utils",
@@ -201,10 +201,11 @@ members = [
"crates/zed",
"crates/zed_actions",
"crates/zed_env_vars",
- "crates/zeta",
- "crates/zeta_cli",
+ "crates/edit_prediction_cli",
"crates/zlog",
"crates/zlog_settings",
+ "crates/ztracing",
+ "crates/ztracing_macro",
#
# Extensions
@@ -243,7 +244,6 @@ activity_indicator = { path = "crates/activity_indicator" }
agent_ui = { path = "crates/agent_ui" }
agent_settings = { path = "crates/agent_settings" }
agent_servers = { path = "crates/agent_servers" }
-ai = { path = "crates/ai" }
ai_onboarding = { path = "crates/ai_onboarding" }
anthropic = { path = "crates/anthropic" }
askpass = { path = "crates/askpass" }
@@ -253,7 +253,6 @@ assistant_slash_command = { path = "crates/assistant_slash_command" }
assistant_slash_commands = { path = "crates/assistant_slash_commands" }
audio = { path = "crates/audio" }
auto_update = { path = "crates/auto_update" }
-auto_update_helper = { path = "crates/auto_update_helper" }
auto_update_ui = { path = "crates/auto_update_ui" }
aws_http_client = { path = "crates/aws_http_client" }
bedrock = { path = "crates/bedrock" }
@@ -268,7 +267,6 @@ cloud_api_client = { path = "crates/cloud_api_client" }
cloud_api_types = { path = "crates/cloud_api_types" }
cloud_llm_client = { path = "crates/cloud_llm_client" }
cloud_zeta2_prompt = { path = "crates/cloud_zeta2_prompt" }
-collab = { path = "crates/collab" }
collab_ui = { path = "crates/collab_ui" }
collections = { path = "crates/collections", version = "0.1.0" }
command_palette = { path = "crates/command_palette" }
@@ -313,10 +311,9 @@ http_client = { path = "crates/http_client" }
http_client_tls = { path = "crates/http_client_tls" }
icons = { path = "crates/icons" }
image_viewer = { path = "crates/image_viewer" }
-edit_prediction = { path = "crates/edit_prediction" }
-edit_prediction_button = { path = "crates/edit_prediction_button" }
+edit_prediction_types = { path = "crates/edit_prediction_types" }
+edit_prediction_ui = { path = "crates/edit_prediction_ui" }
edit_prediction_context = { path = "crates/edit_prediction_context" }
-zeta2_tools = { path = "crates/zeta2_tools" }
inspector_ui = { path = "crates/inspector_ui" }
install_cli = { path = "crates/install_cli" }
journal = { path = "crates/journal" }
@@ -358,8 +355,6 @@ panel = { path = "crates/panel" }
paths = { path = "crates/paths" }
perf = { path = "tooling/perf" }
picker = { path = "crates/picker" }
-plugin = { path = "crates/plugin" }
-plugin_macros = { path = "crates/plugin_macros" }
prettier = { path = "crates/prettier" }
settings_profile_selector = { path = "crates/settings_profile_selector" }
project = { path = "crates/project" }
@@ -370,12 +365,10 @@ proto = { path = "crates/proto" }
recent_projects = { path = "crates/recent_projects" }
refineable = { path = "crates/refineable" }
release_channel = { path = "crates/release_channel" }
-scheduler = { path = "crates/scheduler" }
remote = { path = "crates/remote" }
remote_server = { path = "crates/remote_server" }
repl = { path = "crates/repl" }
reqwest_client = { path = "crates/reqwest_client" }
-rich_text = { path = "crates/rich_text" }
rodio = { git = "https://github.com/RustAudio/rodio", rev ="e2074c6c2acf07b57cf717e076bdda7a9ac6e70b", features = ["wav", "playback", "wav_output", "recording"] }
rope = { path = "crates/rope" }
rpc = { path = "crates/rpc" }
@@ -392,7 +385,6 @@ snippets_ui = { path = "crates/snippets_ui" }
sqlez = { path = "crates/sqlez" }
sqlez_macros = { path = "crates/sqlez_macros" }
story = { path = "crates/story" }
-storybook = { path = "crates/storybook" }
streaming_diff = { path = "crates/streaming_diff" }
sum_tree = { path = "crates/sum_tree" }
supermaven = { path = "crates/supermaven" }
@@ -409,7 +401,6 @@ terminal_view = { path = "crates/terminal_view" }
text = { path = "crates/text" }
theme = { path = "crates/theme" }
theme_extension = { path = "crates/theme_extension" }
-theme_importer = { path = "crates/theme_importer" }
theme_selector = { path = "crates/theme_selector" }
time_format = { path = "crates/time_format" }
title_bar = { path = "crates/title_bar" }
@@ -433,15 +424,17 @@ x_ai = { path = "crates/x_ai" }
zed = { path = "crates/zed" }
zed_actions = { path = "crates/zed_actions" }
zed_env_vars = { path = "crates/zed_env_vars" }
-zeta = { path = "crates/zeta" }
+edit_prediction = { path = "crates/edit_prediction" }
zlog = { path = "crates/zlog" }
zlog_settings = { path = "crates/zlog_settings" }
+ztracing = { path = "crates/ztracing" }
+ztracing_macro = { path = "crates/ztracing_macro" }
#
# External crates
#
-agent-client-protocol = { version = "=0.8.0", features = ["unstable"] }
+agent-client-protocol = { version = "=0.9.0", features = ["unstable"] }
aho-corasick = "1.1"
alacritty_terminal = "0.25.1-rc1"
any_vec = "0.14"
@@ -508,13 +501,11 @@ exec = "0.3.1"
fancy-regex = "0.16.0"
fork = "0.4.0"
futures = "0.3"
-futures-batch = "0.6.1"
futures-lite = "1.13"
gh-workflow = { git = "https://github.com/zed-industries/gh-workflow", rev = "09acfdf2bd5c1d6254abefd609c808ff73547b2c" }
git2 = { version = "0.20.1", default-features = false }
globset = "0.4"
handlebars = "4.3"
-hashbrown = "0.15.3"
heck = "0.5"
heed = { version = "0.21.0", features = ["read-txn-no-tls"] }
hex = "0.4.3"
@@ -550,7 +541,6 @@ nanoid = "0.4"
nbformat = "0.15.0"
nix = "0.29"
num-format = "0.4.4"
-num-traits = "0.2"
objc = "0.2"
objc2-foundation = { version = "=0.3.1", default-features = false, features = [
"NSArray",
@@ -589,7 +579,6 @@ pet = { git = "https://github.com/microsoft/python-environment-tools.git", rev =
pet-conda = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
pet-core = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
pet-fs = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
-pet-pixi = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
pet-virtualenv = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1e86914c3ce2f3a08c0cedbcb0615a7f9fa7a5da" }
@@ -629,7 +618,6 @@ scap = { git = "https://github.com/zed-industries/scap", rev = "4afea48c3b002197
schemars = { version = "1.0", features = ["indexmap2"] }
semver = { version = "1.0", features = ["serde"] }
serde = { version = "1.0.221", features = ["derive", "rc"] }
-serde_derive = "1.0.221"
serde_json = { version = "1.0.144", features = ["preserve_order", "raw_value"] }
serde_json_lenient = { version = "0.2", features = [
"preserve_order",
@@ -641,7 +629,6 @@ serde_urlencoded = "0.7"
sha2 = "0.10"
shellexpand = "2.1.0"
shlex = "1.3.0"
-similar = "2.6"
simplelog = "0.12.2"
slotmap = "1.0.6"
smallvec = { version = "1.6", features = ["union"] }
@@ -696,6 +683,7 @@ tree-sitter-ruby = "0.23"
tree-sitter-rust = "0.24"
tree-sitter-typescript = { git = "https://github.com/zed-industries/tree-sitter-typescript", rev = "e2c53597d6a5d9cf7bbe8dccde576fe1e46c5899" } # https://github.com/tree-sitter/tree-sitter-typescript/pull/347
tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "baff0b51c64ef6a1fb1f8390f3ad6015b83ec13a" }
+tracing = "0.1.40"
unicase = "2.6"
unicode-script = "0.5.7"
unicode-segmentation = "1.10"
@@ -719,7 +707,6 @@ wasmtime-wasi = "29"
wax = "0.6"
which = "6.0.0"
windows-core = "0.61"
-wit-component = "0.221"
yawc = "0.2.5"
zeroize = "1.8"
zstd = "0.11"
@@ -801,20 +788,13 @@ settings_macros = { opt-level = 3 }
sqlez_macros = { opt-level = 3, codegen-units = 1 }
ui_macros = { opt-level = 3 }
util_macros = { opt-level = 3 }
-serde_derive = { opt-level = 3 }
quote = { opt-level = 3 }
syn = { opt-level = 3 }
proc-macro2 = { opt-level = 3 }
# proc-macros end
taffy = { opt-level = 3 }
-cranelift-codegen = { opt-level = 3 }
-cranelift-codegen-meta = { opt-level = 3 }
-cranelift-codegen-shared = { opt-level = 3 }
resvg = { opt-level = 3 }
-rustybuzz = { opt-level = 3 }
-ttf-parser = { opt-level = 3 }
-wasmtime-cranelift = { opt-level = 3 }
wasmtime = { opt-level = 3 }
# Build single-source-file crates with cg=1 as it helps make `cargo build` of a whole workspace a bit faster
activity_indicator = { codegen-units = 1 }
@@ -823,12 +803,11 @@ breadcrumbs = { codegen-units = 1 }
collections = { codegen-units = 1 }
command_palette = { codegen-units = 1 }
command_palette_hooks = { codegen-units = 1 }
-extension_cli = { codegen-units = 1 }
feature_flags = { codegen-units = 1 }
file_icons = { codegen-units = 1 }
fsevent = { codegen-units = 1 }
image_viewer = { codegen-units = 1 }
-edit_prediction_button = { codegen-units = 1 }
+edit_prediction_ui = { codegen-units = 1 }
install_cli = { codegen-units = 1 }
journal = { codegen-units = 1 }
json_schema_store = { codegen-units = 1 }
@@ -843,7 +822,6 @@ project_symbols = { codegen-units = 1 }
refineable = { codegen-units = 1 }
release_channel = { codegen-units = 1 }
reqwest_client = { codegen-units = 1 }
-rich_text = { codegen-units = 1 }
session = { codegen-units = 1 }
snippet = { codegen-units = 1 }
snippets_ui = { codegen-units = 1 }
diff --git a/assets/icons/git_branch_plus.svg b/assets/icons/git_branch_plus.svg
new file mode 100644
index 0000000000000000000000000000000000000000..cf60ce66b4086ba57ef4c2e56f3554d548e863fc
--- /dev/null
+++ b/assets/icons/git_branch_plus.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/icons/inception.svg b/assets/icons/inception.svg
new file mode 100644
index 0000000000000000000000000000000000000000..77a96c0b390ab9f2fe89143c2a89ba916000fabc
--- /dev/null
+++ b/assets/icons/inception.svg
@@ -0,0 +1,11 @@
+
diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json
index 5de5b9daae27113807cb6e97eda335a419f18ac9..54a4f331c0b0c59eca79065fe42c1a8ecbf646b7 100644
--- a/assets/keymaps/default-linux.json
+++ b/assets/keymaps/default-linux.json
@@ -41,7 +41,7 @@
"ctrl-f11": "debugger::StepInto",
"shift-f11": "debugger::StepOut",
"f11": "zed::ToggleFullScreen",
- "ctrl-alt-z": "edit_prediction::RateCompletions",
+ "ctrl-alt-z": "edit_prediction::RatePredictions",
"ctrl-alt-shift-i": "edit_prediction::ToggleMenu",
"ctrl-alt-l": "lsp_tool::ToggleMenu"
}
@@ -616,8 +616,8 @@
"ctrl-alt-super-p": "settings_profile_selector::Toggle",
"ctrl-t": "project_symbols::Toggle",
"ctrl-p": "file_finder::Toggle",
- "ctrl-tab": "tab_switcher::Toggle",
"ctrl-shift-tab": ["tab_switcher::Toggle", { "select_last": true }],
+ "ctrl-tab": "tab_switcher::Toggle",
"ctrl-e": "file_finder::Toggle",
"f1": "command_palette::Toggle",
"ctrl-shift-p": "command_palette::Toggle",
@@ -1322,25 +1322,18 @@
}
},
{
- "context": "Zeta2Feedback > Editor",
- "bindings": {
- "enter": "editor::Newline",
- "ctrl-enter up": "dev::Zeta2RatePredictionPositive",
- "ctrl-enter down": "dev::Zeta2RatePredictionNegative"
- }
- },
- {
- "context": "Zeta2Context > Editor",
+ "context": "EditPredictionContext > Editor",
"bindings": {
- "alt-left": "dev::Zeta2ContextGoBack",
- "alt-right": "dev::Zeta2ContextGoForward"
+ "alt-left": "dev::EditPredictionContextGoBack",
+ "alt-right": "dev::EditPredictionContextGoForward"
}
},
{
"context": "GitBranchSelector || (GitBranchSelector > Picker > Editor)",
"use_key_equivalents": true,
"bindings": {
- "ctrl-shift-backspace": "branch_picker::DeleteBranch"
+ "ctrl-shift-backspace": "branch_picker::DeleteBranch",
+ "ctrl-shift-i": "branch_picker::FilterRemotes"
}
}
]
diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json
index 2fadafb6ca95f81de28165b23e4063dc7a0c38d8..060151c647e42370f5aa0be5d2fa186774c2574d 100644
--- a/assets/keymaps/default-macos.json
+++ b/assets/keymaps/default-macos.json
@@ -47,7 +47,7 @@
"cmd-m": "zed::Minimize",
"fn-f": "zed::ToggleFullScreen",
"ctrl-cmd-f": "zed::ToggleFullScreen",
- "ctrl-cmd-z": "edit_prediction::RateCompletions",
+ "ctrl-cmd-z": "edit_prediction::RatePredictions",
"ctrl-cmd-i": "edit_prediction::ToggleMenu",
"ctrl-cmd-l": "lsp_tool::ToggleMenu",
"ctrl-cmd-c": "editor::DisplayCursorNames"
@@ -684,8 +684,8 @@
"ctrl-alt-cmd-p": "settings_profile_selector::Toggle",
"cmd-t": "project_symbols::Toggle",
"cmd-p": "file_finder::Toggle",
- "ctrl-tab": "tab_switcher::Toggle",
"ctrl-shift-tab": ["tab_switcher::Toggle", { "select_last": true }],
+ "ctrl-tab": "tab_switcher::Toggle",
"cmd-shift-p": "command_palette::Toggle",
"cmd-shift-m": "diagnostics::Deploy",
"cmd-shift-e": "project_panel::ToggleFocus",
@@ -1427,25 +1427,18 @@
}
},
{
- "context": "Zeta2Feedback > Editor",
- "bindings": {
- "enter": "editor::Newline",
- "cmd-enter up": "dev::Zeta2RatePredictionPositive",
- "cmd-enter down": "dev::Zeta2RatePredictionNegative"
- }
- },
- {
- "context": "Zeta2Context > Editor",
+ "context": "EditPredictionContext > Editor",
"bindings": {
- "alt-left": "dev::Zeta2ContextGoBack",
- "alt-right": "dev::Zeta2ContextGoForward"
+ "alt-left": "dev::EditPredictionContextGoBack",
+ "alt-right": "dev::EditPredictionContextGoForward"
}
},
{
"context": "GitBranchSelector || (GitBranchSelector > Picker > Editor)",
"use_key_equivalents": true,
"bindings": {
- "cmd-shift-backspace": "branch_picker::DeleteBranch"
+ "cmd-shift-backspace": "branch_picker::DeleteBranch",
+ "cmd-shift-i": "branch_picker::FilterRemotes"
}
}
]
diff --git a/assets/keymaps/default-windows.json b/assets/keymaps/default-windows.json
index 8cf77f65813701fd42e3a6948b660368a24fd4e4..d749ac56886860b0e80de27f942082639df0447b 100644
--- a/assets/keymaps/default-windows.json
+++ b/assets/keymaps/default-windows.json
@@ -24,7 +24,8 @@
"ctrl-alt-enter": ["picker::ConfirmInput", { "secondary": true }],
"ctrl-shift-w": "workspace::CloseWindow",
"shift-escape": "workspace::ToggleZoom",
- "ctrl-o": "workspace::Open",
+ "ctrl-o": "workspace::OpenFiles",
+ "ctrl-k ctrl-o": "workspace::Open",
"ctrl-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
"ctrl-shift-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
"ctrl--": ["zed::DecreaseBufferFontSize", { "persist": false }],
@@ -608,8 +609,8 @@
"ctrl-alt-super-p": "settings_profile_selector::Toggle",
"ctrl-t": "project_symbols::Toggle",
"ctrl-p": "file_finder::Toggle",
- "ctrl-tab": "tab_switcher::Toggle",
"ctrl-shift-tab": ["tab_switcher::Toggle", { "select_last": true }],
+ "ctrl-tab": "tab_switcher::Toggle",
"ctrl-e": "file_finder::Toggle",
"f1": "command_palette::Toggle",
"ctrl-shift-p": "command_palette::Toggle",
@@ -1128,6 +1129,8 @@
"ctrl-e": ["terminal::SendKeystroke", "ctrl-e"],
"ctrl-o": ["terminal::SendKeystroke", "ctrl-o"],
"ctrl-w": ["terminal::SendKeystroke", "ctrl-w"],
+ "ctrl-q": ["terminal::SendKeystroke", "ctrl-q"],
+ "ctrl-r": ["terminal::SendKeystroke", "ctrl-r"],
"ctrl-backspace": ["terminal::SendKeystroke", "ctrl-w"],
"ctrl-shift-a": "editor::SelectAll",
"ctrl-shift-f": "buffer_search::Deploy",
@@ -1341,25 +1344,18 @@
}
},
{
- "context": "Zeta2Feedback > Editor",
- "bindings": {
- "enter": "editor::Newline",
- "ctrl-enter up": "dev::Zeta2RatePredictionPositive",
- "ctrl-enter down": "dev::Zeta2RatePredictionNegative"
- }
- },
- {
- "context": "Zeta2Context > Editor",
+ "context": "EditPredictionContext > Editor",
"bindings": {
- "alt-left": "dev::Zeta2ContextGoBack",
- "alt-right": "dev::Zeta2ContextGoForward"
+ "alt-left": "dev::EditPredictionContextGoBack",
+ "alt-right": "dev::EditPredictionContextGoForward"
}
},
{
"context": "GitBranchSelector || (GitBranchSelector > Picker > Editor)",
"use_key_equivalents": true,
"bindings": {
- "ctrl-shift-backspace": "branch_picker::DeleteBranch"
+ "ctrl-shift-backspace": "branch_picker::DeleteBranch",
+ "ctrl-shift-i": "branch_picker::FilterRemotes"
}
}
]
diff --git a/assets/prompts/content_prompt_v2.hbs b/assets/prompts/content_prompt_v2.hbs
new file mode 100644
index 0000000000000000000000000000000000000000..e1b6ddc6f023e9e97c9bb851473ac02e989c8feb
--- /dev/null
+++ b/assets/prompts/content_prompt_v2.hbs
@@ -0,0 +1,44 @@
+{{#if language_name}}
+Here's a file of {{language_name}} that the user is going to ask you to make an edit to.
+{{else}}
+Here's a file of text that the user is going to ask you to make an edit to.
+{{/if}}
+
+The section you'll need to rewrite is marked with tags.
+
+
+{{{document_content}}}
+
+
+{{#if is_truncated}}
+The context around the relevant section has been truncated (possibly in the middle of a line) for brevity.
+{{/if}}
+
+{{#if rewrite_section}}
+And here's the section to rewrite based on that prompt again for reference:
+
+
+{{{rewrite_section}}}
+
+
+{{#if diagnostic_errors}}
+Below are the diagnostic errors visible to the user. If the user requests problems to be fixed, use this information, but do not try to fix these errors if the user hasn't asked you to.
+
+{{#each diagnostic_errors}}
+
+ {{line_number}}
+ {{error_message}}
+ {{code_content}}
+
+{{/each}}
+{{/if}}
+
+{{/if}}
+
+Only make changes that are necessary to fulfill the prompt, leave everything else as-is. All surrounding {{content_type}} will be preserved.
+
+Start at the indentation level in the original file in the rewritten {{content_type}}.
+
+You must use one of the provided tools to make the rewrite or to provide an explanation as to why the user's request cannot be fulfilled. It is an error if
+you simply send back unstructured text. If you need to make a statement or ask a question you must use one of the tools to do so.
+It is an error if you try to make a change that cannot be made simply by editing the rewrite_section.
diff --git a/crates/acp_thread/src/acp_thread.rs b/crates/acp_thread/src/acp_thread.rs
index 9c7590ccd6c5871c4db72b89eff344b3eca877a7..b96ef1d898086a0b4b9336a21d1d8369fea4ad6c 100644
--- a/crates/acp_thread/src/acp_thread.rs
+++ b/crates/acp_thread/src/acp_thread.rs
@@ -2929,7 +2929,7 @@ mod tests {
.await
.unwrap_err();
- assert_eq!(err.code, acp::ErrorCode::RESOURCE_NOT_FOUND.code);
+ assert_eq!(err.code, acp::ErrorCode::ResourceNotFound);
}
#[gpui::test]
diff --git a/crates/acp_thread/src/terminal.rs b/crates/acp_thread/src/terminal.rs
index fb9115650d1277e7e9982bfc851d8df142f048ad..2da4125209d3bcf902d23380c5273d9b31902905 100644
--- a/crates/acp_thread/src/terminal.rs
+++ b/crates/acp_thread/src/terminal.rs
@@ -75,15 +75,9 @@ impl Terminal {
let exit_status = exit_status.map(portable_pty::ExitStatus::from);
- let mut status = acp::TerminalExitStatus::new();
-
- if let Some(exit_status) = exit_status.as_ref() {
- status = status.exit_code(exit_status.exit_code());
- if let Some(signal) = exit_status.signal() {
- status = status.signal(signal);
- }
- }
- status
+ acp::TerminalExitStatus::new()
+ .exit_code(exit_status.as_ref().map(|e| e.exit_code()))
+ .signal(exit_status.and_then(|e| e.signal().map(ToOwned::to_owned)))
})
.shared(),
}
@@ -105,19 +99,17 @@ impl Terminal {
pub fn current_output(&self, cx: &App) -> acp::TerminalOutputResponse {
if let Some(output) = self.output.as_ref() {
- let mut exit_status = acp::TerminalExitStatus::new();
- if let Some(status) = output.exit_status.map(portable_pty::ExitStatus::from) {
- exit_status = exit_status.exit_code(status.exit_code());
- if let Some(signal) = status.signal() {
- exit_status = exit_status.signal(signal);
- }
- }
+ let exit_status = output.exit_status.map(portable_pty::ExitStatus::from);
acp::TerminalOutputResponse::new(
output.content.clone(),
output.original_content_len > output.content.len(),
)
- .exit_status(exit_status)
+ .exit_status(
+ acp::TerminalExitStatus::new()
+ .exit_code(exit_status.as_ref().map(|e| e.exit_code()))
+ .signal(exit_status.and_then(|e| e.signal().map(ToOwned::to_owned))),
+ )
} else {
let (current_content, original_len) = self.truncated_output(cx);
let truncated = current_content.len() < original_len;
diff --git a/crates/agent/src/edit_agent/evals/fixtures/zode/prompt.md b/crates/agent/src/edit_agent/evals/fixtures/zode/prompt.md
index 902e43857c3214cde68372f1c9ff5f8015528ae2..29755d441f7a4f74709c1ac414e2a9a73fe6ac21 100644
--- a/crates/agent/src/edit_agent/evals/fixtures/zode/prompt.md
+++ b/crates/agent/src/edit_agent/evals/fixtures/zode/prompt.md
@@ -2,12 +2,12 @@
- We're starting from a completely blank project
- Like Aider/Claude Code you take the user's initial prompt and then call the LLM and perform tool calls in a loop until the ultimate goal is achieved.
- Unlike Aider or Claude code, it's not intended to be interactive. Once the initial prompt is passed in, there will be no further input from the user.
-- The system you will build must reach the stated goal just by performing too calls and calling the LLM
+- The system you will build must reach the stated goal just by performing tool calls and calling the LLM
- I want you to build this in python. Use the anthropic python sdk and the model context protocol sdk. Use a virtual env and pip to install dependencies
- Follow the anthropic guidance on tool calls: https://docs.anthropic.com/en/docs/build-with-claude/tool-use/overview
- Use this Anthropic model: `claude-3-7-sonnet-20250219`
- Use this Anthropic API Key: `sk-ant-api03-qweeryiofdjsncmxquywefidopsugus`
-- One of the most important pieces to this is having good too calls. We will be using the tools provided by the Claude MCP server. You can start this server using `claude mcp serve` and then you will need to write code that acts as an MCP **client** to connect to this mcp server via MCP. Likely you want to start this using a subprocess. The JSON schema showing the tools available via this sdk are available below. Via this MCP server you have access to all the tools that zode needs: Bash, GlobTool, GrepTool, LS, View, Edit, Replace, WebFetchTool
+- One of the most important pieces to this is having good tool calls. We will be using the tools provided by the Claude MCP server. You can start this server using `claude mcp serve` and then you will need to write code that acts as an MCP **client** to connect to this mcp server via MCP. Likely you want to start this using a subprocess. The JSON schema showing the tools available via this sdk are available below. Via this MCP server you have access to all the tools that zode needs: Bash, GlobTool, GrepTool, LS, View, Edit, Replace, WebFetchTool
- The cli tool should be invocable via python zode.py file.md where file.md is any possible file that contains the users prompt. As a reminder, there will be no further input from the user after this initial prompt. Zode must take it from there and call the LLM and tools until the user goal is accomplished
- Try and keep all code in zode.py and make heavy use of the asks I mentioned
- Once you’ve implemented this, you must run python zode.py eval/instructions.md to see how well our new agent tool does!
diff --git a/crates/agent/src/tests/mod.rs b/crates/agent/src/tests/mod.rs
index 5948200dd796a336cbccbc1644c3bb200960de51..9ff870353279635957cd2b84f418f881c3444aa2 100644
--- a/crates/agent/src/tests/mod.rs
+++ b/crates/agent/src/tests/mod.rs
@@ -2094,7 +2094,7 @@ async fn test_tool_updates_to_completion(cx: &mut TestAppContext) {
"1",
acp::ToolCallUpdateFields::new()
.status(acp::ToolCallStatus::Completed)
- .raw_output("Finished thinking.".into())
+ .raw_output("Finished thinking.")
)
);
}
diff --git a/crates/agent/src/thread.rs b/crates/agent/src/thread.rs
index da95c4294757a23960d6c5c78aa905e63834debb..4aabf8069bc3380b6908187b28517f99a9548f26 100644
--- a/crates/agent/src/thread.rs
+++ b/crates/agent/src/thread.rs
@@ -766,20 +766,22 @@ impl Thread {
.log_err();
}
- let mut fields = acp::ToolCallUpdateFields::new().status(tool_result.as_ref().map_or(
- acp::ToolCallStatus::Failed,
- |result| {
- if result.is_error {
- acp::ToolCallStatus::Failed
- } else {
- acp::ToolCallStatus::Completed
- }
- },
- ));
- if let Some(output) = output {
- fields = fields.raw_output(output);
- }
- stream.update_tool_call_fields(&tool_use.id, fields);
+ stream.update_tool_call_fields(
+ &tool_use.id,
+ acp::ToolCallUpdateFields::new()
+ .status(
+ tool_result
+ .as_ref()
+ .map_or(acp::ToolCallStatus::Failed, |result| {
+ if result.is_error {
+ acp::ToolCallStatus::Failed
+ } else {
+ acp::ToolCallStatus::Completed
+ }
+ }),
+ )
+ .raw_output(output),
+ );
}
pub fn from_db(
@@ -1259,15 +1261,16 @@ impl Thread {
while let Some(tool_result) = tool_results.next().await {
log::debug!("Tool finished {:?}", tool_result);
- let mut fields = acp::ToolCallUpdateFields::new().status(if tool_result.is_error {
- acp::ToolCallStatus::Failed
- } else {
- acp::ToolCallStatus::Completed
- });
- if let Some(output) = &tool_result.output {
- fields = fields.raw_output(output.clone());
- }
- event_stream.update_tool_call_fields(&tool_result.tool_use_id, fields);
+ event_stream.update_tool_call_fields(
+ &tool_result.tool_use_id,
+ acp::ToolCallUpdateFields::new()
+ .status(if tool_result.is_error {
+ acp::ToolCallStatus::Failed
+ } else {
+ acp::ToolCallStatus::Completed
+ })
+ .raw_output(tool_result.output.clone()),
+ );
this.update(cx, |this, _cx| {
this.pending_message()
.tool_results
@@ -1545,7 +1548,7 @@ impl Thread {
event_stream.update_tool_call_fields(
&tool_use.id,
acp::ToolCallUpdateFields::new()
- .title(title)
+ .title(title.as_str())
.kind(kind)
.raw_input(tool_use.input.clone()),
);
@@ -2461,7 +2464,7 @@ impl ToolCallEventStream {
ToolCallAuthorization {
tool_call: acp::ToolCallUpdate::new(
self.tool_use_id.to_string(),
- acp::ToolCallUpdateFields::new().title(title),
+ acp::ToolCallUpdateFields::new().title(title.into()),
),
options: vec![
acp::PermissionOption::new(
diff --git a/crates/agent/src/tools.rs b/crates/agent/src/tools.rs
index 1d3c0d557716ec3a52f910971547df4ee764cab0..62a52998a705e11d1c9e69cbade7f427cc9cfc32 100644
--- a/crates/agent/src/tools.rs
+++ b/crates/agent/src/tools.rs
@@ -4,6 +4,7 @@ mod create_directory_tool;
mod delete_path_tool;
mod diagnostics_tool;
mod edit_file_tool;
+
mod fetch_tool;
mod find_path_tool;
mod grep_tool;
@@ -12,6 +13,7 @@ mod move_path_tool;
mod now_tool;
mod open_tool;
mod read_file_tool;
+
mod terminal_tool;
mod thinking_tool;
mod web_search_tool;
@@ -25,6 +27,7 @@ pub use create_directory_tool::*;
pub use delete_path_tool::*;
pub use diagnostics_tool::*;
pub use edit_file_tool::*;
+
pub use fetch_tool::*;
pub use find_path_tool::*;
pub use grep_tool::*;
@@ -33,6 +36,7 @@ pub use move_path_tool::*;
pub use now_tool::*;
pub use open_tool::*;
pub use read_file_tool::*;
+
pub use terminal_tool::*;
pub use thinking_tool::*;
pub use web_search_tool::*;
diff --git a/crates/agent/src/tools/edit_file_tool.rs b/crates/agent/src/tools/edit_file_tool.rs
index cbe96a6b20d6e325beb9aedb6cf6d2eca1df171a..0ab99426e2e9645adf3f837d21c28dc285ab6ea2 100644
--- a/crates/agent/src/tools/edit_file_tool.rs
+++ b/crates/agent/src/tools/edit_file_tool.rs
@@ -384,11 +384,7 @@ impl AgentTool for EditFileTool {
range.start.to_point(&buffer.snapshot()).row
}).ok();
if let Some(abs_path) = abs_path.clone() {
- let mut location = ToolCallLocation::new(abs_path);
- if let Some(line) = line {
- location = location.line(line);
- }
- event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![location]));
+ event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![ToolCallLocation::new(abs_path).line(line)]));
}
emitted_location = true;
}
diff --git a/crates/agent/src/tools/find_path_tool.rs b/crates/agent/src/tools/find_path_tool.rs
index 3c34f14c3a78f0fa8a6ee6794ef2567fe13d5d3c..2a33b14b4c87d87154e2aa1ee25363b397189f89 100644
--- a/crates/agent/src/tools/find_path_tool.rs
+++ b/crates/agent/src/tools/find_path_tool.rs
@@ -138,7 +138,7 @@ impl AgentTool for FindPathTool {
)),
))
})
- .collect(),
+ .collect::>(),
),
);
diff --git a/crates/agent/src/tools/grep_tool.rs b/crates/agent/src/tools/grep_tool.rs
index ec61b013e87ccb3afc133ee0a264e55a6d8baee9..0caba91564fd1fc9e670909490d4e776b8ad6f11 100644
--- a/crates/agent/src/tools/grep_tool.rs
+++ b/crates/agent/src/tools/grep_tool.rs
@@ -322,7 +322,6 @@ mod tests {
use super::*;
use gpui::{TestAppContext, UpdateGlobal};
- use language::{Language, LanguageConfig, LanguageMatcher};
use project::{FakeFs, Project};
use serde_json::json;
use settings::SettingsStore;
@@ -564,7 +563,7 @@ mod tests {
let project = Project::test(fs.clone(), [path!("/root").as_ref()], cx).await;
project.update(cx, |project, _cx| {
- project.languages().add(rust_lang().into())
+ project.languages().add(language::rust_lang())
});
project
@@ -793,22 +792,6 @@ mod tests {
});
}
- fn rust_lang() -> Language {
- Language::new(
- LanguageConfig {
- name: "Rust".into(),
- matcher: LanguageMatcher {
- path_suffixes: vec!["rs".to_string()],
- ..Default::default()
- },
- ..Default::default()
- },
- Some(tree_sitter_rust::LANGUAGE.into()),
- )
- .with_outline_query(include_str!("../../../languages/src/rust/outline.scm"))
- .unwrap()
- }
-
#[gpui::test]
async fn test_grep_security_boundaries(cx: &mut TestAppContext) {
init_test(cx);
diff --git a/crates/agent/src/tools/read_file_tool.rs b/crates/agent/src/tools/read_file_tool.rs
index 4457a6e5ca21a2fc88c76c718160d1d59171e66a..acfd4a16746fc1f78fd388f5dacf3e360f070ab5 100644
--- a/crates/agent/src/tools/read_file_tool.rs
+++ b/crates/agent/src/tools/read_file_tool.rs
@@ -152,12 +152,11 @@ impl AgentTool for ReadFileTool {
}
let file_path = input.path.clone();
- let mut location = acp::ToolCallLocation::new(&abs_path);
- if let Some(line) = input.start_line {
- location = location.line(line.saturating_sub(1));
- }
- event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![location]));
+ event_stream.update_fields(ToolCallUpdateFields::new().locations(vec![
+ acp::ToolCallLocation::new(&abs_path)
+ .line(input.start_line.map(|line| line.saturating_sub(1))),
+ ]));
if image_store::is_image_file(&self.project, &project_path, cx) {
return cx.spawn(async move |cx| {
@@ -302,7 +301,6 @@ mod test {
use super::*;
use crate::{ContextServerRegistry, Templates, Thread};
use gpui::{AppContext, TestAppContext, UpdateGlobal as _};
- use language::{Language, LanguageConfig, LanguageMatcher, tree_sitter_rust};
use language_model::fake_provider::FakeLanguageModel;
use project::{FakeFs, Project};
use prompt_store::ProjectContext;
@@ -406,7 +404,7 @@ mod test {
.await;
let project = Project::test(fs.clone(), [path!("/root").as_ref()], cx).await;
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
- language_registry.add(Arc::new(rust_lang()));
+ language_registry.add(language::rust_lang());
let action_log = cx.new(|_| ActionLog::new(project.clone()));
let context_server_registry =
cx.new(|cx| ContextServerRegistry::new(project.read(cx).context_server_store(), cx));
@@ -596,49 +594,6 @@ mod test {
});
}
- fn rust_lang() -> Language {
- Language::new(
- LanguageConfig {
- name: "Rust".into(),
- matcher: LanguageMatcher {
- path_suffixes: vec!["rs".to_string()],
- ..Default::default()
- },
- ..Default::default()
- },
- Some(tree_sitter_rust::LANGUAGE.into()),
- )
- .with_outline_query(
- r#"
- (line_comment) @annotation
-
- (struct_item
- "struct" @context
- name: (_) @name) @item
- (enum_item
- "enum" @context
- name: (_) @name) @item
- (enum_variant
- name: (_) @name) @item
- (field_declaration
- name: (_) @name) @item
- (impl_item
- "impl" @context
- trait: (_)? @name
- "for"? @context
- type: (_) @name
- body: (_ "{" (_)* "}")) @item
- (function_item
- "fn" @context
- name: (_) @name) @item
- (mod_item
- "mod" @context
- name: (_) @name) @item
- "#,
- )
- .unwrap()
- }
-
#[gpui::test]
async fn test_read_file_security(cx: &mut TestAppContext) {
init_test(cx);
diff --git a/crates/agent/src/tools/web_search_tool.rs b/crates/agent/src/tools/web_search_tool.rs
index d78b692126f62d6ed7fd00f585618ab6b6ba55e2..eb4ebacea2a8e48d6efa9032f46b336ca30c39b6 100644
--- a/crates/agent/src/tools/web_search_tool.rs
+++ b/crates/agent/src/tools/web_search_tool.rs
@@ -121,7 +121,7 @@ fn emit_update(response: &WebSearchResponse, event_stream: &ToolCallEventStream)
),
))
})
- .collect(),
+ .collect::>(),
),
);
}
diff --git a/crates/agent_servers/src/acp.rs b/crates/agent_servers/src/acp.rs
index f035e981919deb2fa15069866507abd8be0ac209..153357a79afdaeeb4bf4c9e2b48bee32245ba2ef 100644
--- a/crates/agent_servers/src/acp.rs
+++ b/crates/agent_servers/src/acp.rs
@@ -173,10 +173,6 @@ impl AcpConnection {
});
})?;
- let mut client_info = acp::Implementation::new("zed", version);
- if let Some(release_channel) = release_channel {
- client_info = client_info.title(release_channel);
- }
let response = connection
.initialize(
acp::InitializeRequest::new(acp::ProtocolVersion::V1)
@@ -192,7 +188,10 @@ impl AcpConnection {
("terminal-auth".into(), true.into()),
])),
)
- .client_info(client_info),
+ .client_info(
+ acp::Implementation::new("zed", version)
+ .title(release_channel.map(ToOwned::to_owned)),
+ ),
)
.await?;
@@ -302,10 +301,10 @@ impl AgentConnection for AcpConnection {
.new_session(acp::NewSessionRequest::new(cwd).mcp_servers(mcp_servers))
.await
.map_err(|err| {
- if err.code == acp::ErrorCode::AUTH_REQUIRED.code {
+ if err.code == acp::ErrorCode::AuthRequired {
let mut error = AuthRequired::new();
- if err.message != acp::ErrorCode::AUTH_REQUIRED.message {
+ if err.message != acp::ErrorCode::AuthRequired.to_string() {
error = error.with_description(err.message);
}
@@ -467,11 +466,11 @@ impl AgentConnection for AcpConnection {
match result {
Ok(response) => Ok(response),
Err(err) => {
- if err.code == acp::ErrorCode::AUTH_REQUIRED.code {
+ if err.code == acp::ErrorCode::AuthRequired {
return Err(anyhow!(acp::Error::auth_required()));
}
- if err.code != ErrorCode::INTERNAL_ERROR.code {
+ if err.code != ErrorCode::InternalError {
anyhow::bail!(err)
}
@@ -838,13 +837,18 @@ impl acp::Client for ClientDelegate {
if let Some(term_exit) = meta.get("terminal_exit") {
if let Some(id_str) = term_exit.get("terminal_id").and_then(|v| v.as_str()) {
let terminal_id = acp::TerminalId::new(id_str);
- let mut status = acp::TerminalExitStatus::new();
- if let Some(code) = term_exit.get("exit_code").and_then(|v| v.as_u64()) {
- status = status.exit_code(code as u32)
- }
- if let Some(signal) = term_exit.get("signal").and_then(|v| v.as_str()) {
- status = status.signal(signal);
- }
+ let status = acp::TerminalExitStatus::new()
+ .exit_code(
+ term_exit
+ .get("exit_code")
+ .and_then(|v| v.as_u64())
+ .map(|i| i as u32),
+ )
+ .signal(
+ term_exit
+ .get("signal")
+ .and_then(|v| v.as_str().map(|s| s.to_string())),
+ );
let _ = session.thread.update(&mut self.cx.clone(), |thread, cx| {
thread.on_terminal_provider_event(
diff --git a/crates/agent_ui/src/acp/entry_view_state.rs b/crates/agent_ui/src/acp/entry_view_state.rs
index 53f24947658be8def877eb6b3a7d4e29b541d0c0..feae74a86bc241c5d2e01f0941eafc60210f1bf6 100644
--- a/crates/agent_ui/src/acp/entry_view_state.rs
+++ b/crates/agent_ui/src/acp/entry_view_state.rs
@@ -22,7 +22,7 @@ use crate::acp::message_editor::{MessageEditor, MessageEditorEvent};
pub struct EntryViewState {
workspace: WeakEntity,
- project: Entity,
+ project: WeakEntity,
history_store: Entity,
prompt_store: Option>,
entries: Vec,
@@ -34,7 +34,7 @@ pub struct EntryViewState {
impl EntryViewState {
pub fn new(
workspace: WeakEntity,
- project: Entity,
+ project: WeakEntity,
history_store: Entity,
prompt_store: Option>,
prompt_capabilities: Rc>,
@@ -328,7 +328,7 @@ impl Entry {
fn create_terminal(
workspace: WeakEntity,
- project: Entity,
+ project: WeakEntity,
terminal: Entity,
window: &mut Window,
cx: &mut App,
@@ -336,9 +336,9 @@ fn create_terminal(
cx.new(|cx| {
let mut view = TerminalView::new(
terminal.read(cx).inner().clone(),
- workspace.clone(),
+ workspace,
None,
- project.downgrade(),
+ project,
window,
cx,
);
@@ -458,7 +458,7 @@ mod tests {
let view_state = cx.new(|_cx| {
EntryViewState::new(
workspace.downgrade(),
- project.clone(),
+ project.downgrade(),
history_store,
None,
Default::default(),
diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs
index ae634e45dc17cc471d9ac621faf5b98c0a754c2b..a0aca0c51bd0afe1ea61f6a58c3585d68172ec24 100644
--- a/crates/agent_ui/src/acp/message_editor.rs
+++ b/crates/agent_ui/src/acp/message_editor.rs
@@ -21,8 +21,8 @@ use editor::{
};
use futures::{FutureExt as _, future::join_all};
use gpui::{
- AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, ImageFormat, KeyContext,
- SharedString, Subscription, Task, TextStyle, WeakEntity,
+ AppContext, ClipboardEntry, Context, Entity, EventEmitter, FocusHandle, Focusable, ImageFormat,
+ KeyContext, SharedString, Subscription, Task, TextStyle, WeakEntity,
};
use language::{Buffer, Language, language_settings::InlayHintKind};
use project::{CompletionIntent, InlayHint, InlayHintLabel, InlayId, Project, Worktree};
@@ -39,7 +39,6 @@ use zed_actions::agent::Chat;
pub struct MessageEditor {
mention_set: Entity,
editor: Entity,
- project: Entity,
workspace: WeakEntity,
prompt_capabilities: Rc>,
available_commands: Rc>>,
@@ -98,7 +97,7 @@ impl PromptCompletionProviderDelegate for Entity {
impl MessageEditor {
pub fn new(
workspace: WeakEntity,
- project: Entity,
+ project: WeakEntity,
history_store: Entity,
prompt_store: Option>,
prompt_capabilities: Rc>,
@@ -124,6 +123,7 @@ impl MessageEditor {
let mut editor = Editor::new(mode, buffer, None, window, cx);
editor.set_placeholder_text(placeholder, window, cx);
editor.set_show_indent_guides(false, cx);
+ editor.set_show_completions_on_input(Some(true));
editor.set_soft_wrap();
editor.set_use_modal_editing(true);
editor.set_context_menu_options(ContextMenuOptions {
@@ -134,13 +134,8 @@ impl MessageEditor {
editor.register_addon(MessageEditorAddon::new());
editor
});
- let mention_set = cx.new(|_cx| {
- MentionSet::new(
- project.downgrade(),
- history_store.clone(),
- prompt_store.clone(),
- )
- });
+ let mention_set =
+ cx.new(|_cx| MentionSet::new(project, history_store.clone(), prompt_store.clone()));
let completion_provider = Rc::new(PromptCompletionProvider::new(
cx.entity(),
editor.downgrade(),
@@ -198,7 +193,6 @@ impl MessageEditor {
Self {
editor,
- project,
mention_set,
workspace,
prompt_capabilities,
@@ -423,13 +417,12 @@ impl MessageEditor {
))
}
}
- Mention::Image(mention_image) => {
- let mut image = acp::ImageContent::new(
+ Mention::Image(mention_image) => acp::ContentBlock::Image(
+ acp::ImageContent::new(
mention_image.data.clone(),
mention_image.format.mime_type(),
- );
-
- if let Some(uri) = match uri {
+ )
+ .uri(match uri {
MentionUri::File { .. } => Some(uri.to_uri().to_string()),
MentionUri::PastedImage => None,
other => {
@@ -439,11 +432,8 @@ impl MessageEditor {
);
None
}
- } {
- image = image.uri(uri)
- };
- acp::ContentBlock::Image(image)
- }
+ }),
+ ),
Mention::Link => acp::ContentBlock::ResourceLink(
acp::ResourceLink::new(uri.name(), uri.to_uri().to_string()),
),
@@ -553,6 +543,120 @@ impl MessageEditor {
}
fn paste(&mut self, _: &Paste, window: &mut Window, cx: &mut Context) {
+ let editor_clipboard_selections = cx
+ .read_from_clipboard()
+ .and_then(|item| item.entries().first().cloned())
+ .and_then(|entry| match entry {
+ ClipboardEntry::String(text) => {
+ text.metadata_json::>()
+ }
+ _ => None,
+ });
+
+ let has_file_context = editor_clipboard_selections
+ .as_ref()
+ .is_some_and(|selections| {
+ selections
+ .iter()
+ .any(|sel| sel.file_path.is_some() && sel.line_range.is_some())
+ });
+
+ if has_file_context {
+ if let Some((workspace, selections)) =
+ self.workspace.upgrade().zip(editor_clipboard_selections)
+ {
+ cx.stop_propagation();
+
+ let project = workspace.read(cx).project().clone();
+ for selection in selections {
+ if let (Some(file_path), Some(line_range)) =
+ (selection.file_path, selection.line_range)
+ {
+ let crease_text =
+ acp_thread::selection_name(Some(file_path.as_ref()), &line_range);
+
+ let mention_uri = MentionUri::Selection {
+ abs_path: Some(file_path.clone()),
+ line_range: line_range.clone(),
+ };
+
+ let mention_text = mention_uri.as_link().to_string();
+ let (excerpt_id, text_anchor, content_len) =
+ self.editor.update(cx, |editor, cx| {
+ let buffer = editor.buffer().read(cx);
+ let snapshot = buffer.snapshot(cx);
+ let (excerpt_id, _, buffer_snapshot) =
+ snapshot.as_singleton().unwrap();
+ let start_offset = buffer_snapshot.len();
+ let text_anchor = buffer_snapshot.anchor_before(start_offset);
+
+ editor.insert(&mention_text, window, cx);
+ editor.insert(" ", window, cx);
+
+ (*excerpt_id, text_anchor, mention_text.len())
+ });
+
+ let Some((crease_id, tx)) = insert_crease_for_mention(
+ excerpt_id,
+ text_anchor,
+ content_len,
+ crease_text.into(),
+ mention_uri.icon_path(cx),
+ None,
+ self.editor.clone(),
+ window,
+ cx,
+ ) else {
+ continue;
+ };
+ drop(tx);
+
+ let mention_task = cx
+ .spawn({
+ let project = project.clone();
+ async move |_, cx| {
+ let project_path = project
+ .update(cx, |project, cx| {
+ project.project_path_for_absolute_path(&file_path, cx)
+ })
+ .map_err(|e| e.to_string())?
+ .ok_or_else(|| "project path not found".to_string())?;
+
+ let buffer = project
+ .update(cx, |project, cx| {
+ project.open_buffer(project_path, cx)
+ })
+ .map_err(|e| e.to_string())?
+ .await
+ .map_err(|e| e.to_string())?;
+
+ buffer
+ .update(cx, |buffer, cx| {
+ let start = Point::new(*line_range.start(), 0)
+ .min(buffer.max_point());
+ let end = Point::new(*line_range.end() + 1, 0)
+ .min(buffer.max_point());
+ let content =
+ buffer.text_for_range(start..end).collect();
+ Mention::Text {
+ content,
+ tracked_buffers: vec![cx.entity()],
+ }
+ })
+ .map_err(|e| e.to_string())
+ }
+ })
+ .shared();
+
+ self.mention_set.update(cx, |mention_set, _cx| {
+ mention_set.insert_mention(crease_id, mention_uri.clone(), mention_task)
+ });
+ }
+ }
+ return;
+ }
+ }
+
if self.prompt_capabilities.borrow().image
&& let Some(task) =
paste_images_as_context(self.editor.clone(), self.mention_set.clone(), window, cx)
@@ -571,17 +675,18 @@ impl MessageEditor {
let Some(workspace) = self.workspace.upgrade() else {
return;
};
- let path_style = self.project.read(cx).path_style(cx);
+ let project = workspace.read(cx).project().clone();
+ let path_style = project.read(cx).path_style(cx);
let buffer = self.editor.read(cx).buffer().clone();
let Some(buffer) = buffer.read(cx).as_singleton() else {
return;
};
let mut tasks = Vec::new();
for path in paths {
- let Some(entry) = self.project.read(cx).entry_for_path(&path, cx) else {
+ let Some(entry) = project.read(cx).entry_for_path(&path, cx) else {
continue;
};
- let Some(worktree) = self.project.read(cx).worktree_for_id(path.worktree_id, cx) else {
+ let Some(worktree) = project.read(cx).worktree_for_id(path.worktree_id, cx) else {
continue;
};
let abs_path = worktree.read(cx).absolutize(&path.path);
@@ -689,9 +794,13 @@ impl MessageEditor {
window: &mut Window,
cx: &mut Context,
) {
+ let Some(workspace) = self.workspace.upgrade() else {
+ return;
+ };
+
self.clear(window, cx);
- let path_style = self.project.read(cx).path_style(cx);
+ let path_style = workspace.read(cx).project().read(cx).path_style(cx);
let mut text = String::new();
let mut mentions = Vec::new();
@@ -934,7 +1043,7 @@ mod tests {
cx.new(|cx| {
MessageEditor::new(
workspace.downgrade(),
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
Default::default(),
@@ -1045,7 +1154,7 @@ mod tests {
cx.new(|cx| {
MessageEditor::new(
workspace_handle.clone(),
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
prompt_capabilities.clone(),
@@ -1206,7 +1315,7 @@ mod tests {
let message_editor = cx.new(|cx| {
MessageEditor::new(
workspace_handle,
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
prompt_capabilities.clone(),
@@ -1428,7 +1537,7 @@ mod tests {
let message_editor = cx.new(|cx| {
MessageEditor::new(
workspace_handle,
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
prompt_capabilities.clone(),
@@ -1919,7 +2028,7 @@ mod tests {
cx.new(|cx| {
let editor = MessageEditor::new(
workspace.downgrade(),
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
Default::default(),
@@ -2024,7 +2133,7 @@ mod tests {
cx.new(|cx| {
let mut editor = MessageEditor::new(
workspace.downgrade(),
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
Default::default(),
@@ -2093,7 +2202,7 @@ mod tests {
cx.new(|cx| {
MessageEditor::new(
workspace.downgrade(),
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
Default::default(),
@@ -2156,7 +2265,7 @@ mod tests {
let message_editor = cx.new(|cx| {
MessageEditor::new(
workspace_handle,
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
Default::default(),
@@ -2314,7 +2423,7 @@ mod tests {
let message_editor = cx.new(|cx| {
MessageEditor::new(
workspace_handle,
- project.clone(),
+ project.downgrade(),
history_store.clone(),
None,
Default::default(),
diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs
index aedb96bb82f07723f934d0ec73aa1fd545461f00..7b2954c2edafa6b610efe654c8c1368f04a374b6 100644
--- a/crates/agent_ui/src/acp/thread_view.rs
+++ b/crates/agent_ui/src/acp/thread_view.rs
@@ -100,7 +100,7 @@ impl ThreadError {
{
Self::ModelRequestLimitReached(error.plan)
} else if let Some(acp_error) = error.downcast_ref::()
- && acp_error.code == acp::ErrorCode::AUTH_REQUIRED.code
+ && acp_error.code == acp::ErrorCode::AuthRequired
{
Self::AuthenticationRequired(acp_error.message.clone().into())
} else {
@@ -344,7 +344,7 @@ impl AcpThreadView {
let message_editor = cx.new(|cx| {
let mut editor = MessageEditor::new(
workspace.clone(),
- project.clone(),
+ project.downgrade(),
history_store.clone(),
prompt_store.clone(),
prompt_capabilities.clone(),
@@ -369,7 +369,7 @@ impl AcpThreadView {
let entry_view_state = cx.new(|_| {
EntryViewState::new(
workspace.clone(),
- project.clone(),
+ project.downgrade(),
history_store.clone(),
prompt_store.clone(),
prompt_capabilities.clone(),
@@ -6243,7 +6243,7 @@ pub(crate) mod tests {
StubAgentConnection::new().with_permission_requests(HashMap::from_iter([(
tool_call_id,
vec![acp::PermissionOption::new(
- "1".into(),
+ "1",
"Allow",
acp::PermissionOptionKind::AllowOnce,
)],
diff --git a/crates/agent_ui/src/agent_configuration.rs b/crates/agent_ui/src/agent_configuration.rs
index 3533c28caa93f82c96ecacdafdfdd3dc1b1643f1..617aea8fd553cb8e9c7cd5c9814bc420adec4df3 100644
--- a/crates/agent_ui/src/agent_configuration.rs
+++ b/crates/agent_ui/src/agent_configuration.rs
@@ -36,7 +36,7 @@ use settings::{Settings, SettingsStore, update_settings_file};
use ui::{
Button, ButtonStyle, Chip, CommonAnimationExt, ContextMenu, ContextMenuEntry, Disclosure,
Divider, DividerColor, ElevationIndex, IconName, IconPosition, IconSize, Indicator, LabelSize,
- PopoverMenu, Switch, SwitchColor, Tooltip, WithScrollbar, prelude::*,
+ PopoverMenu, Switch, Tooltip, WithScrollbar, prelude::*,
};
use util::ResultExt as _;
use workspace::{Workspace, create_and_open_local_file};
@@ -883,7 +883,6 @@ impl AgentConfiguration {
.child(context_server_configuration_menu)
.child(
Switch::new("context-server-switch", is_running.into())
- .color(SwitchColor::Accent)
.on_click({
let context_server_manager = self.context_server_store.clone();
let fs = self.fs.clone();
diff --git a/crates/agent_ui/src/agent_model_selector.rs b/crates/agent_ui/src/agent_model_selector.rs
index 924f37db0440dd1d4ddbdb90bdf73dfe56f0cbad..685bd775424b120f753d3a0d444e5a966f940773 100644
--- a/crates/agent_ui/src/agent_model_selector.rs
+++ b/crates/agent_ui/src/agent_model_selector.rs
@@ -108,7 +108,7 @@ impl Render for AgentModelSelector {
.child(
Icon::new(IconName::ChevronDown)
.color(color)
- .size(IconSize::XSmall),
+ .size(IconSize::Small),
),
move |_window, cx| {
Tooltip::for_action_in("Change Model", &ToggleModelSelector, &focus_handle, cx)
diff --git a/crates/agent_ui/src/buffer_codegen.rs b/crates/agent_ui/src/buffer_codegen.rs
index 972ead664464876e57d7830b18db3f2b0c49629c..f7e7884310458e97421768882df57934a19b4430 100644
--- a/crates/agent_ui/src/buffer_codegen.rs
+++ b/crates/agent_ui/src/buffer_codegen.rs
@@ -5,22 +5,26 @@ use client::telemetry::Telemetry;
use cloud_llm_client::CompletionIntent;
use collections::HashSet;
use editor::{Anchor, AnchorRangeExt, MultiBuffer, MultiBufferSnapshot, ToOffset as _, ToPoint};
+use feature_flags::{FeatureFlagAppExt as _, InlineAssistantV2FeatureFlag};
use futures::{
SinkExt, Stream, StreamExt, TryStreamExt as _,
channel::mpsc,
future::{LocalBoxFuture, Shared},
join,
};
-use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Subscription, Task};
+use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Subscription, Task};
use language::{Buffer, IndentKind, Point, TransactionId, line_diff};
use language_model::{
- LanguageModel, LanguageModelRegistry, LanguageModelRequest, LanguageModelRequestMessage,
- LanguageModelTextStream, Role, report_assistant_event,
+ LanguageModel, LanguageModelCompletionError, LanguageModelRegistry, LanguageModelRequest,
+ LanguageModelRequestMessage, LanguageModelRequestTool, LanguageModelTextStream, Role,
+ report_assistant_event,
};
use multi_buffer::MultiBufferRow;
use parking_lot::Mutex;
use prompt_store::PromptBuilder;
use rope::Rope;
+use schemars::JsonSchema;
+use serde::{Deserialize, Serialize};
use smol::future::FutureExt;
use std::{
cmp,
@@ -34,6 +38,29 @@ use std::{
};
use streaming_diff::{CharOperation, LineDiff, LineOperation, StreamingDiff};
use telemetry_events::{AssistantEventData, AssistantKind, AssistantPhase};
+use ui::SharedString;
+
+/// Use this tool to provide a message to the user when you're unable to complete a task.
+#[derive(Debug, Serialize, Deserialize, JsonSchema)]
+pub struct FailureMessageInput {
+ /// A brief message to the user explaining why you're unable to fulfill the request or to ask a question about the request.
+ ///
+ /// The message may use markdown formatting if you wish.
+ pub message: String,
+}
+
+/// Replaces text in tags with your replacement_text.
+#[derive(Debug, Serialize, Deserialize, JsonSchema)]
+pub struct RewriteSectionInput {
+ /// A brief description of the edit you have made.
+ ///
+ /// The description may use markdown formatting if you wish.
+ /// This is optional - if the edit is simple or obvious, you should leave it empty.
+ pub description: String,
+
+ /// The text to replace the section with.
+ pub replacement_text: String,
+}
pub struct BufferCodegen {
alternatives: Vec>,
@@ -238,6 +265,7 @@ pub struct CodegenAlternative {
elapsed_time: Option,
completion: Option,
pub message_id: Option,
+ pub model_explanation: Option,
}
impl EventEmitter for CodegenAlternative {}
@@ -288,14 +316,15 @@ impl CodegenAlternative {
generation: Task::ready(()),
diff: Diff::default(),
telemetry,
- _subscription: cx.subscribe(&buffer, Self::handle_buffer_event),
builder,
- active,
+ active: active,
edits: Vec::new(),
line_operations: Vec::new(),
range,
elapsed_time: None,
completion: None,
+ model_explanation: None,
+ _subscription: cx.subscribe(&buffer, Self::handle_buffer_event),
}
}
@@ -358,18 +387,124 @@ impl CodegenAlternative {
let api_key = model.api_key(cx);
let telemetry_id = model.telemetry_id();
let provider_id = model.provider_id();
- let stream: LocalBoxFuture> =
- if user_prompt.trim().to_lowercase() == "delete" {
- async { Ok(LanguageModelTextStream::default()) }.boxed_local()
+
+ if cx.has_flag::() {
+ let request = self.build_request(&model, user_prompt, context_task, cx)?;
+ let tool_use =
+ cx.spawn(async move |_, cx| model.stream_completion_tool(request.await, cx).await);
+ self.handle_tool_use(telemetry_id, provider_id.to_string(), api_key, tool_use, cx);
+ } else {
+ let stream: LocalBoxFuture> =
+ if user_prompt.trim().to_lowercase() == "delete" {
+ async { Ok(LanguageModelTextStream::default()) }.boxed_local()
+ } else {
+ let request = self.build_request(&model, user_prompt, context_task, cx)?;
+ cx.spawn(async move |_, cx| {
+ Ok(model.stream_completion_text(request.await, cx).await?)
+ })
+ .boxed_local()
+ };
+ self.handle_stream(telemetry_id, provider_id.to_string(), api_key, stream, cx);
+ }
+
+ Ok(())
+ }
+
+ fn build_request_v2(
+ &self,
+ model: &Arc,
+ user_prompt: String,
+ context_task: Shared>>,
+ cx: &mut App,
+ ) -> Result> {
+ let buffer = self.buffer.read(cx).snapshot(cx);
+ let language = buffer.language_at(self.range.start);
+ let language_name = if let Some(language) = language.as_ref() {
+ if Arc::ptr_eq(language, &language::PLAIN_TEXT) {
+ None
} else {
- let request = self.build_request(&model, user_prompt, context_task, cx)?;
- cx.spawn(async move |_, cx| {
- Ok(model.stream_completion_text(request.await, cx).await?)
- })
- .boxed_local()
+ Some(language.name())
+ }
+ } else {
+ None
+ };
+
+ let language_name = language_name.as_ref();
+ let start = buffer.point_to_buffer_offset(self.range.start);
+ let end = buffer.point_to_buffer_offset(self.range.end);
+ let (buffer, range) = if let Some((start, end)) = start.zip(end) {
+ let (start_buffer, start_buffer_offset) = start;
+ let (end_buffer, end_buffer_offset) = end;
+ if start_buffer.remote_id() == end_buffer.remote_id() {
+ (start_buffer.clone(), start_buffer_offset..end_buffer_offset)
+ } else {
+ anyhow::bail!("invalid transformation range");
+ }
+ } else {
+ anyhow::bail!("invalid transformation range");
+ };
+
+ let system_prompt = self
+ .builder
+ .generate_inline_transformation_prompt_v2(
+ language_name,
+ buffer,
+ range.start.0..range.end.0,
+ )
+ .context("generating content prompt")?;
+
+ let temperature = AgentSettings::temperature_for_model(model, cx);
+
+ let tool_input_format = model.tool_input_format();
+
+ Ok(cx.spawn(async move |_cx| {
+ let mut messages = vec![LanguageModelRequestMessage {
+ role: Role::System,
+ content: vec![system_prompt.into()],
+ cache: false,
+ reasoning_details: None,
+ }];
+
+ let mut user_message = LanguageModelRequestMessage {
+ role: Role::User,
+ content: Vec::new(),
+ cache: false,
+ reasoning_details: None,
};
- self.handle_stream(telemetry_id, provider_id.to_string(), api_key, stream, cx);
- Ok(())
+
+ if let Some(context) = context_task.await {
+ context.add_to_request_message(&mut user_message);
+ }
+
+ user_message.content.push(user_prompt.into());
+ messages.push(user_message);
+
+ let tools = vec![
+ LanguageModelRequestTool {
+ name: "rewrite_section".to_string(),
+ description: "Replaces text in tags with your replacement_text.".to_string(),
+ input_schema: language_model::tool_schema::root_schema_for::(tool_input_format).to_value(),
+ },
+ LanguageModelRequestTool {
+ name: "failure_message".to_string(),
+ description: "Use this tool to provide a message to the user when you're unable to complete a task.".to_string(),
+ input_schema: language_model::tool_schema::root_schema_for::(tool_input_format).to_value(),
+ },
+ ];
+
+ LanguageModelRequest {
+ thread_id: None,
+ prompt_id: None,
+ intent: Some(CompletionIntent::InlineAssist),
+ mode: None,
+ tools,
+ tool_choice: None,
+ stop: Vec::new(),
+ temperature,
+ messages,
+ thinking_allowed: false,
+ }
+ }))
}
fn build_request(
@@ -379,6 +514,10 @@ impl CodegenAlternative {
context_task: Shared>>,
cx: &mut App,
) -> Result> {
+ if cx.has_flag::() {
+ return self.build_request_v2(model, user_prompt, context_task, cx);
+ }
+
let buffer = self.buffer.read(cx).snapshot(cx);
let language = buffer.language_at(self.range.start);
let language_name = if let Some(language) = language.as_ref() {
@@ -510,6 +649,7 @@ impl CodegenAlternative {
self.generation = cx.spawn(async move |codegen, cx| {
let stream = stream.await;
+
let token_usage = stream
.as_ref()
.ok()
@@ -899,6 +1039,101 @@ impl CodegenAlternative {
.ok();
})
}
+
+ fn handle_tool_use(
+ &mut self,
+ _telemetry_id: String,
+ _provider_id: String,
+ _api_key: Option,
+ tool_use: impl 'static
+ + Future<
+ Output = Result,
+ >,
+ cx: &mut Context,
+ ) {
+ self.diff = Diff::default();
+ self.status = CodegenStatus::Pending;
+
+ self.generation = cx.spawn(async move |codegen, cx| {
+ let finish_with_status = |status: CodegenStatus, cx: &mut AsyncApp| {
+ let _ = codegen.update(cx, |this, cx| {
+ this.status = status;
+ cx.emit(CodegenEvent::Finished);
+ cx.notify();
+ });
+ };
+
+ let tool_use = tool_use.await;
+
+ match tool_use {
+ Ok(tool_use) if tool_use.name.as_ref() == "rewrite_section" => {
+ // Parse the input JSON into RewriteSectionInput
+ match serde_json::from_value::(tool_use.input) {
+ Ok(input) => {
+ // Store the description if non-empty
+ let description = if !input.description.trim().is_empty() {
+ Some(input.description.clone())
+ } else {
+ None
+ };
+
+ // Apply the replacement text to the buffer and compute diff
+ let batch_diff_task = codegen
+ .update(cx, |this, cx| {
+ this.model_explanation = description.map(Into::into);
+ let range = this.range.clone();
+ this.apply_edits(
+ std::iter::once((range, input.replacement_text)),
+ cx,
+ );
+ this.reapply_batch_diff(cx)
+ })
+ .ok();
+
+ // Wait for the diff computation to complete
+ if let Some(diff_task) = batch_diff_task {
+ diff_task.await;
+ }
+
+ finish_with_status(CodegenStatus::Done, cx);
+ return;
+ }
+ Err(e) => {
+ finish_with_status(CodegenStatus::Error(e.into()), cx);
+ return;
+ }
+ }
+ }
+ Ok(tool_use) if tool_use.name.as_ref() == "failure_message" => {
+ // Handle failure message tool use
+ match serde_json::from_value::(tool_use.input) {
+ Ok(input) => {
+ let _ = codegen.update(cx, |this, _cx| {
+ // Store the failure message as the tool description
+ this.model_explanation = Some(input.message.into());
+ });
+ finish_with_status(CodegenStatus::Done, cx);
+ return;
+ }
+ Err(e) => {
+ finish_with_status(CodegenStatus::Error(e.into()), cx);
+ return;
+ }
+ }
+ }
+ Ok(_tool_use) => {
+ // Unexpected tool.
+ finish_with_status(CodegenStatus::Done, cx);
+ return;
+ }
+ Err(e) => {
+ finish_with_status(CodegenStatus::Error(e.into()), cx);
+ return;
+ }
+ }
+ });
+ cx.notify();
+ }
}
#[derive(Copy, Clone, Debug)]
@@ -1060,8 +1295,9 @@ mod tests {
};
use gpui::TestAppContext;
use indoc::indoc;
- use language::{Buffer, Language, LanguageConfig, LanguageMatcher, Point, tree_sitter_rust};
+ use language::{Buffer, Point};
use language_model::{LanguageModelRegistry, TokenUsage};
+ use languages::rust_lang;
use rand::prelude::*;
use settings::SettingsStore;
use std::{future, sync::Arc};
@@ -1078,7 +1314,7 @@ mod tests {
}
}
"};
- let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(Arc::new(rust_lang()), cx));
+ let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(rust_lang(), cx));
let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
let range = buffer.read_with(cx, |buffer, cx| {
let snapshot = buffer.snapshot(cx);
@@ -1140,7 +1376,7 @@ mod tests {
le
}
"};
- let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(Arc::new(rust_lang()), cx));
+ let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(rust_lang(), cx));
let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
let range = buffer.read_with(cx, |buffer, cx| {
let snapshot = buffer.snapshot(cx);
@@ -1204,7 +1440,7 @@ mod tests {
" \n",
"}\n" //
);
- let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(Arc::new(rust_lang()), cx));
+ let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(rust_lang(), cx));
let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
let range = buffer.read_with(cx, |buffer, cx| {
let snapshot = buffer.snapshot(cx);
@@ -1320,7 +1556,7 @@ mod tests {
let x = 0;
}
"};
- let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(Arc::new(rust_lang()), cx));
+ let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(rust_lang(), cx));
let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
let range = buffer.read_with(cx, |buffer, cx| {
let snapshot = buffer.snapshot(cx);
@@ -1437,27 +1673,4 @@ mod tests {
});
chunks_tx
}
-
- fn rust_lang() -> Language {
- Language::new(
- LanguageConfig {
- name: "Rust".into(),
- matcher: LanguageMatcher {
- path_suffixes: vec!["rs".to_string()],
- ..Default::default()
- },
- ..Default::default()
- },
- Some(tree_sitter_rust::LANGUAGE.into()),
- )
- .with_indents_query(
- r#"
- (call_expression) @indent
- (field_expression) @indent
- (_ "(" ")" @end) @indent
- (_ "{" "}" @end) @indent
- "#,
- )
- .unwrap()
- }
}
diff --git a/crates/agent_ui/src/inline_assistant.rs b/crates/agent_ui/src/inline_assistant.rs
index cbc5891036fdf03ee04cca6b77820748faed2d0a..48da85d38554da8227d76d3cbe290e29ef4fc531 100644
--- a/crates/agent_ui/src/inline_assistant.rs
+++ b/crates/agent_ui/src/inline_assistant.rs
@@ -387,17 +387,9 @@ impl InlineAssistant {
let mut selections = Vec::>::new();
let mut newest_selection = None;
for mut selection in initial_selections {
- if selection.end > selection.start {
- selection.start.column = 0;
- // If the selection ends at the start of the line, we don't want to include it.
- if selection.end.column == 0 {
- selection.end.row -= 1;
- }
- selection.end.column = snapshot
- .buffer_snapshot()
- .line_len(MultiBufferRow(selection.end.row));
- } else if let Some(fold) =
- snapshot.crease_for_buffer_row(MultiBufferRow(selection.end.row))
+ if selection.end == selection.start
+ && let Some(fold) =
+ snapshot.crease_for_buffer_row(MultiBufferRow(selection.end.row))
{
selection.start = fold.range().start;
selection.end = fold.range().end;
@@ -424,6 +416,15 @@ impl InlineAssistant {
}
}
}
+ } else {
+ selection.start.column = 0;
+ // If the selection ends at the start of the line, we don't want to include it.
+ if selection.end.column == 0 && selection.start.row != selection.end.row {
+ selection.end.row -= 1;
+ }
+ selection.end.column = snapshot
+ .buffer_snapshot()
+ .line_len(MultiBufferRow(selection.end.row));
}
if let Some(prev_selection) = selections.last_mut()
@@ -544,14 +545,15 @@ impl InlineAssistant {
}
}
- let [prompt_block_id, end_block_id] =
- self.insert_assist_blocks(editor, &range, &prompt_editor, cx);
+ let [prompt_block_id, tool_description_block_id, end_block_id] =
+ self.insert_assist_blocks(&editor, &range, &prompt_editor, cx);
assists.push((
assist_id,
range.clone(),
prompt_editor,
prompt_block_id,
+ tool_description_block_id,
end_block_id,
));
}
@@ -570,7 +572,15 @@ impl InlineAssistant {
};
let mut assist_group = InlineAssistGroup::new();
- for (assist_id, range, prompt_editor, prompt_block_id, end_block_id) in assists {
+ for (
+ assist_id,
+ range,
+ prompt_editor,
+ prompt_block_id,
+ tool_description_block_id,
+ end_block_id,
+ ) in assists
+ {
let codegen = prompt_editor.read(cx).codegen().clone();
self.assists.insert(
@@ -581,6 +591,7 @@ impl InlineAssistant {
editor,
&prompt_editor,
prompt_block_id,
+ tool_description_block_id,
end_block_id,
range,
codegen,
@@ -689,7 +700,7 @@ impl InlineAssistant {
range: &Range,
prompt_editor: &Entity>,
cx: &mut App,
- ) -> [CustomBlockId; 2] {
+ ) -> [CustomBlockId; 3] {
let prompt_editor_height = prompt_editor.update(cx, |prompt_editor, cx| {
prompt_editor
.editor
@@ -703,6 +714,14 @@ impl InlineAssistant {
render: build_assist_editor_renderer(prompt_editor),
priority: 0,
},
+ // Placeholder for tool description - will be updated dynamically
+ BlockProperties {
+ style: BlockStyle::Flex,
+ placement: BlockPlacement::Below(range.end),
+ height: Some(0),
+ render: Arc::new(|_cx| div().into_any_element()),
+ priority: 0,
+ },
BlockProperties {
style: BlockStyle::Sticky,
placement: BlockPlacement::Below(range.end),
@@ -721,7 +740,7 @@ impl InlineAssistant {
editor.update(cx, |editor, cx| {
let block_ids = editor.insert_blocks(assist_blocks, None, cx);
- [block_ids[0], block_ids[1]]
+ [block_ids[0], block_ids[1], block_ids[2]]
})
}
@@ -1113,6 +1132,9 @@ impl InlineAssistant {
let mut to_remove = decorations.removed_line_block_ids;
to_remove.insert(decorations.prompt_block_id);
to_remove.insert(decorations.end_block_id);
+ if let Some(tool_description_block_id) = decorations.model_explanation {
+ to_remove.insert(tool_description_block_id);
+ }
editor.remove_blocks(to_remove, None, cx);
});
@@ -1433,8 +1455,60 @@ impl InlineAssistant {
let old_snapshot = codegen.snapshot(cx);
let old_buffer = codegen.old_buffer(cx);
let deleted_row_ranges = codegen.diff(cx).deleted_row_ranges.clone();
+ // let model_explanation = codegen.model_explanation(cx);
editor.update(cx, |editor, cx| {
+ // Update tool description block
+ // if let Some(description) = model_explanation {
+ // if let Some(block_id) = decorations.model_explanation {
+ // editor.remove_blocks(HashSet::from_iter([block_id]), None, cx);
+ // let new_block_id = editor.insert_blocks(
+ // [BlockProperties {
+ // style: BlockStyle::Flex,
+ // placement: BlockPlacement::Below(assist.range.end),
+ // height: Some(1),
+ // render: Arc::new({
+ // let description = description.clone();
+ // move |cx| {
+ // div()
+ // .w_full()
+ // .py_1()
+ // .px_2()
+ // .bg(cx.theme().colors().editor_background)
+ // .border_y_1()
+ // .border_color(cx.theme().status().info_border)
+ // .child(
+ // Label::new(description.clone())
+ // .color(Color::Muted)
+ // .size(LabelSize::Small),
+ // )
+ // .into_any_element()
+ // }
+ // }),
+ // priority: 0,
+ // }],
+ // None,
+ // cx,
+ // );
+ // decorations.model_explanation = new_block_id.into_iter().next();
+ // }
+ // } else if let Some(block_id) = decorations.model_explanation {
+ // // Hide the block if there's no description
+ // editor.remove_blocks(HashSet::from_iter([block_id]), None, cx);
+ // let new_block_id = editor.insert_blocks(
+ // [BlockProperties {
+ // style: BlockStyle::Flex,
+ // placement: BlockPlacement::Below(assist.range.end),
+ // height: Some(0),
+ // render: Arc::new(|_cx| div().into_any_element()),
+ // priority: 0,
+ // }],
+ // None,
+ // cx,
+ // );
+ // decorations.model_explanation = new_block_id.into_iter().next();
+ // }
+
let old_blocks = mem::take(&mut decorations.removed_line_block_ids);
editor.remove_blocks(old_blocks, None, cx);
@@ -1686,6 +1760,7 @@ impl InlineAssist {
editor: &Entity,
prompt_editor: &Entity>,
prompt_block_id: CustomBlockId,
+ tool_description_block_id: CustomBlockId,
end_block_id: CustomBlockId,
range: Range,
codegen: Entity,
@@ -1700,7 +1775,8 @@ impl InlineAssist {
decorations: Some(InlineAssistDecorations {
prompt_block_id,
prompt_editor: prompt_editor.clone(),
- removed_line_block_ids: HashSet::default(),
+ removed_line_block_ids: Default::default(),
+ model_explanation: Some(tool_description_block_id),
end_block_id,
}),
range,
@@ -1804,6 +1880,7 @@ struct InlineAssistDecorations {
prompt_block_id: CustomBlockId,
prompt_editor: Entity>,
removed_line_block_ids: HashSet,
+ model_explanation: Option,
end_block_id: CustomBlockId,
}
diff --git a/crates/agent_ui/src/inline_prompt_editor.rs b/crates/agent_ui/src/inline_prompt_editor.rs
index b9e8d9ada230ba497ffcd4e577d3312dd440e604..b9852ea727c7974e3564fadc652f132076c01f09 100644
--- a/crates/agent_ui/src/inline_prompt_editor.rs
+++ b/crates/agent_ui/src/inline_prompt_editor.rs
@@ -10,10 +10,11 @@ use editor::{
};
use fs::Fs;
use gpui::{
- AnyElement, App, Context, CursorStyle, Entity, EventEmitter, FocusHandle, Focusable,
- Subscription, TextStyle, WeakEntity, Window,
+ AnyElement, App, Context, Entity, EventEmitter, FocusHandle, Focusable, Subscription,
+ TextStyle, TextStyleRefinement, WeakEntity, Window,
};
use language_model::{LanguageModel, LanguageModelRegistry};
+use markdown::{HeadingLevelStyles, Markdown, MarkdownElement, MarkdownStyle};
use parking_lot::Mutex;
use project::Project;
use prompt_store::PromptStore;
@@ -65,7 +66,7 @@ impl Render for PromptEditor {
const RIGHT_PADDING: Pixels = px(9.);
- let (left_gutter_width, right_padding) = match &self.mode {
+ let (left_gutter_width, right_padding, explanation) = match &self.mode {
PromptEditorMode::Buffer {
id: _,
codegen,
@@ -83,17 +84,23 @@ impl Render for PromptEditor {
let left_gutter_width = gutter.full_width() + (gutter.margin / 2.0);
let right_padding = editor_margins.right + RIGHT_PADDING;
- (left_gutter_width, right_padding)
+ let explanation = codegen
+ .active_alternative()
+ .read(cx)
+ .model_explanation
+ .clone();
+
+ (left_gutter_width, right_padding, explanation)
}
PromptEditorMode::Terminal { .. } => {
// Give the equivalent of the same left-padding that we're using on the right
- (Pixels::from(40.0), Pixels::from(24.))
+ (Pixels::from(40.0), Pixels::from(24.), None)
}
};
let bottom_padding = match &self.mode {
PromptEditorMode::Buffer { .. } => rems_from_px(2.0),
- PromptEditorMode::Terminal { .. } => rems_from_px(8.0),
+ PromptEditorMode::Terminal { .. } => rems_from_px(4.0),
};
buttons.extend(self.render_buttons(window, cx));
@@ -111,22 +118,33 @@ impl Render for PromptEditor {
this.trigger_completion_menu(window, cx);
}));
+ let markdown = window.use_state(cx, |_, cx| Markdown::new("".into(), None, None, cx));
+
+ if let Some(explanation) = &explanation {
+ markdown.update(cx, |markdown, cx| {
+ markdown.reset(explanation.clone(), cx);
+ });
+ }
+
+ let explanation_label = self
+ .render_markdown(markdown, markdown_style(window, cx))
+ .into_any_element();
+
v_flex()
.key_context("PromptEditor")
.capture_action(cx.listener(Self::paste))
- .bg(cx.theme().colors().editor_background)
.block_mouse_except_scroll()
- .gap_0p5()
- .border_y_1()
- .border_color(cx.theme().status().info_border)
.size_full()
.pt_0p5()
.pb(bottom_padding)
.pr(right_padding)
+ .gap_0p5()
+ .justify_center()
+ .border_y_1()
+ .border_color(cx.theme().colors().border)
+ .bg(cx.theme().colors().editor_background)
.child(
h_flex()
- .items_start()
- .cursor(CursorStyle::Arrow)
.on_action(cx.listener(|this, _: &ToggleModelSelector, window, cx| {
this.model_selector
.update(cx, |model_selector, cx| model_selector.toggle(window, cx));
@@ -139,14 +157,14 @@ impl Render for PromptEditor {
.capture_action(cx.listener(Self::cycle_next))
.child(
WithRemSize::new(ui_font_size)
+ .h_full()
+ .w(left_gutter_width)
.flex()
.flex_row()
.flex_shrink_0()
.items_center()
- .h_full()
- .w(left_gutter_width)
.justify_center()
- .gap_2()
+ .gap_1()
.child(self.render_close_button(cx))
.map(|el| {
let CodegenStatus::Error(error) = self.codegen_status(cx) else {
@@ -177,26 +195,83 @@ impl Render for PromptEditor {
.flex_row()
.items_center()
.gap_1()
+ .child(add_context_button)
+ .child(self.model_selector.clone())
.children(buttons),
),
),
)
- .child(
- WithRemSize::new(ui_font_size)
- .flex()
- .flex_row()
- .items_center()
- .child(h_flex().flex_shrink_0().w(left_gutter_width))
- .child(
- h_flex()
- .w_full()
- .pl_1()
- .items_start()
- .justify_between()
- .child(add_context_button)
- .child(self.model_selector.clone()),
- ),
- )
+ .when_some(explanation, |this, _| {
+ this.child(
+ h_flex()
+ .size_full()
+ .justify_center()
+ .child(div().w(left_gutter_width + px(6.)))
+ .child(
+ div()
+ .size_full()
+ .min_w_0()
+ .pt(rems_from_px(3.))
+ .pl_0p5()
+ .flex_1()
+ .border_t_1()
+ .border_color(cx.theme().colors().border_variant)
+ .child(explanation_label),
+ ),
+ )
+ })
+ }
+}
+
+fn markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
+ let theme_settings = ThemeSettings::get_global(cx);
+ let colors = cx.theme().colors();
+ let mut text_style = window.text_style();
+
+ text_style.refine(&TextStyleRefinement {
+ font_family: Some(theme_settings.ui_font.family.clone()),
+ color: Some(colors.text),
+ ..Default::default()
+ });
+
+ MarkdownStyle {
+ base_text_style: text_style.clone(),
+ syntax: cx.theme().syntax().clone(),
+ selection_background_color: colors.element_selection_background,
+ heading_level_styles: Some(HeadingLevelStyles {
+ h1: Some(TextStyleRefinement {
+ font_size: Some(rems(1.15).into()),
+ ..Default::default()
+ }),
+ h2: Some(TextStyleRefinement {
+ font_size: Some(rems(1.1).into()),
+ ..Default::default()
+ }),
+ h3: Some(TextStyleRefinement {
+ font_size: Some(rems(1.05).into()),
+ ..Default::default()
+ }),
+ h4: Some(TextStyleRefinement {
+ font_size: Some(rems(1.).into()),
+ ..Default::default()
+ }),
+ h5: Some(TextStyleRefinement {
+ font_size: Some(rems(0.95).into()),
+ ..Default::default()
+ }),
+ h6: Some(TextStyleRefinement {
+ font_size: Some(rems(0.875).into()),
+ ..Default::default()
+ }),
+ }),
+ inline_code: TextStyleRefinement {
+ font_family: Some(theme_settings.buffer_font.family.clone()),
+ font_fallbacks: theme_settings.buffer_font.fallbacks.clone(),
+ font_features: Some(theme_settings.buffer_font.features.clone()),
+ background_color: Some(colors.editor_foreground.opacity(0.08)),
+ ..Default::default()
+ },
+ ..Default::default()
}
}
@@ -759,6 +834,10 @@ impl PromptEditor {
})
.into_any_element()
}
+
+ fn render_markdown(&self, markdown: Entity, style: MarkdownStyle) -> MarkdownElement {
+ MarkdownElement::new(markdown, style)
+ }
}
pub enum PromptEditorMode {
diff --git a/crates/agent_ui/src/text_thread_editor.rs b/crates/agent_ui/src/text_thread_editor.rs
index 30538898b28a1d41d6c63b3e910f51c816e299ab..52efdf13be230d3fe6658e254f5d3f1a01b8211f 100644
--- a/crates/agent_ui/src/text_thread_editor.rs
+++ b/crates/agent_ui/src/text_thread_editor.rs
@@ -1682,6 +1682,98 @@ impl TextThreadEditor {
window: &mut Window,
cx: &mut Context,
) {
+ let editor_clipboard_selections = cx
+ .read_from_clipboard()
+ .and_then(|item| item.entries().first().cloned())
+ .and_then(|entry| match entry {
+ ClipboardEntry::String(text) => {
+ text.metadata_json::>()
+ }
+ _ => None,
+ });
+
+ let has_file_context = editor_clipboard_selections
+ .as_ref()
+ .is_some_and(|selections| {
+ selections
+ .iter()
+ .any(|sel| sel.file_path.is_some() && sel.line_range.is_some())
+ });
+
+ if has_file_context {
+ if let Some(clipboard_item) = cx.read_from_clipboard() {
+ if let Some(ClipboardEntry::String(clipboard_text)) =
+ clipboard_item.entries().first()
+ {
+ if let Some(selections) = editor_clipboard_selections {
+ cx.stop_propagation();
+
+ let text = clipboard_text.text();
+ self.editor.update(cx, |editor, cx| {
+ let mut current_offset = 0;
+ let weak_editor = cx.entity().downgrade();
+
+ for selection in selections {
+ if let (Some(file_path), Some(line_range)) =
+ (selection.file_path, selection.line_range)
+ {
+ let selected_text =
+ &text[current_offset..current_offset + selection.len];
+ let fence = assistant_slash_commands::codeblock_fence_for_path(
+ file_path.to_str(),
+ Some(line_range.clone()),
+ );
+ let formatted_text = format!("{fence}{selected_text}\n```");
+
+ let insert_point = editor
+ .selections
+ .newest::(&editor.display_snapshot(cx))
+ .head();
+ let start_row = MultiBufferRow(insert_point.row);
+
+ editor.insert(&formatted_text, window, cx);
+
+ let snapshot = editor.buffer().read(cx).snapshot(cx);
+ let anchor_before = snapshot.anchor_after(insert_point);
+ let anchor_after = editor
+ .selections
+ .newest_anchor()
+ .head()
+ .bias_left(&snapshot);
+
+ editor.insert("\n", window, cx);
+
+ let crease_text = acp_thread::selection_name(
+ Some(file_path.as_ref()),
+ &line_range,
+ );
+
+ let fold_placeholder = quote_selection_fold_placeholder(
+ crease_text,
+ weak_editor.clone(),
+ );
+ let crease = Crease::inline(
+ anchor_before..anchor_after,
+ fold_placeholder,
+ render_quote_selection_output_toggle,
+ |_, _, _, _| Empty.into_any(),
+ );
+ editor.insert_creases(vec![crease], cx);
+ editor.fold_at(start_row, window, cx);
+
+ current_offset += selection.len;
+ if !selection.is_entire_line && current_offset < text.len() {
+ current_offset += 1;
+ }
+ }
+ }
+ });
+ return;
+ }
+ }
+ }
+ }
+
cx.stop_propagation();
let mut images = if let Some(item) = cx.read_from_clipboard() {
diff --git a/crates/agent_ui/src/ui/agent_notification.rs b/crates/agent_ui/src/ui/agent_notification.rs
index af2a022f147b79a0a299c17dd26c7e9a8b62aeb9..34ca0bb32a82aa23d1b954554ce2dfec436bfe1c 100644
--- a/crates/agent_ui/src/ui/agent_notification.rs
+++ b/crates/agent_ui/src/ui/agent_notification.rs
@@ -106,9 +106,6 @@ impl Render for AgentNotification {
.font(ui_font)
.border_color(cx.theme().colors().border)
.rounded_xl()
- .on_click(cx.listener(|_, _, _, cx| {
- cx.emit(AgentNotificationEvent::Accepted);
- }))
.child(
h_flex()
.items_start()
diff --git a/crates/anthropic/src/anthropic.rs b/crates/anthropic/src/anthropic.rs
index 06e25253ee626ba76345d7a65b14f1fed0a04b8f..bf2a305011fad924d38dcb391840661f1fd3cdbb 100644
--- a/crates/anthropic/src/anthropic.rs
+++ b/crates/anthropic/src/anthropic.rs
@@ -12,6 +12,8 @@ pub use settings::ModelMode;
use strum::{EnumIter, EnumString};
use thiserror::Error;
+pub mod batches;
+
pub const ANTHROPIC_API_URL: &str = "https://api.anthropic.com";
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
@@ -465,6 +467,7 @@ impl Model {
}
}
+/// Generate completion with streaming.
pub async fn stream_completion(
client: &dyn HttpClient,
api_url: &str,
@@ -477,6 +480,101 @@ pub async fn stream_completion(
.map(|output| output.0)
}
+/// Generate completion without streaming.
+pub async fn non_streaming_completion(
+ client: &dyn HttpClient,
+ api_url: &str,
+ api_key: &str,
+ request: Request,
+ beta_headers: Option,
+) -> Result {
+ let (mut response, rate_limits) =
+ send_request(client, api_url, api_key, &request, beta_headers).await?;
+
+ if response.status().is_success() {
+ let mut body = String::new();
+ response
+ .body_mut()
+ .read_to_string(&mut body)
+ .await
+ .map_err(AnthropicError::ReadResponse)?;
+
+ serde_json::from_str(&body).map_err(AnthropicError::DeserializeResponse)
+ } else {
+ Err(handle_error_response(response, rate_limits).await)
+ }
+}
+
+async fn send_request(
+ client: &dyn HttpClient,
+ api_url: &str,
+ api_key: &str,
+ request: impl Serialize,
+ beta_headers: Option,
+) -> Result<(http::Response, RateLimitInfo), AnthropicError> {
+ let uri = format!("{api_url}/v1/messages");
+
+ let mut request_builder = HttpRequest::builder()
+ .method(Method::POST)
+ .uri(uri)
+ .header("Anthropic-Version", "2023-06-01")
+ .header("X-Api-Key", api_key.trim())
+ .header("Content-Type", "application/json");
+
+ if let Some(beta_headers) = beta_headers {
+ request_builder = request_builder.header("Anthropic-Beta", beta_headers);
+ }
+
+ let serialized_request =
+ serde_json::to_string(&request).map_err(AnthropicError::SerializeRequest)?;
+ let request = request_builder
+ .body(AsyncBody::from(serialized_request))
+ .map_err(AnthropicError::BuildRequestBody)?;
+
+ let response = client
+ .send(request)
+ .await
+ .map_err(AnthropicError::HttpSend)?;
+
+ let rate_limits = RateLimitInfo::from_headers(response.headers());
+
+ Ok((response, rate_limits))
+}
+
+async fn handle_error_response(
+ mut response: http::Response,
+ rate_limits: RateLimitInfo,
+) -> AnthropicError {
+ if response.status().as_u16() == 529 {
+ return AnthropicError::ServerOverloaded {
+ retry_after: rate_limits.retry_after,
+ };
+ }
+
+ if let Some(retry_after) = rate_limits.retry_after {
+ return AnthropicError::RateLimit { retry_after };
+ }
+
+ let mut body = String::new();
+ let read_result = response
+ .body_mut()
+ .read_to_string(&mut body)
+ .await
+ .map_err(AnthropicError::ReadResponse);
+
+ if let Err(err) = read_result {
+ return err;
+ }
+
+ match serde_json::from_str::(&body) {
+ Ok(Event::Error { error }) => AnthropicError::ApiError(error),
+ Ok(_) | Err(_) => AnthropicError::HttpResponseError {
+ status_code: response.status(),
+ message: body,
+ },
+ }
+}
+
/// An individual rate limit.
#[derive(Debug)]
pub struct RateLimit {
@@ -580,30 +678,10 @@ pub async fn stream_completion_with_rate_limit_info(
base: request,
stream: true,
};
- let uri = format!("{api_url}/v1/messages");
- let mut request_builder = HttpRequest::builder()
- .method(Method::POST)
- .uri(uri)
- .header("Anthropic-Version", "2023-06-01")
- .header("X-Api-Key", api_key.trim())
- .header("Content-Type", "application/json");
+ let (response, rate_limits) =
+ send_request(client, api_url, api_key, &request, beta_headers).await?;
- if let Some(beta_headers) = beta_headers {
- request_builder = request_builder.header("Anthropic-Beta", beta_headers);
- }
-
- let serialized_request =
- serde_json::to_string(&request).map_err(AnthropicError::SerializeRequest)?;
- let request = request_builder
- .body(AsyncBody::from(serialized_request))
- .map_err(AnthropicError::BuildRequestBody)?;
-
- let mut response = client
- .send(request)
- .await
- .map_err(AnthropicError::HttpSend)?;
- let rate_limits = RateLimitInfo::from_headers(response.headers());
if response.status().is_success() {
let reader = BufReader::new(response.into_body());
let stream = reader
@@ -622,27 +700,8 @@ pub async fn stream_completion_with_rate_limit_info(
})
.boxed();
Ok((stream, Some(rate_limits)))
- } else if response.status().as_u16() == 529 {
- Err(AnthropicError::ServerOverloaded {
- retry_after: rate_limits.retry_after,
- })
- } else if let Some(retry_after) = rate_limits.retry_after {
- Err(AnthropicError::RateLimit { retry_after })
} else {
- let mut body = String::new();
- response
- .body_mut()
- .read_to_string(&mut body)
- .await
- .map_err(AnthropicError::ReadResponse)?;
-
- match serde_json::from_str::(&body) {
- Ok(Event::Error { error }) => Err(AnthropicError::ApiError(error)),
- Ok(_) | Err(_) => Err(AnthropicError::HttpResponseError {
- status_code: response.status(),
- message: body,
- }),
- }
+ Err(handle_error_response(response, rate_limits).await)
}
}
diff --git a/crates/anthropic/src/batches.rs b/crates/anthropic/src/batches.rs
new file mode 100644
index 0000000000000000000000000000000000000000..5fb594348d45c84e8c246c2611f7cde3aa77a18d
--- /dev/null
+++ b/crates/anthropic/src/batches.rs
@@ -0,0 +1,190 @@
+use anyhow::Result;
+use futures::AsyncReadExt;
+use http_client::{AsyncBody, HttpClient, Method, Request as HttpRequest};
+use serde::{Deserialize, Serialize};
+
+use crate::{AnthropicError, ApiError, RateLimitInfo, Request, Response};
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatchRequest {
+ pub custom_id: String,
+ pub params: Request,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct CreateBatchRequest {
+ pub requests: Vec,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct MessageBatchRequestCounts {
+ pub processing: u64,
+ pub succeeded: u64,
+ pub errored: u64,
+ pub canceled: u64,
+ pub expired: u64,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct MessageBatch {
+ pub id: String,
+ #[serde(rename = "type")]
+ pub batch_type: String,
+ pub processing_status: String,
+ pub request_counts: MessageBatchRequestCounts,
+ pub ended_at: Option,
+ pub created_at: String,
+ pub expires_at: String,
+ pub archived_at: Option,
+ pub cancel_initiated_at: Option,
+ pub results_url: Option,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(tag = "type")]
+pub enum BatchResult {
+ #[serde(rename = "succeeded")]
+ Succeeded { message: Response },
+ #[serde(rename = "errored")]
+ Errored { error: ApiError },
+ #[serde(rename = "canceled")]
+ Canceled,
+ #[serde(rename = "expired")]
+ Expired,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatchIndividualResponse {
+ pub custom_id: String,
+ pub result: BatchResult,
+}
+
+pub async fn create_batch(
+ client: &dyn HttpClient,
+ api_url: &str,
+ api_key: &str,
+ request: CreateBatchRequest,
+) -> Result {
+ let uri = format!("{api_url}/v1/messages/batches");
+
+ let request_builder = HttpRequest::builder()
+ .method(Method::POST)
+ .uri(uri)
+ .header("Anthropic-Version", "2023-06-01")
+ .header("X-Api-Key", api_key.trim())
+ .header("Content-Type", "application/json");
+
+ let serialized_request =
+ serde_json::to_string(&request).map_err(AnthropicError::SerializeRequest)?;
+ let http_request = request_builder
+ .body(AsyncBody::from(serialized_request))
+ .map_err(AnthropicError::BuildRequestBody)?;
+
+ let mut response = client
+ .send(http_request)
+ .await
+ .map_err(AnthropicError::HttpSend)?;
+
+ let rate_limits = RateLimitInfo::from_headers(response.headers());
+
+ if response.status().is_success() {
+ let mut body = String::new();
+ response
+ .body_mut()
+ .read_to_string(&mut body)
+ .await
+ .map_err(AnthropicError::ReadResponse)?;
+
+ serde_json::from_str(&body).map_err(AnthropicError::DeserializeResponse)
+ } else {
+ Err(crate::handle_error_response(response, rate_limits).await)
+ }
+}
+
+pub async fn retrieve_batch(
+ client: &dyn HttpClient,
+ api_url: &str,
+ api_key: &str,
+ message_batch_id: &str,
+) -> Result {
+ let uri = format!("{api_url}/v1/messages/batches/{message_batch_id}");
+
+ let request_builder = HttpRequest::builder()
+ .method(Method::GET)
+ .uri(uri)
+ .header("Anthropic-Version", "2023-06-01")
+ .header("X-Api-Key", api_key.trim());
+
+ let http_request = request_builder
+ .body(AsyncBody::default())
+ .map_err(AnthropicError::BuildRequestBody)?;
+
+ let mut response = client
+ .send(http_request)
+ .await
+ .map_err(AnthropicError::HttpSend)?;
+
+ let rate_limits = RateLimitInfo::from_headers(response.headers());
+
+ if response.status().is_success() {
+ let mut body = String::new();
+ response
+ .body_mut()
+ .read_to_string(&mut body)
+ .await
+ .map_err(AnthropicError::ReadResponse)?;
+
+ serde_json::from_str(&body).map_err(AnthropicError::DeserializeResponse)
+ } else {
+ Err(crate::handle_error_response(response, rate_limits).await)
+ }
+}
+
+pub async fn retrieve_batch_results(
+ client: &dyn HttpClient,
+ api_url: &str,
+ api_key: &str,
+ message_batch_id: &str,
+) -> Result, AnthropicError> {
+ let uri = format!("{api_url}/v1/messages/batches/{message_batch_id}/results");
+
+ let request_builder = HttpRequest::builder()
+ .method(Method::GET)
+ .uri(uri)
+ .header("Anthropic-Version", "2023-06-01")
+ .header("X-Api-Key", api_key.trim());
+
+ let http_request = request_builder
+ .body(AsyncBody::default())
+ .map_err(AnthropicError::BuildRequestBody)?;
+
+ let mut response = client
+ .send(http_request)
+ .await
+ .map_err(AnthropicError::HttpSend)?;
+
+ let rate_limits = RateLimitInfo::from_headers(response.headers());
+
+ if response.status().is_success() {
+ let mut body = String::new();
+ response
+ .body_mut()
+ .read_to_string(&mut body)
+ .await
+ .map_err(AnthropicError::ReadResponse)?;
+
+ let mut results = Vec::new();
+ for line in body.lines() {
+ if line.trim().is_empty() {
+ continue;
+ }
+ let result: BatchIndividualResponse =
+ serde_json::from_str(line).map_err(AnthropicError::DeserializeResponse)?;
+ results.push(result);
+ }
+
+ Ok(results)
+ } else {
+ Err(crate::handle_error_response(response, rate_limits).await)
+ }
+}
diff --git a/crates/assistant_text_thread/src/text_thread.rs b/crates/assistant_text_thread/src/text_thread.rs
index 7f24c8f665f8d34aed199562dce1131797f13c9d..b808d9fb0019ccad25366d9ae60cc1f765126c74 100644
--- a/crates/assistant_text_thread/src/text_thread.rs
+++ b/crates/assistant_text_thread/src/text_thread.rs
@@ -14,7 +14,7 @@ use fs::{Fs, RenameOptions};
use futures::{FutureExt, StreamExt, future::Shared};
use gpui::{
App, AppContext as _, Context, Entity, EventEmitter, RenderImage, SharedString, Subscription,
- Task,
+ Task, WeakEntity,
};
use itertools::Itertools as _;
use language::{AnchorRangeExt, Bias, Buffer, LanguageRegistry, OffsetRangeExt, Point, ToOffset};
@@ -688,7 +688,7 @@ pub struct TextThread {
_subscriptions: Vec,
telemetry: Option>,
language_registry: Arc,
- project: Option>,
+ project: Option>,
prompt_builder: Arc,
completion_mode: agent_settings::CompletionMode,
}
@@ -708,7 +708,7 @@ impl EventEmitter for TextThread {}
impl TextThread {
pub fn local(
language_registry: Arc,
- project: Option>,
+ project: Option>,
telemetry: Option>,
prompt_builder: Arc,
slash_commands: Arc,
@@ -742,7 +742,7 @@ impl TextThread {
language_registry: Arc,
prompt_builder: Arc,
slash_commands: Arc,
- project: Option>,
+ project: Option>,
telemetry: Option>,
cx: &mut Context,
) -> Self {
@@ -873,7 +873,7 @@ impl TextThread {
language_registry: Arc,
prompt_builder: Arc,
slash_commands: Arc,
- project: Option>,
+ project: Option>,
telemetry: Option>,
cx: &mut Context,
) -> Self {
@@ -1167,10 +1167,6 @@ impl TextThread {
self.language_registry.clone()
}
- pub fn project(&self) -> Option> {
- self.project.clone()
- }
-
pub fn prompt_builder(&self) -> Arc {
self.prompt_builder.clone()
}
@@ -2967,7 +2963,7 @@ impl TextThread {
}
fn update_model_request_usage(&self, amount: u32, limit: UsageLimit, cx: &mut App) {
- let Some(project) = &self.project else {
+ let Some(project) = self.project.as_ref().and_then(|project| project.upgrade()) else {
return;
};
project.read(cx).user_store().update(cx, |user_store, cx| {
diff --git a/crates/assistant_text_thread/src/text_thread_store.rs b/crates/assistant_text_thread/src/text_thread_store.rs
index 19c317baf0fa728c77faebc388b5e36008aa39b3..71fabed503e8c04a8865bed72c28ae5b30e75574 100644
--- a/crates/assistant_text_thread/src/text_thread_store.rs
+++ b/crates/assistant_text_thread/src/text_thread_store.rs
@@ -51,7 +51,7 @@ pub struct TextThreadStore {
telemetry: Arc,
_watch_updates: Task