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

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];
@@ -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-16114",
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-16114",
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-16114",
39
39
  "aws4fetch": "1.0.20",
40
40
  "effect": "4.0.0-beta.98",
41
41
  "google-auth-library": "10.5.0"