@opencode-ai/ai 0.0.0-next-16111 → 0.0.0-next-16116

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.
@@ -102,6 +102,13 @@ export declare const AnthropicMessagesBody: Schema.Struct<{
102
102
  readonly type: Schema.tag<"ephemeral">;
103
103
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
104
104
  }>>;
105
+ }>, Schema.Struct<{
106
+ readonly type: Schema.tag<"redacted_thinking">;
107
+ readonly data: Schema.String;
108
+ readonly cache_control: Schema.optional<Schema.Struct<{
109
+ readonly type: Schema.tag<"ephemeral">;
110
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
111
+ }>>;
105
112
  }>, Schema.Struct<{
106
113
  readonly type: Schema.tag<"tool_use">;
107
114
  readonly id: Schema.String;
@@ -268,6 +275,13 @@ export declare const protocol: Protocol<{
268
275
  readonly type: Schema.tag<"ephemeral">;
269
276
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
270
277
  }>>;
278
+ }>, Schema.Struct<{
279
+ readonly type: Schema.tag<"redacted_thinking">;
280
+ readonly data: Schema.String;
281
+ readonly cache_control: Schema.optional<Schema.Struct<{
282
+ readonly type: Schema.tag<"ephemeral">;
283
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
284
+ }>>;
271
285
  }>, Schema.Struct<{
272
286
  readonly type: Schema.tag<"tool_use">;
273
287
  readonly id: Schema.String;
@@ -375,6 +389,7 @@ export declare const protocol: Protocol<{
375
389
  readonly type: string;
376
390
  readonly text?: string | undefined;
377
391
  readonly name?: string | undefined;
392
+ readonly data?: string | undefined;
378
393
  readonly content?: unknown;
379
394
  readonly id?: string | undefined;
380
395
  readonly input?: unknown;
@@ -483,6 +498,13 @@ export declare const route: Route<{
483
498
  readonly type: Schema.tag<"ephemeral">;
484
499
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
485
500
  }>>;
501
+ }>, Schema.Struct<{
502
+ readonly type: Schema.tag<"redacted_thinking">;
503
+ readonly data: Schema.String;
504
+ readonly cache_control: Schema.optional<Schema.Struct<{
505
+ readonly type: Schema.tag<"ephemeral">;
506
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
507
+ }>>;
486
508
  }>, Schema.Struct<{
487
509
  readonly type: Schema.tag<"tool_use">;
488
510
  readonly id: Schema.String;
@@ -51,6 +51,14 @@ const AnthropicThinkingBlock = Schema.Struct({
51
51
  signature: Schema.optional(Schema.String),
52
52
  cache_control: Schema.optional(AnthropicCacheControl),
53
53
  });
54
+ // Safety-filtered thinking arrives as an opaque encrypted `data` payload with
55
+ // no visible text. It must round-trip verbatim so multi-turn thinking + tool
56
+ // use conversations keep their reasoning continuity.
57
+ const AnthropicRedactedThinkingBlock = Schema.Struct({
58
+ type: Schema.tag("redacted_thinking"),
59
+ data: Schema.String,
60
+ cache_control: Schema.optional(AnthropicCacheControl),
61
+ });
54
62
  const AnthropicToolUseBlock = Schema.Struct({
55
63
  type: Schema.tag("tool_use"),
56
64
  id: Schema.String,
@@ -101,6 +109,7 @@ const AnthropicUserBlock = Schema.Union([
101
109
  const AnthropicAssistantBlock = Schema.Union([
102
110
  AnthropicTextBlock,
103
111
  AnthropicThinkingBlock,
112
+ AnthropicRedactedThinkingBlock,
104
113
  AnthropicToolUseBlock,
105
114
  AnthropicServerToolUseBlock,
106
115
  AnthropicServerToolResultBlock,
@@ -165,6 +174,9 @@ const AnthropicStreamBlock = Schema.Struct({
165
174
  text: Schema.optional(Schema.String),
166
175
  thinking: Schema.optional(Schema.String),
167
176
  signature: Schema.optional(Schema.String),
177
+ // redacted_thinking blocks arrive whole in content_block_start with the
178
+ // encrypted payload in `data`; there is no streaming delta sequence.
179
+ data: Schema.optional(Schema.String),
168
180
  input: Schema.optional(Schema.Unknown),
169
181
  // *_tool_result blocks arrive whole as content_block_start (no streaming
170
182
  // delta) with the structured payload in `content` and the originating
@@ -222,6 +234,12 @@ const signatureFromMetadata = (metadata) => {
222
234
  return undefined;
223
235
  return typeof anthropic.signature === "string" ? anthropic.signature : undefined;
224
236
  };
237
+ const redactedDataFromMetadata = (metadata) => {
238
+ const anthropic = metadata?.anthropic;
239
+ if (!ProviderShared.isRecord(anthropic))
240
+ return undefined;
241
+ return typeof anthropic.redactedData === "string" ? anthropic.redactedData : undefined;
242
+ };
225
243
  const lowerTool = (breakpoints, tool, inputSchema) => ({
226
244
  name: tool.name,
227
245
  description: tool.description,
@@ -386,11 +404,16 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (re
386
404
  continue;
387
405
  }
388
406
  if (part.type === "reasoning") {
389
- content.push({
390
- type: "thinking",
391
- thinking: part.text,
392
- signature: part.encrypted ?? signatureFromMetadata(part.providerMetadata),
393
- });
407
+ // Mirrors Vercel's @ai-sdk/anthropic: a signature marks visible
408
+ // thinking; only signature-less parts carrying redactedData
409
+ // round-trip as opaque redacted_thinking blocks.
410
+ const signature = part.encrypted ?? signatureFromMetadata(part.providerMetadata);
411
+ const redactedData = redactedDataFromMetadata(part.providerMetadata);
412
+ if (signature === undefined && redactedData !== undefined) {
413
+ content.push({ type: "redacted_thinking", data: redactedData });
414
+ continue;
415
+ }
416
+ content.push({ type: "thinking", thinking: part.text, signature });
394
417
  continue;
395
418
  }
396
419
  if (part.type === "tool-call") {
@@ -637,6 +660,19 @@ const onContentBlockStart = (state, event) => {
637
660
  events,
638
661
  ];
639
662
  }
663
+ // Redacted thinking surfaces as an empty reasoning part carrying the opaque
664
+ // payload as `redactedData` metadata (same model as Vercel's
665
+ // @ai-sdk/anthropic). The existing content_block_stop closes the part.
666
+ if (block.type === "redacted_thinking" && block.data) {
667
+ const events = [];
668
+ return [
669
+ {
670
+ ...state,
671
+ lifecycle: Lifecycle.reasoningStart(state.lifecycle, events, `reasoning-${event.index ?? 0}`, anthropicMetadata({ redactedData: block.data })),
672
+ },
673
+ events,
674
+ ];
675
+ }
640
676
  const result = serverToolResultEvent(block);
641
677
  if (!result)
642
678
  return [state, NO_EVENTS];
@@ -63,12 +63,14 @@ declare const BedrockConverseBody: Schema.Struct<{
63
63
  readonly content: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
64
64
  readonly text: Schema.String;
65
65
  }>, Schema.Struct<{
66
- readonly reasoningContent: Schema.Struct<{
67
- readonly reasoningText: Schema.optional<Schema.Struct<{
66
+ readonly reasoningContent: Schema.Union<readonly [Schema.Struct<{
67
+ readonly reasoningText: Schema.Struct<{
68
68
  readonly text: Schema.String;
69
69
  readonly signature: Schema.optional<Schema.String>;
70
- }>>;
71
- }>;
70
+ }>;
71
+ }>, Schema.Struct<{
72
+ readonly redactedContent: Schema.String;
73
+ }>]>;
72
74
  }>, Schema.Struct<{
73
75
  readonly toolUse: Schema.Struct<{
74
76
  readonly toolUseId: Schema.String;
@@ -194,12 +196,14 @@ export declare const protocol: Protocol<{
194
196
  readonly content: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
195
197
  readonly text: Schema.String;
196
198
  }>, Schema.Struct<{
197
- readonly reasoningContent: Schema.Struct<{
198
- readonly reasoningText: Schema.optional<Schema.Struct<{
199
+ readonly reasoningContent: Schema.Union<readonly [Schema.Struct<{
200
+ readonly reasoningText: Schema.Struct<{
199
201
  readonly text: Schema.String;
200
202
  readonly signature: Schema.optional<Schema.String>;
201
- }>>;
202
- }>;
203
+ }>;
204
+ }>, Schema.Struct<{
205
+ readonly redactedContent: Schema.String;
206
+ }>]>;
203
207
  }>, Schema.Struct<{
204
208
  readonly toolUse: Schema.Struct<{
205
209
  readonly toolUseId: Schema.String;
@@ -289,6 +293,7 @@ export declare const protocol: Protocol<{
289
293
  readonly reasoningContent?: {
290
294
  readonly text?: string | undefined;
291
295
  readonly signature?: string | undefined;
296
+ readonly redactedContent?: string | undefined;
292
297
  } | undefined;
293
298
  } | undefined;
294
299
  } | undefined;
@@ -347,6 +352,7 @@ export declare const protocol: Protocol<{
347
352
  readonly reasoningContent?: {
348
353
  readonly text?: string | undefined;
349
354
  readonly signature?: string | undefined;
355
+ readonly redactedContent?: string | undefined;
350
356
  } | undefined;
351
357
  } | undefined;
352
358
  } | undefined;
@@ -429,12 +435,14 @@ export declare const route: Route<{
429
435
  readonly content: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
430
436
  readonly text: Schema.String;
431
437
  }>, Schema.Struct<{
432
- readonly reasoningContent: Schema.Struct<{
433
- readonly reasoningText: Schema.optional<Schema.Struct<{
438
+ readonly reasoningContent: Schema.Union<readonly [Schema.Struct<{
439
+ readonly reasoningText: Schema.Struct<{
434
440
  readonly text: Schema.String;
435
441
  readonly signature: Schema.optional<Schema.String>;
436
- }>>;
437
- }>;
442
+ }>;
443
+ }>, Schema.Struct<{
444
+ readonly redactedContent: Schema.String;
445
+ }>]>;
438
446
  }>, Schema.Struct<{
439
447
  readonly toolUse: Schema.Struct<{
440
448
  readonly toolUseId: Schema.String;
@@ -40,12 +40,15 @@ const BedrockToolResultBlock = Schema.Struct({
40
40
  }),
41
41
  });
42
42
  const BedrockReasoningBlock = Schema.Struct({
43
- reasoningContent: Schema.Struct({
44
- reasoningText: Schema.optional(Schema.Struct({
45
- text: Schema.String,
46
- signature: Schema.optional(Schema.String),
47
- })),
48
- }),
43
+ reasoningContent: Schema.Union([
44
+ Schema.Struct({
45
+ reasoningText: Schema.Struct({
46
+ text: Schema.String,
47
+ signature: Schema.optional(Schema.String),
48
+ }),
49
+ }),
50
+ Schema.Struct({ redactedContent: Schema.String }),
51
+ ]),
49
52
  });
50
53
  const BedrockUserBlock = Schema.Union([
51
54
  BedrockTextBlock,
@@ -124,6 +127,8 @@ const BedrockEvent = Schema.Struct({
124
127
  reasoningContent: Schema.optional(Schema.Struct({
125
128
  text: Schema.optional(Schema.String),
126
129
  signature: Schema.optional(Schema.String),
130
+ // Blob fields in Bedrock's JSON event stream are base64 strings.
131
+ redactedContent: Schema.optional(Schema.String),
127
132
  })),
128
133
  })),
129
134
  })),
@@ -178,6 +183,12 @@ const reasoningSignature = (part) => {
178
183
  return (part.encrypted ??
179
184
  (ProviderShared.isRecord(bedrock) && typeof bedrock.signature === "string" ? bedrock.signature : undefined));
180
185
  };
186
+ const reasoningRedactedData = (part) => {
187
+ const bedrock = part.providerMetadata?.bedrock;
188
+ return ProviderShared.isRecord(bedrock) && typeof bedrock.redactedData === "string"
189
+ ? bedrock.redactedData
190
+ : undefined;
191
+ };
181
192
  const lowerToolCall = (part) => ({
182
193
  toolUse: {
183
194
  toolUseId: part.id,
@@ -259,11 +270,13 @@ const lowerMessages = Effect.fn("BedrockConverse.lowerMessages")(function* (requ
259
270
  continue;
260
271
  }
261
272
  if (part.type === "reasoning") {
262
- content.push({
263
- reasoningContent: {
264
- reasoningText: { text: part.text, signature: reasoningSignature(part) },
265
- },
266
- });
273
+ const signature = reasoningSignature(part);
274
+ const redactedData = reasoningRedactedData(part);
275
+ if (signature === undefined && redactedData !== undefined) {
276
+ content.push({ reasoningContent: { redactedContent: redactedData } });
277
+ continue;
278
+ }
279
+ content.push({ reasoningContent: { reasoningText: { text: part.text, signature } } });
267
280
  continue;
268
281
  }
269
282
  if (part.type === "tool-call") {
@@ -399,12 +412,15 @@ const step = (state, event) => Effect.gen(function* () {
399
412
  const index = event.contentBlockDelta.contentBlockIndex;
400
413
  const reasoning = event.contentBlockDelta.delta.reasoningContent;
401
414
  const events = [];
415
+ const lifecycle = reasoning.text
416
+ ? Lifecycle.reasoningDelta(state.lifecycle, events, `reasoning-${index}`, reasoning.text)
417
+ : reasoning.redactedContent !== undefined
418
+ ? Lifecycle.reasoningStart(state.lifecycle, events, `reasoning-${index}`, bedrockMetadata({ redactedData: reasoning.redactedContent }))
419
+ : state.lifecycle;
402
420
  return [
403
421
  {
404
422
  ...state,
405
- lifecycle: reasoning.text
406
- ? Lifecycle.reasoningDelta(state.lifecycle, events, `reasoning-${index}`, reasoning.text)
407
- : state.lifecycle,
423
+ lifecycle,
408
424
  reasoningSignatures: reasoning.signature
409
425
  ? { ...state.reasoningSignatures, [index]: reasoning.signature }
410
426
  : state.reasoningSignatures,
@@ -76,12 +76,14 @@ export declare const routes: import("../route").Route<{
76
76
  readonly content: import("effect/Schema").$Array<import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
77
77
  readonly text: import("effect/Schema").String;
78
78
  }>, import("effect/Schema").Struct<{
79
- readonly reasoningContent: import("effect/Schema").Struct<{
80
- readonly reasoningText: import("effect/Schema").optional<import("effect/Schema").Struct<{
79
+ readonly reasoningContent: import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
80
+ readonly reasoningText: import("effect/Schema").Struct<{
81
81
  readonly text: import("effect/Schema").String;
82
82
  readonly signature: import("effect/Schema").optional<import("effect/Schema").String>;
83
- }>>;
84
- }>;
83
+ }>;
84
+ }>, import("effect/Schema").Struct<{
85
+ readonly redactedContent: import("effect/Schema").String;
86
+ }>]>;
85
87
  }>, import("effect/Schema").Struct<{
86
88
  readonly toolUse: import("effect/Schema").Struct<{
87
89
  readonly toolUseId: import("effect/Schema").String;
@@ -105,6 +105,13 @@ export declare const routes: import("../route").Route<{
105
105
  readonly type: import("effect/Schema").tag<"ephemeral">;
106
106
  readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
107
107
  }>>;
108
+ }>, import("effect/Schema").Struct<{
109
+ readonly type: import("effect/Schema").tag<"redacted_thinking">;
110
+ readonly data: import("effect/Schema").String;
111
+ readonly cache_control: import("effect/Schema").optional<import("effect/Schema").Struct<{
112
+ readonly type: import("effect/Schema").tag<"ephemeral">;
113
+ readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
114
+ }>>;
108
115
  }>, import("effect/Schema").Struct<{
109
116
  readonly type: import("effect/Schema").tag<"tool_use">;
110
117
  readonly id: import("effect/Schema").String;
@@ -91,6 +91,13 @@ export declare const routes: import("../route").Route<{
91
91
  readonly type: import("effect/Schema").tag<"ephemeral">;
92
92
  readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
93
93
  }>>;
94
+ }>, import("effect/Schema").Struct<{
95
+ readonly type: import("effect/Schema").tag<"redacted_thinking">;
96
+ readonly data: import("effect/Schema").String;
97
+ readonly cache_control: import("effect/Schema").optional<import("effect/Schema").Struct<{
98
+ readonly type: import("effect/Schema").tag<"ephemeral">;
99
+ readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
100
+ }>>;
94
101
  }>, import("effect/Schema").Struct<{
95
102
  readonly type: import("effect/Schema").tag<"tool_use">;
96
103
  readonly id: import("effect/Schema").String;
@@ -114,6 +114,13 @@ export declare const routes: Route<{
114
114
  readonly type: Schema.tag<"ephemeral">;
115
115
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
116
116
  }>>;
117
+ }>, Schema.Struct<{
118
+ readonly type: Schema.tag<"redacted_thinking">;
119
+ readonly data: Schema.String;
120
+ readonly cache_control: Schema.optional<Schema.Struct<{
121
+ readonly type: Schema.tag<"ephemeral">;
122
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
123
+ }>>;
117
124
  }>, Schema.Struct<{
118
125
  readonly type: Schema.tag<"tool_use">;
119
126
  readonly id: Schema.String;
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-16111",
3
+ "version": "0.0.0-next-16116",
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-16111",
29
+ "@opencode-ai/http-recorder": "0.0.0-next-16116",
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-16111",
38
+ "@opencode-ai/schema": "0.0.0-next-16116",
39
39
  "aws4fetch": "1.0.20",
40
40
  "effect": "4.0.0-beta.98",
41
41
  "google-auth-library": "10.5.0"