@moxt-ai/mobius 0.0.299 → 0.0.301
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/dist/acp/harness/claude/endpoint.d.ts.map +1 -1
- package/dist/acp/harness/claude/endpoint.js +2 -0
- package/dist/acp/harness/claude/endpoint.js.map +1 -1
- package/dist/acp/harness/claude/parent-lifeline.d.ts +3 -0
- package/dist/acp/harness/claude/parent-lifeline.d.ts.map +1 -0
- package/dist/acp/harness/claude/parent-lifeline.js +73 -0
- package/dist/acp/harness/claude/parent-lifeline.js.map +1 -0
- package/dist/acp/harness/codex/settings.d.ts.map +1 -1
- package/dist/acp/harness/codex/settings.js +4 -0
- package/dist/acp/harness/codex/settings.js.map +1 -1
- package/dist/acp/harness/pi/endpoint.d.ts.map +1 -1
- package/dist/acp/harness/pi/endpoint.js +1 -0
- package/dist/acp/harness/pi/endpoint.js.map +1 -1
- package/dist/acp/native-history/codex/native-history-events.d.ts.map +1 -1
- package/dist/acp/native-history/codex/native-history-events.js +10 -0
- package/dist/acp/native-history/codex/native-history-events.js.map +1 -1
- package/dist/cli.js +604 -60
- package/dist/cli.js.map +4 -4
- package/dist/generated/acp-session-store-migrations.d.ts +3 -0
- package/dist/generated/acp-session-store-migrations.d.ts.map +1 -1
- package/dist/generated/acp-session-store-migrations.js +5 -1
- package/dist/generated/acp-session-store-migrations.js.map +1 -1
- package/dist/runtime/command/registry/prompt.d.ts.map +1 -1
- package/dist/runtime/command/registry/prompt.js +6 -0
- package/dist/runtime/command/registry/prompt.js.map +1 -1
- package/dist/runtime/engine.d.ts +1 -0
- package/dist/runtime/engine.d.ts.map +1 -1
- package/dist/runtime/engine.js +8 -0
- package/dist/runtime/engine.js.map +1 -1
- package/dist/runtime/run.d.ts +1 -0
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +3 -0
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime.js +569 -53
- package/dist/runtime.js.map +4 -4
- package/dist/schema/acp-session-store/execution-receipt.d.ts +136 -0
- package/dist/schema/acp-session-store/execution-receipt.d.ts.map +1 -0
- package/dist/schema/acp-session-store/execution-receipt.js +12 -0
- package/dist/schema/acp-session-store/execution-receipt.js.map +1 -0
- package/dist/schema/acp-session-store/index.d.ts +1 -0
- package/dist/schema/acp-session-store/index.d.ts.map +1 -1
- package/dist/schema/acp-session-store/index.js +1 -0
- package/dist/schema/acp-session-store/index.js.map +1 -1
- package/dist/session/api/session-api.d.ts +4 -0
- package/dist/session/api/session-api.d.ts.map +1 -1
- package/dist/session/api/session-api.js.map +1 -1
- package/dist/session/api/session-layer.d.ts +2 -0
- package/dist/session/api/session-layer.d.ts.map +1 -1
- package/dist/session/api/session-layer.js +25 -4
- package/dist/session/api/session-layer.js.map +1 -1
- package/dist/session/history/session-event-store.d.ts +7 -4
- package/dist/session/history/session-event-store.d.ts.map +1 -1
- package/dist/session/history/session-event-store.js +13 -7
- package/dist/session/history/session-event-store.js.map +1 -1
- package/dist/session/history/session-history.d.ts +1 -4
- package/dist/session/history/session-history.d.ts.map +1 -1
- package/dist/session/history/session-history.js +1 -4
- package/dist/session/history/session-history.js.map +1 -1
- package/dist/session/live/agent-session-restore.d.ts +1 -0
- package/dist/session/live/agent-session-restore.d.ts.map +1 -1
- package/dist/session/live/agent-session.d.ts +2 -0
- package/dist/session/live/agent-session.d.ts.map +1 -1
- package/dist/session/live/agent-session.js +15 -4
- package/dist/session/live/agent-session.js.map +1 -1
- package/dist/session/live/session-restore.d.ts.map +1 -1
- package/dist/session/live/session-restore.js +37 -0
- package/dist/session/live/session-restore.js.map +1 -1
- package/dist/session/manager/session-manager.d.ts.map +1 -1
- package/dist/session/manager/session-manager.js +11 -3
- package/dist/session/manager/session-manager.js.map +1 -1
- package/dist/session/prompt/execute-prompt.d.ts.map +1 -1
- package/dist/session/prompt/execute-prompt.js +6 -1
- package/dist/session/prompt/execute-prompt.js.map +1 -1
- package/dist/session/prompt/prompt-lifecycle.d.ts +1 -0
- package/dist/session/prompt/prompt-lifecycle.d.ts.map +1 -1
- package/dist/session/prompt/prompt-lifecycle.js +9 -1
- package/dist/session/prompt/prompt-lifecycle.js.map +1 -1
- package/dist/session/turn/execution-receipts.d.ts +23 -2
- package/dist/session/turn/execution-receipts.d.ts.map +1 -1
- package/dist/session/turn/execution-receipts.js +161 -10
- package/dist/session/turn/execution-receipts.js.map +1 -1
- package/dist/storage/session/execution-receipt-table.d.ts +45 -0
- package/dist/storage/session/execution-receipt-table.d.ts.map +1 -0
- package/dist/storage/session/execution-receipt-table.js +64 -0
- package/dist/storage/session/execution-receipt-table.js.map +1 -0
- package/package.json +2 -2
package/dist/runtime.js
CHANGED
|
@@ -21633,6 +21633,10 @@ var SessionPromptDisposition = Object.freeze({
|
|
|
21633
21633
|
Reject: "reject",
|
|
21634
21634
|
Steer: "steer"
|
|
21635
21635
|
});
|
|
21636
|
+
var SessionHistoryPolicy = Object.freeze({
|
|
21637
|
+
Eager: "eager",
|
|
21638
|
+
ExecutionOnly: "execution-only"
|
|
21639
|
+
});
|
|
21636
21640
|
var MAX_PROMPT_LENGTH = 1e5;
|
|
21637
21641
|
var MAX_PROMPT_ATTACHMENT_LENGTH = 6e6;
|
|
21638
21642
|
var promptImageSchema = external_exports.object({
|
|
@@ -21694,6 +21698,9 @@ function decodeSessionPromptCommand(encoded) {
|
|
|
21694
21698
|
directoryId: readDirectoryIdentifier(value, "directoryId"),
|
|
21695
21699
|
disposition,
|
|
21696
21700
|
images,
|
|
21701
|
+
...value["historyPolicy"] === void 0 ? {} : {
|
|
21702
|
+
historyPolicy: readHistoryPolicy(value)
|
|
21703
|
+
},
|
|
21697
21704
|
kind: SESSION_PROMPT_KIND,
|
|
21698
21705
|
prompt,
|
|
21699
21706
|
resources,
|
|
@@ -21702,6 +21709,13 @@ function decodeSessionPromptCommand(encoded) {
|
|
|
21702
21709
|
targetCommandId
|
|
21703
21710
|
};
|
|
21704
21711
|
}
|
|
21712
|
+
function readHistoryPolicy(value) {
|
|
21713
|
+
const field = value["historyPolicy"];
|
|
21714
|
+
if (field === SessionHistoryPolicy.Eager || field === SessionHistoryPolicy.ExecutionOnly) {
|
|
21715
|
+
return field;
|
|
21716
|
+
}
|
|
21717
|
+
throw new ProtocolMessageError("Invalid value field: historyPolicy");
|
|
21718
|
+
}
|
|
21705
21719
|
function decodeSessionCancelCommand(encoded) {
|
|
21706
21720
|
const value = parseJson(encoded);
|
|
21707
21721
|
assertKind(value, SESSION_CANCEL_KIND);
|
|
@@ -22627,16 +22641,28 @@ import { fetch as fetch3 } from "undici";
|
|
|
22627
22641
|
// package.json
|
|
22628
22642
|
var package_default = {
|
|
22629
22643
|
name: "@moxt-ai/mobius",
|
|
22630
|
-
version: "0.0.
|
|
22644
|
+
version: "0.0.301",
|
|
22631
22645
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
22632
22646
|
type: "module",
|
|
22633
22647
|
bin: {
|
|
22634
22648
|
mobius: "dist/cli.js"
|
|
22635
22649
|
},
|
|
22636
22650
|
exports: {
|
|
22637
|
-
"./runtime":
|
|
22638
|
-
|
|
22639
|
-
|
|
22651
|
+
"./runtime": {
|
|
22652
|
+
"mobius-source": "./src/runtime.ts",
|
|
22653
|
+
types: "./dist/runtime.d.ts",
|
|
22654
|
+
default: "./dist/runtime.js"
|
|
22655
|
+
},
|
|
22656
|
+
"./process": {
|
|
22657
|
+
"mobius-source": "./src/util/process/executable.ts",
|
|
22658
|
+
types: "./dist/util/process/executable.d.ts",
|
|
22659
|
+
default: "./dist/util/process/executable.js"
|
|
22660
|
+
},
|
|
22661
|
+
"./filesystem": {
|
|
22662
|
+
"mobius-source": "./src/util/filesystem/private-path.ts",
|
|
22663
|
+
types: "./dist/util/filesystem/private-path.d.ts",
|
|
22664
|
+
default: "./dist/util/filesystem/private-path.js"
|
|
22665
|
+
}
|
|
22640
22666
|
},
|
|
22641
22667
|
files: [
|
|
22642
22668
|
"dist"
|
|
@@ -22718,6 +22744,78 @@ var package_default = {
|
|
|
22718
22744
|
homepage: "https://github.com/moxt-ai/mobius#readme"
|
|
22719
22745
|
};
|
|
22720
22746
|
|
|
22747
|
+
// src/acp/harness/claude/parent-lifeline.ts
|
|
22748
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
22749
|
+
import { Duplex } from "node:stream";
|
|
22750
|
+
var supervisor = `
|
|
22751
|
+
const { spawn, spawnSync } = require("node:child_process");
|
|
22752
|
+
const { Socket } = require("node:net");
|
|
22753
|
+
const [command, ...args] = process.argv.slice(1);
|
|
22754
|
+
const child = spawn(command, args, { stdio: ["pipe", "pipe", "pipe"], detached: process.platform !== "win32", windowsHide: true });
|
|
22755
|
+
const lifeline = new Socket({ fd: 3, readable: true, writable: false });
|
|
22756
|
+
let exited = false;
|
|
22757
|
+
function terminate() {
|
|
22758
|
+
if (exited || child.pid === undefined) return;
|
|
22759
|
+
if (process.platform === "win32") {
|
|
22760
|
+
spawnSync("taskkill", ["/pid", String(child.pid), "/T", "/F"], { timeout: 5000, windowsHide: true, stdio: "ignore" });
|
|
22761
|
+
} else {
|
|
22762
|
+
try { process.kill(-child.pid, "SIGKILL"); }
|
|
22763
|
+
catch (error) { if (error.code !== "ESRCH") throw error; }
|
|
22764
|
+
}
|
|
22765
|
+
}
|
|
22766
|
+
lifeline.on("end", terminate).on("error", terminate).resume();
|
|
22767
|
+
process.on("SIGTERM", terminate).on("SIGINT", terminate);
|
|
22768
|
+
process.stdin.pipe(child.stdin);
|
|
22769
|
+
child.stdin.on("error", () => {});
|
|
22770
|
+
child.stdout.pipe(process.stdout);
|
|
22771
|
+
child.stderr.pipe(process.stderr);
|
|
22772
|
+
child.once("error", (error) => { process.stderr.write(error.message); process.exitCode = 1; lifeline.destroy(); process.stdin.destroy(); });
|
|
22773
|
+
child.once("close", (code) => { exited = true; process.exitCode = code ?? 1; lifeline.destroy(); process.stdin.destroy(); });
|
|
22774
|
+
`;
|
|
22775
|
+
function spawnClaudeWithParentLifeline(options) {
|
|
22776
|
+
options.signal.throwIfAborted();
|
|
22777
|
+
const child = spawn2(process.execPath, ["-e", supervisor, "--", options.command, ...options.args], {
|
|
22778
|
+
cwd: options.cwd,
|
|
22779
|
+
env: options.env,
|
|
22780
|
+
stdio: ["pipe", "pipe", "pipe", "pipe"],
|
|
22781
|
+
windowsHide: true
|
|
22782
|
+
});
|
|
22783
|
+
const lifeline = child.stdio[3];
|
|
22784
|
+
if (child.stdin === null || child.stdout === null || child.stderr === null || !(lifeline instanceof Duplex)) {
|
|
22785
|
+
child.kill("SIGKILL");
|
|
22786
|
+
throw new Error("The Claude process supervisor has no parent lifeline");
|
|
22787
|
+
}
|
|
22788
|
+
let termination = "running";
|
|
22789
|
+
const stop = () => {
|
|
22790
|
+
termination = "requested";
|
|
22791
|
+
lifeline.end();
|
|
22792
|
+
return true;
|
|
22793
|
+
};
|
|
22794
|
+
options.signal.addEventListener("abort", stop, { once: true });
|
|
22795
|
+
if (options.signal.aborted) {
|
|
22796
|
+
stop();
|
|
22797
|
+
}
|
|
22798
|
+
child.once("close", () => options.signal.removeEventListener("abort", stop));
|
|
22799
|
+
child.stderr.pipe(process.stderr, { end: false });
|
|
22800
|
+
return {
|
|
22801
|
+
stdin: child.stdin,
|
|
22802
|
+
stdout: child.stdout,
|
|
22803
|
+
get killed() {
|
|
22804
|
+
return termination === "requested";
|
|
22805
|
+
},
|
|
22806
|
+
get exitCode() {
|
|
22807
|
+
return child.exitCode;
|
|
22808
|
+
},
|
|
22809
|
+
get signalCode() {
|
|
22810
|
+
return child.signalCode;
|
|
22811
|
+
},
|
|
22812
|
+
kill: stop,
|
|
22813
|
+
on: child.on.bind(child),
|
|
22814
|
+
once: child.once.bind(child),
|
|
22815
|
+
off: child.off.bind(child)
|
|
22816
|
+
};
|
|
22817
|
+
}
|
|
22818
|
+
|
|
22721
22819
|
// src/acp/harness/claude/upstream/dist/acp-agent.js
|
|
22722
22820
|
import { execFile as execFile3 } from "node:child_process";
|
|
22723
22821
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
@@ -62438,6 +62536,7 @@ async function waitForMcpAuthentication(sessions, sessionId, query, serverName,
|
|
|
62438
62536
|
return false;
|
|
62439
62537
|
}
|
|
62440
62538
|
var ClaudeAcpAgent = class {
|
|
62539
|
+
spawnClaudeCodeProcess;
|
|
62441
62540
|
sessions;
|
|
62442
62541
|
client;
|
|
62443
62542
|
clientCapabilities;
|
|
@@ -62454,7 +62553,8 @@ var ClaudeAcpAgent = class {
|
|
|
62454
62553
|
* return "cancelled". See {@link DEFAULT_FORCE_CANCEL_GRACE_MS}. Mutable so
|
|
62455
62554
|
* tests can shrink it. */
|
|
62456
62555
|
forceCancelGraceMs = DEFAULT_FORCE_CANCEL_GRACE_MS;
|
|
62457
|
-
constructor(client2, logger, environment = process.env) {
|
|
62556
|
+
constructor(client2, logger, environment = process.env, spawnClaudeCodeProcess) {
|
|
62557
|
+
this.spawnClaudeCodeProcess = spawnClaudeCodeProcess;
|
|
62458
62558
|
this.sessions = {};
|
|
62459
62559
|
this.client = client2;
|
|
62460
62560
|
this.logger = logger ?? console;
|
|
@@ -65031,6 +65131,7 @@ ${message.api_refusal_explanation}` : "";
|
|
|
65031
65131
|
supportedDialogKinds: [REFUSAL_FALLBACK_DIALOG_KIND]
|
|
65032
65132
|
} : {},
|
|
65033
65133
|
pathToClaudeCodeExecutable: this.environment.CLAUDE_CODE_EXECUTABLE ?? await claudeCliPath(),
|
|
65134
|
+
...this.spawnClaudeCodeProcess === void 0 ? {} : { spawnClaudeCodeProcess: this.spawnClaudeCodeProcess },
|
|
65034
65135
|
extraArgs: {
|
|
65035
65136
|
...userProvidedOptions?.extraArgs,
|
|
65036
65137
|
"replay-user-messages": ""
|
|
@@ -66449,7 +66550,7 @@ async function runPromptWithCancellation(agent, params, signal) {
|
|
|
66449
66550
|
function createClaudeAcpApp(options = {}) {
|
|
66450
66551
|
let agent = null;
|
|
66451
66552
|
const app = acpAgent({ name: "claude-code-acp" }).onConnect((connection) => {
|
|
66452
|
-
agent = new ClaudeAcpAgent(new ClientConnection(connection.client, options.onSessionUpdate), options.logger, options.environment);
|
|
66553
|
+
agent = new ClaudeAcpAgent(new ClientConnection(connection.client, options.onSessionUpdate), options.logger, options.environment, options.spawnClaudeCodeProcess);
|
|
66453
66554
|
options.onConnect?.(connection);
|
|
66454
66555
|
}).onRequest(methods.agent.initialize, (ctx) => requiredAgent(agent).initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => requiredAgent(agent).newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => requiredAgent(agent).loadSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.fork, (ctx) => requiredAgent(agent).unstable_forkSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.list, (ctx) => requiredAgent(agent).listSessions(ctx.params, ctx.signal)).onRequest(methods.agent.session.delete, (ctx) => requiredAgent(agent).deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => requiredAgent(agent).resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => requiredAgent(agent).closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => requiredAgent(agent).setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => requiredAgent(agent).setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => requiredAgent(agent).authenticate(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => requiredAgent(agent).unstable_listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => requiredAgent(agent).unstable_setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => requiredAgent(agent).unstable_disableProvider(ctx.params)).onRequest(methods.agent.logout, (ctx) => requiredAgent(agent).logout(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => runPromptWithCancellation(requiredAgent(agent), ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => requiredAgent(agent).cancel(ctx.params)).onRequest(STEER_METHOD, { parse: parseSteerRequest }, (ctx) => requiredAgent(agent).steer(ctx.params)).onRequest(RENAME_METHOD, { parse: parseRenameRequest }, (ctx) => requiredAgent(agent).renameSession(ctx.params)).onRequest(GOAL_CONTROL_METHOD, { parse: parseGoalRequest }, (ctx) => requiredAgent(agent).goal(ctx.params));
|
|
66455
66556
|
return { agent: () => agent, app };
|
|
@@ -66574,6 +66675,7 @@ var ClaudeAcpEndpoint = class {
|
|
|
66574
66675
|
this.terminated = termination.promise;
|
|
66575
66676
|
this.#resolveTermination = termination.resolve;
|
|
66576
66677
|
const claude = createClaudeAcpApp({
|
|
66678
|
+
spawnClaudeCodeProcess: spawnClaudeWithParentLifeline,
|
|
66577
66679
|
environment: Object.freeze({
|
|
66578
66680
|
...process.env,
|
|
66579
66681
|
...options.environment,
|
|
@@ -66724,7 +66826,7 @@ var AcpConfigurationValueUnavailableError = class extends AcpExecutionError {
|
|
|
66724
66826
|
};
|
|
66725
66827
|
|
|
66726
66828
|
// src/acp/harness/codex/app-server-client.ts
|
|
66727
|
-
import { spawn as
|
|
66829
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
66728
66830
|
|
|
66729
66831
|
// src/acp/agent/in-process-endpoint.ts
|
|
66730
66832
|
function acpEndpointTerminationError(termination) {
|
|
@@ -67057,7 +67159,7 @@ var CodexAppServerClient = class {
|
|
|
67057
67159
|
constructor(options) {
|
|
67058
67160
|
this.#handlers = options.handlers;
|
|
67059
67161
|
const launch = executableLaunch2(options.command, ["app-server"]);
|
|
67060
|
-
this.#child =
|
|
67162
|
+
this.#child = spawn4(launch.command, [...launch.arguments], {
|
|
67061
67163
|
cwd: options.cwd,
|
|
67062
67164
|
...platformSpawnOptions,
|
|
67063
67165
|
env: { ...process.env, ...options.environment },
|
|
@@ -67444,12 +67546,12 @@ function presentToolItem(item) {
|
|
|
67444
67546
|
};
|
|
67445
67547
|
}
|
|
67446
67548
|
if (item.type === "collabAgentToolCall") {
|
|
67447
|
-
const
|
|
67549
|
+
const spawn9 = item.tool === "spawnAgent";
|
|
67448
67550
|
return {
|
|
67449
67551
|
content: [],
|
|
67450
67552
|
kind: "other",
|
|
67451
67553
|
locations: [],
|
|
67452
|
-
rawInput:
|
|
67554
|
+
rawInput: spawn9 ? {
|
|
67453
67555
|
model: item.model,
|
|
67454
67556
|
prompt: item.prompt,
|
|
67455
67557
|
reasoningEffort: item.reasoningEffort,
|
|
@@ -67457,10 +67559,10 @@ function presentToolItem(item) {
|
|
|
67457
67559
|
} : { receiverThreadIds: item.receiverThreadIds, senderThreadId: item.senderThreadId },
|
|
67458
67560
|
rawOutput: {
|
|
67459
67561
|
agentsStates: item.agentsStates,
|
|
67460
|
-
...
|
|
67562
|
+
...spawn9 ? { receiverThreadIds: item.receiverThreadIds } : {}
|
|
67461
67563
|
},
|
|
67462
67564
|
status: collaborationStatus(item.status),
|
|
67463
|
-
title:
|
|
67565
|
+
title: spawn9 ? "Dispatch subagent" : "Wait for subagent"
|
|
67464
67566
|
};
|
|
67465
67567
|
}
|
|
67466
67568
|
if (item.type === "subAgentActivity" && item.kind === "started") {
|
|
@@ -68629,6 +68731,10 @@ var CodexSettings = class {
|
|
|
68629
68731
|
approvalPolicy: mode.approvalPolicy,
|
|
68630
68732
|
approvalsReviewer: mode.approvalsReviewer,
|
|
68631
68733
|
sandboxPolicy: mode.sandboxPolicy,
|
|
68734
|
+
// Codex only streams its provider-authored reasoning summary when the turn opts in.
|
|
68735
|
+
// Keep the summary channel enabled so Thinking has visible content even when no raw
|
|
68736
|
+
// reasoning text is available.
|
|
68737
|
+
summary: "auto",
|
|
68632
68738
|
// The collaboration mode rides on the turn: Codex applies it to the
|
|
68633
68739
|
// thread, where it persists until changed. "Build" is Codex's `default`
|
|
68634
68740
|
// mode, so it is only sent once a choice exists to apply.
|
|
@@ -69221,7 +69327,7 @@ import { basename as basename4, dirname as dirname7, isAbsolute as isAbsolute11,
|
|
|
69221
69327
|
import { RequestError as RequestError7 } from "@agentclientprotocol/sdk";
|
|
69222
69328
|
|
|
69223
69329
|
// src/acp/harness/pi/upstream/dist/pi-rpc/process.js
|
|
69224
|
-
import { spawn as
|
|
69330
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
69225
69331
|
import * as readline from "node:readline";
|
|
69226
69332
|
|
|
69227
69333
|
// src/acp/harness/pi/upstream/dist/pi-rpc/command.js
|
|
@@ -69338,7 +69444,7 @@ var PiRpcProcess = class _PiRpcProcess {
|
|
|
69338
69444
|
args.push("--fork", params.origin.sessionPath);
|
|
69339
69445
|
break;
|
|
69340
69446
|
}
|
|
69341
|
-
const child =
|
|
69447
|
+
const child = spawn5(cmd, args, {
|
|
69342
69448
|
cwd: params.cwd,
|
|
69343
69449
|
stdio: "pipe",
|
|
69344
69450
|
env: params.environment,
|
|
@@ -72338,6 +72444,77 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
72338
72444
|
}, 0);
|
|
72339
72445
|
return { sessionId: session.sessionId, configOptions, modes };
|
|
72340
72446
|
}
|
|
72447
|
+
async resumeSession(params) {
|
|
72448
|
+
if (!isAbsolute11(params.cwd)) {
|
|
72449
|
+
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
72450
|
+
}
|
|
72451
|
+
this.sessions.close(params.sessionId);
|
|
72452
|
+
this.lastSessionCwd = params.cwd;
|
|
72453
|
+
const stored = this.findStoredSession(params.sessionId);
|
|
72454
|
+
if (!stored) {
|
|
72455
|
+
throw RequestError7.invalidParams(`Unknown sessionId: ${params.sessionId}`);
|
|
72456
|
+
}
|
|
72457
|
+
const session = await this.restoreSession(params.sessionId, {
|
|
72458
|
+
cwd: params.cwd,
|
|
72459
|
+
mcpServers: params.mcpServers
|
|
72460
|
+
});
|
|
72461
|
+
let configuration;
|
|
72462
|
+
try {
|
|
72463
|
+
configuration = await getSessionConfiguration(session.proc);
|
|
72464
|
+
} catch (err) {
|
|
72465
|
+
this.sessions.close(session.sessionId);
|
|
72466
|
+
throw err;
|
|
72467
|
+
}
|
|
72468
|
+
const { configOptions, models, modes } = configuration;
|
|
72469
|
+
const enableSkillCommands = getEnableSkillCommands(params.cwd, this.environment);
|
|
72470
|
+
const fileCommands = loadSlashCommands(params.cwd, this.environment);
|
|
72471
|
+
this.sessions.closeAllExcept?.(session.sessionId);
|
|
72472
|
+
this.store.upsert({
|
|
72473
|
+
sessionId: params.sessionId,
|
|
72474
|
+
cwd: params.cwd,
|
|
72475
|
+
sessionFile: stored.sessionFile
|
|
72476
|
+
});
|
|
72477
|
+
const response = {
|
|
72478
|
+
configOptions,
|
|
72479
|
+
models,
|
|
72480
|
+
modes,
|
|
72481
|
+
_meta: {
|
|
72482
|
+
piAcp: {
|
|
72483
|
+
startupInfo: null
|
|
72484
|
+
}
|
|
72485
|
+
}
|
|
72486
|
+
};
|
|
72487
|
+
setTimeout(() => {
|
|
72488
|
+
void (async () => {
|
|
72489
|
+
await session.publishContextUsage();
|
|
72490
|
+
try {
|
|
72491
|
+
const pi2 = await session.proc.getCommands();
|
|
72492
|
+
const { commands } = toAvailableCommandsFromPiGetCommands(pi2, {
|
|
72493
|
+
enableSkillCommands,
|
|
72494
|
+
includeExtensionCommands: false
|
|
72495
|
+
});
|
|
72496
|
+
await this.conn.sessionUpdate({
|
|
72497
|
+
sessionId: session.sessionId,
|
|
72498
|
+
update: {
|
|
72499
|
+
sessionUpdate: "available_commands_update",
|
|
72500
|
+
availableCommands: mergeCommands(commands, builtinAvailableCommands())
|
|
72501
|
+
}
|
|
72502
|
+
});
|
|
72503
|
+
return;
|
|
72504
|
+
} catch {
|
|
72505
|
+
}
|
|
72506
|
+
await this.conn.sessionUpdate({
|
|
72507
|
+
sessionId: session.sessionId,
|
|
72508
|
+
update: {
|
|
72509
|
+
sessionUpdate: "available_commands_update",
|
|
72510
|
+
availableCommands: mergeCommands(toAvailableCommands(fileCommands), builtinAvailableCommands())
|
|
72511
|
+
}
|
|
72512
|
+
});
|
|
72513
|
+
})().catch(() => {
|
|
72514
|
+
});
|
|
72515
|
+
}, 0);
|
|
72516
|
+
return response;
|
|
72517
|
+
}
|
|
72341
72518
|
async loadSession(params) {
|
|
72342
72519
|
if (!isAbsolute11(params.cwd)) {
|
|
72343
72520
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
@@ -72921,6 +73098,9 @@ var PiAcpEndpoint = class {
|
|
|
72921
73098
|
).onRequest(
|
|
72922
73099
|
methods5.agent.session.load,
|
|
72923
73100
|
async (context) => await piAgentOrThrow(piAgent).loadSession(context.params)
|
|
73101
|
+
).onRequest(
|
|
73102
|
+
methods5.agent.session.resume,
|
|
73103
|
+
async (context) => await piAgentOrThrow(piAgent).resumeSession(context.params)
|
|
72924
73104
|
).onRequest(
|
|
72925
73105
|
methods5.agent.session.list,
|
|
72926
73106
|
async (context) => await piAgentOrThrow(piAgent).listSessions(context.params)
|
|
@@ -73200,7 +73380,7 @@ var LocalAgentInventory = class {
|
|
|
73200
73380
|
};
|
|
73201
73381
|
|
|
73202
73382
|
// src/agent/discovery/acp-readiness-probe.ts
|
|
73203
|
-
import { spawn as
|
|
73383
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
73204
73384
|
import {
|
|
73205
73385
|
methods as methods8,
|
|
73206
73386
|
ndJsonStream as ndJsonStream2,
|
|
@@ -73391,7 +73571,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
|
|
|
73391
73571
|
}
|
|
73392
73572
|
}
|
|
73393
73573
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
73394
|
-
const child =
|
|
73574
|
+
const child = spawn6(launch.command, [...launch.arguments], {
|
|
73395
73575
|
cwd: defaultWorkspace,
|
|
73396
73576
|
...platformSpawnOptions,
|
|
73397
73577
|
env: { ...environment, ...agent.environment },
|
|
@@ -75004,7 +75184,7 @@ var ClaudeAdapter = class {
|
|
|
75004
75184
|
};
|
|
75005
75185
|
|
|
75006
75186
|
// src/acp/native-history/codex/codex-history.ts
|
|
75007
|
-
import { spawn as
|
|
75187
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
75008
75188
|
|
|
75009
75189
|
// src/acp/protocol/native-session.ts
|
|
75010
75190
|
var path6 = external_exports.string().min(1).max(2048).refine((value) => !value.includes("\0"));
|
|
@@ -75701,7 +75881,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
|
|
|
75701
75881
|
}
|
|
75702
75882
|
signal.throwIfAborted();
|
|
75703
75883
|
const launch = executableLaunch2(agent.agentIdentity.realPath, ["app-server"]);
|
|
75704
|
-
const child =
|
|
75884
|
+
const child = spawn7(launch.command, [...launch.arguments], {
|
|
75705
75885
|
cwd,
|
|
75706
75886
|
env: { ...process.env, ...agent.environment },
|
|
75707
75887
|
...platformSpawnOptions,
|
|
@@ -75936,6 +76116,16 @@ function toolStatus2(value) {
|
|
|
75936
76116
|
}
|
|
75937
76117
|
}
|
|
75938
76118
|
function activityEvent(activity2) {
|
|
76119
|
+
if (activity2.activityType === "reasoning") {
|
|
76120
|
+
return {
|
|
76121
|
+
payload: {
|
|
76122
|
+
content: { text: activity2.output, type: "text" },
|
|
76123
|
+
messageId: activity2.activityId,
|
|
76124
|
+
sessionUpdate: "agent_thought_chunk"
|
|
76125
|
+
},
|
|
76126
|
+
type: "acp"
|
|
76127
|
+
};
|
|
76128
|
+
}
|
|
75939
76129
|
return {
|
|
75940
76130
|
payload: {
|
|
75941
76131
|
content: activity2.content,
|
|
@@ -81032,6 +81222,18 @@ var acpSession = sqliteTable("acp_session", {
|
|
|
81032
81222
|
updatedAt: text("updated_at").notNull()
|
|
81033
81223
|
});
|
|
81034
81224
|
|
|
81225
|
+
// src/schema/acp-session-store/execution-receipt.ts
|
|
81226
|
+
var executionReceipt = sqliteTable("execution_receipt", {
|
|
81227
|
+
commandId: text("command_id").primaryKey(),
|
|
81228
|
+
sessionId: text("session_id").notNull(),
|
|
81229
|
+
commandHash: text("command_hash").notNull(),
|
|
81230
|
+
attemptId: text("attempt_id").notNull(),
|
|
81231
|
+
state: text("state").notNull(),
|
|
81232
|
+
started: integer2("started", { mode: "boolean" }).notNull(),
|
|
81233
|
+
outcome: text("outcome"),
|
|
81234
|
+
updatedAt: text("updated_at").notNull()
|
|
81235
|
+
});
|
|
81236
|
+
|
|
81035
81237
|
// src/schema/acp-session-store/session-live-event-position-allocation.ts
|
|
81036
81238
|
var sessionLiveEventPositionAllocation = sqliteTable("session_live_event_position_allocation", {
|
|
81037
81239
|
allocatedPosition: integer2("allocated_position").notNull().default(1e4),
|
|
@@ -81073,6 +81275,62 @@ var AcpSessionTable = class {
|
|
|
81073
81275
|
};
|
|
81074
81276
|
};
|
|
81075
81277
|
|
|
81278
|
+
// src/storage/session/execution-receipt-table.ts
|
|
81279
|
+
var receiptFields = external_exports.object({
|
|
81280
|
+
commandId: external_exports.string(),
|
|
81281
|
+
sessionId: external_exports.string(),
|
|
81282
|
+
commandHash: external_exports.string(),
|
|
81283
|
+
attemptId: external_exports.string(),
|
|
81284
|
+
updatedAt: external_exports.string()
|
|
81285
|
+
});
|
|
81286
|
+
var receiptSchema = external_exports.discriminatedUnion("state", [
|
|
81287
|
+
receiptFields.extend({ state: external_exports.literal("dispatching"), started: external_exports.literal(false), outcome: external_exports.null() }),
|
|
81288
|
+
receiptFields.extend({ state: external_exports.literal("running"), started: external_exports.literal(true), outcome: external_exports.string().nullable() }),
|
|
81289
|
+
receiptFields.extend({
|
|
81290
|
+
state: external_exports.enum(["succeeded", "failed", "cancelled"]),
|
|
81291
|
+
started: external_exports.boolean(),
|
|
81292
|
+
outcome: external_exports.string().nullable()
|
|
81293
|
+
})
|
|
81294
|
+
]).readonly();
|
|
81295
|
+
var ExecutionReceiptTable = class {
|
|
81296
|
+
#database;
|
|
81297
|
+
constructor(database) {
|
|
81298
|
+
this.#database = database;
|
|
81299
|
+
}
|
|
81300
|
+
list = () => receiptSchema.array().parse(
|
|
81301
|
+
this.#database.orm.select().from(executionReceipt).orderBy(asc(executionReceipt.updatedAt), asc(executionReceipt.commandId)).all()
|
|
81302
|
+
);
|
|
81303
|
+
save = (receipt) => {
|
|
81304
|
+
this.#database.transaction(() => {
|
|
81305
|
+
this.#database.orm.insert(executionReceipt).values(receipt).onConflictDoUpdate({ target: executionReceipt.commandId, set: receipt }).run();
|
|
81306
|
+
if (receipt.state === "dispatching" || receipt.state === "running") {
|
|
81307
|
+
return;
|
|
81308
|
+
}
|
|
81309
|
+
const retained = this.#database.orm.select({ commandId: executionReceipt.commandId }).from(executionReceipt).where(
|
|
81310
|
+
and(
|
|
81311
|
+
eq2(executionReceipt.sessionId, receipt.sessionId),
|
|
81312
|
+
inArray(executionReceipt.state, ["succeeded", "failed", "cancelled"])
|
|
81313
|
+
)
|
|
81314
|
+
).orderBy(desc(executionReceipt.updatedAt), desc(executionReceipt.commandId)).limit(1024).all();
|
|
81315
|
+
if (retained.length === 1024) {
|
|
81316
|
+
this.#database.orm.delete(executionReceipt).where(
|
|
81317
|
+
and(
|
|
81318
|
+
eq2(executionReceipt.sessionId, receipt.sessionId),
|
|
81319
|
+
inArray(executionReceipt.state, ["succeeded", "failed", "cancelled"]),
|
|
81320
|
+
notInArray(
|
|
81321
|
+
executionReceipt.commandId,
|
|
81322
|
+
retained.map((row) => row.commandId)
|
|
81323
|
+
)
|
|
81324
|
+
)
|
|
81325
|
+
).run();
|
|
81326
|
+
}
|
|
81327
|
+
});
|
|
81328
|
+
};
|
|
81329
|
+
remove = (commandId) => {
|
|
81330
|
+
this.#database.orm.delete(executionReceipt).where(eq2(executionReceipt.commandId, commandId)).run();
|
|
81331
|
+
};
|
|
81332
|
+
};
|
|
81333
|
+
|
|
81076
81334
|
// src/storage/session/live-event-position-table.ts
|
|
81077
81335
|
var allocationRowSchema = external_exports.object({ allocatedPosition: external_exports.number().int().safe().nonnegative() });
|
|
81078
81336
|
var LiveEventPositionTable = class {
|
|
@@ -81292,6 +81550,10 @@ var acpSessionStoreMigrations = [
|
|
|
81292
81550
|
{
|
|
81293
81551
|
"name": "0006_live_event_position_allocation.sql",
|
|
81294
81552
|
"sql": "CREATE TABLE `session_live_event_position_allocation` (\n `allocated_position` integer DEFAULT 10000 NOT NULL,\n `session_id` text PRIMARY KEY NOT NULL\n);\n"
|
|
81553
|
+
},
|
|
81554
|
+
{
|
|
81555
|
+
"name": "0007_busy_excalibur.sql",
|
|
81556
|
+
"sql": "CREATE TABLE `execution_receipt` (\n `command_id` text PRIMARY KEY NOT NULL,\n `session_id` text NOT NULL,\n `command_hash` text NOT NULL,\n `attempt_id` text NOT NULL,\n `state` text NOT NULL,\n `started` integer NOT NULL,\n `outcome` text,\n `updated_at` text NOT NULL\n);\n"
|
|
81295
81557
|
}
|
|
81296
81558
|
];
|
|
81297
81559
|
|
|
@@ -81946,12 +82208,12 @@ var SessionEvents = class {
|
|
|
81946
82208
|
}
|
|
81947
82209
|
};
|
|
81948
82210
|
};
|
|
81949
|
-
function liveEvent(sessionId, sessionGenerationId, eventId, position, event) {
|
|
82211
|
+
function liveEvent(sessionId, sessionGenerationId, eventId, position, event, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
81950
82212
|
return {
|
|
81951
82213
|
eventId,
|
|
81952
82214
|
...event,
|
|
81953
82215
|
position: position.toString(),
|
|
81954
|
-
recordedAt
|
|
82216
|
+
recordedAt,
|
|
81955
82217
|
sessionGenerationId,
|
|
81956
82218
|
sessionId
|
|
81957
82219
|
};
|
|
@@ -81989,7 +82251,7 @@ var MemorySessionEventStore = class {
|
|
|
81989
82251
|
}
|
|
81990
82252
|
return resolved;
|
|
81991
82253
|
};
|
|
81992
|
-
append = (sessionId, event) => {
|
|
82254
|
+
append = (sessionId, event, recordedAt) => {
|
|
81993
82255
|
const session = this.#session(sessionId);
|
|
81994
82256
|
const allocatedPosition = this.#allocatedPositionBySession.get(sessionId) ?? 9999;
|
|
81995
82257
|
if (allocatedPosition === Number.MAX_SAFE_INTEGER) {
|
|
@@ -82002,7 +82264,8 @@ var MemorySessionEventStore = class {
|
|
|
82002
82264
|
session.sessionGenerationId,
|
|
82003
82265
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
82004
82266
|
position,
|
|
82005
|
-
event
|
|
82267
|
+
event,
|
|
82268
|
+
recordedAt
|
|
82006
82269
|
);
|
|
82007
82270
|
session.apply(recorded, this.#resolver(session));
|
|
82008
82271
|
return recorded;
|
|
@@ -82043,12 +82306,14 @@ var MemorySessionEventStore = class {
|
|
|
82043
82306
|
};
|
|
82044
82307
|
};
|
|
82045
82308
|
var CachedSessionEventStore = class {
|
|
82309
|
+
#terminalOutcomes;
|
|
82046
82310
|
#cacheTable;
|
|
82047
82311
|
#eventIds;
|
|
82048
82312
|
#liveEventPositions;
|
|
82049
82313
|
#sessions = /* @__PURE__ */ new Map();
|
|
82050
82314
|
#flushSchedule = { kind: "idle" };
|
|
82051
|
-
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator()) {
|
|
82315
|
+
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator(), terminalOutcomes = () => []) {
|
|
82316
|
+
this.#terminalOutcomes = terminalOutcomes;
|
|
82052
82317
|
this.#eventIds = eventIds;
|
|
82053
82318
|
this.#liveEventPositions = liveEventPositions;
|
|
82054
82319
|
this.#cacheTable = cacheTable;
|
|
@@ -82081,7 +82346,7 @@ var CachedSessionEventStore = class {
|
|
|
82081
82346
|
}
|
|
82082
82347
|
return resolved;
|
|
82083
82348
|
};
|
|
82084
|
-
append = (sessionId, event) => {
|
|
82349
|
+
append = (sessionId, event, recordedAt) => {
|
|
82085
82350
|
if (this.#flushSchedule.kind === "closed") {
|
|
82086
82351
|
throw new Error("The V2 Session event store is closed");
|
|
82087
82352
|
}
|
|
@@ -82092,7 +82357,8 @@ var CachedSessionEventStore = class {
|
|
|
82092
82357
|
session.sessionGenerationId,
|
|
82093
82358
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
82094
82359
|
position,
|
|
82095
|
-
event
|
|
82360
|
+
event,
|
|
82361
|
+
recordedAt
|
|
82096
82362
|
);
|
|
82097
82363
|
session.apply(recorded, this.#resolver(sessionId, session));
|
|
82098
82364
|
this.#sessions.set(sessionId, session);
|
|
@@ -82181,6 +82447,9 @@ var CachedSessionEventStore = class {
|
|
|
82181
82447
|
this.#deletePersisted(sessionId, previous?.sessionGenerationId);
|
|
82182
82448
|
const sessionGenerationId = randomUUID11();
|
|
82183
82449
|
this.#sessions.set(sessionId, new SessionEvents(sessionGenerationId));
|
|
82450
|
+
for (const { event, recordedAt } of this.#terminalOutcomes(sessionId)) {
|
|
82451
|
+
this.append(sessionId, event, recordedAt);
|
|
82452
|
+
}
|
|
82184
82453
|
};
|
|
82185
82454
|
materializedEventCount = (sessionId) => this.#sessions.get(sessionId)?.materializedCount ?? 0;
|
|
82186
82455
|
close = () => {
|
|
@@ -82294,7 +82563,7 @@ function buildPromptContent(options, capabilities) {
|
|
|
82294
82563
|
}
|
|
82295
82564
|
|
|
82296
82565
|
// src/acp/connection/agent-connection.ts
|
|
82297
|
-
import { spawn as
|
|
82566
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
82298
82567
|
import { ndJsonStream as ndJsonStream3, RequestError as RequestError9 } from "@agentclientprotocol/sdk";
|
|
82299
82568
|
function requestErrorMessage(error62) {
|
|
82300
82569
|
const fallback = truncate(error62.message, 500);
|
|
@@ -82404,7 +82673,7 @@ var AgentConnection = class {
|
|
|
82404
82673
|
return;
|
|
82405
82674
|
}
|
|
82406
82675
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
82407
|
-
const child =
|
|
82676
|
+
const child = spawn8(launch.command, [...launch.arguments], {
|
|
82408
82677
|
cwd,
|
|
82409
82678
|
...platformSpawnOptions,
|
|
82410
82679
|
env: { ...process.env, ...agent.environment },
|
|
@@ -83678,6 +83947,19 @@ var RunningAgentTurn = class extends AgentTurnState {
|
|
|
83678
83947
|
|
|
83679
83948
|
// src/session/live/session-restore.ts
|
|
83680
83949
|
import { methods as methods10 } from "@agentclientprotocol/sdk";
|
|
83950
|
+
function hasMethodNotFoundCode(cause) {
|
|
83951
|
+
const visited = /* @__PURE__ */ new Set();
|
|
83952
|
+
let current = cause;
|
|
83953
|
+
while ((current instanceof Error || typeof current === "object" && current !== null) && !visited.has(current)) {
|
|
83954
|
+
visited.add(current);
|
|
83955
|
+
const code = Reflect.get(current, "code");
|
|
83956
|
+
if (code === -32601 || code === "METHOD_NOT_FOUND" || code === "method_not_found") {
|
|
83957
|
+
return true;
|
|
83958
|
+
}
|
|
83959
|
+
current = current instanceof Error ? current.cause : void 0;
|
|
83960
|
+
}
|
|
83961
|
+
return false;
|
|
83962
|
+
}
|
|
83681
83963
|
async function restoreSession(session, signal, recovery, origin) {
|
|
83682
83964
|
if (origin !== void 0) {
|
|
83683
83965
|
session.setSessionTitle(origin.title);
|
|
@@ -83744,6 +84026,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
83744
84026
|
}
|
|
83745
84027
|
session.setPrompted(true);
|
|
83746
84028
|
session.setRestored(true);
|
|
84029
|
+
if (recovery.kind === "execution-only") {
|
|
84030
|
+
session.startExecutionOnlyCapture();
|
|
84031
|
+
}
|
|
83747
84032
|
lifecycleResponse2 = forked;
|
|
83748
84033
|
} else if (stored instanceof FoundStoredSession && stored.session.agentId === session.agentId && stored.session.cwd === session.cwd && arraysEqual(stored.session.additionalDirectories, session.additionalDirectories)) {
|
|
83749
84034
|
session.selectNativeSession(stored.session.nativeSessionId);
|
|
@@ -83762,6 +84047,37 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
83762
84047
|
"session-load",
|
|
83763
84048
|
async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
|
|
83764
84049
|
);
|
|
84050
|
+
} else if (recovery.kind === "execution-only") {
|
|
84051
|
+
try {
|
|
84052
|
+
lifecycleResponse2 = await session.metrics.measure(
|
|
84053
|
+
"session-resume",
|
|
84054
|
+
async () => await session.race(
|
|
84055
|
+
session.agentRequest(
|
|
84056
|
+
methods10.agent.session.resume,
|
|
84057
|
+
{
|
|
84058
|
+
additionalDirectories: [...session.additionalDirectories],
|
|
84059
|
+
cwd: session.cwd,
|
|
84060
|
+
mcpServers: [],
|
|
84061
|
+
sessionId: session.nativeSessionId()
|
|
84062
|
+
},
|
|
84063
|
+
{ cancellationSignal: signal }
|
|
84064
|
+
),
|
|
84065
|
+
"ACP agent exited while resuming a session",
|
|
84066
|
+
signal
|
|
84067
|
+
)
|
|
84068
|
+
);
|
|
84069
|
+
} catch (cause) {
|
|
84070
|
+
signal.throwIfAborted();
|
|
84071
|
+
if (cause instanceof AcpExecutionError && !hasMethodNotFoundCode(cause)) {
|
|
84072
|
+
throw cause;
|
|
84073
|
+
}
|
|
84074
|
+
throw new AcpExecutionError(
|
|
84075
|
+
"This Agent cannot continue a persisted session without replaying native history",
|
|
84076
|
+
{ cause },
|
|
84077
|
+
"execution_only_unsupported"
|
|
84078
|
+
);
|
|
84079
|
+
}
|
|
84080
|
+
session.startExecutionOnlyCapture();
|
|
83765
84081
|
} else if (session.capabilities.resumeSession) {
|
|
83766
84082
|
lifecycleResponse2 = await session.metrics.measure(
|
|
83767
84083
|
"session-resume",
|
|
@@ -83821,6 +84137,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
83821
84137
|
);
|
|
83822
84138
|
session.selectNativeSession(created.sessionId);
|
|
83823
84139
|
session.setNativeHistoryOwnership({ kind: "fresh-session" });
|
|
84140
|
+
if (recovery.kind === "execution-only") {
|
|
84141
|
+
session.startExecutionOnlyCapture();
|
|
84142
|
+
}
|
|
83824
84143
|
lifecycleResponse2 = created;
|
|
83825
84144
|
}
|
|
83826
84145
|
session.restrictSessionCapabilities(lifecycleResponse2);
|
|
@@ -84098,6 +84417,16 @@ var AgentSession = class _AgentSession {
|
|
|
84098
84417
|
}
|
|
84099
84418
|
await this.#completedHistory(signal, "ACP agent exited while loading history");
|
|
84100
84419
|
};
|
|
84420
|
+
/** Starts live event capture without asking the native Agent to replay its persisted history. */
|
|
84421
|
+
startExecutionOnlyCapture = () => {
|
|
84422
|
+
if (this.#sessionLoad.kind !== "not-requested") {
|
|
84423
|
+
return;
|
|
84424
|
+
}
|
|
84425
|
+
this.#sessionLoad = {
|
|
84426
|
+
history: new HistoryReplayCapture(this.#store.events, this.#mobiusSessionId),
|
|
84427
|
+
kind: "execution-only"
|
|
84428
|
+
};
|
|
84429
|
+
};
|
|
84101
84430
|
loadHistoryEvents = async (eventLimit, cursor, signal) => {
|
|
84102
84431
|
if (!this.#capabilities.loadSession) {
|
|
84103
84432
|
throw new AcpExecutionError(
|
|
@@ -84348,7 +84677,7 @@ var AgentSession = class _AgentSession {
|
|
|
84348
84677
|
response: {}
|
|
84349
84678
|
};
|
|
84350
84679
|
}
|
|
84351
|
-
if (this.#capabilities.loadSession) {
|
|
84680
|
+
if (this.#capabilities.loadSession && this.#sessionLoad.kind !== "execution-only") {
|
|
84352
84681
|
await this.#completedHistory(options.signal, "ACP agent exited while loading history before a prompt");
|
|
84353
84682
|
}
|
|
84354
84683
|
const prompt = this.buildPrompt(options);
|
|
@@ -84547,14 +84876,14 @@ var AgentSession = class _AgentSession {
|
|
|
84547
84876
|
onElicitationComplete = (notification) => this.#interactions.onElicitationComplete(notification);
|
|
84548
84877
|
onUpdate = (notification) => this.#updates.receive(notification);
|
|
84549
84878
|
recordControlEvent = async (event) => {
|
|
84550
|
-
if (this.#sessionLoad.kind !== "loaded") {
|
|
84879
|
+
if (this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
84551
84880
|
return false;
|
|
84552
84881
|
}
|
|
84553
84882
|
await this.recordLifecycleEvent(event);
|
|
84554
84883
|
return true;
|
|
84555
84884
|
};
|
|
84556
84885
|
recordLifecycleEvent = async (event) => {
|
|
84557
|
-
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded") {
|
|
84886
|
+
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
84558
84887
|
return;
|
|
84559
84888
|
}
|
|
84560
84889
|
const liveEvent2 = this.#sessionLoad.history.recordLifecycle(event);
|
|
@@ -84575,7 +84904,7 @@ var AgentSession = class _AgentSession {
|
|
|
84575
84904
|
const rawUpdate = decodeAcpSessionUpdate(JSON.stringify(externalized.event));
|
|
84576
84905
|
if (this.#sessionLoad.kind === "capturing") {
|
|
84577
84906
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
84578
|
-
} else if (this.#sessionLoad.kind === "loaded") {
|
|
84907
|
+
} else if (this.#sessionLoad.kind === "loaded" || this.#sessionLoad.kind === "execution-only") {
|
|
84579
84908
|
const onSessionEvent = this.#getObserver().onSessionEvent;
|
|
84580
84909
|
await this.#sessionLoad.history.record(update, rawUpdate, async (liveEvent2) => {
|
|
84581
84910
|
await onSessionEvent?.(liveEvent2);
|
|
@@ -85493,13 +85822,14 @@ var SessionManager2 = class {
|
|
|
85493
85822
|
}
|
|
85494
85823
|
async #replaceExecutionPreparation(existing, options) {
|
|
85495
85824
|
const desiredConfigOptions = existing.prepared().configOptions;
|
|
85825
|
+
const recovery = options.recovery ?? { kind: "interactive-only" };
|
|
85496
85826
|
return await this.#executionProcesses.prepare(options.sessionId, async () => {
|
|
85497
85827
|
await this.#retireSessionProcess(options.sessionId, existing, async () => await existing.close());
|
|
85498
85828
|
const runtime = await this.#startRetainedSessionProcess(
|
|
85499
85829
|
options,
|
|
85500
85830
|
async () => await AgentSession.start(
|
|
85501
85831
|
options,
|
|
85502
|
-
|
|
85832
|
+
recovery,
|
|
85503
85833
|
() => this.#observer,
|
|
85504
85834
|
this.#store,
|
|
85505
85835
|
unmeasuredOperationMetrics,
|
|
@@ -85677,6 +86007,7 @@ var SessionManager2 = class {
|
|
|
85677
86007
|
});
|
|
85678
86008
|
});
|
|
85679
86009
|
prepareExecutionSession = async (options) => this.#operations.run(options, async (options2) => {
|
|
86010
|
+
const recovery = options2.recovery ?? { kind: "interactive-only" };
|
|
85680
86011
|
this.#assertOpen(options2.sessionId);
|
|
85681
86012
|
const pending = this.#executionProcesses.pending(options2.sessionId);
|
|
85682
86013
|
if (pending !== void 0) {
|
|
@@ -85685,7 +86016,7 @@ var SessionManager2 = class {
|
|
|
85685
86016
|
}
|
|
85686
86017
|
const existing = this.#executionProcesses.get(options2.sessionId);
|
|
85687
86018
|
if (existing === void 0) {
|
|
85688
|
-
return (await this.#startPreparation(options2,
|
|
86019
|
+
return (await this.#startPreparation(options2, recovery)).prepared();
|
|
85689
86020
|
}
|
|
85690
86021
|
if (!existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
85691
86022
|
throw new AcpExecutionError(
|
|
@@ -85695,6 +86026,9 @@ var SessionManager2 = class {
|
|
|
85695
86026
|
);
|
|
85696
86027
|
}
|
|
85697
86028
|
if (existing.usesEnvironment(options2.agent.environment)) {
|
|
86029
|
+
if (recovery.kind === "execution-only") {
|
|
86030
|
+
existing.startExecutionOnlyCapture();
|
|
86031
|
+
}
|
|
85698
86032
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
85699
86033
|
return existing.prepared();
|
|
85700
86034
|
}
|
|
@@ -85989,10 +86323,13 @@ var SessionManager2 = class {
|
|
|
85989
86323
|
"session_identity_mismatch"
|
|
85990
86324
|
);
|
|
85991
86325
|
}
|
|
86326
|
+
if (options2.recovery?.kind === "execution-only") {
|
|
86327
|
+
existing.startExecutionOnlyCapture();
|
|
86328
|
+
}
|
|
85992
86329
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
85993
86330
|
return existing;
|
|
85994
86331
|
}
|
|
85995
|
-
await this
|
|
86332
|
+
await this.#prepareSession(options2, options2.recovery ?? { kind: "interactive-only" }, "reopen");
|
|
85996
86333
|
const started = this.#executionProcesses.get(options2.sessionId);
|
|
85997
86334
|
if (started === void 0) {
|
|
85998
86335
|
throw new AcpExecutionError("ACP session did not start");
|
|
@@ -86595,6 +86932,13 @@ var PromptLifecycle = class {
|
|
|
86595
86932
|
}
|
|
86596
86933
|
this.#queued.delete(commandId);
|
|
86597
86934
|
};
|
|
86935
|
+
replayOutcome = async (sessionId, event) => {
|
|
86936
|
+
if (event.type !== "lifecycle-metadata" || !("commandId" in event.payload)) {
|
|
86937
|
+
return;
|
|
86938
|
+
}
|
|
86939
|
+
await this.#recordLifecycle(sessionId, event);
|
|
86940
|
+
this.publishTerminal(sessionId, event.payload.commandId);
|
|
86941
|
+
};
|
|
86598
86942
|
queueChanged = async (sessionId) => {
|
|
86599
86943
|
await this.#recordLifecycle(sessionId, {
|
|
86600
86944
|
type: "lifecycle-metadata",
|
|
@@ -86628,7 +86972,7 @@ var PromptLifecycle = class {
|
|
|
86628
86972
|
type: "lifecycle-metadata",
|
|
86629
86973
|
payload: { kind: "prompt.failed-before-start", commandId, code, message }
|
|
86630
86974
|
});
|
|
86631
|
-
if (!recorded) {
|
|
86975
|
+
if (!recorded || code === SESSION_CLOSED_ERROR_CODE) {
|
|
86632
86976
|
this.#sink.publishOperationFailure(sessionId, commandId, code, message);
|
|
86633
86977
|
}
|
|
86634
86978
|
};
|
|
@@ -86665,18 +87009,149 @@ function isTerminal(state) {
|
|
|
86665
87009
|
}
|
|
86666
87010
|
var ExecutionReceipts = class {
|
|
86667
87011
|
#executions = /* @__PURE__ */ new Map();
|
|
87012
|
+
#recoveredCommands = /* @__PURE__ */ new Set();
|
|
86668
87013
|
#terminalCountBySession = /* @__PURE__ */ new Map();
|
|
87014
|
+
#table;
|
|
87015
|
+
#closing = false;
|
|
87016
|
+
#activeCount = 0;
|
|
87017
|
+
#onCount;
|
|
87018
|
+
constructor(table, onCount = () => void 0) {
|
|
87019
|
+
this.#onCount = onCount;
|
|
87020
|
+
this.#table = table;
|
|
87021
|
+
for (const row of table?.list() ?? []) {
|
|
87022
|
+
this.#executions.set(row.commandId, row);
|
|
87023
|
+
this.#recoveredCommands.add(row.commandId);
|
|
87024
|
+
if (!isTerminal(row.state)) {
|
|
87025
|
+
this.#activeCount += 1;
|
|
87026
|
+
}
|
|
87027
|
+
if (isTerminal(row.state)) {
|
|
87028
|
+
this.#terminalCountBySession.set(
|
|
87029
|
+
row.sessionId,
|
|
87030
|
+
(this.#terminalCountBySession.get(row.sessionId) ?? 0) + 1
|
|
87031
|
+
);
|
|
87032
|
+
}
|
|
87033
|
+
}
|
|
87034
|
+
}
|
|
87035
|
+
#save = (commandId, receipt) => {
|
|
87036
|
+
if (!this.#closing) {
|
|
87037
|
+
this.#table?.save({ ...receipt, commandId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
87038
|
+
}
|
|
87039
|
+
const previous = this.#executions.get(commandId);
|
|
87040
|
+
const wasActive = previous !== void 0 && !isTerminal(previous.state);
|
|
87041
|
+
if (isTerminal(receipt.state)) {
|
|
87042
|
+
this.#executions.delete(commandId);
|
|
87043
|
+
}
|
|
87044
|
+
this.#executions.set(commandId, receipt);
|
|
87045
|
+
this.#activeCount += Number(!isTerminal(receipt.state)) - Number(wasActive);
|
|
87046
|
+
this.#onCount(this.#activeCount);
|
|
87047
|
+
if (isTerminal(receipt.state) && (previous === void 0 || !isTerminal(previous.state))) {
|
|
87048
|
+
this.#terminalCountBySession.set(
|
|
87049
|
+
receipt.sessionId,
|
|
87050
|
+
(this.#terminalCountBySession.get(receipt.sessionId) ?? 0) + 1
|
|
87051
|
+
);
|
|
87052
|
+
this.pruneTerminalReceipts(receipt.sessionId);
|
|
87053
|
+
}
|
|
87054
|
+
};
|
|
87055
|
+
beginShutdown = () => {
|
|
87056
|
+
this.#closing = true;
|
|
87057
|
+
};
|
|
87058
|
+
outcome = (commandId) => {
|
|
87059
|
+
const receipt = this.#executions.get(commandId);
|
|
87060
|
+
return receipt?.outcome === null || receipt === void 0 ? void 0 : sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
|
|
87061
|
+
};
|
|
87062
|
+
recordOutcome = (event) => {
|
|
87063
|
+
if (event.type !== "lifecycle-metadata") {
|
|
87064
|
+
return;
|
|
87065
|
+
}
|
|
87066
|
+
const payload = event.payload;
|
|
87067
|
+
if (payload.kind !== "prompt.completed" && payload.kind !== "prompt.failed" && payload.kind !== "prompt.failed-before-start") {
|
|
87068
|
+
return;
|
|
87069
|
+
}
|
|
87070
|
+
const receipt = this.#executions.get(payload.commandId);
|
|
87071
|
+
if (receipt === void 0) {
|
|
87072
|
+
return;
|
|
87073
|
+
}
|
|
87074
|
+
const sanitized = payload.kind === "prompt.completed" ? payload : { ...payload, message: "The local Agent could not complete the request" };
|
|
87075
|
+
this.#save(payload.commandId, {
|
|
87076
|
+
...receipt,
|
|
87077
|
+
state: payload.kind === "prompt.completed" ? payload.stopReason === "cancelled" ? "cancelled" : "succeeded" : "failed",
|
|
87078
|
+
outcome: JSON.stringify({ type: "lifecycle-metadata", payload: sanitized, recordedAt: event.recordedAt })
|
|
87079
|
+
});
|
|
87080
|
+
};
|
|
87081
|
+
recover = () => {
|
|
87082
|
+
const recovered = [];
|
|
87083
|
+
for (const [commandId, receipt] of [...this.#executions]) {
|
|
87084
|
+
const event = receipt.outcome === null ? {
|
|
87085
|
+
type: "lifecycle-metadata",
|
|
87086
|
+
payload: receipt.started ? {
|
|
87087
|
+
kind: "prompt.failed",
|
|
87088
|
+
commandId,
|
|
87089
|
+
attemptId: receipt.attemptId,
|
|
87090
|
+
code: "runtime_restarted",
|
|
87091
|
+
message: "The local runtime restarted while this request was running"
|
|
87092
|
+
} : {
|
|
87093
|
+
kind: "prompt.failed-before-start",
|
|
87094
|
+
commandId,
|
|
87095
|
+
code: "runtime_restarted",
|
|
87096
|
+
message: "The local runtime restarted before this request started"
|
|
87097
|
+
}
|
|
87098
|
+
} : sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
|
|
87099
|
+
const recordedAt = receipt.outcome === null ? (/* @__PURE__ */ new Date()).toISOString() : external_exports.object({ recordedAt: external_exports.string() }).parse(JSON.parse(receipt.outcome)).recordedAt;
|
|
87100
|
+
recovered.push({ sessionId: receipt.sessionId, event, recordedAt });
|
|
87101
|
+
if (!isTerminal(receipt.state)) {
|
|
87102
|
+
const state = event.type === "lifecycle-metadata" && event.payload.kind === "prompt.completed" ? event.payload.stopReason === "cancelled" ? "cancelled" : "succeeded" : "failed";
|
|
87103
|
+
this.#save(commandId, { ...receipt, state, outcome: JSON.stringify({ ...event, recordedAt }) });
|
|
87104
|
+
}
|
|
87105
|
+
}
|
|
87106
|
+
return recovered;
|
|
87107
|
+
};
|
|
87108
|
+
terminalOutcomes = (sessionId) => [...this.#executions.values()].flatMap((receipt) => {
|
|
87109
|
+
if (receipt.sessionId !== sessionId || receipt.outcome === null) {
|
|
87110
|
+
return [];
|
|
87111
|
+
}
|
|
87112
|
+
const decoded = JSON.parse(receipt.outcome);
|
|
87113
|
+
return [
|
|
87114
|
+
{
|
|
87115
|
+
event: sessionEventPayloadSchema.parse(decoded),
|
|
87116
|
+
recordedAt: external_exports.object({ recordedAt: external_exports.string() }).parse(decoded).recordedAt
|
|
87117
|
+
}
|
|
87118
|
+
];
|
|
87119
|
+
});
|
|
86669
87120
|
claimExecution = (commandId, sessionId, commandJson) => {
|
|
86670
87121
|
const commandHash = createHash6("sha256").update(commandJson).digest("hex");
|
|
86671
|
-
|
|
87122
|
+
let existing = this.#executions.get(commandId);
|
|
87123
|
+
const previous = this.outcome(commandId);
|
|
87124
|
+
if (existing?.sessionId === sessionId && !existing.started && previous?.type === "lifecycle-metadata" && previous.payload.kind === "prompt.failed-before-start" && previous.payload.code === "runtime_restarted") {
|
|
87125
|
+
this.#executions.delete(commandId);
|
|
87126
|
+
this.#recoveredCommands.delete(commandId);
|
|
87127
|
+
this.#table?.remove(commandId);
|
|
87128
|
+
this.#terminalCountBySession.set(
|
|
87129
|
+
sessionId,
|
|
87130
|
+
Math.max(0, (this.#terminalCountBySession.get(sessionId) ?? 1) - 1)
|
|
87131
|
+
);
|
|
87132
|
+
existing = void 0;
|
|
87133
|
+
}
|
|
86672
87134
|
if (existing !== void 0) {
|
|
86673
87135
|
if (existing.sessionId !== sessionId || existing.commandHash !== commandHash) {
|
|
86674
87136
|
return { kind: "conflict" };
|
|
86675
87137
|
}
|
|
86676
|
-
return {
|
|
87138
|
+
return {
|
|
87139
|
+
attemptId: existing.attemptId,
|
|
87140
|
+
commandId,
|
|
87141
|
+
kind: "duplicate",
|
|
87142
|
+
state: existing.state,
|
|
87143
|
+
outcome: this.#recoveredCommands.has(commandId) ? this.outcome(commandId) : void 0
|
|
87144
|
+
};
|
|
86677
87145
|
}
|
|
86678
87146
|
const attemptId = randomUUID13();
|
|
86679
|
-
this.#
|
|
87147
|
+
this.#save(commandId, {
|
|
87148
|
+
attemptId,
|
|
87149
|
+
commandHash,
|
|
87150
|
+
sessionId,
|
|
87151
|
+
state: "dispatching",
|
|
87152
|
+
started: false,
|
|
87153
|
+
outcome: null
|
|
87154
|
+
});
|
|
86680
87155
|
return { attemptId, commandId, kind: "accepted", state: "dispatching" };
|
|
86681
87156
|
};
|
|
86682
87157
|
transitionExecution = (commandId, state) => {
|
|
@@ -86691,16 +87166,13 @@ var ExecutionReceipts = class {
|
|
|
86691
87166
|
if (!allowed) {
|
|
86692
87167
|
throw new Error("The runtime execution transition is invalid");
|
|
86693
87168
|
}
|
|
86694
|
-
|
|
86695
|
-
|
|
86696
|
-
|
|
86697
|
-
|
|
86698
|
-
(this.#terminalCountBySession.get(current.sessionId) ?? 0) + 1
|
|
86699
|
-
);
|
|
86700
|
-
this.pruneTerminalReceipts(current.sessionId);
|
|
87169
|
+
if (state === "running") {
|
|
87170
|
+
this.#save(commandId, { ...current, state, started: true });
|
|
87171
|
+
} else if (isTerminal(state)) {
|
|
87172
|
+
this.#save(commandId, { ...current, state });
|
|
86701
87173
|
}
|
|
86702
87174
|
};
|
|
86703
|
-
/**
|
|
87175
|
+
/** Only commands without a terminal result can still be cancelled. */
|
|
86704
87176
|
findUnsettledAttemptId = (commandId, sessionId) => {
|
|
86705
87177
|
const receipt = this.#executions.get(commandId);
|
|
86706
87178
|
return receipt?.sessionId === sessionId && !isTerminal(receipt.state) ? receipt.attemptId : null;
|
|
@@ -86711,7 +87183,9 @@ var ExecutionReceipts = class {
|
|
|
86711
87183
|
};
|
|
86712
87184
|
close = () => {
|
|
86713
87185
|
this.#executions.clear();
|
|
87186
|
+
this.#recoveredCommands.clear();
|
|
86714
87187
|
this.#terminalCountBySession.clear();
|
|
87188
|
+
this.#activeCount = 0;
|
|
86715
87189
|
};
|
|
86716
87190
|
pruneTerminalReceipts = (sessionId) => {
|
|
86717
87191
|
if ((this.#terminalCountBySession.get(sessionId) ?? 0) <= MAX_TERMINAL_RECEIPTS) {
|
|
@@ -86720,6 +87194,8 @@ var ExecutionReceipts = class {
|
|
|
86720
87194
|
for (const [commandId, receipt] of this.#executions) {
|
|
86721
87195
|
if (receipt.sessionId === sessionId && isTerminal(receipt.state)) {
|
|
86722
87196
|
this.#executions.delete(commandId);
|
|
87197
|
+
this.#recoveredCommands.delete(commandId);
|
|
87198
|
+
this.#table?.remove(commandId);
|
|
86723
87199
|
const remaining = (this.#terminalCountBySession.get(sessionId) ?? 1) - 1;
|
|
86724
87200
|
if (remaining > 0) {
|
|
86725
87201
|
this.#terminalCountBySession.set(sessionId, remaining);
|
|
@@ -87247,10 +87723,14 @@ function buildSessionLayer(options) {
|
|
|
87247
87723
|
const databases = channelSessionDatabasePaths(stateDirectory, channelId);
|
|
87248
87724
|
const sessionDatabase = openAcpSessionDatabase(databases.sessions);
|
|
87249
87725
|
let events;
|
|
87726
|
+
let operations;
|
|
87250
87727
|
try {
|
|
87728
|
+
operations = new ExecutionReceipts(new ExecutionReceiptTable(sessionDatabase), options.onExecutionCountChange);
|
|
87251
87729
|
events = new CachedSessionEventStore(
|
|
87252
87730
|
new SessionEventCacheTable(openSessionEventCacheDatabase(databases.events)),
|
|
87253
|
-
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase))
|
|
87731
|
+
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase)),
|
|
87732
|
+
void 0,
|
|
87733
|
+
(sessionId) => operations.terminalOutcomes(sessionId)
|
|
87254
87734
|
);
|
|
87255
87735
|
} catch (error62) {
|
|
87256
87736
|
sessionDatabase.close();
|
|
@@ -87258,11 +87738,13 @@ function buildSessionLayer(options) {
|
|
|
87258
87738
|
}
|
|
87259
87739
|
const sessionStore = new SqliteSessionStore(new AcpSessionTable(sessionDatabase), events);
|
|
87260
87740
|
const externalContent = new LocalExternalContentStore(stateDirectory);
|
|
87261
|
-
const operations = new ExecutionReceipts();
|
|
87262
87741
|
const activeSessions = new SessionTurns(operations, options.turnActivity);
|
|
87263
87742
|
const directories = new WorkspaceDirectoryService(bindingId, defaultWorkspace);
|
|
87264
87743
|
const manager = new SessionManager2({
|
|
87265
|
-
observer: new SessionLayerObserver((event) =>
|
|
87744
|
+
observer: new SessionLayerObserver((event) => {
|
|
87745
|
+
operations.recordOutcome(event);
|
|
87746
|
+
eventProjection.record(event);
|
|
87747
|
+
}, sink.publishInfo),
|
|
87266
87748
|
store: sessionStore,
|
|
87267
87749
|
adapters: harnessAdapters,
|
|
87268
87750
|
sessionIdentity: "native",
|
|
@@ -87283,7 +87765,15 @@ function buildSessionLayer(options) {
|
|
|
87283
87765
|
});
|
|
87284
87766
|
const eventProjection = new PromptLifecycle(
|
|
87285
87767
|
sink,
|
|
87286
|
-
(sessionId, event) =>
|
|
87768
|
+
async (sessionId, event) => {
|
|
87769
|
+
if (await manager.recordLifecycleEvent(sessionId, event)) {
|
|
87770
|
+
return true;
|
|
87771
|
+
}
|
|
87772
|
+
const recorded = events.append(sessionId, event);
|
|
87773
|
+
operations.recordOutcome(recorded);
|
|
87774
|
+
eventProjection.record(recorded);
|
|
87775
|
+
return true;
|
|
87776
|
+
},
|
|
87287
87777
|
activeSessions.recordSessionEvent
|
|
87288
87778
|
);
|
|
87289
87779
|
const nativeSessions = new NativeSessionService(
|
|
@@ -87306,7 +87796,13 @@ function buildSessionLayer(options) {
|
|
|
87306
87796
|
);
|
|
87307
87797
|
})
|
|
87308
87798
|
);
|
|
87799
|
+
const recoveredEvents = operations.recover().map(({ sessionId, event, recordedAt }) => events.append(sessionId, event, recordedAt));
|
|
87309
87800
|
return {
|
|
87801
|
+
publishRecoveredOutcomes: () => {
|
|
87802
|
+
for (const event of recoveredEvents) {
|
|
87803
|
+
sink.publish(event);
|
|
87804
|
+
}
|
|
87805
|
+
},
|
|
87310
87806
|
activeSessions,
|
|
87311
87807
|
directories,
|
|
87312
87808
|
eventProjection,
|
|
@@ -89103,12 +89599,14 @@ async function executePrompt({
|
|
|
89103
89599
|
const appliedSettings = command.sessionConfigurations === void 0 ? void 0 : agentForSessionConfiguration(agent, command.sessionConfigurations);
|
|
89104
89600
|
const executionAgent = appliedSettings?.agent ?? agent;
|
|
89105
89601
|
const sessionConfigurations = appliedSettings?.sessionConfigurations;
|
|
89602
|
+
const recovery = command.historyPolicy === SessionHistoryPolicy.ExecutionOnly ? { kind: "execution-only" } : { kind: "interactive-only" };
|
|
89106
89603
|
const preparation = {
|
|
89107
89604
|
additionalDirectories: resolved.additionalDirectories,
|
|
89108
89605
|
agent: executionAgent,
|
|
89109
89606
|
cwd: resolved.cwd,
|
|
89110
89607
|
sessionId: command.sessionId,
|
|
89111
|
-
signal
|
|
89608
|
+
signal,
|
|
89609
|
+
recovery
|
|
89112
89610
|
};
|
|
89113
89611
|
let prepared = await sessions.prepareExecutionSession(preparation);
|
|
89114
89612
|
if (command.sessionConfigurations !== void 0) {
|
|
@@ -89177,7 +89675,8 @@ async function executePrompt({
|
|
|
89177
89675
|
resources: attachments.resources,
|
|
89178
89676
|
sessionId: command.sessionId,
|
|
89179
89677
|
signal,
|
|
89180
|
-
targetCommandId: command.targetCommandId
|
|
89678
|
+
targetCommandId: command.targetCommandId,
|
|
89679
|
+
recovery
|
|
89181
89680
|
});
|
|
89182
89681
|
stopReason = result.stopReason;
|
|
89183
89682
|
}
|
|
@@ -89346,6 +89845,12 @@ var sessionPromptCommand = {
|
|
|
89346
89845
|
return;
|
|
89347
89846
|
}
|
|
89348
89847
|
if (receipt.kind === "duplicate") {
|
|
89848
|
+
const outcome = receipt.outcome;
|
|
89849
|
+
if (outcome !== void 0) {
|
|
89850
|
+
void context.eventProjection.replayOutcome(message.sessionId, outcome).catch((cause) => {
|
|
89851
|
+
console.error("Could not replay the persisted execution outcome", cause);
|
|
89852
|
+
});
|
|
89853
|
+
}
|
|
89349
89854
|
return;
|
|
89350
89855
|
}
|
|
89351
89856
|
const turn = context.sessionTurns.start(message, receipt.attemptId);
|
|
@@ -90471,7 +90976,8 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
90471
90976
|
resolveAgent: (agentId, resolveSignal) => resolveCatalogAgent(config2, agentId, resolveSignal),
|
|
90472
90977
|
sink: publisher,
|
|
90473
90978
|
stateDirectory: config2.localContext.stateDirectory,
|
|
90474
|
-
timer
|
|
90979
|
+
timer,
|
|
90980
|
+
onExecutionCountChange: options.onExecutionCountChange ?? (() => void 0)
|
|
90475
90981
|
});
|
|
90476
90982
|
const {
|
|
90477
90983
|
activeSessions,
|
|
@@ -90541,6 +91047,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
90541
91047
|
reportUpgradeAvailability,
|
|
90542
91048
|
diagnostics,
|
|
90543
91049
|
onConnected: () => {
|
|
91050
|
+
layer.publishRecoveredOutcomes();
|
|
90544
91051
|
if (catalogPublished) {
|
|
90545
91052
|
options.onConnectionStatus?.("online");
|
|
90546
91053
|
}
|
|
@@ -90563,6 +91070,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
90563
91070
|
}
|
|
90564
91071
|
} finally {
|
|
90565
91072
|
shutdown.abort();
|
|
91073
|
+
operations.beginShutdown();
|
|
90566
91074
|
await activeSessions.close();
|
|
90567
91075
|
try {
|
|
90568
91076
|
await catalogPublication;
|
|
@@ -90699,6 +91207,10 @@ async function createMobiusRuntimeEngine(connection, signal, environment = proce
|
|
|
90699
91207
|
var MobiusRuntimeEngine = class {
|
|
90700
91208
|
#config;
|
|
90701
91209
|
#options;
|
|
91210
|
+
#activeTurnCount = 0;
|
|
91211
|
+
get activeTurnCount() {
|
|
91212
|
+
return this.#activeTurnCount;
|
|
91213
|
+
}
|
|
90702
91214
|
#state = new IdleMobiusRuntimeState();
|
|
90703
91215
|
constructor(config2, options = {}) {
|
|
90704
91216
|
validateRuntimeConfiguration(config2);
|
|
@@ -90714,11 +91226,15 @@ var MobiusRuntimeEngine = class {
|
|
|
90714
91226
|
try {
|
|
90715
91227
|
await runRuntime(this.#config, signal, void 0, {
|
|
90716
91228
|
...this.#options.turnActivity === void 0 ? {} : { turnActivity: this.#options.turnActivity },
|
|
91229
|
+
onExecutionCountChange: (count) => {
|
|
91230
|
+
this.#activeTurnCount = count;
|
|
91231
|
+
},
|
|
90717
91232
|
...this.#options.onConnectionStatus === void 0 ? {} : { onConnectionStatus: this.#options.onConnectionStatus },
|
|
90718
91233
|
...this.#options.reportUpgradeAvailability === void 0 ? {} : { reportUpgradeAvailability: this.#options.reportUpgradeAvailability },
|
|
90719
91234
|
...this.#options.processLogsDirectory === void 0 ? {} : { processLogsDirectory: this.#options.processLogsDirectory }
|
|
90720
91235
|
});
|
|
90721
91236
|
} finally {
|
|
91237
|
+
this.#activeTurnCount = 0;
|
|
90722
91238
|
this.#state = new FinishedMobiusRuntimeState();
|
|
90723
91239
|
}
|
|
90724
91240
|
};
|