Description
In models.config.mjs, Claude models define all four cost fields (input, output, cache_read, cache_write), but GPT, Gemini, and Kimi models omit cache_write:
// Claude — has cache_write ✓
"Claude Opus 4.6": {
cost: { input: 5.5, output: 27.5, cache_read: 0.55, cache_write: 6.75 },
},
// GPT — missing cache_write ✗
"GPT 5.2": {
cost: { input: 1.75, output: 14.0, cache_read: 0.175 },
},
// Gemini — missing cache_write ✗
"Gemini 2.5 Pro": {
cost: { input: 1.25, output: 10.0, cache_read: 0.125 },
},
// Kimi — missing cache_write ✗
"Kimi K2.5": {
cost: { input: 0.6, output: 3.0, cache_read: 0.1 },
},
Impact
When the downstream consumer (opencode) reads the generated opencode.json and attempts to calculate cache write costs:
const cacheWriteCost = model.cost.cache_write * tokensWrittenToCache;
// → NaN for GPT, Gemini, Kimi (because undefined * number = NaN)
This leads to:
NaN cost calculations displayed to the user.
- Incorrect total cost summaries.
- Potential runtime errors if the consumer expects a number.
Meanwhile, DEFAULT_FALLBACK_COSTS (line 107) does include cache_write: 6.25, so unsupported/unknown models paradoxically get a cache_write value while explicitly supported models like GPT 5.2 do not.
Proposed fix
For models where the provider does not charge for cache writes, explicitly set cache_write: 0:
"GPT 5.2": {
cost: { input: 1.75, output: 14.0, cache_read: 0.175, cache_write: 0 },
},
Alternatively, if cache write pricing is unknown, document it clearly and ensure downstream consumers handle undefined gracefully.
Acceptance criteria
Test cases
test("all supported models should have consistent cost fields", () => {
const requiredFields = ["input", "output", "cache_read", "cache_write"];
for (const [modelName, config] of Object.entries(SUPPORTED_MODELS)) {
if (!config.cost) continue;
for (const field of requiredFields) {
expect(config.cost[field]).toBeDefined();
expect(typeof config.cost[field]).toBe("number");
}
}
});
test("generated config should have numeric cache_write for all models", () => {
const modelsList = [
{ id: "gpt-5", name: "GPT 5.2" },
{ id: "claude", name: "Claude Opus 4.6" },
{ id: "gemini", name: "Gemini 2.5 Pro" },
];
const { models } = processModels(modelsList, {}, true);
for (const [name, model] of Object.entries(models)) {
expect(typeof model.cost.cache_write).toBe("number");
}
});
🤖 Generated with Claude Code
Description
In
models.config.mjs, Claude models define all four cost fields (input,output,cache_read,cache_write), but GPT, Gemini, and Kimi models omitcache_write:Impact
When the downstream consumer (opencode) reads the generated
opencode.jsonand attempts to calculate cache write costs:This leads to:
NaNcost calculations displayed to the user.Meanwhile,
DEFAULT_FALLBACK_COSTS(line 107) does includecache_write: 6.25, so unsupported/unknown models paradoxically get acache_writevalue while explicitly supported models like GPT 5.2 do not.Proposed fix
For models where the provider does not charge for cache writes, explicitly set
cache_write: 0:Alternatively, if cache write pricing is unknown, document it clearly and ensure downstream consumers handle
undefinedgracefully.Acceptance criteria
SUPPORTED_MODELShave a consistent cost schema: all four fields (input,output,cache_read,cache_write) are present.cache_write: 0(not omitted).DEFAULT_FALLBACK_COSTSschema matchesSUPPORTED_MODELScost schema.Test cases
🤖 Generated with Claude Code