@code-yeongyu/senpi 2026.5.14 → 2026.5.15-3

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 (175) hide show
  1. package/CHANGELOG.md +1110 -1175
  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 +109 -7
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/dynamic-prompt/verification.d.ts +31 -0
  8. package/dist/core/dynamic-prompt/verification.d.ts.map +1 -1
  9. package/dist/core/dynamic-prompt/verification.js +41 -0
  10. package/dist/core/dynamic-prompt/verification.js.map +1 -1
  11. package/dist/core/extensions/builtin/compaction/context-reduction.d.ts +97 -0
  12. package/dist/core/extensions/builtin/compaction/context-reduction.d.ts.map +1 -0
  13. package/dist/core/extensions/builtin/compaction/context-reduction.js +420 -0
  14. package/dist/core/extensions/builtin/compaction/context-reduction.js.map +1 -0
  15. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/compaction/index.js +168 -31
  17. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  18. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +197 -0
  19. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -0
  20. package/dist/core/extensions/builtin/compaction/openai-remote.js +690 -0
  21. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -0
  22. package/dist/core/extensions/builtin/compaction/prompts.d.ts +3 -3
  23. package/dist/core/extensions/builtin/compaction/prompts.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/compaction/prompts.js +0 -22
  25. package/dist/core/extensions/builtin/compaction/prompts.js.map +1 -1
  26. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts +4 -0
  27. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts.map +1 -0
  28. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js +48 -0
  29. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js.map +1 -0
  30. package/dist/core/extensions/builtin/compaction/speculative.d.ts +3 -1
  31. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/speculative.js +82 -33
  33. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  34. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts +8 -0
  35. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts.map +1 -1
  36. package/dist/core/extensions/builtin/compaction/todo-bridge.js +12 -6
  37. package/dist/core/extensions/builtin/compaction/todo-bridge.js.map +1 -1
  38. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/index.js +0 -2
  40. package/dist/core/extensions/builtin/index.js.map +1 -1
  41. package/dist/core/extensions/builtin/openai-web-search/index.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/openai-web-search/index.js +26 -1
  43. package/dist/core/extensions/builtin/openai-web-search/index.js.map +1 -1
  44. package/dist/core/extensions/builtin/permission-system/prompt.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/permission-system/prompt.js +0 -5
  46. package/dist/core/extensions/builtin/permission-system/prompt.js.map +1 -1
  47. package/dist/core/extensions/builtin/system-messages.d.ts +7 -7
  48. package/dist/core/extensions/builtin/system-messages.d.ts.map +1 -1
  49. package/dist/core/extensions/builtin/system-messages.js +10 -10
  50. package/dist/core/extensions/builtin/system-messages.js.map +1 -1
  51. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts +1 -1
  52. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts.map +1 -1
  53. package/dist/core/extensions/builtin/todotools/continuation/prompt.js +1 -1
  54. package/dist/core/extensions/builtin/todotools/continuation/prompt.js.map +1 -1
  55. package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
  56. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/todotools/state.js +1 -1
  58. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  59. package/dist/core/extensions/builtin/todotools/system-messages.d.ts +3 -3
  60. package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/todotools/system-messages.js +6 -6
  62. package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -1
  63. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts +1 -1
  64. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/tool-pair-guard/index.js +8 -4
  66. package/dist/core/extensions/builtin/tool-pair-guard/index.js.map +1 -1
  67. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts +3 -0
  68. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts.map +1 -0
  69. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js +89 -0
  70. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js.map +1 -0
  71. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts +3 -0
  72. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts.map +1 -0
  73. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js +122 -0
  74. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js.map +1 -0
  75. package/dist/core/extensions/loader.d.ts.map +1 -1
  76. package/dist/core/extensions/loader.js +2 -0
  77. package/dist/core/extensions/loader.js.map +1 -1
  78. package/dist/core/extensions/runner.d.ts +3 -0
  79. package/dist/core/extensions/runner.d.ts.map +1 -1
  80. package/dist/core/extensions/runner.js +18 -0
  81. package/dist/core/extensions/runner.js.map +1 -1
  82. package/dist/core/extensions/types.d.ts +22 -0
  83. package/dist/core/extensions/types.d.ts.map +1 -1
  84. package/dist/core/extensions/types.js.map +1 -1
  85. package/dist/core/messages.d.ts +3 -3
  86. package/dist/core/messages.d.ts.map +1 -1
  87. package/dist/core/messages.js +5 -10
  88. package/dist/core/messages.js.map +1 -1
  89. package/dist/core/model-registry.d.ts.map +1 -1
  90. package/dist/core/model-registry.js +1 -0
  91. package/dist/core/model-registry.js.map +1 -1
  92. package/dist/core/sdk.d.ts +1 -1
  93. package/dist/core/sdk.d.ts.map +1 -1
  94. package/dist/core/sdk.js +7 -22
  95. package/dist/core/sdk.js.map +1 -1
  96. package/dist/core/session-manager.d.ts.map +1 -1
  97. package/dist/core/session-manager.js +1 -1
  98. package/dist/core/session-manager.js.map +1 -1
  99. package/dist/core/settings-manager.d.ts +0 -5
  100. package/dist/core/settings-manager.d.ts.map +1 -1
  101. package/dist/core/settings-manager.js.map +1 -1
  102. package/dist/core/thinking-levels.d.ts +6 -0
  103. package/dist/core/thinking-levels.d.ts.map +1 -0
  104. package/dist/core/thinking-levels.js +36 -0
  105. package/dist/core/thinking-levels.js.map +1 -0
  106. package/dist/core/tools/bash.d.ts.map +1 -1
  107. package/dist/core/tools/bash.js +15 -1
  108. package/dist/core/tools/bash.js.map +1 -1
  109. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  110. package/dist/modes/interactive/components/compaction-summary-message.js +20 -2
  111. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  112. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  113. package/dist/modes/interactive/components/keybinding-hints.js +3 -1
  114. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  115. package/dist/modes/interactive/interactive-mode.d.ts +8 -0
  116. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  117. package/dist/modes/interactive/interactive-mode.js +137 -49
  118. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  119. package/dist/modes/interactive/working-status.d.ts +15 -0
  120. package/dist/modes/interactive/working-status.d.ts.map +1 -0
  121. package/dist/modes/interactive/working-status.js +60 -0
  122. package/dist/modes/interactive/working-status.js.map +1 -0
  123. package/docs/extensions.md +0 -1
  124. package/docs/index.md +0 -1
  125. package/docs/sdk.md +0 -1
  126. package/docs/settings.md +1 -29
  127. package/docs/termux.md +2 -2
  128. package/docs/usage.md +1 -1
  129. package/examples/README.md +1 -1
  130. package/examples/extensions/README.md +0 -1
  131. package/examples/extensions/overlay-qa-tests.ts +1 -1
  132. package/package.json +4 -4
  133. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts +0 -10
  134. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts.map +0 -1
  135. package/dist/core/extensions/builtin/background-task/cancel-tool.js +0 -109
  136. package/dist/core/extensions/builtin/background-task/cancel-tool.js.map +0 -1
  137. package/dist/core/extensions/builtin/background-task/index.d.ts +0 -3
  138. package/dist/core/extensions/builtin/background-task/index.d.ts.map +0 -1
  139. package/dist/core/extensions/builtin/background-task/index.js +0 -207
  140. package/dist/core/extensions/builtin/background-task/index.js.map +0 -1
  141. package/dist/core/extensions/builtin/background-task/manager.d.ts +0 -17
  142. package/dist/core/extensions/builtin/background-task/manager.d.ts.map +0 -1
  143. package/dist/core/extensions/builtin/background-task/manager.js +0 -114
  144. package/dist/core/extensions/builtin/background-task/manager.js.map +0 -1
  145. package/dist/core/extensions/builtin/background-task/notification.d.ts +0 -22
  146. package/dist/core/extensions/builtin/background-task/notification.d.ts.map +0 -1
  147. package/dist/core/extensions/builtin/background-task/notification.js +0 -105
  148. package/dist/core/extensions/builtin/background-task/notification.js.map +0 -1
  149. package/dist/core/extensions/builtin/background-task/output-tool.d.ts +0 -11
  150. package/dist/core/extensions/builtin/background-task/output-tool.d.ts.map +0 -1
  151. package/dist/core/extensions/builtin/background-task/output-tool.js +0 -127
  152. package/dist/core/extensions/builtin/background-task/output-tool.js.map +0 -1
  153. package/dist/core/extensions/builtin/background-task/spawner.d.ts +0 -8
  154. package/dist/core/extensions/builtin/background-task/spawner.d.ts.map +0 -1
  155. package/dist/core/extensions/builtin/background-task/spawner.js +0 -207
  156. package/dist/core/extensions/builtin/background-task/spawner.js.map +0 -1
  157. package/dist/core/extensions/builtin/background-task/task-tool.d.ts +0 -20
  158. package/dist/core/extensions/builtin/background-task/task-tool.d.ts.map +0 -1
  159. package/dist/core/extensions/builtin/background-task/task-tool.js +0 -302
  160. package/dist/core/extensions/builtin/background-task/task-tool.js.map +0 -1
  161. package/dist/core/extensions/builtin/background-task/types.d.ts +0 -72
  162. package/dist/core/extensions/builtin/background-task/types.d.ts.map +0 -1
  163. package/dist/core/extensions/builtin/background-task/types.js +0 -32
  164. package/dist/core/extensions/builtin/background-task/types.js.map +0 -1
  165. package/docs/agents.md +0 -348
  166. package/examples/extensions/subagent/README.md +0 -172
  167. package/examples/extensions/subagent/agents/planner.md +0 -37
  168. package/examples/extensions/subagent/agents/reviewer.md +0 -35
  169. package/examples/extensions/subagent/agents/scout.md +0 -50
  170. package/examples/extensions/subagent/agents/worker.md +0 -24
  171. package/examples/extensions/subagent/agents.ts +0 -126
  172. package/examples/extensions/subagent/index.ts +0 -987
  173. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  174. package/examples/extensions/subagent/prompts/implement.md +0 -10
  175. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
@@ -1,12 +1,14 @@
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
+ import { BUILTIN_CONTEXT_REDUCTION_OPTIONS, reduceContextMessages, shouldApplyContextReduction, } from "./context-reduction.js";
6
7
  import { createDegradationMonitorState, handleMessageEnd, handleTurnEnd, RECOVERY_INSTRUCTIONS, resetOnSessionCompact, } from "./degradation-monitor.js";
7
- import * as overflow from "./overflow-detection.js";
8
+ import { rewriteOpenAiPayloadWithRemoteCompaction, runOpenAiRemoteCompaction, SENPI_COMPACTION_EVENT, } from "./openai-remote.js";
8
9
  import * as cap from "./per-turn-cap.js";
9
10
  import * as policy from "./policy.js";
11
+ import { repairOrphanedToolResults } from "./repair-tool-pairs.js";
10
12
  import * as restoration from "./restoration-tracker.js";
11
13
  import { applyGeneratedCompaction, createSpeculativeCompactionSnapshot, getPromptVariant, hardLimitEmergencyPrune, runExtensionCompaction, } from "./speculative.js";
12
14
  import { createInitialState, resetTurnCounter } from "./state.js";
@@ -15,9 +17,27 @@ import * as truncation from "./tool-truncation.js";
15
17
  const DEFAULT_CONTEXT_WINDOW = 200_000;
16
18
  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
19
  const PROACTIVE_COMPACTION_INSTRUCTIONS = "Proactively compact before the next agent turn.";
20
+ const MAX_PENDING_METADATA = 8;
21
+ const IMAGE_PROMPT_TOKEN_ESTIMATE = 1_200;
18
22
  function approxTokens(text) {
19
23
  return Math.ceil(text.length / 4);
20
24
  }
25
+ function isOpenAiResponsesModel(model) {
26
+ return model?.provider === "openai" && model.api === "openai-responses";
27
+ }
28
+ function estimatePendingPromptTokens(event) {
29
+ return approxTokens(event.prompt ?? "") + (event.images?.length ?? 0) * IMAGE_PROMPT_TOKEN_ESTIMATE;
30
+ }
31
+ function withAdditionalTokens(usage, additionalTokens) {
32
+ if (usage.tokens === null || additionalTokens <= 0)
33
+ return usage;
34
+ const tokens = usage.tokens + additionalTokens;
35
+ return {
36
+ ...usage,
37
+ tokens,
38
+ percent: usage.contextWindow > 0 ? (tokens / usage.contextWindow) * 100 : usage.percent,
39
+ };
40
+ }
21
41
  function isMonitorableMessageEvent(event) {
22
42
  return "content" in event.message && Array.isArray(event.message.content);
23
43
  }
@@ -31,6 +51,37 @@ function recentCheckpoint(ctx) {
31
51
  return null;
32
52
  return Date.now() - checkpoint.timestamp <= 60_000 ? checkpoint : null;
33
53
  }
54
+ function shouldEndFeedback(result) {
55
+ return !result.applied && result.reason !== "rejected";
56
+ }
57
+ function endCompactionFeedback(ctx, signal, result) {
58
+ if (shouldEndFeedback(result)) {
59
+ ctx.endCompaction?.({ reason: "extension", aborted: signal?.aborted });
60
+ }
61
+ }
62
+ function linkAbortSignal(source, target) {
63
+ if (!source)
64
+ return () => { };
65
+ if (source.aborted) {
66
+ target.abort();
67
+ return () => { };
68
+ }
69
+ const abort = () => target.abort();
70
+ source.addEventListener("abort", abort, { once: true });
71
+ return () => source.removeEventListener("abort", abort);
72
+ }
73
+ function createBlockingRemoteCompactionEvent(ctx, snapshot, customInstructions, signal) {
74
+ return {
75
+ type: "session_before_compact",
76
+ reason: "extension",
77
+ willRetry: false,
78
+ requestId: randomUUID(),
79
+ preparation: snapshot.preparation,
80
+ branchEntries: ctx.sessionManager.getBranch(),
81
+ customInstructions,
82
+ signal,
83
+ };
84
+ }
34
85
  export default function compactionExtension(pi) {
35
86
  let state = createInitialState();
36
87
  const degradationState = createDegradationMonitorState();
@@ -38,6 +89,7 @@ export default function compactionExtension(pi) {
38
89
  state = { ...state, restoration: restorationState };
39
90
  let speculativeGeneration = 0;
40
91
  let speculativeJob;
92
+ const pendingMetadata = new Map();
41
93
  function invalidateSpeculativeCompaction() {
42
94
  speculativeGeneration++;
43
95
  speculativeJob?.controller.abort();
@@ -54,23 +106,95 @@ export default function compactionExtension(pi) {
54
106
  const promise = runExtensionCompaction(ctx, snapshot, controller.signal).catch(() => undefined);
55
107
  speculativeJob = { generation, snapshot, controller, promise };
56
108
  }
109
+ function capturePendingMetadata(requestId, ctx) {
110
+ pendingMetadata.set(requestId, {
111
+ checkpoint: checkpointState.captureAgentCheckpoint(pi, ctx),
112
+ todoSnapshot: todoBridge.createTodoSnapshot(ctx),
113
+ });
114
+ while (pendingMetadata.size > MAX_PENDING_METADATA) {
115
+ const oldestRequestId = pendingMetadata.keys().next().value;
116
+ if (oldestRequestId === undefined)
117
+ break;
118
+ pendingMetadata.delete(oldestRequestId);
119
+ }
120
+ }
121
+ function persistAcceptedMetadata(requestId) {
122
+ const metadata = pendingMetadata.get(requestId);
123
+ if (!metadata)
124
+ return;
125
+ pendingMetadata.delete(requestId);
126
+ checkpointState.persistCheckpoint(pi, metadata.checkpoint);
127
+ todoBridge.persistTodoSnapshot(pi, metadata.todoSnapshot);
128
+ }
57
129
  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") {
130
+ let feedbackSignal = ctx.beginCompaction?.({ reason: "extension" });
131
+ try {
132
+ if (isOpenAiResponsesModel(ctx.model)) {
133
+ const remoteGeneration = speculativeGeneration + 1;
134
+ const remoteSnapshot = createSpeculativeCompactionSnapshot(ctx, {
135
+ generation: remoteGeneration,
136
+ customInstructions,
137
+ });
138
+ if (remoteSnapshot) {
139
+ const remoteSignal = feedbackSignal ?? new AbortController().signal;
140
+ const remoteCompaction = await runOpenAiRemoteCompaction(ctx, createBlockingRemoteCompactionEvent(ctx, remoteSnapshot, customInstructions, remoteSignal), (data) => pi.events.emit(SENPI_COMPACTION_EVENT, data));
141
+ if (remoteCompaction) {
142
+ if (speculativeGeneration !== remoteGeneration - 1) {
143
+ const result = { applied: false, reason: "stale" };
144
+ endCompactionFeedback(ctx, feedbackSignal, result);
145
+ return result;
146
+ }
147
+ speculativeGeneration = remoteGeneration;
148
+ speculativeJob?.controller.abort();
149
+ speculativeJob = undefined;
150
+ const result = await applyGeneratedCompaction(ctx, remoteSnapshot, () => speculativeGeneration, remoteCompaction);
151
+ endCompactionFeedback(ctx, feedbackSignal, result);
152
+ return result;
153
+ }
154
+ }
155
+ }
156
+ const pendingJob = speculativeJob;
157
+ if (pendingJob) {
158
+ const unlinkAbort = linkAbortSignal(feedbackSignal, pendingJob.controller);
159
+ let compaction;
160
+ try {
161
+ compaction = await pendingJob.promise;
162
+ }
163
+ finally {
164
+ unlinkAbort();
165
+ }
166
+ const result = await applyGeneratedCompaction(ctx, pendingJob.snapshot, () => speculativeGeneration, compaction);
167
+ if (result.applied || result.reason === "stale") {
168
+ speculativeJob = undefined;
169
+ endCompactionFeedback(ctx, feedbackSignal, result);
170
+ return result;
171
+ }
172
+ if (result.reason === "rejected") {
173
+ feedbackSignal = ctx.beginCompaction?.({ reason: "extension" });
174
+ }
63
175
  speculativeJob = undefined;
176
+ }
177
+ const generation = ++speculativeGeneration;
178
+ const snapshot = createSpeculativeCompactionSnapshot(ctx, { generation, customInstructions });
179
+ if (!snapshot) {
180
+ const result = { applied: false, reason: "unavailable" };
181
+ endCompactionFeedback(ctx, feedbackSignal, result);
64
182
  return result;
65
183
  }
66
- speculativeJob = undefined;
184
+ const compaction = await runExtensionCompaction(ctx, snapshot, feedbackSignal, (delta) => ctx.updateCompaction?.({ reason: "extension", delta }));
185
+ const result = await applyGeneratedCompaction(ctx, snapshot, () => speculativeGeneration, compaction);
186
+ endCompactionFeedback(ctx, feedbackSignal, result);
187
+ return result;
188
+ }
189
+ catch (error) {
190
+ const message = error instanceof Error ? error.message : String(error);
191
+ ctx.endCompaction?.({
192
+ reason: "extension",
193
+ aborted: feedbackSignal?.aborted,
194
+ errorMessage: `Compaction failed: ${message}`,
195
+ });
196
+ throw error;
67
197
  }
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
198
  }
75
199
  pi.on("session_before_compact", async (event, ctx) => {
76
200
  invalidateSpeculativeCompaction();
@@ -78,11 +202,14 @@ export default function compactionExtension(pi) {
78
202
  return { cancel: true };
79
203
  if (breaker.isTripped(state, Date.now()) && !breaker.shouldBypass(state, { reason: event.reason }))
80
204
  return { cancel: true };
81
- checkpointState.persistCheckpoint(pi, checkpointState.captureAgentCheckpoint(pi, ctx));
82
- todoBridge.captureTodoSnapshot(pi, ctx);
205
+ capturePendingMetadata(event.requestId, ctx);
83
206
  const model = ctx.model;
84
207
  if (!model)
85
208
  return undefined;
209
+ const remoteCompaction = await runOpenAiRemoteCompaction(ctx, event, (data) => pi.events.emit(SENPI_COMPACTION_EVENT, data));
210
+ if (remoteCompaction) {
211
+ return { compaction: remoteCompaction };
212
+ }
86
213
  const snapshot = {
87
214
  generation: ++speculativeGeneration,
88
215
  expectedRevision: ctx.getMessageRevision(),
@@ -92,9 +219,11 @@ export default function compactionExtension(pi) {
92
219
  promptVariant: getPromptVariant(event),
93
220
  customInstructions: event.customInstructions,
94
221
  };
95
- const compaction = await runExtensionCompaction(ctx, snapshot, event.signal);
96
- if (!compaction)
222
+ const compaction = await runExtensionCompaction(ctx, snapshot, event.signal, (delta) => ctx.updateCompaction?.({ reason: event.reason, delta }));
223
+ if (!compaction) {
224
+ pendingMetadata.delete(event.requestId);
97
225
  return { cancel: true };
226
+ }
98
227
  return {
99
228
  compaction,
100
229
  };
@@ -102,6 +231,7 @@ export default function compactionExtension(pi) {
102
231
  pi.on("session_compact", async (event, ctx) => {
103
232
  invalidateSpeculativeCompaction();
104
233
  if (event.accepted) {
234
+ persistAcceptedMetadata(event.requestId);
105
235
  const branchEntries = ctx.sessionManager.getBranch();
106
236
  const firstKeptIndex = branchEntries.findIndex((entry) => entry.id === event.compactionEntry.firstKeptEntryId);
107
237
  const keptEntries = firstKeptIndex === -1 ? [] : branchEntries.slice(firstKeptIndex);
@@ -141,15 +271,17 @@ export default function compactionExtension(pi) {
141
271
  const usage = ctx.getContextUsage();
142
272
  const contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;
143
273
  const settings = ctx.getCompactionSettings();
144
- if (usage && policy.isAtHardLimit(usage, contextWindow, settings.reserveTokens)) {
274
+ const pendingPromptTokens = estimatePendingPromptTokens(event);
275
+ const usageWithPendingPrompt = usage ? withAdditionalTokens(usage, pendingPromptTokens) : undefined;
276
+ if (usage && policy.isAtHardLimit(usage, contextWindow, settings.reserveTokens, pendingPromptTokens)) {
145
277
  await applyBlockingCompaction(ctx, EMERGENCY_COMPACTION_INSTRUCTIONS);
146
278
  }
147
- else if (usage &&
148
- policy.shouldTriggerCompaction(usage, contextWindow, settings, state.lastYield ?? undefined)) {
279
+ else if (usageWithPendingPrompt &&
280
+ policy.shouldTriggerCompaction(usageWithPendingPrompt, contextWindow, settings, state.lastYield ?? undefined)) {
149
281
  await applyBlockingCompaction(ctx, PROACTIVE_COMPACTION_INSTRUCTIONS);
150
282
  }
151
- else if (usage &&
152
- policy.shouldStartSpeculativeCompaction(usage, contextWindow, settings, state.lastYield ?? undefined)) {
283
+ else if (usageWithPendingPrompt &&
284
+ policy.shouldStartSpeculativeCompaction(usageWithPendingPrompt, contextWindow, settings, state.lastYield ?? undefined)) {
153
285
  startSpeculativeCompaction(ctx, PROACTIVE_COMPACTION_INSTRUCTIONS);
154
286
  }
155
287
  if (systemPrompt === event.systemPrompt && !message)
@@ -157,10 +289,21 @@ export default function compactionExtension(pi) {
157
289
  return message ? { systemPrompt, message } : { systemPrompt };
158
290
  });
159
291
  pi.on("context", (event, ctx) => {
160
- const contextWindow = ctx.getContextUsage()?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;
161
- const emergency = hardLimitEmergencyPrune(event.messages, contextWindow);
292
+ const usage = ctx.getContextUsage();
293
+ const contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;
294
+ const sourceMessages = shouldApplyContextReduction({
295
+ usageTokens: usage?.tokens ?? null,
296
+ contextWindow,
297
+ isProviderNativeCompactionPath: isOpenAiResponsesModel(ctx.model),
298
+ })
299
+ ? reduceContextMessages(event.messages, BUILTIN_CONTEXT_REDUCTION_OPTIONS).messages
300
+ : event.messages;
301
+ const emergency = hardLimitEmergencyPrune(sourceMessages, contextWindow);
162
302
  return { messages: repairOrphanedToolResults(convertToLlm(emergency.messages)) };
163
303
  });
304
+ pi.on("before_provider_request", (event, ctx) => {
305
+ return rewriteOpenAiPayloadWithRemoteCompaction(event.payload, { model: ctx.model, branchEntries: ctx.sessionManager.getBranch() }, (data) => pi.events.emit(SENPI_COMPACTION_EVENT, data));
306
+ });
164
307
  pi.on("turn_end", async (_event, ctx) => {
165
308
  handleTurnEnd(degradationState);
166
309
  if (degradationState.recoveryTriggeredThisCycle)
@@ -181,12 +324,6 @@ export default function compactionExtension(pi) {
181
324
  notify: (message) => ctx.ui.notify(message, "warning"),
182
325
  });
183
326
  }
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
327
  });
191
328
  pi.on("tool_result", (event) => {
192
329
  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\tBUILTIN_CONTEXT_REDUCTION_OPTIONS,\n\treduceContextMessages,\n\tshouldApplyContextReduction,\n} from \"./context-reduction.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 usage = ctx.getContextUsage();\n\t\tconst contextWindow = usage?.contextWindow ?? ctx.model?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\t\tconst sourceMessages = shouldApplyContextReduction({\n\t\t\tusageTokens: usage?.tokens ?? null,\n\t\t\tcontextWindow,\n\t\t\tisProviderNativeCompactionPath: isOpenAiResponsesModel(ctx.model),\n\t\t})\n\t\t\t? reduceContextMessages(event.messages, BUILTIN_CONTEXT_REDUCTION_OPTIONS).messages\n\t\t\t: event.messages;\n\t\tconst emergency = hardLimitEmergencyPrune(sourceMessages, 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