@moxt-ai/mobius 0.0.166 → 0.0.167

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.
Files changed (48) hide show
  1. package/dist/acp/agent-query-processes.d.ts +2 -1
  2. package/dist/acp/agent-query-processes.d.ts.map +1 -1
  3. package/dist/acp/agent-query-processes.js +6 -4
  4. package/dist/acp/agent-query-processes.js.map +1 -1
  5. package/dist/acp/agent-runtime-manager.d.ts +2 -1
  6. package/dist/acp/agent-runtime-manager.d.ts.map +1 -1
  7. package/dist/acp/agent-runtime-manager.js +11 -6
  8. package/dist/acp/agent-runtime-manager.js.map +1 -1
  9. package/dist/acp/agent-session.d.ts +3 -2
  10. package/dist/acp/agent-session.d.ts.map +1 -1
  11. package/dist/acp/agent-session.js +9 -6
  12. package/dist/acp/agent-session.js.map +1 -1
  13. package/dist/artifacts/local-file-streamer.d.ts +2 -1
  14. package/dist/artifacts/local-file-streamer.d.ts.map +1 -1
  15. package/dist/artifacts/local-file-streamer.js +6 -5
  16. package/dist/artifacts/local-file-streamer.js.map +1 -1
  17. package/dist/cli.js +387 -94
  18. package/dist/cli.js.map +4 -4
  19. package/dist/config.d.ts +1 -1
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +1 -1
  22. package/dist/config.js.map +1 -1
  23. package/dist/daemon-command-handler.d.ts +3 -1
  24. package/dist/daemon-command-handler.d.ts.map +1 -1
  25. package/dist/daemon-command-handler.js +2 -2
  26. package/dist/daemon-command-handler.js.map +1 -1
  27. package/dist/external-content/acp-content-externalizer.d.ts +8 -0
  28. package/dist/external-content/acp-content-externalizer.d.ts.map +1 -0
  29. package/dist/external-content/acp-content-externalizer.js +131 -0
  30. package/dist/external-content/acp-content-externalizer.js.map +1 -0
  31. package/dist/external-content/local-external-content-store.d.ts +32 -0
  32. package/dist/external-content/local-external-content-store.d.ts.map +1 -0
  33. package/dist/external-content/local-external-content-store.js +88 -0
  34. package/dist/external-content/local-external-content-store.js.map +1 -0
  35. package/dist/index.js +445 -158
  36. package/dist/index.js.map +4 -4
  37. package/dist/relay-connection/run-relay-connection.d.ts +3 -1
  38. package/dist/relay-connection/run-relay-connection.d.ts.map +1 -1
  39. package/dist/relay-connection/run-relay-connection.js +2 -1
  40. package/dist/relay-connection/run-relay-connection.js.map +1 -1
  41. package/dist/run-daemon.d.ts.map +1 -1
  42. package/dist/run-daemon.js +5 -1
  43. package/dist/run-daemon.js.map +1 -1
  44. package/dist/runtime.d.ts +2 -1
  45. package/dist/runtime.d.ts.map +1 -1
  46. package/dist/runtime.js +386 -98
  47. package/dist/runtime.js.map +4 -4
  48. package/package.json +16 -10
package/dist/runtime.js CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/runtime.ts
8
- import { mkdir as mkdir6, realpath as realpath10, stat as stat9 } from "node:fs/promises";
8
+ import { mkdir as mkdir7, realpath as realpath11, stat as stat10 } from "node:fs/promises";
9
9
  import { resolve as resolve8 } from "node:path";
10
10
 
11
11
  // ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.js
@@ -21189,6 +21189,7 @@ var MAX_JSON_KEYS = 1e3;
21189
21189
  var SESSION_EVENT_V2_KIND = "session.event.v2";
21190
21190
  var boundedString = external_exports.string().max(MAX_CONTENT_LENGTH);
21191
21191
  var shortString = external_exports.string().max(2048);
21192
+ var externalContentKeySchema = external_exports.string().regex(/^[a-f0-9]{64}$/u);
21192
21193
  function boundedJsonIssue(value, depth = 0) {
21193
21194
  if (depth > MAX_JSON_DEPTH) {
21194
21195
  return "JSON nesting exceeds the maximum depth";
@@ -21256,6 +21257,30 @@ var imageContentSchema = external_exports.object({
21256
21257
  uri: boundedString.nullable().optional()
21257
21258
  }).readonly();
21258
21259
  var audioContentSchema = external_exports.object({ ...contentFields, data: boundedString, mimeType: shortString, type: external_exports.literal("audio") }).readonly();
21260
+ var externalImageContentSchema = external_exports.strictObject({
21261
+ ...contentFields,
21262
+ byteLength: external_exports.number().int().positive().safe(),
21263
+ imageKey: externalContentKeySchema,
21264
+ mimeType: shortString,
21265
+ type: external_exports.literal("external_image"),
21266
+ uri: boundedString.nullable().optional()
21267
+ }).readonly();
21268
+ var externalAudioContentSchema = external_exports.strictObject({
21269
+ ...contentFields,
21270
+ audioKey: externalContentKeySchema,
21271
+ byteLength: external_exports.number().int().positive().safe(),
21272
+ mimeType: shortString,
21273
+ type: external_exports.literal("external_audio")
21274
+ }).readonly();
21275
+ var externalResourceContentSchema = external_exports.strictObject({
21276
+ ...contentFields,
21277
+ byteLength: external_exports.number().int().positive().safe(),
21278
+ encoding: external_exports.enum(["binary", "text"]),
21279
+ mimeType: shortString.nullable().optional(),
21280
+ resourceKey: externalContentKeySchema,
21281
+ type: external_exports.literal("external_resource"),
21282
+ uri: boundedString
21283
+ }).readonly();
21259
21284
  var resourceLinkSchema = external_exports.object({
21260
21285
  ...contentFields,
21261
21286
  description: boundedString.nullable().optional(),
@@ -21288,7 +21313,10 @@ var contentBlockV2Schema = external_exports.discriminatedUnion("type", [
21288
21313
  imageContentSchema,
21289
21314
  audioContentSchema,
21290
21315
  resourceLinkSchema,
21291
- embeddedResourceSchema
21316
+ embeddedResourceSchema,
21317
+ externalImageContentSchema,
21318
+ externalAudioContentSchema,
21319
+ externalResourceContentSchema
21292
21320
  ]);
21293
21321
  var toolCallContentSchema = external_exports.discriminatedUnion("type", [
21294
21322
  external_exports.object({ _meta: optionalMetadata, content: contentBlockV2Schema, type: external_exports.literal("content") }).readonly(),
@@ -27183,8 +27211,8 @@ function createDaemonConfig(connection, agents = [], installableAgents = [], loc
27183
27211
  }
27184
27212
 
27185
27213
  // src/run-daemon.ts
27186
- import { createHash as createHash6, randomUUID as randomUUID6 } from "node:crypto";
27187
- import { join as join17 } from "node:path";
27214
+ import { createHash as createHash7, randomUUID as randomUUID7 } from "node:crypto";
27215
+ import { join as join18 } from "node:path";
27188
27216
  import { styleText } from "node:util";
27189
27217
 
27190
27218
  // src/acp/active-executions.ts
@@ -30556,7 +30584,7 @@ function sql(strings, ...params) {
30556
30584
  return new SQL([new StringChunk(str)]);
30557
30585
  }
30558
30586
  sql2.raw = raw;
30559
- function join19(chunks, separator) {
30587
+ function join20(chunks, separator) {
30560
30588
  const result = [];
30561
30589
  for (const [i, chunk] of chunks.entries()) {
30562
30590
  if (i > 0 && separator !== void 0) {
@@ -30566,7 +30594,7 @@ function sql(strings, ...params) {
30566
30594
  }
30567
30595
  return new SQL(result);
30568
30596
  }
30569
- sql2.join = join19;
30597
+ sql2.join = join20;
30570
30598
  function identifier(value) {
30571
30599
  return new Name(value);
30572
30600
  }
@@ -33110,7 +33138,7 @@ var SQLiteSelectQueryBuilderBase = class extends TypedQueryBuilder {
33110
33138
  const baseTableName = this.tableName;
33111
33139
  const tableName = getTableLikeName(table);
33112
33140
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
33113
- if (typeof tableName === "string" && this.config.joins?.some((join19) => join19.alias === tableName)) {
33141
+ if (typeof tableName === "string" && this.config.joins?.some((join20) => join20.alias === tableName)) {
33114
33142
  throw new Error(`Alias "${tableName}" is already used in this query`);
33115
33143
  }
33116
33144
  if (!this.isPartialSelect) {
@@ -33969,7 +33997,7 @@ var SQLiteUpdateBase = class extends QueryPromise {
33969
33997
  createJoin(joinType) {
33970
33998
  return (table, on) => {
33971
33999
  const tableName = getTableLikeName(table);
33972
- if (typeof tableName === "string" && this.config.joins.some((join19) => join19.alias === tableName)) {
34000
+ if (typeof tableName === "string" && this.config.joins.some((join20) => join20.alias === tableName)) {
33973
34001
  throw new Error(`Alias "${tableName}" is already used in this query`);
33974
34002
  }
33975
34003
  if (typeof on === "function") {
@@ -35292,6 +35320,7 @@ function recordsEqual(left, right) {
35292
35320
  }
35293
35321
  var AgentSession = class _AgentSession {
35294
35322
  #connection;
35323
+ #contentExternalizer;
35295
35324
  #interactions;
35296
35325
  #additionalDirectories;
35297
35326
  #agentId;
@@ -35319,7 +35348,7 @@ var AgentSession = class _AgentSession {
35319
35348
  #sessionTitle = null;
35320
35349
  #sessionUpdatedAt = "";
35321
35350
  #turn = new IdleAcpTurn();
35322
- constructor(agent, cwd, additionalDirectories, mobiusSessionId, getObserver, store, metrics) {
35351
+ constructor(agent, cwd, additionalDirectories, mobiusSessionId, getObserver, store, metrics, contentExternalizer) {
35323
35352
  this.#updates = new AgentUpdateStream((notification) => this.#processUpdate(notification));
35324
35353
  this.#additionalDirectories = [...additionalDirectories];
35325
35354
  this.#agentId = agent.id;
@@ -35339,8 +35368,9 @@ var AgentSession = class _AgentSession {
35339
35368
  observer: getObserver
35340
35369
  });
35341
35370
  this.#connection = new AgentConnection(agent, cwd, this);
35371
+ this.#contentExternalizer = contentExternalizer;
35342
35372
  }
35343
- static async #start(options, getObserver, store, initialize, metrics) {
35373
+ static async #start(options, getObserver, store, initialize, metrics, contentExternalizer) {
35344
35374
  for (let attempt = 1; attempt <= 2; attempt += 1) {
35345
35375
  options.signal.throwIfAborted();
35346
35376
  const unchanged = await metrics.measure(
@@ -35368,7 +35398,8 @@ var AgentSession = class _AgentSession {
35368
35398
  options.sessionId,
35369
35399
  getObserver,
35370
35400
  store,
35371
- metrics
35401
+ metrics,
35402
+ contentExternalizer
35372
35403
  )
35373
35404
  );
35374
35405
  try {
@@ -35391,19 +35422,21 @@ var AgentSession = class _AgentSession {
35391
35422
  }
35392
35423
  throw new AcpExecutionError("ACP agent initialization failed");
35393
35424
  }
35394
- static start = async (options, getObserver, store, metrics = unmeasuredOperationMetrics) => await _AgentSession.#start(
35425
+ static start = async (options, getObserver, store, metrics, contentExternalizer) => await _AgentSession.#start(
35395
35426
  options,
35396
35427
  getObserver,
35397
35428
  store,
35398
35429
  async (runtime) => await runtime.initialize(options.signal, options.origin),
35399
- metrics
35430
+ metrics,
35431
+ contentExternalizer
35400
35432
  );
35401
- static startNativeSessionBrowser = async (options, getObserver, store) => await _AgentSession.#start(
35433
+ static startNativeSessionBrowser = async (options, getObserver, store, contentExternalizer) => await _AgentSession.#start(
35402
35434
  options,
35403
35435
  getObserver,
35404
35436
  store,
35405
35437
  async (runtime) => await runtime.#initializeAgent(options.signal),
35406
- unmeasuredOperationMetrics
35438
+ unmeasuredOperationMetrics,
35439
+ contentExternalizer
35407
35440
  );
35408
35441
  belongsTo = (agentId, cwd, additionalDirectories) => this.#agentId === agentId && this.#cwd === cwd && arraysEqual(this.#additionalDirectories, additionalDirectories);
35409
35442
  usesEnvironment = (environment) => recordsEqual(this.#environment, environment);
@@ -36108,7 +36141,12 @@ var AgentSession = class _AgentSession {
36108
36141
  #processUpdate = async (notification) => {
36109
36142
  this.assertNativeSession(notification.sessionId);
36110
36143
  const update = notification.update;
36111
- const rawUpdate = decodeAcpSessionUpdateV2(JSON.stringify(update));
36144
+ const externalized = await this.#contentExternalizer.update(
36145
+ this.#mobiusSessionId,
36146
+ update,
36147
+ AbortSignal.timeout(3e4)
36148
+ );
36149
+ const rawUpdate = decodeAcpSessionUpdateV2(JSON.stringify(externalized));
36112
36150
  if (this.#sessionLoad.kind === "capturing") {
36113
36151
  await this.#sessionLoad.history.record(update, rawUpdate);
36114
36152
  } else {
@@ -36395,8 +36433,10 @@ var AgentQueryProcesses = class {
36395
36433
  #processes;
36396
36434
  #observer = new NullAcpSessionObserver();
36397
36435
  #store = new MemoryAcpSessionStore();
36398
- constructor(processes) {
36436
+ #contentExternalizer;
36437
+ constructor(processes, contentExternalizer) {
36399
36438
  this.#processes = processes;
36439
+ this.#contentExternalizer = contentExternalizer;
36400
36440
  this.#processesByQuery = new RetainedAgentProcesses({
36401
36441
  touch: processes.touch,
36402
36442
  changed: processes.notifyChanged
@@ -36412,7 +36452,12 @@ var AgentQueryProcesses = class {
36412
36452
  async #startRetained(options) {
36413
36453
  const runtime = await this.#processes.startRetained(
36414
36454
  options.signal,
36415
- () => AgentSession.startNativeSessionBrowser(options, () => this.#observer, this.#store),
36455
+ () => AgentSession.startNativeSessionBrowser(
36456
+ options,
36457
+ () => this.#observer,
36458
+ this.#store,
36459
+ this.#contentExternalizer
36460
+ ),
36416
36461
  {
36417
36462
  isBusy: () => this.#processesByQuery.isBusy(options.sessionId),
36418
36463
  retire: (runtime2) => this.retire(options.sessionId, runtime2)
@@ -36488,7 +36533,8 @@ var AgentQueryProcesses = class {
36488
36533
  async () => await AgentSession.startNativeSessionBrowser(
36489
36534
  options,
36490
36535
  () => this.#observer,
36491
- new MemoryAcpSessionStore()
36536
+ new MemoryAcpSessionStore(),
36537
+ this.#contentExternalizer
36492
36538
  ),
36493
36539
  async (runtime) => {
36494
36540
  runtime.selectNativeSession(nativeSessionId);
@@ -36503,7 +36549,8 @@ var AgentQueryProcesses = class {
36503
36549
  async () => await AgentSession.startNativeSessionBrowser(
36504
36550
  options,
36505
36551
  () => this.#observer,
36506
- new MemoryAcpSessionStore()
36552
+ new MemoryAcpSessionStore(),
36553
+ this.#contentExternalizer
36507
36554
  ),
36508
36555
  async (runtime) => {
36509
36556
  runtime.selectNativeSession(nativeSessionId);
@@ -36519,6 +36566,220 @@ var AgentQueryProcesses = class {
36519
36566
  };
36520
36567
  };
36521
36568
 
36569
+ // src/external-content/acp-content-externalizer.ts
36570
+ var MAXIMUM_ENCODED_CONTENT_CHARACTERS = 4e6;
36571
+ function decodeBase64(data) {
36572
+ if (data.length > MAXIMUM_ENCODED_CONTENT_CHARACTERS || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)) {
36573
+ throw new Error("The ACP embedded content is not valid bounded base64");
36574
+ }
36575
+ return Buffer.from(data, "base64");
36576
+ }
36577
+ var AcpContentExternalizer = class {
36578
+ #store;
36579
+ constructor(store) {
36580
+ this.#store = store;
36581
+ }
36582
+ async #content(sessionId, content, signal) {
36583
+ switch (content.type) {
36584
+ case "text":
36585
+ case "resource_link":
36586
+ return content;
36587
+ case "image": {
36588
+ if (content.data.length === 0) {
36589
+ return content;
36590
+ }
36591
+ const stored = await this.#store.put({
36592
+ bytes: decodeBase64(content.data),
36593
+ kind: "image",
36594
+ mediaType: content.mimeType,
36595
+ name: "image",
36596
+ sessionId,
36597
+ signal
36598
+ });
36599
+ return {
36600
+ _meta: content._meta,
36601
+ annotations: content.annotations,
36602
+ byteLength: stored.byteLength,
36603
+ imageKey: stored.key,
36604
+ mimeType: content.mimeType,
36605
+ type: "external_image",
36606
+ uri: content.uri
36607
+ };
36608
+ }
36609
+ case "audio": {
36610
+ if (content.data.length === 0) {
36611
+ return content;
36612
+ }
36613
+ const stored = await this.#store.put({
36614
+ bytes: decodeBase64(content.data),
36615
+ kind: "audio",
36616
+ mediaType: content.mimeType,
36617
+ name: "audio",
36618
+ sessionId,
36619
+ signal
36620
+ });
36621
+ return {
36622
+ _meta: content._meta,
36623
+ annotations: content.annotations,
36624
+ audioKey: stored.key,
36625
+ byteLength: stored.byteLength,
36626
+ mimeType: content.mimeType,
36627
+ type: "external_audio"
36628
+ };
36629
+ }
36630
+ case "resource": {
36631
+ const embedded = content.resource;
36632
+ const encoding = "text" in embedded ? "text" : "binary";
36633
+ const bytes = "text" in embedded ? Buffer.from(embedded.text, "utf8") : decodeBase64(embedded.blob);
36634
+ if (bytes.byteLength === 0) {
36635
+ return content;
36636
+ }
36637
+ const mediaType = embedded.mimeType ?? "application/octet-stream";
36638
+ const stored = await this.#store.put({
36639
+ bytes,
36640
+ kind: "resource",
36641
+ mediaType,
36642
+ name: "resource",
36643
+ sessionId,
36644
+ signal
36645
+ });
36646
+ return {
36647
+ _meta: content._meta,
36648
+ annotations: content.annotations,
36649
+ byteLength: stored.byteLength,
36650
+ encoding,
36651
+ mimeType: embedded.mimeType,
36652
+ resourceKey: stored.key,
36653
+ type: "external_resource",
36654
+ uri: embedded.uri
36655
+ };
36656
+ }
36657
+ }
36658
+ }
36659
+ async #toolContent(sessionId, item, signal) {
36660
+ return item.type === "content" ? { ...item, content: await this.#content(sessionId, item.content, signal) } : item;
36661
+ }
36662
+ update = async (sessionId, update, signal) => {
36663
+ switch (update.sessionUpdate) {
36664
+ case "user_message_chunk":
36665
+ case "agent_message_chunk":
36666
+ case "agent_thought_chunk":
36667
+ case "compaction_summary_chunk":
36668
+ return { ...update, content: await this.#content(sessionId, update.content, signal) };
36669
+ case "tool_call":
36670
+ case "tool_call_update":
36671
+ return update.content === void 0 || update.content === null ? update : {
36672
+ ...update,
36673
+ content: await Promise.all(
36674
+ update.content.map(async (item) => await this.#toolContent(sessionId, item, signal))
36675
+ )
36676
+ };
36677
+ case "compaction_update":
36678
+ return update.summary === void 0 || update.summary === null ? update : {
36679
+ ...update,
36680
+ summary: await Promise.all(
36681
+ update.summary.map(async (content) => await this.#content(sessionId, content, signal))
36682
+ )
36683
+ };
36684
+ case "plan":
36685
+ case "plan_update":
36686
+ case "plan_removed":
36687
+ case "available_commands_update":
36688
+ case "current_mode_update":
36689
+ case "config_option_update":
36690
+ case "session_info_update":
36691
+ case "usage_update":
36692
+ return update;
36693
+ }
36694
+ };
36695
+ };
36696
+
36697
+ // src/external-content/local-external-content-store.ts
36698
+ import { createHash as createHash2, randomUUID } from "node:crypto";
36699
+ import { lstat, mkdir as mkdir4, readFile as readFile3, realpath as realpath7, rename as rename3, rm as rm3, stat as stat6, writeFile as writeFile3 } from "node:fs/promises";
36700
+ import { dirname as dirname4, join as join15 } from "node:path";
36701
+ var contentRequest = /^mobius-content:(image|audio|resource):([a-f0-9]{64})$/u;
36702
+ var metadataSchema2 = external_exports.strictObject({
36703
+ kind: external_exports.enum(["image", "audio", "resource"]),
36704
+ mediaType: external_exports.string().min(1).max(2048).regex(/^[\u0020-\u007e]+$/u),
36705
+ name: external_exports.string().min(1).max(500)
36706
+ });
36707
+ var UnretainedExternalContentStore = class {
36708
+ put = async ({ bytes, signal }) => {
36709
+ signal.throwIfAborted();
36710
+ return { byteLength: bytes.byteLength, key: createHash2("sha256").update(bytes).digest("hex") };
36711
+ };
36712
+ resolve = (_sessionId, _request, signal) => {
36713
+ signal.throwIfAborted();
36714
+ return Promise.resolve(null);
36715
+ };
36716
+ };
36717
+ function sessionScope(sessionId) {
36718
+ return createHash2("sha256").update(sessionId).digest("hex");
36719
+ }
36720
+ async function atomicWrite(path2, bytes, signal) {
36721
+ const temporary = `${path2}.${randomUUID()}.tmp`;
36722
+ try {
36723
+ await writeFile3(temporary, bytes, { mode: 384, signal });
36724
+ signal.throwIfAborted();
36725
+ await rename3(temporary, path2);
36726
+ } finally {
36727
+ await rm3(temporary, { force: true });
36728
+ }
36729
+ }
36730
+ var LocalExternalContentStore = class {
36731
+ #root;
36732
+ constructor(stateDirectory) {
36733
+ this.#root = join15(stateDirectory, "tmp", "session-content");
36734
+ }
36735
+ put = async ({ bytes, kind, mediaType, name, sessionId, signal }) => {
36736
+ signal.throwIfAborted();
36737
+ const key = createHash2("sha256").update(bytes).digest("hex");
36738
+ const directory = join15(this.#root, sessionScope(sessionId), kind);
36739
+ await mkdir4(directory, { mode: 448, recursive: true });
36740
+ signal.throwIfAborted();
36741
+ const path2 = join15(directory, key);
36742
+ await atomicWrite(path2, bytes, signal);
36743
+ await atomicWrite(
36744
+ `${path2}.json`,
36745
+ Buffer.from(JSON.stringify(metadataSchema2.parse({ kind, mediaType, name })), "utf8"),
36746
+ signal
36747
+ );
36748
+ return { byteLength: bytes.byteLength, key };
36749
+ };
36750
+ resolve = async (sessionId, request, signal) => {
36751
+ const matched = contentRequest.exec(request);
36752
+ if (matched === null) {
36753
+ return null;
36754
+ }
36755
+ const kind = matched[1];
36756
+ const key = matched[2];
36757
+ if (kind !== "image" && kind !== "audio" && kind !== "resource" || key === void 0) {
36758
+ return null;
36759
+ }
36760
+ const directory = join15(this.#root, sessionScope(sessionId), kind);
36761
+ const path2 = join15(directory, key);
36762
+ try {
36763
+ const [resolvedDirectory, resolvedPath, file2, metadata] = await Promise.all([
36764
+ realpath7(directory),
36765
+ realpath7(path2),
36766
+ lstat(path2),
36767
+ readFile3(`${path2}.json`, "utf8").then((value) => metadataSchema2.parse(JSON.parse(value)))
36768
+ ]);
36769
+ signal.throwIfAborted();
36770
+ if (!file2.isFile() || dirname4(resolvedPath) !== resolvedDirectory || metadata.kind !== kind) {
36771
+ return null;
36772
+ }
36773
+ await stat6(resolvedPath);
36774
+ signal.throwIfAborted();
36775
+ return { mediaType: metadata.mediaType, name: metadata.name, path: resolvedPath };
36776
+ } catch {
36777
+ signal.throwIfAborted();
36778
+ return null;
36779
+ }
36780
+ };
36781
+ };
36782
+
36522
36783
  // src/native-sessions/chat-agent.ts
36523
36784
  function supportsNativeChat(agentId) {
36524
36785
  return agentId === "codex" || agentId === "claude" || agentId === "opencode" || agentId === "pi";
@@ -36735,7 +36996,7 @@ var AgentRuntimeManager = class {
36735
36996
  touch: this.#processes.touch,
36736
36997
  changed: this.#processes.notifyChanged
36737
36998
  });
36738
- #queryProcesses = new AgentQueryProcesses(this.#processes);
36999
+ #queryProcesses;
36739
37000
  #executions = new ActiveExecutions();
36740
37001
  #agentSettingsObserver = new NullAcpSessionObserver();
36741
37002
  #nativeOperations = /* @__PURE__ */ new Set();
@@ -36743,13 +37004,16 @@ var AgentRuntimeManager = class {
36743
37004
  #nativeHistoryReader;
36744
37005
  #sessionIdentity;
36745
37006
  #onSessionStatusChanged;
37007
+ #contentExternalizer;
36746
37008
  #observer;
36747
- constructor(observer = new NullAcpSessionObserver(), store = new MemoryAcpSessionStore(), nativeHistoryReader = null, sessionIdentity = "assigned", onSessionStatusChanged = () => void 0) {
37009
+ constructor(observer = new NullAcpSessionObserver(), store = new MemoryAcpSessionStore(), nativeHistoryReader = null, sessionIdentity = "assigned", onSessionStatusChanged = () => void 0, contentExternalizer = new AcpContentExternalizer(new UnretainedExternalContentStore())) {
36748
37010
  this.#observer = observer;
36749
37011
  this.#store = store;
36750
37012
  this.#nativeHistoryReader = nativeHistoryReader;
36751
37013
  this.#sessionIdentity = sessionIdentity;
36752
37014
  this.#onSessionStatusChanged = onSessionStatusChanged;
37015
+ this.#contentExternalizer = contentExternalizer;
37016
+ this.#queryProcesses = new AgentQueryProcesses(this.#processes, contentExternalizer);
36753
37017
  }
36754
37018
  setObserver = (observer) => {
36755
37019
  this.#observer = observer;
@@ -36790,7 +37054,8 @@ var AgentRuntimeManager = class {
36790
37054
  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,
36791
37055
  () => this.#observer,
36792
37056
  this.#store,
36793
- metrics
37057
+ metrics,
37058
+ this.#contentExternalizer
36794
37059
  )
36795
37060
  );
36796
37061
  });
@@ -36805,7 +37070,13 @@ var AgentRuntimeManager = class {
36805
37070
  this.#store.remove(options.sessionId);
36806
37071
  return await this.#startRetainedSessionProcess(
36807
37072
  options,
36808
- async () => await AgentSession.start(options, () => this.#observer, this.#store, metrics)
37073
+ async () => await AgentSession.start(
37074
+ options,
37075
+ () => this.#observer,
37076
+ this.#store,
37077
+ metrics,
37078
+ this.#contentExternalizer
37079
+ )
36809
37080
  );
36810
37081
  });
36811
37082
  }
@@ -36815,7 +37086,13 @@ var AgentRuntimeManager = class {
36815
37086
  await this.#retireSessionProcess(options.sessionId, existing, async () => await existing.close());
36816
37087
  const runtime = await this.#startRetainedSessionProcess(
36817
37088
  options,
36818
- async () => await AgentSession.start(options, () => this.#observer, this.#store)
37089
+ async () => await AgentSession.start(
37090
+ options,
37091
+ () => this.#observer,
37092
+ this.#store,
37093
+ unmeasuredOperationMetrics,
37094
+ this.#contentExternalizer
37095
+ )
36819
37096
  );
36820
37097
  try {
36821
37098
  for (const desired of desiredConfigOptions) {
@@ -36911,7 +37188,9 @@ var AgentRuntimeManager = class {
36911
37188
  sessionId: `agent-settings-${crypto.randomUUID()}`
36912
37189
  },
36913
37190
  () => this.#agentSettingsObserver,
36914
- new MemoryAcpSessionStore()
37191
+ new MemoryAcpSessionStore(),
37192
+ unmeasuredOperationMetrics,
37193
+ this.#contentExternalizer
36915
37194
  ),
36916
37195
  async (runtime) => {
36917
37196
  const prepared = runtime.prepared();
@@ -37964,9 +38243,9 @@ var FixedInstallationExecutor = class {
37964
38243
  };
37965
38244
 
37966
38245
  // src/authorization/workspace-directory.ts
37967
- import { readdir as readdir2, realpath as realpath7, stat as stat6 } from "node:fs/promises";
38246
+ import { readdir as readdir2, realpath as realpath8, stat as stat7 } from "node:fs/promises";
37968
38247
  import { homedir as homedir2 } from "node:os";
37969
- import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute9, join as join15, normalize as normalize3, relative as relative4 } from "node:path";
38248
+ import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute9, join as join16, normalize as normalize3, relative as relative4 } from "node:path";
37970
38249
 
37971
38250
  // src/authorization/local-authorization-error.ts
37972
38251
  var LocalAuthorizationError = class extends Error {
@@ -38045,9 +38324,9 @@ var WorkspaceDirectoryService = class {
38045
38324
  throw new LocalAuthorizationError("The local directory path is invalid");
38046
38325
  }
38047
38326
  try {
38048
- const target = await realpath7(requested);
38327
+ const target = await realpath8(requested);
38049
38328
  signal.throwIfAborted();
38050
- const metadata = await stat6(target);
38329
+ const metadata = await stat7(target);
38051
38330
  signal.throwIfAborted();
38052
38331
  if (!isAbsolute9(target) || normalize3(target) !== target || !metadata.isDirectory()) {
38053
38332
  throw new LocalAuthorizationError("The selected location is not a directory");
@@ -38095,7 +38374,7 @@ var WorkspaceDirectoryService = class {
38095
38374
  continue;
38096
38375
  }
38097
38376
  try {
38098
- const path2 = await this.resolvePath(join15(target, child2.name), signal);
38377
+ const path2 = await this.resolvePath(join16(target, child2.name), signal);
38099
38378
  entries.push({ directoryId: encodePath(path2), name: child2.name });
38100
38379
  } catch (cause) {
38101
38380
  signal.throwIfAborted();
@@ -38105,7 +38384,7 @@ var WorkspaceDirectoryService = class {
38105
38384
  }
38106
38385
  }
38107
38386
  entries.sort((a, b) => a.name.localeCompare(b.name));
38108
- const parent = dirname4(target);
38387
+ const parent = dirname5(target);
38109
38388
  return new WorkspaceDirectoryListing(
38110
38389
  id,
38111
38390
  this.label(target),
@@ -38131,15 +38410,15 @@ var WorkspaceDirectoryService = class {
38131
38410
 
38132
38411
  // src/daemon-diagnostic-log.ts
38133
38412
  import { appendFileSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, statSync as statSync3, writeFileSync } from "node:fs";
38134
- import { join as join16 } from "node:path";
38413
+ import { join as join17 } from "node:path";
38135
38414
  var MAXIMUM_DAEMON_LOG_BYTES = 1 * 1024 * 1024;
38136
38415
  var DaemonDiagnosticLog = class {
38137
38416
  #directory;
38138
38417
  #path;
38139
38418
  #maximumBytes;
38140
38419
  constructor(stateDirectory, maximumBytes = MAXIMUM_DAEMON_LOG_BYTES) {
38141
- this.#directory = join16(stateDirectory, "logs");
38142
- this.#path = join16(this.#directory, "daemon.log");
38420
+ this.#directory = join17(stateDirectory, "logs");
38421
+ this.#path = join17(this.#directory, "daemon.log");
38143
38422
  this.#maximumBytes = maximumBytes;
38144
38423
  }
38145
38424
  record = (diagnostic) => {
@@ -38184,7 +38463,7 @@ import { WebSocket as WebSocket2 } from "undici";
38184
38463
  import { WebSocket } from "undici";
38185
38464
 
38186
38465
  // src/prompt-artifact-resolver.ts
38187
- import { createHash as createHash2 } from "node:crypto";
38466
+ import { createHash as createHash3 } from "node:crypto";
38188
38467
  import { fetch as fetch3 } from "undici";
38189
38468
  var ARTIFACT_SCHEME = "mobius-artifact:";
38190
38469
  var ARTIFACT_DOWNLOAD_TIMEOUT_MILLISECONDS = 2e4;
@@ -38322,7 +38601,7 @@ async function download(config2, command, reference, signal) {
38322
38601
  );
38323
38602
  }
38324
38603
  const bytes = await responseBytes(response, reference.byteLength, requestSignal);
38325
- if (createHash2("sha256").update(bytes).digest("hex") !== reference.sha256) {
38604
+ if (createHash3("sha256").update(bytes).digest("hex") !== reference.sha256) {
38326
38605
  throw new PromptArtifactError(
38327
38606
  "artifact_integrity_failed",
38328
38607
  "The prompt artifact failed integrity validation"
@@ -38627,7 +38906,7 @@ var DaemonInstallationObserver = class {
38627
38906
  };
38628
38907
 
38629
38908
  // src/daemon-active-turn.ts
38630
- import { randomUUID } from "node:crypto";
38909
+ import { randomUUID as randomUUID2 } from "node:crypto";
38631
38910
  function activeMessageCharacters(message) {
38632
38911
  return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
38633
38912
  }
@@ -38661,7 +38940,7 @@ var ActiveDaemonTurn = class {
38661
38940
  #timeline;
38662
38941
  #sequence = 0;
38663
38942
  #interaction = null;
38664
- #epoch = decodeIdentifier(randomUUID());
38943
+ #epoch = decodeIdentifier(randomUUID2());
38665
38944
  constructor(command, attemptId) {
38666
38945
  this.attemptId = attemptId;
38667
38946
  this.command = command;
@@ -38723,7 +39002,7 @@ var ActiveDaemonTurn = class {
38723
39002
  if (!this.#activities.has(event.activityId)) {
38724
39003
  this.#timeline = [
38725
39004
  ...this.#timeline,
38726
- { activityId: event.activityId, id: decodeIdentifier(randomUUID()), kind: "activity" }
39005
+ { activityId: event.activityId, id: decodeIdentifier(randomUUID2()), kind: "activity" }
38727
39006
  ];
38728
39007
  }
38729
39008
  this.#activities.set(event.activityId, {
@@ -38744,7 +39023,7 @@ var ActiveDaemonTurn = class {
38744
39023
  if (previous === void 0) {
38745
39024
  this.#timeline = [
38746
39025
  ...this.#timeline,
38747
- { activityId: event.activityId, id: decodeIdentifier(randomUUID()), kind: "activity" }
39026
+ { activityId: event.activityId, id: decodeIdentifier(randomUUID2()), kind: "activity" }
38748
39027
  ];
38749
39028
  }
38750
39029
  this.#activities.set(event.activityId, {
@@ -38769,7 +39048,7 @@ var ActiveDaemonTurn = class {
38769
39048
  ...this.#timeline,
38770
39049
  {
38771
39050
  content: /* @__PURE__ */ new Map([[event.contentId, event.content]]),
38772
- id: decodeIdentifier(randomUUID()),
39051
+ id: decodeIdentifier(randomUUID2()),
38773
39052
  kind: "message",
38774
39053
  sourceMessageId: event.messageId,
38775
39054
  text: ""
@@ -38809,7 +39088,7 @@ var ActiveDaemonTurn = class {
38809
39088
  ...this.#timeline,
38810
39089
  {
38811
39090
  content: /* @__PURE__ */ new Map(),
38812
- id: decodeIdentifier(randomUUID()),
39091
+ id: decodeIdentifier(randomUUID2()),
38813
39092
  kind: "message",
38814
39093
  sourceMessageId: messageId,
38815
39094
  text: remaining.slice(0, ACTIVE_TURN_TEXT_CHUNK_LIMIT)
@@ -39785,7 +40064,7 @@ var readCodexFullHistory = async (agent, cwd, nativeSessionId, signal, nativeTur
39785
40064
  });
39786
40065
 
39787
40066
  // src/native-sessions/service.ts
39788
- import { randomUUID as randomUUID2 } from "node:crypto";
40067
+ import { randomUUID as randomUUID3 } from "node:crypto";
39789
40068
  import { basename as basename4 } from "node:path";
39790
40069
 
39791
40070
  // src/native-sessions/acp-history.ts
@@ -40000,7 +40279,7 @@ var NativeSessionService = class {
40000
40279
  if (authorized === null) {
40001
40280
  return null;
40002
40281
  }
40003
- const entryId = decodeIdentifier(randomUUID2());
40282
+ const entryId = decodeIdentifier(randomUUID3());
40004
40283
  if (this.#entries.size >= 5e3) {
40005
40284
  this.#entries.clear();
40006
40285
  }
@@ -40056,7 +40335,7 @@ var NativeSessionService = class {
40056
40335
  "invalid_native_session_response"
40057
40336
  );
40058
40337
  }
40059
- nextCursor = decodeIdentifier(randomUUID2());
40338
+ nextCursor = decodeIdentifier(randomUUID3());
40060
40339
  if (this.#cursors.size >= 500) {
40061
40340
  this.#cursors.clear();
40062
40341
  }
@@ -40338,7 +40617,7 @@ var NativeSessionService = class {
40338
40617
  };
40339
40618
 
40340
40619
  // src/relay-connection/daemon-operation-state.ts
40341
- import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
40620
+ import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
40342
40621
  var MAX_TERMINAL_RECEIPTS = 1024;
40343
40622
  function isTerminal(state) {
40344
40623
  return state === "succeeded" || state === "failed" || state === "cancelled";
@@ -40347,7 +40626,7 @@ var DaemonOperationState = class {
40347
40626
  #executions = /* @__PURE__ */ new Map();
40348
40627
  #terminalCount = 0;
40349
40628
  claimExecution = (commandId, sessionId, commandJson) => {
40350
- const commandHash = createHash3("sha256").update(commandJson).digest("hex");
40629
+ const commandHash = createHash4("sha256").update(commandJson).digest("hex");
40351
40630
  const existing = this.#executions.get(commandId);
40352
40631
  if (existing !== void 0) {
40353
40632
  if (existing.sessionId !== sessionId || existing.commandHash !== commandHash) {
@@ -40355,7 +40634,7 @@ var DaemonOperationState = class {
40355
40634
  }
40356
40635
  return { attemptId: existing.attemptId, commandId, kind: "duplicate", state: existing.state };
40357
40636
  }
40358
- const attemptId = randomUUID3();
40637
+ const attemptId = randomUUID4();
40359
40638
  this.#executions.set(commandId, { attemptId, commandHash, sessionId, state: "dispatching" });
40360
40639
  return { attemptId, commandId, kind: "accepted", state: "dispatching" };
40361
40640
  };
@@ -40691,7 +40970,7 @@ function createAgentCatalogRefreshHandler(dependencies) {
40691
40970
  import { WebSocket as WebSocket4 } from "undici";
40692
40971
 
40693
40972
  // src/agent-catalog/discover-agent-settings.ts
40694
- import { createHash as createHash4 } from "node:crypto";
40973
+ import { createHash as createHash5 } from "node:crypto";
40695
40974
 
40696
40975
  // src/agent-catalog/agent-settings-base.ts
40697
40976
  var AgentSettingsConfigurationError = class extends Error {
@@ -41155,7 +41434,7 @@ function settingsRevision(agent, reportedAgentVersion, settings, modelEffort) {
41155
41434
  unsupportedModelIds: modelEffort.unsupportedModelIds,
41156
41435
  valuesByModel: {}
41157
41436
  };
41158
- return createHash4("sha256").update(
41437
+ return createHash5("sha256").update(
41159
41438
  JSON.stringify({
41160
41439
  adapterVersion: agent.kind === "acp-adapter-process" ? agent.adapterVersion : agent.agentVersion,
41161
41440
  agentId: agent.id,
@@ -41306,7 +41585,7 @@ function createAgentSettingsDiscoveryHandler(dependencies) {
41306
41585
 
41307
41586
  // src/artifacts/local-file-streamer.ts
41308
41587
  import { createReadStream as createReadStream2 } from "node:fs";
41309
- import { realpath as realpath8, stat as stat7 } from "node:fs/promises";
41588
+ import { realpath as realpath9, stat as stat8 } from "node:fs/promises";
41310
41589
  import { basename as basename5, isAbsolute as isAbsolute10, normalize as normalize4, resolve as resolve5 } from "node:path";
41311
41590
  import { fileURLToPath as fileURLToPath2 } from "node:url";
41312
41591
  var CHUNK_BYTES = 192 * 1024;
@@ -41334,7 +41613,7 @@ async function resolveFile(value, workingDirectory, signal) {
41334
41613
  return null;
41335
41614
  }
41336
41615
  try {
41337
- const target = await realpath8(requested);
41616
+ const target = await realpath9(requested);
41338
41617
  signal.throwIfAborted();
41339
41618
  return isAbsolute10(target) && normalize4(target) === target ? target : null;
41340
41619
  } catch {
@@ -41342,23 +41621,24 @@ async function resolveFile(value, workingDirectory, signal) {
41342
41621
  return null;
41343
41622
  }
41344
41623
  }
41345
- async function streamLocalFile(command, send2, signal, workingDirectory) {
41346
- const target = await resolveFile(command.path, workingDirectory, signal);
41624
+ async function streamLocalFile(command, send2, signal, workingDirectory, externalContent) {
41625
+ const external = await externalContent.resolve(command.sessionId, command.path, signal);
41626
+ const target = external?.path ?? await resolveFile(command.path, workingDirectory, signal);
41347
41627
  if (target === null) {
41348
41628
  throw new Error("The local file is unavailable");
41349
41629
  }
41350
- const before = await stat7(target);
41630
+ const before = await stat8(target);
41351
41631
  signal.throwIfAborted();
41352
41632
  if (!before.isFile() || before.size < 1 || before.size > command.maxBytes) {
41353
41633
  throw new Error("The local file is too large to read");
41354
41634
  }
41355
- const raster = await readLocalRaster(target, signal);
41635
+ const raster = external === null ? await readLocalRaster(target, signal) : null;
41356
41636
  send2({
41357
41637
  byteLength: before.size,
41358
41638
  kind: FILE_BEGIN_KIND,
41359
- mediaType: raster?.mimeType ?? "application/octet-stream",
41639
+ mediaType: external?.mediaType ?? raster?.mimeType ?? "application/octet-stream",
41360
41640
  modifiedAt: before.mtime.toISOString(),
41361
- name: basename5(target) || "file",
41641
+ name: external?.name ?? (basename5(target) || "file"),
41362
41642
  requestId: command.requestId,
41363
41643
  sessionId: command.sessionId
41364
41644
  });
@@ -41375,7 +41655,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
41375
41655
  });
41376
41656
  sequence += 1;
41377
41657
  }
41378
- const after = await stat7(target);
41658
+ const after = await stat8(target);
41379
41659
  signal.throwIfAborted();
41380
41660
  if (after.size !== before.size || after.mtimeMs !== before.mtimeMs) {
41381
41661
  throw new Error("The local file changed during transfer");
@@ -41388,7 +41668,7 @@ async function streamLocalFile(command, send2, signal, workingDirectory) {
41388
41668
  }
41389
41669
 
41390
41670
  // src/daemon-history-commands.ts
41391
- import { createHash as createHash5 } from "node:crypto";
41671
+ import { createHash as createHash6 } from "node:crypto";
41392
41672
 
41393
41673
  // src/authorization/resolve-session-directories.ts
41394
41674
  import { basename as basename6 } from "node:path";
@@ -41782,7 +42062,7 @@ async function executeSessionLiveHistoryPageLoad(socket, command, config2, direc
41782
42062
  }
41783
42063
  function replayEvent(sessionId, position, update) {
41784
42064
  const encoded = JSON.stringify(update);
41785
- const eventId = `native-${createHash5("sha256").update(sessionId).update(":").update(position.toString()).update(":").update(encoded).digest("hex")}`;
42065
+ const eventId = `native-${createHash6("sha256").update(sessionId).update(":").update(position.toString()).update(":").update(encoded).digest("hex")}`;
41786
42066
  return {
41787
42067
  eventId,
41788
42068
  payload: update,
@@ -41865,7 +42145,7 @@ async function executeSessionLiveHistoryV2PageLoad(socket, command, config2, dir
41865
42145
  }
41866
42146
 
41867
42147
  // src/acp/session-config/apply-session-configuration.ts
41868
- import { randomUUID as randomUUID4 } from "node:crypto";
42148
+ import { randomUUID as randomUUID5 } from "node:crypto";
41869
42149
  function invalidSessionConfiguration(message) {
41870
42150
  return new AcpExecutionError(message, {}, "invalid_session_configuration");
41871
42151
  }
@@ -42006,7 +42286,7 @@ async function applySessionConfigurationSelection(sessions, audit, options, sele
42006
42286
  booleanValue: selection.booleanValue,
42007
42287
  configId: selection.configId,
42008
42288
  cwd,
42009
- requestId: `cfg_${randomUUID4()}`,
42289
+ requestId: `cfg_${randomUUID5()}`,
42010
42290
  sessionId,
42011
42291
  signal,
42012
42292
  value: selection.value,
@@ -42680,6 +42960,7 @@ function createDaemonCommandHandler({
42680
42960
  operations,
42681
42961
  publisher,
42682
42962
  eventLogV2,
42963
+ externalContent,
42683
42964
  activeTurns,
42684
42965
  diagnostics,
42685
42966
  socket,
@@ -42788,7 +43069,8 @@ function createDaemonCommandHandler({
42788
43069
  command2,
42789
43070
  (message2) => send(socket, message2),
42790
43071
  signal,
42791
- sessions.findSessions([command2.sessionId])[0]?.cwd ?? null
43072
+ sessions.findSessions([command2.sessionId])[0]?.cwd ?? null,
43073
+ externalContent
42792
43074
  ).catch((error62) => {
42793
43075
  if (socket.readyState !== WebSocket6.OPEN || signal.aborted) {
42794
43076
  return;
@@ -43127,7 +43409,7 @@ function connectRelay(url2, signal) {
43127
43409
  }
43128
43410
 
43129
43411
  // src/relay-connection/liveness.ts
43130
- import { randomUUID as randomUUID5 } from "node:crypto";
43412
+ import { randomUUID as randomUUID6 } from "node:crypto";
43131
43413
  var HEARTBEAT_ACK_TIMEOUT_MILLISECONDS = 1e4;
43132
43414
  var HEARTBEAT_INTERVAL_MILLISECONDS = 2e4;
43133
43415
  var RelayLivenessState = class {
@@ -43216,7 +43498,7 @@ var RelayConnectionLiveness = class {
43216
43498
  }
43217
43499
  throw new Error("Heartbeat was scheduled in an invalid state");
43218
43500
  }
43219
- const heartbeatId = randomUUID5();
43501
+ const heartbeatId = randomUUID6();
43220
43502
  this.#state = new AwaitingHeartbeatAckState(
43221
43503
  heartbeatId,
43222
43504
  this.#timer.schedule(this.#handleTimeout, HEARTBEAT_ACK_TIMEOUT_MILLISECONDS)
@@ -43256,6 +43538,7 @@ async function runRelayConnection({
43256
43538
  operations,
43257
43539
  publisher,
43258
43540
  eventLogV2,
43541
+ externalContent,
43259
43542
  activeTurns,
43260
43543
  connectionEpoch,
43261
43544
  diagnostics,
@@ -43279,6 +43562,7 @@ async function runRelayConnection({
43279
43562
  operations,
43280
43563
  publisher,
43281
43564
  eventLogV2,
43565
+ externalContent,
43282
43566
  activeTurns,
43283
43567
  diagnostics,
43284
43568
  socket,
@@ -43757,7 +44041,7 @@ async function installDetectedAgentIntegrations(config2, installations, signal)
43757
44041
  {
43758
44042
  agentId: agent.id,
43759
44043
  kind: AGENT_INSTALL_REQUEST_KIND,
43760
- requestId: `automatic-integration-${randomUUID6()}`
44044
+ requestId: `automatic-integration-${randomUUID7()}`
43761
44045
  },
43762
44046
  signal
43763
44047
  );
@@ -43776,8 +44060,9 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43776
44060
  stateDirectory
43777
44061
  });
43778
44062
  const sessionStore = new SqliteAcpSessionStore(
43779
- join17(stateDirectory, "sessions", `${createHash6("sha256").update(config2.channelId).digest("hex")}.sqlite`)
44063
+ join18(stateDirectory, "sessions", `${createHash7("sha256").update(config2.channelId).digest("hex")}.sqlite`)
43780
44064
  );
44065
+ const externalContent = new LocalExternalContentStore(stateDirectory);
43781
44066
  const operations = new DaemonOperationState();
43782
44067
  const publisher = new DaemonSessionEventPublisher(sessionStore);
43783
44068
  const eventLogV2 = new DaemonSessionEventLogV2(publisher, sessionStore);
@@ -43798,7 +44083,8 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43798
44083
  )).history : null
43799
44084
  },
43800
44085
  "native",
43801
- publisher.publishStatus
44086
+ publisher.publishStatus,
44087
+ new AcpContentExternalizer(externalContent)
43802
44088
  );
43803
44089
  const directories = new WorkspaceDirectoryService(config2.bindingId, config2.defaultWorkspace);
43804
44090
  const installationObserver = new DaemonInstallationObserver();
@@ -43912,6 +44198,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43912
44198
  operations,
43913
44199
  publisher,
43914
44200
  eventLogV2,
44201
+ externalContent,
43915
44202
  activeTurns,
43916
44203
  connectionEpoch,
43917
44204
  diagnostics,
@@ -43968,15 +44255,15 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
43968
44255
  }
43969
44256
 
43970
44257
  // src/pairing/pair-local-machine.ts
43971
- import { mkdir as mkdir5, realpath as realpath9, stat as stat8 } from "node:fs/promises";
44258
+ import { mkdir as mkdir6, realpath as realpath10, stat as stat9 } from "node:fs/promises";
43972
44259
  import { hostname as hostname3 } from "node:os";
43973
44260
  import { basename as basename7, resolve as resolve7 } from "node:path";
43974
44261
  import { fetch as fetch4 } from "undici";
43975
44262
 
43976
44263
  // src/storage/runtime-installation-store.ts
43977
- import { createHash as createHash7, randomUUID as randomUUID7 } from "node:crypto";
43978
- import { mkdir as mkdir4, open as open5, readdir as readdir3, rename as rename3, unlink, writeFile as writeFile3 } from "node:fs/promises";
43979
- import { dirname as dirname5, join as join18, resolve as resolve6 } from "node:path";
44264
+ import { createHash as createHash8, randomUUID as randomUUID8 } from "node:crypto";
44265
+ import { mkdir as mkdir5, open as open5, readdir as readdir3, rename as rename4, unlink, writeFile as writeFile4 } from "node:fs/promises";
44266
+ import { dirname as dirname6, join as join19, resolve as resolve6 } from "node:path";
43980
44267
  var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
43981
44268
  var CONNECTION_ID_PATTERN = /^mcn_[a-f0-9]{32}$/;
43982
44269
  var INSTALLATION_ID_PATTERN = /^min_[a-f0-9]{32}$/;
@@ -44104,13 +44391,13 @@ function parseRelayOrigin(value) {
44104
44391
  return origin;
44105
44392
  }
44106
44393
  function connectionId() {
44107
- return `mcn_${randomUUID7().replaceAll("-", "")}`;
44394
+ return `mcn_${randomUUID8().replaceAll("-", "")}`;
44108
44395
  }
44109
44396
  function installationId() {
44110
- return `min_${randomUUID7().replaceAll("-", "")}`;
44397
+ return `min_${randomUUID8().replaceAll("-", "")}`;
44111
44398
  }
44112
44399
  function channelIndexFileName(channelId) {
44113
- return `mci_${createHash7("sha256").update(channelId).digest("hex")}.json`;
44400
+ return `mci_${createHash8("sha256").update(channelId).digest("hex")}.json`;
44114
44401
  }
44115
44402
  function decodeInstallationPointer(value) {
44116
44403
  if (!isRecord9(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
@@ -44218,15 +44505,15 @@ async function readJsonFile(path2, signal, missingCode) {
44218
44505
  }
44219
44506
  async function writeJsonAtomically(path2, value, signal) {
44220
44507
  signal.throwIfAborted();
44221
- const directory = dirname5(path2);
44222
- const temporaryPath = join18(directory, `.${randomUUID7()}.tmp`);
44508
+ const directory = dirname6(path2);
44509
+ const temporaryPath = join19(directory, `.${randomUUID8()}.tmp`);
44223
44510
  try {
44224
- await mkdir4(directory, { mode: 448, recursive: true });
44511
+ await mkdir5(directory, { mode: 448, recursive: true });
44225
44512
  signal.throwIfAborted();
44226
- await writeFile3(temporaryPath, `${JSON.stringify(value, null, 2)}
44513
+ await writeFile4(temporaryPath, `${JSON.stringify(value, null, 2)}
44227
44514
  `, { flag: "wx", mode: 384 });
44228
44515
  signal.throwIfAborted();
44229
- await rename3(temporaryPath, path2);
44516
+ await rename4(temporaryPath, path2);
44230
44517
  } catch (cause) {
44231
44518
  await unlink(temporaryPath).catch(() => void 0);
44232
44519
  signal.throwIfAborted();
@@ -44245,16 +44532,16 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
44245
44532
  this.applicationId = applicationId;
44246
44533
  this.installationId = installationId2;
44247
44534
  this.stateDirectory = stateDirectory;
44248
- this.#channelDirectory = join18(stateDirectory, "channels");
44249
- this.#connectionDirectory = join18(stateDirectory, "connections");
44535
+ this.#channelDirectory = join19(stateDirectory, "channels");
44536
+ this.#connectionDirectory = join19(stateDirectory, "connections");
44250
44537
  }
44251
44538
  static open = async (options, signal) => {
44252
44539
  signal.throwIfAborted();
44253
44540
  const applicationId = validateApplicationId(options.applicationId);
44254
44541
  const rootDirectory = resolve6(options.stateDirectory);
44255
- const applicationDirectory = join18(rootDirectory, "installations", applicationId);
44542
+ const applicationDirectory = join19(rootDirectory, "installations", applicationId);
44256
44543
  try {
44257
- await mkdir4(applicationDirectory, { mode: 448, recursive: true });
44544
+ await mkdir5(applicationDirectory, { mode: 448, recursive: true });
44258
44545
  } catch (cause) {
44259
44546
  throw new RuntimeInstallationStoreError(
44260
44547
  "installation_unavailable",
@@ -44265,9 +44552,9 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
44265
44552
  );
44266
44553
  }
44267
44554
  const storedInstallationId = await readOrCreateInstallationId(applicationDirectory, signal);
44268
- const stateDirectory = join18(applicationDirectory, storedInstallationId);
44555
+ const stateDirectory = join19(applicationDirectory, storedInstallationId);
44269
44556
  try {
44270
- await mkdir4(stateDirectory, { mode: 448, recursive: true });
44557
+ await mkdir5(stateDirectory, { mode: 448, recursive: true });
44271
44558
  } catch (cause) {
44272
44559
  throw new RuntimeInstallationStoreError(
44273
44560
  "installation_unavailable",
@@ -44280,8 +44567,8 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
44280
44567
  signal.throwIfAborted();
44281
44568
  return new _RuntimeInstallationStore(applicationId, storedInstallationId, stateDirectory);
44282
44569
  };
44283
- connectionPath = (connectionId2) => join18(this.#connectionDirectory, `${validateConnectionId(connectionId2)}.json`);
44284
- channelIndexPath = (channelId) => join18(this.#channelDirectory, channelIndexFileName(validateIdentifier(channelId, "invalid_channel_id")));
44570
+ connectionPath = (connectionId2) => join19(this.#connectionDirectory, `${validateConnectionId(connectionId2)}.json`);
44571
+ channelIndexPath = (channelId) => join19(this.#channelDirectory, channelIndexFileName(validateIdentifier(channelId, "invalid_channel_id")));
44285
44572
  readConnection = async (connectionId2, signal) => {
44286
44573
  const stored = decodeConnection(
44287
44574
  await readJsonFile(this.connectionPath(connectionId2), signal, "connection_not_found")
@@ -44443,7 +44730,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
44443
44730
  };
44444
44731
  };
44445
44732
  async function readOrCreateInstallationId(applicationDirectory, signal) {
44446
- const pointerPath = join18(applicationDirectory, "current.json");
44733
+ const pointerPath = join19(applicationDirectory, "current.json");
44447
44734
  try {
44448
44735
  return decodeInstallationPointer(await readJsonFile(pointerPath, signal, "installation_not_found")).installationId;
44449
44736
  } catch (cause) {
@@ -44453,7 +44740,7 @@ async function readOrCreateInstallationId(applicationDirectory, signal) {
44453
44740
  }
44454
44741
  const candidate = installationId();
44455
44742
  try {
44456
- await writeFile3(pointerPath, `${JSON.stringify({ installationId: candidate, version: 1 })}
44743
+ await writeFile4(pointerPath, `${JSON.stringify({ installationId: candidate, version: 1 })}
44457
44744
  `, {
44458
44745
  flag: "wx",
44459
44746
  mode: 384
@@ -44537,9 +44824,9 @@ function validatePairingId(value) {
44537
44824
  async function resolveDefaultWorkspace2(path2) {
44538
44825
  const requestedWorkspace = resolve7(path2);
44539
44826
  try {
44540
- await mkdir5(requestedWorkspace, { recursive: true, mode: 448 });
44541
- const defaultWorkspace = await realpath9(requestedWorkspace);
44542
- const metadata = await stat8(defaultWorkspace);
44827
+ await mkdir6(requestedWorkspace, { recursive: true, mode: 448 });
44828
+ const defaultWorkspace = await realpath10(requestedWorkspace);
44829
+ const metadata = await stat9(defaultWorkspace);
44543
44830
  if (!metadata.isDirectory()) {
44544
44831
  throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
44545
44832
  }
@@ -44773,9 +45060,9 @@ function loadMobiusRuntimeConnection(environment = process.env) {
44773
45060
  async function resolveWorkspace(path2) {
44774
45061
  const requested = resolve8(path2);
44775
45062
  try {
44776
- await mkdir6(requested, { recursive: true, mode: 448 });
44777
- const resolved = await realpath10(requested);
44778
- const metadata = await stat9(resolved);
45063
+ await mkdir7(requested, { recursive: true, mode: 448 });
45064
+ const resolved = await realpath11(requested);
45065
+ const metadata = await stat10(resolved);
44779
45066
  if (!metadata.isDirectory()) {
44780
45067
  throw new MobiusRuntimeConfigurationError("The Runtime workspace is not a directory");
44781
45068
  }
@@ -44843,6 +45130,7 @@ var MobiusRuntimeEngine = class {
44843
45130
  export {
44844
45131
  DaemonLocalContext,
44845
45132
  DaemonReconnectTarget,
45133
+ InProcessAcpAgentDefinition,
44846
45134
  MobiusRuntimeConfigurationError,
44847
45135
  MobiusRuntimeEngine,
44848
45136
  OpaqueDaemonReconnectTarget,