Commit Graph
996 Commits
Author SHA1 Message Date
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
Anthony Eid 6d9ddb96b2 Bench app context phase 2 (#58202)
This PR builds out GPUI's benchmark harness so render benchmarks measure
realistic frame costs using GPUI-owned, runtime-gated instrumentation.
It adds measurements for frame draw time, dirty-to-draw latency,
invalidation coalescing, and frame-budget overruns, and runs benchmark
workloads with production-like concurrency.

## How it works

**Frame timings flow through the GPUI profiler.** `Window::draw` emits a
`FrameTiming { window_id, dirty_at, invalidations, draw_start, draw_end
}` event into a global ring buffer in `gpui::profiler`, mirroring the
existing task-timing channel. Collection is runtime-gated by
`profiler::set_frame_trace_enabled` (one relaxed atomic load when
disabled — no `Instant::now` calls in production). `BenchReport` is a
pure listener: it drains events through a cursor-based
`FrameTimingCollector` and builds histograms in the bench layer.
`Window` carries no bench-only cfg fields, and the same event channel
can later feed the miniprofiler UI or an in-app frame-time HUD.

**`BenchDispatcher`** is a multithreaded `PlatformDispatcher` for
benchmarks: background tasks run on a worker pool (same priority queue
as `LinuxDispatcher`, with task-profiler hooks), timers fire in real
time on a dedicated thread, and foreground tasks queue until the bench
thread drains them with a blocking `run_until_idle()`. Unlike
`TestDispatcher`, work executes in parallel in real time, so wall-clock
measurements reflect production concurrency. In-flight accounting is
panic-safe via drop guards.

**`gpui::bench_platform()`** returns a per-process `TestPlatform` backed
by the `BenchDispatcher`, cached in a thread-local so worker threads
persist across Criterion calibration passes. This replaces the earlier
approach of constructing a real platform per invocation, which had
process-global singleton issues, never ran foreground tasks (no run loop
pumped the main queue), and couldn't open windows on headless CI.

**Text shaping** uses `NoopTextSystem`: deterministic across
machines/font installations and CI-portable. Measured cost of this
trade: ~10% of editor draw time vs `MacTextSystem` (Noop still emits one
glyph per character at fixed advances, so downstream layout/paint
structure is preserved).

**GPU coverage (macOS only for now).** `PlatformHeadlessRenderer` gained
`render_scene`, which encodes and submits the scene to Metal against a
cached offscreen target without blocking on completion or reading pixels
back — matching production `present()` CPU cost (`render_scene_to_image`
would overstate it: it waits for the GPU and copies pixels back).
`TestWindow::draw` forwards scenes to the renderer, the real
`MetalAtlas` means glyph/SVG rasterization happens during paint, and
`bench_renderer` presents after each measured update. Platforms without
a headless renderer degrade to discarding the scene.

## Example

```rust
#[gpui::bench]
fn editor_render(cx: &mut BenchAppContext) {
    init_context(cx);

    let buffer = cx.update(|cx| { /* build a MultiBuffer */ });

    let mut window = cx.add_empty_window();
    let editor = window.update(|window, cx| {
        let editor = window.replace_root(cx, |window, cx| {
            let mut editor = Editor::new(EditorMode::full(), buffer, None, window, cx);
            editor.set_style(editor::EditorStyle::default(), window, cx);
            editor
        });
        window.focus(&editor.focus_handle(cx), cx);
        editor
    });

    let mut move_down = true;
    cx.bench_renderer(editor, move |editor, window, cx| {
        if move_down {
            editor.move_down(&MoveDown, window, cx);
        } else {
            editor.move_up(&MoveUp, window, cx);
        }
        move_down = !move_down;
    });
}
```

## Example output (release, M-series)

```
editor_render           time:   [329.75 µs 330.17 µs 330.69 µs]

GPUI bench report (all observed iterations): editor_render
  note: includes Criterion warmup/calibration
  window dirty-to-draw:
    samples: 31533
    mean: 0.321ms
    p50: 0.322ms
    p90: 0.336ms
    p95: 0.342ms
    p99: 0.360ms
    max: 0.504ms
    frame budget overruns total: 0
    frame budget overruns max: 0
  window draw:
    samples: 31533
    mean: 0.295ms
    p50: 0.295ms
    p90: 0.307ms
    p95: 0.313ms
    p99: 0.330ms
    max: 0.455ms
    frame budget overruns total: 0
    frame budget overruns max: 0
  invalidations per frame: mean 5.00, max 5
```

(`invalidations per frame: mean 5.00` is real signal: each `move_down`
notifies the window five times before the draw.)

## Known limitations

- **Draw-per-flush**: the harness draws synchronously when effects flush
rather than coalescing invalidations to a vsync tick, so `dirty-to-draw`
excludes queueing delay, and `frame budget overruns` is a draw-time
budget proxy rather than actual missed presents. A frame-paced mode is
natural follow-up work.
- **GPU submission is measured on macOS only**; other platforms have no
headless renderer yet.
- The GPUI report includes Criterion warmup/calibration samples (noted
in the output); Criterion's `time` is the regression-gating number.
- `run_until_idle` waits for queued, running, and already-due work, but
not for timers that haven't reached their due time — the dispatcher runs
in real time and can't skip ahead like `TestDispatcher`'s virtual clock.

## Future work

- A vsync-like frame-pacing mode (suppress draw-on-flush; tick-driven
draw + present) so dirty-to-draw captures queueing delay
- Record present duration in `FrameTiming` so the report can split draw
vs present
- Benches that scroll through novel content (cold layout caches) and an
agent-panel render bench
- Headless renderers for Windows/Linux
- Move benches into a dedicated crate

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

Release Notes:

- N/A
2026-06-10 09:26:50 +00:00
Richard FeldmanandBennet Bo Fenner 5c6fbb2674 Add telemetry for context compaction (#58928)
Adds an `"Agent Compaction Completed"` telemetry event that fires for
both threshold-triggered auto-compaction and the manual `/compact`
command (both already behind the `handoff` flag). The event records the
model, model provider, thinking effort, the model's context window size,
the token counts immediately before and after compaction, whether the
compaction succeeded/failed/canceled (with the error string on failure),
the user's configured auto-compaction threshold (both the raw form and
the resolved absolute token count), whether auto-compaction is enabled,
and the number of retries.

Both compaction paths funnel through `stream_compaction`, so a
`CompactionTelemetry` snapshot is captured when a compaction starts and
stashed on the thread. On success, emission is deferred until the next
completion request reports usage, so `tokens_after` reflects the real
post-compaction context size rather than an estimate (we have no
token-counting API, and it's safe to assume a compaction is always
followed by another request). On failure or cancellation the event fires
immediately with no `tokens_after`. Retries are accumulated across
attempts so a single logical compaction produces exactly one event.

While wiring up retry counting I noticed the existing auto-compaction
retry path in `run_turn_internal` never increments `attempt`, so a
repeatedly-failing retryable compaction could retry without bound. I
left that behavior untouched as out of scope, but the new `retries`
field will surface it if it happens.

Release Notes:

- N/A

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-10 09:20:25 +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
Bennet Bo Fenner 97fab606c9 agent: Improve compaction UX (#58913)
Makes it so that we show "Compaction cancelled" when the user interrupts
generation.
Also fixes another small issue where the chevron of the expanded state
would not reflect if it is expanded/collapsed while there is no summary
yet.

Release Notes:

- N/A
2026-06-09 11:34:38 +00:00
Richard FeldmanandBennet Bo Fenner df4528c941 Add auto_compact agent settings (#58883)
Adds two new agent settings nested under `auto_compact`, `enabled` and
`threshold`, which control automatic compaction of the agent's context
window as part of the handoff feature. Both surface in the settings UI
under Agent Configuration, gated behind the `handoff` feature flag so
they only appear for users on that flag.

The `threshold` accepts three forms: a percentage string ending in `%`
(e.g. `"80%"` or `"95.5%"`) measured against the model's context window,
a positive integer to compact after that many tokens have been used, or
a negative integer to compact once that many tokens remain in the
window. `0` and bare non-integer numbers are rejected. It deserializes
from either a JSON string or integer and resolves to a typed enum,
falling back to the `"80%"` default (with a logged warning) when the
configured value is invalid. In the settings UI the threshold is a
free-form text field so all three forms can be entered.

Release Notes:

- N/A

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-09 10:52:58 +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
Veesh GoldmanandClaude Opus 4.8 576a2a3e17 agent: Don't offer feature-flag-gated tools in agent profiles (#58581)
Closes #56778

## Problem

The agent-profile tool configuration lists every built-in tool from
`agent::ALL_TOOL_NAMES`, filtering only by provider support
(`crates/agent_ui/src/agent_configuration/manage_profiles_modal.rs`).
But `Thread::enabled_tools` additionally drops feature-flag-gated tools
before they reach the model — the LSP tools (`go_to_definition`,
`find_references`, `get_code_actions`, `apply_code_action`) behind
`LspToolFeatureFlag`, `rename_symbol` behind `RenameToolFeatureFlag`,
and `create_thread` / `list_agents_and_models` / `update_plan` /
`update_title` behind their own flags.

The result: when a flag is off, a user can enable the tool in a profile,
but the agent never receives it. The picker and the runtime gate
disagreed.

## Fix

Extract the feature-flag gating into a single shared predicate,
`agent::tool_feature_flag_enabled`, and route **both**
`Thread::enabled_tools` and the profile tool picker through it. The
configuration UI can no longer offer a tool the agent would silently
drop, and the two call sites can't drift apart. Also updated the "silent
drop gates" comment in `tools.rs` to document this third gate.

This matches the behavior requested in the issue (don't list tools that
can't be used). The alternative — showing them disabled with an
explanation — is also possible; happy to switch if preferred.

## Testing

- Added `lsp_tools_are_gated_by_their_feature_flag` in
`crates/agent/src/tools.rs`.
- `cargo test -p agent`, `cargo clippy -p agent`, and `cargo fmt` are
clean.
- (`agent_ui` doesn't build in my local environment due to an unrelated
`webrtc-sys` C++ toolchain issue; the `agent_ui` change is a one-line
filter addition mirroring the adjacent provider-support check — relying
on CI to confirm.)

Release Notes:

- Fixed feature-flag-gated tools (such as the LSP tools) being listed in
agent profile configuration when they could not actually be used by the
agent.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 09:17:11 +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
MartinYe1234 cfa58e5a8c Restore access to old threads that mention rules (#58560)
Removing the `Rule` variant from `MentionUri` in #58080 broke
deserialization of any thread saved before the rules-to-skills
migration. Loading one failed with `unknown variant `Rule``, making
those threads inaccessible.

This restores access without bringing back the rules feature:

- Reintroduce a backward-compatible `Rule` mention variant so legacy
threads deserialize again.
- Preserve the original rule `id` through save/load so a thread re-saved
by a newer build still loads on older Zed versions (and synthesize a
valid placeholder when the id is missing).
- Clicking a legacy rule mention now opens the skill the rule was
migrated into, and shows a notification linking the Skills docs. On
remote/collab projects the migrated file lives on the local machine, so
it opens as a read-only buffer. If no matching skill exists, it does
nothing.

Closes https://github.com/zed-industries/zed/issues/58498
Closes AI-371

Release Notes:

- Fixed old threads that mention Rules being inaccessible after Rules
were migrated to Skills
2026-06-04 16:53:09 +00:00
MartinYe1234 da7945aeae Hide Always Allow option for agent skills edits (#58463)
Edits targeting the agent skills directory (project `.agents/skills/`
and global `~/.agents/skills/`) always prompt regardless of permission
settings, because they route through `authorize_always_prompt` which
never consults the persisted `always_allow` rules.

The permission prompt still rendered an "Always allow" button, though.
Clicking it wrote an `always_allow` rule into settings that was then
silently ignored on the next skills edit, so users were re-prompted
every time despite having chosen "always allow" — exactly the confusion
reported in AI-346.

This keeps the always-prompt behavior intact and just hides the
misleading "Always allow" / "Always deny" options for skills, leaving
once-only Allow/Deny. Applies to all mutating skills tools: `edit_file`,
`write_file`, `copy_path`, `move_path`, `delete_path`, and
`create_directory`.

Implementation:
- New `ToolPermissionScope::AgentSkills`, set via
`ToolPermissionContext::for_agent_skills()`.
- `build_permission_options` returns flat once-only Allow/Deny for that
scope (mirrors the existing `SymlinkTarget` handling).
- Wired into both authorization entry points (`authorize_file_edit` and
`authorize_with_sensitive_settings`).
- Tests assert no `AllowAlways` option is offered for each affected
tool.

Settings-file prompts (`.zed/settings.json`, global config) are
intentionally left unchanged.

Closes AI-346

Release Notes:

- Removed the misleading "Always allow" button from agent permission
prompts for edits to the agent skills directory, since those edits
always require confirmation.
2026-06-04 15:39:02 +00:00
Anant GoelandBen Brandt 5f2eba257d agent: Accumulate and persist cumulative token usage for threads (#58378)
`Thread::cumulative_token_usage` has been dead code since the agent2
rewrite: the field was added as a persistence placeholder in #36483 with
`#[allow(unused)]`, and the accumulation logic was deleted along with
agent1 in #40495. Since then, every saved thread persists
`cumulative_token_usage` as `{}` in `threads.db`, breaking offline
token-usage analysis and silently degrading eval reporting (`eval_cli`
prefers this value and was always falling back to the last request's
snapshot, undercounting multi-step turns).

This PR restores the accumulation, mirroring the original agent1
implementation:

- Providers emit multiple cumulative-per-request `UsageUpdate` snapshots
during a single request, so naive `+=` would double-count. We track the
previous snapshot for the in-flight request
(`current_request_token_usage`) and accumulate only the delta, resetting
the tracker each time a new completion request is built in
`run_turn_internal`. This counts each request exactly once, including
tool-call rounds and retries within a turn.
- Unlike agent1, the delta uses per-field `saturating_sub` instead of
the panicking `Sub` impl, so a provider reporting a smaller snapshot
can't crash Zed.
- Removed the `#[allow(unused)]`; the value now round-trips through
`to_db`/`from_db`, surviving restarts and continuing to grow when a
thread is reopened.
- Added a `cumulative_token_usage()` accessor following the
`latest_request_token_usage` convention.

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

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-06-04 15:24:02 +00:00
Anthony Eid 0e559e5519 agent: Fix a UTF-8 boundary panic in the agent streaming parser (#58432)
The parser stores emitted byte offsets between partial tool-call parses.
Because partial JSON can be repaired differently as more bytes arrive, a
byte offset that was valid in an earlier string can land inside a
multibyte character in a later string. We now normalize those offsets
with `find_char_boundary` before slicing.

Added property tests covering boundary-sensitive write/edit streaming
sequences to prevent regressions.

Fixes Sentry ZED-8Y1 / 7523469866.

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:

- Fixed a crash that could occur while streaming agent edits containing
multibyte characters.
2026-06-03 15:49:01 +00:00
Bennet Bo FennerandRichard Feldman 7a1d4e670b agent: Fix compaction limit (#58431)
Release Notes:

- N/A

Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-06-03 15:39:50 +00:00
d178767443 sidebar: Add right-click menu to thread items (#58232)
Closes AI-286

This PR adds a right-click menu to thread items in the sidebar. A big
motivation for this addition was surfacing the "regenerate thread title"
action. And because this action and the "open thread as markdown" action
previously only worked on the already-loaded agent panel, there was a
load of plumbing needed to make that work even for threads in workspaces
that haven't been loaded, mostly using the thread metadata store. At the
end of the day, the title regeneration feature is only possible for the
Zed agent, so this is gated from external agents. But I believe it's now
in a slightly nicer spot due to some refactors to better expose the
state in which the title regeneration can fall into.

Release Notes:

- Agent: Added a right-click menu to thread items in the sidebar,
allowing to regenerate a thread title, rename a thread title, open the
thread as markdown, and archive it.

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-03 13:44:48 +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
2f6b1a6997 Improve sandbox write-path handling (#58283)
Follow-up hardening on top of #57972 (granular sandbox write
permissions), based on a review of that branch. The most important fix
is that model-requested `fs_write_paths` were joined but never
normalized, so a path containing `..` could pass the lexical
subtree-containment checks while seatbelt canonicalized it to somewhere
else entirely — causing skipped approval prompts and silent runtime
write denials. Write paths are now lexically normalized (via
`util::paths::normalize_lexically`) at the point they enter the system,
both for model requests and for hand-edited persistent grants, so the
containment check, the approval prompt, and the enforced sandbox policy
all operate on the same path.

The subtree insert/prune and containment logic had drifted into roughly
five near-identical copies across `agent`, `agent_settings`, and
`settings_content`; these now share `util::paths::insert_subtree` and
`path_within_subtree`. The dead `SandboxPermissions::covers` (only ever
exercised by its own tests, duplicating the production
`covers_with_persistent`) is removed, and its tests rewritten to cover
the real settings-compilation path including `..` normalization.

The remaining changes reduce brittleness: the sandbox permission option
ids (`allow`, `allow_thread`, `allow_always`, `deny`) are now shared
constants in `acp_thread` instead of bare string literals scattered
across the agent and UI, `persist_sandbox_always_permission` logs
instead of silently doing nothing when no filesystem is available, and a
comment documents why replay always resolves the terminal tool to the
non-sandboxed variant.

Release Notes:

- N/A

---------

Co-authored-by: Martin Ye <martin@zed.dev>
Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
2026-06-02 18:15:07 +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
e25ce9e8a0 agent: Implement compaction (experimental) (#58315)
Release Notes:

- N/A

---------

Co-authored-by: Gaauwe Rombouts <mail@grombouts.nl>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-06-02 15:11:58 +00:00
6d9ed1fc35 Add granular per-path write permissions for the agent terminal sandbox (#57972)
Adds granular, per-path write permissions to the agent's sandboxed
`terminal` tool.

Previously a command could only request unrestricted filesystem writes
(`allow_fs_write: true`) as an all-or-nothing escape hatch. Now the
model can request write access to specific paths via `fs_write_paths`,
and each granted directory covers its whole subtree. The broad escape
hatch is still available as `allow_fs_write_all: true` for cases where
the paths can't be enumerated up front.

Approval prompts now let the user grant a write request either just for
that command or for the rest of the conversation. Conversation grants
are tracked in memory (never persisted) using pure subtree containment,
so later commands writing under an already-granted path run without
prompting again.

Closes AI-335
Release Notes:

- Improved the agent's terminal sandbox so commands can request write
access to specific paths instead of all-or-nothing filesystem access,
with the option to grant access for a single command or the rest of the
conversation.

---------

Co-authored-by: Anant Goel <anantdgoel@gmail.com>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-06-02 01:07:05 +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
Richard Feldman 377708befa agent: Enable terminal output controls for everyone (#58271)
Removes the feature flag around terminal output selection so the
terminal tool always exposes head_lines and tail_lines. This keeps the
simpler behavior from the landed implementation while avoiding a
separate rollout path for the tool schema.

Release Notes:

- Improved agent terminal output controls by making them available
without a feature flag
2026-06-01 21:29:15 +00:00
Richard Feldman 67cb7a1fdf agent: Add terminal output head and tail options (#58257)
Adds optional terminal tool parameters that let agents receive only the
first lines, last lines, or both from a command's final output while
leaving the live terminal output visible to users. This is gated by the
terminal-tail feature flag and updates the tool descriptions to steer
agents away from piping through head, tail, or similar filters.

Closes AI-36

Release Notes:

- Let agents use the terminal tool with builtin "head/tail" so they
don't have to pipe to head/tail and lose incremental output
2026-06-01 20:24:47 +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 FeldmanandBennet Bo Fenner 6d3015d2ba agent: Respect compaction boundaries in request windows (#58241)
Agent request construction now honors persisted compaction markers by
rebuilding the model-visible window from the latest boundary, retaining
recent user context for summary compactions, and treating
provider-native compactions as suffix-only until native replay lands.

Release Notes:

- N/A

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-01 16:00:38 +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
Richard BoisvertandChristopher Biscardi 8f4c983b68 git_ui: Add setting for custom commit message instructions (#58188)
There's currently no way to customize AI-generated commit messages on a
per-commit basis. You can put instructions in AGENTS.md or a project
rules file, but those get fed into every agent interaction, not just
commit generation. The built-in "Commit message" prompt used to be
editable in the Rules Library, but that was replaced by Skills, which
aren't used when generating commit messages.

This PR adds an `agent.commit_message_instructions` setting. Its
contents are added to the commit message prompt in their own section,
alongside any project rules, so you can ask for a specific format
(Conventional Commits, a ticket prefix, etc.) without changing how the
agent behaves elsewhere:

```json
{
  "agent": {
    "commit_message_instructions": "Use the Conventional Commits format: <type>(<scope>): <description>."
  }
}
```

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

Addresses #26503

Release Notes:

- Added an `agent.commit_message_instructions` setting to customize
AI-generated git commit messages.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-06-01 03:19:28 +00:00
Bennet Bo Fenner eb0e804713 agent_ui: Remove unused rule APIs (#58080)
Removes unused `@rule` mentions and unused APIs from `prompt_store`

Follow up to #58067

Release Notes:

- N/A
2026-05-29 15:27:28 +00:00
Jakub Konka efd671682b Revert "Improve ChatGPT subscription response resilience" (#58035)
Reverts zed-industries/zed#57891
2026-05-29 11:23:56 +00:00
Anthony Eid f0f2a96d90 agent: Batch streaming edit operations (#58037)
## Summary

While profiling agent sessions that make a lot of `edit_file`
operations, I noticed the LSP `textDocument/didChange` handler firing
excessively. Looking into this, I found out that the streaming edit
pipeline was applying each `CharOperation` from `StreamingDiff` as its
own `buffer.edit` transaction, and every transaction emits a
`BufferEvent::Edited` event. Each event can trigger several other
expensive events depending on whether the buffer is being rendered in an
editor or is registered with a language.

For example, there are `didChange` LSP events, the editor's on edit work
(matching brackets, bracket colorization, code actions, outline), and
more. A single `edit_file` could trigger hundreds of these at the higher
end in a single synchronous app update, which would block the foreground
thread for a bit and cause Zed to drop frames.

I fixed this by collecting all of a chunk's `CharOperation`s and
applying them in one `buffer.edit` call, so only a single
`BufferEvent::Edited` event gets emitted. This is safe because
operations are non overlapping by design of streaming diff (the edit
cursor only advances).

## Why this wasn't caught earlier

The cost only fully appears when a buffer is both registered with a
language server and rendered in an editor. Without that, most of the per
transaction observers never run, so the existing `edit_file_tool`
benchmark (which ran the tool against a bare buffer) didn't surface it.
I reworked the benchmark to open the edited buffer in an editor view,
register a fake language server with per edit diagnostics, and lay out a
frame, so it exercises the same cascade as the real editor. I also added
a larger fixture.

## Results

Measured with the `release-fast` profile on the reworked benchmark:

| Fixture | Initial file | Before | After | Improvement |
| --- | --- | --- | --- | --- |
| `tiny_function_rewrite` | 1.4 KB | 31.1 ms | 12.1 ms | −61% |
| `small_function_rewrite` | 3.0 KB | 42.4 ms | 19.3 ms | −55% |
| `medium_many_small_changes` | 4.6 KB | 309.2 ms | 151.5 ms | −51% |
| `medium_insertions` | 4.6 KB | 171.8 ms | 126.1 ms | −27% |
| `large_multi_edit` | 44 KB | 9,549 ms | 919 ms | −90% |

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

Release Notes:
- Improved agent's edit file tool performance
2026-05-29 09:49:55 +00:00
morgankrey f87a8ca82f Improve ChatGPT subscription response resilience (#57891)
## Summary

This started from #57636, after we saw ChatGPT subscription/Codex
requests stall over the past week. OpenCode v1.15.11 shipped related
resilience fixes for the same class of Codex subscription endpoint
issues, so this ports the relevant pieces into Zed's native ChatGPT
subscription provider.

When Zed asks ChatGPT/Codex for a response, sometimes the server
connection can get stuck before it even sends the first response
headers. Before this PR, Zed could wait indefinitely, which looks like
OpenCode/Zed “stalling.”

This PR makes Zed:

- Wait up to 10 seconds for the server to start responding.
- If nothing comes back in that window, treat it as a temporary
network/API failure.
- Let the existing retry logic try again instead of leaving the user
stuck.
- Send a stable session-id header so OpenAI’s Codex backend can
associate requests with the same Zed agent thread.
- Add tests to make sure:
  - stuck-before-response requests time out,
  - normal slow streaming responses are not cut off,
  - ChatGPT subscription requests send the right session header,
  - the agent retries this kind of failure.

intended user-facing result is: fewer “the assistant is just sitting
there forever” failures when using ChatGPT subscription models.

## Verification

- cargo test -p open_ai responses
- cargo test -p language_models openai_subscribed
- cargo test -p agent test_send_retry_on_http_send_error
- cargo check -p open_ai
- cargo check -p language_models
- cargo check -p agent

Release Notes:

- Fixed ChatGPT subscription requests stalling indefinitely before
response headers arrive.
2026-05-28 16:41:26 +00:00
Ben Kunkleandzed-zippy[bot] bf9255e53a ep: Fix agent edits triggering edit predictions due to diagnostic refresh (#57832)
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:

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

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-05-28 13:27:55 +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
Anthony Eid 35fd2dd9fc Speed up StreamingDiff::push_new part two (#57849)
Follow-up to #57772.

While comparing the `edit_file_tool_streaming/medium_insertions`
benchmark in Criterion and xctrace, I noticed the DP scoring loop was
spending most of its time on inlined `Matrix::get`/`Matrix::set` access
in `StreamingDiff::push_new`.

This changes the loop to split the previous and current score columns
once per DP column and then index those column slices directly. This
keeps the scoring algorithm the same, but hoists the column offset
calculation out of the inner loop and gives the compiler clearer
aliasing information between the immutable previous column and mutable
current column.

In xctrace, the hottest DP scoring line dropped from 10,407 samples
before to 9,409 samples after on
`edit_file_tool_streaming/medium_insertions`, and total
`StreamingDiff::push_new` leaf samples dropped from 10,800 to 9,822.

This is consistently faster in the end-to-end `edit_file_tool`
benchmark, and gives a small speed-up for the targeted workload without
changing the scoring algorithm.

### Results

Benchmarked with `release-fast` against a clean baseline using
Criterion’s `before_slice` baseline.

#### `streaming_diff_push_new`

| Fixture | Before median | After median | Change |
| --- | ---: | ---: | ---: |
| `tiny_function_rewrite` | `7.6317 ms` | `6.4951 ms` | 10.8% faster |
| `small_function_rewrite` | `45.961 ms` | `44.839 ms` | No significant
change |
| `medium_many_small_changes` | `99.694 ms` | `104.83 ms` | 5.2% slower
|
| `medium_insertions` | `95.909 ms` | `83.093 ms` | 13.5% faster |

#### `edit_file_tool_streaming`

| Fixture | Before median | After median | Change |
| --- | ---: | ---: | ---: |
| `tiny_function_rewrite` | `1.1110 ms` | `1.0617 ms` | 7.1% faster |
| `small_function_rewrite` | `2.4554 ms` | `2.2751 ms` | 7.1% faster |
| `medium_many_small_changes` | `87.272 ms` | `77.065 ms` | 11.5% faster
|
| `medium_insertions` | `92.469 ms` | `87.478 ms` | 5.9% faster |

The lower-level `streaming_diff_push_new` benchmark is mixed, but the
end-to-end `edit_file_tool_streaming` workload improves across all
fixtures.

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 or Added/Fixed/Improved ...
2026-05-27 19:33:04 +00:00
cb1518128b markdown: Merman (#57644)
Big PR that replaces `mermaid-rs` with `merman`.

Adds a new crate `mermaid_render` that exposes a simple API for
rendering a mermaid diagram to an SVG string.

## Why is it so big?

Some of this is explained in the crate-level docs for `mermaid_render`,
but the short version is:
- `mermaid-rs` emits "good enough" SVGs for most use cases. It also
ships with a reasonable default theme
- `merman` emits *very accurate* SVGs, but with borderline unusable CSS
- Most of the new code in this PR are a series of passes to clean up the
output SVG by:
  - Injecting good CSS
  - Fixing issues in the `merman`-generated SVGs
- Tweaking the final result to avoid issues with `usvg` and `resvg`,
which are what will eventually be used to rasterize the SVG
- This code *could* be much smaller, but the following design decisions
made it take a lot more code:
  - Using a real XML parser instead of basic string manipulation
  - Avoiding allocating strings in as many places as possible

Because of this, the design is as follows:
- First, construct a `merman` theme from the user's theme, and render
the mermaid to an SVG string
- Post-process - each step is roughly a `fn(Iterator<Item =
Event<'short>>) -> Iterator<Item = Event<'short>>`, where `Event` is the
type for events produced by `quick-xml` (a pull-based XML parser)
 

## Note for reviewers

It's a big diff, sorry 😅 happy to pair review. 

The new crate is essentially a leaf crate - it does technically depend
on `gpui`, but only for the `Hsla` and `Rgba` types. Extracting a new
`gpui_color` crate felt like overkill for this already-very-big PR.

Each post-process pass is in its own submodule, and has a doc comment
explaining the before/after. Note that bugs in this code are perhaps
less serious than bugs in other parts of the code:
- The code has been thoroughly audited for potentially-panicking code
paths - as far as I know, there are none (excluding some `.expect()`s on
calls to `write!` with `String`, which is [cannot return `Err`][string
write])
- A bug in this code (given that it will not cause a panic) will, at
worst, result in an invalid diagram being rendered, or simply falling
back to showing the code.
- The current `mermaid-rs` renderer *already* does this in quite a lot
of cases, sometimes showing outright misleading information.
---

Some eye candy:
| Before (`mermaid-rs`) | After (`merman`) |
| - | - |
| <img width="1227" height="340" alt="image"
src="https://github.com/user-attachments/assets/58d6904e-64bc-478a-8d67-f75ad4ccbc9e"
/> | <img width="1169" height="482" alt="image"
src="https://github.com/user-attachments/assets/d4bb9cd5-240f-4bf6-ba7f-4862049ed8b0"
/> |
| <img width="842" height="564" alt="image"
src="https://github.com/user-attachments/assets/1668a50d-68f6-4145-8cef-359e4c6a4589"
/> | <img width="869" height="543" alt="image"
src="https://github.com/user-attachments/assets/2ec1a7eb-fc3c-4392-b577-1ad52396b87c"
/> |
| Failed to render | <img width="822" height="1123" alt="image"
src="https://github.com/user-attachments/assets/a97308a1-6b3a-48b6-9778-abf3507c6ad3"
/> |
| <img width="252" height="517" alt="image"
src="https://github.com/user-attachments/assets/dbf86274-004a-4ee4-be89-cc6ff4f6cf35"
/> | <img width="361" height="680" alt="image"
src="https://github.com/user-attachments/assets/8457b6ed-3ca9-4bed-9496-60388ba08206"
/> |
| <img width="550" height="1050" alt="image"
src="https://github.com/user-attachments/assets/c21b8513-fb86-422e-870a-015e0add783a"
/> | <img width="819" height="1148" alt="image"
src="https://github.com/user-attachments/assets/ca646165-302d-41aa-8da5-39e89c96ebb7"
/> |
| <img width="1218" height="225" alt="image"
src="https://github.com/user-attachments/assets/3006a1bf-efe6-46f5-9f9d-289a3fdf9adc"
/> | <img width="1118" height="965" alt="image"
src="https://github.com/user-attachments/assets/90d76098-bf3d-4c69-bc9b-00dd9cbf6990"
/> |
| <img width="800" height="584" alt="image"
src="https://github.com/user-attachments/assets/f688693b-df3d-4514-b105-ccaa3874e40c"
/> | <img width="1153" height="417" alt="image"
src="https://github.com/user-attachments/assets/eeb05f58-7184-4321-a47b-ea3cc53f0d02"
/> |
| <img width="539" height="464" alt="image"
src="https://github.com/user-attachments/assets/0076105d-eef9-4011-9b9a-581918575e49"
/> | <img width="638" height="556" alt="image"
src="https://github.com/user-attachments/assets/72a51966-c296-48d0-b1e2-66835b1a0d5b"
/> |
| <img width="607" height="430" alt="image"
src="https://github.com/user-attachments/assets/d3530814-532b-41ed-a2b6-fd5740d8db58"
/> | <img width="725" height="489" alt="image"
src="https://github.com/user-attachments/assets/c43687d9-f426-4cb8-8a45-23a3c0070c8f"
/> |
| <img width="869" height="577" alt="image"
src="https://github.com/user-attachments/assets/b607f3fd-136c-4f41-a88e-596520e276b9"
/> | <img width="784" height="586" alt="image"
src="https://github.com/user-attachments/assets/22305a64-b4d0-474a-b6f6-8973f2bca933"
/> |
| <img width="1214" height="263" alt="image"
src="https://github.com/user-attachments/assets/183ff0df-a6f3-470c-b271-8099c3e33044"
/> | <img width="1195" height="632" alt="image"
src="https://github.com/user-attachments/assets/868bcb7f-62c6-4d20-ba1e-3f25f8165fff"
/> |
| <img width="573" height="597" alt="image"
src="https://github.com/user-attachments/assets/6414e409-b879-4892-8ef6-89489219b56f"
/> | <img width="578" height="608" alt="image"
src="https://github.com/user-attachments/assets/8ac71b03-f603-4e32-87aa-b993317d4e29"
/> |
| <img width="543" height="472" alt="image"
src="https://github.com/user-attachments/assets/1f19929c-cf07-4287-b9cf-b976eea9faaa"
/> | <img width="760" height="599" alt="image"
src="https://github.com/user-attachments/assets/73926075-db47-4eb1-854e-7aee30522684"
/> |
| <img width="1205" height="219" alt="image"
src="https://github.com/user-attachments/assets/5f3dc936-4b89-44f4-a00a-4dbc47e06504"
/> | <img width="1133" height="349" alt="image"
src="https://github.com/user-attachments/assets/e62901ff-9d75-4fde-a30e-974ff2e783b1"
/> |


Release Notes:

- Improved: Mermaid diagrams now render faster and more accurately

[string write]:
https://doc.rust-lang.org/src/alloc/string.rs.html#3342-3354

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-05-27 16:27:18 +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
MartinYe1234 bed089c8cd Allow path tools to operate on global agent skills (#57760)
Extends the same `~/.agents/skills` special case that
`create_directory`, `edit_file`, and `write_file` already use to the
path tools, so the agent can copy or move skills into and out of the
global skills folder and delete individual skills or skill resources
beneath it.

- `copy_path` now allows source and/or destination to be a descendant of
`~/.agents/skills`, going through `fs::copy_recursive` directly when one
side is outside the project.
- `move_path` now allows source and/or destination to be a descendant of
`~/.agents/skills`, going through `fs.rename` directly when one side is
outside the project. Moving the `~/.agents/skills` root itself is
rejected.
- `delete_path` now allows deleting any file or directory beneath
`~/.agents/skills`, going through `fs.remove_dir` / `fs.remove_file`
directly. Deleting the `~/.agents/skills` root itself is rejected.
- All three tools still always prompt for approval on agent-skill paths,
even when default tool permissions are set to allow.
- Added shared helpers in `tool_permissions.rs` for resolving global
skill descendants and rejecting operations on the skills root where
needed.
- Added tests covering copying and moving skills in both directions,
deleting a global skill directory/file, and rejecting deletion of the
skills root.

Release Notes:

- Agent can now copy or move skills into and out of `~/.agents/skills`
and delete individual skills, with an explicit confirmation prompt for
each operation
2026-05-27 14:02:18 +00:00
Lukas Wirth 3055f0a908 sidebar: Improve performance of rebuild_contents (#57717)
Release Notes:

- N/A or Added/Fixed/Improved ...
2026-05-27 10:31:57 +00:00
Lukas Wirth 6f4aee7074 Bump ctor (#57728)
Otherwise miri might fail in some gpui projects on macos.

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-05-27 10:31:53 +00:00
MartinYe1234andRichard Feldman a33fd709b2 Allow agent tools to edit global skills (#57678)
Summary

- Allow write_file and edit_file to create or modify files under
~/.agents/skills.
- Keep the global skills exception constrained to that directory and
preserve existing project-path behavior.
- Document global skill file editing support in the built-in
create-skill instructions.

Tests

- cargo fmt -p agent
- cargo test -p agent global_skill_file
- cargo test -p agent
test_create_directory_allows_global_skill_directory

Release Notes:

- Fixed agent file editing for global skills

---------

Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-05-26 20:16:43 +00:00