@opencode-ai/ai 0.0.0-next-16184 → 0.0.0-next-16187

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -395,18 +395,36 @@ export declare const protocol: Protocol<{
395
395
  } | undefined;
396
396
  readonly message?: {
397
397
  readonly usage?: {
398
+ readonly [x: string]: unknown;
399
+ readonly server_tool_use?: {
400
+ readonly [x: string]: unknown;
401
+ readonly web_search_requests?: number | undefined;
402
+ } | null | undefined;
398
403
  readonly input_tokens?: number | undefined;
399
404
  readonly output_tokens?: number | undefined;
400
405
  readonly cache_creation_input_tokens?: number | null | undefined;
401
406
  readonly cache_read_input_tokens?: number | null | undefined;
407
+ readonly output_tokens_details?: {
408
+ readonly [x: string]: unknown;
409
+ readonly thinking_tokens?: number | undefined;
410
+ } | null | undefined;
402
411
  } | undefined;
403
412
  } | undefined;
404
413
  readonly index?: number | undefined;
405
414
  readonly usage?: {
415
+ readonly [x: string]: unknown;
416
+ readonly server_tool_use?: {
417
+ readonly [x: string]: unknown;
418
+ readonly web_search_requests?: number | undefined;
419
+ } | null | undefined;
406
420
  readonly input_tokens?: number | undefined;
407
421
  readonly output_tokens?: number | undefined;
408
422
  readonly cache_creation_input_tokens?: number | null | undefined;
409
423
  readonly cache_read_input_tokens?: number | null | undefined;
424
+ readonly output_tokens_details?: {
425
+ readonly [x: string]: unknown;
426
+ readonly thinking_tokens?: number | undefined;
427
+ } | null | undefined;
410
428
  } | undefined;
411
429
  readonly content_block?: {
412
430
  readonly type: string;
@@ -4,7 +4,7 @@ import { Auth } from "../route/auth";
4
4
  import { Endpoint } from "../route/endpoint";
5
5
  import { Framing } from "../route/framing";
6
6
  import { Protocol } from "../route/protocol";
7
- import { LLMError, LLMEvent, Usage, } from "../schema";
7
+ import { LLMError, LLMEvent, mergeJsonRecords, Usage, } from "../schema";
8
8
  import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared";
9
9
  import { classifyProviderFailure } from "../provider-error";
10
10
  import * as Cache from "./utils/cache";
@@ -161,12 +161,14 @@ const AnthropicBodyFields = {
161
161
  output_config: Schema.optional(AnthropicOutputConfig),
162
162
  };
163
163
  export const AnthropicMessagesBody = Schema.Struct(AnthropicBodyFields);
164
- const AnthropicUsage = Schema.Struct({
164
+ const AnthropicUsage = Schema.StructWithRest(Schema.Struct({
165
165
  input_tokens: Schema.optional(Schema.Number),
166
166
  output_tokens: Schema.optional(Schema.Number),
167
167
  cache_creation_input_tokens: optionalNull(Schema.Number),
168
168
  cache_read_input_tokens: optionalNull(Schema.Number),
169
- });
169
+ server_tool_use: optionalNull(Schema.StructWithRest(Schema.Struct({ web_search_requests: Schema.optional(Schema.Number) }), [Schema.Record(Schema.String, Schema.Unknown)])),
170
+ output_tokens_details: optionalNull(Schema.StructWithRest(Schema.Struct({ thinking_tokens: Schema.optional(Schema.Number) }), [Schema.Record(Schema.String, Schema.Unknown)])),
171
+ }), [Schema.Record(Schema.String, Schema.Unknown)]);
170
172
  const AnthropicStreamBlock = Schema.Struct({
171
173
  type: Schema.String,
172
174
  id: Schema.optional(Schema.String),
@@ -535,9 +537,8 @@ const mapFinishReason = (reason) => {
535
537
  // `input_tokens` is the *non-cached* count per the Messages API docs, with
536
538
  // cache reads and writes as separate fields. We sum them to derive the
537
539
  // inclusive `inputTokens` the rest of the contract expects. Extended
538
- // thinking tokens are *not* broken out by Anthropic — they're billed as
539
- // part of `output_tokens`, so `reasoningTokens` stays `undefined` and
540
- // `outputTokens` carries the combined total.
540
+ // thinking tokens are included in `output_tokens`; newer responses also
541
+ // expose that subset through `output_tokens_details.thinking_tokens`.
541
542
  const mapUsage = (usage) => {
542
543
  if (!usage)
543
544
  return undefined;
@@ -551,6 +552,7 @@ const mapUsage = (usage) => {
551
552
  nonCachedInputTokens: nonCached,
552
553
  cacheReadInputTokens: cacheRead,
553
554
  cacheWriteInputTokens: cacheWrite,
555
+ reasoningTokens: usage.output_tokens_details?.thinking_tokens,
554
556
  totalTokens: ProviderShared.totalTokens(inputTokens, usage.output_tokens, undefined),
555
557
  providerMetadata: { anthropic: usage },
556
558
  });
@@ -570,18 +572,17 @@ const mergeUsage = (left, right) => {
570
572
  const cacheWriteInputTokens = right.cacheWriteInputTokens ?? left.cacheWriteInputTokens;
571
573
  const inputTokens = ProviderShared.sumTokens(nonCachedInputTokens, cacheReadInputTokens, cacheWriteInputTokens);
572
574
  const outputTokens = right.outputTokens ?? left.outputTokens;
575
+ const reasoningTokens = right.reasoningTokens ?? left.reasoningTokens;
573
576
  return new Usage({
574
577
  inputTokens,
575
578
  outputTokens,
576
579
  nonCachedInputTokens,
577
580
  cacheReadInputTokens,
578
581
  cacheWriteInputTokens,
582
+ reasoningTokens,
579
583
  totalTokens: ProviderShared.totalTokens(inputTokens, outputTokens, undefined),
580
584
  providerMetadata: {
581
- anthropic: {
582
- ...left.providerMetadata?.["anthropic"],
583
- ...right.providerMetadata?.["anthropic"],
584
- },
585
+ anthropic: mergeJsonRecords(left.providerMetadata?.["anthropic"], right.providerMetadata?.["anthropic"]) ?? {},
585
586
  },
586
587
  });
587
588
  };
@@ -495,14 +495,14 @@ export declare const protocol: Protocol<{
495
495
  readonly usage?: {
496
496
  readonly input_tokens?: number | undefined;
497
497
  readonly output_tokens?: number | undefined;
498
+ readonly output_tokens_details?: {
499
+ readonly reasoning_tokens?: number | undefined;
500
+ } | null | undefined;
498
501
  readonly total_tokens?: number | undefined;
499
502
  readonly input_tokens_details?: {
500
503
  readonly cached_tokens?: number | undefined;
501
504
  readonly cache_write_tokens?: number | undefined;
502
505
  } | null | undefined;
503
- readonly output_tokens_details?: {
504
- readonly reasoning_tokens?: number | undefined;
505
- } | null | undefined;
506
506
  } | null | undefined;
507
507
  readonly service_tier?: string | null | undefined;
508
508
  readonly incomplete_details?: {
@@ -220,14 +220,14 @@ export declare const protocol: Protocol<{
220
220
  readonly usage?: {
221
221
  readonly input_tokens?: number | undefined;
222
222
  readonly output_tokens?: number | undefined;
223
+ readonly output_tokens_details?: {
224
+ readonly reasoning_tokens?: number | undefined;
225
+ } | null | undefined;
223
226
  readonly total_tokens?: number | undefined;
224
227
  readonly input_tokens_details?: {
225
228
  readonly cached_tokens?: number | undefined;
226
229
  readonly cache_write_tokens?: number | undefined;
227
230
  } | null | undefined;
228
- readonly output_tokens_details?: {
229
- readonly reasoning_tokens?: number | undefined;
230
- } | null | undefined;
231
231
  } | null | undefined;
232
232
  readonly service_tier?: string | null | undefined;
233
233
  readonly incomplete_details?: {
@@ -47,9 +47,9 @@ declare const Usage_base: Schema.Class<Usage, Schema.Struct<{
47
47
  * - Anthropic and Bedrock report the input breakdown natively: Anthropic's
48
48
  * `input_tokens` and Bedrock's `inputTokens` are non-cached only. Their
49
49
  * mappers sum the breakdown to derive the inclusive `inputTokens`.
50
- * Anthropic does *not* break extended-thinking out of `output_tokens`, so
51
- * `reasoningTokens` is `undefined` and `outputTokens` carries the
52
- * combined total a documented limitation of the Anthropic API.
50
+ * Anthropic's `outputTokens` includes extended thinking. Newer responses
51
+ * expose that subset as `output_tokens_details.thinking_tokens`, which maps
52
+ * to `reasoningTokens`; older responses leave it undefined.
53
53
  *
54
54
  * `providerMetadata` always carries the provider's raw usage payload —
55
55
  * keyed by provider name (`{ openai: ... }`, `{ anthropic: ... }`, etc.)
@@ -39,9 +39,9 @@ import { ProviderFailureClassification } from "./errors";
39
39
  * - Anthropic and Bedrock report the input breakdown natively: Anthropic's
40
40
  * `input_tokens` and Bedrock's `inputTokens` are non-cached only. Their
41
41
  * mappers sum the breakdown to derive the inclusive `inputTokens`.
42
- * Anthropic does *not* break extended-thinking out of `output_tokens`, so
43
- * `reasoningTokens` is `undefined` and `outputTokens` carries the
44
- * combined total a documented limitation of the Anthropic API.
42
+ * Anthropic's `outputTokens` includes extended thinking. Newer responses
43
+ * expose that subset as `output_tokens_details.thinking_tokens`, which maps
44
+ * to `reasoningTokens`; older responses leave it undefined.
45
45
  *
46
46
  * `providerMetadata` always carries the provider's raw usage payload —
47
47
  * keyed by provider name (`{ openai: ... }`, `{ anthropic: ... }`, etc.)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "0.0.0-next-16184",
3
+ "version": "0.0.0-next-16187",
4
4
  "name": "@opencode-ai/ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,7 +26,7 @@
26
26
  "devDependencies": {
27
27
  "@clack/prompts": "1.0.0-alpha.1",
28
28
  "@effect/platform-node": "4.0.0-beta.98",
29
- "@opencode-ai/http-recorder": "0.0.0-next-16184",
29
+ "@opencode-ai/http-recorder": "0.0.0-next-16187",
30
30
  "@tsconfig/bun": "1.0.9",
31
31
  "@types/bun": "1.3.13",
32
32
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -35,7 +35,7 @@
35
35
  "dependencies": {
36
36
  "@smithy/eventstream-codec": "4.2.14",
37
37
  "@smithy/util-utf8": "4.2.2",
38
- "@opencode-ai/schema": "0.0.0-next-16184",
38
+ "@opencode-ai/schema": "0.0.0-next-16187",
39
39
  "aws4fetch": "1.0.20",
40
40
  "effect": "4.0.0-beta.98",
41
41
  "google-auth-library": "10.5.0"