feat: pass through cost + limit metadata from /v1/models #1

Merged
devtrev merged 2 commits from feat/cost-limit-passthrough into dev 2026-07-11 00:01:08 -06:00
Owner

Summary

  • Read cost and limit metadata from aor's GET /v1/models response and inject them into opencode's per-model config via the config hook.
  • This enables opencode's TUI to display $ spent (computed client-side from tokens × pricing) and % context used (computed from tokens / context limit).

Changes

  • src/index.ts: Updated ModelEntry type to capture cost and limit from the /v1/models response. Updated discoverModels to pass them through as DiscoveredModel entries. The config hook injects them into each model's config entry.
  • README.md: New "Cost tracking & context window" section documenting how the passthrough works and the v2 runner cost: 0 caveat.

How it works

opencode's config provider builder (packages/opencode/src/provider/provider.ts:1463-1476) reads per-model cost and limit from the config we inject:

cost: {
  input: model?.cost?.input ?? 0,
  output: model?.cost?.output ?? 0,
  cache: {
    read: model?.cost?.cache_read ?? 0,
    write: model?.cost?.cache_write ?? 0,
  },
},
limit: {
  context: model.limit?.context ?? 0,
  output: model.limit?.output ?? 0,
},

opencode computes cost entirely client-side (Session.getUsage — tokens × pricing / 1M). It does NOT read cost from response bodies. So injecting pricing via config is the correct and only channel.

Depends on

aor PR #5 (trevin/feat/model-limits-cost-metadata) — adds the cost and limit fields to aor's /v1/models response.

## Summary - Read `cost` and `limit` metadata from aor's `GET /v1/models` response and inject them into opencode's per-model config via the `config` hook. - This enables opencode's TUI to display `$ spent` (computed client-side from tokens × pricing) and `% context used` (computed from tokens / context limit). ## Changes - `src/index.ts`: Updated `ModelEntry` type to capture `cost` and `limit` from the `/v1/models` response. Updated `discoverModels` to pass them through as `DiscoveredModel` entries. The `config` hook injects them into each model's config entry. - `README.md`: New "Cost tracking & context window" section documenting how the passthrough works and the v2 runner `cost: 0` caveat. ## How it works opencode's config provider builder (`packages/opencode/src/provider/provider.ts:1463-1476`) reads per-model `cost` and `limit` from the config we inject: ```typescript cost: { input: model?.cost?.input ?? 0, output: model?.cost?.output ?? 0, cache: { read: model?.cost?.cache_read ?? 0, write: model?.cost?.cache_write ?? 0, }, }, limit: { context: model.limit?.context ?? 0, output: model.limit?.output ?? 0, }, ``` opencode computes cost entirely client-side (`Session.getUsage` — tokens × pricing / 1M). It does NOT read cost from response bodies. So injecting pricing via config is the correct and only channel. ## Depends on aor PR #5 (`trevin/feat/model-limits-cost-metadata`) — adds the `cost` and `limit` fields to aor's `/v1/models` response.
Read the `cost` and `limit` fields from aor's GET /v1/models response
and inject them into opencode's per-model config via the config hook.

opencode's provider builder maps:
  cost.input, cost.output, cost.cache_read -> cache.read,
  cost.cache_write -> cache.write
  limit.context, limit.output

This enables opencode's TUI to display:
- "$ spent" — computed client-side from tokens × injected pricing
- "% context used" — computed from tokens / injected limit.context

Both values come from aor's primary (highest-priority) provider per model.
Requires aor PR #5 for the /v1/models cost+limit fields.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
devtrev/opencode-aor!1
No description provided.