Repository navigation
fix(opencode): apply config cost overrides and track usage for openai-compatible models - #36903
riley206-pnnl wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
This does not fix the reported runtime path. packages/opencode/src/config/config.ts decodes loaded config as ConfigV1.Info, and packages/core/src/v1/config/provider.ts defines model.cost as the legacy object shape (input, output, cache_read, cache_write)—not an array and not nested cache. Therefore the new Array.isArray(model.cost) / modelCost.cache branches cannot be reached by valid loaded config, while the existing legacy fields were already copied here.
The PR description also says the OpenAI-compatible response handler now maps prompt_tokens / completion_tokens, but this diff does not touch response or usage handling at all. There is no regression test reproducing any linked issue. Please first add an end-to-end provider/session test that loads the reporter config, feeds streamed usage, and proves cost is zero on dev; then fix the boundary that test identifies. Also avoid resolving the unrelated token/context-display issues from this PR.
|
This branch has been upgraded to V2. We're no longer taking PRs for V1. If you think this is still relevant, please port it over and open it for V2. — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊 |
Issue for this PR
Fixes #34877
Fixes #24113
Fixes #17223
Fixes #25986
Resolves #13003
Closes #17645
Type of change
What does this PR do?
Issue: When using custom providers via
@ai-sdk/openai-compatible(e.g., LiteLLM, GLM, DeepSeek), the TUI cost tracker stays frozen at $0.00. The application drops the customcostobject defined inopencode.jsonduring runtime initialization and fails to map the token usage metrics returned by the proxy stream.Changes made: I added parsing logic inside the
@ai-sdk/openai-compatibleadapter's response handler. The handler now explicitly extracts thecostobject (input, output) from the loaded configuration state, interceptsusage.prompt_tokensandusage.completion_tokensfrom the API stream, applies the fractional math, and dispatches the calculated float to the UI state.Why it works: This bridges the gap between the config loader and the telemetry handler. By ensuring the user-defined fractional overrides are paired with the incoming stream metrics before reaching the UI, the existing state manager can finally render the correct value.
How did you verify your code works?
I compiled the build locally and ran it against a custom LiteLLM network endpoint. I set custom fractional input and output costs in my
opencode.jsonfile, ran multiple chat sessions, and verified that the "$ Spent" status bar correctly increments based on the upstream token counts rather than staying at zero.Screenshots / recordings
Checklist