@moxt-ai/mobius 0.0.299 → 0.0.301
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acp/harness/claude/endpoint.d.ts.map +1 -1
- package/dist/acp/harness/claude/endpoint.js +2 -0
- package/dist/acp/harness/claude/endpoint.js.map +1 -1
- package/dist/acp/harness/claude/parent-lifeline.d.ts +3 -0
- package/dist/acp/harness/claude/parent-lifeline.d.ts.map +1 -0
- package/dist/acp/harness/claude/parent-lifeline.js +73 -0
- package/dist/acp/harness/claude/parent-lifeline.js.map +1 -0
- package/dist/acp/harness/codex/settings.d.ts.map +1 -1
- package/dist/acp/harness/codex/settings.js +4 -0
- package/dist/acp/harness/codex/settings.js.map +1 -1
- package/dist/acp/harness/pi/endpoint.d.ts.map +1 -1
- package/dist/acp/harness/pi/endpoint.js +1 -0
- package/dist/acp/harness/pi/endpoint.js.map +1 -1
- package/dist/acp/native-history/codex/native-history-events.d.ts.map +1 -1
- package/dist/acp/native-history/codex/native-history-events.js +10 -0
- package/dist/acp/native-history/codex/native-history-events.js.map +1 -1
- package/dist/cli.js +604 -60
- package/dist/cli.js.map +4 -4
- package/dist/generated/acp-session-store-migrations.d.ts +3 -0
- package/dist/generated/acp-session-store-migrations.d.ts.map +1 -1
- package/dist/generated/acp-session-store-migrations.js +5 -1
- package/dist/generated/acp-session-store-migrations.js.map +1 -1
- package/dist/runtime/command/registry/prompt.d.ts.map +1 -1
- package/dist/runtime/command/registry/prompt.js +6 -0
- package/dist/runtime/command/registry/prompt.js.map +1 -1
- package/dist/runtime/engine.d.ts +1 -0
- package/dist/runtime/engine.d.ts.map +1 -1
- package/dist/runtime/engine.js +8 -0
- package/dist/runtime/engine.js.map +1 -1
- package/dist/runtime/run.d.ts +1 -0
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +3 -0
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime.js +569 -53
- package/dist/runtime.js.map +4 -4
- package/dist/schema/acp-session-store/execution-receipt.d.ts +136 -0
- package/dist/schema/acp-session-store/execution-receipt.d.ts.map +1 -0
- package/dist/schema/acp-session-store/execution-receipt.js +12 -0
- package/dist/schema/acp-session-store/execution-receipt.js.map +1 -0
- package/dist/schema/acp-session-store/index.d.ts +1 -0
- package/dist/schema/acp-session-store/index.d.ts.map +1 -1
- package/dist/schema/acp-session-store/index.js +1 -0
- package/dist/schema/acp-session-store/index.js.map +1 -1
- package/dist/session/api/session-api.d.ts +4 -0
- package/dist/session/api/session-api.d.ts.map +1 -1
- package/dist/session/api/session-api.js.map +1 -1
- package/dist/session/api/session-layer.d.ts +2 -0
- package/dist/session/api/session-layer.d.ts.map +1 -1
- package/dist/session/api/session-layer.js +25 -4
- package/dist/session/api/session-layer.js.map +1 -1
- package/dist/session/history/session-event-store.d.ts +7 -4
- package/dist/session/history/session-event-store.d.ts.map +1 -1
- package/dist/session/history/session-event-store.js +13 -7
- package/dist/session/history/session-event-store.js.map +1 -1
- package/dist/session/history/session-history.d.ts +1 -4
- package/dist/session/history/session-history.d.ts.map +1 -1
- package/dist/session/history/session-history.js +1 -4
- package/dist/session/history/session-history.js.map +1 -1
- package/dist/session/live/agent-session-restore.d.ts +1 -0
- package/dist/session/live/agent-session-restore.d.ts.map +1 -1
- package/dist/session/live/agent-session.d.ts +2 -0
- package/dist/session/live/agent-session.d.ts.map +1 -1
- package/dist/session/live/agent-session.js +15 -4
- package/dist/session/live/agent-session.js.map +1 -1
- package/dist/session/live/session-restore.d.ts.map +1 -1
- package/dist/session/live/session-restore.js +37 -0
- package/dist/session/live/session-restore.js.map +1 -1
- package/dist/session/manager/session-manager.d.ts.map +1 -1
- package/dist/session/manager/session-manager.js +11 -3
- package/dist/session/manager/session-manager.js.map +1 -1
- package/dist/session/prompt/execute-prompt.d.ts.map +1 -1
- package/dist/session/prompt/execute-prompt.js +6 -1
- package/dist/session/prompt/execute-prompt.js.map +1 -1
- package/dist/session/prompt/prompt-lifecycle.d.ts +1 -0
- package/dist/session/prompt/prompt-lifecycle.d.ts.map +1 -1
- package/dist/session/prompt/prompt-lifecycle.js +9 -1
- package/dist/session/prompt/prompt-lifecycle.js.map +1 -1
- package/dist/session/turn/execution-receipts.d.ts +23 -2
- package/dist/session/turn/execution-receipts.d.ts.map +1 -1
- package/dist/session/turn/execution-receipts.js +161 -10
- package/dist/session/turn/execution-receipts.js.map +1 -1
- package/dist/storage/session/execution-receipt-table.d.ts +45 -0
- package/dist/storage/session/execution-receipt-table.d.ts.map +1 -0
- package/dist/storage/session/execution-receipt-table.js +64 -0
- package/dist/storage/session/execution-receipt-table.js.map +1 -0
- package/package.json +2 -2
package/dist/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({
|
|
@@ -75236,6 +75345,10 @@ var init_settings3 = __esm({
|
|
|
75236
75345
|
approvalPolicy: mode.approvalPolicy,
|
|
75237
75346
|
approvalsReviewer: mode.approvalsReviewer,
|
|
75238
75347
|
sandboxPolicy: mode.sandboxPolicy,
|
|
75348
|
+
// Codex only streams its provider-authored reasoning summary when the turn opts in.
|
|
75349
|
+
// Keep the summary channel enabled so Thinking has visible content even when no raw
|
|
75350
|
+
// reasoning text is available.
|
|
75351
|
+
summary: "auto",
|
|
75239
75352
|
// The collaboration mode rides on the turn: Codex applies it to the
|
|
75240
75353
|
// thread, where it persists until changed. "Build" is Codex's `default`
|
|
75241
75354
|
// mode, so it is only sent once a choice exists to apply.
|
|
@@ -75862,7 +75975,7 @@ var init_command2 = __esm({
|
|
|
75862
75975
|
});
|
|
75863
75976
|
|
|
75864
75977
|
// src/acp/harness/pi/upstream/dist/pi-rpc/process.js
|
|
75865
|
-
import { spawn as
|
|
75978
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
75866
75979
|
import * as readline from "node:readline";
|
|
75867
75980
|
function stripAnsi(s) {
|
|
75868
75981
|
return s.replace(ANSI_ESCAPE_REGEX, "");
|
|
@@ -75966,7 +76079,7 @@ var init_process = __esm({
|
|
|
75966
76079
|
args.push("--fork", params.origin.sessionPath);
|
|
75967
76080
|
break;
|
|
75968
76081
|
}
|
|
75969
|
-
const child =
|
|
76082
|
+
const child = spawn5(cmd, args, {
|
|
75970
76083
|
cwd: params.cwd,
|
|
75971
76084
|
stdio: "pipe",
|
|
75972
76085
|
env: params.environment,
|
|
@@ -79406,6 +79519,77 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
79406
79519
|
}, 0);
|
|
79407
79520
|
return { sessionId: session.sessionId, configOptions, modes };
|
|
79408
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
|
+
}
|
|
79409
79593
|
async loadSession(params) {
|
|
79410
79594
|
if (!isAbsolute11(params.cwd)) {
|
|
79411
79595
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
@@ -79685,6 +79869,9 @@ var init_endpoint2 = __esm({
|
|
|
79685
79869
|
).onRequest(
|
|
79686
79870
|
methods5.agent.session.load,
|
|
79687
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)
|
|
79688
79875
|
).onRequest(
|
|
79689
79876
|
methods5.agent.session.list,
|
|
79690
79877
|
async (context) => await piAgentOrThrow(piAgent).listSessions(context.params)
|
|
@@ -80211,7 +80398,7 @@ var init_create_client = __esm({
|
|
|
80211
80398
|
});
|
|
80212
80399
|
|
|
80213
80400
|
// src/agent/discovery/acp-readiness-probe.ts
|
|
80214
|
-
import { spawn as
|
|
80401
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
80215
80402
|
import {
|
|
80216
80403
|
methods as methods8,
|
|
80217
80404
|
ndJsonStream as ndJsonStream2,
|
|
@@ -80368,7 +80555,7 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
|
|
|
80368
80555
|
}
|
|
80369
80556
|
}
|
|
80370
80557
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
80371
|
-
const child =
|
|
80558
|
+
const child = spawn6(launch.command, [...launch.arguments], {
|
|
80372
80559
|
cwd: defaultWorkspace,
|
|
80373
80560
|
...platformSpawnOptions,
|
|
80374
80561
|
env: { ...environment, ...agent.environment },
|
|
@@ -83039,7 +83226,7 @@ var init_worker_lifecycle_log = __esm({
|
|
|
83039
83226
|
});
|
|
83040
83227
|
|
|
83041
83228
|
// src/daemon/lifecycle/worker-process.ts
|
|
83042
|
-
import { spawn as
|
|
83229
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
83043
83230
|
import { isAbsolute as isAbsolute13, resolve as resolve16 } from "node:path";
|
|
83044
83231
|
function currentWorkerLaunch(version2) {
|
|
83045
83232
|
const entry = process.argv[1];
|
|
@@ -83099,7 +83286,7 @@ var init_worker_process = __esm({
|
|
|
83099
83286
|
constructor(launch, signal, environment) {
|
|
83100
83287
|
signal.throwIfAborted();
|
|
83101
83288
|
this.launch = launch;
|
|
83102
|
-
this.#child =
|
|
83289
|
+
this.#child = spawn7(launch.executable, [launch.entry, "__worker"], {
|
|
83103
83290
|
env: environment,
|
|
83104
83291
|
windowsHide: true,
|
|
83105
83292
|
stdio: ["ignore", "pipe", "pipe", "ipc"]
|
|
@@ -83432,9 +83619,9 @@ var init_manager2 = __esm({
|
|
|
83432
83619
|
});
|
|
83433
83620
|
|
|
83434
83621
|
// src/daemon/lifecycle/manager-client.ts
|
|
83435
|
-
import { spawn as
|
|
83622
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
83436
83623
|
async function spawnManager() {
|
|
83437
|
-
const child =
|
|
83624
|
+
const child = spawn8(process.execPath, [process.argv[1] ?? "", "__manager"], {
|
|
83438
83625
|
detached: true,
|
|
83439
83626
|
windowsHide: true,
|
|
83440
83627
|
env: process.env,
|
|
@@ -83840,7 +84027,7 @@ var init_history_images = __esm({
|
|
|
83840
84027
|
});
|
|
83841
84028
|
|
|
83842
84029
|
// src/acp/native-history/codex/codex-history.ts
|
|
83843
|
-
import { spawn as
|
|
84030
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
83844
84031
|
function bounded(value, maximum) {
|
|
83845
84032
|
return value.slice(0, maximum);
|
|
83846
84033
|
}
|
|
@@ -84216,7 +84403,7 @@ async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal,
|
|
|
84216
84403
|
}
|
|
84217
84404
|
signal.throwIfAborted();
|
|
84218
84405
|
const launch = executableLaunch2(agent.agentIdentity.realPath, ["app-server"]);
|
|
84219
|
-
const child =
|
|
84406
|
+
const child = spawn9(launch.command, [...launch.arguments], {
|
|
84220
84407
|
cwd,
|
|
84221
84408
|
env: { ...process.env, ...agent.environment },
|
|
84222
84409
|
...platformSpawnOptions,
|
|
@@ -84561,6 +84748,16 @@ function toolStatus2(value) {
|
|
|
84561
84748
|
}
|
|
84562
84749
|
}
|
|
84563
84750
|
function activityEvent(activity2) {
|
|
84751
|
+
if (activity2.activityType === "reasoning") {
|
|
84752
|
+
return {
|
|
84753
|
+
payload: {
|
|
84754
|
+
content: { text: activity2.output, type: "text" },
|
|
84755
|
+
messageId: activity2.activityId,
|
|
84756
|
+
sessionUpdate: "agent_thought_chunk"
|
|
84757
|
+
},
|
|
84758
|
+
type: "acp"
|
|
84759
|
+
};
|
|
84760
|
+
}
|
|
84564
84761
|
return {
|
|
84565
84762
|
payload: {
|
|
84566
84763
|
content: activity2.content,
|
|
@@ -90219,6 +90416,25 @@ var init_acp_session = __esm({
|
|
|
90219
90416
|
}
|
|
90220
90417
|
});
|
|
90221
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
|
+
|
|
90222
90438
|
// src/schema/acp-session-store/session-live-event-position-allocation.ts
|
|
90223
90439
|
var sessionLiveEventPositionAllocation;
|
|
90224
90440
|
var init_session_live_event_position_allocation = __esm({
|
|
@@ -90237,6 +90453,7 @@ var init_acp_session_store = __esm({
|
|
|
90237
90453
|
"src/schema/acp-session-store/index.ts"() {
|
|
90238
90454
|
"use strict";
|
|
90239
90455
|
init_acp_session();
|
|
90456
|
+
init_execution_receipt();
|
|
90240
90457
|
init_session_live_event_position_allocation();
|
|
90241
90458
|
}
|
|
90242
90459
|
});
|
|
@@ -90285,6 +90502,71 @@ var init_acp_session_table = __esm({
|
|
|
90285
90502
|
}
|
|
90286
90503
|
});
|
|
90287
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
|
+
|
|
90288
90570
|
// src/storage/session/live-event-position-table.ts
|
|
90289
90571
|
var allocationRowSchema, LiveEventPositionTable;
|
|
90290
90572
|
var init_live_event_position_table = __esm({
|
|
@@ -90538,6 +90820,10 @@ var init_acp_session_store_migrations = __esm({
|
|
|
90538
90820
|
{
|
|
90539
90821
|
"name": "0006_live_event_position_allocation.sql",
|
|
90540
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"
|
|
90541
90827
|
}
|
|
90542
90828
|
];
|
|
90543
90829
|
}
|
|
@@ -91156,12 +91442,12 @@ var init_session_event_id_allocator = __esm({
|
|
|
91156
91442
|
|
|
91157
91443
|
// src/session/history/session-event-store.ts
|
|
91158
91444
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
91159
|
-
function liveEvent(sessionId, sessionGenerationId, eventId, position, event) {
|
|
91445
|
+
function liveEvent(sessionId, sessionGenerationId, eventId, position, event, recordedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
91160
91446
|
return {
|
|
91161
91447
|
eventId,
|
|
91162
91448
|
...event,
|
|
91163
91449
|
position: position.toString(),
|
|
91164
|
-
recordedAt
|
|
91450
|
+
recordedAt,
|
|
91165
91451
|
sessionGenerationId,
|
|
91166
91452
|
sessionId
|
|
91167
91453
|
};
|
|
@@ -91322,7 +91608,7 @@ var init_session_event_store = __esm({
|
|
|
91322
91608
|
}
|
|
91323
91609
|
return resolved;
|
|
91324
91610
|
};
|
|
91325
|
-
append = (sessionId, event) => {
|
|
91611
|
+
append = (sessionId, event, recordedAt) => {
|
|
91326
91612
|
const session = this.#session(sessionId);
|
|
91327
91613
|
const allocatedPosition = this.#allocatedPositionBySession.get(sessionId) ?? 9999;
|
|
91328
91614
|
if (allocatedPosition === Number.MAX_SAFE_INTEGER) {
|
|
@@ -91335,7 +91621,8 @@ var init_session_event_store = __esm({
|
|
|
91335
91621
|
session.sessionGenerationId,
|
|
91336
91622
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
91337
91623
|
position,
|
|
91338
|
-
event
|
|
91624
|
+
event,
|
|
91625
|
+
recordedAt
|
|
91339
91626
|
);
|
|
91340
91627
|
session.apply(recorded, this.#resolver(session));
|
|
91341
91628
|
return recorded;
|
|
@@ -91376,12 +91663,14 @@ var init_session_event_store = __esm({
|
|
|
91376
91663
|
};
|
|
91377
91664
|
};
|
|
91378
91665
|
CachedSessionEventStore = class {
|
|
91666
|
+
#terminalOutcomes;
|
|
91379
91667
|
#cacheTable;
|
|
91380
91668
|
#eventIds;
|
|
91381
91669
|
#liveEventPositions;
|
|
91382
91670
|
#sessions = /* @__PURE__ */ new Map();
|
|
91383
91671
|
#flushSchedule = { kind: "idle" };
|
|
91384
|
-
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator()) {
|
|
91672
|
+
constructor(cacheTable, liveEventPositions, eventIds = new InMemorySessionEventIdAllocator(), terminalOutcomes = () => []) {
|
|
91673
|
+
this.#terminalOutcomes = terminalOutcomes;
|
|
91385
91674
|
this.#eventIds = eventIds;
|
|
91386
91675
|
this.#liveEventPositions = liveEventPositions;
|
|
91387
91676
|
this.#cacheTable = cacheTable;
|
|
@@ -91414,7 +91703,7 @@ var init_session_event_store = __esm({
|
|
|
91414
91703
|
}
|
|
91415
91704
|
return resolved;
|
|
91416
91705
|
};
|
|
91417
|
-
append = (sessionId, event) => {
|
|
91706
|
+
append = (sessionId, event, recordedAt) => {
|
|
91418
91707
|
if (this.#flushSchedule.kind === "closed") {
|
|
91419
91708
|
throw new Error("The V2 Session event store is closed");
|
|
91420
91709
|
}
|
|
@@ -91425,7 +91714,8 @@ var init_session_event_store = __esm({
|
|
|
91425
91714
|
session.sessionGenerationId,
|
|
91426
91715
|
this.#eventIds.allocate(sessionId, session.sessionGenerationId),
|
|
91427
91716
|
position,
|
|
91428
|
-
event
|
|
91717
|
+
event,
|
|
91718
|
+
recordedAt
|
|
91429
91719
|
);
|
|
91430
91720
|
session.apply(recorded, this.#resolver(sessionId, session));
|
|
91431
91721
|
this.#sessions.set(sessionId, session);
|
|
@@ -91514,6 +91804,9 @@ var init_session_event_store = __esm({
|
|
|
91514
91804
|
this.#deletePersisted(sessionId, previous?.sessionGenerationId);
|
|
91515
91805
|
const sessionGenerationId = randomUUID12();
|
|
91516
91806
|
this.#sessions.set(sessionId, new SessionEvents(sessionGenerationId));
|
|
91807
|
+
for (const { event, recordedAt } of this.#terminalOutcomes(sessionId)) {
|
|
91808
|
+
this.append(sessionId, event, recordedAt);
|
|
91809
|
+
}
|
|
91517
91810
|
};
|
|
91518
91811
|
materializedEventCount = (sessionId) => this.#sessions.get(sessionId)?.materializedCount ?? 0;
|
|
91519
91812
|
close = () => {
|
|
@@ -91634,7 +91927,7 @@ var init_prompt_content = __esm({
|
|
|
91634
91927
|
});
|
|
91635
91928
|
|
|
91636
91929
|
// src/acp/connection/agent-connection.ts
|
|
91637
|
-
import { spawn as
|
|
91930
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
91638
91931
|
import { ndJsonStream as ndJsonStream3, RequestError as RequestError9 } from "@agentclientprotocol/sdk";
|
|
91639
91932
|
function requestErrorMessage(error62) {
|
|
91640
91933
|
const fallback = truncate2(error62.message, 500);
|
|
@@ -91753,7 +92046,7 @@ var init_agent_connection = __esm({
|
|
|
91753
92046
|
return;
|
|
91754
92047
|
}
|
|
91755
92048
|
const launch = executableLaunch2(agent.adapterPath, agent.arguments);
|
|
91756
|
-
const child =
|
|
92049
|
+
const child = spawn10(launch.command, [...launch.arguments], {
|
|
91757
92050
|
cwd,
|
|
91758
92051
|
...platformSpawnOptions,
|
|
91759
92052
|
env: { ...process.env, ...agent.environment },
|
|
@@ -93107,6 +93400,19 @@ var init_agent_turn = __esm({
|
|
|
93107
93400
|
|
|
93108
93401
|
// src/session/live/session-restore.ts
|
|
93109
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
|
+
}
|
|
93110
93416
|
async function restoreSession(session, signal, recovery, origin) {
|
|
93111
93417
|
if (origin !== void 0) {
|
|
93112
93418
|
session.setSessionTitle(origin.title);
|
|
@@ -93173,6 +93479,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93173
93479
|
}
|
|
93174
93480
|
session.setPrompted(true);
|
|
93175
93481
|
session.setRestored(true);
|
|
93482
|
+
if (recovery.kind === "execution-only") {
|
|
93483
|
+
session.startExecutionOnlyCapture();
|
|
93484
|
+
}
|
|
93176
93485
|
lifecycleResponse2 = forked;
|
|
93177
93486
|
} else if (stored instanceof FoundStoredSession && stored.session.agentId === session.agentId && stored.session.cwd === session.cwd && arraysEqual(stored.session.additionalDirectories, session.additionalDirectories)) {
|
|
93178
93487
|
session.selectNativeSession(stored.session.nativeSessionId);
|
|
@@ -93191,6 +93500,37 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93191
93500
|
"session-load",
|
|
93192
93501
|
async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
|
|
93193
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();
|
|
93194
93534
|
} else if (session.capabilities.resumeSession) {
|
|
93195
93535
|
lifecycleResponse2 = await session.metrics.measure(
|
|
93196
93536
|
"session-resume",
|
|
@@ -93250,6 +93590,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
93250
93590
|
);
|
|
93251
93591
|
session.selectNativeSession(created.sessionId);
|
|
93252
93592
|
session.setNativeHistoryOwnership({ kind: "fresh-session" });
|
|
93593
|
+
if (recovery.kind === "execution-only") {
|
|
93594
|
+
session.startExecutionOnlyCapture();
|
|
93595
|
+
}
|
|
93253
93596
|
lifecycleResponse2 = created;
|
|
93254
93597
|
}
|
|
93255
93598
|
session.restrictSessionCapabilities(lifecycleResponse2);
|
|
@@ -93565,6 +93908,16 @@ var init_agent_session = __esm({
|
|
|
93565
93908
|
}
|
|
93566
93909
|
await this.#completedHistory(signal, "ACP agent exited while loading history");
|
|
93567
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
|
+
};
|
|
93568
93921
|
loadHistoryEvents = async (eventLimit, cursor, signal) => {
|
|
93569
93922
|
if (!this.#capabilities.loadSession) {
|
|
93570
93923
|
throw new AcpExecutionError(
|
|
@@ -93815,7 +94168,7 @@ var init_agent_session = __esm({
|
|
|
93815
94168
|
response: {}
|
|
93816
94169
|
};
|
|
93817
94170
|
}
|
|
93818
|
-
if (this.#capabilities.loadSession) {
|
|
94171
|
+
if (this.#capabilities.loadSession && this.#sessionLoad.kind !== "execution-only") {
|
|
93819
94172
|
await this.#completedHistory(options.signal, "ACP agent exited while loading history before a prompt");
|
|
93820
94173
|
}
|
|
93821
94174
|
const prompt = this.buildPrompt(options);
|
|
@@ -94014,14 +94367,14 @@ var init_agent_session = __esm({
|
|
|
94014
94367
|
onElicitationComplete = (notification) => this.#interactions.onElicitationComplete(notification);
|
|
94015
94368
|
onUpdate = (notification) => this.#updates.receive(notification);
|
|
94016
94369
|
recordControlEvent = async (event) => {
|
|
94017
|
-
if (this.#sessionLoad.kind !== "loaded") {
|
|
94370
|
+
if (this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
94018
94371
|
return false;
|
|
94019
94372
|
}
|
|
94020
94373
|
await this.recordLifecycleEvent(event);
|
|
94021
94374
|
return true;
|
|
94022
94375
|
};
|
|
94023
94376
|
recordLifecycleEvent = async (event) => {
|
|
94024
|
-
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded") {
|
|
94377
|
+
if (event.type !== "lifecycle-metadata" || this.#sessionLoad.kind !== "loaded" && this.#sessionLoad.kind !== "execution-only") {
|
|
94025
94378
|
return;
|
|
94026
94379
|
}
|
|
94027
94380
|
const liveEvent2 = this.#sessionLoad.history.recordLifecycle(event);
|
|
@@ -94042,7 +94395,7 @@ var init_agent_session = __esm({
|
|
|
94042
94395
|
const rawUpdate = decodeAcpSessionUpdate(JSON.stringify(externalized.event));
|
|
94043
94396
|
if (this.#sessionLoad.kind === "capturing") {
|
|
94044
94397
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
94045
|
-
} else if (this.#sessionLoad.kind === "loaded") {
|
|
94398
|
+
} else if (this.#sessionLoad.kind === "loaded" || this.#sessionLoad.kind === "execution-only") {
|
|
94046
94399
|
const onSessionEvent = this.#getObserver().onSessionEvent;
|
|
94047
94400
|
await this.#sessionLoad.history.record(update, rawUpdate, async (liveEvent2) => {
|
|
94048
94401
|
await onSessionEvent?.(liveEvent2);
|
|
@@ -95029,13 +95382,14 @@ var init_session_manager = __esm({
|
|
|
95029
95382
|
}
|
|
95030
95383
|
async #replaceExecutionPreparation(existing, options) {
|
|
95031
95384
|
const desiredConfigOptions = existing.prepared().configOptions;
|
|
95385
|
+
const recovery = options.recovery ?? { kind: "interactive-only" };
|
|
95032
95386
|
return await this.#executionProcesses.prepare(options.sessionId, async () => {
|
|
95033
95387
|
await this.#retireSessionProcess(options.sessionId, existing, async () => await existing.close());
|
|
95034
95388
|
const runtime = await this.#startRetainedSessionProcess(
|
|
95035
95389
|
options,
|
|
95036
95390
|
async () => await AgentSession.start(
|
|
95037
95391
|
options,
|
|
95038
|
-
|
|
95392
|
+
recovery,
|
|
95039
95393
|
() => this.#observer,
|
|
95040
95394
|
this.#store,
|
|
95041
95395
|
unmeasuredOperationMetrics,
|
|
@@ -95213,6 +95567,7 @@ var init_session_manager = __esm({
|
|
|
95213
95567
|
});
|
|
95214
95568
|
});
|
|
95215
95569
|
prepareExecutionSession = async (options) => this.#operations.run(options, async (options2) => {
|
|
95570
|
+
const recovery = options2.recovery ?? { kind: "interactive-only" };
|
|
95216
95571
|
this.#assertOpen(options2.sessionId);
|
|
95217
95572
|
const pending = this.#executionProcesses.pending(options2.sessionId);
|
|
95218
95573
|
if (pending !== void 0) {
|
|
@@ -95221,7 +95576,7 @@ var init_session_manager = __esm({
|
|
|
95221
95576
|
}
|
|
95222
95577
|
const existing = this.#executionProcesses.get(options2.sessionId);
|
|
95223
95578
|
if (existing === void 0) {
|
|
95224
|
-
return (await this.#startPreparation(options2,
|
|
95579
|
+
return (await this.#startPreparation(options2, recovery)).prepared();
|
|
95225
95580
|
}
|
|
95226
95581
|
if (!existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
95227
95582
|
throw new AcpExecutionError(
|
|
@@ -95231,6 +95586,9 @@ var init_session_manager = __esm({
|
|
|
95231
95586
|
);
|
|
95232
95587
|
}
|
|
95233
95588
|
if (existing.usesEnvironment(options2.agent.environment)) {
|
|
95589
|
+
if (recovery.kind === "execution-only") {
|
|
95590
|
+
existing.startExecutionOnlyCapture();
|
|
95591
|
+
}
|
|
95234
95592
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
95235
95593
|
return existing.prepared();
|
|
95236
95594
|
}
|
|
@@ -95525,10 +95883,13 @@ var init_session_manager = __esm({
|
|
|
95525
95883
|
"session_identity_mismatch"
|
|
95526
95884
|
);
|
|
95527
95885
|
}
|
|
95886
|
+
if (options2.recovery?.kind === "execution-only") {
|
|
95887
|
+
existing.startExecutionOnlyCapture();
|
|
95888
|
+
}
|
|
95528
95889
|
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
95529
95890
|
return existing;
|
|
95530
95891
|
}
|
|
95531
|
-
await this
|
|
95892
|
+
await this.#prepareSession(options2, options2.recovery ?? { kind: "interactive-only" }, "reopen");
|
|
95532
95893
|
const started = this.#executionProcesses.get(options2.sessionId);
|
|
95533
95894
|
if (started === void 0) {
|
|
95534
95895
|
throw new AcpExecutionError("ACP session did not start");
|
|
@@ -96086,6 +96447,7 @@ var PromptLifecycle;
|
|
|
96086
96447
|
var init_prompt_lifecycle = __esm({
|
|
96087
96448
|
"src/session/prompt/prompt-lifecycle.ts"() {
|
|
96088
96449
|
"use strict";
|
|
96450
|
+
init_protocol();
|
|
96089
96451
|
PromptLifecycle = class {
|
|
96090
96452
|
#sink;
|
|
96091
96453
|
#terminal = /* @__PURE__ */ new Map();
|
|
@@ -96167,6 +96529,13 @@ var init_prompt_lifecycle = __esm({
|
|
|
96167
96529
|
}
|
|
96168
96530
|
this.#queued.delete(commandId);
|
|
96169
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
|
+
};
|
|
96170
96539
|
queueChanged = async (sessionId) => {
|
|
96171
96540
|
await this.#recordLifecycle(sessionId, {
|
|
96172
96541
|
type: "lifecycle-metadata",
|
|
@@ -96200,7 +96569,7 @@ var init_prompt_lifecycle = __esm({
|
|
|
96200
96569
|
type: "lifecycle-metadata",
|
|
96201
96570
|
payload: { kind: "prompt.failed-before-start", commandId, code, message }
|
|
96202
96571
|
});
|
|
96203
|
-
if (!recorded) {
|
|
96572
|
+
if (!recorded || code === SESSION_CLOSED_ERROR_CODE) {
|
|
96204
96573
|
this.#sink.publishOperationFailure(sessionId, commandId, code, message);
|
|
96205
96574
|
}
|
|
96206
96575
|
};
|
|
@@ -96225,21 +96594,154 @@ var MAX_TERMINAL_RECEIPTS, ExecutionReceipts;
|
|
|
96225
96594
|
var init_execution_receipts = __esm({
|
|
96226
96595
|
"src/session/turn/execution-receipts.ts"() {
|
|
96227
96596
|
"use strict";
|
|
96597
|
+
init_protocol();
|
|
96598
|
+
init_zod();
|
|
96228
96599
|
MAX_TERMINAL_RECEIPTS = 1024;
|
|
96229
96600
|
ExecutionReceipts = class {
|
|
96230
96601
|
#executions = /* @__PURE__ */ new Map();
|
|
96602
|
+
#recoveredCommands = /* @__PURE__ */ new Set();
|
|
96231
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
|
+
});
|
|
96232
96710
|
claimExecution = (commandId, sessionId, commandJson) => {
|
|
96233
96711
|
const commandHash = createHash7("sha256").update(commandJson).digest("hex");
|
|
96234
|
-
|
|
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
|
+
}
|
|
96235
96724
|
if (existing !== void 0) {
|
|
96236
96725
|
if (existing.sessionId !== sessionId || existing.commandHash !== commandHash) {
|
|
96237
96726
|
return { kind: "conflict" };
|
|
96238
96727
|
}
|
|
96239
|
-
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
|
+
};
|
|
96240
96735
|
}
|
|
96241
96736
|
const attemptId = randomUUID14();
|
|
96242
|
-
this.#
|
|
96737
|
+
this.#save(commandId, {
|
|
96738
|
+
attemptId,
|
|
96739
|
+
commandHash,
|
|
96740
|
+
sessionId,
|
|
96741
|
+
state: "dispatching",
|
|
96742
|
+
started: false,
|
|
96743
|
+
outcome: null
|
|
96744
|
+
});
|
|
96243
96745
|
return { attemptId, commandId, kind: "accepted", state: "dispatching" };
|
|
96244
96746
|
};
|
|
96245
96747
|
transitionExecution = (commandId, state) => {
|
|
@@ -96254,16 +96756,13 @@ var init_execution_receipts = __esm({
|
|
|
96254
96756
|
if (!allowed) {
|
|
96255
96757
|
throw new Error("The runtime execution transition is invalid");
|
|
96256
96758
|
}
|
|
96257
|
-
|
|
96258
|
-
|
|
96259
|
-
|
|
96260
|
-
|
|
96261
|
-
(this.#terminalCountBySession.get(current.sessionId) ?? 0) + 1
|
|
96262
|
-
);
|
|
96263
|
-
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 });
|
|
96264
96763
|
}
|
|
96265
96764
|
};
|
|
96266
|
-
/**
|
|
96765
|
+
/** Only commands without a terminal result can still be cancelled. */
|
|
96267
96766
|
findUnsettledAttemptId = (commandId, sessionId) => {
|
|
96268
96767
|
const receipt = this.#executions.get(commandId);
|
|
96269
96768
|
return receipt?.sessionId === sessionId && !isTerminal(receipt.state) ? receipt.attemptId : null;
|
|
@@ -96274,7 +96773,9 @@ var init_execution_receipts = __esm({
|
|
|
96274
96773
|
};
|
|
96275
96774
|
close = () => {
|
|
96276
96775
|
this.#executions.clear();
|
|
96776
|
+
this.#recoveredCommands.clear();
|
|
96277
96777
|
this.#terminalCountBySession.clear();
|
|
96778
|
+
this.#activeCount = 0;
|
|
96278
96779
|
};
|
|
96279
96780
|
pruneTerminalReceipts = (sessionId) => {
|
|
96280
96781
|
if ((this.#terminalCountBySession.get(sessionId) ?? 0) <= MAX_TERMINAL_RECEIPTS) {
|
|
@@ -96283,6 +96784,8 @@ var init_execution_receipts = __esm({
|
|
|
96283
96784
|
for (const [commandId, receipt] of this.#executions) {
|
|
96284
96785
|
if (receipt.sessionId === sessionId && isTerminal(receipt.state)) {
|
|
96285
96786
|
this.#executions.delete(commandId);
|
|
96787
|
+
this.#recoveredCommands.delete(commandId);
|
|
96788
|
+
this.#table?.remove(commandId);
|
|
96286
96789
|
const remaining = (this.#terminalCountBySession.get(sessionId) ?? 1) - 1;
|
|
96287
96790
|
if (remaining > 0) {
|
|
96288
96791
|
this.#terminalCountBySession.set(sessionId, remaining);
|
|
@@ -96833,10 +97336,14 @@ function buildSessionLayer(options) {
|
|
|
96833
97336
|
const databases = channelSessionDatabasePaths(stateDirectory, channelId);
|
|
96834
97337
|
const sessionDatabase = openAcpSessionDatabase(databases.sessions);
|
|
96835
97338
|
let events;
|
|
97339
|
+
let operations;
|
|
96836
97340
|
try {
|
|
97341
|
+
operations = new ExecutionReceipts(new ExecutionReceiptTable(sessionDatabase), options.onExecutionCountChange);
|
|
96837
97342
|
events = new CachedSessionEventStore(
|
|
96838
97343
|
new SessionEventCacheTable(openSessionEventCacheDatabase(databases.events)),
|
|
96839
|
-
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase))
|
|
97344
|
+
new SqliteSessionLiveEventPosition(new LiveEventPositionTable(sessionDatabase)),
|
|
97345
|
+
void 0,
|
|
97346
|
+
(sessionId) => operations.terminalOutcomes(sessionId)
|
|
96840
97347
|
);
|
|
96841
97348
|
} catch (error62) {
|
|
96842
97349
|
sessionDatabase.close();
|
|
@@ -96844,11 +97351,13 @@ function buildSessionLayer(options) {
|
|
|
96844
97351
|
}
|
|
96845
97352
|
const sessionStore = new SqliteSessionStore(new AcpSessionTable(sessionDatabase), events);
|
|
96846
97353
|
const externalContent = new LocalExternalContentStore(stateDirectory);
|
|
96847
|
-
const operations = new ExecutionReceipts();
|
|
96848
97354
|
const activeSessions = new SessionTurns(operations, options.turnActivity);
|
|
96849
97355
|
const directories = new WorkspaceDirectoryService(bindingId, defaultWorkspace);
|
|
96850
97356
|
const manager = new SessionManager2({
|
|
96851
|
-
observer: new SessionLayerObserver((event) =>
|
|
97357
|
+
observer: new SessionLayerObserver((event) => {
|
|
97358
|
+
operations.recordOutcome(event);
|
|
97359
|
+
eventProjection.record(event);
|
|
97360
|
+
}, sink.publishInfo),
|
|
96852
97361
|
store: sessionStore,
|
|
96853
97362
|
adapters: harnessAdapters,
|
|
96854
97363
|
sessionIdentity: "native",
|
|
@@ -96869,7 +97378,15 @@ function buildSessionLayer(options) {
|
|
|
96869
97378
|
});
|
|
96870
97379
|
const eventProjection = new PromptLifecycle(
|
|
96871
97380
|
sink,
|
|
96872
|
-
(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
|
+
},
|
|
96873
97390
|
activeSessions.recordSessionEvent
|
|
96874
97391
|
);
|
|
96875
97392
|
const nativeSessions = new NativeSessionService(
|
|
@@ -96892,7 +97409,13 @@ function buildSessionLayer(options) {
|
|
|
96892
97409
|
);
|
|
96893
97410
|
})
|
|
96894
97411
|
);
|
|
97412
|
+
const recoveredEvents = operations.recover().map(({ sessionId, event, recordedAt }) => events.append(sessionId, event, recordedAt));
|
|
96895
97413
|
return {
|
|
97414
|
+
publishRecoveredOutcomes: () => {
|
|
97415
|
+
for (const event of recoveredEvents) {
|
|
97416
|
+
sink.publish(event);
|
|
97417
|
+
}
|
|
97418
|
+
},
|
|
96896
97419
|
activeSessions,
|
|
96897
97420
|
directories,
|
|
96898
97421
|
eventProjection,
|
|
@@ -96910,6 +97433,7 @@ var init_session_layer = __esm({
|
|
|
96910
97433
|
init_registry();
|
|
96911
97434
|
init_content_externalizer();
|
|
96912
97435
|
init_acp_session_table();
|
|
97436
|
+
init_execution_receipt_table();
|
|
96913
97437
|
init_live_event_position_table();
|
|
96914
97438
|
init_session_event_cache_table();
|
|
96915
97439
|
init_local_databases();
|
|
@@ -98790,12 +99314,14 @@ async function executePrompt({
|
|
|
98790
99314
|
const appliedSettings = command.sessionConfigurations === void 0 ? void 0 : agentForSessionConfiguration(agent, command.sessionConfigurations);
|
|
98791
99315
|
const executionAgent = appliedSettings?.agent ?? agent;
|
|
98792
99316
|
const sessionConfigurations = appliedSettings?.sessionConfigurations;
|
|
99317
|
+
const recovery = command.historyPolicy === SessionHistoryPolicy.ExecutionOnly ? { kind: "execution-only" } : { kind: "interactive-only" };
|
|
98793
99318
|
const preparation = {
|
|
98794
99319
|
additionalDirectories: resolved.additionalDirectories,
|
|
98795
99320
|
agent: executionAgent,
|
|
98796
99321
|
cwd: resolved.cwd,
|
|
98797
99322
|
sessionId: command.sessionId,
|
|
98798
|
-
signal
|
|
99323
|
+
signal,
|
|
99324
|
+
recovery
|
|
98799
99325
|
};
|
|
98800
99326
|
let prepared = await sessions.prepareExecutionSession(preparation);
|
|
98801
99327
|
if (command.sessionConfigurations !== void 0) {
|
|
@@ -98864,7 +99390,8 @@ async function executePrompt({
|
|
|
98864
99390
|
resources: attachments.resources,
|
|
98865
99391
|
sessionId: command.sessionId,
|
|
98866
99392
|
signal,
|
|
98867
|
-
targetCommandId: command.targetCommandId
|
|
99393
|
+
targetCommandId: command.targetCommandId,
|
|
99394
|
+
recovery
|
|
98868
99395
|
});
|
|
98869
99396
|
stopReason = result.stopReason;
|
|
98870
99397
|
}
|
|
@@ -99062,6 +99589,12 @@ var init_prompt2 = __esm({
|
|
|
99062
99589
|
return;
|
|
99063
99590
|
}
|
|
99064
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
|
+
}
|
|
99065
99598
|
return;
|
|
99066
99599
|
}
|
|
99067
99600
|
const turn = context.sessionTurns.start(message, receipt.attemptId);
|
|
@@ -100268,7 +100801,8 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100268
100801
|
resolveAgent: (agentId, resolveSignal) => resolveCatalogAgent(config2, agentId, resolveSignal),
|
|
100269
100802
|
sink: publisher,
|
|
100270
100803
|
stateDirectory: config2.localContext.stateDirectory,
|
|
100271
|
-
timer
|
|
100804
|
+
timer,
|
|
100805
|
+
onExecutionCountChange: options.onExecutionCountChange ?? (() => void 0)
|
|
100272
100806
|
});
|
|
100273
100807
|
const {
|
|
100274
100808
|
activeSessions,
|
|
@@ -100338,6 +100872,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100338
100872
|
reportUpgradeAvailability,
|
|
100339
100873
|
diagnostics,
|
|
100340
100874
|
onConnected: () => {
|
|
100875
|
+
layer.publishRecoveredOutcomes();
|
|
100341
100876
|
if (catalogPublished) {
|
|
100342
100877
|
options.onConnectionStatus?.("online");
|
|
100343
100878
|
}
|
|
@@ -100360,6 +100895,7 @@ async function runRuntime(config2, parentSignal, timer = systemTimer, options =
|
|
|
100360
100895
|
}
|
|
100361
100896
|
} finally {
|
|
100362
100897
|
shutdown.abort();
|
|
100898
|
+
operations.beginShutdown();
|
|
100363
100899
|
await activeSessions.close();
|
|
100364
100900
|
try {
|
|
100365
100901
|
await catalogPublication;
|
|
@@ -100454,6 +100990,10 @@ var init_engine = __esm({
|
|
|
100454
100990
|
MobiusRuntimeEngine = class {
|
|
100455
100991
|
#config;
|
|
100456
100992
|
#options;
|
|
100993
|
+
#activeTurnCount = 0;
|
|
100994
|
+
get activeTurnCount() {
|
|
100995
|
+
return this.#activeTurnCount;
|
|
100996
|
+
}
|
|
100457
100997
|
#state = new IdleMobiusRuntimeState();
|
|
100458
100998
|
constructor(config2, options = {}) {
|
|
100459
100999
|
validateRuntimeConfiguration(config2);
|
|
@@ -100469,11 +101009,15 @@ var init_engine = __esm({
|
|
|
100469
101009
|
try {
|
|
100470
101010
|
await runRuntime(this.#config, signal, void 0, {
|
|
100471
101011
|
...this.#options.turnActivity === void 0 ? {} : { turnActivity: this.#options.turnActivity },
|
|
101012
|
+
onExecutionCountChange: (count) => {
|
|
101013
|
+
this.#activeTurnCount = count;
|
|
101014
|
+
},
|
|
100472
101015
|
...this.#options.onConnectionStatus === void 0 ? {} : { onConnectionStatus: this.#options.onConnectionStatus },
|
|
100473
101016
|
...this.#options.reportUpgradeAvailability === void 0 ? {} : { reportUpgradeAvailability: this.#options.reportUpgradeAvailability },
|
|
100474
101017
|
...this.#options.processLogsDirectory === void 0 ? {} : { processLogsDirectory: this.#options.processLogsDirectory }
|
|
100475
101018
|
});
|
|
100476
101019
|
} finally {
|
|
101020
|
+
this.#activeTurnCount = 0;
|
|
100477
101021
|
this.#state = new FinishedMobiusRuntimeState();
|
|
100478
101022
|
}
|
|
100479
101023
|
};
|