@moxt-ai/mobius 0.0.300 → 0.0.302
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/agent.d.ts.map +1 -1
- package/dist/acp/harness/codex/agent.js +5 -1
- package/dist/acp/harness/codex/agent.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/cli.js +595 -61
- 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 +560 -54
- 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/cli.js
CHANGED
|
@@ -2086,16 +2086,28 @@ var init_package = __esm({
|
|
|
2086
2086
|
"package.json"() {
|
|
2087
2087
|
package_default = {
|
|
2088
2088
|
name: "@moxt-ai/mobius",
|
|
2089
|
-
version: "0.0.
|
|
2089
|
+
version: "0.0.302",
|
|
2090
2090
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
2091
2091
|
type: "module",
|
|
2092
2092
|
bin: {
|
|
2093
2093
|
mobius: "dist/cli.js"
|
|
2094
2094
|
},
|
|
2095
2095
|
exports: {
|
|
2096
|
-
"./runtime":
|
|
2097
|
-
|
|
2098
|
-
|
|
2096
|
+
"./runtime": {
|
|
2097
|
+
"mobius-source": "./src/runtime.ts",
|
|
2098
|
+
types: "./dist/runtime.d.ts",
|
|
2099
|
+
default: "./dist/runtime.js"
|
|
2100
|
+
},
|
|
2101
|
+
"./process": {
|
|
2102
|
+
"mobius-source": "./src/util/process/executable.ts",
|
|
2103
|
+
types: "./dist/util/process/executable.d.ts",
|
|
2104
|
+
default: "./dist/util/process/executable.js"
|
|
2105
|
+
},
|
|
2106
|
+
"./filesystem": {
|
|
2107
|
+
"mobius-source": "./src/util/filesystem/private-path.ts",
|
|
2108
|
+
types: "./dist/util/filesystem/private-path.d.ts",
|
|
2109
|
+
default: "./dist/util/filesystem/private-path.js"
|
|
2110
|
+
}
|
|
2099
2111
|
},
|
|
2100
2112
|
files: [
|
|
2101
2113
|
"dist"
|
|
@@ -5593,6 +5605,84 @@ var init_commander = __esm({
|
|
|
5593
5605
|
}
|
|
5594
5606
|
});
|
|
5595
5607
|
|
|
5608
|
+
// src/acp/harness/claude/parent-lifeline.ts
|
|
5609
|
+
import { spawn } from "node:child_process";
|
|
5610
|
+
import { Duplex } from "node:stream";
|
|
5611
|
+
function spawnClaudeWithParentLifeline(options) {
|
|
5612
|
+
options.signal.throwIfAborted();
|
|
5613
|
+
const child = spawn(process.execPath, ["-e", supervisor, "--", options.command, ...options.args], {
|
|
5614
|
+
cwd: options.cwd,
|
|
5615
|
+
env: options.env,
|
|
5616
|
+
stdio: ["pipe", "pipe", "pipe", "pipe"],
|
|
5617
|
+
windowsHide: true
|
|
5618
|
+
});
|
|
5619
|
+
const lifeline = child.stdio[3];
|
|
5620
|
+
if (child.stdin === null || child.stdout === null || child.stderr === null || !(lifeline instanceof Duplex)) {
|
|
5621
|
+
child.kill("SIGKILL");
|
|
5622
|
+
throw new Error("The Claude process supervisor has no parent lifeline");
|
|
5623
|
+
}
|
|
5624
|
+
let termination = "running";
|
|
5625
|
+
const stop = () => {
|
|
5626
|
+
termination = "requested";
|
|
5627
|
+
lifeline.end();
|
|
5628
|
+
return true;
|
|
5629
|
+
};
|
|
5630
|
+
options.signal.addEventListener("abort", stop, { once: true });
|
|
5631
|
+
if (options.signal.aborted) {
|
|
5632
|
+
stop();
|
|
5633
|
+
}
|
|
5634
|
+
child.once("close", () => options.signal.removeEventListener("abort", stop));
|
|
5635
|
+
child.stderr.pipe(process.stderr, { end: false });
|
|
5636
|
+
return {
|
|
5637
|
+
stdin: child.stdin,
|
|
5638
|
+
stdout: child.stdout,
|
|
5639
|
+
get killed() {
|
|
5640
|
+
return termination === "requested";
|
|
5641
|
+
},
|
|
5642
|
+
get exitCode() {
|
|
5643
|
+
return child.exitCode;
|
|
5644
|
+
},
|
|
5645
|
+
get signalCode() {
|
|
5646
|
+
return child.signalCode;
|
|
5647
|
+
},
|
|
5648
|
+
kill: stop,
|
|
5649
|
+
on: child.on.bind(child),
|
|
5650
|
+
once: child.once.bind(child),
|
|
5651
|
+
off: child.off.bind(child)
|
|
5652
|
+
};
|
|
5653
|
+
}
|
|
5654
|
+
var supervisor;
|
|
5655
|
+
var init_parent_lifeline = __esm({
|
|
5656
|
+
"src/acp/harness/claude/parent-lifeline.ts"() {
|
|
5657
|
+
"use strict";
|
|
5658
|
+
supervisor = `
|
|
5659
|
+
const { spawn, spawnSync } = require("node:child_process");
|
|
5660
|
+
const { Socket } = require("node:net");
|
|
5661
|
+
const [command, ...args] = process.argv.slice(1);
|
|
5662
|
+
const child = spawn(command, args, { stdio: ["pipe", "pipe", "pipe"], detached: process.platform !== "win32", windowsHide: true });
|
|
5663
|
+
const lifeline = new Socket({ fd: 3, readable: true, writable: false });
|
|
5664
|
+
let exited = false;
|
|
5665
|
+
function terminate() {
|
|
5666
|
+
if (exited || child.pid === undefined) return;
|
|
5667
|
+
if (process.platform === "win32") {
|
|
5668
|
+
spawnSync("taskkill", ["/pid", String(child.pid), "/T", "/F"], { timeout: 5000, windowsHide: true, stdio: "ignore" });
|
|
5669
|
+
} else {
|
|
5670
|
+
try { process.kill(-child.pid, "SIGKILL"); }
|
|
5671
|
+
catch (error) { if (error.code !== "ESRCH") throw error; }
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5674
|
+
lifeline.on("end", terminate).on("error", terminate).resume();
|
|
5675
|
+
process.on("SIGTERM", terminate).on("SIGINT", terminate);
|
|
5676
|
+
process.stdin.pipe(child.stdin);
|
|
5677
|
+
child.stdin.on("error", () => {});
|
|
5678
|
+
child.stdout.pipe(process.stdout);
|
|
5679
|
+
child.stderr.pipe(process.stderr);
|
|
5680
|
+
child.once("error", (error) => { process.stderr.write(error.message); process.exitCode = 1; lifeline.destroy(); process.stdin.destroy(); });
|
|
5681
|
+
child.once("close", (code) => { exited = true; process.exitCode = code ?? 1; lifeline.destroy(); process.stdin.destroy(); });
|
|
5682
|
+
`;
|
|
5683
|
+
}
|
|
5684
|
+
});
|
|
5685
|
+
|
|
5596
5686
|
// ../../node_modules/.pnpm/@anthropic-ai+claude-agent-sdk@0.3.257_@anthropic-ai+sdk@0.122.0_zod@4.6.5__@modelconte_b0b90ed00d211c5955785f7de7f8dbf4/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
5597
5687
|
import { createRequire as $ne } from "node:module";
|
|
5598
5688
|
import * as xr from "node:fs/promises";
|
|
@@ -66545,7 +66635,7 @@ async function runPromptWithCancellation(agent, params, signal) {
|
|
|
66545
66635
|
function createClaudeAcpApp(options = {}) {
|
|
66546
66636
|
let agent = null;
|
|
66547
66637
|
const app = acpAgent({ name: "claude-code-acp" }).onConnect((connection) => {
|
|
66548
|
-
agent = new ClaudeAcpAgent(new ClientConnection(connection.client, options.onSessionUpdate), options.logger, options.environment);
|
|
66638
|
+
agent = new ClaudeAcpAgent(new ClientConnection(connection.client, options.onSessionUpdate), options.logger, options.environment, options.spawnClaudeCodeProcess);
|
|
66549
66639
|
options.onConnect?.(connection);
|
|
66550
66640
|
}).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));
|
|
66551
66641
|
return { agent: () => agent, app };
|
|
@@ -66741,6 +66831,7 @@ var init_acp_agent = __esm({
|
|
|
66741
66831
|
};
|
|
66742
66832
|
mcpAuthentications = /* @__PURE__ */ new WeakMap();
|
|
66743
66833
|
ClaudeAcpAgent = class {
|
|
66834
|
+
spawnClaudeCodeProcess;
|
|
66744
66835
|
sessions;
|
|
66745
66836
|
client;
|
|
66746
66837
|
clientCapabilities;
|
|
@@ -66757,7 +66848,8 @@ var init_acp_agent = __esm({
|
|
|
66757
66848
|
* return "cancelled". See {@link DEFAULT_FORCE_CANCEL_GRACE_MS}. Mutable so
|
|
66758
66849
|
* tests can shrink it. */
|
|
66759
66850
|
forceCancelGraceMs = DEFAULT_FORCE_CANCEL_GRACE_MS;
|
|
66760
|
-
constructor(client2, logger, environment = process.env) {
|
|
66851
|
+
constructor(client2, logger, environment = process.env, spawnClaudeCodeProcess) {
|
|
66852
|
+
this.spawnClaudeCodeProcess = spawnClaudeCodeProcess;
|
|
66761
66853
|
this.sessions = {};
|
|
66762
66854
|
this.client = client2;
|
|
66763
66855
|
this.logger = logger ?? console;
|
|
@@ -69334,6 +69426,7 @@ ${message.api_refusal_explanation}` : "";
|
|
|
69334
69426
|
supportedDialogKinds: [REFUSAL_FALLBACK_DIALOG_KIND]
|
|
69335
69427
|
} : {},
|
|
69336
69428
|
pathToClaudeCodeExecutable: this.environment.CLAUDE_CODE_EXECUTABLE ?? await claudeCliPath(),
|
|
69429
|
+
...this.spawnClaudeCodeProcess === void 0 ? {} : { spawnClaudeCodeProcess: this.spawnClaudeCodeProcess },
|
|
69337
69430
|
extraArgs: {
|
|
69338
69431
|
...userProvidedOptions?.extraArgs,
|
|
69339
69432
|
"replay-user-messages": ""
|
|
@@ -69609,6 +69702,7 @@ var ClaudeAcpEndpoint;
|
|
|
69609
69702
|
var init_endpoint = __esm({
|
|
69610
69703
|
"src/acp/harness/claude/endpoint.ts"() {
|
|
69611
69704
|
"use strict";
|
|
69705
|
+
init_parent_lifeline();
|
|
69612
69706
|
init_lib();
|
|
69613
69707
|
ClaudeAcpEndpoint = class {
|
|
69614
69708
|
#agent;
|
|
@@ -69622,6 +69716,7 @@ var init_endpoint = __esm({
|
|
|
69622
69716
|
this.terminated = termination.promise;
|
|
69623
69717
|
this.#resolveTermination = termination.resolve;
|
|
69624
69718
|
const claude = createClaudeAcpApp({
|
|
69719
|
+
spawnClaudeCodeProcess: spawnClaudeWithParentLifeline,
|
|
69625
69720
|
environment: Object.freeze({
|
|
69626
69721
|
...process.env,
|
|
69627
69722
|
...options.environment,
|
|
@@ -70256,7 +70351,7 @@ var init_platform = __esm({
|
|
|
70256
70351
|
});
|
|
70257
70352
|
|
|
70258
70353
|
// src/util/process/executable.ts
|
|
70259
|
-
import { spawn as
|
|
70354
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
70260
70355
|
import { stat as stat4 } from "node:fs/promises";
|
|
70261
70356
|
import { join as join12, resolve as resolve8 } from "node:path";
|
|
70262
70357
|
async function resolveExecutablePath(requestedPath2, platform2 = process.platform) {
|
|
@@ -70422,7 +70517,7 @@ async function runBoundedProcess(options) {
|
|
|
70422
70517
|
options.signal.throwIfAborted();
|
|
70423
70518
|
const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES;
|
|
70424
70519
|
const launch = executableLaunch2(options.command, options.arguments);
|
|
70425
|
-
const child =
|
|
70520
|
+
const child = spawn3(launch.command, [...launch.arguments], {
|
|
70426
70521
|
cwd: options.cwd,
|
|
70427
70522
|
...hostPlatform.spawnOptions,
|
|
70428
70523
|
env: { ...options.environment },
|
|
@@ -71053,7 +71148,7 @@ var init_app_server_protocol = __esm({
|
|
|
71053
71148
|
});
|
|
71054
71149
|
|
|
71055
71150
|
// src/acp/harness/codex/app-server-client.ts
|
|
71056
|
-
import { spawn as
|
|
71151
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
71057
71152
|
var INITIALIZE_TIMEOUT_MILLISECONDS, MESSAGE_OUTPUT_LIMIT_BYTES, CodexAppServerError, CodexAppServerClient;
|
|
71058
71153
|
var init_app_server_client = __esm({
|
|
71059
71154
|
"src/acp/harness/codex/app-server-client.ts"() {
|
|
@@ -71085,7 +71180,7 @@ var init_app_server_client = __esm({
|
|
|
71085
71180
|
constructor(options) {
|
|
71086
71181
|
this.#handlers = options.handlers;
|
|
71087
71182
|
const launch = executableLaunch2(options.command, ["app-server"]);
|
|
71088
|
-
this.#child =
|
|
71183
|
+
this.#child = spawn4(launch.command, [...launch.arguments], {
|
|
71089
71184
|
cwd: options.cwd,
|
|
71090
71185
|
...platformSpawnOptions,
|
|
71091
71186
|
env: { ...process.env, ...options.environment },
|
|
@@ -71468,12 +71563,12 @@ function presentToolItem(item) {
|
|
|
71468
71563
|
};
|
|
71469
71564
|
}
|
|
71470
71565
|
if (item.type === "collabAgentToolCall") {
|
|
71471
|
-
const
|
|
71566
|
+
const spawn11 = item.tool === "spawnAgent";
|
|
71472
71567
|
return {
|
|
71473
71568
|
content: [],
|
|
71474
71569
|
kind: "other",
|
|
71475
71570
|
locations: [],
|
|
71476
|
-
rawInput:
|
|
71571
|
+
rawInput: spawn11 ? {
|
|
71477
71572
|
model: item.model,
|
|
71478
71573
|
prompt: item.prompt,
|
|
71479
71574
|
reasoningEffort: item.reasoningEffort,
|
|
@@ -71481,10 +71576,10 @@ function presentToolItem(item) {
|
|
|
71481
71576
|
} : { receiverThreadIds: item.receiverThreadIds, senderThreadId: item.senderThreadId },
|
|
71482
71577
|
rawOutput: {
|
|
71483
71578
|
agentsStates: item.agentsStates,
|
|
71484
|
-
...
|
|
71579
|
+
...spawn11 ? { receiverThreadIds: item.receiverThreadIds } : {}
|
|
71485
71580
|
},
|
|
71486
71581
|
status: collaborationStatus(item.status),
|
|
71487
|
-
title:
|
|
71582
|
+
title: spawn11 ? "Dispatch subagent" : "Wait for subagent"
|
|
71488
71583
|
};
|
|
71489
71584
|
}
|
|
71490
71585
|
if (item.type === "subAgentActivity" && item.kind === "started") {
|
|
@@ -73624,6 +73719,9 @@ function decodeSessionPromptCommand(encoded) {
|
|
|
73624
73719
|
directoryId: readDirectoryIdentifier(value, "directoryId"),
|
|
73625
73720
|
disposition,
|
|
73626
73721
|
images,
|
|
73722
|
+
...value["historyPolicy"] === void 0 ? {} : {
|
|
73723
|
+
historyPolicy: readHistoryPolicy(value)
|
|
73724
|
+
},
|
|
73627
73725
|
kind: SESSION_PROMPT_KIND,
|
|
73628
73726
|
prompt,
|
|
73629
73727
|
resources,
|
|
@@ -73632,6 +73730,13 @@ function decodeSessionPromptCommand(encoded) {
|
|
|
73632
73730
|
targetCommandId
|
|
73633
73731
|
};
|
|
73634
73732
|
}
|
|
73733
|
+
function readHistoryPolicy(value) {
|
|
73734
|
+
const field = value["historyPolicy"];
|
|
73735
|
+
if (field === SessionHistoryPolicy.Eager || field === SessionHistoryPolicy.ExecutionOnly) {
|
|
73736
|
+
return field;
|
|
73737
|
+
}
|
|
73738
|
+
throw new ProtocolMessageError("Invalid value field: historyPolicy");
|
|
73739
|
+
}
|
|
73635
73740
|
function decodeSessionCancelCommand(encoded) {
|
|
73636
73741
|
const value = parseJson(encoded);
|
|
73637
73742
|
assertKind(value, SESSION_CANCEL_KIND);
|
|
@@ -73663,7 +73768,7 @@ function encodeSessionCancelCommand(message) {
|
|
|
73663
73768
|
function encodeSessionPromptDispositionCommand(message) {
|
|
73664
73769
|
return JSON.stringify(decodeSessionPromptDispositionCommand(JSON.stringify(message)));
|
|
73665
73770
|
}
|
|
73666
|
-
var SESSION_PROMPT_KIND, SESSION_PROMPT_DISPOSITION_KIND, SESSION_CANCEL_KIND, SessionPromptDisposition, MAX_PROMPT_LENGTH, MAX_PROMPT_ATTACHMENT_LENGTH, promptImageSchema, promptResourceSchema, decodePromptImagesValue, decodePromptResourcesValue;
|
|
73771
|
+
var SESSION_PROMPT_KIND, SESSION_PROMPT_DISPOSITION_KIND, SESSION_CANCEL_KIND, SessionPromptDisposition, SessionHistoryPolicy, MAX_PROMPT_LENGTH, MAX_PROMPT_ATTACHMENT_LENGTH, promptImageSchema, promptResourceSchema, decodePromptImagesValue, decodePromptResourcesValue;
|
|
73667
73772
|
var init_commands = __esm({
|
|
73668
73773
|
"../mobius-sdk/src/protocol/session/prompt/commands.ts"() {
|
|
73669
73774
|
"use strict";
|
|
@@ -73679,6 +73784,10 @@ var init_commands = __esm({
|
|
|
73679
73784
|
Reject: "reject",
|
|
73680
73785
|
Steer: "steer"
|
|
73681
73786
|
});
|
|
73787
|
+
SessionHistoryPolicy = Object.freeze({
|
|
73788
|
+
Eager: "eager",
|
|
73789
|
+
ExecutionOnly: "execution-only"
|
|
73790
|
+
});
|
|
73682
73791
|
MAX_PROMPT_LENGTH = 1e5;
|
|
73683
73792
|
MAX_PROMPT_ATTACHMENT_LENGTH = 6e6;
|
|
73684
73793
|
promptImageSchema = external_exports.object({
|
|
@@ -75612,7 +75721,11 @@ var init_agent = __esm({
|
|
|
75612
75721
|
const decoded = threadListResponseSchema.parse(
|
|
75613
75722
|
await this.#appServer.request(
|
|
75614
75723
|
"thread/list",
|
|
75615
|
-
{
|
|
75724
|
+
{
|
|
75725
|
+
cursor: context.params.cursor ?? null,
|
|
75726
|
+
// Codex defaults to interactive sources and otherwise hides exec handoffs.
|
|
75727
|
+
sourceKinds: ["cli", "vscode", "exec", "appServer"]
|
|
75728
|
+
},
|
|
75616
75729
|
AbortSignal.any([context.signal, AbortSignal.timeout(SESSION_LIST_TIMEOUT_MILLISECONDS2)])
|
|
75617
75730
|
)
|
|
75618
75731
|
);
|
|
@@ -75866,7 +75979,7 @@ var init_command2 = __esm({
|
|
|
75866
75979
|
});
|
|
75867
75980
|
|
|
75868
75981
|
// src/acp/harness/pi/upstream/dist/pi-rpc/process.js
|
|
75869
|
-
import { spawn as
|
|
75982
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
75870
75983
|
import * as readline from "node:readline";
|
|
75871
75984
|
function stripAnsi(s) {
|
|
75872
75985
|
return s.replace(ANSI_ESCAPE_REGEX, "");
|
|
@@ -75970,7 +76083,7 @@ var init_process = __esm({
|
|
|
75970
76083
|
args.push("--fork", params.origin.sessionPath);
|
|
75971
76084
|
break;
|
|
75972
76085
|
}
|
|
75973
|
-
const child =
|
|
76086
|
+
const child = spawn5(cmd, args, {
|
|
75974
76087
|
cwd: params.cwd,
|
|
75975
76088
|
stdio: "pipe",
|
|
75976
76089
|
env: params.environment,
|
|
@@ -79410,6 +79523,77 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
79410
79523
|
}, 0);
|
|
79411
79524
|
return { sessionId: session.sessionId, configOptions, modes };
|
|
79412
79525
|
}
|
|
79526
|
+
async resumeSession(params) {
|
|
79527
|
+
if (!isAbsolute11(params.cwd)) {
|
|
79528
|
+
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
79529
|
+
}
|
|
79530
|
+
this.sessions.close(params.sessionId);
|
|
79531
|
+
this.lastSessionCwd = params.cwd;
|
|
79532
|
+
const stored = this.findStoredSession(params.sessionId);
|
|
79533
|
+
if (!stored) {
|
|
79534
|
+
throw RequestError7.invalidParams(`Unknown sessionId: ${params.sessionId}`);
|
|
79535
|
+
}
|
|
79536
|
+
const session = await this.restoreSession(params.sessionId, {
|
|
79537
|
+
cwd: params.cwd,
|
|
79538
|
+
mcpServers: params.mcpServers
|
|
79539
|
+
});
|
|
79540
|
+
let configuration;
|
|
79541
|
+
try {
|
|
79542
|
+
configuration = await getSessionConfiguration(session.proc);
|
|
79543
|
+
} catch (err) {
|
|
79544
|
+
this.sessions.close(session.sessionId);
|
|
79545
|
+
throw err;
|
|
79546
|
+
}
|
|
79547
|
+
const { configOptions, models, modes } = configuration;
|
|
79548
|
+
const enableSkillCommands = getEnableSkillCommands(params.cwd, this.environment);
|
|
79549
|
+
const fileCommands = loadSlashCommands(params.cwd, this.environment);
|
|
79550
|
+
this.sessions.closeAllExcept?.(session.sessionId);
|
|
79551
|
+
this.store.upsert({
|
|
79552
|
+
sessionId: params.sessionId,
|
|
79553
|
+
cwd: params.cwd,
|
|
79554
|
+
sessionFile: stored.sessionFile
|
|
79555
|
+
});
|
|
79556
|
+
const response = {
|
|
79557
|
+
configOptions,
|
|
79558
|
+
models,
|
|
79559
|
+
modes,
|
|
79560
|
+
_meta: {
|
|
79561
|
+
piAcp: {
|
|
79562
|
+
startupInfo: null
|
|
79563
|
+
}
|
|
79564
|
+
}
|
|
79565
|
+
};
|
|
79566
|
+
setTimeout(() => {
|
|
79567
|
+
void (async () => {
|
|
79568
|
+
await session.publishContextUsage();
|
|
79569
|
+
try {
|
|
79570
|
+
const pi2 = await session.proc.getCommands();
|
|
79571
|
+
const { commands } = toAvailableCommandsFromPiGetCommands(pi2, {
|
|
79572
|
+
enableSkillCommands,
|
|
79573
|
+
includeExtensionCommands: false
|
|
79574
|
+
});
|
|
79575
|
+
await this.conn.sessionUpdate({
|
|
79576
|
+
sessionId: session.sessionId,
|
|
79577
|
+
update: {
|
|
79578
|
+
sessionUpdate: "available_commands_update",
|
|
79579
|
+
availableCommands: mergeCommands(commands, builtinAvailableCommands())
|
|
79580
|
+
}
|
|
79581
|
+
});
|
|
79582
|
+
return;
|
|
79583
|
+
} catch {
|
|
79584
|
+
}
|
|
79585
|
+
await this.conn.sessionUpdate({
|
|
79586
|
+
sessionId: session.sessionId,
|
|
79587
|
+
update: {
|
|
79588
|
+
sessionUpdate: "available_commands_update",
|
|
79589
|
+
availableCommands: mergeCommands(toAvailableCommands(fileCommands), builtinAvailableCommands())
|
|
79590
|
+
}
|
|
79591
|
+
});
|
|
79592
|
+
})().catch(() => {
|
|
79593
|
+
});
|
|
79594
|
+
}, 0);
|
|
79595
|
+
return response;
|
|
79596
|
+
}
|
|
79413
79597
|
async loadSession(params) {
|
|
79414
79598
|
if (!isAbsolute11(params.cwd)) {
|
|
79415
79599
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
@@ -79689,6 +79873,9 @@ var init_endpoint2 = __esm({
|
|
|
79689
79873
|
).onRequest(
|
|
79690
79874
|
methods5.agent.session.load,
|
|
79691
79875
|
async (context) => await piAgentOrThrow(piAgent).loadSession(context.params)
|
|
79876
|
+
).onRequest(
|
|
79877
|
+
methods5.agent.session.resume,
|
|
79878
|
+
async (context) => await piAgentOrThrow(piAgent).resumeSession(context.params)
|
|
79692
79879
|
).onRequest(
|
|
79693
79880
|
methods5.agent.session.list,
|
|
79694
79881
|
async (context) => await piAgentOrThrow(piAgent).listSessions(context.params)
|
|
@@ -80215,7 +80402,7 @@ var init_create_client = __esm({
|
|
|
80215
80402
|
});
|
|
80216
80403
|
|
|
80217
80404
|
// src/agent/discovery/acp-readiness-probe.ts
|
|
80218
|
-
import { spawn as
|
|
80405
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
80219
80406
|
import {
|
|
80220
80407
|
methods as methods8,
|
|
80221
80408
|
ndJsonStream as ndJsonStream2,
|
|
@@ -80372,7 +80559,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
|
|
|
80372
80559
|
}
|
|
80373
80560
|
}
|
|
80374
80561
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
80375
|
-
const child =
|
|
80562
|
+
const child = spawn6(launch.command, [...launch.arguments], {
|
|
80376
80563
|
cwd: defaultWorkspace,
|
|
80377
80564
|
...platformSpawnOptions,
|
|
80378
80565
|
env: { ...environment, ...agent.environment },
|
|
@@ -83043,7 +83230,7 @@ var init_worker_lifecycle_log = __esm({
|
|
|
83043
83230
|
});
|
|
83044
83231
|
|
|
83045
83232
|
// src/daemon/lifecycle/worker-process.ts
|
|
83046
|
-
import { spawn as
|
|
83233
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
83047
83234
|
import { isAbsolute as isAbsolute13, resolve as resolve16 } from "node:path";
|
|
83048
83235
|
function currentWorkerLaunch(version2) {
|
|
83049
83236
|
const entry = process.argv[1];
|
|
@@ -83103,7 +83290,7 @@ var init_worker_process = __esm({
|
|
|
83103
83290
|
constructor(launch, signal, environment) {
|
|
83104
83291
|
signal.throwIfAborted();
|
|
83105
83292
|
this.launch = launch;
|
|
83106
|
-
this.#child =
|
|
83293
|
+
this.#child = spawn7(launch.executable, [launch.entry, "__worker"], {
|
|
83107
83294
|
env: environment,
|
|
83108
83295
|
windowsHide: true,
|
|
83109
83296
|
stdio: ["ignore", "pipe", "pipe", "ipc"]
|
|
@@ -83436,9 +83623,9 @@ var init_manager2 = __esm({
|
|
|
83436
83623
|
});
|
|
83437
83624
|
|
|
83438
83625
|
// src/daemon/lifecycle/manager-client.ts
|
|
83439
|
-
import { spawn as
|
|
83626
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
83440
83627
|
async function spawnManager() {
|
|
83441
|
-
const child =
|
|
83628
|
+
const child = spawn8(process.execPath, [process.argv[1] ?? "", "__manager"], {
|
|
83442
83629
|
detached: true,
|
|
83443
83630
|
windowsHide: true,
|
|
83444
83631
|
env: process.env,
|
|
@@ -83844,7 +84031,7 @@ var init_history_images = __esm({
|
|
|
83844
84031
|
});
|
|
83845
84032
|
|
|
83846
84033
|
// src/acp/native-history/codex/codex-history.ts
|
|
83847
|
-
import { spawn as
|
|
84034
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
83848
84035
|
function bounded(value, maximum) {
|
|
83849
84036
|
return value.slice(0, maximum);
|
|
83850
84037
|
}
|
|
@@ -84220,7 +84407,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
|
|
|
84220
84407
|
}
|
|
84221
84408
|
signal.throwIfAborted();
|
|
84222
84409
|
const launch = executableLaunch2(agent.agentIdentity.realPath, ["app-server"]);
|
|
84223
|
-
const child =
|
|
84410
|
+
const child = spawn9(launch.command, [...launch.arguments], {
|
|
84224
84411
|
cwd,
|
|
84225
84412
|
env: { ...process.env, ...agent.environment },
|
|
84226
84413
|
...platformSpawnOptions,
|
|
@@ -90233,6 +90420,25 @@ var init_acp_session = __esm({
|
|
|
90233
90420
|
}
|
|
90234
90421
|
});
|
|
90235
90422
|
|
|
90423
|
+
// src/schema/acp-session-store/execution-receipt.ts
|
|
90424
|
+
var executionReceipt;
|
|
90425
|
+
var init_execution_receipt = __esm({
|
|
90426
|
+
"src/schema/acp-session-store/execution-receipt.ts"() {
|
|
90427
|
+
"use strict";
|
|
90428
|
+
init_sqlite_core();
|
|
90429
|
+
executionReceipt = sqliteTable("execution_receipt", {
|
|
90430
|
+
commandId: text("command_id").primaryKey(),
|
|
90431
|
+
sessionId: text("session_id").notNull(),
|
|
90432
|
+
commandHash: text("command_hash").notNull(),
|
|
90433
|
+
attemptId: text("attempt_id").notNull(),
|
|
90434
|
+
state: text("state").notNull(),
|
|
90435
|
+
started: integer2("started", { mode: "boolean" }).notNull(),
|
|
90436
|
+
outcome: text("outcome"),
|
|
90437
|
+
updatedAt: text("updated_at").notNull()
|
|
90438
|
+
});
|
|
90439
|
+
}
|
|
90440
|
+
});
|
|
90441
|
+
|
|
90236
90442
|
// src/schema/acp-session-store/session-live-event-position-allocation.ts
|
|
90237
90443
|
var sessionLiveEventPositionAllocation;
|
|
90238
90444
|
var init_session_live_event_position_allocation = __esm({
|
|
@@ -90251,6 +90457,7 @@ var init_acp_session_store = __esm({
|
|
|
90251
90457
|
"src/schema/acp-session-store/index.ts"() {
|
|
90252
90458
|
"use strict";
|
|
90253
90459
|
init_acp_session();
|
|
90460
|
+
init_execution_receipt();
|
|
90254
90461
|
init_session_live_event_position_allocation();
|
|
90255
90462
|
}
|
|
90256
90463
|
});
|
|
@@ -90299,6 +90506,71 @@ var init_acp_session_table = __esm({
|
|
|
90299
90506
|
}
|
|
90300
90507
|
});
|
|
90301
90508
|
|
|
90509
|
+
// src/storage/session/execution-receipt-table.ts
|
|
90510
|
+
var receiptFields, receiptSchema, ExecutionReceiptTable;
|
|
90511
|
+
var init_execution_receipt_table = __esm({
|
|
90512
|
+
"src/storage/session/execution-receipt-table.ts"() {
|
|
90513
|
+
"use strict";
|
|
90514
|
+
init_drizzle_orm();
|
|
90515
|
+
init_zod();
|
|
90516
|
+
init_acp_session_store();
|
|
90517
|
+
receiptFields = external_exports.object({
|
|
90518
|
+
commandId: external_exports.string(),
|
|
90519
|
+
sessionId: external_exports.string(),
|
|
90520
|
+
commandHash: external_exports.string(),
|
|
90521
|
+
attemptId: external_exports.string(),
|
|
90522
|
+
updatedAt: external_exports.string()
|
|
90523
|
+
});
|
|
90524
|
+
receiptSchema = external_exports.discriminatedUnion("state", [
|
|
90525
|
+
receiptFields.extend({ state: external_exports.literal("dispatching"), started: external_exports.literal(false), outcome: external_exports.null() }),
|
|
90526
|
+
receiptFields.extend({ state: external_exports.literal("running"), started: external_exports.literal(true), outcome: external_exports.string().nullable() }),
|
|
90527
|
+
receiptFields.extend({
|
|
90528
|
+
state: external_exports.enum(["succeeded", "failed", "cancelled"]),
|
|
90529
|
+
started: external_exports.boolean(),
|
|
90530
|
+
outcome: external_exports.string().nullable()
|
|
90531
|
+
})
|
|
90532
|
+
]).readonly();
|
|
90533
|
+
ExecutionReceiptTable = class {
|
|
90534
|
+
#database;
|
|
90535
|
+
constructor(database) {
|
|
90536
|
+
this.#database = database;
|
|
90537
|
+
}
|
|
90538
|
+
list = () => receiptSchema.array().parse(
|
|
90539
|
+
this.#database.orm.select().from(executionReceipt).orderBy(asc(executionReceipt.updatedAt), asc(executionReceipt.commandId)).all()
|
|
90540
|
+
);
|
|
90541
|
+
save = (receipt) => {
|
|
90542
|
+
this.#database.transaction(() => {
|
|
90543
|
+
this.#database.orm.insert(executionReceipt).values(receipt).onConflictDoUpdate({ target: executionReceipt.commandId, set: receipt }).run();
|
|
90544
|
+
if (receipt.state === "dispatching" || receipt.state === "running") {
|
|
90545
|
+
return;
|
|
90546
|
+
}
|
|
90547
|
+
const retained = this.#database.orm.select({ commandId: executionReceipt.commandId }).from(executionReceipt).where(
|
|
90548
|
+
and(
|
|
90549
|
+
eq2(executionReceipt.sessionId, receipt.sessionId),
|
|
90550
|
+
inArray(executionReceipt.state, ["succeeded", "failed", "cancelled"])
|
|
90551
|
+
)
|
|
90552
|
+
).orderBy(desc(executionReceipt.updatedAt), desc(executionReceipt.commandId)).limit(1024).all();
|
|
90553
|
+
if (retained.length === 1024) {
|
|
90554
|
+
this.#database.orm.delete(executionReceipt).where(
|
|
90555
|
+
and(
|
|
90556
|
+
eq2(executionReceipt.sessionId, receipt.sessionId),
|
|
90557
|
+
inArray(executionReceipt.state, ["succeeded", "failed", "cancelled"]),
|
|
90558
|
+
notInArray(
|
|
90559
|
+
executionReceipt.commandId,
|
|
90560
|
+
retained.map((row) => row.commandId)
|
|
90561
|
+
)
|
|
90562
|
+
)
|
|
90563
|
+
).run();
|
|
90564
|
+
}
|
|
90565
|
+
});
|
|
90566
|
+
};
|
|
90567
|
+
remove = (commandId) => {
|
|
90568
|
+
this.#database.orm.delete(executionReceipt).where(eq2(executionReceipt.commandId, commandId)).run();
|
|
90569
|
+
};
|
|
90570
|
+
};
|
|
90571
|
+
}
|
|
90572
|
+
});
|
|
90573
|
+
|
|
90302
90574
|
// src/storage/session/live-event-position-table.ts
|
|
90303
90575
|
var allocationRowSchema, LiveEventPositionTable;
|
|
90304
90576
|
var init_live_event_position_table = __esm({
|
|
@@ -90552,6 +90824,10 @@ var init_acp_session_store_migrations = __esm({
|
|
|
90552
90824
|
{
|
|
90553
90825
|
"name": "0006_live_event_position_allocation.sql",
|
|
90554
90826
|
"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"
|
|
90827
|
+
},
|
|
90828
|
+
{
|
|
90829
|
+
"name": "0007_busy_excalibur.sql",
|
|
90830
|
+
"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"
|
|
90555
90831
|
}
|
|
90556
90832
|
];
|
|
90557
90833
|
}
|
|
@@ -91170,12 +91446,12 @@ var init_session_event_id_allocator = __esm({
|
|
|
91170
91446
|
|
|
91171
91447
|
// src/session/history/session-event-store.ts
|
|
91172
91448
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
91173
|
-
function liveEvent(sessionId, sessionGenerationId, eventId, position, event) {
|
|
91449
|
+
function liveEvent(sessionId, sessionGenerationId, eventId, position, event, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
91174
91450
|
return {
|
|
91175
91451
|
eventId,
|
|
91176
91452
|
...event,
|
|
91177
91453
|
position: position.toString(),
|
|
91178
|
-
recordedAt
|
|
91454
|
+
recordedAt,
|
|
91179
91455
|
sessionGenerationId,
|
|
91180
91456
|
sessionId
|
|
91181
91457
|
};
|
|
@@ -91336,7 +91612,7 @@ var init_session_event_store = __esm({
|
|
|
91336
91612
|
}
|
|
91337
91613
|
return resolved;
|
|
91338
91614
|
};
|
|
91339
|
-
append = (sessionId, event) => {
|
|
91615
|
+
append = (sessionId, event, recordedAt) => {
|
|
91340
91616
|
const session = this.#session(sessionId);
|
|
91341
91617
|
const allocatedPosition = this.#allocatedPositionBySession.get(sessionId) ?? 9999;
|
|
91342
91618
|
if (allocatedPosition === Number.MAX_SAFE_INTEGER) {
|
|
@@ -91349,7 +91625,8 @@ var init_session_event_store = __esm({
|
|
|
91349
91625
|
session.sessionGenerationId,
|
|
91350
91626
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
91351
91627
|
position,
|
|
91352
|
-
event
|
|
91628
|
+
event,
|
|
91629
|
+
recordedAt
|
|
91353
91630
|
);
|
|
91354
91631
|
session.apply(recorded, this.#resolver(session));
|
|
91355
91632
|
return recorded;
|
|
@@ -91390,12 +91667,14 @@ var init_session_event_store = __esm({
|
|
|
91390
91667
|
};
|
|
91391
91668
|
};
|
|
91392
91669
|
CachedSessionEventStore = class {
|
|
91670
|
+
#terminalOutcomes;
|
|
91393
91671
|
#cacheTable;
|
|
91394
91672
|
#eventIds;
|
|
91395
91673
|
#liveEventPositions;
|
|
91396
91674
|
#sessions = /* @__PURE__ */ new Map();
|
|
91397
91675
|
#flushSchedule = { kind: "idle" };
|
|
91398
|
-
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator()) {
|
|
91676
|
+
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator(), terminalOutcomes = () => []) {
|
|
91677
|
+
this.#terminalOutcomes = terminalOutcomes;
|
|
91399
91678
|
this.#eventIds = eventIds;
|
|
91400
91679
|
this.#liveEventPositions = liveEventPositions;
|
|
91401
91680
|
this.#cacheTable = cacheTable;
|
|
@@ -91428,7 +91707,7 @@ var init_session_event_store = __esm({
|
|
|
91428
91707
|
}
|
|
91429
91708
|
return resolved;
|
|
91430
91709
|
};
|
|
91431
|
-
append = (sessionId, event) => {
|
|
91710
|
+
append = (sessionId, event, recordedAt) => {
|
|
91432
91711
|
if (this.#flushSchedule.kind === "closed") {
|
|
91433
91712
|
throw new Error("The V2 Session event store is closed");
|
|
91434
91713
|
}
|
|
@@ -91439,7 +91718,8 @@ var init_session_event_store = __esm({
|
|
|
91439
91718
|
session.sessionGenerationId,
|
|
91440
91719
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
91441
91720
|
position,
|
|
91442
|
-
event
|
|
91721
|
+
event,
|
|
91722
|
+
recordedAt
|
|
91443
91723
|
);
|
|
91444
91724
|
session.apply(recorded, this.#resolver(sessionId, session));
|
|
91445
91725
|
this.#sessions.set(sessionId, session);
|
|
@@ -91528,6 +91808,9 @@ var init_session_event_store = __esm({
|
|
|
91528
91808
|
this.#deletePersisted(sessionId, previous?.sessionGenerationId);
|
|
91529
91809
|
const sessionGenerationId = randomUUID12();
|
|
91530
91810
|
this.#sessions.set(sessionId, new SessionEvents(sessionGenerationId));
|
|
91811
|
+
for (const { event, recordedAt } of this.#terminalOutcomes(sessionId)) {
|
|
91812
|
+
this.append(sessionId, event, recordedAt);
|
|
91813
|
+
}
|
|
91531
91814
|
};
|
|
91532
91815
|
materializedEventCount = (sessionId) => this.#sessions.get(sessionId)?.materializedCount ?? 0;
|
|
91533
91816
|
close = () => {
|
|
@@ -91648,7 +91931,7 @@ var init_prompt_content = __esm({
|
|
|
91648
91931
|
});
|
|
91649
91932
|
|
|
91650
91933
|
// src/acp/connection/agent-connection.ts
|
|
91651
|
-
import { spawn as
|
|
91934
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
91652
91935
|
import { ndJsonStream as ndJsonStream3, RequestError as RequestError9 } from "@agentclientprotocol/sdk";
|
|
91653
91936
|
function requestErrorMessage(error62) {
|
|
91654
91937
|
const fallback = truncate2(error62.message, 500);
|
|
@@ -91767,7 +92050,7 @@ var init_agent_connection = __esm({
|
|
|
91767
92050
|
return;
|
|
91768
92051
|
}
|
|
91769
92052
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
91770
|
-
const child =
|
|
92053
|
+
const child = spawn10(launch.command, [...launch.arguments], {
|
|
91771
92054
|
cwd,
|
|
91772
92055
|
...platformSpawnOptions,
|
|
91773
92056
|
env: { ...process.env, ...agent.environment },
|
|
@@ -93121,6 +93404,19 @@ var init_agent_turn = __esm({
|
|
|
93121
93404
|
|
|
93122
93405
|
// src/session/live/session-restore.ts
|
|
93123
93406
|
import { methods as methods10 } from "@agentclientprotocol/sdk";
|
|
93407
|
+
function hasMethodNotFoundCode(cause) {
|
|
93408
|
+
const visited = /* @__PURE__ */ new Set();
|
|
93409
|
+
let current = cause;
|
|
93410
|
+
while ((current instanceof Error || typeof current === "object" && current !== null) && !visited.has(current)) {
|
|
93411
|
+
visited.add(current);
|
|
93412
|
+
const code = Reflect.get(current, "code");
|
|
93413
|
+
if (code === -32601 || code === "METHOD_NOT_FOUND" || code === "method_not_found") {
|
|
93414
|
+
return true;
|
|
93415
|
+
}
|
|
93416
|
+
current = current instanceof Error ? current.cause : void 0;
|
|
93417
|
+
}
|
|
93418
|
+
return false;
|
|
93419
|
+
}
|
|
93124
93420
|
async function restoreSession(session, signal, recovery, origin) {
|
|
93125
93421
|
if (origin !== void 0) {
|
|
93126
93422
|
session.setSessionTitle(origin.title);
|
|
@@ -93187,6 +93483,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93187
93483
|
}
|
|
93188
93484
|
session.setPrompted(true);
|
|
93189
93485
|
session.setRestored(true);
|
|
93486
|
+
if (recovery.kind === "execution-only") {
|
|
93487
|
+
session.startExecutionOnlyCapture();
|
|
93488
|
+
}
|
|
93190
93489
|
lifecycleResponse2 = forked;
|
|
93191
93490
|
} else if (stored instanceof FoundStoredSession && stored.session.agentId === session.agentId && stored.session.cwd === session.cwd && arraysEqual(stored.session.additionalDirectories, session.additionalDirectories)) {
|
|
93192
93491
|
session.selectNativeSession(stored.session.nativeSessionId);
|
|
@@ -93205,6 +93504,37 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93205
93504
|
"session-load",
|
|
93206
93505
|
async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
|
|
93207
93506
|
);
|
|
93507
|
+
} else if (recovery.kind === "execution-only") {
|
|
93508
|
+
try {
|
|
93509
|
+
lifecycleResponse2 = await session.metrics.measure(
|
|
93510
|
+
"session-resume",
|
|
93511
|
+
async () => await session.race(
|
|
93512
|
+
session.agentRequest(
|
|
93513
|
+
methods10.agent.session.resume,
|
|
93514
|
+
{
|
|
93515
|
+
additionalDirectories: [...session.additionalDirectories],
|
|
93516
|
+
cwd: session.cwd,
|
|
93517
|
+
mcpServers: [],
|
|
93518
|
+
sessionId: session.nativeSessionId()
|
|
93519
|
+
},
|
|
93520
|
+
{ cancellationSignal: signal }
|
|
93521
|
+
),
|
|
93522
|
+
"ACP agent exited while resuming a session",
|
|
93523
|
+
signal
|
|
93524
|
+
)
|
|
93525
|
+
);
|
|
93526
|
+
} catch (cause) {
|
|
93527
|
+
signal.throwIfAborted();
|
|
93528
|
+
if (cause instanceof AcpExecutionError && !hasMethodNotFoundCode(cause)) {
|
|
93529
|
+
throw cause;
|
|
93530
|
+
}
|
|
93531
|
+
throw new AcpExecutionError(
|
|
93532
|
+
"This Agent cannot continue a persisted session without replaying native history",
|
|
93533
|
+
{ cause },
|
|
93534
|
+
"execution_only_unsupported"
|
|
93535
|
+
);
|
|
93536
|
+
}
|
|
93537
|
+
session.startExecutionOnlyCapture();
|
|
93208
93538
|
} else if (session.capabilities.resumeSession) {
|
|
93209
93539
|
lifecycleResponse2 = await session.metrics.measure(
|
|
93210
93540
|
"session-resume",
|
|
@@ -93264,6 +93594,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93264
93594
|
);
|
|
93265
93595
|
session.selectNativeSession(created.sessionId);
|
|
93266
93596
|
session.setNativeHistoryOwnership({ kind: "fresh-session" });
|
|
93597
|
+
if (recovery.kind === "execution-only") {
|
|
93598
|
+
session.startExecutionOnlyCapture();
|
|
93599
|
+
}
|
|
93267
93600
|
lifecycleResponse2 = created;
|
|
93268
93601
|
}
|
|
93269
93602
|
session.restrictSessionCapabilities(lifecycleResponse2);
|
|
@@ -93579,6 +93912,16 @@ var init_agent_session = __esm({
|
|
|
93579
93912
|
}
|
|
93580
93913
|
await this.#completedHistory(signal, "ACP agent exited while loading history");
|
|
93581
93914
|
};
|
|
93915
|
+
/** Starts live event capture without asking the native Agent to replay its persisted history. */
|
|
93916
|
+
startExecutionOnlyCapture = () => {
|
|
93917
|
+
if (this.#sessionLoad.kind !== "not-requested") {
|
|
93918
|
+
return;
|
|
93919
|
+
}
|
|
93920
|
+
this.#sessionLoad = {
|
|
93921
|
+
history: new HistoryReplayCapture(this.#store.events, this.#mobiusSessionId),
|
|
93922
|
+
kind: "execution-only"
|
|
93923
|
+
};
|
|
93924
|
+
};
|
|
93582
93925
|
loadHistoryEvents = async (eventLimit, cursor, signal) => {
|
|
93583
93926
|
if (!this.#capabilities.loadSession) {
|
|
93584
93927
|
throw new AcpExecutionError(
|
|
@@ -93829,7 +94172,7 @@ var init_agent_session = __esm({
|
|
|
93829
94172
|
response: {}
|
|
93830
94173
|
};
|
|
93831
94174
|
}
|
|
93832
|
-
if (this.#capabilities.loadSession) {
|
|
94175
|
+
if (this.#capabilities.loadSession && this.#sessionLoad.kind !== "execution-only") {
|
|
93833
94176
|
await this.#completedHistory(options.signal, "ACP agent exited while loading history before a prompt");
|
|
93834
94177
|
}
|
|
93835
94178
|
const prompt = this.buildPrompt(options);
|
|
@@ -94028,14 +94371,14 @@ var init_agent_session = __esm({
|
|
|
94028
94371
|
onElicitationComplete = (notification) => this.#interactions.onElicitationComplete(notification);
|
|
94029
94372
|
onUpdate = (notification) => this.#updates.receive(notification);
|
|
94030
94373
|
recordControlEvent = async (event) => {
|
|
94031
|
-
if (this.#sessionLoad.kind !== "loaded") {
|
|
94374
|
+
if (this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
94032
94375
|
return false;
|
|
94033
94376
|
}
|
|
94034
94377
|
await this.recordLifecycleEvent(event);
|
|
94035
94378
|
return true;
|
|
94036
94379
|
};
|
|
94037
94380
|
recordLifecycleEvent = async (event) => {
|
|
94038
|
-
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded") {
|
|
94381
|
+
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
94039
94382
|
return;
|
|
94040
94383
|
}
|
|
94041
94384
|
const liveEvent2 = this.#sessionLoad.history.recordLifecycle(event);
|
|
@@ -94056,7 +94399,7 @@ var init_agent_session = __esm({
|
|
|
94056
94399
|
const rawUpdate = decodeAcpSessionUpdate(JSON.stringify(externalized.event));
|
|
94057
94400
|
if (this.#sessionLoad.kind === "capturing") {
|
|
94058
94401
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
94059
|
-
} else if (this.#sessionLoad.kind === "loaded") {
|
|
94402
|
+
} else if (this.#sessionLoad.kind === "loaded" || this.#sessionLoad.kind === "execution-only") {
|
|
94060
94403
|
const onSessionEvent = this.#getObserver().onSessionEvent;
|
|
94061
94404
|
await this.#sessionLoad.history.record(update, rawUpdate, async (liveEvent2) => {
|
|
94062
94405
|
await onSessionEvent?.(liveEvent2);
|
|
@@ -95043,13 +95386,14 @@ var init_session_manager = __esm({
|
|
|
95043
95386
|
}
|
|
95044
95387
|
async #replaceExecutionPreparation(existing, options) {
|
|
95045
95388
|
const desiredConfigOptions = existing.prepared().configOptions;
|
|
95389
|
+
const recovery = options.recovery ?? { kind: "interactive-only" };
|
|
95046
95390
|
return await this.#executionProcesses.prepare(options.sessionId, async () => {
|
|
95047
95391
|
await this.#retireSessionProcess(options.sessionId, existing, async () => await existing.close());
|
|
95048
95392
|
const runtime = await this.#startRetainedSessionProcess(
|
|
95049
95393
|
options,
|
|
95050
95394
|
async () => await AgentSession.start(
|
|
95051
95395
|
options,
|
|
95052
|
-
|
|
95396
|
+
recovery,
|
|
95053
95397
|
() => this.#observer,
|
|
95054
95398
|
this.#store,
|
|
95055
95399
|
unmeasuredOperationMetrics,
|
|
@@ -95227,6 +95571,7 @@ var init_session_manager = __esm({
|
|
|
95227
95571
|
});
|
|
95228
95572
|
});
|
|
95229
95573
|
prepareExecutionSession = async (options) => this.#operations.run(options, async (options2) => {
|
|
95574
|
+
const recovery = options2.recovery ?? { kind: "interactive-only" };
|
|
95230
95575
|
this.#assertOpen(options2.sessionId);
|
|
95231
95576
|
const pending = this.#executionProcesses.pending(options2.sessionId);
|
|
95232
95577
|
if (pending !== void 0) {
|
|
@@ -95235,7 +95580,7 @@ var init_session_manager = __esm({
|
|
|
95235
95580
|
}
|
|
95236
95581
|
const existing = this.#executionProcesses.get(options2.sessionId);
|
|
95237
95582
|
if (existing === void 0) {
|
|
95238
|
-
return (await this.#startPreparation(options2,
|
|
95583
|
+
return (await this.#startPreparation(options2, recovery)).prepared();
|
|
95239
95584
|
}
|
|
95240
95585
|
if (!existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
95241
95586
|
throw new AcpExecutionError(
|
|
@@ -95245,6 +95590,9 @@ var init_session_manager = __esm({
|
|
|
95245
95590
|
);
|
|
95246
95591
|
}
|
|
95247
95592
|
if (existing.usesEnvironment(options2.agent.environment)) {
|
|
95593
|
+
if (recovery.kind === "execution-only") {
|
|
95594
|
+
existing.startExecutionOnlyCapture();
|
|
95595
|
+
}
|
|
95248
95596
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
95249
95597
|
return existing.prepared();
|
|
95250
95598
|
}
|
|
@@ -95539,10 +95887,13 @@ var init_session_manager = __esm({
|
|
|
95539
95887
|
"session_identity_mismatch"
|
|
95540
95888
|
);
|
|
95541
95889
|
}
|
|
95890
|
+
if (options2.recovery?.kind === "execution-only") {
|
|
95891
|
+
existing.startExecutionOnlyCapture();
|
|
95892
|
+
}
|
|
95542
95893
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
95543
95894
|
return existing;
|
|
95544
95895
|
}
|
|
95545
|
-
await this
|
|
95896
|
+
await this.#prepareSession(options2, options2.recovery ?? { kind: "interactive-only" }, "reopen");
|
|
95546
95897
|
const started = this.#executionProcesses.get(options2.sessionId);
|
|
95547
95898
|
if (started === void 0) {
|
|
95548
95899
|
throw new AcpExecutionError("ACP session did not start");
|
|
@@ -96100,6 +96451,7 @@ var PromptLifecycle;
|
|
|
96100
96451
|
var init_prompt_lifecycle = __esm({
|
|
96101
96452
|
"src/session/prompt/prompt-lifecycle.ts"() {
|
|
96102
96453
|
"use strict";
|
|
96454
|
+
init_protocol();
|
|
96103
96455
|
PromptLifecycle = class {
|
|
96104
96456
|
#sink;
|
|
96105
96457
|
#terminal = /* @__PURE__ */ new Map();
|
|
@@ -96181,6 +96533,13 @@ var init_prompt_lifecycle = __esm({
|
|
|
96181
96533
|
}
|
|
96182
96534
|
this.#queued.delete(commandId);
|
|
96183
96535
|
};
|
|
96536
|
+
replayOutcome = async (sessionId, event) => {
|
|
96537
|
+
if (event.type !== "lifecycle-metadata" || !("commandId" in event.payload)) {
|
|
96538
|
+
return;
|
|
96539
|
+
}
|
|
96540
|
+
await this.#recordLifecycle(sessionId, event);
|
|
96541
|
+
this.publishTerminal(sessionId, event.payload.commandId);
|
|
96542
|
+
};
|
|
96184
96543
|
queueChanged = async (sessionId) => {
|
|
96185
96544
|
await this.#recordLifecycle(sessionId, {
|
|
96186
96545
|
type: "lifecycle-metadata",
|
|
@@ -96214,7 +96573,7 @@ var init_prompt_lifecycle = __esm({
|
|
|
96214
96573
|
type: "lifecycle-metadata",
|
|
96215
96574
|
payload: { kind: "prompt.failed-before-start", commandId, code, message }
|
|
96216
96575
|
});
|
|
96217
|
-
if (!recorded) {
|
|
96576
|
+
if (!recorded || code === SESSION_CLOSED_ERROR_CODE) {
|
|
96218
96577
|
this.#sink.publishOperationFailure(sessionId, commandId, code, message);
|
|
96219
96578
|
}
|
|
96220
96579
|
};
|
|
@@ -96239,21 +96598,154 @@ var MAX_TERMINAL_RECEIPTS, ExecutionReceipts;
|
|
|
96239
96598
|
var init_execution_receipts = __esm({
|
|
96240
96599
|
"src/session/turn/execution-receipts.ts"() {
|
|
96241
96600
|
"use strict";
|
|
96601
|
+
init_protocol();
|
|
96602
|
+
init_zod();
|
|
96242
96603
|
MAX_TERMINAL_RECEIPTS = 1024;
|
|
96243
96604
|
ExecutionReceipts = class {
|
|
96244
96605
|
#executions = /* @__PURE__ */ new Map();
|
|
96606
|
+
#recoveredCommands = /* @__PURE__ */ new Set();
|
|
96245
96607
|
#terminalCountBySession = /* @__PURE__ */ new Map();
|
|
96608
|
+
#table;
|
|
96609
|
+
#closing = false;
|
|
96610
|
+
#activeCount = 0;
|
|
96611
|
+
#onCount;
|
|
96612
|
+
constructor(table, onCount = () => void 0) {
|
|
96613
|
+
this.#onCount = onCount;
|
|
96614
|
+
this.#table = table;
|
|
96615
|
+
for (const row of table?.list() ?? []) {
|
|
96616
|
+
this.#executions.set(row.commandId, row);
|
|
96617
|
+
this.#recoveredCommands.add(row.commandId);
|
|
96618
|
+
if (!isTerminal(row.state)) {
|
|
96619
|
+
this.#activeCount += 1;
|
|
96620
|
+
}
|
|
96621
|
+
if (isTerminal(row.state)) {
|
|
96622
|
+
this.#terminalCountBySession.set(
|
|
96623
|
+
row.sessionId,
|
|
96624
|
+
(this.#terminalCountBySession.get(row.sessionId) ?? 0) + 1
|
|
96625
|
+
);
|
|
96626
|
+
}
|
|
96627
|
+
}
|
|
96628
|
+
}
|
|
96629
|
+
#save = (commandId, receipt) => {
|
|
96630
|
+
if (!this.#closing) {
|
|
96631
|
+
this.#table?.save({ ...receipt, commandId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
96632
|
+
}
|
|
96633
|
+
const previous = this.#executions.get(commandId);
|
|
96634
|
+
const wasActive = previous !== void 0 && !isTerminal(previous.state);
|
|
96635
|
+
if (isTerminal(receipt.state)) {
|
|
96636
|
+
this.#executions.delete(commandId);
|
|
96637
|
+
}
|
|
96638
|
+
this.#executions.set(commandId, receipt);
|
|
96639
|
+
this.#activeCount += Number(!isTerminal(receipt.state)) - Number(wasActive);
|
|
96640
|
+
this.#onCount(this.#activeCount);
|
|
96641
|
+
if (isTerminal(receipt.state) && (previous === void 0 || !isTerminal(previous.state))) {
|
|
96642
|
+
this.#terminalCountBySession.set(
|
|
96643
|
+
receipt.sessionId,
|
|
96644
|
+
(this.#terminalCountBySession.get(receipt.sessionId) ?? 0) + 1
|
|
96645
|
+
);
|
|
96646
|
+
this.pruneTerminalReceipts(receipt.sessionId);
|
|
96647
|
+
}
|
|
96648
|
+
};
|
|
96649
|
+
beginShutdown = () => {
|
|
96650
|
+
this.#closing = true;
|
|
96651
|
+
};
|
|
96652
|
+
outcome = (commandId) => {
|
|
96653
|
+
const receipt = this.#executions.get(commandId);
|
|
96654
|
+
return receipt?.outcome === null || receipt === void 0 ? void 0 : sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
|
|
96655
|
+
};
|
|
96656
|
+
recordOutcome = (event) => {
|
|
96657
|
+
if (event.type !== "lifecycle-metadata") {
|
|
96658
|
+
return;
|
|
96659
|
+
}
|
|
96660
|
+
const payload = event.payload;
|
|
96661
|
+
if (payload.kind !== "prompt.completed" && payload.kind !== "prompt.failed" && payload.kind !== "prompt.failed-before-start") {
|
|
96662
|
+
return;
|
|
96663
|
+
}
|
|
96664
|
+
const receipt = this.#executions.get(payload.commandId);
|
|
96665
|
+
if (receipt === void 0) {
|
|
96666
|
+
return;
|
|
96667
|
+
}
|
|
96668
|
+
const sanitized = payload.kind === "prompt.completed" ? payload : { ...payload, message: "The local Agent could not complete the request" };
|
|
96669
|
+
this.#save(payload.commandId, {
|
|
96670
|
+
...receipt,
|
|
96671
|
+
state: payload.kind === "prompt.completed" ? payload.stopReason === "cancelled" ? "cancelled" : "succeeded" : "failed",
|
|
96672
|
+
outcome: JSON.stringify({ type: "lifecycle-metadata", payload: sanitized, recordedAt: event.recordedAt })
|
|
96673
|
+
});
|
|
96674
|
+
};
|
|
96675
|
+
recover = () => {
|
|
96676
|
+
const recovered = [];
|
|
96677
|
+
for (const [commandId, receipt] of [...this.#executions]) {
|
|
96678
|
+
const event = receipt.outcome === null ? {
|
|
96679
|
+
type: "lifecycle-metadata",
|
|
96680
|
+
payload: receipt.started ? {
|
|
96681
|
+
kind: "prompt.failed",
|
|
96682
|
+
commandId,
|
|
96683
|
+
attemptId: receipt.attemptId,
|
|
96684
|
+
code: "runtime_restarted",
|
|
96685
|
+
message: "The local runtime restarted while this request was running"
|
|
96686
|
+
} : {
|
|
96687
|
+
kind: "prompt.failed-before-start",
|
|
96688
|
+
commandId,
|
|
96689
|
+
code: "runtime_restarted",
|
|
96690
|
+
message: "The local runtime restarted before this request started"
|
|
96691
|
+
}
|
|
96692
|
+
} : sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
|
|
96693
|
+
const recordedAt = receipt.outcome === null ? (/* @__PURE__ */ new Date()).toISOString() : external_exports.object({ recordedAt: external_exports.string() }).parse(JSON.parse(receipt.outcome)).recordedAt;
|
|
96694
|
+
recovered.push({ sessionId: receipt.sessionId, event, recordedAt });
|
|
96695
|
+
if (!isTerminal(receipt.state)) {
|
|
96696
|
+
const state = event.type === "lifecycle-metadata" && event.payload.kind === "prompt.completed" ? event.payload.stopReason === "cancelled" ? "cancelled" : "succeeded" : "failed";
|
|
96697
|
+
this.#save(commandId, { ...receipt, state, outcome: JSON.stringify({ ...event, recordedAt }) });
|
|
96698
|
+
}
|
|
96699
|
+
}
|
|
96700
|
+
return recovered;
|
|
96701
|
+
};
|
|
96702
|
+
terminalOutcomes = (sessionId) => [...this.#executions.values()].flatMap((receipt) => {
|
|
96703
|
+
if (receipt.sessionId !== sessionId || receipt.outcome === null) {
|
|
96704
|
+
return [];
|
|
96705
|
+
}
|
|
96706
|
+
const decoded = JSON.parse(receipt.outcome);
|
|
96707
|
+
return [
|
|
96708
|
+
{
|
|
96709
|
+
event: sessionEventPayloadSchema.parse(decoded),
|
|
96710
|
+
recordedAt: external_exports.object({ recordedAt: external_exports.string() }).parse(decoded).recordedAt
|
|
96711
|
+
}
|
|
96712
|
+
];
|
|
96713
|
+
});
|
|
96246
96714
|
claimExecution = (commandId, sessionId, commandJson) => {
|
|
96247
96715
|
const commandHash = createHash7("sha256").update(commandJson).digest("hex");
|
|
96248
|
-
|
|
96716
|
+
let existing = this.#executions.get(commandId);
|
|
96717
|
+
const previous = this.outcome(commandId);
|
|
96718
|
+
if (existing?.sessionId === sessionId && !existing.started && previous?.type === "lifecycle-metadata" && previous.payload.kind === "prompt.failed-before-start" && previous.payload.code === "runtime_restarted") {
|
|
96719
|
+
this.#executions.delete(commandId);
|
|
96720
|
+
this.#recoveredCommands.delete(commandId);
|
|
96721
|
+
this.#table?.remove(commandId);
|
|
96722
|
+
this.#terminalCountBySession.set(
|
|
96723
|
+
sessionId,
|
|
96724
|
+
Math.max(0, (this.#terminalCountBySession.get(sessionId) ?? 1) - 1)
|
|
96725
|
+
);
|
|
96726
|
+
existing = void 0;
|
|
96727
|
+
}
|
|
96249
96728
|
if (existing !== void 0) {
|
|
96250
96729
|
if (existing.sessionId !== sessionId || existing.commandHash !== commandHash) {
|
|
96251
96730
|
return { kind: "conflict" };
|
|
96252
96731
|
}
|
|
96253
|
-
return {
|
|
96732
|
+
return {
|
|
96733
|
+
attemptId: existing.attemptId,
|
|
96734
|
+
commandId,
|
|
96735
|
+
kind: "duplicate",
|
|
96736
|
+
state: existing.state,
|
|
96737
|
+
outcome: this.#recoveredCommands.has(commandId) ? this.outcome(commandId) : void 0
|
|
96738
|
+
};
|
|
96254
96739
|
}
|
|
96255
96740
|
const attemptId = randomUUID14();
|
|
96256
|
-
this.#
|
|
96741
|
+
this.#save(commandId, {
|
|
96742
|
+
attemptId,
|
|
96743
|
+
commandHash,
|
|
96744
|
+
sessionId,
|
|
96745
|
+
state: "dispatching",
|
|
96746
|
+
started: false,
|
|
96747
|
+
outcome: null
|
|
96748
|
+
});
|
|
96257
96749
|
return { attemptId, commandId, kind: "accepted", state: "dispatching" };
|
|
96258
96750
|
};
|
|
96259
96751
|
transitionExecution = (commandId, state) => {
|
|
@@ -96268,16 +96760,13 @@ var init_execution_receipts = __esm({
|
|
|
96268
96760
|
if (!allowed) {
|
|
96269
96761
|
throw new Error("The runtime execution transition is invalid");
|
|
96270
96762
|
}
|
|
96271
|
-
|
|
96272
|
-
|
|
96273
|
-
|
|
96274
|
-
|
|
96275
|
-
(this.#terminalCountBySession.get(current.sessionId) ?? 0) + 1
|
|
96276
|
-
);
|
|
96277
|
-
this.pruneTerminalReceipts(current.sessionId);
|
|
96763
|
+
if (state === "running") {
|
|
96764
|
+
this.#save(commandId, { ...current, state, started: true });
|
|
96765
|
+
} else if (isTerminal(state)) {
|
|
96766
|
+
this.#save(commandId, { ...current, state });
|
|
96278
96767
|
}
|
|
96279
96768
|
};
|
|
96280
|
-
/**
|
|
96769
|
+
/** Only commands without a terminal result can still be cancelled. */
|
|
96281
96770
|
findUnsettledAttemptId = (commandId, sessionId) => {
|
|
96282
96771
|
const receipt = this.#executions.get(commandId);
|
|
96283
96772
|
return receipt?.sessionId === sessionId && !isTerminal(receipt.state) ? receipt.attemptId : null;
|
|
@@ -96288,7 +96777,9 @@ var init_execution_receipts = __esm({
|
|
|
96288
96777
|
};
|
|
96289
96778
|
close = () => {
|
|
96290
96779
|
this.#executions.clear();
|
|
96780
|
+
this.#recoveredCommands.clear();
|
|
96291
96781
|
this.#terminalCountBySession.clear();
|
|
96782
|
+
this.#activeCount = 0;
|
|
96292
96783
|
};
|
|
96293
96784
|
pruneTerminalReceipts = (sessionId) => {
|
|
96294
96785
|
if ((this.#terminalCountBySession.get(sessionId) ?? 0) <= MAX_TERMINAL_RECEIPTS) {
|
|
@@ -96297,6 +96788,8 @@ var init_execution_receipts = __esm({
|
|
|
96297
96788
|
for (const [commandId, receipt] of this.#executions) {
|
|
96298
96789
|
if (receipt.sessionId === sessionId && isTerminal(receipt.state)) {
|
|
96299
96790
|
this.#executions.delete(commandId);
|
|
96791
|
+
this.#recoveredCommands.delete(commandId);
|
|
96792
|
+
this.#table?.remove(commandId);
|
|
96300
96793
|
const remaining = (this.#terminalCountBySession.get(sessionId) ?? 1) - 1;
|
|
96301
96794
|
if (remaining > 0) {
|
|
96302
96795
|
this.#terminalCountBySession.set(sessionId, remaining);
|
|
@@ -96847,10 +97340,14 @@ function buildSessionLayer(options) {
|
|
|
96847
97340
|
const databases = channelSessionDatabasePaths(stateDirectory, channelId);
|
|
96848
97341
|
const sessionDatabase = openAcpSessionDatabase(databases.sessions);
|
|
96849
97342
|
let events;
|
|
97343
|
+
let operations;
|
|
96850
97344
|
try {
|
|
97345
|
+
operations = new ExecutionReceipts(new ExecutionReceiptTable(sessionDatabase), options.onExecutionCountChange);
|
|
96851
97346
|
events = new CachedSessionEventStore(
|
|
96852
97347
|
new SessionEventCacheTable(openSessionEventCacheDatabase(databases.events)),
|
|
96853
|
-
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase))
|
|
97348
|
+
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase)),
|
|
97349
|
+
void 0,
|
|
97350
|
+
(sessionId) => operations.terminalOutcomes(sessionId)
|
|
96854
97351
|
);
|
|
96855
97352
|
} catch (error62) {
|
|
96856
97353
|
sessionDatabase.close();
|
|
@@ -96858,11 +97355,13 @@ function buildSessionLayer(options) {
|
|
|
96858
97355
|
}
|
|
96859
97356
|
const sessionStore = new SqliteSessionStore(new AcpSessionTable(sessionDatabase), events);
|
|
96860
97357
|
const externalContent = new LocalExternalContentStore(stateDirectory);
|
|
96861
|
-
const operations = new ExecutionReceipts();
|
|
96862
97358
|
const activeSessions = new SessionTurns(operations, options.turnActivity);
|
|
96863
97359
|
const directories = new WorkspaceDirectoryService(bindingId, defaultWorkspace);
|
|
96864
97360
|
const manager = new SessionManager2({
|
|
96865
|
-
observer: new SessionLayerObserver((event) =>
|
|
97361
|
+
observer: new SessionLayerObserver((event) => {
|
|
97362
|
+
operations.recordOutcome(event);
|
|
97363
|
+
eventProjection.record(event);
|
|
97364
|
+
}, sink.publishInfo),
|
|
96866
97365
|
store: sessionStore,
|
|
96867
97366
|
adapters: harnessAdapters,
|
|
96868
97367
|
sessionIdentity: "native",
|
|
@@ -96883,7 +97382,15 @@ function buildSessionLayer(options) {
|
|
|
96883
97382
|
});
|
|
96884
97383
|
const eventProjection = new PromptLifecycle(
|
|
96885
97384
|
sink,
|
|
96886
|
-
(sessionId, event) =>
|
|
97385
|
+
async (sessionId, event) => {
|
|
97386
|
+
if (await manager.recordLifecycleEvent(sessionId, event)) {
|
|
97387
|
+
return true;
|
|
97388
|
+
}
|
|
97389
|
+
const recorded = events.append(sessionId, event);
|
|
97390
|
+
operations.recordOutcome(recorded);
|
|
97391
|
+
eventProjection.record(recorded);
|
|
97392
|
+
return true;
|
|
97393
|
+
},
|
|
96887
97394
|
activeSessions.recordSessionEvent
|
|
96888
97395
|
);
|
|
96889
97396
|
const nativeSessions = new NativeSessionService(
|
|
@@ -96906,7 +97413,13 @@ function buildSessionLayer(options) {
|
|
|
96906
97413
|
);
|
|
96907
97414
|
})
|
|
96908
97415
|
);
|
|
97416
|
+
const recoveredEvents = operations.recover().map(({ sessionId, event, recordedAt }) => events.append(sessionId, event, recordedAt));
|
|
96909
97417
|
return {
|
|
97418
|
+
publishRecoveredOutcomes: () => {
|
|
97419
|
+
for (const event of recoveredEvents) {
|
|
97420
|
+
sink.publish(event);
|
|
97421
|
+
}
|
|
97422
|
+
},
|
|
96910
97423
|
activeSessions,
|
|
96911
97424
|
directories,
|
|
96912
97425
|
eventProjection,
|
|
@@ -96924,6 +97437,7 @@ var init_session_layer = __esm({
|
|
|
96924
97437
|
init_registry();
|
|
96925
97438
|
init_content_externalizer();
|
|
96926
97439
|
init_acp_session_table();
|
|
97440
|
+
init_execution_receipt_table();
|
|
96927
97441
|
init_live_event_position_table();
|
|
96928
97442
|
init_session_event_cache_table();
|
|
96929
97443
|
init_local_databases();
|
|
@@ -98804,12 +99318,14 @@ async function executePrompt({
|
|
|
98804
99318
|
const appliedSettings = command.sessionConfigurations === void 0 ? void 0 : agentForSessionConfiguration(agent, command.sessionConfigurations);
|
|
98805
99319
|
const executionAgent = appliedSettings?.agent ?? agent;
|
|
98806
99320
|
const sessionConfigurations = appliedSettings?.sessionConfigurations;
|
|
99321
|
+
const recovery = command.historyPolicy === SessionHistoryPolicy.ExecutionOnly ? { kind: "execution-only" } : { kind: "interactive-only" };
|
|
98807
99322
|
const preparation = {
|
|
98808
99323
|
additionalDirectories: resolved.additionalDirectories,
|
|
98809
99324
|
agent: executionAgent,
|
|
98810
99325
|
cwd: resolved.cwd,
|
|
98811
99326
|
sessionId: command.sessionId,
|
|
98812
|
-
signal
|
|
99327
|
+
signal,
|
|
99328
|
+
recovery
|
|
98813
99329
|
};
|
|
98814
99330
|
let prepared = await sessions.prepareExecutionSession(preparation);
|
|
98815
99331
|
if (command.sessionConfigurations !== void 0) {
|
|
@@ -98878,7 +99394,8 @@ async function executePrompt({
|
|
|
98878
99394
|
resources: attachments.resources,
|
|
98879
99395
|
sessionId: command.sessionId,
|
|
98880
99396
|
signal,
|
|
98881
|
-
targetCommandId: command.targetCommandId
|
|
99397
|
+
targetCommandId: command.targetCommandId,
|
|
99398
|
+
recovery
|
|
98882
99399
|
});
|
|
98883
99400
|
stopReason = result.stopReason;
|
|
98884
99401
|
}
|
|
@@ -99076,6 +99593,12 @@ var init_prompt2 = __esm({
|
|
|
99076
99593
|
return;
|
|
99077
99594
|
}
|
|
99078
99595
|
if (receipt.kind === "duplicate") {
|
|
99596
|
+
const outcome = receipt.outcome;
|
|
99597
|
+
if (outcome !== void 0) {
|
|
99598
|
+
void context.eventProjection.replayOutcome(message.sessionId, outcome).catch((cause) => {
|
|
99599
|
+
console.error("Could not replay the persisted execution outcome", cause);
|
|
99600
|
+
});
|
|
99601
|
+
}
|
|
99079
99602
|
return;
|
|
99080
99603
|
}
|
|
99081
99604
|
const turn = context.sessionTurns.start(message, receipt.attemptId);
|
|
@@ -100282,7 +100805,8 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100282
100805
|
resolveAgent: (agentId, resolveSignal) => resolveCatalogAgent(config2, agentId, resolveSignal),
|
|
100283
100806
|
sink: publisher,
|
|
100284
100807
|
stateDirectory: config2.localContext.stateDirectory,
|
|
100285
|
-
timer
|
|
100808
|
+
timer,
|
|
100809
|
+
onExecutionCountChange: options.onExecutionCountChange ?? (() => void 0)
|
|
100286
100810
|
});
|
|
100287
100811
|
const {
|
|
100288
100812
|
activeSessions,
|
|
@@ -100352,6 +100876,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100352
100876
|
reportUpgradeAvailability,
|
|
100353
100877
|
diagnostics,
|
|
100354
100878
|
onConnected: () => {
|
|
100879
|
+
layer.publishRecoveredOutcomes();
|
|
100355
100880
|
if (catalogPublished) {
|
|
100356
100881
|
options.onConnectionStatus?.("online");
|
|
100357
100882
|
}
|
|
@@ -100374,6 +100899,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100374
100899
|
}
|
|
100375
100900
|
} finally {
|
|
100376
100901
|
shutdown.abort();
|
|
100902
|
+
operations.beginShutdown();
|
|
100377
100903
|
await activeSessions.close();
|
|
100378
100904
|
try {
|
|
100379
100905
|
await catalogPublication;
|
|
@@ -100468,6 +100994,10 @@ var init_engine = __esm({
|
|
|
100468
100994
|
MobiusRuntimeEngine = class {
|
|
100469
100995
|
#config;
|
|
100470
100996
|
#options;
|
|
100997
|
+
#activeTurnCount = 0;
|
|
100998
|
+
get activeTurnCount() {
|
|
100999
|
+
return this.#activeTurnCount;
|
|
101000
|
+
}
|
|
100471
101001
|
#state = new IdleMobiusRuntimeState();
|
|
100472
101002
|
constructor(config2, options = {}) {
|
|
100473
101003
|
validateRuntimeConfiguration(config2);
|
|
@@ -100483,11 +101013,15 @@ var init_engine = __esm({
|
|
|
100483
101013
|
try {
|
|
100484
101014
|
await runRuntime(this.#config, signal, void 0, {
|
|
100485
101015
|
...this.#options.turnActivity === void 0 ? {} : { turnActivity: this.#options.turnActivity },
|
|
101016
|
+
onExecutionCountChange: (count) => {
|
|
101017
|
+
this.#activeTurnCount = count;
|
|
101018
|
+
},
|
|
100486
101019
|
...this.#options.onConnectionStatus === void 0 ? {} : { onConnectionStatus: this.#options.onConnectionStatus },
|
|
100487
101020
|
...this.#options.reportUpgradeAvailability === void 0 ? {} : { reportUpgradeAvailability: this.#options.reportUpgradeAvailability },
|
|
100488
101021
|
...this.#options.processLogsDirectory === void 0 ? {} : { processLogsDirectory: this.#options.processLogsDirectory }
|
|
100489
101022
|
});
|
|
100490
101023
|
} finally {
|
|
101024
|
+
this.#activeTurnCount = 0;
|
|
100491
101025
|
this.#state = new FinishedMobiusRuntimeState();
|
|
100492
101026
|
}
|
|
100493
101027
|
};
|