From 40d4cef7dcd32452670bb40410bf417698aa011f Mon Sep 17 00:00:00 2001 From: Chaoran Huang Date: Wed, 17 Jun 2026 13:03:47 -0400 Subject: [PATCH] docs(ai): clarify reasoningTokens availability across providers The Anthropic Messages API and Amazon Bedrock Converse API do not report reasoning tokens as a discrete value; reasoning tokens are included in outputTokens. Document this on Response.Usage.reasoningTokens and at the usage-mapping sites in the Anthropic and Amazon Bedrock providers so consumers do not rely on the field for cost calculations. No runtime behavior changes. Refs Effect-TS/effect#6186 Co-authored-by: Cursor --- .changeset/clarify-reasoning-tokens-usage.md | 9 +++++++++ packages/ai/ai/src/Response.ts | 8 ++++++++ .../ai/amazon-bedrock/src/AmazonBedrockLanguageModel.ts | 8 ++++++++ packages/ai/anthropic/src/AnthropicLanguageModel.ts | 8 ++++++++ 4 files changed, 33 insertions(+) create mode 100644 .changeset/clarify-reasoning-tokens-usage.md diff --git a/.changeset/clarify-reasoning-tokens-usage.md b/.changeset/clarify-reasoning-tokens-usage.md new file mode 100644 index 00000000000..ab6b03dec60 --- /dev/null +++ b/.changeset/clarify-reasoning-tokens-usage.md @@ -0,0 +1,9 @@ +--- +"@effect/ai": patch +"@effect/ai-anthropic": patch +"@effect/ai-amazon-bedrock": patch +--- + +Clarify that `Response.Usage.reasoningTokens` is only populated by providers whose API reports reasoning tokens as a discrete value (e.g. OpenAI via `output_tokens_details.reasoning_tokens`). + +The Anthropic Messages API and the Amazon Bedrock Converse API do **not** report reasoning tokens separately - when extended thinking is enabled, reasoning tokens are already included in `outputTokens`. The `@effect/ai-anthropic` and `@effect/ai-amazon-bedrock` providers therefore leave `reasoningTokens` unset. This documents the behavior so consumers do not rely on the field for cost calculations with these providers. No runtime behavior changes. diff --git a/packages/ai/ai/src/Response.ts b/packages/ai/ai/src/Response.ts index 5e3de4449f6..15acdddcada 100644 --- a/packages/ai/ai/src/Response.ts +++ b/packages/ai/ai/src/Response.ts @@ -2214,6 +2214,14 @@ export class Usage extends Schema.Class("@effect/ai/AiResponse/Usage")({ /** * The number of reasoning tokens that the model used to generate the output * for the request. + * + * **NOTE**: This value is only populated by providers whose API reports + * reasoning tokens as a discrete value (e.g. OpenAI via + * `output_tokens_details.reasoning_tokens`). Providers such as Anthropic and + * Amazon Bedrock do not report reasoning tokens separately - for those + * providers reasoning tokens are already included in `outputTokens`, and this + * field will be left unset. Do not rely on this field for cost calculations + * unless your provider is known to report it. */ reasoningTokens: Schema.optional(Schema.Number), /** diff --git a/packages/ai/amazon-bedrock/src/AmazonBedrockLanguageModel.ts b/packages/ai/amazon-bedrock/src/AmazonBedrockLanguageModel.ts index 1c24e0d1f4c..8172c74617a 100644 --- a/packages/ai/amazon-bedrock/src/AmazonBedrockLanguageModel.ts +++ b/packages/ai/amazon-bedrock/src/AmazonBedrockLanguageModel.ts @@ -609,6 +609,10 @@ const makeResponse: ( parts.push({ type: "finish", reason: finishReason, + // NOTE: `reasoningTokens` is intentionally left unset. The Bedrock Converse + // API does not report reasoning tokens as a discrete value - when extended + // thinking is enabled, reasoning tokens are already included in + // `outputTokens`. See the `TokenUsage` schema in `AmazonBedrockSchema.ts`. usage: { inputTokens: response.usage.inputTokens, outputTokens: response.usage.outputTokens, @@ -657,6 +661,10 @@ const makeStreamResponse: ( let trace: ConverseTrace | undefined = undefined let cacheWriteInputTokens: number | undefined = undefined let finishReason: Response.FinishReason | undefined = undefined + // NOTE: `reasoningTokens` is intentionally omitted. The Bedrock Converse API + // does not report reasoning tokens as a discrete value - when extended + // thinking is enabled, reasoning tokens are already included in + // `outputTokens`. See the `TokenUsage` schema in `AmazonBedrockSchema.ts`. const usage: Mutable = { inputTokens: undefined, outputTokens: undefined, diff --git a/packages/ai/anthropic/src/AnthropicLanguageModel.ts b/packages/ai/anthropic/src/AnthropicLanguageModel.ts index c9ee13ba11d..b9488d02a3d 100644 --- a/packages/ai/anthropic/src/AnthropicLanguageModel.ts +++ b/packages/ai/anthropic/src/AnthropicLanguageModel.ts @@ -887,6 +887,10 @@ const makeResponse: ( parts.push({ type: "finish", reason: finishReason, + // NOTE: `reasoningTokens` is intentionally left unset. The Anthropic + // Messages API does not report reasoning tokens as a discrete value - + // when extended thinking is enabled, reasoning tokens are already + // included in `output_tokens`. See the `Usage` schema in `Generated.ts`. usage: { inputTokens: response.usage.input_tokens, outputTokens: response.usage.output_tokens, @@ -951,6 +955,10 @@ const makeStreamResponse: ( | "mcp_tool_result" | "container_upload" | undefined = undefined + // NOTE: `reasoningTokens` is intentionally omitted. The Anthropic Messages + // API does not report reasoning tokens as a discrete value - when extended + // thinking is enabled, reasoning tokens are already included in + // `output_tokens`. See the `Usage` schema in `Generated.ts`. const usage: Mutable = { inputTokens: undefined, outputTokens: undefined,