@prestyj/agent 4.3.239 → 4.5.0
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/dist/index.cjs +64 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +66 -14
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -5,7 +5,8 @@ import { EventStream as EventStream2 } from "@prestyj/ai";
|
|
|
5
5
|
import { ZodError, prettifyError } from "zod";
|
|
6
6
|
import {
|
|
7
7
|
stream,
|
|
8
|
-
EventStream
|
|
8
|
+
EventStream,
|
|
9
|
+
isHardBillingMessage
|
|
9
10
|
} from "@prestyj/ai";
|
|
10
11
|
var DEFAULT_MAX_TURNS = 300;
|
|
11
12
|
var _diagFn = null;
|
|
@@ -23,6 +24,8 @@ function isAbortError(err) {
|
|
|
23
24
|
}
|
|
24
25
|
function isContextOverflow(err) {
|
|
25
26
|
if (!(err instanceof Error)) return false;
|
|
27
|
+
const overflowStatus = err.statusCode;
|
|
28
|
+
if (overflowStatus === 402) return false;
|
|
26
29
|
if (isBillingError(err)) return false;
|
|
27
30
|
const msg = err.message.toLowerCase();
|
|
28
31
|
return msg.includes("prompt is too long") || msg.includes("prompt too long") || msg.includes("input is too long") || msg.includes("context_length_exceeded") || msg.includes("context_window_exceeded") || msg.includes("maximum context length") || msg.includes("exceeds model context window") || msg.includes("exceeds the context window") || msg.includes("content_too_large") || msg.includes("request_too_large") || msg.includes("reduce the length") || msg.includes("please shorten") || msg.includes("token") && msg.includes("exceed");
|
|
@@ -67,13 +70,21 @@ function extractContextOverflowDetails(err) {
|
|
|
67
70
|
}
|
|
68
71
|
function isBillingError(err) {
|
|
69
72
|
if (!(err instanceof Error)) return false;
|
|
70
|
-
const
|
|
71
|
-
|
|
73
|
+
const statusCode = err.statusCode;
|
|
74
|
+
if (statusCode === 402) return true;
|
|
75
|
+
return isHardBillingMessage(err.message);
|
|
72
76
|
}
|
|
73
77
|
function isUsageLimitError(err) {
|
|
74
78
|
if (!(err instanceof Error)) return false;
|
|
75
79
|
return /usage limit reached/i.test(err.message);
|
|
76
80
|
}
|
|
81
|
+
function serverResetDelayMs(err) {
|
|
82
|
+
if (!(err instanceof Error)) return void 0;
|
|
83
|
+
const resetsAt = err.resetsAt;
|
|
84
|
+
if (typeof resetsAt !== "number" || !Number.isFinite(resetsAt)) return void 0;
|
|
85
|
+
const delayMs = resetsAt * 1e3 - Date.now();
|
|
86
|
+
return delayMs > 0 ? delayMs : void 0;
|
|
87
|
+
}
|
|
77
88
|
function isToolPairingError(err) {
|
|
78
89
|
if (!(err instanceof Error)) return false;
|
|
79
90
|
const msg = err.message.toLowerCase();
|
|
@@ -94,6 +105,7 @@ function classifyOverload(err) {
|
|
|
94
105
|
const msg = err.message.toLowerCase();
|
|
95
106
|
const errorWithStatus = err;
|
|
96
107
|
const statusCode = typeof errorWithStatus.statusCode === "number" ? errorWithStatus.statusCode : void 0;
|
|
108
|
+
if (statusCode === 402) return null;
|
|
97
109
|
if (statusCode === 429 || msg.includes("rate_limit") || msg.includes("rate limit") || msg.includes("too many requests") || msg.includes("429")) {
|
|
98
110
|
return "rate_limit";
|
|
99
111
|
}
|
|
@@ -153,23 +165,51 @@ function isTransportFailure(err) {
|
|
|
153
165
|
}
|
|
154
166
|
return false;
|
|
155
167
|
}
|
|
168
|
+
function createAbortError() {
|
|
169
|
+
return new DOMException("Aborted", "AbortError");
|
|
170
|
+
}
|
|
171
|
+
function abortablePromise(promise, signal) {
|
|
172
|
+
if (!signal) return promise;
|
|
173
|
+
if (signal.aborted) return Promise.reject(createAbortError());
|
|
174
|
+
return new Promise((resolve, reject) => {
|
|
175
|
+
let settled = false;
|
|
176
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
177
|
+
const resolveOnce = (value) => {
|
|
178
|
+
if (settled) return;
|
|
179
|
+
settled = true;
|
|
180
|
+
cleanup();
|
|
181
|
+
resolve(value);
|
|
182
|
+
};
|
|
183
|
+
const rejectOnce = (err) => {
|
|
184
|
+
if (settled) return;
|
|
185
|
+
settled = true;
|
|
186
|
+
cleanup();
|
|
187
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
188
|
+
};
|
|
189
|
+
const onAbort = () => rejectOnce(createAbortError());
|
|
190
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
191
|
+
promise.then(resolveOnce, rejectOnce);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
156
194
|
function abortableSleep(ms, signal) {
|
|
157
|
-
if (signal?.aborted)
|
|
158
|
-
return Promise.reject(new DOMException("Aborted", "AbortError"));
|
|
159
|
-
}
|
|
195
|
+
if (signal?.aborted) return Promise.reject(createAbortError());
|
|
160
196
|
return new Promise((resolve, reject) => {
|
|
161
|
-
let onAbort = null;
|
|
162
197
|
const timer = setTimeout(() => {
|
|
163
|
-
|
|
198
|
+
signal?.removeEventListener("abort", onAbort);
|
|
164
199
|
resolve();
|
|
165
200
|
}, ms);
|
|
166
|
-
onAbort = () => {
|
|
201
|
+
const onAbort = () => {
|
|
167
202
|
clearTimeout(timer);
|
|
168
|
-
reject(
|
|
203
|
+
reject(createAbortError());
|
|
169
204
|
};
|
|
170
205
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
171
206
|
});
|
|
172
207
|
}
|
|
208
|
+
function closeIterator(iterator) {
|
|
209
|
+
if (!iterator?.return) return;
|
|
210
|
+
Promise.resolve(iterator.return()).catch(() => {
|
|
211
|
+
});
|
|
212
|
+
}
|
|
173
213
|
async function* agentLoop(messages, options) {
|
|
174
214
|
const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
175
215
|
const maxContinuations = options.maxContinuations ?? 5;
|
|
@@ -294,6 +334,7 @@ async function* agentLoop(messages, options) {
|
|
|
294
334
|
idleTimedOut = true;
|
|
295
335
|
streamController.abort();
|
|
296
336
|
}, hardTimeoutMs);
|
|
337
|
+
let streamIterator = null;
|
|
297
338
|
try {
|
|
298
339
|
diag("stream_call", { nonStreaming: useNonStreamingFallback });
|
|
299
340
|
streamCallStart = Date.now();
|
|
@@ -316,9 +357,11 @@ async function* agentLoop(messages, options) {
|
|
|
316
357
|
promptCacheKey: options.promptCacheKey,
|
|
317
358
|
serviceTier: options.serviceTier,
|
|
318
359
|
supportsImages: options.supportsImages,
|
|
360
|
+
supportsVideo: options.supportsVideo,
|
|
319
361
|
compaction: options.compaction,
|
|
320
362
|
clearToolUses: options.clearToolUses,
|
|
321
363
|
userAgent: options.userAgent,
|
|
364
|
+
defaultHeaders: options.defaultHeaders,
|
|
322
365
|
// Flip to non-streaming fallback after repeated stream stalls.
|
|
323
366
|
...useNonStreamingFallback ? { streaming: false } : {}
|
|
324
367
|
});
|
|
@@ -331,7 +374,11 @@ async function* agentLoop(messages, options) {
|
|
|
331
374
|
streamCallStart = Date.now();
|
|
332
375
|
lastYieldEndTime = Date.now();
|
|
333
376
|
resetIdleTimer();
|
|
334
|
-
|
|
377
|
+
streamIterator = result[Symbol.asyncIterator]();
|
|
378
|
+
while (true) {
|
|
379
|
+
const next = await abortablePromise(streamIterator.next(), streamController.signal);
|
|
380
|
+
if (next.done) break;
|
|
381
|
+
const event = next.value;
|
|
335
382
|
const pullTime = Date.now();
|
|
336
383
|
const consumerLag = pullTime - lastYieldEndTime;
|
|
337
384
|
if (streamEventCount > 0 && consumerLag > maxConsumerLagMs) {
|
|
@@ -428,8 +475,9 @@ async function* agentLoop(messages, options) {
|
|
|
428
475
|
maxConsumerLagMs,
|
|
429
476
|
eventTypes: eventTypeCounts
|
|
430
477
|
});
|
|
431
|
-
response = await result.response;
|
|
478
|
+
response = await abortablePromise(result.response, streamController.signal);
|
|
432
479
|
} catch (err) {
|
|
480
|
+
if (streamController.signal.aborted) closeIterator(streamIterator);
|
|
433
481
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
434
482
|
diag("stream_error", {
|
|
435
483
|
error: errMsg.slice(0, 200),
|
|
@@ -528,7 +576,8 @@ async function* agentLoop(messages, options) {
|
|
|
528
576
|
const overloadKind = classifyOverload(err);
|
|
529
577
|
if (overloadRetries < MAX_OVERLOAD_RETRIES && overloadKind) {
|
|
530
578
|
overloadRetries++;
|
|
531
|
-
const
|
|
579
|
+
const serverDelayMs = serverResetDelayMs(err);
|
|
580
|
+
const delayMs = serverDelayMs !== void 0 ? Math.min(serverDelayMs, OVERLOAD_MAX_DELAY_MS) : Math.min(
|
|
532
581
|
OVERLOAD_BASE_DELAY_MS * 2 ** (overloadRetries - 1),
|
|
533
582
|
OVERLOAD_MAX_DELAY_MS
|
|
534
583
|
);
|
|
@@ -828,7 +877,10 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
|
|
|
828
877
|
});
|
|
829
878
|
}
|
|
830
879
|
};
|
|
831
|
-
const raw = await
|
|
880
|
+
const raw = await abortablePromise(
|
|
881
|
+
Promise.resolve().then(() => tool.execute(parsed, ctx)),
|
|
882
|
+
ctx.signal
|
|
883
|
+
);
|
|
832
884
|
const normalized = normalizeToolResult(raw);
|
|
833
885
|
resultContent = normalized.content;
|
|
834
886
|
details = normalized.details;
|