@openclaw/ai 2026.9.2 → 2026.9.4

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 (115) hide show
  1. package/README.md +3 -2
  2. package/dist/anthropic-C4Qu4H0Z.mjs +377 -0
  3. package/dist/{anthropic-payload-policy-d46X2pR0.d.mts → anthropic-payload-policy-BZ8umAbk.d.mts} +16 -6
  4. package/dist/{anthropic-compaction-replay-DB2FGLQc.mjs → anthropic-stream-reducer-CILWF7JD.mjs} +931 -184
  5. package/dist/{api-registry-DWtPjzyn.d.mts → api-registry-ByUwIR0e.d.mts} +2 -2
  6. package/dist/assistant-output-tLt4H-iQ.mjs +16 -0
  7. package/dist/assistant-text-phase-C20rxWwP.mjs +55 -0
  8. package/dist/{azure-openai-responses-C5bZRfAP.mjs → azure-openai-responses-BAlqlKKc.mjs} +5 -5
  9. package/dist/{base64-CEFBpSkN.mjs → base64-D-su8YVo.mjs} +1 -27
  10. package/dist/{diagnostics-DfFyKeX_.mjs → diagnostics-QuErwCIl.mjs} +96 -21
  11. package/dist/diagnostics.d.mts +3 -1
  12. package/dist/diagnostics.mjs +3 -3
  13. package/dist/{event-stream-BhT5T1Ay.d.mts → event-stream-Bt5Y4Pav.d.mts} +11 -3
  14. package/dist/event-stream-C3WGFsum.d.mts +1 -0
  15. package/dist/{event-stream-BgDvQeum.mjs → event-stream-D8PARQfL.mjs} +45 -1
  16. package/dist/event-stream.d.mts +2 -2
  17. package/dist/event-stream.mjs +1 -1
  18. package/dist/{github-copilot-headers-NCJtz9i0.mjs → github-copilot-headers-B37TB3rB.mjs} +3 -10
  19. package/dist/github-copilot-request-facts-BTEBMeOv.mjs +16 -0
  20. package/dist/{google-4qeuE8iX.mjs → google-DPBAOaOW.mjs} +10 -10
  21. package/dist/google-messages-6JkpHrhJ.mjs +448 -0
  22. package/dist/google-shared-BvBeW9aq.mjs +185 -0
  23. package/dist/{google-vertex-O9BcnB6X.mjs → google-vertex-k-TMCAYD.mjs} +7 -6
  24. package/dist/{host-DjzGmdZ2.d.mts → host-4atIX-2V.d.mts} +5 -3
  25. package/dist/{host-CEvLw30U.mjs → host-B8YfDGd4.mjs} +181 -41
  26. package/dist/host-policy-Zcg_cNz8.mjs +37 -0
  27. package/dist/{index-FnHM2FcI.d.mts → index-DdD3qerf.d.mts} +4 -4
  28. package/dist/index.d.mts +7 -7
  29. package/dist/index.mjs +7 -6
  30. package/dist/internal/anthropic.d.mts +7 -7
  31. package/dist/internal/anthropic.mjs +4 -4
  32. package/dist/internal/google-model-family.d.mts +5 -0
  33. package/dist/internal/google-model-family.mjs +15 -0
  34. package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
  35. package/dist/internal/openai-responses-payload-policy.mjs +3 -2
  36. package/dist/internal/openai.d.mts +8 -103
  37. package/dist/internal/openai.mjs +9 -10
  38. package/dist/internal/retry-after.d.mts +2 -4
  39. package/dist/internal/retry-after.mjs +57 -8
  40. package/dist/internal/runtime.d.mts +43 -7
  41. package/dist/internal/runtime.mjs +6 -7
  42. package/dist/internal/shared.d.mts +43 -3
  43. package/dist/internal/shared.mjs +5 -4
  44. package/dist/internal/tool-schema.d.mts +63 -0
  45. package/dist/internal/tool-schema.mjs +3 -0
  46. package/dist/{mistral-Tb6oalqH.mjs → mistral-CxUZ1jUb.mjs} +10 -37
  47. package/dist/model-transport-url-DKocrEsb.d.mts +28 -0
  48. package/dist/{openai-chatgpt-responses-yUXjPNfu.mjs → openai-chatgpt-responses-CgO6kZfo.mjs} +50 -41
  49. package/dist/{openai-completions-compat-CpjYUArk.d.mts → openai-completions-compat-eHgh5UPE.d.mts} +26 -4
  50. package/dist/{openai-completions-stream-BsrBe3Gg.mjs → openai-completions-stream-Da2vvl-S.mjs} +654 -453
  51. package/dist/openai-completions-yJuk7eis.mjs +187 -0
  52. package/dist/openai-prompt-cache-B4eYo2-I.d.mts +16 -0
  53. package/dist/openai-prompt-cache-Bds-n_9Q.mjs +220 -0
  54. package/dist/openai-provider-client-S2gCrM2Z.mjs +24 -0
  55. package/dist/{openai-responses-CCL41ALM.mjs → openai-responses-DaYwH05E.mjs} +14 -29
  56. package/dist/{openai-responses-compaction-window-BMVHFOtq.mjs → openai-responses-compaction-window-CIhBAkkq.mjs} +6 -246
  57. package/dist/{openai-responses-contracts-rF5DDRNS.d.mts → openai-responses-contracts-BjBAqAg_.d.mts} +5 -38
  58. package/dist/openai-responses-contracts-DDOHA62Y.mjs +245 -0
  59. package/dist/{openai-responses-prompt-observer-internal-D0bhBfgL.mjs → openai-responses-prompt-observer-internal-f8J7wpsk.mjs} +3 -3
  60. package/dist/{openai-responses-shared-Bmma_3Qc.mjs → openai-responses-shared-B8RdBPCv.mjs} +47 -118
  61. package/dist/openai-tool-projection-793cE3QX.d.mts +37 -0
  62. package/dist/{openai-tool-schema-_pTAJqKF.mjs → openai-tool-schema-CzjyYXun.mjs} +38 -556
  63. package/dist/openai-tool-schema-ynZBgqW-.d.mts +38 -0
  64. package/dist/openai-transport-params-9aPuV5YY.mjs +675 -0
  65. package/dist/positive-integer-41zhOdcV.mjs +8 -0
  66. package/dist/{provider-error-9TraxGvt.mjs → provider-error-BA-v_tKd.mjs} +70 -11
  67. package/dist/{provider-options-Bcc_p-TU.d.mts → provider-options-Ceqv1OKk.d.mts} +4 -39
  68. package/dist/{provider-replay-context-BuSUaAk5.mjs → provider-replay-context-CJ_YvcEW.mjs} +1 -1
  69. package/dist/{provider-transcript-transform-BaMbI1hr.mjs → provider-transcript-transform-V5YzU9zh.mjs} +1 -1
  70. package/dist/provider-transport-turn-state-D5EXOFL2.mjs +42 -0
  71. package/dist/provider-types-CVjKjsuq.d.mts +29 -0
  72. package/dist/provider-types.d.mts +6 -31
  73. package/dist/providers.d.mts +2 -2
  74. package/dist/providers.mjs +11 -11
  75. package/dist/{reasoning-tag-text-partitioner-DLCNXki6.mjs → reasoning-tag-text-partitioner-BcR5pztD.mjs} +19 -19
  76. package/dist/record-coerce-DwRYMj3t.mjs +32 -0
  77. package/dist/retry-after-CdCURCVg.d.mts +15 -0
  78. package/dist/session-affinity-Bcunsn4I.mjs +23 -0
  79. package/dist/{simple-options-BjHCCh4v.mjs → simple-options-BQbb4yQL.mjs} +24 -5
  80. package/dist/src-DDmEryvj.mjs +2 -0
  81. package/dist/{stream-first-event-timeout-DcNjoFQE.mjs → stream-first-event-timeout-2hfrquuz.mjs} +1 -1
  82. package/dist/string-coerce-fsri9iCu.mjs +34 -0
  83. package/dist/{string-normalization--fwJ4S2q.mjs → string-normalization-CmLIasuf.mjs} +1 -1
  84. package/dist/{tool-schema-json-projection-mJhXDcyz.mjs → tool-schema-json-projection-ClptDdAO.mjs} +2 -38
  85. package/dist/{transport-stream-shared-xnaqxmbP.d.mts → transport-stream-shared-DNvmoWnv.d.mts} +20 -36
  86. package/dist/{transport-stream-shared-CZqMhfIw.mjs → transport-stream-shared-zHll9BxO.mjs} +225 -13
  87. package/dist/transport-utils-zrYjICLZ.mjs +118 -0
  88. package/dist/transports.d.mts +137 -193
  89. package/dist/transports.mjs +204 -1334
  90. package/dist/types-DlfwzH3T.d.mts +1 -0
  91. package/dist/types-LFWwv0cF.mjs +8 -0
  92. package/dist/{types-CJ1-Ht7A.d.mts → types-Ntv5z2g2.d.mts} +74 -57
  93. package/dist/types.d.mts +6 -6
  94. package/dist/types.mjs +6 -5
  95. package/dist/{src-2qBGKg8O.mjs → usage-cost-BNWbbXav.mjs} +0 -1
  96. package/dist/utf16-slice-CvGodqok.mjs +29 -0
  97. package/dist/{validation-AKZBDGQd.d.mts → validation-B0t_G2H6.d.mts} +1 -1
  98. package/dist/{validation-CJZtym2g.mjs → validation-BDzVDnTs.mjs} +9 -1
  99. package/dist/validation.d.mts +1 -1
  100. package/dist/validation.mjs +1 -1
  101. package/package.json +13 -3
  102. package/dist/anthropic-BDdqdVLK.mjs +0 -886
  103. package/dist/event-stream-zctLx0yr.d.mts +0 -1
  104. package/dist/google-shared-CWeG8RIl.mjs +0 -636
  105. package/dist/google-thinking-level-C-V3tecN.mjs +0 -9
  106. package/dist/hash-CHgqbJmD.mjs +0 -16
  107. package/dist/json-parse-BuAJEbdW.mjs +0 -146
  108. package/dist/openai-completions-BIUV3RDT.mjs +0 -403
  109. package/dist/openai-prompt-cache-CGnVB74a.mjs +0 -21
  110. package/dist/openai-prompt-cache-CNoIfHYC.d.mts +0 -16
  111. package/dist/sanitize-unicode-D6xUvZaS.mjs +0 -83
  112. package/dist/transport-utils-7il795_9.mjs +0 -138
  113. package/dist/types-3Lnm-QSJ.d.mts +0 -1
  114. package/dist/types-BDdaOVi2.mjs +0 -6
  115. package/dist/utf16-slice-qz3nsy87.mjs +0 -84
@@ -0,0 +1,187 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
+ import { t as AssistantMessageEventStream } from "./event-stream-D8PARQfL.mjs";
3
+ import { M as clampThinkingLevel } from "./host-B8YfDGd4.mjs";
4
+ import { s as resolveOpenAICompletionsCompat } from "./openai-prompt-cache-Bds-n_9Q.mjs";
5
+ import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
6
+ import { n as buildBaseOptions, o as reasoningTagTextPolicy } from "./simple-options-BQbb4yQL.mjs";
7
+ import { _ as createOpenAIProviderAcceptanceHook, y as isOpenAICompletionsThinkingEnabled } from "./openai-transport-params-9aPuV5YY.mjs";
8
+ import { n as getEnvApiKey } from "./env-api-keys-bktO00EJ.mjs";
9
+ import { b as withProviderResponseHook, n as assignTransportErrorDetails, v as transportAbortError } from "./transport-stream-shared-zHll9BxO.mjs";
10
+ import { a as tagUnresolvedTextAsCommentary, t as clearPendingCommentaryText } from "./assistant-text-phase-C20rxWwP.mjs";
11
+ import { t as createAssistantOutput } from "./assistant-output-tLt4H-iQ.mjs";
12
+ import { a as convertMessages, i as buildOpenAICompletionsRequest, s as finalizeOpenAICompletionsToolCalls, t as processCompletionsStream } from "./openai-completions-stream-Da2vvl-S.mjs";
13
+ import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-2hfrquuz.mjs";
14
+ import { n as resolveProviderSimpleCompletionHeaders } from "./provider-transport-turn-state-D5EXOFL2.mjs";
15
+ import { n as hasCopilotVisionInput, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-B37TB3rB.mjs";
16
+ import { t as createOpenAIProviderClient } from "./openai-provider-client-S2gCrM2Z.mjs";
17
+ //#region packages/ai/src/providers/openai-completions.ts
18
+ var openai_completions_exports = /* @__PURE__ */ __exportAll({
19
+ convertMessages: () => convertMessages,
20
+ streamOpenAICompletions: () => streamOpenAICompletions,
21
+ streamSimpleOpenAICompletions: () => streamSimpleOpenAICompletions
22
+ });
23
+ const streamOpenAICompletions = (model, context, options) => {
24
+ const stream = new AssistantMessageEventStream();
25
+ (async () => {
26
+ const output = createAssistantOutput(model);
27
+ const provisionalCommentaryTags = /* @__PURE__ */ new Map();
28
+ let firstEventAbort;
29
+ try {
30
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
31
+ const compat = resolveOpenAICompletionsCompat(model);
32
+ const shouldEmitReasoning = Boolean(model.reasoning && options?.reasoningEffort && isOpenAICompletionsThinkingEnabled(options.reasoningEffort));
33
+ const cacheRetention = resolveCacheRetention(options?.cacheRetention);
34
+ const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
35
+ const client = createClient(model, context, apiKey, resolveProviderSimpleCompletionHeaders(model, options), cacheSessionId, compat);
36
+ let params = buildOpenAICompletionsRequest(model, context, options, {
37
+ mode: "direct",
38
+ compat,
39
+ cacheRetention
40
+ });
41
+ const nextParams = await options?.onPayload?.(params, model);
42
+ if (nextParams !== void 0) params = nextParams;
43
+ firstEventAbort = createFirstStreamEventAbortController(options?.signal);
44
+ const requestOptions = {
45
+ signal: firstEventAbort.signal,
46
+ ...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
47
+ maxRetries: 0
48
+ };
49
+ const { data: openaiStream, response } = await client.chat.completions.create(params, requestOptions).withResponse();
50
+ const hookedOpenAIStream = withProviderResponseHook({
51
+ stream: openaiStream,
52
+ signal: firstEventAbort.signal,
53
+ abort: firstEventAbort.abort,
54
+ hook: createOpenAIProviderAcceptanceHook(options, response, model),
55
+ onReady: () => stream.push({
56
+ type: "start",
57
+ partial: output
58
+ })
59
+ });
60
+ const finishedBlocks = /* @__PURE__ */ new Set();
61
+ const contentIndices = /* @__PURE__ */ new WeakMap();
62
+ let openTextBlock;
63
+ let openThinkingBlock;
64
+ const finishBlock = (block) => {
65
+ const contentIndex = contentIndices.get(block);
66
+ if (contentIndex === void 0 || finishedBlocks.has(block)) return;
67
+ finishedBlocks.add(block);
68
+ if (block.type === "text") {
69
+ openTextBlock = void 0;
70
+ stream.push({
71
+ type: "text_end",
72
+ contentIndex,
73
+ content: block.text,
74
+ partial: output
75
+ });
76
+ } else if (block.type === "thinking") {
77
+ openThinkingBlock = void 0;
78
+ stream.push({
79
+ type: "thinking_end",
80
+ contentIndex,
81
+ content: block.thinking,
82
+ partial: output
83
+ });
84
+ } else if (block.type === "toolCall") stream.push({
85
+ type: "toolcall_end",
86
+ contentIndex,
87
+ toolCall: block,
88
+ partial: output
89
+ });
90
+ };
91
+ const directEventStream = { push(event) {
92
+ if (event.type === "text_start" || event.type === "thinking_start" || event.type === "toolcall_start") {
93
+ const block = output.content[event.contentIndex];
94
+ if (block) {
95
+ contentIndices.set(block, event.contentIndex);
96
+ if (block.type === "text") openTextBlock = block;
97
+ else if (block.type === "thinking") openThinkingBlock = block;
98
+ }
99
+ }
100
+ stream.push(event);
101
+ } };
102
+ try {
103
+ await processCompletionsStream(hookedOpenAIStream, output, model, directEventStream, {
104
+ mode: "direct",
105
+ beforeContentBlock(nextType) {
106
+ if (openThinkingBlock) finishBlock(openThinkingBlock);
107
+ if (openTextBlock && nextType !== "toolCall") finishBlock(openTextBlock);
108
+ },
109
+ provisionalCommentaryTags,
110
+ signal: options?.signal,
111
+ emitReasoning: shouldEmitReasoning,
112
+ strictReasoningTags: reasoningTagTextPolicy.isStrict(options),
113
+ firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
114
+ abortFirstEventStream: firstEventAbort.abort,
115
+ onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options)
116
+ });
117
+ if (options?.signal?.aborted) throw transportAbortError(options.signal);
118
+ if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage || (output.stopReason === "aborted" ? "Request was aborted" : "Provider returned an invalid tool call"));
119
+ } catch (error) {
120
+ for (const block of output.content) if (block.type !== "toolCall") finishBlock(block);
121
+ throw error;
122
+ }
123
+ for (const block of output.content) if (block.type !== "toolCall" || output.stopReason === "toolUse") finishBlock(block);
124
+ stream.push({
125
+ type: "done",
126
+ reason: output.stopReason,
127
+ message: output
128
+ });
129
+ stream.end();
130
+ } catch (error) {
131
+ const terminal = assignTransportErrorDetails(output, error, options?.signal);
132
+ finalizeOpenAICompletionsToolCalls(output, { allowSilentToolCallPromotion: false });
133
+ clearPendingCommentaryText(provisionalCommentaryTags);
134
+ tagUnresolvedTextAsCommentary(output);
135
+ for (const block of output.content) {
136
+ delete block.index;
137
+ delete block.partialArgs;
138
+ delete block.streamIndex;
139
+ }
140
+ stream.push({
141
+ type: "error",
142
+ reason: terminal.stopReason,
143
+ error: output
144
+ });
145
+ stream.end();
146
+ } finally {
147
+ firstEventAbort?.dispose();
148
+ }
149
+ })();
150
+ return stream;
151
+ };
152
+ const streamSimpleOpenAICompletions = (model, context, options) => {
153
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider);
154
+ if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
155
+ const base = buildBaseOptions(model, options, apiKey);
156
+ const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : void 0;
157
+ const reasoningEffort = clampedReasoning === "off" ? void 0 : clampedReasoning === "max" ? "xhigh" : clampedReasoning;
158
+ const toolChoice = options?.toolChoice;
159
+ return streamOpenAICompletions(model, context, {
160
+ ...base,
161
+ reasoningEffort,
162
+ toolChoice
163
+ });
164
+ };
165
+ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = resolveOpenAICompletionsCompat(model)) {
166
+ if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
167
+ const headers = { ...model.headers };
168
+ if (model.provider === "github-copilot") {
169
+ const hasImages = hasCopilotVisionInput(context.messages);
170
+ const copilotHeaders = buildCopilotDynamicHeaders({
171
+ messages: context.messages,
172
+ hasImages
173
+ });
174
+ Object.assign(headers, copilotHeaders);
175
+ }
176
+ if (sessionId && compat.sessionAffinity !== "none") {
177
+ if (compat.sessionAffinity === "openrouter") headers["x-session-id"] = sessionId;
178
+ else {
179
+ headers.session_id = sessionId;
180
+ headers["x-client-request-id"] = sessionId;
181
+ headers["x-session-affinity"] = sessionId;
182
+ }
183
+ }
184
+ return createOpenAIProviderClient(model, apiKey, headers, optionsHeaders);
185
+ }
186
+ //#endregion
187
+ export { streamOpenAICompletions as n, streamSimpleOpenAICompletions as r, openai_completions_exports as t };
@@ -0,0 +1,16 @@
1
+ import { M as OpenAICompletionsCompat, O as Model, l as CacheRetention } from "./types-Ntv5z2g2.mjs";
2
+ import "./types-DlfwzH3T.mjs";
3
+ //#region packages/ai/src/providers/openai-prompt-cache.d.ts
4
+ /** Selects documented lifetime fields shared by Responses and Chat Completions. */
5
+ declare function resolveOpenAIPromptCacheParams(model: Pick<Model, "id" | "provider" | "baseUrl">, cacheRetention: CacheRetention, compat: Required<Pick<OpenAICompletionsCompat, "supportsPromptCacheKey" | "supportsLongCacheRetention">>): {
6
+ prompt_cache_retention?: "24h";
7
+ prompt_cache_options?: {
8
+ ttl: "30m";
9
+ };
10
+ };
11
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
12
+ declare const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
13
+ /** Truncates a prompt cache key by Unicode code point count. */
14
+ declare function clampOpenAIPromptCacheKey(key: string | undefined): string | undefined;
15
+ //#endregion
16
+ export { clampOpenAIPromptCacheKey as n, resolveOpenAIPromptCacheParams as r, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
@@ -0,0 +1,220 @@
1
+ import { o as isRecord } from "./record-coerce-DwRYMj3t.mjs";
2
+ import { a as resolveProviderRequestCapabilities } from "./host-policy-Zcg_cNz8.mjs";
3
+ //#region packages/normalization-core/src/code-points.ts
4
+ /** Truncates to a nonnegative code-point budget; grapheme clusters may be split. */
5
+ function truncateCodePoints(text, maxCodePoints) {
6
+ const limit = Math.max(0, Math.trunc(maxCodePoints) || 0);
7
+ if (text.length <= limit) return text;
8
+ const prefix = [];
9
+ for (const codePoint of text) {
10
+ if (prefix.length >= limit) break;
11
+ prefix.push(codePoint);
12
+ }
13
+ return prefix.join("");
14
+ }
15
+ //#endregion
16
+ //#region packages/ai/src/providers/openai-response-format.ts
17
+ const JSON_SCHEMA_RESPONSE_FORMAT_NAME = "openclaw_response";
18
+ const OLLAMA_CLOUD_ORIGIN = "https://ollama.com";
19
+ function isKnownOpenAIJsonSchemaModelId(modelId) {
20
+ if (typeof modelId !== "string") return false;
21
+ if (/^gpt-5(?:[.-]|$)/i.test(modelId) || /^gpt-4\.1(?:-|$)/i.test(modelId)) return true;
22
+ const gpt4o = /^gpt-4o(-mini)?(?:-(\d{4}-\d{2}-\d{2}))?$/i.exec(modelId);
23
+ if (gpt4o) {
24
+ const snapshot = gpt4o[2];
25
+ return !snapshot || snapshot >= (gpt4o[1] ? "2024-07-18" : "2024-08-06");
26
+ }
27
+ return /^(?:o1|o3(?:-mini|-pro)?|o4-mini)(?:-\d{4}-\d{2}-\d{2})?$/i.test(modelId);
28
+ }
29
+ function shouldOmitOllamaCompatResponseFormat(params) {
30
+ if (!params.provider.includes("ollama")) return false;
31
+ if (params.hasTools()) return true;
32
+ try {
33
+ return new URL(params.baseUrl).origin === OLLAMA_CLOUD_ORIGIN;
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Maps the shared JSON Schema option to Chat Completions while preserving the
40
+ * older provider-shaped json_object/json_schema inputs accepted by model params.
41
+ */
42
+ function resolveOpenAICompletionsResponseFormat(responseFormat, supportsJsonSchemaResponseFormat) {
43
+ if (!responseFormat) return;
44
+ if (responseFormat.type === "json_object") return responseFormat;
45
+ if (responseFormat.type === "text") return responseFormat;
46
+ if (responseFormat.type === "json_schema" && isRecord(responseFormat.json_schema)) return responseFormat;
47
+ if (!supportsJsonSchemaResponseFormat) return;
48
+ return {
49
+ type: "json_schema",
50
+ json_schema: {
51
+ name: JSON_SCHEMA_RESPONSE_FORMAT_NAME,
52
+ schema: responseFormat
53
+ }
54
+ };
55
+ }
56
+ //#endregion
57
+ //#region packages/ai/src/transports/openai-completions-compat.ts
58
+ function isDefaultRouteProvider(provider, ...ids) {
59
+ return provider !== void 0 && ids.includes(provider);
60
+ }
61
+ /** Native OpenAI defaults never apply to a configured proxy endpoint. */
62
+ function isNativeOpenAIEndpoint(model) {
63
+ const baseUrl = model.baseUrl?.trim();
64
+ if (!baseUrl) return model.provider === "openai";
65
+ const endpoint = URL.parse(baseUrl);
66
+ return endpoint?.protocol === "https:" && (endpoint.hostname === "api.openai.com" || endpoint.hostname.endsWith(".api.openai.com"));
67
+ }
68
+ function isOpenAICodexResponsesModel(model) {
69
+ return model.provider === "openai" && (model.api === "openai-chatgpt-responses" || model.api === "openclaw-openai-chatgpt-responses-transport");
70
+ }
71
+ function isNativeOpenAICodexResponsesBaseUrl(baseUrl) {
72
+ const trimmed = typeof baseUrl === "string" ? baseUrl.trim() : "";
73
+ if (!trimmed) return false;
74
+ try {
75
+ const url = new URL(trimmed);
76
+ if (url.protocol !== "http:" && url.protocol !== "https:") return false;
77
+ if (url.hostname.toLowerCase() !== "chatgpt.com") return false;
78
+ const pathname = url.pathname.replace(/\/+$/u, "").toLowerCase();
79
+ return [
80
+ "/backend-api",
81
+ "/backend-api/v1",
82
+ "/backend-api/codex",
83
+ "/backend-api/codex/v1",
84
+ "/backend-api/codex/responses"
85
+ ].includes(pathname);
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
90
+ function usesNativeOpenAICodexResponsesBackend(model) {
91
+ return isOpenAICodexResponsesModel(model) && isNativeOpenAICodexResponsesBaseUrl(model.baseUrl);
92
+ }
93
+ function resolveOpenAIPromptCacheKeySupport(model) {
94
+ return model.compat?.supportsPromptCacheKey ?? (isNativeOpenAIEndpoint(model) || usesNativeOpenAICodexResponsesBackend(model));
95
+ }
96
+ /** Resolves default request flags for an OpenAI-compatible completions endpoint. */
97
+ function resolveOpenAICompletionsCompatDefaults(input) {
98
+ const { provider, modelId, endpointClass, knownProviderFamily, supportsNativeStreamingUsageCompat = false, supportsOpenAICompletionsStreamingUsageCompat = false, usesExplicitProxyLikeEndpoint = false } = input;
99
+ const isDefaultRoute = endpointClass === "default";
100
+ const usesConfiguredNonOpenAIEndpoint = endpointClass !== "default" && endpointClass !== "openai-public";
101
+ const isMoonshot = knownProviderFamily === "moonshot" || endpointClass === "moonshot-native";
102
+ const isMoonshotLike = isMoonshot || knownProviderFamily === "modelstudio" || endpointClass === "modelstudio-native";
103
+ const isModelStudioLike = knownProviderFamily === "modelstudio" || endpointClass === "modelstudio-native" || isDefaultRoute && isDefaultRouteProvider(provider, "dashscope", "modelstudio", "qwen");
104
+ const isZai = endpointClass === "zai-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "zai");
105
+ const isDeepSeek = endpointClass === "deepseek-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "deepseek");
106
+ const isTogether = knownProviderFamily === "together" || input.baseUrl?.includes("api.together.ai") === true || input.baseUrl?.includes("api.together.xyz") === true || isDefaultRoute && isDefaultRouteProvider(input.provider, "together");
107
+ const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || input.baseUrl?.includes("gateway.ai.cloudflare.com") === true;
108
+ const isXiaomi = endpointClass === "xiaomi-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "xiaomi");
109
+ const isNonStandard = endpointClass === "cerebras-native" || endpointClass === "chutes-native" || endpointClass === "deepseek-native" || endpointClass === "mistral-public" || endpointClass === "opencode-native" || endpointClass === "opencode-go-native" || endpointClass === "xai-native" || isXiaomi || isZai || isDefaultRoute && isDefaultRouteProvider(input.provider, "cerebras", "chutes", "deepseek", "opencode", "xai");
110
+ const isOpenRouterLike = input.provider === "openrouter" || endpointClass === "openrouter";
111
+ const isLocalEndpoint = endpointClass === "local";
112
+ const usesMaxTokens = endpointClass === "chutes-native" || endpointClass === "mistral-public" || knownProviderFamily === "mistral" || isMoonshot || isCloudflareAiGateway || isZai || isTogether || isDefaultRoute && isDefaultRouteProvider(provider, "chutes");
113
+ return {
114
+ supportsStore: !isNonStandard && knownProviderFamily !== "mistral" && !usesExplicitProxyLikeEndpoint,
115
+ supportsDeveloperRole: !isNonStandard && !isMoonshotLike && !usesConfiguredNonOpenAIEndpoint,
116
+ supportsReasoningEffort: !isZai && !isTogether && knownProviderFamily !== "mistral" && endpointClass !== "xai-native" && !usesExplicitProxyLikeEndpoint,
117
+ supportsUsageInStreaming: supportsOpenAICompletionsStreamingUsageCompat || !isNonStandard && (isLocalEndpoint || !usesConfiguredNonOpenAIEndpoint || supportsNativeStreamingUsageCompat),
118
+ maxTokensField: usesMaxTokens ? "max_tokens" : "max_completion_tokens",
119
+ thinkingFormat: isDeepSeek || isXiaomi ? "deepseek" : isZai ? "zai" : isTogether ? "together" : isOpenRouterLike ? "openrouter" : "openai",
120
+ visibleReasoningDetailTypes: isOpenRouterLike ? ["response.output_text", "response.text"] : [],
121
+ supportsStrictMode: !isZai && !usesConfiguredNonOpenAIEndpoint,
122
+ supportsJsonSchemaResponseFormat: (endpointClass === "openai-public" || isDefaultRoute && isDefaultRouteProvider(provider, "openai")) && isKnownOpenAIJsonSchemaModelId(modelId),
123
+ requiresReasoningContentOnAssistantMessages: isDeepSeek || isXiaomi,
124
+ requiresNonEmptyUserOrAssistantMessage: isModelStudioLike,
125
+ cacheControlFormat: isModelStudioLike && endpointClass !== "custom" || modelId?.toLowerCase().startsWith("anthropic/") === true && (endpointClass === "openrouter" || isDefaultRoute && provider === "openrouter" || provider === "deepinfra") ? "anthropic" : void 0,
126
+ sessionAffinityFormat: isOpenRouterLike ? "openrouter" : "openai",
127
+ supportsLongCacheRetention: !isModelStudioLike && provider !== "cloudflare-workers-ai" && provider !== "cloudflare-ai-gateway" && knownProviderFamily !== "together" && !input.baseUrl?.includes("api.cloudflare.com") && !input.baseUrl?.includes("gateway.ai.cloudflare.com") && !input.baseUrl?.includes("api.together.ai") && !input.baseUrl?.includes("api.together.xyz")
128
+ };
129
+ }
130
+ function resolveOpenAICompletionsCompatDefaultsFromCapabilities(input) {
131
+ return resolveOpenAICompletionsCompatDefaults(input);
132
+ }
133
+ /** Detects endpoint capabilities and defaults for an OpenAI-completions model. */
134
+ function detectOpenAICompletionsCompat(model, resolveCapabilities) {
135
+ const capabilities = (resolveCapabilities ?? ((input) => resolveProviderRequestCapabilities(input, model)))({
136
+ provider: model.provider,
137
+ api: "openai-completions",
138
+ baseUrl: model.baseUrl,
139
+ capability: "llm",
140
+ transport: "stream",
141
+ modelId: model.id,
142
+ compat: model.compat && typeof model.compat === "object" ? model.compat : void 0
143
+ });
144
+ return {
145
+ capabilities,
146
+ defaults: resolveOpenAICompletionsCompatDefaultsFromCapabilities({
147
+ provider: model.provider,
148
+ modelId: model.id,
149
+ baseUrl: model.baseUrl,
150
+ ...capabilities
151
+ })
152
+ };
153
+ }
154
+ function resolveSessionAffinity(model, detectedFormat) {
155
+ if (model.compat?.sendSessionAffinityHeaders !== true) return "none";
156
+ if (detectedFormat === "openrouter" || model.compat.thinkingFormat === "openrouter" || model.compat.openRouterRouting !== void 0) return "openrouter";
157
+ return "openai";
158
+ }
159
+ /** Applies explicit model overrides once on top of the canonical transport defaults. */
160
+ function resolveOpenAICompletionsCompat(model, resolveCapabilities) {
161
+ const { defaults } = detectOpenAICompletionsCompat(model, resolveCapabilities);
162
+ const configured = model.compat;
163
+ return {
164
+ supportsStore: configured?.supportsStore ?? defaults.supportsStore,
165
+ supportsDeveloperRole: configured?.supportsDeveloperRole ?? defaults.supportsDeveloperRole,
166
+ supportsReasoningEffort: configured?.supportsReasoningEffort ?? defaults.supportsReasoningEffort,
167
+ supportsUsageInStreaming: configured?.supportsUsageInStreaming ?? defaults.supportsUsageInStreaming,
168
+ maxTokensField: configured?.maxTokensField ?? defaults.maxTokensField,
169
+ requiresToolResultName: configured?.requiresToolResultName ?? false,
170
+ requiresAssistantAfterToolResult: configured?.requiresAssistantAfterToolResult ?? false,
171
+ requiresThinkingAsText: configured?.requiresThinkingAsText ?? false,
172
+ requiresReasoningContentOnAssistantMessages: configured?.requiresReasoningContentOnAssistantMessages ?? defaults.requiresReasoningContentOnAssistantMessages,
173
+ thinkingFormat: configured?.thinkingFormat ?? defaults.thinkingFormat,
174
+ openRouterRouting: configured?.openRouterRouting,
175
+ vercelGatewayRouting: configured?.vercelGatewayRouting ?? {},
176
+ zaiToolStream: configured?.zaiToolStream ?? false,
177
+ supportsStrictMode: configured?.supportsStrictMode ?? defaults.supportsStrictMode,
178
+ supportsJsonSchemaResponseFormat: configured?.supportsJsonSchemaResponseFormat ?? defaults.supportsJsonSchemaResponseFormat,
179
+ cacheControlFormat: configured?.cacheControlFormat ?? defaults.cacheControlFormat,
180
+ sessionAffinity: resolveSessionAffinity(model, defaults.sessionAffinityFormat),
181
+ supportsPromptCacheKey: resolveOpenAIPromptCacheKeySupport(model),
182
+ supportsLongCacheRetention: configured?.supportsLongCacheRetention ?? (usesNativeOpenAICodexResponsesBackend(model) ? false : defaults.supportsLongCacheRetention),
183
+ configuredSupportsLongCacheRetention: configured?.supportsLongCacheRetention,
184
+ visibleReasoningDetailTypes: configured && "visibleReasoningDetailTypes" in configured ? configured.visibleReasoningDetailTypes ?? defaults.visibleReasoningDetailTypes : defaults.visibleReasoningDetailTypes,
185
+ requiresNonEmptyUserOrAssistantMessage: defaults.requiresNonEmptyUserOrAssistantMessage
186
+ };
187
+ }
188
+ //#endregion
189
+ //#region packages/ai/src/providers/openai-prompt-cache.ts
190
+ const EXTENDED_RETENTION_MODELS = /* @__PURE__ */ new Set([
191
+ "gpt-5.5",
192
+ "gpt-5.5-pro",
193
+ "gpt-5.4",
194
+ "gpt-5.2",
195
+ "gpt-5.1-codex-max",
196
+ "gpt-5.1",
197
+ "gpt-5.1-codex",
198
+ "gpt-5.1-codex-mini",
199
+ "gpt-5.1-chat-latest",
200
+ "gpt-5",
201
+ "gpt-5-codex",
202
+ "gpt-4.1"
203
+ ]);
204
+ /** Selects documented lifetime fields shared by Responses and Chat Completions. */
205
+ function resolveOpenAIPromptCacheParams(model, cacheRetention, compat) {
206
+ if (cacheRetention !== "long" || !compat.supportsPromptCacheKey || !compat.supportsLongCacheRetention) return {};
207
+ const version = /^gpt-(\d+)(?:\.(\d+))?(?:-|$)/.exec(model.id);
208
+ if (version && (Number(version[1]) > 5 || Number(version[1]) === 5 && Number(version[2]) >= 6)) return { prompt_cache_options: { ttl: "30m" } };
209
+ const modelId = model.id.replace(/-\d{4}-\d{2}-\d{2}$/, "");
210
+ return !isNativeOpenAIEndpoint(model) || EXTENDED_RETENTION_MODELS.has(modelId) ? { prompt_cache_retention: "24h" } : {};
211
+ }
212
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
213
+ const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
214
+ /** Truncates a prompt cache key by Unicode code point count. */
215
+ function clampOpenAIPromptCacheKey(key) {
216
+ if (key === void 0) return;
217
+ return truncateCodePoints(key, 64);
218
+ }
219
+ //#endregion
220
+ export { isNativeOpenAIEndpoint as a, resolveOpenAIPromptCacheKeySupport as c, shouldOmitOllamaCompatResponseFormat as d, detectOpenAICompletionsCompat as i, usesNativeOpenAICodexResponsesBackend as l, clampOpenAIPromptCacheKey as n, isOpenAICodexResponsesModel as o, resolveOpenAIPromptCacheParams as r, resolveOpenAICompletionsCompat as s, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t, resolveOpenAICompletionsResponseFormat as u };
@@ -0,0 +1,24 @@
1
+ import { n as getAiTransportHost } from "./host-B8YfDGd4.mjs";
2
+ import { T as resolveOpenAIClientBaseUrl } from "./openai-transport-params-9aPuV5YY.mjs";
3
+ import { i as resolveCloudflareBaseUrl, r as isCloudflareProvider } from "./github-copilot-headers-B37TB3rB.mjs";
4
+ import OpenAI from "openai";
5
+ //#region packages/ai/src/providers/openai-provider-client.ts
6
+ function createOpenAIProviderClient(model, apiKey, headers, optionsHeaders) {
7
+ if (optionsHeaders) Object.assign(headers, optionsHeaders);
8
+ const defaultHeaders = model.provider === "cloudflare-ai-gateway" ? {
9
+ ...headers,
10
+ Authorization: headers.Authorization ?? null,
11
+ "cf-aig-authorization": `Bearer ${apiKey}`
12
+ } : headers;
13
+ const baseUrl = isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl;
14
+ return new OpenAI({
15
+ apiKey,
16
+ baseURL: resolveOpenAIClientBaseUrl(model, baseUrl),
17
+ dangerouslyAllowBrowser: true,
18
+ defaultHeaders,
19
+ maxRetries: 0,
20
+ fetch: getAiTransportHost().buildModelFetch(model)
21
+ });
22
+ }
23
+ //#endregion
24
+ export { createOpenAIProviderClient as t };
@@ -1,15 +1,14 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-BgDvQeum.mjs";
3
- import { n as getAiTransportHost } from "./host-CEvLw30U.mjs";
4
- import { n as clampOpenAIPromptCacheKey, r as resolveOpenAIResponsesCacheParams } from "./openai-prompt-cache-CGnVB74a.mjs";
2
+ import { t as AssistantMessageEventStream } from "./event-stream-D8PARQfL.mjs";
3
+ import { n as clampOpenAIPromptCacheKey, r as resolveOpenAIPromptCacheParams, s as resolveOpenAICompletionsCompat } from "./openai-prompt-cache-Bds-n_9Q.mjs";
5
4
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
6
- import { n as buildBaseOptions } from "./simple-options-BjHCCh4v.mjs";
5
+ import { n as buildBaseOptions } from "./simple-options-BQbb4yQL.mjs";
7
6
  import { n as getEnvApiKey } from "./env-api-keys-bktO00EJ.mjs";
8
- import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, r as convertResponsesMessages, s as runResponsesStreamLifecycle, t as applyCommonResponsesParams } from "./openai-responses-shared-Bmma_3Qc.mjs";
9
- import { j as resolveOpenAIClientBaseUrl } from "./openai-tool-schema-_pTAJqKF.mjs";
10
- import { j as supportsOpenAITemperature } from "./openai-responses-compaction-window-BMVHFOtq.mjs";
11
- import { i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-NCJtz9i0.mjs";
12
- import OpenAI from "openai";
7
+ import { C as supportsOpenAITemperature } from "./openai-responses-contracts-DDOHA62Y.mjs";
8
+ import { n as resolveProviderSimpleCompletionHeaders } from "./provider-transport-turn-state-D5EXOFL2.mjs";
9
+ import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, r as convertResponsesMessages, s as runResponsesStreamLifecycle, t as applyCommonResponsesParams } from "./openai-responses-shared-B8RdBPCv.mjs";
10
+ import { n as hasCopilotVisionInput, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-B37TB3rB.mjs";
11
+ import { t as createOpenAIProviderClient } from "./openai-provider-client-S2gCrM2Z.mjs";
13
12
  //#region packages/ai/src/providers/openai-responses.ts
14
13
  var openai_responses_exports = /* @__PURE__ */ __exportAll({
15
14
  streamOpenAIResponses: () => streamOpenAIResponses,
@@ -18,8 +17,8 @@ var openai_responses_exports = /* @__PURE__ */ __exportAll({
18
17
  const OPENAI_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "opencode"]);
19
18
  function getCompat(model) {
20
19
  return {
21
- sendSessionIdHeader: model.compat?.sendSessionIdHeader ?? true,
22
- supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true
20
+ ...resolveOpenAICompletionsCompat(model),
21
+ sendSessionIdHeader: model.compat?.sendSessionIdHeader ?? true
23
22
  };
24
23
  }
25
24
  /**
@@ -36,7 +35,7 @@ const streamOpenAIResponses = (model, context, options) => {
36
35
  createClient: () => {
37
36
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
38
37
  const cacheSessionId = resolveCacheRetention(options?.cacheRetention) === "none" ? void 0 : options?.sessionId;
39
- return createClient(model, context, apiKey, options?.headers, cacheSessionId);
38
+ return createClient(model, context, apiKey, resolveProviderSimpleCompletionHeaders(model, options), cacheSessionId);
40
39
  },
41
40
  buildParams: (_requestModel, replayMode) => buildParams(model, context, options, replayMode),
42
41
  processStreamOptions: {
@@ -74,21 +73,7 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId) {
74
73
  if (compat.sendSessionIdHeader) headers.session_id = sessionId;
75
74
  headers["x-client-request-id"] = sessionId;
76
75
  }
77
- if (optionsHeaders) Object.assign(headers, optionsHeaders);
78
- const defaultHeaders = model.provider === "cloudflare-ai-gateway" ? {
79
- ...headers,
80
- Authorization: headers.Authorization ?? null,
81
- "cf-aig-authorization": `Bearer ${apiKey}`
82
- } : headers;
83
- const baseUrl = isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl;
84
- return new OpenAI({
85
- apiKey,
86
- baseURL: resolveOpenAIClientBaseUrl(model, baseUrl),
87
- dangerouslyAllowBrowser: true,
88
- defaultHeaders,
89
- maxRetries: 0,
90
- fetch: getAiTransportHost().buildModelFetch(model)
91
- });
76
+ return createOpenAIProviderClient(model, apiKey, headers, optionsHeaders);
92
77
  }
93
78
  function buildParams(model, context, options, replayMode = "checkpoint") {
94
79
  const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, {
@@ -103,8 +88,8 @@ function buildParams(model, context, options, replayMode = "checkpoint") {
103
88
  model: model.id,
104
89
  input: messages,
105
90
  stream: true,
106
- prompt_cache_key: cacheRetention === "none" ? void 0 : clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId),
107
- ...resolveOpenAIResponsesCacheParams(model, cacheRetention, compat.supportsLongCacheRetention),
91
+ prompt_cache_key: cacheRetention === "none" || !compat.supportsPromptCacheKey ? void 0 : clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId),
92
+ ...resolveOpenAIPromptCacheParams(model, cacheRetention, compat),
108
93
  store: false
109
94
  };
110
95
  if (options?.maxTokens) params.max_output_tokens = options?.maxTokens;