From c20d070b9aaffdb8c3a016a57228e64909789123 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Sun, 10 May 2026 22:08:12 -0400 Subject: [PATCH] docs(llm): fix stale references in protocols/shared.ts and gemini.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - subtractTokens JSDoc said the raw payload lives on Usage.native, but that field was renamed to providerMetadata earlier in this PR. - totalTokens JSDoc still described the abandoned "additive" first-pass contract where inputTokens/outputTokens were non-cached / visible only. We landed on inclusive totals; the fallback already covers cache and reasoning. - Removed a duplicate inline comment in Gemini's mapUsage — the function-level comment already explains the visible/reasoning sum and the undefined-when-incomplete rule. --- packages/llm/src/protocols/gemini.ts | 6 ++---- packages/llm/src/protocols/shared.ts | 13 ++++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/llm/src/protocols/gemini.ts b/packages/llm/src/protocols/gemini.ts index ff6f3f83ec..a59b0e5017 100644 --- a/packages/llm/src/protocols/gemini.ts +++ b/packages/llm/src/protocols/gemini.ts @@ -285,14 +285,12 @@ const fromRequest = Effect.fn("Gemini.fromRequest")(function* (request: LLMReque // `cachedContentTokenCount` subset. `candidatesTokenCount` is *exclusive* // of `thoughtsTokenCount` — visible-only, not a total — so we sum the two // to produce the inclusive `outputTokens` the rest of the contract expects. +// Output is left undefined when the visible component is missing, so we +// don't fabricate an inclusive number from a partial breakdown. const mapUsage = (usage: GeminiUsage | undefined) => { if (!usage) return undefined const cached = usage.cachedContentTokenCount const nonCached = ProviderShared.subtractTokens(usage.promptTokenCount, cached) - // `candidatesTokenCount` is visible-only; sum with thoughts to produce the - // inclusive `outputTokens` the contract expects. Only compute the total - // when the visible component is reported — otherwise we'd fabricate an - // inclusive number from a partial breakdown. const outputTokens = usage.candidatesTokenCount !== undefined ? usage.candidatesTokenCount + (usage.thoughtsTokenCount ?? 0) diff --git a/packages/llm/src/protocols/shared.ts b/packages/llm/src/protocols/shared.ts index 3b9886553a..a07d38bd19 100644 --- a/packages/llm/src/protocols/shared.ts +++ b/packages/llm/src/protocols/shared.ts @@ -43,12 +43,10 @@ export interface ToolAccumulator { * when at least one is defined. Returns `undefined` when neither input nor * output is known so routes don't publish a misleading `0`. * - * Under the additive `LLM.Usage` contract, `inputTokens` and `outputTokens` - * are the non-cached input and visible output only. The provider-supplied - * `total` is the source of truth when present; the computed fallback - * under-counts cache and reasoning by design and exists mainly so - * Anthropic-style providers (which don't surface a total) still get a - * sensible aggregate on the input + output axes. + * Under the `LLM.Usage` contract, `inputTokens` and `outputTokens` are + * inclusive totals, so the computed fallback already covers cache reads / + * writes and reasoning — used mainly for Anthropic-style providers that + * don't surface a top-level total. */ export const totalTokens = ( inputTokens: number | undefined, @@ -69,7 +67,8 @@ export const totalTokens = ( * * If `total` is `undefined`, returns `undefined` (we don't fabricate * counts). If `subtrahend` is `undefined`, returns `total` unchanged. The - * provider-native breakdown stays available on `Usage.native` for debugging. + * provider-native breakdown stays available on `Usage.providerMetadata` + * for debugging. */ export const subtractTokens = ( total: number | undefined,