@opencode/ai 2.1.1 → 2.1.3

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.
Files changed (99) hide show
  1. package/dist/cache-policy.js +6 -5
  2. package/dist/experimental/evaluation.d.ts +7 -6
  3. package/dist/experimental/evaluation.js +2 -3
  4. package/dist/experimental/realtime.d.ts +59 -0
  5. package/dist/experimental/realtime.js +32 -19
  6. package/dist/experimental/system-one.js +8 -8
  7. package/dist/experimental.d.ts +1 -1
  8. package/dist/generation.js +1 -1
  9. package/dist/image-client.d.ts +3 -1
  10. package/dist/image.d.ts +10 -2
  11. package/dist/image.js +2 -2
  12. package/dist/llm.d.ts +2 -4
  13. package/dist/llm.js +2 -2
  14. package/dist/media-model.d.ts +2 -2
  15. package/dist/media-model.js +1 -1
  16. package/dist/media.js +3 -3
  17. package/dist/promise.d.ts +1 -1
  18. package/dist/promise.js +3 -5
  19. package/dist/protocols/alibaba-chat.d.ts +6 -6
  20. package/dist/protocols/alibaba-chat.js +3 -3
  21. package/dist/protocols/alibaba-messages.d.ts +1 -1
  22. package/dist/protocols/alibaba-messages.js +1 -1
  23. package/dist/protocols/alibaba-responses.d.ts +3 -3
  24. package/dist/protocols/anthropic-messages.js +10 -12
  25. package/dist/protocols/bedrock-converse.d.ts +6 -53
  26. package/dist/protocols/bedrock-converse.js +4 -3
  27. package/dist/protocols/bedrock-event-stream.d.ts +6 -1
  28. package/dist/protocols/bedrock-event-stream.js +9 -8
  29. package/dist/protocols/cohere-chat.d.ts +6 -2
  30. package/dist/protocols/cohere-chat.js +2 -2
  31. package/dist/protocols/gemini.d.ts +12 -2
  32. package/dist/protocols/gemini.js +10 -13
  33. package/dist/protocols/google-interactions.d.ts +2 -1
  34. package/dist/protocols/google-interactions.js +14 -9
  35. package/dist/protocols/meta-responses.d.ts +6 -6
  36. package/dist/protocols/mistral-chat.js +1 -4
  37. package/dist/protocols/open-responses.d.ts +21 -21
  38. package/dist/protocols/open-responses.js +3 -3
  39. package/dist/protocols/openai-chat.d.ts +8 -7
  40. package/dist/protocols/openai-chat.js +4 -5
  41. package/dist/protocols/openai-compatible-responses.d.ts +3 -3
  42. package/dist/protocols/openai-responses.d.ts +18 -18
  43. package/dist/protocols/utils/open-responses-options.d.ts +8 -8
  44. package/dist/protocols/utils/open-responses-options.js +4 -6
  45. package/dist/protocols/utils/partial-json.js +5 -4
  46. package/dist/protocols/utils/tool-schema.d.ts +0 -3
  47. package/dist/protocols/utils/tool-schema.js +0 -4
  48. package/dist/protocols/venice-chat.js +6 -6
  49. package/dist/protocols/xai-images.js +3 -4
  50. package/dist/protocols/xai-responses.d.ts +3 -3
  51. package/dist/provider-error.js +4 -5
  52. package/dist/providers/alibaba.d.ts +30 -30
  53. package/dist/providers/amazon-bedrock-mantle.d.ts +3 -3
  54. package/dist/providers/amazon-bedrock.d.ts +11 -8
  55. package/dist/providers/azure.d.ts +6 -6
  56. package/dist/providers/cloudflare-ai-gateway.d.ts +7 -7
  57. package/dist/providers/cloudflare-ai-gateway.js +2 -4
  58. package/dist/providers/cohere.d.ts +6 -2
  59. package/dist/providers/google-vertex-interactions.d.ts +3 -3
  60. package/dist/providers/google-vertex-messages.d.ts +18 -18
  61. package/dist/providers/google-vertex-mistral.d.ts +3 -3
  62. package/dist/providers/google-vertex-responses.d.ts +3 -3
  63. package/dist/providers/google.d.ts +66 -66
  64. package/dist/providers/meta.d.ts +21 -21
  65. package/dist/providers/minimax.d.ts +195 -195
  66. package/dist/providers/moonshot.d.ts +3 -3
  67. package/dist/providers/openai-compatible-responses.d.ts +3 -3
  68. package/dist/providers/openai-options.d.ts +3 -3
  69. package/dist/providers/openai.d.ts +3 -3
  70. package/dist/providers/openrouter.d.ts +135 -76
  71. package/dist/providers/openrouter.js +40 -33
  72. package/dist/providers/vercel-ai-gateway.js +7 -6
  73. package/dist/providers/zai-coding-plan.d.ts +3 -3
  74. package/dist/route/client.d.ts +0 -216
  75. package/dist/route/client.js +1 -5
  76. package/dist/route/executor-service.d.ts +6 -2
  77. package/dist/route/executor-service.js +7 -0
  78. package/dist/route/executor.d.ts +2 -3
  79. package/dist/route/executor.js +6 -11
  80. package/dist/route/media-protocol.d.ts +1 -1
  81. package/dist/route/media-protocol.js +3 -3
  82. package/dist/route/transport/http.js +5 -8
  83. package/dist/route/transport/websocket.d.ts +0 -24
  84. package/dist/route/transport/websocket.js +0 -50
  85. package/dist/schema/errors.d.ts +9 -8
  86. package/dist/schema/errors.js +9 -5
  87. package/dist/schema/messages.js +4 -7
  88. package/dist/speech-client.d.ts +3 -1
  89. package/dist/speech.d.ts +10 -2
  90. package/dist/speech.js +2 -2
  91. package/dist/transcription-client.d.ts +3 -1
  92. package/dist/transcription.d.ts +10 -2
  93. package/dist/transcription.js +2 -2
  94. package/dist/video-client.d.ts +3 -1
  95. package/dist/video.d.ts +10 -2
  96. package/dist/video.js +2 -2
  97. package/package.json +4 -4
  98. package/dist/protocols/utils/openai-options.d.ts +0 -16
  99. package/dist/protocols/utils/openai-options.js +0 -15
@@ -5,7 +5,7 @@ import { OpenResponsesOptions } from "./utils/open-responses-options.js";
5
5
  declare const Options: Schema.Struct<{
6
6
  readonly effort: Schema.optional<Schema.declare<OpenResponsesOptions.ReasoningEffort, OpenResponsesOptions.ReasoningEffort>>;
7
7
  readonly thinking: Schema.optional<Schema.Struct<{
8
- readonly type: Schema.declare<"disabled" | "enabled" | (string & {}), "disabled" | "enabled" | (string & {})>;
8
+ readonly type: Schema.declare<import("../schema/options.js").OpenString<"disabled" | "enabled">, import("../schema/options.js").OpenString<"disabled" | "enabled">>;
9
9
  readonly budgetTokens: Schema.optional<Schema.Int>;
10
10
  readonly budget_tokens: Schema.optional<Schema.Int>;
11
11
  }>>;
@@ -7,7 +7,7 @@ import { OpenResponsesOptions } from "./utils/open-responses-options.js";
7
7
  const Options = Schema.Struct({
8
8
  effort: Schema.optional(OpenResponsesOptions.ReasoningEffort),
9
9
  thinking: Schema.optional(Schema.Struct({
10
- type: Schema.declare(Schema.is(Schema.String)),
10
+ type: ProviderShared.knownString(),
11
11
  budgetTokens: Schema.optional(Schema.Int),
12
12
  budget_tokens: Schema.optional(Schema.Int),
13
13
  })),
@@ -169,15 +169,15 @@ export declare const protocol: Protocol<{
169
169
  } | undefined;
170
170
  readonly top_logprobs?: number | undefined;
171
171
  readonly truncation?: "auto" | "disabled" | undefined;
172
- readonly service_tier?: OpenResponsesOptions.ServiceTier | undefined;
172
+ readonly service_tier?: import("../index.js").OpenString<"auto" | "default" | "flex" | "priority"> | undefined;
173
173
  readonly prompt_cache_key?: string | undefined;
174
- readonly include?: readonly OpenResponsesOptions.ResponseIncludable[] | undefined;
174
+ readonly include?: readonly import("../index.js").OpenString<"code_interpreter_call.outputs" | "computer_call_output.output.image_url" | "file_search_call.results" | "message.input_image.image_url" | "message.output_text.logprobs" | "reasoning.encrypted_content" | "web_search_call.action.sources" | "web_search_call.results">[] | undefined;
175
175
  readonly reasoning?: {
176
176
  readonly effort?: OpenResponsesOptions.ReasoningEffort | undefined;
177
177
  readonly summary?: "auto" | "concise" | "detailed" | undefined;
178
178
  } | undefined;
179
179
  readonly text?: {
180
- readonly verbosity?: OpenResponsesOptions.TextVerbosity | undefined;
180
+ readonly verbosity?: import("../index.js").OpenString<"high" | "low" | "medium"> | undefined;
181
181
  } | undefined;
182
182
  readonly max_output_tokens?: number | undefined;
183
183
  readonly max_tool_calls?: number | undefined;
@@ -400,13 +400,13 @@ const cacheControl = (breakpoints, cache) => {
400
400
  const providerMetadata = (key, metadata) => ({ [key]: metadata });
401
401
  const signatureFromMetadata = (metadata, key) => {
402
402
  const provider = metadata?.[key];
403
- if (!ProviderShared.isRecord(provider))
403
+ if (!provider)
404
404
  return undefined;
405
405
  return typeof provider.signature === "string" ? provider.signature : undefined;
406
406
  };
407
407
  const redactedDataFromMetadata = (metadata, key) => {
408
408
  const provider = metadata?.[key];
409
- if (!ProviderShared.isRecord(provider))
409
+ if (!provider)
410
410
  return undefined;
411
411
  return typeof provider.redactedData === "string" ? provider.redactedData : undefined;
412
412
  };
@@ -477,7 +477,7 @@ const lowerServerToolResult = Effect.fnUntraced(function* (part, providerMetadat
477
477
  };
478
478
  });
479
479
  const fileIdFromMetadata = (metadata) => {
480
- if (!ProviderShared.isRecord(metadata))
480
+ if (!metadata)
481
481
  return undefined;
482
482
  const anthropic = metadata.anthropic;
483
483
  if (ProviderShared.isRecord(anthropic)) {
@@ -493,7 +493,7 @@ const fileIdFromMetadata = (metadata) => {
493
493
  return undefined;
494
494
  };
495
495
  const transformationsFromMetadata = (metadata) => {
496
- if (!ProviderShared.isRecord(metadata))
496
+ if (!metadata)
497
497
  return undefined;
498
498
  const anthropic = ProviderShared.isRecord(metadata.anthropic) ? metadata.anthropic : undefined;
499
499
  const raw = anthropic?.transformations ?? metadata.transformations;
@@ -507,19 +507,19 @@ const transformationsFromMetadata = (metadata) => {
507
507
  return undefined;
508
508
  };
509
509
  const documentTitleFromPart = (part) => {
510
- if (ProviderShared.isRecord(part.metadata)) {
510
+ if (part.metadata !== undefined) {
511
511
  const anthropic = part.metadata.anthropic;
512
512
  if (ProviderShared.isRecord(anthropic) && typeof anthropic.title === "string")
513
513
  return anthropic.title;
514
514
  if (typeof part.metadata.title === "string")
515
515
  return part.metadata.title;
516
516
  }
517
- if (typeof part.filename === "string" && part.filename.length > 0)
517
+ if (part.filename && part.filename.length > 0)
518
518
  return part.filename;
519
519
  return undefined;
520
520
  };
521
521
  const documentContextFromMetadata = (metadata) => {
522
- if (!ProviderShared.isRecord(metadata))
522
+ if (!metadata)
523
523
  return undefined;
524
524
  const anthropic = ProviderShared.isRecord(metadata.anthropic) ? metadata.anthropic : undefined;
525
525
  if (anthropic && typeof anthropic.context === "string")
@@ -529,7 +529,7 @@ const documentContextFromMetadata = (metadata) => {
529
529
  return undefined;
530
530
  };
531
531
  const citationsFromMetadata = (metadata) => {
532
- if (!ProviderShared.isRecord(metadata))
532
+ if (!metadata)
533
533
  return undefined;
534
534
  const raw = ProviderShared.isRecord(metadata.anthropic)
535
535
  ? (metadata.anthropic.citations ?? metadata.citations)
@@ -796,7 +796,7 @@ const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
796
796
  content.push({ type: "redacted_thinking", data: redactedData });
797
797
  continue;
798
798
  }
799
- if (typeof signature !== "string" || signature.trim().length === 0) {
799
+ if (!signature || signature.trim().length === 0) {
800
800
  if (part.text.trim().length === 0)
801
801
  continue;
802
802
  if (!requireThinkingSignature(request)) {
@@ -1044,9 +1044,7 @@ const isServerToolResultType = (type) => type in SERVER_TOOL_RESULT_NAMES;
1044
1044
  const serverToolResultEvent = (block, providerMetadataKey) => {
1045
1045
  if (!block.type || !isServerToolResultType(block.type))
1046
1046
  return undefined;
1047
- const errorPayload = typeof block.content === "object" && block.content !== null && "type" in block.content
1048
- ? String(block.content.type)
1049
- : "";
1047
+ const errorPayload = ProviderShared.isRecord(block.content) && "type" in block.content ? String(block.content.type) : "";
1050
1048
  const isError = errorPayload.endsWith("_tool_result_error");
1051
1049
  return LLMEvent.toolResult({
1052
1050
  id: block.tool_use_id ?? "",
@@ -260,58 +260,8 @@ export declare const protocol: Protocol<{
260
260
  readonly [x: string]: unknown;
261
261
  } | undefined;
262
262
  }, {
263
- readonly messageStart?: {
264
- readonly role: string;
265
- } | undefined;
266
- readonly contentBlockStart?: {
267
- readonly contentBlockIndex: number;
268
- readonly start?: {
269
- readonly toolUse?: {
270
- readonly toolUseId: string;
271
- readonly name: string;
272
- } | undefined;
273
- } | undefined;
274
- } | undefined;
275
- readonly contentBlockDelta?: {
276
- readonly contentBlockIndex: number;
277
- readonly delta?: {
278
- readonly text?: string | undefined;
279
- readonly toolUse?: {
280
- readonly input: string;
281
- } | undefined;
282
- readonly reasoningContent?: {
283
- readonly text?: string | undefined;
284
- readonly signature?: string | undefined;
285
- readonly redactedContent?: string | undefined;
286
- readonly data?: string | undefined;
287
- } | undefined;
288
- } | undefined;
289
- } | undefined;
290
- readonly contentBlockStop?: {
291
- readonly contentBlockIndex: number;
292
- } | undefined;
293
- readonly messageStop?: {
294
- readonly stopReason: string;
295
- readonly additionalModelResponseFields?: unknown;
296
- } | undefined;
297
- readonly metadata?: {
298
- readonly usage?: {
299
- readonly inputTokens?: number | undefined;
300
- readonly outputTokens?: number | undefined;
301
- readonly totalTokens?: number | undefined;
302
- readonly cacheReadInputTokens?: number | undefined;
303
- readonly cacheWriteInputTokens?: number | undefined;
304
- } | undefined;
305
- readonly metrics?: unknown;
306
- } | undefined;
307
- readonly exception?: {
308
- readonly type: string;
309
- readonly details: {
310
- readonly message?: string | undefined;
311
- readonly originalMessage?: string | undefined;
312
- readonly originalStatusCode?: number | undefined;
313
- };
314
- } | undefined;
263
+ readonly [x: string]: unknown;
264
+ readonly rawBody: string;
315
265
  }, {
316
266
  readonly messageStart?: {
317
267
  readonly role: string;
@@ -497,6 +447,9 @@ export declare const route: Route<{
497
447
  readonly additionalModelRequestFields?: {
498
448
  readonly [x: string]: unknown;
499
449
  } | undefined;
500
- }, import("../route/transport/http.js").HttpPrepared<object>, import("../route/client.js").CompactionOperations | undefined>;
450
+ }, import("../route/transport/http.js").HttpPrepared<{
451
+ readonly [x: string]: unknown;
452
+ readonly rawBody: string;
453
+ }>, import("../route/client.js").CompactionOperations | undefined>;
501
454
  export declare const sigV4Auth: typeof BedrockAuth.sigV4;
502
455
  export * as BedrockConverse from "./bedrock-converse.js";
@@ -189,12 +189,12 @@ const reasoningSignature = (part, providerMetadataKey) => {
189
189
  const metadata = part.providerMetadata?.[providerMetadataKey];
190
190
  if (part.encrypted !== undefined)
191
191
  return part.encrypted;
192
- if (ProviderShared.isRecord(metadata) && typeof metadata.signature === "string")
192
+ if (typeof metadata?.signature === "string")
193
193
  return metadata.signature;
194
194
  };
195
195
  const reasoningRedactedData = (part, providerMetadataKey) => {
196
196
  const metadata = part.providerMetadata?.[providerMetadataKey];
197
- if (ProviderShared.isRecord(metadata) && typeof metadata.redactedData === "string")
197
+ if (typeof metadata?.redactedData === "string")
198
198
  return metadata.redactedData;
199
199
  };
200
200
  const removeEmptyToolInputKeys = (input) => {
@@ -647,6 +647,7 @@ const step = (state, event) => Effect.gen(function* () {
647
647
  return yield* new AIError({
648
648
  reason: classifyProviderFailure({
649
649
  message,
650
+ status: event.exception.details.originalStatusCode,
650
651
  rawBody: body,
651
652
  }),
652
653
  });
@@ -690,7 +691,7 @@ export const protocol = Protocol.make({
690
691
  from: fromRequest,
691
692
  },
692
693
  stream: {
693
- event: BedrockEvent,
694
+ event: BedrockEventStream.Frame.pipe(Schema.decodeTo(BedrockEvent)),
694
695
  initial: (request) => ({
695
696
  providerMetadataKey: request.model.route.providerMetadataKey ?? String(request.model.provider),
696
697
  tools: ToolStream.empty(),
@@ -1,9 +1,14 @@
1
+ import { Schema } from "effect";
1
2
  import { Framing } from "../route/framing.js";
3
+ export declare const Frame: Schema.StructWithRest<Schema.Struct<{
4
+ readonly rawBody: Schema.String;
5
+ }>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>;
6
+ export type Frame = typeof Frame.Type;
2
7
  /**
3
8
  * AWS event-stream framing for Bedrock Converse. Each frame is decoded by
4
9
  * `@smithy/eventstream-codec` (length + header + payload + CRC) and rewrapped
5
10
  * under its `:event-type` header so the chunk schema can match the JSON
6
11
  * payload directly.
7
12
  */
8
- export declare const framing: (route: string) => Framing.Definition<object>;
13
+ export declare const framing: (route: string) => Framing.Definition<Frame>;
9
14
  export * as BedrockEventStream from "./bedrock-event-stream.js";
@@ -1,6 +1,6 @@
1
1
  import { EventStreamCodec } from "@smithy/eventstream-codec";
2
2
  import { fromUtf8, toUtf8 } from "@smithy/util-utf8";
3
- import { Effect, Stream } from "effect";
3
+ import { Effect, Schema, Stream } from "effect";
4
4
  import { Base64 } from "effect/encoding";
5
5
  import { AIError, AIErrorReason, InvalidProviderOutputError } from "../schema/index.js";
6
6
  import { Framing } from "../route/framing.js";
@@ -12,6 +12,7 @@ import { ProviderShared } from "./shared.js";
12
12
  const eventCodec = new EventStreamCodec(toUtf8, fromUtf8);
13
13
  const utf8 = new TextDecoder();
14
14
  const initialFrameBuffer = { buffer: new Uint8Array(0), offset: 0 };
15
+ export const Frame = Schema.StructWithRest(Schema.Struct({ rawBody: Schema.String }), [ProviderShared.JsonObject]);
15
16
  const endOfStream = { _tag: "End" };
16
17
  const appendChunk = (state, chunk) => {
17
18
  const remaining = state.buffer.length - state.offset;
@@ -71,14 +72,14 @@ const consumeFrames = (route) => (state, input) => Effect.gen(function* () {
71
72
  // before handing the object to the chunk schema. JSON decode goes
72
73
  // through the shared Schema-driven codec to satisfy the package rule
73
74
  // against ad-hoc `JSON.parse` calls.
74
- const parsed = (yield* ProviderShared.parseJson(route, payload, "Failed to parse Bedrock Converse event-stream payload").pipe(Effect.mapError((error) => new AIError({
75
+ const parsed = yield* ProviderShared.parseJson(route, payload, "Failed to parse Bedrock Converse event-stream payload").pipe(Effect.mapError((error) => new AIError({
75
76
  reason: AIErrorReason.make({ ...error.reason, message: error.message, cause: error.reason.cause, body }),
76
- }))));
77
- delete parsed.p;
77
+ })));
78
+ if (!ProviderShared.isRecord(parsed))
79
+ return yield* ProviderShared.eventError(route, "Failed to parse Bedrock Converse event-stream payload", body);
80
+ const { p: _, ...event } = parsed;
78
81
  out.push({
79
- ...(messageType === "exception"
80
- ? { exception: { type: eventType, details: parsed } }
81
- : { [eventType]: parsed }),
82
+ ...(messageType === "exception" ? { exception: { type: eventType, details: event } } : { [eventType]: event }),
82
83
  rawBody: body,
83
84
  });
84
85
  }
@@ -92,7 +93,7 @@ const consumeFrames = (route) => (state, input) => Effect.gen(function* () {
92
93
  */
93
94
  export const framing = (route) => ({
94
95
  id: "aws-event-stream",
95
- body: (frame) => ("rawBody" in frame && typeof frame.rawBody === "string" ? frame.rawBody : undefined),
96
+ body: (frame) => frame.rawBody,
96
97
  frame: (bytes) => bytes.pipe(Stream.map((bytes) => ({ _tag: "Chunk", bytes })), Stream.concat(Stream.succeed(endOfStream)), Stream.mapAccumEffect(() => initialFrameBuffer, consumeFrames(route))),
97
98
  });
98
99
  export * as BedrockEventStream from "./bedrock-event-stream.js";
@@ -49,7 +49,9 @@ export declare const protocol: Protocol<{
49
49
  readonly function: {
50
50
  readonly name: string;
51
51
  readonly description?: string | undefined;
52
- readonly parameters: unknown;
52
+ readonly parameters: {
53
+ readonly [x: string]: unknown;
54
+ };
53
55
  };
54
56
  }[] | undefined;
55
57
  readonly tool_choice?: "NONE" | "REQUIRED" | undefined;
@@ -161,7 +163,9 @@ export declare const route: Route<{
161
163
  readonly function: {
162
164
  readonly name: string;
163
165
  readonly description?: string | undefined;
164
- readonly parameters: unknown;
166
+ readonly parameters: {
167
+ readonly [x: string]: unknown;
168
+ };
165
169
  };
166
170
  }[] | undefined;
167
171
  readonly tool_choice?: "NONE" | "REQUIRED" | undefined;
@@ -4,7 +4,7 @@ import { Endpoint } from "../route/endpoint.js";
4
4
  import { Framing } from "../route/framing.js";
5
5
  import { Protocol } from "../route/protocol.js";
6
6
  import { LLMEvent, Usage } from "../schema/index.js";
7
- import { ProviderShared } from "./shared.js";
7
+ import { JsonObject, ProviderShared } from "./shared.js";
8
8
  import { Lifecycle } from "./utils/lifecycle.js";
9
9
  import { ToolStream } from "./utils/tool-stream.js";
10
10
  const ADAPTER = "cohere-chat";
@@ -41,7 +41,7 @@ const Body = Schema.Struct({
41
41
  function: Schema.Struct({
42
42
  name: Schema.String,
43
43
  description: Schema.optional(Schema.String),
44
- parameters: Schema.Unknown,
44
+ parameters: JsonObject,
45
45
  }),
46
46
  }))),
47
47
  tool_choice: Schema.optional(Schema.Literals(["NONE", "REQUIRED"])),
@@ -239,7 +239,12 @@ export declare const protocol: Protocol<{
239
239
  } | undefined;
240
240
  readonly continuationToken?: string | undefined;
241
241
  }, NextRequest | {
242
- readonly error?: unknown;
242
+ readonly error?: {
243
+ readonly [x: string]: unknown;
244
+ readonly code?: number | undefined;
245
+ readonly message?: string | undefined;
246
+ readonly status?: string | undefined;
247
+ } | undefined;
243
248
  readonly candidates?: readonly {
244
249
  readonly content?: {
245
250
  readonly role?: "model" | "user" | null | undefined;
@@ -261,7 +266,12 @@ export declare const protocol: Protocol<{
261
266
  readonly totalTokenCount?: number | null | undefined;
262
267
  } | null | undefined;
263
268
  }, NextRequest | {
264
- readonly error?: unknown;
269
+ readonly error?: {
270
+ readonly [x: string]: unknown;
271
+ readonly code?: number | undefined;
272
+ readonly message?: string | undefined;
273
+ readonly status?: string | undefined;
274
+ } | undefined;
265
275
  readonly candidates?: readonly {
266
276
  readonly content?: {
267
277
  readonly role?: "model" | "user" | null | undefined;
@@ -182,8 +182,13 @@ const GeminiPromptFeedback = Schema.StructWithRest(Schema.Struct({
182
182
  blockReasonMessage: optionalNull(Schema.String),
183
183
  safetyRatings: optionalNull(Schema.Unknown),
184
184
  }), [Schema.Record(Schema.String, Schema.Unknown)]);
185
+ const GeminiError = Schema.StructWithRest(Schema.Struct({
186
+ code: lenient(Schema.Number),
187
+ message: lenient(Schema.String),
188
+ status: lenient(Schema.String),
189
+ }), [Schema.Record(Schema.String, Schema.Unknown)]);
185
190
  const GeminiEvent = Schema.Struct({
186
- error: Schema.optional(Schema.Unknown),
191
+ error: Schema.optional(GeminiError),
187
192
  candidates: optionalNull(Schema.Array(GeminiCandidate)),
188
193
  promptFeedback: optionalNull(GeminiPromptFeedback),
189
194
  usageMetadata: optionalNull(GeminiUsage),
@@ -211,9 +216,7 @@ const lowerContentPart = Effect.fnUntraced(function* (part) {
211
216
  const providerMetadata = (key, metadata) => ({ [key]: metadata });
212
217
  const thoughtSignature = (metadata, key) => {
213
218
  const value = metadata?.[key];
214
- return ProviderShared.isRecord(value) && typeof value.thoughtSignature === "string"
215
- ? value.thoughtSignature
216
- : undefined;
219
+ return typeof value?.thoughtSignature === "string" ? value.thoughtSignature : undefined;
217
220
  };
218
221
  const lowerToolCall = (part, omitIds, metadataKey) => ({
219
222
  functionCall: { ...(omitIds ? {} : { id: part.id }), name: part.name, args: part.input },
@@ -511,22 +514,16 @@ const step = (state, event) => {
511
514
  },
512
515
  [],
513
516
  ]);
514
- if (ProviderShared.isRecord(event.error)) {
517
+ if (event.error) {
515
518
  const body = ProviderShared.encodeJson(event);
516
519
  return Effect.fail(new AIError({
517
520
  reason: classifyProviderFailure({
518
- message: typeof event.error.message === "string" && event.error.message.length > 0
519
- ? event.error.message
520
- : typeof event.error.status === "string" && event.error.status.length > 0
521
- ? event.error.status
522
- : "Gemini provider error",
523
- status: typeof event.error.code === "number" ? event.error.code : undefined,
521
+ message: event.error.message || event.error.status || "Gemini provider error",
522
+ status: event.error.code,
524
523
  rawBody: body,
525
524
  }),
526
525
  }));
527
526
  }
528
- if ("error" in event)
529
- return Effect.fail(ProviderShared.eventError(state.route, `Invalid ${state.route} stream event`, ProviderShared.encodeJson(event)));
530
527
  const candidate = event.candidates?.[0];
531
528
  const nextState = {
532
529
  ...state,
@@ -137,7 +137,8 @@ export declare const protocol: Protocol<{
137
137
  readonly text: string;
138
138
  };
139
139
  } | {
140
- readonly type: string;
140
+ readonly type: "unknown";
141
+ readonly rawType: string;
141
142
  };
142
143
  } | {
143
144
  readonly event_type: "step.stop";
@@ -108,13 +108,20 @@ const OutputStep = Schema.Struct({
108
108
  summary: Schema.optional(Schema.Array(Text)),
109
109
  content: Schema.optional(Schema.Array(Schema.Struct({ type: Schema.String, text: Schema.optional(Schema.String) }))),
110
110
  });
111
+ const KNOWN_DELTA_TYPES = new Set(["text", "arguments_delta", "thought_signature", "thought_summary"]);
112
+ const UnknownDelta = Schema.Struct({
113
+ type: Schema.String.check(Schema.makeFilter((type) => !KNOWN_DELTA_TYPES.has(type))),
114
+ }).pipe(Schema.decodeTo(Schema.Struct({ type: Schema.Literal("unknown"), rawType: Schema.String }), {
115
+ decode: SchemaGetter.transform((delta) => ({ type: "unknown", rawType: delta.type })),
116
+ encode: SchemaGetter.forbidden(() => "Unknown Google Interactions deltas are decode-only"),
117
+ }));
111
118
  const Delta = Schema.Union([
112
119
  Schema.Struct({ type: Schema.Literal("text"), text: Schema.String }),
113
120
  Schema.Struct({ type: Schema.Literal("arguments_delta"), arguments: Schema.String }),
114
121
  Schema.Struct({ type: Schema.Literal("thought_signature"), signature: Schema.String }),
115
122
  Schema.Struct({ type: Schema.Literal("thought_summary"), content: Text }),
116
123
  // Unknown output modalities must fail explicitly rather than disappearing from a successful response.
117
- Schema.Struct({ type: Schema.String }),
124
+ UnknownDelta,
118
125
  ]);
119
126
  const Interaction = Schema.StructWithRest(Schema.Struct({
120
127
  id: Schema.optional(Schema.String),
@@ -173,9 +180,7 @@ const mediaContent = Effect.fnUntraced(function* (asset) {
173
180
  });
174
181
  const signature = (metadata, key) => {
175
182
  const value = metadata?.[key];
176
- return ProviderShared.isRecord(value) && typeof value.interactionSignature === "string"
177
- ? value.interactionSignature
178
- : undefined;
183
+ return typeof value?.interactionSignature === "string" ? value.interactionSignature : undefined;
179
184
  };
180
185
  const lowerMessages = Effect.fnUntraced(function* (request) {
181
186
  const steps = [];
@@ -362,17 +367,17 @@ const onDelta = Effect.fnUntraced(function* (state, index, delta) {
362
367
  if (!step)
363
368
  return yield* ProviderShared.eventError(ADAPTER, "Interactions delta without step.start", encodeJson(delta));
364
369
  const events = [];
365
- if (delta.type === "text" && "text" in delta && step.type === "model_output")
370
+ if (delta.type === "text" && step.type === "model_output")
366
371
  return [
367
372
  { ...state, lifecycle: Lifecycle.textDelta(state.lifecycle, events, String(index), delta.text) },
368
373
  events,
369
374
  ];
370
- if (delta.type === "thought_summary" && "content" in delta && step.type === "thought")
375
+ if (delta.type === "thought_summary" && step.type === "thought")
371
376
  return [
372
377
  { ...state, lifecycle: Lifecycle.reasoningDelta(state.lifecycle, events, String(index), delta.content.text) },
373
378
  events,
374
379
  ];
375
- if (delta.type === "thought_signature" && "signature" in delta) {
380
+ if (delta.type === "thought_signature") {
376
381
  const next = { ...step, signature: delta.signature };
377
382
  const tool = state.tools[index];
378
383
  return [
@@ -384,13 +389,13 @@ const onDelta = Effect.fnUntraced(function* (state, index, delta) {
384
389
  events,
385
390
  ];
386
391
  }
387
- if (delta.type === "arguments_delta" && "arguments" in delta && step.type === "function_call") {
392
+ if (delta.type === "arguments_delta" && step.type === "function_call") {
388
393
  const result = ToolStream.appendExisting(ADAPTER, state.tools, index, delta.arguments, "Interactions arguments without function call");
389
394
  if (ToolStream.isError(result))
390
395
  return yield* result;
391
396
  return [{ ...state, tools: result.tools }, result.events];
392
397
  }
393
- return yield* ProviderShared.eventError(ADAPTER, `Unsupported Interactions delta: ${delta.type}`, encodeJson(delta));
398
+ return yield* ProviderShared.eventError(ADAPTER, `Unsupported Interactions delta: ${delta.type === "unknown" ? delta.rawType : delta.type}`, encodeJson(delta));
394
399
  });
395
400
  const onStop = Effect.fnUntraced(function* (state, index) {
396
401
  const step = state.steps[index];
@@ -183,15 +183,15 @@ export declare const protocol: Protocol<{
183
183
  } | undefined;
184
184
  readonly top_logprobs?: number | undefined;
185
185
  readonly truncation?: "auto" | "disabled" | undefined;
186
- readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
186
+ readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "default" | "flex" | "priority"> | undefined;
187
187
  readonly prompt_cache_key?: string | undefined;
188
- readonly include?: readonly import("./utils/open-responses-options.js").ResponseIncludable[] | undefined;
188
+ readonly include?: readonly import("../schema/options.js").OpenString<"code_interpreter_call.outputs" | "computer_call_output.output.image_url" | "file_search_call.results" | "message.input_image.image_url" | "message.output_text.logprobs" | "reasoning.encrypted_content" | "web_search_call.action.sources" | "web_search_call.results">[] | undefined;
189
189
  readonly reasoning?: {
190
190
  readonly effort?: import("../schema/options.js").ReasoningEffort | undefined;
191
191
  readonly summary?: "auto" | "concise" | "detailed" | undefined;
192
192
  } | undefined;
193
193
  readonly text?: {
194
- readonly verbosity?: import("./utils/open-responses-options.js").TextVerbosity | undefined;
194
+ readonly verbosity?: import("../schema/options.js").OpenString<"high" | "low" | "medium"> | undefined;
195
195
  } | undefined;
196
196
  readonly max_output_tokens?: number | undefined;
197
197
  readonly max_tool_calls?: number | undefined;
@@ -419,15 +419,15 @@ export declare const httpTransport: import("../route/transport/http.js").HttpJso
419
419
  } | undefined;
420
420
  readonly top_logprobs?: number | undefined;
421
421
  readonly truncation?: "auto" | "disabled" | undefined;
422
- readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
422
+ readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "default" | "flex" | "priority"> | undefined;
423
423
  readonly prompt_cache_key?: string | undefined;
424
- readonly include?: readonly import("./utils/open-responses-options.js").ResponseIncludable[] | undefined;
424
+ readonly include?: readonly import("../schema/options.js").OpenString<"code_interpreter_call.outputs" | "computer_call_output.output.image_url" | "file_search_call.results" | "message.input_image.image_url" | "message.output_text.logprobs" | "reasoning.encrypted_content" | "web_search_call.action.sources" | "web_search_call.results">[] | undefined;
425
425
  readonly reasoning?: {
426
426
  readonly effort?: import("../schema/options.js").ReasoningEffort | undefined;
427
427
  readonly summary?: "auto" | "concise" | "detailed" | undefined;
428
428
  } | undefined;
429
429
  readonly text?: {
430
- readonly verbosity?: import("./utils/open-responses-options.js").TextVerbosity | undefined;
430
+ readonly verbosity?: import("../schema/options.js").OpenString<"high" | "low" | "medium"> | undefined;
431
431
  } | undefined;
432
432
  readonly max_output_tokens?: number | undefined;
433
433
  readonly max_tool_calls?: number | undefined;
@@ -290,9 +290,6 @@ const lowerTool = (tool) => ({
290
290
  });
291
291
  export const fromRequest = Effect.fn("MistralChat.fromRequest")(function* (request) {
292
292
  const options = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(MistralOptions))(request.providerOptions ?? {});
293
- const selected = request.toolChoice?.type === "tool" ? request.toolChoice.name : undefined;
294
- if (request.toolChoice?.type === "tool" && !selected)
295
- return yield* ProviderShared.invalidRequest("Mistral Chat tool choice requires a tool name");
296
293
  if (options.reasoningEffort !== undefined && options.promptMode !== undefined)
297
294
  return yield* ProviderShared.invalidRequest("Mistral Chat reasoningEffort and promptMode provider options are mutually exclusive");
298
295
  const toolChoice = request.toolChoice
@@ -372,7 +369,7 @@ const thinkingUnits = (value) => {
372
369
  return [];
373
370
  return value.filter(Schema.is(MistralThinkingUnit));
374
371
  };
375
- const thinkingText = (thinking) => thinking.flatMap((unit) => (typeof unit.text === "string" ? [unit.text] : [])).join("");
372
+ const thinkingText = (thinking) => thinking.flatMap((unit) => (unit.text !== undefined ? [unit.text] : [])).join("");
376
373
  const thinkingMetadata = (thinking) => ({ mistral: { thinking } });
377
374
  const closeActive = (state, events) => {
378
375
  if (!state.active)