@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 CHANGED
@@ -258,7 +258,7 @@ function closeIterator(iterator) {
258
258
  async function* agentLoop(messages, options) {
259
259
  const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
260
260
  const maxContinuations = options.maxContinuations ?? 5;
261
- const toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
261
+ let toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
262
262
  const totalUsage = { inputTokens: 0, outputTokens: 0 };
263
263
  let turn = 0;
264
264
  let hitMaxTurns = false;
@@ -280,6 +280,8 @@ async function* agentLoop(messages, options) {
280
280
  const MAX_OVERFLOW_COMPACTIONS = 2;
281
281
  const STALL_RETRIES_BEFORE_NON_STREAMING = 2;
282
282
  const STALL_DELAY_MS = 1e3;
283
+ const MIN_PARTIAL_PRESERVE_CHARS = 200;
284
+ 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.]";
283
285
  const OVERLOAD_BASE_DELAY_MS = 2e3;
284
286
  const OVERLOAD_MAX_DELAY_MS = 3e4;
285
287
  const STREAM_FIRST_EVENT_TIMEOUT_MS = 45e3;
@@ -298,6 +300,7 @@ async function* agentLoop(messages, options) {
298
300
  while (turn < maxTurns) {
299
301
  options.signal?.throwIfAborted();
300
302
  turn++;
303
+ toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
301
304
  if (_diagFn) {
302
305
  let msgChars = 0;
303
306
  for (const m of messages) {
@@ -354,6 +357,7 @@ async function* agentLoop(messages, options) {
354
357
  let toolcallDeltaChars = 0;
355
358
  let toolcallDeltaCount = 0;
356
359
  let runawayDetected = null;
360
+ let attemptText = "";
357
361
  let lastYieldEndTime = Date.now();
358
362
  let maxConsumerLagMs = 0;
359
363
  const forwardAbort = () => streamController.abort();
@@ -479,6 +483,7 @@ async function* agentLoop(messages, options) {
479
483
  idleTimer = null;
480
484
  }
481
485
  if (event.type === "text_delta") {
486
+ attemptText += event.text;
482
487
  yield { type: "text_delta", text: event.text };
483
488
  } else if (event.type === "thinking_delta") {
484
489
  yield { type: "thinking_delta", text: event.text };
@@ -681,13 +686,23 @@ async function* agentLoop(messages, options) {
681
686
  });
682
687
  }
683
688
  const delayMs = Math.min(STALL_DELAY_MS * 2 ** (stallRetries - 1), 8e3);
689
+ let preservedChars = 0;
690
+ if (attemptText.length >= MIN_PARTIAL_PRESERVE_CHARS && toolcallDeltaCount === 0) {
691
+ messages.push({
692
+ role: "assistant",
693
+ content: [{ type: "text", text: attemptText }]
694
+ });
695
+ messages.push({ role: "user", content: PARTIAL_CONTINUATION_PROMPT });
696
+ preservedChars = attemptText.length;
697
+ }
684
698
  diag("retry", {
685
699
  reason: cause,
686
700
  attempt: stallRetries,
687
701
  maxAttempts: MAX_STALL_RETRIES,
688
702
  delayMs,
689
703
  events: streamEventCount,
690
- nonStreaming: useNonStreamingFallback
704
+ nonStreaming: useNonStreamingFallback,
705
+ preservedChars
691
706
  });
692
707
  yield {
693
708
  type: "retry",
@@ -695,7 +710,8 @@ async function* agentLoop(messages, options) {
695
710
  attempt: stallRetries,
696
711
  maxAttempts: MAX_STALL_RETRIES,
697
712
  delayMs,
698
- silent: stallRetries <= 2
713
+ silent: stallRetries <= 2,
714
+ ...preservedChars > 0 ? { preservedChars } : {}
699
715
  };
700
716
  await abortableSleep(delayMs, options.signal);
701
717
  turn--;