clementine-agent 1.18.194 → 1.18.196

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.
@@ -2606,20 +2606,68 @@ export class Gateway {
2606
2606
  // result with terminalReason), we surface a clean "rephrase or
2607
2607
  // /plan" message via the `case 'context_overflow':` handler
2608
2608
  // below. No more "Planning failed" half-finished chains.
2609
- let runAgentResult;
2610
- try {
2611
- runAgentResult = await runAgent(finalPrompt, buildRunAgentChatOptions({
2612
- ...(priorSdkSessionId ? { resumeSessionId: priorSdkSessionId } : {}),
2609
+ // 1.18.196 — smart session reset on overflow.
2610
+ //
2611
+ // SDK session files on disk can grow to 80+ MB after months of
2612
+ // chat. When we resume one of those, the SDK tries to load the
2613
+ // entire accumulated JSONL into context — easily blows past
2614
+ // 200K tokens on the very first user message after a daemon
2615
+ // start. Zach hit this on a freshly-installed 1.18.195 because
2616
+ // his topshelfbot session had months of history.
2617
+ //
2618
+ // The fix is the same thing any human would do: throw the
2619
+ // resume away, start a fresh SDK session, send the same user
2620
+ // message. The user loses chat memory of the prior session
2621
+ // (it's gone anyway — we can't load it), but they get an
2622
+ // actual response instead of a "rephrase smaller" message.
2623
+ //
2624
+ // This is ONE retry max. If the fresh session also overflows,
2625
+ // that's a genuine ceiling — surface the recovery message.
2626
+ // No planner queueing, no compression dance, no second retry.
2627
+ //
2628
+ // Distinct from the deleted-in-1.18.194 pipeline because:
2629
+ // - No prompt compression — the prompt is fine
2630
+ // - No planner background task — that was the failing piece
2631
+ // - No second retry — one shot only
2632
+ // - Triggered only when we WERE resuming (overflow on a
2633
+ // virgin session is a real ceiling, not a stale-history
2634
+ // problem)
2635
+ let didFreshSessionRetry = false;
2636
+ const runAgentOnce = async (resumeId) => {
2637
+ return runAgent(finalPrompt, buildRunAgentChatOptions({
2638
+ ...(resumeId ? { resumeSessionId: resumeId } : {}),
2613
2639
  ...(chatSystemAppend ? { systemPromptAppend: chatSystemAppend } : {}),
2614
2640
  }));
2641
+ };
2642
+ const maybeRetryFresh = async () => {
2643
+ if (didFreshSessionRetry || !priorSdkSessionId)
2644
+ return null;
2645
+ didFreshSessionRetry = true;
2646
+ logger.info({
2647
+ sessionKey: effectiveSessionKey,
2648
+ priorSdkSessionId,
2649
+ }, 'Context overflow on resumed session — clearing session and retrying once with fresh SDK session');
2650
+ this.assistant.clearSession(effectiveSessionKey);
2651
+ if (onProgress) {
2652
+ await onProgress('long conversation history — starting a fresh session...').catch(() => { });
2653
+ }
2654
+ return runAgentOnce(undefined);
2655
+ };
2656
+ let runAgentResult;
2657
+ try {
2658
+ runAgentResult = await runAgentOnce(priorSdkSessionId);
2615
2659
  }
2616
2660
  catch (err) {
2617
2661
  if (chatAc.signal.aborted || classifyChatError(err) !== 'context_overflow') {
2618
2662
  throw err;
2619
2663
  }
2620
- // Re-throw so the outer catch's classifyChatError gets it
2621
- // and routes to the 'context_overflow' case.
2622
- throw err;
2664
+ // First attempt overflowed. If we were resuming, try once
2665
+ // with a fresh session. Otherwise (no resume to drop),
2666
+ // surface the recovery message.
2667
+ const retried = await maybeRetryFresh();
2668
+ if (!retried)
2669
+ throw err;
2670
+ runAgentResult = retried;
2623
2671
  }
2624
2672
  if (!chatAc.signal.aborted && runAgentResultIndicatesContextOverflow(runAgentResult)) {
2625
2673
  logger.info({
@@ -2627,8 +2675,15 @@ export class Gateway {
2627
2675
  subtype: runAgentResult.subtype,
2628
2676
  terminalReason: runAgentResult.terminalReason,
2629
2677
  textPreview: runAgentResult.text?.slice(0, 240),
2630
- }, 'Context overflow result — autocompact ceiling reached, surfacing recovery message');
2631
- throw new Error('context_overflow_after_autocompact');
2678
+ didFreshSessionRetry,
2679
+ }, 'Context overflow result — attempting fresh-session retry or surfacing recovery');
2680
+ const retried = await maybeRetryFresh();
2681
+ if (retried && !runAgentResultIndicatesContextOverflow(retried)) {
2682
+ runAgentResult = retried;
2683
+ }
2684
+ else {
2685
+ throw new Error('context_overflow_after_autocompact');
2686
+ }
2632
2687
  }
2633
2688
  if (ledgerRunMetadata) {
2634
2689
  ledgerRunMetadata.runId = runAgentResult.runId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.194",
3
+ "version": "1.18.196",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,8 +28,8 @@
28
28
  "postinstall": "node scripts/postinstall.js 2>/dev/null || true"
29
29
  },
30
30
  "dependencies": {
31
- "@anthropic-ai/claude-agent-sdk": "^0.2.138",
32
- "@anthropic-ai/sdk": "^0.91.0",
31
+ "@anthropic-ai/claude-agent-sdk": "^0.2.139",
32
+ "@anthropic-ai/sdk": "^0.95.2",
33
33
  "@composio/claude-agent-sdk": "^0.8.1",
34
34
  "@composio/core": "^0.8.1",
35
35
  "@huggingface/transformers": "^4.2.0",
@@ -56,6 +56,10 @@
56
56
  "ws": "^8.19.0",
57
57
  "zod": "^4.3.6"
58
58
  },
59
+ "//overrides": "1.18.195 — force nested @anthropic-ai/sdk to a version that fixes GHSA-p7fg-763f-g4gf (Local Filesystem Memory Tool file-permissions). claude-agent-sdk pulls in 0.81.0 transitively; this override pins it across the tree.",
60
+ "overrides": {
61
+ "@anthropic-ai/sdk": "^0.95.2"
62
+ },
59
63
  "devDependencies": {
60
64
  "@types/better-sqlite3": "^7.6.13",
61
65
  "@types/express": "^5.0.0",