@opencode/ai 2.1.2 → 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 (87) 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 +21 -13
  6. package/dist/experimental.d.ts +1 -1
  7. package/dist/generation.js +1 -1
  8. package/dist/image-client.d.ts +3 -1
  9. package/dist/image.d.ts +10 -2
  10. package/dist/image.js +2 -2
  11. package/dist/llm.d.ts +2 -4
  12. package/dist/llm.js +2 -2
  13. package/dist/media-model.d.ts +2 -2
  14. package/dist/media-model.js +1 -1
  15. package/dist/promise.d.ts +1 -1
  16. package/dist/promise.js +3 -5
  17. package/dist/protocols/alibaba-chat.d.ts +6 -6
  18. package/dist/protocols/alibaba-chat.js +3 -3
  19. package/dist/protocols/alibaba-messages.d.ts +1 -1
  20. package/dist/protocols/alibaba-messages.js +1 -1
  21. package/dist/protocols/alibaba-responses.d.ts +3 -3
  22. package/dist/protocols/anthropic-messages.js +10 -12
  23. package/dist/protocols/bedrock-converse.d.ts +6 -53
  24. package/dist/protocols/bedrock-converse.js +4 -3
  25. package/dist/protocols/bedrock-event-stream.d.ts +6 -1
  26. package/dist/protocols/bedrock-event-stream.js +9 -8
  27. package/dist/protocols/cohere-chat.d.ts +6 -2
  28. package/dist/protocols/cohere-chat.js +2 -2
  29. package/dist/protocols/gemini.d.ts +12 -2
  30. package/dist/protocols/gemini.js +10 -13
  31. package/dist/protocols/google-interactions.d.ts +2 -1
  32. package/dist/protocols/google-interactions.js +14 -9
  33. package/dist/protocols/meta-responses.d.ts +6 -6
  34. package/dist/protocols/mistral-chat.js +1 -4
  35. package/dist/protocols/open-responses.d.ts +21 -21
  36. package/dist/protocols/open-responses.js +3 -3
  37. package/dist/protocols/openai-chat.d.ts +8 -7
  38. package/dist/protocols/openai-chat.js +4 -5
  39. package/dist/protocols/openai-compatible-responses.d.ts +3 -3
  40. package/dist/protocols/openai-responses.d.ts +18 -18
  41. package/dist/protocols/utils/open-responses-options.d.ts +8 -8
  42. package/dist/protocols/utils/open-responses-options.js +4 -6
  43. package/dist/protocols/utils/partial-json.js +5 -4
  44. package/dist/protocols/utils/tool-schema.d.ts +0 -3
  45. package/dist/protocols/utils/tool-schema.js +0 -4
  46. package/dist/protocols/xai-images.js +3 -4
  47. package/dist/protocols/xai-responses.d.ts +3 -3
  48. package/dist/provider-error.js +3 -4
  49. package/dist/providers/alibaba.d.ts +30 -30
  50. package/dist/providers/amazon-bedrock-mantle.d.ts +3 -3
  51. package/dist/providers/amazon-bedrock.d.ts +11 -8
  52. package/dist/providers/azure.d.ts +6 -6
  53. package/dist/providers/cloudflare-ai-gateway.d.ts +7 -7
  54. package/dist/providers/cloudflare-ai-gateway.js +2 -4
  55. package/dist/providers/cohere.d.ts +6 -2
  56. package/dist/providers/google-vertex-interactions.d.ts +3 -3
  57. package/dist/providers/google-vertex-messages.d.ts +18 -18
  58. package/dist/providers/google-vertex-mistral.d.ts +3 -3
  59. package/dist/providers/google-vertex-responses.d.ts +3 -3
  60. package/dist/providers/google.d.ts +66 -66
  61. package/dist/providers/meta.d.ts +21 -21
  62. package/dist/providers/minimax.d.ts +195 -195
  63. package/dist/providers/moonshot.d.ts +3 -3
  64. package/dist/providers/openai-compatible-responses.d.ts +3 -3
  65. package/dist/providers/openai-options.d.ts +3 -3
  66. package/dist/providers/openai.d.ts +3 -3
  67. package/dist/providers/openrouter.d.ts +135 -76
  68. package/dist/providers/openrouter.js +40 -33
  69. package/dist/providers/zai-coding-plan.d.ts +3 -3
  70. package/dist/route/client.d.ts +0 -216
  71. package/dist/route/client.js +0 -3
  72. package/dist/route/transport/http.js +5 -8
  73. package/dist/schema/errors.d.ts +1 -1
  74. package/dist/schema/errors.js +1 -1
  75. package/dist/schema/messages.js +4 -7
  76. package/dist/speech-client.d.ts +3 -1
  77. package/dist/speech.d.ts +10 -2
  78. package/dist/speech.js +2 -2
  79. package/dist/transcription-client.d.ts +3 -1
  80. package/dist/transcription.d.ts +10 -2
  81. package/dist/transcription.js +2 -2
  82. package/dist/video-client.d.ts +3 -1
  83. package/dist/video.d.ts +10 -2
  84. package/dist/video.js +2 -2
  85. package/package.json +4 -4
  86. package/dist/protocols/utils/openai-options.d.ts +0 -16
  87. package/dist/protocols/utils/openai-options.js +0 -15
@@ -94,8 +94,9 @@ const markSystemBoundaries = (system, hint, budget) => {
94
94
  return changed ? next : system;
95
95
  };
96
96
  const lastIndexOfRole = (messages, role) => messages.findLastIndex((m) => m.role === role);
97
+ const isCacheablePart = (part) => part.type !== "compaction" && part.type !== "effort";
97
98
  // Mark the last text part of `messages[index]`. If no text part exists, mark
98
- // the last content part regardless of type — that's the breakpoint position
99
+ // the last cacheable content part — that's the breakpoint position
99
100
  // in tool-result-only messages too.
100
101
  const markMessageAt = (messages, index, hint, budget) => {
101
102
  if (index < 0 || index >= messages.length)
@@ -104,12 +105,12 @@ const markMessageAt = (messages, index, hint, budget) => {
104
105
  if (target.content.length === 0)
105
106
  return messages;
106
107
  const lastTextIndex = target.content.findLastIndex((part) => part.type === "text");
107
- const markAt = lastTextIndex >= 0 ? lastTextIndex : target.content.length - 1;
108
+ const markAt = lastTextIndex >= 0 ? lastTextIndex : target.content.findLastIndex(isCacheablePart);
108
109
  const existing = target.content[markAt];
109
- if (("cache" in existing && existing.cache) || budget.remaining === 0)
110
+ if (!existing || !isCacheablePart(existing) || existing.cache || budget.remaining === 0)
110
111
  return messages;
111
112
  budget.remaining -= 1;
112
- const nextContent = target.content.map((part, i) => (i === markAt ? { ...part, cache: hint } : part));
113
+ const nextContent = target.content.map((part, i) => (i === markAt ? { ...existing, cache: hint } : part));
113
114
  const next = new Message({ ...target, content: nextContent });
114
115
  // Single pass over `messages`, substituting the one updated entry. Long
115
116
  // conversations call this on every request, so avoid `.map()` here — its
@@ -141,7 +142,7 @@ const markMessages = (messages, strategy, hint, budget) => {
141
142
  const countHints = (request) => countToolHints(request.tools) +
142
143
  request.system.reduce((count, part) => count + (part.cache === undefined ? 0 : 1), 0) +
143
144
  request.messages.reduce((count, message) => count +
144
- message.content.reduce((contentCount, part) => contentCount + ("cache" in part && part.cache !== undefined ? 1 : 0), 0), 0);
145
+ message.content.reduce((contentCount, part) => contentCount + (isCacheablePart(part) && part.cache !== undefined ? 1 : 0), 0), 0);
145
146
  export const applyCachePolicy = (request) => {
146
147
  const policy = selectPolicy(request);
147
148
  if (!policy.tools && !policy.system && !policy.messages)
@@ -101,10 +101,10 @@ export type AnswersFor<Questions extends EvaluationQuestions> = {
101
101
  export type EvaluationOptions = Record<string, unknown>;
102
102
  export interface EvaluationRoute<Options extends EvaluationOptions = EvaluationOptions> {
103
103
  readonly id: string;
104
- readonly evaluate: (request: EvaluationRequestFor<Options>, execute: Execute) => Effect.Effect<EvaluationResponse, AIError>;
104
+ evaluate(request: EvaluationRequestFor<Options>, execute: Execute): Effect.Effect<EvaluationResponse, AIError>;
105
105
  }
106
106
  export declare class EvaluationModel<Options extends EvaluationOptions = EvaluationOptions> {
107
- protected readonly _Options: (options: Options) => Options;
107
+ protected readonly _Options: Options;
108
108
  readonly id: ModelID;
109
109
  readonly provider: ProviderID;
110
110
  readonly route: EvaluationRoute<Options>;
@@ -193,12 +193,12 @@ export type EvaluationRequestFor<Options extends EvaluationOptions = EvaluationO
193
193
  readonly questions: Questions;
194
194
  readonly options?: Options;
195
195
  };
196
- export type EvaluationRequestInput<Model extends object = EvaluationModel, Questions extends EvaluationQuestions = EvaluationQuestions> = Omit<ConstructorParameters<typeof EvaluationRequest>[0], "model" | "questions" | "options" | "http"> & {
196
+ export type EvaluationRequestInput<Model extends EvaluationModel = EvaluationModel, Questions extends EvaluationQuestions = EvaluationQuestions> = Omit<ConstructorParameters<typeof EvaluationRequest>[0], "model" | "questions" | "options" | "http"> & {
197
197
  readonly model: Model;
198
198
  readonly questions: Questions;
199
199
  readonly options?: NoInfer<EvaluationModelOptions<Model>>;
200
200
  readonly http?: HttpOptions.Input;
201
- } & (Model extends EvaluationModel<EvaluationModelOptions<Model>> ? unknown : never);
201
+ };
202
202
  declare const EvaluationRounding_base: Schema.Class<EvaluationRounding, Schema.Struct<{
203
203
  readonly probabilityDecimals: Schema.optional<Schema.Int>;
204
204
  readonly scoreDecimals: Schema.optional<Schema.Int>;
@@ -230,9 +230,10 @@ export declare class EvaluationResponse extends EvaluationResponse_base {
230
230
  export type EvaluationResponseFor<Questions extends EvaluationQuestions> = Omit<EvaluationResponse, "answers"> & {
231
231
  readonly answers: AnswersFor<Questions>;
232
232
  };
233
- export declare function request<const Model extends object, const Questions extends EvaluationQuestions>(input: EvaluationRequestInput<Model, Questions>): EvaluationRequestFor<EvaluationModelOptions<Model>, Questions>;
233
+ export declare function request<const Model extends EvaluationModel, const Questions extends EvaluationQuestions>(input: EvaluationRequestInput<Model, Questions>): EvaluationRequestFor<EvaluationModelOptions<Model>, Questions>;
234
234
  export declare function request(input: EvaluationRequest): EvaluationRequest;
235
- export declare function run<const Model extends object, const Questions extends EvaluationQuestions>(input: EvaluationRequestInput<Model, Questions>): Effect.Effect<EvaluationResponseFor<Questions>, AIError, Service>;
235
+ export declare function request(input: EvaluationRequest | EvaluationRequestInput): EvaluationRequest;
236
+ export declare function run<const Model extends EvaluationModel, const Questions extends EvaluationQuestions>(input: EvaluationRequestInput<Model, Questions>): Effect.Effect<EvaluationResponseFor<Questions>, AIError, Service>;
236
237
  export declare function run(input: EvaluationRequest): Effect.Effect<EvaluationResponse, AIError, Service>;
237
238
  export declare const Evaluation: {
238
239
  readonly request: typeof request;
@@ -95,20 +95,19 @@ export function request(input) {
95
95
  return input;
96
96
  return new EvaluationRequest({
97
97
  ...input,
98
- model: input.model,
99
98
  http: HttpOptions.make(input.http),
100
99
  });
101
100
  }
102
101
  export function run(input) {
103
102
  return Effect.try({
104
- try: () => (input instanceof EvaluationRequest ? input : request(input)),
103
+ try: () => request(input),
105
104
  catch: (cause) => new AIError({
106
105
  reason: new InvalidRequestError({
107
106
  message: cause instanceof Error ? cause.message : String(cause),
108
107
  cause,
109
108
  }),
110
109
  }),
111
- }).pipe(Effect.flatMap((request) => EvaluationClient.evaluate(request)));
110
+ }).pipe(Effect.flatMap(EvaluationClient.evaluate));
112
111
  }
113
112
  export const Evaluation = {
114
113
  request,
@@ -7,6 +7,7 @@ export type RealtimeTransportInput = {
7
7
  } | {
8
8
  readonly type: "websocket";
9
9
  };
10
+ export type RealtimeTransportType = RealtimeTransportInput["type"];
10
11
  export type RealtimeTransport = {
11
12
  readonly type: "webrtc";
12
13
  readonly sdp: string;
@@ -23,25 +24,83 @@ export interface RealtimeConnectInput {
23
24
  readonly session?: RealtimeSession;
24
25
  readonly transport: RealtimeTransportInput;
25
26
  }
27
+ export declare const engines: readonly [{
28
+ readonly family: "gpt-live";
29
+ readonly model: "gpt-live-1";
30
+ readonly id: "openai-live";
31
+ readonly provider: "openai";
32
+ readonly transports: readonly ["webrtc"];
33
+ }, {
34
+ readonly family: "gpt-realtime";
35
+ readonly model: "gpt-realtime-2.1";
36
+ readonly id: "openai-realtime";
37
+ readonly provider: "openai";
38
+ readonly transports: readonly ["webrtc", "websocket"];
39
+ }, {
40
+ readonly family: "grok-voice";
41
+ readonly model: "grok-voice-3.0";
42
+ readonly id: "xai-realtime";
43
+ readonly provider: "xai";
44
+ readonly transports: readonly ["websocket"];
45
+ }, {
46
+ readonly family: "gemini-3.8-live";
47
+ readonly model: "gemini-3.8-live";
48
+ readonly id: "gemini-live";
49
+ readonly provider: "google";
50
+ readonly transports: readonly ["websocket"];
51
+ }];
26
52
  export declare const engine: (model: string) => {
27
53
  readonly family: "gpt-live";
54
+ readonly model: "gpt-live-1";
28
55
  readonly id: "openai-live";
29
56
  readonly provider: "openai";
57
+ readonly transports: readonly ["webrtc"];
30
58
  } | {
31
59
  readonly family: "gpt-realtime";
60
+ readonly model: "gpt-realtime-2.1";
32
61
  readonly id: "openai-realtime";
33
62
  readonly provider: "openai";
63
+ readonly transports: readonly ["webrtc", "websocket"];
34
64
  } | {
35
65
  readonly family: "grok-voice";
66
+ readonly model: "grok-voice-3.0";
36
67
  readonly id: "xai-realtime";
37
68
  readonly provider: "xai";
69
+ readonly transports: readonly ["websocket"];
38
70
  } | {
39
71
  readonly family: "gemini-3.8-live";
72
+ readonly model: "gemini-3.8-live";
40
73
  readonly id: "gemini-live";
41
74
  readonly provider: "google";
75
+ readonly transports: readonly ["websocket"];
42
76
  } | undefined;
43
77
  export declare const connect: (input: RealtimeConnectInput) => Effect.Effect<RealtimeTransport, AIError, import("../route/executor-service.js").RequestExecutorService>;
44
78
  export declare const Realtime: {
79
+ readonly engines: readonly [{
80
+ readonly family: "gpt-live";
81
+ readonly model: "gpt-live-1";
82
+ readonly id: "openai-live";
83
+ readonly provider: "openai";
84
+ readonly transports: readonly ["webrtc"];
85
+ }, {
86
+ readonly family: "gpt-realtime";
87
+ readonly model: "gpt-realtime-2.1";
88
+ readonly id: "openai-realtime";
89
+ readonly provider: "openai";
90
+ readonly transports: readonly ["webrtc", "websocket"];
91
+ }, {
92
+ readonly family: "grok-voice";
93
+ readonly model: "grok-voice-3.0";
94
+ readonly id: "xai-realtime";
95
+ readonly provider: "xai";
96
+ readonly transports: readonly ["websocket"];
97
+ }, {
98
+ readonly family: "gemini-3.8-live";
99
+ readonly model: "gemini-3.8-live";
100
+ readonly id: "gemini-live";
101
+ readonly provider: "google";
102
+ readonly transports: readonly ["websocket"];
103
+ }];
45
104
  readonly engine: typeof engine;
46
105
  readonly connect: (input: RealtimeConnectInput) => Effect.Effect<RealtimeTransport, AIError, import("../route/executor-service.js").RequestExecutorService>;
47
106
  };
@@ -6,11 +6,23 @@ import { encodeJson } from "../utils/json.js";
6
6
  const OPENAI_BASE_URL = "https://api.openai.com/v1";
7
7
  const XAI_BASE_URL = "https://api.x.ai/v1";
8
8
  const GOOGLE_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
9
- const engines = [
10
- { family: "gpt-live", id: "openai-live", provider: "openai" },
11
- { family: "gpt-realtime", id: "openai-realtime", provider: "openai" },
12
- { family: "grok-voice", id: "xai-realtime", provider: "xai" },
13
- { family: "gemini-3.8-live", id: "gemini-live", provider: "google" },
9
+ export const engines = [
10
+ { family: "gpt-live", model: "gpt-live-1", id: "openai-live", provider: "openai", transports: ["webrtc"] },
11
+ {
12
+ family: "gpt-realtime",
13
+ model: "gpt-realtime-2.1",
14
+ id: "openai-realtime",
15
+ provider: "openai",
16
+ transports: ["webrtc", "websocket"],
17
+ },
18
+ { family: "grok-voice", model: "grok-voice-3.0", id: "xai-realtime", provider: "xai", transports: ["websocket"] },
19
+ {
20
+ family: "gemini-3.8-live",
21
+ model: "gemini-3.8-live",
22
+ id: "gemini-live",
23
+ provider: "google",
24
+ transports: ["websocket"],
25
+ },
14
26
  ];
15
27
  // Matches the bare family name (`gpt-realtime`) and its versions (`gpt-realtime-2.1`, `gpt-realtime-mini`).
16
28
  export const engine = (model) => engines.find((item) => model === item.family || model.startsWith(`${item.family}-`));
@@ -18,11 +30,11 @@ export const connect = Effect.fn("Realtime.connect")(function* (input) {
18
30
  const resolved = engine(input.model);
19
31
  if (!resolved)
20
32
  return yield* invalidRequest(`Unsupported voice model: ${input.model}`);
33
+ if (!resolved.transports.some((type) => type === input.transport.type))
34
+ return yield* invalidRequest(`${input.model} only supports ${resolved.transports.join(", ")} transport`);
21
35
  const session = { ...input.session, model: input.model };
22
36
  switch (resolved.id) {
23
37
  case "openai-live": {
24
- if (input.transport.type !== "webrtc")
25
- return yield* invalidRequest("OpenAI GPT-Live only supports WebRTC transport");
26
38
  const data = yield* post(resolved.id, `${OPENAI_BASE_URL}/live/sessions`, input.apiKey, { session, transport: input.transport }, LiveSessionResponse);
27
39
  return { type: "webrtc", sdp: data.transport.sdp };
28
40
  }
@@ -39,16 +51,11 @@ export const connect = Effect.fn("Realtime.connect")(function* (input) {
39
51
  const sdp = yield* post(resolved.id, `${OPENAI_BASE_URL}/realtime/calls${query}`, input.apiKey, form, Schema.String);
40
52
  return { type: "webrtc", sdp };
41
53
  }
42
- case "xai-realtime": {
43
- if (input.transport.type !== "websocket")
44
- return yield* invalidRequest("xAI Grok Voice only supports WebSocket transport");
54
+ case "xai-realtime":
45
55
  return yield* clientSecret(resolved.id, XAI_BASE_URL, input.model, input.apiKey, {
46
56
  expires_after: { seconds: 60 },
47
57
  });
48
- }
49
58
  case "gemini-live": {
50
- if (input.transport.type !== "websocket")
51
- return yield* invalidRequest("Google Gemini Live only supports WebSocket transport");
52
59
  const now = yield* Clock.currentTimeMillis;
53
60
  const expiresAt = now + 60_000;
54
61
  const data = yield* post(resolved.id, `${GOOGLE_BASE_URL}/auth_tokens`, input.apiKey, {
@@ -67,6 +74,7 @@ export const connect = Effect.fn("Realtime.connect")(function* (input) {
67
74
  }
68
75
  });
69
76
  export const Realtime = {
77
+ engines,
70
78
  engine,
71
79
  connect,
72
80
  };
@@ -2,4 +2,4 @@ export { EvaluationClient } from "./experimental/evaluation-client.js";
2
2
  export { BooleanAnswer, BooleanQuestion, ChoiceAnswer, ChoiceQuestion, Evaluation, EvaluationAnswer, EvaluationInput, EvaluationModel, EvaluationModelSchema, EvaluationQuestion, EvaluationRequest, EvaluationResponse, EvaluationRounding, ScoreAnswer, ScoreQuestion, } from "./experimental/evaluation.js";
3
3
  export type { AnswerFor, AnswersFor, EvaluationModelOptions, EvaluationOptions, EvaluationQuestions, EvaluationRequestFor, EvaluationRequestInput, EvaluationResponseFor, EvaluationRoute, } from "./experimental/evaluation.js";
4
4
  export { Realtime } from "./experimental/realtime.js";
5
- export type { RealtimeConnectInput, RealtimeSession, RealtimeTransport, RealtimeTransportInput, } from "./experimental/realtime.js";
5
+ export type { RealtimeConnectInput, RealtimeSession, RealtimeTransport, RealtimeTransportInput, RealtimeTransportType, } from "./experimental/realtime.js";
@@ -110,6 +110,6 @@ const within = (effect, id, timeout, deadline) => Clock.currentTimeMillis.pipe(E
110
110
  const timeoutError = (id, timeout) => new AIError({
111
111
  reason: new TimeoutError({
112
112
  message: `Generation ${id} did not finish within ${Duration.format(timeout)}`,
113
- timeoutMs: Duration.toMillis(timeout),
113
+ timeoutMs: Math.min(Number.MAX_SAFE_INTEGER, Math.max(0, Math.ceil(Duration.toMillis(timeout)))),
114
114
  }),
115
115
  });
@@ -57,7 +57,9 @@ export declare const ImageClient: {
57
57
  } | undefined;
58
58
  } | import("./generation.js").Observation, import("./index.js").AIError, ImageClientService>;
59
59
  readonly start: (request: ImageRequestFor) => import("effect/Effect").Effect<import("./generation.js").Generation<ImageResponse>, import("./index.js").AIError, ImageClientService>;
60
- readonly resume: (model: import("./image.js").ImageModel<import("./media-model.js").MediaModel.Options>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<ImageResponse>, import("./index.js").AIError, ImageClientService>;
60
+ readonly resume: (model: import("./image.js").ImageModel<{
61
+ readonly [x: string]: unknown;
62
+ }>, token: unknown) => import("effect/Effect").Effect<import("./generation.js").Generation<ImageResponse>, import("./index.js").AIError, ImageClientService>;
61
63
  readonly Service: typeof ImageClientService;
62
64
  };
63
65
  export {};
package/dist/image.d.ts CHANGED
@@ -14,14 +14,22 @@ export declare class ImageModel<Options extends ImageOptions = ImageOptions> ext
14
14
  static fromRoute<Options extends ImageOptions, Frame, State>(route: MediaModel.StreamRouteInput<ImageRequestFor<Options>, ImageEvent, Frame, State>, input: MediaRoute.ModelInput): ImageModel<Options>;
15
15
  static fromRoute<Options extends ImageOptions, Token>(route: MediaModel.QueuedRouteInput<ImageRequestFor<Options>, ImageResponse, Token>, input: MediaRoute.ModelInput): ImageModel<Options>;
16
16
  }
17
- export declare const ImageModelSchema: Schema.declare<ImageModel<MediaModel.Options>, ImageModel<MediaModel.Options>>;
17
+ export declare const ImageModelSchema: Schema.declare<ImageModel<{
18
+ readonly [x: string]: unknown;
19
+ }>, ImageModel<{
20
+ readonly [x: string]: unknown;
21
+ }>>;
18
22
  export type ImageSize = `${number}x${number}`;
19
23
  export declare const ImageSize: Schema.declare<`${number}x${number}`, `${number}x${number}`>;
20
24
  export type ImageAspectRatio = Media.AspectRatio;
21
25
  export declare const ImageAspectRatio: Schema.declare<`${number}:${number}`, `${number}:${number}`>;
22
26
  export type ImageFormat = OpenString<"png" | "jpeg" | "webp">;
23
27
  declare const ImageRequest_base: Schema.Class<ImageRequest, Schema.Struct<{
24
- readonly model: Schema.declare<ImageModel<MediaModel.Options>, ImageModel<MediaModel.Options>>;
28
+ readonly model: Schema.declare<ImageModel<{
29
+ readonly [x: string]: unknown;
30
+ }>, ImageModel<{
31
+ readonly [x: string]: unknown;
32
+ }>>;
25
33
  readonly prompt: Schema.String;
26
34
  /** Edit sources or style/subject references, in order. */
27
35
  readonly images: Schema.optional<Schema.$Array<Schema.decodeTo<Schema.declare<Media.Asset, Media.Asset>, Schema.Struct<{
package/dist/image.js CHANGED
@@ -3,7 +3,7 @@ import { Generation, ProgressEvent, QueuedEvent } from "./generation.js";
3
3
  import { Media } from "./media.js";
4
4
  import { MediaModel, composeRoute, tryRequest } from "./media-model.js";
5
5
  import { MediaRoute } from "./route/media.js";
6
- import { AIError, HttpOptions, MediaUsage, ProviderMetadata } from "./schema/index.js";
6
+ import { AIError, HttpOptions, MediaUsage, ProviderMetadata, ProviderOptions, } from "./schema/index.js";
7
7
  import { ImageClient, Service } from "./image-client.js";
8
8
  export class ImageModel extends MediaModel {
9
9
  static fromRoute(route, input) {
@@ -32,7 +32,7 @@ export class ImageRequest extends Schema.Class("Image.Request")({
32
32
  aspectRatio: Schema.optional(ImageAspectRatio),
33
33
  seed: Schema.optional(Schema.Number),
34
34
  format: Schema.optional(Schema.String),
35
- providerOptions: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
35
+ providerOptions: Schema.optional(ProviderOptions),
36
36
  http: Schema.optional(HttpOptions),
37
37
  }) {
38
38
  }
package/dist/llm.d.ts CHANGED
@@ -14,10 +14,8 @@ export type RequestInput<SelectedLanguageModel extends LanguageModel = LanguageM
14
14
  readonly providerOptions?: NoInfer<LanguageModelProviderOptions<SelectedLanguageModel>>;
15
15
  readonly http?: HttpOptions.Input;
16
16
  };
17
- export declare function generate<const Model extends LanguageModel>(input: RequestInput<Model>, options?: StreamOptions): Effect.Effect<LLMResponse, AIError, Service>;
18
- export declare function generate(input: LLMRequest, options?: StreamOptions): Effect.Effect<LLMResponse, AIError, Service>;
19
- export declare function stream<const Model extends LanguageModel>(input: RequestInput<Model>, options?: StreamOptions): Stream.Stream<LLMEvent, AIError, Service>;
20
- export declare function stream(input: LLMRequest, options?: StreamOptions): Stream.Stream<LLMEvent, AIError, Service>;
17
+ export declare function generate<const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: StreamOptions): Effect.Effect<LLMResponse, AIError, Service>;
18
+ export declare function stream<const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: StreamOptions): Stream.Stream<LLMEvent, AIError, Service>;
21
19
  export declare const request: <const SelectedLanguageModel extends LanguageModel>(input: RequestInput<SelectedLanguageModel>) => LLMRequest<SelectedLanguageModel>;
22
20
  type GenerateObjectBase<SelectedLanguageModel extends LanguageModel = LanguageModel> = Omit<RequestInput<SelectedLanguageModel>, "tools" | "toolChoice">;
23
21
  export declare class GenerateObjectResponse<T> {
package/dist/llm.js CHANGED
@@ -46,8 +46,8 @@ const runGenerateObject = Effect.fn("LLM.generateObject")(function* (options, to
46
46
  toolChoice: ToolChoice.named(GENERATE_OBJECT_TOOL_NAME),
47
47
  });
48
48
  const response = yield* LLMClient.generate(generateRequest);
49
- const call = response.toolCalls.find((event) => LLMEvent.is.toolCall(event) && event.name === GENERATE_OBJECT_TOOL_NAME);
50
- if (!call || !LLMEvent.is.toolCall(call))
49
+ const call = response.toolCalls.find((event) => event.name === GENERATE_OBJECT_TOOL_NAME);
50
+ if (!call)
51
51
  return yield* new AIError({
52
52
  reason: new InvalidProviderOutputError({
53
53
  message: `generateObject: model did not call the forced \`${GENERATE_OBJECT_TOOL_NAME}\` tool`,
@@ -2,7 +2,7 @@ import { Effect } from "effect";
2
2
  import { Endpoint } from "./route/endpoint.js";
3
3
  import { MediaRoute } from "./route/media.js";
4
4
  import type { MediaProtocol } from "./route/media-protocol.js";
5
- import { AIError, HttpOptions, ModelID, ProviderID } from "./schema/index.js";
5
+ import { AIError, HttpOptions, ModelID, ProviderID, type ProviderOptions } from "./schema/index.js";
6
6
  /**
7
7
  * What every media model carries: ids, the configured route, and deployment `http` overlays. Modality classes
8
8
  * (`ImageModel`, `VideoModel`, `SpeechModel`, `TranscriptionModel`) extend it with their route type and a nominal
@@ -17,7 +17,7 @@ export declare class MediaModel<Route, Options> {
17
17
  constructor(input: MediaModel.Input<Route>);
18
18
  }
19
19
  export declare namespace MediaModel {
20
- type Options = Record<string, unknown>;
20
+ type Options = ProviderOptions;
21
21
  interface Input<Route> {
22
22
  readonly id: string | ModelID;
23
23
  readonly provider: string | ProviderID;
@@ -1,7 +1,7 @@
1
1
  import { Effect } from "effect";
2
2
  import { Endpoint } from "./route/endpoint.js";
3
3
  import { MediaRoute } from "./route/media.js";
4
- import { AIError, HttpOptions, InvalidRequestError, ModelID, ProviderID } from "./schema/index.js";
4
+ import { AIError, HttpOptions, InvalidRequestError, ModelID, ProviderID, } from "./schema/index.js";
5
5
  /**
6
6
  * What every media model carries: ids, the configured route, and deployment `http` overlays. Modality classes
7
7
  * (`ImageModel`, `VideoModel`, `SpeechModel`, `TranscriptionModel`) extend it with their route type and a nominal
package/dist/promise.d.ts CHANGED
@@ -5,7 +5,7 @@ import { type ImageModel, type ImageRequest, type ImageRequestInput } from "./im
5
5
  import { LLM } from "./index.js";
6
6
  import { Media } from "./media.js";
7
7
  import { RequestExecutor } from "./route/executor.js";
8
- import { LanguageModel, LLMRequest } from "./schema/index.js";
8
+ import { LanguageModel, type LLMRequest } from "./schema/index.js";
9
9
  import type { RequestInput } from "./llm.js";
10
10
  import { type SpeechModel, type SpeechRequest, type SpeechRequestInput } from "./speech.js";
11
11
  import { type TranscriptionModel, type TranscriptionRequest, type TranscriptionRequestInput } from "./transcription.js";
package/dist/promise.js CHANGED
@@ -3,9 +3,8 @@ import { AIClient } from "./ai-client.js";
3
3
  import { Image } from "./image.js";
4
4
  import { LLM } from "./index.js";
5
5
  import { Media } from "./media.js";
6
- import { tryRequest } from "./media-model.js";
7
6
  import { RequestExecutor } from "./route/executor.js";
8
- import { AIError, InvalidRequestError, LanguageModel, LLMRequest } from "./schema/index.js";
7
+ import { AIError, InvalidRequestError, LanguageModel } from "./schema/index.js";
9
8
  import { Speech } from "./speech.js";
10
9
  import { Transcription, } from "./transcription.js";
11
10
  import { fileMediaType } from "./utils/media-type.js";
@@ -36,7 +35,6 @@ export const make = (options = {}) => {
36
35
  refresh: (options) => run(generation.refresh(), options).then(handle),
37
36
  cancel: (options) => run(generation.cancel(), options),
38
37
  });
39
- const llmRequest = (input) => input instanceof LLMRequest ? Effect.succeed(input) : tryRequest(() => LLM.request(input));
40
38
  return {
41
39
  run,
42
40
  /** Decoded asset bytes, downloading `url` sources through the executor. */
@@ -65,8 +63,8 @@ export const make = (options = {}) => {
65
63
  },
66
64
  llm: {
67
65
  request: LLM.request,
68
- generate: (input, options) => run(Effect.flatMap(llmRequest(input), LLM.generate), options),
69
- stream: (input, options) => iterate(Stream.unwrap(Effect.map(llmRequest(input), LLM.stream)), options),
66
+ generate: (input, options) => run(LLM.generate(input), options),
67
+ stream: (input, options) => iterate(LLM.stream(input), options),
70
68
  },
71
69
  image: {
72
70
  request: Image.request,
@@ -10,19 +10,19 @@ declare const Options: Schema.Struct<{
10
10
  readonly preserveThinking: Schema.optional<Schema.Boolean>;
11
11
  readonly clearThinking: Schema.optional<Schema.Boolean>;
12
12
  readonly thinking: Schema.optional<Schema.Struct<{
13
- readonly type: Schema.declare<"adaptive" | "disabled" | (string & {}), "adaptive" | "disabled" | (string & {})>;
13
+ readonly type: Schema.declare<import("../schema/options.js").OpenString<"adaptive" | "disabled">, import("../schema/options.js").OpenString<"adaptive" | "disabled">>;
14
14
  }>>;
15
15
  readonly toolStream: Schema.optional<Schema.Boolean>;
16
16
  readonly parallelToolCalls: Schema.optional<Schema.Boolean>;
17
17
  readonly repetitionPenalty: Schema.optional<Schema.Number>;
18
18
  readonly responseFormat: Schema.optional<Schema.Struct<{
19
- readonly type: Schema.declare<"json_object" | "json_schema" | "text" | (string & {}), "json_object" | "json_schema" | "text" | (string & {})>;
19
+ readonly type: Schema.declare<import("../schema/options.js").OpenString<"json_object" | "json_schema" | "text">, import("../schema/options.js").OpenString<"json_object" | "json_schema" | "text">>;
20
20
  readonly json_schema: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
21
21
  }>>;
22
22
  readonly enableSearch: Schema.optional<Schema.Boolean>;
23
23
  readonly searchOptions: Schema.optional<Schema.Struct<{
24
24
  readonly forced_search: Schema.optional<Schema.Boolean>;
25
- readonly search_strategy: Schema.optional<Schema.declare<"agent" | "agent_max" | "max" | "turbo" | (string & {}), "agent" | "agent_max" | "max" | "turbo" | (string & {})>>;
25
+ readonly search_strategy: Schema.optional<Schema.declare<import("../schema/options.js").OpenString<"agent" | "agent_max" | "max" | "turbo">, import("../schema/options.js").OpenString<"agent" | "agent_max" | "max" | "turbo">>>;
26
26
  readonly enable_search_extension: Schema.optional<Schema.Boolean>;
27
27
  }>>;
28
28
  }>;
@@ -159,13 +159,13 @@ export declare const protocol: Protocol<{
159
159
  readonly preserve_thinking?: boolean | undefined;
160
160
  readonly clear_thinking?: boolean | undefined;
161
161
  readonly thinking?: {
162
- readonly type: "adaptive" | "disabled" | (string & {});
162
+ readonly type: import("../schema/options.js").OpenString<"adaptive" | "disabled">;
163
163
  } | undefined;
164
164
  readonly parallel_tool_calls?: boolean | undefined;
165
165
  readonly repetition_penalty?: number | undefined;
166
166
  readonly top_k?: number | undefined;
167
167
  readonly response_format?: {
168
- readonly type: "json_object" | "json_schema" | "text" | (string & {});
168
+ readonly type: import("../schema/options.js").OpenString<"json_object" | "json_schema" | "text">;
169
169
  readonly json_schema?: {
170
170
  readonly [x: string]: unknown;
171
171
  } | undefined;
@@ -173,7 +173,7 @@ export declare const protocol: Protocol<{
173
173
  readonly enable_search?: boolean | undefined;
174
174
  readonly search_options?: {
175
175
  readonly forced_search?: boolean | undefined;
176
- readonly search_strategy?: "agent" | "agent_max" | "max" | "turbo" | (string & {}) | undefined;
176
+ readonly search_strategy?: import("../schema/options.js").OpenString<"agent" | "agent_max" | "max" | "turbo"> | undefined;
177
177
  readonly enable_search_extension?: boolean | undefined;
178
178
  } | undefined;
179
179
  }, string, "[DONE]" | {
@@ -11,19 +11,19 @@ const Options = Schema.Struct({
11
11
  preserveThinking: Schema.optional(Schema.Boolean),
12
12
  clearThinking: Schema.optional(Schema.Boolean),
13
13
  thinking: Schema.optional(Schema.Struct({
14
- type: Schema.declare(Schema.is(Schema.String)),
14
+ type: ProviderShared.knownString(),
15
15
  })),
16
16
  toolStream: Schema.optional(Schema.Boolean),
17
17
  parallelToolCalls: Schema.optional(Schema.Boolean),
18
18
  repetitionPenalty: Schema.optional(Schema.Number),
19
19
  responseFormat: Schema.optional(Schema.Struct({
20
- type: Schema.declare(Schema.is(Schema.String)),
20
+ type: ProviderShared.knownString(),
21
21
  json_schema: Schema.optional(JsonObject),
22
22
  })),
23
23
  enableSearch: Schema.optional(Schema.Boolean),
24
24
  searchOptions: Schema.optional(Schema.Struct({
25
25
  forced_search: Schema.optional(Schema.Boolean),
26
- search_strategy: Schema.optional(Schema.declare(Schema.is(Schema.String))),
26
+ search_strategy: Schema.optional(ProviderShared.knownString()),
27
27
  enable_search_extension: Schema.optional(Schema.Boolean),
28
28
  })),
29
29
  });
@@ -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;