@vibe-lark/larkpal 0.1.85 → 0.1.86

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 (106) hide show
  1. package/dist/account-id-BM1T6029-DYjVxojW.mjs +46 -0
  2. package/dist/activation-context--5yu1dPF-Bwsn3moT.mjs +172 -0
  3. package/dist/anthropic-TH8ERTXK.mjs +5962 -0
  4. package/dist/assistant-visible-text-DuFWokAt-CsbII5KS.mjs +596 -0
  5. package/dist/azure-openai-responses-Bt_Ag9Er.mjs +166 -0
  6. package/dist/boundary-file-read-BSd9MXPy--KThL5e6.mjs +594 -0
  7. package/dist/browser-lifecycle-cleanup-BdNsMhMD-O3tnAM4i.mjs +60 -0
  8. package/dist/build-DgTrEpge.mjs +3333 -0
  9. package/dist/bundled-compat-BpaDaAAu-D7oazKjD.mjs +5216 -0
  10. package/dist/bundled-dir-U738ay4K-DXK0q_TV.mjs +258 -0
  11. package/dist/call-DimWbpgJ-ColD4W-y.mjs +9993 -0
  12. package/dist/channel-bootstrap.runtime-BVclcGv1-DJv_Z-Kr.mjs +2 -0
  13. package/dist/channel-bootstrap.runtime-Cwcr38m2-VRfVCR-i.mjs +33 -0
  14. package/dist/chunk-D6SyT4dJ.mjs +36 -0
  15. package/dist/cli.mjs +6 -6
  16. package/dist/command-format-LSnUCVVF-BQ2SMKka.mjs +685 -0
  17. package/dist/config-Bim2pi8a-BQUdfiEi.mjs +9 -0
  18. package/dist/delivery-context.shared-j5hC5qb1-CI83RXXZ.mjs +72 -0
  19. package/dist/diagnostic-ClMwNnUA-D6nUtLnb.mjs +140 -0
  20. package/dist/dist-CEGw8-2W.mjs +429 -0
  21. package/dist/dist-DD2aJ2UL.mjs +125135 -0
  22. package/dist/env-api-keys-BVvSg7T2.mjs +68 -0
  23. package/dist/event-stream-xaQWmyas.mjs +15226 -0
  24. package/dist/facade-loader-DFzIYYt_-CIr4HKtE.mjs +194 -0
  25. package/dist/from-DF7cl2wz.mjs +3842 -0
  26. package/dist/gateway-method-policy-C7rf0SeV-CJQMEYIE.mjs +28 -0
  27. package/dist/github-copilot-headers-DjqWtUoP.mjs +22 -0
  28. package/dist/google-C2pVrgBZ.mjs +336 -0
  29. package/dist/google-gemini-cli-BBxgS5Ho.mjs +623 -0
  30. package/dist/google-shared-BsWgwEk1.mjs +22791 -0
  31. package/dist/google-vertex-BsVLJrrC.mjs +358 -0
  32. package/dist/hash-DAFtW_W7.mjs +16 -0
  33. package/dist/headers-R3HdCbAE.mjs +8 -0
  34. package/dist/home-dir-C44RaPME-CBRS4HLP.mjs +93 -0
  35. package/dist/ids-BPsM98Uu-CwuxvUai.mjs +77 -0
  36. package/dist/image-2w3cApg7-CxpHvoB5.mjs +207 -0
  37. package/dist/io-CH2g3vsv-BOGlLlB8.mjs +26218 -0
  38. package/dist/jiti-loader-cache-Bat69wam-D6hCxboy.mjs +5049 -0
  39. package/dist/json-file-BQRNuxmK-DhJM5NsG.mjs +108 -0
  40. package/dist/json-parse-v_HIJjjI.mjs +381 -0
  41. package/dist/jws-GFcTvvVT.mjs +2291 -0
  42. package/dist/{lark-cli-provider-7LvtOIF_.mjs → lark-cli-provider-BARgbbmo.mjs} +1 -1
  43. package/dist/{live-smoke-nvTUPtrv.mjs → live-smoke-BhkBOcH9.mjs} +3 -3
  44. package/dist/load-context-mb7uvLSn-B10MAi3I.mjs +29 -0
  45. package/dist/loader-708jrx4Y-BOswuvpe.mjs +5053 -0
  46. package/dist/main.mjs +56550 -205
  47. package/dist/manifest-registry-_hxKCS2K-CZdeyN0f.mjs +3512 -0
  48. package/dist/mcp-server.mjs +1 -1
  49. package/dist/message-channel-Bk_YHfQg-AeNrPPpp.mjs +50 -0
  50. package/dist/message-channel-core-DTA--Gjh-CY4Tkb7N.mjs +29 -0
  51. package/dist/message.config.runtime-K-k4XOyq-DZTmXomP.mjs +2 -0
  52. package/dist/message.gateway.runtime-DqHOHRTQ-DH4ml0YF.mjs +2 -0
  53. package/dist/mistral-CaR4DiLu.mjs +28657 -0
  54. package/dist/model-auth-env-oyg2Hexc-DU_rOUU5.mjs +1306 -0
  55. package/dist/models-config-BmpSQJQF-Gfvh1n3A.mjs +1282 -0
  56. package/dist/models-config.runtime-BsU_22xk.mjs +2 -0
  57. package/dist/multipart-parser-DedmaB5g.mjs +294 -0
  58. package/dist/oauth-DOJeGfcE.mjs +6392 -0
  59. package/dist/openai-BDtIh3Ja.mjs +6693 -0
  60. package/dist/openai-codex-responses-C5EORu31.mjs +664 -0
  61. package/dist/openai-completions-CR_cS6gX.mjs +669 -0
  62. package/dist/openai-responses-oGxwZyuC.mjs +184 -0
  63. package/dist/openai-responses-shared-BixMSDZE.mjs +398 -0
  64. package/dist/paths-D6msg0S1-C2lYuisN.mjs +189 -0
  65. package/dist/paths-D92DjaZ--CTOESW2b.mjs +192 -0
  66. package/dist/pi-model-discovery-Bd0TWzo8-BFsJmeMb.mjs +227 -0
  67. package/dist/pi-model-discovery-runtime-CCCZxkd8.mjs +2 -0
  68. package/dist/pi-tools.before-tool-call.runtime-Bn7uqKie-C5ewk8kK.mjs +399 -0
  69. package/dist/plugin-auto-enable-DdH3n9V8-DsA1isaF.mjs +1456 -0
  70. package/dist/process-scoped-map-B2cWkYET-CXwUZ8CZ.mjs +61 -0
  71. package/dist/provider-discovery.runtime-BPzz1PFj.mjs +58 -0
  72. package/dist/provider-model-compat-CFqcq0it-BDDuBI3A.mjs +118 -0
  73. package/dist/provider-runtime-C8rljsNs-CIT93zoy.mjs +2 -0
  74. package/dist/provider-runtime-CT50mNIX-BwEV6GyO.mjs +573 -0
  75. package/dist/provider-stream-COLujAAo-CbJPDngm.mjs +35449 -0
  76. package/dist/providers.runtime-Ba7tOlq7-CXkhkzU9.mjs +219 -0
  77. package/dist/public-surface-loader-BVl0NQAE-C0piXtsT.mjs +117 -0
  78. package/dist/resolve-C33B7eeu-BNvYTl6k.mjs +1041 -0
  79. package/dist/runtime-Cym-fqI8-DaSDMH-a.mjs +120 -0
  80. package/dist/runtime-channel-state-CohMybAh-hXR6y5Gx.mjs +19 -0
  81. package/dist/runtime-snapshot-C54O1-gI-40cbyi7P.mjs +677 -0
  82. package/dist/runtime-state-IBOIXKOx-Bf9tcLvc.mjs +10 -0
  83. package/dist/runtime-web-tools-fallback.runtime-Ca-qn1mj-BCVImm7a.mjs +39 -0
  84. package/dist/runtime-web-tools-manifest.runtime-BgxQTjmq-Cb4nJkRT.mjs +2 -0
  85. package/dist/runtime-web-tools-public-artifacts.runtime-D9qcoWIX-BrQdXzOQ.mjs +2 -0
  86. package/dist/session-archive.runtime-B52_5vs4-BG-_IwNJ.mjs +2 -0
  87. package/dist/session-key-Cn2QoOyX-CuHbJMgR.mjs +82 -0
  88. package/dist/session-transcript-files.fs-DEeFXruQ-B1PF6nLy.mjs +147 -0
  89. package/dist/src-BgCX0MLG.mjs +813 -0
  90. package/dist/src-DYbqlAqf.mjs +1177 -0
  91. package/dist/subagent-announce-L5WsQatW-CQWI9GMd.mjs +344 -0
  92. package/dist/subagent-announce.registry.runtime-DiqZyeTs-BKuniyi3.mjs +28 -0
  93. package/dist/subagent-registry-steer-runtime-DFgZFC0j-BhBz0roy.mjs +211 -0
  94. package/dist/subagent-system-prompt-C1qnN--K-DpnTFP47.mjs +3061 -0
  95. package/dist/target-parsing-loaded-DKkb6jJY-BMD4CkpS.mjs +1002 -0
  96. package/dist/task-registry-delivery-runtime-Dd1CUkZF-C8U40a3O.mjs +2950 -0
  97. package/dist/task-registry-delivery-runtime-ragbeVx5-CNbFAkjD.mjs +2 -0
  98. package/dist/thinking-Bh-7MqXz-D3woGbO7.mjs +2 -0
  99. package/dist/transcript-E_-ISOkD-DWCfZP2p.mjs +2019 -0
  100. package/dist/transcript.runtime-BqhvZZdl-BPy42vBP.mjs +2 -0
  101. package/dist/transform-messages-DbhIzTxq.mjs +207 -0
  102. package/dist/web-provider-public-artifacts-BlpRwIUS-CGPSV4W2.mjs +295 -0
  103. package/dist/web-search-providers.runtime--0aUtC3b-DyuhC95V.mjs +200 -0
  104. package/package.json +3 -3
  105. package/dist/rolldown-runtime-wcPFST8Q.mjs +0 -13
  106. /package/dist/{interactive-init-B6j8j_Ap.mjs → interactive-init-BXQBalNr.mjs} +0 -0
@@ -0,0 +1,664 @@
1
+ import { t as getEnvApiKey } from "./env-api-keys-BVvSg7T2.mjs";
2
+ import { o as supportsXhigh, t as AssistantMessageEventStream } from "./event-stream-xaQWmyas.mjs";
3
+ import { t as headersToRecord } from "./headers-R3HdCbAE.mjs";
4
+ import { i as clampReasoning, r as buildBaseOptions } from "./transform-messages-DbhIzTxq.mjs";
5
+ import { n as convertResponsesTools, r as processResponsesStream, t as convertResponsesMessages } from "./openai-responses-shared-BixMSDZE.mjs";
6
+ //#region node_modules/.pnpm/@mariozechner+pi-ai@0.69.0_@modelcontextprotocol+sdk@1.29.0_zod@4.3.6__ws@8.21.0_zod@4.3.6/node_modules/@mariozechner/pi-ai/dist/providers/openai-codex-responses.js
7
+ let _os = null;
8
+ const dynamicImport = (specifier) => import(specifier);
9
+ const NODE_OS_SPECIFIER = "node:os";
10
+ if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) dynamicImport(NODE_OS_SPECIFIER).then((m) => {
11
+ _os = m;
12
+ });
13
+ const DEFAULT_CODEX_BASE_URL = "https://chatgpt.com/backend-api";
14
+ const JWT_CLAIM_PATH = "https://api.openai.com/auth";
15
+ const MAX_RETRIES = 3;
16
+ const BASE_DELAY_MS = 1e3;
17
+ const CODEX_TOOL_CALL_PROVIDERS = new Set([
18
+ "openai",
19
+ "openai-codex",
20
+ "opencode"
21
+ ]);
22
+ const CODEX_RESPONSE_STATUSES = new Set([
23
+ "completed",
24
+ "incomplete",
25
+ "failed",
26
+ "cancelled",
27
+ "queued",
28
+ "in_progress"
29
+ ]);
30
+ function isRetryableError(status, errorText) {
31
+ if (status === 429 || status === 500 || status === 502 || status === 503 || status === 504) return true;
32
+ return /rate.?limit|overloaded|service.?unavailable|upstream.?connect|connection.?refused/i.test(errorText);
33
+ }
34
+ function sleep(ms, signal) {
35
+ return new Promise((resolve, reject) => {
36
+ if (signal?.aborted) {
37
+ reject(/* @__PURE__ */ new Error("Request was aborted"));
38
+ return;
39
+ }
40
+ const timeout = setTimeout(resolve, ms);
41
+ signal?.addEventListener("abort", () => {
42
+ clearTimeout(timeout);
43
+ reject(/* @__PURE__ */ new Error("Request was aborted"));
44
+ });
45
+ });
46
+ }
47
+ const streamOpenAICodexResponses = (model, context, options) => {
48
+ const stream = new AssistantMessageEventStream();
49
+ (async () => {
50
+ const output = {
51
+ role: "assistant",
52
+ content: [],
53
+ api: "openai-codex-responses",
54
+ provider: model.provider,
55
+ model: model.id,
56
+ usage: {
57
+ input: 0,
58
+ output: 0,
59
+ cacheRead: 0,
60
+ cacheWrite: 0,
61
+ totalTokens: 0,
62
+ cost: {
63
+ input: 0,
64
+ output: 0,
65
+ cacheRead: 0,
66
+ cacheWrite: 0,
67
+ total: 0
68
+ }
69
+ },
70
+ stopReason: "stop",
71
+ timestamp: Date.now()
72
+ };
73
+ try {
74
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
75
+ if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
76
+ const accountId = extractAccountId(apiKey);
77
+ let body = buildRequestBody(model, context, options);
78
+ const nextBody = await options?.onPayload?.(body, model);
79
+ if (nextBody !== void 0) body = nextBody;
80
+ const websocketRequestId = options?.sessionId || createCodexRequestId();
81
+ const sseHeaders = buildSSEHeaders(model.headers, options?.headers, accountId, apiKey, options?.sessionId);
82
+ const websocketHeaders = buildWebSocketHeaders(model.headers, options?.headers, accountId, apiKey, websocketRequestId);
83
+ const bodyJson = JSON.stringify(body);
84
+ const transport = options?.transport || "sse";
85
+ if (transport !== "sse") {
86
+ let websocketStarted = false;
87
+ try {
88
+ await processWebSocketStream(resolveCodexWebSocketUrl(model.baseUrl), body, websocketHeaders, output, stream, model, () => {
89
+ websocketStarted = true;
90
+ }, options);
91
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
92
+ stream.push({
93
+ type: "done",
94
+ reason: output.stopReason,
95
+ message: output
96
+ });
97
+ stream.end();
98
+ return;
99
+ } catch (error) {
100
+ if (transport === "websocket" || websocketStarted) throw error;
101
+ }
102
+ }
103
+ let response;
104
+ let lastError;
105
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
106
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
107
+ try {
108
+ response = await fetch(resolveCodexUrl(model.baseUrl), {
109
+ method: "POST",
110
+ headers: sseHeaders,
111
+ body: bodyJson,
112
+ signal: options?.signal
113
+ });
114
+ await options?.onResponse?.({
115
+ status: response.status,
116
+ headers: headersToRecord(response.headers)
117
+ }, model);
118
+ if (response.ok) break;
119
+ const errorText = await response.text();
120
+ if (attempt < MAX_RETRIES && isRetryableError(response.status, errorText)) {
121
+ await sleep(BASE_DELAY_MS * 2 ** attempt, options?.signal);
122
+ continue;
123
+ }
124
+ const info = await parseErrorResponse(new Response(errorText, {
125
+ status: response.status,
126
+ statusText: response.statusText
127
+ }));
128
+ throw new Error(info.friendlyMessage || info.message);
129
+ } catch (error) {
130
+ if (error instanceof Error) {
131
+ if (error.name === "AbortError" || error.message === "Request was aborted") throw new Error("Request was aborted");
132
+ }
133
+ lastError = error instanceof Error ? error : new Error(String(error));
134
+ if (attempt < MAX_RETRIES && !lastError.message.includes("usage limit")) {
135
+ await sleep(BASE_DELAY_MS * 2 ** attempt, options?.signal);
136
+ continue;
137
+ }
138
+ throw lastError;
139
+ }
140
+ }
141
+ if (!response?.ok) throw lastError ?? /* @__PURE__ */ new Error("Failed after retries");
142
+ if (!response.body) throw new Error("No response body");
143
+ stream.push({
144
+ type: "start",
145
+ partial: output
146
+ });
147
+ await processStream(response, output, stream, model, options);
148
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
149
+ stream.push({
150
+ type: "done",
151
+ reason: output.stopReason,
152
+ message: output
153
+ });
154
+ stream.end();
155
+ } catch (error) {
156
+ for (const block of output.content) delete block.partialJson;
157
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
158
+ output.errorMessage = error instanceof Error ? error.message : String(error);
159
+ stream.push({
160
+ type: "error",
161
+ reason: output.stopReason,
162
+ error: output
163
+ });
164
+ stream.end();
165
+ }
166
+ })();
167
+ return stream;
168
+ };
169
+ const streamSimpleOpenAICodexResponses = (model, context, options) => {
170
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider);
171
+ if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
172
+ const base = buildBaseOptions(model, options, apiKey);
173
+ const reasoningEffort = supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning);
174
+ return streamOpenAICodexResponses(model, context, {
175
+ ...base,
176
+ reasoningEffort
177
+ });
178
+ };
179
+ function buildRequestBody(model, context, options) {
180
+ const messages = convertResponsesMessages(model, context, CODEX_TOOL_CALL_PROVIDERS, { includeSystemPrompt: false });
181
+ const body = {
182
+ model: model.id,
183
+ store: false,
184
+ stream: true,
185
+ instructions: context.systemPrompt,
186
+ input: messages,
187
+ text: { verbosity: options?.textVerbosity || "medium" },
188
+ include: ["reasoning.encrypted_content"],
189
+ prompt_cache_key: options?.sessionId,
190
+ tool_choice: "auto",
191
+ parallel_tool_calls: true
192
+ };
193
+ if (options?.temperature !== void 0) body.temperature = options.temperature;
194
+ if (options?.serviceTier !== void 0) body.service_tier = options.serviceTier;
195
+ if (context.tools) body.tools = convertResponsesTools(context.tools, { strict: null });
196
+ if (options?.reasoningEffort !== void 0) body.reasoning = {
197
+ effort: clampReasoningEffort(model.id, options.reasoningEffort),
198
+ summary: options.reasoningSummary ?? "auto"
199
+ };
200
+ return body;
201
+ }
202
+ function clampReasoningEffort(modelId, effort) {
203
+ const id = modelId.includes("/") ? modelId.split("/").pop() : modelId;
204
+ if ((id.startsWith("gpt-5.2") || id.startsWith("gpt-5.3") || id.startsWith("gpt-5.4")) && effort === "minimal") return "low";
205
+ if (id === "gpt-5.1" && effort === "xhigh") return "high";
206
+ if (id === "gpt-5.1-codex-mini") return effort === "high" || effort === "xhigh" ? "high" : "medium";
207
+ return effort;
208
+ }
209
+ function getServiceTierCostMultiplier(serviceTier) {
210
+ switch (serviceTier) {
211
+ case "flex": return .5;
212
+ case "priority": return 2;
213
+ default: return 1;
214
+ }
215
+ }
216
+ function applyServiceTierPricing(usage, serviceTier) {
217
+ const multiplier = getServiceTierCostMultiplier(serviceTier);
218
+ if (multiplier === 1) return;
219
+ usage.cost.input *= multiplier;
220
+ usage.cost.output *= multiplier;
221
+ usage.cost.cacheRead *= multiplier;
222
+ usage.cost.cacheWrite *= multiplier;
223
+ usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
224
+ }
225
+ function resolveCodexServiceTier(responseServiceTier, requestServiceTier) {
226
+ if (responseServiceTier === "default" && (requestServiceTier === "flex" || requestServiceTier === "priority")) return requestServiceTier;
227
+ return responseServiceTier ?? requestServiceTier;
228
+ }
229
+ function resolveCodexUrl(baseUrl) {
230
+ const normalized = (baseUrl && baseUrl.trim().length > 0 ? baseUrl : DEFAULT_CODEX_BASE_URL).replace(/\/+$/, "");
231
+ if (normalized.endsWith("/codex/responses")) return normalized;
232
+ if (normalized.endsWith("/codex")) return `${normalized}/responses`;
233
+ return `${normalized}/codex/responses`;
234
+ }
235
+ function resolveCodexWebSocketUrl(baseUrl) {
236
+ const url = new URL(resolveCodexUrl(baseUrl));
237
+ if (url.protocol === "https:") url.protocol = "wss:";
238
+ if (url.protocol === "http:") url.protocol = "ws:";
239
+ return url.toString();
240
+ }
241
+ async function processStream(response, output, stream, model, options) {
242
+ await processResponsesStream(mapCodexEvents(parseSSE(response)), output, stream, model, {
243
+ serviceTier: options?.serviceTier,
244
+ resolveServiceTier: resolveCodexServiceTier,
245
+ applyServiceTierPricing
246
+ });
247
+ }
248
+ async function* mapCodexEvents(events) {
249
+ for await (const event of events) {
250
+ const type = typeof event.type === "string" ? event.type : void 0;
251
+ if (!type) continue;
252
+ if (type === "error") {
253
+ const code = event.code || "";
254
+ const message = event.message || "";
255
+ throw new Error(`Codex error: ${message || code || JSON.stringify(event)}`);
256
+ }
257
+ if (type === "response.failed") {
258
+ const msg = event.response?.error?.message;
259
+ throw new Error(msg || "Codex response failed");
260
+ }
261
+ if (type === "response.done" || type === "response.completed" || type === "response.incomplete") {
262
+ const response = event.response;
263
+ const normalizedResponse = response ? {
264
+ ...response,
265
+ status: normalizeCodexStatus(response.status)
266
+ } : response;
267
+ yield {
268
+ ...event,
269
+ type: "response.completed",
270
+ response: normalizedResponse
271
+ };
272
+ return;
273
+ }
274
+ yield event;
275
+ }
276
+ }
277
+ function normalizeCodexStatus(status) {
278
+ if (typeof status !== "string") return void 0;
279
+ return CODEX_RESPONSE_STATUSES.has(status) ? status : void 0;
280
+ }
281
+ async function* parseSSE(response) {
282
+ if (!response.body) return;
283
+ const reader = response.body.getReader();
284
+ const decoder = new TextDecoder();
285
+ let buffer = "";
286
+ try {
287
+ while (true) {
288
+ const { done, value } = await reader.read();
289
+ if (done) break;
290
+ buffer += decoder.decode(value, { stream: true });
291
+ let idx = buffer.indexOf("\n\n");
292
+ while (idx !== -1) {
293
+ const chunk = buffer.slice(0, idx);
294
+ buffer = buffer.slice(idx + 2);
295
+ const dataLines = chunk.split("\n").filter((l) => l.startsWith("data:")).map((l) => l.slice(5).trim());
296
+ if (dataLines.length > 0) {
297
+ const data = dataLines.join("\n").trim();
298
+ if (data && data !== "[DONE]") try {
299
+ yield JSON.parse(data);
300
+ } catch {}
301
+ }
302
+ idx = buffer.indexOf("\n\n");
303
+ }
304
+ }
305
+ } finally {
306
+ try {
307
+ await reader.cancel();
308
+ } catch {}
309
+ try {
310
+ reader.releaseLock();
311
+ } catch {}
312
+ }
313
+ }
314
+ const OPENAI_BETA_RESPONSES_WEBSOCKETS = "responses_websockets=2026-02-06";
315
+ const SESSION_WEBSOCKET_CACHE_TTL_MS = 300 * 1e3;
316
+ const websocketSessionCache = /* @__PURE__ */ new Map();
317
+ function getWebSocketConstructor() {
318
+ const ctor = globalThis.WebSocket;
319
+ if (typeof ctor !== "function") return null;
320
+ return ctor;
321
+ }
322
+ function getWebSocketReadyState(socket) {
323
+ const readyState = socket.readyState;
324
+ return typeof readyState === "number" ? readyState : void 0;
325
+ }
326
+ function isWebSocketReusable(socket) {
327
+ const readyState = getWebSocketReadyState(socket);
328
+ return readyState === void 0 || readyState === 1;
329
+ }
330
+ function closeWebSocketSilently(socket, code = 1e3, reason = "done") {
331
+ try {
332
+ socket.close(code, reason);
333
+ } catch {}
334
+ }
335
+ function scheduleSessionWebSocketExpiry(sessionId, entry) {
336
+ if (entry.idleTimer) clearTimeout(entry.idleTimer);
337
+ entry.idleTimer = setTimeout(() => {
338
+ if (entry.busy) return;
339
+ closeWebSocketSilently(entry.socket, 1e3, "idle_timeout");
340
+ websocketSessionCache.delete(sessionId);
341
+ }, SESSION_WEBSOCKET_CACHE_TTL_MS);
342
+ }
343
+ async function connectWebSocket(url, headers, signal) {
344
+ const WebSocketCtor = getWebSocketConstructor();
345
+ if (!WebSocketCtor) throw new Error("WebSocket transport is not available in this runtime");
346
+ const wsHeaders = headersToRecord(headers);
347
+ delete wsHeaders["OpenAI-Beta"];
348
+ return new Promise((resolve, reject) => {
349
+ let settled = false;
350
+ let socket;
351
+ try {
352
+ socket = new WebSocketCtor(url, { headers: wsHeaders });
353
+ } catch (error) {
354
+ reject(error instanceof Error ? error : new Error(String(error)));
355
+ return;
356
+ }
357
+ const onOpen = () => {
358
+ if (settled) return;
359
+ settled = true;
360
+ cleanup();
361
+ resolve(socket);
362
+ };
363
+ const onError = (event) => {
364
+ const error = extractWebSocketError(event);
365
+ if (settled) return;
366
+ settled = true;
367
+ cleanup();
368
+ reject(error);
369
+ };
370
+ const onClose = (event) => {
371
+ const error = extractWebSocketCloseError(event);
372
+ if (settled) return;
373
+ settled = true;
374
+ cleanup();
375
+ reject(error);
376
+ };
377
+ const onAbort = () => {
378
+ if (settled) return;
379
+ settled = true;
380
+ cleanup();
381
+ socket.close(1e3, "aborted");
382
+ reject(/* @__PURE__ */ new Error("Request was aborted"));
383
+ };
384
+ const cleanup = () => {
385
+ socket.removeEventListener("open", onOpen);
386
+ socket.removeEventListener("error", onError);
387
+ socket.removeEventListener("close", onClose);
388
+ signal?.removeEventListener("abort", onAbort);
389
+ };
390
+ socket.addEventListener("open", onOpen);
391
+ socket.addEventListener("error", onError);
392
+ socket.addEventListener("close", onClose);
393
+ signal?.addEventListener("abort", onAbort);
394
+ });
395
+ }
396
+ async function acquireWebSocket(url, headers, sessionId, signal) {
397
+ if (!sessionId) {
398
+ const socket = await connectWebSocket(url, headers, signal);
399
+ return {
400
+ socket,
401
+ release: ({ keep } = {}) => {
402
+ if (keep === false) {
403
+ closeWebSocketSilently(socket);
404
+ return;
405
+ }
406
+ closeWebSocketSilently(socket);
407
+ }
408
+ };
409
+ }
410
+ const cached = websocketSessionCache.get(sessionId);
411
+ if (cached) {
412
+ if (cached.idleTimer) {
413
+ clearTimeout(cached.idleTimer);
414
+ cached.idleTimer = void 0;
415
+ }
416
+ if (!cached.busy && isWebSocketReusable(cached.socket)) {
417
+ cached.busy = true;
418
+ return {
419
+ socket: cached.socket,
420
+ release: ({ keep } = {}) => {
421
+ if (!keep || !isWebSocketReusable(cached.socket)) {
422
+ closeWebSocketSilently(cached.socket);
423
+ websocketSessionCache.delete(sessionId);
424
+ return;
425
+ }
426
+ cached.busy = false;
427
+ scheduleSessionWebSocketExpiry(sessionId, cached);
428
+ }
429
+ };
430
+ }
431
+ if (cached.busy) {
432
+ const socket = await connectWebSocket(url, headers, signal);
433
+ return {
434
+ socket,
435
+ release: () => {
436
+ closeWebSocketSilently(socket);
437
+ }
438
+ };
439
+ }
440
+ if (!isWebSocketReusable(cached.socket)) {
441
+ closeWebSocketSilently(cached.socket);
442
+ websocketSessionCache.delete(sessionId);
443
+ }
444
+ }
445
+ const socket = await connectWebSocket(url, headers, signal);
446
+ const entry = {
447
+ socket,
448
+ busy: true
449
+ };
450
+ websocketSessionCache.set(sessionId, entry);
451
+ return {
452
+ socket,
453
+ release: ({ keep } = {}) => {
454
+ if (!keep || !isWebSocketReusable(entry.socket)) {
455
+ closeWebSocketSilently(entry.socket);
456
+ if (entry.idleTimer) clearTimeout(entry.idleTimer);
457
+ if (websocketSessionCache.get(sessionId) === entry) websocketSessionCache.delete(sessionId);
458
+ return;
459
+ }
460
+ entry.busy = false;
461
+ scheduleSessionWebSocketExpiry(sessionId, entry);
462
+ }
463
+ };
464
+ }
465
+ function extractWebSocketError(event) {
466
+ if (event && typeof event === "object" && "message" in event) {
467
+ const message = event.message;
468
+ if (typeof message === "string" && message.length > 0) return new Error(message);
469
+ }
470
+ return /* @__PURE__ */ new Error("WebSocket error");
471
+ }
472
+ function extractWebSocketCloseError(event) {
473
+ if (event && typeof event === "object") {
474
+ const code = "code" in event ? event.code : void 0;
475
+ const reason = "reason" in event ? event.reason : void 0;
476
+ const codeText = typeof code === "number" ? ` ${code}` : "";
477
+ const reasonText = typeof reason === "string" && reason.length > 0 ? ` ${reason}` : "";
478
+ return new Error(`WebSocket closed${codeText}${reasonText}`.trim());
479
+ }
480
+ return /* @__PURE__ */ new Error("WebSocket closed");
481
+ }
482
+ async function decodeWebSocketData(data) {
483
+ if (typeof data === "string") return data;
484
+ if (data instanceof ArrayBuffer) return new TextDecoder().decode(new Uint8Array(data));
485
+ if (ArrayBuffer.isView(data)) {
486
+ const view = data;
487
+ return new TextDecoder().decode(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
488
+ }
489
+ if (data && typeof data === "object" && "arrayBuffer" in data) {
490
+ const arrayBuffer = await data.arrayBuffer();
491
+ return new TextDecoder().decode(new Uint8Array(arrayBuffer));
492
+ }
493
+ return null;
494
+ }
495
+ async function* parseWebSocket(socket, signal) {
496
+ const queue = [];
497
+ let pending = null;
498
+ let done = false;
499
+ let failed = null;
500
+ let sawCompletion = false;
501
+ const wake = () => {
502
+ if (!pending) return;
503
+ const resolve = pending;
504
+ pending = null;
505
+ resolve();
506
+ };
507
+ const onMessage = (event) => {
508
+ (async () => {
509
+ if (!event || typeof event !== "object" || !("data" in event)) return;
510
+ const text = await decodeWebSocketData(event.data);
511
+ if (!text) return;
512
+ try {
513
+ const parsed = JSON.parse(text);
514
+ const type = typeof parsed.type === "string" ? parsed.type : "";
515
+ if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
516
+ sawCompletion = true;
517
+ done = true;
518
+ }
519
+ queue.push(parsed);
520
+ wake();
521
+ } catch {}
522
+ })();
523
+ };
524
+ const onError = (event) => {
525
+ failed = extractWebSocketError(event);
526
+ done = true;
527
+ wake();
528
+ };
529
+ const onClose = (event) => {
530
+ if (sawCompletion) {
531
+ done = true;
532
+ wake();
533
+ return;
534
+ }
535
+ if (!failed) failed = extractWebSocketCloseError(event);
536
+ done = true;
537
+ wake();
538
+ };
539
+ const onAbort = () => {
540
+ failed = /* @__PURE__ */ new Error("Request was aborted");
541
+ done = true;
542
+ wake();
543
+ };
544
+ socket.addEventListener("message", onMessage);
545
+ socket.addEventListener("error", onError);
546
+ socket.addEventListener("close", onClose);
547
+ signal?.addEventListener("abort", onAbort);
548
+ try {
549
+ while (true) {
550
+ if (signal?.aborted) throw new Error("Request was aborted");
551
+ if (queue.length > 0) {
552
+ yield queue.shift();
553
+ continue;
554
+ }
555
+ if (done) break;
556
+ await new Promise((resolve) => {
557
+ pending = resolve;
558
+ });
559
+ }
560
+ if (failed) throw failed;
561
+ if (!sawCompletion) throw new Error("WebSocket stream closed before response.completed");
562
+ } finally {
563
+ socket.removeEventListener("message", onMessage);
564
+ socket.removeEventListener("error", onError);
565
+ socket.removeEventListener("close", onClose);
566
+ signal?.removeEventListener("abort", onAbort);
567
+ }
568
+ }
569
+ async function processWebSocketStream(url, body, headers, output, stream, model, onStart, options) {
570
+ const { socket, release } = await acquireWebSocket(url, headers, options?.sessionId, options?.signal);
571
+ let keepConnection = true;
572
+ try {
573
+ socket.send(JSON.stringify({
574
+ type: "response.create",
575
+ ...body
576
+ }));
577
+ onStart();
578
+ stream.push({
579
+ type: "start",
580
+ partial: output
581
+ });
582
+ await processResponsesStream(mapCodexEvents(parseWebSocket(socket, options?.signal)), output, stream, model, {
583
+ serviceTier: options?.serviceTier,
584
+ resolveServiceTier: resolveCodexServiceTier,
585
+ applyServiceTierPricing
586
+ });
587
+ if (options?.signal?.aborted) keepConnection = false;
588
+ } catch (error) {
589
+ keepConnection = false;
590
+ throw error;
591
+ } finally {
592
+ release({ keep: keepConnection });
593
+ }
594
+ }
595
+ async function parseErrorResponse(response) {
596
+ const raw = await response.text();
597
+ let message = raw || response.statusText || "Request failed";
598
+ let friendlyMessage;
599
+ try {
600
+ const err = JSON.parse(raw)?.error;
601
+ if (err) {
602
+ const code = err.code || err.type || "";
603
+ if (/usage_limit_reached|usage_not_included|rate_limit_exceeded/i.test(code) || response.status === 429) {
604
+ const plan = err.plan_type ? ` (${err.plan_type.toLowerCase()} plan)` : "";
605
+ const mins = err.resets_at ? Math.max(0, Math.round((err.resets_at * 1e3 - Date.now()) / 6e4)) : void 0;
606
+ friendlyMessage = `You have hit your ChatGPT usage limit${plan}.${mins !== void 0 ? ` Try again in ~${mins} min.` : ""}`.trim();
607
+ }
608
+ message = err.message || friendlyMessage || message;
609
+ }
610
+ } catch {}
611
+ return {
612
+ message,
613
+ friendlyMessage
614
+ };
615
+ }
616
+ function extractAccountId(token) {
617
+ try {
618
+ const parts = token.split(".");
619
+ if (parts.length !== 3) throw new Error("Invalid token");
620
+ const accountId = JSON.parse(atob(parts[1]))?.[JWT_CLAIM_PATH]?.chatgpt_account_id;
621
+ if (!accountId) throw new Error("No account ID in token");
622
+ return accountId;
623
+ } catch {
624
+ throw new Error("Failed to extract accountId from token");
625
+ }
626
+ }
627
+ function createCodexRequestId() {
628
+ if (typeof globalThis.crypto?.randomUUID === "function") return globalThis.crypto.randomUUID();
629
+ return `codex_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
630
+ }
631
+ function buildBaseCodexHeaders(initHeaders, additionalHeaders, accountId, token) {
632
+ const headers = new Headers(initHeaders);
633
+ for (const [key, value] of Object.entries(additionalHeaders || {})) headers.set(key, value);
634
+ headers.set("Authorization", `Bearer ${token}`);
635
+ headers.set("chatgpt-account-id", accountId);
636
+ headers.set("originator", "pi");
637
+ const userAgent = _os ? `pi (${_os.platform()} ${_os.release()}; ${_os.arch()})` : "pi (browser)";
638
+ headers.set("User-Agent", userAgent);
639
+ return headers;
640
+ }
641
+ function buildSSEHeaders(initHeaders, additionalHeaders, accountId, token, sessionId) {
642
+ const headers = buildBaseCodexHeaders(initHeaders, additionalHeaders, accountId, token);
643
+ headers.set("OpenAI-Beta", "responses=experimental");
644
+ headers.set("accept", "text/event-stream");
645
+ headers.set("content-type", "application/json");
646
+ if (sessionId) {
647
+ headers.set("session_id", sessionId);
648
+ headers.set("x-client-request-id", sessionId);
649
+ }
650
+ return headers;
651
+ }
652
+ function buildWebSocketHeaders(initHeaders, additionalHeaders, accountId, token, requestId) {
653
+ const headers = buildBaseCodexHeaders(initHeaders, additionalHeaders, accountId, token);
654
+ headers.delete("accept");
655
+ headers.delete("content-type");
656
+ headers.delete("OpenAI-Beta");
657
+ headers.delete("openai-beta");
658
+ headers.set("OpenAI-Beta", OPENAI_BETA_RESPONSES_WEBSOCKETS);
659
+ headers.set("x-client-request-id", requestId);
660
+ headers.set("session_id", requestId);
661
+ return headers;
662
+ }
663
+ //#endregion
664
+ export { streamOpenAICodexResponses, streamSimpleOpenAICodexResponses };