Commit Graph
160 Commits
Author SHA1 Message Date
Grant HutchinsandKirill Bulatov f7fcd09512 agent: Release completed terminal PTY resources (#62978)
Closes #62972

Completed Agent terminal cards remain alive so conversation history can
render their output. Each retained terminal also kept its Alacritty PTY
sender alive, which retained a poller and one kqueue descriptor after
the command exited.

Terminal lifecycle state is now more strongly typed to prevent this
class of regression. Task terminals are created through a sealed
`TerminalMode` API that pairs their running state with the correct
completion channel, while PTY resources use explicit active and released
states. This makes invalid lifecycle combinations unrepresentable
instead of relying on callers to coordinate independent `Option` values
correctly.

- Release the live PTY sender after final terminal output is captured.
- Preserve PTY process metadata and working-directory behavior for
historical terminal cards.
- Represent PTY resources as explicit active or released lifecycle
states.
- Construct interactive and task terminals through typed modes so a task
cannot omit its running state or use a mismatched completion channel.
- Keep resource release idempotent for later ACP release and entity
destruction.
- Add a macOS regression test that retains the historical terminal
entity while exercising the complete sandboxed terminal tool path.

Release Notes:

- Fixed Agent terminal tool calls leaking file descriptors on macOS.

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-26 17:56:33 +00:00
ProhectandKirill Bulatov e9b18cd2d5 agent: Coalesce thread saves into a single worker (#63053)
# Objective

- Reduce excessive RAM usage during long agent sessions. Previously
every
`Thread::notify` triggered a full serialization of the entire
conversation
(including any embedded base64 image) to JSON, so streaming bursts
queued
many large, redundant saves and ballooned memory into the multi-GB
range.
- Related to #57126.
- Related to #62133.

## Solution

- Replace the per-notification save task with a single coalescing save
worker
  per session in `crates/agent/src/agent.rs`.
- `save_thread` now writes the latest snapshot into an in-place buffer
and wakes
  the worker via a `watch` channel, instead of spawning a fresh
  full-conversation save on every notification.
- The worker drains the buffer in a loop, saving only the latest
snapshot per
burst (latest-wins coalescing), and preserves save-on-close by draining
the
  final snapshot before exiting.

## Testing

- `cargo check -p agent`
- `cargo test -p agent test_close_session_saves_thread`
- `cargo test -p agent test_save_load_thread`
- `cargo test -p agent test_threads_flushed_to_database_on_app_quit`

## 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 (no UI change)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Improved memory usage during long agent sessions.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-26 14:33:17 +00:00
Conrad Irwin c8518b3317 Preserve language model provider rejection details (#63095)
Language model providers can reject a request inside an otherwise
successful response stream. Those failures were represented by
overlapping completion-error variants and provider-specific code enums,
and OpenAI Responses errors such as `cyber_policy` fell through to
`Other`. Agent sessions consequently retried permanent provider
rejections and user interfaces lost the provider's actionable message.

This gives every provider-originated failure one shared representation.
`ProviderRejection` preserves the provider, exact message, retry delay,
raw provider code, and an HTTP status only when one was actually
reported. `ProviderErrorCategory` supplies the normalized meaning used
by shared UI and policy code. Provider adapters map their native wire
errors into that category explicitly, so typed SDK exceptions and errors
embedded in successful streams no longer fabricate HTTP statuses.

Retry selection is independent from error construction.
`LanguageModelCompletionError::retry_delay` owns transient
classification and a bounded schedule of 5, 10, 20, then 40 seconds. A
provider-supplied `retry_after` overrides that schedule. The scheduling
layer adds positive jitter of up to 10%, while interactive requests and
evaluation runs retain their own attempt budgets. Permanent status-less
errors such as `cyber_policy` do not retry. OpenRouter also keeps its
numeric body code distinct from an optional HTTP status, including for
errors embedded in a stream.

Testing performed:

- `corgi test -p language_model_core`
- `corgi test -p anthropic` (33 tests)
- `corgi test -p open_ai` (77 tests)
- `cargo nextest run -p open_router -p copilot_chat -p
language_models_cloud -p language_models` (125 tests)
- `cargo nextest run -p agent -p agent_ui` (1,153 tests; 11 skipped)
- `cargo check -p open_router -p copilot_chat -p language_models_cloud
-p language_models -p agent -p agent_ui`
- `./script/clippy -p language_model_core -p anthropic -p open_ai -p
open_router -p copilot_chat -p language_models_cloud -p language_models
-p agent -p agent_ui` completed the release Clippy phase; Cargo Shear
then reported the repository's existing warnings
- `cargo fmt --all --check`

Suggested .rules additions

None.

Release Notes:

- Fixed permanent language model provider rejections being retried and
displayed without their actionable provider message.
2026-08-24 19:36:04 +00:00
Ethan Williams d2bbf4a835 agent: Add ask_user tool using elicitation forms (#61497)
## Summary

Adds a first-party `ask_user` tool to Zed's native agent
(`crates/agent`) that lets the agent ask the user a question and get an
answer back through a proper **elicitation form** rather than free-form
chat text.

This is a step towards the interactive-question experience requested in
[discussion
#48784](https://github.com/zed-industries/zed/discussions/48784)
(implement the ACP elicitation spec for agent questions). Zed already
renders elicitation forms client-side; this wires the native agent up to
that existing rail so the agent can drive single-select and/or free-text
prompts.

## What it does

The tool takes:

- `question` — the prompt shown to the user
- `options` — optional list of selectable choices (single-select)
- `allow_free_text` — whether the user may type a custom answer instead
of picking an option

The agent decides the shape of each question:

| `options` | `allow_free_text` | Result |
| --- | --- | --- |
| 2+ | `false` | Single-select only |
| 2+ | `true` | Single-select with a free-text "other" field |
| empty | `true` | Free-text only |

A typed answer takes precedence over a selected option, and the tool
always resolves (a cancelled or failed elicitation is reported back to
the agent rather than hanging).

## Demo



https://github.com/user-attachments/assets/9d438d87-af65-4fa2-b500-b1232007d0a0


## Implementation

- `thread.rs` — new `ThreadEvent::Elicitation(ElicitationRequest)`
variant plus `ToolCallEventStream::request_elicitation`, mirroring the
existing `prompt_for_decision` permission rail.
- `agent.rs` — handles the elicitation event by building a
session-scoped `acp::CreateElicitationRequest` and routing it through
`AcpThread::request_elicitation`, piping the response back to the tool.
- `tools/ask_user_tool.rs` — the tool itself, including schema
construction and response extraction.
- Registered in the `write` and `ask` profiles and excluded from the
tool-permissions setup UI.

No client-side UI changes were needed — the existing elicitation form
rendering handles it.

## Tests

`cargo test -p agent ask_user` — 5 unit tests covering schema
construction, validation, and accept/decline/cancel handling.

Release Notes:

- Added an `ask_user` tool that lets the agent ask the user a question
with selectable options and/or free-text input, rendered as an
elicitation form
2026-08-17 00:36:02 +00:00
Ben Kunkle 1d61d7f42a 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
Lukas Wirth 6b6393fb0b 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 Fennerandcameron 866babd389 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
Ben BrandtandBennet Bo Fenner 17d77565ad 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
5727cea5be 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
8167681779 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
Ben Brandt 37387b59ac acp: Update agent client protocol crate to 0.15.0 (#59593)
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
Neel 7e882399f9 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
92d9a8b356 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
Richard Feldman 759972e285 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
9c950c7830 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
Ben Brandt 35526d8e60 acp_thread: Preserve waiting tool call status on updates (#58537)
Allows contents to update without dropping the permission (caused by
claude subagents)

Closes
https://github.com/agentclientprotocol/claude-agent-acp/issues/708

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:

- acp: Fix failed permissions requests for external agents
2026-06-11 10:17:58 +00:00
MartinYe1234 c089c237ef agent: Flush thread content to database on app quit (#58962)
After prompting an agent, no response was received and only a spinner
was shown. After updating and reopening Zed, the thread still appeared
in the sidebar but failed to restore with `Failed to Launch` / `no
thread found with ID: SessionId(...)`, and the original prompt was lost.

## Root cause

A native agent thread is tracked by two independent persistence layers:

- **Sidebar metadata** (`ThreadMetadataStore`) and the **serialized
agent panel** record the thread's `session_id` through fast, separate
write paths.
- **Thread content** (`ThreadsDatabase`) is written by a per-session
async task (`NativeAgent::save_thread`) that can still be in flight when
the process exits.

When a graceful quit or update restart raced that async content save,
the metadata/serialized session id was persisted but the content row was
not. On restore, the metadata gate passes, then `load_thread` finds no
content row and hard-fails with `no thread found with ID`.

## Fix

Register an `on_app_quit` handler on `NativeAgent` that synchronously
commits every newly created non-empty thread's content to
`ThreadsDatabase` during shutdown, keeping the two stores consistent
across a graceful quit/restart (the auto-updater's path).

Closes AI-374

Release Notes:

- Fixed agent threads failing to restore after quitting or updating Zed
while a response was still in progress
2026-06-10 23:22:09 +00:00
Richard FeldmanandBennet Bo Fenner cb7838bb3a Remove handoff feature flag and un-gate compaction (#58931)
Removes the `handoff` feature flag entirely and un-gates context
compaction so auto-compaction and the `/compact` command are available
to everyone. The `HandoffFeatureFlag` definition is deleted, and every
flag check is removed: auto-compaction always runs in the agent turn
loop (still governed by the `agent.auto_compact` setting and the model's
context window size), the `/compact` slash command is always registered
and routed to manual compaction, the token-limit callout always defers
to auto-compaction when the window is large enough, and the Auto Compact
settings always appear in the settings UI.

Merging this is the switch that ships the feature; until then it stays
stacked behind the telemetry and retry-fix PRs.

Release Notes:

- Added auto-compaction and /compact to Zed Agent

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-10 10:02:53 +00:00
Richard FeldmanandMikayla Maki 3877fad40a Add Claude Fable 5 to Anthropic BYOK (#58945)
<img width="325" height="201" alt="Screenshot 2026-06-09 at 1 38 32 PM"
src="https://github.com/user-attachments/assets/a6518073-1e17-41ff-a8fc-cb279fcd4436"
/>

Adds support for Anthropic's Claude Fable 5 model when using your own
Anthropic API key. Because Fable 5 cannot be offered under Zero Data
Retention (Anthropic retains inference logs for 30 days), this gates the
model behind an explicit data-retention consent: a new
telemetry.anthropic_retention setting (default off, surfaced in the
Privacy section of the settings UI), and a hard, non-retryable check in
the cloud completion path that raises a typed error when consent is
missing.

When Fable 5 declines a request, it transparently falls back to Claude
Opus 4.8 (matching Anthropic's server-side behavior), and the agent
panel shows a callout for the consent error with "Switch to Opus 4.8" /
"Accept" actions that resume the failed turn so the user's message
continues without retyping.

Closes AI-382

Release Notes:

- Add Claude Fable 5 to Anthropic BYOK

---------

Co-authored-by: Mikayla Maki <mikayla@zed.dev>
2026-06-09 17:53:59 +00:00
Bennet Bo FennerandRichard Feldman 8c8fe80a60 agent: Hide token usage after running /compact (#58937)
We can't compute the actual token usage until we send a new request, so
we hide the token count until you send another message. Matching the
behaviour that we have for new threads

Release Notes:

- N/A

Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-06-09 15:10:24 +00:00
Danilo Leal f616f66e7a thread_view: Add refinements to compaction UI design (#58926)
Here are the things I tried to tackle on this PR:

- Make the compaction call stand out a bit more from other regular tool
calls
- Make text size of the compaction's markdown output be consistent with
the thread body text
- Don't show regular thread loading spinner while compaction is in
progress, given that has its own spinner
- Add a different icon than scissors for compaction and add it to the
autocomplete menu so its consistent w/ skills items

<img width="600" alt="Screenshot 2026-06-09 at 10  57@2x"
src="https://github.com/user-attachments/assets/5c3d25af-aa49-42e1-b6b6-c3f95c664456"
/>

Release Notes:

- N/A
2026-06-09 14:38:34 +00:00
Bennet Bo Fenner 2e5ade11ae agent: Fix handoff feature flag tests (#58916)
Accidentally broke CI in #58891

Since
https://github.com/zed-industries/zed/blob/c68bc98bacb80c34df0e1b6ef4de186d763b3820/crates/feature_flags/src/store.rs#L180
defaults to true in debug mode (effectively sets staff to `true`) the
tests would fail.

We can work around this by manually disabling the feature flag for tests
in settings.

Also, since we are planning to ship to preview tomorrow these tests will
be removed soon.


Release Notes:

- N/A
2026-06-09 12:16:01 +00:00
Richard FeldmanandBennet Bo Fenner b5ad35a5fa Add built-in /compact slash command to the native agent (#58663)
<img width="851" height="315" alt="Screenshot 2026-06-09 at 2 15 51 AM"
src="https://github.com/user-attachments/assets/958f2d2f-db7d-4afb-b4b3-ed11f36b00e7"
/>

<img width="644" height="260" alt="Screenshot 2026-06-09 at 2 16 04 AM"
src="https://github.com/user-attachments/assets/e6a74c6b-aba5-4fbb-991c-25842ced5832"
/>

<img width="619" height="128" alt="Screenshot 2026-06-09 at 2 18 08 AM"
src="https://github.com/user-attachments/assets/ba7fa303-852b-4a17-b8df-ea5bd4df7c11"
/>


Adds an always-available `/compact` slash command to Zed's native agent
that forces a summary-based context compaction of the current
conversation, regardless of token usage. This reuses the agent's
existing compaction logic (always the summary strategy, never
provider-native), bypassing the automatic-compaction token threshold and
minimum-context-window guard since the user explicitly asked to compact.
The command lives entirely in `NativeAgent`/`NativeAgentConnection`, so
external (ACP) agents are untouched and keep their own `/compact`
implementations.

The command is gated behind the `handoff` feature flag, matching the
gate on automatic compaction, so it's only advertised and dispatched
when that flag is enabled. When the flag is off, typing `/compact` is
treated as an ordinary prompt.

Because the agent panel always renders the typed `/compact` as a user
message, the manual compaction records a matching zero-content user
message in the model thread (skipped when building model requests) so
that rewinding/truncating that message works instead of erroring, while
keeping the command itself out of the model's context.

The slash-command popup now groups commands into separate sections by
source — "Commands" (built-in, e.g. `/compact`), "MCP Server Commands",
and "ACP Agent Commands" — so same-named commands from different sources
show up as distinguishable duplicates. The source category travels on
each command's ACP `_meta`.

Release Notes:

- N/A

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-09 09:34:01 +00:00
Ben Brandt 8c88c06390 agent: Remove experimental plan and title agent tools (#58824)
Neither really panned out, removing for now.

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:

- N/A
2026-06-08 11:39:49 +00:00
69946b28da agent: Warn about long skill descriptions (#58356)
Closes #58046 
Closes AI-353

Skills with descriptions over the 1024-byte limit now load with a
warning instead of failing. The warning appears in the thread footer
with clickable skill file rows, and the skill picker keeps the skill
icon while showing a right-aligned warning badge whose hover text
explains the issue.

Warning for single out-of-spec skill
<img width="2790" height="870" alt="image"
src="https://github.com/user-attachments/assets/f454b55a-8e05-438e-b4ff-356259ff6843"
/>

Warning for multiple out-of-spec skills
<img width="2796" height="646" alt="image"
src="https://github.com/user-attachments/assets/a0808cdd-4857-4a6b-a26e-15156afbffe9"
/>

Skill selection popup
<img width="1234" height="1118" alt="image"
src="https://github.com/user-attachments/assets/5bb463f6-7adb-4e39-8522-e322bf078aff"
/>

Skill management in settings
<img width="1768" height="1390" alt="image"
src="https://github.com/user-attachments/assets/85c6b179-e268-4518-8ca7-c73b55f92355"
/>


Release Notes:

- Allow loading skills whose descriptions exceed the 1024-byte limit by
showing warnings instead of failing to load them.

---------

Co-authored-by: Martin Ye <martin@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-06-05 19:46:05 +00:00
Ben Brandt 6942dc2faa acp: Enable ACP session usage and deletion features (#58680)
Stabilizes context windows + persistent session/delete for acp agents
that support them

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:

- acp: Show context window usage and cost metrics for external agents
that support it.
- acp: Persist session deletion from history for external agents that
support it.
2026-06-05 17:52:45 +00:00
6635ea690c agent: Improve compaction UI (#58409)
Reworked the UI so we can actually see the compaction output. Design
pass TBD


https://github.com/user-attachments/assets/89108398-476b-493f-a5eb-d20159fc6830



Release Notes:

- N/A

---------

Co-authored-by: Gaauwe Rombouts <mail@grombouts.nl>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-06-03 12:18:28 +00:00
Ben Brandt 71f975e514 acp: Update agent-client-protocol sdk to 0.13.1 (#58308)
Brings stable logout and additional directories support as well as
removing dep on rmcp + tokio

This also removed the unstable model selector (replaced awhile ago by
session config options) so it removes all of that code.

Native agent still uses it because we have a special model selector that
would need more work to rip out

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:

- N/A
2026-06-02 15:30:37 +00:00
Eric Holk 77d433192f Add create_thread and list_agents_and_models agent tools (#57987)
Adds two built-in agent tools, behind the staff-only
`create-thread-tool` feature flag, that let the agent spawn independent
sibling threads:

- **`create_thread`** creates a new thread with a title and initial
prompt. It runs on the user's behalf and shows up in the agent sidebar
like a thread the user started themselves, but it runs in the background
— the active thread is never interrupted — and it does **not** report
results back to the caller. (Use `spawn_agent` when you want the
results.)
- **`list_agents_and_models`** enumerates the configured agents and, for
the native agent, the available models, so the agent can pick a
cheaper/faster model for bulk work. The motivating stress test was
"spawn 100 threads that each write a haiku, using Haiku instead of
Opus."

By default the sibling shares the parent's project and worktree. If
`use_new_worktree` is set, `create_thread` instead opens a new
background workspace backed by fresh linked git worktrees of the
project's repos — the same flow you get from the worktree picker's
"Create worktree" — and starts the thread there. The new workspace opens
as a background tab so it doesn't pull you away from what you're doing.

A few notes on the design:

- The `agent` crate can't depend on the UI, so there's a
`SiblingThreadHost` trait that `agent_ui::AgentPanel` implements and
installs on the `NativeAgent`. Tool calls in a native-agent thread route
through it.
- Sibling threads go through the same `create_agent_thread` →
`ConversationView` path as the user-facing "new thread" action, so
eviction, persistence, and sidebar rendering match user-created threads.
- An explicit `agent`/`model` override doesn't clobber the panel's
selected agent or the last-used-agent preference — those are snapshotted
and restored around the call.
- The worktree path reuses the existing "Create worktree" machinery
rather than reimplementing it; the agent flow just opens the new
workspace in the background instead of activating it.

A couple of things I left out or want to call out:

- There's no tool to operate on an already-created sibling by session
id. The success payload deliberately omits it, since the session is
populated asynchronously and nothing consumes it yet.
- When a project has multiple worktrees that are linked worktrees of the
*same* underlying repo, they collapse into a single new worktree (they
resolve to the same target path). The tool returns a warning in that
case rather than failing — and this also fixes a latent collision the
manual "Create worktree" flow would hit in the same situation.

Release Notes:

- N/A
2026-06-01 23:44:18 +00:00
fe4203a541 Allow symlinked global skill directories (#58095)
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

Closes #58088

Release Notes:
- Allows for symlinked global skill directories

---------

Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Co-authored-by: Martin Ye <martin@zed.dev>
2026-06-01 16:45:03 +00:00
Richard Feldman 0584c934dd Gate sandboxed terminal tempdir to local projects (#58240)
[PR #57878](https://github.com/zed-industries/zed/pull/57878) introduced
a per-thread sandboxing temp directory that, for every terminal command,
overrode `TMPDIR`/`TMP`/`TEMP` and pushed the directory into the sandbox
writable scope. For remote projects this temp directory is created on
the client while the terminal actually runs on the remote host, so it
leaked client-side environment variables into the remote terminal and
pointed `$TMPDIR` at a path that doesn't exist there.

This gates the temp-directory logic behind `project.is_local()`, so
remote projects no longer get their terminal environment infected. This
doesn't restore the per-thread tempdir behavior for remoting, but it
undoes the regression.

Closes AI-348

Release Notes:

- Fixed remote terminals having their environment overridden by
client-side temp directory variables
2026-06-01 15:59:58 +00:00
Richard Feldman 72de52d291 Add context compaction markers (#58089)
Adds the flat context compaction marker data model and replays persisted
markers into native agent transcripts as static dividers. This lets
compacted thread boundaries deserialize, render, and export to Markdown
without enabling automatic compaction behavior yet.

Release Notes:

- Improved agent threads to show restored context compaction dividers in
conversations
2026-06-01 14:29:15 +00:00
MartinYe1234andCole Miller 4d1c71f5c1 Load project skills through worktree buffers (#58094)
Project-local skills now load through project buffers so remote
workspaces can resolve them consistently with other project files.

Validation:
- cargo check -p agent_skills -p agent
- cargo test -p agent_skills
- cargo test -p agent skills

Closes AI-329

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

Release Notes:

- Improved project skills support in remote workspaces.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-06-01 13:23:28 +00:00
5226db6eae Persist terminal tempdirs by thread (#57878)
Summary:
- Store a lazily-created sandboxed terminal temp directory on each agent
thread.
- Persist the tempdir path and remove it when deleting archived threads.
- Update sandbox prompt wording to describe per-thread tempdir reuse.

Tests:
- cargo fmt --package agent --package agent_ui --package zed
- cargo test -p agent db::tests::test_sandboxed_terminal_temp_dir --
--nocapture
- cargo test -p agent
db::tests::test_delete_thread_removes_sandboxed_terminal_temp_dir --
--nocapture
- cargo check -p agent_ui -p zed

Release Notes:

- Improved agent terminal sandboxing to preserve temporary files across
commands in the same thread

---------

Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Co-authored-by: Martin Ye <martin@zed.dev>
2026-05-28 00:58:56 +00:00
Richard FeldmanandMartinYe1234 356c8cae07 Wrap agent terminal commands in macOS Seatbelt sandbox (#57431)
Stacked on top of #57430.

When the `sandboxing` feature flag is on (macOS only), agent-run
terminal commands are launched under `/usr/bin/sandbox-exec` with a
per-command Seatbelt policy:

- **Reads:** any path on the filesystem.
- **Writes:** each project worktree plus a per-command `$TMPDIR`.
- **Network:** blocked.

The model can request relaxations on individual calls via three new
input flags on the `terminal` tool:

- `allow_network: true`
- `allow_fs_write: true`
- `unsandboxed: true`

Each one triggers a separate always-prompt user approval (bypassing any
`always_allow` rules, since escalation is a stronger trust boundary than
the baseline command approval). The flags are silently ignored when
sandboxing is off, so the model can't surreptitiously change runtime
behavior by setting them in the no-op case.

The per-command tempdir is provisioned regardless of sandbox state so
the model can't infer whether the sandbox is in effect by looking at
`$TMPDIR`.

The Seatbelt config file's lifetime is tied to the `Terminal` entity via
an opaque RAII handle (`SandboxConfigHandle = Box<dyn Any + Send>`), so
cancellation paths drop it automatically.

### Notes for review

- The writable scope passed to the sandbox is the project's worktree
paths plus the per-command tempdir, **not** the resolved `cd` working
directory — `cd` is model-controlled, and using it as the writable scope
would let the model widen its own write permissions outside the project.
- The new tool flags are always present in the JSON schema (with
`#[serde(default)]`), even when the sandbox prompt section isn't
rendered. The system prompt only documents them when the section is
present, so the model shouldn't try to use them when it's not — but the
schema doesn't actively reject them, just ignores them.
- I opted not to add an end-to-end test for the escalation prompt path:
the existing `FakeThreadEnvironment` ignores the new params and toggling
the feature flag in tests is more wiring than felt worth it for a first
cut. The pure-function pieces (`sandbox_approval_title`, schema,
deserialization) are covered, and the sandbox crate itself has
end-to-end tests that actually invoke `sandbox-exec`.

Release Notes:

- N/A

---------

Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
2026-05-27 21:38:17 +00:00
18c70a73a6 Render terminal sandbox section in system prompt behind feature flag (#57430)
Stacked on top of #57429.

Adds a new `sandboxing` feature flag (off for staff by default) and a
single source-of-truth helper `sandboxing_enabled(cx) = cfg!(target_os =
"macos") && cx.has_flag::<SandboxingFeatureFlag>()`. When the helper
returns true, the agent's system prompt gains a new `## Terminal
sandbox` section that:

- Lists each worktree's absolute path as a writable directory.
- Describes the per-command `$TMPDIR` scratch directory.
- States that outbound network access is blocked.
- Documents the three per-command flags (`allow_network`,
`allow_fs_write`, `unsandboxed`) the model can request to relax the
sandbox.
- Tells the model the section is stable for the duration of the
conversation.

When the flag is off, the section is omitted entirely — no mention of
sandboxing at all.

No behavior change to terminal execution yet; that's the next PR in the
stack.

Three new tests cover: section omitted when `sandboxing: false`, section
rendered with all worktrees + flag docs when `sandboxing: true`, and the
zero-worktrees case.

Release Notes:

- N/A

---------

Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Co-authored-by: Martin Ye <martin@zed.dev>
2026-05-27 21:11:27 +00:00
MartinYe1234 b50784098b Stop loading deprecated agent rules (#57844)
Summary:

- Stop loading persisted default Zed Rules into native agent project
context.
- Remove legacy user-rules rendering from agent system prompt templates.
- Keep Skills and project rules file support unchanged.

Tests:

- cargo test -p agent
test_system_prompt_does_not_render_legacy_zed_rules_section --lib
- cargo test -p prompt_store test_empty_skills_sets_has_skills_false
- cargo test -p prompt_store
test_project_context_does_not_filter_by_budget

Closes AI-325
Release Notes:

- Fixed deprecated Rules being automatically included in new agent
requests.
2026-05-27 16:21:30 +00:00
Bennet Bo FennerandRichard Feldman e068c9d6c3 git_ui: Respect global AGENTS.md when generating commit message (#57827)
Release Notes:

- agent: Fixed an issue where commit message generation would not
respect instructions from global `AGENTS.md`

---------

Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-05-27 14:08:15 +00:00
Lukas Wirth 02bec843ac agent: Make messages vec cheap to clone (#57712)
For long threads we will spend more and more time cloning the messages
just to save them to the database, as we need a copy of everything to do
so asynchronously. Messages are really expensive to clone though and we
accumulate a lot of them really fast, so even for smaller threads we
start seeing pauses in the millisecond range. The fix to this is fairly
simple though, we never mutate the messages once pushed to the vec, so
just Arc them.

This PR also slightly changes `UserMessage` to be a bit faster to clone
as well.

Release Notes:

- Fixed a cause of stutters when interacting with the agent
2026-05-26 10:00:34 +00:00
MartinYe1234 96f41cca8c Update skill settings immediately after changes (#57447)
## Summary
- Hide deleted skills immediately in Settings while deletion completes
- Refresh the skill index after creating a skill so Settings updates
without reopening

Closes AI-299
Release Notes:

- Fixed skill management so newly created and deleted skills update in
Settings immediately.
2026-05-21 22:51:57 +00:00
7da1bf1a82 Remove Skills feature flag (#57162)
Removes the `skills` feature flag now that Skills are ready to ship to
all users. Cleans up all `cx.has_flag::<SkillsFeatureFlag>()` gates
across the agent, agent_ui, prompt_store, and title_bar crates, drops
the now-unused `feature_flags` dependency from `prompt_store` and
`title_bar`, and removes the dead `update_flags(true, vec!["skills"])`
calls from the agent's skills tests.

Closes AI-269

Release Notes:

- Enabled Skills for all users.

---------

Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Co-authored-by: Martin Ye <martinye022@gmail.com>
2026-05-20 00:28:09 +00:00
Danilo Leal 1fe2489821 Add settings UI page for skills (#57101)
Closes AI-267

This PR adds a skills subpage in the settings UI, where we display
global skills in the user tab and project skills in the corresponding
project tab. The approach taken here was the simplest one out of the
possible avenues we could've taken to implement this (which would
possibly require bigger refactors), given this is potentially the very
first page in the settings UI where we're displaying stuff that does not
correspond to data available in the `settings.json`.

Important to note that a major limitation of the global approach is that
it's dependent on the native agent having loaded the skill index,
meaning there's an edge case where, if you open the settings UI _before_
having opened the agent panel, you won't immediately see the available
skills. Something to discuss but that it felt like a viable option for a
first ship.

Release Notes:

- Agent: Added a skills section to the settings UI.
2026-05-19 21:12:44 +00:00
Danilo LealandRichard Feldman c9591b91e4 Add built-in create-skill skill (#57064)
Closes AI-266

This PR adds a built-in skill called `create-skill`, which allows the
Zed agent to have access to a skill that teaches it how to properly
create skills for Zed. You can manually invoke it as well as just
letting the model auto-invoke it in case your prompt suggests creating a
new skill.

Release Notes:

- Agent: Added a built-in skill called `create-skill` to make the Zed
agent informed about how to do that.

---------

Co-authored-by: Richard Feldman <richard@zed.dev>
2026-05-19 00:16:04 +00:00
Ben Brandt 72163f746a acp: Add ACP session deletion support (#57004)
Still behind a flag until RFD progresses. But also fixes one area where
we would have called delete even if we didn't have support.

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:

- N/A
2026-05-17 17:03:17 +00:00
Danilo LealandMartinYe1234 71d610e3e2 agent_ui: Render skills as creases (#56689)
Closes AI-230

This PR makes skills, added as /-mentions, be rendered in the agent
panel as creases, like anything you'd @-mention. Naturally, clicking on
the crease button opens the corresponding skill file in a buffer.

It turned out to be quite a bit of plumbing to make this work,
particularly as I am also introducing an interface to display dividers
and headers in the completion menu. This was relevant to me to add
because it sets a good foundation to convert many agent panel-related
actions as slash commands.

Release Notes:

- N/A

---------

Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
2026-05-14 22:20:34 +00:00
Richard Feldman af6f7d1004 Load global AGENTS.md into native agent system prompt (#56757)
Watches a user-global `AGENTS.md` file alongside `settings.json` (at
`~/.config/zed/AGENTS.md` on macOS/Linux, `%APPDATA%\Zed\AGENTS.md` on
Windows) and includes its trimmed contents in the native agent's system
prompt.

This matches the pattern used by Codex (`CODEX_HOME/AGENTS.md`,
defaulting to `~/.codex/AGENTS.md`) and OpenCode
(`~/.config/opencode/AGENTS.md`): personal instructions live next to
other app config and apply across every project the user opens.

## Behavior

- Native Zed agent only. Not passed to ACP / external agents.
- Reads the local config dir, so SSH-remoted projects still get the
local user's personal `AGENTS.md` (project rules continue to come from
the remote workspace).
- Missing, empty, or whitespace-only files are silently treated as no
`AGENTS.md`.
- Read errors surface through the same notification UI as settings
errors, with a stable notification ID that's dismissed once the file
becomes readable again.
- The file is read in full, matching how existing project rules / repo
`AGENTS.md` files are loaded today.

## System prompt rendering

In the system prompt, the user-global `AGENTS.md` appears as `###
Personal AGENTS.md` immediately before `### Project Rules`, so the model
sees personal defaults first and project guidance later (project rules
take precedence on conflicts).

## Tests

- `user_agents_md` watcher: initial load, empty/whitespace ignored,
reacts to file edits.
- `SystemPromptTemplate`: renders personal `AGENTS.md` before project
rules; omits the section when no user `AGENTS.md` is present.

Closes AI-231

Release Notes:

- Added support for a global `AGENTS.md` file alongside `settings.json`
that is automatically included in the agent's instructions for every
project.
2026-05-14 15:02:33 +00:00
94be293463 Restrict tools from editing sensitive agents folders (#56456)
Treat `.agents/skills/` (project-local) and `~/.agents/skills/` (global)
as **sensitive paths**, on par with `.zed/` and the global config
directory. The agent's built-in editing tools (`edit_file`,
`write_file`, `create_directory`, `delete_path`, `move_path`,
`copy_path`) now require explicit user authorization before modifying
anything inside those paths, because the contents of skill files control
agent behavior.

This protection is worth landing on its own, ahead of Zed adding its own
skills support: other agents (e.g. Claude Code) already write skill
files into these locations, so a Zed installation may already have
skills on disk that should not be silently editable by the agent.

Also tightens the **pre-existing `.zed/` check** to compare path
components case-insensitively. macOS and Windows use case-insensitive
filesystems by default, so without this fix a malicious settings author
could bypass the local-settings classifier with `.ZED/settings.json`
(the canonicalized inode would match, but the path-component comparison
would miss it). The new `.agents/skills/` check has the same hazard and
now shares a single `component_matches_ignore_ascii_case` helper with
the `.zed/` check.

Introduces the `agent_skills` crate, scoped for now to just the path
constants and helpers (`global_skills_dir`,
`project_skills_relative_path`, `SKILL_FILE_NAME`) so the
tool-permission machinery can recognize the agent skills tree without
depending on a skill discovery / parsing / loading layer. Those will
land in follow-up PRs.

Closes AI-217

Release Notes:

- Agent: Require user confirmation before letting tools modify files
inside `.agents/skills/` (per-project) or `~/.agents/skills/` (global),
so skills installed by any agent are protected from unsolicited edits

---------

Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Co-authored-by: Martin Ye <martinye022@gmail.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-05-12 22:47:51 +00:00
Bennet Bo FennerandBen Brandt a6b56268bf agent: Improve UX when agent tries to edit unsaved buffer (#55655)
Before:

1. Agent tries to edit unsaved file
2. Tool call fails with error telling the agent to ask the user to save
or discard edits
3. User types save/restore
4. Agent uses save/restore tool


https://github.com/user-attachments/assets/c94dd361-e8e0-48ee-be31-da8afe594419

After:

1. Agent tries to edit unsaved file
2. User is prompted to save/restore file
3. User accepts/rejects or saves/discards file manually


https://github.com/user-attachments/assets/1d98a0c4-4420-4426-94f2-42355de230be

Release Notes:

- agent: Improved UX when agent tries to edit unsaved buffer

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-05-08 11:26:03 +00:00
Conrad Irwin cb7a717a67 Merge gpui::Task and scheduler::Task (#53674)
Release Notes:

- N/A or Added/Fixed/Improved ...
2026-05-05 22:41:13 +00:00
Bennet Bo Fenner 84d855d772 agent: Remove old edit file tool (#55612)
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

Closes #ISSUE

Release Notes:

- agent: Improve reliability when LLM edits file
2026-05-04 09:54:39 +00:00