@prestyj/agent 4.4.0 → 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 +47 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +47 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -194,23 +194,51 @@ function isTransportFailure(err) {
|
|
|
194
194
|
}
|
|
195
195
|
return false;
|
|
196
196
|
}
|
|
197
|
+
function createAbortError() {
|
|
198
|
+
return new DOMException("Aborted", "AbortError");
|
|
199
|
+
}
|
|
200
|
+
function abortablePromise(promise, signal) {
|
|
201
|
+
if (!signal) return promise;
|
|
202
|
+
if (signal.aborted) return Promise.reject(createAbortError());
|
|
203
|
+
return new Promise((resolve, reject) => {
|
|
204
|
+
let settled = false;
|
|
205
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
206
|
+
const resolveOnce = (value) => {
|
|
207
|
+
if (settled) return;
|
|
208
|
+
settled = true;
|
|
209
|
+
cleanup();
|
|
210
|
+
resolve(value);
|
|
211
|
+
};
|
|
212
|
+
const rejectOnce = (err) => {
|
|
213
|
+
if (settled) return;
|
|
214
|
+
settled = true;
|
|
215
|
+
cleanup();
|
|
216
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
217
|
+
};
|
|
218
|
+
const onAbort = () => rejectOnce(createAbortError());
|
|
219
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
220
|
+
promise.then(resolveOnce, rejectOnce);
|
|
221
|
+
});
|
|
222
|
+
}
|
|
197
223
|
function abortableSleep(ms, signal) {
|
|
198
|
-
if (signal?.aborted)
|
|
199
|
-
return Promise.reject(new DOMException("Aborted", "AbortError"));
|
|
200
|
-
}
|
|
224
|
+
if (signal?.aborted) return Promise.reject(createAbortError());
|
|
201
225
|
return new Promise((resolve, reject) => {
|
|
202
|
-
let onAbort = null;
|
|
203
226
|
const timer = setTimeout(() => {
|
|
204
|
-
|
|
227
|
+
signal?.removeEventListener("abort", onAbort);
|
|
205
228
|
resolve();
|
|
206
229
|
}, ms);
|
|
207
|
-
onAbort = () => {
|
|
230
|
+
const onAbort = () => {
|
|
208
231
|
clearTimeout(timer);
|
|
209
|
-
reject(
|
|
232
|
+
reject(createAbortError());
|
|
210
233
|
};
|
|
211
234
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
212
235
|
});
|
|
213
236
|
}
|
|
237
|
+
function closeIterator(iterator) {
|
|
238
|
+
if (!iterator?.return) return;
|
|
239
|
+
Promise.resolve(iterator.return()).catch(() => {
|
|
240
|
+
});
|
|
241
|
+
}
|
|
214
242
|
async function* agentLoop(messages, options) {
|
|
215
243
|
const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
216
244
|
const maxContinuations = options.maxContinuations ?? 5;
|
|
@@ -335,6 +363,7 @@ async function* agentLoop(messages, options) {
|
|
|
335
363
|
idleTimedOut = true;
|
|
336
364
|
streamController.abort();
|
|
337
365
|
}, hardTimeoutMs);
|
|
366
|
+
let streamIterator = null;
|
|
338
367
|
try {
|
|
339
368
|
diag("stream_call", { nonStreaming: useNonStreamingFallback });
|
|
340
369
|
streamCallStart = Date.now();
|
|
@@ -374,7 +403,11 @@ async function* agentLoop(messages, options) {
|
|
|
374
403
|
streamCallStart = Date.now();
|
|
375
404
|
lastYieldEndTime = Date.now();
|
|
376
405
|
resetIdleTimer();
|
|
377
|
-
|
|
406
|
+
streamIterator = result[Symbol.asyncIterator]();
|
|
407
|
+
while (true) {
|
|
408
|
+
const next = await abortablePromise(streamIterator.next(), streamController.signal);
|
|
409
|
+
if (next.done) break;
|
|
410
|
+
const event = next.value;
|
|
378
411
|
const pullTime = Date.now();
|
|
379
412
|
const consumerLag = pullTime - lastYieldEndTime;
|
|
380
413
|
if (streamEventCount > 0 && consumerLag > maxConsumerLagMs) {
|
|
@@ -471,8 +504,9 @@ async function* agentLoop(messages, options) {
|
|
|
471
504
|
maxConsumerLagMs,
|
|
472
505
|
eventTypes: eventTypeCounts
|
|
473
506
|
});
|
|
474
|
-
response = await result.response;
|
|
507
|
+
response = await abortablePromise(result.response, streamController.signal);
|
|
475
508
|
} catch (err) {
|
|
509
|
+
if (streamController.signal.aborted) closeIterator(streamIterator);
|
|
476
510
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
477
511
|
diag("stream_error", {
|
|
478
512
|
error: errMsg.slice(0, 200),
|
|
@@ -872,7 +906,10 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
|
|
|
872
906
|
});
|
|
873
907
|
}
|
|
874
908
|
};
|
|
875
|
-
const raw = await
|
|
909
|
+
const raw = await abortablePromise(
|
|
910
|
+
Promise.resolve().then(() => tool.execute(parsed, ctx)),
|
|
911
|
+
ctx.signal
|
|
912
|
+
);
|
|
876
913
|
const normalized = normalizeToolResult(raw);
|
|
877
914
|
resultContent = normalized.content;
|
|
878
915
|
details = normalized.details;
|