@opencode-ai/ai 0.0.0-beta-17963 → 0.0.0-beta-18045

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 (39) hide show
  1. package/dist/protocols/anthropic-messages.d.ts +4 -0
  2. package/dist/protocols/anthropic-messages.js +23 -14
  3. package/dist/protocols/gemini.d.ts +40 -40
  4. package/dist/protocols/gemini.js +68 -50
  5. package/dist/protocols/open-responses-channel.js +3 -0
  6. package/dist/protocols/open-responses.d.ts +6 -6
  7. package/dist/protocols/open-responses.js +19 -7
  8. package/dist/protocols/openai-chat.d.ts +42 -2
  9. package/dist/protocols/openai-chat.js +37 -7
  10. package/dist/protocols/openai-compatible-responses.d.ts +1 -1
  11. package/dist/protocols/openai-responses.d.ts +6 -6
  12. package/dist/protocols/openai-responses.js +1 -2
  13. package/dist/protocols/shared.d.ts +2 -0
  14. package/dist/protocols/shared.js +11 -0
  15. package/dist/protocols/utils/open-responses-options.d.ts +4 -3
  16. package/dist/protocols/utils/open-responses-options.js +2 -1
  17. package/dist/protocols/utils/openai-options.d.ts +3 -3
  18. package/dist/protocols/utils/openai-options.js +1 -1
  19. package/dist/protocols/utils/tool-schema.js +1 -28
  20. package/dist/protocols/xai-responses.d.ts +1 -1
  21. package/dist/providers/amazon-bedrock-mantle.d.ts +11 -11
  22. package/dist/providers/anthropic-compatible.d.ts +1 -0
  23. package/dist/providers/anthropic.d.ts +1 -0
  24. package/dist/providers/azure.d.ts +8 -8
  25. package/dist/providers/cloudflare.d.ts +2 -2
  26. package/dist/providers/google-vertex-chat.d.ts +2 -2
  27. package/dist/providers/google-vertex-messages.d.ts +1 -0
  28. package/dist/providers/google-vertex-responses.d.ts +1 -1
  29. package/dist/providers/google-vertex.d.ts +7 -7
  30. package/dist/providers/google-vertex.js +13 -1
  31. package/dist/providers/google.d.ts +7 -7
  32. package/dist/providers/openai-compatible-responses.d.ts +1 -1
  33. package/dist/providers/openai-compatible.d.ts +9 -9
  34. package/dist/providers/openai-options.d.ts +6 -2
  35. package/dist/providers/openai.d.ts +12 -12
  36. package/dist/providers/openrouter.d.ts +22 -0
  37. package/dist/providers/openrouter.js +3 -2
  38. package/dist/providers/xai.d.ts +11 -11
  39. package/package.json +5 -5
@@ -1,7 +1,7 @@
1
1
  import { Effect, Schema } from "effect";
2
2
  import { HttpTransport } from "../route/transport/index.js";
3
3
  import { Protocol } from "../route/protocol.js";
4
- import { AIError, LLMEvent, Usage, } from "../schema/index.js";
4
+ import { AIError, LLMEvent, ProviderInternalReason, Usage, } from "../schema/index.js";
5
5
  import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js";
6
6
  import { classifyProviderFailure } from "../provider-error.js";
7
7
  import { OpenResponsesOptions } from "./utils/open-responses-options.js";
@@ -234,7 +234,7 @@ export const lowerTool = Effect.fn("OpenResponses.lowerTool")(function* (protoco
234
234
  type: "function",
235
235
  name: tool.name,
236
236
  description: tool.description,
237
- parameters: ToolSchemaProjection.responses(inputSchema),
237
+ parameters: inputSchema,
238
238
  // The common tool definition does not currently express Responses strict-schema policy.
239
239
  strict: false,
240
240
  };
@@ -290,7 +290,7 @@ const lowerMedia = Effect.fn("OpenResponses.lowerMedia")(function* (part, reques
290
290
  return {
291
291
  type: "input_file",
292
292
  filename: part.filename ?? (media.mime === "application/pdf" ? "document.pdf" : "file"),
293
- ...(url ? { file_url: url } : { file_data: media.base64 }),
293
+ ...(url ? { file_url: url } : { file_data: media.dataUrl }),
294
294
  };
295
295
  }
296
296
  return { type: "input_image", image_url: url ?? media.dataUrl };
@@ -416,8 +416,12 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
416
416
  const id = itemID(part.providerMetadata, providerMetadataKey);
417
417
  if (store !== false && id && !hostedToolReferences.has(id))
418
418
  input.push({ type: "item_reference", id });
419
- if (store === false && part.result.type === "content") {
420
- const content = part.result.value;
419
+ if (store === false) {
420
+ // The server is not storing this exchange, so the tool outcome has to
421
+ // travel in the input. Non-content results degrade to their text form.
422
+ const content = part.result.type === "content"
423
+ ? part.result.value
424
+ : [{ type: "text", text: ProviderShared.toolResultText(part) }];
421
425
  input.push({
422
426
  role: "user",
423
427
  content: yield* Effect.forEach(content, (item) => lowerHostedToolResultContentItem(item, request, extension)),
@@ -456,6 +460,7 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
456
460
  });
457
461
  const lowerOptions = (request) => {
458
462
  const options = OpenResponsesOptions.resolve(request);
463
+ const cacheKey = ProviderShared.clampPromptCacheKey(request.promptCacheKey);
459
464
  return {
460
465
  ...(options.instructions ? { instructions: options.instructions } : {}),
461
466
  ...(options.store !== undefined ? { store: options.store } : {}),
@@ -465,7 +470,7 @@ const lowerOptions = (request) => {
465
470
  ? { stream_options: { include_obfuscation: options.streamOptions.includeObfuscation } }
466
471
  : {}),
467
472
  ...(options.topLogprobs !== undefined ? { top_logprobs: options.topLogprobs } : {}),
468
- ...(request.promptCacheKey ? { prompt_cache_key: request.promptCacheKey } : {}),
473
+ ...(cacheKey ? { prompt_cache_key: cacheKey } : {}),
469
474
  ...(options.include ? { include: options.include } : {}),
470
475
  ...(options.reasoningEffort || options.reasoningSummary
471
476
  ? { reasoning: { effort: options.reasoningEffort, summary: options.reasoningSummary } }
@@ -856,11 +861,18 @@ export const providerFailure = (id, event, fallback) => {
856
861
  : typeof event.status_code === "number"
857
862
  ? event.status_code
858
863
  : undefined;
864
+ const reason = event.type === "error" &&
865
+ event.error === undefined &&
866
+ event.response === undefined &&
867
+ summary === undefined &&
868
+ status === undefined
869
+ ? new ProviderInternalReason({ message })
870
+ : classifyProviderFailure({ message, code, status, rawBody: body });
859
871
  return new AIError({
860
872
  module: id,
861
873
  method: "stream",
862
874
  body,
863
- reason: classifyProviderFailure({ message, code, status, rawBody: body }),
875
+ reason,
864
876
  });
865
877
  };
866
878
  const providerError = (state, event, fallback) => providerFailure(state.id, event, fallback);
@@ -201,7 +201,7 @@ declare const OpenAIChatBody: Schema.Struct<{
201
201
  }>;
202
202
  export type OpenAIChatBody = Schema.Schema.Type<typeof OpenAIChatBody>;
203
203
  export declare const OpenAIChatEvent: Schema.Struct<{
204
- readonly choices: Schema.optional<Schema.NullOr<Schema.$Array<Schema.Struct<{
204
+ readonly choices: Schema.optional<Schema.NullOr<Schema.$Array<Schema.StructWithRest<Schema.Struct<{
205
205
  readonly delta: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
206
206
  readonly content: Schema.optional<Schema.NullOr<Schema.String>>;
207
207
  readonly refusal: Schema.optional<Schema.NullOr<Schema.String>>;
@@ -220,11 +220,29 @@ export declare const OpenAIChatEvent: Schema.Struct<{
220
220
  }>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
221
221
  readonly finish_reason: Schema.optional<Schema.NullOr<Schema.String>>;
222
222
  readonly native_finish_reason: Schema.optional<Schema.NullOr<Schema.String>>;
223
- }>>>>;
223
+ readonly usage: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
224
+ readonly prompt_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
225
+ readonly completion_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
226
+ readonly total_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
227
+ readonly cached_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
228
+ readonly prompt_cache_hit_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
229
+ readonly prompt_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
230
+ readonly cached_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
231
+ readonly cache_write_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
232
+ }>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
233
+ readonly completion_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
234
+ readonly reasoning_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
235
+ readonly accepted_prediction_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
236
+ readonly rejected_prediction_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
237
+ }>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
238
+ }>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
239
+ }>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>>;
224
240
  readonly usage: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
225
241
  readonly prompt_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
226
242
  readonly completion_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
227
243
  readonly total_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
244
+ readonly cached_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
245
+ readonly prompt_cache_hit_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
228
246
  readonly prompt_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
229
247
  readonly cached_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
230
248
  readonly cache_write_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
@@ -566,6 +584,8 @@ export declare const protocol: Protocol<{
566
584
  readonly prompt_tokens?: number | null | undefined;
567
585
  readonly completion_tokens?: number | null | undefined;
568
586
  readonly total_tokens?: number | null | undefined;
587
+ readonly cached_tokens?: number | null | undefined;
588
+ readonly prompt_cache_hit_tokens?: number | null | undefined;
569
589
  readonly prompt_tokens_details?: {
570
590
  readonly [x: string]: unknown;
571
591
  readonly cached_tokens?: number | null | undefined;
@@ -579,6 +599,7 @@ export declare const protocol: Protocol<{
579
599
  } | null | undefined;
580
600
  } | null | undefined;
581
601
  readonly choices?: readonly {
602
+ readonly [x: string]: unknown;
582
603
  readonly delta?: {
583
604
  readonly [x: string]: unknown;
584
605
  readonly reasoning?: string | null | undefined;
@@ -596,6 +617,25 @@ export declare const protocol: Protocol<{
596
617
  }[] | null | undefined;
597
618
  readonly reasoning_details?: unknown;
598
619
  } | null | undefined;
620
+ readonly usage?: {
621
+ readonly [x: string]: unknown;
622
+ readonly prompt_tokens?: number | null | undefined;
623
+ readonly completion_tokens?: number | null | undefined;
624
+ readonly total_tokens?: number | null | undefined;
625
+ readonly cached_tokens?: number | null | undefined;
626
+ readonly prompt_cache_hit_tokens?: number | null | undefined;
627
+ readonly prompt_tokens_details?: {
628
+ readonly [x: string]: unknown;
629
+ readonly cached_tokens?: number | null | undefined;
630
+ readonly cache_write_tokens?: number | null | undefined;
631
+ } | null | undefined;
632
+ readonly completion_tokens_details?: {
633
+ readonly [x: string]: unknown;
634
+ readonly reasoning_tokens?: number | null | undefined;
635
+ readonly accepted_prediction_tokens?: number | null | undefined;
636
+ readonly rejected_prediction_tokens?: number | null | undefined;
637
+ } | null | undefined;
638
+ } | null | undefined;
599
639
  readonly finish_reason?: string | null | undefined;
600
640
  readonly native_finish_reason?: string | null | undefined;
601
641
  }[] | null | undefined;
@@ -123,6 +123,9 @@ const OpenAIChatUsage = Schema.StructWithRest(Schema.Struct({
123
123
  prompt_tokens: optionalNull(Schema.Number),
124
124
  completion_tokens: optionalNull(Schema.Number),
125
125
  total_tokens: optionalNull(Schema.Number),
126
+ // Zai reports cache hits as top-level `cached_tokens`; DeepSeek uses `prompt_cache_hit_tokens`.
127
+ cached_tokens: optionalNull(Schema.Number),
128
+ prompt_cache_hit_tokens: optionalNull(Schema.Number),
126
129
  prompt_tokens_details: optionalNull(Schema.StructWithRest(Schema.Struct({
127
130
  cached_tokens: optionalNull(Schema.Number),
128
131
  cache_write_tokens: optionalNull(Schema.Number),
@@ -151,11 +154,13 @@ const OpenAIChatDelta = Schema.StructWithRest(Schema.Struct({
151
154
  reasoning_details: optionalNull(Schema.Unknown),
152
155
  tool_calls: optionalNull(Schema.Array(OpenAIChatToolCallDelta)),
153
156
  }), [Schema.Record(Schema.String, Schema.Unknown)]);
154
- const OpenAIChatChoice = Schema.Struct({
157
+ const OpenAIChatChoice = Schema.StructWithRest(Schema.Struct({
155
158
  delta: optionalNull(OpenAIChatDelta),
156
159
  finish_reason: optionalNull(Schema.String),
157
160
  native_finish_reason: optionalNull(Schema.String),
158
- });
161
+ // Moonshot streams usage on `choice.usage` instead of top-level `usage`.
162
+ usage: optionalNull(OpenAIChatUsage),
163
+ }), [Schema.Record(Schema.String, Schema.Unknown)]);
159
164
  const OpenAIChatError = Schema.Struct({
160
165
  code: optionalNull(Schema.Union([Schema.String, Schema.Number])),
161
166
  message: Schema.String,
@@ -170,7 +175,7 @@ const lowerTool = (tool, inputSchema, options) => ({
170
175
  function: {
171
176
  name: tool.name,
172
177
  description: tool.description,
173
- parameters: ToolSchemaProjection.openAI(inputSchema),
178
+ parameters: inputSchema,
174
179
  },
175
180
  cache_control: options.cacheControl?.(tool.cache),
176
181
  });
@@ -396,11 +401,24 @@ const lowerMessages = Effect.fn("OpenAIChat.lowerMessages")(function* (request,
396
401
  flushImages();
397
402
  return messages;
398
403
  });
404
+ // Anthropic via LiteLLM and Amazon Bedrock require `tools` to be present
405
+ // whenever the conversation history contains tool calls/results. Send an
406
+ // explicit empty array when we have history but no active tools.
407
+ const hasToolHistory = (messages) => {
408
+ for (const message of messages) {
409
+ if (message.role === "tool")
410
+ return true;
411
+ if (message.role === "assistant" && message.content.some((part) => part.type === "tool-call"))
412
+ return true;
413
+ }
414
+ return false;
415
+ };
399
416
  const lowerOptions = (request) => {
400
417
  const options = OpenAIOptions.resolve(request);
418
+ const cacheKey = ProviderShared.clampPromptCacheKey(request.promptCacheKey);
401
419
  return {
402
420
  ...(options.store !== undefined ? { store: options.store } : {}),
403
- ...(request.promptCacheKey ? { prompt_cache_key: request.promptCacheKey } : {}),
421
+ ...(cacheKey ? { prompt_cache_key: cacheKey } : {}),
404
422
  ...(options.reasoningEffort ? { reasoning_effort: options.reasoningEffort } : {}),
405
423
  };
406
424
  };
@@ -413,11 +431,14 @@ export const fromRequest = Effect.fn("OpenAIChat.fromRequest")(function* (reques
413
431
  const generation = request.generation;
414
432
  const toolSchemaCompatibility = request.model.compatibility?.toolSchema;
415
433
  const maxTokensField = request.model.compatibility?.maxTokensField ?? "max_tokens";
434
+ const hasHistory = hasToolHistory(request.messages);
416
435
  return {
417
436
  model: request.model.id,
418
437
  messages: yield* lowerMessages(request, options),
419
438
  tools: request.tools.length === 0
420
- ? undefined
439
+ ? hasHistory
440
+ ? []
441
+ : undefined
421
442
  : request.tools.map((tool) => lowerTool(tool, ToolSchemaProjection.modelCompatibility(tool.inputSchema, toolSchemaCompatibility), options)),
422
443
  tool_choice: request.toolChoice ? yield* lowerToolChoice(request.toolChoice) : undefined,
423
444
  stream: true,
@@ -458,12 +479,18 @@ const mapFinishReason = (reason) => {
458
479
  // total) with a `reasoning_tokens` subset. We pass the inclusive totals
459
480
  // through and derive the non-cached breakdown so the `AI.Usage` contract is
460
481
  // satisfied on both sides.
482
+ // Providers differ on cache-hit location: OpenAI uses
483
+ // `prompt_tokens_details.cached_tokens`, DeepSeek uses
484
+ // `prompt_cache_hit_tokens`, and Zai uses top-level `cached_tokens`.
461
485
  const mapUsage = (usage) => {
462
486
  if (!usage)
463
487
  return undefined;
464
488
  const input = usage.prompt_tokens ?? undefined;
465
489
  const output = usage.completion_tokens ?? undefined;
466
- const cached = usage.prompt_tokens_details?.cached_tokens ?? undefined;
490
+ const cached = (usage.prompt_tokens_details?.cached_tokens ??
491
+ usage.prompt_cache_hit_tokens ??
492
+ usage.cached_tokens ??
493
+ undefined);
467
494
  const cacheWrite = usage.prompt_tokens_details?.cache_write_tokens ?? undefined;
468
495
  const reasoning = usage.completion_tokens_details?.reasoning_tokens ?? undefined;
469
496
  const nonCached = ProviderShared.subtractTokens(input, ProviderShared.sumTokens(cached, cacheWrite));
@@ -554,8 +581,11 @@ const step = (state, event) => Effect.gen(function* () {
554
581
  }),
555
582
  });
556
583
  const events = [];
557
- const usage = mapUsage(event.usage) ?? state.usage;
558
584
  const choice = event.choices?.[0];
585
+ // Moonshot (and a few other OpenAI-compatible providers) attach usage to
586
+ // `choice.usage` instead of the top-level `usage` field.
587
+ const choiceUsage = choice?.usage;
588
+ const usage = mapUsage(event.usage) ?? (choiceUsage ? mapUsage(choiceUsage) : undefined) ?? state.usage;
559
589
  const rawFinishReason = choice?.finish_reason;
560
590
  const finishReason = rawFinishReason !== undefined && rawFinishReason !== null
561
591
  ? { normalized: mapFinishReason(rawFinishReason), raw: choice?.native_finish_reason ?? rawFinishReason }
@@ -117,7 +117,7 @@ export declare const route: Route<{
117
117
  readonly presence_penalty?: number | undefined;
118
118
  readonly safety_identifier?: string | undefined;
119
119
  readonly top_logprobs?: number | undefined;
120
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
120
+ readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
121
121
  readonly max_output_tokens?: number | undefined;
122
122
  readonly max_tool_calls?: number | undefined;
123
123
  readonly parallel_tool_calls?: boolean | undefined;
@@ -112,7 +112,7 @@ declare const OpenAIResponsesBody: Schema.Struct<{
112
112
  }>>;
113
113
  readonly top_logprobs: Schema.optional<Schema.Int>;
114
114
  readonly truncation: Schema.optional<Schema.Literals<readonly ["auto", "disabled"]>>;
115
- readonly service_tier: Schema.optional<Schema.Literals<readonly ["auto", "default", "flex", "priority"]>>;
115
+ readonly service_tier: Schema.optional<Schema.declare<import("./utils/open-responses-options.js").ServiceTier, import("./utils/open-responses-options.js").ServiceTier>>;
116
116
  readonly prompt_cache_key: Schema.optional<Schema.String>;
117
117
  readonly include: Schema.optional<Schema.$Array<Schema.declare<import("./utils/open-responses-options.js").ResponseIncludable, import("./utils/open-responses-options.js").ResponseIncludable>>>;
118
118
  readonly reasoning: Schema.optional<Schema.Struct<{
@@ -255,7 +255,7 @@ export declare const protocol: Protocol<{
255
255
  readonly presence_penalty?: number | undefined;
256
256
  readonly safety_identifier?: string | undefined;
257
257
  readonly top_logprobs?: number | undefined;
258
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
258
+ readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
259
259
  readonly max_output_tokens?: number | undefined;
260
260
  readonly max_tool_calls?: number | undefined;
261
261
  readonly parallel_tool_calls?: boolean | undefined;
@@ -438,7 +438,7 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
438
438
  readonly presence_penalty?: number | undefined;
439
439
  readonly safety_identifier?: string | undefined;
440
440
  readonly top_logprobs?: number | undefined;
441
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
441
+ readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
442
442
  readonly max_output_tokens?: number | undefined;
443
443
  readonly max_tool_calls?: number | undefined;
444
444
  readonly parallel_tool_calls?: boolean | undefined;
@@ -567,7 +567,7 @@ export declare const channelTransport: (options: import("./open-responses-channe
567
567
  readonly presence_penalty?: number | undefined;
568
568
  readonly safety_identifier?: string | undefined;
569
569
  readonly top_logprobs?: number | undefined;
570
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
570
+ readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
571
571
  readonly max_output_tokens?: number | undefined;
572
572
  readonly max_tool_calls?: number | undefined;
573
573
  readonly parallel_tool_calls?: boolean | undefined;
@@ -696,7 +696,7 @@ export declare const transport: import("../route/transport/index.js").Transport<
696
696
  readonly presence_penalty?: number | undefined;
697
697
  readonly safety_identifier?: string | undefined;
698
698
  readonly top_logprobs?: number | undefined;
699
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
699
+ readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
700
700
  readonly max_output_tokens?: number | undefined;
701
701
  readonly max_tool_calls?: number | undefined;
702
702
  readonly parallel_tool_calls?: boolean | undefined;
@@ -825,7 +825,7 @@ export declare const route: Route<{
825
825
  readonly presence_penalty?: number | undefined;
826
826
  readonly safety_identifier?: string | undefined;
827
827
  readonly top_logprobs?: number | undefined;
828
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
828
+ readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
829
829
  readonly max_output_tokens?: number | undefined;
830
830
  readonly max_tool_calls?: number | undefined;
831
831
  readonly parallel_tool_calls?: boolean | undefined;
@@ -109,13 +109,12 @@ const HOSTED_TOOLS = {
109
109
  name: "code_interpreter",
110
110
  input: (item) => ({ code: item.code, container_id: item.container_id }),
111
111
  },
112
- computer_use_call: { name: "computer_use", input: (item) => item.action ?? {} },
112
+ computer_call: { name: "computer_use", input: (item) => item.action ?? {} },
113
113
  image_generation_call: { name: "image_generation", input: () => ({}), result: hostedToolResult },
114
114
  mcp_call: {
115
115
  name: "mcp",
116
116
  input: (item) => ({ server_label: item.server_label, name: item.name, arguments: item.arguments }),
117
117
  },
118
- local_shell_call: { name: "local_shell", input: (item) => item.action ?? {} },
119
118
  };
120
119
  const step = (state, event) => {
121
120
  if (event.type === "response.reasoning_text.delta" || event.type === "response.reasoning_summary.delta")
@@ -10,6 +10,8 @@ export declare const encodeJson: (input: unknown, options?: import("effect/Schem
10
10
  export declare const JsonObject: Schema.$Record<Schema.String, Schema.Unknown>;
11
11
  export declare const optionalArray: <const S extends Schema.Top>(schema: S) => Schema.optional<Schema.$Array<S>>;
12
12
  export declare const optionalNull: <const S extends Schema.Top>(schema: S) => Schema.optional<Schema.NullOr<S>>;
13
+ export declare const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
14
+ export declare const clampPromptCacheKey: (key: string | undefined) => string | undefined;
13
15
  /**
14
16
  * Streaming tool-call accumulator. Adapters that build a tool call across
15
17
  * multiple `tool-input-delta` chunks store the partial JSON input string here
@@ -13,6 +13,17 @@ const isJson = Schema.is(Schema.Json);
13
13
  export const JsonObject = Schema.Record(Schema.String, Schema.Unknown);
14
14
  export const optionalArray = (schema) => Schema.optional(Schema.Array(schema));
15
15
  export const optionalNull = (schema) => Schema.optional(Schema.NullOr(schema));
16
+ export const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
17
+ // OpenAI limits `prompt_cache_key` to 64 chars; DeepSeek and Zai inherit the same
18
+ // limit via their OpenAI-compatible APIs. Clamp with unicode-aware slicing.
19
+ export const clampPromptCacheKey = (key) => {
20
+ if (key === undefined)
21
+ return undefined;
22
+ const chars = Array.from(key);
23
+ if (chars.length <= OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH)
24
+ return key;
25
+ return chars.slice(0, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH).join("");
26
+ };
16
27
  /**
17
28
  * `Usage.totalTokens` policy shared by every route. Honors a provider-
18
29
  * supplied total; otherwise falls back to `inputTokens + outputTokens` only
@@ -9,12 +9,13 @@ export declare const TextVerbosity: Schema.declare<TextVerbosity, TextVerbosity>
9
9
  export declare const ResponseIncludables: readonly ["file_search_call.results", "web_search_call.results", "web_search_call.action.sources", "message.input_image.image_url", "computer_call_output.output.image_url", "code_interpreter_call.outputs", "reasoning.encrypted_content", "message.output_text.logprobs"];
10
10
  export type ResponseIncludable = (typeof ResponseIncludables)[number] | (string & {});
11
11
  export declare const ServiceTiers: readonly ["auto", "default", "flex", "priority"];
12
- export type ServiceTier = (typeof ServiceTiers)[number];
12
+ export type ServiceTier = (typeof ServiceTiers)[number] | (string & {});
13
+ export declare const ServiceTier: Schema.declare<ServiceTier, ServiceTier>;
13
14
  export declare const Truncations: readonly ["auto", "disabled"];
14
15
  export type Truncation = (typeof Truncations)[number];
15
16
  export declare const TextVerbositySchema: Schema.declare<TextVerbosity, TextVerbosity>;
16
17
  export declare const ResponseIncludableSchema: Schema.declare<ResponseIncludable, ResponseIncludable>;
17
- export declare const ServiceTierSchema: Schema.Literals<readonly ["auto", "default", "flex", "priority"]>;
18
+ export declare const ServiceTierSchema: Schema.declare<ServiceTier, ServiceTier>;
18
19
  export declare const TruncationSchema: Schema.Literals<readonly ["auto", "disabled"]>;
19
20
  export declare const AllowedTools: Schema.Struct<{
20
21
  readonly toolNames: Schema.$Array<Schema.String>;
@@ -37,7 +38,7 @@ export declare const Options: Schema.Struct<{
37
38
  readonly reasoningSummary: Schema.optional<Schema.Literals<readonly ["auto", "concise", "detailed"]>>;
38
39
  readonly include: Schema.optional<Schema.$Array<Schema.declare<ResponseIncludable, ResponseIncludable>>>;
39
40
  readonly textVerbosity: Schema.optional<Schema.declare<TextVerbosity, TextVerbosity>>;
40
- readonly serviceTier: Schema.optional<Schema.Literals<readonly ["auto", "default", "flex", "priority"]>>;
41
+ readonly serviceTier: Schema.optional<Schema.declare<ServiceTier, ServiceTier>>;
41
42
  readonly truncation: Schema.optional<Schema.Literals<readonly ["auto", "disabled"]>>;
42
43
  readonly allowedTools: Schema.optional<Schema.Struct<{
43
44
  readonly toolNames: Schema.$Array<Schema.String>;
@@ -14,10 +14,11 @@ export const ResponseIncludables = [
14
14
  "message.output_text.logprobs",
15
15
  ];
16
16
  export const ServiceTiers = ["auto", "default", "flex", "priority"];
17
+ export const ServiceTier = Schema.declare((value) => typeof value === "string", { title: "ServiceTier" });
17
18
  export const Truncations = ["auto", "disabled"];
18
19
  export const TextVerbositySchema = TextVerbosity;
19
20
  export const ResponseIncludableSchema = Schema.declare((value) => typeof value === "string", { title: "ResponseIncludable" });
20
- export const ServiceTierSchema = Schema.Literals(ServiceTiers);
21
+ export const ServiceTierSchema = ServiceTier;
21
22
  export const TruncationSchema = Schema.Literals(Truncations);
22
23
  export const AllowedTools = Schema.Struct({
23
24
  toolNames: Schema.Array(Schema.String),
@@ -5,12 +5,12 @@ export declare const OpenAITextVerbosities: readonly ["low", "medium", "high"];
5
5
  export type OpenAITextVerbosity = OpenResponsesOptions.TextVerbosity;
6
6
  export declare const OpenAIResponseIncludables: readonly ["file_search_call.results", "web_search_call.results", "web_search_call.action.sources", "message.input_image.image_url", "computer_call_output.output.image_url", "code_interpreter_call.outputs", "reasoning.encrypted_content", "message.output_text.logprobs"];
7
7
  export type OpenAIResponseIncludable = OpenResponsesOptions.ResponseIncludable;
8
- export declare const OpenAIServiceTiers: readonly ["auto", "default", "flex", "priority"];
9
- export type OpenAIServiceTier = OpenResponsesOptions.ServiceTier;
8
+ export declare const OpenAIServiceTiers: readonly ["auto", "default", "flex", "priority", "scale"];
9
+ export type OpenAIServiceTier = (typeof OpenAIServiceTiers)[number] | (string & {});
10
10
  export declare const OpenAIReasoningEffort: import("effect/Schema").declare<OpenResponsesOptions.ReasoningEffort, OpenResponsesOptions.ReasoningEffort>;
11
11
  export declare const OpenAITextVerbosity: import("effect/Schema").declare<OpenResponsesOptions.TextVerbosity, OpenResponsesOptions.TextVerbosity>;
12
12
  export declare const OpenAIResponseIncludable: import("effect/Schema").declare<OpenResponsesOptions.ResponseIncludable, OpenResponsesOptions.ResponseIncludable>;
13
- export declare const OpenAIServiceTier: import("effect/Schema").Literals<readonly ["auto", "default", "flex", "priority"]>;
13
+ export declare const OpenAIServiceTier: import("effect/Schema").declare<OpenResponsesOptions.ServiceTier, OpenResponsesOptions.ServiceTier>;
14
14
  export declare const isReasoningEffort: (effort: unknown) => effort is OpenAIReasoningEffort;
15
15
  export declare const resolve: (request: import("../../index.js").LLMRequest) => OpenResponsesOptions.Resolved;
16
16
  export * as OpenAIOptions from "./openai-options.js";
@@ -4,7 +4,7 @@ export const OpenAITextVerbosities = OpenResponsesOptions.TextVerbosities;
4
4
  // Mirrors OpenAI's `ResponseIncludable` union from the official SDK. Keep this
5
5
  // in lockstep with `openai-node/src/resources/responses/responses.ts`.
6
6
  export const OpenAIResponseIncludables = OpenResponsesOptions.ResponseIncludables;
7
- export const OpenAIServiceTiers = OpenResponsesOptions.ServiceTiers;
7
+ export const OpenAIServiceTiers = [...OpenResponsesOptions.ServiceTiers, "scale"];
8
8
  export const OpenAIReasoningEffort = OpenResponsesOptions.ReasoningEffort;
9
9
  export const OpenAITextVerbosity = OpenResponsesOptions.TextVerbosity;
10
10
  export const OpenAIResponseIncludable = OpenResponsesOptions.ResponseIncludableSchema;
@@ -1,20 +1,5 @@
1
1
  import { isRecord } from "../../utils/record.js";
2
2
  import { GeminiToolSchema } from "./gemini-tool-schema.js";
3
- const removeNullSchemas = (value) => {
4
- if (Array.isArray(value))
5
- return value.map(removeNullSchemas);
6
- if (!isRecord(value))
7
- return value;
8
- const fields = Object.fromEntries(Object.entries(value)
9
- .filter(([key]) => key !== "anyOf")
10
- .map(([key, field]) => [key, removeNullSchemas(field)]));
11
- if (!Array.isArray(value.anyOf))
12
- return fields;
13
- const variants = value.anyOf.filter((variant) => !isRecord(variant) || variant.type !== "null").map(removeNullSchemas);
14
- if (variants.length === 1 && isRecord(variants[0]))
15
- return { ...fields, ...variants[0] };
16
- return { ...fields, anyOf: variants };
17
- };
18
3
  const tupleItemsSchema = (items) => {
19
4
  const projected = items.map(moonshotNode);
20
5
  if (projected.length === 0)
@@ -47,19 +32,7 @@ const moonshot = (schema) => {
47
32
  const projected = moonshotNode(schema);
48
33
  return isRecord(projected) ? projected : {};
49
34
  };
50
- const openAI = (schema) => {
51
- const variants = Array.isArray(schema.anyOf) ? schema.anyOf.filter(isRecord) : [];
52
- const flattened = variants.length === 0
53
- ? { ...schema, type: "object" }
54
- : {
55
- ...Object.fromEntries(Object.entries(schema).filter(([key]) => key !== "anyOf")),
56
- type: "object",
57
- properties: variants.reduce((properties, variant) => ({ ...(isRecord(variant.properties) ? variant.properties : {}), ...properties }), {}),
58
- additionalProperties: false,
59
- };
60
- const normalized = removeNullSchemas(flattened);
61
- return isRecord(normalized) ? normalized : { type: "object" };
62
- };
35
+ const openAI = (schema) => schema;
63
36
  const responses = openAI;
64
37
  const gemini = (schema) => GeminiToolSchema.convert(schema) ?? {};
65
38
  const modelCompatibility = (schema, compatibility) => {
@@ -112,7 +112,7 @@ export declare const protocol: Protocol<{
112
112
  readonly presence_penalty?: number | undefined;
113
113
  readonly safety_identifier?: string | undefined;
114
114
  readonly top_logprobs?: number | undefined;
115
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
115
+ readonly service_tier?: import("./utils/open-responses-options.js").ServiceTier | undefined;
116
116
  readonly max_output_tokens?: number | undefined;
117
117
  readonly max_tool_calls?: number | undefined;
118
118
  readonly parallel_tool_calls?: boolean | undefined;
@@ -239,31 +239,31 @@ export declare const routes: (RouteDef<{
239
239
  readonly presence_penalty?: number | undefined;
240
240
  readonly safety_identifier?: string | undefined;
241
241
  readonly top_logprobs?: number | undefined;
242
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
242
+ readonly service_tier?: import("../protocols/utils/open-responses-options.js").ServiceTier | undefined;
243
243
  readonly max_output_tokens?: number | undefined;
244
244
  readonly max_tool_calls?: number | undefined;
245
245
  readonly parallel_tool_calls?: boolean | undefined;
246
246
  }, import("../protocols/open-responses-channel.js").Prepared>)[];
247
247
  export declare const configure: (input?: Config) => {
248
248
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
249
- model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
250
- chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
251
- responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
249
+ model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
250
+ chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
251
+ responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
252
252
  configure: (input?: Config) => /*elided*/ any;
253
253
  };
254
254
  export declare const provider: {
255
255
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
256
- model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
257
- chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
258
- responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
256
+ model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
257
+ chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
258
+ responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
259
259
  configure: (input?: Config) => {
260
260
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
261
- model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
262
- chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
263
- responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
261
+ model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
262
+ chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
263
+ responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
264
264
  configure: /*elided*/ any;
265
265
  };
266
266
  };
267
267
  export declare const chatModel: ProviderPackage.Definition<Settings, OpenAIProviderOptionsInput>["model"];
268
268
  export declare const responsesModel: ProviderPackage.Definition<Settings, OpenAIProviderOptionsInput>["model"];
269
- export declare const model: (modelID: string, settings: Settings) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
269
+ export declare const model: (modelID: string, settings: Settings) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
@@ -182,6 +182,7 @@ export declare const routes: import("../route/client.js").Route<{
182
182
  readonly thinking?: {
183
183
  readonly type: "enabled";
184
184
  readonly budget_tokens: number;
185
+ readonly display?: "summarized" | "omitted" | undefined;
185
186
  } | {
186
187
  readonly type: "adaptive";
187
188
  readonly display?: "summarized" | "omitted" | undefined;
@@ -166,6 +166,7 @@ export declare const routes: import("../route/client.js").Route<{
166
166
  readonly thinking?: {
167
167
  readonly type: "enabled";
168
168
  readonly budget_tokens: number;
169
+ readonly display?: "summarized" | "omitted" | undefined;
169
170
  } | {
170
171
  readonly type: "adaptive";
171
172
  readonly display?: "summarized" | "omitted" | undefined;
@@ -242,29 +242,29 @@ export declare const routes: (RouteDef<{
242
242
  readonly presence_penalty?: number | undefined;
243
243
  readonly safety_identifier?: string | undefined;
244
244
  readonly top_logprobs?: number | undefined;
245
- readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
245
+ readonly service_tier?: import("../protocols/utils/open-responses-options.js").ServiceTier | undefined;
246
246
  readonly max_output_tokens?: number | undefined;
247
247
  readonly max_tool_calls?: number | undefined;
248
248
  readonly parallel_tool_calls?: boolean | undefined;
249
249
  }, import("../protocols/open-responses-channel.js").Prepared>)[];
250
250
  export declare const configure: (input: Config) => {
251
251
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
252
- model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
253
- responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
254
- chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
252
+ model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
253
+ responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
254
+ chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
255
255
  configure: (input: Config) => /*elided*/ any;
256
256
  };
257
257
  export declare const provider: {
258
258
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
259
259
  configure: (input: Config) => {
260
260
  id: string & import("effect/Brand").Brand<"AI.ProviderID">;
261
- model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
262
- responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
263
- chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
261
+ model: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
262
+ responses: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
263
+ chat: (modelID: string | ModelID) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
264
264
  configure: /*elided*/ any;
265
265
  };
266
266
  };
267
267
  export declare const responsesModel: ProviderPackage.Definition<Settings, OpenAIProviderOptionsInput>["model"];
268
268
  export declare const chatModel: ProviderPackage.Definition<Settings, OpenAIProviderOptionsInput>["model"];
269
- export declare const model: (modelID: string, settings: Settings) => import("../schema/options.js").LanguageModel<import("./open-responses-options.js").OpenResponsesOptionsInput>;
269
+ export declare const model: (modelID: string, settings: Settings) => import("../schema/options.js").LanguageModel<import("./openai-options.js").OpenAIOptionsInput>;
270
270
  export {};