@moxt-ai/mobius 0.0.166 → 0.0.168
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-query-processes.d.ts +2 -1
- package/dist/acp/agent-query-processes.d.ts.map +1 -1
- package/dist/acp/agent-query-processes.js +6 -4
- package/dist/acp/agent-query-processes.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 +11 -6
- package/dist/acp/agent-runtime-manager.js.map +1 -1
- package/dist/acp/agent-session.d.ts +3 -2
- package/dist/acp/agent-session.d.ts.map +1 -1
- package/dist/acp/agent-session.js +10 -7
- package/dist/acp/agent-session.js.map +1 -1
- package/dist/artifacts/local-file-streamer.d.ts +2 -1
- package/dist/artifacts/local-file-streamer.d.ts.map +1 -1
- package/dist/artifacts/local-file-streamer.js +6 -5
- package/dist/artifacts/local-file-streamer.js.map +1 -1
- package/dist/authorization/local-raster.d.ts +1 -0
- package/dist/authorization/local-raster.d.ts.map +1 -1
- package/dist/authorization/local-raster.js +1 -1
- package/dist/authorization/local-raster.js.map +1 -1
- package/dist/cli.js +565 -99
- package/dist/cli.js.map +4 -4
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/daemon-command-handler.d.ts +3 -1
- package/dist/daemon-command-handler.d.ts.map +1 -1
- package/dist/daemon-command-handler.js +2 -2
- package/dist/daemon-command-handler.js.map +1 -1
- package/dist/external-content/acp-content-externalizer.d.ts +12 -0
- package/dist/external-content/acp-content-externalizer.d.ts.map +1 -0
- package/dist/external-content/acp-content-externalizer.js +233 -0
- package/dist/external-content/acp-content-externalizer.js.map +1 -0
- package/dist/external-content/local-external-content-store.d.ts +34 -0
- package/dist/external-content/local-external-content-store.d.ts.map +1 -0
- package/dist/external-content/local-external-content-store.js +174 -0
- package/dist/external-content/local-external-content-store.js.map +1 -0
- package/dist/index.js +639 -179
- package/dist/index.js.map +4 -4
- package/dist/relay-connection/run-relay-connection.d.ts +3 -1
- package/dist/relay-connection/run-relay-connection.d.ts.map +1 -1
- package/dist/relay-connection/run-relay-connection.js +2 -1
- package/dist/relay-connection/run-relay-connection.js.map +1 -1
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +208 -140
- package/dist/run-daemon.js.map +1 -1
- package/dist/runtime.d.ts +2 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +572 -111
- package/dist/runtime.js.map +4 -4
- package/package.json +16 -10
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ var __export = (target, all) => {
|
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
9
|
import { constants as constants2 } from "node:fs";
|
|
10
|
-
import { mkdir as
|
|
10
|
+
import { mkdir as mkdir7, open as open6 } from "node:fs/promises";
|
|
11
11
|
import { resolve as resolve8 } from "node:path";
|
|
12
12
|
|
|
13
13
|
// ../../node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
|
|
@@ -3381,21 +3381,16 @@ 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.168",
|
|
3385
3385
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
3386
3386
|
type: "module",
|
|
3387
3387
|
bin: {
|
|
3388
3388
|
mobius: "dist/cli.js"
|
|
3389
3389
|
},
|
|
3390
|
+
types: "./src/index.ts",
|
|
3390
3391
|
exports: {
|
|
3391
|
-
".":
|
|
3392
|
-
|
|
3393
|
-
import: "./dist/index.js"
|
|
3394
|
-
},
|
|
3395
|
-
"./runtime": {
|
|
3396
|
-
types: "./dist/runtime.d.ts",
|
|
3397
|
-
import: "./dist/runtime.js"
|
|
3398
|
-
}
|
|
3392
|
+
".": "./src/index.ts",
|
|
3393
|
+
"./runtime": "./src/runtime.ts"
|
|
3399
3394
|
},
|
|
3400
3395
|
files: [
|
|
3401
3396
|
"dist"
|
|
@@ -3404,7 +3399,18 @@ var package_default = {
|
|
|
3404
3399
|
node: ">=22.13.0"
|
|
3405
3400
|
},
|
|
3406
3401
|
publishConfig: {
|
|
3407
|
-
access: "public"
|
|
3402
|
+
access: "public",
|
|
3403
|
+
types: "./dist/index.d.ts",
|
|
3404
|
+
exports: {
|
|
3405
|
+
".": {
|
|
3406
|
+
types: "./dist/index.d.ts",
|
|
3407
|
+
import: "./dist/index.js"
|
|
3408
|
+
},
|
|
3409
|
+
"./runtime": {
|
|
3410
|
+
types: "./dist/runtime.d.ts",
|
|
3411
|
+
import: "./dist/runtime.js"
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3408
3414
|
},
|
|
3409
3415
|
repository: {
|
|
3410
3416
|
type: "git",
|
|
@@ -29799,6 +29805,7 @@ var MAX_JSON_KEYS = 1e3;
|
|
|
29799
29805
|
var SESSION_EVENT_V2_KIND = "session.event.v2";
|
|
29800
29806
|
var boundedString = external_exports.string().max(MAX_CONTENT_LENGTH);
|
|
29801
29807
|
var shortString = external_exports.string().max(2048);
|
|
29808
|
+
var externalContentKeySchema = external_exports.string().regex(/^[a-f0-9]{64}$/u);
|
|
29802
29809
|
function boundedJsonIssue(value, depth = 0) {
|
|
29803
29810
|
if (depth > MAX_JSON_DEPTH) {
|
|
29804
29811
|
return "JSON nesting exceeds the maximum depth";
|
|
@@ -29866,6 +29873,30 @@ var imageContentSchema = external_exports.object({
|
|
|
29866
29873
|
uri: boundedString.nullable().optional()
|
|
29867
29874
|
}).readonly();
|
|
29868
29875
|
var audioContentSchema = external_exports.object({ ...contentFields, data: boundedString, mimeType: shortString, type: external_exports.literal("audio") }).readonly();
|
|
29876
|
+
var externalImageContentSchema = external_exports.strictObject({
|
|
29877
|
+
...contentFields,
|
|
29878
|
+
byteLength: external_exports.number().int().positive().safe(),
|
|
29879
|
+
imageKey: externalContentKeySchema,
|
|
29880
|
+
mimeType: shortString,
|
|
29881
|
+
type: external_exports.literal("external_image"),
|
|
29882
|
+
uri: boundedString.nullable().optional()
|
|
29883
|
+
}).readonly();
|
|
29884
|
+
var externalAudioContentSchema = external_exports.strictObject({
|
|
29885
|
+
...contentFields,
|
|
29886
|
+
audioKey: externalContentKeySchema,
|
|
29887
|
+
byteLength: external_exports.number().int().positive().safe(),
|
|
29888
|
+
mimeType: shortString,
|
|
29889
|
+
type: external_exports.literal("external_audio")
|
|
29890
|
+
}).readonly();
|
|
29891
|
+
var externalResourceContentSchema = external_exports.strictObject({
|
|
29892
|
+
...contentFields,
|
|
29893
|
+
byteLength: external_exports.number().int().positive().safe(),
|
|
29894
|
+
encoding: external_exports.enum(["binary", "text"]),
|
|
29895
|
+
mimeType: shortString.nullable().optional(),
|
|
29896
|
+
resourceKey: externalContentKeySchema,
|
|
29897
|
+
type: external_exports.literal("external_resource"),
|
|
29898
|
+
uri: boundedString
|
|
29899
|
+
}).readonly();
|
|
29869
29900
|
var resourceLinkSchema = external_exports.object({
|
|
29870
29901
|
...contentFields,
|
|
29871
29902
|
description: boundedString.nullable().optional(),
|
|
@@ -29898,7 +29929,10 @@ var contentBlockV2Schema = external_exports.discriminatedUnion("type", [
|
|
|
29898
29929
|
imageContentSchema,
|
|
29899
29930
|
audioContentSchema,
|
|
29900
29931
|
resourceLinkSchema,
|
|
29901
|
-
embeddedResourceSchema
|
|
29932
|
+
embeddedResourceSchema,
|
|
29933
|
+
externalImageContentSchema,
|
|
29934
|
+
externalAudioContentSchema,
|
|
29935
|
+
externalResourceContentSchema
|
|
29902
29936
|
]);
|
|
29903
29937
|
var toolCallContentSchema = external_exports.discriminatedUnion("type", [
|
|
29904
29938
|
external_exports.object({ _meta: optionalMetadata, content: contentBlockV2Schema, type: external_exports.literal("content") }).readonly(),
|
|
@@ -30710,11 +30744,11 @@ function createDaemonConfig(connection, agents = [], installableAgents = [], loc
|
|
|
30710
30744
|
|
|
30711
30745
|
// src/daemon-manager.ts
|
|
30712
30746
|
import { spawn as spawn6 } from "node:child_process";
|
|
30713
|
-
import { createHash as
|
|
30714
|
-
import { readFile as readFile3, unlink as unlink2, writeFile as
|
|
30747
|
+
import { createHash as createHash9, randomBytes } from "node:crypto";
|
|
30748
|
+
import { readFile as readFile3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
|
|
30715
30749
|
import { createConnection, createServer } from "node:net";
|
|
30716
30750
|
import { tmpdir } from "node:os";
|
|
30717
|
-
import { join as
|
|
30751
|
+
import { join as join20 } from "node:path";
|
|
30718
30752
|
|
|
30719
30753
|
// src/pairing/pair-local-machine.ts
|
|
30720
30754
|
import { mkdir as mkdir5, realpath as realpath6, stat as stat5 } from "node:fs/promises";
|
|
@@ -31544,8 +31578,8 @@ var AuditStore = class {
|
|
|
31544
31578
|
};
|
|
31545
31579
|
|
|
31546
31580
|
// src/run-daemon.ts
|
|
31547
|
-
import { createHash as
|
|
31548
|
-
import { join as
|
|
31581
|
+
import { createHash as createHash8, randomUUID as randomUUID8 } from "node:crypto";
|
|
31582
|
+
import { join as join19 } from "node:path";
|
|
31549
31583
|
import { styleText } from "node:util";
|
|
31550
31584
|
|
|
31551
31585
|
// src/acp/active-executions.ts
|
|
@@ -34917,7 +34951,7 @@ function sql(strings, ...params) {
|
|
|
34917
34951
|
return new SQL([new StringChunk(str)]);
|
|
34918
34952
|
}
|
|
34919
34953
|
sql2.raw = raw;
|
|
34920
|
-
function
|
|
34954
|
+
function join21(chunks, separator) {
|
|
34921
34955
|
const result = [];
|
|
34922
34956
|
for (const [i, chunk] of chunks.entries()) {
|
|
34923
34957
|
if (i > 0 && separator !== void 0) {
|
|
@@ -34927,7 +34961,7 @@ function sql(strings, ...params) {
|
|
|
34927
34961
|
}
|
|
34928
34962
|
return new SQL(result);
|
|
34929
34963
|
}
|
|
34930
|
-
sql2.join =
|
|
34964
|
+
sql2.join = join21;
|
|
34931
34965
|
function identifier(value) {
|
|
34932
34966
|
return new Name(value);
|
|
34933
34967
|
}
|
|
@@ -37471,7 +37505,7 @@ var SQLiteSelectQueryBuilderBase = class extends TypedQueryBuilder {
|
|
|
37471
37505
|
const baseTableName = this.tableName;
|
|
37472
37506
|
const tableName = getTableLikeName(table);
|
|
37473
37507
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
37474
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
37508
|
+
if (typeof tableName === "string" && this.config.joins?.some((join21) => join21.alias === tableName)) {
|
|
37475
37509
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
37476
37510
|
}
|
|
37477
37511
|
if (!this.isPartialSelect) {
|
|
@@ -38330,7 +38364,7 @@ var SQLiteUpdateBase = class extends QueryPromise {
|
|
|
38330
38364
|
createJoin(joinType) {
|
|
38331
38365
|
return (table, on) => {
|
|
38332
38366
|
const tableName = getTableLikeName(table);
|
|
38333
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
38367
|
+
if (typeof tableName === "string" && this.config.joins.some((join21) => join21.alias === tableName)) {
|
|
38334
38368
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
38335
38369
|
}
|
|
38336
38370
|
if (typeof on === "function") {
|
|
@@ -39653,6 +39687,7 @@ function recordsEqual(left, right) {
|
|
|
39653
39687
|
}
|
|
39654
39688
|
var AgentSession = class _AgentSession {
|
|
39655
39689
|
#connection;
|
|
39690
|
+
#contentExternalizer;
|
|
39656
39691
|
#interactions;
|
|
39657
39692
|
#additionalDirectories;
|
|
39658
39693
|
#agentId;
|
|
@@ -39680,7 +39715,7 @@ var AgentSession = class _AgentSession {
|
|
|
39680
39715
|
#sessionTitle = null;
|
|
39681
39716
|
#sessionUpdatedAt = "";
|
|
39682
39717
|
#turn = new IdleAcpTurn();
|
|
39683
|
-
constructor(agent, cwd, additionalDirectories, mobiusSessionId, getObserver, store, metrics) {
|
|
39718
|
+
constructor(agent, cwd, additionalDirectories, mobiusSessionId, getObserver, store, metrics, contentExternalizer) {
|
|
39684
39719
|
this.#updates = new AgentUpdateStream((notification) => this.#processUpdate(notification));
|
|
39685
39720
|
this.#additionalDirectories = [...additionalDirectories];
|
|
39686
39721
|
this.#agentId = agent.id;
|
|
@@ -39700,8 +39735,9 @@ var AgentSession = class _AgentSession {
|
|
|
39700
39735
|
observer: getObserver
|
|
39701
39736
|
});
|
|
39702
39737
|
this.#connection = new AgentConnection(agent, cwd, this);
|
|
39738
|
+
this.#contentExternalizer = contentExternalizer;
|
|
39703
39739
|
}
|
|
39704
|
-
static async #start(options, getObserver, store, initialize, metrics) {
|
|
39740
|
+
static async #start(options, getObserver, store, initialize, metrics, contentExternalizer) {
|
|
39705
39741
|
for (let attempt = 1; attempt <= 2; attempt += 1) {
|
|
39706
39742
|
options.signal.throwIfAborted();
|
|
39707
39743
|
const unchanged = await metrics.measure(
|
|
@@ -39729,7 +39765,8 @@ var AgentSession = class _AgentSession {
|
|
|
39729
39765
|
options.sessionId,
|
|
39730
39766
|
getObserver,
|
|
39731
39767
|
store,
|
|
39732
|
-
metrics
|
|
39768
|
+
metrics,
|
|
39769
|
+
contentExternalizer
|
|
39733
39770
|
)
|
|
39734
39771
|
);
|
|
39735
39772
|
try {
|
|
@@ -39752,19 +39789,21 @@ var AgentSession = class _AgentSession {
|
|
|
39752
39789
|
}
|
|
39753
39790
|
throw new AcpExecutionError("ACP agent initialization failed");
|
|
39754
39791
|
}
|
|
39755
|
-
static start = async (options, getObserver, store, metrics
|
|
39792
|
+
static start = async (options, getObserver, store, metrics, contentExternalizer) => await _AgentSession.#start(
|
|
39756
39793
|
options,
|
|
39757
39794
|
getObserver,
|
|
39758
39795
|
store,
|
|
39759
39796
|
async (runtime) => await runtime.initialize(options.signal, options.origin),
|
|
39760
|
-
metrics
|
|
39797
|
+
metrics,
|
|
39798
|
+
contentExternalizer
|
|
39761
39799
|
);
|
|
39762
|
-
static startNativeSessionBrowser = async (options, getObserver, store) => await _AgentSession.#start(
|
|
39800
|
+
static startNativeSessionBrowser = async (options, getObserver, store, contentExternalizer) => await _AgentSession.#start(
|
|
39763
39801
|
options,
|
|
39764
39802
|
getObserver,
|
|
39765
39803
|
store,
|
|
39766
39804
|
async (runtime) => await runtime.#initializeAgent(options.signal),
|
|
39767
|
-
unmeasuredOperationMetrics
|
|
39805
|
+
unmeasuredOperationMetrics,
|
|
39806
|
+
contentExternalizer
|
|
39768
39807
|
);
|
|
39769
39808
|
belongsTo = (agentId, cwd, additionalDirectories) => this.#agentId === agentId && this.#cwd === cwd && arraysEqual(this.#additionalDirectories, additionalDirectories);
|
|
39770
39809
|
usesEnvironment = (environment) => recordsEqual(this.#environment, environment);
|
|
@@ -40468,8 +40507,13 @@ var AgentSession = class _AgentSession {
|
|
|
40468
40507
|
};
|
|
40469
40508
|
#processUpdate = async (notification) => {
|
|
40470
40509
|
this.assertNativeSession(notification.sessionId);
|
|
40471
|
-
const
|
|
40472
|
-
|
|
40510
|
+
const externalized = await this.#contentExternalizer.update(
|
|
40511
|
+
this.#mobiusSessionId,
|
|
40512
|
+
notification.update,
|
|
40513
|
+
AbortSignal.timeout(3e4)
|
|
40514
|
+
);
|
|
40515
|
+
const update = externalized.agent;
|
|
40516
|
+
const rawUpdate = decodeAcpSessionUpdateV2(JSON.stringify(externalized.event));
|
|
40473
40517
|
if (this.#sessionLoad.kind === "capturing") {
|
|
40474
40518
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
40475
40519
|
} else {
|
|
@@ -40756,8 +40800,10 @@ var AgentQueryProcesses = class {
|
|
|
40756
40800
|
#processes;
|
|
40757
40801
|
#observer = new NullAcpSessionObserver();
|
|
40758
40802
|
#store = new MemoryAcpSessionStore();
|
|
40759
|
-
|
|
40803
|
+
#contentExternalizer;
|
|
40804
|
+
constructor(processes, contentExternalizer) {
|
|
40760
40805
|
this.#processes = processes;
|
|
40806
|
+
this.#contentExternalizer = contentExternalizer;
|
|
40761
40807
|
this.#processesByQuery = new RetainedAgentProcesses({
|
|
40762
40808
|
touch: processes.touch,
|
|
40763
40809
|
changed: processes.notifyChanged
|
|
@@ -40773,7 +40819,12 @@ var AgentQueryProcesses = class {
|
|
|
40773
40819
|
async #startRetained(options) {
|
|
40774
40820
|
const runtime = await this.#processes.startRetained(
|
|
40775
40821
|
options.signal,
|
|
40776
|
-
() => AgentSession.startNativeSessionBrowser(
|
|
40822
|
+
() => AgentSession.startNativeSessionBrowser(
|
|
40823
|
+
options,
|
|
40824
|
+
() => this.#observer,
|
|
40825
|
+
this.#store,
|
|
40826
|
+
this.#contentExternalizer
|
|
40827
|
+
),
|
|
40777
40828
|
{
|
|
40778
40829
|
isBusy: () => this.#processesByQuery.isBusy(options.sessionId),
|
|
40779
40830
|
retire: (runtime2) => this.retire(options.sessionId, runtime2)
|
|
@@ -40849,7 +40900,8 @@ var AgentQueryProcesses = class {
|
|
|
40849
40900
|
async () => await AgentSession.startNativeSessionBrowser(
|
|
40850
40901
|
options,
|
|
40851
40902
|
() => this.#observer,
|
|
40852
|
-
new MemoryAcpSessionStore()
|
|
40903
|
+
new MemoryAcpSessionStore(),
|
|
40904
|
+
this.#contentExternalizer
|
|
40853
40905
|
),
|
|
40854
40906
|
async (runtime) => {
|
|
40855
40907
|
runtime.selectNativeSession(nativeSessionId);
|
|
@@ -40864,7 +40916,8 @@ var AgentQueryProcesses = class {
|
|
|
40864
40916
|
async () => await AgentSession.startNativeSessionBrowser(
|
|
40865
40917
|
options,
|
|
40866
40918
|
() => this.#observer,
|
|
40867
|
-
new MemoryAcpSessionStore()
|
|
40919
|
+
new MemoryAcpSessionStore(),
|
|
40920
|
+
this.#contentExternalizer
|
|
40868
40921
|
),
|
|
40869
40922
|
async (runtime) => {
|
|
40870
40923
|
runtime.selectNativeSession(nativeSessionId);
|
|
@@ -40880,6 +40933,393 @@ var AgentQueryProcesses = class {
|
|
|
40880
40933
|
};
|
|
40881
40934
|
};
|
|
40882
40935
|
|
|
40936
|
+
// src/external-content/acp-content-externalizer.ts
|
|
40937
|
+
var MAXIMUM_ENCODED_CONTENT_CHARACTERS = 4e6;
|
|
40938
|
+
function decodeBase64(data) {
|
|
40939
|
+
if (data.length > MAXIMUM_ENCODED_CONTENT_CHARACTERS || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)) {
|
|
40940
|
+
throw new Error("The ACP embedded content is not valid bounded base64");
|
|
40941
|
+
}
|
|
40942
|
+
const bytes = Buffer.from(data, "base64");
|
|
40943
|
+
if (bytes.toString("base64") !== data) {
|
|
40944
|
+
throw new Error("The ACP embedded content is not canonical base64");
|
|
40945
|
+
}
|
|
40946
|
+
return bytes;
|
|
40947
|
+
}
|
|
40948
|
+
var embeddedImageSchema = external_exports.looseObject({
|
|
40949
|
+
type: external_exports.literal("image"),
|
|
40950
|
+
data: external_exports.string(),
|
|
40951
|
+
mimeType: external_exports.string()
|
|
40952
|
+
});
|
|
40953
|
+
function isRecord10(value) {
|
|
40954
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40955
|
+
}
|
|
40956
|
+
var AcpContentExternalizer = class {
|
|
40957
|
+
#store;
|
|
40958
|
+
constructor(store) {
|
|
40959
|
+
this.#store = store;
|
|
40960
|
+
}
|
|
40961
|
+
async #content(sessionId, content, signal) {
|
|
40962
|
+
switch (content.type) {
|
|
40963
|
+
case "text":
|
|
40964
|
+
case "resource_link":
|
|
40965
|
+
return { agent: content, event: content };
|
|
40966
|
+
case "image": {
|
|
40967
|
+
if (content.data.length === 0) {
|
|
40968
|
+
return { agent: content, event: content };
|
|
40969
|
+
}
|
|
40970
|
+
try {
|
|
40971
|
+
const bytes = decodeBase64(content.data);
|
|
40972
|
+
if (sniffRasterMime(bytes) !== content.mimeType) {
|
|
40973
|
+
throw new Error("Embedded image bytes do not match a supported image MIME type");
|
|
40974
|
+
}
|
|
40975
|
+
const stored = await this.#store.put({
|
|
40976
|
+
bytes,
|
|
40977
|
+
kind: "image",
|
|
40978
|
+
mediaType: content.mimeType,
|
|
40979
|
+
name: "image",
|
|
40980
|
+
sessionId,
|
|
40981
|
+
signal
|
|
40982
|
+
});
|
|
40983
|
+
return {
|
|
40984
|
+
agent: { ...content, data: "", uri: `mobius-content:image:${stored.key}` },
|
|
40985
|
+
event: {
|
|
40986
|
+
_meta: content._meta,
|
|
40987
|
+
annotations: content.annotations,
|
|
40988
|
+
byteLength: stored.byteLength,
|
|
40989
|
+
imageKey: stored.key,
|
|
40990
|
+
mimeType: content.mimeType,
|
|
40991
|
+
type: "external_image",
|
|
40992
|
+
uri: content.uri
|
|
40993
|
+
}
|
|
40994
|
+
};
|
|
40995
|
+
} catch {
|
|
40996
|
+
signal.throwIfAborted();
|
|
40997
|
+
const unavailable = { type: "text", text: "[Image unavailable]" };
|
|
40998
|
+
return { agent: unavailable, event: unavailable };
|
|
40999
|
+
}
|
|
41000
|
+
}
|
|
41001
|
+
case "audio": {
|
|
41002
|
+
if (content.data.length === 0) {
|
|
41003
|
+
return { agent: content, event: content };
|
|
41004
|
+
}
|
|
41005
|
+
const stored = await this.#store.put({
|
|
41006
|
+
bytes: decodeBase64(content.data),
|
|
41007
|
+
kind: "audio",
|
|
41008
|
+
mediaType: content.mimeType,
|
|
41009
|
+
name: "audio",
|
|
41010
|
+
sessionId,
|
|
41011
|
+
signal
|
|
41012
|
+
});
|
|
41013
|
+
return {
|
|
41014
|
+
agent: content,
|
|
41015
|
+
event: {
|
|
41016
|
+
_meta: content._meta,
|
|
41017
|
+
annotations: content.annotations,
|
|
41018
|
+
audioKey: stored.key,
|
|
41019
|
+
byteLength: stored.byteLength,
|
|
41020
|
+
mimeType: content.mimeType,
|
|
41021
|
+
type: "external_audio"
|
|
41022
|
+
}
|
|
41023
|
+
};
|
|
41024
|
+
}
|
|
41025
|
+
case "resource": {
|
|
41026
|
+
const embedded = content.resource;
|
|
41027
|
+
const encoding = "text" in embedded ? "text" : "binary";
|
|
41028
|
+
const bytes = "text" in embedded ? Buffer.from(embedded.text, "utf8") : decodeBase64(embedded.blob);
|
|
41029
|
+
if (bytes.byteLength === 0) {
|
|
41030
|
+
return { agent: content, event: content };
|
|
41031
|
+
}
|
|
41032
|
+
const mediaType = embedded.mimeType ?? "application/octet-stream";
|
|
41033
|
+
const stored = await this.#store.put({
|
|
41034
|
+
bytes,
|
|
41035
|
+
kind: "resource",
|
|
41036
|
+
mediaType,
|
|
41037
|
+
name: "resource",
|
|
41038
|
+
sessionId,
|
|
41039
|
+
signal
|
|
41040
|
+
});
|
|
41041
|
+
return {
|
|
41042
|
+
agent: content,
|
|
41043
|
+
event: {
|
|
41044
|
+
_meta: content._meta,
|
|
41045
|
+
annotations: content.annotations,
|
|
41046
|
+
byteLength: stored.byteLength,
|
|
41047
|
+
encoding,
|
|
41048
|
+
mimeType: embedded.mimeType,
|
|
41049
|
+
resourceKey: stored.key,
|
|
41050
|
+
type: "external_resource",
|
|
41051
|
+
uri: embedded.uri
|
|
41052
|
+
}
|
|
41053
|
+
};
|
|
41054
|
+
}
|
|
41055
|
+
}
|
|
41056
|
+
}
|
|
41057
|
+
async #rawOutput(sessionId, value, images, signal, depth = 0) {
|
|
41058
|
+
signal.throwIfAborted();
|
|
41059
|
+
if (depth > 16) {
|
|
41060
|
+
throw new Error("ACP tool output exceeds the maximum nesting depth");
|
|
41061
|
+
}
|
|
41062
|
+
if (Array.isArray(value)) {
|
|
41063
|
+
const result2 = [];
|
|
41064
|
+
for (const item of value) {
|
|
41065
|
+
result2.push(await this.#rawOutput(sessionId, item, images, signal, depth + 1));
|
|
41066
|
+
}
|
|
41067
|
+
return result2;
|
|
41068
|
+
}
|
|
41069
|
+
if (!isRecord10(value)) {
|
|
41070
|
+
return value;
|
|
41071
|
+
}
|
|
41072
|
+
const image = embeddedImageSchema.safeParse(value);
|
|
41073
|
+
if (image.success && image.data.data.length > 0) {
|
|
41074
|
+
const prepared = await this.#content(sessionId, image.data, signal);
|
|
41075
|
+
if (isRecord10(prepared.event) && typeof prepared.event["imageKey"] === "string") {
|
|
41076
|
+
images.set(prepared.event["imageKey"], prepared);
|
|
41077
|
+
} else {
|
|
41078
|
+
images.set(`unavailable:${images.size}`, prepared);
|
|
41079
|
+
}
|
|
41080
|
+
return prepared.event;
|
|
41081
|
+
}
|
|
41082
|
+
const result = {};
|
|
41083
|
+
for (const [key, item] of Object.entries(value)) {
|
|
41084
|
+
result[key] = await this.#rawOutput(sessionId, item, images, signal, depth + 1);
|
|
41085
|
+
}
|
|
41086
|
+
return result;
|
|
41087
|
+
}
|
|
41088
|
+
async #toolUpdate(sessionId, update, signal) {
|
|
41089
|
+
const images = /* @__PURE__ */ new Map();
|
|
41090
|
+
const rawOutput = update.rawOutput === void 0 ? void 0 : await this.#rawOutput(sessionId, update.rawOutput, images, signal);
|
|
41091
|
+
const originalJson = images.size === 0 ? void 0 : JSON.stringify(update.rawOutput);
|
|
41092
|
+
const rewrittenJson = images.size === 0 ? void 0 : JSON.stringify(rawOutput);
|
|
41093
|
+
const agentContent = [];
|
|
41094
|
+
const eventContent = [];
|
|
41095
|
+
for (const item of update.content ?? []) {
|
|
41096
|
+
if (item.type !== "content") {
|
|
41097
|
+
agentContent.push(item);
|
|
41098
|
+
eventContent.push(item);
|
|
41099
|
+
continue;
|
|
41100
|
+
}
|
|
41101
|
+
const content = item.content.type === "text" && item.content.text === originalJson && rewrittenJson !== void 0 ? { ...item.content, text: rewrittenJson } : item.content;
|
|
41102
|
+
const prepared = await this.#content(sessionId, content, signal);
|
|
41103
|
+
agentContent.push({ ...item, content: prepared.agent });
|
|
41104
|
+
eventContent.push({ ...item, content: prepared.event });
|
|
41105
|
+
if (isRecord10(prepared.event) && typeof prepared.event["imageKey"] === "string") {
|
|
41106
|
+
images.delete(prepared.event["imageKey"]);
|
|
41107
|
+
}
|
|
41108
|
+
}
|
|
41109
|
+
for (const prepared of images.values()) {
|
|
41110
|
+
agentContent.push({ type: "content", content: prepared.agent });
|
|
41111
|
+
eventContent.push({ type: "content", content: prepared.event });
|
|
41112
|
+
}
|
|
41113
|
+
const output2 = update.rawOutput === void 0 ? {} : { rawOutput };
|
|
41114
|
+
const hasContent = update.content !== void 0 && update.content !== null || agentContent.length > 0;
|
|
41115
|
+
return {
|
|
41116
|
+
agent: { ...update, ...output2, ...hasContent ? { content: agentContent } : {} },
|
|
41117
|
+
event: { ...update, ...output2, ...hasContent ? { content: eventContent } : {} }
|
|
41118
|
+
};
|
|
41119
|
+
}
|
|
41120
|
+
update = async (sessionId, update, signal) => {
|
|
41121
|
+
switch (update.sessionUpdate) {
|
|
41122
|
+
case "user_message_chunk":
|
|
41123
|
+
case "agent_message_chunk":
|
|
41124
|
+
case "agent_thought_chunk":
|
|
41125
|
+
case "compaction_summary_chunk": {
|
|
41126
|
+
const content = await this.#content(sessionId, update.content, signal);
|
|
41127
|
+
return {
|
|
41128
|
+
agent: { ...update, content: content.agent },
|
|
41129
|
+
event: { ...update, content: content.event }
|
|
41130
|
+
};
|
|
41131
|
+
}
|
|
41132
|
+
case "tool_call":
|
|
41133
|
+
case "tool_call_update":
|
|
41134
|
+
return await this.#toolUpdate(sessionId, update, signal);
|
|
41135
|
+
case "compaction_update": {
|
|
41136
|
+
if (update.summary === void 0 || update.summary === null) {
|
|
41137
|
+
return { agent: update, event: update };
|
|
41138
|
+
}
|
|
41139
|
+
const content = await Promise.all(
|
|
41140
|
+
update.summary.map(async (item) => await this.#content(sessionId, item, signal))
|
|
41141
|
+
);
|
|
41142
|
+
return {
|
|
41143
|
+
agent: { ...update, summary: content.map((item) => item.agent) },
|
|
41144
|
+
event: { ...update, summary: content.map((item) => item.event) }
|
|
41145
|
+
};
|
|
41146
|
+
}
|
|
41147
|
+
case "plan":
|
|
41148
|
+
case "plan_update":
|
|
41149
|
+
case "plan_removed":
|
|
41150
|
+
case "available_commands_update":
|
|
41151
|
+
case "current_mode_update":
|
|
41152
|
+
case "config_option_update":
|
|
41153
|
+
case "session_info_update":
|
|
41154
|
+
case "usage_update":
|
|
41155
|
+
return { agent: update, event: update };
|
|
41156
|
+
}
|
|
41157
|
+
};
|
|
41158
|
+
};
|
|
41159
|
+
|
|
41160
|
+
// src/external-content/local-external-content-store.ts
|
|
41161
|
+
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
41162
|
+
import { lstat, mkdir as mkdir6, readdir as readdir3, realpath as realpath8, rename as rename4, rm as rm3, stat as stat7, utimes, writeFile as writeFile4 } from "node:fs/promises";
|
|
41163
|
+
import { dirname as dirname5, join as join16 } from "node:path";
|
|
41164
|
+
var contentRequest = /^mobius-content:(image|audio|resource):([a-f0-9]{64})$/u;
|
|
41165
|
+
var CONTENT_LIFETIME_MILLISECONDS = 24 * 60 * 60 * 1e3;
|
|
41166
|
+
var metadataSchema2 = external_exports.strictObject({
|
|
41167
|
+
kind: external_exports.enum(["image", "audio", "resource"]),
|
|
41168
|
+
mediaType: external_exports.string().min(1).max(2048).regex(/^[\u0020-\u007e]+$/u),
|
|
41169
|
+
name: external_exports.string().min(1).max(500)
|
|
41170
|
+
});
|
|
41171
|
+
var UnretainedExternalContentStore = class {
|
|
41172
|
+
put = async ({ bytes, signal }) => {
|
|
41173
|
+
signal.throwIfAborted();
|
|
41174
|
+
return { byteLength: bytes.byteLength, key: createHash3("sha256").update(bytes).digest("hex") };
|
|
41175
|
+
};
|
|
41176
|
+
resolve = (_sessionId, _request, signal) => {
|
|
41177
|
+
signal.throwIfAborted();
|
|
41178
|
+
return Promise.resolve(null);
|
|
41179
|
+
};
|
|
41180
|
+
};
|
|
41181
|
+
async function atomicWrite(path3, bytes, signal) {
|
|
41182
|
+
const temporary = `${path3}.${randomUUID2()}.tmp`;
|
|
41183
|
+
try {
|
|
41184
|
+
await writeFile4(temporary, bytes, { mode: 384, signal });
|
|
41185
|
+
signal.throwIfAborted();
|
|
41186
|
+
await rename4(temporary, path3);
|
|
41187
|
+
} finally {
|
|
41188
|
+
await rm3(temporary, { force: true });
|
|
41189
|
+
}
|
|
41190
|
+
}
|
|
41191
|
+
var LocalExternalContentStore = class {
|
|
41192
|
+
#root;
|
|
41193
|
+
#entries = /* @__PURE__ */ new Map();
|
|
41194
|
+
#operations = /* @__PURE__ */ new Set();
|
|
41195
|
+
#lifetime = new AbortController();
|
|
41196
|
+
#expirationTimer;
|
|
41197
|
+
#cleanup = Promise.resolve();
|
|
41198
|
+
constructor(stateDirectory) {
|
|
41199
|
+
this.#root = join16(stateDirectory, "tmp", "session-content", randomUUID2());
|
|
41200
|
+
this.#expirationTimer = setInterval(() => {
|
|
41201
|
+
void this.#expire().catch(() => void 0);
|
|
41202
|
+
}, 6e4);
|
|
41203
|
+
this.#expirationTimer.unref();
|
|
41204
|
+
}
|
|
41205
|
+
#expire = () => {
|
|
41206
|
+
this.#cleanup = this.#cleanup.catch(() => void 0).then(async () => {
|
|
41207
|
+
await mkdir6(this.#root, { mode: 448, recursive: true });
|
|
41208
|
+
const now = /* @__PURE__ */ new Date();
|
|
41209
|
+
await utimes(this.#root, now, now);
|
|
41210
|
+
for (const directory of await readdir3(dirname5(this.#root), { withFileTypes: true })) {
|
|
41211
|
+
if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
|
|
41212
|
+
continue;
|
|
41213
|
+
}
|
|
41214
|
+
const path3 = join16(dirname5(this.#root), directory.name);
|
|
41215
|
+
if (path3 === this.#root) {
|
|
41216
|
+
continue;
|
|
41217
|
+
}
|
|
41218
|
+
const modified = await stat7(path3).then(
|
|
41219
|
+
(entry) => entry.mtimeMs,
|
|
41220
|
+
() => Date.now()
|
|
41221
|
+
);
|
|
41222
|
+
if (modified + CONTENT_LIFETIME_MILLISECONDS <= Date.now()) {
|
|
41223
|
+
await rm3(path3, { force: true, recursive: true });
|
|
41224
|
+
}
|
|
41225
|
+
}
|
|
41226
|
+
for (const [request, entry] of this.#entries) {
|
|
41227
|
+
if (entry.expiresAt > Date.now()) {
|
|
41228
|
+
continue;
|
|
41229
|
+
}
|
|
41230
|
+
await rm3(entry.path, { force: true });
|
|
41231
|
+
this.#entries.delete(request);
|
|
41232
|
+
}
|
|
41233
|
+
});
|
|
41234
|
+
return this.#cleanup;
|
|
41235
|
+
};
|
|
41236
|
+
#track = async (operation) => {
|
|
41237
|
+
this.#lifetime.signal.throwIfAborted();
|
|
41238
|
+
const pending = operation();
|
|
41239
|
+
this.#operations.add(pending);
|
|
41240
|
+
try {
|
|
41241
|
+
return await pending;
|
|
41242
|
+
} finally {
|
|
41243
|
+
this.#operations.delete(pending);
|
|
41244
|
+
}
|
|
41245
|
+
};
|
|
41246
|
+
put = (input2) => this.#track(() => this.#put(input2));
|
|
41247
|
+
#put = async ({ bytes, kind, mediaType, name, sessionId, signal }) => {
|
|
41248
|
+
const active = AbortSignal.any([signal, this.#lifetime.signal]);
|
|
41249
|
+
active.throwIfAborted();
|
|
41250
|
+
const metadata = metadataSchema2.parse({ kind, mediaType, name });
|
|
41251
|
+
const key = createHash3("sha256").update(bytes).digest("hex");
|
|
41252
|
+
const request = `mobius-content:${kind}:${key}`;
|
|
41253
|
+
const existing = this.#entries.get(request);
|
|
41254
|
+
if (existing !== void 0 && existing.expiresAt > Date.now()) {
|
|
41255
|
+
this.#entries.set(request, {
|
|
41256
|
+
...existing,
|
|
41257
|
+
expiresAt: Date.now() + CONTENT_LIFETIME_MILLISECONDS,
|
|
41258
|
+
sessions: /* @__PURE__ */ new Set([...existing.sessions, sessionId])
|
|
41259
|
+
});
|
|
41260
|
+
return { byteLength: existing.byteLength, key };
|
|
41261
|
+
}
|
|
41262
|
+
await this.#expire();
|
|
41263
|
+
active.throwIfAborted();
|
|
41264
|
+
const directory = join16(this.#root, kind);
|
|
41265
|
+
await mkdir6(directory, { mode: 448, recursive: true });
|
|
41266
|
+
active.throwIfAborted();
|
|
41267
|
+
const path3 = join16(directory, key);
|
|
41268
|
+
const write = atomicWrite(path3, bytes, active);
|
|
41269
|
+
await write;
|
|
41270
|
+
active.throwIfAborted();
|
|
41271
|
+
const retained = this.#entries.get(request);
|
|
41272
|
+
this.#entries.set(request, {
|
|
41273
|
+
byteLength: bytes.byteLength,
|
|
41274
|
+
expiresAt: Date.now() + CONTENT_LIFETIME_MILLISECONDS,
|
|
41275
|
+
mediaType: metadata.mediaType,
|
|
41276
|
+
name: metadata.name,
|
|
41277
|
+
path: path3,
|
|
41278
|
+
sessions: /* @__PURE__ */ new Set([...retained?.sessions ?? [], sessionId])
|
|
41279
|
+
});
|
|
41280
|
+
return { byteLength: bytes.byteLength, key };
|
|
41281
|
+
};
|
|
41282
|
+
resolve = (sessionId, request, signal) => this.#track(() => this.#resolve(sessionId, request, AbortSignal.any([signal, this.#lifetime.signal])));
|
|
41283
|
+
#resolve = async (sessionId, request, signal) => {
|
|
41284
|
+
signal.throwIfAborted();
|
|
41285
|
+
this.#lifetime.signal.throwIfAborted();
|
|
41286
|
+
if (!contentRequest.test(request)) {
|
|
41287
|
+
return null;
|
|
41288
|
+
}
|
|
41289
|
+
const entry = this.#entries.get(request);
|
|
41290
|
+
if (entry === void 0 || !entry.sessions.has(sessionId)) {
|
|
41291
|
+
return null;
|
|
41292
|
+
}
|
|
41293
|
+
if (entry.expiresAt <= Date.now()) {
|
|
41294
|
+
await this.#expire();
|
|
41295
|
+
signal.throwIfAborted();
|
|
41296
|
+
return null;
|
|
41297
|
+
}
|
|
41298
|
+
try {
|
|
41299
|
+
const [resolvedDirectory, resolvedPath, file2] = await Promise.all([
|
|
41300
|
+
realpath8(dirname5(entry.path)),
|
|
41301
|
+
realpath8(entry.path),
|
|
41302
|
+
lstat(entry.path)
|
|
41303
|
+
]);
|
|
41304
|
+
signal.throwIfAborted();
|
|
41305
|
+
if (!file2.isFile() || file2.isSymbolicLink() || dirname5(resolvedPath) !== resolvedDirectory) {
|
|
41306
|
+
return null;
|
|
41307
|
+
}
|
|
41308
|
+
return { mediaType: entry.mediaType, name: entry.name, path: resolvedPath };
|
|
41309
|
+
} catch {
|
|
41310
|
+
signal.throwIfAborted();
|
|
41311
|
+
return null;
|
|
41312
|
+
}
|
|
41313
|
+
};
|
|
41314
|
+
[Symbol.asyncDispose] = async () => {
|
|
41315
|
+
clearInterval(this.#expirationTimer);
|
|
41316
|
+
this.#lifetime.abort();
|
|
41317
|
+
await Promise.allSettled([...this.#operations, this.#cleanup]);
|
|
41318
|
+
this.#entries.clear();
|
|
41319
|
+
await rm3(this.#root, { force: true, recursive: true });
|
|
41320
|
+
};
|
|
41321
|
+
};
|
|
41322
|
+
|
|
40883
41323
|
// src/native-sessions/chat-agent.ts
|
|
40884
41324
|
function supportsNativeChat(agentId) {
|
|
40885
41325
|
return agentId === "codex" || agentId === "claude" || agentId === "opencode" || agentId === "pi";
|
|
@@ -41096,7 +41536,7 @@ var AgentRuntimeManager = class {
|
|
|
41096
41536
|
touch: this.#processes.touch,
|
|
41097
41537
|
changed: this.#processes.notifyChanged
|
|
41098
41538
|
});
|
|
41099
|
-
#queryProcesses
|
|
41539
|
+
#queryProcesses;
|
|
41100
41540
|
#executions = new ActiveExecutions();
|
|
41101
41541
|
#agentSettingsObserver = new NullAcpSessionObserver();
|
|
41102
41542
|
#nativeOperations = /* @__PURE__ */ new Set();
|
|
@@ -41104,13 +41544,16 @@ var AgentRuntimeManager = class {
|
|
|
41104
41544
|
#nativeHistoryReader;
|
|
41105
41545
|
#sessionIdentity;
|
|
41106
41546
|
#onSessionStatusChanged;
|
|
41547
|
+
#contentExternalizer;
|
|
41107
41548
|
#observer;
|
|
41108
|
-
constructor(observer = new NullAcpSessionObserver(), store = new MemoryAcpSessionStore(), nativeHistoryReader = null, sessionIdentity = "assigned", onSessionStatusChanged = () => void 0) {
|
|
41549
|
+
constructor(observer = new NullAcpSessionObserver(), store = new MemoryAcpSessionStore(), nativeHistoryReader = null, sessionIdentity = "assigned", onSessionStatusChanged = () => void 0, contentExternalizer = new AcpContentExternalizer(new UnretainedExternalContentStore())) {
|
|
41109
41550
|
this.#observer = observer;
|
|
41110
41551
|
this.#store = store;
|
|
41111
41552
|
this.#nativeHistoryReader = nativeHistoryReader;
|
|
41112
41553
|
this.#sessionIdentity = sessionIdentity;
|
|
41113
41554
|
this.#onSessionStatusChanged = onSessionStatusChanged;
|
|
41555
|
+
this.#contentExternalizer = contentExternalizer;
|
|
41556
|
+
this.#queryProcesses = new AgentQueryProcesses(this.#processes, contentExternalizer);
|
|
41114
41557
|
}
|
|
41115
41558
|
setObserver = (observer) => {
|
|
41116
41559
|
this.#observer = observer;
|
|
@@ -41151,7 +41594,8 @@ var AgentRuntimeManager = class {
|
|
|
41151
41594
|
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,
|
|
41152
41595
|
() => this.#observer,
|
|
41153
41596
|
this.#store,
|
|
41154
|
-
metrics
|
|
41597
|
+
metrics,
|
|
41598
|
+
this.#contentExternalizer
|
|
41155
41599
|
)
|
|
41156
41600
|
);
|
|
41157
41601
|
});
|
|
@@ -41166,7 +41610,13 @@ var AgentRuntimeManager = class {
|
|
|
41166
41610
|
this.#store.remove(options.sessionId);
|
|
41167
41611
|
return await this.#startRetainedSessionProcess(
|
|
41168
41612
|
options,
|
|
41169
|
-
async () => await AgentSession.start(
|
|
41613
|
+
async () => await AgentSession.start(
|
|
41614
|
+
options,
|
|
41615
|
+
() => this.#observer,
|
|
41616
|
+
this.#store,
|
|
41617
|
+
metrics,
|
|
41618
|
+
this.#contentExternalizer
|
|
41619
|
+
)
|
|
41170
41620
|
);
|
|
41171
41621
|
});
|
|
41172
41622
|
}
|
|
@@ -41176,7 +41626,13 @@ var AgentRuntimeManager = class {
|
|
|
41176
41626
|
await this.#retireSessionProcess(options.sessionId, existing, async () => await existing.close());
|
|
41177
41627
|
const runtime = await this.#startRetainedSessionProcess(
|
|
41178
41628
|
options,
|
|
41179
|
-
async () => await AgentSession.start(
|
|
41629
|
+
async () => await AgentSession.start(
|
|
41630
|
+
options,
|
|
41631
|
+
() => this.#observer,
|
|
41632
|
+
this.#store,
|
|
41633
|
+
unmeasuredOperationMetrics,
|
|
41634
|
+
this.#contentExternalizer
|
|
41635
|
+
)
|
|
41180
41636
|
);
|
|
41181
41637
|
try {
|
|
41182
41638
|
for (const desired of desiredConfigOptions) {
|
|
@@ -41272,7 +41728,9 @@ var AgentRuntimeManager = class {
|
|
|
41272
41728
|
sessionId: `agent-settings-${crypto.randomUUID()}`
|
|
41273
41729
|
},
|
|
41274
41730
|
() => this.#agentSettingsObserver,
|
|
41275
|
-
new MemoryAcpSessionStore()
|
|
41731
|
+
new MemoryAcpSessionStore(),
|
|
41732
|
+
unmeasuredOperationMetrics,
|
|
41733
|
+
this.#contentExternalizer
|
|
41276
41734
|
),
|
|
41277
41735
|
async (runtime) => {
|
|
41278
41736
|
const prepared = runtime.prepared();
|
|
@@ -41781,7 +42239,7 @@ var AgentCatalogPublishError = class extends Error {
|
|
|
41781
42239
|
this.name = "AgentCatalogPublishError";
|
|
41782
42240
|
}
|
|
41783
42241
|
};
|
|
41784
|
-
function
|
|
42242
|
+
function isRecord11(value) {
|
|
41785
42243
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41786
42244
|
}
|
|
41787
42245
|
function isSafeRelayErrorMessage(value) {
|
|
@@ -41794,7 +42252,7 @@ async function rejectedCatalogError(response) {
|
|
|
41794
42252
|
} catch {
|
|
41795
42253
|
return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
|
|
41796
42254
|
}
|
|
41797
|
-
if (!
|
|
42255
|
+
if (!isRecord11(value) || !isRecord11(value["error"])) {
|
|
41798
42256
|
return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
|
|
41799
42257
|
}
|
|
41800
42258
|
const code = value["error"]["code"];
|
|
@@ -42325,9 +42783,9 @@ var FixedInstallationExecutor = class {
|
|
|
42325
42783
|
};
|
|
42326
42784
|
|
|
42327
42785
|
// src/authorization/workspace-directory.ts
|
|
42328
|
-
import { readdir as
|
|
42786
|
+
import { readdir as readdir4, realpath as realpath9, stat as stat8 } from "node:fs/promises";
|
|
42329
42787
|
import { homedir as homedir2 } from "node:os";
|
|
42330
|
-
import { basename as basename4, dirname as
|
|
42788
|
+
import { basename as basename4, dirname as dirname6, isAbsolute as isAbsolute9, join as join17, normalize as normalize3, relative as relative4 } from "node:path";
|
|
42331
42789
|
|
|
42332
42790
|
// src/authorization/local-authorization-error.ts
|
|
42333
42791
|
var LocalAuthorizationError = class extends Error {
|
|
@@ -42406,9 +42864,9 @@ var WorkspaceDirectoryService = class {
|
|
|
42406
42864
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
42407
42865
|
}
|
|
42408
42866
|
try {
|
|
42409
|
-
const target = await
|
|
42867
|
+
const target = await realpath9(requested);
|
|
42410
42868
|
signal.throwIfAborted();
|
|
42411
|
-
const metadata = await
|
|
42869
|
+
const metadata = await stat8(target);
|
|
42412
42870
|
signal.throwIfAborted();
|
|
42413
42871
|
if (!isAbsolute9(target) || normalize3(target) !== target || !metadata.isDirectory()) {
|
|
42414
42872
|
throw new LocalAuthorizationError("The selected location is not a directory");
|
|
@@ -42445,7 +42903,7 @@ var WorkspaceDirectoryService = class {
|
|
|
42445
42903
|
list = async (bindingId, id, signal) => {
|
|
42446
42904
|
const target = await this.resolve(bindingId, id, signal);
|
|
42447
42905
|
try {
|
|
42448
|
-
const children = await
|
|
42906
|
+
const children = await readdir4(target, { withFileTypes: true });
|
|
42449
42907
|
signal.throwIfAborted();
|
|
42450
42908
|
const entries = [];
|
|
42451
42909
|
for (const child2 of children) {
|
|
@@ -42456,7 +42914,7 @@ var WorkspaceDirectoryService = class {
|
|
|
42456
42914
|
continue;
|
|
42457
42915
|
}
|
|
42458
42916
|
try {
|
|
42459
|
-
const path3 = await this.resolvePath(
|
|
42917
|
+
const path3 = await this.resolvePath(join17(target, child2.name), signal);
|
|
42460
42918
|
entries.push({ directoryId: encodePath(path3), name: child2.name });
|
|
42461
42919
|
} catch (cause) {
|
|
42462
42920
|
signal.throwIfAborted();
|
|
@@ -42466,7 +42924,7 @@ var WorkspaceDirectoryService = class {
|
|
|
42466
42924
|
}
|
|
42467
42925
|
}
|
|
42468
42926
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
42469
|
-
const parent =
|
|
42927
|
+
const parent = dirname6(target);
|
|
42470
42928
|
return new WorkspaceDirectoryListing(
|
|
42471
42929
|
id,
|
|
42472
42930
|
this.label(target),
|
|
@@ -42492,15 +42950,15 @@ var WorkspaceDirectoryService = class {
|
|
|
42492
42950
|
|
|
42493
42951
|
// src/daemon-diagnostic-log.ts
|
|
42494
42952
|
import { appendFileSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, statSync as statSync3, writeFileSync } from "node:fs";
|
|
42495
|
-
import { join as
|
|
42953
|
+
import { join as join18 } from "node:path";
|
|
42496
42954
|
var MAXIMUM_DAEMON_LOG_BYTES = 1 * 1024 * 1024;
|
|
42497
42955
|
var DaemonDiagnosticLog = class {
|
|
42498
42956
|
#directory;
|
|
42499
42957
|
#path;
|
|
42500
42958
|
#maximumBytes;
|
|
42501
42959
|
constructor(stateDirectory, maximumBytes = MAXIMUM_DAEMON_LOG_BYTES) {
|
|
42502
|
-
this.#directory =
|
|
42503
|
-
this.#path =
|
|
42960
|
+
this.#directory = join18(stateDirectory, "logs");
|
|
42961
|
+
this.#path = join18(this.#directory, "daemon.log");
|
|
42504
42962
|
this.#maximumBytes = maximumBytes;
|
|
42505
42963
|
}
|
|
42506
42964
|
record = (diagnostic) => {
|
|
@@ -42545,7 +43003,7 @@ import { WebSocket as WebSocket2 } from "undici";
|
|
|
42545
43003
|
import { WebSocket } from "undici";
|
|
42546
43004
|
|
|
42547
43005
|
// src/prompt-artifact-resolver.ts
|
|
42548
|
-
import { createHash as
|
|
43006
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
42549
43007
|
import { fetch as fetch4 } from "undici";
|
|
42550
43008
|
var ARTIFACT_SCHEME = "mobius-artifact:";
|
|
42551
43009
|
var ARTIFACT_DOWNLOAD_TIMEOUT_MILLISECONDS = 2e4;
|
|
@@ -42683,7 +43141,7 @@ async function download(config2, command, reference, signal) {
|
|
|
42683
43141
|
);
|
|
42684
43142
|
}
|
|
42685
43143
|
const bytes = await responseBytes(response, reference.byteLength, requestSignal);
|
|
42686
|
-
if (
|
|
43144
|
+
if (createHash4("sha256").update(bytes).digest("hex") !== reference.sha256) {
|
|
42687
43145
|
throw new PromptArtifactError(
|
|
42688
43146
|
"artifact_integrity_failed",
|
|
42689
43147
|
"The prompt artifact failed integrity validation"
|
|
@@ -42988,7 +43446,7 @@ var DaemonInstallationObserver = class {
|
|
|
42988
43446
|
};
|
|
42989
43447
|
|
|
42990
43448
|
// src/daemon-active-turn.ts
|
|
42991
|
-
import { randomUUID as
|
|
43449
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
42992
43450
|
function activeMessageCharacters(message) {
|
|
42993
43451
|
return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
|
|
42994
43452
|
}
|
|
@@ -43022,7 +43480,7 @@ var ActiveDaemonTurn = class {
|
|
|
43022
43480
|
#timeline;
|
|
43023
43481
|
#sequence = 0;
|
|
43024
43482
|
#interaction = null;
|
|
43025
|
-
#epoch = decodeIdentifier(
|
|
43483
|
+
#epoch = decodeIdentifier(randomUUID3());
|
|
43026
43484
|
constructor(command, attemptId) {
|
|
43027
43485
|
this.attemptId = attemptId;
|
|
43028
43486
|
this.command = command;
|
|
@@ -43084,7 +43542,7 @@ var ActiveDaemonTurn = class {
|
|
|
43084
43542
|
if (!this.#activities.has(event.activityId)) {
|
|
43085
43543
|
this.#timeline = [
|
|
43086
43544
|
...this.#timeline,
|
|
43087
|
-
{ activityId: event.activityId, id: decodeIdentifier(
|
|
43545
|
+
{ activityId: event.activityId, id: decodeIdentifier(randomUUID3()), kind: "activity" }
|
|
43088
43546
|
];
|
|
43089
43547
|
}
|
|
43090
43548
|
this.#activities.set(event.activityId, {
|
|
@@ -43105,7 +43563,7 @@ var ActiveDaemonTurn = class {
|
|
|
43105
43563
|
if (previous === void 0) {
|
|
43106
43564
|
this.#timeline = [
|
|
43107
43565
|
...this.#timeline,
|
|
43108
|
-
{ activityId: event.activityId, id: decodeIdentifier(
|
|
43566
|
+
{ activityId: event.activityId, id: decodeIdentifier(randomUUID3()), kind: "activity" }
|
|
43109
43567
|
];
|
|
43110
43568
|
}
|
|
43111
43569
|
this.#activities.set(event.activityId, {
|
|
@@ -43130,7 +43588,7 @@ var ActiveDaemonTurn = class {
|
|
|
43130
43588
|
...this.#timeline,
|
|
43131
43589
|
{
|
|
43132
43590
|
content: /* @__PURE__ */ new Map([[event.contentId, event.content]]),
|
|
43133
|
-
id: decodeIdentifier(
|
|
43591
|
+
id: decodeIdentifier(randomUUID3()),
|
|
43134
43592
|
kind: "message",
|
|
43135
43593
|
sourceMessageId: event.messageId,
|
|
43136
43594
|
text: ""
|
|
@@ -43170,7 +43628,7 @@ var ActiveDaemonTurn = class {
|
|
|
43170
43628
|
...this.#timeline,
|
|
43171
43629
|
{
|
|
43172
43630
|
content: /* @__PURE__ */ new Map(),
|
|
43173
|
-
id: decodeIdentifier(
|
|
43631
|
+
id: decodeIdentifier(randomUUID3()),
|
|
43174
43632
|
kind: "message",
|
|
43175
43633
|
sourceMessageId: messageId,
|
|
43176
43634
|
text: remaining.slice(0, ACTIVE_TURN_TEXT_CHUNK_LIMIT)
|
|
@@ -44146,7 +44604,7 @@ var readCodexFullHistory = async (agent, cwd, nativeSessionId, signal, nativeTur
|
|
|
44146
44604
|
});
|
|
44147
44605
|
|
|
44148
44606
|
// src/native-sessions/service.ts
|
|
44149
|
-
import { randomUUID as
|
|
44607
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
44150
44608
|
import { basename as basename5 } from "node:path";
|
|
44151
44609
|
|
|
44152
44610
|
// src/native-sessions/acp-history.ts
|
|
@@ -44361,7 +44819,7 @@ var NativeSessionService = class {
|
|
|
44361
44819
|
if (authorized === null) {
|
|
44362
44820
|
return null;
|
|
44363
44821
|
}
|
|
44364
|
-
const entryId = decodeIdentifier(
|
|
44822
|
+
const entryId = decodeIdentifier(randomUUID4());
|
|
44365
44823
|
if (this.#entries.size >= 5e3) {
|
|
44366
44824
|
this.#entries.clear();
|
|
44367
44825
|
}
|
|
@@ -44417,7 +44875,7 @@ var NativeSessionService = class {
|
|
|
44417
44875
|
"invalid_native_session_response"
|
|
44418
44876
|
);
|
|
44419
44877
|
}
|
|
44420
|
-
nextCursor = decodeIdentifier(
|
|
44878
|
+
nextCursor = decodeIdentifier(randomUUID4());
|
|
44421
44879
|
if (this.#cursors.size >= 500) {
|
|
44422
44880
|
this.#cursors.clear();
|
|
44423
44881
|
}
|
|
@@ -44699,7 +45157,7 @@ var NativeSessionService = class {
|
|
|
44699
45157
|
};
|
|
44700
45158
|
|
|
44701
45159
|
// src/relay-connection/daemon-operation-state.ts
|
|
44702
|
-
import { createHash as
|
|
45160
|
+
import { createHash as createHash5, randomUUID as randomUUID5 } from "node:crypto";
|
|
44703
45161
|
var MAX_TERMINAL_RECEIPTS = 1024;
|
|
44704
45162
|
function isTerminal(state) {
|
|
44705
45163
|
return state === "succeeded" || state === "failed" || state === "cancelled";
|
|
@@ -44708,7 +45166,7 @@ var DaemonOperationState = class {
|
|
|
44708
45166
|
#executions = /* @__PURE__ */ new Map();
|
|
44709
45167
|
#terminalCount = 0;
|
|
44710
45168
|
claimExecution = (commandId, sessionId, commandJson) => {
|
|
44711
|
-
const commandHash =
|
|
45169
|
+
const commandHash = createHash5("sha256").update(commandJson).digest("hex");
|
|
44712
45170
|
const existing = this.#executions.get(commandId);
|
|
44713
45171
|
if (existing !== void 0) {
|
|
44714
45172
|
if (existing.sessionId !== sessionId || existing.commandHash !== commandHash) {
|
|
@@ -44716,7 +45174,7 @@ var DaemonOperationState = class {
|
|
|
44716
45174
|
}
|
|
44717
45175
|
return { attemptId: existing.attemptId, commandId, kind: "duplicate", state: existing.state };
|
|
44718
45176
|
}
|
|
44719
|
-
const attemptId =
|
|
45177
|
+
const attemptId = randomUUID5();
|
|
44720
45178
|
this.#executions.set(commandId, { attemptId, commandHash, sessionId, state: "dispatching" });
|
|
44721
45179
|
return { attemptId, commandId, kind: "accepted", state: "dispatching" };
|
|
44722
45180
|
};
|
|
@@ -45052,7 +45510,7 @@ function createAgentCatalogRefreshHandler(dependencies) {
|
|
|
45052
45510
|
import { WebSocket as WebSocket4 } from "undici";
|
|
45053
45511
|
|
|
45054
45512
|
// src/agent-catalog/discover-agent-settings.ts
|
|
45055
|
-
import { createHash as
|
|
45513
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
45056
45514
|
|
|
45057
45515
|
// src/agent-catalog/agent-settings-base.ts
|
|
45058
45516
|
var AgentSettingsConfigurationError = class extends Error {
|
|
@@ -45516,7 +45974,7 @@ function settingsRevision(agent, reportedAgentVersion, settings, modelEffort) {
|
|
|
45516
45974
|
unsupportedModelIds: modelEffort.unsupportedModelIds,
|
|
45517
45975
|
valuesByModel: {}
|
|
45518
45976
|
};
|
|
45519
|
-
return
|
|
45977
|
+
return createHash6("sha256").update(
|
|
45520
45978
|
JSON.stringify({
|
|
45521
45979
|
adapterVersion: agent.kind === "acp-adapter-process" ? agent.adapterVersion : agent.agentVersion,
|
|
45522
45980
|
agentId: agent.id,
|
|
@@ -45667,7 +46125,7 @@ function createAgentSettingsDiscoveryHandler(dependencies) {
|
|
|
45667
46125
|
|
|
45668
46126
|
// src/artifacts/local-file-streamer.ts
|
|
45669
46127
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
45670
|
-
import { realpath as
|
|
46128
|
+
import { realpath as realpath10, stat as stat9 } from "node:fs/promises";
|
|
45671
46129
|
import { basename as basename6, isAbsolute as isAbsolute10, normalize as normalize4, resolve as resolve7 } from "node:path";
|
|
45672
46130
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
45673
46131
|
var CHUNK_BYTES = 192 * 1024;
|
|
@@ -45695,7 +46153,7 @@ async function resolveFile(value, workingDirectory, signal) {
|
|
|
45695
46153
|
return null;
|
|
45696
46154
|
}
|
|
45697
46155
|
try {
|
|
45698
|
-
const target = await
|
|
46156
|
+
const target = await realpath10(requested);
|
|
45699
46157
|
signal.throwIfAborted();
|
|
45700
46158
|
return isAbsolute10(target) && normalize4(target) === target ? target : null;
|
|
45701
46159
|
} catch {
|
|
@@ -45703,23 +46161,24 @@ async function resolveFile(value, workingDirectory, signal) {
|
|
|
45703
46161
|
return null;
|
|
45704
46162
|
}
|
|
45705
46163
|
}
|
|
45706
|
-
async function streamLocalFile(command, send2, signal, workingDirectory) {
|
|
45707
|
-
const
|
|
46164
|
+
async function streamLocalFile(command, send2, signal, workingDirectory, externalContent) {
|
|
46165
|
+
const external = await externalContent.resolve(command.sessionId, command.path, signal);
|
|
46166
|
+
const target = external?.path ?? await resolveFile(command.path, workingDirectory, signal);
|
|
45708
46167
|
if (target === null) {
|
|
45709
46168
|
throw new Error("The local file is unavailable");
|
|
45710
46169
|
}
|
|
45711
|
-
const before = await
|
|
46170
|
+
const before = await stat9(target);
|
|
45712
46171
|
signal.throwIfAborted();
|
|
45713
46172
|
if (!before.isFile() || before.size < 1 || before.size > command.maxBytes) {
|
|
45714
46173
|
throw new Error("The local file is too large to read");
|
|
45715
46174
|
}
|
|
45716
|
-
const raster = await readLocalRaster(target, signal);
|
|
46175
|
+
const raster = external === null ? await readLocalRaster(target, signal) : null;
|
|
45717
46176
|
send2({
|
|
45718
46177
|
byteLength: before.size,
|
|
45719
46178
|
kind: FILE_BEGIN_KIND,
|
|
45720
|
-
mediaType: raster?.mimeType ?? "application/octet-stream",
|
|
46179
|
+
mediaType: external?.mediaType ?? raster?.mimeType ?? "application/octet-stream",
|
|
45721
46180
|
modifiedAt: before.mtime.toISOString(),
|
|
45722
|
-
name: basename6(target) || "file",
|
|
46181
|
+
name: external?.name ?? (basename6(target) || "file"),
|
|
45723
46182
|
requestId: command.requestId,
|
|
45724
46183
|
sessionId: command.sessionId
|
|
45725
46184
|
});
|
|
@@ -45736,7 +46195,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
|
|
|
45736
46195
|
});
|
|
45737
46196
|
sequence += 1;
|
|
45738
46197
|
}
|
|
45739
|
-
const after = await
|
|
46198
|
+
const after = await stat9(target);
|
|
45740
46199
|
signal.throwIfAborted();
|
|
45741
46200
|
if (after.size !== before.size || after.mtimeMs !== before.mtimeMs) {
|
|
45742
46201
|
throw new Error("The local file changed during transfer");
|
|
@@ -45749,7 +46208,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
|
|
|
45749
46208
|
}
|
|
45750
46209
|
|
|
45751
46210
|
// src/daemon-history-commands.ts
|
|
45752
|
-
import { createHash as
|
|
46211
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
45753
46212
|
|
|
45754
46213
|
// src/authorization/resolve-session-directories.ts
|
|
45755
46214
|
import { basename as basename7 } from "node:path";
|
|
@@ -46143,7 +46602,7 @@ async function executeSessionLiveHistoryPageLoad(socket, command, config2, direc
|
|
|
46143
46602
|
}
|
|
46144
46603
|
function replayEvent(sessionId, position, update) {
|
|
46145
46604
|
const encoded = JSON.stringify(update);
|
|
46146
|
-
const eventId = `native-${
|
|
46605
|
+
const eventId = `native-${createHash7("sha256").update(sessionId).update(":").update(position.toString()).update(":").update(encoded).digest("hex")}`;
|
|
46147
46606
|
return {
|
|
46148
46607
|
eventId,
|
|
46149
46608
|
payload: update,
|
|
@@ -46226,7 +46685,7 @@ async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, dir
|
|
|
46226
46685
|
}
|
|
46227
46686
|
|
|
46228
46687
|
// src/acp/session-config/apply-session-configuration.ts
|
|
46229
|
-
import { randomUUID as
|
|
46688
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
46230
46689
|
function invalidSessionConfiguration(message) {
|
|
46231
46690
|
return new AcpExecutionError(message, {}, "invalid_session_configuration");
|
|
46232
46691
|
}
|
|
@@ -46367,7 +46826,7 @@ async function applySessionConfigurationSelection(sessions, audit, options, sele
|
|
|
46367
46826
|
booleanValue: selection.booleanValue,
|
|
46368
46827
|
configId: selection.configId,
|
|
46369
46828
|
cwd,
|
|
46370
|
-
requestId: `cfg_${
|
|
46829
|
+
requestId: `cfg_${randomUUID6()}`,
|
|
46371
46830
|
sessionId,
|
|
46372
46831
|
signal,
|
|
46373
46832
|
value: selection.value,
|
|
@@ -47041,6 +47500,7 @@ function createDaemonCommandHandler({
|
|
|
47041
47500
|
operations,
|
|
47042
47501
|
publisher,
|
|
47043
47502
|
eventLogV2,
|
|
47503
|
+
externalContent,
|
|
47044
47504
|
activeTurns,
|
|
47045
47505
|
diagnostics,
|
|
47046
47506
|
socket,
|
|
@@ -47149,7 +47609,8 @@ function createDaemonCommandHandler({
|
|
|
47149
47609
|
command2,
|
|
47150
47610
|
(message2) => send(socket, message2),
|
|
47151
47611
|
signal,
|
|
47152
|
-
sessions.findSessions([command2.sessionId])[0]?.cwd ?? null
|
|
47612
|
+
sessions.findSessions([command2.sessionId])[0]?.cwd ?? null,
|
|
47613
|
+
externalContent
|
|
47153
47614
|
).catch((error62) => {
|
|
47154
47615
|
if (socket.readyState !== WebSocket6.OPEN || signal.aborted) {
|
|
47155
47616
|
return;
|
|
@@ -47488,7 +47949,7 @@ function connectRelay(url2, signal) {
|
|
|
47488
47949
|
}
|
|
47489
47950
|
|
|
47490
47951
|
// src/relay-connection/liveness.ts
|
|
47491
|
-
import { randomUUID as
|
|
47952
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
47492
47953
|
var HEARTBEAT_ACK_TIMEOUT_MILLISECONDS = 1e4;
|
|
47493
47954
|
var HEARTBEAT_INTERVAL_MILLISECONDS = 2e4;
|
|
47494
47955
|
var RelayLivenessState = class {
|
|
@@ -47577,7 +48038,7 @@ var RelayConnectionLiveness = class {
|
|
|
47577
48038
|
}
|
|
47578
48039
|
throw new Error("Heartbeat was scheduled in an invalid state");
|
|
47579
48040
|
}
|
|
47580
|
-
const heartbeatId =
|
|
48041
|
+
const heartbeatId = randomUUID7();
|
|
47581
48042
|
this.#state = new AwaitingHeartbeatAckState(
|
|
47582
48043
|
heartbeatId,
|
|
47583
48044
|
this.#timer.schedule(this.#handleTimeout, HEARTBEAT_ACK_TIMEOUT_MILLISECONDS)
|
|
@@ -47617,6 +48078,7 @@ async function runRelayConnection({
|
|
|
47617
48078
|
operations,
|
|
47618
48079
|
publisher,
|
|
47619
48080
|
eventLogV2,
|
|
48081
|
+
externalContent,
|
|
47620
48082
|
activeTurns,
|
|
47621
48083
|
connectionEpoch,
|
|
47622
48084
|
diagnostics,
|
|
@@ -47640,6 +48102,7 @@ async function runRelayConnection({
|
|
|
47640
48102
|
operations,
|
|
47641
48103
|
publisher,
|
|
47642
48104
|
eventLogV2,
|
|
48105
|
+
externalContent,
|
|
47643
48106
|
activeTurns,
|
|
47644
48107
|
diagnostics,
|
|
47645
48108
|
socket,
|
|
@@ -48118,7 +48581,7 @@ async function installDetectedAgentIntegrations(config2, installations, signal)
|
|
|
48118
48581
|
{
|
|
48119
48582
|
agentId: agent.id,
|
|
48120
48583
|
kind: AGENT_INSTALL_REQUEST_KIND,
|
|
48121
|
-
requestId: `automatic-integration-${
|
|
48584
|
+
requestId: `automatic-integration-${randomUUID8()}`
|
|
48122
48585
|
},
|
|
48123
48586
|
signal
|
|
48124
48587
|
);
|
|
@@ -48137,8 +48600,9 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
|
|
|
48137
48600
|
stateDirectory
|
|
48138
48601
|
});
|
|
48139
48602
|
const sessionStore = new SqliteAcpSessionStore(
|
|
48140
|
-
|
|
48603
|
+
join19(stateDirectory, "sessions", `${createHash8("sha256").update(config2.channelId).digest("hex")}.sqlite`)
|
|
48141
48604
|
);
|
|
48605
|
+
await using externalContent = new LocalExternalContentStore(stateDirectory);
|
|
48142
48606
|
const operations = new DaemonOperationState();
|
|
48143
48607
|
const publisher = new DaemonSessionEventPublisher(sessionStore);
|
|
48144
48608
|
const eventLogV2 = new DaemonSessionEventLogV2(publisher, sessionStore);
|
|
@@ -48159,7 +48623,8 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
|
|
|
48159
48623
|
)).history : null
|
|
48160
48624
|
},
|
|
48161
48625
|
"native",
|
|
48162
|
-
publisher.publishStatus
|
|
48626
|
+
publisher.publishStatus,
|
|
48627
|
+
new AcpContentExternalizer(externalContent)
|
|
48163
48628
|
);
|
|
48164
48629
|
const directories = new WorkspaceDirectoryService(config2.bindingId, config2.defaultWorkspace);
|
|
48165
48630
|
const installationObserver = new DaemonInstallationObserver();
|
|
@@ -48273,6 +48738,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
|
|
|
48273
48738
|
operations,
|
|
48274
48739
|
publisher,
|
|
48275
48740
|
eventLogV2,
|
|
48741
|
+
externalContent,
|
|
48276
48742
|
activeTurns,
|
|
48277
48743
|
connectionEpoch,
|
|
48278
48744
|
diagnostics,
|
|
@@ -48394,10 +48860,10 @@ var START_TIMEOUT_MILLISECONDS = 12e4;
|
|
|
48394
48860
|
var MAXIMUM_MESSAGE_BYTES = 64 * 1024;
|
|
48395
48861
|
var CONNECTION_ID_PATTERN2 = /^mcn_[a-f0-9]{32}$/;
|
|
48396
48862
|
async function acquireManagerLock(stateDirectory) {
|
|
48397
|
-
const path3 =
|
|
48863
|
+
const path3 = join20(stateDirectory, "manager.lock");
|
|
48398
48864
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
48399
48865
|
try {
|
|
48400
|
-
await
|
|
48866
|
+
await writeFile5(path3, `${process.pid.toString()}
|
|
48401
48867
|
`, { flag: "wx", mode: 384 });
|
|
48402
48868
|
return async () => await unlink2(path3).catch(() => void 0);
|
|
48403
48869
|
} catch (cause) {
|
|
@@ -48421,15 +48887,15 @@ async function acquireManagerLock(stateDirectory) {
|
|
|
48421
48887
|
}
|
|
48422
48888
|
return null;
|
|
48423
48889
|
}
|
|
48424
|
-
function
|
|
48890
|
+
function isRecord12(value) {
|
|
48425
48891
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
48426
48892
|
}
|
|
48427
48893
|
function controlSocketPath(stateDirectory) {
|
|
48428
|
-
const installationHash =
|
|
48429
|
-
return process.platform === "win32" ? `\\\\.\\pipe\\mobius-${installationHash}` :
|
|
48894
|
+
const installationHash = createHash9("sha256").update(stateDirectory).digest("hex").slice(0, 32);
|
|
48895
|
+
return process.platform === "win32" ? `\\\\.\\pipe\\mobius-${installationHash}` : join20(tmpdir(), `mobius-${installationHash}.sock`);
|
|
48430
48896
|
}
|
|
48431
48897
|
function controlTokenPath(stateDirectory) {
|
|
48432
|
-
return
|
|
48898
|
+
return join20(stateDirectory, "manager.token");
|
|
48433
48899
|
}
|
|
48434
48900
|
async function readOrCreateControlToken(stateDirectory) {
|
|
48435
48901
|
const path3 = controlTokenPath(stateDirectory);
|
|
@@ -48442,7 +48908,7 @@ async function readOrCreateControlToken(stateDirectory) {
|
|
|
48442
48908
|
}
|
|
48443
48909
|
const token = randomBytes(32).toString("base64url");
|
|
48444
48910
|
try {
|
|
48445
|
-
await
|
|
48911
|
+
await writeFile5(path3, `${token}
|
|
48446
48912
|
`, { flag: "wx", mode: 384 });
|
|
48447
48913
|
return token;
|
|
48448
48914
|
} catch (cause) {
|
|
@@ -48456,7 +48922,7 @@ function isNodeError2(error62, code) {
|
|
|
48456
48922
|
return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === code;
|
|
48457
48923
|
}
|
|
48458
48924
|
function decodeCommand(value, expectedToken) {
|
|
48459
|
-
if (!
|
|
48925
|
+
if (!isRecord12(value) || value["token"] !== expectedToken || typeof value["kind"] !== "string") {
|
|
48460
48926
|
throw new Error("The manager request is invalid");
|
|
48461
48927
|
}
|
|
48462
48928
|
if (value["kind"] === "list" || value["kind"] === "stop") {
|
|
@@ -48475,7 +48941,7 @@ function decodeCommand(value, expectedToken) {
|
|
|
48475
48941
|
throw new Error("The manager command is unsupported");
|
|
48476
48942
|
}
|
|
48477
48943
|
function decodeResponse(value) {
|
|
48478
|
-
if (!
|
|
48944
|
+
if (!isRecord12(value) || typeof value["kind"] !== "string") {
|
|
48479
48945
|
throw new Error("The Mobius manager returned an invalid response");
|
|
48480
48946
|
}
|
|
48481
48947
|
if (value["kind"] === "error" && typeof value["code"] === "string" && typeof value["message"] === "string") {
|
|
@@ -48502,7 +48968,7 @@ function decodeResponse(value) {
|
|
|
48502
48968
|
throw new Error("The Mobius manager returned an invalid response");
|
|
48503
48969
|
}
|
|
48504
48970
|
function isManagedRuntimeSummary(value) {
|
|
48505
|
-
return
|
|
48971
|
+
return isRecord12(value) && typeof value["appId"] === "string" && typeof value["connectionId"] === "string" && typeof value["runtimeId"] === "string" && typeof value["workspace"] === "string" && ["starting", "online", "reconnecting", "failed", "stopped"].includes(String(value["status"]));
|
|
48506
48972
|
}
|
|
48507
48973
|
function summary(connection, status) {
|
|
48508
48974
|
return {
|
|
@@ -48761,7 +49227,7 @@ async function waitForManagerExit(stateDirectory, signal) {
|
|
|
48761
49227
|
const deadline = AbortSignal.any([signal, AbortSignal.timeout(1e4)]);
|
|
48762
49228
|
while (!deadline.aborted) {
|
|
48763
49229
|
try {
|
|
48764
|
-
await readFile3(
|
|
49230
|
+
await readFile3(join20(stateDirectory, "manager.lock"), "utf8");
|
|
48765
49231
|
} catch (cause) {
|
|
48766
49232
|
if (isNodeError2(cause, "ENOENT")) {
|
|
48767
49233
|
return;
|
|
@@ -49039,7 +49505,7 @@ function createProgram() {
|
|
|
49039
49505
|
const installation = await openMobiusCliInstallation(shutdown.signal, process.env);
|
|
49040
49506
|
const localContext = new DaemonLocalContext(installation.stateDirectory, process.env);
|
|
49041
49507
|
const defaultWorkspace = loadDefaultWorkspace(localContext.environment);
|
|
49042
|
-
await
|
|
49508
|
+
await mkdir7(defaultWorkspace, { recursive: true, mode: 448 });
|
|
49043
49509
|
const inventory = await discoverLocalAgentInventory({
|
|
49044
49510
|
defaultWorkspace,
|
|
49045
49511
|
environment: localContext.environment,
|