pi2dsh 0.3.0 → 0.3.2
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.
- package/README.md +31 -11
- package/README.zh.md +31 -11
- package/dist/all-Rt4K68QA.mjs +28512 -0
- package/dist/all-Rt4K68QA.mjs.map +1 -0
- package/dist/anthropic-messages-Beym0_aC.mjs +6438 -0
- package/dist/anthropic-messages-Beym0_aC.mjs.map +1 -0
- package/dist/azure-openai-responses-cHqZTgLD.mjs +209 -0
- package/dist/azure-openai-responses-cHqZTgLD.mjs.map +1 -0
- package/dist/{build-DsGYAgiT.mjs → build-BG7p2Lbr.mjs} +2 -2
- package/dist/{build-DsGYAgiT.mjs.map → build-BG7p2Lbr.mjs.map} +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/compat/pi-ai.d.mts +25 -3
- package/dist/compat/pi-ai.d.mts.map +1 -1
- package/dist/compat/pi-ai.mjs +3 -2919
- package/dist/compat/pi-coding-agent.d.mts +12 -1
- package/dist/compat/pi-coding-agent.d.mts.map +1 -1
- package/dist/compat/pi-coding-agent.mjs +2 -2
- package/dist/credentials-oauth.d.mts +27 -0
- package/dist/credentials-oauth.d.mts.map +1 -0
- package/dist/credentials-oauth.mjs +91 -0
- package/dist/credentials-oauth.mjs.map +1 -0
- package/dist/deferred-tools-BD4g5QUx.mjs +32 -0
- package/dist/deferred-tools-BD4g5QUx.mjs.map +1 -0
- package/dist/diagnostics-CJye1UFh.mjs +99 -0
- package/dist/diagnostics-CJye1UFh.mjs.map +1 -0
- package/dist/dist-IQKOgQyt.mjs +10035 -0
- package/dist/dist-IQKOgQyt.mjs.map +1 -0
- package/dist/dist-QBBA-dL_.mjs +1246 -0
- package/dist/dist-QBBA-dL_.mjs.map +1 -0
- package/dist/error-body-DKA3lknR.mjs +104 -0
- package/dist/error-body-DKA3lknR.mjs.map +1 -0
- package/dist/github-copilot-headers-CZo2QHrt.mjs +25 -0
- package/dist/github-copilot-headers-CZo2QHrt.mjs.map +1 -0
- package/dist/google-generative-ai-B7OZs5lu.mjs +358 -0
- package/dist/google-generative-ai-B7OZs5lu.mjs.map +1 -0
- package/dist/google-shared-CRsAUItF.mjs +29042 -0
- package/dist/google-shared-CRsAUItF.mjs.map +1 -0
- package/dist/google-vertex-DmdaHQtB.mjs +402 -0
- package/dist/google-vertex-DmdaHQtB.mjs.map +1 -0
- package/dist/hash-Dbggamac.mjs +19 -0
- package/dist/hash-Dbggamac.mjs.map +1 -0
- package/dist/headers-CPzZhJQn.mjs +17 -0
- package/dist/headers-CPzZhJQn.mjs.map +1 -0
- package/dist/host.d.mts.map +1 -1
- package/dist/host.mjs +15 -3
- package/dist/host.mjs.map +1 -1
- package/dist/images-models-DJtHo9Rp.mjs +1068 -0
- package/dist/images-models-DJtHo9Rp.mjs.map +1 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/json-parse-CFyFZSLJ.mjs +384 -0
- package/dist/json-parse-CFyFZSLJ.mjs.map +1 -0
- package/dist/{mcp-config-gqg7GJEE.mjs → mcp-config-D2B3kv-Z.mjs} +34 -16
- package/dist/mcp-config-D2B3kv-Z.mjs.map +1 -0
- package/dist/mistral-conversations-HHZCcFv_.mjs +42007 -0
- package/dist/mistral-conversations-HHZCcFv_.mjs.map +1 -0
- package/dist/multipart-parser-CIa5BbwO.mjs +301 -0
- package/dist/multipart-parser-CIa5BbwO.mjs.map +1 -0
- package/dist/oauth-bridge-C6fL1qSv.mjs +375 -0
- package/dist/oauth-bridge-C6fL1qSv.mjs.map +1 -0
- package/dist/openai-DkzRh5_G.mjs +6732 -0
- package/dist/openai-DkzRh5_G.mjs.map +1 -0
- package/dist/openai-codex-responses-vmovNu-q.mjs +1169 -0
- package/dist/openai-codex-responses-vmovNu-q.mjs.map +1 -0
- package/dist/openai-completions-fXHhRolF.mjs +947 -0
- package/dist/openai-completions-fXHhRolF.mjs.map +1 -0
- package/dist/openai-prompt-cache-BDWtZRKh.mjs +11 -0
- package/dist/openai-prompt-cache-BDWtZRKh.mjs.map +1 -0
- package/dist/openai-responses-DKdCYf3h.mjs +247 -0
- package/dist/openai-responses-DKdCYf3h.mjs.map +1 -0
- package/dist/openai-responses-shared-D0Jq7yVP.mjs +572 -0
- package/dist/openai-responses-shared-D0Jq7yVP.mjs.map +1 -0
- package/dist/openrouter-images-fG3Aj6M4.mjs +127 -0
- package/dist/openrouter-images-fG3Aj6M4.mjs.map +1 -0
- package/dist/otel-BQSQRBLF.mjs +24935 -0
- package/dist/otel-BQSQRBLF.mjs.map +1 -0
- package/dist/pi-ai-DhYGgq4Y.mjs +2984 -0
- package/dist/pi-ai-DhYGgq4Y.mjs.map +1 -0
- package/dist/{pi-coding-agent-Z1hTs61i.mjs → pi-coding-agent-fPHwKP4d.mjs} +27 -3
- package/dist/{pi-coding-agent-Z1hTs61i.mjs.map → pi-coding-agent-fPHwKP4d.mjs.map} +1 -1
- package/dist/pi-messages-CV-Ts8An.mjs +306 -0
- package/dist/pi-messages-CV-Ts8An.mjs.map +1 -0
- package/dist/provider-env-C72pF4vP.mjs +40 -0
- package/dist/provider-env-C72pF4vP.mjs.map +1 -0
- package/dist/provider-retry-Cw6YJ4cr.mjs +80 -0
- package/dist/provider-retry-Cw6YJ4cr.mjs.map +1 -0
- package/dist/rolldown-runtime-CTfmNlz1.mjs +44 -0
- package/dist/{runtime-oLd2EInK.mjs → runtime-B9R7bDWT.mjs} +838 -345
- package/dist/runtime-B9R7bDWT.mjs.map +1 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/sanitize-unicode-wLA11KvZ.mjs +29 -0
- package/dist/sanitize-unicode-wLA11KvZ.mjs.map +1 -0
- package/dist/src-C3WBfOks.mjs +5031 -0
- package/dist/src-C3WBfOks.mjs.map +1 -0
- package/dist/transform-messages-DGq9mvhA.mjs +379 -0
- package/dist/transform-messages-DGq9mvhA.mjs.map +1 -0
- package/dist/uuid-DtFT7tOE.mjs +65 -0
- package/dist/uuid-DtFT7tOE.mjs.map +1 -0
- package/package.json +11 -1
- package/dist/compat/pi-ai.mjs.map +0 -1
- package/dist/mcp-config-gqg7GJEE.mjs.map +0 -1
- package/dist/rolldown-runtime-D-uZhY3_.mjs +0 -16
- package/dist/runtime-oLd2EInK.mjs.map +0 -1
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
|
|
2
|
+
import { a as AssistantMessageEventStream, n as createAssistantMessageDiagnostic, t as appendAssistantMessageDiagnostic } from "./diagnostics-CJye1UFh.mjs";
|
|
3
|
+
import { n as providerHeadersToRecord, t as headersToRecord } from "./headers-CPzZhJQn.mjs";
|
|
4
|
+
import { n as parseStreamingJson } from "./json-parse-CFyFZSLJ.mjs";
|
|
5
|
+
import { t as getProviderEnvValue } from "./provider-env-C72pF4vP.mjs";
|
|
6
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.js
|
|
7
|
+
/**
|
|
8
|
+
* pi-messages API implementation.
|
|
9
|
+
*
|
|
10
|
+
* Streams pi's own message protocol directly to a backend: the request is a
|
|
11
|
+
* single POST of `{ model, context, options }` to `<baseUrl>/messages`, the
|
|
12
|
+
* response is an SSE stream of serialized assistant-message events plus a
|
|
13
|
+
* terminal `done`/`error` event. This is the wire protocol spoken by the
|
|
14
|
+
* Radius gateway, but any backend implementing it can be used, e.g. via a
|
|
15
|
+
* models.json custom provider with `"api": "pi-messages"`.
|
|
16
|
+
*/
|
|
17
|
+
var PiMessagesResponseError = class extends Error {
|
|
18
|
+
code;
|
|
19
|
+
diagnosticDetails;
|
|
20
|
+
constructor(message, code, diagnosticDetails) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "PiMessagesResponseError";
|
|
23
|
+
this.code = code;
|
|
24
|
+
this.diagnosticDetails = diagnosticDetails;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function parsePiMessagesErrorBody(body) {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(body);
|
|
30
|
+
const error = parsed?.error;
|
|
31
|
+
return parsed && typeof error === "object" && error !== null && !Array.isArray(error) ? parsed : void 0;
|
|
32
|
+
} catch {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function truncateDiagnosticString(value) {
|
|
37
|
+
const maxLength = 8192;
|
|
38
|
+
return value.length > maxLength ? `${value.slice(0, maxLength)}…` : value;
|
|
39
|
+
}
|
|
40
|
+
function formatPiMessagesResponseError(response, body, errorBody) {
|
|
41
|
+
const message = typeof errorBody?.error?.message === "string" ? errorBody.error.message : void 0;
|
|
42
|
+
const code = typeof errorBody?.error?.code === "string" ? errorBody.error.code : void 0;
|
|
43
|
+
const suffix = message ?? body;
|
|
44
|
+
const codeSuffix = code ? ` (${code})` : "";
|
|
45
|
+
return `${response.status} ${response.statusText}: ${suffix}${codeSuffix}`;
|
|
46
|
+
}
|
|
47
|
+
function createPiMessagesResponseError(model, url, response, body) {
|
|
48
|
+
const errorBody = parsePiMessagesErrorBody(body);
|
|
49
|
+
const code = typeof errorBody?.error?.code === "string" ? errorBody.error.code : void 0;
|
|
50
|
+
return new PiMessagesResponseError(formatPiMessagesResponseError(response, body, errorBody), code, {
|
|
51
|
+
version: 1,
|
|
52
|
+
provider: model.provider,
|
|
53
|
+
model: model.id,
|
|
54
|
+
url: url.toString(),
|
|
55
|
+
status: response.status,
|
|
56
|
+
statusText: response.statusText,
|
|
57
|
+
error: errorBody?.error,
|
|
58
|
+
body: errorBody ? void 0 : truncateDiagnosticString(body),
|
|
59
|
+
timestampMs: Date.now()
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function createEmptyUsage() {
|
|
63
|
+
return {
|
|
64
|
+
input: 0,
|
|
65
|
+
output: 0,
|
|
66
|
+
cacheRead: 0,
|
|
67
|
+
cacheWrite: 0,
|
|
68
|
+
totalTokens: 0,
|
|
69
|
+
cost: {
|
|
70
|
+
input: 0,
|
|
71
|
+
output: 0,
|
|
72
|
+
cacheRead: 0,
|
|
73
|
+
cacheWrite: 0,
|
|
74
|
+
total: 0
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function appendRewriteDiagnostic(message, rewrite) {
|
|
79
|
+
if (!rewrite) return;
|
|
80
|
+
appendAssistantMessageDiagnostic(message, {
|
|
81
|
+
type: "pi_messages_rewrite",
|
|
82
|
+
timestamp: Date.now(),
|
|
83
|
+
details: { ...rewrite }
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function createEventConverter(model) {
|
|
87
|
+
const partial = {
|
|
88
|
+
role: "assistant",
|
|
89
|
+
content: [],
|
|
90
|
+
api: model.api,
|
|
91
|
+
provider: model.provider,
|
|
92
|
+
model: model.id,
|
|
93
|
+
usage: createEmptyUsage(),
|
|
94
|
+
stopReason: "pending",
|
|
95
|
+
timestamp: Date.now()
|
|
96
|
+
};
|
|
97
|
+
const toolJson = /* @__PURE__ */ new Map();
|
|
98
|
+
return (event) => {
|
|
99
|
+
switch (event.type) {
|
|
100
|
+
case "done":
|
|
101
|
+
Object.assign(partial, {
|
|
102
|
+
stopReason: event.reason,
|
|
103
|
+
usage: event.usage,
|
|
104
|
+
responseId: event.responseId
|
|
105
|
+
});
|
|
106
|
+
appendRewriteDiagnostic(partial, event.rewrite);
|
|
107
|
+
return {
|
|
108
|
+
type: "done",
|
|
109
|
+
reason: event.reason,
|
|
110
|
+
message: partial
|
|
111
|
+
};
|
|
112
|
+
case "error":
|
|
113
|
+
Object.assign(partial, {
|
|
114
|
+
stopReason: event.reason,
|
|
115
|
+
usage: event.usage,
|
|
116
|
+
errorMessage: event.errorMessage,
|
|
117
|
+
responseId: event.responseId
|
|
118
|
+
});
|
|
119
|
+
appendRewriteDiagnostic(partial, event.rewrite);
|
|
120
|
+
return {
|
|
121
|
+
type: "error",
|
|
122
|
+
reason: event.reason,
|
|
123
|
+
error: partial
|
|
124
|
+
};
|
|
125
|
+
case "start": break;
|
|
126
|
+
case "text_start":
|
|
127
|
+
partial.content[event.contentIndex] = {
|
|
128
|
+
type: "text",
|
|
129
|
+
text: ""
|
|
130
|
+
};
|
|
131
|
+
break;
|
|
132
|
+
case "text_delta":
|
|
133
|
+
partial.content[event.contentIndex].text += event.delta;
|
|
134
|
+
break;
|
|
135
|
+
case "text_end":
|
|
136
|
+
Object.assign(partial.content[event.contentIndex], {
|
|
137
|
+
text: event.content,
|
|
138
|
+
textSignature: event.contentSignature
|
|
139
|
+
});
|
|
140
|
+
break;
|
|
141
|
+
case "thinking_start":
|
|
142
|
+
partial.content[event.contentIndex] = {
|
|
143
|
+
type: "thinking",
|
|
144
|
+
thinking: ""
|
|
145
|
+
};
|
|
146
|
+
break;
|
|
147
|
+
case "thinking_delta":
|
|
148
|
+
partial.content[event.contentIndex].thinking += event.delta;
|
|
149
|
+
break;
|
|
150
|
+
case "thinking_end":
|
|
151
|
+
Object.assign(partial.content[event.contentIndex], {
|
|
152
|
+
thinking: event.content,
|
|
153
|
+
thinkingSignature: event.contentSignature,
|
|
154
|
+
redacted: event.redacted
|
|
155
|
+
});
|
|
156
|
+
break;
|
|
157
|
+
case "toolcall_start":
|
|
158
|
+
partial.content[event.contentIndex] = {
|
|
159
|
+
type: "toolCall",
|
|
160
|
+
id: event.id,
|
|
161
|
+
name: event.toolName,
|
|
162
|
+
arguments: {}
|
|
163
|
+
};
|
|
164
|
+
toolJson.set(event.contentIndex, "");
|
|
165
|
+
break;
|
|
166
|
+
case "toolcall_delta": {
|
|
167
|
+
const json = `${toolJson.get(event.contentIndex) ?? ""}${event.delta}`;
|
|
168
|
+
toolJson.set(event.contentIndex, json);
|
|
169
|
+
partial.content[event.contentIndex].arguments = parseStreamingJson(json);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
case "toolcall_end":
|
|
173
|
+
Object.assign(partial.content[event.contentIndex], event.toolCall);
|
|
174
|
+
toolJson.delete(event.contentIndex);
|
|
175
|
+
return {
|
|
176
|
+
type: "toolcall_end",
|
|
177
|
+
contentIndex: event.contentIndex,
|
|
178
|
+
toolCall: partial.content[event.contentIndex],
|
|
179
|
+
partial
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
...event,
|
|
184
|
+
partial
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
async function* readPiMessagesEvents(stream) {
|
|
189
|
+
const decoder = new TextDecoder();
|
|
190
|
+
const reader = stream.getReader();
|
|
191
|
+
let buffer = "";
|
|
192
|
+
try {
|
|
193
|
+
while (true) {
|
|
194
|
+
const { done, value } = await reader.read();
|
|
195
|
+
buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });
|
|
196
|
+
buffer = buffer.replace(/\r\n/g, "\n");
|
|
197
|
+
let split = buffer.indexOf("\n\n");
|
|
198
|
+
while (split !== -1) {
|
|
199
|
+
const event = parsePiMessagesEvent(buffer.slice(0, split));
|
|
200
|
+
if (event) yield event;
|
|
201
|
+
buffer = buffer.slice(split + 2);
|
|
202
|
+
split = buffer.indexOf("\n\n");
|
|
203
|
+
}
|
|
204
|
+
if (done) break;
|
|
205
|
+
}
|
|
206
|
+
if (buffer.trim()) {
|
|
207
|
+
const event = parsePiMessagesEvent(buffer);
|
|
208
|
+
if (event) yield event;
|
|
209
|
+
}
|
|
210
|
+
} finally {
|
|
211
|
+
reader.releaseLock();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function parsePiMessagesEvent(raw) {
|
|
215
|
+
const data = raw.split("\n").find((line) => line.startsWith("data:"))?.slice(5).trim();
|
|
216
|
+
return data && data !== "[DONE]" ? JSON.parse(data) : void 0;
|
|
217
|
+
}
|
|
218
|
+
function createErrorEvent(model, error, aborted) {
|
|
219
|
+
const reason = aborted ? "aborted" : "error";
|
|
220
|
+
const assistantMessage = {
|
|
221
|
+
role: "assistant",
|
|
222
|
+
content: [],
|
|
223
|
+
api: model.api,
|
|
224
|
+
provider: model.provider,
|
|
225
|
+
model: model.id,
|
|
226
|
+
usage: createEmptyUsage(),
|
|
227
|
+
stopReason: reason,
|
|
228
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
229
|
+
timestamp: Date.now()
|
|
230
|
+
};
|
|
231
|
+
if (!aborted && error instanceof PiMessagesResponseError) appendAssistantMessageDiagnostic(assistantMessage, createAssistantMessageDiagnostic("pi_messages_response_failure", error, error.diagnosticDetails));
|
|
232
|
+
return {
|
|
233
|
+
type: "error",
|
|
234
|
+
reason,
|
|
235
|
+
error: assistantMessage
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function resolveCacheRetention(cacheRetention, env) {
|
|
239
|
+
if (cacheRetention) return cacheRetention;
|
|
240
|
+
return getProviderEnvValue("PI_CACHE_RETENTION", env) === "long" ? "long" : void 0;
|
|
241
|
+
}
|
|
242
|
+
const stream = (model, context, options) => {
|
|
243
|
+
const eventStream = new AssistantMessageEventStream();
|
|
244
|
+
const convertEvent = createEventConverter(model);
|
|
245
|
+
(async () => {
|
|
246
|
+
try {
|
|
247
|
+
const apiKey = options?.apiKey;
|
|
248
|
+
if (!apiKey) throw new Error(`No API key provided for provider "${model.provider}"`);
|
|
249
|
+
const url = new URL(`${model.baseUrl.replace(/\/+$/u, "")}/messages`);
|
|
250
|
+
if (options?.debug) url.searchParams.set("debug", "1");
|
|
251
|
+
let payload = {
|
|
252
|
+
model: model.id,
|
|
253
|
+
context,
|
|
254
|
+
options: {
|
|
255
|
+
temperature: options?.temperature,
|
|
256
|
+
maxTokens: options?.maxTokens,
|
|
257
|
+
reasoning: options?.reasoning,
|
|
258
|
+
cacheRetention: resolveCacheRetention(options?.cacheRetention, options?.env),
|
|
259
|
+
sessionId: options?.sessionId,
|
|
260
|
+
toolChoice: options?.toolChoice
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
const nextPayload = await options?.onPayload?.(payload, model);
|
|
264
|
+
if (nextPayload !== void 0) payload = nextPayload;
|
|
265
|
+
const response = await (options?.fetch ?? globalThis.fetch)(url, {
|
|
266
|
+
method: "POST",
|
|
267
|
+
headers: {
|
|
268
|
+
authorization: `Bearer ${apiKey}`,
|
|
269
|
+
accept: "text/event-stream",
|
|
270
|
+
"content-type": "application/json",
|
|
271
|
+
...providerHeadersToRecord(options?.headers)
|
|
272
|
+
},
|
|
273
|
+
body: JSON.stringify(payload),
|
|
274
|
+
signal: options?.signal
|
|
275
|
+
});
|
|
276
|
+
await options?.onResponse?.({
|
|
277
|
+
status: response.status,
|
|
278
|
+
headers: headersToRecord(response.headers)
|
|
279
|
+
}, model);
|
|
280
|
+
if (!response.ok) throw createPiMessagesResponseError(model, url, response, await response.text());
|
|
281
|
+
if (!response.body) throw new Error(`${model.provider} response has no body`);
|
|
282
|
+
for await (const piEvent of readPiMessagesEvents(response.body)) {
|
|
283
|
+
const event = convertEvent(piEvent);
|
|
284
|
+
eventStream.push(event);
|
|
285
|
+
if (event.type === "done" || event.type === "error") return;
|
|
286
|
+
}
|
|
287
|
+
throw new Error(`${model.provider} stream ended without a terminal event`);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
eventStream.push(createErrorEvent(model, error, options?.signal?.aborted ?? false));
|
|
290
|
+
}
|
|
291
|
+
})();
|
|
292
|
+
return eventStream;
|
|
293
|
+
};
|
|
294
|
+
const streamSimple = (model, context, options) => {
|
|
295
|
+
const extra = options;
|
|
296
|
+
return stream(model, context, {
|
|
297
|
+
...options,
|
|
298
|
+
reasoning: options?.reasoning,
|
|
299
|
+
toolChoice: extra?.toolChoice,
|
|
300
|
+
debug: extra?.debug
|
|
301
|
+
});
|
|
302
|
+
};
|
|
303
|
+
//#endregion
|
|
304
|
+
export { PiMessagesResponseError, stream, streamSimple };
|
|
305
|
+
|
|
306
|
+
//# sourceMappingURL=pi-messages-CV-Ts8An.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-messages-CV-Ts8An.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/pi-messages.js"],"sourcesContent":["/**\n * pi-messages API implementation.\n *\n * Streams pi's own message protocol directly to a backend: the request is a\n * single POST of `{ model, context, options }` to `<baseUrl>/messages`, the\n * response is an SSE stream of serialized assistant-message events plus a\n * terminal `done`/`error` event. This is the wire protocol spoken by the\n * Radius gateway, but any backend implementing it can be used, e.g. via a\n * models.json custom provider with `\"api\": \"pi-messages\"`.\n */\nimport { appendAssistantMessageDiagnostic, createAssistantMessageDiagnostic } from \"../utils/diagnostics.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport { headersToRecord, providerHeadersToRecord } from \"../utils/headers.js\";\nimport { parseStreamingJson } from \"../utils/json-parse.js\";\nimport { getProviderEnvValue } from \"../utils/provider-env.js\";\nexport class PiMessagesResponseError extends Error {\n code;\n diagnosticDetails;\n constructor(message, code, diagnosticDetails) {\n super(message);\n this.name = \"PiMessagesResponseError\";\n this.code = code;\n this.diagnosticDetails = diagnosticDetails;\n }\n}\nfunction parsePiMessagesErrorBody(body) {\n try {\n const parsed = JSON.parse(body);\n const error = parsed?.error;\n return parsed && typeof error === \"object\" && error !== null && !Array.isArray(error) ? parsed : undefined;\n }\n catch {\n return undefined;\n }\n}\nfunction truncateDiagnosticString(value) {\n const maxLength = 8192;\n return value.length > maxLength ? `${value.slice(0, maxLength)}…` : value;\n}\nfunction formatPiMessagesResponseError(response, body, errorBody) {\n const message = typeof errorBody?.error?.message === \"string\" ? errorBody.error.message : undefined;\n const code = typeof errorBody?.error?.code === \"string\" ? errorBody.error.code : undefined;\n const suffix = message ?? body;\n const codeSuffix = code ? ` (${code})` : \"\";\n return `${response.status} ${response.statusText}: ${suffix}${codeSuffix}`;\n}\nfunction createPiMessagesResponseError(model, url, response, body) {\n const errorBody = parsePiMessagesErrorBody(body);\n const code = typeof errorBody?.error?.code === \"string\" ? errorBody.error.code : undefined;\n return new PiMessagesResponseError(formatPiMessagesResponseError(response, body, errorBody), code, {\n version: 1,\n provider: model.provider,\n model: model.id,\n url: url.toString(),\n status: response.status,\n statusText: response.statusText,\n error: errorBody?.error,\n body: errorBody ? undefined : truncateDiagnosticString(body),\n timestampMs: Date.now(),\n });\n}\nfunction createEmptyUsage() {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n };\n}\nfunction appendRewriteDiagnostic(message, rewrite) {\n if (!rewrite) {\n return;\n }\n appendAssistantMessageDiagnostic(message, {\n type: \"pi_messages_rewrite\",\n timestamp: Date.now(),\n details: { ...rewrite },\n });\n}\nfunction createEventConverter(model) {\n const partial = {\n role: \"assistant\",\n content: [],\n api: model.api,\n provider: model.provider,\n model: model.id,\n usage: createEmptyUsage(),\n stopReason: \"pending\",\n timestamp: Date.now(),\n };\n const toolJson = new Map();\n return (event) => {\n switch (event.type) {\n case \"done\":\n Object.assign(partial, {\n stopReason: event.reason,\n usage: event.usage,\n responseId: event.responseId,\n });\n appendRewriteDiagnostic(partial, event.rewrite);\n return { type: \"done\", reason: event.reason, message: partial };\n case \"error\":\n Object.assign(partial, {\n stopReason: event.reason,\n usage: event.usage,\n errorMessage: event.errorMessage,\n responseId: event.responseId,\n });\n appendRewriteDiagnostic(partial, event.rewrite);\n return { type: \"error\", reason: event.reason, error: partial };\n case \"start\":\n break;\n case \"text_start\":\n partial.content[event.contentIndex] = { type: \"text\", text: \"\" };\n break;\n case \"text_delta\":\n partial.content[event.contentIndex].text += event.delta;\n break;\n case \"text_end\":\n Object.assign(partial.content[event.contentIndex], {\n text: event.content,\n textSignature: event.contentSignature,\n });\n break;\n case \"thinking_start\":\n partial.content[event.contentIndex] = { type: \"thinking\", thinking: \"\" };\n break;\n case \"thinking_delta\":\n partial.content[event.contentIndex].thinking += event.delta;\n break;\n case \"thinking_end\":\n Object.assign(partial.content[event.contentIndex], {\n thinking: event.content,\n thinkingSignature: event.contentSignature,\n redacted: event.redacted,\n });\n break;\n case \"toolcall_start\":\n partial.content[event.contentIndex] = {\n type: \"toolCall\",\n id: event.id,\n name: event.toolName,\n arguments: {},\n };\n toolJson.set(event.contentIndex, \"\");\n break;\n case \"toolcall_delta\": {\n const json = `${toolJson.get(event.contentIndex) ?? \"\"}${event.delta}`;\n toolJson.set(event.contentIndex, json);\n partial.content[event.contentIndex].arguments =\n parseStreamingJson(json);\n break;\n }\n case \"toolcall_end\":\n Object.assign(partial.content[event.contentIndex], event.toolCall);\n toolJson.delete(event.contentIndex);\n return {\n type: \"toolcall_end\",\n contentIndex: event.contentIndex,\n toolCall: partial.content[event.contentIndex],\n partial,\n };\n }\n return { ...event, partial };\n };\n}\nasync function* readPiMessagesEvents(stream) {\n const decoder = new TextDecoder();\n const reader = stream.getReader();\n let buffer = \"\";\n try {\n while (true) {\n const { done, value } = await reader.read();\n buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });\n buffer = buffer.replace(/\\r\\n/g, \"\\n\");\n let split = buffer.indexOf(\"\\n\\n\");\n while (split !== -1) {\n const event = parsePiMessagesEvent(buffer.slice(0, split));\n if (event) {\n yield event;\n }\n buffer = buffer.slice(split + 2);\n split = buffer.indexOf(\"\\n\\n\");\n }\n if (done) {\n break;\n }\n }\n if (buffer.trim()) {\n const event = parsePiMessagesEvent(buffer);\n if (event) {\n yield event;\n }\n }\n }\n finally {\n reader.releaseLock();\n }\n}\nfunction parsePiMessagesEvent(raw) {\n const data = raw\n .split(\"\\n\")\n .find((line) => line.startsWith(\"data:\"))\n ?.slice(5)\n .trim();\n return data && data !== \"[DONE]\" ? JSON.parse(data) : undefined;\n}\nfunction createErrorEvent(model, error, aborted) {\n const reason = aborted ? \"aborted\" : \"error\";\n const assistantMessage = {\n role: \"assistant\",\n content: [],\n api: model.api,\n provider: model.provider,\n model: model.id,\n usage: createEmptyUsage(),\n stopReason: reason,\n errorMessage: error instanceof Error ? error.message : String(error),\n timestamp: Date.now(),\n };\n if (!aborted && error instanceof PiMessagesResponseError) {\n appendAssistantMessageDiagnostic(assistantMessage, createAssistantMessageDiagnostic(\"pi_messages_response_failure\", error, error.diagnosticDetails));\n }\n return { type: \"error\", reason, error: assistantMessage };\n}\nfunction resolveCacheRetention(cacheRetention, env) {\n if (cacheRetention) {\n return cacheRetention;\n }\n // Backend defaults apply when unset; only the legacy env opt-in is mapped.\n return getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\" ? \"long\" : undefined;\n}\nexport const stream = (model, context, options) => {\n const eventStream = new AssistantMessageEventStream();\n const convertEvent = createEventConverter(model);\n void (async () => {\n try {\n const apiKey = options?.apiKey;\n if (!apiKey) {\n throw new Error(`No API key provided for provider \"${model.provider}\"`);\n }\n const url = new URL(`${model.baseUrl.replace(/\\/+$/u, \"\")}/messages`);\n if (options?.debug) {\n url.searchParams.set(\"debug\", \"1\");\n }\n let payload = {\n model: model.id,\n context,\n options: {\n temperature: options?.temperature,\n maxTokens: options?.maxTokens,\n reasoning: options?.reasoning,\n cacheRetention: resolveCacheRetention(options?.cacheRetention, options?.env),\n sessionId: options?.sessionId,\n toolChoice: options?.toolChoice,\n },\n };\n const nextPayload = await options?.onPayload?.(payload, model);\n if (nextPayload !== undefined) {\n payload = nextPayload;\n }\n const response = await (options?.fetch ?? globalThis.fetch)(url, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${apiKey}`,\n accept: \"text/event-stream\",\n \"content-type\": \"application/json\",\n ...providerHeadersToRecord(options?.headers),\n },\n body: JSON.stringify(payload),\n signal: options?.signal,\n });\n await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n if (!response.ok) {\n const body = await response.text();\n throw createPiMessagesResponseError(model, url, response, body);\n }\n if (!response.body) {\n throw new Error(`${model.provider} response has no body`);\n }\n for await (const piEvent of readPiMessagesEvents(response.body)) {\n const event = convertEvent(piEvent);\n eventStream.push(event);\n if (event.type === \"done\" || event.type === \"error\") {\n return;\n }\n }\n throw new Error(`${model.provider} stream ended without a terminal event`);\n }\n catch (error) {\n eventStream.push(createErrorEvent(model, error, options?.signal?.aborted ?? false));\n }\n })();\n return eventStream;\n};\nexport const streamSimple = (model, context, options) => {\n const extra = options;\n return stream(model, context, {\n ...options,\n reasoning: options?.reasoning,\n toolChoice: extra?.toolChoice,\n debug: extra?.debug,\n });\n};\n//# sourceMappingURL=pi-messages.js.map"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
import { i as __require } from "./rolldown-runtime-CTfmNlz1.mjs";
|
|
3
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/provider-env.js
|
|
4
|
+
let procEnvCache = null;
|
|
5
|
+
/**
|
|
6
|
+
* Fallback for https://github.com/oven-sh/bun/issues/27802.
|
|
7
|
+
* Bun compiled binaries can expose an empty process.env inside Linux sandboxes
|
|
8
|
+
* even though /proc/self/environ contains the environment.
|
|
9
|
+
*
|
|
10
|
+
* This intentionally duplicates restoreSandboxEnv() in
|
|
11
|
+
* packages/coding-agent/src/bun/restore-sandbox-env.ts. The ai package can be
|
|
12
|
+
* used directly, without going through that entrypoint, so provider env lookup
|
|
13
|
+
* must not depend on process.env having been patched.
|
|
14
|
+
*/
|
|
15
|
+
function getBunSandboxEnvValue(name) {
|
|
16
|
+
if (typeof process === "undefined" || !process.versions?.bun || Object.keys(process.env).length > 0) return;
|
|
17
|
+
if (procEnvCache === null) {
|
|
18
|
+
procEnvCache = /* @__PURE__ */ new Map();
|
|
19
|
+
try {
|
|
20
|
+
const { readFileSync } = __require("node:fs");
|
|
21
|
+
const data = readFileSync("/proc/self/environ", "utf-8");
|
|
22
|
+
for (const entry of data.split("\0")) {
|
|
23
|
+
const idx = entry.indexOf("=");
|
|
24
|
+
if (idx > 0) procEnvCache.set(entry.slice(0, idx), entry.slice(idx + 1));
|
|
25
|
+
}
|
|
26
|
+
} catch {}
|
|
27
|
+
}
|
|
28
|
+
return procEnvCache.get(name);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a provider env value from scoped overrides, normal process.env, then
|
|
32
|
+
* the duplicated Bun sandbox fallback for direct pi-ai consumers.
|
|
33
|
+
*/
|
|
34
|
+
function getProviderEnvValue(name, env) {
|
|
35
|
+
return env?.[name] || (typeof process !== "undefined" ? process.env[name] : void 0) || getBunSandboxEnvValue(name) || void 0;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { getProviderEnvValue as t };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=provider-env-C72pF4vP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-env-C72pF4vP.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/provider-env.js"],"sourcesContent":["let procEnvCache = null;\n/**\n * Fallback for https://github.com/oven-sh/bun/issues/27802.\n * Bun compiled binaries can expose an empty process.env inside Linux sandboxes\n * even though /proc/self/environ contains the environment.\n *\n * This intentionally duplicates restoreSandboxEnv() in\n * packages/coding-agent/src/bun/restore-sandbox-env.ts. The ai package can be\n * used directly, without going through that entrypoint, so provider env lookup\n * must not depend on process.env having been patched.\n */\nfunction getBunSandboxEnvValue(name) {\n if (typeof process === \"undefined\" || !process.versions?.bun || Object.keys(process.env).length > 0) {\n return undefined;\n }\n if (procEnvCache === null) {\n procEnvCache = new Map();\n try {\n const { readFileSync } = require(\"node:fs\");\n const data = readFileSync(\"/proc/self/environ\", \"utf-8\");\n for (const entry of data.split(\"\\0\")) {\n const idx = entry.indexOf(\"=\");\n if (idx > 0) {\n procEnvCache.set(entry.slice(0, idx), entry.slice(idx + 1));\n }\n }\n }\n catch {\n // /proc/self/environ may not exist or may not be readable.\n }\n }\n return procEnvCache.get(name);\n}\n/**\n * Resolve a provider env value from scoped overrides, normal process.env, then\n * the duplicated Bun sandbox fallback for direct pi-ai consumers.\n */\nexport function getProviderEnvValue(name, env) {\n return (env?.[name] ||\n (typeof process !== \"undefined\" ? process.env[name] : undefined) ||\n getBunSandboxEnvValue(name) ||\n undefined);\n}\n//# sourceMappingURL=provider-env.js.map"],"x_google_ignoreList":[0],"mappings":";;;AAAA,IAAI,eAAe;;;;;;;;;;;AAWnB,SAAS,sBAAsB,MAAM;CACjC,IAAI,OAAO,YAAY,eAAe,CAAC,QAAQ,UAAU,OAAO,OAAO,KAAK,QAAQ,GAAG,CAAC,CAAC,SAAS,GAC9F;CAEJ,IAAI,iBAAiB,MAAM;EACvB,+BAAe,IAAI,IAAI;EACvB,IAAI;GACA,MAAM,EAAE,iBAAA,UAAyB,SAAS;GAC1C,MAAM,OAAO,aAAa,sBAAsB,OAAO;GACvD,KAAK,MAAM,SAAS,KAAK,MAAM,IAAI,GAAG;IAClC,MAAM,MAAM,MAAM,QAAQ,GAAG;IAC7B,IAAI,MAAM,GACN,aAAa,IAAI,MAAM,MAAM,GAAG,GAAG,GAAG,MAAM,MAAM,MAAM,CAAC,CAAC;GAElE;EACJ,QACM,CAEN;CACJ;CACA,OAAO,aAAa,IAAI,IAAI;AAChC;;;;;AAKA,SAAgB,oBAAoB,MAAM,KAAK;CAC3C,OAAQ,MAAM,UACT,OAAO,YAAY,cAAc,QAAQ,IAAI,QAAQ,KAAA,MACtD,sBAAsB,IAAI,KAC1B,KAAA;AACR"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
|
|
2
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/provider-retry.js
|
|
3
|
+
const DEFAULT_MAX_RETRY_DELAY_MS = 6e4;
|
|
4
|
+
function isProviderError(error) {
|
|
5
|
+
if (!(error instanceof Error) || !("status" in error) || !("headers" in error)) return false;
|
|
6
|
+
return (error.status === void 0 || typeof error.status === "number") && (error.headers === void 0 || error.headers instanceof Headers);
|
|
7
|
+
}
|
|
8
|
+
/** Mirrors the pinned OpenAI/Anthropic SDK retry policy; review when either SDK is upgraded. */
|
|
9
|
+
function isRetryableProviderError(error) {
|
|
10
|
+
const shouldRetry = error.headers?.get("x-should-retry");
|
|
11
|
+
if (shouldRetry === "true") return true;
|
|
12
|
+
if (shouldRetry === "false") return false;
|
|
13
|
+
if (error.status === void 0) return true;
|
|
14
|
+
return error.status === 408 || error.status === 409 || error.status === 429 || typeof error.status === "number" && error.status >= 500;
|
|
15
|
+
}
|
|
16
|
+
function validateServerRetryDelayMs(delayMs, maxRetryDelayMs, providerErrorMessage) {
|
|
17
|
+
const maxDelayMs = maxRetryDelayMs ?? DEFAULT_MAX_RETRY_DELAY_MS;
|
|
18
|
+
if (maxDelayMs > 0 && delayMs > maxDelayMs) throw new Error(`Server requested ${Math.ceil(delayMs / 1e3)}s retry delay (max: ${Math.ceil(maxDelayMs / 1e3)}s). ${providerErrorMessage}`);
|
|
19
|
+
return delayMs;
|
|
20
|
+
}
|
|
21
|
+
function getRetryDelayMs(error, retryIndex, maxRetryDelayMs) {
|
|
22
|
+
const retryAfterMs = error.headers?.get("retry-after-ms");
|
|
23
|
+
if (retryAfterMs) {
|
|
24
|
+
const value = Number.parseFloat(retryAfterMs);
|
|
25
|
+
if (!Number.isNaN(value)) return validateServerRetryDelayMs(value, maxRetryDelayMs, error.message);
|
|
26
|
+
}
|
|
27
|
+
const retryAfter = error.headers?.get("retry-after");
|
|
28
|
+
if (retryAfter) {
|
|
29
|
+
const seconds = Number.parseFloat(retryAfter);
|
|
30
|
+
return validateServerRetryDelayMs(Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1e3, maxRetryDelayMs, error.message);
|
|
31
|
+
}
|
|
32
|
+
return Math.min(.5 * 2 ** retryIndex, 8) * 1e3 * (1 - Math.random() * .25);
|
|
33
|
+
}
|
|
34
|
+
function createAbortError() {
|
|
35
|
+
const error = /* @__PURE__ */ new Error("Request aborted");
|
|
36
|
+
error.name = "AbortError";
|
|
37
|
+
return error;
|
|
38
|
+
}
|
|
39
|
+
function abortableSleep(ms, signal) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
if (signal?.aborted) {
|
|
42
|
+
reject(createAbortError());
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const onAbort = () => {
|
|
46
|
+
clearTimeout(timeout);
|
|
47
|
+
reject(createAbortError());
|
|
48
|
+
};
|
|
49
|
+
const timeout = setTimeout(() => {
|
|
50
|
+
signal?.removeEventListener("abort", onAbort);
|
|
51
|
+
resolve();
|
|
52
|
+
}, Math.max(0, ms));
|
|
53
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Reproduce the retry behavior used by the OpenAI and Anthropic SDKs while making
|
|
58
|
+
* their backoff sleep interruptible. Their built-in retry timers ignore the
|
|
59
|
+
* request AbortSignal, so callers must invoke the SDK with `maxRetries: 0` and
|
|
60
|
+
* wrap the request with this helper. Provider-requested delays above
|
|
61
|
+
* `maxRetryDelayMs` fail immediately (60 seconds by default); set it to zero to
|
|
62
|
+
* disable the limit.
|
|
63
|
+
*/
|
|
64
|
+
async function retryProviderRequest(request, options = {}) {
|
|
65
|
+
const maxRetries = options.maxRetries ?? 0;
|
|
66
|
+
let retriesRemaining = maxRetries;
|
|
67
|
+
for (;;) try {
|
|
68
|
+
return await request();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (options.signal?.aborted) throw createAbortError();
|
|
71
|
+
if (retriesRemaining <= 0 || !isProviderError(error) || !isRetryableProviderError(error)) throw error;
|
|
72
|
+
const retryIndex = maxRetries - retriesRemaining;
|
|
73
|
+
retriesRemaining--;
|
|
74
|
+
await abortableSleep(getRetryDelayMs(error, retryIndex, options.maxRetryDelayMs), options.signal);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
export { retryProviderRequest as t };
|
|
79
|
+
|
|
80
|
+
//# sourceMappingURL=provider-retry-Cw6YJ4cr.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-retry-Cw6YJ4cr.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/provider-retry.js"],"sourcesContent":["const DEFAULT_MAX_RETRY_DELAY_MS = 60_000;\nfunction isProviderError(error) {\n if (!(error instanceof Error) || !(\"status\" in error) || !(\"headers\" in error))\n return false;\n return ((error.status === undefined || typeof error.status === \"number\") &&\n (error.headers === undefined || error.headers instanceof Headers));\n}\n/** Mirrors the pinned OpenAI/Anthropic SDK retry policy; review when either SDK is upgraded. */\nfunction isRetryableProviderError(error) {\n const shouldRetry = error.headers?.get(\"x-should-retry\");\n if (shouldRetry === \"true\")\n return true;\n if (shouldRetry === \"false\")\n return false;\n if (error.status === undefined)\n return true;\n return (error.status === 408 ||\n error.status === 409 ||\n error.status === 429 ||\n (typeof error.status === \"number\" && error.status >= 500));\n}\nfunction validateServerRetryDelayMs(delayMs, maxRetryDelayMs, providerErrorMessage) {\n const maxDelayMs = maxRetryDelayMs ?? DEFAULT_MAX_RETRY_DELAY_MS;\n if (maxDelayMs > 0 && delayMs > maxDelayMs) {\n throw new Error(`Server requested ${Math.ceil(delayMs / 1000)}s retry delay (max: ${Math.ceil(maxDelayMs / 1000)}s). ${providerErrorMessage}`);\n }\n return delayMs;\n}\nfunction getRetryDelayMs(error, retryIndex, maxRetryDelayMs) {\n const retryAfterMs = error.headers?.get(\"retry-after-ms\");\n if (retryAfterMs) {\n const value = Number.parseFloat(retryAfterMs);\n if (!Number.isNaN(value))\n return validateServerRetryDelayMs(value, maxRetryDelayMs, error.message);\n }\n const retryAfter = error.headers?.get(\"retry-after\");\n if (retryAfter) {\n const seconds = Number.parseFloat(retryAfter);\n const delayMs = Number.isNaN(seconds) ? Date.parse(retryAfter) - Date.now() : seconds * 1000;\n return validateServerRetryDelayMs(delayMs, maxRetryDelayMs, error.message);\n }\n const exponentialDelay = Math.min(0.5 * 2 ** retryIndex, 8) * 1000;\n return exponentialDelay * (1 - Math.random() * 0.25);\n}\nfunction createAbortError() {\n const error = new Error(\"Request aborted\");\n error.name = \"AbortError\";\n return error;\n}\nfunction abortableSleep(ms, signal) {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(createAbortError());\n return;\n }\n const onAbort = () => {\n clearTimeout(timeout);\n reject(createAbortError());\n };\n const timeout = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, Math.max(0, ms));\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n/**\n * Reproduce the retry behavior used by the OpenAI and Anthropic SDKs while making\n * their backoff sleep interruptible. Their built-in retry timers ignore the\n * request AbortSignal, so callers must invoke the SDK with `maxRetries: 0` and\n * wrap the request with this helper. Provider-requested delays above\n * `maxRetryDelayMs` fail immediately (60 seconds by default); set it to zero to\n * disable the limit.\n */\nexport async function retryProviderRequest(request, options = {}) {\n const maxRetries = options.maxRetries ?? 0;\n let retriesRemaining = maxRetries;\n for (;;) {\n try {\n // Each retry is a fresh SDK request, so X-Stainless-Retry-Count remains zero.\n return await request();\n }\n catch (error) {\n if (options.signal?.aborted)\n throw createAbortError();\n if (retriesRemaining <= 0 || !isProviderError(error) || !isRetryableProviderError(error))\n throw error;\n const retryIndex = maxRetries - retriesRemaining;\n retriesRemaining--;\n await abortableSleep(getRetryDelayMs(error, retryIndex, options.maxRetryDelayMs), options.signal);\n }\n }\n}\n//# sourceMappingURL=provider-retry.js.map"],"x_google_ignoreList":[0],"mappings":";;AAAA,MAAM,6BAA6B;AACnC,SAAS,gBAAgB,OAAO;CAC5B,IAAI,EAAE,iBAAiB,UAAU,EAAE,YAAY,UAAU,EAAE,aAAa,QACpE,OAAO;CACX,QAAS,MAAM,WAAW,KAAA,KAAa,OAAO,MAAM,WAAW,cAC1D,MAAM,YAAY,KAAA,KAAa,MAAM,mBAAmB;AACjE;;AAEA,SAAS,yBAAyB,OAAO;CACrC,MAAM,cAAc,MAAM,SAAS,IAAI,gBAAgB;CACvD,IAAI,gBAAgB,QAChB,OAAO;CACX,IAAI,gBAAgB,SAChB,OAAO;CACX,IAAI,MAAM,WAAW,KAAA,GACjB,OAAO;CACX,OAAQ,MAAM,WAAW,OACrB,MAAM,WAAW,OACjB,MAAM,WAAW,OAChB,OAAO,MAAM,WAAW,YAAY,MAAM,UAAU;AAC7D;AACA,SAAS,2BAA2B,SAAS,iBAAiB,sBAAsB;CAChF,MAAM,aAAa,mBAAmB;CACtC,IAAI,aAAa,KAAK,UAAU,YAC5B,MAAM,IAAI,MAAM,oBAAoB,KAAK,KAAK,UAAU,GAAI,EAAE,sBAAsB,KAAK,KAAK,aAAa,GAAI,EAAE,MAAM,sBAAsB;CAEjJ,OAAO;AACX;AACA,SAAS,gBAAgB,OAAO,YAAY,iBAAiB;CACzD,MAAM,eAAe,MAAM,SAAS,IAAI,gBAAgB;CACxD,IAAI,cAAc;EACd,MAAM,QAAQ,OAAO,WAAW,YAAY;EAC5C,IAAI,CAAC,OAAO,MAAM,KAAK,GACnB,OAAO,2BAA2B,OAAO,iBAAiB,MAAM,OAAO;CAC/E;CACA,MAAM,aAAa,MAAM,SAAS,IAAI,aAAa;CACnD,IAAI,YAAY;EACZ,MAAM,UAAU,OAAO,WAAW,UAAU;EAE5C,OAAO,2BADS,OAAO,MAAM,OAAO,IAAI,KAAK,MAAM,UAAU,IAAI,KAAK,IAAI,IAAI,UAAU,KAC7C,iBAAiB,MAAM,OAAO;CAC7E;CAEA,OADyB,KAAK,IAAI,KAAM,KAAK,YAAY,CAAC,IAAI,OACnC,IAAI,KAAK,OAAO,IAAI;AACnD;AACA,SAAS,mBAAmB;CACxB,MAAM,wBAAQ,IAAI,MAAM,iBAAiB;CACzC,MAAM,OAAO;CACb,OAAO;AACX;AACA,SAAS,eAAe,IAAI,QAAQ;CAChC,OAAO,IAAI,SAAS,SAAS,WAAW;EACpC,IAAI,QAAQ,SAAS;GACjB,OAAO,iBAAiB,CAAC;GACzB;EACJ;EACA,MAAM,gBAAgB;GAClB,aAAa,OAAO;GACpB,OAAO,iBAAiB,CAAC;EAC7B;EACA,MAAM,UAAU,iBAAiB;GAC7B,QAAQ,oBAAoB,SAAS,OAAO;GAC5C,QAAQ;EACZ,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC;EAClB,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;CAC7D,CAAC;AACL;;;;;;;;;AASA,eAAsB,qBAAqB,SAAS,UAAU,CAAC,GAAG;CAC9D,MAAM,aAAa,QAAQ,cAAc;CACzC,IAAI,mBAAmB;CACvB,SACI,IAAI;EAEA,OAAO,MAAM,QAAQ;CACzB,SACO,OAAO;EACV,IAAI,QAAQ,QAAQ,SAChB,MAAM,iBAAiB;EAC3B,IAAI,oBAAoB,KAAK,CAAC,gBAAgB,KAAK,KAAK,CAAC,yBAAyB,KAAK,GACnF,MAAM;EACV,MAAM,aAAa,aAAa;EAChC;EACA,MAAM,eAAe,gBAAgB,OAAO,YAAY,QAAQ,eAAe,GAAG,QAAQ,MAAM;CACpG;AAER"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
//#region \0rolldown/runtime.js
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __esmMin = (fn, res, err) => () => {
|
|
11
|
+
if (err) throw err[0];
|
|
12
|
+
try {
|
|
13
|
+
return fn && (res = fn(fn = 0)), res;
|
|
14
|
+
} catch (e) {
|
|
15
|
+
throw err = [e], e;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
19
|
+
var __exportAll = (all, no_symbols) => {
|
|
20
|
+
let target = {};
|
|
21
|
+
for (var name in all) __defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true
|
|
24
|
+
});
|
|
25
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
26
|
+
return target;
|
|
27
|
+
};
|
|
28
|
+
var __copyProps = (to, from, except, desc) => {
|
|
29
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
30
|
+
key = keys[i];
|
|
31
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
32
|
+
get: ((k) => from[k]).bind(null, key),
|
|
33
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return to;
|
|
37
|
+
};
|
|
38
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
39
|
+
value: mod,
|
|
40
|
+
enumerable: true
|
|
41
|
+
}) : target, mod));
|
|
42
|
+
var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
|
|
43
|
+
//#endregion
|
|
44
|
+
export { __toESM as a, __require as i, __esmMin as n, __exportAll as r, __commonJSMin as t };
|