Skip to content

feat(providers): add Zed agent provider#594

Merged
iamtoruk merged 3 commits into
mainfrom
feat/zed-provider
Jul 2, 2026
Merged

feat(providers): add Zed agent provider#594
iamtoruk merged 3 commits into
mainfrom
feat/zed-provider

Conversation

@iamtoruk

@iamtoruk iamtoruk commented Jul 2, 2026

Copy link
Copy Markdown
Member

Closes #480.

Adds a provider for Zed's built-in agent. Full credit to @chatzinikolakisk for documenting the on-disk format in the issue; the schema was additionally verified byte-for-byte against a real Zed install.

How it works

  • Single source: threads.db (macOS ~/Library/Application Support/Zed/threads/threads.db, with Linux and Windows paths mapped). One row per thread; the data blob is zstd-compressed JSON.
  • Each thread's request_token_usage map is emitted as one call per request with exact input/output/cache_creation/cache_read token fields (Anthropic semantics), priced through the existing LiteLLM engine, deduped as zed:<threadId>:<requestId>.
  • In-progress threads with an empty per-request map fall back to cumulative_token_usage so they still count.
  • Decompression uses Node's built-in zlib.zstdDecompressSync (no new dependency). It ships from Node 22.15; since the package floor is 22.13, the provider feature-detects and skips with a notice on older Nodes, mirroring the node:sqlite guard.
  • Registered as a lazy provider like the other SQLite-backed ones, so --provider zed validates and non-Zed users load nothing extra.

Testing

  • Six fixture tests build a real threads.db (exact schema) with zstd-compressed thread JSON: per-request emission with exact token fields, cumulative fallback, non-zstd and malformed-blob skipping, cross-parse dedup, zero-usage threads, and missing-DB discovery.
  • Full suite passes (1,393 tests). CLI smoke against a real (empty) Zed install runs clean.

Known limits

  • Per-request timestamps do not exist in the map, so all of a thread's calls carry the thread's updated_at; day-level attribution for long-running threads is approximate.
  • The local install used for verification has an empty threads table, so numbers were validated via fixtures, not real history. @chatzinikolakisk, if you are up for it, running codeburn overview --provider zed on this branch against your real usage and posting the result would be a great validation.
  • folder_paths is not yet mapped to per-project attribution; all Zed usage lands under a single zed project for now.

iamtoruk added 3 commits July 2, 2026 05:41
Reads Zed's agent threads from the single threads.db SQLite store: each
row's zstd-compressed JSON carries the thread model and per-request
Anthropic-shaped token usage, so calls are emitted per request with
exact input/output/cache fields and priced through the existing engine.
In-progress threads with an empty per-request map fall back to the
cumulative counter. zstd comes from node:zlib, which ships it from
22.15; on older Nodes the provider skips with a notice instead of
failing. On-disk format documented by @chatzinikolakisk in #480 and the
schema verified against a real Zed install.
Zed's DataType enum carries both zstd (the current save path) and json;
verified against crates/agent/src/db.rs, along with the exact TokenUsage
field names, the SerializedLanguageModel {provider, model} shape, and
RFC3339 updated_at serialization.
Validated against a real thread: request_token_usage is keyed by user
message and covered only part of the requests (cumulative was ~3x the
map sum), so per-request calls are now supplemented by one remainder
entry that brings each thread exactly to cumulative_token_usage. Live
run matches the store token-for-token on all four fields.
@iamtoruk

iamtoruk commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

Validated end-to-end against a real Zed thread now (fresh install, real agent chat): the provider's output matches the store token-for-token on all four fields (input 37,786 / output 3,594 / cacheRead 176,640 / cacheWrite 0). Two findings from the live data are folded in: the per-request map undercounts (cumulative was ~3x the map sum), so threads now top up to the exact cumulative counter with a remainder entry, and legacy uncompressed json rows are read alongside zstd. Format details additionally verified against Zed's source (crates/agent/src/db.rs: DataType, DbThread, TokenUsage, SerializedLanguageModel).

@iamtoruk iamtoruk merged commit 1690483 into main Jul 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Zed agent provider (threads.db / zstd JSON schema documented)

1 participant