* feat: Amp support - read the local thread mirror (#1572) Amp (Sourcegraph's coding agent) mirrors every thread it serves as one JSON document per thread at ~/.local/share/amp/threads/ (AMP_DATA_DIR honored, comma-separated). Each file is { id, messages, usageLedger?{events} }; the ledger's events are the per-request record (tokens.input/output, cache tokens joined from the billed message through toMessageId -> messages[].messageId), with a per-assistant- message usage fallback for threads without a ledger and a total-only record billing as output. Amp bills a subscription and records no charged dollars, so every call is priced from the underlying model's token rates and marked costIsEstimated; the recorded credits field is ignored (no published per-credit dollar rate). Thread files carry no cwd, so sessions group under the provider name. Registered eager; parse version usage-ledger-v1; no artwork yet (mono-initial fallback, like Codebuff). Surfaces: CLI registry + doctor probe roots, Electron sandbox read paths + menubar catalog (Amp after Cursor, matching the Swift order), Windows tray tab color + usage_guard root, GNOME prefs dropdown, macOS ProviderConnectionCatalog, docs/providers/amp.md, README tool list, CHANGELOG. * fix: address Amp provider review feedback
3.6 KiB
Amp
Amp, Sourcegraph's coding agent (ampcode.com), as a CLI or editor extension. Reported in #1572.
- Source:
src/providers/amp.ts - Loading: eager (
src/providers/index.ts) - Test:
tests/providers/amp.test.ts
Where it reads from
$AMP_DATA_DIR/threads/ (or ~/.local/share/amp/threads/). AMP_DATA_DIR is Amp's own override; CodeBurn accepts a comma-separated list the way Amp does. One JSON document per thread, discovered recursively under threads/**/*.json.
Storage format
A thread file is { id, messages: [...], usageLedger?: { events: [...] } }. usageLedger.events is the per-request record: { id, timestamp, model, tokens: { input, output, total }, toMessageId, credits }. Cache tokens are not on the event - they live on the thread message the event billed for, joined through toMessageId -> messages[].messageId -> usage.cacheCreationInputTokens / usage.cacheReadInputTokens. Threads without a ledger fall back to per-assistant-message usage blocks ({ inputTokens, outputTokens, cacheCreationInputTokens, cacheReadInputTokens, totalTokens, timestamp, model }, with timestamp and model allowed on the message itself). The format is mapped against ccusage's amp adapter, which parses real thread files.
Token model
Ledger-first. When a thread carries a usage ledger, each event is one call. Any positive remainder of tokens.total after subtracting input, output, and both cache-token counts is added to output. A total-only tokens record ({"total": N}) without cache tokens therefore bills as N output tokens. Cache tokens come from the billed message via toMessageId; a record whose toMessageId does not resolve prices without cache. No reasoning field exists, so reasoningTokens is 0.
Fallback. Without a ledger, every assistant message with a usable usage block is one call.
A record with all four token fields empty or malformed contributes nothing; untrusted numbers are clamped to finite non-negative before they can reach the aggregate.
Pricing
Every call is priced from the model's token rates in src/models.ts and carries costIsEstimated; Amp's own credits field is not converted. Amp's model ids are the underlying OpenAI/Anthropic/Google ids and price through the standard catalog.
Caching
Cache-read and cache-creation counts arrive through the ledger join (or the message's usage block). Token-priced costs are not cached; the cached call is re-priced on read, so a pricing update reaches history.
Deduplication
Per amp:<thread-id>:<event-id> from the ledger, or amp:<thread-id>:<timestamp>:<model> on the message fallback path.
Quirks
- No project attribution. Thread files carry no cwd, so Amp sessions group under the provider name (
Amp) instead of a repository. - No tool capture. Thread files expose no tool-call records CodeBurn could read, so
toolsandbashCommandsare empty. - Estimated costs by design. Every call is marked
costIsEstimated(see Pricing). Token counts themselves are provider-recorded. creditsis not converted. CodeBurn estimates cost from tokens rather than summing Amp's recorded credits.
When fixing a bug here
- Discovery: check the recursive
threads/**/*.jsonwalk, the.jsonextension filter (without reading file contents), and theAMP_DATA_DIRresolution (comma-separated). - Token accounting: see
parseThreadFile(ledger join throughtoMessageId->messages[].messageId, then the per-message fallback). - Add a fixture-format thread under
tests/providers/amp.test.ts; do not mock the filesystem.