Skip to content

bug: AI SDK V2 providers silently lose usage and disable auto-compaction #50338

Description

@ton618to

Description

OpenCode silently drops token usage for dynamically loaded providers that implement AI SDK LanguageModelV2. This is severe because it does not only hide the context-usage indicator: it also disables automatic context compaction.

The affected model can have a valid positive limit.context, but every assistant message is persisted with zero input/output/cache tokens. session/overflow.ts therefore never sees the session approach the model's context limit and never schedules compaction. Long-running sessions continue growing without warning until the provider rejects the request at its hard context limit. Users lose the normal compaction safety mechanism and receive no visible indication that it has stopped working.

Observed with SAP AI Core using @jerome-benoit/sap-ai-provider-v2@4.6.7, but the bug is version-based rather than SAP-specific and can affect any dynamically loaded AI SDK V2 provider.

The model metadata was not the problem: the affected model reported limit.context = 1,000,000 correctly.

Root cause

Provider.getLanguage() is typed as returning LanguageModelV3, although dynamically loaded providers can return a runtime V2 model.

packages/opencode/src/session/llm.ts unconditionally passes that model to wrapLanguageModel() with V3 middleware. The wrapper labels the result as V3 before AI SDK can run its V2-to-V3 compatibility conversion. Finish usage is then lost.

A minimal differential probe produced:

base V2 model:    finish-step usage = input 14, output 4, total 18
V3-wrapped model: finish-step usage = undefined

Plugins

None required. Reproduced with --pure.

OpenCode version

1.18.31 / dev commit 0a429ed441

Steps to reproduce

  1. Configure a dynamically loaded AI SDK V2 provider with a model that has a valid context limit.
  2. Run:
opencode run --pure --format json --model <provider>/<model> --agent build "Reply exactly OK"
  1. Inspect the step_finish event.

Actual result:

{
  "tokens": {
    "input": 0,
    "output": 0,
    "reasoning": 0,
    "cache": { "read": 0, "write": 0 }
  }
}
  1. Continue the session. The context usage indicator remains absent and automatic compaction never triggers, even as the conversation approaches the model's context limit.

Expected behavior

  • V2 provider usage MUST survive message transformation and AI SDK compatibility conversion.
  • Assistant messages MUST persist non-zero token usage when the provider reports it.
  • Automatic compaction MUST continue to trigger based on the model's context limit.

A working fix is to inspect the runtime specificationVersion:

  • V2 model: transform messages before streamText and pass the model unwrapped, allowing AI SDK's V2-to-V3 converter to preserve usage.
  • V3 model: retain the existing V3 middleware path.

With that change, the same end-to-end command produced non-zero usage (total: 82061, input: 82057, output: 4), restoring both context display and auto-compaction.

Operating System

macOS 27 (arm64)

Terminal

Zed terminal

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions