opencode-anthropic-optimizer
v0.1.8
Published
Anthropic account connector and context optimizer for OpenCode.
Readme
opencode-anthropic-optimizer
Anthropic account auth and request optimization for OpenCode.
This plugin is for people who use OpenCode with Anthropic models and want lower repeated-context usage in long tool-heavy sessions.
Responsibility
This plugin is provided with no guarantees. It changes how OpenCode authenticates and sends requests, and it may affect agent behavior, account usage, costs, or standing with a provider.
Review the code and configuration before using it. You are responsible for your own usage, credentials, costs, and compliance with any provider terms. Do not use this plugin for abusive traffic patterns or unattended high-volume loops.
Quick Start
Add the plugin to your OpenCode config:
{ "plugin": ["[email protected]"] }Pinning the version avoids unexpected plugin changes on startup.
Start OpenCode, choose Anthropic account, and complete the auth flow.
That is the normal setup. Optimization is enabled by default.
Measured Impact
These are local benchmark runs from this repository using claude-opus-4-8 / high reasoning on read-only code-inspection tasks. They are not a billing guarantee.
| Scenario | OpenCode + optimizer | Comparison | Result |
|---|---:|---:|---:|
| Single deterministic task | $0.104372 | Claude Code $0.103958 | roughly parity |
| 4-turn continued session | $0.570947 | Claude Code $0.729381 | 21.7% lower |
| 4-turn continued rerun | $0.664518 | Claude Code $0.729381 | 8.9% lower |
| 4-turn session, optimizer off | $1.767615 | Optimizer $0.570947 | 67.7% lower with optimizer |
In these local tests, optimized OpenCode was roughly 2x-3x cheaper than unoptimized OpenCode for long tool-heavy sessions. Larger savings are possible when the unoptimized request shape repeatedly rewrites large volatile context, but they should be treated as workload-specific rather than guaranteed.
The largest reduction came from stable prompt-cache handling and shrinking repeated request context. Quality is workload-dependent; the optimizer preserves tool schemas and compact skill metadata because removing those saved tokens but hurt routing/answer quality in testing.
What Gets Optimized
The plugin rewrites Anthropic requests before they leave OpenCode.
Stable prompt-cache handling
Tool-use and tool-result message blocks change every turn. The plugin removes cache markers from those volatile blocks while preserving stable cache markers on system/user/tool sections. This reduces expensive cache rewrites.
Cache marker safety
Anthropic accepts at most 4
cache_controlblocks per request. The plugin enforces that limit after all request rewriting, so long sessions do not fail with cache-marker overflow.Static prompt slimming
OpenCode can send large static system sections on every request. The plugin removes OpenCode-specific prompt bloat such as task-management text, tool-policy text, branding, and docs links while preserving project/user instructions and compact skill metadata.
Tool definition compaction
Long top-level tool descriptions are shortened. Tool schemas are preserved because stripping schema details reduced quality in testing.
Old transcript compaction
Once message history grows past the configured byte budget, old text blocks are compacted. Recent messages stay intact. The default keeps the newest 2 messages fully intact.
Old tool-result compaction
Older tool results are compacted to head + tail + a truncation marker. Recent tool results stay intact.
Stable old-message cache breakpoint
The plugin adds one cache marker behind recent messages so older stable context can be reused instead of rewritten.
Tool-definition cache marker
If OpenCode sends tools without a cache marker, the plugin adds one to the last tool definition.
Behavior efficiency hint
The plugin adds a short hint asking the model to use targeted reads/searches, avoid pre-tool narration, avoid unnecessary verification commands for read-only tasks, and honor exact output shapes.
Metrics
Metrics are off by default. Enable them in plugin options:
{
"plugin": [
[
"[email protected]",
{
"observability": {
"metrics": true
}
}
]
]
}Default metrics file:
~/.local/state/opencode-anthropic-optimizer/metrics.jsonlUseful fields:
bodyBytesBefore/bodyBytesAfter- request-size reductioncacheControlBefore/cacheControlAfter- prompt-cache marker shapecacheCreate/cacheRead- cache write/read token behaviortoolResultTruncation- old tool-result compaction statstranscriptCompaction- old transcript compaction statsactualCostUsd- estimated cost of the observed requestestimatedBaselineCostUsd- passive estimate of the unoptimized requestestimatedSavedUsd/estimatedSavingsPct- passive savings estimate
Cost estimates use available model pricing from OpenCode's model catalog when present. They are useful for trend checks, not provider billing truth.
Configuration
Most users should not need configuration beyond enabling the plugin.
Disable optimization and keep auth only:
{
"plugin": [
[
"[email protected]",
{
"optimization": {
"enabled": false
}
}
]
]
}Full options:
{
"plugin": [
[
"[email protected]",
{
"optimization": {
"enabled": true,
"promptCache": {
"mode": "stable"
},
"behavior": {
"toolCallDiscipline": false
},
"toolResults": {
"mode": "compact-old",
"maxBytes": 2500,
"keepRecent": 4
},
"transcript": {
"mode": "compact-old",
"maxBytes": 120000,
"keepRecent": 2,
"blockMaxBytes": 1500
}
},
"observability": {
"metrics": false,
"metricsFile": "~/.local/state/opencode-anthropic-optimizer/metrics.jsonl",
"cacheDetail": false,
"abLog": false
}
}
]
]
}Prompt-cache modes:
observe- preserve existing cache markersstable- remove cache markers from tool-use and tool-result message blocksminimal- remove cache markers from all messagesoff- remove cache markers from system, messages, and tools
Tool-result modes:
preserve- keep tool results unchangedcompact-old- compact old results; keep newestkeepRecentintactcompact-all- compact all tool results
Transcript modes:
preserve- keep transcript text unchangedcompact-old- compact old text blocks after message payload exceedsmaxBytes
Option reference:
optimization.enabled-falsedisables request optimization and keeps auth behavior.optimization.preset-defaultenables the normal optimizer;offdisables it. Legacy valuessafe,balanced, andaggressiveare accepted for compatibility and map to current behavior.optimization.promptCache.mode- controls which cache markers are preserved or removed.optimization.behavior.toolCallDiscipline- opt-in system hint asking the agent to be less eager with tool calls, avoid repeated state checks, delegate long-running monitors to scripts/watchers, and keep responses concise.optimization.toolResults.maxBytes- target byte budget for each compacted old tool result.optimization.toolResults.keepRecent- number of newest tool results left untouched.optimization.transcript.maxBytes- total message-history byte threshold before old transcript text is compacted.optimization.transcript.keepRecent- number of newest messages left untouched during transcript compaction.optimization.transcript.blockMaxBytes- target byte budget for each compacted old text block.observability.metrics- writes request/usage metrics to JSONL.observability.metricsFile- custom JSONL path. Defaults to~/.local/state/opencode-anthropic-optimizer/metrics.jsonl.observability.cacheDetail- records detailed cache-marker paths in metrics.observability.abLog- records extra before/after request-shape data for debugging comparisons.
Changing optimization settings in a long session can force a one-time cache rebuild. For clean comparisons, start a fresh session or wait until the cache stabilizes.
Troubleshooting
Invalid authentication credentials
Re-run OpenCode auth and choose Anthropic account.
Existing anthropic credentials in OpenCode may be stale or may have been created by a different auth flow. If both the access token and refresh token are invalid, the plugin cannot repair them automatically.
Cache-control limit errors
The optimizer enforces Anthropic's 4-marker limit. If you still see A maximum of 4 blocks with cache_control may be provided, make sure OpenCode is loading the rebuilt/published plugin version you expect.
Development
bun install
bun run types
bun run test:unit
OPENCODE_ANTHROPIC_E2E_LIVE=0 bun run test:e2e
bun run build