Commit graph

1004 commits

Author SHA1 Message Date
Ben Kunkle
a1510de54e
agent: Report follow-up messages as tool permission denials (#61754)
# Objective

- Treat a follow-up sent during pending tool approval as a denial the
agent can understand.

## Solution

- Preserve the follow-up interruption through permission handling and
return a specific denial result to the model.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Agent: Fixed agents not recognizing follow-up messages as denial of
pending tool calls.
2026-07-28 03:18:02 +00:00
Mendel Feygelson
068691a80f
agent: Improve error messaging for edit_file tool (#61662)
# Objective

Currently, when a model provides the wrong parameters to the edit file
tool, it gets back the opaque error message `data did not match any
variant of untagged enum ValueOrJsonString`.

At least some models (DeepSeek in my experience) can't figure out what
to do from this point, and keep trying the same wrong parameter names in
the tool call before eventually falling back to using `ed`.

This may address https://github.com/zed-industries/zed/issues/58622.

## Solution

Rather than attempting to deserialize to the `ValueOrJsonString` enum,
try to deserialize as a JSON string and then as a value in turn, so that
deserialization errors better propagate.

## Testing

Using DeepSeek V4 Pro.

Tried it out in a reloaded conversation where the edit tool was
consistently failing.

Asked it to stress-test the edit tool. Only one edit failed after a few
successful attempts, and returned the error message "missing field
`new_text`".

Subsequent edits worked again rather than resulting in a doom loop. I
don't think the model noticed what happened, but it seemed to help.

<img width="366" height="551" alt="image"
src="https://github.com/user-attachments/assets/6f9c0c8d-bf94-4670-bad0-0ead5c1fff4e"
/>

...

<img width="346" height="153" alt="image"
src="https://github.com/user-attachments/assets/2afa2901-9a90-4142-aa9d-ff32a7be0d0c"
/>


---

Release Notes:

- Improved edit_file tool error messaging.

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-07-27 12:06:13 +00:00
Nevo Poran
f7d481c415
Treat blank spawn_agent session IDs as absent (#60893)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
# Objective

Fix `spawn_agent` calls that provide an empty or whitespace-only
`session_id`.

Currently, an empty string is deserialized as a real session id, so the
tool attempts to resume a session with an empty id instead of starting a
new subagent session. This can happen when callers serialize an optional
`session_id` field as `""`.

Related: Refs #55987. This addresses one concrete session-id failure
mode described there, but that issue also covers broader
OpenAI-compatible provider/subagent reliability concerns.

## Solution

- Add custom deserialization for `SpawnAgentToolInput.session_id`.
- Treat omitted, `null`, empty, and whitespace-only values as `None`.
- Preserve existing behavior for non-empty `session_id` values, so
follow-up calls still resume an existing subagent session.
- Clarify the field docs.
- Add a regression test covering omitted, `null`, empty,
whitespace-only, and non-empty values.

## Testing

Tested locally on macOS:

- `RUSTUP_TOOLCHAIN=1.95.0 cargo fmt --manifest-path zed/Cargo.toml
--package agent --check`
- `RUSTUP_TOOLCHAIN=1.95.0 cargo test --manifest-path zed/Cargo.toml -p
agent -p gpui_macos --features gpui_macos/runtime_shaders
deserializes_blank_session_id_as_absent`
- `RUSTUP_TOOLCHAIN=1.95.0 cargo build --manifest-path zed/Cargo.toml -p
zed -p gpui_platform --features gpui_platform/runtime_shaders`
- `RUSTUP_TOOLCHAIN=1.95.0 cargo clippy --manifest-path zed/Cargo.toml
-p agent -p gpui_macos --features gpui_macos/runtime_shaders --tests --
-D warnings`

The local build uses runtime shaders because this machine does not have
the full Xcode Metal CLI toolchain available. CI should cover the
standard build matrix.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed `spawn_agent` handling so blank `session_id` values are treated
as absent and start a new subagent session.

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
2026-07-24 14:03:06 +00:00
Enoch
9a5344b9eb
agent: Add agent.compaction_model setting for context compaction (#60012)
# Objective

Add a new `agent.compaction_model` setting that lets users specify a
separate language model for context compaction (`/compact` and
auto-compaction), independent of the thread's active conversation model.

Compaction is just summarization — there's no reason to pay Opus prices
for it when a cheaper model does the job faster. We've also seen
reasoning models misbehave on this task (empty responses, repetition
loops at high effort), so picking a dedicated non-reasoning model for
compaction is useful.


## Solution

- New `compaction_model: Option<LanguageModelSelection>` field in
`AgentSettingsContent` and `AgentSettings`, mirroring
`thread_summary_model`.
- New `compaction_model: Option<ConfiguredModel>` slot on
`LanguageModelRegistry` with `select_/set_/compaction_model()` trio,
mirroring the existing pattern. The setter deliberately does **not**
emit a registry event in v1; callers read the slot lazily at compaction
time.
- New `Thread::compaction_model(&self, cx: &App)` helper that returns
the configured model or falls back to `self.model()`. Two call sites —
`Thread::compact` and `perform_compaction_if_needed` — now go through
this helper instead of reading `self.model()` directly.
- `build_compaction_telemetry` accepts the compaction model explicitly
so the `model` field reflects the model that actually streamed the
request. `max_tokens` still derives from `thread.model()` (threshold
semantics are unchanged).
- Documentation updated at `docs/src/ai/agent-settings.md` (new
user-facing setting).

**Example:**

```json
{
  "agent": {
    "default_model": {
      "provider": "anthropic",
      "model": "claude-opus-4-6"
    },
    "compaction_model": {
      "provider": "anthropic",
      "model": "claude-sonnet-4-5"
    }
  }
}
```

**Resolution chain:**

```
agent.compaction_model (if set & available)
  → thread.model()  (always available, current behavior)
```

**Behavior change:**

| Trigger | Before | After |
| --- | --- | --- |
| Manual `/compact` | Uses `thread.model()` | Uses
`agent.compaction_model` if set & available; else `thread.model()` |
| Auto-compaction | Uses `thread.model()` | Same as above |
| `/compact` when thread has no model | `NoModelConfiguredError` |
Succeeds if `compaction_model` resolves |
| `compaction_model` configured but provider missing / model id unknown
| n/a | Falls back to `thread.model()` and logs a one-time warning |

**Explicit non-goals:**

- No `Event::CompactionModelChanged`(no consumer; the `_cx` parameter on
`set_compaction_model` is intentionally accepted for future use).
- No GUI selector (consistent with all other feature-specific models).
- No per-profile override.
- No runtime API-error fallback — only config-time failure (provider not
registered, model id not in `provided_models`) triggers fallback. This
matches every other feature-specific model.
- No change to threshold calculation, auto-compact trigger, or
`COMPACTION_PROMPT`.
- No propagation to subagent threads.

## Testing

3 new unit tests in `crates/agent/src/thread.rs::tests`:

- `test_compaction_uses_configured_compaction_model` — manual `/compact`
routes to the configured model; thread's primary model receives no
request; telemetry reflects the configured model.
- `test_compaction_falls_back_when_compaction_model_unavailable` —
configured-but-unresolvable falls back to `thread.model()`; telemetry
reflects the fallback model.
- `test_auto_compaction_uses_compaction_model` — auto-compaction
triggered by threshold honors the same setting.

All 14 existing compaction tests still pass. Test suites in
`crates/agent_settings`, `crates/language_model`,
`crates/settings_content`, `crates/agent_ui` unchanged. `cargo clippy`
clean on the changed crates.

**How reviewers can test:**

1. Add `agent.compaction_model` to `settings.json` with a cheaper model
than the thread's primary model, run `/compact`, observe the cheaper
model receives the request.
2. Set `agent.compaction_model` to a non-existent provider/model id, run
`/compact`, observe fallback to thread model and a `log::warn!` line.
3. Trigger auto-compaction by reaching the threshold, observe it uses
`compaction_model`.

**Platforms tested:** local Linux (cargo check + cargo test on agent /
agent_settings / language_model / settings_content / agent_ui crates).

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — no `unsafe`
blocks introduced
- [x] The content adheres to Zed's UI standards — N/A: settings-only
change, no UI touched
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable — model
resolution is an O(1) registry lookup, not on any hot path; no new work
in the streaming loop


Release Notes:

- agent: Add support for specifying which model is used for compaction
(`agent.compaction_model`)

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
2026-07-24 12:48:58 +00:00
Anant Goel
9eb615298b
bedrock: Fix duplicated messages and colliding tool call ids from Bedrock Mantle (#60998)
## Problem

AWS Bedrock's Mantle endpoint (used for GPT-5.x models via the
OpenAI-compatible Responses API) has two independent bugs that both
cause visible duplication/corruption in the agent panel:

1. **Duplicated message text.** Mantle streams a reply as a series of
new `message` output items, where each new item's text is a growing
prefix-superset of the previous one, and the full `output_text.delta`
sequence is replayed for each item. Forwarding these events through the
shared `OpenAiResponseEventMapper` unmodified caused the assistant's
reply (and its phase/reasoning metadata) to appear duplicated in the UI.
2. **Colliding tool call ids.** Mantle assigns raw `tool_use` ids as a
simple per-request counter (`call_1`, `call_2`, ...) that resets to
`call_1` on every request/response cycle to the model — including
separate cycles within a single agent turn as it performs tool calls
sequentially. Since `acp::ToolCallId` was built directly from that raw
id, and `AcpThread::upsert_tool_call` matches tool calls by id across a
thread's entire entry list, a later, unrelated tool call reusing a raw
id would silently overwrite an earlier, already-completed one instead of
appearing as a new entry — visible as "old tool calls getting replaced
by new ones."

Both were confirmed against real raw Mantle SSE traces and a real
persisted thread (`call_1` recurring across 10+ separate request cycles
within a single turn).

## Fix

**For message duplication:** `MantleResponseEventMapper` wraps
`OpenAiResponseEventMapper` and collapses adjacent, same-phase,
strict-prefix message extensions into a single logical message,
forwarding only the replayed suffix as ordinary incremental text.
- Only adjacent, same-phase, strict-prefix extensions are collapsed.
Equal, shrinking, divergent, or different-phase messages are still shown
as-is.
- Any non-message output item (reasoning, tool call) is a hard boundary:
it's forwarded unchanged and clears the merge state, so a message after
a tool call is never merged with the one before it.
- When a message is merged into the previous one, its `StartMessage` and
`ReasoningDetails` metadata events are suppressed, since they'd
otherwise duplicate what was already emitted for the first message.

**For tool call id collisions:** `scoped_tool_call_id(message_ix,
tool_use_id)` combines the raw provider id with the index of the
`AgentMessage` it belongs to in `Thread::messages`. That index is stable
for the lifetime of one request/response cycle (`flush_pending_message`
only runs on the next `StartMessage` event), so ids stay unique across
the whole thread without needing the raw provider id itself to be
globally unique. The index is threaded through explicitly from where
each tool call is created (`handle_tool_use_event`/`run_tool`) to where
it's later referenced (`process_tool_result`), rather than recomputed
later by re-reading `Thread::messages.len()`.

We deliberately did not rewrite the raw `tool_use` id itself at the
provider layer to make it globally unique, since that id round-trips
back to Mantle verbatim as `call_id` in `function_call_output` items on
the next request — rewriting it would require a fragile reverse-mapping
on every code path that replays tool results.

## Testing

- `cargo test -p language_models --lib bedrock` — 23/23 pass (11 tests
covering coalescing, independent messages, phase boundaries,
tool/reasoning boundaries, chained cumulative extensions, and metadata
deduplication).
- `cargo test -p agent --lib` — 699/699 pass (2 new regression tests for
tool call id scoping: one via live streaming across two request cycles
in one turn, one via persistence/`Thread::replay()` across two separate
turns).
- `script/clippy -p language_models -p agent` — clean.

Release Notes:

- Fixed duplicated assistant replies and colliding tool calls when using
GPT-5.x models on Amazon Bedrock's Mantle endpoint
2026-07-23 18:40:30 +00:00
MartinYe1234
f8851b686c
agent: Fix edit_file failing to match exact mid-line old_text fragments (#61489)
Fixes the `edit_file` tool failing to resolve `old_text` fragments that
only cover part of a longer line. The streaming matcher compared the
query against whole trimmed buffer lines, so an exact substring like
`keyboard WASD, voxel-based` inside a much longer line failed the fuzzy
similarity threshold and the edit was rejected with "did not match any
content".

Supersedes #60615 — thanks to @ziimakc for the report, reproduction, and
initial investigation there. This PR takes a different approach based on
review feedback on that PR.

## Approach

- `StreamingFuzzyMatcher::push()` is unchanged: it still fuzzy-matches
completed lines incrementally so the UI can reveal the likely edit
location while `old_text` streams in.
- `finish()` now first searches the buffer for the complete raw query as
an exact byte substring (rope-native, overlap-aware KMP; no copy of the
buffer). Exact matches take precedence; fuzzy matching remains the
fallback for indentation drift, typos, and inserted/omitted lines.
- Exact matches are capped at two occurrences — enough to prove
ambiguity — and ambiguous or overlapping matches are rejected with the
existing "matched multiple locations" error instead of silently editing
one.
- The matcher now returns match candidates with their line alignment and
exact/fuzzy provenance in one result, and the edit pipeline uses that to
reindent correctly: for an exact mid-line match the first replacement
line keeps the retained prefix (zero delta) while subsequent lines get
the contextual indentation.
- The streaming parser now preserves the trailing newline of finalized
`old_text` (it still strips it from `new_text` to avoid duplicate line
endings, per #52661), so `"foo\n"` can disambiguate a standalone `foo`
line from `foo suffix`.

## Notes

- Exact-search cost is O(buffer + query) at finalization only; the
buffer is never copied into a `String` (the main concern with the
original PR).
- New regression tests cover mid-line fragments, exact-over-fuzzy
precedence, overlapping-match ambiguity, multiline replacement
indentation (spaces and tabs), trailing-newline disambiguation, and
newline-only edits.

Closes https://github.com/zed-industries/zed/issues/59369

Release Notes:

- Fixed agent edits failing when the text to replace is only part of a
line
2026-07-23 17:05:53 +00:00
Finn Evers
e49d280094
language: Refactor available_languages into its own struct (#61388)
This adds a dedicated `AvailableLanguages` struct in preparation for a
more cabable language matching based on a given language config. No
functional changes, just shuffling some code around for this round.

Also made the LanguageMatcher non-cloneable in favor of wrapping it in
an Arc, since cloning is rather expensive for this and having a
reference is sufficient in all cases right now.

Release Notes:

- N/A

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-07-23 11:22:43 +00:00
Cameron Mcloughlin
39bea4e56d
agent: Temporarily remove sandbox feature (#61484)
see title

---

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
2026-07-22 22:39:21 +00:00
Dino
b562439e93
project_panel: Add remote support for undo/redo system (#59709)
# Objective

Add remote (SSH) and collaboration support for trashing and restoring
files in the project panel, which in turn enables undo/redo of trash
operations against remote and collab projects.

Relates to #5039.

## Solution

- Updated the project panel undo system to carry `TrashId` instead of
`TrashedEntry`.
- Using `TrashedEntry` could get hairy, as it includes paths, which
wouldn't play too nicely when using, for exapmle, macOS as the client
and Windows as the host. Using a simple identifier is much easier in
this regard and simplifies implementation.
- Enabled the Trash action and context-menu entry on remote projects,
and removed the command palette filter in `ProjectPanel::new` that was
still hiding the action on remote.
- As far as I can tell, there isn't a reliable way to detect whether a
given remote actually supports the OS trash, so we expose the action
everywhere rather than guessing. On a remote without trash support the
action will fail when invoked but this is a conscious tradeoff until we
find a better way to handle this.
- `fs` now tracks trashed files in a `SlotMap<TrashId, TrashedEntry>` on
each `Fs` implementation. Trashed files are referenced by an opaque
`TrashId` instead of passing a `TrashedEntry` around, which avoids
serializing filesystem paths in remote messages.
- Split the old `delete_entry(trash: bool)` API into distinct
`trash_entry`/`trash_file` (returning a `TrashId`) and
`delete_entry`/`delete_file` across `Project`, `Worktree`,
`LocalWorktree` and `RemoteWorktree`.
- This lets us drop the optional trash result (`Option<TrashedEntry>`)
from the delete path and require a `TrashId` from the trash path.
- Added new proto messages (`TrashProjectEntry`,
`TrashProjectEntryResponse`, `RestoreProjectEntry`,
`RestoreProjectEntryResponse`) to let clients request the host to trash
or restore entries.
- This deprecates `DeleteProjectEntry::use_trash`, but the host still
honors it. An older collab peer may request trashing via that flag
instead of the newer `TrashProjectEntry`. If the host ignored it, a
newer host would permanently delete a file the user meant to send to the
trash. The field will be removed in a later PR once all supported peers
use `TrashProjectEntry`.

## Testing

The following tests were introduced to ensure the new behavior is
correctly tested:

* `remote_server::remote_editing_tests::test_remote_trash_restore` –
Tests trashing a project entry in remote
*
`remote_server::remote_editing_tests::test_remote_delete_project_entry_with_trash`
– Test to ensure we continue respecting `DeleteProjectEntry::use_trash`
until it is fully removed
* `project_panel::tests::undo::trash_directory_undo_redo` – Not related
to these changes but a nice to have as we were missing a test ensuring
that trashing and then undoing and redoing it for a directory works as
expected

Besides these, the following scenarios were manually tested against a
remote session on the same machine (macOS):

- Trashing → Undo (Restore) → Redo (Trashing)
- Batch Trashing → Undo (Batch Restore) → Redo (Batch Trashing)
- Rename → Undo (Rename) → Redo (Rename)
- Move → Undo (Move) → Redo (Move)
- Batch Move → Undo (Batch Move) → Redo (Batch Move)

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Release Notes:

- N/A

---------

Co-authored-by: Yara <git@yara.blue>
2026-07-16 09:41:21 +00:00
Lukas Wirth
f181a2f47b
Split out RelPath into a separate crate (#61029)
This is necessary to remove some `util` dependencies from crates, as
well as better sharing for our projects. This also includes the WIP
AbsPath abstraction as well as some bug fixes from internal tooling.


Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-15 08:33:25 +00:00
Bennet Bo Fenner
d94ca551bc
agent: Show title generation error in tooltip (#60982)
Closes #57117

<img width="305" height="84" alt="image"
src="https://github.com/user-attachments/assets/5626040c-5c3f-4f3f-8931-31331406015e"
/>

Release Notes:

- agent: Show actual error message when title generation fails

---------

Co-authored-by: Martin Ye <martin@zed.dev>
2026-07-14 15:48:02 +00:00
Cameron Mcloughlin
795c44f61d
agent: Sandbox DNS rebinding and redirect cleanup (#60941)
Tidies up the host resolution code a bit and closes some small gaps

---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-14 15:29:30 +00:00
Ahmed Ghait
8906914149
agent: Show MCP tool primary argument in tool-call header (#54604)
## Problem

Built-in tools like `Fetch` render their primary argument next to the
tool name in the collapsed tool-call header (e.g. `Fetch
https://example.com`). MCP tools don't — they always show `Run MCP tool
<name>` and the argument is hidden inside the expandable "Raw Input"
JSON block.

For Playwright, fetch, search, or any MCP tool where one argument
carries all the context, this makes every call opaque. You have to click
to expand just to see which URL is being opened or which file is being
read.

Before:

```
⊙ mcp__playwright__open_url_in_browser
  [click to expand]
  Raw Input:
  {
    "url": "https://linkedin.com/in/neuodev"
  }
```

After:

```
⊙ Run MCP tool `mcp__playwright__open_url_in_browser` https://linkedin.com/in/neuodev
```

## Root cause

`ContextServerTool::initial_title` at
`crates/agent/src/tools/context_server_registry.rs` discards the input:

```rust
fn initial_title(&self, _input: serde_json::Value, _cx: &mut App) -> SharedString {
    format!("Run MCP tool `{}`", self.tool.name).into()
}
```

Built-in tools read the input (`fetch_tool.rs`: `format!("Fetch {}",
MarkdownEscaped(&input.url))`) but the generic MCP path never did.

## Change

When the MCP tool's input is a JSON object with exactly one
string-valued field, inline that value next to the tool name. All other
shapes (multi-field objects, non-string values, null/empty input) fall
back to the existing `Run MCP tool <name>` label, so behavior is
unchanged for them.

- Value is truncated at 120 chars with `…` on overflow (char-safe, not
byte-safe — "café" won't panic).
- Value is run through `MarkdownEscaped` so markdown metacharacters
render literally.
- Single-string heuristic was chosen because the MCP spec has no
standard field for a display template, and the common case (`url`,
`path`, `query`, `selector`, `name`) is covered. I considered honoring
`Tool.annotations.title` or `_meta["zed/title"]` as a template — happy
to follow up with that if the team prefers an opt-in mechanism, but
wanted to start with something that works out of the box for every
existing MCP server.

## Tests

Added 10 unit tests in the existing `mod tests` block covering: happy
path, no args, null input, multi-field fallback, non-string fallback,
truncation, markdown escaping, multibyte chars, and empty-string
preservation.

`cargo check -p agent --tests` passes locally. I couldn't run the full
test binary on my machine because `wasmtime-c-api-impl` (a transitive
test-dep) needs `cmake`, but the new code is pure string-manipulation
with no wasm/runtime touch — CI should cover.

## Scope

One file, +127/-3. No behavior change for any tool shape other than
single-string-input MCP tools.

## Per CONTRIBUTING.md

Happy to convert to a discussion first if the team prefers — didn't see
a tracking issue for this. Also filed under CLA (signed).

Release Notes:

- Show MCP tool primary argument in tool header if space allows

---------

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
2026-07-13 14:00:40 +00:00
Lukas Wirth
d7c922c4a3
agent: Treat context window overflows as prompt-too-large errors (#60525)
Map OpenAI's context_length_exceeded errors (both the in-stream error
events sent by the Responses API / ChatGPT Codex backend and HTTP 400
responses carrying the code) to
LanguageModelCompletionError::PromptTooLarge. This stops pointless
retries and surfaces the dedicated token-limit UI instead of a raw error
string.

Also record a synthetic request token usage when a completion fails with
PromptTooLarge, so the context indicator reports Exceeded rather than
the stale usage of the last successful request, and the next prompt
qualifies for auto-compaction.

Ought to help a bit with
https://github.com/zed-industries/zed/issues/59600

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-07-13 11:08:22 +00:00
Cameron Mcloughlin
8f92822cbf
agent: Sandbox security review and docs update (#60291)
Closes security loopholes and updates docs:
- installs seccomp filter for blocking naughty syscalls
- tightens macos seatbelt profile
- fetch tool responses that redirect are now constrained by allowed
domains list

Also adds a few "Learn More" buttons that link to the new docs.

Also fixes a bug where the agent would try to create a
`~/.config/zed/AGENTS.md` directory

Also adds unicode confusable detection to URL/path privilege escalation
prompts.

---

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-07-10 22:51:41 +00:00
MartinYe1234
7344a31ddc
agent: Fix edit_file corrupting indentation when old_text omits first-line indent (#60613)
The `edit_file` tool re-indents `new_text` by computing a single indent
delta from the first line of `old_text` versus the matched buffer line,
then applying that delta to every line of the replacement. When a model
omits the leading indentation on only the first line of
`old_text`/`new_text` (a common pattern when copying from mid-line
context), the delta computed from the first line was wrongly applied to
the remaining, already-correctly-indented lines, doubling their
indentation.

This PR:

- Tracks the `(query_row, buffer_row)` line pairs aligned by the
streaming fuzzy matcher so the indent of each `old_text` line can be
compared against the buffer line it actually matched.
- Computes a separate indent delta for the lines after the first: when
those lines agree on a consistent delta, it's used for the rest of the
replacement; otherwise the previous uniform behavior is preserved.
- Keeps `query_lines`/line pairs in sync when `finish()` extends a match
with a trailing incomplete line.
- Adds an end-to-end regression test reproducing the issue, plus unit
tests for the new re-indentation logic.

Closes https://github.com/zed-industries/zed/issues/60302

Release Notes:

- Fixed the agent's `edit_file` tool corrupting indentation when a
replacement omitted leading whitespace on only its first line.
2026-07-10 20:21:26 +00:00
Ben Kunkle
3e976e89bc
language_model: Add OpenAI Responses API custom tool support (#60638)
# Objective

Allow zed's language model stack to express OpenAI Responses API custom
tools (freeform text-input tools with an optional lark/regex grammar),
so downstream consumers can offer tools like a freeform `apply_patch` to
GPT models.
## Solution

- `LanguageModelRequestTool` now carries a Function-vs-Custom input
variant; `LanguageModelCustomToolFormat` models text/grammar formats.
- `LanguageModelToolUse.input` becomes a typed
`LanguageModelToolUseInput::{Json, Text}`. Serialization is tagged so
persisted Text inputs round-trip losslessly; legacy plain JSON values
still deserialize as `Json`.
- `open_ai` gains the custom tool wire types (tool definition,
`custom_tool_call`/`custom_tool_call_output` input items with
string-or-content-part outputs, output item, and
`custom_tool_call_input` delta/done stream events). The Responses event
mapper accumulates raw text deltas into `ToolUse` events, and history
replay derives custom-vs-function tool results from the matching
`ToolUse` by id.
- All non-OpenAI providers and the Chat Completions path error
explicitly when a request contains custom tools — no silent drops or
empty-schema coercions.

Release Notes:

- N/A
2026-07-09 12:05:50 +00:00
Tom Houlé
2ab35c6b7d
Consistently use context() to preserve sources for anyhow errors (#59112)
When you use `anyhow::anyhow!("{error}")` to convert a preexisting error
to an `anyhow::Error`, the error source can be lost (depending on the
`Display` impl of the error). Anyhow errors can display the whole source
chain when printed. This commit makes us consistently use `context()`
instead to preserve the underlying error's source.

Release Notes:

- N/A
2026-07-08 12:20:52 +00:00
Bennet Bo Fenner
69664ab9d3
agent: Show errors when provider is not authenticated but model is configured (#60417)
This PR improves the onboarding experience when using the agent panel.
Previously we would pick a fallback model in case the provider failed to
authenticate/was slow to resolve models. However, this code had a race
condition (for providers that resolve models dynamically like
Anthropic/GitHub Copilot), since we pick a fallback immediately after
all providers have been authenticated. However, at that point the
configured provider might not have resolved its models, so we would fall
back to a different provider. At some point we added a workaround for
the zed.dev provider.
We landed on a much simpler approach that eliminates the race condition:
We only pick a fallback model in case the user actually has no model
configured in his settings. In case the user has a model configured, we
won't fallback and show an actionable error message:

1. Model is not set and no fallback available

<img width="862" height="78" alt="image"
src="https://github.com/user-attachments/assets/e8e7472a-1c05-4cd2-8efc-49e6d921b0a4"
/>

2. Model is set, but provider is not authenticated

<img width="865" height="65" alt="image"
src="https://github.com/user-attachments/assets/3c8cbf1d-7dd5-4b2e-809a-61e6662721a3"
/>

3. Model is set, provider is authenticated, but model is not in model
list

<img width="863" height="63" alt="image"
src="https://github.com/user-attachments/assets/b97defa2-3fb4-4ec0-b3c6-26878d1c815c"
/>

4. Model is set, but provider is not recognised

<img width="865" height="67" alt="image"
src="https://github.com/user-attachments/assets/ecff1e3f-4f6b-47eb-a25d-125a104baafc"
/>



This plays well with the reason why we have the fallback model in the
first place: We only want to pick a fallback for users that open Zed for
a first time and e.g. have an Anthropic API key present in their
environment. As soon as the user manually changes his provider/model we
won't apply the fallback anymore.



Release Notes:

- agent: Improved error messaging when provider is not configured
- agent: Improve fallback model selection

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
2026-07-06 08:18:50 +00:00
di404
6e9ff7a4f3
Fix agent hyperlinks do not open files (#56283)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
## Summary

Fix agent message hyperlinks that point to Windows file paths but are
not parsed as openable project paths.

This covers links like:

```md
[Cargo.toml](</C:/Projects/Example Workspace/Cargo.toml:2>)
[filename.ext](C:\Projects\Example%20Workspace\path\to\filename.ext:42)
[AGENTS.md](</c/Projects/Example Workspace/AGENTS.md>)
```

## Problem

Agent responses can emit Markdown hyperlinks whose targets are Windows
paths rather than `file://` URLs. Some of those targets include a
leading slash before the drive (`/C:/...`), Git Bash/MSYS-style drive
prefixes (`/c/...`), percent-escaped spaces, or line suffixes. These
were not normalized before mention parsing, so clicking the hyperlink
could do nothing instead of opening the file.

## Solution

- Normalize hyperlink path targets before parsing them as `MentionUri`
paths.
- Decode percent escapes in bare path targets so `%20` becomes a literal
space before path/line parsing.
- Convert Windows-compatible hyperlink paths such as `/C:/...` and
`/c/...` into native Windows paths.
- Generate file resource links from `find_path_tool` through
`MentionUri::to_uri()` instead of hand-building `file://` strings.

## Result

Before: clicking agent path hyperlinks did not open the referenced file.

After:  


https://github.com/user-attachments/assets/6c7fad77-4a1e-4497-a4f9-4a4fdf86d527


## Validation

- `cargo test -p acp_thread test_parse_windows --features test-support`
- `cargo fmt --check`

## Follow-up changes

Additions on top of the original work above:

- Moved the hyperlink heuristics into a dedicated
`MentionUri::parse_hyperlink` entry point. `MentionUri::parse` stays
strict, so canonical mention URIs round-trip verbatim and other callers
(message editor, thread deserialization, resource links) are unaffected.
- Percent escapes that decode to path separators (`%2F`, `%5C`) are left
encoded, so decoding can never change which directories a path
traverses.
- Bare paths with escapes are ambiguous (a file may literally be named
`a%20b.rs`): `open_link` prefers the decoded interpretation and falls
back to `MentionUri::parse_hyperlink_literal` when the decoded path
doesn't resolve in the project but the literal one does.
- Links to files outside the project's worktrees now open, gated by an
async existence check through the project `Fs` (correct for remote
projects; broken links no longer create empty buffers or add worktrees).
`open_link` and the mention-crease open path are unified into one
`open_abs_path_at_point`, which now also places the cursor for
out-of-project selection/symbol links.
- `grep_tool` resource links also go through `MentionUri::to_uri()` now,
fixing malformed `file://C:\...` URIs and unencoded spaces.
- Added tests: percent-escape disambiguation, out-of-project link
opening, drive-letter normalization, UNC paths, and literal-path parsing
(`cargo test -p acp_thread mention`, `cargo test -p agent_ui open_link`,
`cargo test -p agent grep_tool`); manually verified the link spellings
above on Windows.

Release Notes:

- Fixed agent path hyperlinks on Windows when paths contain spaces or
shell-style drive prefixes.

---------

Co-authored-by: Martin Ye <martin@zed.dev>
2026-07-05 03:54:54 +00:00
Cameron Mcloughlin
3648fe6f19
agent: Sandboxing polish (#60173)
Removes git sandbox feature

The reason is essentially:
- write access to a `.git` dir can be trivially escalated to unsandboxed
access
- therefore, it is misleading to offer git access separate from
unsandboxed access
- instead, we encourage the model to use `--no-optional-locks` to avoid
needing write access to `git status`, etc.


Adds sandboxing to fetch tool
 


---

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-07-01 14:55:30 +00:00
Bennet Bo Fenner
03125da544
agent: Sanitize MCP tool names for stricter provider naming rules (#60154)
Closes #59038

Release Notes:

- agent: Fixed an issue where MCP servers with specific tool names would
cause errors when using Anthropic/OpenAI models
2026-07-01 07:41:49 +00:00
Cameron Mcloughlin
4a99aa870e
agent: More sandboxing changes (#60111)
Large change to sandboxing:
- fixes a nasty TOCTOU relating to a symlink swap attack, documented in
the `sandboxing/README.md`
- Adds UI and restrictions when in an untrusted workspace
- Adds tests for (soon to be removed) git support


---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-06-30 11:10:04 +00:00
Lavi Sharma
3856272188
agent: Add commit message project rules toggle (#56867)
This follows up on discussion #56551.

Right now, when Zed generates a commit message, it includes project
rules files like `AGENTS.md`, `CLAUDE.md`, and `.rules` in the prompt
alongside the git diff. That can add a lot of extra context for a task
that is really just summarizing the changes in a commit.

This PR adds an `include_project_rules` option to
`agent.commit_message_model`. When it is set to `false`, Zed skips
loading project rules when generating commit messages. If the option is
omitted, the current behavior stays the same.

Example:

```json
   {
     "agent": {
       "commit_message_model": {
         "provider": "anthropic",
         "model": "claude-3-5-haiku",
         "include_project_rules": false
       }
     }
   }
 ```

I also updated the settings plumbing so this option is only used for commit message generation and defaults to true when not specified.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

 Release Notes:

 - agent: Added setting to exclude project rules files from commit message generation prompts (`agent.commit_message_include_project_rules`)

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-30 10:21:40 +00:00
Bennet Bo Fenner
6a1ced4a8e
agent: Use compaction boundaries when generating summaries and titles (#60141)
Summary:

- Use the compaction-aware request history when generating thread
summaries.
- Reuse the same compaction boundary logic for thread title generation,
including saved-thread title regeneration.
- Add regression tests for summary and title request construction with
compacted history.

Tests:

- `cargo test -p agent uses_compacted_history`

Release Notes:

- Improved agent thread summary and title generation to respect
compaction boundaries.

Co-authored-by: gaauwe <gaauwe@users.noreply.github.com>
2026-06-30 09:35:16 +00:00
Bennet Bo Fenner
9cb139fc38
agent: Delete subagent threads when deleting parent thread (#60071)
Some checks are pending
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
Closes #59584

Release Notes:

- agent: Delete subagent threads from database when deleting parent
thread
2026-06-29 10:25:26 +00:00
MartinYe1234
3d1b26d683
Protect Git metadata in Windows sandboxes (#59799)
Summary:

- Protect Git metadata in Windows/WSL sandboxes by passing Git policy
into the WSL Bubblewrap wrapper.
- Map protected Git paths and overlay them read-only, while allowing
approved Git metadata paths to be writable.
- Update tool descriptions and sandboxing docs for platform-specific Git
metadata behavior.

Validation:

- cargo check -p sandbox
- cargo check -p sandbox --tests --target x86_64-pc-windows-msvc
- cargo check -p agent -p acp_thread
- git --no-pager diff --check

Release Notes:

- Improved Windows agent sandboxing to protect Git metadata unless
access is approved
2026-06-29 09:54:36 +00:00
Ben Brandt
70fd3c5774
acp: Handle acp message ids when we get them (#59927)
This separates the two user-message identities we currently need in
agent threads:

- `protocol_id`: the ACP `messageId` used to group or split streamed
message chunks from ACP agents.
- `client_id`: the Zed-generated user message ID used by the native
agent for truncate, rewind, edit/regenerate, checkpoints, token usage,
and persistence.

The main behavior change is that ACP protocol message IDs now affect
message merging/rendering without leaking Zed-native client IDs into ACP
agents by default. Agents that can accept Zed-generated user message IDs
opt into that path through `AgentSessionClientUserMessageIds`, which
owns both ID generation and prompt submission. The native Zed agent
implements that capability; normal ACP agents continue through the
protocol-only `prompt` path.

In ACP v2 we'll have a mechanism for getting user message replays that
will allow the agent to adequately generate it's own opaque id that we
can then use for these other capabilities. But for now, this split at
least makes sure we keep the two concepts distinct.

Release Notes:

- N/A

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-29 07:21:09 +00:00
Marshall Bowers
1fd93cbd34
Unship shared threads (#59981)
This PR unships shared threads.

The feature is not used much and is getting in the way, at this point.

These are only ever made available to staff.

The corresponding database schema migration has been created in the
Cloud repo and applied to the production database.

Release Notes:

- N/A
2026-06-26 20:50:37 +00:00
Danilo Leal
5c58d5c49a
agent_ui: Refactor the queue feature and add steering ability (#59310)
Closes AI-367

This PR significantly refactors the queue feature so that we don't rely
on indexes being counted and synced across various state points of the
thread view. Instead, I'm introducing a dedicated message queue module
where we control through a stable queue entry ID all the states of a
given queued message.

Additionally, it's relevant to note that I changed the default behavior
of queued messages on this PR so that they get sent only at the end of
the generation. This makes the out-of-the-box, default behavior of the
feature consistent across the native and external agents, given we never
could pull off the feature with the latter. I personally never liked
that behavior anyway, but I do appreciate how some people do. Because of
that, though, for the Zed agent, a "Steer" toggle button is available
for whenever you'd like to signal that a queued message should be sent
at the turn boundary. This is not a setting, though; decided to go
simpler at this moment. It's something you can choose on a per-message
basis.

Ultimately, I think this implementation makes the overall shape of the
feature much more stable and easier to maintain overtime.

Release Notes:

- Agent: Changed the default behavior of queued messages for the Zed
agent so that they get send at the end of the generation. The ability to
steer them (i.e., send the message at the end of a turn boundary) is
still possible to be toggled.
2026-06-26 11:45:58 +00:00
Richard Feldman
697cff57bc
Remove SSH agent access from sandbox docs (#59797)
This removes sandbox prompt and documentation wording that claimed Git
metadata access exposes the inherited SSH agent socket. Git access
remains limited to protected metadata paths, and the Seatbelt wrapper no
longer carries SSH-agent-specific handling or examples.

Release Notes:

- Fixed AI sandboxing documentation to avoid implying Git metadata
access grants SSH agent access.
2026-06-24 15:19:59 +00:00
Richard Feldman
5d06fffd98
Harden Git sandbox metadata grants (#59785)
Agent terminal commands that request Git metadata access now verify
linked-worktree and submodule metadata before moving Git paths from
protected to writable sandbox paths. This prevents a mutated `.git`
gitfile from redirecting a grant to unrelated repository metadata while
preserving standard submodule layouts.

Release Notes:

- Improved agent terminal sandboxing for Git metadata access.

---------

Co-authored-by: Martin Ye <martin@zed.dev>
2026-06-24 04:16:25 +00:00
Cameron Mcloughlin
c49a29f461
sandbox: Linux domain filtering and some more cleanup (#59790)
---

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: MartinYe1234 <martin@zed.dev>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-06-24 01:42:52 +00:00
Richard Feldman
eea5f57dc5
Allow sandboxed Git writes from worktrees (#57981)
Agent terminal sandboxing now protects `.git` metadata by default and
exposes an explicit `allow_git_access` approval. Without it, file
contents of the `.git` directories for opened worktrees and discovered
repositories (including a linked worktree's common `.git`) cannot be
read or written, though their metadata stays visible; when approved,
those Git directories become writable so commands like fetch/commit
work. SSH commit signing keeps working because the inherited
`SSH_AUTH_SOCK` is allowed as local Unix-socket IPC, which does not let
sandboxed commands send network packets to other machines. The Seatbelt
profile also allows PTY terminal-control ioctls so signing/passphrase
prompts can manage terminal state.

This intentionally restricts only `.git` itself (whose location we know
exactly, including the worktree case) rather than
`.gitignore`/`.gitattributes`/`.gitmodules`, since those can be nested
arbitrarily and the goal is to keep the policy expressible as a plain
deny-by-default allowlist that will port to Linux and Windows sandboxes
later.

Closes AI-334

Release Notes:

- Improved agent terminal sandboxing for Git metadata, Git worktrees,
and SSH commit signing.
2026-06-23 15:20:21 +00:00
Manoj Mishra
4eb039b451
ollama: Don't abort entire model fetch if one model's details fail to load (#59606)
## Summary

Fixes #37815.

`State::fetch_models()` calls `/api/tags` to list models, then calls
`/api/show` for **every** model in that list to get its capabilities,
collecting the results with `collect::<Result<Vec<_>>>()?`. If
`/api/show` errors for even one model, the whole batch fails and
`fetched_models` is never populated. Since `is_authenticated()` is
defined as `!self.fetched_models.is_empty()`, this means a single bad
model permanently breaks both authentication state and the model picker
for the entire Ollama provider - with no error surfaced anywhere (not
the UI, not the logs), which matches the reports in #37815 of "Connect
does nothing" / "no logs, no nothing".

I hit this myself: I had a stale local reference to an Ollama Cloud
model that had been retired server-side. `/api/show` for that one model
returned `410 Gone`, which silently broke Connect and the model picker
for every other model too. Removing the retired model with `ollama rm`
fixed it immediately, which confirmed the root cause.

## Fix

Instead of aborting the whole fetch on the first error, skip individual
models that fail `/api/show` and log a warning, keeping the rest.
Extracted this into a small `skip_failed_models` helper so it's
unit-testable without mocking HTTP.

## Disclosure

I used Claude (Anthropic's Claude Code) to help track down this root
cause (tracing through `fetch_models`/`is_authenticated` in this file)
and draft the fix + tests below. I reviewed and understand the change -
it's a small, targeted fix to a single function plus two unit tests for
the new helper.

## Test plan

- [x] `cargo check -p language_models` passes
- [x] `cargo test -p language_models --lib ollama::` - all 3 tests pass
(the 2 new ones plus the existing
`test_merge_settings_preserves_display_names_for_similar_models`,
unaffected by this change)
- [x] `cargo fmt -p language_models -- --check` - no diff

## Release Notes

Release Notes:

- Fixed Ollama models silently failing to show up in the model picker
(and "Connect" appearing to do nothing) when a single model's details
couldn't be fetched, e.g. a retired Ollama Cloud model

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-06-23 09:21:31 +00:00
MartinYe1234
037f32aef0
Refine agent terminal sandbox off-switch and expand WSL env blocklist (#59520)
Follow-ups to the recently-landed agent terminal sandboxing work.

- Make the persistent "Allow Unsandboxed Terminal Commands" setting
(`allow_unsandboxed`) the single off-switch for the agent terminal
sandbox: when enabled, the sandboxed terminal tool isn't exposed and the
system prompt omits the sandbox section, so the model uses the plain
`terminal` tool (and on Windows, WSL sandbox setup is skipped). This
removes the dead, unwired `disabled` setting that was meant to do the
same thing but had no UI, writer, or docs. Per-command and per-thread
`unsandboxed: true` grants are unchanged.
- Expand the blocklist of Windows-specific environment variables that
aren't forwarded into the WSL sandbox (system locations, `HOME`/profile
paths, host/session identity, CPU descriptors, etc.) so they can't
shadow or break Linux commands. It stays a blocklist, so portable
variables like `LANG` still reach the command.

Release Notes:

- N/A
2026-06-22 21:14:30 +00:00
Ben Brandt
8ba35e5eac
acp: Update agent client protocol crate to 0.15.0 (#59593)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
We finally have a cancellation mechanism to use! Made the non
side-effectful handlers stop their work if we get a cancel request
notification.

Release Notes:

- N/A
2026-06-22 09:04:29 +00:00
Yara 🏳️‍⚧️
ccf4058b7a
Add preview to pickers and make them resizable (#59604)
Overhauls Zed's pickers to make them resizable and give them a preview.

Closes #8279 

### Background
The most requested Zed feature has the last year has been a [Telescope
like search box](https://github.com/zed-industries/zed/issues/8279)
[discussion](https://github.com/zed-industries/zed/discussions/22581).
To understand why this is so popular we need to understand search can
serve thee goals:
- Navigation: fuzzy search is faster & easier then clicking in a file
tree
- Exploration: example, find a function by a word in its doc comment
- Collecting: example, getting a list of functions to change

The project search which shows results in a multibuffer is the perfect
way to operate on a list of items. Navigation and Exploration need a lot
of context around each result and offer fast navigation between them.
For both of these live searching is also critical.

The `telescope UI` is a picker with a preview to the right or below.
It's offered in various editors and IDE's most famously Neovim (through
the Telescope plugin), IntelliJ (natively), Helix (natively) and of
course VScode (plugins) and it's _many_ forks.

While having a UI like that for text search (our project search) is most
requested the UX pattern is applied widely, from `find_all_references`
to `bookmarks`. It enhances most pickers. Note that we have over 50
different picker modals!

The community has tried to build something like this for Zed:
- https://github.com/zed-industries/zed/pull/44530
- https://github.com/zed-industries/zed/pull/45307
- https://github.com/zed-industries/zed/pull/46478
- https://github.com/zed-industries/zed/pull/43790

These all became huge PR's that we could not merge for various reasons.
This is a really hard feature to integrate in Zed!
This PR got started as https://github.com/zed-industries/zed/pull/46478
and supercedes that.

### Design
- Extend pickers to support an optional preview with minimal changes to
the pickers themselves.
- Make pickers resizable.
- Complement the existing search do not replace it by having both UI's
share the underlying search and allow freely switching between them.
- Allow extending the preview to things other then files.
- Maintain a clean design on all the pickers.

### Heigh level Implementation overview
- Adds an `Option<Preview>` to `Picker`
- Gives `PickerDelegate` a method to communicate a preview to the Picker
- Overhaul the way pickers are drawn to allow for resizing them.
Implemented on the `Shape` and `SizeBouds` structs.
- Adds a high level way to draw the `footer` and `editor` so we do not
need to change much to the pickers.
- Adds a new text finder Picker
- Adds a way to take a running search from project search and hand it to
the text finder Picker and the other way round
- Give the file finder a preview

### Next steps
A more detailed list and how to help out will be added to the tracking
issue for [Pickes with
previews](https://github.com/zed-industries/zed/issues/56037)
- Add more previews to more pickers!
- Enable selectioning multiple items in pickers and performing actions
on those
- Open selected items in a multibuffer
- Add a way to restore the last picker
- Make popovers (picker attached to some menu) resizable as well

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase
TODO (will be done post merge)

---

Release Notes:
- Added resizing via dragging to all picker modals. 
- Added a preview to the File finder, the preview can be to the right or
below.
- Added a Text finder picker with a preview as alternative project
search UI. The search is shared and allowes switch between UIs while
running.

---------

Co-authored-by: ozacod <47009516+ozacod@users.noreply.github.com>
Co-authored-by: ozacod <ozacod@users.noreply.github.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-06-19 17:43:07 +00:00
Neel
080838387a
agent: Preserve saved model selection until provider loads (#59417)
This PR fixes a bug where a thread could fall back to a BYOK model when
a remote provider hasn't yet returned its list of available models. On a
cold start, a thread previously using a Cloud model would fall over to a
BYOK model (if a key is defined) because Cloud models aren't loaded yet.

Note: there is a small behaviour change here, where previously the
priority was `default_model → profile_model → default_model`. The new
order is `profile_model → default_model`.

Release Notes:

- Improved saved thread model selection for cloud-based providers
2026-06-18 18:27:21 +00:00
MartinYe1234
40211567b8
Make grep tool results clickable in agent panel (#59230)
The agent panel's `grep` tool output previously rendered file paths and
line numbers as plain markdown text, so search results weren't clickable
(unlike `find_path`, which emits `ResourceLink` content blocks).

This PR makes `grep` results clickable in the same way `find_path` does:

- `grep` now streams a `ResourceLink` content block per match
(`crates/foo/bar.rs#L12-15` → `file:///abs/path#L12-15`) followed by the
code snippet, via `event_stream.update_fields`, and sets `locations` on
the tool call.
- `render_resource_link` in `agent_ui` now splits an optional `#L...`
fragment off `file://` URIs before resolving the project-relative path,
so labels render as `path#L12-15` instead of falling back to the raw
absolute URI. Clicking opens the file at the matched line (handled by
the existing `MentionUri` selection parsing).
- The model-facing text output of the tool is unchanged.

Closes AI-401

Release Notes:

- Improved the agent panel so that file search results from the agent's
`grep` tool are clickable and open the file at the matched line.
2026-06-18 13:24:24 +00:00
Richard Feldman
5ef7b14a7d
Enable sandboxing for staff by default (#59507)
Enable the existing agent sandboxing feature flag for staff by default,
so staff builds use sandboxed terminal commands without needing an
explicit flag override.

Release Notes:

- N/A

---------

Co-authored-by: Martin Ye <martin@zed.dev>
2026-06-17 22:42:46 +00:00
MartinYe1234
dfd44a45dd
Add Windows terminal sandboxing via WSL (#58971)
Summary

- Adds Windows agent terminal sandboxing by routing commands through WSL
and Bubblewrap.
- Supports native Windows and WSL project paths, including elevated
write grants for WSL paths.
- Shows a confirmation prompt to turn off sandboxing when WSL sandbox
setup is unavailable.

This builds on the work in the sandbox-linux branch.

Closes AI-376

Release Notes:

- Added Windows terminal sandboxing for agent commands when sandboxing
is enabled.

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-06-17 21:07:29 +00:00
MartinYe1234
54cd092189
Add agent sandbox permissions settings page (#59448)
Adds a dedicated Sandbox settings page under the AI settings, letting
users review and manage the elevated terminal sandbox permissions that
are always allowed without prompting.

The page exposes:
- Network: an "Allow All Domains" toggle and an editable list of allowed
domains (exact domains or leading-`*.` subdomain wildcards), with
validation.
- Filesystem: an "Allow All Filesystem Writes" toggle and an editable
list of writable paths.
- Sandbox: an "Allow Unsandboxed Terminal Commands" toggle.

This replaces the single "Allow Unsandboxed Terminal Commands" setting
item with the new page, and updates the agent panel's settings shortcut
to open it. "Allow always" sandbox grants now persist to settings only
and are no longer also cached as an in-memory thread grant.

Closes AI-413

Release Notes:

- Added a settings page for managing the agent terminal sandbox
permissions (allowed domains, writable paths, and unsandboxed command
execution).
2026-06-17 14:59:09 +00:00
Bennet Bo Fenner
ea035a7a46
agent: Account for max_output_tokens in compaction threshold (#59469)
Follow up to #58883

This makes sure that we subtract the max output tokens before checking
the threshold for auto compaction was reached, we had that logic before
#58883 but we lost it when introducing the settings. Without this GPT
models will run out of tokens before auto-compaction is run

Release Notes:

- (Preview only) Fixed an issue where auto compaction would not be
triggered
2026-06-17 11:56:44 +00:00
MartinYe1234
fd5d42dd55
Add terminal thread init command (#59374)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
## Summary

- Adds an `agent.terminal_init_command` setting for Terminal Threads.
- Runs the configured command automatically when creating a new Terminal
Thread, while skipping restored terminal threads.
- Documents the setting and exposes it in the AI settings page.

Closes https://github.com/zed-industries/zed/issues/58697

Closes AI-337

Release Notes:

- Added a setting to automatically run a command when opening a new
terminal thread in the agent panel.

---------

Co-authored-by: Anant Goel <anant@zed.dev>
2026-06-16 22:50:58 +00:00
Cameron Mcloughlin
e52cc1abe9
agent: Better sandboxing UI (#59437)
Adds UI for the various scenarios where sandboxing can fail on linux:
- no `bwrap` on the path
- `bwrap` is setuid
- `bwrap` exists but cannot create unprivileged userns

---

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: Martin Ye <martin@zed.dev>
2026-06-16 17:04:21 +00:00
Richard Feldman
8ad9d18b93
agent: Address review follow-ups for quit-time thread flush (#59079)
Follow-up to #58962 addressing review feedback on the quit-time thread
flush.

The flush now builds its save payloads through the same helper as
`save_thread`, so the two write paths can't drift — in particular, the
flush now captures the current draft prompt the same way ordinary saves
do, instead of writing whatever stale draft was last serialized. It also
logs database connection errors instead of silently discarding them, and
runs the per-thread saves concurrently, since all quit observers share
gpui's 200ms `SHUTDOWN_TIMEOUT` and serial saves risked a partial flush.

The regression test now quits through the real `App::shutdown` path, so
the `on_app_quit` registration itself is exercised rather than just the
flush method, and it additionally covers draft-prompt capture and the
empty-thread skip.

Release Notes:

- N/A
2026-06-16 14:30:18 +00:00
Agus Zubiaga
33a54ce423
Support provider-side compaction in the language model clients (#59145)
Adds provider-side context compaction support to the Anthropic and
OpenAI API clients. Client plumbing only; not wired into the UI.

Release Notes:

- N/A
2026-06-16 13:06:20 +00:00
Cameron Mcloughlin
6661273a41
agent: Sanboxing on linux (#58355)
Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Co-authored-by: Martin Ye <martin@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-06-16 12:18:29 +00:00
Richard Feldman
2c0a044237
Make unrestricted sandbox network access explicit (#59385)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / extension_tests (push) Blocked by required conditions
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
This makes unrestricted sandbox network access an explicit sandbox mode
instead of a fallback when the enforcing proxy is unavailable.
Host-specific network access still uses the proxy, while approved
arbitrary network access skips proxy setup and maps directly to
unrestricted egress.

Release Notes:

- Improved agent terminal sandbox network permission handling.

---------

Co-authored-by: Martin Ye <martin@zed.dev>
Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
2026-06-15 22:40:16 +00:00