openRouterDecider drops usage.cost, and decide() meta cannot surface the Decisions response id/provider
@AlemTuzlak ci sta già lavorando.
Dal 23/9/2026.
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
Summary
openRouterDecider / createOpenRouterDecider (@tanstack/ai-openrouter, used with decide() from @tanstack/ai) drops data the OpenRouter Decisions API returns:
usage.costis never attached toresult.meta.usage, even though the endpoint returns it on every response and the same package already hasextractUsageCost()which the text/image adapters use.- The response's
id(OpenRouter generation id) andproviderare not surfaced anywhere, becauseEvaluateAdapterResult/EvaluateResultMetaonly carrymodel,answersandusage.
I'm billing per request off usage.cost and reconciling with GET /api/v1/generation?id=, so both are needed.
Environment
@tanstack/[email protected]@tanstack/[email protected]@tanstack/[email protected]- Node v24.20.0, server-side (no framework)
Reproduction
import { decide, boolean } from '@tanstack/ai'
import { openRouterDecider } from '@tanstack/ai-openrouter'
const result = await decide({
adapter: openRouterDecider('typesafe/jev-1.13'),
state: 'Customer says the invoice total is wrong after applying a coupon.',
questions: {
isBug: boolean({ instructions: 'Is this a software bug report?' }),
},
})
console.log(result.meta.usage)
// { promptTokens: 30, completionTokens: 3, totalTokens: 33 }
// no `cost`, although the raw response body had usage.cost
console.log(result.meta)
// { model: 'typesafe/jev-1.13-20260917', usage: { ... } }
// no `id`, no `provider`
The raw POST https://openrouter.ai/api/alpha/decisions response (from OpenRouter's API reference) is:
{
"answers": { "...": "..." },
"id": "gen-dec-1789738314-X5e5eKGQdvR9rblyX250",
"model": "typesafe/jev-1.13-20260917",
"provider": "TypeSafe",
"usage": { "cost": 0.000019992, "input_tokens": 476, "output_tokens": 70 }
}
Expected
result.meta.usage.costis0.000019992(andcostDetailswhen present), the same aschat()/generateImage()with the OpenRouter adapters.TokenUsagealready declarescost?: numberandcostDetails?: UsageCostBreakdown(@tanstack/ai-event-clientindex.d.ts,TokenUsage).result.metaexposes the response'sidandprovider(or aproviderMetadatabag) so the request can be reconciled againstGET /api/v1/generation?id=.
Actual
result.meta.usagehas onlypromptTokens/completionTokens/totalTokens;costisundefined.result.metahas onlymodelandusage;idandproviderare unreachable fromdecide()without writing a custom adapter.
Where it happens
@tanstack/ai-openrouter/dist/esm/adapters/evaluate.js, mapUsage() (lines 51–65) reads only the token keys and calls buildBaseUsage with them:
function mapUsage(usage) {
if (!isRecord(usage)) return buildBaseUsage({ promptTokens: 0, completionTokens: 0, totalTokens: 0 });
const promptTokens = readNumber(usage, ["input_tokens", "prompt_tokens"]) ?? 0;
const completionTokens = readNumber(usage, ["output_tokens", "completion_tokens"]) ?? 0;
const totalTokens = readNumber(usage, ["total_tokens"]) ?? promptTokens + completionTokens;
return buildBaseUsage({ promptTokens, completionTokens, totalTokens });
}
and evaluate() (lines 104–108) returns only model / answers / usage:
return {
model: json.model ?? model,
answers: json.answers,
usage: mapUsage(json.usage)
};
extractUsageCost() lives in the same package (adapters/cost.js, exported with cost.d.ts) and is already spread into usage in adapters/text.js (lines 155, 386, 735), adapters/responses-text.js (133, 439, 1083) and adapters/image.js (121). evaluate.js does not import it.
On the core side, @tanstack/ai/dist/esm/activities/evaluate/adapter.d.ts lines 103–108:
export interface EvaluateAdapterResult {
/** Resolved model id from the provider. */
model: string;
answers: Record<string, WireAnswer>;
usage: TokenUsage;
}
and activities/evaluate/index.d.ts lines 50–54:
export interface EvaluateResultMeta {
/** Resolved model id from the provider. */
model: string;
usage: TokenUsage;
}
so even a custom adapter has no typed place to put id / provider.
Suggested fix
-
@tanstack/ai-openrouteradapters/evaluate.ts: spread the existing helper into the mapped usage, matching the other adapters:import { extractUsageCost } from './cost' return { ...buildBaseUsage({ promptTokens, completionTokens, totalTokens }), ...extractUsageCost(usage), } -
@tanstack/aiactivities/evaluate: add optionalid?: stringandprovider?: string(orproviderMetadata?: Record<string, unknown>) toEvaluateAdapterResultand pass them through toEvaluateResultMetaindecide(). The OpenRouter adapter would then returnid: json.id, provider: json.provider.
Both are additive; existing adapters and callers keep working.
I'm happy to open a PR for either or both if that's welcome.
- Lingua principale
- TypeScript
- Stelle
- 3.1k
- Fork
- 331
- Merge medio
- 2g 6h
- PR unite (30g)
- 155
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di TanStack/ai
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 52/100
-
waiting-on: maintainer
-
Client tools never execute against spec-compliant AG-UI servers (plain `success` RUN_FINISHED) Apertawaiting-on: maintainer
-
waiting-on: maintainer
Difficoltà 3/5 1-2 giorni Idoneità per principianti 70/100
-
waiting-on: maintainer
Issue simili
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
motiondivision/motion#3849 ·
-
Add: S Play Event HD Apertacheck:passed streams:add
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
LiteLLM proxy response_cost (x-litellm-response-cost) is never applied to ChatModelOutput.cost Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
i-am-bee/beeai-framework#1697 · 1 reazione ·
-
Support bun dedupe Apertaenhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
antfu/node-modules-inspector#214 ·