@astralyn/pi 0.82.3 → 0.82.4

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.
Files changed (109) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/cli/config-selector.d.ts.map +1 -1
  3. package/dist/cli/config-selector.js +3 -2
  4. package/dist/cli/config-selector.js.map +1 -1
  5. package/dist/cli/startup-ui.d.ts.map +1 -1
  6. package/dist/cli/startup-ui.js +3 -2
  7. package/dist/cli/startup-ui.js.map +1 -1
  8. package/dist/core/agent-session.d.ts +2 -0
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +31 -12
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/extensions/index.d.ts +1 -1
  13. package/dist/core/extensions/index.d.ts.map +1 -1
  14. package/dist/core/extensions/index.js.map +1 -1
  15. package/dist/core/extensions/types.d.ts +9 -0
  16. package/dist/core/extensions/types.d.ts.map +1 -1
  17. package/dist/core/extensions/types.js.map +1 -1
  18. package/dist/extensions/index.d.ts.map +1 -1
  19. package/dist/extensions/index.js +2 -0
  20. package/dist/extensions/index.js.map +1 -1
  21. package/dist/extensions/plan/constants.d.ts +31 -0
  22. package/dist/extensions/plan/constants.d.ts.map +1 -0
  23. package/dist/extensions/plan/constants.js +57 -0
  24. package/dist/extensions/plan/constants.js.map +1 -0
  25. package/dist/extensions/plan/index.d.ts +21 -0
  26. package/dist/extensions/plan/index.d.ts.map +1 -0
  27. package/dist/extensions/plan/index.js +291 -0
  28. package/dist/extensions/plan/index.js.map +1 -0
  29. package/dist/extensions/plan/schema.d.ts +15 -0
  30. package/dist/extensions/plan/schema.d.ts.map +1 -0
  31. package/dist/extensions/plan/schema.js +13 -0
  32. package/dist/extensions/plan/schema.js.map +1 -0
  33. package/dist/extensions/plan/state.d.ts +29 -0
  34. package/dist/extensions/plan/state.d.ts.map +1 -0
  35. package/dist/extensions/plan/state.js +74 -0
  36. package/dist/extensions/plan/state.js.map +1 -0
  37. package/dist/extensions/plan/storage.d.ts +18 -0
  38. package/dist/extensions/plan/storage.d.ts.map +1 -0
  39. package/dist/extensions/plan/storage.js +58 -0
  40. package/dist/extensions/plan/storage.js.map +1 -0
  41. package/dist/extensions/rewind/anchor.d.ts +29 -0
  42. package/dist/extensions/rewind/anchor.d.ts.map +1 -0
  43. package/dist/extensions/rewind/anchor.js +35 -0
  44. package/dist/extensions/rewind/anchor.js.map +1 -0
  45. package/dist/extensions/rewind/engine.d.ts +2 -6
  46. package/dist/extensions/rewind/engine.d.ts.map +1 -1
  47. package/dist/extensions/rewind/engine.js +41 -10
  48. package/dist/extensions/rewind/engine.js.map +1 -1
  49. package/dist/extensions/rewind/index.d.ts.map +1 -1
  50. package/dist/extensions/rewind/index.js +55 -21
  51. package/dist/extensions/rewind/index.js.map +1 -1
  52. package/dist/extensions/rewind/menu.d.ts.map +1 -1
  53. package/dist/extensions/rewind/menu.js +7 -2
  54. package/dist/extensions/rewind/menu.js.map +1 -1
  55. package/dist/extensions/rewind/restore.d.ts +26 -9
  56. package/dist/extensions/rewind/restore.d.ts.map +1 -1
  57. package/dist/extensions/rewind/restore.js +58 -16
  58. package/dist/extensions/rewind/restore.js.map +1 -1
  59. package/dist/extensions/subagent/activity.d.ts +1 -0
  60. package/dist/extensions/subagent/activity.d.ts.map +1 -1
  61. package/dist/extensions/subagent/activity.js +20 -4
  62. package/dist/extensions/subagent/activity.js.map +1 -1
  63. package/dist/extensions/subagent/agents.d.ts.map +1 -1
  64. package/dist/extensions/subagent/agents.js +2 -13
  65. package/dist/extensions/subagent/agents.js.map +1 -1
  66. package/dist/extensions/subagent/constants.d.ts +4 -3
  67. package/dist/extensions/subagent/constants.d.ts.map +1 -1
  68. package/dist/extensions/subagent/constants.js +9 -3
  69. package/dist/extensions/subagent/constants.js.map +1 -1
  70. package/dist/extensions/subagent/index.d.ts.map +1 -1
  71. package/dist/extensions/subagent/index.js +12 -5
  72. package/dist/extensions/subagent/index.js.map +1 -1
  73. package/dist/extensions/subagent/render.d.ts.map +1 -1
  74. package/dist/extensions/subagent/render.js +166 -41
  75. package/dist/extensions/subagent/render.js.map +1 -1
  76. package/dist/extensions/subagent/resolve.d.ts +2 -5
  77. package/dist/extensions/subagent/resolve.d.ts.map +1 -1
  78. package/dist/extensions/subagent/resolve.js +8 -13
  79. package/dist/extensions/subagent/resolve.js.map +1 -1
  80. package/dist/extensions/subagent/runner.d.ts +3 -1
  81. package/dist/extensions/subagent/runner.d.ts.map +1 -1
  82. package/dist/extensions/subagent/runner.js +111 -66
  83. package/dist/extensions/subagent/runner.js.map +1 -1
  84. package/dist/extensions/subagent/schema.d.ts +0 -6
  85. package/dist/extensions/subagent/schema.d.ts.map +1 -1
  86. package/dist/extensions/subagent/schema.js +2 -3
  87. package/dist/extensions/subagent/schema.js.map +1 -1
  88. package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
  89. package/dist/extensions/subagent/sdk-runner.js +32 -16
  90. package/dist/extensions/subagent/sdk-runner.js.map +1 -1
  91. package/dist/extensions/subagent/types.d.ts +3 -2
  92. package/dist/extensions/subagent/types.d.ts.map +1 -1
  93. package/dist/extensions/subagent/types.js.map +1 -1
  94. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  95. package/dist/modes/interactive/interactive-mode.js +3 -2
  96. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  97. package/dist/utils/coalescing-terminal.d.ts +62 -0
  98. package/dist/utils/coalescing-terminal.d.ts.map +1 -0
  99. package/dist/utils/coalescing-terminal.js +151 -0
  100. package/dist/utils/coalescing-terminal.js.map +1 -0
  101. package/docs/bundled/extensions/README.md +1 -0
  102. package/docs/bundled/extensions/plan.md +31 -0
  103. package/docs/bundled/extensions/rewind.md +19 -8
  104. package/docs/bundled/extensions/subagent.md +15 -15
  105. package/docs/compaction.md +6 -2
  106. package/docs/docs.json +4 -0
  107. package/docs/extensions.md +4 -2
  108. package/npm-shrinkwrap.json +2 -2
  109. package/package.json +1 -1
@@ -71,6 +71,7 @@ function estimateMessagesTokens(messages) {
71
71
  // Constants
72
72
  // ============================================================================
73
73
  const CONTEXT_REMAINS_OVER_COMPACTION_THRESHOLD = "Estimated retained context remains above the configured auto-compaction threshold. Reduce compaction.keepRecentTokens, remove large retained content, or switch to a model with a larger context window before continuing.";
74
+ const NOTHING_TO_COMPACT_WITHIN_KEEP_WINDOW = "Nothing to compact while preserving the configured recent context. Reduce compaction.keepRecentTokens, remove large retained content, or switch to a model with a larger context window before continuing.";
74
75
  const AUTO_COMPACTION_STOPPED_BEFORE_NEXT_PROVIDER = "Stopped before the next provider request because auto-compaction did not produce a safe context. Review the compaction warning before continuing.";
75
76
  /** Standard thinking levels */
76
77
  const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high"];
@@ -98,6 +99,8 @@ export class AgentSession {
98
99
  _compactionAbortController = undefined;
99
100
  _autoCompactionAbortController = undefined;
100
101
  _stopAfterTurnRequested = false;
102
+ /** An extension cancelled a mid-turn compaction; skip further mid-turn checks this run. */
103
+ _midTurnCompactionDeclined = false;
101
104
  _overflowRecoveryAttempted = false;
102
105
  // Branch summarization state
103
106
  _branchSummaryAbortController = undefined;
@@ -764,6 +767,7 @@ export class AgentSession {
764
767
  async _runAgentPrompt(messages) {
765
768
  this._isAgentRunActive = true;
766
769
  this._stopAfterTurnRequested = false;
770
+ this._midTurnCompactionDeclined = false;
767
771
  try {
768
772
  await this.agent.prompt(messages);
769
773
  while (await this._handlePostAgentRun()) {
@@ -890,7 +894,7 @@ export class AgentSession {
890
894
  // The user's new prompt is sent below, so do not call agent.continue() here.
891
895
  const lastAssistant = this._findLastAssistantMessage();
892
896
  if (lastAssistant) {
893
- await this._checkCompaction(lastAssistant, false);
897
+ await this._checkCompaction(lastAssistant, false, "prePrompt");
894
898
  }
895
899
  const compactionSettings = this.settingsManager.getCompactionSettings();
896
900
  // A compaction entry can be valid while its retained suffix is still too large.
@@ -1433,6 +1437,7 @@ export class AgentSession {
1433
1437
  branchEntries: pathEntries,
1434
1438
  customInstructions,
1435
1439
  reason: "manual",
1440
+ timing: "manual",
1436
1441
  willRetry: false,
1437
1442
  signal: this._compactionAbortController.signal,
1438
1443
  }));
@@ -1551,7 +1556,13 @@ export class AgentSession {
1551
1556
  if (signal?.aborted) {
1552
1557
  return { stopErrorMessage: AUTO_COMPACTION_STOPPED_BEFORE_NEXT_PROVIDER };
1553
1558
  }
1554
- if (turn.toolResults.length === 0) {
1559
+ // Tool batches always continue the run; a turn without tool results only
1560
+ // continues when steering/follow-up messages are queued, otherwise the
1561
+ // post-run path covers it.
1562
+ if (turn.toolResults.length === 0 && !this.agent.hasQueuedMessages()) {
1563
+ return {};
1564
+ }
1565
+ if (this._midTurnCompactionDeclined) {
1555
1566
  return {};
1556
1567
  }
1557
1568
  const settings = this.settingsManager.getCompactionSettings();
@@ -1563,8 +1574,13 @@ export class AgentSession {
1563
1574
  if (!shouldCompact(contextTokens, contextWindow, settings)) {
1564
1575
  return {};
1565
1576
  }
1566
- const outcome = await this._runAutoCompactionWithOutcome("threshold", false, signal);
1577
+ const outcome = await this._runAutoCompactionWithOutcome("threshold", false, "midTurn", signal);
1567
1578
  if (!outcome.compacted) {
1579
+ if (outcome.cancelled && signal?.aborted !== true) {
1580
+ // The extension took ownership of the risk; don't re-ask on every batch.
1581
+ this._midTurnCompactionDeclined = true;
1582
+ return {};
1583
+ }
1568
1584
  return { stopErrorMessage: AUTO_COMPACTION_STOPPED_BEFORE_NEXT_PROVIDER };
1569
1585
  }
1570
1586
  return {
@@ -1587,7 +1603,7 @@ export class AgentSession {
1587
1603
  * @param assistantMessage The assistant message to check
1588
1604
  * @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true
1589
1605
  */
1590
- async _checkCompaction(assistantMessage, skipAbortedCheck = true) {
1606
+ async _checkCompaction(assistantMessage, skipAbortedCheck = true, timing = "postRun") {
1591
1607
  const settings = this.settingsManager.getCompactionSettings();
1592
1608
  if (!settings.enabled)
1593
1609
  return false;
@@ -1615,7 +1631,7 @@ export class AgentSession {
1615
1631
  if (sameModel && isContextOverflow(assistantMessage, contextWindow)) {
1616
1632
  const willRetry = assistantMessage.stopReason !== "stop";
1617
1633
  if (!willRetry) {
1618
- return await this._runAutoCompaction("overflow", false);
1634
+ return await this._runAutoCompaction("overflow", false, timing);
1619
1635
  }
1620
1636
  if (this._overflowRecoveryAttempted) {
1621
1637
  this._stopAfterTurnRequested = true;
@@ -1636,7 +1652,7 @@ export class AgentSession {
1636
1652
  if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
1637
1653
  this.agent.state.messages = messages.slice(0, -1);
1638
1654
  }
1639
- return await this._runAutoCompaction("overflow", willRetry);
1655
+ return await this._runAutoCompaction("overflow", willRetry, timing);
1640
1656
  }
1641
1657
  // Case 2: Threshold - context is getting large
1642
1658
  // For error messages or all-zero usage messages, estimate from the last valid response.
@@ -1664,21 +1680,21 @@ export class AgentSession {
1664
1680
  contextTokens = directContextTokens;
1665
1681
  }
1666
1682
  if (shouldCompact(contextTokens, contextWindow, settings)) {
1667
- return await this._runAutoCompaction("threshold", false);
1683
+ return await this._runAutoCompaction("threshold", false, timing);
1668
1684
  }
1669
1685
  return false;
1670
1686
  }
1671
1687
  /**
1672
1688
  * Internal: Run auto-compaction with events.
1673
1689
  */
1674
- async _runAutoCompaction(reason, willRetry) {
1675
- const outcome = await this._runAutoCompactionWithOutcome(reason, willRetry);
1690
+ async _runAutoCompaction(reason, willRetry, timing = "postRun") {
1691
+ const outcome = await this._runAutoCompactionWithOutcome(reason, willRetry, timing);
1676
1692
  if (!outcome.compacted || outcome.mustStop) {
1677
1693
  this._stopAfterTurnRequested = true;
1678
1694
  }
1679
1695
  return outcome.shouldContinue;
1680
1696
  }
1681
- async _runAutoCompactionWithOutcome(reason, willRetry, parentSignal) {
1697
+ async _runAutoCompactionWithOutcome(reason, willRetry, timing, parentSignal) {
1682
1698
  const settings = this.settingsManager.getCompactionSettings();
1683
1699
  let started = false;
1684
1700
  let controller;
@@ -1721,7 +1737,7 @@ export class AgentSession {
1721
1737
  const pathEntries = this.sessionManager.getBranch();
1722
1738
  const preparation = prepareCompaction(pathEntries, settings);
1723
1739
  if (!preparation) {
1724
- throw new Error("Nothing to compact while preserving the configured recent context.");
1740
+ throw new Error(NOTHING_TO_COMPACT_WITHIN_KEEP_WINDOW);
1725
1741
  }
1726
1742
  if (this._extensionRunner.hasHandlers("session_before_compact")) {
1727
1743
  const extensionResult = (await this._extensionRunner.emit({
@@ -1730,6 +1746,7 @@ export class AgentSession {
1730
1746
  branchEntries: pathEntries,
1731
1747
  customInstructions: undefined,
1732
1748
  reason,
1749
+ timing,
1733
1750
  willRetry,
1734
1751
  signal: controller.signal,
1735
1752
  }));
@@ -1741,7 +1758,9 @@ export class AgentSession {
1741
1758
  aborted: true,
1742
1759
  willRetry: false,
1743
1760
  });
1744
- return { compacted: false, shouldContinue: false };
1761
+ // A cancel produced by an abort (abortCompaction/parent abort) is not an
1762
+ // extension decision; only a voluntary cancel hands the risk to the extension.
1763
+ return { compacted: false, shouldContinue: false, cancelled: !controller.signal.aborted };
1745
1764
  }
1746
1765
  if (extensionResult?.compaction) {
1747
1766
  extensionCompaction = extensionResult.compaction;