@prestyj/agent 5.3.0 → 5.4.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 +19 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +19 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -84,6 +84,13 @@ interface AgentRetryEvent {
|
|
|
84
84
|
observedLimit?: number;
|
|
85
85
|
/** When true, the retry should not be shown to the user (hidden retry). */
|
|
86
86
|
silent?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Chars of streamed text preserved in message history across this retry
|
|
89
|
+
* (transport failures only). When > 0 the retry CONTINUES from the partial
|
|
90
|
+
* instead of replaying — UIs must keep the streamed text on screen rather
|
|
91
|
+
* than rolling it back.
|
|
92
|
+
*/
|
|
93
|
+
preservedChars?: number;
|
|
87
94
|
}
|
|
88
95
|
interface AgentToolCallDeltaEvent {
|
|
89
96
|
type: "toolcall_delta";
|
package/dist/index.js
CHANGED
|
@@ -230,7 +230,7 @@ function closeIterator(iterator) {
|
|
|
230
230
|
async function* agentLoop(messages, options) {
|
|
231
231
|
const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
232
232
|
const maxContinuations = options.maxContinuations ?? 5;
|
|
233
|
-
|
|
233
|
+
let toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
|
|
234
234
|
const totalUsage = { inputTokens: 0, outputTokens: 0 };
|
|
235
235
|
let turn = 0;
|
|
236
236
|
let hitMaxTurns = false;
|
|
@@ -252,6 +252,8 @@ async function* agentLoop(messages, options) {
|
|
|
252
252
|
const MAX_OVERFLOW_COMPACTIONS = 2;
|
|
253
253
|
const STALL_RETRIES_BEFORE_NON_STREAMING = 2;
|
|
254
254
|
const STALL_DELAY_MS = 1e3;
|
|
255
|
+
const MIN_PARTIAL_PRESERVE_CHARS = 200;
|
|
256
|
+
const PARTIAL_CONTINUATION_PROMPT = "[Your previous response was cut off by a connection failure. The text above is what was already delivered to the user. Continue exactly from where it stopped \u2014 do not repeat or restart it.]";
|
|
255
257
|
const OVERLOAD_BASE_DELAY_MS = 2e3;
|
|
256
258
|
const OVERLOAD_MAX_DELAY_MS = 3e4;
|
|
257
259
|
const STREAM_FIRST_EVENT_TIMEOUT_MS = 45e3;
|
|
@@ -270,6 +272,7 @@ async function* agentLoop(messages, options) {
|
|
|
270
272
|
while (turn < maxTurns) {
|
|
271
273
|
options.signal?.throwIfAborted();
|
|
272
274
|
turn++;
|
|
275
|
+
toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
|
|
273
276
|
if (_diagFn) {
|
|
274
277
|
let msgChars = 0;
|
|
275
278
|
for (const m of messages) {
|
|
@@ -326,6 +329,7 @@ async function* agentLoop(messages, options) {
|
|
|
326
329
|
let toolcallDeltaChars = 0;
|
|
327
330
|
let toolcallDeltaCount = 0;
|
|
328
331
|
let runawayDetected = null;
|
|
332
|
+
let attemptText = "";
|
|
329
333
|
let lastYieldEndTime = Date.now();
|
|
330
334
|
let maxConsumerLagMs = 0;
|
|
331
335
|
const forwardAbort = () => streamController.abort();
|
|
@@ -451,6 +455,7 @@ async function* agentLoop(messages, options) {
|
|
|
451
455
|
idleTimer = null;
|
|
452
456
|
}
|
|
453
457
|
if (event.type === "text_delta") {
|
|
458
|
+
attemptText += event.text;
|
|
454
459
|
yield { type: "text_delta", text: event.text };
|
|
455
460
|
} else if (event.type === "thinking_delta") {
|
|
456
461
|
yield { type: "thinking_delta", text: event.text };
|
|
@@ -653,13 +658,23 @@ async function* agentLoop(messages, options) {
|
|
|
653
658
|
});
|
|
654
659
|
}
|
|
655
660
|
const delayMs = Math.min(STALL_DELAY_MS * 2 ** (stallRetries - 1), 8e3);
|
|
661
|
+
let preservedChars = 0;
|
|
662
|
+
if (attemptText.length >= MIN_PARTIAL_PRESERVE_CHARS && toolcallDeltaCount === 0) {
|
|
663
|
+
messages.push({
|
|
664
|
+
role: "assistant",
|
|
665
|
+
content: [{ type: "text", text: attemptText }]
|
|
666
|
+
});
|
|
667
|
+
messages.push({ role: "user", content: PARTIAL_CONTINUATION_PROMPT });
|
|
668
|
+
preservedChars = attemptText.length;
|
|
669
|
+
}
|
|
656
670
|
diag("retry", {
|
|
657
671
|
reason: cause,
|
|
658
672
|
attempt: stallRetries,
|
|
659
673
|
maxAttempts: MAX_STALL_RETRIES,
|
|
660
674
|
delayMs,
|
|
661
675
|
events: streamEventCount,
|
|
662
|
-
nonStreaming: useNonStreamingFallback
|
|
676
|
+
nonStreaming: useNonStreamingFallback,
|
|
677
|
+
preservedChars
|
|
663
678
|
});
|
|
664
679
|
yield {
|
|
665
680
|
type: "retry",
|
|
@@ -667,7 +682,8 @@ async function* agentLoop(messages, options) {
|
|
|
667
682
|
attempt: stallRetries,
|
|
668
683
|
maxAttempts: MAX_STALL_RETRIES,
|
|
669
684
|
delayMs,
|
|
670
|
-
silent: stallRetries <= 2
|
|
685
|
+
silent: stallRetries <= 2,
|
|
686
|
+
...preservedChars > 0 ? { preservedChars } : {}
|
|
671
687
|
};
|
|
672
688
|
await abortableSleep(delayMs, options.signal);
|
|
673
689
|
turn--;
|