@opencode/ai 2.0.14 → 2.0.15

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 (86) hide show
  1. package/README.md +115 -56
  2. package/dist/experimental/evaluation-client.d.ts +1 -1
  3. package/dist/experimental/evaluation-client.js +39 -3
  4. package/dist/experimental/evaluation.d.ts +4 -4
  5. package/dist/experimental/evaluation.js +2 -2
  6. package/dist/experimental/system-one.d.ts +3 -3
  7. package/dist/experimental/system-one.js +40 -51
  8. package/dist/generation.d.ts +69 -0
  9. package/dist/generation.js +84 -0
  10. package/dist/image-client.d.ts +6 -4
  11. package/dist/image-client.js +11 -11
  12. package/dist/image.d.ts +1040 -62
  13. package/dist/image.js +80 -52
  14. package/dist/index.d.ts +5 -2
  15. package/dist/index.js +3 -1
  16. package/dist/llm.d.ts +9 -1
  17. package/dist/media.d.ts +212 -0
  18. package/dist/media.js +228 -0
  19. package/dist/promise.d.ts +554 -0
  20. package/dist/promise.js +44 -0
  21. package/dist/protocols/anthropic-messages.js +7 -17
  22. package/dist/protocols/bedrock-converse.d.ts +4 -4
  23. package/dist/protocols/bedrock-converse.js +1 -6
  24. package/dist/protocols/gemini.d.ts +21 -0
  25. package/dist/protocols/gemini.js +42 -6
  26. package/dist/protocols/google-images.d.ts +9 -21
  27. package/dist/protocols/google-images.js +169 -132
  28. package/dist/protocols/meta-images.d.ts +7 -12
  29. package/dist/protocols/meta-images.js +92 -66
  30. package/dist/protocols/mistral-chat.js +7 -6
  31. package/dist/protocols/open-responses.d.ts +11 -3
  32. package/dist/protocols/open-responses.js +23 -12
  33. package/dist/protocols/openai-chat.d.ts +34 -1
  34. package/dist/protocols/openai-chat.js +100 -31
  35. package/dist/protocols/openai-images.d.ts +9 -20
  36. package/dist/protocols/openai-images.js +112 -142
  37. package/dist/protocols/shared.d.ts +17 -17
  38. package/dist/protocols/shared.js +32 -35
  39. package/dist/protocols/utils/bedrock-media.d.ts +2 -3
  40. package/dist/protocols/utils/bedrock-media.js +4 -4
  41. package/dist/protocols/utils/media-input.d.ts +10 -0
  42. package/dist/protocols/utils/media-input.js +17 -0
  43. package/dist/protocols/utils/responses-compaction.js +6 -5
  44. package/dist/protocols/utils/tool-stream.d.ts +27 -3
  45. package/dist/protocols/xai-images.d.ts +9 -15
  46. package/dist/protocols/xai-images.js +85 -83
  47. package/dist/protocols/zai-images.d.ts +9 -13
  48. package/dist/protocols/zai-images.js +59 -57
  49. package/dist/providers/amazon-bedrock.d.ts +2 -2
  50. package/dist/providers/cerebras.js +6 -1
  51. package/dist/providers/deepinfra.js +6 -1
  52. package/dist/providers/google-vertex.d.ts +7 -0
  53. package/dist/providers/google.d.ts +7 -0
  54. package/dist/providers/index.d.ts +1 -0
  55. package/dist/providers/index.js +1 -0
  56. package/dist/providers/openrouter.d.ts +19 -0
  57. package/dist/providers/openrouter.js +13 -1
  58. package/dist/providers/vercel-ai-gateway.d.ts +41 -0
  59. package/dist/providers/vercel-ai-gateway.js +85 -0
  60. package/dist/route/client.d.ts +9 -1
  61. package/dist/route/endpoint.d.ts +10 -10
  62. package/dist/route/executor-service.d.ts +12 -0
  63. package/dist/route/executor-service.js +3 -0
  64. package/dist/route/executor.d.ts +4 -9
  65. package/dist/route/executor.js +3 -3
  66. package/dist/route/index.d.ts +2 -0
  67. package/dist/route/index.js +2 -0
  68. package/dist/route/media-protocol.d.ts +45 -0
  69. package/dist/route/media-protocol.js +40 -0
  70. package/dist/route/media.d.ts +46 -0
  71. package/dist/route/media.js +64 -0
  72. package/dist/schema/errors.d.ts +13 -3
  73. package/dist/schema/errors.js +7 -0
  74. package/dist/schema/events.d.ts +563 -40
  75. package/dist/schema/events.js +35 -2
  76. package/dist/schema/messages.d.ts +98 -8
  77. package/dist/schema/messages.js +8 -6
  78. package/dist/schema/options.d.ts +2 -0
  79. package/dist/schema/options.js +3 -0
  80. package/dist/testing.d.ts +72 -8
  81. package/dist/utils/media-type.d.ts +6 -0
  82. package/dist/utils/media-type.js +49 -0
  83. package/dist/utils/sanitize.js +3 -1
  84. package/package.json +7 -3
  85. package/dist/protocols/utils/image-input.d.ts +0 -21
  86. package/dist/protocols/utils/image-input.js +0 -20
@@ -0,0 +1,554 @@
1
+ import { Effect, Layer } from "effect";
2
+ import { ImageModel, ImageRequest, type ImageRequestInput } from "./image.js";
3
+ import { ImageClient } from "./image-client.js";
4
+ import { LLMClient } from "./route/client.js";
5
+ import { RequestExecutor } from "./route/executor.js";
6
+ import { LanguageModel, LLMRequest } from "./schema/index.js";
7
+ import type { RequestInput } from "./llm.js";
8
+ /**
9
+ * Promise-first entrypoint for scripts and non-Effect callers. One `ManagedRuntime` hosts the LLM and image clients
10
+ * over a request executor; every method runs the corresponding Effect API and rethrows `AIError` unchanged.
11
+ */
12
+ export interface Options {
13
+ /** Executor layer; defaults to `RequestExecutor.fetchLayer`. Inject a recorder or middleware here. */
14
+ readonly layer?: Layer.Layer<RequestExecutor.Service>;
15
+ }
16
+ export interface RunOptions {
17
+ readonly signal?: AbortSignal;
18
+ }
19
+ export type Services = Layer.Success<typeof LLMClient.layer> | Layer.Success<typeof ImageClient.layer> | RequestExecutor.Service;
20
+ export declare const make: (options?: Options) => {
21
+ run: <A, E>(effect: Effect.Effect<A, E, Services>, options?: RunOptions) => Promise<A>;
22
+ llm: {
23
+ request: <const SelectedLanguageModel extends LanguageModel>(input: RequestInput<SelectedLanguageModel>) => LLMRequest<SelectedLanguageModel>;
24
+ generate: <const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: RunOptions) => Promise<import("./index.js").LLMResponse>;
25
+ stream: <const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: RunOptions) => AsyncIterable<({
26
+ readonly type: "compaction";
27
+ readonly provider: string & import("effect/Brand").Brand<"AI.ProviderID">;
28
+ readonly id?: string | undefined;
29
+ readonly text?: string | null | undefined;
30
+ readonly encrypted?: string | undefined;
31
+ } & ({
32
+ readonly encrypted: string;
33
+ readonly text?: never;
34
+ } | {
35
+ readonly text: string | null;
36
+ readonly encrypted?: never;
37
+ })) | {
38
+ readonly type: "step-start";
39
+ readonly index: number;
40
+ } | {
41
+ readonly id: string;
42
+ readonly type: "text-start";
43
+ readonly providerMetadata?: {
44
+ readonly [x: string]: {
45
+ readonly [x: string]: unknown;
46
+ };
47
+ } | undefined;
48
+ } | {
49
+ readonly id: string;
50
+ readonly type: "text-delta";
51
+ readonly text: string;
52
+ readonly providerMetadata?: {
53
+ readonly [x: string]: {
54
+ readonly [x: string]: unknown;
55
+ };
56
+ } | undefined;
57
+ } | {
58
+ readonly id: string;
59
+ readonly type: "text-end";
60
+ readonly text?: string | undefined;
61
+ readonly providerMetadata?: {
62
+ readonly [x: string]: {
63
+ readonly [x: string]: unknown;
64
+ };
65
+ } | undefined;
66
+ } | {
67
+ readonly id: string;
68
+ readonly type: "reasoning-start";
69
+ readonly providerMetadata?: {
70
+ readonly [x: string]: {
71
+ readonly [x: string]: unknown;
72
+ };
73
+ } | undefined;
74
+ } | {
75
+ readonly id: string;
76
+ readonly type: "reasoning-delta";
77
+ readonly text: string;
78
+ readonly providerMetadata?: {
79
+ readonly [x: string]: {
80
+ readonly [x: string]: unknown;
81
+ };
82
+ } | undefined;
83
+ } | {
84
+ readonly id: string;
85
+ readonly type: "reasoning-end";
86
+ readonly text?: string | undefined;
87
+ readonly providerMetadata?: {
88
+ readonly [x: string]: {
89
+ readonly [x: string]: unknown;
90
+ };
91
+ } | undefined;
92
+ } | {
93
+ readonly id: string;
94
+ readonly type: "tool-input-start";
95
+ readonly name: string;
96
+ readonly providerMetadata?: {
97
+ readonly [x: string]: {
98
+ readonly [x: string]: unknown;
99
+ };
100
+ } | undefined;
101
+ readonly namespace?: string | undefined;
102
+ readonly providerExecuted?: boolean | undefined;
103
+ } | {
104
+ readonly id: string;
105
+ readonly type: "tool-input-delta";
106
+ readonly name: string;
107
+ readonly text: string;
108
+ readonly input?: unknown;
109
+ readonly namespace?: string | undefined;
110
+ } | {
111
+ readonly id: string;
112
+ readonly type: "tool-input-end";
113
+ readonly name: string;
114
+ readonly providerMetadata?: {
115
+ readonly [x: string]: {
116
+ readonly [x: string]: unknown;
117
+ };
118
+ } | undefined;
119
+ readonly namespace?: string | undefined;
120
+ } | {
121
+ readonly id: string;
122
+ readonly type: "tool-input-error";
123
+ readonly name: string;
124
+ readonly raw: string;
125
+ readonly namespace?: string | undefined;
126
+ } | {
127
+ readonly id: string;
128
+ readonly type: "tool-call";
129
+ readonly name: string;
130
+ readonly input: unknown;
131
+ readonly providerMetadata?: {
132
+ readonly [x: string]: {
133
+ readonly [x: string]: unknown;
134
+ };
135
+ } | undefined;
136
+ readonly namespace?: string | undefined;
137
+ readonly providerExecuted?: boolean | undefined;
138
+ } | {
139
+ readonly id: string;
140
+ readonly type: "tool-result";
141
+ readonly name: string;
142
+ readonly result: {
143
+ readonly type: "json";
144
+ readonly value: unknown;
145
+ } | {
146
+ readonly type: "text";
147
+ readonly value: unknown;
148
+ } | {
149
+ readonly type: "error";
150
+ readonly value: unknown;
151
+ } | {
152
+ readonly type: "content";
153
+ readonly value: readonly ({
154
+ readonly type: "text";
155
+ readonly text: string;
156
+ } | {
157
+ readonly type: "file";
158
+ readonly uri: string;
159
+ readonly mime: string;
160
+ readonly name?: string | undefined;
161
+ })[];
162
+ };
163
+ readonly output?: {
164
+ readonly structured: unknown;
165
+ readonly content: readonly ({
166
+ readonly type: "text";
167
+ readonly text: string;
168
+ } | {
169
+ readonly type: "file";
170
+ readonly uri: string;
171
+ readonly mime: string;
172
+ readonly name?: string | undefined;
173
+ })[];
174
+ } | undefined;
175
+ readonly providerMetadata?: {
176
+ readonly [x: string]: {
177
+ readonly [x: string]: unknown;
178
+ };
179
+ } | undefined;
180
+ readonly namespace?: string | undefined;
181
+ readonly providerExecuted?: boolean | undefined;
182
+ } | {
183
+ readonly id: string;
184
+ readonly type: "tool-error";
185
+ readonly name: string;
186
+ readonly message: string;
187
+ readonly error?: unknown;
188
+ readonly providerMetadata?: {
189
+ readonly [x: string]: {
190
+ readonly [x: string]: unknown;
191
+ };
192
+ } | undefined;
193
+ readonly namespace?: string | undefined;
194
+ } | {
195
+ readonly type: "media";
196
+ readonly media: import("./media.js").Asset;
197
+ readonly providerMetadata?: {
198
+ readonly [x: string]: {
199
+ readonly [x: string]: unknown;
200
+ };
201
+ } | undefined;
202
+ } | {
203
+ readonly type: "step-finish";
204
+ readonly reason: {
205
+ readonly normalized: "length" | "stop" | "tool-calls" | "content-filter" | "error" | "unknown";
206
+ readonly raw?: string | undefined;
207
+ };
208
+ readonly index: number;
209
+ readonly providerMetadata?: {
210
+ readonly [x: string]: {
211
+ readonly [x: string]: unknown;
212
+ };
213
+ } | undefined;
214
+ readonly usage?: import("./index.js").Usage | undefined;
215
+ } | {
216
+ readonly type: "finish";
217
+ readonly reason: {
218
+ readonly normalized: "length" | "stop" | "tool-calls" | "content-filter" | "error" | "unknown";
219
+ readonly raw?: string | undefined;
220
+ };
221
+ readonly providerMetadata?: {
222
+ readonly [x: string]: {
223
+ readonly [x: string]: unknown;
224
+ };
225
+ } | undefined;
226
+ readonly usage?: import("./index.js").Usage | undefined;
227
+ } | {
228
+ readonly type: "provider-error";
229
+ readonly message: string;
230
+ readonly classification?: "context-overflow" | "payload-too-large" | undefined;
231
+ readonly providerMetadata?: {
232
+ readonly [x: string]: {
233
+ readonly [x: string]: unknown;
234
+ };
235
+ } | undefined;
236
+ }>;
237
+ };
238
+ image: {
239
+ request: typeof import("./image.js").request;
240
+ generate: <const Model extends ImageModel>(input: ImageRequestInput<Model> | ImageRequest, options?: RunOptions) => Promise<import("./image.js").ImageResponse>;
241
+ stream: <const Model extends ImageModel>(input: ImageRequestInput<Model> | ImageRequest, options?: RunOptions) => AsyncIterable<{
242
+ readonly type: "image";
243
+ readonly index: number;
244
+ readonly image: import("./media.js").Asset;
245
+ } | {
246
+ readonly type: "finish";
247
+ readonly providerMetadata?: {
248
+ readonly [x: string]: {
249
+ readonly [x: string]: unknown;
250
+ };
251
+ } | undefined;
252
+ readonly usage?: {
253
+ readonly type: "tokens";
254
+ readonly input?: number | undefined;
255
+ readonly output?: number | undefined;
256
+ readonly total?: number | undefined;
257
+ readonly details?: {
258
+ readonly [x: string]: unknown;
259
+ } | undefined;
260
+ } | {
261
+ readonly type: "seconds";
262
+ readonly seconds: number;
263
+ } | {
264
+ readonly type: "characters";
265
+ readonly characters: number;
266
+ } | {
267
+ readonly type: "credits";
268
+ readonly credits: number;
269
+ } | {
270
+ readonly type: "compute";
271
+ readonly seconds: number;
272
+ } | undefined;
273
+ readonly notices?: readonly {
274
+ readonly type: "other" | "moderated" | "filtered";
275
+ readonly message: string;
276
+ readonly providerMetadata?: {
277
+ readonly [x: string]: {
278
+ readonly [x: string]: unknown;
279
+ };
280
+ } | undefined;
281
+ }[] | undefined;
282
+ }>;
283
+ };
284
+ dispose: () => Promise<void>;
285
+ };
286
+ export type Client = ReturnType<typeof make>;
287
+ /** Default client over `RequestExecutor.fetchLayer` for scripts; the runtime builds its layer on first use. */
288
+ export declare const ai: {
289
+ run: <A, E>(effect: Effect.Effect<A, E, Services>, options?: RunOptions) => Promise<A>;
290
+ llm: {
291
+ request: <const SelectedLanguageModel extends LanguageModel>(input: RequestInput<SelectedLanguageModel>) => LLMRequest<SelectedLanguageModel>;
292
+ generate: <const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: RunOptions) => Promise<import("./index.js").LLMResponse>;
293
+ stream: <const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: RunOptions) => AsyncIterable<({
294
+ readonly type: "compaction";
295
+ readonly provider: string & import("effect/Brand").Brand<"AI.ProviderID">;
296
+ readonly id?: string | undefined;
297
+ readonly text?: string | null | undefined;
298
+ readonly encrypted?: string | undefined;
299
+ } & ({
300
+ readonly encrypted: string;
301
+ readonly text?: never;
302
+ } | {
303
+ readonly text: string | null;
304
+ readonly encrypted?: never;
305
+ })) | {
306
+ readonly type: "step-start";
307
+ readonly index: number;
308
+ } | {
309
+ readonly id: string;
310
+ readonly type: "text-start";
311
+ readonly providerMetadata?: {
312
+ readonly [x: string]: {
313
+ readonly [x: string]: unknown;
314
+ };
315
+ } | undefined;
316
+ } | {
317
+ readonly id: string;
318
+ readonly type: "text-delta";
319
+ readonly text: string;
320
+ readonly providerMetadata?: {
321
+ readonly [x: string]: {
322
+ readonly [x: string]: unknown;
323
+ };
324
+ } | undefined;
325
+ } | {
326
+ readonly id: string;
327
+ readonly type: "text-end";
328
+ readonly text?: string | undefined;
329
+ readonly providerMetadata?: {
330
+ readonly [x: string]: {
331
+ readonly [x: string]: unknown;
332
+ };
333
+ } | undefined;
334
+ } | {
335
+ readonly id: string;
336
+ readonly type: "reasoning-start";
337
+ readonly providerMetadata?: {
338
+ readonly [x: string]: {
339
+ readonly [x: string]: unknown;
340
+ };
341
+ } | undefined;
342
+ } | {
343
+ readonly id: string;
344
+ readonly type: "reasoning-delta";
345
+ readonly text: string;
346
+ readonly providerMetadata?: {
347
+ readonly [x: string]: {
348
+ readonly [x: string]: unknown;
349
+ };
350
+ } | undefined;
351
+ } | {
352
+ readonly id: string;
353
+ readonly type: "reasoning-end";
354
+ readonly text?: string | undefined;
355
+ readonly providerMetadata?: {
356
+ readonly [x: string]: {
357
+ readonly [x: string]: unknown;
358
+ };
359
+ } | undefined;
360
+ } | {
361
+ readonly id: string;
362
+ readonly type: "tool-input-start";
363
+ readonly name: string;
364
+ readonly providerMetadata?: {
365
+ readonly [x: string]: {
366
+ readonly [x: string]: unknown;
367
+ };
368
+ } | undefined;
369
+ readonly namespace?: string | undefined;
370
+ readonly providerExecuted?: boolean | undefined;
371
+ } | {
372
+ readonly id: string;
373
+ readonly type: "tool-input-delta";
374
+ readonly name: string;
375
+ readonly text: string;
376
+ readonly input?: unknown;
377
+ readonly namespace?: string | undefined;
378
+ } | {
379
+ readonly id: string;
380
+ readonly type: "tool-input-end";
381
+ readonly name: string;
382
+ readonly providerMetadata?: {
383
+ readonly [x: string]: {
384
+ readonly [x: string]: unknown;
385
+ };
386
+ } | undefined;
387
+ readonly namespace?: string | undefined;
388
+ } | {
389
+ readonly id: string;
390
+ readonly type: "tool-input-error";
391
+ readonly name: string;
392
+ readonly raw: string;
393
+ readonly namespace?: string | undefined;
394
+ } | {
395
+ readonly id: string;
396
+ readonly type: "tool-call";
397
+ readonly name: string;
398
+ readonly input: unknown;
399
+ readonly providerMetadata?: {
400
+ readonly [x: string]: {
401
+ readonly [x: string]: unknown;
402
+ };
403
+ } | undefined;
404
+ readonly namespace?: string | undefined;
405
+ readonly providerExecuted?: boolean | undefined;
406
+ } | {
407
+ readonly id: string;
408
+ readonly type: "tool-result";
409
+ readonly name: string;
410
+ readonly result: {
411
+ readonly type: "json";
412
+ readonly value: unknown;
413
+ } | {
414
+ readonly type: "text";
415
+ readonly value: unknown;
416
+ } | {
417
+ readonly type: "error";
418
+ readonly value: unknown;
419
+ } | {
420
+ readonly type: "content";
421
+ readonly value: readonly ({
422
+ readonly type: "text";
423
+ readonly text: string;
424
+ } | {
425
+ readonly type: "file";
426
+ readonly uri: string;
427
+ readonly mime: string;
428
+ readonly name?: string | undefined;
429
+ })[];
430
+ };
431
+ readonly output?: {
432
+ readonly structured: unknown;
433
+ readonly content: readonly ({
434
+ readonly type: "text";
435
+ readonly text: string;
436
+ } | {
437
+ readonly type: "file";
438
+ readonly uri: string;
439
+ readonly mime: string;
440
+ readonly name?: string | undefined;
441
+ })[];
442
+ } | undefined;
443
+ readonly providerMetadata?: {
444
+ readonly [x: string]: {
445
+ readonly [x: string]: unknown;
446
+ };
447
+ } | undefined;
448
+ readonly namespace?: string | undefined;
449
+ readonly providerExecuted?: boolean | undefined;
450
+ } | {
451
+ readonly id: string;
452
+ readonly type: "tool-error";
453
+ readonly name: string;
454
+ readonly message: string;
455
+ readonly error?: unknown;
456
+ readonly providerMetadata?: {
457
+ readonly [x: string]: {
458
+ readonly [x: string]: unknown;
459
+ };
460
+ } | undefined;
461
+ readonly namespace?: string | undefined;
462
+ } | {
463
+ readonly type: "media";
464
+ readonly media: import("./media.js").Asset;
465
+ readonly providerMetadata?: {
466
+ readonly [x: string]: {
467
+ readonly [x: string]: unknown;
468
+ };
469
+ } | undefined;
470
+ } | {
471
+ readonly type: "step-finish";
472
+ readonly reason: {
473
+ readonly normalized: "length" | "stop" | "tool-calls" | "content-filter" | "error" | "unknown";
474
+ readonly raw?: string | undefined;
475
+ };
476
+ readonly index: number;
477
+ readonly providerMetadata?: {
478
+ readonly [x: string]: {
479
+ readonly [x: string]: unknown;
480
+ };
481
+ } | undefined;
482
+ readonly usage?: import("./index.js").Usage | undefined;
483
+ } | {
484
+ readonly type: "finish";
485
+ readonly reason: {
486
+ readonly normalized: "length" | "stop" | "tool-calls" | "content-filter" | "error" | "unknown";
487
+ readonly raw?: string | undefined;
488
+ };
489
+ readonly providerMetadata?: {
490
+ readonly [x: string]: {
491
+ readonly [x: string]: unknown;
492
+ };
493
+ } | undefined;
494
+ readonly usage?: import("./index.js").Usage | undefined;
495
+ } | {
496
+ readonly type: "provider-error";
497
+ readonly message: string;
498
+ readonly classification?: "context-overflow" | "payload-too-large" | undefined;
499
+ readonly providerMetadata?: {
500
+ readonly [x: string]: {
501
+ readonly [x: string]: unknown;
502
+ };
503
+ } | undefined;
504
+ }>;
505
+ };
506
+ image: {
507
+ request: typeof import("./image.js").request;
508
+ generate: <const Model extends ImageModel>(input: ImageRequestInput<Model> | ImageRequest, options?: RunOptions) => Promise<import("./image.js").ImageResponse>;
509
+ stream: <const Model extends ImageModel>(input: ImageRequestInput<Model> | ImageRequest, options?: RunOptions) => AsyncIterable<{
510
+ readonly type: "image";
511
+ readonly index: number;
512
+ readonly image: import("./media.js").Asset;
513
+ } | {
514
+ readonly type: "finish";
515
+ readonly providerMetadata?: {
516
+ readonly [x: string]: {
517
+ readonly [x: string]: unknown;
518
+ };
519
+ } | undefined;
520
+ readonly usage?: {
521
+ readonly type: "tokens";
522
+ readonly input?: number | undefined;
523
+ readonly output?: number | undefined;
524
+ readonly total?: number | undefined;
525
+ readonly details?: {
526
+ readonly [x: string]: unknown;
527
+ } | undefined;
528
+ } | {
529
+ readonly type: "seconds";
530
+ readonly seconds: number;
531
+ } | {
532
+ readonly type: "characters";
533
+ readonly characters: number;
534
+ } | {
535
+ readonly type: "credits";
536
+ readonly credits: number;
537
+ } | {
538
+ readonly type: "compute";
539
+ readonly seconds: number;
540
+ } | undefined;
541
+ readonly notices?: readonly {
542
+ readonly type: "other" | "moderated" | "filtered";
543
+ readonly message: string;
544
+ readonly providerMetadata?: {
545
+ readonly [x: string]: {
546
+ readonly [x: string]: unknown;
547
+ };
548
+ } | undefined;
549
+ }[] | undefined;
550
+ }>;
551
+ };
552
+ dispose: () => Promise<void>;
553
+ };
554
+ export * as AI from "./promise.js";
@@ -0,0 +1,44 @@
1
+ import { Effect, Layer, ManagedRuntime, Stream } from "effect";
2
+ import { Image, ImageModel, ImageRequest } from "./image.js";
3
+ import { ImageClient } from "./image-client.js";
4
+ import { LLM } from "./index.js";
5
+ import { LLMClient } from "./route/client.js";
6
+ import { RequestExecutor } from "./route/executor.js";
7
+ import { LanguageModel, LLMRequest } from "./schema/index.js";
8
+ const abortEffect = (signal) => signal === undefined
9
+ ? Effect.never
10
+ : Effect.callback((resume) => {
11
+ if (signal.aborted) {
12
+ resume(Effect.void);
13
+ return;
14
+ }
15
+ const onAbort = () => resume(Effect.void);
16
+ signal.addEventListener("abort", onAbort, { once: true });
17
+ return Effect.sync(() => signal.removeEventListener("abort", onAbort));
18
+ });
19
+ export const make = (options = {}) => {
20
+ const runtime = ManagedRuntime.make(Layer.mergeAll(LLMClient.layer, ImageClient.layer).pipe(Layer.provideMerge(options.layer ?? RequestExecutor.fetchLayer)));
21
+ /** Run any package Effect (for example `asset.bytes()`) inside this runtime. */
22
+ const run = (effect, options) => runtime.runPromise(effect, { signal: options?.signal });
23
+ const iterate = (stream, options) => Stream.toAsyncIterable(Stream.unwrap(runtime.contextEffect.pipe(Effect.map((context) => stream.pipe(Stream.interruptWhen(abortEffect(options?.signal)), Stream.provideContext(context))))));
24
+ // The typed `generate`/`stream` overloads take a concrete input or a request, not the union; normalize once here.
25
+ const llmRequest = (input) => (input instanceof LLMRequest ? input : LLM.request(input));
26
+ const imageRequest = (input) => input instanceof ImageRequest ? input : Image.request(input);
27
+ return {
28
+ run,
29
+ llm: {
30
+ request: LLM.request,
31
+ generate: (input, options) => run(LLM.generate(llmRequest(input)), options),
32
+ stream: (input, options) => iterate(LLM.stream(llmRequest(input)), options),
33
+ },
34
+ image: {
35
+ request: Image.request,
36
+ generate: (input, options) => run(Image.generate(imageRequest(input)), options),
37
+ stream: (input, options) => iterate(Image.stream(imageRequest(input)), options),
38
+ },
39
+ dispose: () => runtime.dispose(),
40
+ };
41
+ };
42
+ /** Default client over `RequestExecutor.fetchLayer` for scripts; the runtime builds its layer on first use. */
43
+ export const ai = make();
44
+ export * as AI from "./promise.js";
@@ -537,7 +537,7 @@ const citationsFromMetadata = (metadata) => {
537
537
  };
538
538
  const isHttpUrl = (value) => /^https?:\/\//i.test(value.trim());
539
539
  const lowerMedia = Effect.fn("AnthropicMessages.lowerMedia")(function* (part, breakpoints) {
540
- const mime = part.mediaType.toLowerCase();
540
+ const mime = part.media.mediaType.toLowerCase();
541
541
  const cacheControlValue = breakpoints ? cacheControl(breakpoints, part.cache) : undefined;
542
542
  const fileId = fileIdFromMetadata(part.metadata);
543
543
  // SDK file sources: FileImageSource:2350 / FileDocumentSource:2344 {type:"file", file_id}
@@ -564,9 +564,9 @@ const lowerMedia = Effect.fn("AnthropicMessages.lowerMedia")(function* (part, br
564
564
  : { citations: citationsFromMetadata(part.metadata) }),
565
565
  };
566
566
  }
567
- const rawString = typeof part.data === "string" ? part.data.trim() : undefined;
567
+ const rawString = ProviderShared.mediaUrl(part.media)?.trim();
568
568
  // SDK URL sources: URLImageSource:3817 / URLPDFSource:3823 {type:"url", url}
569
- if (rawString && isHttpUrl(rawString) && !rawString.startsWith("data:")) {
569
+ if (rawString && isHttpUrl(rawString)) {
570
570
  if (mime.startsWith("image/"))
571
571
  return {
572
572
  type: "image",
@@ -590,19 +590,10 @@ const lowerMedia = Effect.fn("AnthropicMessages.lowerMedia")(function* (part, br
590
590
  : { citations: citationsFromMetadata(part.metadata) }),
591
591
  };
592
592
  }
593
+ const media = yield* ProviderShared.requireInlineMedia("Anthropic Messages", part.media);
593
594
  // SDK PlainTextSource:2716 {type:"text", media_type:"text/plain", data}
594
595
  if (mime === "text/plain") {
595
- const textData = typeof part.data !== "string"
596
- ? Buffer.from(part.data).toString("utf8")
597
- : part.data.startsWith("data:")
598
- ? (() => {
599
- const comma = part.data.indexOf(",");
600
- const payload = comma >= 0 ? part.data.slice(comma + 1) : part.data;
601
- return part.data.includes(";base64")
602
- ? Buffer.from(payload, "base64").toString("utf8")
603
- : decodeURIComponent(payload);
604
- })()
605
- : part.data;
596
+ const textData = Buffer.from(media.base64, "base64").toString("utf8");
606
597
  return {
607
598
  type: "document",
608
599
  source: { type: "text", media_type: "text/plain", data: textData },
@@ -616,7 +607,6 @@ const lowerMedia = Effect.fn("AnthropicMessages.lowerMedia")(function* (part, br
616
607
  : { citations: citationsFromMetadata(part.metadata) }),
617
608
  };
618
609
  }
619
- const media = ProviderShared.normalizeMedia(part);
620
610
  if (media.mime === "application/pdf")
621
611
  return {
622
612
  type: "document",
@@ -635,7 +625,7 @@ const lowerMedia = Effect.fn("AnthropicMessages.lowerMedia")(function* (part, br
635
625
  : { citations: citationsFromMetadata(part.metadata) }),
636
626
  };
637
627
  if (!media.mime.startsWith("image/"))
638
- return yield* invalid(`Anthropic Messages does not support media type ${part.mediaType}`);
628
+ return yield* invalid(`Anthropic Messages does not support media type ${part.media.mediaType}`);
639
629
  return {
640
630
  type: "image",
641
631
  source: {
@@ -654,7 +644,7 @@ const lowerMedia = Effect.fn("AnthropicMessages.lowerMedia")(function* (part, br
654
644
  const lowerToolResultContentItem = Effect.fnUntraced(function* (item) {
655
645
  if (item.type === "text")
656
646
  return { type: "text", text: item.text };
657
- return yield* lowerMedia({ type: "media", mediaType: item.mime, data: item.uri, filename: item.name });
647
+ return yield* lowerMedia(ProviderShared.toolFileMedia(item));
658
648
  });
659
649
  const lowerToolResultContent = Effect.fnUntraced(function* (part) {
660
650
  // Text / json / error results stay as a string for backward compatibility