@opencode/ai 0.0.0-dev-20536 → 0.0.0-dev-20537

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.
@@ -462,7 +462,7 @@ const serverToolResultType = (name) => {
462
462
  return "web_fetch_tool_result";
463
463
  return undefined;
464
464
  };
465
- const lowerServerToolResult = Effect.fn("AnthropicMessages.lowerServerToolResult")(function* (part, providerMetadataKey) {
465
+ const lowerServerToolResult = Effect.fnUntraced(function* (part, providerMetadataKey) {
466
466
  const wireType = serverToolResultType(part.name);
467
467
  if (!wireType)
468
468
  return yield* invalid(`Anthropic Messages does not know how to round-trip server tool result for ${part.name}`);
@@ -538,7 +538,7 @@ const citationsFromMetadata = (metadata) => {
538
538
  return undefined;
539
539
  };
540
540
  const isHttpUrl = (value) => /^https?:\/\//i.test(value.trim());
541
- const lowerMedia = Effect.fn("AnthropicMessages.lowerMedia")(function* (part, breakpoints) {
541
+ const lowerMedia = Effect.fnUntraced(function* (part, breakpoints) {
542
542
  const mime = part.media.mediaType.toLowerCase();
543
543
  const cacheControlValue = breakpoints ? cacheControl(breakpoints, part.cache) : undefined;
544
544
  const fileId = fileIdFromMetadata(part.metadata);
@@ -716,7 +716,7 @@ const splitsLocalToolResults = (messages, index) => {
716
716
  }
717
717
  return pending.size > 0;
718
718
  };
719
- const lowerNativeSystemUpdate = Effect.fn("AnthropicMessages.lowerNativeSystemUpdate")(function* (message, breakpoints) {
719
+ const lowerNativeSystemUpdate = Effect.fnUntraced(function* (message, breakpoints) {
720
720
  const content = yield* ProviderShared.systemUpdateText("Anthropic Messages", message);
721
721
  return {
722
722
  role: "system",
@@ -727,7 +727,7 @@ const lowerNativeSystemUpdate = Effect.fn("AnthropicMessages.lowerNativeSystemUp
727
727
  })),
728
728
  };
729
729
  });
730
- const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (request, breakpoints) {
730
+ const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
731
731
  const messages = [];
732
732
  const providerMetadataKey = request.model.route.providerMetadataKey ?? String(request.model.provider);
733
733
  for (const [index, message] of request.messages.entries()) {
@@ -211,7 +211,7 @@ const lowerToolCall = (part, normalizeID) => ({
211
211
  input: removeEmptyToolInputKeys(part.input),
212
212
  },
213
213
  });
214
- const lowerToolResultContent = Effect.fn("BedrockConverse.lowerToolResultContent")(function* (part, documentNames) {
214
+ const lowerToolResultContent = Effect.fnUntraced(function* (part, documentNames) {
215
215
  if (part.result.type === "text" || part.result.type === "error")
216
216
  return [{ text: ProviderShared.toolResultText(part) }];
217
217
  if (part.result.type === "json")
@@ -227,7 +227,7 @@ const lowerToolResultContent = Effect.fn("BedrockConverse.lowerToolResultContent
227
227
  }
228
228
  return content;
229
229
  });
230
- const lowerToolResult = Effect.fn("BedrockConverse.lowerToolResult")(function* (part, documentNames, normalizeID) {
230
+ const lowerToolResult = Effect.fnUntraced(function* (part, documentNames, normalizeID) {
231
231
  return {
232
232
  toolResult: {
233
233
  toolUseId: normalizeID(part.id),
@@ -238,7 +238,7 @@ const lowerToolResult = Effect.fn("BedrockConverse.lowerToolResult")(function* (
238
238
  });
239
239
  // Keep Claude and Nova tool-result images inline; put other models' images beside the result.
240
240
  const keepToolImagesInline = (id) => id.includes("anthropic.claude-") || id.includes("amazon.nova-");
241
- const lowerMessages = Effect.fn("BedrockConverse.lowerMessages")(function* (request, breakpoints) {
241
+ const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
242
242
  const messages = [];
243
243
  const documentNames = new Set();
244
244
  // Mistral can reject replay IDs even when they satisfy Converse's broader ID syntax.
@@ -201,7 +201,7 @@ const lowerToolConfig = (toolChoice) => ProviderShared.matchToolChoice("Gemini",
201
201
  required: () => ({ functionCallingConfig: { mode: "ANY" } }),
202
202
  tool: (name) => ({ functionCallingConfig: { mode: "ANY", allowedFunctionNames: [name] } }),
203
203
  });
204
- const lowerContentPart = Effect.fn("Gemini.lowerContentPart")(function* (part) {
204
+ const lowerContentPart = Effect.fnUntraced(function* (part) {
205
205
  if (part.type === "text")
206
206
  return { text: part.text };
207
207
  return yield* GeminiGenerateContent.mediaPart("Gemini", part.media);
@@ -217,7 +217,7 @@ const lowerToolCall = (part, omitIds, metadataKey) => ({
217
217
  functionCall: { ...(omitIds ? {} : { id: part.id }), name: part.name, args: part.input },
218
218
  thoughtSignature: thoughtSignature(part.providerMetadata, metadataKey),
219
219
  });
220
- const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
220
+ const lowerMessages = Effect.fnUntraced(function* (request) {
221
221
  const contents = [];
222
222
  const metadataKey = request.model.route.providerMetadataKey ?? String(request.model.provider);
223
223
  const omitCallIds = omitsFunctionCallIds(request.model.id);
@@ -140,7 +140,7 @@ const Event = Schema.Union([
140
140
  // =============================================================================
141
141
  // Request Body Construction
142
142
  // =============================================================================
143
- const mediaContent = Effect.fn("GoogleInteractions.mediaContent")(function* (asset) {
143
+ const mediaContent = Effect.fnUntraced(function* (asset) {
144
144
  if (asset.kind !== "image" &&
145
145
  asset.kind !== "audio" &&
146
146
  asset.kind !== "video" &&
@@ -160,7 +160,7 @@ const signature = (metadata, key) => {
160
160
  ? value.interactionSignature
161
161
  : undefined;
162
162
  };
163
- const lowerMessages = Effect.fn("GoogleInteractions.lowerMessages")(function* (request) {
163
+ const lowerMessages = Effect.fnUntraced(function* (request) {
164
164
  const steps = [];
165
165
  const key = request.model.route.providerMetadataKey ?? String(request.model.provider);
166
166
  for (const message of request.messages) {
@@ -223,7 +223,7 @@ const lowerMessages = Effect.fn("GoogleInteractions.lowerMessages")(function* (r
223
223
  }
224
224
  return steps;
225
225
  });
226
- const lowerToolResult = Effect.fn("GoogleInteractions.lowerToolResult")(function* (part) {
226
+ const lowerToolResult = Effect.fnUntraced(function* (part) {
227
227
  if (part.result.type === "json" && ProviderShared.isRecord(part.result.value))
228
228
  return part.result.value;
229
229
  if (part.result.type !== "content")
@@ -143,7 +143,7 @@ const MistralEvent = Schema.StructWithRest(Schema.Struct({
143
143
  error: optionalNull(MistralError),
144
144
  }), [Schema.Record(Schema.String, Schema.Unknown)]);
145
145
  const MistralStreamEvent = Schema.Union([Schema.Literal(DONE), Protocol.jsonEvent(MistralEvent)]);
146
- const lowerMedia = Effect.fn("MistralChat.lowerMedia")(function* (part) {
146
+ const lowerMedia = Effect.fnUntraced(function* (part) {
147
147
  const mime = part.media.mediaType.toLowerCase();
148
148
  const url = ProviderShared.mediaUrl(part.media) ??
149
149
  (yield* ProviderShared.requireInlineMedia("Mistral Chat", part.media)).dataUrl;
@@ -153,7 +153,7 @@ const lowerMedia = Effect.fn("MistralChat.lowerMedia")(function* (part) {
153
153
  return { type: "document_url", document_url: url };
154
154
  return yield* ProviderShared.invalidRequest(`Mistral Chat does not support media type ${part.media.mediaType}`);
155
155
  });
156
- const lowerUser = Effect.fn("MistralChat.lowerUser")(function* (message) {
156
+ const lowerUser = Effect.fnUntraced(function* (message) {
157
157
  const content = [];
158
158
  for (const part of message.content) {
159
159
  if (part.type === "text") {
@@ -175,7 +175,7 @@ const lowerToolCall = (part, normalizeID) => ({
175
175
  type: "function",
176
176
  function: { name: part.name, arguments: ProviderShared.encodeJson(part.input) },
177
177
  });
178
- const lowerAssistant = Effect.fn("MistralChat.lowerAssistant")(function* (message, normalizeID, prefix) {
178
+ const lowerAssistant = Effect.fnUntraced(function* (message, normalizeID, prefix) {
179
179
  const structured = message.content.some((part) => part.type === "reasoning" && isMistralThinkingContent(part.providerMetadata?.mistral?.thinking));
180
180
  const content = [];
181
181
  const text = [];
@@ -211,7 +211,7 @@ const lowerAssistant = Effect.fn("MistralChat.lowerAssistant")(function* (messag
211
211
  ...(prefix ? { prefix: true } : {}),
212
212
  };
213
213
  });
214
- const lowerToolResults = Effect.fn("MistralChat.lowerToolResults")(function* (message, normalizeID) {
214
+ const lowerToolResults = Effect.fnUntraced(function* (message, normalizeID) {
215
215
  const output = [];
216
216
  for (const part of message.content) {
217
217
  if (part.type !== "tool-result")
@@ -244,7 +244,7 @@ const lowerToolResults = Effect.fn("MistralChat.lowerToolResults")(function* (me
244
244
  }
245
245
  return output;
246
246
  });
247
- const lowerMessages = Effect.fn("MistralChat.lowerMessages")(function* (request) {
247
+ const lowerMessages = Effect.fnUntraced(function* (request) {
248
248
  const normalizeID = MistralToolID.normalizer(request);
249
249
  const messages = request.system.length === 0
250
250
  ? []
@@ -289,7 +289,7 @@ const BASE_ADAPTER = { id: ADAPTER, name: NAME };
289
289
  // =============================================================================
290
290
  // Request Lowering
291
291
  // =============================================================================
292
- export const lowerTool = Effect.fn("OpenResponses.lowerTool")(function* (protocolName, tool) {
292
+ export const lowerTool = Effect.fnUntraced(function* (protocolName, tool) {
293
293
  if (tool.native !== undefined)
294
294
  return yield* ProviderShared.invalidRequest(`${protocolName} does not support provider-native tool ${tool.name}`);
295
295
  return {
@@ -343,12 +343,15 @@ const lowerReasoning = (part, providerMetadataKey) => {
343
343
  encrypted_content: encryptedContent,
344
344
  };
345
345
  };
346
- const lowerMedia = Effect.fn("OpenResponses.lowerMedia")(function* (part, request, adapter, target) {
346
+ const decodeImageDetail = ProviderShared.validateWith(Schema.decodeUnknownEffect(OpenResponsesInputImage.fields.detail));
347
+ const decodeMessageMetadata = ProviderShared.validateWith(Schema.decodeUnknownEffect(MessageMetadata));
348
+ const lowerMedia = Effect.fnUntraced(function* (part, request, adapter, target) {
347
349
  const media = part.media.inline();
348
350
  const providerMedia = adapter.lowerMedia?.({ part, media, request });
349
351
  if (providerMedia)
350
352
  return providerMedia;
351
- const detail = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(OpenResponsesInputImage.fields.detail))(part.providerMetadata?.[metadataKey(request.model)]?.detail);
353
+ const rawDetail = part.providerMetadata?.[metadataKey(request.model)]?.detail;
354
+ const detail = rawDetail === undefined ? undefined : yield* decodeImageDetail(rawDetail);
352
355
  const mime = part.media.mediaType.toLowerCase();
353
356
  const url = ProviderShared.mediaUrl(part.media);
354
357
  const location = url ?? (yield* ProviderShared.requireInlineMedia(adapter.name, part.media)).dataUrl;
@@ -403,11 +406,12 @@ const lowerToolResultOutput = Effect.fnUntraced(function* (part, request, adapte
403
406
  return yield* Effect.forEach(content, (item) => lowerToolResultContentItem(item, request, adapter));
404
407
  });
405
408
  const DEFAULT_EFFORT = "medium";
406
- const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (request, adapter) {
409
+ const lowerMessages = Effect.fnUntraced(function* (request, adapter) {
407
410
  const input = [];
408
411
  const providerMetadataKey = metadataKey(request.model);
409
412
  for (const message of request.messages) {
410
- const metadata = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Schema.UndefinedOr(MessageMetadata)))(message.providerMetadata?.[providerMetadataKey]);
413
+ const rawMetadata = message.providerMetadata?.[providerMetadataKey];
414
+ const metadata = rawMetadata === undefined ? undefined : yield* decodeMessageMetadata(rawMetadata);
411
415
  if (message.role === "system") {
412
416
  const update = effortUpdate(message);
413
417
  if (update) {
@@ -555,7 +559,7 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
555
559
  }
556
560
  return input;
557
561
  });
558
- export const lowerConversation = Effect.fn("OpenResponses.lowerConversation")(function* (request, adapter) {
562
+ export const lowerConversation = Effect.fnUntraced(function* (request, adapter) {
559
563
  const instructions = ProviderShared.joinText(request.system);
560
564
  return {
561
565
  model: request.model.id,
@@ -233,7 +233,7 @@ const lowerToolCall = (part, options) => ({
233
233
  },
234
234
  extra_content: decodeExtraContent(part.providerMetadata?.[options.providerMetadataKey]?.extraContent),
235
235
  });
236
- const lowerMedia = Effect.fn("OpenAIChat.lowerMedia")(function* (part) {
236
+ const lowerMedia = Effect.fnUntraced(function* (part) {
237
237
  // Chat Completions accepts PDFs, and no other documents, as inline `file` parts; file URLs are not supported.
238
238
  if (part.media.mediaType.toLowerCase() === "application/pdf")
239
239
  return {
@@ -273,7 +273,7 @@ const lowerReasoningDetail = (detail) => {
273
273
  return detail;
274
274
  };
275
275
  const isKimiDetail = (detail) => detail.type === "summary" || detail.type === "encrypted";
276
- const lowerUserMessage = Effect.fn("OpenAIChat.lowerUserMessage")(function* (message, options) {
276
+ const lowerUserMessage = Effect.fnUntraced(function* (message, options) {
277
277
  const content = [];
278
278
  for (const part of message.content) {
279
279
  if (part.type === "text") {
@@ -293,7 +293,7 @@ const lowerUserMessage = Effect.fn("OpenAIChat.lowerUserMessage")(function* (mes
293
293
  };
294
294
  return { role: "user", content };
295
295
  });
296
- const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(function* (message, configuredField, requireReasoning, options) {
296
+ const lowerAssistantMessage = Effect.fnUntraced(function* (message, configuredField, requireReasoning, options) {
297
297
  const content = [];
298
298
  const reasoning = [];
299
299
  const toolCalls = [];
@@ -359,7 +359,7 @@ const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(func
359
359
  return result;
360
360
  return { ...result, [field]: reasoningText };
361
361
  });
362
- const lowerToolMessages = Effect.fn("OpenAIChat.lowerToolMessages")(function* (message, options) {
362
+ const lowerToolMessages = Effect.fnUntraced(function* (message, options) {
363
363
  const messages = [];
364
364
  const attachments = [];
365
365
  for (const part of message.content) {
@@ -383,14 +383,14 @@ const toolMessage = (toolCallID, text, cacheControl) => ({
383
383
  tool_call_id: toolCallID,
384
384
  content: cacheControl === undefined ? text : [{ type: "text", text, cache_control: cacheControl }],
385
385
  });
386
- const lowerMessage = Effect.fn("OpenAIChat.lowerMessage")(function* (message, reasoningField, requireReasoning, options) {
386
+ const lowerMessage = Effect.fnUntraced(function* (message, reasoningField, requireReasoning, options) {
387
387
  if (message.role === "user")
388
388
  return [yield* lowerUserMessage(message, options)];
389
389
  if (message.role === "assistant")
390
390
  return [yield* lowerAssistantMessage(message, reasoningField, requireReasoning, options)];
391
391
  return (yield* lowerToolMessages(message, options)).messages;
392
392
  });
393
- const lowerMessages = Effect.fn("OpenAIChat.lowerMessages")(function* (request, options) {
393
+ const lowerMessages = Effect.fnUntraced(function* (request, options) {
394
394
  const system = request.system.length === 0
395
395
  ? []
396
396
  : request.system.some((part) => part.cache !== undefined) && options.cacheControl !== undefined
@@ -126,7 +126,7 @@ const nativeImageTool = (tool) => {
126
126
  const native = nativeImageToolInput(tool);
127
127
  return Schema.is(OpenAIResponsesImageGenerationTool)(native) ? native : undefined;
128
128
  };
129
- const lowerTool = Effect.fn("OpenAIResponses.lowerTool")(function* (tool) {
129
+ const lowerTool = Effect.fnUntraced(function* (tool) {
130
130
  const native = nativeImageToolInput(tool);
131
131
  if (native !== undefined) {
132
132
  if (Schema.is(OpenAIResponsesImageGenerationTool)(native))
@@ -137,7 +137,7 @@ const lowerTool = Effect.fn("OpenAIResponses.lowerTool")(function* (tool) {
137
137
  });
138
138
  // Native namespaces hold only function tools, so deeper levels flatten into
139
139
  // the leaf names the same way non-native protocols flatten the whole tree.
140
- const lowerToolEntry = Effect.fn("OpenAIResponses.lowerToolEntry")(function* (tool) {
140
+ const lowerToolEntry = Effect.fnUntraced(function* (tool) {
141
141
  if (tool.type === "tool")
142
142
  return yield* lowerTool(tool);
143
143
  // OpenAI requires a namespace description; fall back to a generic one so a
@@ -108,7 +108,7 @@ export const wrapSystemUpdate = (parts) => `<system-update>\n${escapeSystemUpdat
108
108
  * raw retrieved, tool, or web content into privileged updates: keep untrusted
109
109
  * data in ordinary user/tool messages instead.
110
110
  */
111
- export const systemUpdateText = Effect.fn("ProviderShared.systemUpdateText")(function* (route, message) {
111
+ export const systemUpdateText = Effect.fnUntraced(function* (route, message) {
112
112
  const content = [];
113
113
  for (const part of message.content) {
114
114
  if (!supportsContent(part, ["text"]))
@@ -118,7 +118,7 @@ export const systemUpdateText = Effect.fn("ProviderShared.systemUpdateText")(fun
118
118
  return content;
119
119
  });
120
120
  /** Lower an unsupported privileged update into visible, in-order user text. */
121
- export const wrappedSystemUpdate = Effect.fn("ProviderShared.wrappedSystemUpdate")(function* (route, message) {
121
+ export const wrappedSystemUpdate = Effect.fnUntraced(function* (route, message) {
122
122
  const content = yield* systemUpdateText(route, message);
123
123
  return { type: "text", text: wrapSystemUpdate(content), cache: content.at(-1)?.cache };
124
124
  });
@@ -61,7 +61,7 @@ function documentName(filename, names) {
61
61
  names.add(name);
62
62
  return name;
63
63
  }
64
- const mediaBase64 = Effect.fn("BedrockMedia.mediaBase64")(function* (part) {
64
+ const mediaBase64 = Effect.fnUntraced(function* (part) {
65
65
  const media = yield* ProviderShared.requireInlineMedia("Bedrock Converse", part.media);
66
66
  const bytes = yield* Effect.fromResult(Encoding.decodeBase64(media.base64)).pipe(Effect.mapError((cause) => ProviderShared.invalidRequest("Bedrock Converse media data must be valid base64", cause)));
67
67
  return Encoding.encodeBase64(bytes);
@@ -71,7 +71,7 @@ const mediaBase64 = Effect.fn("BedrockMedia.mediaBase64")(function* (part) {
71
71
  // document block. Image MIME types not in `IMAGE_FORMATS` (e.g. `image/svg+xml`)
72
72
  // get an image-specific error so the caller knows it's a format-support issue,
73
73
  // not a kind-detection issue.
74
- export const lower = Effect.fn("BedrockMedia.lower")(function* (part, documentNames) {
74
+ export const lower = Effect.fnUntraced(function* (part, documentNames) {
75
75
  const mime = part.media.mediaType.toLowerCase();
76
76
  const imageFormat = IMAGE_FORMATS[mime];
77
77
  if (imageFormat) {
@@ -14,32 +14,32 @@ export const sseFraming = (bytes, events, includeDone = false) => bytes.pipe(Str
14
14
  return {
15
15
  output,
16
16
  parser: makeParser((event) => {
17
- if (event._tag === "Event")
18
- output.push(event);
17
+ if (event._tag === "Event" &&
18
+ (events === undefined || events.has(event.event)) &&
19
+ event.data.length > 0 &&
20
+ // Some OpenAI-compatible proxies serialize an empty flush as a bare
21
+ // `data: null`, between events or after `[DONE]`. No protocol has a
22
+ // null event, so it carries nothing and must not abort the stream.
23
+ event.data !== "null" &&
24
+ // Vertex AI partner models (e.g. `xai/grok-4.6`) send their SSE
25
+ // keepalive comment as `data: : keepalive` while reasoning.
26
+ event.data !== ": keepalive" &&
27
+ (event.data !== "[DONE]" || includeDone || (events !== undefined && event.event !== "message")))
28
+ output.push(event.data);
19
29
  }),
20
30
  };
21
- }, (state, chunk) => Effect.gen(function* () {
31
+ }, (state, chunk) => {
22
32
  const error = state.parser.feed(chunk);
23
- if (error)
24
- return yield* new AIError({
25
- reason: new InvalidProviderOutputError({
26
- route: "sse",
27
- message: error.message,
28
- body: chunk,
29
- cause: error,
30
- }),
31
- });
32
- return [state, state.output.splice(0)];
33
- })), Stream.filter((event) => (events === undefined || events.has(event.event)) &&
34
- event.data.length > 0 &&
35
- // Some OpenAI-compatible proxies serialize an empty flush as a bare
36
- // `data: null`, between events or after `[DONE]`. No protocol has a
37
- // null event, so it carries nothing and must not abort the stream.
38
- event.data !== "null" &&
39
- // Vertex AI partner models (e.g. `xai/grok-4.6`) send their SSE
40
- // keepalive comment as `data: : keepalive` while reasoning.
41
- event.data !== ": keepalive" &&
42
- (event.data !== "[DONE]" || includeDone || (events !== undefined && event.event !== "message"))), Stream.map((event) => event.data));
33
+ if (!error)
34
+ return Effect.succeed([state, state.output.splice(0)]);
35
+ const reason = new InvalidProviderOutputError({
36
+ route: "sse",
37
+ message: error.message,
38
+ body: chunk,
39
+ cause: error,
40
+ });
41
+ return Effect.fail(new AIError({ reason }));
42
+ }));
43
43
  /** Server-Sent Events framing. Used by every JSON-streaming HTTP provider. */
44
44
  export const sse = { id: "sse", frame: sseFraming };
45
45
  /** Server-Sent Events framing that retains the conventional `[DONE]` sentinel. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "0.0.0-dev-20536",
3
+ "version": "0.0.0-dev-20537",
4
4
  "name": "@opencode/ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -34,7 +34,7 @@
34
34
  "devDependencies": {
35
35
  "@clack/prompts": "1.0.0-alpha.1",
36
36
  "@effect/platform-node": "4.0.0-rc.112",
37
- "@opencode/http-recorder": "0.0.0-dev-20536",
37
+ "@opencode/http-recorder": "0.0.0-dev-20537",
38
38
  "@tsconfig/bun": "1.0.9",
39
39
  "@types/bun": "1.4.0",
40
40
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -44,7 +44,7 @@
44
44
  "@aws-sdk/credential-providers": "3.1057.0",
45
45
  "@smithy/eventstream-codec": "4.2.14",
46
46
  "@smithy/util-utf8": "4.2.2",
47
- "@opencode/schema": "0.0.0-dev-20536",
47
+ "@opencode/schema": "0.0.0-dev-20537",
48
48
  "aws4fetch": "1.0.20",
49
49
  "effect": "4.0.0-rc.112",
50
50
  "google-auth-library": "10.5.0"