@moxt-ai/mobius 0.0.182 → 0.0.184
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/agent-connection.d.ts.map +1 -1
- package/dist/acp/agent-connection.js +14 -2
- package/dist/acp/agent-connection.js.map +1 -1
- package/dist/acp/agent-runtime-manager.d.ts +2 -1
- package/dist/acp/agent-runtime-manager.d.ts.map +1 -1
- package/dist/acp/agent-runtime-manager.js +46 -36
- package/dist/acp/agent-runtime-manager.js.map +1 -1
- package/dist/acp/agent-session.d.ts +4 -3
- package/dist/acp/agent-session.d.ts.map +1 -1
- package/dist/acp/agent-session.js +15 -3
- package/dist/acp/agent-session.js.map +1 -1
- package/dist/acp/codex/app-server-protocol.d.ts +4 -0
- package/dist/acp/codex/app-server-protocol.d.ts.map +1 -1
- package/dist/acp/codex/app-server-protocol.js +2 -0
- package/dist/acp/codex/app-server-protocol.js.map +1 -1
- package/dist/acp/codex/items.d.ts.map +1 -1
- package/dist/acp/codex/items.js +35 -11
- package/dist/acp/codex/items.js.map +1 -1
- package/dist/acp/session-contracts.d.ts +5 -0
- package/dist/acp/session-contracts.d.ts.map +1 -1
- package/dist/acp/session-contracts.js.map +1 -1
- package/dist/cli.js +177 -83
- package/dist/cli.js.map +4 -4
- package/dist/daemon-session-commands.d.ts.map +1 -1
- package/dist/daemon-session-commands.js +6 -4
- package/dist/daemon-session-commands.js.map +1 -1
- package/dist/external-content/acp-content-externalizer.d.ts.map +1 -1
- package/dist/external-content/acp-content-externalizer.js +13 -0
- package/dist/external-content/acp-content-externalizer.js.map +1 -1
- package/dist/index.js +171 -79
- package/dist/index.js.map +3 -3
- package/dist/runtime.js +174 -82
- package/dist/runtime.js.map +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3381,7 +3381,7 @@ var program = new Command();
|
|
|
3381
3381
|
// package.json
|
|
3382
3382
|
var package_default = {
|
|
3383
3383
|
name: "@moxt-ai/mobius",
|
|
3384
|
-
version: "0.0.
|
|
3384
|
+
version: "0.0.184",
|
|
3385
3385
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
3386
3386
|
type: "module",
|
|
3387
3387
|
bin: {
|
|
@@ -4975,6 +4975,9 @@ function sessionFailureMeta(failure2) {
|
|
|
4975
4975
|
// src/acp/codex/app-server-client.ts
|
|
4976
4976
|
import { spawn as spawn2 } from "node:child_process";
|
|
4977
4977
|
|
|
4978
|
+
// src/acp/codex/app-server-protocol.ts
|
|
4979
|
+
import { isAbsolute as isAbsolute2 } from "node:path";
|
|
4980
|
+
|
|
4978
4981
|
// ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.js
|
|
4979
4982
|
var external_exports = {};
|
|
4980
4983
|
__export(external_exports, {
|
|
@@ -24714,6 +24717,7 @@ var imageGenerationItemSchema = external_exports.object({
|
|
|
24714
24717
|
});
|
|
24715
24718
|
var threadItemSchema = external_exports.discriminatedUnion("type", [
|
|
24716
24719
|
imageGenerationItemSchema,
|
|
24720
|
+
external_exports.object({ type: external_exports.literal("imageView"), id: boundedText(256), path: boundedText(32768).refine(isAbsolute2) }),
|
|
24717
24721
|
external_exports.object({
|
|
24718
24722
|
id: boundedText(256),
|
|
24719
24723
|
text: boundedText(1e6),
|
|
@@ -25138,6 +25142,7 @@ var CodexAppServerClient = class {
|
|
|
25138
25142
|
};
|
|
25139
25143
|
|
|
25140
25144
|
// src/acp/codex/items.ts
|
|
25145
|
+
import { pathToFileURL } from "node:url";
|
|
25141
25146
|
var TOOL_OUTPUT_CHARACTER_LIMIT = 32768;
|
|
25142
25147
|
var TITLE_CHARACTER_LIMIT = 500;
|
|
25143
25148
|
function truncate2(value, limit) {
|
|
@@ -25159,6 +25164,14 @@ function textContent(text2) {
|
|
|
25159
25164
|
const block = { text: truncate2(text2, TOOL_OUTPUT_CHARACTER_LIMIT), type: "text" };
|
|
25160
25165
|
return { content: block, type: "content" };
|
|
25161
25166
|
}
|
|
25167
|
+
function structuredToolText(value) {
|
|
25168
|
+
const result = external_exports.object({ content: external_exports.array(external_exports.unknown()) }).safeParse(value);
|
|
25169
|
+
const items = Array.isArray(value) ? value : result.success ? result.data.content : [];
|
|
25170
|
+
return items.flatMap((item) => {
|
|
25171
|
+
const text2 = external_exports.object({ type: external_exports.enum(["text", "inputText"]), text: external_exports.string() }).safeParse(item);
|
|
25172
|
+
return text2.success ? [textContent(text2.data.text)] : [];
|
|
25173
|
+
});
|
|
25174
|
+
}
|
|
25162
25175
|
function firstLine(value) {
|
|
25163
25176
|
const line = value.split("\n", 1)[0] ?? "";
|
|
25164
25177
|
return line.trim().length > 0 ? line.trim() : value.trim();
|
|
@@ -25179,6 +25192,22 @@ function mcpStatus(status) {
|
|
|
25179
25192
|
return status === "inProgress" ? "in_progress" : status === "completed" ? "completed" : "failed";
|
|
25180
25193
|
}
|
|
25181
25194
|
function presentToolItem(item) {
|
|
25195
|
+
if (item.type === "imageView") {
|
|
25196
|
+
return {
|
|
25197
|
+
content: [
|
|
25198
|
+
{
|
|
25199
|
+
type: "content",
|
|
25200
|
+
content: { type: "image", data: "", mimeType: "", uri: pathToFileURL(item.path).href }
|
|
25201
|
+
}
|
|
25202
|
+
],
|
|
25203
|
+
kind: "read",
|
|
25204
|
+
locations: [{ path: item.path }],
|
|
25205
|
+
rawInput: { path: item.path },
|
|
25206
|
+
rawOutput: null,
|
|
25207
|
+
status: "completed",
|
|
25208
|
+
title: "View image"
|
|
25209
|
+
};
|
|
25210
|
+
}
|
|
25182
25211
|
if (item.type === "imageGeneration") {
|
|
25183
25212
|
const failed = item.failure != null || item.status === "failed";
|
|
25184
25213
|
const content = [];
|
|
@@ -25243,13 +25272,7 @@ function presentToolItem(item) {
|
|
|
25243
25272
|
}
|
|
25244
25273
|
if (item.type === "mcpToolCall") {
|
|
25245
25274
|
const label = `${item.server}/${item.tool}`;
|
|
25246
|
-
const content =
|
|
25247
|
-
if (item.result != null) {
|
|
25248
|
-
content.push(textContent(JSON.stringify(item.result)));
|
|
25249
|
-
}
|
|
25250
|
-
if (item.error != null) {
|
|
25251
|
-
content.push(textContent(JSON.stringify(item.error)));
|
|
25252
|
-
}
|
|
25275
|
+
const content = structuredToolText(item.error ?? item.result);
|
|
25253
25276
|
return {
|
|
25254
25277
|
content,
|
|
25255
25278
|
kind: "other",
|
|
@@ -25262,13 +25285,13 @@ function presentToolItem(item) {
|
|
|
25262
25285
|
}
|
|
25263
25286
|
if (item.type === "dynamicToolCall") {
|
|
25264
25287
|
const label = item.namespace == null ? item.tool : `${item.namespace}/${item.tool}`;
|
|
25265
|
-
const content = (item.contentItems
|
|
25288
|
+
const content = structuredToolText(item.contentItems);
|
|
25266
25289
|
return {
|
|
25267
25290
|
content,
|
|
25268
25291
|
kind: "other",
|
|
25269
25292
|
locations: [],
|
|
25270
25293
|
rawInput: item.arguments ?? null,
|
|
25271
|
-
rawOutput: item.
|
|
25294
|
+
rawOutput: item.contentItems ?? null,
|
|
25272
25295
|
status: mcpStatus(item.status),
|
|
25273
25296
|
title: truncate2(label, TITLE_CHARACTER_LIMIT)
|
|
25274
25297
|
};
|
|
@@ -25281,12 +25304,12 @@ function toolCallUpdate(item, lifecycle) {
|
|
|
25281
25304
|
return null;
|
|
25282
25305
|
}
|
|
25283
25306
|
return {
|
|
25284
|
-
content: [...presentation.content],
|
|
25307
|
+
content: item.type === "imageView" && lifecycle === "started" ? [] : [...presentation.content],
|
|
25285
25308
|
kind: presentation.kind,
|
|
25286
25309
|
locations: [...presentation.locations],
|
|
25287
25310
|
rawInput: presentation.rawInput,
|
|
25288
25311
|
rawOutput: presentation.rawOutput,
|
|
25289
|
-
status: lifecycle === "completed" && presentation.status === "in_progress" ? "completed" : presentation.status,
|
|
25312
|
+
status: item.type === "imageView" && lifecycle === "started" ? "in_progress" : lifecycle === "completed" && presentation.status === "in_progress" ? "completed" : presentation.status,
|
|
25290
25313
|
title: presentation.title,
|
|
25291
25314
|
toolCallId: item.id
|
|
25292
25315
|
};
|
|
@@ -26510,12 +26533,12 @@ var AgentProbeError = class extends Error {
|
|
|
26510
26533
|
};
|
|
26511
26534
|
|
|
26512
26535
|
// src/agent-catalog/agents/resolve-user-local-executable.ts
|
|
26513
|
-
import { isAbsolute as
|
|
26536
|
+
import { isAbsolute as isAbsolute3, join as join4 } from "node:path";
|
|
26514
26537
|
async function resolveUserLocalExecutable(executableName, context) {
|
|
26515
26538
|
context.signal.throwIfAborted();
|
|
26516
26539
|
const platform = context.platform ?? process.platform;
|
|
26517
26540
|
const homeDirectory = context.environment["HOME"];
|
|
26518
|
-
if (platform === "win32" || homeDirectory === void 0 || !
|
|
26541
|
+
if (platform === "win32" || homeDirectory === void 0 || !isAbsolute3(homeDirectory)) {
|
|
26519
26542
|
return [];
|
|
26520
26543
|
}
|
|
26521
26544
|
const executable = await resolveExecutablePath(join4(homeDirectory, ".local", "bin", executableName), platform);
|
|
@@ -26608,7 +26631,7 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26608
26631
|
|
|
26609
26632
|
// src/agent-catalog/agents/deepseek-harness-agent.ts
|
|
26610
26633
|
import { mkdir as mkdir2, realpath as realpath3, stat as stat3, writeFile } from "node:fs/promises";
|
|
26611
|
-
import { isAbsolute as
|
|
26634
|
+
import { isAbsolute as isAbsolute4, join as join6, normalize } from "node:path";
|
|
26612
26635
|
|
|
26613
26636
|
// src/agent-installation/deepseek-managed-package.ts
|
|
26614
26637
|
var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
|
|
@@ -26643,7 +26666,7 @@ var DEEPSEEK_HARNESS_IMAGE_PROMPT_PATCH = `# Managed by Mobius: pin the ACP brid
|
|
|
26643
26666
|
model: deepseek-v4-flash-vision-exp
|
|
26644
26667
|
`;
|
|
26645
26668
|
async function prepareAgentHome(path3, imagePrompts) {
|
|
26646
|
-
if (!
|
|
26669
|
+
if (!isAbsolute4(path3) || normalize(path3) !== path3) {
|
|
26647
26670
|
throw new AgentProbeError("agent_environment_invalid", "The configured Agent home is invalid");
|
|
26648
26671
|
}
|
|
26649
26672
|
try {
|
|
@@ -26775,7 +26798,7 @@ var GeminiCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26775
26798
|
|
|
26776
26799
|
// src/agent-catalog/agents/grok-build-agent.ts
|
|
26777
26800
|
import { realpath as realpath4 } from "node:fs/promises";
|
|
26778
|
-
import { isAbsolute as
|
|
26801
|
+
import { isAbsolute as isAbsolute5, join as join7, relative as relative2, sep as sep2 } from "node:path";
|
|
26779
26802
|
import {
|
|
26780
26803
|
RequestError
|
|
26781
26804
|
} from "@agentclientprotocol/sdk";
|
|
@@ -26841,7 +26864,7 @@ function grokBuildManagedPackage(platform, architecture) {
|
|
|
26841
26864
|
// src/agent-catalog/agents/grok-build-agent.ts
|
|
26842
26865
|
function isContainedPath2(root, candidate) {
|
|
26843
26866
|
const difference = relative2(root, candidate);
|
|
26844
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !
|
|
26867
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute5(difference);
|
|
26845
26868
|
}
|
|
26846
26869
|
var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
26847
26870
|
adapterVersion = GROK_BUILD_MANAGED_VERSION;
|
|
@@ -26990,7 +27013,7 @@ import { join as join9 } from "node:path";
|
|
|
26990
27013
|
import { createHash } from "node:crypto";
|
|
26991
27014
|
import { createReadStream } from "node:fs";
|
|
26992
27015
|
import { chmod, copyFile, mkdir as mkdir3, mkdtemp as mkdtemp2, open as open3, realpath as realpath5, rename as rename2, rm as rm2, stat as stat4, writeFile as writeFile2 } from "node:fs/promises";
|
|
26993
|
-
import { delimiter as delimiter2, dirname as dirname2, isAbsolute as
|
|
27016
|
+
import { delimiter as delimiter2, dirname as dirname2, isAbsolute as isAbsolute6, join as join8, relative as relative3, sep as sep3 } from "node:path";
|
|
26994
27017
|
|
|
26995
27018
|
// src/agent-installation/verified-download.ts
|
|
26996
27019
|
import { fetch } from "undici";
|
|
@@ -27096,7 +27119,7 @@ function isRecord4(value) {
|
|
|
27096
27119
|
}
|
|
27097
27120
|
function isContainedPath3(root, candidate) {
|
|
27098
27121
|
const difference = relative3(root, candidate);
|
|
27099
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !
|
|
27122
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute6(difference);
|
|
27100
27123
|
}
|
|
27101
27124
|
async function hashFile(path3, signal) {
|
|
27102
27125
|
signal.throwIfAborted();
|
|
@@ -27486,7 +27509,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
|
27486
27509
|
};
|
|
27487
27510
|
|
|
27488
27511
|
// src/agent-catalog/agents/workbuddy-agent.ts
|
|
27489
|
-
import { isAbsolute as
|
|
27512
|
+
import { isAbsolute as isAbsolute7, join as join11 } from "node:path";
|
|
27490
27513
|
|
|
27491
27514
|
// src/agent-installation/workbuddy-managed-package.ts
|
|
27492
27515
|
var WORKBUDDY_MANAGED_VERSION = "2.146.0";
|
|
@@ -27554,7 +27577,7 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
27554
27577
|
}
|
|
27555
27578
|
const requestedPaths = [join11("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
|
|
27556
27579
|
const homeDirectory = context.environment["HOME"];
|
|
27557
|
-
if (homeDirectory !== void 0 &&
|
|
27580
|
+
if (homeDirectory !== void 0 && isAbsolute7(homeDirectory)) {
|
|
27558
27581
|
requestedPaths.unshift(join11(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
|
|
27559
27582
|
}
|
|
27560
27583
|
const executables = [];
|
|
@@ -27919,7 +27942,7 @@ function isAgentVersionSupported(reportedVersion, minimumSupportedVersion) {
|
|
|
27919
27942
|
}
|
|
27920
27943
|
|
|
27921
27944
|
// src/agent-catalog/executable-discovery.ts
|
|
27922
|
-
import { isAbsolute as
|
|
27945
|
+
import { isAbsolute as isAbsolute8, join as join13 } from "node:path";
|
|
27923
27946
|
|
|
27924
27947
|
// src/agent-installation/managed-adapter-installer.ts
|
|
27925
27948
|
import { join as join12 } from "node:path";
|
|
@@ -28024,7 +28047,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
|
|
|
28024
28047
|
async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, resolveManaged, context) {
|
|
28025
28048
|
const override = context.environment[overrideVariable];
|
|
28026
28049
|
if (override !== void 0) {
|
|
28027
|
-
if (override.length === 0 || !
|
|
28050
|
+
if (override.length === 0 || !isAbsolute8(override)) {
|
|
28028
28051
|
return [];
|
|
28029
28052
|
}
|
|
28030
28053
|
const executable = await resolveExecutablePath(override, context.platform);
|
|
@@ -31314,7 +31337,7 @@ import {
|
|
|
31314
31337
|
|
|
31315
31338
|
// src/authorization/local-raster.ts
|
|
31316
31339
|
import { open as open5, readFile as readFile2, realpath as realpath7, stat as stat6 } from "node:fs/promises";
|
|
31317
|
-
import { basename as basename2, isAbsolute as
|
|
31340
|
+
import { basename as basename2, isAbsolute as isAbsolute9, normalize as normalize2 } from "node:path";
|
|
31318
31341
|
import { fileURLToPath } from "node:url";
|
|
31319
31342
|
var MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
|
|
31320
31343
|
var MAX_INLINE_RASTER_BYTES = 3e6;
|
|
@@ -31380,13 +31403,13 @@ function readInlineRaster(data, name2 = "Image") {
|
|
|
31380
31403
|
}
|
|
31381
31404
|
async function resolveCanonicalPath(requested, signal) {
|
|
31382
31405
|
signal.throwIfAborted();
|
|
31383
|
-
if (!
|
|
31406
|
+
if (!isAbsolute9(requested) || requested.includes("\0") || normalize2(requested) !== requested) {
|
|
31384
31407
|
return null;
|
|
31385
31408
|
}
|
|
31386
31409
|
try {
|
|
31387
31410
|
const target = await realpath7(requested);
|
|
31388
31411
|
signal.throwIfAborted();
|
|
31389
|
-
if (!
|
|
31412
|
+
if (!isAbsolute9(target) || normalize2(target) !== target) {
|
|
31390
31413
|
return null;
|
|
31391
31414
|
}
|
|
31392
31415
|
return target;
|
|
@@ -31894,6 +31917,18 @@ function isProgressMessage(content) {
|
|
|
31894
31917
|
// src/acp/agent-connection.ts
|
|
31895
31918
|
import { spawn as spawn4 } from "node:child_process";
|
|
31896
31919
|
import { ndJsonStream as ndJsonStream2, RequestError as RequestError3 } from "@agentclientprotocol/sdk";
|
|
31920
|
+
function requestErrorMessage(error62) {
|
|
31921
|
+
const fallback = truncate(error62.message, 500);
|
|
31922
|
+
if (error62.message !== "Internal error" || !isRecord3(error62.data)) {
|
|
31923
|
+
return fallback;
|
|
31924
|
+
}
|
|
31925
|
+
const agentError = error62.data["error"];
|
|
31926
|
+
if (!isRecord3(agentError) || agentError["code"] !== "invalid_prompt") {
|
|
31927
|
+
return fallback;
|
|
31928
|
+
}
|
|
31929
|
+
const message = agentError["message"];
|
|
31930
|
+
return typeof message === "string" && message.length > 0 ? truncate(message, 500) : fallback;
|
|
31931
|
+
}
|
|
31897
31932
|
function readableWebStream(input2) {
|
|
31898
31933
|
let streamOpen = true;
|
|
31899
31934
|
return new ReadableStream({
|
|
@@ -32065,7 +32100,7 @@ var AgentConnection = class {
|
|
|
32065
32100
|
);
|
|
32066
32101
|
}
|
|
32067
32102
|
if (error62 instanceof RequestError3) {
|
|
32068
|
-
throw new AcpExecutionError(
|
|
32103
|
+
throw new AcpExecutionError(requestErrorMessage(error62), { cause: error62 }, "acp_agent_error");
|
|
32069
32104
|
}
|
|
32070
32105
|
throw error62;
|
|
32071
32106
|
}
|
|
@@ -38873,11 +38908,11 @@ var AgentSession = class _AgentSession {
|
|
|
38873
38908
|
}
|
|
38874
38909
|
throw new AcpExecutionError("ACP agent initialization failed");
|
|
38875
38910
|
}
|
|
38876
|
-
static start = async (options, getObserver, store, metrics, contentExternalizer) => await _AgentSession.#start(
|
|
38911
|
+
static start = async (options, recovery, getObserver, store, metrics, contentExternalizer) => await _AgentSession.#start(
|
|
38877
38912
|
options,
|
|
38878
38913
|
getObserver,
|
|
38879
38914
|
store,
|
|
38880
|
-
async (runtime) => await runtime.initialize(options.signal, options.origin),
|
|
38915
|
+
async (runtime) => await runtime.initialize(options.signal, recovery, options.origin),
|
|
38881
38916
|
metrics,
|
|
38882
38917
|
contentExternalizer
|
|
38883
38918
|
);
|
|
@@ -38915,6 +38950,16 @@ var AgentSession = class _AgentSession {
|
|
|
38915
38950
|
const history = await this.#completedHistory(signal, "ACP agent exited while loading history");
|
|
38916
38951
|
return await embedLocalHistoryImages(await history.snapshot(), signal);
|
|
38917
38952
|
};
|
|
38953
|
+
ensureHistoryLoaded = async (signal) => {
|
|
38954
|
+
if (!this.#capabilities.loadSession) {
|
|
38955
|
+
throw new AcpExecutionError(
|
|
38956
|
+
"This Agent restores context but does not provide message history.",
|
|
38957
|
+
{},
|
|
38958
|
+
"native_history_unsupported"
|
|
38959
|
+
);
|
|
38960
|
+
}
|
|
38961
|
+
await this.#completedHistory(signal, "ACP agent exited while loading history");
|
|
38962
|
+
};
|
|
38918
38963
|
loadHistoryEventsV2 = async (eventLimit, cursor, signal) => {
|
|
38919
38964
|
if (!this.#capabilities.loadSession) {
|
|
38920
38965
|
throw new AcpExecutionError(
|
|
@@ -39087,7 +39132,7 @@ var AgentSession = class _AgentSession {
|
|
|
39087
39132
|
128
|
|
39088
39133
|
);
|
|
39089
39134
|
}
|
|
39090
|
-
initialize = async (signal, origin) => {
|
|
39135
|
+
initialize = async (signal, recovery, origin) => {
|
|
39091
39136
|
await this.#initializeAgent(signal);
|
|
39092
39137
|
let stored = this.#metrics.measureSync(
|
|
39093
39138
|
"session-state-read",
|
|
@@ -39156,7 +39201,19 @@ var AgentSession = class _AgentSession {
|
|
|
39156
39201
|
this.#prompted = stored.session.prompted;
|
|
39157
39202
|
this.#sessionTitle = stored.session.title;
|
|
39158
39203
|
this.#restored = true;
|
|
39159
|
-
if (
|
|
39204
|
+
if (recovery.kind === "history-required") {
|
|
39205
|
+
if (!this.#capabilities.loadSession) {
|
|
39206
|
+
throw new AcpExecutionError(
|
|
39207
|
+
"This Agent restores context but does not provide message history.",
|
|
39208
|
+
{},
|
|
39209
|
+
"native_history_unsupported"
|
|
39210
|
+
);
|
|
39211
|
+
}
|
|
39212
|
+
lifecycleResponse = await this.#metrics.measure(
|
|
39213
|
+
"session-load",
|
|
39214
|
+
async () => (await this.#loadSession(signal, "ACP agent exited while loading a session")).response
|
|
39215
|
+
);
|
|
39216
|
+
} else if (this.#capabilities.resumeSession) {
|
|
39160
39217
|
lifecycleResponse = await this.#metrics.measure(
|
|
39161
39218
|
"session-resume",
|
|
39162
39219
|
async () => await this.race(
|
|
@@ -40114,8 +40171,15 @@ var embeddedImageSchema = external_exports.looseObject({
|
|
|
40114
40171
|
data: external_exports.string(),
|
|
40115
40172
|
mimeType: external_exports.string()
|
|
40116
40173
|
});
|
|
40174
|
+
var inlineImageUrlSchema = external_exports.string().regex(/^data:image\/(?:png|jpeg|gif|webp);base64,/u).transform((url2) => ({
|
|
40175
|
+
type: "image",
|
|
40176
|
+
data: url2.slice(url2.indexOf(",") + 1),
|
|
40177
|
+
mimeType: url2.slice(5, url2.indexOf(";"))
|
|
40178
|
+
}));
|
|
40117
40179
|
var toolImageSchema = external_exports.union([
|
|
40118
40180
|
embeddedImageSchema,
|
|
40181
|
+
external_exports.object({ type: external_exports.literal("file"), mime: external_exports.string(), url: inlineImageUrlSchema }).refine(({ mime, url: url2 }) => mime === url2.mimeType).transform(({ url: url2 }) => url2),
|
|
40182
|
+
external_exports.object({ type: external_exports.literal("inputImage"), imageUrl: inlineImageUrlSchema }).transform(({ imageUrl }) => imageUrl),
|
|
40119
40183
|
external_exports.object({
|
|
40120
40184
|
type: external_exports.literal("image"),
|
|
40121
40185
|
source: external_exports.object({ type: external_exports.literal("base64"), data: external_exports.string(), media_type: external_exports.string() })
|
|
@@ -40767,12 +40831,13 @@ var AgentRuntimeManager = class {
|
|
|
40767
40831
|
this.#executionProcesses.retain(options.sessionId, runtime);
|
|
40768
40832
|
return runtime;
|
|
40769
40833
|
}
|
|
40770
|
-
async #startPreparation(options, metrics = unmeasuredOperationMetrics) {
|
|
40834
|
+
async #startPreparation(options, recovery, metrics = unmeasuredOperationMetrics) {
|
|
40771
40835
|
return await this.#executionProcesses.prepare(options.sessionId, async () => {
|
|
40772
40836
|
return await this.#startRetainedSessionProcess(
|
|
40773
40837
|
options,
|
|
40774
40838
|
async () => await AgentSession.start(
|
|
40775
40839
|
options.origin === void 0 && this.#sessionIdentity === "native" && isNativeChatSessionId(options.agent.id, options.sessionId) && this.#store.read(options.sessionId) instanceof MissingAcpStoredSession ? { ...options, origin: { kind: "import", nativeSessionId: options.sessionId } } : options,
|
|
40840
|
+
recovery,
|
|
40776
40841
|
() => this.#observer,
|
|
40777
40842
|
this.#store,
|
|
40778
40843
|
metrics,
|
|
@@ -40781,7 +40846,7 @@ var AgentRuntimeManager = class {
|
|
|
40781
40846
|
);
|
|
40782
40847
|
});
|
|
40783
40848
|
}
|
|
40784
|
-
async #replacePreparation(existing, options, metrics) {
|
|
40849
|
+
async #replacePreparation(existing, options, recovery, metrics) {
|
|
40785
40850
|
return await this.#executionProcesses.prepare(options.sessionId, async () => {
|
|
40786
40851
|
await this.#retireSessionProcess(
|
|
40787
40852
|
options.sessionId,
|
|
@@ -40793,6 +40858,7 @@ var AgentRuntimeManager = class {
|
|
|
40793
40858
|
options,
|
|
40794
40859
|
async () => await AgentSession.start(
|
|
40795
40860
|
options,
|
|
40861
|
+
recovery,
|
|
40796
40862
|
() => this.#observer,
|
|
40797
40863
|
this.#store,
|
|
40798
40864
|
metrics,
|
|
@@ -40809,6 +40875,7 @@ var AgentRuntimeManager = class {
|
|
|
40809
40875
|
options,
|
|
40810
40876
|
async () => await AgentSession.start(
|
|
40811
40877
|
options,
|
|
40878
|
+
{ kind: "interactive-only" },
|
|
40812
40879
|
() => this.#observer,
|
|
40813
40880
|
this.#store,
|
|
40814
40881
|
unmeasuredOperationMetrics,
|
|
@@ -40852,42 +40919,58 @@ var AgentRuntimeManager = class {
|
|
|
40852
40919
|
return runtime;
|
|
40853
40920
|
});
|
|
40854
40921
|
}
|
|
40855
|
-
|
|
40856
|
-
|
|
40857
|
-
|
|
40858
|
-
|
|
40859
|
-
|
|
40860
|
-
const pending = this.#executionProcesses.pending(options2.sessionId);
|
|
40861
|
-
if (pending !== void 0) {
|
|
40862
|
-
const runtime2 = await metrics.measure(
|
|
40863
|
-
"session-preparation-wait",
|
|
40864
|
-
async () => await waitForSharedOperation(pending, options2.signal)
|
|
40865
|
-
);
|
|
40866
|
-
if (runtime2.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
40867
|
-
this.#executionProcesses.touch(options2.sessionId, runtime2);
|
|
40868
|
-
return runtime2.prepared();
|
|
40869
|
-
}
|
|
40870
|
-
return await this.prepareSession(options2, metrics);
|
|
40871
|
-
}
|
|
40872
|
-
const existing = this.#executionProcesses.get(options2.sessionId);
|
|
40873
|
-
if (existing !== void 0) {
|
|
40874
|
-
if (existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
40875
|
-
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
40876
|
-
return existing.prepared();
|
|
40922
|
+
async #prepareSession(options, recovery, metrics = unmeasuredOperationMetrics) {
|
|
40923
|
+
return await this.#operations.run(options, async (options2) => {
|
|
40924
|
+
const stored = metrics.measureSync("session-state-read", () => this.#store.read(options2.sessionId));
|
|
40925
|
+
if (stored instanceof FoundAcpStoredSession && this.#nativeOperations.has(`${stored.session.agentId}:${stored.session.nativeSessionId}`)) {
|
|
40926
|
+
throw new AcpExecutionError("The native session is being managed", {}, "session_busy");
|
|
40877
40927
|
}
|
|
40878
|
-
|
|
40879
|
-
|
|
40880
|
-
|
|
40881
|
-
|
|
40882
|
-
|
|
40928
|
+
const pending = this.#executionProcesses.pending(options2.sessionId);
|
|
40929
|
+
if (pending !== void 0) {
|
|
40930
|
+
const runtime2 = await metrics.measure(
|
|
40931
|
+
"session-preparation-wait",
|
|
40932
|
+
async () => await waitForSharedOperation(pending, options2.signal)
|
|
40883
40933
|
);
|
|
40934
|
+
if (runtime2.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
40935
|
+
this.#executionProcesses.touch(options2.sessionId, runtime2);
|
|
40936
|
+
if (recovery.kind === "history-required") {
|
|
40937
|
+
await metrics.measure(
|
|
40938
|
+
"session-load",
|
|
40939
|
+
async () => await runtime2.ensureHistoryLoaded(options2.signal)
|
|
40940
|
+
);
|
|
40941
|
+
}
|
|
40942
|
+
return runtime2.prepared();
|
|
40943
|
+
}
|
|
40944
|
+
return await this.#prepareSession(options2, recovery, metrics);
|
|
40945
|
+
}
|
|
40946
|
+
const existing = this.#executionProcesses.get(options2.sessionId);
|
|
40947
|
+
if (existing !== void 0) {
|
|
40948
|
+
if (existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
40949
|
+
this.#executionProcesses.touch(options2.sessionId, existing);
|
|
40950
|
+
if (recovery.kind === "history-required") {
|
|
40951
|
+
await metrics.measure(
|
|
40952
|
+
"session-load",
|
|
40953
|
+
async () => await existing.ensureHistoryLoaded(options2.signal)
|
|
40954
|
+
);
|
|
40955
|
+
}
|
|
40956
|
+
return existing.prepared();
|
|
40957
|
+
}
|
|
40958
|
+
if (!existing.canRebind()) {
|
|
40959
|
+
throw new AcpExecutionError(
|
|
40960
|
+
"The agent or workspace cannot change after a conversation has started",
|
|
40961
|
+
{},
|
|
40962
|
+
"session_identity_mismatch"
|
|
40963
|
+
);
|
|
40964
|
+
}
|
|
40965
|
+
const runtime2 = await this.#replacePreparation(existing, options2, recovery, metrics);
|
|
40966
|
+
return runtime2.prepared();
|
|
40884
40967
|
}
|
|
40885
|
-
const
|
|
40886
|
-
return
|
|
40887
|
-
}
|
|
40888
|
-
|
|
40889
|
-
|
|
40890
|
-
});
|
|
40968
|
+
const runtime = await this.#startPreparation(options2, recovery, metrics);
|
|
40969
|
+
return runtime.prepared();
|
|
40970
|
+
});
|
|
40971
|
+
}
|
|
40972
|
+
prepareSession = async (options, metrics = unmeasuredOperationMetrics) => await this.#prepareSession(options, { kind: "interactive-only" }, metrics);
|
|
40973
|
+
restoreSession = async (options, metrics = unmeasuredOperationMetrics) => await this.#prepareSession(options, { kind: "history-required" }, metrics);
|
|
40891
40974
|
/**
|
|
40892
40975
|
* Opens a short-lived native ACP session only to read the local Agent's
|
|
40893
40976
|
* authoritative settings. Its identity and store are private to this
|
|
@@ -40901,6 +40984,7 @@ var AgentRuntimeManager = class {
|
|
|
40901
40984
|
...options2,
|
|
40902
40985
|
sessionId: `agent-settings-${crypto.randomUUID()}`
|
|
40903
40986
|
},
|
|
40987
|
+
{ kind: "interactive-only" },
|
|
40904
40988
|
() => this.#agentSettingsObserver,
|
|
40905
40989
|
new MemoryAcpSessionStore(),
|
|
40906
40990
|
unmeasuredOperationMetrics,
|
|
@@ -40938,7 +41022,7 @@ var AgentRuntimeManager = class {
|
|
|
40938
41022
|
);
|
|
40939
41023
|
}
|
|
40940
41024
|
return await this.#executionProcesses.use(options2.sessionId, async () => {
|
|
40941
|
-
const runtime = await this.#startPreparation(options2, metrics);
|
|
41025
|
+
const runtime = await this.#startPreparation(options2, { kind: "interactive-only" }, metrics);
|
|
40942
41026
|
try {
|
|
40943
41027
|
return runtime.prepared();
|
|
40944
41028
|
} finally {
|
|
@@ -40958,7 +41042,7 @@ var AgentRuntimeManager = class {
|
|
|
40958
41042
|
}
|
|
40959
41043
|
const existing = this.#executionProcesses.get(options2.sessionId);
|
|
40960
41044
|
if (existing === void 0) {
|
|
40961
|
-
return (await this.#startPreparation(options2)).prepared();
|
|
41045
|
+
return (await this.#startPreparation(options2, { kind: "interactive-only" })).prepared();
|
|
40962
41046
|
}
|
|
40963
41047
|
if (!existing.belongsTo(options2.agent.id, options2.cwd, options2.additionalDirectories)) {
|
|
40964
41048
|
throw new AcpExecutionError(
|
|
@@ -41143,7 +41227,7 @@ var AgentRuntimeManager = class {
|
|
|
41143
41227
|
const temporaryOptions = { ...options2, sessionId: temporarySessionId };
|
|
41144
41228
|
return await this.#executionProcesses.use(temporarySessionId, async () => {
|
|
41145
41229
|
try {
|
|
41146
|
-
const runtime = await this.#startPreparation(temporaryOptions);
|
|
41230
|
+
const runtime = await this.#startPreparation(temporaryOptions, { kind: "interactive-only" });
|
|
41147
41231
|
let adopted = false;
|
|
41148
41232
|
try {
|
|
41149
41233
|
const nativeSessionId = runtime.nativeSessionId();
|
|
@@ -41309,7 +41393,7 @@ var AgentRuntimeManager = class {
|
|
|
41309
41393
|
return await this.#executionProcesses.use(options2.sessionId, async () => {
|
|
41310
41394
|
this.#nativeOperations.add(key);
|
|
41311
41395
|
try {
|
|
41312
|
-
const runtime = await this.#startPreparation({ ...options2, origin });
|
|
41396
|
+
const runtime = await this.#startPreparation({ ...options2, origin }, { kind: "interactive-only" });
|
|
41313
41397
|
const openedKey = `${options2.agent.id}:${runtime.nativeSessionId()}`;
|
|
41314
41398
|
this.#nativeOperations.add(openedKey);
|
|
41315
41399
|
try {
|
|
@@ -41922,7 +42006,7 @@ var FixedInstallationExecutor = class {
|
|
|
41922
42006
|
// src/authorization/workspace-directory.ts
|
|
41923
42007
|
import { readdir as readdir4, realpath as realpath9, stat as stat8 } from "node:fs/promises";
|
|
41924
42008
|
import { homedir as homedir2 } from "node:os";
|
|
41925
|
-
import { basename as basename4, dirname as dirname5, isAbsolute as
|
|
42009
|
+
import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute10, join as join17, normalize as normalize3, relative as relative4 } from "node:path";
|
|
41926
42010
|
|
|
41927
42011
|
// src/authorization/local-authorization-error.ts
|
|
41928
42012
|
var LocalAuthorizationError = class extends Error {
|
|
@@ -41989,7 +42073,7 @@ var WorkspaceDirectoryService = class {
|
|
|
41989
42073
|
}
|
|
41990
42074
|
if (id.startsWith("path-")) {
|
|
41991
42075
|
const path3 = expandCurrentUserHome(decodePath(id, "path-"));
|
|
41992
|
-
if (
|
|
42076
|
+
if (isAbsolute10(path3)) {
|
|
41993
42077
|
return path3;
|
|
41994
42078
|
}
|
|
41995
42079
|
}
|
|
@@ -41997,7 +42081,7 @@ var WorkspaceDirectoryService = class {
|
|
|
41997
42081
|
};
|
|
41998
42082
|
resolvePath = async (requested, signal) => {
|
|
41999
42083
|
signal.throwIfAborted();
|
|
42000
|
-
if (!
|
|
42084
|
+
if (!isAbsolute10(requested) || requested.includes("\0") || normalize3(requested) !== requested) {
|
|
42001
42085
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
42002
42086
|
}
|
|
42003
42087
|
try {
|
|
@@ -42005,7 +42089,7 @@ var WorkspaceDirectoryService = class {
|
|
|
42005
42089
|
signal.throwIfAborted();
|
|
42006
42090
|
const metadata = await stat8(target);
|
|
42007
42091
|
signal.throwIfAborted();
|
|
42008
|
-
if (!
|
|
42092
|
+
if (!isAbsolute10(target) || normalize3(target) !== target || !metadata.isDirectory()) {
|
|
42009
42093
|
throw new LocalAuthorizationError("The selected location is not a directory");
|
|
42010
42094
|
}
|
|
42011
42095
|
return target;
|
|
@@ -42021,7 +42105,7 @@ var WorkspaceDirectoryService = class {
|
|
|
42021
42105
|
};
|
|
42022
42106
|
label = (path3) => {
|
|
42023
42107
|
const suffix = relative4(homedir2(), path3);
|
|
42024
|
-
return suffix === "" ? "~" : !
|
|
42108
|
+
return suffix === "" ? "~" : !isAbsolute10(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path3;
|
|
42025
42109
|
};
|
|
42026
42110
|
identify = async (bindingId, requestedPath2, signal) => {
|
|
42027
42111
|
this.authorizeMachine(bindingId);
|
|
@@ -45099,7 +45183,7 @@ function createAgentSettingsDiscoveryHandler(dependencies) {
|
|
|
45099
45183
|
// src/artifacts/local-file-streamer.ts
|
|
45100
45184
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
45101
45185
|
import { realpath as realpath10, stat as stat9 } from "node:fs/promises";
|
|
45102
|
-
import { basename as basename5, isAbsolute as
|
|
45186
|
+
import { basename as basename5, isAbsolute as isAbsolute11, normalize as normalize4, resolve as resolve7 } from "node:path";
|
|
45103
45187
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
45104
45188
|
var CHUNK_BYTES = 192 * 1024;
|
|
45105
45189
|
function requestedPath(value) {
|
|
@@ -45118,17 +45202,17 @@ function requestedPath(value) {
|
|
|
45118
45202
|
}
|
|
45119
45203
|
async function resolveFile(value, workingDirectory, signal) {
|
|
45120
45204
|
const path3 = requestedPath(value);
|
|
45121
|
-
if (path3 === null || !
|
|
45205
|
+
if (path3 === null || !isAbsolute11(path3) && workingDirectory === null) {
|
|
45122
45206
|
return null;
|
|
45123
45207
|
}
|
|
45124
45208
|
const requested = workingDirectory === null ? path3 : resolve7(workingDirectory, path3);
|
|
45125
|
-
if (!
|
|
45209
|
+
if (!isAbsolute11(requested) || isAbsolute11(path3) && normalize4(path3) !== path3) {
|
|
45126
45210
|
return null;
|
|
45127
45211
|
}
|
|
45128
45212
|
try {
|
|
45129
45213
|
const target = await realpath10(requested);
|
|
45130
45214
|
signal.throwIfAborted();
|
|
45131
|
-
return
|
|
45215
|
+
return isAbsolute11(target) && normalize4(target) === target ? target : null;
|
|
45132
45216
|
} catch {
|
|
45133
45217
|
signal.throwIfAborted();
|
|
45134
45218
|
return null;
|
|
@@ -45657,7 +45741,7 @@ async function executePrompt({
|
|
|
45657
45741
|
}
|
|
45658
45742
|
|
|
45659
45743
|
// src/daemon-session-commands.ts
|
|
45660
|
-
async function prepareSession(command, config2, directories, audit, sessions, metrics, signal) {
|
|
45744
|
+
async function prepareSession(command, recovery, config2, directories, audit, sessions, metrics, signal) {
|
|
45661
45745
|
return await metrics.measure("prepare-total", async () => {
|
|
45662
45746
|
const resolved = await metrics.measure(
|
|
45663
45747
|
"workspace-resolve",
|
|
@@ -45677,7 +45761,7 @@ async function prepareSession(command, config2, directories, audit, sessions, me
|
|
|
45677
45761
|
sessionId: command.sessionId,
|
|
45678
45762
|
signal
|
|
45679
45763
|
};
|
|
45680
|
-
const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
|
|
45764
|
+
const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics) : await sessions.prepareSession(preparation, metrics);
|
|
45681
45765
|
const configuration = command.configuration;
|
|
45682
45766
|
const configOptions = configuration === void 0 ? prepared.configOptions : await metrics.measure(
|
|
45683
45767
|
"configuration",
|
|
@@ -45747,7 +45831,16 @@ async function executeWorkspaceList(socket, command, directories, audit, signal)
|
|
|
45747
45831
|
async function executeSessionPrepare(socket, command, config2, directories, audit, sessions, diagnostics, signal) {
|
|
45748
45832
|
const metrics = new AccumulatingOperationMetrics();
|
|
45749
45833
|
try {
|
|
45750
|
-
const readyEvent = await prepareSession(
|
|
45834
|
+
const readyEvent = await prepareSession(
|
|
45835
|
+
command,
|
|
45836
|
+
{ kind: "interactive-only" },
|
|
45837
|
+
config2,
|
|
45838
|
+
directories,
|
|
45839
|
+
audit,
|
|
45840
|
+
sessions,
|
|
45841
|
+
metrics,
|
|
45842
|
+
signal
|
|
45843
|
+
);
|
|
45751
45844
|
send(socket, {
|
|
45752
45845
|
...readyEvent,
|
|
45753
45846
|
runtimeTimings: metrics.snapshot()
|
|
@@ -45796,6 +45889,7 @@ async function executeSessionRestore(socket, command, config2, directories, audi
|
|
|
45796
45889
|
sessionId: command.sessionId,
|
|
45797
45890
|
sessionState: "provisioned"
|
|
45798
45891
|
},
|
|
45892
|
+
{ kind: "history-required" },
|
|
45799
45893
|
config2,
|
|
45800
45894
|
directories,
|
|
45801
45895
|
audit,
|