@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/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.301",
|
|
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({
|
|
@@ -75866,7 +75975,7 @@ var init_command2 = __esm({
|
|
|
75866
75975
|
});
|
|
75867
75976
|
|
|
75868
75977
|
// src/acp/harness/pi/upstream/dist/pi-rpc/process.js
|
|
75869
|
-
import { spawn as
|
|
75978
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
75870
75979
|
import * as readline from "node:readline";
|
|
75871
75980
|
function stripAnsi(s) {
|
|
75872
75981
|
return s.replace(ANSI_ESCAPE_REGEX, "");
|
|
@@ -75970,7 +76079,7 @@ var init_process = __esm({
|
|
|
75970
76079
|
args.push("--fork", params.origin.sessionPath);
|
|
75971
76080
|
break;
|
|
75972
76081
|
}
|
|
75973
|
-
const child =
|
|
76082
|
+
const child = spawn5(cmd, args, {
|
|
75974
76083
|
cwd: params.cwd,
|
|
75975
76084
|
stdio: "pipe",
|
|
75976
76085
|
env: params.environment,
|
|
@@ -79410,6 +79519,77 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
79410
79519
|
}, 0);
|
|
79411
79520
|
return { sessionId: session.sessionId, configOptions, modes };
|
|
79412
79521
|
}
|
|
79522
|
+
async resumeSession(params) {
|
|
79523
|
+
if (!isAbsolute11(params.cwd)) {
|
|
79524
|
+
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
79525
|
+
}
|
|
79526
|
+
this.sessions.close(params.sessionId);
|
|
79527
|
+
this.lastSessionCwd = params.cwd;
|
|
79528
|
+
const stored = this.findStoredSession(params.sessionId);
|
|
79529
|
+
if (!stored) {
|
|
79530
|
+
throw RequestError7.invalidParams(`Unknown sessionId: ${params.sessionId}`);
|
|
79531
|
+
}
|
|
79532
|
+
const session = await this.restoreSession(params.sessionId, {
|
|
79533
|
+
cwd: params.cwd,
|
|
79534
|
+
mcpServers: params.mcpServers
|
|
79535
|
+
});
|
|
79536
|
+
let configuration;
|
|
79537
|
+
try {
|
|
79538
|
+
configuration = await getSessionConfiguration(session.proc);
|
|
79539
|
+
} catch (err) {
|
|
79540
|
+
this.sessions.close(session.sessionId);
|
|
79541
|
+
throw err;
|
|
79542
|
+
}
|
|
79543
|
+
const { configOptions, models, modes } = configuration;
|
|
79544
|
+
const enableSkillCommands = getEnableSkillCommands(params.cwd, this.environment);
|
|
79545
|
+
const fileCommands = loadSlashCommands(params.cwd, this.environment);
|
|
79546
|
+
this.sessions.closeAllExcept?.(session.sessionId);
|
|
79547
|
+
this.store.upsert({
|
|
79548
|
+
sessionId: params.sessionId,
|
|
79549
|
+
cwd: params.cwd,
|
|
79550
|
+
sessionFile: stored.sessionFile
|
|
79551
|
+
});
|
|
79552
|
+
const response = {
|
|
79553
|
+
configOptions,
|
|
79554
|
+
models,
|
|
79555
|
+
modes,
|
|
79556
|
+
_meta: {
|
|
79557
|
+
piAcp: {
|
|
79558
|
+
startupInfo: null
|
|
79559
|
+
}
|
|
79560
|
+
}
|
|
79561
|
+
};
|
|
79562
|
+
setTimeout(() => {
|
|
79563
|
+
void (async () => {
|
|
79564
|
+
await session.publishContextUsage();
|
|
79565
|
+
try {
|
|
79566
|
+
const pi2 = await session.proc.getCommands();
|
|
79567
|
+
const { commands } = toAvailableCommandsFromPiGetCommands(pi2, {
|
|
79568
|
+
enableSkillCommands,
|
|
79569
|
+
includeExtensionCommands: false
|
|
79570
|
+
});
|
|
79571
|
+
await this.conn.sessionUpdate({
|
|
79572
|
+
sessionId: session.sessionId,
|
|
79573
|
+
update: {
|
|
79574
|
+
sessionUpdate: "available_commands_update",
|
|
79575
|
+
availableCommands: mergeCommands(commands, builtinAvailableCommands())
|
|
79576
|
+
}
|
|
79577
|
+
});
|
|
79578
|
+
return;
|
|
79579
|
+
} catch {
|
|
79580
|
+
}
|
|
79581
|
+
await this.conn.sessionUpdate({
|
|
79582
|
+
sessionId: session.sessionId,
|
|
79583
|
+
update: {
|
|
79584
|
+
sessionUpdate: "available_commands_update",
|
|
79585
|
+
availableCommands: mergeCommands(toAvailableCommands(fileCommands), builtinAvailableCommands())
|
|
79586
|
+
}
|
|
79587
|
+
});
|
|
79588
|
+
})().catch(() => {
|
|
79589
|
+
});
|
|
79590
|
+
}, 0);
|
|
79591
|
+
return response;
|
|
79592
|
+
}
|
|
79413
79593
|
async loadSession(params) {
|
|
79414
79594
|
if (!isAbsolute11(params.cwd)) {
|
|
79415
79595
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
@@ -79689,6 +79869,9 @@ var init_endpoint2 = __esm({
|
|
|
79689
79869
|
).onRequest(
|
|
79690
79870
|
methods5.agent.session.load,
|
|
79691
79871
|
async (context) => await piAgentOrThrow(piAgent).loadSession(context.params)
|
|
79872
|
+
).onRequest(
|
|
79873
|
+
methods5.agent.session.resume,
|
|
79874
|
+
async (context) => await piAgentOrThrow(piAgent).resumeSession(context.params)
|
|
79692
79875
|
).onRequest(
|
|
79693
79876
|
methods5.agent.session.list,
|
|
79694
79877
|
async (context) => await piAgentOrThrow(piAgent).listSessions(context.params)
|
|
@@ -80215,7 +80398,7 @@ var init_create_client = __esm({
|
|
|
80215
80398
|
});
|
|
80216
80399
|
|
|
80217
80400
|
// src/agent/discovery/acp-readiness-probe.ts
|
|
80218
|
-
import { spawn as
|
|
80401
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
80219
80402
|
import {
|
|
80220
80403
|
methods as methods8,
|
|
80221
80404
|
ndJsonStream as ndJsonStream2,
|
|
@@ -80372,7 +80555,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
|
|
|
80372
80555
|
}
|
|
80373
80556
|
}
|
|
80374
80557
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
80375
|
-
const child =
|
|
80558
|
+
const child = spawn6(launch.command, [...launch.arguments], {
|
|
80376
80559
|
cwd: defaultWorkspace,
|
|
80377
80560
|
...platformSpawnOptions,
|
|
80378
80561
|
env: { ...environment, ...agent.environment },
|
|
@@ -83043,7 +83226,7 @@ var init_worker_lifecycle_log = __esm({
|
|
|
83043
83226
|
});
|
|
83044
83227
|
|
|
83045
83228
|
// src/daemon/lifecycle/worker-process.ts
|
|
83046
|
-
import { spawn as
|
|
83229
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
83047
83230
|
import { isAbsolute as isAbsolute13, resolve as resolve16 } from "node:path";
|
|
83048
83231
|
function currentWorkerLaunch(version2) {
|
|
83049
83232
|
const entry = process.argv[1];
|
|
@@ -83103,7 +83286,7 @@ var init_worker_process = __esm({
|
|
|
83103
83286
|
constructor(launch, signal, environment) {
|
|
83104
83287
|
signal.throwIfAborted();
|
|
83105
83288
|
this.launch = launch;
|
|
83106
|
-
this.#child =
|
|
83289
|
+
this.#child = spawn7(launch.executable, [launch.entry, "__worker"], {
|
|
83107
83290
|
env: environment,
|
|
83108
83291
|
windowsHide: true,
|
|
83109
83292
|
stdio: ["ignore", "pipe", "pipe", "ipc"]
|
|
@@ -83436,9 +83619,9 @@ var init_manager2 = __esm({
|
|
|
83436
83619
|
});
|
|
83437
83620
|
|
|
83438
83621
|
// src/daemon/lifecycle/manager-client.ts
|
|
83439
|
-
import { spawn as
|
|
83622
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
83440
83623
|
async function spawnManager() {
|
|
83441
|
-
const child =
|
|
83624
|
+
const child = spawn8(process.execPath, [process.argv[1] ?? "", "__manager"], {
|
|
83442
83625
|
detached: true,
|
|
83443
83626
|
windowsHide: true,
|
|
83444
83627
|
env: process.env,
|
|
@@ -83844,7 +84027,7 @@ var init_history_images = __esm({
|
|
|
83844
84027
|
});
|
|
83845
84028
|
|
|
83846
84029
|
// src/acp/native-history/codex/codex-history.ts
|
|
83847
|
-
import { spawn as
|
|
84030
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
83848
84031
|
function bounded(value, maximum) {
|
|
83849
84032
|
return value.slice(0, maximum);
|
|
83850
84033
|
}
|
|
@@ -84220,7 +84403,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
|
|
|
84220
84403
|
}
|
|
84221
84404
|
signal.throwIfAborted();
|
|
84222
84405
|
const launch = executableLaunch2(agent.agentIdentity.realPath, ["app-server"]);
|
|
84223
|
-
const child =
|
|
84406
|
+
const child = spawn9(launch.command, [...launch.arguments], {
|
|
84224
84407
|
cwd,
|
|
84225
84408
|
env: { ...process.env, ...agent.environment },
|
|
84226
84409
|
...platformSpawnOptions,
|
|
@@ -90233,6 +90416,25 @@ var init_acp_session = __esm({
|
|
|
90233
90416
|
}
|
|
90234
90417
|
});
|
|
90235
90418
|
|
|
90419
|
+
// src/schema/acp-session-store/execution-receipt.ts
|
|
90420
|
+
var executionReceipt;
|
|
90421
|
+
var init_execution_receipt = __esm({
|
|
90422
|
+
"src/schema/acp-session-store/execution-receipt.ts"() {
|
|
90423
|
+
"use strict";
|
|
90424
|
+
init_sqlite_core();
|
|
90425
|
+
executionReceipt = sqliteTable("execution_receipt", {
|
|
90426
|
+
commandId: text("command_id").primaryKey(),
|
|
90427
|
+
sessionId: text("session_id").notNull(),
|
|
90428
|
+
commandHash: text("command_hash").notNull(),
|
|
90429
|
+
attemptId: text("attempt_id").notNull(),
|
|
90430
|
+
state: text("state").notNull(),
|
|
90431
|
+
started: integer2("started", { mode: "boolean" }).notNull(),
|
|
90432
|
+
outcome: text("outcome"),
|
|
90433
|
+
updatedAt: text("updated_at").notNull()
|
|
90434
|
+
});
|
|
90435
|
+
}
|
|
90436
|
+
});
|
|
90437
|
+
|
|
90236
90438
|
// src/schema/acp-session-store/session-live-event-position-allocation.ts
|
|
90237
90439
|
var sessionLiveEventPositionAllocation;
|
|
90238
90440
|
var init_session_live_event_position_allocation = __esm({
|
|
@@ -90251,6 +90453,7 @@ var init_acp_session_store = __esm({
|
|
|
90251
90453
|
"src/schema/acp-session-store/index.ts"() {
|
|
90252
90454
|
"use strict";
|
|
90253
90455
|
init_acp_session();
|
|
90456
|
+
init_execution_receipt();
|
|
90254
90457
|
init_session_live_event_position_allocation();
|
|
90255
90458
|
}
|
|
90256
90459
|
});
|
|
@@ -90299,6 +90502,71 @@ var init_acp_session_table = __esm({
|
|
|
90299
90502
|
}
|
|
90300
90503
|
});
|
|
90301
90504
|
|
|
90505
|
+
// src/storage/session/execution-receipt-table.ts
|
|
90506
|
+
var receiptFields, receiptSchema, ExecutionReceiptTable;
|
|
90507
|
+
var init_execution_receipt_table = __esm({
|
|
90508
|
+
"src/storage/session/execution-receipt-table.ts"() {
|
|
90509
|
+
"use strict";
|
|
90510
|
+
init_drizzle_orm();
|
|
90511
|
+
init_zod();
|
|
90512
|
+
init_acp_session_store();
|
|
90513
|
+
receiptFields = external_exports.object({
|
|
90514
|
+
commandId: external_exports.string(),
|
|
90515
|
+
sessionId: external_exports.string(),
|
|
90516
|
+
commandHash: external_exports.string(),
|
|
90517
|
+
attemptId: external_exports.string(),
|
|
90518
|
+
updatedAt: external_exports.string()
|
|
90519
|
+
});
|
|
90520
|
+
receiptSchema = external_exports.discriminatedUnion("state", [
|
|
90521
|
+
receiptFields.extend({ state: external_exports.literal("dispatching"), started: external_exports.literal(false), outcome: external_exports.null() }),
|
|
90522
|
+
receiptFields.extend({ state: external_exports.literal("running"), started: external_exports.literal(true), outcome: external_exports.string().nullable() }),
|
|
90523
|
+
receiptFields.extend({
|
|
90524
|
+
state: external_exports.enum(["succeeded", "failed", "cancelled"]),
|
|
90525
|
+
started: external_exports.boolean(),
|
|
90526
|
+
outcome: external_exports.string().nullable()
|
|
90527
|
+
})
|
|
90528
|
+
]).readonly();
|
|
90529
|
+
ExecutionReceiptTable = class {
|
|
90530
|
+
#database;
|
|
90531
|
+
constructor(database) {
|
|
90532
|
+
this.#database = database;
|
|
90533
|
+
}
|
|
90534
|
+
list = () => receiptSchema.array().parse(
|
|
90535
|
+
this.#database.orm.select().from(executionReceipt).orderBy(asc(executionReceipt.updatedAt), asc(executionReceipt.commandId)).all()
|
|
90536
|
+
);
|
|
90537
|
+
save = (receipt) => {
|
|
90538
|
+
this.#database.transaction(() => {
|
|
90539
|
+
this.#database.orm.insert(executionReceipt).values(receipt).onConflictDoUpdate({ target: executionReceipt.commandId, set: receipt }).run();
|
|
90540
|
+
if (receipt.state === "dispatching" || receipt.state === "running") {
|
|
90541
|
+
return;
|
|
90542
|
+
}
|
|
90543
|
+
const retained = this.#database.orm.select({ commandId: executionReceipt.commandId }).from(executionReceipt).where(
|
|
90544
|
+
and(
|
|
90545
|
+
eq2(executionReceipt.sessionId, receipt.sessionId),
|
|
90546
|
+
inArray(executionReceipt.state, ["succeeded", "failed", "cancelled"])
|
|
90547
|
+
)
|
|
90548
|
+
).orderBy(desc(executionReceipt.updatedAt), desc(executionReceipt.commandId)).limit(1024).all();
|
|
90549
|
+
if (retained.length === 1024) {
|
|
90550
|
+
this.#database.orm.delete(executionReceipt).where(
|
|
90551
|
+
and(
|
|
90552
|
+
eq2(executionReceipt.sessionId, receipt.sessionId),
|
|
90553
|
+
inArray(executionReceipt.state, ["succeeded", "failed", "cancelled"]),
|
|
90554
|
+
notInArray(
|
|
90555
|
+
executionReceipt.commandId,
|
|
90556
|
+
retained.map((row) => row.commandId)
|
|
90557
|
+
)
|
|
90558
|
+
)
|
|
90559
|
+
).run();
|
|
90560
|
+
}
|
|
90561
|
+
});
|
|
90562
|
+
};
|
|
90563
|
+
remove = (commandId) => {
|
|
90564
|
+
this.#database.orm.delete(executionReceipt).where(eq2(executionReceipt.commandId, commandId)).run();
|
|
90565
|
+
};
|
|
90566
|
+
};
|
|
90567
|
+
}
|
|
90568
|
+
});
|
|
90569
|
+
|
|
90302
90570
|
// src/storage/session/live-event-position-table.ts
|
|
90303
90571
|
var allocationRowSchema, LiveEventPositionTable;
|
|
90304
90572
|
var init_live_event_position_table = __esm({
|
|
@@ -90552,6 +90820,10 @@ var init_acp_session_store_migrations = __esm({
|
|
|
90552
90820
|
{
|
|
90553
90821
|
"name": "0006_live_event_position_allocation.sql",
|
|
90554
90822
|
"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"
|
|
90823
|
+
},
|
|
90824
|
+
{
|
|
90825
|
+
"name": "0007_busy_excalibur.sql",
|
|
90826
|
+
"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
90827
|
}
|
|
90556
90828
|
];
|
|
90557
90829
|
}
|
|
@@ -91170,12 +91442,12 @@ var init_session_event_id_allocator = __esm({
|
|
|
91170
91442
|
|
|
91171
91443
|
// src/session/history/session-event-store.ts
|
|
91172
91444
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
91173
|
-
function liveEvent(sessionId, sessionGenerationId, eventId, position, event) {
|
|
91445
|
+
function liveEvent(sessionId, sessionGenerationId, eventId, position, event, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
91174
91446
|
return {
|
|
91175
91447
|
eventId,
|
|
91176
91448
|
...event,
|
|
91177
91449
|
position: position.toString(),
|
|
91178
|
-
recordedAt
|
|
91450
|
+
recordedAt,
|
|
91179
91451
|
sessionGenerationId,
|
|
91180
91452
|
sessionId
|
|
91181
91453
|
};
|
|
@@ -91336,7 +91608,7 @@ var init_session_event_store = __esm({
|
|
|
91336
91608
|
}
|
|
91337
91609
|
return resolved;
|
|
91338
91610
|
};
|
|
91339
|
-
append = (sessionId, event) => {
|
|
91611
|
+
append = (sessionId, event, recordedAt) => {
|
|
91340
91612
|
const session = this.#session(sessionId);
|
|
91341
91613
|
const allocatedPosition = this.#allocatedPositionBySession.get(sessionId) ?? 9999;
|
|
91342
91614
|
if (allocatedPosition === Number.MAX_SAFE_INTEGER) {
|
|
@@ -91349,7 +91621,8 @@ var init_session_event_store = __esm({
|
|
|
91349
91621
|
session.sessionGenerationId,
|
|
91350
91622
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
91351
91623
|
position,
|
|
91352
|
-
event
|
|
91624
|
+
event,
|
|
91625
|
+
recordedAt
|
|
91353
91626
|
);
|
|
91354
91627
|
session.apply(recorded, this.#resolver(session));
|
|
91355
91628
|
return recorded;
|
|
@@ -91390,12 +91663,14 @@ var init_session_event_store = __esm({
|
|
|
91390
91663
|
};
|
|
91391
91664
|
};
|
|
91392
91665
|
CachedSessionEventStore = class {
|
|
91666
|
+
#terminalOutcomes;
|
|
91393
91667
|
#cacheTable;
|
|
91394
91668
|
#eventIds;
|
|
91395
91669
|
#liveEventPositions;
|
|
91396
91670
|
#sessions = /* @__PURE__ */ new Map();
|
|
91397
91671
|
#flushSchedule = { kind: "idle" };
|
|
91398
|
-
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator()) {
|
|
91672
|
+
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator(), terminalOutcomes = () => []) {
|
|
91673
|
+
this.#terminalOutcomes = terminalOutcomes;
|
|
91399
91674
|
this.#eventIds = eventIds;
|
|
91400
91675
|
this.#liveEventPositions = liveEventPositions;
|
|
91401
91676
|
this.#cacheTable = cacheTable;
|
|
@@ -91428,7 +91703,7 @@ var init_session_event_store = __esm({
|
|
|
91428
91703
|
}
|
|
91429
91704
|
return resolved;
|
|
91430
91705
|
};
|
|
91431
|
-
append = (sessionId, event) => {
|
|
91706
|
+
append = (sessionId, event, recordedAt) => {
|
|
91432
91707
|
if (this.#flushSchedule.kind === "closed") {
|
|
91433
91708
|
throw new Error("The V2 Session event store is closed");
|
|
91434
91709
|
}
|
|
@@ -91439,7 +91714,8 @@ var init_session_event_store = __esm({
|
|
|
91439
91714
|
session.sessionGenerationId,
|
|
91440
91715
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
91441
91716
|
position,
|
|
91442
|
-
event
|
|
91717
|
+
event,
|
|
91718
|
+
recordedAt
|
|
91443
91719
|
);
|
|
91444
91720
|
session.apply(recorded, this.#resolver(sessionId, session));
|
|
91445
91721
|
this.#sessions.set(sessionId, session);
|
|
@@ -91528,6 +91804,9 @@ var init_session_event_store = __esm({
|
|
|
91528
91804
|
this.#deletePersisted(sessionId, previous?.sessionGenerationId);
|
|
91529
91805
|
const sessionGenerationId = randomUUID12();
|
|
91530
91806
|
this.#sessions.set(sessionId, new SessionEvents(sessionGenerationId));
|
|
91807
|
+
for (const { event, recordedAt } of this.#terminalOutcomes(sessionId)) {
|
|
91808
|
+
this.append(sessionId, event, recordedAt);
|
|
91809
|
+
}
|
|
91531
91810
|
};
|
|
91532
91811
|
materializedEventCount = (sessionId) => this.#sessions.get(sessionId)?.materializedCount ?? 0;
|
|
91533
91812
|
close = () => {
|
|
@@ -91648,7 +91927,7 @@ var init_prompt_content = __esm({
|
|
|
91648
91927
|
});
|
|
91649
91928
|
|
|
91650
91929
|
// src/acp/connection/agent-connection.ts
|
|
91651
|
-
import { spawn as
|
|
91930
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
91652
91931
|
import { ndJsonStream as ndJsonStream3, RequestError as RequestError9 } from "@agentclientprotocol/sdk";
|
|
91653
91932
|
function requestErrorMessage(error62) {
|
|
91654
91933
|
const fallback = truncate2(error62.message, 500);
|
|
@@ -91767,7 +92046,7 @@ var init_agent_connection = __esm({
|
|
|
91767
92046
|
return;
|
|
91768
92047
|
}
|
|
91769
92048
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
91770
|
-
const child =
|
|
92049
|
+
const child = spawn10(launch.command, [...launch.arguments], {
|
|
91771
92050
|
cwd,
|
|
91772
92051
|
...platformSpawnOptions,
|
|
91773
92052
|
env: { ...process.env, ...agent.environment },
|
|
@@ -93121,6 +93400,19 @@ var init_agent_turn = __esm({
|
|
|
93121
93400
|
|
|
93122
93401
|
// src/session/live/session-restore.ts
|
|
93123
93402
|
import { methods as methods10 } from "@agentclientprotocol/sdk";
|
|
93403
|
+
function hasMethodNotFoundCode(cause) {
|
|
93404
|
+
const visited = /* @__PURE__ */ new Set();
|
|
93405
|
+
let current = cause;
|
|
93406
|
+
while ((current instanceof Error || typeof current === "object" && current !== null) && !visited.has(current)) {
|
|
93407
|
+
visited.add(current);
|
|
93408
|
+
const code = Reflect.get(current, "code");
|
|
93409
|
+
if (code === -32601 || code === "METHOD_NOT_FOUND" || code === "method_not_found") {
|
|
93410
|
+
return true;
|
|
93411
|
+
}
|
|
93412
|
+
current = current instanceof Error ? current.cause : void 0;
|
|
93413
|
+
}
|
|
93414
|
+
return false;
|
|
93415
|
+
}
|
|
93124
93416
|
async function restoreSession(session, signal, recovery, origin) {
|
|
93125
93417
|
if (origin !== void 0) {
|
|
93126
93418
|
session.setSessionTitle(origin.title);
|
|
@@ -93187,6 +93479,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93187
93479
|
}
|
|
93188
93480
|
session.setPrompted(true);
|
|
93189
93481
|
session.setRestored(true);
|
|
93482
|
+
if (recovery.kind === "execution-only") {
|
|
93483
|
+
session.startExecutionOnlyCapture();
|
|
93484
|
+
}
|
|
93190
93485
|
lifecycleResponse2 = forked;
|
|
93191
93486
|
} else if (stored instanceof FoundStoredSession && stored.session.agentId === session.agentId && stored.session.cwd === session.cwd && arraysEqual(stored.session.additionalDirectories, session.additionalDirectories)) {
|
|
93192
93487
|
session.selectNativeSession(stored.session.nativeSessionId);
|
|
@@ -93205,6 +93500,37 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93205
93500
|
"session-load",
|
|
93206
93501
|
async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
|
|
93207
93502
|
);
|
|
93503
|
+
} else if (recovery.kind === "execution-only") {
|
|
93504
|
+
try {
|
|
93505
|
+
lifecycleResponse2 = await session.metrics.measure(
|
|
93506
|
+
"session-resume",
|
|
93507
|
+
async () => await session.race(
|
|
93508
|
+
session.agentRequest(
|
|
93509
|
+
methods10.agent.session.resume,
|
|
93510
|
+
{
|
|
93511
|
+
additionalDirectories: [...session.additionalDirectories],
|
|
93512
|
+
cwd: session.cwd,
|
|
93513
|
+
mcpServers: [],
|
|
93514
|
+
sessionId: session.nativeSessionId()
|
|
93515
|
+
},
|
|
93516
|
+
{ cancellationSignal: signal }
|
|
93517
|
+
),
|
|
93518
|
+
"ACP agent exited while resuming a session",
|
|
93519
|
+
signal
|
|
93520
|
+
)
|
|
93521
|
+
);
|
|
93522
|
+
} catch (cause) {
|
|
93523
|
+
signal.throwIfAborted();
|
|
93524
|
+
if (cause instanceof AcpExecutionError && !hasMethodNotFoundCode(cause)) {
|
|
93525
|
+
throw cause;
|
|
93526
|
+
}
|
|
93527
|
+
throw new AcpExecutionError(
|
|
93528
|
+
"This Agent cannot continue a persisted session without replaying native history",
|
|
93529
|
+
{ cause },
|
|
93530
|
+
"execution_only_unsupported"
|
|
93531
|
+
);
|
|
93532
|
+
}
|
|
93533
|
+
session.startExecutionOnlyCapture();
|
|
93208
93534
|
} else if (session.capabilities.resumeSession) {
|
|
93209
93535
|
lifecycleResponse2 = await session.metrics.measure(
|
|
93210
93536
|
"session-resume",
|
|
@@ -93264,6 +93590,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93264
93590
|
);
|
|
93265
93591
|
session.selectNativeSession(created.sessionId);
|
|
93266
93592
|
session.setNativeHistoryOwnership({ kind: "fresh-session" });
|
|
93593
|
+
if (recovery.kind === "execution-only") {
|
|
93594
|
+
session.startExecutionOnlyCapture();
|
|
93595
|
+
}
|
|
93267
93596
|
lifecycleResponse2 = created;
|
|
93268
93597
|
}
|
|
93269
93598
|
session.restrictSessionCapabilities(lifecycleResponse2);
|
|
@@ -93579,6 +93908,16 @@ var init_agent_session = __esm({
|
|
|
93579
93908
|
}
|
|
93580
93909
|
await this.#completedHistory(signal, "ACP agent exited while loading history");
|
|
93581
93910
|
};
|
|
93911
|
+
/** Starts live event capture without asking the native Agent to replay its persisted history. */
|
|
93912
|
+
startExecutionOnlyCapture = () => {
|
|
93913
|
+
if (this.#sessionLoad.kind !== "not-requested") {
|
|
93914
|
+
return;
|
|
93915
|
+
}
|
|
93916
|
+
this.#sessionLoad = {
|
|
93917
|
+
history: new HistoryReplayCapture(this.#store.events, this.#mobiusSessionId),
|
|
93918
|
+
kind: "execution-only"
|
|
93919
|
+
};
|
|
93920
|
+
};
|
|
93582
93921
|
loadHistoryEvents = async (eventLimit, cursor, signal) => {
|
|
93583
93922
|
if (!this.#capabilities.loadSession) {
|
|
93584
93923
|
throw new AcpExecutionError(
|
|
@@ -93829,7 +94168,7 @@ var init_agent_session = __esm({
|
|
|
93829
94168
|
response: {}
|
|
93830
94169
|
};
|
|
93831
94170
|
}
|
|
93832
|
-
if (this.#capabilities.loadSession) {
|
|
94171
|
+
if (this.#capabilities.loadSession && this.#sessionLoad.kind !== "execution-only") {
|
|
93833
94172
|
await this.#completedHistory(options.signal, "ACP agent exited while loading history before a prompt");
|
|
93834
94173
|
}
|
|
93835
94174
|
const prompt = this.buildPrompt(options);
|
|
@@ -94028,14 +94367,14 @@ var init_agent_session = __esm({
|
|
|
94028
94367
|
onElicitationComplete = (notification) => this.#interactions.onElicitationComplete(notification);
|
|
94029
94368
|
onUpdate = (notification) => this.#updates.receive(notification);
|
|
94030
94369
|
recordControlEvent = async (event) => {
|
|
94031
|
-
if (this.#sessionLoad.kind !== "loaded") {
|
|
94370
|
+
if (this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
94032
94371
|
return false;
|
|
94033
94372
|
}
|
|
94034
94373
|
await this.recordLifecycleEvent(event);
|
|
94035
94374
|
return true;
|
|
94036
94375
|
};
|
|
94037
94376
|
recordLifecycleEvent = async (event) => {
|
|
94038
|
-
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded") {
|
|
94377
|
+
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
94039
94378
|
return;
|
|
94040
94379
|
}
|
|
94041
94380
|
const liveEvent2 = this.#sessionLoad.history.recordLifecycle(event);
|
|
@@ -94056,7 +94395,7 @@ var init_agent_session = __esm({
|
|
|
94056
94395
|
const rawUpdate = decodeAcpSessionUpdate(JSON.stringify(externalized.event));
|
|
94057
94396
|
if (this.#sessionLoad.kind === "capturing") {
|
|
94058
94397
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
94059
|
-
} else if (this.#sessionLoad.kind === "loaded") {
|
|
94398
|
+
} else if (this.#sessionLoad.kind === "loaded" || this.#sessionLoad.kind === "execution-only") {
|
|
94060
94399
|
const onSessionEvent = this.#getObserver().onSessionEvent;
|
|
94061
94400
|
await this.#sessionLoad.history.record(update, rawUpdate, async (liveEvent2) => {
|
|
94062
94401
|
await onSessionEvent?.(liveEvent2);
|
|
@@ -95043,13 +95382,14 @@ var init_session_manager = __esm({
|
|
|
95043
95382
|
}
|
|
95044
95383
|
async #replaceExecutionPreparation(existing, options) {
|
|
95045
95384
|
const desiredConfigOptions = existing.prepared().configOptions;
|
|
95385
|
+
const recovery = options.recovery ?? { kind: "interactive-only" };
|
|
95046
95386
|
return await this.#executionProcesses.prepare(options.sessionId, async () => {
|
|
95047
95387
|
await this.#retireSessionProcess(options.sessionId, existing, async () => await existing.close());
|
|
95048
95388
|
const runtime = await this.#startRetainedSessionProcess(
|
|
95049
95389
|
options,
|
|
95050
95390
|
async () => await AgentSession.start(
|
|
95051
95391
|
options,
|
|
95052
|
-
|
|
95392
|
+
recovery,
|
|
95053
95393
|
() => this.#observer,
|
|
95054
95394
|
this.#store,
|
|
95055
95395
|
unmeasuredOperationMetrics,
|
|
@@ -95227,6 +95567,7 @@ var init_session_manager = __esm({
|
|
|
95227
95567
|
});
|
|
95228
95568
|
});
|
|
95229
95569
|
prepareExecutionSession = async (options) => this.#operations.run(options, async (options2) => {
|
|
95570
|
+
const recovery = options2.recovery ?? { kind: "interactive-only" };
|
|
95230
95571
|
this.#assertOpen(options2.sessionId);
|
|
95231
95572
|
const pending = this.#executionProcesses.pending(options2.sessionId);
|
|
95232
95573
|
if (pending !== void 0) {
|
|
@@ -95235,7 +95576,7 @@ var init_session_manager = __esm({
|
|
|
95235
95576
|
}
|
|
95236
95577
|
const existing = this.#executionProcesses.get(options2.sessionId);
|
|
95237
95578
|
if (existing === void 0) {
|
|
95238
|
-
return (await this.#startPreparation(options2,
|
|
95579
|
+
return (await this.#startPreparation(options2, recovery)).prepared();
|
|
95239
95580
|
}
|
|
95240
95581
|
if (!existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
95241
95582
|
throw new AcpExecutionError(
|
|
@@ -95245,6 +95586,9 @@ var init_session_manager = __esm({
|
|
|
95245
95586
|
);
|
|
95246
95587
|
}
|
|
95247
95588
|
if (existing.usesEnvironment(options2.agent.environment)) {
|
|
95589
|
+
if (recovery.kind === "execution-only") {
|
|
95590
|
+
existing.startExecutionOnlyCapture();
|
|
95591
|
+
}
|
|
95248
95592
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
95249
95593
|
return existing.prepared();
|
|
95250
95594
|
}
|
|
@@ -95539,10 +95883,13 @@ var init_session_manager = __esm({
|
|
|
95539
95883
|
"session_identity_mismatch"
|
|
95540
95884
|
);
|
|
95541
95885
|
}
|
|
95886
|
+
if (options2.recovery?.kind === "execution-only") {
|
|
95887
|
+
existing.startExecutionOnlyCapture();
|
|
95888
|
+
}
|
|
95542
95889
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
95543
95890
|
return existing;
|
|
95544
95891
|
}
|
|
95545
|
-
await this
|
|
95892
|
+
await this.#prepareSession(options2, options2.recovery ?? { kind: "interactive-only" }, "reopen");
|
|
95546
95893
|
const started = this.#executionProcesses.get(options2.sessionId);
|
|
95547
95894
|
if (started === void 0) {
|
|
95548
95895
|
throw new AcpExecutionError("ACP session did not start");
|
|
@@ -96100,6 +96447,7 @@ var PromptLifecycle;
|
|
|
96100
96447
|
var init_prompt_lifecycle = __esm({
|
|
96101
96448
|
"src/session/prompt/prompt-lifecycle.ts"() {
|
|
96102
96449
|
"use strict";
|
|
96450
|
+
init_protocol();
|
|
96103
96451
|
PromptLifecycle = class {
|
|
96104
96452
|
#sink;
|
|
96105
96453
|
#terminal = /* @__PURE__ */ new Map();
|
|
@@ -96181,6 +96529,13 @@ var init_prompt_lifecycle = __esm({
|
|
|
96181
96529
|
}
|
|
96182
96530
|
this.#queued.delete(commandId);
|
|
96183
96531
|
};
|
|
96532
|
+
replayOutcome = async (sessionId, event) => {
|
|
96533
|
+
if (event.type !== "lifecycle-metadata" || !("commandId" in event.payload)) {
|
|
96534
|
+
return;
|
|
96535
|
+
}
|
|
96536
|
+
await this.#recordLifecycle(sessionId, event);
|
|
96537
|
+
this.publishTerminal(sessionId, event.payload.commandId);
|
|
96538
|
+
};
|
|
96184
96539
|
queueChanged = async (sessionId) => {
|
|
96185
96540
|
await this.#recordLifecycle(sessionId, {
|
|
96186
96541
|
type: "lifecycle-metadata",
|
|
@@ -96214,7 +96569,7 @@ var init_prompt_lifecycle = __esm({
|
|
|
96214
96569
|
type: "lifecycle-metadata",
|
|
96215
96570
|
payload: { kind: "prompt.failed-before-start", commandId, code, message }
|
|
96216
96571
|
});
|
|
96217
|
-
if (!recorded) {
|
|
96572
|
+
if (!recorded || code === SESSION_CLOSED_ERROR_CODE) {
|
|
96218
96573
|
this.#sink.publishOperationFailure(sessionId, commandId, code, message);
|
|
96219
96574
|
}
|
|
96220
96575
|
};
|
|
@@ -96239,21 +96594,154 @@ var MAX_TERMINAL_RECEIPTS, ExecutionReceipts;
|
|
|
96239
96594
|
var init_execution_receipts = __esm({
|
|
96240
96595
|
"src/session/turn/execution-receipts.ts"() {
|
|
96241
96596
|
"use strict";
|
|
96597
|
+
init_protocol();
|
|
96598
|
+
init_zod();
|
|
96242
96599
|
MAX_TERMINAL_RECEIPTS = 1024;
|
|
96243
96600
|
ExecutionReceipts = class {
|
|
96244
96601
|
#executions = /* @__PURE__ */ new Map();
|
|
96602
|
+
#recoveredCommands = /* @__PURE__ */ new Set();
|
|
96245
96603
|
#terminalCountBySession = /* @__PURE__ */ new Map();
|
|
96604
|
+
#table;
|
|
96605
|
+
#closing = false;
|
|
96606
|
+
#activeCount = 0;
|
|
96607
|
+
#onCount;
|
|
96608
|
+
constructor(table, onCount = () => void 0) {
|
|
96609
|
+
this.#onCount = onCount;
|
|
96610
|
+
this.#table = table;
|
|
96611
|
+
for (const row of table?.list() ?? []) {
|
|
96612
|
+
this.#executions.set(row.commandId, row);
|
|
96613
|
+
this.#recoveredCommands.add(row.commandId);
|
|
96614
|
+
if (!isTerminal(row.state)) {
|
|
96615
|
+
this.#activeCount += 1;
|
|
96616
|
+
}
|
|
96617
|
+
if (isTerminal(row.state)) {
|
|
96618
|
+
this.#terminalCountBySession.set(
|
|
96619
|
+
row.sessionId,
|
|
96620
|
+
(this.#terminalCountBySession.get(row.sessionId) ?? 0) + 1
|
|
96621
|
+
);
|
|
96622
|
+
}
|
|
96623
|
+
}
|
|
96624
|
+
}
|
|
96625
|
+
#save = (commandId, receipt) => {
|
|
96626
|
+
if (!this.#closing) {
|
|
96627
|
+
this.#table?.save({ ...receipt, commandId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
96628
|
+
}
|
|
96629
|
+
const previous = this.#executions.get(commandId);
|
|
96630
|
+
const wasActive = previous !== void 0 && !isTerminal(previous.state);
|
|
96631
|
+
if (isTerminal(receipt.state)) {
|
|
96632
|
+
this.#executions.delete(commandId);
|
|
96633
|
+
}
|
|
96634
|
+
this.#executions.set(commandId, receipt);
|
|
96635
|
+
this.#activeCount += Number(!isTerminal(receipt.state)) - Number(wasActive);
|
|
96636
|
+
this.#onCount(this.#activeCount);
|
|
96637
|
+
if (isTerminal(receipt.state) && (previous === void 0 || !isTerminal(previous.state))) {
|
|
96638
|
+
this.#terminalCountBySession.set(
|
|
96639
|
+
receipt.sessionId,
|
|
96640
|
+
(this.#terminalCountBySession.get(receipt.sessionId) ?? 0) + 1
|
|
96641
|
+
);
|
|
96642
|
+
this.pruneTerminalReceipts(receipt.sessionId);
|
|
96643
|
+
}
|
|
96644
|
+
};
|
|
96645
|
+
beginShutdown = () => {
|
|
96646
|
+
this.#closing = true;
|
|
96647
|
+
};
|
|
96648
|
+
outcome = (commandId) => {
|
|
96649
|
+
const receipt = this.#executions.get(commandId);
|
|
96650
|
+
return receipt?.outcome === null || receipt === void 0 ? void 0 : sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
|
|
96651
|
+
};
|
|
96652
|
+
recordOutcome = (event) => {
|
|
96653
|
+
if (event.type !== "lifecycle-metadata") {
|
|
96654
|
+
return;
|
|
96655
|
+
}
|
|
96656
|
+
const payload = event.payload;
|
|
96657
|
+
if (payload.kind !== "prompt.completed" && payload.kind !== "prompt.failed" && payload.kind !== "prompt.failed-before-start") {
|
|
96658
|
+
return;
|
|
96659
|
+
}
|
|
96660
|
+
const receipt = this.#executions.get(payload.commandId);
|
|
96661
|
+
if (receipt === void 0) {
|
|
96662
|
+
return;
|
|
96663
|
+
}
|
|
96664
|
+
const sanitized = payload.kind === "prompt.completed" ? payload : { ...payload, message: "The local Agent could not complete the request" };
|
|
96665
|
+
this.#save(payload.commandId, {
|
|
96666
|
+
...receipt,
|
|
96667
|
+
state: payload.kind === "prompt.completed" ? payload.stopReason === "cancelled" ? "cancelled" : "succeeded" : "failed",
|
|
96668
|
+
outcome: JSON.stringify({ type: "lifecycle-metadata", payload: sanitized, recordedAt: event.recordedAt })
|
|
96669
|
+
});
|
|
96670
|
+
};
|
|
96671
|
+
recover = () => {
|
|
96672
|
+
const recovered = [];
|
|
96673
|
+
for (const [commandId, receipt] of [...this.#executions]) {
|
|
96674
|
+
const event = receipt.outcome === null ? {
|
|
96675
|
+
type: "lifecycle-metadata",
|
|
96676
|
+
payload: receipt.started ? {
|
|
96677
|
+
kind: "prompt.failed",
|
|
96678
|
+
commandId,
|
|
96679
|
+
attemptId: receipt.attemptId,
|
|
96680
|
+
code: "runtime_restarted",
|
|
96681
|
+
message: "The local runtime restarted while this request was running"
|
|
96682
|
+
} : {
|
|
96683
|
+
kind: "prompt.failed-before-start",
|
|
96684
|
+
commandId,
|
|
96685
|
+
code: "runtime_restarted",
|
|
96686
|
+
message: "The local runtime restarted before this request started"
|
|
96687
|
+
}
|
|
96688
|
+
} : sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
|
|
96689
|
+
const recordedAt = receipt.outcome === null ? (/* @__PURE__ */ new Date()).toISOString() : external_exports.object({ recordedAt: external_exports.string() }).parse(JSON.parse(receipt.outcome)).recordedAt;
|
|
96690
|
+
recovered.push({ sessionId: receipt.sessionId, event, recordedAt });
|
|
96691
|
+
if (!isTerminal(receipt.state)) {
|
|
96692
|
+
const state = event.type === "lifecycle-metadata" && event.payload.kind === "prompt.completed" ? event.payload.stopReason === "cancelled" ? "cancelled" : "succeeded" : "failed";
|
|
96693
|
+
this.#save(commandId, { ...receipt, state, outcome: JSON.stringify({ ...event, recordedAt }) });
|
|
96694
|
+
}
|
|
96695
|
+
}
|
|
96696
|
+
return recovered;
|
|
96697
|
+
};
|
|
96698
|
+
terminalOutcomes = (sessionId) => [...this.#executions.values()].flatMap((receipt) => {
|
|
96699
|
+
if (receipt.sessionId !== sessionId || receipt.outcome === null) {
|
|
96700
|
+
return [];
|
|
96701
|
+
}
|
|
96702
|
+
const decoded = JSON.parse(receipt.outcome);
|
|
96703
|
+
return [
|
|
96704
|
+
{
|
|
96705
|
+
event: sessionEventPayloadSchema.parse(decoded),
|
|
96706
|
+
recordedAt: external_exports.object({ recordedAt: external_exports.string() }).parse(decoded).recordedAt
|
|
96707
|
+
}
|
|
96708
|
+
];
|
|
96709
|
+
});
|
|
96246
96710
|
claimExecution = (commandId, sessionId, commandJson) => {
|
|
96247
96711
|
const commandHash = createHash7("sha256").update(commandJson).digest("hex");
|
|
96248
|
-
|
|
96712
|
+
let existing = this.#executions.get(commandId);
|
|
96713
|
+
const previous = this.outcome(commandId);
|
|
96714
|
+
if (existing?.sessionId === sessionId && !existing.started && previous?.type === "lifecycle-metadata" && previous.payload.kind === "prompt.failed-before-start" && previous.payload.code === "runtime_restarted") {
|
|
96715
|
+
this.#executions.delete(commandId);
|
|
96716
|
+
this.#recoveredCommands.delete(commandId);
|
|
96717
|
+
this.#table?.remove(commandId);
|
|
96718
|
+
this.#terminalCountBySession.set(
|
|
96719
|
+
sessionId,
|
|
96720
|
+
Math.max(0, (this.#terminalCountBySession.get(sessionId) ?? 1) - 1)
|
|
96721
|
+
);
|
|
96722
|
+
existing = void 0;
|
|
96723
|
+
}
|
|
96249
96724
|
if (existing !== void 0) {
|
|
96250
96725
|
if (existing.sessionId !== sessionId || existing.commandHash !== commandHash) {
|
|
96251
96726
|
return { kind: "conflict" };
|
|
96252
96727
|
}
|
|
96253
|
-
return {
|
|
96728
|
+
return {
|
|
96729
|
+
attemptId: existing.attemptId,
|
|
96730
|
+
commandId,
|
|
96731
|
+
kind: "duplicate",
|
|
96732
|
+
state: existing.state,
|
|
96733
|
+
outcome: this.#recoveredCommands.has(commandId) ? this.outcome(commandId) : void 0
|
|
96734
|
+
};
|
|
96254
96735
|
}
|
|
96255
96736
|
const attemptId = randomUUID14();
|
|
96256
|
-
this.#
|
|
96737
|
+
this.#save(commandId, {
|
|
96738
|
+
attemptId,
|
|
96739
|
+
commandHash,
|
|
96740
|
+
sessionId,
|
|
96741
|
+
state: "dispatching",
|
|
96742
|
+
started: false,
|
|
96743
|
+
outcome: null
|
|
96744
|
+
});
|
|
96257
96745
|
return { attemptId, commandId, kind: "accepted", state: "dispatching" };
|
|
96258
96746
|
};
|
|
96259
96747
|
transitionExecution = (commandId, state) => {
|
|
@@ -96268,16 +96756,13 @@ var init_execution_receipts = __esm({
|
|
|
96268
96756
|
if (!allowed) {
|
|
96269
96757
|
throw new Error("The runtime execution transition is invalid");
|
|
96270
96758
|
}
|
|
96271
|
-
|
|
96272
|
-
|
|
96273
|
-
|
|
96274
|
-
|
|
96275
|
-
(this.#terminalCountBySession.get(current.sessionId) ?? 0) + 1
|
|
96276
|
-
);
|
|
96277
|
-
this.pruneTerminalReceipts(current.sessionId);
|
|
96759
|
+
if (state === "running") {
|
|
96760
|
+
this.#save(commandId, { ...current, state, started: true });
|
|
96761
|
+
} else if (isTerminal(state)) {
|
|
96762
|
+
this.#save(commandId, { ...current, state });
|
|
96278
96763
|
}
|
|
96279
96764
|
};
|
|
96280
|
-
/**
|
|
96765
|
+
/** Only commands without a terminal result can still be cancelled. */
|
|
96281
96766
|
findUnsettledAttemptId = (commandId, sessionId) => {
|
|
96282
96767
|
const receipt = this.#executions.get(commandId);
|
|
96283
96768
|
return receipt?.sessionId === sessionId && !isTerminal(receipt.state) ? receipt.attemptId : null;
|
|
@@ -96288,7 +96773,9 @@ var init_execution_receipts = __esm({
|
|
|
96288
96773
|
};
|
|
96289
96774
|
close = () => {
|
|
96290
96775
|
this.#executions.clear();
|
|
96776
|
+
this.#recoveredCommands.clear();
|
|
96291
96777
|
this.#terminalCountBySession.clear();
|
|
96778
|
+
this.#activeCount = 0;
|
|
96292
96779
|
};
|
|
96293
96780
|
pruneTerminalReceipts = (sessionId) => {
|
|
96294
96781
|
if ((this.#terminalCountBySession.get(sessionId) ?? 0) <= MAX_TERMINAL_RECEIPTS) {
|
|
@@ -96297,6 +96784,8 @@ var init_execution_receipts = __esm({
|
|
|
96297
96784
|
for (const [commandId, receipt] of this.#executions) {
|
|
96298
96785
|
if (receipt.sessionId === sessionId && isTerminal(receipt.state)) {
|
|
96299
96786
|
this.#executions.delete(commandId);
|
|
96787
|
+
this.#recoveredCommands.delete(commandId);
|
|
96788
|
+
this.#table?.remove(commandId);
|
|
96300
96789
|
const remaining = (this.#terminalCountBySession.get(sessionId) ?? 1) - 1;
|
|
96301
96790
|
if (remaining > 0) {
|
|
96302
96791
|
this.#terminalCountBySession.set(sessionId, remaining);
|
|
@@ -96847,10 +97336,14 @@ function buildSessionLayer(options) {
|
|
|
96847
97336
|
const databases = channelSessionDatabasePaths(stateDirectory, channelId);
|
|
96848
97337
|
const sessionDatabase = openAcpSessionDatabase(databases.sessions);
|
|
96849
97338
|
let events;
|
|
97339
|
+
let operations;
|
|
96850
97340
|
try {
|
|
97341
|
+
operations = new ExecutionReceipts(new ExecutionReceiptTable(sessionDatabase), options.onExecutionCountChange);
|
|
96851
97342
|
events = new CachedSessionEventStore(
|
|
96852
97343
|
new SessionEventCacheTable(openSessionEventCacheDatabase(databases.events)),
|
|
96853
|
-
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase))
|
|
97344
|
+
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase)),
|
|
97345
|
+
void 0,
|
|
97346
|
+
(sessionId) => operations.terminalOutcomes(sessionId)
|
|
96854
97347
|
);
|
|
96855
97348
|
} catch (error62) {
|
|
96856
97349
|
sessionDatabase.close();
|
|
@@ -96858,11 +97351,13 @@ function buildSessionLayer(options) {
|
|
|
96858
97351
|
}
|
|
96859
97352
|
const sessionStore = new SqliteSessionStore(new AcpSessionTable(sessionDatabase), events);
|
|
96860
97353
|
const externalContent = new LocalExternalContentStore(stateDirectory);
|
|
96861
|
-
const operations = new ExecutionReceipts();
|
|
96862
97354
|
const activeSessions = new SessionTurns(operations, options.turnActivity);
|
|
96863
97355
|
const directories = new WorkspaceDirectoryService(bindingId, defaultWorkspace);
|
|
96864
97356
|
const manager = new SessionManager2({
|
|
96865
|
-
observer: new SessionLayerObserver((event) =>
|
|
97357
|
+
observer: new SessionLayerObserver((event) => {
|
|
97358
|
+
operations.recordOutcome(event);
|
|
97359
|
+
eventProjection.record(event);
|
|
97360
|
+
}, sink.publishInfo),
|
|
96866
97361
|
store: sessionStore,
|
|
96867
97362
|
adapters: harnessAdapters,
|
|
96868
97363
|
sessionIdentity: "native",
|
|
@@ -96883,7 +97378,15 @@ function buildSessionLayer(options) {
|
|
|
96883
97378
|
});
|
|
96884
97379
|
const eventProjection = new PromptLifecycle(
|
|
96885
97380
|
sink,
|
|
96886
|
-
(sessionId, event) =>
|
|
97381
|
+
async (sessionId, event) => {
|
|
97382
|
+
if (await manager.recordLifecycleEvent(sessionId, event)) {
|
|
97383
|
+
return true;
|
|
97384
|
+
}
|
|
97385
|
+
const recorded = events.append(sessionId, event);
|
|
97386
|
+
operations.recordOutcome(recorded);
|
|
97387
|
+
eventProjection.record(recorded);
|
|
97388
|
+
return true;
|
|
97389
|
+
},
|
|
96887
97390
|
activeSessions.recordSessionEvent
|
|
96888
97391
|
);
|
|
96889
97392
|
const nativeSessions = new NativeSessionService(
|
|
@@ -96906,7 +97409,13 @@ function buildSessionLayer(options) {
|
|
|
96906
97409
|
);
|
|
96907
97410
|
})
|
|
96908
97411
|
);
|
|
97412
|
+
const recoveredEvents = operations.recover().map(({ sessionId, event, recordedAt }) => events.append(sessionId, event, recordedAt));
|
|
96909
97413
|
return {
|
|
97414
|
+
publishRecoveredOutcomes: () => {
|
|
97415
|
+
for (const event of recoveredEvents) {
|
|
97416
|
+
sink.publish(event);
|
|
97417
|
+
}
|
|
97418
|
+
},
|
|
96910
97419
|
activeSessions,
|
|
96911
97420
|
directories,
|
|
96912
97421
|
eventProjection,
|
|
@@ -96924,6 +97433,7 @@ var init_session_layer = __esm({
|
|
|
96924
97433
|
init_registry();
|
|
96925
97434
|
init_content_externalizer();
|
|
96926
97435
|
init_acp_session_table();
|
|
97436
|
+
init_execution_receipt_table();
|
|
96927
97437
|
init_live_event_position_table();
|
|
96928
97438
|
init_session_event_cache_table();
|
|
96929
97439
|
init_local_databases();
|
|
@@ -98804,12 +99314,14 @@ async function executePrompt({
|
|
|
98804
99314
|
const appliedSettings = command.sessionConfigurations === void 0 ? void 0 : agentForSessionConfiguration(agent, command.sessionConfigurations);
|
|
98805
99315
|
const executionAgent = appliedSettings?.agent ?? agent;
|
|
98806
99316
|
const sessionConfigurations = appliedSettings?.sessionConfigurations;
|
|
99317
|
+
const recovery = command.historyPolicy === SessionHistoryPolicy.ExecutionOnly ? { kind: "execution-only" } : { kind: "interactive-only" };
|
|
98807
99318
|
const preparation = {
|
|
98808
99319
|
additionalDirectories: resolved.additionalDirectories,
|
|
98809
99320
|
agent: executionAgent,
|
|
98810
99321
|
cwd: resolved.cwd,
|
|
98811
99322
|
sessionId: command.sessionId,
|
|
98812
|
-
signal
|
|
99323
|
+
signal,
|
|
99324
|
+
recovery
|
|
98813
99325
|
};
|
|
98814
99326
|
let prepared = await sessions.prepareExecutionSession(preparation);
|
|
98815
99327
|
if (command.sessionConfigurations !== void 0) {
|
|
@@ -98878,7 +99390,8 @@ async function executePrompt({
|
|
|
98878
99390
|
resources: attachments.resources,
|
|
98879
99391
|
sessionId: command.sessionId,
|
|
98880
99392
|
signal,
|
|
98881
|
-
targetCommandId: command.targetCommandId
|
|
99393
|
+
targetCommandId: command.targetCommandId,
|
|
99394
|
+
recovery
|
|
98882
99395
|
});
|
|
98883
99396
|
stopReason = result.stopReason;
|
|
98884
99397
|
}
|
|
@@ -99076,6 +99589,12 @@ var init_prompt2 = __esm({
|
|
|
99076
99589
|
return;
|
|
99077
99590
|
}
|
|
99078
99591
|
if (receipt.kind === "duplicate") {
|
|
99592
|
+
const outcome = receipt.outcome;
|
|
99593
|
+
if (outcome !== void 0) {
|
|
99594
|
+
void context.eventProjection.replayOutcome(message.sessionId, outcome).catch((cause) => {
|
|
99595
|
+
console.error("Could not replay the persisted execution outcome", cause);
|
|
99596
|
+
});
|
|
99597
|
+
}
|
|
99079
99598
|
return;
|
|
99080
99599
|
}
|
|
99081
99600
|
const turn = context.sessionTurns.start(message, receipt.attemptId);
|
|
@@ -100282,7 +100801,8 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100282
100801
|
resolveAgent: (agentId, resolveSignal) => resolveCatalogAgent(config2, agentId, resolveSignal),
|
|
100283
100802
|
sink: publisher,
|
|
100284
100803
|
stateDirectory: config2.localContext.stateDirectory,
|
|
100285
|
-
timer
|
|
100804
|
+
timer,
|
|
100805
|
+
onExecutionCountChange: options.onExecutionCountChange ?? (() => void 0)
|
|
100286
100806
|
});
|
|
100287
100807
|
const {
|
|
100288
100808
|
activeSessions,
|
|
@@ -100352,6 +100872,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100352
100872
|
reportUpgradeAvailability,
|
|
100353
100873
|
diagnostics,
|
|
100354
100874
|
onConnected: () => {
|
|
100875
|
+
layer.publishRecoveredOutcomes();
|
|
100355
100876
|
if (catalogPublished) {
|
|
100356
100877
|
options.onConnectionStatus?.("online");
|
|
100357
100878
|
}
|
|
@@ -100374,6 +100895,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100374
100895
|
}
|
|
100375
100896
|
} finally {
|
|
100376
100897
|
shutdown.abort();
|
|
100898
|
+
operations.beginShutdown();
|
|
100377
100899
|
await activeSessions.close();
|
|
100378
100900
|
try {
|
|
100379
100901
|
await catalogPublication;
|
|
@@ -100468,6 +100990,10 @@ var init_engine = __esm({
|
|
|
100468
100990
|
MobiusRuntimeEngine = class {
|
|
100469
100991
|
#config;
|
|
100470
100992
|
#options;
|
|
100993
|
+
#activeTurnCount = 0;
|
|
100994
|
+
get activeTurnCount() {
|
|
100995
|
+
return this.#activeTurnCount;
|
|
100996
|
+
}
|
|
100471
100997
|
#state = new IdleMobiusRuntimeState();
|
|
100472
100998
|
constructor(config2, options = {}) {
|
|
100473
100999
|
validateRuntimeConfiguration(config2);
|
|
@@ -100483,11 +101009,15 @@ var init_engine = __esm({
|
|
|
100483
101009
|
try {
|
|
100484
101010
|
await runRuntime(this.#config, signal, void 0, {
|
|
100485
101011
|
...this.#options.turnActivity === void 0 ? {} : { turnActivity: this.#options.turnActivity },
|
|
101012
|
+
onExecutionCountChange: (count) => {
|
|
101013
|
+
this.#activeTurnCount = count;
|
|
101014
|
+
},
|
|
100486
101015
|
...this.#options.onConnectionStatus === void 0 ? {} : { onConnectionStatus: this.#options.onConnectionStatus },
|
|
100487
101016
|
...this.#options.reportUpgradeAvailability === void 0 ? {} : { reportUpgradeAvailability: this.#options.reportUpgradeAvailability },
|
|
100488
101017
|
...this.#options.processLogsDirectory === void 0 ? {} : { processLogsDirectory: this.#options.processLogsDirectory }
|
|
100489
101018
|
});
|
|
100490
101019
|
} finally {
|
|
101020
|
+
this.#activeTurnCount = 0;
|
|
100491
101021
|
this.#state = new FinishedMobiusRuntimeState();
|
|
100492
101022
|
}
|
|
100493
101023
|
};
|