@moxt-ai/mobius 0.0.300 → 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/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/cli.js +590 -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 +555 -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") {
|
|
@@ -69225,7 +69327,7 @@ import { basename as basename4, dirname as dirname7, isAbsolute as isAbsolute11,
|
|
|
69225
69327
|
import { RequestError as RequestError7 } from "@agentclientprotocol/sdk";
|
|
69226
69328
|
|
|
69227
69329
|
// src/acp/harness/pi/upstream/dist/pi-rpc/process.js
|
|
69228
|
-
import { spawn as
|
|
69330
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
69229
69331
|
import * as readline from "node:readline";
|
|
69230
69332
|
|
|
69231
69333
|
// src/acp/harness/pi/upstream/dist/pi-rpc/command.js
|
|
@@ -69342,7 +69444,7 @@ var PiRpcProcess = class _PiRpcProcess {
|
|
|
69342
69444
|
args.push("--fork", params.origin.sessionPath);
|
|
69343
69445
|
break;
|
|
69344
69446
|
}
|
|
69345
|
-
const child =
|
|
69447
|
+
const child = spawn5(cmd, args, {
|
|
69346
69448
|
cwd: params.cwd,
|
|
69347
69449
|
stdio: "pipe",
|
|
69348
69450
|
env: params.environment,
|
|
@@ -72342,6 +72444,77 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
72342
72444
|
}, 0);
|
|
72343
72445
|
return { sessionId: session.sessionId, configOptions, modes };
|
|
72344
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
|
+
}
|
|
72345
72518
|
async loadSession(params) {
|
|
72346
72519
|
if (!isAbsolute11(params.cwd)) {
|
|
72347
72520
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
@@ -72925,6 +73098,9 @@ var PiAcpEndpoint = class {
|
|
|
72925
73098
|
).onRequest(
|
|
72926
73099
|
methods5.agent.session.load,
|
|
72927
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)
|
|
72928
73104
|
).onRequest(
|
|
72929
73105
|
methods5.agent.session.list,
|
|
72930
73106
|
async (context) => await piAgentOrThrow(piAgent).listSessions(context.params)
|
|
@@ -73204,7 +73380,7 @@ var LocalAgentInventory = class {
|
|
|
73204
73380
|
};
|
|
73205
73381
|
|
|
73206
73382
|
// src/agent/discovery/acp-readiness-probe.ts
|
|
73207
|
-
import { spawn as
|
|
73383
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
73208
73384
|
import {
|
|
73209
73385
|
methods as methods8,
|
|
73210
73386
|
ndJsonStream as ndJsonStream2,
|
|
@@ -73395,7 +73571,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
|
|
|
73395
73571
|
}
|
|
73396
73572
|
}
|
|
73397
73573
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
73398
|
-
const child =
|
|
73574
|
+
const child = spawn6(launch.command, [...launch.arguments], {
|
|
73399
73575
|
cwd: defaultWorkspace,
|
|
73400
73576
|
...platformSpawnOptions,
|
|
73401
73577
|
env: { ...environment, ...agent.environment },
|
|
@@ -75008,7 +75184,7 @@ var ClaudeAdapter = class {
|
|
|
75008
75184
|
};
|
|
75009
75185
|
|
|
75010
75186
|
// src/acp/native-history/codex/codex-history.ts
|
|
75011
|
-
import { spawn as
|
|
75187
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
75012
75188
|
|
|
75013
75189
|
// src/acp/protocol/native-session.ts
|
|
75014
75190
|
var path6 = external_exports.string().min(1).max(2048).refine((value) => !value.includes("\0"));
|
|
@@ -75705,7 +75881,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
|
|
|
75705
75881
|
}
|
|
75706
75882
|
signal.throwIfAborted();
|
|
75707
75883
|
const launch = executableLaunch2(agent.agentIdentity.realPath, ["app-server"]);
|
|
75708
|
-
const child =
|
|
75884
|
+
const child = spawn7(launch.command, [...launch.arguments], {
|
|
75709
75885
|
cwd,
|
|
75710
75886
|
env: { ...process.env, ...agent.environment },
|
|
75711
75887
|
...platformSpawnOptions,
|
|
@@ -81046,6 +81222,18 @@ var acpSession = sqliteTable("acp_session", {
|
|
|
81046
81222
|
updatedAt: text("updated_at").notNull()
|
|
81047
81223
|
});
|
|
81048
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
|
+
|
|
81049
81237
|
// src/schema/acp-session-store/session-live-event-position-allocation.ts
|
|
81050
81238
|
var sessionLiveEventPositionAllocation = sqliteTable("session_live_event_position_allocation", {
|
|
81051
81239
|
allocatedPosition: integer2("allocated_position").notNull().default(1e4),
|
|
@@ -81087,6 +81275,62 @@ var AcpSessionTable = class {
|
|
|
81087
81275
|
};
|
|
81088
81276
|
};
|
|
81089
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
|
+
|
|
81090
81334
|
// src/storage/session/live-event-position-table.ts
|
|
81091
81335
|
var allocationRowSchema = external_exports.object({ allocatedPosition: external_exports.number().int().safe().nonnegative() });
|
|
81092
81336
|
var LiveEventPositionTable = class {
|
|
@@ -81306,6 +81550,10 @@ var acpSessionStoreMigrations = [
|
|
|
81306
81550
|
{
|
|
81307
81551
|
"name": "0006_live_event_position_allocation.sql",
|
|
81308
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"
|
|
81309
81557
|
}
|
|
81310
81558
|
];
|
|
81311
81559
|
|
|
@@ -81960,12 +82208,12 @@ var SessionEvents = class {
|
|
|
81960
82208
|
}
|
|
81961
82209
|
};
|
|
81962
82210
|
};
|
|
81963
|
-
function liveEvent(sessionId, sessionGenerationId, eventId, position, event) {
|
|
82211
|
+
function liveEvent(sessionId, sessionGenerationId, eventId, position, event, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
81964
82212
|
return {
|
|
81965
82213
|
eventId,
|
|
81966
82214
|
...event,
|
|
81967
82215
|
position: position.toString(),
|
|
81968
|
-
recordedAt
|
|
82216
|
+
recordedAt,
|
|
81969
82217
|
sessionGenerationId,
|
|
81970
82218
|
sessionId
|
|
81971
82219
|
};
|
|
@@ -82003,7 +82251,7 @@ var MemorySessionEventStore = class {
|
|
|
82003
82251
|
}
|
|
82004
82252
|
return resolved;
|
|
82005
82253
|
};
|
|
82006
|
-
append = (sessionId, event) => {
|
|
82254
|
+
append = (sessionId, event, recordedAt) => {
|
|
82007
82255
|
const session = this.#session(sessionId);
|
|
82008
82256
|
const allocatedPosition = this.#allocatedPositionBySession.get(sessionId) ?? 9999;
|
|
82009
82257
|
if (allocatedPosition === Number.MAX_SAFE_INTEGER) {
|
|
@@ -82016,7 +82264,8 @@ var MemorySessionEventStore = class {
|
|
|
82016
82264
|
session.sessionGenerationId,
|
|
82017
82265
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
82018
82266
|
position,
|
|
82019
|
-
event
|
|
82267
|
+
event,
|
|
82268
|
+
recordedAt
|
|
82020
82269
|
);
|
|
82021
82270
|
session.apply(recorded, this.#resolver(session));
|
|
82022
82271
|
return recorded;
|
|
@@ -82057,12 +82306,14 @@ var MemorySessionEventStore = class {
|
|
|
82057
82306
|
};
|
|
82058
82307
|
};
|
|
82059
82308
|
var CachedSessionEventStore = class {
|
|
82309
|
+
#terminalOutcomes;
|
|
82060
82310
|
#cacheTable;
|
|
82061
82311
|
#eventIds;
|
|
82062
82312
|
#liveEventPositions;
|
|
82063
82313
|
#sessions = /* @__PURE__ */ new Map();
|
|
82064
82314
|
#flushSchedule = { kind: "idle" };
|
|
82065
|
-
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator()) {
|
|
82315
|
+
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator(), terminalOutcomes = () => []) {
|
|
82316
|
+
this.#terminalOutcomes = terminalOutcomes;
|
|
82066
82317
|
this.#eventIds = eventIds;
|
|
82067
82318
|
this.#liveEventPositions = liveEventPositions;
|
|
82068
82319
|
this.#cacheTable = cacheTable;
|
|
@@ -82095,7 +82346,7 @@ var CachedSessionEventStore = class {
|
|
|
82095
82346
|
}
|
|
82096
82347
|
return resolved;
|
|
82097
82348
|
};
|
|
82098
|
-
append = (sessionId, event) => {
|
|
82349
|
+
append = (sessionId, event, recordedAt) => {
|
|
82099
82350
|
if (this.#flushSchedule.kind === "closed") {
|
|
82100
82351
|
throw new Error("The V2 Session event store is closed");
|
|
82101
82352
|
}
|
|
@@ -82106,7 +82357,8 @@ var CachedSessionEventStore = class {
|
|
|
82106
82357
|
session.sessionGenerationId,
|
|
82107
82358
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
82108
82359
|
position,
|
|
82109
|
-
event
|
|
82360
|
+
event,
|
|
82361
|
+
recordedAt
|
|
82110
82362
|
);
|
|
82111
82363
|
session.apply(recorded, this.#resolver(sessionId, session));
|
|
82112
82364
|
this.#sessions.set(sessionId, session);
|
|
@@ -82195,6 +82447,9 @@ var CachedSessionEventStore = class {
|
|
|
82195
82447
|
this.#deletePersisted(sessionId, previous?.sessionGenerationId);
|
|
82196
82448
|
const sessionGenerationId = randomUUID11();
|
|
82197
82449
|
this.#sessions.set(sessionId, new SessionEvents(sessionGenerationId));
|
|
82450
|
+
for (const { event, recordedAt } of this.#terminalOutcomes(sessionId)) {
|
|
82451
|
+
this.append(sessionId, event, recordedAt);
|
|
82452
|
+
}
|
|
82198
82453
|
};
|
|
82199
82454
|
materializedEventCount = (sessionId) => this.#sessions.get(sessionId)?.materializedCount ?? 0;
|
|
82200
82455
|
close = () => {
|
|
@@ -82308,7 +82563,7 @@ function buildPromptContent(options, capabilities) {
|
|
|
82308
82563
|
}
|
|
82309
82564
|
|
|
82310
82565
|
// src/acp/connection/agent-connection.ts
|
|
82311
|
-
import { spawn as
|
|
82566
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
82312
82567
|
import { ndJsonStream as ndJsonStream3, RequestError as RequestError9 } from "@agentclientprotocol/sdk";
|
|
82313
82568
|
function requestErrorMessage(error62) {
|
|
82314
82569
|
const fallback = truncate(error62.message, 500);
|
|
@@ -82418,7 +82673,7 @@ var AgentConnection = class {
|
|
|
82418
82673
|
return;
|
|
82419
82674
|
}
|
|
82420
82675
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
82421
|
-
const child =
|
|
82676
|
+
const child = spawn8(launch.command, [...launch.arguments], {
|
|
82422
82677
|
cwd,
|
|
82423
82678
|
...platformSpawnOptions,
|
|
82424
82679
|
env: { ...process.env, ...agent.environment },
|
|
@@ -83692,6 +83947,19 @@ var RunningAgentTurn = class extends AgentTurnState {
|
|
|
83692
83947
|
|
|
83693
83948
|
// src/session/live/session-restore.ts
|
|
83694
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
|
+
}
|
|
83695
83963
|
async function restoreSession(session, signal, recovery, origin) {
|
|
83696
83964
|
if (origin !== void 0) {
|
|
83697
83965
|
session.setSessionTitle(origin.title);
|
|
@@ -83758,6 +84026,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
83758
84026
|
}
|
|
83759
84027
|
session.setPrompted(true);
|
|
83760
84028
|
session.setRestored(true);
|
|
84029
|
+
if (recovery.kind === "execution-only") {
|
|
84030
|
+
session.startExecutionOnlyCapture();
|
|
84031
|
+
}
|
|
83761
84032
|
lifecycleResponse2 = forked;
|
|
83762
84033
|
} else if (stored instanceof FoundStoredSession && stored.session.agentId === session.agentId && stored.session.cwd === session.cwd && arraysEqual(stored.session.additionalDirectories, session.additionalDirectories)) {
|
|
83763
84034
|
session.selectNativeSession(stored.session.nativeSessionId);
|
|
@@ -83776,6 +84047,37 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
83776
84047
|
"session-load",
|
|
83777
84048
|
async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
|
|
83778
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();
|
|
83779
84081
|
} else if (session.capabilities.resumeSession) {
|
|
83780
84082
|
lifecycleResponse2 = await session.metrics.measure(
|
|
83781
84083
|
"session-resume",
|
|
@@ -83835,6 +84137,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
83835
84137
|
);
|
|
83836
84138
|
session.selectNativeSession(created.sessionId);
|
|
83837
84139
|
session.setNativeHistoryOwnership({ kind: "fresh-session" });
|
|
84140
|
+
if (recovery.kind === "execution-only") {
|
|
84141
|
+
session.startExecutionOnlyCapture();
|
|
84142
|
+
}
|
|
83838
84143
|
lifecycleResponse2 = created;
|
|
83839
84144
|
}
|
|
83840
84145
|
session.restrictSessionCapabilities(lifecycleResponse2);
|
|
@@ -84112,6 +84417,16 @@ var AgentSession = class _AgentSession {
|
|
|
84112
84417
|
}
|
|
84113
84418
|
await this.#completedHistory(signal, "ACP agent exited while loading history");
|
|
84114
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
|
+
};
|
|
84115
84430
|
loadHistoryEvents = async (eventLimit, cursor, signal) => {
|
|
84116
84431
|
if (!this.#capabilities.loadSession) {
|
|
84117
84432
|
throw new AcpExecutionError(
|
|
@@ -84362,7 +84677,7 @@ var AgentSession = class _AgentSession {
|
|
|
84362
84677
|
response: {}
|
|
84363
84678
|
};
|
|
84364
84679
|
}
|
|
84365
|
-
if (this.#capabilities.loadSession) {
|
|
84680
|
+
if (this.#capabilities.loadSession && this.#sessionLoad.kind !== "execution-only") {
|
|
84366
84681
|
await this.#completedHistory(options.signal, "ACP agent exited while loading history before a prompt");
|
|
84367
84682
|
}
|
|
84368
84683
|
const prompt = this.buildPrompt(options);
|
|
@@ -84561,14 +84876,14 @@ var AgentSession = class _AgentSession {
|
|
|
84561
84876
|
onElicitationComplete = (notification) => this.#interactions.onElicitationComplete(notification);
|
|
84562
84877
|
onUpdate = (notification) => this.#updates.receive(notification);
|
|
84563
84878
|
recordControlEvent = async (event) => {
|
|
84564
|
-
if (this.#sessionLoad.kind !== "loaded") {
|
|
84879
|
+
if (this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
84565
84880
|
return false;
|
|
84566
84881
|
}
|
|
84567
84882
|
await this.recordLifecycleEvent(event);
|
|
84568
84883
|
return true;
|
|
84569
84884
|
};
|
|
84570
84885
|
recordLifecycleEvent = async (event) => {
|
|
84571
|
-
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded") {
|
|
84886
|
+
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
84572
84887
|
return;
|
|
84573
84888
|
}
|
|
84574
84889
|
const liveEvent2 = this.#sessionLoad.history.recordLifecycle(event);
|
|
@@ -84589,7 +84904,7 @@ var AgentSession = class _AgentSession {
|
|
|
84589
84904
|
const rawUpdate = decodeAcpSessionUpdate(JSON.stringify(externalized.event));
|
|
84590
84905
|
if (this.#sessionLoad.kind === "capturing") {
|
|
84591
84906
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
84592
|
-
} else if (this.#sessionLoad.kind === "loaded") {
|
|
84907
|
+
} else if (this.#sessionLoad.kind === "loaded" || this.#sessionLoad.kind === "execution-only") {
|
|
84593
84908
|
const onSessionEvent = this.#getObserver().onSessionEvent;
|
|
84594
84909
|
await this.#sessionLoad.history.record(update, rawUpdate, async (liveEvent2) => {
|
|
84595
84910
|
await onSessionEvent?.(liveEvent2);
|
|
@@ -85507,13 +85822,14 @@ var SessionManager2 = class {
|
|
|
85507
85822
|
}
|
|
85508
85823
|
async #replaceExecutionPreparation(existing, options) {
|
|
85509
85824
|
const desiredConfigOptions = existing.prepared().configOptions;
|
|
85825
|
+
const recovery = options.recovery ?? { kind: "interactive-only" };
|
|
85510
85826
|
return await this.#executionProcesses.prepare(options.sessionId, async () => {
|
|
85511
85827
|
await this.#retireSessionProcess(options.sessionId, existing, async () => await existing.close());
|
|
85512
85828
|
const runtime = await this.#startRetainedSessionProcess(
|
|
85513
85829
|
options,
|
|
85514
85830
|
async () => await AgentSession.start(
|
|
85515
85831
|
options,
|
|
85516
|
-
|
|
85832
|
+
recovery,
|
|
85517
85833
|
() => this.#observer,
|
|
85518
85834
|
this.#store,
|
|
85519
85835
|
unmeasuredOperationMetrics,
|
|
@@ -85691,6 +86007,7 @@ var SessionManager2 = class {
|
|
|
85691
86007
|
});
|
|
85692
86008
|
});
|
|
85693
86009
|
prepareExecutionSession = async (options) => this.#operations.run(options, async (options2) => {
|
|
86010
|
+
const recovery = options2.recovery ?? { kind: "interactive-only" };
|
|
85694
86011
|
this.#assertOpen(options2.sessionId);
|
|
85695
86012
|
const pending = this.#executionProcesses.pending(options2.sessionId);
|
|
85696
86013
|
if (pending !== void 0) {
|
|
@@ -85699,7 +86016,7 @@ var SessionManager2 = class {
|
|
|
85699
86016
|
}
|
|
85700
86017
|
const existing = this.#executionProcesses.get(options2.sessionId);
|
|
85701
86018
|
if (existing === void 0) {
|
|
85702
|
-
return (await this.#startPreparation(options2,
|
|
86019
|
+
return (await this.#startPreparation(options2, recovery)).prepared();
|
|
85703
86020
|
}
|
|
85704
86021
|
if (!existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
85705
86022
|
throw new AcpExecutionError(
|
|
@@ -85709,6 +86026,9 @@ var SessionManager2 = class {
|
|
|
85709
86026
|
);
|
|
85710
86027
|
}
|
|
85711
86028
|
if (existing.usesEnvironment(options2.agent.environment)) {
|
|
86029
|
+
if (recovery.kind === "execution-only") {
|
|
86030
|
+
existing.startExecutionOnlyCapture();
|
|
86031
|
+
}
|
|
85712
86032
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
85713
86033
|
return existing.prepared();
|
|
85714
86034
|
}
|
|
@@ -86003,10 +86323,13 @@ var SessionManager2 = class {
|
|
|
86003
86323
|
"session_identity_mismatch"
|
|
86004
86324
|
);
|
|
86005
86325
|
}
|
|
86326
|
+
if (options2.recovery?.kind === "execution-only") {
|
|
86327
|
+
existing.startExecutionOnlyCapture();
|
|
86328
|
+
}
|
|
86006
86329
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
86007
86330
|
return existing;
|
|
86008
86331
|
}
|
|
86009
|
-
await this
|
|
86332
|
+
await this.#prepareSession(options2, options2.recovery ?? { kind: "interactive-only" }, "reopen");
|
|
86010
86333
|
const started = this.#executionProcesses.get(options2.sessionId);
|
|
86011
86334
|
if (started === void 0) {
|
|
86012
86335
|
throw new AcpExecutionError("ACP session did not start");
|
|
@@ -86609,6 +86932,13 @@ var PromptLifecycle = class {
|
|
|
86609
86932
|
}
|
|
86610
86933
|
this.#queued.delete(commandId);
|
|
86611
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
|
+
};
|
|
86612
86942
|
queueChanged = async (sessionId) => {
|
|
86613
86943
|
await this.#recordLifecycle(sessionId, {
|
|
86614
86944
|
type: "lifecycle-metadata",
|
|
@@ -86642,7 +86972,7 @@ var PromptLifecycle = class {
|
|
|
86642
86972
|
type: "lifecycle-metadata",
|
|
86643
86973
|
payload: { kind: "prompt.failed-before-start", commandId, code, message }
|
|
86644
86974
|
});
|
|
86645
|
-
if (!recorded) {
|
|
86975
|
+
if (!recorded || code === SESSION_CLOSED_ERROR_CODE) {
|
|
86646
86976
|
this.#sink.publishOperationFailure(sessionId, commandId, code, message);
|
|
86647
86977
|
}
|
|
86648
86978
|
};
|
|
@@ -86679,18 +87009,149 @@ function isTerminal(state) {
|
|
|
86679
87009
|
}
|
|
86680
87010
|
var ExecutionReceipts = class {
|
|
86681
87011
|
#executions = /* @__PURE__ */ new Map();
|
|
87012
|
+
#recoveredCommands = /* @__PURE__ */ new Set();
|
|
86682
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
|
+
});
|
|
86683
87120
|
claimExecution = (commandId, sessionId, commandJson) => {
|
|
86684
87121
|
const commandHash = createHash6("sha256").update(commandJson).digest("hex");
|
|
86685
|
-
|
|
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
|
+
}
|
|
86686
87134
|
if (existing !== void 0) {
|
|
86687
87135
|
if (existing.sessionId !== sessionId || existing.commandHash !== commandHash) {
|
|
86688
87136
|
return { kind: "conflict" };
|
|
86689
87137
|
}
|
|
86690
|
-
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
|
+
};
|
|
86691
87145
|
}
|
|
86692
87146
|
const attemptId = randomUUID13();
|
|
86693
|
-
this.#
|
|
87147
|
+
this.#save(commandId, {
|
|
87148
|
+
attemptId,
|
|
87149
|
+
commandHash,
|
|
87150
|
+
sessionId,
|
|
87151
|
+
state: "dispatching",
|
|
87152
|
+
started: false,
|
|
87153
|
+
outcome: null
|
|
87154
|
+
});
|
|
86694
87155
|
return { attemptId, commandId, kind: "accepted", state: "dispatching" };
|
|
86695
87156
|
};
|
|
86696
87157
|
transitionExecution = (commandId, state) => {
|
|
@@ -86705,16 +87166,13 @@ var ExecutionReceipts = class {
|
|
|
86705
87166
|
if (!allowed) {
|
|
86706
87167
|
throw new Error("The runtime execution transition is invalid");
|
|
86707
87168
|
}
|
|
86708
|
-
|
|
86709
|
-
|
|
86710
|
-
|
|
86711
|
-
|
|
86712
|
-
(this.#terminalCountBySession.get(current.sessionId) ?? 0) + 1
|
|
86713
|
-
);
|
|
86714
|
-
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 });
|
|
86715
87173
|
}
|
|
86716
87174
|
};
|
|
86717
|
-
/**
|
|
87175
|
+
/** Only commands without a terminal result can still be cancelled. */
|
|
86718
87176
|
findUnsettledAttemptId = (commandId, sessionId) => {
|
|
86719
87177
|
const receipt = this.#executions.get(commandId);
|
|
86720
87178
|
return receipt?.sessionId === sessionId && !isTerminal(receipt.state) ? receipt.attemptId : null;
|
|
@@ -86725,7 +87183,9 @@ var ExecutionReceipts = class {
|
|
|
86725
87183
|
};
|
|
86726
87184
|
close = () => {
|
|
86727
87185
|
this.#executions.clear();
|
|
87186
|
+
this.#recoveredCommands.clear();
|
|
86728
87187
|
this.#terminalCountBySession.clear();
|
|
87188
|
+
this.#activeCount = 0;
|
|
86729
87189
|
};
|
|
86730
87190
|
pruneTerminalReceipts = (sessionId) => {
|
|
86731
87191
|
if ((this.#terminalCountBySession.get(sessionId) ?? 0) <= MAX_TERMINAL_RECEIPTS) {
|
|
@@ -86734,6 +87194,8 @@ var ExecutionReceipts = class {
|
|
|
86734
87194
|
for (const [commandId, receipt] of this.#executions) {
|
|
86735
87195
|
if (receipt.sessionId === sessionId && isTerminal(receipt.state)) {
|
|
86736
87196
|
this.#executions.delete(commandId);
|
|
87197
|
+
this.#recoveredCommands.delete(commandId);
|
|
87198
|
+
this.#table?.remove(commandId);
|
|
86737
87199
|
const remaining = (this.#terminalCountBySession.get(sessionId) ?? 1) - 1;
|
|
86738
87200
|
if (remaining > 0) {
|
|
86739
87201
|
this.#terminalCountBySession.set(sessionId, remaining);
|
|
@@ -87261,10 +87723,14 @@ function buildSessionLayer(options) {
|
|
|
87261
87723
|
const databases = channelSessionDatabasePaths(stateDirectory, channelId);
|
|
87262
87724
|
const sessionDatabase = openAcpSessionDatabase(databases.sessions);
|
|
87263
87725
|
let events;
|
|
87726
|
+
let operations;
|
|
87264
87727
|
try {
|
|
87728
|
+
operations = new ExecutionReceipts(new ExecutionReceiptTable(sessionDatabase), options.onExecutionCountChange);
|
|
87265
87729
|
events = new CachedSessionEventStore(
|
|
87266
87730
|
new SessionEventCacheTable(openSessionEventCacheDatabase(databases.events)),
|
|
87267
|
-
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase))
|
|
87731
|
+
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase)),
|
|
87732
|
+
void 0,
|
|
87733
|
+
(sessionId) => operations.terminalOutcomes(sessionId)
|
|
87268
87734
|
);
|
|
87269
87735
|
} catch (error62) {
|
|
87270
87736
|
sessionDatabase.close();
|
|
@@ -87272,11 +87738,13 @@ function buildSessionLayer(options) {
|
|
|
87272
87738
|
}
|
|
87273
87739
|
const sessionStore = new SqliteSessionStore(new AcpSessionTable(sessionDatabase), events);
|
|
87274
87740
|
const externalContent = new LocalExternalContentStore(stateDirectory);
|
|
87275
|
-
const operations = new ExecutionReceipts();
|
|
87276
87741
|
const activeSessions = new SessionTurns(operations, options.turnActivity);
|
|
87277
87742
|
const directories = new WorkspaceDirectoryService(bindingId, defaultWorkspace);
|
|
87278
87743
|
const manager = new SessionManager2({
|
|
87279
|
-
observer: new SessionLayerObserver((event) =>
|
|
87744
|
+
observer: new SessionLayerObserver((event) => {
|
|
87745
|
+
operations.recordOutcome(event);
|
|
87746
|
+
eventProjection.record(event);
|
|
87747
|
+
}, sink.publishInfo),
|
|
87280
87748
|
store: sessionStore,
|
|
87281
87749
|
adapters: harnessAdapters,
|
|
87282
87750
|
sessionIdentity: "native",
|
|
@@ -87297,7 +87765,15 @@ function buildSessionLayer(options) {
|
|
|
87297
87765
|
});
|
|
87298
87766
|
const eventProjection = new PromptLifecycle(
|
|
87299
87767
|
sink,
|
|
87300
|
-
(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
|
+
},
|
|
87301
87777
|
activeSessions.recordSessionEvent
|
|
87302
87778
|
);
|
|
87303
87779
|
const nativeSessions = new NativeSessionService(
|
|
@@ -87320,7 +87796,13 @@ function buildSessionLayer(options) {
|
|
|
87320
87796
|
);
|
|
87321
87797
|
})
|
|
87322
87798
|
);
|
|
87799
|
+
const recoveredEvents = operations.recover().map(({ sessionId, event, recordedAt }) => events.append(sessionId, event, recordedAt));
|
|
87323
87800
|
return {
|
|
87801
|
+
publishRecoveredOutcomes: () => {
|
|
87802
|
+
for (const event of recoveredEvents) {
|
|
87803
|
+
sink.publish(event);
|
|
87804
|
+
}
|
|
87805
|
+
},
|
|
87324
87806
|
activeSessions,
|
|
87325
87807
|
directories,
|
|
87326
87808
|
eventProjection,
|
|
@@ -89117,12 +89599,14 @@ async function executePrompt({
|
|
|
89117
89599
|
const appliedSettings = command.sessionConfigurations === void 0 ? void 0 : agentForSessionConfiguration(agent, command.sessionConfigurations);
|
|
89118
89600
|
const executionAgent = appliedSettings?.agent ?? agent;
|
|
89119
89601
|
const sessionConfigurations = appliedSettings?.sessionConfigurations;
|
|
89602
|
+
const recovery = command.historyPolicy === SessionHistoryPolicy.ExecutionOnly ? { kind: "execution-only" } : { kind: "interactive-only" };
|
|
89120
89603
|
const preparation = {
|
|
89121
89604
|
additionalDirectories: resolved.additionalDirectories,
|
|
89122
89605
|
agent: executionAgent,
|
|
89123
89606
|
cwd: resolved.cwd,
|
|
89124
89607
|
sessionId: command.sessionId,
|
|
89125
|
-
signal
|
|
89608
|
+
signal,
|
|
89609
|
+
recovery
|
|
89126
89610
|
};
|
|
89127
89611
|
let prepared = await sessions.prepareExecutionSession(preparation);
|
|
89128
89612
|
if (command.sessionConfigurations !== void 0) {
|
|
@@ -89191,7 +89675,8 @@ async function executePrompt({
|
|
|
89191
89675
|
resources: attachments.resources,
|
|
89192
89676
|
sessionId: command.sessionId,
|
|
89193
89677
|
signal,
|
|
89194
|
-
targetCommandId: command.targetCommandId
|
|
89678
|
+
targetCommandId: command.targetCommandId,
|
|
89679
|
+
recovery
|
|
89195
89680
|
});
|
|
89196
89681
|
stopReason = result.stopReason;
|
|
89197
89682
|
}
|
|
@@ -89360,6 +89845,12 @@ var sessionPromptCommand = {
|
|
|
89360
89845
|
return;
|
|
89361
89846
|
}
|
|
89362
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
|
+
}
|
|
89363
89854
|
return;
|
|
89364
89855
|
}
|
|
89365
89856
|
const turn = context.sessionTurns.start(message, receipt.attemptId);
|
|
@@ -90485,7 +90976,8 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
90485
90976
|
resolveAgent: (agentId, resolveSignal) => resolveCatalogAgent(config2, agentId, resolveSignal),
|
|
90486
90977
|
sink: publisher,
|
|
90487
90978
|
stateDirectory: config2.localContext.stateDirectory,
|
|
90488
|
-
timer
|
|
90979
|
+
timer,
|
|
90980
|
+
onExecutionCountChange: options.onExecutionCountChange ?? (() => void 0)
|
|
90489
90981
|
});
|
|
90490
90982
|
const {
|
|
90491
90983
|
activeSessions,
|
|
@@ -90555,6 +91047,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
90555
91047
|
reportUpgradeAvailability,
|
|
90556
91048
|
diagnostics,
|
|
90557
91049
|
onConnected: () => {
|
|
91050
|
+
layer.publishRecoveredOutcomes();
|
|
90558
91051
|
if (catalogPublished) {
|
|
90559
91052
|
options.onConnectionStatus?.("online");
|
|
90560
91053
|
}
|
|
@@ -90577,6 +91070,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
90577
91070
|
}
|
|
90578
91071
|
} finally {
|
|
90579
91072
|
shutdown.abort();
|
|
91073
|
+
operations.beginShutdown();
|
|
90580
91074
|
await activeSessions.close();
|
|
90581
91075
|
try {
|
|
90582
91076
|
await catalogPublication;
|
|
@@ -90713,6 +91207,10 @@ async function createMobiusRuntimeEngine(connection, signal, environment = proce
|
|
|
90713
91207
|
var MobiusRuntimeEngine = class {
|
|
90714
91208
|
#config;
|
|
90715
91209
|
#options;
|
|
91210
|
+
#activeTurnCount = 0;
|
|
91211
|
+
get activeTurnCount() {
|
|
91212
|
+
return this.#activeTurnCount;
|
|
91213
|
+
}
|
|
90716
91214
|
#state = new IdleMobiusRuntimeState();
|
|
90717
91215
|
constructor(config2, options = {}) {
|
|
90718
91216
|
validateRuntimeConfiguration(config2);
|
|
@@ -90728,11 +91226,15 @@ var MobiusRuntimeEngine = class {
|
|
|
90728
91226
|
try {
|
|
90729
91227
|
await runRuntime(this.#config, signal, void 0, {
|
|
90730
91228
|
...this.#options.turnActivity === void 0 ? {} : { turnActivity: this.#options.turnActivity },
|
|
91229
|
+
onExecutionCountChange: (count) => {
|
|
91230
|
+
this.#activeTurnCount = count;
|
|
91231
|
+
},
|
|
90731
91232
|
...this.#options.onConnectionStatus === void 0 ? {} : { onConnectionStatus: this.#options.onConnectionStatus },
|
|
90732
91233
|
...this.#options.reportUpgradeAvailability === void 0 ? {} : { reportUpgradeAvailability: this.#options.reportUpgradeAvailability },
|
|
90733
91234
|
...this.#options.processLogsDirectory === void 0 ? {} : { processLogsDirectory: this.#options.processLogsDirectory }
|
|
90734
91235
|
});
|
|
90735
91236
|
} finally {
|
|
91237
|
+
this.#activeTurnCount = 0;
|
|
90736
91238
|
this.#state = new FinishedMobiusRuntimeState();
|
|
90737
91239
|
}
|
|
90738
91240
|
};
|