@code-yeongyu/senpi 2026.5.13 → 2026.5.15-2

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 (274) hide show
  1. package/CHANGELOG.md +1109 -1150
  2. package/README.md +1 -2
  3. package/dist/core/agent-session.d.ts +9 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +121 -12
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/bash-executor.d.ts.map +1 -1
  8. package/dist/core/bash-executor.js +1 -1
  9. package/dist/core/bash-executor.js.map +1 -1
  10. package/dist/core/compaction/compaction.d.ts.map +1 -1
  11. package/dist/core/compaction/compaction.js +2 -2
  12. package/dist/core/compaction/compaction.js.map +1 -1
  13. package/dist/core/dynamic-prompt/verification.d.ts +31 -0
  14. package/dist/core/dynamic-prompt/verification.d.ts.map +1 -1
  15. package/dist/core/dynamic-prompt/verification.js +41 -0
  16. package/dist/core/dynamic-prompt/verification.js.map +1 -1
  17. package/dist/core/export-html/index.d.ts.map +1 -1
  18. package/dist/core/export-html/index.js +8 -1
  19. package/dist/core/export-html/index.js.map +1 -1
  20. package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/anthropic-web-search/index.js +20 -0
  22. package/dist/core/extensions/builtin/anthropic-web-search/index.js.map +1 -1
  23. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/compaction/index.js +157 -29
  25. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  26. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +197 -0
  27. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -0
  28. package/dist/core/extensions/builtin/compaction/openai-remote.js +690 -0
  29. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -0
  30. package/dist/core/extensions/builtin/compaction/prompts.d.ts +3 -3
  31. package/dist/core/extensions/builtin/compaction/prompts.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/prompts.js +0 -22
  33. package/dist/core/extensions/builtin/compaction/prompts.js.map +1 -1
  34. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts +4 -0
  35. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts.map +1 -0
  36. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js +48 -0
  37. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js.map +1 -0
  38. package/dist/core/extensions/builtin/compaction/speculative.d.ts +3 -1
  39. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/compaction/speculative.js +82 -33
  41. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  42. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts +8 -0
  43. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts.map +1 -1
  44. package/dist/core/extensions/builtin/compaction/todo-bridge.js +12 -6
  45. package/dist/core/extensions/builtin/compaction/todo-bridge.js.map +1 -1
  46. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/index.js +0 -20
  48. package/dist/core/extensions/builtin/index.js.map +1 -1
  49. package/dist/core/extensions/builtin/openai-web-search/index.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/openai-web-search/index.js +28 -0
  51. package/dist/core/extensions/builtin/openai-web-search/index.js.map +1 -1
  52. package/dist/core/extensions/builtin/permission-system/prompt.d.ts.map +1 -1
  53. package/dist/core/extensions/builtin/permission-system/prompt.js +0 -5
  54. package/dist/core/extensions/builtin/permission-system/prompt.js.map +1 -1
  55. package/dist/core/extensions/builtin/system-messages.d.ts +7 -7
  56. package/dist/core/extensions/builtin/system-messages.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/system-messages.js +10 -10
  58. package/dist/core/extensions/builtin/system-messages.js.map +1 -1
  59. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts +1 -1
  60. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/todotools/continuation/prompt.js +1 -1
  62. package/dist/core/extensions/builtin/todotools/continuation/prompt.js.map +1 -1
  63. package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
  64. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/todotools/state.js +2 -2
  66. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  67. package/dist/core/extensions/builtin/todotools/system-messages.d.ts +3 -3
  68. package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/todotools/system-messages.js +6 -6
  70. package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -1
  71. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts +1 -1
  72. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/tool-pair-guard/index.js +8 -4
  74. package/dist/core/extensions/builtin/tool-pair-guard/index.js.map +1 -1
  75. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts +3 -0
  76. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts.map +1 -0
  77. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js +89 -0
  78. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js.map +1 -0
  79. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts +3 -0
  80. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts.map +1 -0
  81. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js +122 -0
  82. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js.map +1 -0
  83. package/dist/core/extensions/loader.d.ts.map +1 -1
  84. package/dist/core/extensions/loader.js +2 -0
  85. package/dist/core/extensions/loader.js.map +1 -1
  86. package/dist/core/extensions/runner.d.ts +3 -0
  87. package/dist/core/extensions/runner.d.ts.map +1 -1
  88. package/dist/core/extensions/runner.js +18 -0
  89. package/dist/core/extensions/runner.js.map +1 -1
  90. package/dist/core/extensions/types.d.ts +22 -0
  91. package/dist/core/extensions/types.d.ts.map +1 -1
  92. package/dist/core/extensions/types.js.map +1 -1
  93. package/dist/core/messages.d.ts +3 -3
  94. package/dist/core/messages.d.ts.map +1 -1
  95. package/dist/core/messages.js +5 -10
  96. package/dist/core/messages.js.map +1 -1
  97. package/dist/core/resource-loader.d.ts.map +1 -1
  98. package/dist/core/resource-loader.js +0 -9
  99. package/dist/core/resource-loader.js.map +1 -1
  100. package/dist/core/sdk.d.ts +2 -2
  101. package/dist/core/sdk.d.ts.map +1 -1
  102. package/dist/core/sdk.js +8 -23
  103. package/dist/core/sdk.js.map +1 -1
  104. package/dist/core/session-manager.d.ts.map +1 -1
  105. package/dist/core/session-manager.js +1 -1
  106. package/dist/core/session-manager.js.map +1 -1
  107. package/dist/core/settings-manager.d.ts +0 -5
  108. package/dist/core/settings-manager.d.ts.map +1 -1
  109. package/dist/core/settings-manager.js.map +1 -1
  110. package/dist/core/thinking-levels.d.ts +6 -0
  111. package/dist/core/thinking-levels.d.ts.map +1 -0
  112. package/dist/core/thinking-levels.js +36 -0
  113. package/dist/core/thinking-levels.js.map +1 -0
  114. package/dist/core/tools/bash.d.ts.map +1 -1
  115. package/dist/core/tools/bash.js +15 -1
  116. package/dist/core/tools/bash.js.map +1 -1
  117. package/dist/core/tools/render-utils.d.ts.map +1 -1
  118. package/dist/core/tools/render-utils.js +1 -1
  119. package/dist/core/tools/render-utils.js.map +1 -1
  120. package/dist/main.d.ts.map +1 -1
  121. package/dist/main.js +3 -2
  122. package/dist/main.js.map +1 -1
  123. package/dist/modes/interactive/components/assistant-message.d.ts +0 -3
  124. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  125. package/dist/modes/interactive/components/assistant-message.js +3 -22
  126. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  127. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  128. package/dist/modes/interactive/components/bash-execution.js +1 -1
  129. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  130. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  131. package/dist/modes/interactive/components/compaction-summary-message.js +20 -2
  132. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  133. package/dist/modes/interactive/components/extension-selector.d.ts +2 -0
  134. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  135. package/dist/modes/interactive/components/extension-selector.js +6 -1
  136. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  137. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  138. package/dist/modes/interactive/components/keybinding-hints.js +3 -1
  139. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  140. package/dist/modes/interactive/interactive-mode.d.ts +23 -0
  141. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  142. package/dist/modes/interactive/interactive-mode.js +139 -54
  143. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  144. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  145. package/dist/modes/interactive/theme/theme.js +2 -2
  146. package/dist/modes/interactive/theme/theme.js.map +1 -1
  147. package/dist/modes/print-mode.d.ts.map +1 -1
  148. package/dist/modes/print-mode.js +3 -11
  149. package/dist/modes/print-mode.js.map +1 -1
  150. package/dist/modes/provider-native-rendering.d.ts +5 -0
  151. package/dist/modes/provider-native-rendering.d.ts.map +1 -0
  152. package/dist/modes/provider-native-rendering.js +247 -0
  153. package/dist/modes/provider-native-rendering.js.map +1 -0
  154. package/dist/utils/ansi.d.ts +2 -0
  155. package/dist/utils/ansi.d.ts.map +1 -0
  156. package/dist/utils/ansi.js +52 -0
  157. package/dist/utils/ansi.js.map +1 -0
  158. package/dist/utils/html.d.ts +7 -0
  159. package/dist/utils/html.d.ts.map +1 -0
  160. package/dist/utils/html.js +40 -0
  161. package/dist/utils/html.js.map +1 -0
  162. package/dist/utils/mime.d.ts +1 -0
  163. package/dist/utils/mime.d.ts.map +1 -1
  164. package/dist/utils/mime.js +59 -16
  165. package/dist/utils/mime.js.map +1 -1
  166. package/dist/utils/syntax-highlight.d.ts +12 -0
  167. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  168. package/dist/utils/syntax-highlight.js +118 -0
  169. package/dist/utils/syntax-highlight.js.map +1 -0
  170. package/dist/utils/tools-manager.d.ts.map +1 -1
  171. package/dist/utils/tools-manager.js +76 -7
  172. package/dist/utils/tools-manager.js.map +1 -1
  173. package/docs/extensions.md +0 -1
  174. package/docs/index.md +0 -1
  175. package/docs/sdk.md +25 -44
  176. package/docs/settings.md +1 -29
  177. package/docs/termux.md +2 -2
  178. package/docs/usage.md +1 -1
  179. package/examples/README.md +1 -1
  180. package/examples/extensions/README.md +0 -1
  181. package/examples/extensions/overlay-qa-tests.ts +1 -1
  182. package/examples/sdk/01-minimal.ts +14 -10
  183. package/examples/sdk/02-custom-model.ts +12 -8
  184. package/examples/sdk/03-custom-prompt.ts +24 -16
  185. package/examples/sdk/04-skills.ts +2 -2
  186. package/examples/sdk/05-tools.ts +8 -4
  187. package/examples/sdk/06-extensions.ts +11 -7
  188. package/examples/sdk/07-context-files.ts +2 -2
  189. package/examples/sdk/08-prompt-templates.ts +2 -2
  190. package/examples/sdk/09-api-keys-and-oauth.ts +8 -4
  191. package/examples/sdk/10-settings.ts +4 -4
  192. package/examples/sdk/11-sessions.ts +4 -0
  193. package/examples/sdk/12-full-control.ts +11 -7
  194. package/examples/sdk/README.md +6 -9
  195. package/package.json +7 -12
  196. package/dist/core/extensions/builtin/anthropic-code-execution/index.d.ts +0 -7
  197. package/dist/core/extensions/builtin/anthropic-code-execution/index.d.ts.map +0 -1
  198. package/dist/core/extensions/builtin/anthropic-code-execution/index.js +0 -79
  199. package/dist/core/extensions/builtin/anthropic-code-execution/index.js.map +0 -1
  200. package/dist/core/extensions/builtin/anthropic-computer-use/index.d.ts +0 -53
  201. package/dist/core/extensions/builtin/anthropic-computer-use/index.d.ts.map +0 -1
  202. package/dist/core/extensions/builtin/anthropic-computer-use/index.js +0 -676
  203. package/dist/core/extensions/builtin/anthropic-computer-use/index.js.map +0 -1
  204. package/dist/core/extensions/builtin/anthropic-text-editor/index.d.ts +0 -25
  205. package/dist/core/extensions/builtin/anthropic-text-editor/index.d.ts.map +0 -1
  206. package/dist/core/extensions/builtin/anthropic-text-editor/index.js +0 -244
  207. package/dist/core/extensions/builtin/anthropic-text-editor/index.js.map +0 -1
  208. package/dist/core/extensions/builtin/anthropic-tool-search/index.d.ts +0 -6
  209. package/dist/core/extensions/builtin/anthropic-tool-search/index.d.ts.map +0 -1
  210. package/dist/core/extensions/builtin/anthropic-tool-search/index.js +0 -112
  211. package/dist/core/extensions/builtin/anthropic-tool-search/index.js.map +0 -1
  212. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts +0 -10
  213. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts.map +0 -1
  214. package/dist/core/extensions/builtin/background-task/cancel-tool.js +0 -109
  215. package/dist/core/extensions/builtin/background-task/cancel-tool.js.map +0 -1
  216. package/dist/core/extensions/builtin/background-task/index.d.ts +0 -3
  217. package/dist/core/extensions/builtin/background-task/index.d.ts.map +0 -1
  218. package/dist/core/extensions/builtin/background-task/index.js +0 -207
  219. package/dist/core/extensions/builtin/background-task/index.js.map +0 -1
  220. package/dist/core/extensions/builtin/background-task/manager.d.ts +0 -17
  221. package/dist/core/extensions/builtin/background-task/manager.d.ts.map +0 -1
  222. package/dist/core/extensions/builtin/background-task/manager.js +0 -114
  223. package/dist/core/extensions/builtin/background-task/manager.js.map +0 -1
  224. package/dist/core/extensions/builtin/background-task/notification.d.ts +0 -22
  225. package/dist/core/extensions/builtin/background-task/notification.d.ts.map +0 -1
  226. package/dist/core/extensions/builtin/background-task/notification.js +0 -105
  227. package/dist/core/extensions/builtin/background-task/notification.js.map +0 -1
  228. package/dist/core/extensions/builtin/background-task/output-tool.d.ts +0 -11
  229. package/dist/core/extensions/builtin/background-task/output-tool.d.ts.map +0 -1
  230. package/dist/core/extensions/builtin/background-task/output-tool.js +0 -127
  231. package/dist/core/extensions/builtin/background-task/output-tool.js.map +0 -1
  232. package/dist/core/extensions/builtin/background-task/spawner.d.ts +0 -8
  233. package/dist/core/extensions/builtin/background-task/spawner.d.ts.map +0 -1
  234. package/dist/core/extensions/builtin/background-task/spawner.js +0 -207
  235. package/dist/core/extensions/builtin/background-task/spawner.js.map +0 -1
  236. package/dist/core/extensions/builtin/background-task/task-tool.d.ts +0 -20
  237. package/dist/core/extensions/builtin/background-task/task-tool.d.ts.map +0 -1
  238. package/dist/core/extensions/builtin/background-task/task-tool.js +0 -302
  239. package/dist/core/extensions/builtin/background-task/task-tool.js.map +0 -1
  240. package/dist/core/extensions/builtin/background-task/types.d.ts +0 -72
  241. package/dist/core/extensions/builtin/background-task/types.d.ts.map +0 -1
  242. package/dist/core/extensions/builtin/background-task/types.js +0 -32
  243. package/dist/core/extensions/builtin/background-task/types.js.map +0 -1
  244. package/dist/core/extensions/builtin/google-code-execution/index.d.ts +0 -7
  245. package/dist/core/extensions/builtin/google-code-execution/index.d.ts.map +0 -1
  246. package/dist/core/extensions/builtin/google-code-execution/index.js +0 -73
  247. package/dist/core/extensions/builtin/google-code-execution/index.js.map +0 -1
  248. package/dist/core/extensions/builtin/google-google-search/index.d.ts +0 -7
  249. package/dist/core/extensions/builtin/google-google-search/index.d.ts.map +0 -1
  250. package/dist/core/extensions/builtin/google-google-search/index.js +0 -83
  251. package/dist/core/extensions/builtin/google-google-search/index.js.map +0 -1
  252. package/dist/core/extensions/builtin/google-url-context/index.d.ts +0 -7
  253. package/dist/core/extensions/builtin/google-url-context/index.d.ts.map +0 -1
  254. package/dist/core/extensions/builtin/google-url-context/index.js +0 -82
  255. package/dist/core/extensions/builtin/google-url-context/index.js.map +0 -1
  256. package/dist/core/extensions/builtin/openai-api-parallel-tool-calls/index.d.ts +0 -6
  257. package/dist/core/extensions/builtin/openai-api-parallel-tool-calls/index.d.ts.map +0 -1
  258. package/dist/core/extensions/builtin/openai-api-parallel-tool-calls/index.js +0 -57
  259. package/dist/core/extensions/builtin/openai-api-parallel-tool-calls/index.js.map +0 -1
  260. package/dist/core/extensions/builtin/openai-code-interpreter/index.d.ts +0 -10
  261. package/dist/core/extensions/builtin/openai-code-interpreter/index.d.ts.map +0 -1
  262. package/dist/core/extensions/builtin/openai-code-interpreter/index.js +0 -95
  263. package/dist/core/extensions/builtin/openai-code-interpreter/index.js.map +0 -1
  264. package/docs/agents.md +0 -348
  265. package/examples/extensions/subagent/README.md +0 -172
  266. package/examples/extensions/subagent/agents/planner.md +0 -37
  267. package/examples/extensions/subagent/agents/reviewer.md +0 -35
  268. package/examples/extensions/subagent/agents/scout.md +0 -50
  269. package/examples/extensions/subagent/agents/worker.md +0 -24
  270. package/examples/extensions/subagent/agents.ts +0 -126
  271. package/examples/extensions/subagent/index.ts +0 -987
  272. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  273. package/examples/extensions/subagent/prompts/implement.md +0 -10
  274. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
@@ -1,12 +1,13 @@
1
- import { repairOrphanedToolResults } from "@earendil-works/pi-ai";
1
+ import { randomUUID } from "node:crypto";
2
2
  import { DEFAULT_COMPACTION_SETTINGS } from "../../../compaction/index.js";
3
3
  import { convertToLlm } from "../../../messages.js";
4
4
  import * as checkpointState from "./checkpoint-state.js";
5
5
  import * as breaker from "./circuit-breaker.js";
6
6
  import { createDegradationMonitorState, handleMessageEnd, handleTurnEnd, RECOVERY_INSTRUCTIONS, resetOnSessionCompact, } from "./degradation-monitor.js";
7
- import * as overflow from "./overflow-detection.js";
7
+ import { rewriteOpenAiPayloadWithRemoteCompaction, runOpenAiRemoteCompaction, SENPI_COMPACTION_EVENT, } from "./openai-remote.js";
8
8
  import * as cap from "./per-turn-cap.js";
9
9
  import * as policy from "./policy.js";
10
+ import { repairOrphanedToolResults } from "./repair-tool-pairs.js";
10
11
  import * as restoration from "./restoration-tracker.js";
11
12
  import { applyGeneratedCompaction, createSpeculativeCompactionSnapshot, getPromptVariant, hardLimitEmergencyPrune, runExtensionCompaction, } from "./speculative.js";
12
13
  import { createInitialState, resetTurnCounter } from "./state.js";
@@ -15,9 +16,27 @@ import * as truncation from "./tool-truncation.js";
15
16
  const DEFAULT_CONTEXT_WINDOW = 200_000;
16
17
  const EMERGENCY_COMPACTION_INSTRUCTIONS = "EMERGENCY: hard context limit reached. Produce an aggressive recovery summary that preserves current goal, constraints, files touched, tool outcomes, and exact next steps. Prefer concise factual state over transcript detail.";
17
18
  const PROACTIVE_COMPACTION_INSTRUCTIONS = "Proactively compact before the next agent turn.";
19
+ const MAX_PENDING_METADATA = 8;
20
+ const IMAGE_PROMPT_TOKEN_ESTIMATE = 1_200;
18
21
  function approxTokens(text) {
19
22
  return Math.ceil(text.length / 4);
20
23
  }
24
+ function isOpenAiResponsesModel(model) {
25
+ return model?.provider === "openai" && model.api === "openai-responses";
26
+ }
27
+ function estimatePendingPromptTokens(event) {
28
+ return approxTokens(event.prompt ?? "") + (event.images?.length ?? 0) * IMAGE_PROMPT_TOKEN_ESTIMATE;
29
+ }
30
+ function withAdditionalTokens(usage, additionalTokens) {
31
+ if (usage.tokens === null || additionalTokens <= 0)
32
+ return usage;
33
+ const tokens = usage.tokens + additionalTokens;
34
+ return {
35
+ ...usage,
36
+ tokens,
37
+ percent: usage.contextWindow > 0 ? (tokens / usage.contextWindow) * 100 : usage.percent,
38
+ };
39
+ }
21
40
  function isMonitorableMessageEvent(event) {
22
41
  return "content" in event.message && Array.isArray(event.message.content);
23
42
  }
@@ -31,6 +50,37 @@ function recentCheckpoint(ctx) {
31
50
  return null;
32
51
  return Date.now() - checkpoint.timestamp <= 60_000 ? checkpoint : null;
33
52
  }
53
+ function shouldEndFeedback(result) {
54
+ return !result.applied && result.reason !== "rejected";
55
+ }
56
+ function endCompactionFeedback(ctx, signal, result) {
57
+ if (shouldEndFeedback(result)) {
58
+ ctx.endCompaction?.({ reason: "extension", aborted: signal?.aborted });
59
+ }
60
+ }
61
+ function linkAbortSignal(source, target) {
62
+ if (!source)
63
+ return () => { };
64
+ if (source.aborted) {
65
+ target.abort();
66
+ return () => { };
67
+ }
68
+ const abort = () => target.abort();
69
+ source.addEventListener("abort", abort, { once: true });
70
+ return () => source.removeEventListener("abort", abort);
71
+ }
72
+ function createBlockingRemoteCompactionEvent(ctx, snapshot, customInstructions, signal) {
73
+ return {
74
+ type: "session_before_compact",
75
+ reason: "extension",
76
+ willRetry: false,
77
+ requestId: randomUUID(),
78
+ preparation: snapshot.preparation,
79
+ branchEntries: ctx.sessionManager.getBranch(),
80
+ customInstructions,
81
+ signal,
82
+ };
83
+ }
34
84
  export default function compactionExtension(pi) {
35
85
  let state = createInitialState();
36
86
  const degradationState = createDegradationMonitorState();
@@ -38,6 +88,7 @@ export default function compactionExtension(pi) {
38
88
  state = { ...state, restoration: restorationState };
39
89
  let speculativeGeneration = 0;
40
90
  let speculativeJob;
91
+ const pendingMetadata = new Map();
41
92
  function invalidateSpeculativeCompaction() {
42
93
  speculativeGeneration++;
43
94
  speculativeJob?.controller.abort();
@@ -54,23 +105,95 @@ export default function compactionExtension(pi) {
54
105
  const promise = runExtensionCompaction(ctx, snapshot, controller.signal).catch(() => undefined);
55
106
  speculativeJob = { generation, snapshot, controller, promise };
56
107
  }
108
+ function capturePendingMetadata(requestId, ctx) {
109
+ pendingMetadata.set(requestId, {
110
+ checkpoint: checkpointState.captureAgentCheckpoint(pi, ctx),
111
+ todoSnapshot: todoBridge.createTodoSnapshot(ctx),
112
+ });
113
+ while (pendingMetadata.size > MAX_PENDING_METADATA) {
114
+ const oldestRequestId = pendingMetadata.keys().next().value;
115
+ if (oldestRequestId === undefined)
116
+ break;
117
+ pendingMetadata.delete(oldestRequestId);
118
+ }
119
+ }
120
+ function persistAcceptedMetadata(requestId) {
121
+ const metadata = pendingMetadata.get(requestId);
122
+ if (!metadata)
123
+ return;
124
+ pendingMetadata.delete(requestId);
125
+ checkpointState.persistCheckpoint(pi, metadata.checkpoint);
126
+ todoBridge.persistTodoSnapshot(pi, metadata.todoSnapshot);
127
+ }
57
128
  async function applyBlockingCompaction(ctx, customInstructions) {
58
- const pendingJob = speculativeJob;
59
- if (pendingJob) {
60
- const compaction = await pendingJob.promise;
61
- const result = await applyGeneratedCompaction(ctx, pendingJob.snapshot, () => speculativeGeneration, compaction);
62
- if (result.applied || result.reason === "stale") {
129
+ let feedbackSignal = ctx.beginCompaction?.({ reason: "extension" });
130
+ try {
131
+ if (isOpenAiResponsesModel(ctx.model)) {
132
+ const remoteGeneration = speculativeGeneration + 1;
133
+ const remoteSnapshot = createSpeculativeCompactionSnapshot(ctx, {
134
+ generation: remoteGeneration,
135
+ customInstructions,
136
+ });
137
+ if (remoteSnapshot) {
138
+ const remoteSignal = feedbackSignal ?? new AbortController().signal;
139
+ const remoteCompaction = await runOpenAiRemoteCompaction(ctx, createBlockingRemoteCompactionEvent(ctx, remoteSnapshot, customInstructions, remoteSignal), (data) => pi.events.emit(SENPI_COMPACTION_EVENT, data));
140
+ if (remoteCompaction) {
141
+ if (speculativeGeneration !== remoteGeneration - 1) {
142
+ const result = { applied: false, reason: "stale" };
143
+ endCompactionFeedback(ctx, feedbackSignal, result);
144
+ return result;
145
+ }
146
+ speculativeGeneration = remoteGeneration;
147
+ speculativeJob?.controller.abort();
148
+ speculativeJob = undefined;
149
+ const result = await applyGeneratedCompaction(ctx, remoteSnapshot, () => speculativeGeneration, remoteCompaction);
150
+ endCompactionFeedback(ctx, feedbackSignal, result);
151
+ return result;
152
+ }
153
+ }
154
+ }
155
+ const pendingJob = speculativeJob;
156
+ if (pendingJob) {
157
+ const unlinkAbort = linkAbortSignal(feedbackSignal, pendingJob.controller);
158
+ let compaction;
159
+ try {
160
+ compaction = await pendingJob.promise;
161
+ }
162
+ finally {
163
+ unlinkAbort();
164
+ }
165
+ const result = await applyGeneratedCompaction(ctx, pendingJob.snapshot, () => speculativeGeneration, compaction);
166
+ if (result.applied || result.reason === "stale") {
167
+ speculativeJob = undefined;
168
+ endCompactionFeedback(ctx, feedbackSignal, result);
169
+ return result;
170
+ }
171
+ if (result.reason === "rejected") {
172
+ feedbackSignal = ctx.beginCompaction?.({ reason: "extension" });
173
+ }
63
174
  speculativeJob = undefined;
175
+ }
176
+ const generation = ++speculativeGeneration;
177
+ const snapshot = createSpeculativeCompactionSnapshot(ctx, { generation, customInstructions });
178
+ if (!snapshot) {
179
+ const result = { applied: false, reason: "unavailable" };
180
+ endCompactionFeedback(ctx, feedbackSignal, result);
64
181
  return result;
65
182
  }
66
- speculativeJob = undefined;
183
+ const compaction = await runExtensionCompaction(ctx, snapshot, feedbackSignal, (delta) => ctx.updateCompaction?.({ reason: "extension", delta }));
184
+ const result = await applyGeneratedCompaction(ctx, snapshot, () => speculativeGeneration, compaction);
185
+ endCompactionFeedback(ctx, feedbackSignal, result);
186
+ return result;
187
+ }
188
+ catch (error) {
189
+ const message = error instanceof Error ? error.message : String(error);
190
+ ctx.endCompaction?.({
191
+ reason: "extension",
192
+ aborted: feedbackSignal?.aborted,
193
+ errorMessage: `Compaction failed: ${message}`,
194
+ });
195
+ throw error;
67
196
  }
68
- const generation = ++speculativeGeneration;
69
- const snapshot = createSpeculativeCompactionSnapshot(ctx, { generation, customInstructions });
70
- if (!snapshot)
71
- return { applied: false, reason: "unavailable" };
72
- const compaction = await runExtensionCompaction(ctx, snapshot);
73
- return await applyGeneratedCompaction(ctx, snapshot, () => speculativeGeneration, compaction);
74
197
  }
75
198
  pi.on("session_before_compact", async (event, ctx) => {
76
199
  invalidateSpeculativeCompaction();
@@ -78,11 +201,14 @@ export default function compactionExtension(pi) {
78
201
  return { cancel: true };
79
202
  if (breaker.isTripped(state, Date.now()) && !breaker.shouldBypass(state, { reason: event.reason }))
80
203
  return { cancel: true };
81
- checkpointState.persistCheckpoint(pi, checkpointState.captureAgentCheckpoint(pi, ctx));
82
- todoBridge.captureTodoSnapshot(pi, ctx);
204
+ capturePendingMetadata(event.requestId, ctx);
83
205
  const model = ctx.model;
84
206
  if (!model)
85
207
  return undefined;
208
+ const remoteCompaction = await runOpenAiRemoteCompaction(ctx, event, (data) => pi.events.emit(SENPI_COMPACTION_EVENT, data));
209
+ if (remoteCompaction) {
210
+ return { compaction: remoteCompaction };
211
+ }
86
212
  const snapshot = {
87
213
  generation: ++speculativeGeneration,
88
214
  expectedRevision: ctx.getMessageRevision(),
@@ -92,9 +218,11 @@ export default function compactionExtension(pi) {
92
218
  promptVariant: getPromptVariant(event),
93
219
  customInstructions: event.customInstructions,
94
220
  };
95
- const compaction = await runExtensionCompaction(ctx, snapshot, event.signal);
96
- if (!compaction)
221
+ const compaction = await runExtensionCompaction(ctx, snapshot, event.signal, (delta) => ctx.updateCompaction?.({ reason: event.reason, delta }));
222
+ if (!compaction) {
223
+ pendingMetadata.delete(event.requestId);
97
224
  return { cancel: true };
225
+ }
98
226
  return {
99
227
  compaction,
100
228
  };
@@ -102,6 +230,7 @@ export default function compactionExtension(pi) {
102
230
  pi.on("session_compact", async (event, ctx) => {
103
231
  invalidateSpeculativeCompaction();
104
232
  if (event.accepted) {
233
+ persistAcceptedMetadata(event.requestId);
105
234
  const branchEntries = ctx.sessionManager.getBranch();
106
235
  const firstKeptIndex = branchEntries.findIndex((entry) => entry.id === event.compactionEntry.firstKeptEntryId);
107
236
  const keptEntries = firstKeptIndex === -1 ? [] : branchEntries.slice(firstKeptIndex);
@@ -141,15 +270,17 @@ export default function compactionExtension(pi) {
141
270
  const usage = ctx.getContextUsage();
142
271
  const contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;
143
272
  const settings = ctx.getCompactionSettings();
144
- if (usage && policy.isAtHardLimit(usage, contextWindow, settings.reserveTokens)) {
273
+ const pendingPromptTokens = estimatePendingPromptTokens(event);
274
+ const usageWithPendingPrompt = usage ? withAdditionalTokens(usage, pendingPromptTokens) : undefined;
275
+ if (usage && policy.isAtHardLimit(usage, contextWindow, settings.reserveTokens, pendingPromptTokens)) {
145
276
  await applyBlockingCompaction(ctx, EMERGENCY_COMPACTION_INSTRUCTIONS);
146
277
  }
147
- else if (usage &&
148
- policy.shouldTriggerCompaction(usage, contextWindow, settings, state.lastYield ?? undefined)) {
278
+ else if (usageWithPendingPrompt &&
279
+ policy.shouldTriggerCompaction(usageWithPendingPrompt, contextWindow, settings, state.lastYield ?? undefined)) {
149
280
  await applyBlockingCompaction(ctx, PROACTIVE_COMPACTION_INSTRUCTIONS);
150
281
  }
151
- else if (usage &&
152
- policy.shouldStartSpeculativeCompaction(usage, contextWindow, settings, state.lastYield ?? undefined)) {
282
+ else if (usageWithPendingPrompt &&
283
+ policy.shouldStartSpeculativeCompaction(usageWithPendingPrompt, contextWindow, settings, state.lastYield ?? undefined)) {
153
284
  startSpeculativeCompaction(ctx, PROACTIVE_COMPACTION_INSTRUCTIONS);
154
285
  }
155
286
  if (systemPrompt === event.systemPrompt && !message)
@@ -161,6 +292,9 @@ export default function compactionExtension(pi) {
161
292
  const emergency = hardLimitEmergencyPrune(event.messages, contextWindow);
162
293
  return { messages: repairOrphanedToolResults(convertToLlm(emergency.messages)) };
163
294
  });
295
+ pi.on("before_provider_request", (event, ctx) => {
296
+ return rewriteOpenAiPayloadWithRemoteCompaction(event.payload, { model: ctx.model, branchEntries: ctx.sessionManager.getBranch() }, (data) => pi.events.emit(SENPI_COMPACTION_EVENT, data));
297
+ });
164
298
  pi.on("turn_end", async (_event, ctx) => {
165
299
  handleTurnEnd(degradationState);
166
300
  if (degradationState.recoveryTriggeredThisCycle)
@@ -181,12 +315,6 @@ export default function compactionExtension(pi) {
181
315
  notify: (message) => ctx.ui.notify(message, "warning"),
182
316
  });
183
317
  }
184
- if (event.message.role === "assistant" && event.message.stopReason === "error") {
185
- const detected = overflow.isContextOverflowError(new Error(event.message.errorMessage ?? ""));
186
- if (detected.detected) {
187
- void applyBlockingCompaction(ctx, `RECOVERY: context overflow detected (${detected.confidence})`);
188
- }
189
- }
190
318
  });
191
319
  pi.on("tool_result", (event) => {
192
320
  const [truncated] = truncation.truncateOversizedToolResults([{ content: event.content, details: event.details }]);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport { repairOrphanedToolResults } from \"@earendil-works/pi-ai\";\nimport { type CompactionResult, DEFAULT_COMPACTION_SETTINGS } from \"../../../compaction/index.js\";\nimport { convertToLlm } from \"../../../messages.js\";\nimport type { CompactionEntry } from \"../../../session-manager.js\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.js\";\nimport * as checkpointState from \"./checkpoint-state.js\";\nimport * as breaker from \"./circuit-breaker.js\";\nimport {\n\tcreateDegradationMonitorState,\n\thandleMessageEnd,\n\thandleTurnEnd,\n\tRECOVERY_INSTRUCTIONS,\n\tresetOnSessionCompact,\n} from \"./degradation-monitor.js\";\nimport * as overflow from \"./overflow-detection.js\";\nimport * as cap from \"./per-turn-cap.js\";\nimport * as policy from \"./policy.js\";\nimport * as restoration from \"./restoration-tracker.js\";\nimport {\n\tapplyGeneratedCompaction,\n\tcreateSpeculativeCompactionSnapshot,\n\tgetPromptVariant,\n\thardLimitEmergencyPrune,\n\trunExtensionCompaction,\n\ttype SpeculativeCompactionResult,\n\ttype SpeculativeCompactionSnapshot,\n} from \"./speculative.js\";\nimport { type CompactionExtensionState, createInitialState, resetTurnCounter } from \"./state.js\";\nimport * as todoBridge from \"./todo-bridge.js\";\nimport * as truncation from \"./tool-truncation.js\";\n\nconst DEFAULT_CONTEXT_WINDOW = 200_000;\nconst EMERGENCY_COMPACTION_INSTRUCTIONS =\n\t\"EMERGENCY: hard context limit reached. Produce an aggressive recovery summary that preserves current goal, constraints, files touched, tool outcomes, and exact next steps. Prefer concise factual state over transcript detail.\";\nconst PROACTIVE_COMPACTION_INSTRUCTIONS = \"Proactively compact before the next agent turn.\";\n\nfunction approxTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\nfunction isMonitorableMessageEvent(event: { message: AgentMessage }): event is {\n\tmessage: AgentMessage & { content: Array<{ type: string; text?: string }> };\n} {\n\treturn \"content\" in event.message && Array.isArray(event.message.content);\n}\n\nfunction updateLastYield(state: CompactionExtensionState, entry: CompactionEntry): CompactionExtensionState {\n\tconst savedTokens = Math.max(0, entry.tokensBefore - approxTokens(entry.summary));\n\treturn { ...state, lastYield: { savedTokens, tokensBefore: entry.tokensBefore } };\n}\n\nfunction recentCheckpoint(ctx: ExtensionContext): checkpointState.AgentCheckpoint | null {\n\tconst checkpoint = checkpointState.getLatestCheckpoint(ctx);\n\tif (!checkpoint?.timestamp) return null;\n\treturn Date.now() - checkpoint.timestamp <= 60_000 ? checkpoint : null;\n}\n\nexport default function compactionExtension(pi: ExtensionAPI): void {\n\tlet state: CompactionExtensionState = createInitialState();\n\tconst degradationState = createDegradationMonitorState();\n\tconst restorationState = state.restoration ?? restoration.createRestorationTrackerState();\n\tstate = { ...state, restoration: restorationState };\n\tlet speculativeGeneration = 0;\n\tlet speculativeJob:\n\t\t| {\n\t\t\t\tgeneration: number;\n\t\t\t\tsnapshot: SpeculativeCompactionSnapshot;\n\t\t\t\tcontroller: AbortController;\n\t\t\t\tpromise: Promise<CompactionResult | undefined>;\n\t\t }\n\t\t| undefined;\n\n\tfunction invalidateSpeculativeCompaction(): void {\n\t\tspeculativeGeneration++;\n\t\tspeculativeJob?.controller.abort();\n\t\tspeculativeJob = undefined;\n\t}\n\n\tfunction startSpeculativeCompaction(ctx: ExtensionContext, customInstructions: string): void {\n\t\tif (speculativeJob) return;\n\t\tconst generation = ++speculativeGeneration;\n\t\tconst snapshot = createSpeculativeCompactionSnapshot(ctx, { generation, customInstructions });\n\t\tif (!snapshot) return;\n\n\t\tconst controller = new AbortController();\n\t\tconst promise = runExtensionCompaction(ctx, snapshot, controller.signal).catch(() => undefined);\n\t\tspeculativeJob = { generation, snapshot, controller, promise };\n\t}\n\n\tasync function applyBlockingCompaction(\n\t\tctx: ExtensionContext,\n\t\tcustomInstructions: string,\n\t): Promise<SpeculativeCompactionResult> {\n\t\tconst pendingJob = speculativeJob;\n\t\tif (pendingJob) {\n\t\t\tconst compaction = await pendingJob.promise;\n\t\t\tconst result = await applyGeneratedCompaction(\n\t\t\t\tctx,\n\t\t\t\tpendingJob.snapshot,\n\t\t\t\t() => speculativeGeneration,\n\t\t\t\tcompaction,\n\t\t\t);\n\t\t\tif (result.applied || result.reason === \"stale\") {\n\t\t\t\tspeculativeJob = undefined;\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tspeculativeJob = undefined;\n\t\t}\n\n\t\tconst generation = ++speculativeGeneration;\n\t\tconst snapshot = createSpeculativeCompactionSnapshot(ctx, { generation, customInstructions });\n\t\tif (!snapshot) return { applied: false, reason: \"unavailable\" };\n\t\tconst compaction = await runExtensionCompaction(ctx, snapshot);\n\t\treturn await applyGeneratedCompaction(ctx, snapshot, () => speculativeGeneration, compaction);\n\t}\n\n\tpi.on(\"session_before_compact\", async (event, ctx) => {\n\t\tinvalidateSpeculativeCompaction();\n\t\tif (cap.shouldRejectByCap(state, { reason: event.reason }).cancel) return { cancel: true };\n\t\tif (breaker.isTripped(state, Date.now()) && !breaker.shouldBypass(state, { reason: event.reason }))\n\t\t\treturn { cancel: true };\n\n\t\tcheckpointState.persistCheckpoint(pi, checkpointState.captureAgentCheckpoint(pi, ctx));\n\t\ttodoBridge.captureTodoSnapshot(pi, ctx);\n\n\t\tconst model = ctx.model;\n\t\tif (!model) return undefined;\n\t\tconst snapshot = {\n\t\t\tgeneration: ++speculativeGeneration,\n\t\t\texpectedRevision: ctx.getMessageRevision(),\n\t\t\tmodel,\n\t\t\tcontextWindow: ctx.getContextUsage()?.contextWindow ?? model.contextWindow ?? DEFAULT_CONTEXT_WINDOW,\n\t\t\tpreparation: event.preparation,\n\t\t\tpromptVariant: getPromptVariant(event),\n\t\t\tcustomInstructions: event.customInstructions,\n\t\t};\n\t\tconst compaction = await runExtensionCompaction(ctx, snapshot, event.signal);\n\t\tif (!compaction) return { cancel: true };\n\n\t\treturn {\n\t\t\tcompaction,\n\t\t};\n\t});\n\n\tpi.on(\"session_compact\", async (event, ctx) => {\n\t\tinvalidateSpeculativeCompaction();\n\t\tif (event.accepted) {\n\t\t\tconst branchEntries = ctx.sessionManager.getBranch();\n\t\t\tconst firstKeptIndex = branchEntries.findIndex((entry) => entry.id === event.compactionEntry.firstKeptEntryId);\n\t\t\tconst keptEntries = firstKeptIndex === -1 ? [] : branchEntries.slice(firstKeptIndex);\n\t\t\tstate = cap.incrementAccepted(state);\n\t\t\tstate = breaker.recordSuccess(state);\n\t\t\tstate = updateLastYield(state, event.compactionEntry);\n\t\t\tresetOnSessionCompact(degradationState);\n\t\t\ttodoBridge.restoreTodosIfMissing(pi, ctx);\n\t\t\tconst usage = ctx.getContextUsage();\n\t\t\tif (DEFAULT_COMPACTION_SETTINGS.restorationEnabled) {\n\t\t\t\trestoration.preparePendingPayload(restorationState, {\n\t\t\t\t\taccepted: true,\n\t\t\t\t\treason: event.reason,\n\t\t\t\t\tcompactionEntryId: event.compactionEntry.id,\n\t\t\t\t\tcontextWindow: usage?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW,\n\t\t\t\t\tusageTokens: usage?.tokens ?? null,\n\t\t\t\t\treserveTokens: DEFAULT_COMPACTION_SETTINGS.reserveTokens,\n\t\t\t\t\tsettings: DEFAULT_COMPACTION_SETTINGS,\n\t\t\t\t\tkeptMessages: keptEntries.flatMap((entry) => {\n\t\t\t\t\t\tif (entry.type !== \"message\") return [];\n\t\t\t\t\t\treturn [entry.message];\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tstate = breaker.recordFailure(state, Date.now(), { route: event.reason });\n\t\tctx.ui.notify(`Compaction rejected: ${event.rejectionCause ?? \"unknown\"}`, \"warning\");\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tlet systemPrompt = event.systemPrompt;\n\t\tconst message = restoration.consumePendingPayload(restorationState);\n\t\tconst checkpoint = recentCheckpoint(ctx);\n\t\tif (checkpoint) systemPrompt = checkpointState.injectRestorationDirective(systemPrompt, checkpoint);\n\n\t\tconst usage = ctx.getContextUsage();\n\t\tconst contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\t\tconst settings = ctx.getCompactionSettings();\n\t\tif (usage && policy.isAtHardLimit(usage, contextWindow, settings.reserveTokens)) {\n\t\t\tawait applyBlockingCompaction(ctx, EMERGENCY_COMPACTION_INSTRUCTIONS);\n\t\t} else if (\n\t\t\tusage &&\n\t\t\tpolicy.shouldTriggerCompaction(usage, contextWindow, settings, state.lastYield ?? undefined)\n\t\t) {\n\t\t\tawait applyBlockingCompaction(ctx, PROACTIVE_COMPACTION_INSTRUCTIONS);\n\t\t} else if (\n\t\t\tusage &&\n\t\t\tpolicy.shouldStartSpeculativeCompaction(usage, contextWindow, settings, state.lastYield ?? undefined)\n\t\t) {\n\t\t\tstartSpeculativeCompaction(ctx, PROACTIVE_COMPACTION_INSTRUCTIONS);\n\t\t}\n\n\t\tif (systemPrompt === event.systemPrompt && !message) return undefined;\n\t\treturn message ? { systemPrompt, message } : { systemPrompt };\n\t});\n\n\tpi.on(\"context\", (event, ctx) => {\n\t\tconst contextWindow = ctx.getContextUsage()?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\t\tconst emergency = hardLimitEmergencyPrune(event.messages, contextWindow);\n\t\treturn { messages: repairOrphanedToolResults(convertToLlm(emergency.messages)) };\n\t});\n\n\tpi.on(\"turn_end\", async (_event, ctx) => {\n\t\thandleTurnEnd(degradationState);\n\t\tif (degradationState.recoveryTriggeredThisCycle) return;\n\t\tif (state.lastYield && state.lastYield.savedTokens <= 0) {\n\t\t\tvoid applyBlockingCompaction(ctx, RECOVERY_INSTRUCTIONS);\n\t\t}\n\t});\n\n\tpi.on(\"agent_end\", () => {\n\t\tstate = resetTurnCounter(state, \"\");\n\t});\n\n\tpi.on(\"message_end\", async (event, ctx) => {\n\t\tif (isMonitorableMessageEvent(event)) {\n\t\t\tawait handleMessageEnd(degradationState, event, {\n\t\t\t\tapplyCompaction: async (options) => {\n\t\t\t\t\treturn await applyBlockingCompaction(ctx, options.customInstructions);\n\t\t\t\t},\n\t\t\t\tnotify: (message) => ctx.ui.notify(message, \"warning\"),\n\t\t\t});\n\t\t}\n\t\tif (event.message.role === \"assistant\" && event.message.stopReason === \"error\") {\n\t\t\tconst detected = overflow.isContextOverflowError(new Error(event.message.errorMessage ?? \"\"));\n\t\t\tif (detected.detected) {\n\t\t\t\tvoid applyBlockingCompaction(ctx, `RECOVERY: context overflow detected (${detected.confidence})`);\n\t\t\t}\n\t\t}\n\t});\n\n\tpi.on(\"tool_result\", (event) => {\n\t\tconst [truncated] = truncation.truncateOversizedToolResults([{ content: event.content, details: event.details }]);\n\t\treturn truncated ? { content: truncated.content, details: event.details, isError: event.isError } : undefined;\n\t});\n\n\tpi.on(\"tool_call\", (event) => {\n\t\trestoration.trackToolCall(restorationState, event);\n\t});\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport { type CompactionResult, DEFAULT_COMPACTION_SETTINGS } from \"../../../compaction/index.js\";\nimport { convertToLlm } from \"../../../messages.js\";\nimport type { CompactionEntry } from \"../../../session-manager.js\";\nimport type { ContextUsage, ExtensionAPI, ExtensionContext, SessionBeforeCompactEvent } from \"../../types.js\";\nimport * as checkpointState from \"./checkpoint-state.js\";\nimport * as breaker from \"./circuit-breaker.js\";\nimport {\n\tcreateDegradationMonitorState,\n\thandleMessageEnd,\n\thandleTurnEnd,\n\tRECOVERY_INSTRUCTIONS,\n\tresetOnSessionCompact,\n} from \"./degradation-monitor.js\";\nimport {\n\trewriteOpenAiPayloadWithRemoteCompaction,\n\trunOpenAiRemoteCompaction,\n\tSENPI_COMPACTION_EVENT,\n} from \"./openai-remote.js\";\nimport * as cap from \"./per-turn-cap.js\";\nimport * as policy from \"./policy.js\";\nimport { repairOrphanedToolResults } from \"./repair-tool-pairs.js\";\nimport * as restoration from \"./restoration-tracker.js\";\nimport {\n\tapplyGeneratedCompaction,\n\tcreateSpeculativeCompactionSnapshot,\n\tgetPromptVariant,\n\thardLimitEmergencyPrune,\n\trunExtensionCompaction,\n\ttype SpeculativeCompactionResult,\n\ttype SpeculativeCompactionSnapshot,\n} from \"./speculative.js\";\nimport { type CompactionExtensionState, createInitialState, resetTurnCounter } from \"./state.js\";\nimport * as todoBridge from \"./todo-bridge.js\";\nimport * as truncation from \"./tool-truncation.js\";\n\nconst DEFAULT_CONTEXT_WINDOW = 200_000;\nconst EMERGENCY_COMPACTION_INSTRUCTIONS =\n\t\"EMERGENCY: hard context limit reached. Produce an aggressive recovery summary that preserves current goal, constraints, files touched, tool outcomes, and exact next steps. Prefer concise factual state over transcript detail.\";\nconst PROACTIVE_COMPACTION_INSTRUCTIONS = \"Proactively compact before the next agent turn.\";\nconst MAX_PENDING_METADATA = 8;\nconst IMAGE_PROMPT_TOKEN_ESTIMATE = 1_200;\n\ninterface PendingCompactionMetadata {\n\tcheckpoint: checkpointState.AgentCheckpoint;\n\ttodoSnapshot: todoBridge.TodoSnapshotPayload;\n}\n\nfunction approxTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\nfunction isOpenAiResponsesModel(model: ExtensionContext[\"model\"]): boolean {\n\treturn model?.provider === \"openai\" && model.api === \"openai-responses\";\n}\n\nfunction estimatePendingPromptTokens(event: { prompt?: string; images?: readonly unknown[] }): number {\n\treturn approxTokens(event.prompt ?? \"\") + (event.images?.length ?? 0) * IMAGE_PROMPT_TOKEN_ESTIMATE;\n}\n\nfunction withAdditionalTokens(usage: ContextUsage, additionalTokens: number): ContextUsage {\n\tif (usage.tokens === null || additionalTokens <= 0) return usage;\n\tconst tokens = usage.tokens + additionalTokens;\n\treturn {\n\t\t...usage,\n\t\ttokens,\n\t\tpercent: usage.contextWindow > 0 ? (tokens / usage.contextWindow) * 100 : usage.percent,\n\t};\n}\n\nfunction isMonitorableMessageEvent(event: { message: AgentMessage }): event is {\n\tmessage: AgentMessage & { content: Array<{ type: string; text?: string }> };\n} {\n\treturn \"content\" in event.message && Array.isArray(event.message.content);\n}\n\nfunction updateLastYield(state: CompactionExtensionState, entry: CompactionEntry): CompactionExtensionState {\n\tconst savedTokens = Math.max(0, entry.tokensBefore - approxTokens(entry.summary));\n\treturn { ...state, lastYield: { savedTokens, tokensBefore: entry.tokensBefore } };\n}\n\nfunction recentCheckpoint(ctx: ExtensionContext): checkpointState.AgentCheckpoint | null {\n\tconst checkpoint = checkpointState.getLatestCheckpoint(ctx);\n\tif (!checkpoint?.timestamp) return null;\n\treturn Date.now() - checkpoint.timestamp <= 60_000 ? checkpoint : null;\n}\n\nfunction shouldEndFeedback(result: SpeculativeCompactionResult): boolean {\n\treturn !result.applied && result.reason !== \"rejected\";\n}\n\nfunction endCompactionFeedback(\n\tctx: ExtensionContext,\n\tsignal: AbortSignal | undefined,\n\tresult: SpeculativeCompactionResult,\n): void {\n\tif (shouldEndFeedback(result)) {\n\t\tctx.endCompaction?.({ reason: \"extension\", aborted: signal?.aborted });\n\t}\n}\n\nfunction linkAbortSignal(source: AbortSignal | undefined, target: AbortController): () => void {\n\tif (!source) return () => {};\n\tif (source.aborted) {\n\t\ttarget.abort();\n\t\treturn () => {};\n\t}\n\tconst abort = () => target.abort();\n\tsource.addEventListener(\"abort\", abort, { once: true });\n\treturn () => source.removeEventListener(\"abort\", abort);\n}\n\nfunction createBlockingRemoteCompactionEvent(\n\tctx: ExtensionContext,\n\tsnapshot: SpeculativeCompactionSnapshot,\n\tcustomInstructions: string,\n\tsignal: AbortSignal,\n): SessionBeforeCompactEvent {\n\treturn {\n\t\ttype: \"session_before_compact\",\n\t\treason: \"extension\",\n\t\twillRetry: false,\n\t\trequestId: randomUUID(),\n\t\tpreparation: snapshot.preparation,\n\t\tbranchEntries: ctx.sessionManager.getBranch(),\n\t\tcustomInstructions,\n\t\tsignal,\n\t};\n}\n\nexport default function compactionExtension(pi: ExtensionAPI): void {\n\tlet state: CompactionExtensionState = createInitialState();\n\tconst degradationState = createDegradationMonitorState();\n\tconst restorationState = state.restoration ?? restoration.createRestorationTrackerState();\n\tstate = { ...state, restoration: restorationState };\n\tlet speculativeGeneration = 0;\n\tlet speculativeJob:\n\t\t| {\n\t\t\t\tgeneration: number;\n\t\t\t\tsnapshot: SpeculativeCompactionSnapshot;\n\t\t\t\tcontroller: AbortController;\n\t\t\t\tpromise: Promise<CompactionResult | undefined>;\n\t\t }\n\t\t| undefined;\n\tconst pendingMetadata = new Map<string, PendingCompactionMetadata>();\n\n\tfunction invalidateSpeculativeCompaction(): void {\n\t\tspeculativeGeneration++;\n\t\tspeculativeJob?.controller.abort();\n\t\tspeculativeJob = undefined;\n\t}\n\n\tfunction startSpeculativeCompaction(ctx: ExtensionContext, customInstructions: string): void {\n\t\tif (speculativeJob) return;\n\t\tconst generation = ++speculativeGeneration;\n\t\tconst snapshot = createSpeculativeCompactionSnapshot(ctx, { generation, customInstructions });\n\t\tif (!snapshot) return;\n\n\t\tconst controller = new AbortController();\n\t\tconst promise = runExtensionCompaction(ctx, snapshot, controller.signal).catch(() => undefined);\n\t\tspeculativeJob = { generation, snapshot, controller, promise };\n\t}\n\n\tfunction capturePendingMetadata(requestId: string, ctx: ExtensionContext): void {\n\t\tpendingMetadata.set(requestId, {\n\t\t\tcheckpoint: checkpointState.captureAgentCheckpoint(pi, ctx),\n\t\t\ttodoSnapshot: todoBridge.createTodoSnapshot(ctx),\n\t\t});\n\t\twhile (pendingMetadata.size > MAX_PENDING_METADATA) {\n\t\t\tconst oldestRequestId = pendingMetadata.keys().next().value;\n\t\t\tif (oldestRequestId === undefined) break;\n\t\t\tpendingMetadata.delete(oldestRequestId);\n\t\t}\n\t}\n\n\tfunction persistAcceptedMetadata(requestId: string): void {\n\t\tconst metadata = pendingMetadata.get(requestId);\n\t\tif (!metadata) return;\n\t\tpendingMetadata.delete(requestId);\n\t\tcheckpointState.persistCheckpoint(pi, metadata.checkpoint);\n\t\ttodoBridge.persistTodoSnapshot(pi, metadata.todoSnapshot);\n\t}\n\n\tasync function applyBlockingCompaction(\n\t\tctx: ExtensionContext,\n\t\tcustomInstructions: string,\n\t): Promise<SpeculativeCompactionResult> {\n\t\tlet feedbackSignal = ctx.beginCompaction?.({ reason: \"extension\" });\n\t\ttry {\n\t\t\tif (isOpenAiResponsesModel(ctx.model)) {\n\t\t\t\tconst remoteGeneration = speculativeGeneration + 1;\n\t\t\t\tconst remoteSnapshot = createSpeculativeCompactionSnapshot(ctx, {\n\t\t\t\t\tgeneration: remoteGeneration,\n\t\t\t\t\tcustomInstructions,\n\t\t\t\t});\n\t\t\t\tif (remoteSnapshot) {\n\t\t\t\t\tconst remoteSignal = feedbackSignal ?? new AbortController().signal;\n\t\t\t\t\tconst remoteCompaction = await runOpenAiRemoteCompaction(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\tcreateBlockingRemoteCompactionEvent(ctx, remoteSnapshot, customInstructions, remoteSignal),\n\t\t\t\t\t\t(data) => pi.events.emit(SENPI_COMPACTION_EVENT, data),\n\t\t\t\t\t);\n\t\t\t\t\tif (remoteCompaction) {\n\t\t\t\t\t\tif (speculativeGeneration !== remoteGeneration - 1) {\n\t\t\t\t\t\t\tconst result = { applied: false, reason: \"stale\" } as const;\n\t\t\t\t\t\t\tendCompactionFeedback(ctx, feedbackSignal, result);\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tspeculativeGeneration = remoteGeneration;\n\t\t\t\t\t\tspeculativeJob?.controller.abort();\n\t\t\t\t\t\tspeculativeJob = undefined;\n\t\t\t\t\t\tconst result = await applyGeneratedCompaction(\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\tremoteSnapshot,\n\t\t\t\t\t\t\t() => speculativeGeneration,\n\t\t\t\t\t\t\tremoteCompaction,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tendCompactionFeedback(ctx, feedbackSignal, result);\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pendingJob = speculativeJob;\n\t\t\tif (pendingJob) {\n\t\t\t\tconst unlinkAbort = linkAbortSignal(feedbackSignal, pendingJob.controller);\n\t\t\t\tlet compaction: CompactionResult | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tcompaction = await pendingJob.promise;\n\t\t\t\t} finally {\n\t\t\t\t\tunlinkAbort();\n\t\t\t\t}\n\t\t\t\tconst result = await applyGeneratedCompaction(\n\t\t\t\t\tctx,\n\t\t\t\t\tpendingJob.snapshot,\n\t\t\t\t\t() => speculativeGeneration,\n\t\t\t\t\tcompaction,\n\t\t\t\t);\n\t\t\t\tif (result.applied || result.reason === \"stale\") {\n\t\t\t\t\tspeculativeJob = undefined;\n\t\t\t\t\tendCompactionFeedback(ctx, feedbackSignal, result);\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tif (result.reason === \"rejected\") {\n\t\t\t\t\tfeedbackSignal = ctx.beginCompaction?.({ reason: \"extension\" });\n\t\t\t\t}\n\t\t\t\tspeculativeJob = undefined;\n\t\t\t}\n\n\t\t\tconst generation = ++speculativeGeneration;\n\t\t\tconst snapshot = createSpeculativeCompactionSnapshot(ctx, { generation, customInstructions });\n\t\t\tif (!snapshot) {\n\t\t\t\tconst result = { applied: false, reason: \"unavailable\" } as const;\n\t\t\t\tendCompactionFeedback(ctx, feedbackSignal, result);\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tconst compaction = await runExtensionCompaction(ctx, snapshot, feedbackSignal, (delta) =>\n\t\t\t\tctx.updateCompaction?.({ reason: \"extension\", delta }),\n\t\t\t);\n\t\t\tconst result = await applyGeneratedCompaction(ctx, snapshot, () => speculativeGeneration, compaction);\n\t\t\tendCompactionFeedback(ctx, feedbackSignal, result);\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tctx.endCompaction?.({\n\t\t\t\treason: \"extension\",\n\t\t\t\taborted: feedbackSignal?.aborted,\n\t\t\t\terrorMessage: `Compaction failed: ${message}`,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpi.on(\"session_before_compact\", async (event, ctx) => {\n\t\tinvalidateSpeculativeCompaction();\n\t\tif (cap.shouldRejectByCap(state, { reason: event.reason }).cancel) return { cancel: true };\n\t\tif (breaker.isTripped(state, Date.now()) && !breaker.shouldBypass(state, { reason: event.reason }))\n\t\t\treturn { cancel: true };\n\n\t\tcapturePendingMetadata(event.requestId, ctx);\n\n\t\tconst model = ctx.model;\n\t\tif (!model) return undefined;\n\t\tconst remoteCompaction = await runOpenAiRemoteCompaction(ctx, event, (data) =>\n\t\t\tpi.events.emit(SENPI_COMPACTION_EVENT, data),\n\t\t);\n\t\tif (remoteCompaction) {\n\t\t\treturn { compaction: remoteCompaction };\n\t\t}\n\n\t\tconst snapshot = {\n\t\t\tgeneration: ++speculativeGeneration,\n\t\t\texpectedRevision: ctx.getMessageRevision(),\n\t\t\tmodel,\n\t\t\tcontextWindow: ctx.getContextUsage()?.contextWindow ?? model.contextWindow ?? DEFAULT_CONTEXT_WINDOW,\n\t\t\tpreparation: event.preparation,\n\t\t\tpromptVariant: getPromptVariant(event),\n\t\t\tcustomInstructions: event.customInstructions,\n\t\t};\n\t\tconst compaction = await runExtensionCompaction(ctx, snapshot, event.signal, (delta) =>\n\t\t\tctx.updateCompaction?.({ reason: event.reason, delta }),\n\t\t);\n\t\tif (!compaction) {\n\t\t\tpendingMetadata.delete(event.requestId);\n\t\t\treturn { cancel: true };\n\t\t}\n\n\t\treturn {\n\t\t\tcompaction,\n\t\t};\n\t});\n\n\tpi.on(\"session_compact\", async (event, ctx) => {\n\t\tinvalidateSpeculativeCompaction();\n\t\tif (event.accepted) {\n\t\t\tpersistAcceptedMetadata(event.requestId);\n\t\t\tconst branchEntries = ctx.sessionManager.getBranch();\n\t\t\tconst firstKeptIndex = branchEntries.findIndex((entry) => entry.id === event.compactionEntry.firstKeptEntryId);\n\t\t\tconst keptEntries = firstKeptIndex === -1 ? [] : branchEntries.slice(firstKeptIndex);\n\t\t\tstate = cap.incrementAccepted(state);\n\t\t\tstate = breaker.recordSuccess(state);\n\t\t\tstate = updateLastYield(state, event.compactionEntry);\n\t\t\tresetOnSessionCompact(degradationState);\n\t\t\ttodoBridge.restoreTodosIfMissing(pi, ctx);\n\t\t\tconst usage = ctx.getContextUsage();\n\t\t\tif (DEFAULT_COMPACTION_SETTINGS.restorationEnabled) {\n\t\t\t\trestoration.preparePendingPayload(restorationState, {\n\t\t\t\t\taccepted: true,\n\t\t\t\t\treason: event.reason,\n\t\t\t\t\tcompactionEntryId: event.compactionEntry.id,\n\t\t\t\t\tcontextWindow: usage?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW,\n\t\t\t\t\tusageTokens: usage?.tokens ?? null,\n\t\t\t\t\treserveTokens: DEFAULT_COMPACTION_SETTINGS.reserveTokens,\n\t\t\t\t\tsettings: DEFAULT_COMPACTION_SETTINGS,\n\t\t\t\t\tkeptMessages: keptEntries.flatMap((entry) => {\n\t\t\t\t\t\tif (entry.type !== \"message\") return [];\n\t\t\t\t\t\treturn [entry.message];\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tstate = breaker.recordFailure(state, Date.now(), { route: event.reason });\n\t\tctx.ui.notify(`Compaction rejected: ${event.rejectionCause ?? \"unknown\"}`, \"warning\");\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tlet systemPrompt = event.systemPrompt;\n\t\tconst message = restoration.consumePendingPayload(restorationState);\n\t\tconst checkpoint = recentCheckpoint(ctx);\n\t\tif (checkpoint) systemPrompt = checkpointState.injectRestorationDirective(systemPrompt, checkpoint);\n\n\t\tconst usage = ctx.getContextUsage();\n\t\tconst contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\t\tconst settings = ctx.getCompactionSettings();\n\t\tconst pendingPromptTokens = estimatePendingPromptTokens(event);\n\t\tconst usageWithPendingPrompt = usage ? withAdditionalTokens(usage, pendingPromptTokens) : undefined;\n\t\tif (usage && policy.isAtHardLimit(usage, contextWindow, settings.reserveTokens, pendingPromptTokens)) {\n\t\t\tawait applyBlockingCompaction(ctx, EMERGENCY_COMPACTION_INSTRUCTIONS);\n\t\t} else if (\n\t\t\tusageWithPendingPrompt &&\n\t\t\tpolicy.shouldTriggerCompaction(usageWithPendingPrompt, contextWindow, settings, state.lastYield ?? undefined)\n\t\t) {\n\t\t\tawait applyBlockingCompaction(ctx, PROACTIVE_COMPACTION_INSTRUCTIONS);\n\t\t} else if (\n\t\t\tusageWithPendingPrompt &&\n\t\t\tpolicy.shouldStartSpeculativeCompaction(\n\t\t\t\tusageWithPendingPrompt,\n\t\t\t\tcontextWindow,\n\t\t\t\tsettings,\n\t\t\t\tstate.lastYield ?? undefined,\n\t\t\t)\n\t\t) {\n\t\t\tstartSpeculativeCompaction(ctx, PROACTIVE_COMPACTION_INSTRUCTIONS);\n\t\t}\n\n\t\tif (systemPrompt === event.systemPrompt && !message) return undefined;\n\t\treturn message ? { systemPrompt, message } : { systemPrompt };\n\t});\n\n\tpi.on(\"context\", (event, ctx) => {\n\t\tconst contextWindow = ctx.getContextUsage()?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\t\tconst emergency = hardLimitEmergencyPrune(event.messages, contextWindow);\n\t\treturn { messages: repairOrphanedToolResults(convertToLlm(emergency.messages)) };\n\t});\n\n\tpi.on(\"before_provider_request\", (event, ctx) => {\n\t\treturn rewriteOpenAiPayloadWithRemoteCompaction(\n\t\t\tevent.payload,\n\t\t\t{ model: ctx.model, branchEntries: ctx.sessionManager.getBranch() },\n\t\t\t(data) => pi.events.emit(SENPI_COMPACTION_EVENT, data),\n\t\t);\n\t});\n\n\tpi.on(\"turn_end\", async (_event, ctx) => {\n\t\thandleTurnEnd(degradationState);\n\t\tif (degradationState.recoveryTriggeredThisCycle) return;\n\t\tif (state.lastYield && state.lastYield.savedTokens <= 0) {\n\t\t\tvoid applyBlockingCompaction(ctx, RECOVERY_INSTRUCTIONS);\n\t\t}\n\t});\n\n\tpi.on(\"agent_end\", () => {\n\t\tstate = resetTurnCounter(state, \"\");\n\t});\n\n\tpi.on(\"message_end\", async (event, ctx) => {\n\t\tif (isMonitorableMessageEvent(event)) {\n\t\t\tawait handleMessageEnd(degradationState, event, {\n\t\t\t\tapplyCompaction: async (options) => {\n\t\t\t\t\treturn await applyBlockingCompaction(ctx, options.customInstructions);\n\t\t\t\t},\n\t\t\t\tnotify: (message) => ctx.ui.notify(message, \"warning\"),\n\t\t\t});\n\t\t}\n\t});\n\n\tpi.on(\"tool_result\", (event) => {\n\t\tconst [truncated] = truncation.truncateOversizedToolResults([{ content: event.content, details: event.details }]);\n\t\treturn truncated ? { content: truncated.content, details: event.details, isError: event.isError } : undefined;\n\t});\n\n\tpi.on(\"tool_call\", (event) => {\n\t\trestoration.trackToolCall(restorationState, event);\n\t});\n}\n"]}
@@ -0,0 +1,197 @@
1
+ import { type Api, type AssistantMessage, type Context, type Model, type SimpleStreamOptions } from "@earendil-works/pi-ai";
2
+ import type { CompactionResult } from "../../../compaction/index.js";
3
+ import type { SessionEntry } from "../../../session-manager.js";
4
+ import type { ServiceTier, SessionBeforeCompactEvent } from "../../types.js";
5
+ export declare const OPENAI_REMOTE_COMPACTION_SCHEMA = "senpi.compaction.openai-remote.v1";
6
+ export declare const SENPI_COMPACTION_EVENT = "senpi:compaction";
7
+ type OpenAiInputText = {
8
+ type: "input_text";
9
+ text: string;
10
+ };
11
+ type OpenAiInputImage = {
12
+ type: "input_image";
13
+ detail: "auto";
14
+ image_url: string;
15
+ };
16
+ type OpenAiInputContent = OpenAiInputText | OpenAiInputImage;
17
+ type OpenAiOutputText = {
18
+ type: "output_text";
19
+ text: string;
20
+ annotations: [];
21
+ };
22
+ type OpenAiMessageInputItem = {
23
+ type?: "message";
24
+ id?: string;
25
+ role: "user" | "system" | "developer";
26
+ content: string | OpenAiInputContent[];
27
+ status?: "in_progress" | "completed" | "incomplete";
28
+ };
29
+ type OpenAiAssistantMessageItem = {
30
+ type: "message";
31
+ id: string;
32
+ role: "assistant";
33
+ status: "completed";
34
+ content: OpenAiOutputText[];
35
+ phase?: "commentary" | "final_answer";
36
+ };
37
+ type OpenAiFunctionCallItem = {
38
+ type: "function_call";
39
+ id?: string;
40
+ call_id: string;
41
+ name: string;
42
+ arguments: string;
43
+ };
44
+ type OpenAiFunctionCallOutputItem = {
45
+ type: "function_call_output";
46
+ call_id: string;
47
+ output: string;
48
+ };
49
+ type OpenAiRemoteTransport = "websocket" | "compact-endpoint";
50
+ type OpenAiCompactionItem = {
51
+ type: "compaction";
52
+ encrypted_content: string;
53
+ id?: string | null;
54
+ created_by?: string;
55
+ };
56
+ type OpenAiContextCompactionItem = {
57
+ type: "context_compaction";
58
+ encrypted_content: string;
59
+ id?: string | null;
60
+ created_by?: string;
61
+ };
62
+ type OpenAiProviderNativeItem = Record<string, unknown> & {
63
+ type: string;
64
+ };
65
+ export type OpenAiRemoteInputItem = OpenAiMessageInputItem | OpenAiAssistantMessageItem | OpenAiFunctionCallItem | OpenAiFunctionCallOutputItem | OpenAiCompactionItem | OpenAiContextCompactionItem | OpenAiProviderNativeItem;
66
+ type OpenAiCompactBody = {
67
+ model: string;
68
+ input: OpenAiRemoteInputItem[];
69
+ instructions?: string;
70
+ prompt_cache_key?: string;
71
+ service_tier?: ServiceTier;
72
+ };
73
+ export type OpenAiRemoteCompactionDetails = {
74
+ schema: typeof OPENAI_REMOTE_COMPACTION_SCHEMA;
75
+ mode: "openai-remote";
76
+ provider: "openai";
77
+ api: "openai-responses";
78
+ transport: OpenAiRemoteTransport;
79
+ modelId: string;
80
+ responseId: string;
81
+ createdAt: number;
82
+ requestInputItemCount: number;
83
+ retainedInputItemCount: number;
84
+ replacementInput: OpenAiRemoteInputItem[];
85
+ usage?: Record<string, unknown>;
86
+ };
87
+ export type OpenAiRemoteCompactionRequest = {
88
+ body: OpenAiCompactBody;
89
+ inputItemCount: number;
90
+ tokensBefore: number;
91
+ };
92
+ export type OpenAiRemoteCompactionResult = CompactionResult<OpenAiRemoteCompactionDetails> & {
93
+ details: OpenAiRemoteCompactionDetails;
94
+ };
95
+ type OpenAiCompactedResponse = {
96
+ id: string;
97
+ created_at: number;
98
+ object: "response.compaction";
99
+ output: OpenAiRemoteInputItem[];
100
+ usage?: Record<string, unknown>;
101
+ };
102
+ type OpenAiResponsesStream = {
103
+ result(): Promise<AssistantMessage>;
104
+ };
105
+ type OpenAiResponsesStreamRunner = (model: Model<"openai-responses">, context: Context, options: SimpleStreamOptions) => OpenAiResponsesStream;
106
+ type OpenAiRemoteCompactionDependencies = {
107
+ fetch?: typeof fetch;
108
+ now?: () => number;
109
+ streamRunner?: OpenAiResponsesStreamRunner;
110
+ };
111
+ type OpenAiRemoteCompactionContext = {
112
+ getSystemPrompt(): string;
113
+ model: Model<Api> | undefined;
114
+ modelRegistry: {
115
+ getApiKeyAndHeaders(model: Model<Api>): Promise<{
116
+ ok: true;
117
+ apiKey?: string;
118
+ headers?: Record<string, string>;
119
+ extraBody?: Record<string, unknown>;
120
+ upstreamModelId?: string;
121
+ serviceTier?: ServiceTier;
122
+ } | {
123
+ ok: false;
124
+ error: string;
125
+ }>;
126
+ };
127
+ serviceTier: ServiceTier | undefined;
128
+ sessionManager: {
129
+ getSessionId(): string;
130
+ };
131
+ };
132
+ type OpenAiRemoteCompactionEvent = {
133
+ version: 1;
134
+ action: "remote_started";
135
+ route: "builtin.compaction.openai_remote";
136
+ requestId: string;
137
+ modelId: string;
138
+ inputItemCount: number;
139
+ transport: OpenAiRemoteTransport;
140
+ } | {
141
+ version: 1;
142
+ action: "remote_completed";
143
+ route: "builtin.compaction.openai_remote";
144
+ requestId: string;
145
+ modelId: string;
146
+ responseId: string;
147
+ retainedInputItemCount: number;
148
+ transport: OpenAiRemoteTransport;
149
+ } | {
150
+ version: 1;
151
+ action: "remote_fallback";
152
+ route: "builtin.compaction.openai_remote";
153
+ requestId: string;
154
+ modelId?: string;
155
+ reason: string;
156
+ transport?: OpenAiRemoteTransport;
157
+ } | {
158
+ version: 1;
159
+ action: "remote_payload_rewritten";
160
+ route: "builtin.compaction.openai_remote";
161
+ modelId: string;
162
+ compactionEntryId: string;
163
+ inputItemCount: number;
164
+ };
165
+ type EmitCompactionEvent = (event: OpenAiRemoteCompactionEvent) => void;
166
+ export declare function getOpenAiRemoteCompactionDetails(value: unknown): OpenAiRemoteCompactionDetails | undefined;
167
+ export declare function createOpenAiRemoteCompactionRequest(options: {
168
+ model: Model<Api> | undefined;
169
+ systemPrompt: string;
170
+ branchEntries: SessionEntry[];
171
+ tokensBefore: number;
172
+ promptCacheKey?: string;
173
+ serviceTier?: ServiceTier;
174
+ }): OpenAiRemoteCompactionRequest | undefined;
175
+ export declare function buildOpenAiRemoteCompactionResult(options: {
176
+ model: Model<"openai-responses">;
177
+ firstKeptEntryId: string;
178
+ tokensBefore: number;
179
+ requestInputItemCount: number;
180
+ response: OpenAiCompactedResponse;
181
+ }): OpenAiRemoteCompactionResult;
182
+ export declare function createOpenAiResponsesStreamCompactionPayload(payload: unknown, request: OpenAiRemoteCompactionRequest): unknown | undefined;
183
+ export declare function buildOpenAiResponsesStreamCompactionResult(options: {
184
+ model: Model<"openai-responses">;
185
+ firstKeptEntryId: string;
186
+ tokensBefore: number;
187
+ requestInput: OpenAiRemoteInputItem[];
188
+ response: AssistantMessage;
189
+ now: () => number;
190
+ }): OpenAiRemoteCompactionResult;
191
+ export declare function runOpenAiRemoteCompaction(ctx: OpenAiRemoteCompactionContext, event: SessionBeforeCompactEvent, emit?: EmitCompactionEvent, dependencies?: OpenAiRemoteCompactionDependencies): Promise<OpenAiRemoteCompactionResult | undefined>;
192
+ export declare function rewriteOpenAiPayloadWithRemoteCompaction(payload: unknown, options: {
193
+ model: Model<Api> | undefined;
194
+ branchEntries: SessionEntry[];
195
+ }, emit?: EmitCompactionEvent): unknown | undefined;
196
+ export {};
197
+ //# sourceMappingURL=openai-remote.d.ts.map