@opencode/ai 0.0.0-dev-20122 → 0.0.0-dev-20124

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 (126) hide show
  1. package/dist/experimental/evaluation.js +1 -1
  2. package/dist/generation.d.ts +1 -7
  3. package/dist/generation.js +1 -11
  4. package/dist/image.d.ts +2 -2
  5. package/dist/image.js +2 -2
  6. package/dist/llm.js +1 -1
  7. package/dist/media-model.d.ts +0 -2
  8. package/dist/media-model.js +0 -2
  9. package/dist/protocols/alibaba-messages.d.ts +1 -1
  10. package/dist/protocols/anthropic-messages.d.ts +34 -34
  11. package/dist/protocols/assemblyai-transcription.d.ts +2 -1
  12. package/dist/protocols/assemblyai-transcription.js +10 -14
  13. package/dist/protocols/bfl-images.js +15 -31
  14. package/dist/protocols/cartesia-speech.d.ts +2 -2
  15. package/dist/protocols/cartesia-speech.js +10 -16
  16. package/dist/protocols/deepgram-speech.d.ts +3 -3
  17. package/dist/protocols/deepgram-speech.js +7 -11
  18. package/dist/protocols/deepgram-transcription.d.ts +2 -1
  19. package/dist/protocols/deepgram-transcription.js +9 -13
  20. package/dist/protocols/elevenlabs-speech.d.ts +3 -3
  21. package/dist/protocols/elevenlabs-speech.js +9 -13
  22. package/dist/protocols/fal-images.d.ts +2 -1
  23. package/dist/protocols/fal-images.js +16 -29
  24. package/dist/protocols/fal-video.d.ts +2 -2
  25. package/dist/protocols/fal-video.js +9 -24
  26. package/dist/protocols/gemini.d.ts +13 -13
  27. package/dist/protocols/google-images.d.ts +3 -3
  28. package/dist/protocols/google-images.js +11 -21
  29. package/dist/protocols/google-speech.js +7 -13
  30. package/dist/protocols/google-transcription.d.ts +2 -1
  31. package/dist/protocols/google-transcription.js +8 -20
  32. package/dist/protocols/google-video.d.ts +2 -2
  33. package/dist/protocols/google-video.js +14 -30
  34. package/dist/protocols/meta-images.d.ts +3 -4
  35. package/dist/protocols/meta-images.js +12 -21
  36. package/dist/protocols/meta-messages.d.ts +5 -5
  37. package/dist/protocols/meta-responses.js +5 -2
  38. package/dist/protocols/openai-images.d.ts +4 -5
  39. package/dist/protocols/openai-images.js +24 -55
  40. package/dist/protocols/openai-responses.js +8 -2
  41. package/dist/protocols/openai-speech.js +7 -11
  42. package/dist/protocols/openai-transcription.js +21 -29
  43. package/dist/protocols/replicate-images.js +11 -17
  44. package/dist/protocols/runway-video.d.ts +3 -3
  45. package/dist/protocols/runway-video.js +10 -16
  46. package/dist/protocols/shared.d.ts +5 -17
  47. package/dist/protocols/shared.js +3 -39
  48. package/dist/protocols/stability-images.d.ts +2 -1
  49. package/dist/protocols/stability-images.js +24 -36
  50. package/dist/protocols/utils/fal-queue.d.ts +1 -3
  51. package/dist/protocols/utils/fal-queue.js +4 -6
  52. package/dist/protocols/utils/media-input.d.ts +15 -1
  53. package/dist/protocols/utils/media-input.js +22 -0
  54. package/dist/protocols/utils/speech-stream.d.ts +3 -3
  55. package/dist/protocols/utils/speech-stream.js +1 -4
  56. package/dist/protocols/xai-images.d.ts +4 -4
  57. package/dist/protocols/xai-images.js +12 -28
  58. package/dist/protocols/xai-video.js +12 -18
  59. package/dist/protocols/zai-images.d.ts +2 -2
  60. package/dist/protocols/zai-images.js +8 -11
  61. package/dist/protocols/zai-messages.d.ts +1 -1
  62. package/dist/providers/alibaba.d.ts +1 -1
  63. package/dist/providers/anthropic-compatible.d.ts +5 -5
  64. package/dist/providers/anthropic.d.ts +5 -5
  65. package/dist/providers/assemblyai.d.ts +1 -1
  66. package/dist/providers/assemblyai.js +5 -10
  67. package/dist/providers/azure.js +2 -2
  68. package/dist/providers/black-forest-labs.d.ts +1 -1
  69. package/dist/providers/black-forest-labs.js +5 -10
  70. package/dist/providers/cartesia.d.ts +1 -1
  71. package/dist/providers/cartesia.js +5 -10
  72. package/dist/providers/cloudflare-ai-gateway.d.ts +10 -10
  73. package/dist/providers/deepgram.d.ts +1 -1
  74. package/dist/providers/deepgram.js +6 -12
  75. package/dist/providers/elevenlabs.d.ts +1 -1
  76. package/dist/providers/elevenlabs.js +5 -10
  77. package/dist/providers/fal.d.ts +1 -1
  78. package/dist/providers/fal.js +5 -12
  79. package/dist/providers/google-vertex-messages.d.ts +5 -5
  80. package/dist/providers/google-vertex.d.ts +3 -3
  81. package/dist/providers/google.d.ts +3 -3
  82. package/dist/providers/google.js +7 -12
  83. package/dist/providers/meta.d.ts +8 -8
  84. package/dist/providers/meta.js +4 -8
  85. package/dist/providers/minimax.d.ts +5 -5
  86. package/dist/providers/moonshot.d.ts +5 -5
  87. package/dist/providers/openai.d.ts +7 -8
  88. package/dist/providers/openai.js +10 -11
  89. package/dist/providers/opencode-zen.js +1 -1
  90. package/dist/providers/openrouter.d.ts +6 -7
  91. package/dist/providers/openrouter.js +1 -1
  92. package/dist/providers/replicate.d.ts +1 -1
  93. package/dist/providers/replicate.js +5 -10
  94. package/dist/providers/runway.d.ts +1 -1
  95. package/dist/providers/runway.js +5 -10
  96. package/dist/providers/stability.d.ts +1 -1
  97. package/dist/providers/stability.js +6 -11
  98. package/dist/providers/typesafe-ai.js +1 -1
  99. package/dist/providers/vercel-ai-gateway.js +1 -1
  100. package/dist/providers/xai.js +5 -10
  101. package/dist/providers/zai-coding-plan.d.ts +1 -1
  102. package/dist/providers/zai.js +4 -8
  103. package/dist/route/client.d.ts +0 -1
  104. package/dist/route/client.js +1 -6
  105. package/dist/route/endpoint.d.ts +1 -0
  106. package/dist/route/endpoint.js +2 -2
  107. package/dist/route/framing.d.ts +10 -1
  108. package/dist/route/framing.js +45 -5
  109. package/dist/route/media-protocol.d.ts +42 -35
  110. package/dist/route/media-protocol.js +67 -62
  111. package/dist/route/media.d.ts +6 -2
  112. package/dist/route/media.js +40 -29
  113. package/dist/schema/options.d.ts +6 -3
  114. package/dist/schema/options.js +7 -3
  115. package/dist/speech.d.ts +2 -2
  116. package/dist/speech.js +2 -2
  117. package/dist/transcription.js +2 -2
  118. package/dist/utils/json.d.ts +4 -0
  119. package/dist/utils/json.js +4 -0
  120. package/dist/video.d.ts +2 -2
  121. package/dist/video.js +2 -2
  122. package/package.json +3 -3
  123. package/dist/protocols/utils/meta-image.d.ts +0 -2
  124. package/dist/protocols/utils/meta-image.js +0 -13
  125. package/dist/protocols/utils/openai-image.d.ts +0 -5
  126. package/dist/protocols/utils/openai-image.js +0 -18
@@ -249,20 +249,20 @@ export declare const routes: (Route<{
249
249
  readonly thinking?: {
250
250
  readonly type: "enabled";
251
251
  readonly budget_tokens: number;
252
- readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
252
+ readonly display?: import("../schema/options.js").OpenString<"summarized" | "omitted"> | undefined;
253
253
  readonly block_binding?: {
254
- readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
254
+ readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
255
255
  } | undefined;
256
256
  } | {
257
257
  readonly type: "adaptive";
258
- readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
258
+ readonly display?: import("../schema/options.js").OpenString<"summarized" | "omitted"> | undefined;
259
259
  readonly block_binding?: {
260
- readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
260
+ readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
261
261
  } | undefined;
262
262
  } | {
263
263
  readonly type: "disabled";
264
264
  } | undefined;
265
- readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
265
+ readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "standard_only"> | undefined;
266
266
  readonly container?: string | {
267
267
  readonly id?: string | null | undefined;
268
268
  readonly skills?: readonly {
@@ -247,20 +247,20 @@ export declare const routes: (Route<{
247
247
  readonly thinking?: {
248
248
  readonly type: "enabled";
249
249
  readonly budget_tokens: number;
250
- readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
250
+ readonly display?: import("../schema/options.js").OpenString<"summarized" | "omitted"> | undefined;
251
251
  readonly block_binding?: {
252
- readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
252
+ readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
253
253
  } | undefined;
254
254
  } | {
255
255
  readonly type: "adaptive";
256
- readonly display?: (string & {}) | "summarized" | "omitted" | undefined;
256
+ readonly display?: import("../schema/options.js").OpenString<"summarized" | "omitted"> | undefined;
257
257
  readonly block_binding?: {
258
- readonly prefix_mismatch_behavior?: (string & {}) | "error" | "drop_block" | undefined;
258
+ readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
259
259
  } | undefined;
260
260
  } | {
261
261
  readonly type: "disabled";
262
262
  } | undefined;
263
- readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
263
+ readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "standard_only"> | undefined;
264
264
  readonly container?: string | {
265
265
  readonly id?: string | null | undefined;
266
266
  readonly skills?: readonly {
@@ -1,10 +1,9 @@
1
1
  import { type ProviderAuthOption } from "../route/auth-options.js";
2
2
  import type { Route, RouteDefaultsInput, CompactionOperations } from "../route/client.js";
3
3
  import type { ProviderPackage } from "../provider-package.js";
4
- import { ToolDefinition, type ModelID } from "../schema/index.js";
4
+ import { ToolDefinition, type ModelID, type OpenString } from "../schema/index.js";
5
5
  import * as OpenAIResponses from "../protocols/openai-responses.js";
6
6
  import { type OpenAIProviderOptionsInput } from "./openai-options.js";
7
- import { type OpenAIImageString } from "../protocols/openai-images.js";
8
7
  export type { OpenAIOptionsInput, OpenAIResponseIncludable } from "./openai-options.js";
9
8
  export type { OpenAIImageOptions } from "../protocols/openai-images.js";
10
9
  export type { OpenAISpeechOptions } from "../protocols/openai-speech.js";
@@ -357,14 +356,14 @@ export type Config = RouteDefaultsInput & ProviderAuthOption<"optional"> & {
357
356
  readonly providerOptions?: OpenAIProviderOptionsInput;
358
357
  };
359
358
  export interface ImageGenerationOptions {
360
- readonly action?: OpenAIImageString<"auto" | "generate" | "edit">;
361
- readonly background?: OpenAIImageString<"auto" | "opaque" | "transparent">;
362
- readonly inputFidelity?: OpenAIImageString<"low" | "high">;
359
+ readonly action?: OpenString<"auto" | "generate" | "edit">;
360
+ readonly background?: OpenString<"auto" | "opaque" | "transparent">;
361
+ readonly inputFidelity?: OpenString<"low" | "high">;
363
362
  readonly outputCompression?: number;
364
- readonly outputFormat?: OpenAIImageString<"png" | "jpeg" | "webp">;
363
+ readonly outputFormat?: OpenString<"png" | "jpeg" | "webp">;
365
364
  readonly partialImages?: number;
366
- readonly quality?: OpenAIImageString<"auto" | "low" | "medium" | "high" | "standard" | "hd">;
367
- readonly size?: OpenAIImageString<"auto" | "256x256" | "512x512" | "1024x1024" | "1536x1024" | "1024x1536" | "1792x1024" | "1024x1792">;
365
+ readonly quality?: OpenString<"auto" | "low" | "medium" | "high" | "standard" | "hd">;
366
+ readonly size?: OpenString<"auto" | "256x256" | "512x512" | "1024x1024" | "1536x1024" | "1024x1536" | "1792x1024" | "1024x1792">;
368
367
  }
369
368
  export declare const imageGeneration: (options?: ImageGenerationOptions) => ToolDefinition;
370
369
  export type Settings = ProviderPackage.Settings & OpenAIProviderOptionsInput & {
@@ -1,5 +1,6 @@
1
1
  import { AuthOptions } from "../route/auth-options.js";
2
- import { HttpOptions, ProviderID, ToolDefinition, mergeHttpOptions } from "../schema/index.js";
2
+ import { MediaRoute } from "../route/media.js";
3
+ import { HttpOptions, ProviderID, ToolDefinition, mergeHttpOptions, } from "../schema/index.js";
3
4
  import * as OpenAIChat from "../protocols/openai-chat.js";
4
5
  import * as OpenAIResponses from "../protocols/openai-responses.js";
5
6
  import { withOpenAIOptions } from "./openai-options.js";
@@ -46,16 +47,14 @@ export const configure = (input = {}) => {
46
47
  id,
47
48
  compatibility: { supportsPromptCacheKey: true },
48
49
  });
49
- const media = (modelID) => ({
50
- id: modelID,
51
- auth: auth(input),
52
- baseURL: input.baseURL,
53
- headers: input.headers,
54
- http: mergeHttpOptions(input.http === undefined ? undefined : HttpOptions.make(input.http), input.queryParams === undefined ? undefined : new HttpOptions({ query: input.queryParams })),
55
- });
56
- const image = (modelID) => OpenAIImages.model(media(modelID));
57
- const speech = (modelID) => OpenAISpeech.model(media(modelID));
58
- const transcription = (modelID) => OpenAITranscription.model(media(modelID));
50
+ const deployment = MediaRoute.deployment(input, auth(input));
51
+ const media = {
52
+ ...deployment,
53
+ http: mergeHttpOptions(deployment.http, input.queryParams === undefined ? undefined : new HttpOptions({ query: input.queryParams })),
54
+ };
55
+ const image = (modelID) => OpenAIImages.model({ ...media, id: modelID });
56
+ const speech = (modelID) => OpenAISpeech.model({ ...media, id: modelID });
57
+ const transcription = (modelID) => OpenAITranscription.model({ ...media, id: modelID });
59
58
  return {
60
59
  id,
61
60
  model: responses,
@@ -11,7 +11,7 @@ export const configure = (input = {}) => {
11
11
  auth: AuthOptions.bearer(input, "OPENCODE_API_KEY"),
12
12
  baseURL: input.baseURL ?? baseURL,
13
13
  headers: input.headers,
14
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
14
+ http: HttpOptions.make(input.http),
15
15
  });
16
16
  return { id, experimental: { evaluation }, configure };
17
17
  };
@@ -2,21 +2,20 @@ import { Schema } from "effect";
2
2
  import { Route, type RouteDefaultsInput } from "../route/client.js";
3
3
  import { Protocol } from "../route/protocol.js";
4
4
  import { type ProviderAuthOption } from "../route/auth-options.js";
5
- import { type ModelID } from "../schema/index.js";
5
+ import { type ModelID, type OpenString } from "../schema/index.js";
6
6
  import type { ProviderPackage } from "../provider-package.js";
7
7
  import { OpenAIChat } from "../protocols/openai-chat.js";
8
8
  export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
9
- type OpenRouterString<Known extends string> = Known | (string & {});
10
9
  export interface OpenRouterProviderRouting {
11
10
  readonly [key: string]: unknown;
12
11
  readonly order?: ReadonlyArray<string>;
13
12
  readonly allow_fallbacks?: boolean;
14
13
  readonly require_parameters?: boolean;
15
- readonly data_collection?: OpenRouterString<"allow" | "deny">;
14
+ readonly data_collection?: OpenString<"allow" | "deny">;
16
15
  readonly only?: ReadonlyArray<string>;
17
16
  readonly ignore?: ReadonlyArray<string>;
18
17
  readonly quantizations?: ReadonlyArray<string>;
19
- readonly sort?: OpenRouterString<"price" | "throughput" | "latency">;
18
+ readonly sort?: OpenString<"price" | "throughput" | "latency">;
20
19
  readonly max_price?: Readonly<{
21
20
  prompt?: number | string;
22
21
  completion?: number | string;
@@ -30,7 +29,7 @@ export type OpenRouterPlugin = Readonly<{
30
29
  id: "web";
31
30
  max_results?: number;
32
31
  search_prompt?: string;
33
- engine?: OpenRouterString<"native" | "exa">;
32
+ engine?: OpenString<"native" | "exa">;
34
33
  }> | Readonly<{
35
34
  id: "file-parser";
36
35
  max_files?: number;
@@ -59,7 +58,7 @@ export interface OpenRouterOptions {
59
58
  readonly reasoning?: Readonly<{
60
59
  enabled?: boolean;
61
60
  exclude?: boolean;
62
- effort?: OpenRouterString<"none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
61
+ effort?: OpenString<"none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
63
62
  max_tokens?: number;
64
63
  }>;
65
64
  readonly usage?: boolean | Readonly<{
@@ -69,7 +68,7 @@ export interface OpenRouterOptions {
69
68
  readonly web_search_options?: Readonly<{
70
69
  max_results?: number;
71
70
  search_prompt?: string;
72
- engine?: OpenRouterString<"native" | "exa">;
71
+ engine?: OpenString<"native" | "exa">;
73
72
  }>;
74
73
  }
75
74
  export type OpenRouterProviderOptionsInput = OpenRouterOptions;
@@ -106,7 +106,7 @@ export const configure = (input = {}) => {
106
106
  auth: AuthOptions.bearer(input, "OPENROUTER_API_KEY"),
107
107
  baseURL: input.baseURL ?? baseURL,
108
108
  headers: input.headers,
109
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
109
+ http: HttpOptions.make(input.http),
110
110
  });
111
111
  return {
112
112
  id,
@@ -1,5 +1,5 @@
1
1
  import { type ProviderAuthOption } from "../route/auth-options.js";
2
- import { HttpOptions, type ModelID } from "../schema/index.js";
2
+ import { type HttpOptions, type ModelID } from "../schema/index.js";
3
3
  export type { ReplicateImageOptions } from "../protocols/replicate-images.js";
4
4
  export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
5
5
  export type Config = ProviderAuthOption<"optional"> & {
@@ -1,17 +1,12 @@
1
1
  import { AuthOptions } from "../route/auth-options.js";
2
- import { HttpOptions, ProviderID } from "../schema/index.js";
3
- import { DEFAULT_BASE_URL, ReplicateImages } from "../protocols/replicate-images.js";
2
+ import { MediaRoute } from "../route/media.js";
3
+ import { ProviderID } from "../schema/index.js";
4
+ import { ReplicateImages } from "../protocols/replicate-images.js";
4
5
  export const id = ProviderID.make("replicate");
5
- const baseURL = DEFAULT_BASE_URL;
6
6
  const auth = (options) => AuthOptions.bearer(options, "REPLICATE_API_TOKEN");
7
7
  export const configure = (input = {}) => {
8
- const image = (modelID) => ReplicateImages.model({
9
- id: modelID,
10
- auth: auth(input),
11
- baseURL: input.baseURL ?? baseURL,
12
- headers: input.headers,
13
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
14
- });
8
+ const media = MediaRoute.deployment(input, auth(input));
9
+ const image = (modelID) => ReplicateImages.model({ ...media, id: modelID });
15
10
  return {
16
11
  id,
17
12
  image,
@@ -1,5 +1,5 @@
1
1
  import { type ProviderAuthOption } from "../route/auth-options.js";
2
- import { HttpOptions, type ModelID } from "../schema/index.js";
2
+ import { type HttpOptions, type ModelID } from "../schema/index.js";
3
3
  export type { RunwayVideoOptions } from "../protocols/runway-video.js";
4
4
  export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
5
5
  export type Config = ProviderAuthOption<"optional"> & {
@@ -1,17 +1,12 @@
1
1
  import { AuthOptions } from "../route/auth-options.js";
2
- import { HttpOptions, ProviderID } from "../schema/index.js";
3
- import { DEFAULT_BASE_URL, RunwayVideo } from "../protocols/runway-video.js";
2
+ import { MediaRoute } from "../route/media.js";
3
+ import { ProviderID } from "../schema/index.js";
4
+ import { RunwayVideo } from "../protocols/runway-video.js";
4
5
  export const id = ProviderID.make("runway");
5
- const baseURL = DEFAULT_BASE_URL;
6
6
  const auth = (options) => AuthOptions.bearer(options, "RUNWAYML_API_SECRET");
7
7
  export const configure = (input = {}) => {
8
- const video = (modelID) => RunwayVideo.model({
9
- id: modelID,
10
- auth: auth(input),
11
- baseURL: input.baseURL ?? baseURL,
12
- headers: input.headers,
13
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
14
- });
8
+ const media = MediaRoute.deployment(input, auth(input));
9
+ const video = (modelID) => RunwayVideo.model({ ...media, id: modelID });
15
10
  return {
16
11
  id,
17
12
  video,
@@ -1,5 +1,5 @@
1
1
  import { type ProviderAuthOption } from "../route/auth-options.js";
2
- import { HttpOptions, type ModelID } from "../schema/index.js";
2
+ import { type HttpOptions, type ModelID } from "../schema/index.js";
3
3
  export type { StabilityImageOptions, StabilityUpscaleOptions } from "../protocols/stability-images.js";
4
4
  export declare const id: string & import("effect/Brand").Brand<"AI.ProviderID">;
5
5
  export type Config = ProviderAuthOption<"optional"> & {
@@ -1,20 +1,15 @@
1
1
  import { AuthOptions } from "../route/auth-options.js";
2
- import { HttpOptions, ProviderID } from "../schema/index.js";
3
- import { DEFAULT_BASE_URL, StabilityImages } from "../protocols/stability-images.js";
2
+ import { MediaRoute } from "../route/media.js";
3
+ import { ProviderID } from "../schema/index.js";
4
+ import { StabilityImages } from "../protocols/stability-images.js";
4
5
  export const id = ProviderID.make("stability");
5
- const baseURL = DEFAULT_BASE_URL;
6
6
  const auth = (options) => AuthOptions.bearer(options, "STABILITY_API_KEY");
7
7
  export const configure = (input = {}) => {
8
- const deployment = {
9
- auth: auth(input),
10
- baseURL: input.baseURL ?? baseURL,
11
- headers: input.headers,
12
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
13
- };
8
+ const media = MediaRoute.deployment(input, auth(input));
14
9
  return {
15
10
  id,
16
- image: (modelID) => StabilityImages.model({ ...deployment, id: modelID }),
17
- upscale: () => StabilityImages.upscaleModel(deployment),
11
+ image: (modelID) => StabilityImages.model({ ...media, id: modelID }),
12
+ upscale: () => StabilityImages.upscaleModel(media),
18
13
  configure,
19
14
  };
20
15
  };
@@ -11,7 +11,7 @@ export const configure = (input = {}) => {
11
11
  auth: AuthOptions.bearer(input, "TYPESAFE_API_KEY"),
12
12
  baseURL: input.baseURL ?? baseURL,
13
13
  headers: input.headers,
14
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
14
+ http: HttpOptions.make(input.http),
15
15
  });
16
16
  return { id, experimental: { evaluation }, configure };
17
17
  };
@@ -26,7 +26,7 @@ export const configure = (input = {}) => {
26
26
  const evaluation = (modelID) => EvaluationModel.make({
27
27
  id: modelID,
28
28
  provider: id,
29
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
29
+ http: HttpOptions.make(input.http),
30
30
  route: {
31
31
  id: "vercel-evaluation",
32
32
  evaluate: (req, send) => Effect.gen(function* () {
@@ -1,7 +1,8 @@
1
1
  import { AuthOptions } from "../route/auth-options.js";
2
2
  import { Route } from "../route/client.js";
3
3
  import { Endpoint } from "../route/endpoint.js";
4
- import { HttpOptions, ProviderID } from "../schema/index.js";
4
+ import { MediaRoute } from "../route/media.js";
5
+ import { ProviderID } from "../schema/index.js";
5
6
  import { OpenAIChat } from "../protocols/openai-chat.js";
6
7
  import { OpenResponsesChannel } from "../protocols/open-responses-channel.js";
7
8
  import { XAIResponses } from "../protocols/xai-responses.js";
@@ -60,20 +61,14 @@ export const configure = (input = {}) => {
60
61
  const chatRoute = configuredChatRoute(input);
61
62
  const responses = (modelID) => responsesRoute.model({ id: modelID });
62
63
  const chat = (modelID) => chatRoute.model({ id: modelID });
63
- const media = (modelID) => ({
64
- id: modelID,
65
- auth: auth(input),
66
- baseURL: input.baseURL ?? baseURL,
67
- headers: input.headers,
68
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
69
- });
64
+ const media = MediaRoute.deployment(input, auth(input));
70
65
  return {
71
66
  id,
72
67
  model: responses,
73
68
  responses,
74
69
  chat,
75
- image: (modelID) => XAIImages.model(media(modelID)),
76
- video: (modelID) => XAIVideo.model(media(modelID)),
70
+ image: (modelID) => XAIImages.model({ ...media, id: modelID }),
71
+ video: (modelID) => XAIVideo.model({ ...media, id: modelID }),
77
72
  configure,
78
73
  };
79
74
  };
@@ -520,7 +520,7 @@ export declare const routes: (Route<{
520
520
  readonly thinking?: {
521
521
  readonly type: string;
522
522
  } | undefined;
523
- readonly service_tier?: "auto" | (string & {}) | "standard_only" | undefined;
523
+ readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "standard_only"> | undefined;
524
524
  readonly container?: string | {
525
525
  readonly id?: string | null | undefined;
526
526
  readonly skills?: readonly {
@@ -4,7 +4,8 @@ import { OpenAIChat } from "../protocols/openai-chat.js";
4
4
  import { AuthOptions } from "../route/auth-options.js";
5
5
  import { Route } from "../route/client.js";
6
6
  import { Endpoint } from "../route/endpoint.js";
7
- import { HttpOptions, ProviderID } from "../schema/index.js";
7
+ import { MediaRoute } from "../route/media.js";
8
+ import { ProviderID } from "../schema/index.js";
8
9
  export const id = ProviderID.make("zai");
9
10
  const auth = (options) => AuthOptions.bearer(options, "ZAI_API_KEY");
10
11
  const chatRoute = Route.make({
@@ -25,13 +26,8 @@ export const configure = (input = {}) => {
25
26
  auth: auth(input),
26
27
  })
27
28
  .model({ id: modelID, compatibility: ZAIChat.compatibility });
28
- const image = (modelID) => ZAIImages.model({
29
- id: modelID,
30
- auth: auth(input),
31
- baseURL: input.baseURL,
32
- headers: input.headers,
33
- http: input.http === undefined ? undefined : HttpOptions.make(input.http),
34
- });
29
+ const media = MediaRoute.deployment(input, auth(input));
30
+ const image = (modelID) => ZAIImages.model({ ...media, id: modelID });
35
31
  return {
36
32
  id,
37
33
  model: chat,
@@ -71,7 +71,6 @@ export interface RoutePatch<Body, Prepared> extends RouteDefaultsInput {
71
71
  }
72
72
  type RouteMappedLanguageModelInput = RouteLanguageModelInput | RouteRoutedLanguageModelInput;
73
73
  export declare const generationOptions: (input: GenerationOptions.Input | undefined) => GenerationOptions | undefined;
74
- export declare const httpOptions: (input: HttpOptionsInput | undefined) => HttpOptions | undefined;
75
74
  export interface Interface {
76
75
  readonly compact: CompactMethod;
77
76
  readonly stream: StreamMethod;
@@ -33,7 +33,7 @@ const mergeRouteDefaults = (base, patch) => {
33
33
  headers,
34
34
  generation: mergeGenerationOptions(generationOptions(base?.generation), generationOptions(patch.generation)),
35
35
  providerOptions: mergeProviderOptions(base?.providerOptions, patch.providerOptions),
36
- http: mergeHttpOptions(base?.http, httpOptions(patch.http), headers === undefined ? undefined : new HttpOptions({ headers })),
36
+ http: mergeHttpOptions(base?.http, HttpOptions.make(patch.http), headers === undefined ? undefined : new HttpOptions({ headers })),
37
37
  };
38
38
  };
39
39
  const endpointBaseURL = (endpoint) => typeof endpoint.baseURL === "string" ? endpoint.baseURL : undefined;
@@ -44,11 +44,6 @@ const mergeHeaders = (...items) => {
44
44
  return Object.fromEntries(entries);
45
45
  };
46
46
  export const generationOptions = (input) => input === undefined ? undefined : GenerationOptions.make(input);
47
- export const httpOptions = (input) => {
48
- if (input === undefined)
49
- return input;
50
- return HttpOptions.make(input);
51
- };
52
47
  export function canCompact(request, options) {
53
48
  if (options?.mechanism === "trigger")
54
49
  return request.model.route.compact?.trigger !== undefined;
@@ -24,5 +24,6 @@ export type EndpointPatch<Body, Request = LLMRequest> = Partial<Definition<Body,
24
24
  /** Construct an `Endpoint` from a path string or path function. */
25
25
  export declare const path: <Body, Request = LLMRequest>(value: EndpointPart<Body, Request>, options?: Omit<Definition<Body, Request>, "path">) => Definition<Body, Request>;
26
26
  export declare const merge: <Body, Request = LLMRequest>(base: Definition<Body, Request>, patch: EndpointPatch<Body, Request>) => Definition<Body, Request>;
27
+ export declare const trimBaseUrl: (value: string) => string;
27
28
  export declare const render: <Body, Request = LLMRequest>(endpoint: Definition<Body, Request>, input: EndpointInput<Body, Request>) => URL;
28
29
  export * as Endpoint from "./endpoint.js";
@@ -1,4 +1,3 @@
1
- import * as ProviderShared from "../protocols/shared.js";
2
1
  /** Construct an `Endpoint` from a path string or path function. */
3
2
  export const path = (value, options = {}) => ({
4
3
  ...options,
@@ -11,9 +10,10 @@ export const merge = (base, patch) => ({
11
10
  path: patch.path ?? base.path,
12
11
  query: patch.query === undefined ? base.query : { ...base.query, ...patch.query },
13
12
  });
13
+ export const trimBaseUrl = (value) => value.replace(/\/+$/, "");
14
14
  const renderPart = (part, input) => typeof part === "function" ? part(input) : part;
15
15
  export const render = (endpoint, input) => {
16
- const url = new URL(`${ProviderShared.trimBaseUrl(endpoint.baseURL ?? "")}${renderPart(endpoint.path, input)}`);
16
+ const url = new URL(`${trimBaseUrl(endpoint.baseURL ?? "")}${renderPart(endpoint.path, input)}`);
17
17
  for (const [key, value] of Object.entries(endpoint.query ?? {}))
18
18
  url.searchParams.set(key, value);
19
19
  return url;
@@ -1,5 +1,5 @@
1
1
  import { Stream } from "effect";
2
- import type { AIError } from "../schema/index.js";
2
+ import { AIError } from "../schema/index.js";
3
3
  /**
4
4
  * Decode a streaming HTTP response body into provider-protocol frames.
5
5
  *
@@ -22,6 +22,15 @@ export interface Definition<Frame> {
22
22
  /** Original wire representation when framing transforms the provider payload. */
23
23
  readonly body?: (frame: Frame) => string | undefined;
24
24
  }
25
+ /**
26
+ * `framing` step for Server-Sent Events. Decodes UTF-8, runs the SSE channel
27
+ * decoder, optionally filters named events, and drops empty events and known
28
+ * keepalives that proxies send as data. `[DONE]` is dropped by default or
29
+ * retained for protocols that use it as their stream boundary. Retry control events are ignored without
30
+ * interrupting the stream. Decoder failures become provider output errors so
31
+ * the public error channel stays `AIError`.
32
+ */
33
+ export declare const sseFraming: (bytes: Stream.Stream<Uint8Array, AIError>, events?: ReadonlySet<string>, includeDone?: boolean) => Stream.Stream<string, AIError>;
25
34
  /** Server-Sent Events framing. Used by every JSON-streaming HTTP provider. */
26
35
  export declare const sse: Definition<string>;
27
36
  /** Server-Sent Events framing that retains the conventional `[DONE]` sentinel. */
@@ -1,16 +1,56 @@
1
- import { Stream } from "effect";
2
- import * as ProviderShared from "../protocols/shared.js";
1
+ import { Effect, Stream } from "effect";
2
+ import { makeParser } from "effect/unstable/encoding/Sse";
3
+ import { AIError, InvalidProviderOutputError } from "../schema/index.js";
4
+ /**
5
+ * `framing` step for Server-Sent Events. Decodes UTF-8, runs the SSE channel
6
+ * decoder, optionally filters named events, and drops empty events and known
7
+ * keepalives that proxies send as data. `[DONE]` is dropped by default or
8
+ * retained for protocols that use it as their stream boundary. Retry control events are ignored without
9
+ * interrupting the stream. Decoder failures become provider output errors so
10
+ * the public error channel stays `AIError`.
11
+ */
12
+ export const sseFraming = (bytes, events, includeDone = false) => bytes.pipe(Stream.decodeText(), Stream.mapAccumEffect(() => {
13
+ const output = [];
14
+ return {
15
+ output,
16
+ parser: makeParser((event) => {
17
+ if (event._tag === "Event")
18
+ output.push(event);
19
+ }),
20
+ };
21
+ }, (state, chunk) => Effect.gen(function* () {
22
+ const error = state.parser.feed(chunk);
23
+ if (error)
24
+ return yield* new AIError({
25
+ reason: new InvalidProviderOutputError({
26
+ route: "sse",
27
+ message: error.message,
28
+ body: chunk,
29
+ cause: error,
30
+ }),
31
+ });
32
+ return [state, state.output.splice(0)];
33
+ })), Stream.filter((event) => (events === undefined || events.has(event.event)) &&
34
+ event.data.length > 0 &&
35
+ // Some OpenAI-compatible proxies serialize an empty flush as a bare
36
+ // `data: null`, between events or after `[DONE]`. No protocol has a
37
+ // null event, so it carries nothing and must not abort the stream.
38
+ event.data !== "null" &&
39
+ // Vertex AI partner models (e.g. `xai/grok-4.6`) send their SSE
40
+ // keepalive comment as `data: : keepalive` while reasoning.
41
+ event.data !== ": keepalive" &&
42
+ (event.data !== "[DONE]" || includeDone || (events !== undefined && event.event !== "message"))), Stream.map((event) => event.data));
3
43
  /** Server-Sent Events framing. Used by every JSON-streaming HTTP provider. */
4
- export const sse = { id: "sse", frame: ProviderShared.sseFraming };
44
+ export const sse = { id: "sse", frame: sseFraming };
5
45
  /** Server-Sent Events framing that retains the conventional `[DONE]` sentinel. */
6
46
  export const sseWithDone = {
7
47
  id: "sse",
8
- frame: (bytes) => ProviderShared.sseFraming(bytes, undefined, true),
48
+ frame: (bytes) => sseFraming(bytes, undefined, true),
9
49
  };
10
50
  /** SSE framing restricted to protocol-recognized event names. */
11
51
  export const sseEvents = (events) => ({
12
52
  id: "sse",
13
- frame: (bytes) => ProviderShared.sseFraming(bytes, events),
53
+ frame: (bytes) => sseFraming(bytes, events),
14
54
  });
15
55
  export const lines = {
16
56
  id: "lines",