@nexrall/code-core 1.4.3 → 1.4.5

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.
@@ -1,4 +1,4 @@
1
- import type { Message, AgentLoopOptions } from '../types';
1
+ import type { Message, AgentLoopOptions, EnvContext } from '../types';
2
2
  export declare function resolveMaxIterations(optionValue: number | undefined, settingsRaw: Record<string, unknown>): number;
3
3
  /** Approximate serialised request-body size (bytes) for the messages array. */
4
4
  export declare function estimateBodyBytes(messages: Message[]): number;
@@ -73,5 +73,24 @@ export declare function ledgerSummary(ledger: ProgressLedger): string;
73
73
  * Returns the number of bytes reclaimed (0 if nothing was prunable).
74
74
  */
75
75
  export declare function pruneOldToolResults(messages: Message[]): number;
76
+ /** Rough token estimate for a resumed transcript — no API round-trip needed. */
77
+ export declare function estimateTokensRough(messages: Message[]): number;
78
+ /**
79
+ * Proactively compact `messages` in place if resuming this session would blow
80
+ * past the auto-compact threshold on the very first turn. Returns true if any
81
+ * compaction happened (so the caller can surface a one-line notice to the
82
+ * user). Safe to call on any message array, including empty/small ones (no-op).
83
+ *
84
+ * `model` picks the right context window (mirrors runAgentLoop's own lookup);
85
+ * `onNotice` is optional — pass it to show the same "auto-compacted" message
86
+ * the in-loop path shows, so the behaviour is visually consistent.
87
+ */
88
+ export declare function compactMessagesForResume(messages: Message[], opts: {
89
+ model?: 'turbo' | 'pro' | 'ultra';
90
+ workDir: string;
91
+ clientType?: string;
92
+ env?: EnvContext;
93
+ onNotice?: (text: string) => void;
94
+ }): Promise<boolean>;
76
95
  export declare function runAgentLoop(initialMessages: Message[], options: AgentLoopOptions): Promise<Message[]>;
77
96
  //# sourceMappingURL=loop.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAMP,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAsKlB,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,MAAM,CAWR;AA8RD,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAM7D;AAsBD,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,aAA+G,CAAC;AAC7I,gGAAgG;AAChG,eAAO,MAAM,aAAa,QAA2J,CAAC;AAEtL;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAK5E;AAUD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAwBxD;AAoBD,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,aAAa,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE,qFAAqF;IACrF,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,YAAY,IAAI,cAAc,CAE7C;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,EAAE,EAAE,OAAO,EACX,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAoDN;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA6B5D;AAmBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAmB/D;AA2FD,wBAAsB,YAAY,CAChC,eAAe,EAAE,OAAO,EAAE,EAC1B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,OAAO,EAAE,CAAC,CA2kBpB"}
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAMP,gBAAgB,EAChB,UAAU,EACX,MAAM,UAAU,CAAC;AAsKlB,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,MAAM,CAWR;AA8RD,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAM7D;AAsBD,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,aAA+G,CAAC;AAC7I,gGAAgG;AAChG,eAAO,MAAM,aAAa,QAA2J,CAAC;AAEtL;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAK5E;AAUD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAwBxD;AAoBD,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,aAAa,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE,qFAAqF;IACrF,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,YAAY,IAAI,cAAc,CAE7C;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,EAAE,EAAE,OAAO,EACX,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAoDN;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA6B5D;AAmBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAmB/D;AA+GD,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAE/D;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,EAAE;IACJ,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,GACA,OAAO,CAAC,OAAO,CAAC,CA2DlB;AAID,wBAAsB,YAAY,CAChC,eAAe,EAAE,OAAO,EAAE,EAC1B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,OAAO,EAAE,CAAC,CAulBpB"}
@@ -42,6 +42,8 @@ exports.createLedger = createLedger;
42
42
  exports.ledgerRecord = ledgerRecord;
43
43
  exports.ledgerSummary = ledgerSummary;
44
44
  exports.pruneOldToolResults = pruneOldToolResults;
45
+ exports.estimateTokensRough = estimateTokensRough;
46
+ exports.compactMessagesForResume = compactMessagesForResume;
45
47
  exports.runAgentLoop = runAgentLoop;
46
48
  const client_1 = require("../api/client");
47
49
  const executor_1 = require("../tools/executor");
@@ -772,6 +774,95 @@ async function autoCompactMessages(messages, options, ledger) {
772
774
  void kept;
773
775
  return true;
774
776
  }
777
+ // ─── Resume-time proactive compaction ─────────────────────────────────────────
778
+ //
779
+ // The in-loop auto-compact above only reacts to `lastPromptTokens`, which is
780
+ // populated from the PREVIOUS turn's usage event. On a freshly-resumed session
781
+ // (opening an old chat from history and sending the first new message) there is
782
+ // no previous turn in this process — `lastPromptTokens` starts at 0 — so the
783
+ // token-pressure trigger never fires for turn 0, and the byte-pressure trigger
784
+ // only catches truly huge sessions (MAX_BODY_BYTES is sized to stay under the
785
+ // backend's 25 MB body limit, not to bound cost — 8 MB of tool-heavy JSON is
786
+ // already on the order of the 1M-token context window itself). The result: a
787
+ // resumed session comfortably under both guards, but still hundreds of
788
+ // thousands of tokens, gets sent to the model at FULL PRICE on the very first
789
+ // message after resume, silently, every time.
790
+ //
791
+ // This function closes that gap: call it once, right after loading a stored
792
+ // session and BEFORE the user's next message is sent, so the expensive
793
+ // resend is compacted proactively instead of being missed by both in-loop
794
+ // guards. It reuses the exact same threshold/mechanics as the in-loop guard
795
+ // (cheap prune first, then summarising compaction) so behaviour stays
796
+ // consistent whether compaction happens at resume-time or mid-run.
797
+ const RESUME_CHARS_PER_TOKEN = 4; // rough, conservative estimate for JSON/code-heavy transcripts
798
+ /** Rough token estimate for a resumed transcript — no API round-trip needed. */
799
+ function estimateTokensRough(messages) {
800
+ return Math.ceil(estimateBodyBytes(messages) / RESUME_CHARS_PER_TOKEN);
801
+ }
802
+ /**
803
+ * Proactively compact `messages` in place if resuming this session would blow
804
+ * past the auto-compact threshold on the very first turn. Returns true if any
805
+ * compaction happened (so the caller can surface a one-line notice to the
806
+ * user). Safe to call on any message array, including empty/small ones (no-op).
807
+ *
808
+ * `model` picks the right context window (mirrors runAgentLoop's own lookup);
809
+ * `onNotice` is optional — pass it to show the same "auto-compacted" message
810
+ * the in-loop path shows, so the behaviour is visually consistent.
811
+ */
812
+ async function compactMessagesForResume(messages, opts) {
813
+ if (messages.length <= COMPACT_KEEP_MIN + 2)
814
+ return false;
815
+ const settings = (0, rules_1.loadSettings)(opts.workDir);
816
+ if (!resolveAutoCompact(undefined, settings.raw))
817
+ return false;
818
+ const contextWindow = MODEL_CONTEXT_TOKENS[opts.model ?? 'turbo'] ?? 1000000;
819
+ let bodyBytes = estimateBodyBytes(messages);
820
+ let tokenGuess = estimateTokensRough(messages);
821
+ const overThreshold = () => tokenGuess > contextWindow * AUTO_COMPACT_THRESHOLD || bodyBytes > MAX_BODY_BYTES;
822
+ if (!overThreshold())
823
+ return false;
824
+ let compacted = false;
825
+ // Cheap pass first — shrinks old tool_result blocks with no model call.
826
+ if (messages.length > PRUNE_KEEP_RECENT + 2) {
827
+ const reclaimed = pruneOldToolResults(messages);
828
+ if (reclaimed > 0) {
829
+ bodyBytes = estimateBodyBytes(messages);
830
+ tokenGuess = estimateTokensRough(messages);
831
+ compacted = true;
832
+ opts.onNotice?.(`\n\u267b\ufe0f Trimmed ~${(reclaimed / (1024 * 1024)).toFixed(1)}MB of older tool output before resuming this chat.\n`);
833
+ }
834
+ }
835
+ // If still over threshold, fall through to summarising compaction — same
836
+ // mechanism the in-loop guard uses, so this can safely loop (a single
837
+ // summarisation pass may still leave a very long session over threshold).
838
+ let guard = 0;
839
+ while (overThreshold() && messages.length > COMPACT_KEEP_MIN + 2 && guard < 5) {
840
+ guard += 1;
841
+ // No ledger at resume time — the ledger is per-run, in-memory, and would
842
+ // have been created fresh anyway since this is a new process/run. The
843
+ // ORIGINAL TASK verbatim pin (inside autoCompactMessages) still applies.
844
+ const did = await autoCompactMessages(messages, {
845
+ workDir: opts.workDir,
846
+ model: opts.model,
847
+ clientType: opts.clientType,
848
+ env: opts.env,
849
+ onText: () => { },
850
+ onToolUse: () => { },
851
+ onToolResult: () => { },
852
+ onUsage: () => { },
853
+ requestPermission: async () => false,
854
+ });
855
+ if (!did)
856
+ break;
857
+ compacted = true;
858
+ bodyBytes = estimateBodyBytes(messages);
859
+ tokenGuess = estimateTokensRough(messages);
860
+ }
861
+ if (compacted) {
862
+ opts.onNotice?.(`\n\u267b\ufe0f Auto-compacted this chat's earlier history before resuming, to avoid resending it at full cost.\n`);
863
+ }
864
+ return compacted;
865
+ }
775
866
  // ─── Agent Loop ───────────────────────────────────────────────────────────────
776
867
  async function runAgentLoop(initialMessages, options) {
777
868
  const messages = [...initialMessages];
@@ -922,6 +1013,12 @@ async function runAgentLoop(initialMessages, options) {
922
1013
  case 'message_complete':
923
1014
  // The complete message is returned from streamChat, we handle it below
924
1015
  break;
1016
+ case 'retry':
1017
+ options.onRetry?.(event.attempt, event.maxAttempts, event.reason);
1018
+ break;
1019
+ case 'retry_resolved':
1020
+ options.onRetryResolved?.();
1021
+ break;
925
1022
  case 'done':
926
1023
  case 'error':
927
1024
  break;
@@ -970,7 +1067,11 @@ async function runAgentLoop(initialMessages, options) {
970
1067
  completedCleanly = true;
971
1068
  break;
972
1069
  }
973
- messages.push(assistantMessage);
1070
+ // stopReason is transient, single-turn metadata for the truncated-tool-call guard
1071
+ // below — it must never be replayed to the API as part of message history (Anthropic
1072
+ // rejects unknown fields on a request message with a 400).
1073
+ const { stopReason: _stopReason, ...historyMessage } = assistantMessage;
1074
+ messages.push(historyMessage);
974
1075
  // 3. Collect tool_use blocks from the completed message.
975
1076
  // Server-side tools (e.g. web_search_20260209) are executed by Anthropic and their
976
1077
  // tool_result blocks appear in the SAME assistant message. We must skip those —
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAA8B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKrH,eAAO,MAAM,QAAQ,4BAA4B,CAAC;AAiBlD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,oFAAoF;IACpF,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACjG,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,GAC7B,OAAO,CAAC,OAAO,CAAC,CA4XlB;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAalD;AAID,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAgB1E;AAID,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBhF"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAA8B,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAKrH,eAAO,MAAM,QAAQ,4BAA4B,CAAC;AAiBlD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,oFAAoF;IACpF,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACjG,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgBD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,GAC7B,OAAO,CAAC,OAAO,CAAC,CA0alB;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAalD;AAID,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAgB1E;AAID,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBhF"}
@@ -30,6 +30,10 @@ const RETRY_BASE_MS = 1000;
30
30
  function sleep(ms) {
31
31
  return new Promise((r) => setTimeout(r, ms));
32
32
  }
33
+ /** Total number of network-level attempts a single streamChat() call may make
34
+ * (connect-time retries × outer stream-retries), used only to report a
35
+ * meaningful "attempt N of M" to the UI — not a hard limit by itself. */
36
+ const MAX_TOTAL_ATTEMPTS = (MAX_RETRIES + 1) * (MAX_RETRIES + 1);
33
37
  async function streamChat(messages, options, onEvent) {
34
38
  const { model, env, editorContext, nexrallMd, mode, effort, clientType, abortSignal, extraTools, agents } = options;
35
39
  // Bridge custom abort signal → native AbortController so fetch is cancelled immediately
@@ -56,6 +60,25 @@ async function streamChat(messages, options, onEvent) {
56
60
  // — but only while nothing has been emitted to the caller yet, so a retry can never
57
61
  // duplicate already-rendered text or tool calls.
58
62
  const isRetryableStreamMsg = (m) => /overloaded|rate.?limit|temporarily|unavailable|try again|internal server error/i.test(String(m ?? ''));
63
+ // Tracks whether a "reconnecting…" signal has been shown to the caller so we know to
64
+ // clear it (retry_resolved) once real data starts flowing again. Shared across both
65
+ // the connect-time retry loop and the outer stream-retry loop below, and across a
66
+ // network-level disconnect that spans machine sleep/wake — the caller previously had
67
+ // NO visibility into this at all, so a pause-then-silently-resume looked like nothing
68
+ // happened (this is the fix for that gap).
69
+ let didRetry = false;
70
+ let totalAttemptsMade = 0;
71
+ const reportRetry = (reason) => {
72
+ totalAttemptsMade++;
73
+ didRetry = true;
74
+ onEvent({ type: 'retry', attempt: totalAttemptsMade, maxAttempts: MAX_TOTAL_ATTEMPTS, reason });
75
+ };
76
+ const clearRetryIfNeeded = () => {
77
+ if (didRetry) {
78
+ didRetry = false;
79
+ onEvent({ type: 'retry_resolved' });
80
+ }
81
+ };
59
82
  // One network attempt: connect (with connect-time 429/5xx retry) and consume the stream to
60
83
  // completion. Returns the assembled assistant Message, or throws — tagging a transient
61
84
  // pre-content failure with { retryable: true } for the outer loop below.
@@ -67,11 +90,13 @@ async function streamChat(messages, options, onEvent) {
67
90
  try {
68
91
  response = await (0, node_fetch_1.default)(...fetchArgs);
69
92
  if (response.status === 429 && attempt < MAX_RETRIES) {
93
+ reportRetry('Rate limited by the API — retrying');
70
94
  const retryAfter = parseInt(response.headers.get('retry-after') ?? '0', 10);
71
95
  await sleep(retryAfter > 0 ? retryAfter * 1000 : RETRY_BASE_MS * Math.pow(2, attempt));
72
96
  continue;
73
97
  }
74
98
  if (response.status >= 500 && response.status < 600 && attempt < MAX_RETRIES) {
99
+ reportRetry(`Server error (${response.status}) — retrying`);
75
100
  await sleep(RETRY_BASE_MS * Math.pow(2, attempt));
76
101
  continue;
77
102
  }
@@ -87,6 +112,9 @@ async function streamChat(messages, options, onEvent) {
87
112
  throw err;
88
113
  lastErr = err;
89
114
  if (attempt < MAX_RETRIES) {
115
+ // Connection couldn't even be established — network drop / DNS blip / the
116
+ // machine just woke from sleep and Wi-Fi hasn't reconnected yet.
117
+ reportRetry('Connection lost — attempting to reconnect');
90
118
  await sleep(RETRY_BASE_MS * Math.pow(2, attempt));
91
119
  continue;
92
120
  }
@@ -152,7 +180,17 @@ async function streamChat(messages, options, onEvent) {
152
180
  if (now - lastDataAt > HEARTBEAT_TIMEOUT_MS) {
153
181
  clearInterval(heartbeatWatchdog);
154
182
  stream.destroy?.();
155
- reject(new Error('Connection lost no data received for 45 s. Retry your message.'));
183
+ // Same rule as the stall watchdog below: if nothing has been shown to the
184
+ // caller yet, a fresh attempt can't duplicate output, so retry transparently
185
+ // instead of surfacing a hard error. This is also the common path when the
186
+ // machine just woke from sleep — JS timers freeze during sleep, so on wake
187
+ // `now - lastDataAt` immediately reads as a large gap even though nothing is
188
+ // actually wrong with the connection; without this it used to hard-fail
189
+ // instead of silently reconnecting.
190
+ const deadErr = new Error(emittedToCaller
191
+ ? 'Connection lost — no data received for 45 s. Retry your message.'
192
+ : 'Connection lost — no data received for 45 s. Reconnecting…');
193
+ reject(emittedToCaller ? deadErr : Object.assign(deadErr, { retryable: true }));
156
194
  return;
157
195
  }
158
196
  const stallLimitMs = sawModelEvent ? PROGRESS_TIMEOUT_MS : FIRST_EVENT_TIMEOUT_MS;
@@ -197,6 +235,9 @@ async function streamChat(messages, options, onEvent) {
197
235
  // comments never produce a ParsedEvent with data) — count it as real progress.
198
236
  lastProgressAt = Date.now();
199
237
  sawModelEvent = true;
238
+ // Real data is flowing again — clear any "reconnecting…" indicator the caller
239
+ // may be showing from an earlier retry on THIS same attempt.
240
+ clearRetryIfNeeded();
200
241
  switch (evt.type) {
201
242
  case 'text': {
202
243
  const text = typeof evt.text === 'string' ? evt.text : '';
@@ -384,12 +425,15 @@ async function streamChat(messages, options, onEvent) {
384
425
  try {
385
426
  for (let sAttempt = 0; sAttempt <= MAX_RETRIES; sAttempt++) {
386
427
  try {
387
- return await runAttempt();
428
+ const result = await runAttempt();
429
+ clearRetryIfNeeded();
430
+ return result;
388
431
  }
389
432
  catch (err) {
390
433
  if (abortSignal?.aborted || controller.signal.aborted || err.name === 'AbortError')
391
434
  throw err;
392
435
  if (err.retryable && sAttempt < MAX_RETRIES) {
436
+ reportRetry(err.message || 'Connection interrupted — reconnecting');
393
437
  await sleep(RETRY_BASE_MS * Math.pow(2, sAttempt));
394
438
  continue;
395
439
  }
package/dist/types.d.ts CHANGED
@@ -66,7 +66,25 @@ export interface SSEThinkingDeltaEvent {
66
66
  type: 'thinking_delta';
67
67
  text: string;
68
68
  }
69
- export type SSEEvent = SSETextEvent | SSEToolUseEvent | SSEMessageCompleteEvent | SSEUsageEvent | SSEDoneEvent | SSEErrorEvent | SSEThinkingEvent | SSEThinkingProgressEvent | SSEThinkingDeltaEvent;
69
+ /**
70
+ * Emitted whenever streamChat is about to transparently retry a turn after a
71
+ * transient failure — a dropped connection (network blip, sleep/wake, proxy
72
+ * reset), an overloaded upstream, or a stall — WITHOUT anything having been
73
+ * shown to the user yet. This never represents a fatal error: it exists so
74
+ * the UI can show a "reconnecting…" indicator instead of silently pausing
75
+ * and resuming with no visible sign anything happened.
76
+ */
77
+ export interface SSERetryEvent {
78
+ type: 'retry';
79
+ attempt: number;
80
+ maxAttempts: number;
81
+ reason: string;
82
+ }
83
+ /** Emitted once a retried attempt starts receiving real data again, so the UI can clear the "reconnecting…" indicator. */
84
+ export interface SSERetryResolvedEvent {
85
+ type: 'retry_resolved';
86
+ }
87
+ export type SSEEvent = SSETextEvent | SSEToolUseEvent | SSEMessageCompleteEvent | SSEUsageEvent | SSEDoneEvent | SSEErrorEvent | SSEThinkingEvent | SSEThinkingProgressEvent | SSEThinkingDeltaEvent | SSERetryEvent | SSERetryResolvedEvent;
70
88
  export interface UsageInfo {
71
89
  input_tokens: number;
72
90
  output_tokens: number;
@@ -143,6 +161,16 @@ export interface AgentLoopOptions {
143
161
  onToolUse: (name: string, input: Record<string, unknown>, isSubTask?: boolean) => void;
144
162
  onToolResult: (name: string, result: ToolResult, isSubTask?: boolean) => void;
145
163
  onUsage: (u: UsageInfo) => void;
164
+ /**
165
+ * Fired when the network layer is about to transparently retry a turn after
166
+ * a transient disconnect (network drop, machine sleep/wake, overloaded
167
+ * upstream) — nothing has been lost, the loop is simply reconnecting. Lets
168
+ * the UI show "Reconnecting… (attempt N)" instead of appearing to freeze
169
+ * silently and then resume with no explanation.
170
+ */
171
+ onRetry?: (attempt: number, maxAttempts: number, reason: string) => void;
172
+ /** Fired once a retried attempt starts receiving data again — clear any "reconnecting…" UI. */
173
+ onRetryResolved?: () => void;
146
174
  model?: 'turbo' | 'pro' | 'ultra';
147
175
  mode?: string;
148
176
  effort?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexrall/code-core",
3
- "version": "1.4.3",
3
+ "version": "1.4.5",
4
4
  "description": "Core agent loop, tools, and extension primitives for Nexrall Code — embed an AI coding agent in any Node.js application.",
5
5
  "license": "MIT",
6
6
  "author": "Nexrall <support@nexrall.com> (https://nexrall.com)",