@opencode-ai/ai 0.0.0-next-16033 → 0.0.0-next-16040

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.
@@ -35,6 +35,17 @@ export declare const AnthropicMessagesBody: Schema.Struct<{
35
35
  readonly type: Schema.tag<"ephemeral">;
36
36
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
37
37
  }>>;
38
+ }>, Schema.Struct<{
39
+ readonly type: Schema.tag<"document">;
40
+ readonly source: Schema.Struct<{
41
+ readonly type: Schema.tag<"base64">;
42
+ readonly media_type: Schema.Literal<"application/pdf">;
43
+ readonly data: Schema.String;
44
+ }>;
45
+ readonly cache_control: Schema.optional<Schema.Struct<{
46
+ readonly type: Schema.tag<"ephemeral">;
47
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
48
+ }>>;
38
49
  }>, Schema.Struct<{
39
50
  readonly type: Schema.tag<"tool_result">;
40
51
  readonly tool_use_id: Schema.String;
@@ -56,6 +67,17 @@ export declare const AnthropicMessagesBody: Schema.Struct<{
56
67
  readonly type: Schema.tag<"ephemeral">;
57
68
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
58
69
  }>>;
70
+ }>, Schema.Struct<{
71
+ readonly type: Schema.tag<"document">;
72
+ readonly source: Schema.Struct<{
73
+ readonly type: Schema.tag<"base64">;
74
+ readonly media_type: Schema.Literal<"application/pdf">;
75
+ readonly data: Schema.String;
76
+ }>;
77
+ readonly cache_control: Schema.optional<Schema.Struct<{
78
+ readonly type: Schema.tag<"ephemeral">;
79
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
80
+ }>>;
59
81
  }>]>>]>;
60
82
  readonly is_error: Schema.optional<Schema.Boolean>;
61
83
  readonly cache_control: Schema.optional<Schema.Struct<{
@@ -179,6 +201,17 @@ export declare const protocol: Protocol<{
179
201
  readonly type: Schema.tag<"ephemeral">;
180
202
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
181
203
  }>>;
204
+ }>, Schema.Struct<{
205
+ readonly type: Schema.tag<"document">;
206
+ readonly source: Schema.Struct<{
207
+ readonly type: Schema.tag<"base64">;
208
+ readonly media_type: Schema.Literal<"application/pdf">;
209
+ readonly data: Schema.String;
210
+ }>;
211
+ readonly cache_control: Schema.optional<Schema.Struct<{
212
+ readonly type: Schema.tag<"ephemeral">;
213
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
214
+ }>>;
182
215
  }>, Schema.Struct<{
183
216
  readonly type: Schema.tag<"tool_result">;
184
217
  readonly tool_use_id: Schema.String;
@@ -200,6 +233,17 @@ export declare const protocol: Protocol<{
200
233
  readonly type: Schema.tag<"ephemeral">;
201
234
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
202
235
  }>>;
236
+ }>, Schema.Struct<{
237
+ readonly type: Schema.tag<"document">;
238
+ readonly source: Schema.Struct<{
239
+ readonly type: Schema.tag<"base64">;
240
+ readonly media_type: Schema.Literal<"application/pdf">;
241
+ readonly data: Schema.String;
242
+ }>;
243
+ readonly cache_control: Schema.optional<Schema.Struct<{
244
+ readonly type: Schema.tag<"ephemeral">;
245
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
246
+ }>>;
203
247
  }>]>>]>;
204
248
  readonly is_error: Schema.optional<Schema.Boolean>;
205
249
  readonly cache_control: Schema.optional<Schema.Struct<{
@@ -372,6 +416,17 @@ export declare const route: Route<{
372
416
  readonly type: Schema.tag<"ephemeral">;
373
417
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
374
418
  }>>;
419
+ }>, Schema.Struct<{
420
+ readonly type: Schema.tag<"document">;
421
+ readonly source: Schema.Struct<{
422
+ readonly type: Schema.tag<"base64">;
423
+ readonly media_type: Schema.Literal<"application/pdf">;
424
+ readonly data: Schema.String;
425
+ }>;
426
+ readonly cache_control: Schema.optional<Schema.Struct<{
427
+ readonly type: Schema.tag<"ephemeral">;
428
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
429
+ }>>;
375
430
  }>, Schema.Struct<{
376
431
  readonly type: Schema.tag<"tool_result">;
377
432
  readonly tool_use_id: Schema.String;
@@ -393,6 +448,17 @@ export declare const route: Route<{
393
448
  readonly type: Schema.tag<"ephemeral">;
394
449
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
395
450
  }>>;
451
+ }>, Schema.Struct<{
452
+ readonly type: Schema.tag<"document">;
453
+ readonly source: Schema.Struct<{
454
+ readonly type: Schema.tag<"base64">;
455
+ readonly media_type: Schema.Literal<"application/pdf">;
456
+ readonly data: Schema.String;
457
+ }>;
458
+ readonly cache_control: Schema.optional<Schema.Struct<{
459
+ readonly type: Schema.tag<"ephemeral">;
460
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
461
+ }>>;
396
462
  }>]>>]>;
397
463
  readonly is_error: Schema.optional<Schema.Boolean>;
398
464
  readonly cache_control: Schema.optional<Schema.Struct<{
@@ -12,6 +12,7 @@ import { Lifecycle } from "./utils/lifecycle";
12
12
  import { ToolSchemaProjection } from "./utils/tool-schema";
13
13
  import { ToolStream } from "./utils/tool-stream";
14
14
  const ADAPTER = "anthropic-messages";
15
+ const MEDIA_MIMES = new Set([...ProviderShared.IMAGE_MIMES, ...ProviderShared.PDF_MIMES]);
15
16
  export const DEFAULT_BASE_URL = "https://api.anthropic.com/v1";
16
17
  export const PATH = "/messages";
17
18
  // =============================================================================
@@ -35,6 +36,15 @@ const AnthropicImageBlock = Schema.Struct({
35
36
  }),
36
37
  cache_control: Schema.optional(AnthropicCacheControl),
37
38
  });
39
+ const AnthropicDocumentBlock = Schema.Struct({
40
+ type: Schema.tag("document"),
41
+ source: Schema.Struct({
42
+ type: Schema.tag("base64"),
43
+ media_type: Schema.Literal("application/pdf"),
44
+ data: Schema.String,
45
+ }),
46
+ cache_control: Schema.optional(AnthropicCacheControl),
47
+ });
38
48
  const AnthropicThinkingBlock = Schema.Struct({
39
49
  type: Schema.tag("thinking"),
40
50
  thinking: Schema.String,
@@ -71,13 +81,10 @@ const AnthropicServerToolResultBlock = Schema.Struct({
71
81
  content: Schema.Unknown,
72
82
  cache_control: Schema.optional(AnthropicCacheControl),
73
83
  });
74
- // Anthropic accepts either a plain string or an ordered array of text/image
75
- // blocks inside `tool_result.content`. The array form is required when a tool
76
- // returns image bytes (screenshot, image search, etc.) so they can be passed
77
- // to the model as proper image inputs instead of being JSON-stringified into
78
- // the prompt — which silently inflates context by megabytes and can push the
79
- // conversation over the model's token limit.
80
- const AnthropicToolResultContent = Schema.Union([AnthropicTextBlock, AnthropicImageBlock]);
84
+ // Anthropic accepts either a plain string or an ordered array of text, image, and
85
+ // document blocks inside `tool_result.content`. The array form keeps media as native
86
+ // model input instead of JSON-stringifying base64 into prompt text.
87
+ const AnthropicToolResultContent = Schema.Union([AnthropicTextBlock, AnthropicImageBlock, AnthropicDocumentBlock]);
81
88
  const AnthropicToolResultBlock = Schema.Struct({
82
89
  type: Schema.tag("tool_result"),
83
90
  tool_use_id: Schema.String,
@@ -85,7 +92,12 @@ const AnthropicToolResultBlock = Schema.Struct({
85
92
  is_error: Schema.optional(Schema.Boolean),
86
93
  cache_control: Schema.optional(AnthropicCacheControl),
87
94
  });
88
- const AnthropicUserBlock = Schema.Union([AnthropicTextBlock, AnthropicImageBlock, AnthropicToolResultBlock]);
95
+ const AnthropicUserBlock = Schema.Union([
96
+ AnthropicTextBlock,
97
+ AnthropicImageBlock,
98
+ AnthropicDocumentBlock,
99
+ AnthropicToolResultBlock,
100
+ ]);
89
101
  const AnthropicAssistantBlock = Schema.Union([
90
102
  AnthropicTextBlock,
91
103
  AnthropicThinkingBlock,
@@ -252,8 +264,17 @@ const lowerServerToolResult = Effect.fn("AnthropicMessages.lowerServerToolResult
252
264
  return yield* invalid(`Anthropic Messages does not know how to round-trip server tool result for ${part.name}`);
253
265
  return { type: wireType, tool_use_id: part.id, content: part.result.value };
254
266
  });
255
- const lowerImage = Effect.fn("AnthropicMessages.lowerImage")(function* (part) {
256
- const media = yield* ProviderShared.validateMedia("Anthropic Messages", part, new Set(ProviderShared.IMAGE_MIMES));
267
+ const lowerMedia = Effect.fn("AnthropicMessages.lowerMedia")(function* (part) {
268
+ const media = yield* ProviderShared.validateMedia("Anthropic Messages", part, MEDIA_MIMES);
269
+ if (media.mime === "application/pdf")
270
+ return {
271
+ type: "document",
272
+ source: {
273
+ type: "base64",
274
+ media_type: "application/pdf",
275
+ data: media.base64,
276
+ },
277
+ };
257
278
  return {
258
279
  type: "image",
259
280
  source: {
@@ -263,20 +284,12 @@ const lowerImage = Effect.fn("AnthropicMessages.lowerImage")(function* (part) {
263
284
  },
264
285
  };
265
286
  });
266
- // Tool results may carry structured text/images. Keep media as provider-native
287
+ // Tool results may carry structured text, images, and documents. Keep media as provider-native
267
288
  // content instead of JSON-stringifying base64 into a prompt string.
268
289
  const lowerToolResultContentItem = Effect.fn("AnthropicMessages.lowerToolResultContentItem")(function* (item) {
269
290
  if (item.type === "text")
270
291
  return { type: "text", text: item.text };
271
- const media = yield* ProviderShared.validateToolFile("Anthropic Messages", item, new Set(ProviderShared.IMAGE_MIMES));
272
- return {
273
- type: "image",
274
- source: {
275
- type: "base64",
276
- media_type: media.mime,
277
- data: media.base64,
278
- },
279
- };
292
+ return yield* lowerMedia({ type: "media", mediaType: item.mime, data: item.uri, filename: item.name });
280
293
  });
281
294
  const lowerToolResultContent = Effect.fn("AnthropicMessages.lowerToolResultContent")(function* (part) {
282
295
  // Text / json / error results stay as a string for backward compatibility
@@ -354,7 +367,7 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (re
354
367
  continue;
355
368
  }
356
369
  if (part.type === "media") {
357
- content.push(yield* lowerImage(part));
370
+ content.push(yield* lowerMedia(part));
358
371
  continue;
359
372
  }
360
373
  return yield* ProviderShared.unsupportedContent("Anthropic Messages", "user", ["text", "media"]);
@@ -41,6 +41,14 @@ declare const BedrockConverseBody: Schema.Struct<{
41
41
  readonly bytes: Schema.String;
42
42
  }>;
43
43
  }>;
44
+ }>, Schema.Struct<{
45
+ readonly document: Schema.Struct<{
46
+ readonly format: Schema.Literals<readonly ["pdf", "csv", "doc", "docx", "xls", "xlsx", "html", "txt", "md"]>;
47
+ readonly name: Schema.String;
48
+ readonly source: Schema.Struct<{
49
+ readonly bytes: Schema.String;
50
+ }>;
51
+ }>;
44
52
  }>]>>;
45
53
  readonly status: Schema.optional<Schema.Literals<readonly ["success", "error"]>>;
46
54
  }>;
@@ -164,6 +172,14 @@ export declare const protocol: Protocol<{
164
172
  readonly bytes: Schema.String;
165
173
  }>;
166
174
  }>;
175
+ }>, Schema.Struct<{
176
+ readonly document: Schema.Struct<{
177
+ readonly format: Schema.Literals<readonly ["pdf", "csv", "doc", "docx", "xls", "xlsx", "html", "txt", "md"]>;
178
+ readonly name: Schema.String;
179
+ readonly source: Schema.Struct<{
180
+ readonly bytes: Schema.String;
181
+ }>;
182
+ }>;
167
183
  }>]>>;
168
184
  readonly status: Schema.optional<Schema.Literals<readonly ["success", "error"]>>;
169
185
  }>;
@@ -391,6 +407,14 @@ export declare const route: Route<{
391
407
  readonly bytes: Schema.String;
392
408
  }>;
393
409
  }>;
410
+ }>, Schema.Struct<{
411
+ readonly document: Schema.Struct<{
412
+ readonly format: Schema.Literals<readonly ["pdf", "csv", "doc", "docx", "xls", "xlsx", "html", "txt", "md"]>;
413
+ readonly name: Schema.String;
414
+ readonly source: Schema.Struct<{
415
+ readonly bytes: Schema.String;
416
+ }>;
417
+ }>;
394
418
  }>]>>;
395
419
  readonly status: Schema.optional<Schema.Literals<readonly ["success", "error"]>>;
396
420
  }>;
@@ -30,6 +30,7 @@ const BedrockToolResultContentItem = Schema.Union([
30
30
  Schema.Struct({ text: Schema.String }),
31
31
  Schema.Struct({ json: Schema.Unknown }),
32
32
  BedrockMedia.ImageBlock,
33
+ BedrockMedia.DocumentBlock,
33
34
  ]);
34
35
  const BedrockToolResultBlock = Schema.Struct({
35
36
  toolResult: Schema.Struct({
@@ -201,8 +202,6 @@ const lowerToolResultContent = Effect.fn("BedrockConverse.lowerToolResultContent
201
202
  data: item.uri,
202
203
  filename: item.name,
203
204
  });
204
- if (!("image" in media))
205
- return yield* ProviderShared.invalidRequest("Bedrock Converse only supports image media in tool results");
206
205
  content.push(media);
207
206
  }
208
207
  return content;
@@ -17,14 +17,22 @@ declare const GeminiBody: Schema.Struct<{
17
17
  }>;
18
18
  }>, Schema.Struct<{
19
19
  readonly functionCall: Schema.Struct<{
20
+ readonly id: Schema.optional<Schema.String>;
20
21
  readonly name: Schema.String;
21
22
  readonly args: Schema.Unknown;
22
23
  }>;
23
24
  readonly thoughtSignature: Schema.optional<Schema.String>;
24
25
  }>, Schema.Struct<{
25
26
  readonly functionResponse: Schema.Struct<{
27
+ readonly id: Schema.optional<Schema.String>;
26
28
  readonly name: Schema.String;
27
29
  readonly response: Schema.Unknown;
30
+ readonly parts: Schema.optional<Schema.$Array<Schema.Struct<{
31
+ readonly inlineData: Schema.Struct<{
32
+ readonly mimeType: Schema.String;
33
+ readonly data: Schema.String;
34
+ }>;
35
+ }>>>;
28
36
  }>;
29
37
  }>]>>;
30
38
  }>>;
@@ -78,14 +86,22 @@ export declare const protocol: Protocol<{
78
86
  }>;
79
87
  }>, Schema.Struct<{
80
88
  readonly functionCall: Schema.Struct<{
89
+ readonly id: Schema.optional<Schema.String>;
81
90
  readonly name: Schema.String;
82
91
  readonly args: Schema.Unknown;
83
92
  }>;
84
93
  readonly thoughtSignature: Schema.optional<Schema.String>;
85
94
  }>, Schema.Struct<{
86
95
  readonly functionResponse: Schema.Struct<{
96
+ readonly id: Schema.optional<Schema.String>;
87
97
  readonly name: Schema.String;
88
98
  readonly response: Schema.Unknown;
99
+ readonly parts: Schema.optional<Schema.$Array<Schema.Struct<{
100
+ readonly inlineData: Schema.Struct<{
101
+ readonly mimeType: Schema.String;
102
+ readonly data: Schema.String;
103
+ }>;
104
+ }>>>;
89
105
  }>;
90
106
  }>]>>;
91
107
  }, "Type">[];
@@ -133,14 +149,22 @@ export declare const protocol: Protocol<{
133
149
  }>;
134
150
  }>, Schema.Struct<{
135
151
  readonly functionCall: Schema.Struct<{
152
+ readonly id: Schema.optional<Schema.String>;
136
153
  readonly name: Schema.String;
137
154
  readonly args: Schema.Unknown;
138
155
  }>;
139
156
  readonly thoughtSignature: Schema.optional<Schema.String>;
140
157
  }>, Schema.Struct<{
141
158
  readonly functionResponse: Schema.Struct<{
159
+ readonly id: Schema.optional<Schema.String>;
142
160
  readonly name: Schema.String;
143
161
  readonly response: Schema.Unknown;
162
+ readonly parts: Schema.optional<Schema.$Array<Schema.Struct<{
163
+ readonly inlineData: Schema.Struct<{
164
+ readonly mimeType: Schema.String;
165
+ readonly data: Schema.String;
166
+ }>;
167
+ }>>>;
144
168
  }>;
145
169
  }>]>>;
146
170
  }, "Type"> | undefined;
@@ -172,14 +196,22 @@ export declare const route: Route<{
172
196
  }>;
173
197
  }>, Schema.Struct<{
174
198
  readonly functionCall: Schema.Struct<{
199
+ readonly id: Schema.optional<Schema.String>;
175
200
  readonly name: Schema.String;
176
201
  readonly args: Schema.Unknown;
177
202
  }>;
178
203
  readonly thoughtSignature: Schema.optional<Schema.String>;
179
204
  }>, Schema.Struct<{
180
205
  readonly functionResponse: Schema.Struct<{
206
+ readonly id: Schema.optional<Schema.String>;
181
207
  readonly name: Schema.String;
182
208
  readonly response: Schema.Unknown;
209
+ readonly parts: Schema.optional<Schema.$Array<Schema.Struct<{
210
+ readonly inlineData: Schema.Struct<{
211
+ readonly mimeType: Schema.String;
212
+ readonly data: Schema.String;
213
+ }>;
214
+ }>>>;
183
215
  }>;
184
216
  }>]>>;
185
217
  }, "Type">[];
@@ -28,6 +28,7 @@ const GeminiInlineDataPart = Schema.Struct({
28
28
  });
29
29
  const GeminiFunctionCallPart = Schema.Struct({
30
30
  functionCall: Schema.Struct({
31
+ id: Schema.optional(Schema.String),
31
32
  name: Schema.String,
32
33
  args: Schema.Unknown,
33
34
  }),
@@ -35,8 +36,10 @@ const GeminiFunctionCallPart = Schema.Struct({
35
36
  });
36
37
  const GeminiFunctionResponsePart = Schema.Struct({
37
38
  functionResponse: Schema.Struct({
39
+ id: Schema.optional(Schema.String),
38
40
  name: Schema.String,
39
41
  response: Schema.Unknown,
42
+ parts: Schema.optional(Schema.Array(GeminiInlineDataPart)),
40
43
  }),
41
44
  });
42
45
  const GeminiContentPart = Schema.Union([
@@ -148,8 +151,12 @@ const thoughtSignature = (providerMetadata) => {
148
151
  ? google.thoughtSignature
149
152
  : undefined;
150
153
  };
154
+ const functionCallId = (providerMetadata) => {
155
+ const google = providerMetadata?.google;
156
+ return ProviderShared.isRecord(google) && typeof google.functionCallId === "string" ? google.functionCallId : undefined;
157
+ };
151
158
  const lowerToolCall = (part) => ({
152
- functionCall: { name: part.name, args: part.input },
159
+ functionCall: { id: functionCallId(part.providerMetadata), name: part.name, args: part.input },
153
160
  thoughtSignature: thoughtSignature(part.providerMetadata),
154
161
  });
155
162
  const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
@@ -202,6 +209,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
202
209
  if (part.result.type !== "content") {
203
210
  parts.push({
204
211
  functionResponse: {
212
+ id: functionCallId(part.providerMetadata),
205
213
  name: part.name,
206
214
  response: {
207
215
  name: part.name,
@@ -213,21 +221,24 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
213
221
  }
214
222
  const content = part.result.value;
215
223
  const text = content.filter((item) => item.type === "text").map((item) => item.text);
224
+ const media = [];
225
+ for (const item of content) {
226
+ if (item.type === "text")
227
+ continue;
228
+ const value = yield* ProviderShared.validateToolFile("Gemini", item, MEDIA_MIMES);
229
+ media.push({ inlineData: { mimeType: value.mime, data: value.base64 } });
230
+ }
216
231
  parts.push({
217
232
  functionResponse: {
233
+ id: functionCallId(part.providerMetadata),
218
234
  name: part.name,
219
235
  response: {
220
236
  name: part.name,
221
237
  content: text.join("\n"),
222
238
  },
239
+ parts: media.length > 0 ? media : undefined,
223
240
  },
224
241
  });
225
- for (const item of content) {
226
- if (item.type === "text")
227
- continue;
228
- const media = yield* ProviderShared.validateToolFile("Gemini", item, MEDIA_MIMES);
229
- parts.push({ inlineData: { mimeType: media.mime, data: media.base64 } });
230
- }
231
242
  }
232
243
  contents.push({ role: "user", parts });
233
244
  }
@@ -359,15 +370,17 @@ const step = (state, event) => {
359
370
  if ("functionCall" in part) {
360
371
  const input = part.functionCall.args;
361
372
  const id = `tool_${nextToolCallId++}`;
373
+ const metadata = {
374
+ ...(part.functionCall.id === undefined ? {} : { functionCallId: part.functionCall.id }),
375
+ ...(part.thoughtSignature === undefined ? {} : { thoughtSignature: part.thoughtSignature }),
376
+ };
362
377
  lifecycle = Lifecycle.reasoningEnd(lifecycle, events, "reasoning-0", reasoningSignature ? googleMetadata({ thoughtSignature: reasoningSignature }) : undefined);
363
378
  lifecycle = Lifecycle.stepStart(lifecycle, events);
364
379
  events.push(LLMEvent.toolCall({
365
380
  id,
366
381
  name: part.functionCall.name,
367
382
  input,
368
- providerMetadata: part.thoughtSignature
369
- ? googleMetadata({ thoughtSignature: part.thoughtSignature })
370
- : undefined,
383
+ providerMetadata: Object.keys(metadata).length > 0 ? googleMetadata(metadata) : undefined,
371
384
  }));
372
385
  hasToolCalls = true;
373
386
  }
@@ -28,6 +28,11 @@ export declare const route: Route<{
28
28
  }>, import("effect/Schema").Struct<{
29
29
  readonly type: import("effect/Schema").tag<"input_image">;
30
30
  readonly image_url: import("effect/Schema").String;
31
+ }>, import("effect/Schema").Struct<{
32
+ readonly type: import("effect/Schema").tag<"input_file">;
33
+ readonly filename: import("effect/Schema").String;
34
+ readonly file_data: import("effect/Schema").String;
35
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
31
36
  }>]>>;
32
37
  }, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
33
38
  readonly role: import("effect/Schema").tag<"assistant">;
@@ -49,6 +54,11 @@ export declare const route: Route<{
49
54
  }>, import("effect/Schema").Struct<{
50
55
  readonly type: import("effect/Schema").tag<"input_image">;
51
56
  readonly image_url: import("effect/Schema").String;
57
+ }>, import("effect/Schema").Struct<{
58
+ readonly type: import("effect/Schema").tag<"input_file">;
59
+ readonly filename: import("effect/Schema").String;
60
+ readonly file_data: import("effect/Schema").String;
61
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
52
62
  }>]>>]>;
53
63
  }, "Type">)[];
54
64
  readonly model: string;
@@ -20,6 +20,11 @@ declare const OpenAIResponsesBody: Schema.Struct<{
20
20
  }>, Schema.Struct<{
21
21
  readonly type: Schema.tag<"input_image">;
22
22
  readonly image_url: Schema.String;
23
+ }>, Schema.Struct<{
24
+ readonly type: Schema.tag<"input_file">;
25
+ readonly filename: Schema.String;
26
+ readonly file_data: Schema.String;
27
+ readonly mime_type: Schema.optional<Schema.String>;
23
28
  }>]>>;
24
29
  }>, Schema.Struct<{
25
30
  readonly role: Schema.tag<"assistant">;
@@ -52,6 +57,11 @@ declare const OpenAIResponsesBody: Schema.Struct<{
52
57
  }>, Schema.Struct<{
53
58
  readonly type: Schema.tag<"input_image">;
54
59
  readonly image_url: Schema.String;
60
+ }>, Schema.Struct<{
61
+ readonly type: Schema.tag<"input_file">;
62
+ readonly filename: Schema.String;
63
+ readonly file_data: Schema.String;
64
+ readonly mime_type: Schema.optional<Schema.String>;
55
65
  }>]>>]>;
56
66
  }>]>>;
57
67
  readonly instructions: Schema.optional<Schema.String>;
@@ -122,6 +132,11 @@ export declare const protocol: Protocol<{
122
132
  }>, Schema.Struct<{
123
133
  readonly type: Schema.tag<"input_image">;
124
134
  readonly image_url: Schema.String;
135
+ }>, Schema.Struct<{
136
+ readonly type: Schema.tag<"input_file">;
137
+ readonly filename: Schema.String;
138
+ readonly file_data: Schema.String;
139
+ readonly mime_type: Schema.optional<Schema.String>;
125
140
  }>]>>;
126
141
  }, "Type"> | Schema.Struct.ReadonlySide<{
127
142
  readonly role: Schema.tag<"assistant">;
@@ -143,6 +158,11 @@ export declare const protocol: Protocol<{
143
158
  }>, Schema.Struct<{
144
159
  readonly type: Schema.tag<"input_image">;
145
160
  readonly image_url: Schema.String;
161
+ }>, Schema.Struct<{
162
+ readonly type: Schema.tag<"input_file">;
163
+ readonly filename: Schema.String;
164
+ readonly file_data: Schema.String;
165
+ readonly mime_type: Schema.optional<Schema.String>;
146
166
  }>]>>]>;
147
167
  }, "Type">)[];
148
168
  readonly model: string;
@@ -274,6 +294,11 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
274
294
  }>, Schema.Struct<{
275
295
  readonly type: Schema.tag<"input_image">;
276
296
  readonly image_url: Schema.String;
297
+ }>, Schema.Struct<{
298
+ readonly type: Schema.tag<"input_file">;
299
+ readonly filename: Schema.String;
300
+ readonly file_data: Schema.String;
301
+ readonly mime_type: Schema.optional<Schema.String>;
277
302
  }>]>>;
278
303
  }, "Type"> | Schema.Struct.ReadonlySide<{
279
304
  readonly role: Schema.tag<"assistant">;
@@ -295,6 +320,11 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
295
320
  }>, Schema.Struct<{
296
321
  readonly type: Schema.tag<"input_image">;
297
322
  readonly image_url: Schema.String;
323
+ }>, Schema.Struct<{
324
+ readonly type: Schema.tag<"input_file">;
325
+ readonly filename: Schema.String;
326
+ readonly file_data: Schema.String;
327
+ readonly mime_type: Schema.optional<Schema.String>;
298
328
  }>]>>]>;
299
329
  }, "Type">)[];
300
330
  readonly model: string;
@@ -363,6 +393,11 @@ export declare const route: Route<{
363
393
  }>, Schema.Struct<{
364
394
  readonly type: Schema.tag<"input_image">;
365
395
  readonly image_url: Schema.String;
396
+ }>, Schema.Struct<{
397
+ readonly type: Schema.tag<"input_file">;
398
+ readonly filename: Schema.String;
399
+ readonly file_data: Schema.String;
400
+ readonly mime_type: Schema.optional<Schema.String>;
366
401
  }>]>>;
367
402
  }, "Type"> | Schema.Struct.ReadonlySide<{
368
403
  readonly role: Schema.tag<"assistant">;
@@ -384,6 +419,11 @@ export declare const route: Route<{
384
419
  }>, Schema.Struct<{
385
420
  readonly type: Schema.tag<"input_image">;
386
421
  readonly image_url: Schema.String;
422
+ }>, Schema.Struct<{
423
+ readonly type: Schema.tag<"input_file">;
424
+ readonly filename: Schema.String;
425
+ readonly file_data: Schema.String;
426
+ readonly mime_type: Schema.optional<Schema.String>;
387
427
  }>]>>]>;
388
428
  }, "Type">)[];
389
429
  readonly model: string;
@@ -452,6 +492,11 @@ export declare const webSocketTransport: import("../route/transport/websocket").
452
492
  }>, Schema.Struct<{
453
493
  readonly type: Schema.tag<"input_image">;
454
494
  readonly image_url: Schema.String;
495
+ }>, Schema.Struct<{
496
+ readonly type: Schema.tag<"input_file">;
497
+ readonly filename: Schema.String;
498
+ readonly file_data: Schema.String;
499
+ readonly mime_type: Schema.optional<Schema.String>;
455
500
  }>]>>;
456
501
  }, "Type"> | Schema.Struct.ReadonlySide<{
457
502
  readonly role: Schema.tag<"assistant">;
@@ -473,6 +518,11 @@ export declare const webSocketTransport: import("../route/transport/websocket").
473
518
  }>, Schema.Struct<{
474
519
  readonly type: Schema.tag<"input_image">;
475
520
  readonly image_url: Schema.String;
521
+ }>, Schema.Struct<{
522
+ readonly type: Schema.tag<"input_file">;
523
+ readonly filename: Schema.String;
524
+ readonly file_data: Schema.String;
525
+ readonly mime_type: Schema.optional<Schema.String>;
476
526
  }>]>>]>;
477
527
  }, "Type">)[];
478
528
  readonly model: string;
@@ -542,6 +592,11 @@ export declare const webSocketTransport: import("../route/transport/websocket").
542
592
  }>, Schema.Struct<{
543
593
  readonly type: Schema.tag<"input_image">;
544
594
  readonly image_url: Schema.String;
595
+ }>, Schema.Struct<{
596
+ readonly type: Schema.tag<"input_file">;
597
+ readonly filename: Schema.String;
598
+ readonly file_data: Schema.String;
599
+ readonly mime_type: Schema.optional<Schema.String>;
545
600
  }>]>>;
546
601
  }, "Type"> | Schema.Struct.ReadonlySide<{
547
602
  readonly role: Schema.tag<"assistant">;
@@ -563,6 +618,11 @@ export declare const webSocketTransport: import("../route/transport/websocket").
563
618
  }>, Schema.Struct<{
564
619
  readonly type: Schema.tag<"input_image">;
565
620
  readonly image_url: Schema.String;
621
+ }>, Schema.Struct<{
622
+ readonly type: Schema.tag<"input_file">;
623
+ readonly filename: Schema.String;
624
+ readonly file_data: Schema.String;
625
+ readonly mime_type: Schema.optional<Schema.String>;
566
626
  }>]>>]>;
567
627
  }, "Type">)[];
568
628
  readonly model: string;
@@ -630,6 +690,11 @@ export declare const webSocketRoute: Route<{
630
690
  }>, Schema.Struct<{
631
691
  readonly type: Schema.tag<"input_image">;
632
692
  readonly image_url: Schema.String;
693
+ }>, Schema.Struct<{
694
+ readonly type: Schema.tag<"input_file">;
695
+ readonly filename: Schema.String;
696
+ readonly file_data: Schema.String;
697
+ readonly mime_type: Schema.optional<Schema.String>;
633
698
  }>]>>;
634
699
  }, "Type"> | Schema.Struct.ReadonlySide<{
635
700
  readonly role: Schema.tag<"assistant">;
@@ -651,6 +716,11 @@ export declare const webSocketRoute: Route<{
651
716
  }>, Schema.Struct<{
652
717
  readonly type: Schema.tag<"input_image">;
653
718
  readonly image_url: Schema.String;
719
+ }>, Schema.Struct<{
720
+ readonly type: Schema.tag<"input_file">;
721
+ readonly filename: Schema.String;
722
+ readonly file_data: Schema.String;
723
+ readonly mime_type: Schema.optional<Schema.String>;
654
724
  }>]>>]>;
655
725
  }, "Type">)[];
656
726
  readonly model: string;
@@ -13,6 +13,7 @@ import { ToolSchemaProjection } from "./utils/tool-schema";
13
13
  import { ToolStream } from "./utils/tool-stream";
14
14
  import { OpenAIImage } from "./utils/openai-image";
15
15
  const ADAPTER = "openai-responses";
16
+ const MEDIA_MIMES = new Set([...ProviderShared.IMAGE_MIMES, ...ProviderShared.PDF_MIMES]);
16
17
  export const DEFAULT_BASE_URL = "https://api.openai.com/v1";
17
18
  export const PATH = "/responses";
18
19
  // =============================================================================
@@ -26,7 +27,17 @@ const OpenAIResponsesInputImage = Schema.Struct({
26
27
  type: Schema.tag("input_image"),
27
28
  image_url: Schema.String,
28
29
  });
29
- const OpenAIResponsesInputContent = Schema.Union([OpenAIResponsesInputText, OpenAIResponsesInputImage]);
30
+ const OpenAIResponsesInputFile = Schema.Struct({
31
+ type: Schema.tag("input_file"),
32
+ filename: Schema.String,
33
+ file_data: Schema.String,
34
+ mime_type: Schema.optional(Schema.String),
35
+ });
36
+ const OpenAIResponsesInputContent = Schema.Union([
37
+ OpenAIResponsesInputText,
38
+ OpenAIResponsesInputImage,
39
+ OpenAIResponsesInputFile,
40
+ ]);
30
41
  const OpenAIResponsesOutputText = Schema.Struct({
31
42
  type: Schema.tag("output_text"),
32
43
  text: Schema.String,
@@ -46,9 +57,13 @@ const OpenAIResponsesItemReference = Schema.Struct({
46
57
  id: Schema.String,
47
58
  });
48
59
  // `function_call_output.output` accepts either a plain string or an ordered
49
- // array of content items so tools can return images in addition to text.
60
+ // array of content items so tools can return images and files in addition to text.
50
61
  // https://platform.openai.com/docs/api-reference/responses/object
51
- const OpenAIResponsesFunctionCallOutputContent = Schema.Union([OpenAIResponsesInputText, OpenAIResponsesInputImage]);
62
+ const OpenAIResponsesFunctionCallOutputContent = Schema.Union([
63
+ OpenAIResponsesInputText,
64
+ OpenAIResponsesInputImage,
65
+ OpenAIResponsesInputFile,
66
+ ]);
52
67
  const OpenAIResponsesFunctionCallOutput = Schema.Union([
53
68
  Schema.String,
54
69
  Schema.Array(OpenAIResponsesFunctionCallOutputContent),
@@ -252,31 +267,47 @@ const hostedToolItemID = (part) => {
252
267
  ? openai.itemId
253
268
  : undefined;
254
269
  };
255
- const lowerUserContent = Effect.fn("OpenAIResponses.lowerUserContent")(function* (part) {
270
+ const lowerMedia = Effect.fn("OpenAIResponses.lowerMedia")(function* (part, provider) {
271
+ const media = yield* ProviderShared.validateMedia("OpenAI Responses", part, MEDIA_MIMES);
272
+ if (media.mime === "application/pdf") {
273
+ // xAI models inline bytes and MIME separately; OpenAI uses a data URL in file_data.
274
+ if (provider === "xai")
275
+ return {
276
+ type: "input_file",
277
+ filename: part.filename ?? "document.pdf",
278
+ file_data: media.base64,
279
+ mime_type: media.mime,
280
+ };
281
+ return {
282
+ type: "input_file",
283
+ filename: part.filename ?? "document.pdf",
284
+ file_data: media.dataUrl,
285
+ };
286
+ }
287
+ return { type: "input_image", image_url: media.dataUrl };
288
+ });
289
+ const lowerUserContent = Effect.fn("OpenAIResponses.lowerUserContent")(function* (part, provider) {
256
290
  if (part.type === "text")
257
291
  return { type: "input_text", text: part.text };
258
- if (part.type === "media") {
259
- const media = yield* ProviderShared.validateMedia("OpenAI Responses", part, new Set(ProviderShared.IMAGE_MIMES));
260
- return { type: "input_image", image_url: media.dataUrl };
261
- }
292
+ if (part.type === "media")
293
+ return yield* lowerMedia(part, provider);
262
294
  return yield* ProviderShared.unsupportedContent("OpenAI Responses", "user", ["text", "media"]);
263
295
  });
264
- // Tool results may carry structured text/images. Keep media as provider-native
296
+ // Tool results may carry structured text, images, and files. Keep media as provider-native
265
297
  // content instead of JSON-stringifying base64 into a prompt string.
266
- const lowerToolResultContentItem = Effect.fn("OpenAIResponses.lowerToolResultContentItem")(function* (item) {
298
+ const lowerToolResultContentItem = Effect.fn("OpenAIResponses.lowerToolResultContentItem")(function* (item, provider) {
267
299
  if (item.type === "text")
268
300
  return { type: "input_text", text: item.text };
269
- const media = yield* ProviderShared.validateToolFile("OpenAI Responses", item, new Set(ProviderShared.IMAGE_MIMES));
270
- return { type: "input_image", image_url: media.dataUrl };
301
+ return yield* lowerMedia({ type: "media", mediaType: item.mime, data: item.uri, filename: item.name }, provider);
271
302
  });
272
- const lowerToolResultOutput = Effect.fn("OpenAIResponses.lowerToolResultOutput")(function* (part) {
303
+ const lowerToolResultOutput = Effect.fn("OpenAIResponses.lowerToolResultOutput")(function* (part, provider) {
273
304
  // Text/json/error results are encoded as a plain string for backward
274
305
  // compatibility with existing cassettes and provider expectations.
275
306
  if (part.result.type !== "content")
276
307
  return ProviderShared.toolResultText(part);
277
308
  // Preserve the narrowed array element type when compiled through a consumer package.
278
309
  const content = part.result.value;
279
- return yield* Effect.forEach(content, lowerToolResultContentItem);
310
+ return yield* Effect.forEach(content, (item) => lowerToolResultContentItem(item, provider));
280
311
  });
281
312
  const lowerMessages = Effect.fn("OpenAIResponses.lowerMessages")(function* (request) {
282
313
  const system = request.system.length === 0 ? [] : [{ role: "system", content: ProviderShared.joinText(request.system) }];
@@ -296,7 +327,10 @@ const lowerMessages = Effect.fn("OpenAIResponses.lowerMessages")(function* (requ
296
327
  continue;
297
328
  }
298
329
  if (message.role === "user") {
299
- input.push({ role: "user", content: yield* Effect.forEach(message.content, lowerUserContent) });
330
+ input.push({
331
+ role: "user",
332
+ content: yield* Effect.forEach(message.content, (part) => lowerUserContent(part, request.model.provider)),
333
+ });
300
334
  continue;
301
335
  }
302
336
  if (message.role === "assistant") {
@@ -358,7 +392,7 @@ const lowerMessages = Effect.fn("OpenAIResponses.lowerMessages")(function* (requ
358
392
  const content = part.result.value;
359
393
  input.push({
360
394
  role: "user",
361
- content: yield* Effect.forEach(content, lowerToolResultContentItem),
395
+ content: yield* Effect.forEach(content, (item) => lowerToolResultContentItem(item, request.model.provider)),
362
396
  });
363
397
  }
364
398
  if (itemID)
@@ -381,7 +415,7 @@ const lowerMessages = Effect.fn("OpenAIResponses.lowerMessages")(function* (requ
381
415
  input.push({
382
416
  type: "function_call_output",
383
417
  call_id: part.id,
384
- output: yield* lowerToolResultOutput(part),
418
+ output: yield* lowerToolResultOutput(part, request.model.provider),
385
419
  });
386
420
  }
387
421
  }
@@ -108,7 +108,8 @@ export declare const parseToolInput: (route: string, name: string, raw: string)
108
108
  export declare const IMAGE_MIMES: readonly ["image/png", "image/jpeg", "image/gif", "image/webp"];
109
109
  export declare const VIDEO_MIMES: readonly ["video/mp4", "video/webm", "video/quicktime"];
110
110
  export declare const AUDIO_MIMES: readonly ["audio/wav", "audio/mp3", "audio/aiff", "audio/aac", "audio/ogg", "audio/flac"];
111
- export declare const MEDIA_MIMES: readonly ["image/png", "image/jpeg", "image/gif", "image/webp", "video/mp4", "video/webm", "video/quicktime", "audio/wav", "audio/mp3", "audio/aiff", "audio/aac", "audio/ogg", "audio/flac"];
111
+ export declare const PDF_MIMES: readonly ["application/pdf"];
112
+ export declare const MEDIA_MIMES: readonly ["image/png", "image/jpeg", "image/gif", "image/webp", "video/mp4", "video/webm", "video/quicktime", "audio/wav", "audio/mp3", "audio/aiff", "audio/aac", "audio/ogg", "audio/flac", "application/pdf"];
112
113
  export declare const MAX_MEDIA_ENCODED_BYTES: number;
113
114
  export declare const MAX_MEDIA_DECODED_BYTES: number;
114
115
  export interface ValidatedMedia {
@@ -115,7 +115,8 @@ export const parseToolInput = (route, name, raw) => parseJson(route, raw || "{}"
115
115
  export const IMAGE_MIMES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
116
116
  export const VIDEO_MIMES = ["video/mp4", "video/webm", "video/quicktime"];
117
117
  export const AUDIO_MIMES = ["audio/wav", "audio/mp3", "audio/aiff", "audio/aac", "audio/ogg", "audio/flac"];
118
- export const MEDIA_MIMES = [...IMAGE_MIMES, ...VIDEO_MIMES, ...AUDIO_MIMES];
118
+ export const PDF_MIMES = ["application/pdf"];
119
+ export const MEDIA_MIMES = [...IMAGE_MIMES, ...VIDEO_MIMES, ...AUDIO_MIMES, ...PDF_MIMES];
119
120
  export const MAX_MEDIA_ENCODED_BYTES = 28 * 1024 * 1024;
120
121
  export const MAX_MEDIA_DECODED_BYTES = 20 * 1024 * 1024;
121
122
  const base64Pattern = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
@@ -37,10 +37,10 @@ const DOCUMENT_FORMATS = {
37
37
  "text/plain": "txt",
38
38
  "text/markdown": "md",
39
39
  };
40
- const documentBlock = (part, format, bytes) => ({
40
+ const documentBlock = (name, format, bytes) => ({
41
41
  document: {
42
42
  format,
43
- name: part.filename ?? `document.${format}`,
43
+ name,
44
44
  source: { bytes },
45
45
  },
46
46
  });
@@ -60,8 +60,10 @@ export const lower = Effect.fn("BedrockMedia.lower")(function* (part) {
60
60
  return yield* ProviderShared.invalidRequest(`Bedrock Converse does not support image media type ${part.mediaType}`);
61
61
  const documentFormat = DOCUMENT_FORMATS[mime];
62
62
  if (documentFormat) {
63
+ if (!part.filename)
64
+ return yield* ProviderShared.invalidRequest("Bedrock Converse document media requires a filename");
63
65
  const media = yield* ProviderShared.validateMedia("Bedrock Converse", part, new Set(Object.keys(DOCUMENT_FORMATS)));
64
- return documentBlock(part, documentFormat, media.base64);
66
+ return documentBlock(part.filename, documentFormat, media.base64);
65
67
  }
66
68
  return yield* ProviderShared.invalidRequest(`Bedrock Converse does not support media type ${part.mediaType}`);
67
69
  });
@@ -54,6 +54,14 @@ export declare const routes: import("../route").Route<{
54
54
  readonly bytes: import("effect/Schema").String;
55
55
  }>;
56
56
  }>;
57
+ }>, import("effect/Schema").Struct<{
58
+ readonly document: import("effect/Schema").Struct<{
59
+ readonly format: import("effect/Schema").Literals<readonly ["pdf", "csv", "doc", "docx", "xls", "xlsx", "html", "txt", "md"]>;
60
+ readonly name: import("effect/Schema").String;
61
+ readonly source: import("effect/Schema").Struct<{
62
+ readonly bytes: import("effect/Schema").String;
63
+ }>;
64
+ }>;
57
65
  }>]>>;
58
66
  readonly status: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["success", "error"]>>;
59
67
  }>;
@@ -38,6 +38,17 @@ export declare const routes: import("../route").Route<{
38
38
  readonly type: import("effect/Schema").tag<"ephemeral">;
39
39
  readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
40
40
  }>>;
41
+ }>, import("effect/Schema").Struct<{
42
+ readonly type: import("effect/Schema").tag<"document">;
43
+ readonly source: import("effect/Schema").Struct<{
44
+ readonly type: import("effect/Schema").tag<"base64">;
45
+ readonly media_type: import("effect/Schema").Literal<"application/pdf">;
46
+ readonly data: import("effect/Schema").String;
47
+ }>;
48
+ readonly cache_control: import("effect/Schema").optional<import("effect/Schema").Struct<{
49
+ readonly type: import("effect/Schema").tag<"ephemeral">;
50
+ readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
51
+ }>>;
41
52
  }>, import("effect/Schema").Struct<{
42
53
  readonly type: import("effect/Schema").tag<"tool_result">;
43
54
  readonly tool_use_id: import("effect/Schema").String;
@@ -59,6 +70,17 @@ export declare const routes: import("../route").Route<{
59
70
  readonly type: import("effect/Schema").tag<"ephemeral">;
60
71
  readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
61
72
  }>>;
73
+ }>, import("effect/Schema").Struct<{
74
+ readonly type: import("effect/Schema").tag<"document">;
75
+ readonly source: import("effect/Schema").Struct<{
76
+ readonly type: import("effect/Schema").tag<"base64">;
77
+ readonly media_type: import("effect/Schema").Literal<"application/pdf">;
78
+ readonly data: import("effect/Schema").String;
79
+ }>;
80
+ readonly cache_control: import("effect/Schema").optional<import("effect/Schema").Struct<{
81
+ readonly type: import("effect/Schema").tag<"ephemeral">;
82
+ readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
83
+ }>>;
62
84
  }>]>>]>;
63
85
  readonly is_error: import("effect/Schema").optional<import("effect/Schema").Boolean>;
64
86
  readonly cache_control: import("effect/Schema").optional<import("effect/Schema").Struct<{
@@ -24,6 +24,17 @@ export declare const routes: import("../route").Route<{
24
24
  readonly type: import("effect/Schema").tag<"ephemeral">;
25
25
  readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
26
26
  }>>;
27
+ }>, import("effect/Schema").Struct<{
28
+ readonly type: import("effect/Schema").tag<"document">;
29
+ readonly source: import("effect/Schema").Struct<{
30
+ readonly type: import("effect/Schema").tag<"base64">;
31
+ readonly media_type: import("effect/Schema").Literal<"application/pdf">;
32
+ readonly data: import("effect/Schema").String;
33
+ }>;
34
+ readonly cache_control: import("effect/Schema").optional<import("effect/Schema").Struct<{
35
+ readonly type: import("effect/Schema").tag<"ephemeral">;
36
+ readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
37
+ }>>;
27
38
  }>, import("effect/Schema").Struct<{
28
39
  readonly type: import("effect/Schema").tag<"tool_result">;
29
40
  readonly tool_use_id: import("effect/Schema").String;
@@ -45,6 +56,17 @@ export declare const routes: import("../route").Route<{
45
56
  readonly type: import("effect/Schema").tag<"ephemeral">;
46
57
  readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
47
58
  }>>;
59
+ }>, import("effect/Schema").Struct<{
60
+ readonly type: import("effect/Schema").tag<"document">;
61
+ readonly source: import("effect/Schema").Struct<{
62
+ readonly type: import("effect/Schema").tag<"base64">;
63
+ readonly media_type: import("effect/Schema").Literal<"application/pdf">;
64
+ readonly data: import("effect/Schema").String;
65
+ }>;
66
+ readonly cache_control: import("effect/Schema").optional<import("effect/Schema").Struct<{
67
+ readonly type: import("effect/Schema").tag<"ephemeral">;
68
+ readonly ttl: import("effect/Schema").optional<import("effect/Schema").Literals<readonly ["5m", "1h"]>>;
69
+ }>>;
48
70
  }>]>>]>;
49
71
  readonly is_error: import("effect/Schema").optional<import("effect/Schema").Boolean>;
50
72
  readonly cache_control: import("effect/Schema").optional<import("effect/Schema").Struct<{
@@ -108,6 +108,11 @@ export declare const routes: (RouteDef<{
108
108
  }>, import("effect/Schema").Struct<{
109
109
  readonly type: import("effect/Schema").tag<"input_image">;
110
110
  readonly image_url: import("effect/Schema").String;
111
+ }>, import("effect/Schema").Struct<{
112
+ readonly type: import("effect/Schema").tag<"input_file">;
113
+ readonly filename: import("effect/Schema").String;
114
+ readonly file_data: import("effect/Schema").String;
115
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
111
116
  }>]>>;
112
117
  }, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
113
118
  readonly role: import("effect/Schema").tag<"assistant">;
@@ -129,6 +134,11 @@ export declare const routes: (RouteDef<{
129
134
  }>, import("effect/Schema").Struct<{
130
135
  readonly type: import("effect/Schema").tag<"input_image">;
131
136
  readonly image_url: import("effect/Schema").String;
137
+ }>, import("effect/Schema").Struct<{
138
+ readonly type: import("effect/Schema").tag<"input_file">;
139
+ readonly filename: import("effect/Schema").String;
140
+ readonly file_data: import("effect/Schema").String;
141
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
132
142
  }>]>>]>;
133
143
  }, "Type">)[];
134
144
  readonly model: string;
@@ -96,6 +96,11 @@ export declare const routes: (import("../route").Route<{
96
96
  }>, import("effect/Schema").Struct<{
97
97
  readonly type: import("effect/Schema").tag<"input_image">;
98
98
  readonly image_url: import("effect/Schema").String;
99
+ }>, import("effect/Schema").Struct<{
100
+ readonly type: import("effect/Schema").tag<"input_file">;
101
+ readonly filename: import("effect/Schema").String;
102
+ readonly file_data: import("effect/Schema").String;
103
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
99
104
  }>]>>;
100
105
  }, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
101
106
  readonly role: import("effect/Schema").tag<"assistant">;
@@ -117,6 +122,11 @@ export declare const routes: (import("../route").Route<{
117
122
  }>, import("effect/Schema").Struct<{
118
123
  readonly type: import("effect/Schema").tag<"input_image">;
119
124
  readonly image_url: import("effect/Schema").String;
125
+ }>, import("effect/Schema").Struct<{
126
+ readonly type: import("effect/Schema").tag<"input_file">;
127
+ readonly filename: import("effect/Schema").String;
128
+ readonly file_data: import("effect/Schema").String;
129
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
120
130
  }>]>>]>;
121
131
  }, "Type">)[];
122
132
  readonly model: string;
@@ -47,6 +47,17 @@ export declare const routes: Route<{
47
47
  readonly type: Schema.tag<"ephemeral">;
48
48
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
49
49
  }>>;
50
+ }>, Schema.Struct<{
51
+ readonly type: Schema.tag<"document">;
52
+ readonly source: Schema.Struct<{
53
+ readonly type: Schema.tag<"base64">;
54
+ readonly media_type: Schema.Literal<"application/pdf">;
55
+ readonly data: Schema.String;
56
+ }>;
57
+ readonly cache_control: Schema.optional<Schema.Struct<{
58
+ readonly type: Schema.tag<"ephemeral">;
59
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
60
+ }>>;
50
61
  }>, Schema.Struct<{
51
62
  readonly type: Schema.tag<"tool_result">;
52
63
  readonly tool_use_id: Schema.String;
@@ -68,6 +79,17 @@ export declare const routes: Route<{
68
79
  readonly type: Schema.tag<"ephemeral">;
69
80
  readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
70
81
  }>>;
82
+ }>, Schema.Struct<{
83
+ readonly type: Schema.tag<"document">;
84
+ readonly source: Schema.Struct<{
85
+ readonly type: Schema.tag<"base64">;
86
+ readonly media_type: Schema.Literal<"application/pdf">;
87
+ readonly data: Schema.String;
88
+ }>;
89
+ readonly cache_control: Schema.optional<Schema.Struct<{
90
+ readonly type: Schema.tag<"ephemeral">;
91
+ readonly ttl: Schema.optional<Schema.Literals<readonly ["5m", "1h"]>>;
92
+ }>>;
71
93
  }>]>>]>;
72
94
  readonly is_error: Schema.optional<Schema.Boolean>;
73
95
  readonly cache_control: Schema.optional<Schema.Struct<{
@@ -39,6 +39,11 @@ export declare const routes: import("../route").Route<{
39
39
  }>, import("effect/Schema").Struct<{
40
40
  readonly type: import("effect/Schema").tag<"input_image">;
41
41
  readonly image_url: import("effect/Schema").String;
42
+ }>, import("effect/Schema").Struct<{
43
+ readonly type: import("effect/Schema").tag<"input_file">;
44
+ readonly filename: import("effect/Schema").String;
45
+ readonly file_data: import("effect/Schema").String;
46
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
42
47
  }>]>>;
43
48
  }, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
44
49
  readonly role: import("effect/Schema").tag<"assistant">;
@@ -60,6 +65,11 @@ export declare const routes: import("../route").Route<{
60
65
  }>, import("effect/Schema").Struct<{
61
66
  readonly type: import("effect/Schema").tag<"input_image">;
62
67
  readonly image_url: import("effect/Schema").String;
68
+ }>, import("effect/Schema").Struct<{
69
+ readonly type: import("effect/Schema").tag<"input_file">;
70
+ readonly filename: import("effect/Schema").String;
71
+ readonly file_data: import("effect/Schema").String;
72
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
63
73
  }>]>>]>;
64
74
  }, "Type">)[];
65
75
  readonly model: string;
@@ -34,14 +34,22 @@ export declare const routes: Route<{
34
34
  }>;
35
35
  }>, import("effect/Schema").Struct<{
36
36
  readonly functionCall: import("effect/Schema").Struct<{
37
+ readonly id: import("effect/Schema").optional<import("effect/Schema").String>;
37
38
  readonly name: import("effect/Schema").String;
38
39
  readonly args: import("effect/Schema").Unknown;
39
40
  }>;
40
41
  readonly thoughtSignature: import("effect/Schema").optional<import("effect/Schema").String>;
41
42
  }>, import("effect/Schema").Struct<{
42
43
  readonly functionResponse: import("effect/Schema").Struct<{
44
+ readonly id: import("effect/Schema").optional<import("effect/Schema").String>;
43
45
  readonly name: import("effect/Schema").String;
44
46
  readonly response: import("effect/Schema").Unknown;
47
+ readonly parts: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Struct<{
48
+ readonly inlineData: import("effect/Schema").Struct<{
49
+ readonly mimeType: import("effect/Schema").String;
50
+ readonly data: import("effect/Schema").String;
51
+ }>;
52
+ }>>>;
45
53
  }>;
46
54
  }>]>>;
47
55
  }, "Type">[];
@@ -18,14 +18,22 @@ export declare const routes: import("../route").Route<{
18
18
  }>;
19
19
  }>, import("effect/Schema").Struct<{
20
20
  readonly functionCall: import("effect/Schema").Struct<{
21
+ readonly id: import("effect/Schema").optional<import("effect/Schema").String>;
21
22
  readonly name: import("effect/Schema").String;
22
23
  readonly args: import("effect/Schema").Unknown;
23
24
  }>;
24
25
  readonly thoughtSignature: import("effect/Schema").optional<import("effect/Schema").String>;
25
26
  }>, import("effect/Schema").Struct<{
26
27
  readonly functionResponse: import("effect/Schema").Struct<{
28
+ readonly id: import("effect/Schema").optional<import("effect/Schema").String>;
27
29
  readonly name: import("effect/Schema").String;
28
30
  readonly response: import("effect/Schema").Unknown;
31
+ readonly parts: import("effect/Schema").optional<import("effect/Schema").$Array<import("effect/Schema").Struct<{
32
+ readonly inlineData: import("effect/Schema").Struct<{
33
+ readonly mimeType: import("effect/Schema").String;
34
+ readonly data: import("effect/Schema").String;
35
+ }>;
36
+ }>>>;
29
37
  }>;
30
38
  }>]>>;
31
39
  }, "Type">[];
@@ -37,6 +37,11 @@ export declare const routes: import("../route").Route<{
37
37
  }>, import("effect/Schema").Struct<{
38
38
  readonly type: import("effect/Schema").tag<"input_image">;
39
39
  readonly image_url: import("effect/Schema").String;
40
+ }>, import("effect/Schema").Struct<{
41
+ readonly type: import("effect/Schema").tag<"input_file">;
42
+ readonly filename: import("effect/Schema").String;
43
+ readonly file_data: import("effect/Schema").String;
44
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
40
45
  }>]>>;
41
46
  }, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
42
47
  readonly role: import("effect/Schema").tag<"assistant">;
@@ -58,6 +63,11 @@ export declare const routes: import("../route").Route<{
58
63
  }>, import("effect/Schema").Struct<{
59
64
  readonly type: import("effect/Schema").tag<"input_image">;
60
65
  readonly image_url: import("effect/Schema").String;
66
+ }>, import("effect/Schema").Struct<{
67
+ readonly type: import("effect/Schema").tag<"input_file">;
68
+ readonly filename: import("effect/Schema").String;
69
+ readonly file_data: import("effect/Schema").String;
70
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
61
71
  }>]>>]>;
62
72
  }, "Type">)[];
63
73
  readonly model: string;
@@ -94,6 +94,11 @@ export declare const routes: (Route<{
94
94
  }>, import("effect/Schema").Struct<{
95
95
  readonly type: import("effect/Schema").tag<"input_image">;
96
96
  readonly image_url: import("effect/Schema").String;
97
+ }>, import("effect/Schema").Struct<{
98
+ readonly type: import("effect/Schema").tag<"input_file">;
99
+ readonly filename: import("effect/Schema").String;
100
+ readonly file_data: import("effect/Schema").String;
101
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
97
102
  }>]>>;
98
103
  }, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
99
104
  readonly role: import("effect/Schema").tag<"assistant">;
@@ -115,6 +120,11 @@ export declare const routes: (Route<{
115
120
  }>, import("effect/Schema").Struct<{
116
121
  readonly type: import("effect/Schema").tag<"input_image">;
117
122
  readonly image_url: import("effect/Schema").String;
123
+ }>, import("effect/Schema").Struct<{
124
+ readonly type: import("effect/Schema").tag<"input_file">;
125
+ readonly filename: import("effect/Schema").String;
126
+ readonly file_data: import("effect/Schema").String;
127
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
118
128
  }>]>>]>;
119
129
  }, "Type">)[];
120
130
  readonly model: string;
@@ -182,6 +192,11 @@ export declare const routes: (Route<{
182
192
  }>, import("effect/Schema").Struct<{
183
193
  readonly type: import("effect/Schema").tag<"input_image">;
184
194
  readonly image_url: import("effect/Schema").String;
195
+ }>, import("effect/Schema").Struct<{
196
+ readonly type: import("effect/Schema").tag<"input_file">;
197
+ readonly filename: import("effect/Schema").String;
198
+ readonly file_data: import("effect/Schema").String;
199
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
185
200
  }>]>>;
186
201
  }, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
187
202
  readonly role: import("effect/Schema").tag<"assistant">;
@@ -203,6 +218,11 @@ export declare const routes: (Route<{
203
218
  }>, import("effect/Schema").Struct<{
204
219
  readonly type: import("effect/Schema").tag<"input_image">;
205
220
  readonly image_url: import("effect/Schema").String;
221
+ }>, import("effect/Schema").Struct<{
222
+ readonly type: import("effect/Schema").tag<"input_file">;
223
+ readonly filename: import("effect/Schema").String;
224
+ readonly file_data: import("effect/Schema").String;
225
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
206
226
  }>]>>]>;
207
227
  }, "Type">)[];
208
228
  readonly model: string;
@@ -93,6 +93,11 @@ export declare const routes: (import("../route").Route<{
93
93
  }>, import("effect/Schema").Struct<{
94
94
  readonly type: import("effect/Schema").tag<"input_image">;
95
95
  readonly image_url: import("effect/Schema").String;
96
+ }>, import("effect/Schema").Struct<{
97
+ readonly type: import("effect/Schema").tag<"input_file">;
98
+ readonly filename: import("effect/Schema").String;
99
+ readonly file_data: import("effect/Schema").String;
100
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
96
101
  }>]>>;
97
102
  }, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
98
103
  readonly role: import("effect/Schema").tag<"assistant">;
@@ -114,6 +119,11 @@ export declare const routes: (import("../route").Route<{
114
119
  }>, import("effect/Schema").Struct<{
115
120
  readonly type: import("effect/Schema").tag<"input_image">;
116
121
  readonly image_url: import("effect/Schema").String;
122
+ }>, import("effect/Schema").Struct<{
123
+ readonly type: import("effect/Schema").tag<"input_file">;
124
+ readonly filename: import("effect/Schema").String;
125
+ readonly file_data: import("effect/Schema").String;
126
+ readonly mime_type: import("effect/Schema").optional<import("effect/Schema").String>;
117
127
  }>]>>]>;
118
128
  }, "Type">)[];
119
129
  readonly model: string;
@@ -26,10 +26,29 @@ const result = (call, value, error) => {
26
26
  output: settlement.output,
27
27
  events: settlement.result.type === "error"
28
28
  ? [
29
- LLMEvent.toolError({ id: call.id, name: call.name, message: String(settlement.result.value), error }),
30
- LLMEvent.toolResult({ id: call.id, name: call.name, result: settlement.result }),
29
+ LLMEvent.toolError({
30
+ id: call.id,
31
+ name: call.name,
32
+ message: String(settlement.result.value),
33
+ error,
34
+ providerMetadata: call.providerMetadata,
35
+ }),
36
+ LLMEvent.toolResult({
37
+ id: call.id,
38
+ name: call.name,
39
+ result: settlement.result,
40
+ providerMetadata: call.providerMetadata,
41
+ }),
31
42
  ]
32
- : [LLMEvent.toolResult({ id: call.id, name: call.name, result: settlement.result, output: settlement.output })],
43
+ : [
44
+ LLMEvent.toolResult({
45
+ id: call.id,
46
+ name: call.name,
47
+ result: settlement.result,
48
+ output: settlement.output,
49
+ providerMetadata: call.providerMetadata,
50
+ }),
51
+ ],
33
52
  };
34
53
  };
35
54
  export const ToolRuntime = { dispatch };
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-16033",
3
+ "version": "0.0.0-next-16040",
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-16033",
29
+ "@opencode-ai/http-recorder": "0.0.0-next-16040",
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-16033",
38
+ "@opencode-ai/schema": "0.0.0-next-16040",
39
39
  "aws4fetch": "1.0.20",
40
40
  "effect": "4.0.0-beta.98",
41
41
  "google-auth-library": "10.5.0"