@astralyn/pi 0.87.4 → 0.87.6
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.
- package/CHANGELOG.md +33 -0
- package/dist/bundle/chunks/{chunk-CUDKRZ2V.js → chunk-4W4Q2H6W.js} +58 -57
- package/dist/bundle/chunks/{chunk-ANT4TSUE.js → chunk-IORR2FW4.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-Y2YZRMU3.js → virtual-modules-KUEIEAZN.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts +8 -24
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +54 -109
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/background/session.d.ts +11 -7
- package/dist/core/background/session.d.ts.map +1 -1
- package/dist/core/background/session.js +42 -16
- package/dist/core/background/session.js.map +1 -1
- package/dist/core/context-snapshot.d.ts +17 -4
- package/dist/core/context-snapshot.d.ts.map +1 -1
- package/dist/core/context-snapshot.js +48 -50
- package/dist/core/context-snapshot.js.map +1 -1
- package/dist/core/extensions/distribution-api.d.ts +0 -7
- package/dist/core/extensions/distribution-api.d.ts.map +1 -1
- package/dist/core/extensions/distribution-api.js +6 -6
- package/dist/core/extensions/distribution-api.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +3 -2
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -5
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +10 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +3 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +59 -7
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -3
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +0 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +0 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +0 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +0 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +0 -7
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +0 -11
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +59 -5
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/renderers/edit.d.ts.map +1 -1
- package/dist/core/tools/renderers/edit.js +4 -22
- package/dist/core/tools/renderers/edit.js.map +1 -1
- package/dist/core/tools/renderers/find.d.ts.map +1 -1
- package/dist/core/tools/renderers/find.js +7 -6
- package/dist/core/tools/renderers/find.js.map +1 -1
- package/dist/core/tools/renderers/grep.d.ts.map +1 -1
- package/dist/core/tools/renderers/grep.js +8 -7
- package/dist/core/tools/renderers/grep.js.map +1 -1
- package/dist/core/tools/renderers/ls.d.ts.map +1 -1
- package/dist/core/tools/renderers/ls.js +3 -2
- package/dist/core/tools/renderers/ls.js.map +1 -1
- package/dist/core/tools/renderers/read.d.ts.map +1 -1
- package/dist/core/tools/renderers/read.js +7 -12
- package/dist/core/tools/renderers/read.js.map +1 -1
- package/dist/core/tools/renderers/write.d.ts.map +1 -1
- package/dist/core/tools/renderers/write.js +3 -2
- package/dist/core/tools/renderers/write.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +2 -6
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +5 -4
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/extensions/background/completion-render.d.ts.map +1 -1
- package/dist/extensions/background/completion-render.js +3 -4
- package/dist/extensions/background/completion-render.js.map +1 -1
- package/dist/extensions/background/constants.d.ts +2 -0
- package/dist/extensions/background/constants.d.ts.map +1 -1
- package/dist/extensions/background/constants.js +2 -0
- package/dist/extensions/background/constants.js.map +1 -1
- package/dist/extensions/background/index.d.ts.map +1 -1
- package/dist/extensions/background/index.js +31 -5
- package/dist/extensions/background/index.js.map +1 -1
- package/dist/extensions/question/detail-pane.d.ts +12 -0
- package/dist/extensions/question/detail-pane.d.ts.map +1 -0
- package/dist/extensions/question/detail-pane.js +42 -0
- package/dist/extensions/question/detail-pane.js.map +1 -0
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js +175 -105
- package/dist/extensions/question/dialog.js.map +1 -1
- package/dist/extensions/question/option-window.d.ts +26 -0
- package/dist/extensions/question/option-window.d.ts.map +1 -0
- package/dist/extensions/question/option-window.js +53 -0
- package/dist/extensions/question/option-window.js.map +1 -0
- package/dist/extensions/question/render-cache.d.ts +4 -4
- package/dist/extensions/question/render-cache.d.ts.map +1 -1
- package/dist/extensions/question/render-cache.js +10 -11
- package/dist/extensions/question/render-cache.js.map +1 -1
- package/dist/extensions/todo/constants.d.ts +1 -1
- package/dist/extensions/todo/constants.d.ts.map +1 -1
- package/dist/extensions/todo/constants.js +2 -2
- package/dist/extensions/todo/constants.js.map +1 -1
- package/dist/extensions/todo/index.d.ts.map +1 -1
- package/dist/extensions/todo/index.js +12 -8
- package/dist/extensions/todo/index.js.map +1 -1
- package/dist/extensions/todo/schema.d.ts +1 -0
- package/dist/extensions/todo/schema.d.ts.map +1 -1
- package/dist/extensions/todo/schema.js +1 -1
- package/dist/extensions/todo/schema.js.map +1 -1
- package/dist/extensions/todo/state.d.ts.map +1 -1
- package/dist/extensions/todo/state.js +15 -5
- package/dist/extensions/todo/state.js.map +1 -1
- package/dist/extensions/todo/view.d.ts +4 -4
- package/dist/extensions/todo/view.d.ts.map +1 -1
- package/dist/extensions/todo/view.js +11 -30
- package/dist/extensions/todo/view.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/status-marker.d.ts +2 -2
- package/dist/modes/interactive/components/status-marker.js +2 -2
- package/dist/modes/interactive/components/status-marker.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +7 -10
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +2 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/tool-view/chat.d.ts +20 -0
- package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -0
- package/dist/modes/interactive/tool-view/chat.js +46 -0
- package/dist/modes/interactive/tool-view/chat.js.map +1 -0
- package/dist/modes/interactive/tool-view/fallback.d.ts +14 -0
- package/dist/modes/interactive/tool-view/fallback.d.ts.map +1 -0
- package/dist/modes/interactive/tool-view/fallback.js +52 -0
- package/dist/modes/interactive/tool-view/fallback.js.map +1 -0
- package/dist/modes/interactive/tool-view/style.d.ts +63 -0
- package/dist/modes/interactive/tool-view/style.d.ts.map +1 -0
- package/dist/modes/interactive/tool-view/style.js +83 -0
- package/dist/modes/interactive/tool-view/style.js.map +1 -0
- package/dist/modes/interactive/{components → tool-view}/tool-execution.d.ts +17 -24
- package/dist/modes/interactive/tool-view/tool-execution.d.ts.map +1 -0
- package/dist/modes/interactive/{components → tool-view}/tool-execution.js +42 -116
- package/dist/modes/interactive/tool-view/tool-execution.js.map +1 -0
- package/docs/bundled/README.md +1 -1
- package/docs/bundled/extensions/background.md +1 -1
- package/docs/bundled/extensions/question.md +6 -5
- package/docs/bundled/extensions/todo.md +5 -5
- package/docs/bundled/tool-presentation.md +41 -31
- package/docs/extensions.md +1 -4
- package/docs/keybindings.md +11 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/core/model-stream-options.d.ts +0 -6
- package/dist/core/model-stream-options.d.ts.map +0 -1
- package/dist/core/model-stream-options.js +0 -20
- package/dist/core/model-stream-options.js.map +0 -1
- package/dist/modes/interactive/components/tool-chrome.d.ts +0 -28
- package/dist/modes/interactive/components/tool-chrome.d.ts.map +0 -1
- package/dist/modes/interactive/components/tool-chrome.js +0 -84
- package/dist/modes/interactive/components/tool-chrome.js.map +0 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +0 -1
- package/dist/modes/interactive/components/tool-execution.js.map +0 -1
- package/dist/modes/interactive/components/tool-group.d.ts +0 -17
- package/dist/modes/interactive/components/tool-group.d.ts.map +0 -1
- package/dist/modes/interactive/components/tool-group.js +0 -78
- package/dist/modes/interactive/components/tool-group.js.map +0 -1
- package/dist/modes/interactive/tool-chat.d.ts +0 -21
- package/dist/modes/interactive/tool-chat.d.ts.map +0 -1
- package/dist/modes/interactive/tool-chat.js +0 -58
- package/dist/modes/interactive/tool-chat.js.map +0 -1
|
@@ -10,11 +10,10 @@ interface BackgroundSessionOptions {
|
|
|
10
10
|
/** The main session owns prompt queues, preflight and idle state. */
|
|
11
11
|
canDeliver(): boolean;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* a delivery attempt that ended without the transcript containing the message.
|
|
13
|
+
* Start a completion turn, or enqueue the message and return waitForPersistence().
|
|
14
|
+
* The host owns prompt routing; this adapter owns the queued delivery's lifetime.
|
|
16
15
|
*/
|
|
17
|
-
deliver(message: CustomMessage): Promise<void>;
|
|
16
|
+
deliver(message: CustomMessage, waitForPersistence: () => Promise<void>): Promise<void>;
|
|
18
17
|
onEntry(entry: SessionEntry): void;
|
|
19
18
|
onError(event: string, message: string): void;
|
|
20
19
|
}
|
|
@@ -53,10 +52,15 @@ export declare class BackgroundSession {
|
|
|
53
52
|
private schedule;
|
|
54
53
|
private canDeliver;
|
|
55
54
|
private drain;
|
|
56
|
-
/**
|
|
57
|
-
|
|
55
|
+
/** Record dequeueing before message hooks can fail or rewrite the notification. */
|
|
56
|
+
messageStarted(message: AgentMessage): void;
|
|
57
|
+
/** A queued message that was never emitted remains claimed for the next run. */
|
|
58
|
+
agentEnded(): void;
|
|
59
|
+
queueCleared(): void;
|
|
60
|
+
/** Acknowledge only successful appends, using identity even when metadata was rewritten. */
|
|
61
|
+
messagePersisted(message: AgentMessage): void;
|
|
58
62
|
/** A wait result claims delivery only through its final, persisted marker. */
|
|
59
|
-
acknowledgeWaitResult
|
|
63
|
+
private acknowledgeWaitResult;
|
|
60
64
|
dispose(): void;
|
|
61
65
|
}
|
|
62
66
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/core/background/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAK1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,KAAK,cAAc,EAAwB,MAAM,YAAY,CAAC;AAEvE,UAAU,wBAAwB;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,qEAAqE;IACrE,UAAU,IAAI,OAAO,CAAC;IACtB
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/core/background/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAK1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,KAAK,cAAc,EAAwB,MAAM,YAAY,CAAC;AAEvE,UAAU,wBAAwB;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,qEAAqE;IACrE,UAAU,IAAI,OAAO,CAAC;IACtB;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,+BAA+B;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;CACd;AAWD,qGAAqG;AACrG,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,KAAK,CAAC,CAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;gBAExD,OAAO,EAAE,wBAAwB;IAK7C,IAAI,OAAO,IAAI,iBAAiB,CAE/B;IAED,IAAI,sBAAsB,IAAI,SAAS,+BAA+B,EAAE,CAEvE;IAED,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,2FAA2F;IAC3F,cAAc,IAAI,IAAI;IAMtB,OAAO,CAAC,aAAa;IA0BrB,cAAc,CAAC,OAAO,oBAAe,GAAG,IAAI;IAU5C,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,iBAAiB;IAyBzB,OAAO,CAAC,IAAI;IAQZ,sEAAsE;IACtE,KAAK,IAAI,MAAM,IAAI;IAanB,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,UAAU;YAMJ,KAAK;IAiDnB,mFAAmF;IACnF,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAK3C,gFAAgF;IAChF,UAAU,IAAI,IAAI;IAOlB,YAAY,IAAI,IAAI;IAIpB,4FAA4F;IAC5F,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAU7C,8EAA8E;IAC9E,OAAO,CAAC,qBAAqB;IAY7B,OAAO,IAAI,IAAI;CAOf"}
|
|
@@ -158,21 +158,34 @@ export class BackgroundSession {
|
|
|
158
158
|
this.failures.delete(id);
|
|
159
159
|
}
|
|
160
160
|
const task = service.pendingNotifications().find((task) => !this.failures.has(task.id));
|
|
161
|
-
if (!task
|
|
161
|
+
if (!task)
|
|
162
|
+
return;
|
|
163
|
+
const message = backgroundCompletionMessage(task);
|
|
164
|
+
if (!service.claimNotification(task.id))
|
|
162
165
|
return;
|
|
163
166
|
// Exactly one completion may be in flight, whether queued for steering or running its
|
|
164
167
|
// own turn; there is no separate claim registry.
|
|
165
|
-
const delivery = {
|
|
168
|
+
const delivery = {
|
|
169
|
+
id: task.id,
|
|
170
|
+
service,
|
|
171
|
+
message,
|
|
172
|
+
phase: "pending",
|
|
173
|
+
};
|
|
166
174
|
this.delivery = delivery;
|
|
167
175
|
let deliveryError;
|
|
168
176
|
try {
|
|
169
|
-
await this.options.deliver(
|
|
177
|
+
await this.options.deliver(delivery.message, () => new Promise((resolve, reject) => {
|
|
178
|
+
if (delivery.phase === "persisted")
|
|
179
|
+
resolve();
|
|
180
|
+
else
|
|
181
|
+
delivery.queued = { resolve, reject };
|
|
182
|
+
}));
|
|
170
183
|
}
|
|
171
184
|
catch (error) {
|
|
172
185
|
deliveryError = error;
|
|
173
186
|
}
|
|
174
187
|
finally {
|
|
175
|
-
if (
|
|
188
|
+
if (delivery.phase !== "persisted") {
|
|
176
189
|
service.releaseNotification(task.id);
|
|
177
190
|
if (service === this.service)
|
|
178
191
|
this.failures.add(task.id);
|
|
@@ -185,20 +198,32 @@ export class BackgroundSession {
|
|
|
185
198
|
this.schedule();
|
|
186
199
|
}
|
|
187
200
|
}
|
|
188
|
-
/**
|
|
189
|
-
|
|
190
|
-
if (message.role !== "custom" || message.customType !== "background-completion")
|
|
191
|
-
return;
|
|
192
|
-
const details = message.details;
|
|
201
|
+
/** Record dequeueing before message hooks can fail or rewrite the notification. */
|
|
202
|
+
messageStarted(message) {
|
|
193
203
|
const delivery = this.delivery;
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
204
|
+
if (delivery?.message === message && delivery.phase === "pending")
|
|
205
|
+
delivery.phase = "started";
|
|
206
|
+
}
|
|
207
|
+
/** A queued message that was never emitted remains claimed for the next run. */
|
|
208
|
+
agentEnded() {
|
|
209
|
+
const delivery = this.delivery;
|
|
210
|
+
if (delivery?.phase === "started") {
|
|
211
|
+
delivery.queued?.reject(new Error("the completion message was not persisted"));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
queueCleared() {
|
|
215
|
+
this.delivery?.queued?.reject(new Error("the completion message was dequeued before delivery"));
|
|
216
|
+
}
|
|
217
|
+
/** Acknowledge only successful appends, using identity even when metadata was rewritten. */
|
|
218
|
+
messagePersisted(message) {
|
|
219
|
+
const delivery = this.delivery;
|
|
220
|
+
if (delivery?.message === message && delivery.phase !== "persisted") {
|
|
221
|
+
delivery.phase = "persisted";
|
|
200
222
|
delivery.service.markDelivered(delivery.id);
|
|
201
|
-
|
|
223
|
+
delivery.queued?.resolve();
|
|
224
|
+
}
|
|
225
|
+
if (message.role === "toolResult")
|
|
226
|
+
this.acknowledgeWaitResult(message.details);
|
|
202
227
|
}
|
|
203
228
|
/** A wait result claims delivery only through its final, persisted marker. */
|
|
204
229
|
acknowledgeWaitResult(details) {
|
|
@@ -214,6 +239,7 @@ export class BackgroundSession {
|
|
|
214
239
|
dispose() {
|
|
215
240
|
this.disposed = true;
|
|
216
241
|
this.service.close();
|
|
242
|
+
this.delivery?.queued?.reject(new Error("the session was disposed"));
|
|
217
243
|
if (this.timer)
|
|
218
244
|
clearTimeout(this.timer);
|
|
219
245
|
this.timer = undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/core/background/session.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport type { CustomMessage } from \"../messages.ts\";\nimport type { SessionEntry, SessionManager } from \"../session-manager.ts\";\nimport { truncateHead } from \"../tools/truncate.ts\";\nimport { BACKGROUND_USAGE_TYPE, getBackgroundUsageRecord } from \"../usage-totals.ts\";\nimport { BACKGROUND_HISTORY_VERSION } from \"./history.ts\";\nimport { backgroundCompletionMessage } from \"./presentation.ts\";\nimport { BackgroundService } from \"./service.ts\";\nimport { type BackgroundTask, isBackgroundTerminal } from \"./types.ts\";\n\ninterface BackgroundSessionOptions {\n\tmanager: SessionManager;\n\trole: \"main\" | \"subagent\";\n\t/** The main session owns prompt queues, preflight and idle state. */\n\tcanDeliver(): boolean;\n\t/**\n\t * Hand one completion to the host's prompt path. The promise must settle only after the\n\t * message is persisted, or after it can no longer be persisted: a claim is released for\n\t * a delivery attempt that ended without the transcript containing the message.\n\t */\n\tdeliver(message: CustomMessage): Promise<void>;\n\tonEntry(entry: SessionEntry): void;\n\tonError(event: string, message: string): void;\n}\n\nexport interface QuarantinedBackgroundSettlement {\n\tsessionId: string;\n\tgeneration: number;\n\ttask: BackgroundTask;\n\tusage?: Usage;\n}\n\ninterface Delivery {\n\tid: string;\n\tservice: BackgroundService;\n\tpersisted: boolean;\n}\n\n/** Session persistence and completion delivery; execution supervision stays in BackgroundService. */\nexport class BackgroundSession {\n\tprivate readonly options: BackgroundSessionOptions;\n\tprivate _service: BackgroundService;\n\tprivate enabled = false;\n\tprivate disposed = false;\n\tprivate generation = 0;\n\tprivate pauses = 0;\n\tprivate timer?: ReturnType<typeof setTimeout>;\n\tprivate delivery?: Delivery;\n\tprivate readonly failures = new Set<string>();\n\tprivate readonly quarantine: QuarantinedBackgroundSettlement[] = [];\n\n\tconstructor(options: BackgroundSessionOptions) {\n\t\tthis.options = options;\n\t\tthis._service = this.createService();\n\t}\n\n\tget service(): BackgroundService {\n\t\treturn this._service;\n\t}\n\n\tget quarantinedSettlements(): readonly QuarantinedBackgroundSettlement[] {\n\t\treturn structuredClone(this.quarantine);\n\t}\n\n\tsetEnabled(enabled: boolean): void {\n\t\tthis.enabled = enabled && this.options.role === \"main\";\n\t\tthis.service.setEnabled(this.enabled);\n\t}\n\n\t/** Called after the old service's bounded shutdown, while lifecycle delivery is paused. */\n\treplaceService(): void {\n\t\tthis.service.close();\n\t\tthis._service = this.createService();\n\t\tthis.failures.clear();\n\t}\n\n\tprivate createService(): BackgroundService {\n\t\tconst { manager, role } = this.options;\n\t\tconst generation = ++this.generation;\n\t\tconst sessionId = manager.getSessionId();\n\t\tconst sessionFile = manager.getSessionFile();\n\t\tconst service = new BackgroundService({\n\t\t\tenabled: this.enabled,\n\t\t\trole,\n\t\t\tanchor: () => manager.getLeafId(),\n\t\t\tonCleanupError: (message) => this.warn(\"background_cleanup\", message),\n\t\t\tonSettled: (task, usage) => {\n\t\t\t\tconst onBranch =\n\t\t\t\t\tmanager.getSessionId() === sessionId &&\n\t\t\t\t\t(task.anchorId === null || manager.getBranch().some((entry) => entry.id === task.anchorId));\n\t\t\t\tif (this.disposed || this.service !== service || !onBranch) {\n\t\t\t\t\tthis.quarantineSettlement({ sessionId, generation, task, usage }, sessionFile);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.persistSettlement(task, usage);\n\t\t\t},\n\t\t});\n\t\tthis.restoreHistory(service);\n\t\tservice.subscribe(() => this.schedule());\n\t\treturn service;\n\t}\n\n\trestoreHistory(service = this.service): void {\n\t\tservice.restoreHistory(\n\t\t\tthis.options.manager\n\t\t\t\t.getBranch()\n\t\t\t\t.flatMap((entry) =>\n\t\t\t\t\tentry.type === \"custom\" && entry.customType === \"background-task-result\" ? [entry.data] : [],\n\t\t\t\t),\n\t\t);\n\t}\n\n\tprivate quarantineSettlement(record: QuarantinedBackgroundSettlement, sessionFile: string | undefined): void {\n\t\t// Never move the active leaf to append late usage: JSONL's last entry also\n\t\t// selects its resumed branch. The sidecar is diagnostic evidence only.\n\t\tthis.quarantine.push(structuredClone(record));\n\t\tif (this.quarantine.length > 32) this.quarantine.shift();\n\t\tlet persistence =\n\t\t\t\"Not persisted: only the latest 32 snapshots are retained in quarantinedBackgroundSettlements; late usage is not accounted in session totals.\";\n\t\tif (sessionFile) {\n\t\t\ttry {\n\t\t\t\tmkdirSync(dirname(sessionFile), { recursive: true });\n\t\t\t\tappendFileSync(`${sessionFile}.background-late.jsonl`, `${JSON.stringify({ version: 1, ...record })}\\n`);\n\t\t\t\tpersistence = `Saved diagnostic sidecar: ${sessionFile}.background-late.jsonl (not included in normal session totals).`;\n\t\t\t} catch {\n\t\t\t\tpersistence = `Sidecar write failed. ${persistence}`;\n\t\t\t}\n\t\t}\n\t\tthis.warn(\n\t\t\t\"background_settlement_quarantined\",\n\t\t\t`Late background settlement ${record.task.id} was quarantined. ${persistence}`,\n\t\t);\n\t}\n\n\tprivate persistSettlement(task: BackgroundTask, usage: Usage | undefined): void {\n\t\tconst manager = this.options.manager;\n\t\tconst appended: SessionEntry[] = [];\n\t\tconst append = (customType: string, data: unknown) => {\n\t\t\tconst entry = manager.getEntry(manager.appendCustomEntry(customType, data));\n\t\t\tif (entry) appended.push(entry);\n\t\t};\n\t\ttry {\n\t\t\tif (usage && !manager.getEntries().some((entry) => getBackgroundUsageRecord(entry)?.taskId === task.id)) {\n\t\t\t\tappend(BACKGROUND_USAGE_TYPE, { version: 1, taskId: task.id, usage });\n\t\t\t}\n\t\t\tappend(\"background-task-result\", JSON.parse(JSON.stringify({ version: BACKGROUND_HISTORY_VERSION, task })));\n\t\t} finally {\n\t\t\t// Complete the writes before observers can replace the runtime or its manager.\n\t\t\t// If a write fails, still report entries that were successfully appended.\n\t\t\tfor (const entry of appended) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.options.onEntry(entry);\n\t\t\t\t} catch {\n\t\t\t\t\t// Observers cannot interrupt settlement or result publication.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate warn(event: string, message: string): void {\n\t\ttry {\n\t\t\tthis.options.onError(event, truncateHead(message, { maxBytes: 4096, maxLines: 32 }).content);\n\t\t} catch {\n\t\t\t// Diagnostics cannot reject settlement, cleanup or scheduled callbacks.\n\t\t}\n\t}\n\n\t/** Nestable across asynchronous preflight and service replacement. */\n\tpause(): () => void {\n\t\tthis.pauses++;\n\t\tconst releaseService = this.service.pause();\n\t\tlet released = false;\n\t\treturn () => {\n\t\t\tif (released) return;\n\t\t\treleased = true;\n\t\t\tthis.pauses--;\n\t\t\treleaseService();\n\t\t\tthis.schedule();\n\t\t};\n\t}\n\n\tretry(): void {\n\t\tthis.failures.clear();\n\t\tthis.schedule();\n\t}\n\n\tprivate schedule(): void {\n\t\tif (this.disposed || this.timer || this.delivery) return;\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.timer = undefined;\n\t\t\tvoid this.drain().catch(() =>\n\t\t\t\tthis.warn(\"background_delivery\", \"Background notification drain failed; delivery was not confirmed.\"),\n\t\t\t);\n\t\t}, 0);\n\t\tthis.timer.unref?.();\n\t}\n\n\tprivate canDeliver(service: BackgroundService): boolean {\n\t\treturn (\n\t\t\t!this.disposed && service === this.service && service.enabled && this.pauses === 0 && this.options.canDeliver()\n\t\t);\n\t}\n\n\tprivate async drain(): Promise<void> {\n\t\tconst service = this.service;\n\t\tif (this.delivery || !this.canDeliver(service)) return;\n\t\tif (this.failures.size) {\n\t\t\tconst retained = new Set(service.list().map((task) => task.id));\n\t\t\tfor (const id of this.failures) if (!retained.has(id)) this.failures.delete(id);\n\t\t}\n\t\tconst task = service.pendingNotifications().find((task) => !this.failures.has(task.id));\n\t\tif (!task || !service.claimNotification(task.id)) return;\n\t\t// Exactly one completion may be in flight, whether queued for steering or running its\n\t\t// own turn; there is no separate claim registry.\n\t\tconst delivery: Delivery = { id: task.id, service, persisted: false };\n\t\tthis.delivery = delivery;\n\t\tlet deliveryError: unknown;\n\t\ttry {\n\t\t\tawait this.options.deliver(backgroundCompletionMessage(task));\n\t\t} catch (error) {\n\t\t\tdeliveryError = error;\n\t\t} finally {\n\t\t\tif (!delivery.persisted) {\n\t\t\t\tservice.releaseNotification(task.id);\n\t\t\t\tif (service === this.service) this.failures.add(task.id);\n\t\t\t\tconst reason = deliveryError instanceof Error ? `: ${deliveryError.message}` : \"\";\n\t\t\t\tthis.warn(\n\t\t\t\t\t\"background_delivery\",\n\t\t\t\t\t`Background completion delivery failed for ${task.id}${reason}; it will retry on the next prompt.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.delivery = undefined;\n\t\t\tconst current = this.service;\n\t\t\tif (this.canDeliver(current) && current.pendingNotifications().some((task) => !this.failures.has(task.id)))\n\t\t\t\tthis.schedule();\n\t\t}\n\t}\n\n\t/** Capture before message hooks, invoke only after the resulting message was persisted. */\n\tmessageAcknowledgement(message: AgentMessage): (() => void) | undefined {\n\t\tif (message.role !== \"custom\" || message.customType !== \"background-completion\") return;\n\t\tconst details = message.details as { taskId?: unknown } | undefined;\n\t\tconst delivery = this.delivery;\n\t\tif (!delivery || details?.taskId !== delivery.id) return;\n\t\treturn () => {\n\t\t\tif (delivery.persisted) return;\n\t\t\tdelivery.persisted = true;\n\t\t\tdelivery.service.markDelivered(delivery.id);\n\t\t};\n\t}\n\n\t/** A wait result claims delivery only through its final, persisted marker. */\n\tacknowledgeWaitResult(details: unknown): void {\n\t\tif (!details || typeof details !== \"object\" || !(\"backgroundTaskId\" in details)) return;\n\t\tconst id = details.backgroundTaskId;\n\t\tif (\n\t\t\ttypeof id === \"string\" &&\n\t\t\tthis.service\n\t\t\t\t.list()\n\t\t\t\t.some((task) => task.id === id && task.mode === \"background\" && isBackgroundTerminal(task.status))\n\t\t)\n\t\t\tthis.service.markDelivered(id);\n\t}\n\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tthis.service.close();\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = undefined;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/core/background/session.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport type { CustomMessage } from \"../messages.ts\";\nimport type { SessionEntry, SessionManager } from \"../session-manager.ts\";\nimport { truncateHead } from \"../tools/truncate.ts\";\nimport { BACKGROUND_USAGE_TYPE, getBackgroundUsageRecord } from \"../usage-totals.ts\";\nimport { BACKGROUND_HISTORY_VERSION } from \"./history.ts\";\nimport { backgroundCompletionMessage } from \"./presentation.ts\";\nimport { BackgroundService } from \"./service.ts\";\nimport { type BackgroundTask, isBackgroundTerminal } from \"./types.ts\";\n\ninterface BackgroundSessionOptions {\n\tmanager: SessionManager;\n\trole: \"main\" | \"subagent\";\n\t/** The main session owns prompt queues, preflight and idle state. */\n\tcanDeliver(): boolean;\n\t/**\n\t * Start a completion turn, or enqueue the message and return waitForPersistence().\n\t * The host owns prompt routing; this adapter owns the queued delivery's lifetime.\n\t */\n\tdeliver(message: CustomMessage, waitForPersistence: () => Promise<void>): Promise<void>;\n\tonEntry(entry: SessionEntry): void;\n\tonError(event: string, message: string): void;\n}\n\nexport interface QuarantinedBackgroundSettlement {\n\tsessionId: string;\n\tgeneration: number;\n\ttask: BackgroundTask;\n\tusage?: Usage;\n}\n\ninterface Delivery {\n\tid: string;\n\tservice: BackgroundService;\n\t/** Agent-core preserves message identity; extension rewrites mutate it in place. */\n\tmessage: CustomMessage;\n\tphase: \"pending\" | \"started\" | \"persisted\";\n\tqueued?: { resolve(): void; reject(reason: Error): void };\n}\n\n/** Session persistence and completion delivery; execution supervision stays in BackgroundService. */\nexport class BackgroundSession {\n\tprivate readonly options: BackgroundSessionOptions;\n\tprivate _service: BackgroundService;\n\tprivate enabled = false;\n\tprivate disposed = false;\n\tprivate generation = 0;\n\tprivate pauses = 0;\n\tprivate timer?: ReturnType<typeof setTimeout>;\n\tprivate delivery?: Delivery;\n\tprivate readonly failures = new Set<string>();\n\tprivate readonly quarantine: QuarantinedBackgroundSettlement[] = [];\n\n\tconstructor(options: BackgroundSessionOptions) {\n\t\tthis.options = options;\n\t\tthis._service = this.createService();\n\t}\n\n\tget service(): BackgroundService {\n\t\treturn this._service;\n\t}\n\n\tget quarantinedSettlements(): readonly QuarantinedBackgroundSettlement[] {\n\t\treturn structuredClone(this.quarantine);\n\t}\n\n\tsetEnabled(enabled: boolean): void {\n\t\tthis.enabled = enabled && this.options.role === \"main\";\n\t\tthis.service.setEnabled(this.enabled);\n\t}\n\n\t/** Called after the old service's bounded shutdown, while lifecycle delivery is paused. */\n\treplaceService(): void {\n\t\tthis.service.close();\n\t\tthis._service = this.createService();\n\t\tthis.failures.clear();\n\t}\n\n\tprivate createService(): BackgroundService {\n\t\tconst { manager, role } = this.options;\n\t\tconst generation = ++this.generation;\n\t\tconst sessionId = manager.getSessionId();\n\t\tconst sessionFile = manager.getSessionFile();\n\t\tconst service = new BackgroundService({\n\t\t\tenabled: this.enabled,\n\t\t\trole,\n\t\t\tanchor: () => manager.getLeafId(),\n\t\t\tonCleanupError: (message) => this.warn(\"background_cleanup\", message),\n\t\t\tonSettled: (task, usage) => {\n\t\t\t\tconst onBranch =\n\t\t\t\t\tmanager.getSessionId() === sessionId &&\n\t\t\t\t\t(task.anchorId === null || manager.getBranch().some((entry) => entry.id === task.anchorId));\n\t\t\t\tif (this.disposed || this.service !== service || !onBranch) {\n\t\t\t\t\tthis.quarantineSettlement({ sessionId, generation, task, usage }, sessionFile);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.persistSettlement(task, usage);\n\t\t\t},\n\t\t});\n\t\tthis.restoreHistory(service);\n\t\tservice.subscribe(() => this.schedule());\n\t\treturn service;\n\t}\n\n\trestoreHistory(service = this.service): void {\n\t\tservice.restoreHistory(\n\t\t\tthis.options.manager\n\t\t\t\t.getBranch()\n\t\t\t\t.flatMap((entry) =>\n\t\t\t\t\tentry.type === \"custom\" && entry.customType === \"background-task-result\" ? [entry.data] : [],\n\t\t\t\t),\n\t\t);\n\t}\n\n\tprivate quarantineSettlement(record: QuarantinedBackgroundSettlement, sessionFile: string | undefined): void {\n\t\t// Never move the active leaf to append late usage: JSONL's last entry also\n\t\t// selects its resumed branch. The sidecar is diagnostic evidence only.\n\t\tthis.quarantine.push(structuredClone(record));\n\t\tif (this.quarantine.length > 32) this.quarantine.shift();\n\t\tlet persistence =\n\t\t\t\"Not persisted: only the latest 32 snapshots are retained in quarantinedBackgroundSettlements; late usage is not accounted in session totals.\";\n\t\tif (sessionFile) {\n\t\t\ttry {\n\t\t\t\tmkdirSync(dirname(sessionFile), { recursive: true });\n\t\t\t\tappendFileSync(`${sessionFile}.background-late.jsonl`, `${JSON.stringify({ version: 1, ...record })}\\n`);\n\t\t\t\tpersistence = `Saved diagnostic sidecar: ${sessionFile}.background-late.jsonl (not included in normal session totals).`;\n\t\t\t} catch {\n\t\t\t\tpersistence = `Sidecar write failed. ${persistence}`;\n\t\t\t}\n\t\t}\n\t\tthis.warn(\n\t\t\t\"background_settlement_quarantined\",\n\t\t\t`Late background settlement ${record.task.id} was quarantined. ${persistence}`,\n\t\t);\n\t}\n\n\tprivate persistSettlement(task: BackgroundTask, usage: Usage | undefined): void {\n\t\tconst manager = this.options.manager;\n\t\tconst appended: SessionEntry[] = [];\n\t\tconst append = (customType: string, data: unknown) => {\n\t\t\tconst entry = manager.getEntry(manager.appendCustomEntry(customType, data));\n\t\t\tif (entry) appended.push(entry);\n\t\t};\n\t\ttry {\n\t\t\tif (usage && !manager.getEntries().some((entry) => getBackgroundUsageRecord(entry)?.taskId === task.id)) {\n\t\t\t\tappend(BACKGROUND_USAGE_TYPE, { version: 1, taskId: task.id, usage });\n\t\t\t}\n\t\t\tappend(\"background-task-result\", JSON.parse(JSON.stringify({ version: BACKGROUND_HISTORY_VERSION, task })));\n\t\t} finally {\n\t\t\t// Complete the writes before observers can replace the runtime or its manager.\n\t\t\t// If a write fails, still report entries that were successfully appended.\n\t\t\tfor (const entry of appended) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.options.onEntry(entry);\n\t\t\t\t} catch {\n\t\t\t\t\t// Observers cannot interrupt settlement or result publication.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate warn(event: string, message: string): void {\n\t\ttry {\n\t\t\tthis.options.onError(event, truncateHead(message, { maxBytes: 4096, maxLines: 32 }).content);\n\t\t} catch {\n\t\t\t// Diagnostics cannot reject settlement, cleanup or scheduled callbacks.\n\t\t}\n\t}\n\n\t/** Nestable across asynchronous preflight and service replacement. */\n\tpause(): () => void {\n\t\tthis.pauses++;\n\t\tconst releaseService = this.service.pause();\n\t\tlet released = false;\n\t\treturn () => {\n\t\t\tif (released) return;\n\t\t\treleased = true;\n\t\t\tthis.pauses--;\n\t\t\treleaseService();\n\t\t\tthis.schedule();\n\t\t};\n\t}\n\n\tretry(): void {\n\t\tthis.failures.clear();\n\t\tthis.schedule();\n\t}\n\n\tprivate schedule(): void {\n\t\tif (this.disposed || this.timer || this.delivery) return;\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.timer = undefined;\n\t\t\tvoid this.drain().catch(() =>\n\t\t\t\tthis.warn(\"background_delivery\", \"Background notification drain failed; delivery was not confirmed.\"),\n\t\t\t);\n\t\t}, 0);\n\t\tthis.timer.unref?.();\n\t}\n\n\tprivate canDeliver(service: BackgroundService): boolean {\n\t\treturn (\n\t\t\t!this.disposed && service === this.service && service.enabled && this.pauses === 0 && this.options.canDeliver()\n\t\t);\n\t}\n\n\tprivate async drain(): Promise<void> {\n\t\tconst service = this.service;\n\t\tif (this.delivery || !this.canDeliver(service)) return;\n\t\tif (this.failures.size) {\n\t\t\tconst retained = new Set(service.list().map((task) => task.id));\n\t\t\tfor (const id of this.failures) if (!retained.has(id)) this.failures.delete(id);\n\t\t}\n\t\tconst task = service.pendingNotifications().find((task) => !this.failures.has(task.id));\n\t\tif (!task) return;\n\t\tconst message = backgroundCompletionMessage(task);\n\t\tif (!service.claimNotification(task.id)) return;\n\t\t// Exactly one completion may be in flight, whether queued for steering or running its\n\t\t// own turn; there is no separate claim registry.\n\t\tconst delivery: Delivery = {\n\t\t\tid: task.id,\n\t\t\tservice,\n\t\t\tmessage,\n\t\t\tphase: \"pending\",\n\t\t};\n\t\tthis.delivery = delivery;\n\t\tlet deliveryError: unknown;\n\t\ttry {\n\t\t\tawait this.options.deliver(\n\t\t\t\tdelivery.message,\n\t\t\t\t() =>\n\t\t\t\t\tnew Promise<void>((resolve, reject) => {\n\t\t\t\t\t\tif (delivery.phase === \"persisted\") resolve();\n\t\t\t\t\t\telse delivery.queued = { resolve, reject };\n\t\t\t\t\t}),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tdeliveryError = error;\n\t\t} finally {\n\t\t\tif (delivery.phase !== \"persisted\") {\n\t\t\t\tservice.releaseNotification(task.id);\n\t\t\t\tif (service === this.service) this.failures.add(task.id);\n\t\t\t\tconst reason = deliveryError instanceof Error ? `: ${deliveryError.message}` : \"\";\n\t\t\t\tthis.warn(\n\t\t\t\t\t\"background_delivery\",\n\t\t\t\t\t`Background completion delivery failed for ${task.id}${reason}; it will retry on the next prompt.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.delivery = undefined;\n\t\t\tconst current = this.service;\n\t\t\tif (this.canDeliver(current) && current.pendingNotifications().some((task) => !this.failures.has(task.id)))\n\t\t\t\tthis.schedule();\n\t\t}\n\t}\n\n\t/** Record dequeueing before message hooks can fail or rewrite the notification. */\n\tmessageStarted(message: AgentMessage): void {\n\t\tconst delivery = this.delivery;\n\t\tif (delivery?.message === message && delivery.phase === \"pending\") delivery.phase = \"started\";\n\t}\n\n\t/** A queued message that was never emitted remains claimed for the next run. */\n\tagentEnded(): void {\n\t\tconst delivery = this.delivery;\n\t\tif (delivery?.phase === \"started\") {\n\t\t\tdelivery.queued?.reject(new Error(\"the completion message was not persisted\"));\n\t\t}\n\t}\n\n\tqueueCleared(): void {\n\t\tthis.delivery?.queued?.reject(new Error(\"the completion message was dequeued before delivery\"));\n\t}\n\n\t/** Acknowledge only successful appends, using identity even when metadata was rewritten. */\n\tmessagePersisted(message: AgentMessage): void {\n\t\tconst delivery = this.delivery;\n\t\tif (delivery?.message === message && delivery.phase !== \"persisted\") {\n\t\t\tdelivery.phase = \"persisted\";\n\t\t\tdelivery.service.markDelivered(delivery.id);\n\t\t\tdelivery.queued?.resolve();\n\t\t}\n\t\tif (message.role === \"toolResult\") this.acknowledgeWaitResult(message.details);\n\t}\n\n\t/** A wait result claims delivery only through its final, persisted marker. */\n\tprivate acknowledgeWaitResult(details: unknown): void {\n\t\tif (!details || typeof details !== \"object\" || !(\"backgroundTaskId\" in details)) return;\n\t\tconst id = details.backgroundTaskId;\n\t\tif (\n\t\t\ttypeof id === \"string\" &&\n\t\t\tthis.service\n\t\t\t\t.list()\n\t\t\t\t.some((task) => task.id === id && task.mode === \"background\" && isBackgroundTerminal(task.status))\n\t\t)\n\t\t\tthis.service.markDelivered(id);\n\t}\n\n\tdispose(): void {\n\t\tthis.disposed = true;\n\t\tthis.service.close();\n\t\tthis.delivery?.queued?.reject(new Error(\"the session was disposed\"));\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = undefined;\n\t}\n}\n"]}
|
|
@@ -20,27 +20,40 @@ export interface ContextSnapshot {
|
|
|
20
20
|
/** Includes provider hooks and header transforms, but never the main run's abort signal. */
|
|
21
21
|
streamOptions: ModelsSimpleStreamOptions;
|
|
22
22
|
}
|
|
23
|
+
/** What a session needs from the SDK to describe the request it would send next. */
|
|
24
|
+
export interface ContextSnapshotSource {
|
|
25
|
+
/** Prepare `messages` exactly as the next request would, reusing the recorded main prefix. */
|
|
26
|
+
prepareMessages(messages: AgentMessage[]): Promise<Message[]>;
|
|
27
|
+
/** The stream options the SDK would send for `model`, including provider hooks and header transforms. */
|
|
28
|
+
resolveStreamOptions(model: Model<Api>, options: ModelsSimpleStreamOptions): ModelsSimpleStreamOptions;
|
|
29
|
+
}
|
|
23
30
|
/**
|
|
24
31
|
* Records the actual pre-provider message prefix, after context hooks, the session's request
|
|
25
32
|
* projections, and image policy. A snapshot can reuse it and convert only newly settled
|
|
26
33
|
* messages. In particular, a time-dependent context hook is not rerun over an already
|
|
27
34
|
* prepared cache prefix.
|
|
35
|
+
*
|
|
36
|
+
* The SDK's own `convertToLlm` and request-option builder stay where upstream defines them;
|
|
37
|
+
* this class wraps the former and borrows the latter, so it never keeps a second copy of
|
|
38
|
+
* either.
|
|
28
39
|
*/
|
|
29
|
-
export declare class ContextSnapshotCapture {
|
|
40
|
+
export declare class ContextSnapshotCapture implements ContextSnapshotSource {
|
|
30
41
|
private readonly settings;
|
|
31
42
|
private readonly runnerRef;
|
|
43
|
+
private readonly buildRequestOptions;
|
|
32
44
|
private readonly pending;
|
|
33
45
|
private prepared;
|
|
46
|
+
private agent;
|
|
34
47
|
constructor(settings: SettingsManager, runnerRef: {
|
|
35
48
|
current?: ExtensionRunner;
|
|
36
|
-
});
|
|
49
|
+
}, buildRequestOptions: ContextSnapshotSource["resolveStreamOptions"]);
|
|
37
50
|
/**
|
|
38
51
|
* Record the source of every request context. Install after all other `transformContext`
|
|
39
52
|
* wrappers so the recorded prefix is exactly the array the request converts; a wrapper
|
|
40
53
|
* installed later would return a different array and the prefix would never be reused.
|
|
41
54
|
*/
|
|
42
55
|
install(agent: Agent): void;
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
resolveStreamOptions(model: Model<Api>, options: ModelsSimpleStreamOptions): ModelsSimpleStreamOptions;
|
|
57
|
+
prepareMessages(messages: AgentMessage[]): Promise<Message[]>;
|
|
45
58
|
}
|
|
46
59
|
//# sourceMappingURL=context-snapshot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-snapshot.d.ts","sourceRoot":"","sources":["../../src/core/context-snapshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACxF,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"context-snapshot.d.ts","sourceRoot":"","sources":["../../src/core/context-snapshot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACxF,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,oGAAoG;AACpG,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,4FAA4F;IAC5F,aAAa,EAAE,yBAAyB,CAAC;CACzC;AAED,oFAAoF;AACpF,MAAM,WAAW,qBAAqB;IACrC,8FAA8F;IAC9F,eAAe,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,yGAAyG;IACzG,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,yBAAyB,GAAG,yBAAyB,CAAC;CACvG;AAOD;;;;;;;;;GASG;AACH,qBAAa,sBAAuB,YAAW,qBAAqB;IACnE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAgD;IACpF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiD;IACzE,OAAO,CAAC,QAAQ,CAAoF;IACpG,OAAO,CAAC,KAAK,CAAoB;gBAGhC,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE;QAAE,OAAO,CAAC,EAAE,eAAe,CAAA;KAAE,EACxC,mBAAmB,EAAE,qBAAqB,CAAC,sBAAsB,CAAC;IAOnE;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IA6B3B,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,yBAAyB,GAAG,yBAAyB;IAIhG,eAAe,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAsBnE"}
|
|
@@ -1,63 +1,20 @@
|
|
|
1
1
|
import { isDeepStrictEqual } from "node:util";
|
|
2
|
-
import { convertToLlm } from "./messages.js";
|
|
3
|
-
function convertWithImagePolicy(messages, blockImages) {
|
|
4
|
-
const converted = convertToLlm(messages);
|
|
5
|
-
if (!blockImages)
|
|
6
|
-
return converted;
|
|
7
|
-
return converted.map((message) => {
|
|
8
|
-
if (message.role !== "user" && message.role !== "toolResult")
|
|
9
|
-
return message;
|
|
10
|
-
if (!Array.isArray(message.content) || !message.content.some((part) => part.type === "image"))
|
|
11
|
-
return message;
|
|
12
|
-
const content = message.content
|
|
13
|
-
.map((part) => (part.type === "image" ? { type: "text", text: "Image reading is disabled." } : part))
|
|
14
|
-
.filter((part, i, all) => !(part.type === "text" &&
|
|
15
|
-
part.text === "Image reading is disabled." &&
|
|
16
|
-
i > 0 &&
|
|
17
|
-
all[i - 1].type === "text" &&
|
|
18
|
-
all[i - 1].text === part.text));
|
|
19
|
-
return { ...message, content };
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
2
|
/**
|
|
23
3
|
* Records the actual pre-provider message prefix, after context hooks, the session's request
|
|
24
4
|
* projections, and image policy. A snapshot can reuse it and convert only newly settled
|
|
25
5
|
* messages. In particular, a time-dependent context hook is not rerun over an already
|
|
26
6
|
* prepared cache prefix.
|
|
7
|
+
*
|
|
8
|
+
* The SDK's own `convertToLlm` and request-option builder stay where upstream defines them;
|
|
9
|
+
* this class wraps the former and borrows the latter, so it never keeps a second copy of
|
|
10
|
+
* either.
|
|
27
11
|
*/
|
|
28
12
|
export class ContextSnapshotCapture {
|
|
29
|
-
constructor(settings, runnerRef) {
|
|
13
|
+
constructor(settings, runnerRef, buildRequestOptions) {
|
|
30
14
|
this.pending = new WeakMap();
|
|
31
|
-
this.convertToLlm = (messages) => {
|
|
32
|
-
const blockImages = this.settings.getBlockImages();
|
|
33
|
-
const converted = convertWithImagePolicy(messages, blockImages);
|
|
34
|
-
const source = this.pending.get(messages);
|
|
35
|
-
if (source) {
|
|
36
|
-
this.pending.delete(messages);
|
|
37
|
-
this.prepared = { source, messages: structuredClone(converted), blockImages };
|
|
38
|
-
}
|
|
39
|
-
return converted;
|
|
40
|
-
};
|
|
41
|
-
this.capture = async (messages) => {
|
|
42
|
-
const runner = this.runnerRef.current;
|
|
43
|
-
const blockImages = this.settings.getBlockImages();
|
|
44
|
-
const prepared = this.prepared;
|
|
45
|
-
if (prepared &&
|
|
46
|
-
prepared.source.runner === runner &&
|
|
47
|
-
prepared.blockImages === blockImages &&
|
|
48
|
-
isDeepStrictEqual(messages.slice(0, prepared.source.messages.length), prepared.source.messages)) {
|
|
49
|
-
return [
|
|
50
|
-
...structuredClone(prepared.messages),
|
|
51
|
-
...convertWithImagePolicy(messages.slice(prepared.source.messages.length), blockImages),
|
|
52
|
-
];
|
|
53
|
-
}
|
|
54
|
-
// No request yet, or the branch/context policy changed. Prepare this detached
|
|
55
|
-
// snapshot once; it never replaces the prefix recorded from the main request.
|
|
56
|
-
const transformed = runner ? await runner.emitContext(messages) : messages;
|
|
57
|
-
return structuredClone(convertWithImagePolicy(transformed, blockImages));
|
|
58
|
-
};
|
|
59
15
|
this.settings = settings;
|
|
60
16
|
this.runnerRef = runnerRef;
|
|
17
|
+
this.buildRequestOptions = buildRequestOptions;
|
|
61
18
|
}
|
|
62
19
|
/**
|
|
63
20
|
* Record the source of every request context. Install after all other `transformContext`
|
|
@@ -65,6 +22,7 @@ export class ContextSnapshotCapture {
|
|
|
65
22
|
* installed later would return a different array and the prefix would never be reused.
|
|
66
23
|
*/
|
|
67
24
|
install(agent) {
|
|
25
|
+
this.agent = agent;
|
|
68
26
|
const transform = agent.transformContext;
|
|
69
27
|
agent.transformContext = async (messages, signal) => {
|
|
70
28
|
const runner = this.runnerRef.current;
|
|
@@ -73,7 +31,47 @@ export class ContextSnapshotCapture {
|
|
|
73
31
|
this.pending.set(transformed, source);
|
|
74
32
|
return transformed;
|
|
75
33
|
};
|
|
76
|
-
|
|
34
|
+
const convert = agent.convertToLlm;
|
|
35
|
+
const record = (messages, converted) => {
|
|
36
|
+
const source = this.pending.get(messages);
|
|
37
|
+
if (source) {
|
|
38
|
+
this.pending.delete(messages);
|
|
39
|
+
this.prepared = {
|
|
40
|
+
source,
|
|
41
|
+
messages: structuredClone(converted),
|
|
42
|
+
blockImages: this.settings.getBlockImages(),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return converted;
|
|
46
|
+
};
|
|
47
|
+
agent.convertToLlm = (messages) => {
|
|
48
|
+
const converted = convert(messages);
|
|
49
|
+
return Array.isArray(converted) ? record(messages, converted) : converted.then((all) => record(messages, all));
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
resolveStreamOptions(model, options) {
|
|
53
|
+
return this.buildRequestOptions(model, options);
|
|
54
|
+
}
|
|
55
|
+
async prepareMessages(messages) {
|
|
56
|
+
const agent = this.agent;
|
|
57
|
+
if (!agent)
|
|
58
|
+
throw new Error("Context snapshot capture is not installed");
|
|
59
|
+
const runner = this.runnerRef.current;
|
|
60
|
+
const blockImages = this.settings.getBlockImages();
|
|
61
|
+
const prepared = this.prepared;
|
|
62
|
+
if (prepared &&
|
|
63
|
+
prepared.source.runner === runner &&
|
|
64
|
+
prepared.blockImages === blockImages &&
|
|
65
|
+
isDeepStrictEqual(messages.slice(0, prepared.source.messages.length), prepared.source.messages)) {
|
|
66
|
+
return [
|
|
67
|
+
...structuredClone(prepared.messages),
|
|
68
|
+
...(await agent.convertToLlm(messages.slice(prepared.source.messages.length))),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
// No request yet, or the branch/context policy changed. Prepare this detached
|
|
72
|
+
// snapshot once; it never replaces the prefix recorded from the main request.
|
|
73
|
+
const transformed = runner ? await runner.emitContext(messages) : messages;
|
|
74
|
+
return structuredClone(await agent.convertToLlm(transformed));
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
77
|
//# sourceMappingURL=context-snapshot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-snapshot.js","sourceRoot":"","sources":["../../src/core/context-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"context-snapshot.js","sourceRoot":"","sources":["../../src/core/context-snapshot.ts"],"names":[],"mappings":"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","sourcesContent":["import { isDeepStrictEqual } from \"node:util\";\nimport type { Agent, AgentMessage, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Message, Model, ModelsSimpleStreamOptions, Tool } from \"@earendil-works/pi-ai\";\nimport type { ExtensionRunner } from \"./extensions/runner.ts\";\nimport type { SettingsManager } from \"./settings-manager.ts\";\n\n/** Detached model input and request configuration. Contains no tool executors or session writer. */\nexport interface ContextSnapshot {\n\tcapturedAt: number;\n\tsessionId: string;\n\tleafId: string | null;\n\tmodel: Model<Api>;\n\tthinkingLevel: ThinkingLevel;\n\t/**\n\t * The prompt replayed from the prepared transcript, which is the text the provider received.\n\t * Before the first request it is the session's current prompt, which a consumer's Agent\n\t * declares itself when `messages` carry no system message.\n\t */\n\tsystemPrompt: string;\n\tmessages: Message[];\n\ttools: Tool[];\n\t/** Includes provider hooks and header transforms, but never the main run's abort signal. */\n\tstreamOptions: ModelsSimpleStreamOptions;\n}\n\n/** What a session needs from the SDK to describe the request it would send next. */\nexport interface ContextSnapshotSource {\n\t/** Prepare `messages` exactly as the next request would, reusing the recorded main prefix. */\n\tprepareMessages(messages: AgentMessage[]): Promise<Message[]>;\n\t/** The stream options the SDK would send for `model`, including provider hooks and header transforms. */\n\tresolveStreamOptions(model: Model<Api>, options: ModelsSimpleStreamOptions): ModelsSimpleStreamOptions;\n}\n\ninterface PreparedSource {\n\tmessages: AgentMessage[];\n\trunner: ExtensionRunner | undefined;\n}\n\n/**\n * Records the actual pre-provider message prefix, after context hooks, the session's request\n * projections, and image policy. A snapshot can reuse it and convert only newly settled\n * messages. In particular, a time-dependent context hook is not rerun over an already\n * prepared cache prefix.\n *\n * The SDK's own `convertToLlm` and request-option builder stay where upstream defines them;\n * this class wraps the former and borrows the latter, so it never keeps a second copy of\n * either.\n */\nexport class ContextSnapshotCapture implements ContextSnapshotSource {\n\tprivate readonly settings: SettingsManager;\n\tprivate readonly runnerRef: { current?: ExtensionRunner };\n\tprivate readonly buildRequestOptions: ContextSnapshotSource[\"resolveStreamOptions\"];\n\tprivate readonly pending = new WeakMap<AgentMessage[], PreparedSource>();\n\tprivate prepared: { source: PreparedSource; messages: Message[]; blockImages: boolean } | undefined;\n\tprivate agent: Agent | undefined;\n\n\tconstructor(\n\t\tsettings: SettingsManager,\n\t\trunnerRef: { current?: ExtensionRunner },\n\t\tbuildRequestOptions: ContextSnapshotSource[\"resolveStreamOptions\"],\n\t) {\n\t\tthis.settings = settings;\n\t\tthis.runnerRef = runnerRef;\n\t\tthis.buildRequestOptions = buildRequestOptions;\n\t}\n\n\t/**\n\t * Record the source of every request context. Install after all other `transformContext`\n\t * wrappers so the recorded prefix is exactly the array the request converts; a wrapper\n\t * installed later would return a different array and the prefix would never be reused.\n\t */\n\tinstall(agent: Agent): void {\n\t\tthis.agent = agent;\n\t\tconst transform = agent.transformContext;\n\t\tagent.transformContext = async (messages, signal) => {\n\t\t\tconst runner = this.runnerRef.current;\n\t\t\tconst source = { messages: structuredClone(messages), runner };\n\t\t\tconst transformed = transform ? await transform(messages, signal) : messages;\n\t\t\tthis.pending.set(transformed, source);\n\t\t\treturn transformed;\n\t\t};\n\t\tconst convert = agent.convertToLlm;\n\t\tconst record = (messages: AgentMessage[], converted: Message[]): Message[] => {\n\t\t\tconst source = this.pending.get(messages);\n\t\t\tif (source) {\n\t\t\t\tthis.pending.delete(messages);\n\t\t\t\tthis.prepared = {\n\t\t\t\t\tsource,\n\t\t\t\t\tmessages: structuredClone(converted),\n\t\t\t\t\tblockImages: this.settings.getBlockImages(),\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn converted;\n\t\t};\n\t\tagent.convertToLlm = (messages) => {\n\t\t\tconst converted = convert(messages);\n\t\t\treturn Array.isArray(converted) ? record(messages, converted) : converted.then((all) => record(messages, all));\n\t\t};\n\t}\n\n\tresolveStreamOptions(model: Model<Api>, options: ModelsSimpleStreamOptions): ModelsSimpleStreamOptions {\n\t\treturn this.buildRequestOptions(model, options);\n\t}\n\n\tasync prepareMessages(messages: AgentMessage[]): Promise<Message[]> {\n\t\tconst agent = this.agent;\n\t\tif (!agent) throw new Error(\"Context snapshot capture is not installed\");\n\t\tconst runner = this.runnerRef.current;\n\t\tconst blockImages = this.settings.getBlockImages();\n\t\tconst prepared = this.prepared;\n\t\tif (\n\t\t\tprepared &&\n\t\t\tprepared.source.runner === runner &&\n\t\t\tprepared.blockImages === blockImages &&\n\t\t\tisDeepStrictEqual(messages.slice(0, prepared.source.messages.length), prepared.source.messages)\n\t\t) {\n\t\t\treturn [\n\t\t\t\t...structuredClone(prepared.messages),\n\t\t\t\t...(await agent.convertToLlm(messages.slice(prepared.source.messages.length))),\n\t\t\t];\n\t\t}\n\t\t// No request yet, or the branch/context policy changed. Prepare this detached\n\t\t// snapshot once; it never replaces the prefix recorded from the main request.\n\t\tconst transformed = runner ? await runner.emitContext(messages) : messages;\n\t\treturn structuredClone(await agent.convertToLlm(transformed));\n\t}\n}\n"]}
|
|
@@ -29,13 +29,6 @@ export interface EditorHost {
|
|
|
29
29
|
/** Raw input only while the main editor has focus, without overlays or autocomplete. */
|
|
30
30
|
onInput(handler: TerminalInputHandler): () => void;
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Message thrown when a captured extension ctx/pi is used after the owning
|
|
34
|
-
* session was replaced (newSession/fork/switchSession/reload). Single source of
|
|
35
|
-
* truth so extensions can detect the condition with
|
|
36
|
-
* isStaleExtensionContextError instead of matching message text.
|
|
37
|
-
*/
|
|
38
|
-
export declare const STALE_EXTENSION_CONTEXT_MESSAGE = "This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().";
|
|
39
32
|
/** True when an error came from using a stale extension ctx/pi after session replacement. */
|
|
40
33
|
export declare function isStaleExtensionContextError(error: unknown): boolean;
|
|
41
34
|
//# sourceMappingURL=distribution-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distribution-api.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/distribution-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IACjC,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;CAC3B;AAED,0FAA0F;AAC1F,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC;AAEnH,0FAA0F;AAC1F,MAAM,WAAW,UAAU;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAAC;IACnD,kFAAkF;IAClF,SAAS,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD,wFAAwF;IACxF,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAAC;CACnD;
|
|
1
|
+
{"version":3,"file":"distribution-api.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/distribution-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IACjC,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;CAC3B;AAED,0FAA0F;AAC1F,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC;AAEnH,0FAA0F;AAC1F,MAAM,WAAW,UAAU;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAAC;IACnD,kFAAkF;IAClF,SAAS,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD,wFAAwF;IACxF,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAAC;CACnD;AAUD,6FAA6F;AAC7F,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpE"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* session was replaced (newSession/fork/switchSession/reload).
|
|
4
|
-
*
|
|
5
|
-
* isStaleExtensionContextError instead of matching
|
|
2
|
+
* Upstream words the error it throws when a captured extension ctx/pi is used after the owning
|
|
3
|
+
* session was replaced (newSession/fork/switchSession/reload) in three places. Recognize it by
|
|
4
|
+
* its stable opening rather than copying the whole message, so extensions can detect the
|
|
5
|
+
* condition with isStaleExtensionContextError instead of matching text themselves.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
const STALE_EXTENSION_CONTEXT_PREFIX = "This extension ctx is stale";
|
|
8
8
|
/** True when an error came from using a stale extension ctx/pi after session replacement. */
|
|
9
9
|
export function isStaleExtensionContextError(error) {
|
|
10
|
-
return error instanceof Error && error.message
|
|
10
|
+
return error instanceof Error && error.message.startsWith(STALE_EXTENSION_CONTEXT_PREFIX);
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=distribution-api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distribution-api.js","sourceRoot":"","sources":["../../../src/core/extensions/distribution-api.ts"],"names":[],"mappings":"AA8BA;;;;;GAKG;AACH,MAAM,
|
|
1
|
+
{"version":3,"file":"distribution-api.js","sourceRoot":"","sources":["../../../src/core/extensions/distribution-api.ts"],"names":[],"mappings":"AA8BA;;;;;GAKG;AACH,MAAM,8BAA8B,GAAG,6BAA6B,CAAC;AAErE,6FAA6F;AAC7F,MAAM,UAAU,4BAA4B,CAAC,KAAc;IAC1D,OAAO,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC;AAC3F,CAAC","sourcesContent":["/**\n * This distribution's additions to the extension API. `types.ts` re-exports them, so\n * extensions import them from the same place as the upstream API.\n */\nimport type { TerminalInputHandler } from \"./types.ts\";\n\nexport type { BackgroundContext } from \"../background/types.ts\";\nexport type { ContextSnapshot } from \"../context-snapshot.ts\";\nexport type { ModelRuntime } from \"../model-runtime.ts\";\n\nexport interface EditorSubmitEvent {\n\t/** Expanded, trimmed editor text, before history, command dispatch, or any main-agent queue. */\n\ttext: string;\n\tkind: \"prompt\" | \"command\" | \"bash\";\n\tmode: \"steer\" | \"followUp\";\n}\n\n/** Handlers must claim input synchronously; start asynchronous work after claiming it. */\nexport type EditorSubmitHandler = (event: EditorSubmitEvent) => { handled: true; editorText?: string } | undefined;\n\n/** Main-editor capabilities, present only where a host renders the interactive editor. */\nexport interface EditorHost {\n\t/** Intercept editor submissions, including during compaction. First claim wins. */\n\tonSubmit(handler: EditorSubmitHandler): () => void;\n\t/** Logical cursor position when the editor exposes it. Indices are zero-based. */\n\tgetCursor(): { line: number; col: number } | undefined;\n\t/** Raw input only while the main editor has focus, without overlays or autocomplete. */\n\tonInput(handler: TerminalInputHandler): () => void;\n}\n\n/**\n * Upstream words the error it throws when a captured extension ctx/pi is used after the owning\n * session was replaced (newSession/fork/switchSession/reload) in three places. Recognize it by\n * its stable opening rather than copying the whole message, so extensions can detect the\n * condition with isStaleExtensionContextError instead of matching text themselves.\n */\nconst STALE_EXTENSION_CONTEXT_PREFIX = \"This extension ctx is stale\";\n\n/** True when an error came from using a stale extension ctx/pi after session replacement. */\nexport function isStaleExtensionContextError(error: unknown): boolean {\n\treturn error instanceof Error && error.message.startsWith(STALE_EXTENSION_CONTEXT_PREFIX);\n}\n"]}
|
|
@@ -8,6 +8,6 @@ export { createExtensionRuntime, discoverAndLoadExtensions, loadExtensionFromFac
|
|
|
8
8
|
export type { ExtensionErrorListener, ForkHandler, NavigateTreeHandler, NewSessionHandler, ShutdownHandler, SwitchSessionHandler, } from "./runner.ts";
|
|
9
9
|
export { ExtensionRunner } from "./runner.ts";
|
|
10
10
|
export type { AfterProviderResponseEvent, AgentActivityOutcome, AgentBeforeSettleEvent, AgentBeforeSettleEventResult, AgentEndEvent, AgentSettledEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppendEntryHandler, AppKeybinding, AutocompleteProviderFactory, BashToolCallEvent, BashToolResultEvent, BeforeAgentStartEvent, BeforeAgentStartEventResult, BeforeProviderHeadersEvent, BeforeProviderRequestEvent, BeforeProviderRequestEventResult, BoundaryContextPreview, BoundaryResult, BoundaryState, BuildSystemPromptOptions, CacheWarmingDecisionEvent, CacheWarmingDecisionEventResult, CompactionEntryDraft, CompactOptions, ContextEditEntryDraft, ContextEvent, ContextEventResult, ContextSnapshot, ContextUsage, ContextWithSystemEvent, CustomEntryDraft, CustomMessageEntryDraft, CustomToolCallEvent, CustomToolResultEvent, EditorFactory, EditorHost, EditorSubmitEvent, EditorSubmitHandler, EditToolCallEvent, EditToolResultEvent, EntryRenderer, EntryRenderOptions, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFactory, ExtensionFlag, ExtensionHandler, ExtensionMode, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetOptions, FindToolCallEvent, FindToolResultEvent, GetActiveToolsHandler, GetAllToolsHandler, GetCommandsHandler, GetThinkingLevelHandler, GrepToolCallEvent, GrepToolResultEvent, InlineExtension, InputEvent, InputEventResult, InputSource, KeybindingsManager, LoadExtensionsResult, LsToolCallEvent, LsToolResultEvent, MarkdownTransformContext, MarkdownTransformer, MessageEndEvent, MessageEndEventResult, MessageRenderer, MessageRenderOptions, MessageStartEvent, MessageUpdateEvent, ModelSelectEvent, ModelSelectSource, NormalizedBuildSystemPromptOptions, PowerShellToolCallEvent, PowerShellToolResultEvent, ProjectTrustContext, ProjectTrustEvent, ProjectTrustEventDecision, ProjectTrustEventResult, ProjectTrustHandler, ProviderConfig, ProviderModelConfig, ReadToolCallEvent, ReadToolResultEvent, RegisteredCommand, RegisteredTool, ReplacedSessionContext, ResolvedCommand, ResourcesDiscoverEvent, ResourcesDiscoverResult, SendMessageHandler, SendUserMessageHandler, SessionBeforeCompactEvent, SessionBeforeCompactResult, SessionBeforeForkEvent, SessionBeforeForkResult, SessionBeforeSwitchEvent, SessionBeforeSwitchResult, SessionBeforeTreeEvent, SessionBeforeTreeResult, SessionBoundaryDraft, SessionCompactEvent, SessionCompactFailedEvent, SessionEvent, SessionInfoChangedEvent, SessionShutdownEvent, SessionStartEvent, SessionTreeEvent, SetActiveToolsHandler, SetLabelHandler, SetModelHandler, SetThinkingLevelHandler, TerminalInputHandler, ThinkingLevelSelectEvent, ToolCallEvent, ToolCallEventResult, ToolDefinition, ToolExecutionEndEvent, ToolExecutionMode, ToolExecutionStartEvent, ToolExecutionUpdateEvent, ToolInfo, ToolRenderResultOptions, ToolResultEvent, ToolResultEventResult, TreePreparation, TurnEndEvent, TurnEndEventResult, TurnStartEvent, UIPromptEndEvent, UIPromptKind, UIPromptStartEvent, UserBashEvent, UserBashEventResult, WidgetPlacement, WorkingIndicatorOptions, WriteToolCallEvent, WriteToolResultEvent, } from "./types.ts";
|
|
11
|
-
export { defineTool, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isPowerShellToolResult, isReadToolResult, isStaleExtensionContextError, isToolCallEventType, isWriteToolResult,
|
|
11
|
+
export { defineTool, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isPowerShellToolResult, isReadToolResult, isStaleExtensionContextError, isToolCallEventType, isWriteToolResult, } from "./types.ts";
|
|
12
12
|
export { wrapRegisteredTool, wrapRegisteredTools } from "./wrapper.ts";
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
export { createExtensionRuntime, discoverAndLoadExtensions, loadExtensionFromFactory, loadExtensions, } from "./loader.js";
|
|
5
5
|
export { ExtensionRunner } from "./runner.js";
|
|
6
6
|
// Type guards
|
|
7
|
-
export { defineTool, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isPowerShellToolResult, isReadToolResult, isStaleExtensionContextError, isToolCallEventType, isWriteToolResult,
|
|
7
|
+
export { defineTool, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isPowerShellToolResult, isReadToolResult, isStaleExtensionContextError, isToolCallEventType, isWriteToolResult, } from "./types.js";
|
|
8
8
|
export { wrapRegisteredTool, wrapRegisteredTools } from "./wrapper.js";
|
|
9
9
|
//# sourceMappingURL=index.js.map
|