@caupulican/pi-adaptative 0.93.18 → 0.94.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.
Files changed (164) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +3 -2
  3. package/dist/core/agent-session.d.ts +1 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +22 -12
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction-controller.d.ts +21 -0
  8. package/dist/core/compaction-controller.d.ts.map +1 -1
  9. package/dist/core/compaction-controller.js +149 -26
  10. package/dist/core/compaction-controller.js.map +1 -1
  11. package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
  12. package/dist/core/delegation/worker-agent-control-coordinator.js +1 -0
  13. package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
  14. package/dist/core/delegation/worker-agent-control.d.ts +2 -0
  15. package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
  16. package/dist/core/delegation/worker-agent-control.js.map +1 -1
  17. package/dist/core/extensions/loader.d.ts +0 -1
  18. package/dist/core/extensions/loader.d.ts.map +1 -1
  19. package/dist/core/extensions/loader.js +0 -1
  20. package/dist/core/extensions/loader.js.map +1 -1
  21. package/dist/core/extensions/types.d.ts +0 -4
  22. package/dist/core/extensions/types.d.ts.map +1 -1
  23. package/dist/core/extensions/types.js.map +1 -1
  24. package/dist/core/foreground-lifecycle-adapter.d.ts +27 -0
  25. package/dist/core/foreground-lifecycle-adapter.d.ts.map +1 -0
  26. package/dist/core/foreground-lifecycle-adapter.js +61 -0
  27. package/dist/core/foreground-lifecycle-adapter.js.map +1 -0
  28. package/dist/core/foreground-lifecycle-controller.d.ts +48 -0
  29. package/dist/core/foreground-lifecycle-controller.d.ts.map +1 -0
  30. package/dist/core/foreground-lifecycle-controller.js +404 -0
  31. package/dist/core/foreground-lifecycle-controller.js.map +1 -0
  32. package/dist/core/foreground-recovery-controller.d.ts +3 -0
  33. package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
  34. package/dist/core/foreground-recovery-controller.js +15 -1
  35. package/dist/core/foreground-recovery-controller.js.map +1 -1
  36. package/dist/core/goals/goal-state.d.ts.map +1 -1
  37. package/dist/core/goals/goal-state.js +9 -2
  38. package/dist/core/goals/goal-state.js.map +1 -1
  39. package/dist/core/keybindings.d.ts +2 -2
  40. package/dist/core/keybindings.d.ts.map +1 -1
  41. package/dist/core/keybindings.js +2 -2
  42. package/dist/core/keybindings.js.map +1 -1
  43. package/dist/core/memory/memory-manager.d.ts +22 -0
  44. package/dist/core/memory/memory-manager.d.ts.map +1 -1
  45. package/dist/core/memory/memory-manager.js +108 -49
  46. package/dist/core/memory/memory-manager.js.map +1 -1
  47. package/dist/core/model-router/session-buffer.d.ts +10 -2
  48. package/dist/core/model-router/session-buffer.d.ts.map +1 -1
  49. package/dist/core/model-router/session-buffer.js +35 -9
  50. package/dist/core/model-router/session-buffer.js.map +1 -1
  51. package/dist/core/model-router-controller.d.ts +20 -2
  52. package/dist/core/model-router-controller.d.ts.map +1 -1
  53. package/dist/core/model-router-controller.js +70 -17
  54. package/dist/core/model-router-controller.js.map +1 -1
  55. package/dist/core/provider-request-runtime-controller.d.ts +12 -1
  56. package/dist/core/provider-request-runtime-controller.d.ts.map +1 -1
  57. package/dist/core/provider-request-runtime-controller.js +45 -2
  58. package/dist/core/provider-request-runtime-controller.js.map +1 -1
  59. package/dist/core/tools/artifact-retrieve.d.ts.map +1 -1
  60. package/dist/core/tools/artifact-retrieve.js +0 -1
  61. package/dist/core/tools/artifact-retrieve.js.map +1 -1
  62. package/dist/core/tools/delegate.d.ts.map +1 -1
  63. package/dist/core/tools/delegate.js +4 -2
  64. package/dist/core/tools/delegate.js.map +1 -1
  65. package/dist/core/tools/edit.d.ts.map +1 -1
  66. package/dist/core/tools/edit.js +0 -7
  67. package/dist/core/tools/edit.js.map +1 -1
  68. package/dist/core/tools/find.d.ts.map +1 -1
  69. package/dist/core/tools/find.js +0 -1
  70. package/dist/core/tools/find.js.map +1 -1
  71. package/dist/core/tools/grep.d.ts.map +1 -1
  72. package/dist/core/tools/grep.js +0 -1
  73. package/dist/core/tools/grep.js.map +1 -1
  74. package/dist/core/tools/ls.d.ts.map +1 -1
  75. package/dist/core/tools/ls.js +0 -1
  76. package/dist/core/tools/ls.js.map +1 -1
  77. package/dist/core/tools/skill-audit.d.ts.map +1 -1
  78. package/dist/core/tools/skill-audit.js +0 -1
  79. package/dist/core/tools/skill-audit.js.map +1 -1
  80. package/dist/core/tools/skill.d.ts.map +1 -1
  81. package/dist/core/tools/skill.js +0 -1
  82. package/dist/core/tools/skill.js.map +1 -1
  83. package/dist/core/tools/skillify.d.ts.map +1 -1
  84. package/dist/core/tools/skillify.js +0 -1
  85. package/dist/core/tools/skillify.js.map +1 -1
  86. package/dist/core/tools/write.d.ts.map +1 -1
  87. package/dist/core/tools/write.js +1 -2
  88. package/dist/core/tools/write.js.map +1 -1
  89. package/dist/modes/interactive/components/action-transcript.d.ts +24 -0
  90. package/dist/modes/interactive/components/action-transcript.d.ts.map +1 -0
  91. package/dist/modes/interactive/components/action-transcript.js +72 -0
  92. package/dist/modes/interactive/components/action-transcript.js.map +1 -0
  93. package/dist/modes/interactive/components/active-tool-call-registry.d.ts +12 -0
  94. package/dist/modes/interactive/components/active-tool-call-registry.d.ts.map +1 -0
  95. package/dist/modes/interactive/components/active-tool-call-registry.js +25 -0
  96. package/dist/modes/interactive/components/active-tool-call-registry.js.map +1 -0
  97. package/dist/modes/interactive/components/activity-lane.d.ts +1 -1
  98. package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -1
  99. package/dist/modes/interactive/components/activity-lane.js.map +1 -1
  100. package/dist/modes/interactive/components/assistant-message.d.ts +3 -3
  101. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/assistant-message.js +16 -20
  103. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  104. package/dist/modes/interactive/components/index.d.ts +0 -2
  105. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  106. package/dist/modes/interactive/components/index.js +0 -2
  107. package/dist/modes/interactive/components/index.js.map +1 -1
  108. package/dist/modes/interactive/components/tool-execution.d.ts +0 -7
  109. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  110. package/dist/modes/interactive/components/tool-execution.js +2 -76
  111. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  112. package/dist/modes/interactive/components/transcript-overlay.d.ts +15 -0
  113. package/dist/modes/interactive/components/transcript-overlay.d.ts.map +1 -0
  114. package/dist/modes/interactive/components/transcript-overlay.js +38 -0
  115. package/dist/modes/interactive/components/transcript-overlay.js.map +1 -0
  116. package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
  117. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  118. package/dist/modes/interactive/components/tree-selector.js +7 -4
  119. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  120. package/dist/modes/interactive/interactive-event-controller.d.ts +3 -4
  121. package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -1
  122. package/dist/modes/interactive/interactive-event-controller.js +11 -10
  123. package/dist/modes/interactive/interactive-event-controller.js.map +1 -1
  124. package/dist/modes/interactive/interactive-mode.d.ts +15 -13
  125. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  126. package/dist/modes/interactive/interactive-mode.js +105 -184
  127. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  128. package/dist/modes/interactive/runtime-status-controller.d.ts +40 -0
  129. package/dist/modes/interactive/runtime-status-controller.d.ts.map +1 -0
  130. package/dist/modes/interactive/runtime-status-controller.js +147 -0
  131. package/dist/modes/interactive/runtime-status-controller.js.map +1 -0
  132. package/dist/modes/interactive/runtime-status.d.ts +15 -0
  133. package/dist/modes/interactive/runtime-status.d.ts.map +1 -0
  134. package/dist/modes/interactive/runtime-status.js +18 -0
  135. package/dist/modes/interactive/runtime-status.js.map +1 -0
  136. package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
  137. package/dist/modes/interactive/settings-selector-flow.js +3 -4
  138. package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
  139. package/docs/UI_POLISH_ORCHESTRATION.md +4 -4
  140. package/docs/extensions.md +4 -12
  141. package/docs/json.md +1 -1
  142. package/docs/keybindings.md +3 -2
  143. package/docs/session-format.md +59 -4
  144. package/docs/settings.md +1 -1
  145. package/docs/task-steps.md +3 -3
  146. package/docs/tool-repair.md +1 -1
  147. package/docs/usage.md +1 -1
  148. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  149. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  150. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  151. package/examples/extensions/sandbox/package-lock.json +2 -2
  152. package/examples/extensions/sandbox/package.json +1 -1
  153. package/examples/extensions/with-deps/package-lock.json +2 -2
  154. package/examples/extensions/with-deps/package.json +1 -1
  155. package/npm-shrinkwrap.json +12 -12
  156. package/package.json +4 -4
  157. package/dist/modes/interactive/components/tool-group.d.ts +0 -25
  158. package/dist/modes/interactive/components/tool-group.d.ts.map +0 -1
  159. package/dist/modes/interactive/components/tool-group.js +0 -175
  160. package/dist/modes/interactive/components/tool-group.js.map +0 -1
  161. package/dist/modes/interactive/components/tool-panel-registry.d.ts +0 -30
  162. package/dist/modes/interactive/components/tool-panel-registry.d.ts.map +0 -1
  163. package/dist/modes/interactive/components/tool-panel-registry.js +0 -145
  164. package/dist/modes/interactive/components/tool-panel-registry.js.map +0 -1
@@ -94,6 +94,7 @@ export declare class CompactionController {
94
94
  private manualAbortController;
95
95
  private autoAbortController;
96
96
  private autoRunPromise;
97
+ private activeCompactionLifecycle;
97
98
  private overflowRecoveryAttempted;
98
99
  private providerRecoveryAttempted;
99
100
  private ineffectiveThresholdFrontier;
@@ -102,6 +103,24 @@ export declare class CompactionController {
102
103
  private buildCompactionInstructions;
103
104
  isRunning(): boolean;
104
105
  private buildExecutionOptions;
106
+ /**
107
+ * Open the durable compaction transaction only after deterministic preparation has produced its cut.
108
+ * The caller must invoke this before extension or provider work begins. A failed append deliberately
109
+ * leaves no active lifecycle, so the caller fails closed before starting summarization.
110
+ */
111
+ private beginCompactionLifecycle;
112
+ private recordAppliedCompaction;
113
+ /**
114
+ * Lifecycle records are durable bookkeeping and must not become compaction input or alter the
115
+ * loop's trailing-compaction guard. They remain in the real branch so recovery can inspect them.
116
+ */
117
+ private getCompactionBranch;
118
+ /**
119
+ * Close the one transaction for this compaction retry ladder. The marker is attempted at most once;
120
+ * an append failure is allowed to propagate because success must never be inferred from an unrecorded
121
+ * terminal. A successful terminal always points at the canonical persisted compaction entry.
122
+ */
123
+ private finishCompactionLifecycle;
105
124
  resetOverflowRecovery(): void;
106
125
  admitProviderRequest(input: ProviderRequestCompactionInput): Promise<ProviderRequestCompactionDecision>;
107
126
  abort(): void;
@@ -110,6 +129,8 @@ export declare class CompactionController {
110
129
  private runManualCompaction;
111
130
  check(assistantMessage: AssistantMessage, skipAbortedCheck?: boolean): Promise<boolean>;
112
131
  measureLiveContextTokens(): number;
132
+ /** Prefer authoritative branch order; timestamps are only a fallback for reconstructed messages. */
133
+ private isAssistantFromBeforeCompaction;
113
134
  get isCompacting(): boolean;
114
135
  runAuto(reason: AutoCompactionReason, willRetry: boolean, options?: AutoCompactionRunOptions): Promise<boolean>;
115
136
  private runAutoOnce;
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-controller.d.ts","sourceRoot":"","sources":["../../src/core/compaction-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compaction-controller.d.ts","sourceRoot":"","sources":["../../src/core/compaction-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAIN,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EAOvB,MAAM,iDAAiD,CAAC;AAYzD,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAItE,OAAO,KAAK,EAAE,eAAe,EAA8B,MAAM,uBAAuB,CAAC;AACzF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,mBAAmB,GAAG,WAAW,CAAC;AAElF,MAAM,WAAW,8BAA8B;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,iCAAiC,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE1F,UAAU,wBAAwB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iCAAiC,CAAC,EAAE,OAAO,CAAC;IAC5C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,qBAAa,oCAAqC,SAAQ,KAAK;IAC9D,YAAY,OAAO,EAAE,MAAM,EAG1B;CACD;AA6CD,KAAK,yBAAyB,GAC3B;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,oBAAoB,CAAA;CAAE,GACrE;IACA,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,oBAAoB,CAAC;IACxC,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,wBAAwB;IACxC,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACnC,kBAAkB,IAAI,kBAAkB,CAAC;IACzC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;IAClG,mBAAmB,CAClB,eAAe,EAAE,KAAK,CAAC,GAAG,CAAC,EAC3B,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GACtB,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvG,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACnD,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAAC;IACzC,oBAAoB,CAAC,eAAe,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,GAAG,SAAS,CAAC;IACvG,kBAAkB,IAAI,MAAM,CAAC;IAC7B,kBAAkB,IAAI,eAAe,CAAC;IACtC,WAAW,IAAI,OAAO,CAAC;IACvB,eAAe,IAAI,IAAI,CAAC;IACxB,cAAc,IAAI,IAAI,CAAC;IACvB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAC7C,4BAA4B,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAC/D,cAAc,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IACxF,2BAA2B,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,sBAAsB,IAAI,IAAI,CAAC;IAC/B,gBAAgB,IAAI,qBAAqB,CAAC;IAC1C,wBAAwB,IAAI,MAAM,CAAC;IACnC,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtF,gBAAgB,CACf,GAAG,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EACpC,MAAM,EAAE,WAAW,EACnB,QAAQ,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7B,mBAAmB,CAAC,IAAI,IAAI,CAAC;CAC7B;AAED,wBAAsB,sBAAsB,CAAC,CAAC,EAAE,OAAO,EAAE;IACxD,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAC5E,GAAG,OAAO,CAAC,CAAC,CAAC,CAwBb;AAED,gGAAgG;AAChG,qBAAa,oBAAoB;IAChC,OAAO,CAAC,qBAAqB,CAA8B;IAC3D,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,yBAAyB,CAAwC;IACzE,OAAO,CAAC,yBAAyB,CAAS;IAC1C,OAAO,CAAC,yBAAyB,CAAS;IAC1C,OAAO,CAAC,4BAA4B,CAA2C;IAC/E,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;IAEhD,YAAY,IAAI,EAAE,wBAAwB,EAEzC;YAEa,2BAA2B;IAUzC,SAAS,IAAI,OAAO,CAMnB;IAED,OAAO,CAAC,qBAAqB;IAgC7B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,uBAAuB;IAI/B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IA8BjC,qBAAqB,IAAI,IAAI,CAG5B;IAEK,oBAAoB,CAAC,KAAK,EAAE,8BAA8B,GAAG,OAAO,CAAC,iCAAiC,CAAC,CA0D5G;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,8BAA8B,IAAI,IAAI,CA6BrC;IAEK,OAAO,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuDpE;YAEa,mBAAmB;IA8H3B,KAAK,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,UAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAqEzF;IAED,wBAAwB,IAAI,MAAM,CAWjC;IAED,oGAAoG;IACpG,OAAO,CAAC,+BAA+B;IAkBvC,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,OAAO,CAAC,MAAM,EAAE,oBAAoB,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBlH;YAEa,WAAW;IAoMzB,OAAO,CAAC,yBAAyB;IAmBjC,OAAO,CAAC,uBAAuB;IA2B/B,OAAO,CAAC,4BAA4B;IAY9B,gBAAgB,CACrB,GAAG,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EACpC,MAAM,EAAE,WAAW,EACnB,QAAQ,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;IAED,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,2BAA2B;IAWnC,OAAO,CAAC,kCAAkC;YAY5B,sBAAsB;YA6BtB,WAAW;CAgCzB"}
@@ -1,10 +1,11 @@
1
+ import { randomUUID } from "node:crypto";
1
2
  import { assessCompactionNeed, calculateContextTokens, compact, createDeterministicCompaction, estimateContextTokens, prepareCompaction, shouldCompact, } from "@caupulican/pi-agent-core/compaction/compaction";
2
3
  import { runCompactionLoop } from "@caupulican/pi-agent-core/compaction/loop";
3
4
  import { convertToLlm, createCustomMessage } from "@caupulican/pi-agent-core/messages";
4
5
  import { estimateProviderRequestTokens } from "@caupulican/pi-agent-core/provider-request-estimator";
5
6
  import { projectToolsForProvider } from "@caupulican/pi-agent-core/provider-tool-projection";
6
7
  import { classifyFailure, computeRetryDelayMs, DEFAULT_RETRY_POLICY, sleepAbortable, } from "@caupulican/pi-agent-core/reliability";
7
- import { getLatestCompactionEntry } from "@caupulican/pi-agent-core/session";
8
+ import { getLatestCompactionEntry, isSessionLifecycleEntry, } from "@caupulican/pi-agent-core/session";
8
9
  import { isContextOverflow } from "@caupulican/pi-ai/overflow";
9
10
  import { materializeProviderRequest } from "@caupulican/pi-ai/stream";
10
11
  import { formatNoModelSelectedMessage } from "./auth-guidance.js";
@@ -19,6 +20,16 @@ const COMPACTION_RETRY_PREPARATION_OPTIONS = { allowTrailingCompactionAsPrevious
19
20
  const INEFFECTIVE_THRESHOLD_SKIP_REASON = "previous auto-compaction did not restore headroom; waiting for materially new compactable history";
20
21
  const PROVIDER_RECOVERY_CONTINUATION_CUSTOM_TYPE = "provider_recovery_continuation";
21
22
  const PROVIDER_RECOVERY_CONTINUATION = "Continue the latest owner request from the compacted checkpoint.";
23
+ function boundedCompactionLifecycleError(error) {
24
+ const message = error instanceof Error ? error.message : typeof error === "string" ? error : "compaction failed";
25
+ const sanitized = message
26
+ .replace(/[\u0000-\u001F\u007F]/g, " ")
27
+ .replace(/\s+/g, " ")
28
+ .trim();
29
+ if (!sanitized)
30
+ return "compaction failed";
31
+ return sanitized.length > 500 ? `${sanitized.slice(0, 500)}…` : sanitized;
32
+ }
22
33
  function formatRequestTokenBreakdown(input) {
23
34
  const total = Math.max(0, Math.ceil(input.requestTokens));
24
35
  const nonCompactable = Math.max(0, Math.min(total, Math.ceil(input.nonCompactableTokens)));
@@ -93,6 +104,69 @@ export class CompactionController {
93
104
  };
94
105
  return options;
95
106
  }
107
+ /**
108
+ * Open the durable compaction transaction only after deterministic preparation has produced its cut.
109
+ * The caller must invoke this before extension or provider work begins. A failed append deliberately
110
+ * leaves no active lifecycle, so the caller fails closed before starting summarization.
111
+ */
112
+ beginCompactionLifecycle(preparation) {
113
+ if (this.activeCompactionLifecycle)
114
+ return;
115
+ const compactionId = randomUUID();
116
+ this.deps.sessionManager.appendCompactionStart(compactionId, preparation.firstKeptEntryId, preparation.tokensBefore);
117
+ this.activeCompactionLifecycle = { compactionId, endAttempted: false };
118
+ }
119
+ recordAppliedCompaction(compactionEntryId) {
120
+ if (this.activeCompactionLifecycle)
121
+ this.activeCompactionLifecycle.latestCompactionEntryId = compactionEntryId;
122
+ }
123
+ /**
124
+ * Lifecycle records are durable bookkeeping and must not become compaction input or alter the
125
+ * loop's trailing-compaction guard. They remain in the real branch so recovery can inspect them.
126
+ */
127
+ getCompactionBranch() {
128
+ return this.deps.sessionManager.getBranch().filter((entry) => !isSessionLifecycleEntry(entry));
129
+ }
130
+ /**
131
+ * Close the one transaction for this compaction retry ladder. The marker is attempted at most once;
132
+ * an append failure is allowed to propagate because success must never be inferred from an unrecorded
133
+ * terminal. A successful terminal always points at the canonical persisted compaction entry.
134
+ */
135
+ finishCompactionLifecycle(outcome, error) {
136
+ const lifecycle = this.activeCompactionLifecycle;
137
+ if (!lifecycle || lifecycle.endAttempted)
138
+ return;
139
+ lifecycle.endAttempted = true;
140
+ let terminalOutcome = outcome;
141
+ let terminalError = error === undefined ? undefined : boundedCompactionLifecycleError(error);
142
+ let invalidSuccess = false;
143
+ if (terminalOutcome === "success" && !lifecycle.latestCompactionEntryId) {
144
+ terminalOutcome = "failure";
145
+ terminalError = "compaction succeeded without a persisted compaction entry";
146
+ invalidSuccess = true;
147
+ }
148
+ try {
149
+ if (terminalOutcome === "success") {
150
+ this.deps.sessionManager.appendCompactionEnd(lifecycle.compactionId, terminalOutcome, {
151
+ compactionEntryId: lifecycle.latestCompactionEntryId,
152
+ });
153
+ }
154
+ else if (terminalError) {
155
+ this.deps.sessionManager.appendCompactionEnd(lifecycle.compactionId, terminalOutcome, {
156
+ error: terminalError,
157
+ });
158
+ }
159
+ else {
160
+ this.deps.sessionManager.appendCompactionEnd(lifecycle.compactionId, terminalOutcome);
161
+ }
162
+ }
163
+ finally {
164
+ if (this.activeCompactionLifecycle === lifecycle)
165
+ this.activeCompactionLifecycle = undefined;
166
+ }
167
+ if (invalidSuccess)
168
+ throw new Error(terminalError);
169
+ }
96
170
  resetOverflowRecovery() {
97
171
  this.overflowRecoveryAttempted = false;
98
172
  this.providerRecoveryAttempted = false;
@@ -197,6 +271,12 @@ export class CompactionController {
197
271
  primaryError = error;
198
272
  const message = error instanceof Error ? error.message : String(error);
199
273
  const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
274
+ try {
275
+ this.finishCompactionLifecycle(aborted ? "cancelled" : "failure", aborted ? undefined : error);
276
+ }
277
+ catch (lifecycleError) {
278
+ primaryError = new AggregateError([primaryError, lifecycleError], "Compaction failed and its durable lifecycle terminal could not be recorded");
279
+ }
200
280
  this.deps.emit({
201
281
  type: "compaction_end",
202
282
  reason: "manual",
@@ -243,7 +323,7 @@ export class CompactionController {
243
323
  await this.deps.getRequestAuth(selectedCompactionModel);
244
324
  const selectionReason = this.deps.getSelectionReason() ?? "unknown";
245
325
  const settings = this.deps.getAdaptedSettings();
246
- const initialBranch = this.deps.sessionManager.getBranch();
326
+ const initialBranch = this.getCompactionBranch();
247
327
  const initialPreparation = prepareCompaction(initialBranch, settings);
248
328
  if (!initialPreparation) {
249
329
  const lastEntry = initialBranch[initialBranch.length - 1];
@@ -251,6 +331,7 @@ export class CompactionController {
251
331
  throw new Error("Already compacted");
252
332
  throw new Error("Nothing to compact (session too small)");
253
333
  }
334
+ this.beginCompactionLifecycle(initialPreparation);
254
335
  // Resolve once for the complete retry ladder. Provider hooks can perform durable flushes and
255
336
  // must not be repeated for every summarizer/gate retry.
256
337
  const effectiveInstructions = await this.buildCompactionInstructions(customInstructions);
@@ -258,7 +339,8 @@ export class CompactionController {
258
339
  if (extension.cancelled)
259
340
  throw new Error("Compaction cancelled");
260
341
  if (extension.result) {
261
- await this.applyResult(extension.result, true);
342
+ this.recordAppliedCompaction(await this.applyResult(extension.result, true));
343
+ this.finishCompactionLifecycle("success");
262
344
  this.deps.emit({
263
345
  type: "compaction_end",
264
346
  reason: "manual",
@@ -273,7 +355,7 @@ export class CompactionController {
273
355
  measureLiveTokens: () => Math.max(this.deps.estimateCurrentContextTokens(this.deps.agent.state.messages), 1),
274
356
  shouldCompact: () => true,
275
357
  getPostApplyMargin: () => 0,
276
- getBranch: () => this.deps.sessionManager.getBranch(),
358
+ getBranch: () => this.getCompactionBranch(),
277
359
  getBaseKeepRecentTokens: () => settings.keepRecentTokens,
278
360
  resolveModelAndAuth: async (modelTier) => {
279
361
  const model = modelTier === "cheap" ? selectedCompactionModel : sessionModel;
@@ -296,7 +378,7 @@ export class CompactionController {
296
378
  apply: async (result) => {
297
379
  if (signal.aborted)
298
380
  throw new Error("Compaction cancelled");
299
- await this.applyResult(result, false);
381
+ this.recordAppliedCompaction(await this.applyResult(result, false));
300
382
  appliedResult = result;
301
383
  },
302
384
  verifyPostApplyEffect: () => false,
@@ -316,6 +398,7 @@ export class CompactionController {
316
398
  if (outcome.kind === "skip" || !appliedResult) {
317
399
  throw new Error(outcome.kind === "skip" ? outcome.reason : "Compaction failed");
318
400
  }
401
+ this.finishCompactionLifecycle("success");
319
402
  this.deps.emit({
320
403
  type: "compaction_end",
321
404
  reason: "manual",
@@ -335,7 +418,7 @@ export class CompactionController {
335
418
  const contextWindow = model?.contextWindow ?? 0;
336
419
  const sameModel = model && assistantMessage.provider === model.provider && assistantMessage.model === model.id;
337
420
  const compactionEntry = getLatestCompactionEntry(this.deps.sessionManager.getBranch());
338
- const assistantIsFromBeforeCompaction = compactionEntry !== null && assistantMessage.timestamp <= new Date(compactionEntry.timestamp).getTime();
421
+ const assistantIsFromBeforeCompaction = this.isAssistantFromBeforeCompaction(assistantMessage, compactionEntry);
339
422
  if (assistantIsFromBeforeCompaction)
340
423
  return false;
341
424
  if (sameModel && isContextOverflow(assistantMessage, contextWindow)) {
@@ -371,9 +454,7 @@ export class CompactionController {
371
454
  if (estimate.lastUsageIndex === null)
372
455
  return false;
373
456
  const usageMessage = messages[estimate.lastUsageIndex];
374
- if (compactionEntry &&
375
- usageMessage.role === "assistant" &&
376
- usageMessage.timestamp <= new Date(compactionEntry.timestamp).getTime()) {
457
+ if (usageMessage.role === "assistant" && this.isAssistantFromBeforeCompaction(usageMessage, compactionEntry)) {
377
458
  return false;
378
459
  }
379
460
  contextTokens = estimate.tokens;
@@ -383,9 +464,7 @@ export class CompactionController {
383
464
  const estimate = estimateContextTokens(this.deps.agent.state.messages);
384
465
  if (estimate.lastUsageIndex !== null) {
385
466
  const usageMessage = this.deps.agent.state.messages[estimate.lastUsageIndex];
386
- const usageIsPostCompaction = !(compactionEntry &&
387
- usageMessage.role === "assistant" &&
388
- usageMessage.timestamp <= new Date(compactionEntry.timestamp).getTime());
467
+ const usageIsPostCompaction = !(usageMessage.role === "assistant" && this.isAssistantFromBeforeCompaction(usageMessage, compactionEntry));
389
468
  if (usageIsPostCompaction)
390
469
  contextTokens = Math.max(contextTokens, estimate.tokens);
391
470
  }
@@ -406,11 +485,27 @@ export class CompactionController {
406
485
  return estimatedTokens;
407
486
  }
408
487
  const compactionEntry = getLatestCompactionEntry(this.deps.sessionManager.getBranch());
409
- if (compactionEntry && assistantMessage.timestamp <= new Date(compactionEntry.timestamp).getTime()) {
488
+ if (this.isAssistantFromBeforeCompaction(assistantMessage, compactionEntry)) {
410
489
  return estimatedTokens;
411
490
  }
412
491
  return Math.max(calculateContextTokens(assistantMessage.usage), estimatedTokens);
413
492
  }
493
+ /** Prefer authoritative branch order; timestamps are only a fallback for reconstructed messages. */
494
+ isAssistantFromBeforeCompaction(assistantMessage, compactionEntry) {
495
+ if (!compactionEntry)
496
+ return false;
497
+ const branch = this.deps.sessionManager.getBranch();
498
+ const compactionPosition = branch.findIndex((entry) => entry.id === compactionEntry.id);
499
+ if (compactionPosition >= 0) {
500
+ for (let position = branch.length - 1; position >= 0; position--) {
501
+ const entry = branch[position];
502
+ if (entry?.type === "message" && entry.message === assistantMessage) {
503
+ return position < compactionPosition;
504
+ }
505
+ }
506
+ }
507
+ return assistantMessage.timestamp <= new Date(compactionEntry.timestamp).getTime();
508
+ }
414
509
  get isCompacting() {
415
510
  return this.isRunning();
416
511
  }
@@ -442,6 +537,8 @@ export class CompactionController {
442
537
  let fromExtension = false;
443
538
  let lastCompaction;
444
539
  let extensionCancelled = false;
540
+ let effectiveInstructions;
541
+ let effectiveInstructionsReady = false;
445
542
  try {
446
543
  if (!model) {
447
544
  this.deps.emit({
@@ -456,10 +553,20 @@ export class CompactionController {
456
553
  }
457
554
  const contextWindow = model.contextWindow;
458
555
  const margin = Math.max(0, Math.floor(0.01 * contextWindow));
459
- // One event-driven handoff per compaction run; every retry reuses this bounded value.
460
- const effectiveInstructions = await this.buildCompactionInstructions();
556
+ // When the caller supplied the exact request total (or recovery makes compaction mandatory),
557
+ // open the transaction before model/auth resolution. Threshold runs without an admitted total
558
+ // stay lazy so a changing live measurement cannot create a marker for a later no-op skip.
559
+ const canPreflight = reason !== "threshold" || options.initialTokens !== undefined;
560
+ const preflightShouldCompact = reason !== "threshold" ||
561
+ (options.initialTokens !== undefined &&
562
+ shouldCompact(options.initialTokens, contextWindow, settings, model.autoCompactionTriggerTokens));
563
+ if (canPreflight && preflightShouldCompact) {
564
+ const preflightPreparation = prepareCompaction(this.getCompactionBranch(), settings, options.allowTrailingCompactionAsPrevious ? COMPACTION_RETRY_PREPARATION_OPTIONS : undefined);
565
+ if (preflightPreparation)
566
+ this.beginCompactionLifecycle(preflightPreparation);
567
+ }
461
568
  const outcome = await runCompactionLoop({
462
- getBranch: () => this.deps.sessionManager.getBranch(),
569
+ getBranch: () => this.getCompactionBranch(),
463
570
  measureLiveTokens: () => options.initialTokens ?? this.deps.measureLiveContextTokens(),
464
571
  shouldCompact: reason === "threshold"
465
572
  ? (tokens) => shouldCompact(tokens, contextWindow, settings, model.autoCompactionTriggerTokens)
@@ -475,6 +582,12 @@ export class CompactionController {
475
582
  }, COMPACTION_RETRY_PREPARATION_OPTIONS);
476
583
  if (!preparation)
477
584
  throw new Error("already compacted");
585
+ this.beginCompactionLifecycle(preparation);
586
+ // One event-driven handoff per compaction run; every retry reuses this bounded value.
587
+ if (!effectiveInstructionsReady) {
588
+ effectiveInstructions = await this.buildCompactionInstructions();
589
+ effectiveInstructionsReady = true;
590
+ }
478
591
  const compactionThinkingLevel = this.deps.resolveThinkingLevel(compactModel, model);
479
592
  const extension = await this.getExtensionCompaction(preparation, branchEntries, effectiveInstructions, signal);
480
593
  if (extension.cancelled) {
@@ -489,15 +602,16 @@ export class CompactionController {
489
602
  return { result };
490
603
  },
491
604
  buildDeterministicCheckpoint: (params) => {
492
- const preparation = prepareCompaction(this.deps.sessionManager.getBranch(), { ...settings, keepRecentTokens: params.keepRecentTokens }, COMPACTION_RETRY_PREPARATION_OPTIONS);
605
+ const preparation = prepareCompaction(this.getCompactionBranch(), { ...settings, keepRecentTokens: params.keepRecentTokens }, COMPACTION_RETRY_PREPARATION_OPTIONS);
493
606
  if (!preparation)
494
607
  throw new Error("already compacted");
608
+ this.beginCompactionLifecycle(preparation);
495
609
  fromExtension = false;
496
610
  return { result: createDeterministicCompaction(preparation) };
497
611
  },
498
612
  apply: async (result) => {
499
613
  lastCompaction = result;
500
- await this.applyResult(result, fromExtension);
614
+ this.recordAppliedCompaction(await this.applyResult(result, fromExtension));
501
615
  },
502
616
  verifyPostApplyEffect: reason !== "threshold" || options.singlePass ? () => false : undefined,
503
617
  allowTrailingCompactionAsPrevious: options.allowTrailingCompactionAsPrevious,
@@ -511,6 +625,7 @@ export class CompactionController {
511
625
  signal,
512
626
  });
513
627
  if (outcome.kind === "skip") {
628
+ this.finishCompactionLifecycle("failure", outcome.reason);
514
629
  this.deps.emit({
515
630
  type: "compaction_end",
516
631
  reason,
@@ -523,12 +638,14 @@ export class CompactionController {
523
638
  }
524
639
  if (outcome.kind === "failed") {
525
640
  if (outcome.reason === "aborted") {
641
+ this.finishCompactionLifecycle("cancelled");
526
642
  this.deps.emit({ type: "compaction_end", reason, result: undefined, aborted: true, willRetry: false });
527
643
  return hadQueuedMessages || this.deps.agent.hasQueuedMessages();
528
644
  }
529
645
  throw new Error(outcome.reason);
530
646
  }
531
647
  if (extensionCancelled || signal.aborted) {
648
+ this.finishCompactionLifecycle("cancelled");
532
649
  this.deps.emit({ type: "compaction_end", reason, result: undefined, aborted: true, willRetry: false });
533
650
  return hadQueuedMessages || this.deps.agent.hasQueuedMessages();
534
651
  }
@@ -545,24 +662,29 @@ export class CompactionController {
545
662
  if (reason === "provider_recovery")
546
663
  this.appendProviderRecoveryContinuation();
547
664
  }
665
+ this.finishCompactionLifecycle("success");
548
666
  this.deps.emit({ type: "compaction_end", reason, result, aborted: false, willRetry });
549
667
  if (willRetry)
550
668
  return true;
551
669
  return hadQueuedMessages || this.deps.agent.hasQueuedMessages();
552
670
  }
553
671
  catch (error) {
554
- const errorMessage = error instanceof Error ? error.message : "compaction failed";
672
+ const errorMessage = boundedCompactionLifecycleError(error);
673
+ const aborted = extensionCancelled || signal.aborted || errorMessage === "Compaction cancelled";
674
+ this.finishCompactionLifecycle(aborted ? "cancelled" : "failure", aborted ? undefined : error);
555
675
  this.deps.emit({
556
676
  type: "compaction_end",
557
677
  reason,
558
678
  result: undefined,
559
- aborted: false,
679
+ aborted,
560
680
  willRetry: false,
561
- errorMessage: reason === "overflow"
562
- ? `Context overflow recovery failed: ${errorMessage}`
563
- : reason === "provider_recovery"
564
- ? `Provider failure recovery failed: ${errorMessage}`
565
- : `Auto-compaction failed: ${errorMessage}`,
681
+ errorMessage: aborted
682
+ ? undefined
683
+ : reason === "overflow"
684
+ ? `Context overflow recovery failed: ${errorMessage}`
685
+ : reason === "provider_recovery"
686
+ ? `Provider failure recovery failed: ${errorMessage}`
687
+ : `Auto-compaction failed: ${errorMessage}`,
566
688
  });
567
689
  return hadQueuedMessages || this.deps.agent.hasQueuedMessages();
568
690
  }
@@ -685,7 +807,7 @@ export class CompactionController {
685
807
  result.summary = `${result.summary.trimEnd()}\n\n${transcriptPointer}`;
686
808
  }
687
809
  }
688
- this.deps.sessionManager.appendCompaction(result.summary, result.firstKeptEntryId, result.tokensBefore, result.details, fromExtension, result.usage, result.retention);
810
+ const compactionEntryId = this.deps.sessionManager.appendCompaction(result.summary, result.firstKeptEntryId, result.tokensBefore, result.details, fromExtension, result.usage, result.retention);
689
811
  this.deps.refreshAfterCompaction();
690
812
  const savedEntry = this.deps.sessionManager
691
813
  .getEntries()
@@ -697,6 +819,7 @@ export class CompactionController {
697
819
  fromExtension,
698
820
  });
699
821
  }
822
+ return compactionEntryId;
700
823
  }
701
824
  }
702
825
  //# sourceMappingURL=compaction-controller.js.map