@opencode-ai/ai 0.0.0-next-16169 → 0.0.0-next-16173

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.
@@ -229,6 +229,7 @@ export declare const Event: Schema.StructWithRest<Schema.Struct<{
229
229
  readonly input_tokens: Schema.optional<Schema.Number>;
230
230
  readonly input_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
231
231
  readonly cached_tokens: Schema.optional<Schema.Number>;
232
+ readonly cache_write_tokens: Schema.optional<Schema.Number>;
232
233
  }>>>;
233
234
  readonly output_tokens: Schema.optional<Schema.Number>;
234
235
  readonly output_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
@@ -497,6 +498,7 @@ export declare const protocol: Protocol<{
497
498
  readonly total_tokens?: number | undefined;
498
499
  readonly input_tokens_details?: {
499
500
  readonly cached_tokens?: number | undefined;
501
+ readonly cache_write_tokens?: number | undefined;
500
502
  } | null | undefined;
501
503
  readonly output_tokens_details?: {
502
504
  readonly reasoning_tokens?: number | undefined;
@@ -121,7 +121,10 @@ const OpenResponsesBody = Schema.Struct({
121
121
  });
122
122
  const OpenResponsesUsage = Schema.Struct({
123
123
  input_tokens: Schema.optional(Schema.Number),
124
- input_tokens_details: optionalNull(Schema.Struct({ cached_tokens: Schema.optional(Schema.Number) })),
124
+ input_tokens_details: optionalNull(Schema.Struct({
125
+ cached_tokens: Schema.optional(Schema.Number),
126
+ cache_write_tokens: Schema.optional(Schema.Number),
127
+ })),
125
128
  output_tokens: Schema.optional(Schema.Number),
126
129
  output_tokens_details: optionalNull(Schema.Struct({ reasoning_tokens: Schema.optional(Schema.Number) })),
127
130
  total_tokens: Schema.optional(Schema.Number),
@@ -399,20 +402,22 @@ export const fromRequest = Effect.fn("OpenResponses.fromRequest")(function* (req
399
402
  // Stream Parsing
400
403
  // =============================================================================
401
404
  // Responses APIs report `input_tokens` (inclusive total) with a
402
- // `cached_tokens` subset, and `output_tokens` (inclusive total) with a
403
- // `reasoning_tokens` subset. Pass the totals through and derive the
405
+ // cached-read and cache-write subsets, and `output_tokens` (inclusive total)
406
+ // with a `reasoning_tokens` subset. Pass the totals through and derive the
404
407
  // non-cached breakdown.
405
408
  const mapUsage = (usage, providerMetadataKey) => {
406
409
  if (!usage)
407
410
  return undefined;
408
411
  const cached = usage.input_tokens_details?.cached_tokens;
412
+ const cacheWrite = usage.input_tokens_details?.cache_write_tokens;
409
413
  const reasoning = usage.output_tokens_details?.reasoning_tokens;
410
- const nonCached = ProviderShared.subtractTokens(usage.input_tokens, cached);
414
+ const nonCached = ProviderShared.subtractTokens(usage.input_tokens, ProviderShared.sumTokens(cached, cacheWrite));
411
415
  return new Usage({
412
416
  inputTokens: usage.input_tokens,
413
417
  outputTokens: usage.output_tokens,
414
418
  nonCachedInputTokens: nonCached,
415
419
  cacheReadInputTokens: cached,
420
+ cacheWriteInputTokens: cacheWrite,
416
421
  reasoningTokens: reasoning,
417
422
  totalTokens: ProviderShared.totalTokens(usage.input_tokens, usage.output_tokens, usage.total_tokens),
418
423
  providerMetadata: { [providerMetadataKey]: usage },
@@ -162,6 +162,7 @@ export declare const OpenAIChatEvent: Schema.Struct<{
162
162
  readonly total_tokens: Schema.optional<Schema.Number>;
163
163
  readonly prompt_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
164
164
  readonly cached_tokens: Schema.optional<Schema.Number>;
165
+ readonly cache_write_tokens: Schema.optional<Schema.Number>;
165
166
  }>>>;
166
167
  readonly completion_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
167
168
  readonly reasoning_tokens: Schema.optional<Schema.Number>;
@@ -271,6 +272,7 @@ export declare const protocol: Protocol<{
271
272
  readonly total_tokens?: number | undefined;
272
273
  readonly prompt_tokens_details?: {
273
274
  readonly cached_tokens?: number | undefined;
275
+ readonly cache_write_tokens?: number | undefined;
274
276
  } | null | undefined;
275
277
  readonly completion_tokens_details?: {
276
278
  readonly reasoning_tokens?: number | undefined;
@@ -100,6 +100,7 @@ const OpenAIChatUsage = Schema.Struct({
100
100
  total_tokens: Schema.optional(Schema.Number),
101
101
  prompt_tokens_details: optionalNull(Schema.Struct({
102
102
  cached_tokens: Schema.optional(Schema.Number),
103
+ cache_write_tokens: Schema.optional(Schema.Number),
103
104
  })),
104
105
  completion_tokens_details: optionalNull(Schema.Struct({
105
106
  reasoning_tokens: Schema.optional(Schema.Number),
@@ -373,21 +374,23 @@ const mapFinishReason = (reason) => {
373
374
  return "unknown";
374
375
  };
375
376
  // OpenAI Chat reports `prompt_tokens` (inclusive total) with a
376
- // `cached_tokens` subset, and `completion_tokens` (inclusive total) with
377
- // a `reasoning_tokens` subset. We pass the inclusive totals through and
378
- // derive the non-cached breakdown so the `LLM.Usage` contract is
377
+ // cached-read and cache-write subsets, and `completion_tokens` (inclusive
378
+ // total) with a `reasoning_tokens` subset. We pass the inclusive totals
379
+ // through and derive the non-cached breakdown so the `LLM.Usage` contract is
379
380
  // satisfied on both sides.
380
381
  const mapUsage = (usage) => {
381
382
  if (!usage)
382
383
  return undefined;
383
384
  const cached = usage.prompt_tokens_details?.cached_tokens;
385
+ const cacheWrite = usage.prompt_tokens_details?.cache_write_tokens;
384
386
  const reasoning = usage.completion_tokens_details?.reasoning_tokens;
385
- const nonCached = ProviderShared.subtractTokens(usage.prompt_tokens, cached);
387
+ const nonCached = ProviderShared.subtractTokens(usage.prompt_tokens, ProviderShared.sumTokens(cached, cacheWrite));
386
388
  return new Usage({
387
389
  inputTokens: usage.prompt_tokens,
388
390
  outputTokens: usage.completion_tokens,
389
391
  nonCachedInputTokens: nonCached,
390
392
  cacheReadInputTokens: cached,
393
+ cacheWriteInputTokens: cacheWrite,
391
394
  reasoningTokens: reasoning,
392
395
  totalTokens: ProviderShared.totalTokens(usage.prompt_tokens, usage.completion_tokens, usage.total_tokens),
393
396
  providerMetadata: { openai: usage },
@@ -223,6 +223,7 @@ export declare const protocol: Protocol<{
223
223
  readonly total_tokens?: number | undefined;
224
224
  readonly input_tokens_details?: {
225
225
  readonly cached_tokens?: number | undefined;
226
+ readonly cache_write_tokens?: number | undefined;
226
227
  } | null | undefined;
227
228
  readonly output_tokens_details?: {
228
229
  readonly reasoning_tokens?: number | undefined;
@@ -163,6 +163,7 @@ export declare const protocol: Protocol<{
163
163
  readonly total_tokens?: number | undefined;
164
164
  readonly prompt_tokens_details?: {
165
165
  readonly cached_tokens?: number | undefined;
166
+ readonly cache_write_tokens?: number | undefined;
166
167
  } | null | undefined;
167
168
  readonly completion_tokens_details?: {
168
169
  readonly reasoning_tokens?: number | undefined;
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-16169",
3
+ "version": "0.0.0-next-16173",
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-16169",
29
+ "@opencode-ai/http-recorder": "0.0.0-next-16173",
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-16169",
38
+ "@opencode-ai/schema": "0.0.0-next-16173",
39
39
  "aws4fetch": "1.0.20",
40
40
  "effect": "4.0.0-beta.98",
41
41
  "google-auth-library": "10.5.0"