@moxt-ai/mobius 0.0.307 → 0.0.308

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 (44) hide show
  1. package/dist/acp/adapter/codex/adapter.d.ts.map +1 -1
  2. package/dist/acp/adapter/codex/adapter.js +66 -9
  3. package/dist/acp/adapter/codex/adapter.js.map +1 -1
  4. package/dist/acp/adapter/codex/tool-event.d.ts +6 -0
  5. package/dist/acp/adapter/codex/tool-event.d.ts.map +1 -0
  6. package/dist/acp/adapter/codex/tool-event.js +66 -0
  7. package/dist/acp/adapter/codex/tool-event.js.map +1 -0
  8. package/dist/acp/adapter/session-events.d.ts +2 -2
  9. package/dist/acp/adapter/session-events.d.ts.map +1 -1
  10. package/dist/acp/adapter/session-events.js +81 -56
  11. package/dist/acp/adapter/session-events.js.map +1 -1
  12. package/dist/acp/content/content-externalizer.d.ts.map +1 -1
  13. package/dist/acp/content/content-externalizer.js +1 -31
  14. package/dist/acp/content/content-externalizer.js.map +1 -1
  15. package/dist/acp/harness/codex/agent.d.ts.map +1 -1
  16. package/dist/acp/harness/codex/agent.js +4 -75
  17. package/dist/acp/harness/codex/agent.js.map +1 -1
  18. package/dist/acp/harness/codex/app-server-protocol.d.ts +9 -0
  19. package/dist/acp/harness/codex/app-server-protocol.d.ts.map +1 -1
  20. package/dist/acp/harness/codex/app-server-protocol.js +1 -0
  21. package/dist/acp/harness/codex/app-server-protocol.js.map +1 -1
  22. package/dist/acp/harness/codex/history.d.ts +5 -0
  23. package/dist/acp/harness/codex/history.d.ts.map +1 -0
  24. package/dist/acp/harness/codex/history.js +116 -0
  25. package/dist/acp/harness/codex/history.js.map +1 -0
  26. package/dist/cli.js +723 -1346
  27. package/dist/cli.js.map +4 -4
  28. package/dist/runtime/command/registry/history.d.ts.map +1 -1
  29. package/dist/runtime/command/registry/history.js +5 -36
  30. package/dist/runtime/command/registry/history.js.map +1 -1
  31. package/dist/runtime.js +662 -1287
  32. package/dist/runtime.js.map +4 -4
  33. package/dist/session/history/session-event-history-projection.d.ts.map +1 -1
  34. package/dist/session/history/session-event-history-projection.js +23 -2
  35. package/dist/session/history/session-event-history-projection.js.map +1 -1
  36. package/package.json +2 -2
  37. package/dist/acp/native-history/codex/codex-history.d.ts +0 -17
  38. package/dist/acp/native-history/codex/codex-history.d.ts.map +0 -1
  39. package/dist/acp/native-history/codex/codex-history.js +0 -661
  40. package/dist/acp/native-history/codex/codex-history.js.map +0 -1
  41. package/dist/acp/native-history/codex/native-history-events.d.ts +0 -8
  42. package/dist/acp/native-history/codex/native-history-events.d.ts.map +0 -1
  43. package/dist/acp/native-history/codex/native-history-events.js +0 -92
  44. package/dist/acp/native-history/codex/native-history-events.js.map +0 -1
package/dist/cli.js CHANGED
@@ -2086,7 +2086,7 @@ var init_package = __esm({
2086
2086
  "package.json"() {
2087
2087
  package_default = {
2088
2088
  name: "@moxt-ai/mobius",
2089
- version: "0.0.307",
2089
+ version: "0.0.308",
2090
2090
  description: "Mobius CLI for pairing and running local AI agent services.",
2091
2091
  type: "module",
2092
2092
  bin: {
@@ -65111,11 +65111,11 @@ var init_session_mode = __esm({
65111
65111
  }
65112
65112
  return modes;
65113
65113
  }
65114
- async trySyncMode(query, mode, errorMessage2) {
65114
+ async trySyncMode(query, mode, errorMessage) {
65115
65115
  try {
65116
65116
  await query.setPermissionMode(mode);
65117
65117
  } catch (error62) {
65118
- this.options.logError(errorMessage2, error62);
65118
+ this.options.logError(errorMessage, error62);
65119
65119
  }
65120
65120
  }
65121
65121
  };
@@ -71089,6 +71089,7 @@ var init_app_server_protocol = __esm({
71089
71089
  threadTurnSchema = external_exports.object({
71090
71090
  id: boundedText(256).optional(),
71091
71091
  status: turnStatusSchema.optional(),
71092
+ error: external_exports.object({ message: external_exports.string().transform((message) => message.slice(0, 4096)) }).nullish(),
71092
71093
  items: external_exports.array(external_exports.unknown()).max(1e5)
71093
71094
  });
71094
71095
  threadTurnsSchema = external_exports.array(threadTurnSchema).max(1e5);
@@ -71563,12 +71564,12 @@ function presentToolItem(item) {
71563
71564
  };
71564
71565
  }
71565
71566
  if (item.type === "collabAgentToolCall") {
71566
- const spawn11 = item.tool === "spawnAgent";
71567
+ const spawn10 = item.tool === "spawnAgent";
71567
71568
  return {
71568
71569
  content: [],
71569
71570
  kind: "other",
71570
71571
  locations: [],
71571
- rawInput: spawn11 ? {
71572
+ rawInput: spawn10 ? {
71572
71573
  model: item.model,
71573
71574
  prompt: item.prompt,
71574
71575
  reasoningEffort: item.reasoningEffort,
@@ -71576,10 +71577,10 @@ function presentToolItem(item) {
71576
71577
  } : { receiverThreadIds: item.receiverThreadIds, senderThreadId: item.senderThreadId },
71577
71578
  rawOutput: {
71578
71579
  agentsStates: item.agentsStates,
71579
- ...spawn11 ? { receiverThreadIds: item.receiverThreadIds } : {}
71580
+ ...spawn10 ? { receiverThreadIds: item.receiverThreadIds } : {}
71580
71581
  },
71581
71582
  status: collaborationStatus(item.status),
71582
- title: spawn11 ? "Dispatch subagent" : "Wait for subagent"
71583
+ title: spawn10 ? "Dispatch subagent" : "Wait for subagent"
71583
71584
  };
71584
71585
  }
71585
71586
  if (item.type === "subAgentActivity" && item.kind === "started") {
@@ -71912,6 +71913,291 @@ var init_borrowed_agent = __esm({
71912
71913
  }
71913
71914
  });
71914
71915
 
71916
+ // src/storage/files/local-files.ts
71917
+ import { createReadStream as createReadStream2 } from "node:fs";
71918
+ import { mkdir as mkdir3, open as open4, readdir as readdir4, readFile as readFile5, realpath as realpath6, stat as stat5 } from "node:fs/promises";
71919
+ function entryKind(entry) {
71920
+ if (entry.isDirectory()) {
71921
+ return "directory";
71922
+ }
71923
+ if (entry.isFile()) {
71924
+ return "file";
71925
+ }
71926
+ if (entry.isSymbolicLink()) {
71927
+ return "symbolic-link";
71928
+ }
71929
+ if (entry.isBlockDevice() || entry.isCharacterDevice()) {
71930
+ return "device";
71931
+ }
71932
+ if (entry.isFIFO()) {
71933
+ return "fifo";
71934
+ }
71935
+ return entry.isSocket() ? "socket" : "unknown";
71936
+ }
71937
+ async function canonicalPath(path8) {
71938
+ return await realpath6(path8);
71939
+ }
71940
+ async function readPathMetadata(path8) {
71941
+ const metadata = await stat5(path8);
71942
+ return {
71943
+ kind: metadata.isDirectory() ? "directory" : metadata.isFile() ? "file" : "other",
71944
+ modifiedAt: metadata.mtime,
71945
+ modifiedMilliseconds: metadata.mtimeMs,
71946
+ size: metadata.size
71947
+ };
71948
+ }
71949
+ async function listDirectory(path8) {
71950
+ const entries = await readdir4(path8, { withFileTypes: true });
71951
+ return entries.map((entry) => ({ kind: entryKind(entry), name: entry.name }));
71952
+ }
71953
+ async function ensurePrivateDirectory(path8) {
71954
+ await mkdir3(path8, { mode: 448, recursive: true });
71955
+ }
71956
+ async function ensureCanonicalDirectory(path8) {
71957
+ await ensurePrivateDirectory(path8);
71958
+ const resolved = await realpath6(path8);
71959
+ return (await stat5(resolved)).isDirectory() ? resolved : null;
71960
+ }
71961
+ async function readFileStart(path8, byteLength) {
71962
+ const bytes = new Uint8Array(byteLength);
71963
+ const handle = await open4(path8, "r");
71964
+ try {
71965
+ await handle.read(bytes, 0, byteLength, 0);
71966
+ } finally {
71967
+ await handle.close();
71968
+ }
71969
+ return bytes;
71970
+ }
71971
+ async function readFileBytes(path8) {
71972
+ return await readFile5(path8);
71973
+ }
71974
+ function readFileChunks(path8, chunkBytes, signal) {
71975
+ return createReadStream2(path8, { highWaterMark: chunkBytes, signal });
71976
+ }
71977
+ var init_local_files = __esm({
71978
+ "src/storage/files/local-files.ts"() {
71979
+ "use strict";
71980
+ }
71981
+ });
71982
+
71983
+ // src/acp/content/raster.ts
71984
+ import { basename as basename4, isAbsolute as isAbsolute9, normalize } from "node:path";
71985
+ import { fileURLToPath } from "node:url";
71986
+ function startsWith(bytes, signature, offset = 0) {
71987
+ if (bytes.byteLength < offset + signature.byteLength) {
71988
+ return false;
71989
+ }
71990
+ return signature.every((value, index2) => bytes[offset + index2] === value);
71991
+ }
71992
+ function sniffRasterMime(bytes) {
71993
+ if (startsWith(bytes, PNG_SIGNATURE)) {
71994
+ return "image/png";
71995
+ }
71996
+ if (startsWith(bytes, JPEG_SIGNATURE)) {
71997
+ return "image/jpeg";
71998
+ }
71999
+ if (startsWith(bytes, GIF87_SIGNATURE) || startsWith(bytes, GIF89_SIGNATURE)) {
72000
+ return "image/gif";
72001
+ }
72002
+ if (startsWith(bytes, RIFF_SIGNATURE) && startsWith(bytes, WEBP_SIGNATURE, 8)) {
72003
+ return "image/webp";
72004
+ }
72005
+ return null;
72006
+ }
72007
+ async function resolveCanonicalPath(requested, signal) {
72008
+ signal.throwIfAborted();
72009
+ if (!isAbsolute9(requested) || requested.includes("\0") || normalize(requested) !== requested) {
72010
+ return null;
72011
+ }
72012
+ try {
72013
+ const target = await canonicalPath(requested);
72014
+ signal.throwIfAborted();
72015
+ if (!isAbsolute9(target) || normalize(target) !== target) {
72016
+ return null;
72017
+ }
72018
+ return target;
72019
+ } catch (cause) {
72020
+ signal.throwIfAborted();
72021
+ if (cause instanceof Error && cause.name === "AbortError") {
72022
+ throw cause;
72023
+ }
72024
+ return null;
72025
+ }
72026
+ }
72027
+ function parseLocalImageUri(uri) {
72028
+ const trimmed = uri.trim();
72029
+ if (trimmed.length === 0 || trimmed.length > 2048 || trimmed.includes("\0")) {
72030
+ return null;
72031
+ }
72032
+ if (trimmed.startsWith("data:")) {
72033
+ return null;
72034
+ }
72035
+ if (trimmed.startsWith("file:")) {
72036
+ try {
72037
+ const url2 = new URL(trimmed);
72038
+ if (url2.protocol !== "file:" || url2.host.length > 0) {
72039
+ return null;
72040
+ }
72041
+ return fileURLToPath(url2);
72042
+ } catch {
72043
+ return null;
72044
+ }
72045
+ }
72046
+ if (!isAbsolute9(trimmed) && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
72047
+ return null;
72048
+ }
72049
+ return trimmed;
72050
+ }
72051
+ async function readLocalRaster(uri, signal) {
72052
+ signal.throwIfAborted();
72053
+ const requested = parseLocalImageUri(uri);
72054
+ if (requested === null) {
72055
+ return null;
72056
+ }
72057
+ const target = await resolveCanonicalPath(requested, signal);
72058
+ if (target === null) {
72059
+ return null;
72060
+ }
72061
+ const targetMetadata = await readPathMetadata(target);
72062
+ signal.throwIfAborted();
72063
+ if (targetMetadata.kind !== "file" || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
72064
+ return null;
72065
+ }
72066
+ const header = await readFileStart(target, 12);
72067
+ signal.throwIfAborted();
72068
+ const mimeType = sniffRasterMime(header);
72069
+ if (mimeType === null) {
72070
+ return null;
72071
+ }
72072
+ return new LocalRasterImage(basename4(target) || "Image", mimeType, target);
72073
+ }
72074
+ var MAX_LOCAL_RASTER_BYTES, PNG_SIGNATURE, JPEG_SIGNATURE, GIF87_SIGNATURE, GIF89_SIGNATURE, RIFF_SIGNATURE, WEBP_SIGNATURE, LocalRasterImage;
72075
+ var init_raster = __esm({
72076
+ "src/acp/content/raster.ts"() {
72077
+ "use strict";
72078
+ init_local_files();
72079
+ MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
72080
+ PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
72081
+ JPEG_SIGNATURE = Uint8Array.of(255, 216, 255);
72082
+ GIF87_SIGNATURE = new TextEncoder().encode("GIF87a");
72083
+ GIF89_SIGNATURE = new TextEncoder().encode("GIF89a");
72084
+ RIFF_SIGNATURE = new TextEncoder().encode("RIFF");
72085
+ WEBP_SIGNATURE = new TextEncoder().encode("WEBP");
72086
+ LocalRasterImage = class {
72087
+ mimeType;
72088
+ name;
72089
+ sourceUri;
72090
+ constructor(name2, mimeType, sourceUri) {
72091
+ this.mimeType = mimeType;
72092
+ this.name = name2;
72093
+ this.sourceUri = sourceUri;
72094
+ }
72095
+ base64 = async () => Buffer.from(await readFileBytes(this.sourceUri)).toString("base64");
72096
+ };
72097
+ }
72098
+ });
72099
+
72100
+ // src/acp/native-history/codex/history-images.ts
72101
+ function isRasterMime(value) {
72102
+ return value === "image/png" || value === "image/jpeg" || value === "image/gif" || value === "image/webp";
72103
+ }
72104
+ function parseNativeHistoryImage(uri) {
72105
+ const header = DATA_IMAGE_HEADER.exec(uri);
72106
+ if (header === null) {
72107
+ return null;
72108
+ }
72109
+ const mimeType = header[1] ?? "";
72110
+ const data = uri.slice(header[0].length);
72111
+ if (!isRasterMime(mimeType) || data.length < 4 || data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
72112
+ return null;
72113
+ }
72114
+ if (data.length % 4 !== 0 || !BASE_64.test(data)) {
72115
+ return null;
72116
+ }
72117
+ return { data, mimeType, name: "" };
72118
+ }
72119
+ async function embedLocalHistoryImages(history, signal) {
72120
+ if (history.status !== "available") {
72121
+ return history;
72122
+ }
72123
+ const messages = [];
72124
+ let imageCharacters = 0;
72125
+ for (const message of history.messages) {
72126
+ signal.throwIfAborted();
72127
+ const resolved = await resolveMessageImages(message, imageCharacters, signal);
72128
+ imageCharacters += (resolved.images ?? []).reduce((size, image) => size + image.data.length, 0);
72129
+ messages.push(resolved);
72130
+ }
72131
+ return {
72132
+ ...history,
72133
+ messages
72134
+ };
72135
+ }
72136
+ async function resolveMessageImages(message, usedCharacters, signal) {
72137
+ const images = [...message.images ?? []];
72138
+ let imageCharacters = images.reduce((size, image) => size + image.data.length, 0);
72139
+ const text2 = await replaceImageMarkers(message.text, async (uri) => {
72140
+ if (images.length >= 8 || usedCharacters + imageCharacters >= SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
72141
+ return "[Image unavailable]";
72142
+ }
72143
+ const embedded = parseNativeHistoryImage(uri);
72144
+ if (embedded !== null) {
72145
+ if (usedCharacters + imageCharacters + embedded.data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
72146
+ return "[Image unavailable]";
72147
+ }
72148
+ images.push({ ...embedded, name: `Image ${(images.length + 1).toString()}` });
72149
+ imageCharacters += embedded.data.length;
72150
+ return "";
72151
+ }
72152
+ const local = await readLocalRaster(uri, signal);
72153
+ if (local === null) {
72154
+ return "[Image unavailable]";
72155
+ }
72156
+ const data = await local.base64();
72157
+ if (usedCharacters + imageCharacters + data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
72158
+ return "[Image unavailable]";
72159
+ }
72160
+ images.push({
72161
+ data,
72162
+ mimeType: local.mimeType,
72163
+ name: local.name
72164
+ });
72165
+ imageCharacters += data.length;
72166
+ return "";
72167
+ });
72168
+ return {
72169
+ ...message,
72170
+ text: text2,
72171
+ ...images.length > 0 ? { images } : {}
72172
+ };
72173
+ }
72174
+ async function replaceImageMarkers(text2, replace) {
72175
+ const matches = [...text2.matchAll(IMAGE_MARKER)];
72176
+ if (matches.length === 0) {
72177
+ return text2;
72178
+ }
72179
+ let cursor = 0;
72180
+ let rewritten = "";
72181
+ for (const match of matches) {
72182
+ const index2 = match.index ?? 0;
72183
+ rewritten += text2.slice(cursor, index2);
72184
+ rewritten += await replace(match[1] ?? "");
72185
+ cursor = index2 + match[0].length;
72186
+ }
72187
+ return `${rewritten}${text2.slice(cursor)}`;
72188
+ }
72189
+ var IMAGE_MARKER, DATA_IMAGE_HEADER, BASE_64, SESSION_HISTORY_IMAGE_CHARACTER_LIMIT;
72190
+ var init_history_images = __esm({
72191
+ "src/acp/native-history/codex/history-images.ts"() {
72192
+ "use strict";
72193
+ init_raster();
72194
+ IMAGE_MARKER = /\[@image\]\(([^)\r\n]*)(?:\)|$)/g;
72195
+ DATA_IMAGE_HEADER = /^data:(image\/[a-z+]+);base64,/;
72196
+ BASE_64 = /^[A-Za-z0-9+/]*={0,2}$/;
72197
+ SESSION_HISTORY_IMAGE_CHARACTER_LIMIT = 4e6;
72198
+ }
72199
+ });
72200
+
71915
72201
  // src/acp/harness/codex/owned-agent.ts
71916
72202
  import { randomUUID as randomUUID5 } from "node:crypto";
71917
72203
  import { setTimeout as delay } from "node:timers/promises";
@@ -72574,6 +72860,126 @@ var init_owned_agent = __esm({
72574
72860
  }
72575
72861
  });
72576
72862
 
72863
+ // src/acp/harness/codex/history.ts
72864
+ import { createHash } from "node:crypto";
72865
+ async function replayCodexHistory(client2, threadId, emit, signal) {
72866
+ const deadline = AbortSignal.any([signal, AbortSignal.timeout(6e4)]);
72867
+ const seenCursors = /* @__PURE__ */ new Set();
72868
+ let cursor = null;
72869
+ let turnIndex = 0;
72870
+ for (; ; ) {
72871
+ deadline.throwIfAborted();
72872
+ const page = threadTurnsPageSchema.parse(
72873
+ await client2.request(
72874
+ "thread/turns/list",
72875
+ {
72876
+ threadId,
72877
+ limit: CODEX_HISTORY_TURN_PAGE_LIMIT,
72878
+ sortDirection: "asc",
72879
+ itemsView: "full",
72880
+ ...cursor === null ? {} : { cursor }
72881
+ },
72882
+ deadline
72883
+ )
72884
+ );
72885
+ for (const turn of page.data) {
72886
+ for (const rawItem of turn.items) {
72887
+ deadline.throwIfAborted();
72888
+ const item = decodeThreadItem(rawItem);
72889
+ if (item === null) {
72890
+ continue;
72891
+ }
72892
+ if (item.type === "userMessage") {
72893
+ const text2 = item.content.flatMap((content) => {
72894
+ if (typeof content !== "object" || content === null) {
72895
+ return [];
72896
+ }
72897
+ const type = Reflect.get(content, "type");
72898
+ const text3 = Reflect.get(content, "text");
72899
+ const url2 = Reflect.get(content, "url");
72900
+ if (type === "image" && typeof url2 === "string") {
72901
+ return [`[@image](${url2})`];
72902
+ }
72903
+ return type === "text" && typeof text3 === "string" ? [text3] : [];
72904
+ }).join("");
72905
+ const history = await embedLocalHistoryImages(
72906
+ { status: "available", truncated: false, messages: [{ role: "user", text: text2 }] },
72907
+ deadline
72908
+ );
72909
+ if (history.status !== "available") {
72910
+ continue;
72911
+ }
72912
+ const message = history.messages[0];
72913
+ for (const image of message?.images ?? []) {
72914
+ await emit({
72915
+ content: { type: "image", data: image.data, mimeType: image.mimeType },
72916
+ messageId: item.id,
72917
+ sessionUpdate: "user_message_chunk"
72918
+ });
72919
+ }
72920
+ const restoredText = message?.text ?? "";
72921
+ if (restoredText.length > 0) {
72922
+ await emit({
72923
+ content: { text: restoredText, type: "text" },
72924
+ messageId: item.id,
72925
+ sessionUpdate: "user_message_chunk"
72926
+ });
72927
+ }
72928
+ } else if (item.type === "agentMessage") {
72929
+ await emit(agentMessageUpdate(item.id, item.text));
72930
+ } else if (item.type === "reasoning") {
72931
+ const text2 = reasoningText(item);
72932
+ if (text2 !== null && text2.length > 0) {
72933
+ await emit({
72934
+ content: { text: text2, type: "text" },
72935
+ messageId: item.id,
72936
+ sessionUpdate: "agent_thought_chunk"
72937
+ });
72938
+ }
72939
+ } else if (item.type === "contextCompaction") {
72940
+ await emit({ compactionId: item.id, sessionUpdate: "compaction_update", status: "completed" });
72941
+ } else {
72942
+ const update = toolCallUpdate(item, "snapshot");
72943
+ if (update !== null) {
72944
+ await emit({ ...update, sessionUpdate: "tool_call" });
72945
+ }
72946
+ }
72947
+ }
72948
+ if (turn.error != null) {
72949
+ const identity2 = createHash("sha256").update(threadId).update("\0").update(turn.id ?? turnIndex.toString()).digest("hex");
72950
+ await emit({
72951
+ sessionUpdate: "tool_call",
72952
+ toolCallId: `agent-error-${identity2}`,
72953
+ title: "Agent error",
72954
+ kind: "other",
72955
+ status: "failed",
72956
+ rawOutput: { message: turn.error.message },
72957
+ content: [{ type: "content", content: { type: "text", text: turn.error.message } }]
72958
+ });
72959
+ }
72960
+ turnIndex += 1;
72961
+ }
72962
+ if (page.nextCursor == null) {
72963
+ return;
72964
+ }
72965
+ if (page.data.length === 0 || seenCursors.has(page.nextCursor)) {
72966
+ throw new AcpExecutionError("Codex repeated a history page cursor", {}, "invalid_native_session_response");
72967
+ }
72968
+ seenCursors.add(page.nextCursor);
72969
+ cursor = page.nextCursor;
72970
+ }
72971
+ }
72972
+ var init_history = __esm({
72973
+ "src/acp/harness/codex/history.ts"() {
72974
+ "use strict";
72975
+ init_acp_error();
72976
+ init_history_images();
72977
+ init_app_server_protocol();
72978
+ init_items();
72979
+ init_owned_agent();
72980
+ }
72981
+ });
72982
+
72577
72983
  // ../mobius-sdk/src/protocol/platform/mobius-api.ts
72578
72984
  function parseMobiusApiPrefix(value) {
72579
72985
  if (typeof value !== "string" || !API_PREFIX_PATTERN.test(value)) {
@@ -73856,7 +74262,7 @@ function decode3(schema, encoded) {
73856
74262
  throw new ProtocolMessageError("Invalid native session message", { cause });
73857
74263
  }
73858
74264
  }
73859
- var NATIVE_SESSION_REQUEST_KIND, NATIVE_SESSION_RESULT_KIND, NATIVE_SESSION_CANCEL_KIND, SESSION_HISTORY_CHARACTER_LIMIT, SESSION_HISTORY_MESSAGE_LIMIT, envelope, activeTurnSnapshotSchema, identity, nativeSessionRequestSchema, nativeSessionCommandSchema, nativeSessionEntrySchema, resultEnvelope, nativeSessionResultSchema, nativeSessionCancelSchema, decodeNativeSessionCommand, encodeNativeSessionCommand, decodeNativeSessionResult, encodeNativeSessionResult, decodeNativeSessionCancel, encodeNativeSessionCancel;
74265
+ var NATIVE_SESSION_REQUEST_KIND, NATIVE_SESSION_RESULT_KIND, NATIVE_SESSION_CANCEL_KIND, envelope, activeTurnSnapshotSchema, identity, nativeSessionRequestSchema, nativeSessionCommandSchema, nativeSessionEntrySchema, resultEnvelope, nativeSessionResultSchema, nativeSessionCancelSchema, decodeNativeSessionCommand, encodeNativeSessionCommand, decodeNativeSessionResult, encodeNativeSessionResult, decodeNativeSessionCancel, encodeNativeSessionCancel;
73860
74266
  var init_native = __esm({
73861
74267
  "../mobius-sdk/src/protocol/session/native/index.ts"() {
73862
74268
  "use strict";
@@ -73871,8 +74277,6 @@ var init_native = __esm({
73871
74277
  NATIVE_SESSION_REQUEST_KIND = "native.session.request";
73872
74278
  NATIVE_SESSION_RESULT_KIND = "native.session.result";
73873
74279
  NATIVE_SESSION_CANCEL_KIND = "native.session.cancel";
73874
- SESSION_HISTORY_CHARACTER_LIMIT = 256e3;
73875
- SESSION_HISTORY_MESSAGE_LIMIT = 1e3;
73876
74280
  envelope = {
73877
74281
  requestId: identifierStringSchema,
73878
74282
  sessionId: identifierStringSchema
@@ -74362,6 +74766,7 @@ var init_event_log = __esm({
74362
74766
  nativeEventPageRequestSchema = external_exports.object({
74363
74767
  cursor: external_exports.string().min(1).max(512).nullable(),
74364
74768
  eventLimit: external_exports.number().int().min(1).max(1e4),
74769
+ // Legacy callers may still send this option; readers must ignore it.
74365
74770
  omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional()
74366
74771
  }).readonly();
74367
74772
  queuedPromptRequestEventLogSchema = external_exports.object({
@@ -74391,7 +74796,7 @@ function decode5(schema, encoded) {
74391
74796
  }
74392
74797
  }
74393
74798
  var SESSION_HISTORY_PAGE_LOAD_KIND, SESSION_HISTORY_PAGE_LOADED_KIND, SESSION_PREVIEW_HISTORY_PAGE_LOAD_KIND, SESSION_PREVIEW_HISTORY_PAGE_LOADED_KIND, pageRequestFields, sessionHistoryPageLoadSchema, sessionPreviewHistoryPageLoadSchema, pageLoadedFields, sessionHistoryPageLoadedSchema, sessionPreviewHistoryPageLoadedSchema, decodeSessionHistoryPageLoad, decodeSessionHistoryPageLoaded, decodeSessionPreviewHistoryPageLoad, decodeSessionPreviewHistoryPageLoaded, encodeSessionHistoryPageLoad, encodeSessionHistoryPageLoaded, encodeSessionPreviewHistoryPageLoad, encodeSessionPreviewHistoryPageLoaded;
74394
- var init_history = __esm({
74799
+ var init_history2 = __esm({
74395
74800
  "../mobius-sdk/src/protocol/session/observability/history.ts"() {
74396
74801
  "use strict";
74397
74802
  init_zod();
@@ -74406,6 +74811,7 @@ var init_history = __esm({
74406
74811
  pageRequestFields = {
74407
74812
  cursor: external_exports.string().min(1).max(512).nullable(),
74408
74813
  eventLimit: external_exports.number().int().min(1).max(1e4),
74814
+ // Decode old clients without rejecting their request; omission has no effect.
74409
74815
  omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional(),
74410
74816
  requestId: identifierStringSchema,
74411
74817
  sessionId: identifierStringSchema
@@ -74912,7 +75318,7 @@ var init_daemon_transport = __esm({
74912
75318
  init_lifecycle();
74913
75319
  init_native();
74914
75320
  init_event_log();
74915
- init_history();
75321
+ init_history2();
74916
75322
  init_commands();
74917
75323
  init_workspace();
74918
75324
  init_message_codec();
@@ -75178,7 +75584,7 @@ var init_protocol = __esm({
75178
75584
  init_lifecycle();
75179
75585
  init_native();
75180
75586
  init_event_log();
75181
- init_history();
75587
+ init_history2();
75182
75588
  init_commands();
75183
75589
  init_usage();
75184
75590
  init_turn_history();
@@ -75651,11 +76057,10 @@ var init_agent = __esm({
75651
76057
  "use strict";
75652
76058
  init_zod();
75653
76059
  init_executable();
75654
- init_acp_error();
75655
76060
  init_app_server_client();
75656
76061
  init_app_server_protocol();
75657
76062
  init_borrowed_agent();
75658
- init_items();
76063
+ init_history();
75659
76064
  init_owned_agent();
75660
76065
  init_settings3();
75661
76066
  APPROVAL_TIMEOUT_MILLISECONDS3 = 36e5;
@@ -75885,83 +76290,7 @@ var init_agent = __esm({
75885
76290
  // ACP load requires chronological replay. Resume only restores execution;
75886
76291
  // native pages supply history without a single full-transcript response.
75887
76292
  #replaySavedHistory = async (signal) => {
75888
- const deadline = AbortSignal.any([signal, AbortSignal.timeout(6e4)]);
75889
- const seenCursors = /* @__PURE__ */ new Set();
75890
- let cursor = null;
75891
- for (; ; ) {
75892
- deadline.throwIfAborted();
75893
- const page = threadTurnsPageSchema.parse(
75894
- await this.#appServer.request(
75895
- "thread/turns/list",
75896
- {
75897
- threadId: this.#nativeSessionId,
75898
- limit: CODEX_HISTORY_TURN_PAGE_LIMIT,
75899
- sortDirection: "asc",
75900
- itemsView: "full",
75901
- ...cursor === null ? {} : { cursor }
75902
- },
75903
- deadline
75904
- )
75905
- );
75906
- await this.#replayHistory(page.data, deadline);
75907
- if (page.nextCursor == null) {
75908
- return;
75909
- }
75910
- if (page.data.length === 0 || seenCursors.has(page.nextCursor)) {
75911
- throw new AcpExecutionError(
75912
- "Codex repeated a history page cursor",
75913
- {},
75914
- "invalid_native_session_response"
75915
- );
75916
- }
75917
- seenCursors.add(page.nextCursor);
75918
- cursor = page.nextCursor;
75919
- }
75920
- };
75921
- #replayHistory = async (turns, signal) => {
75922
- for (const turn of turns) {
75923
- for (const rawItem of turn.items) {
75924
- signal.throwIfAborted();
75925
- const item = decodeThreadItem(rawItem);
75926
- if (item === null) {
75927
- continue;
75928
- }
75929
- if (item.type === "userMessage") {
75930
- const text2 = item.content.flatMap((content) => {
75931
- if (typeof content !== "object" || content === null) {
75932
- return [];
75933
- }
75934
- const type = Reflect.get(content, "type");
75935
- const text3 = Reflect.get(content, "text");
75936
- return type === "text" && typeof text3 === "string" ? [text3] : [];
75937
- }).join("");
75938
- if (text2.length > 0) {
75939
- await this.#emit({
75940
- content: { text: text2, type: "text" },
75941
- messageId: item.id,
75942
- sessionUpdate: "user_message_chunk"
75943
- });
75944
- }
75945
- continue;
75946
- }
75947
- if (item.type === "agentMessage") {
75948
- await this.#emit(agentMessageUpdate(item.id, item.text));
75949
- continue;
75950
- }
75951
- if (item.type === "contextCompaction") {
75952
- await this.#emit({
75953
- compactionId: item.id,
75954
- sessionUpdate: "compaction_update",
75955
- status: "completed"
75956
- });
75957
- continue;
75958
- }
75959
- const update = toolCallUpdate(item, "snapshot");
75960
- if (update !== null) {
75961
- await this.#emit({ ...update, sessionUpdate: "tool_call" });
75962
- }
75963
- }
75964
- }
76293
+ await replayCodexHistory(this.#appServer, this.#nativeSessionId, this.#emit, signal);
75965
76294
  };
75966
76295
  /** Announces the manual compact command after every session entry point —
75967
76296
  * new, load, resume, and fork — so clients on restored sessions discover
@@ -76567,7 +76896,7 @@ var init_pi_commands = __esm({
76567
76896
 
76568
76897
  // src/acp/harness/pi/upstream/dist/acp/pi-sessions.js
76569
76898
  import { closeSync as closeSync2, existsSync as existsSync4, openSync as openSync2, readdirSync as readdirSync4, readFileSync as readFileSync3, readSync as readSync2, statSync as statSync2 } from "node:fs";
76570
- import { isAbsolute as isAbsolute9, join as join14, resolve as resolve9 } from "node:path";
76899
+ import { isAbsolute as isAbsolute10, join as join14, resolve as resolve9 } from "node:path";
76571
76900
  function getPiAgentDir(environment) {
76572
76901
  const configured = environment["PI_CODING_AGENT_DIR"];
76573
76902
  return configured ? resolve9(configured) : join14(environmentHome(environment), ".pi", "agent");
@@ -76587,7 +76916,7 @@ function readSessionDirFromSettings(agentDir) {
76587
76916
  if (typeof sessionDir !== "string" || !sessionDir.trim()) {
76588
76917
  return null;
76589
76918
  }
76590
- return isAbsolute9(sessionDir) ? sessionDir : resolve9(agentDir, sessionDir);
76919
+ return isAbsolute10(sessionDir) ? sessionDir : resolve9(agentDir, sessionDir);
76591
76920
  } catch {
76592
76921
  return null;
76593
76922
  }
@@ -77438,7 +77767,7 @@ var init_pi_tools = __esm({
77438
77767
  // src/acp/harness/pi/upstream/dist/acp/session.js
77439
77768
  import { randomUUID as randomUUID6 } from "node:crypto";
77440
77769
  import { readFileSync as readFileSync7 } from "node:fs";
77441
- import { isAbsolute as isAbsolute10, resolve as resolvePath } from "node:path";
77770
+ import { isAbsolute as isAbsolute11, resolve as resolvePath } from "node:path";
77442
77771
  import { RequestError as RequestError6 } from "@agentclientprotocol/sdk";
77443
77772
  function toUsageUpdate(stats) {
77444
77773
  const used = stats?.contextUsage?.tokens;
@@ -77534,7 +77863,7 @@ function toToolCallLocations(args, cwd, line) {
77534
77863
  if (!path8) {
77535
77864
  return void 0;
77536
77865
  }
77537
- const resolvedPath = isAbsolute10(path8) ? path8 : resolvePath(cwd, path8);
77866
+ const resolvedPath = isAbsolute11(path8) ? path8 : resolvePath(cwd, path8);
77538
77867
  return [{ path: resolvedPath, ...typeof line === "number" ? { line } : {} }];
77539
77868
  }
77540
77869
  function stringProp(source, key) {
@@ -78102,7 +78431,7 @@ var init_session = __esm({
78102
78431
  const p = getToolPath(args);
78103
78432
  if (p) {
78104
78433
  try {
78105
- const abs = isAbsolute10(p) ? p : resolvePath(this.cwd, p);
78434
+ const abs = isAbsolute11(p) ? p : resolvePath(this.cwd, p);
78106
78435
  snapshotOldText = readFileSync7(abs, "utf8");
78107
78436
  this.fileSnapshots.set(toolCallId, { path: p, oldText: snapshotOldText });
78108
78437
  if (toolName === "edit") {
@@ -78185,7 +78514,7 @@ var init_session = __esm({
78185
78514
  let hasStructuredDiff = false;
78186
78515
  if (!isError && snapshot) {
78187
78516
  try {
78188
- const abs = isAbsolute10(snapshot.path) ? snapshot.path : resolvePath(this.cwd, snapshot.path);
78517
+ const abs = isAbsolute11(snapshot.path) ? snapshot.path : resolvePath(this.cwd, snapshot.path);
78189
78518
  const newText = readFileSync7(abs, "utf8");
78190
78519
  if (snapshot.oldText === null || newText !== snapshot.oldText) {
78191
78520
  hasStructuredDiff = true;
@@ -78364,7 +78693,7 @@ var init_prompt = __esm({
78364
78693
  import { spawnSync } from "node:child_process";
78365
78694
  import { randomUUID as randomUUID7 } from "node:crypto";
78366
78695
  import { existsSync as existsSync7, readdirSync as readdirSync6, readFileSync as readFileSync8, realpathSync as realpathSync3, statSync as statSync3, unlinkSync as unlinkSync2 } from "node:fs";
78367
- import { basename as basename4, dirname as dirname7, isAbsolute as isAbsolute11, join as join17 } from "node:path";
78696
+ import { basename as basename5, dirname as dirname7, isAbsolute as isAbsolute12, join as join17 } from "node:path";
78368
78697
  import { RequestError as RequestError7 } from "@agentclientprotocol/sdk";
78369
78698
  function thinkingLevelName(id) {
78370
78699
  return id.split(/[_-]/u).map((part) => part.length === 0 ? part : `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -78703,7 +79032,7 @@ function buildStartupInfo(opts) {
78703
79032
  try {
78704
79033
  const prompts = readdirSync6(promptsDir).filter((f) => f.endsWith(".md"));
78705
79034
  for (const f of prompts) {
78706
- promptsItems.push(`/${basename4(f, ".md")}`);
79035
+ promptsItems.push(`/${basename5(f, ".md")}`);
78707
79036
  }
78708
79037
  } catch {
78709
79038
  }
@@ -78922,7 +79251,7 @@ var init_agent2 = __esm({
78922
79251
  };
78923
79252
  }
78924
79253
  async newSession(params) {
78925
- if (!isAbsolute11(params.cwd)) {
79254
+ if (!isAbsolute12(params.cwd)) {
78926
79255
  throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
78927
79256
  }
78928
79257
  this.lastSessionCwd = params.cwd;
@@ -79519,7 +79848,7 @@ ${JSON.stringify(stats, null, 2)}`;
79519
79848
  return { sessions, nextCursor, _meta: {} };
79520
79849
  }
79521
79850
  async forkSession(params) {
79522
- if (!isAbsolute11(params.cwd)) {
79851
+ if (!isAbsolute12(params.cwd)) {
79523
79852
  throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
79524
79853
  }
79525
79854
  const source = this.findStoredSession(params.sessionId);
@@ -79585,7 +79914,7 @@ ${JSON.stringify(stats, null, 2)}`;
79585
79914
  return { sessionId: session.sessionId, configOptions, modes };
79586
79915
  }
79587
79916
  async resumeSession(params) {
79588
- if (!isAbsolute11(params.cwd)) {
79917
+ if (!isAbsolute12(params.cwd)) {
79589
79918
  throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
79590
79919
  }
79591
79920
  this.sessions.close(params.sessionId);
@@ -79656,7 +79985,7 @@ ${JSON.stringify(stats, null, 2)}`;
79656
79985
  return response;
79657
79986
  }
79658
79987
  async loadSession(params) {
79659
- if (!isAbsolute11(params.cwd)) {
79988
+ if (!isAbsolute12(params.cwd)) {
79660
79989
  throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
79661
79990
  }
79662
79991
  this.sessions.close(params.sessionId);
@@ -80025,7 +80354,7 @@ var init_agent_probe_error = __esm({
80025
80354
  });
80026
80355
 
80027
80356
  // src/agent/specification/vendors/pi-agent.ts
80028
- import { createHash } from "node:crypto";
80357
+ import { createHash as createHash2 } from "node:crypto";
80029
80358
  import { join as join19 } from "node:path";
80030
80359
  import {
80031
80360
  methods as methods6
@@ -80046,7 +80375,7 @@ var init_pi_agent = __esm({
80046
80375
  // The Pi ACP fork inlines embedded prompt resources into the turn message, so Mobius
80047
80376
  // keeps the adapter's opt-in capability flag enabled for every launch it owns.
80048
80377
  createLaunchEnvironment = async (_agent, context) => {
80049
- const workspaceHash = createHash("sha256").update(context.defaultWorkspace).digest("hex").slice(0, 24);
80378
+ const workspaceHash = createHash2("sha256").update(context.defaultWorkspace).digest("hex").slice(0, 24);
80050
80379
  const sessionDirectory = join19(
80051
80380
  readStateDirectory(context.environment),
80052
80381
  "agents",
@@ -80253,7 +80582,7 @@ var init_agent_discovery = __esm({
80253
80582
 
80254
80583
  // src/util/process/local-executable.ts
80255
80584
  import { realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
80256
- import { realpath as realpath6, stat as stat5 } from "node:fs/promises";
80585
+ import { realpath as realpath7, stat as stat6 } from "node:fs/promises";
80257
80586
  function readExecutableIdentity(path8) {
80258
80587
  const resolvedPath = realpathSync4(path8);
80259
80588
  const metadata = statSync4(resolvedPath);
@@ -80267,9 +80596,9 @@ function readExecutableIdentity(path8) {
80267
80596
  );
80268
80597
  }
80269
80598
  async function resolveLaunchFiles(entry, executable) {
80270
- const resolvedEntry = await realpath6(entry);
80271
- const resolvedExecutable = await realpath6(executable);
80272
- if (!(await stat5(resolvedEntry)).isFile() || !(await stat5(resolvedExecutable)).isFile()) {
80599
+ const resolvedEntry = await realpath7(entry);
80600
+ const resolvedExecutable = await realpath7(executable);
80601
+ if (!(await stat6(resolvedEntry)).isFile() || !(await stat6(resolvedExecutable)).isFile()) {
80273
80602
  return null;
80274
80603
  }
80275
80604
  return { entry: resolvedEntry, executable: resolvedExecutable };
@@ -80787,11 +81116,11 @@ var init_agent_version = __esm({
80787
81116
  });
80788
81117
 
80789
81118
  // src/agent/discovery/executable-discovery.ts
80790
- import { isAbsolute as isAbsolute12 } from "node:path";
81119
+ import { isAbsolute as isAbsolute13 } from "node:path";
80791
81120
  async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, context) {
80792
81121
  const override = context.environment[overrideVariable];
80793
81122
  if (override !== void 0) {
80794
- if (override.length === 0 || !isAbsolute12(override)) {
81123
+ if (override.length === 0 || !isAbsolute13(override)) {
80795
81124
  return [];
80796
81125
  }
80797
81126
  const executable = await resolveExecutablePath(override, context.platform);
@@ -81366,8 +81695,26 @@ var init_adapter_registry = __esm({
81366
81695
  });
81367
81696
 
81368
81697
  // src/session/history/session-event-history-projection.ts
81698
+ function boundReasoning(payload) {
81699
+ if (payload.content.type !== "text" || Buffer.byteLength(payload.content.text, "utf8") <= MAXIMUM_PROJECTED_REASONING_BYTES) {
81700
+ return payload;
81701
+ }
81702
+ const bytes = Buffer.from(payload.content.text, "utf8");
81703
+ let start = bytes.length - MAXIMUM_PROJECTED_REASONING_BYTES;
81704
+ while (start < bytes.length && (bytes.readUInt8(start) & 192) === 128) {
81705
+ start += 1;
81706
+ }
81707
+ return {
81708
+ ...payload,
81709
+ content: { ...payload.content, text: bytes.toString("utf8", start) },
81710
+ meta: { ...payload.meta, truncated: true }
81711
+ };
81712
+ }
81369
81713
  function projectNewEvent(liveEvent2, eventId) {
81370
81714
  const { position: _position, eventId: _liveEventId, ...event } = liveEvent2;
81715
+ if (event.type === "acp" && event.payload.sessionUpdate === "agent_thought_chunk") {
81716
+ return { ...event, eventId, payload: boundReasoning(event.payload) };
81717
+ }
81371
81718
  return { ...event, eventId };
81372
81719
  }
81373
81720
  function replaceAcpPayload(event, payload) {
@@ -81418,18 +81765,19 @@ function mergeTextChunk(previous, incoming) {
81418
81765
  }
81419
81766
  const content = { text: `${previous.content.text}${incoming.content.text}`, type: "text" };
81420
81767
  if (previous.sessionUpdate === "agent_thought_chunk" && incoming.sessionUpdate === "agent_thought_chunk") {
81421
- return {
81768
+ return boundReasoning({
81422
81769
  ...previous,
81423
81770
  content,
81424
81771
  ...previous.meta?.truncated === true || incoming.meta?.truncated === true ? { meta: { ...previous.meta, ...incoming.meta, truncated: true } } : {}
81425
- };
81772
+ });
81426
81773
  }
81427
81774
  return { ...previous, content };
81428
81775
  }
81429
- var SessionEventHistoryProjection;
81776
+ var MAXIMUM_PROJECTED_REASONING_BYTES, SessionEventHistoryProjection;
81430
81777
  var init_session_event_history_projection = __esm({
81431
81778
  "src/session/history/session-event-history-projection.ts"() {
81432
81779
  "use strict";
81780
+ MAXIMUM_PROJECTED_REASONING_BYTES = 24 * 1024;
81433
81781
  SessionEventHistoryProjection = class {
81434
81782
  #toolCallEventIds = /* @__PURE__ */ new Map();
81435
81783
  #latestEvent = null;
@@ -82979,7 +83327,24 @@ var init_session_config_protocol = __esm({
82979
83327
 
82980
83328
  // src/acp/adapter/session-events.ts
82981
83329
  import { setImmediate as yieldToRuntime2 } from "node:timers/promises";
82982
- var AdapterSessionConnection, AcpSessionConnector;
83330
+ function* reasoningWireUpdates(update) {
83331
+ if (update.sessionUpdate !== "agent_thought_chunk" || update.content.type !== "text" || update.content.text.length <= MAXIMUM_REASONING_UPDATE_CHARACTERS) {
83332
+ yield update;
83333
+ return;
83334
+ }
83335
+ const text2 = update.content.text;
83336
+ for (let start = 0; start < text2.length; ) {
83337
+ let end = Math.min(start + MAXIMUM_REASONING_UPDATE_CHARACTERS, text2.length);
83338
+ const last = text2.charCodeAt(end - 1);
83339
+ const next = text2.charCodeAt(end);
83340
+ if (last >= 55296 && last <= 56319 && next >= 56320 && next <= 57343) {
83341
+ end -= 1;
83342
+ }
83343
+ yield { ...update, content: { ...update.content, text: text2.slice(start, end) } };
83344
+ start = end;
83345
+ }
83346
+ }
83347
+ var MAXIMUM_REASONING_UPDATE_CHARACTERS, AdapterSessionConnection, AcpSessionConnector;
82983
83348
  var init_session_events = __esm({
82984
83349
  "src/acp/adapter/session-events.ts"() {
82985
83350
  "use strict";
@@ -82989,12 +83354,13 @@ var init_session_events = __esm({
82989
83354
  init_agent_connection();
82990
83355
  init_agent_update_stream();
82991
83356
  init_session_config_protocol();
83357
+ MAXIMUM_REASONING_UPDATE_CHARACTERS = 1e6;
82992
83358
  AdapterSessionConnection = class {
82993
83359
  #connection;
82994
83360
  #updates;
82995
83361
  #lifetime = new AbortController();
82996
83362
  events;
82997
- constructor(options, externalizer) {
83363
+ constructor(options, externalizer, normalizeEvent) {
82998
83364
  const protocol = sessionConfigProtocolForAgent(options.agent.id);
82999
83365
  this.#updates = new AgentUpdateStream(async (notification) => {
83000
83366
  this.#lifetime.signal.throwIfAborted();
@@ -83002,58 +83368,60 @@ var init_session_events = __esm({
83002
83368
  throw new AcpExecutionError("ACP agent referenced an unknown session", {}, "invalid_agent_session");
83003
83369
  }
83004
83370
  const signal = AbortSignal.any([this.#lifetime.signal, AbortSignal.timeout(3e4)]);
83005
- const externalized = await externalizer.update(options.sessionId(), notification.update, signal);
83006
- signal.throwIfAborted();
83007
- const update = externalized.agent;
83008
- const payload = decodeAcpSessionUpdate(JSON.stringify(externalized.event));
83009
- let event;
83010
- switch (update.sessionUpdate) {
83011
- case "available_commands_update":
83012
- event = {
83013
- kind: "commands",
83014
- payload,
83015
- commands: update.availableCommands.slice(0, 500).map((command) => ({
83016
- description: truncate2(command.description, 500),
83017
- inputHint: truncate2(command.input?.hint ?? "", 255),
83018
- name: truncate2(command.name, 128)
83019
- })).filter((command) => command.name.length > 0)
83020
- };
83021
- break;
83022
- case "config_option_update":
83023
- event = {
83024
- kind: "configuration",
83025
- payload,
83026
- configOptions: protocol.normalizeUpdate(options.configOptions(), update.configOptions)
83027
- };
83028
- break;
83029
- case "current_mode_update":
83030
- event = { kind: "mode", payload, modeId: update.currentModeId };
83031
- break;
83032
- case "session_info_update": {
83033
- const changes = [];
83034
- if (Object.hasOwn(update, "title")) {
83035
- changes.push({ kind: "title", value: truncate2(update.title ?? "", 500) });
83036
- }
83037
- if (Object.hasOwn(update, "updatedAt")) {
83038
- changes.push({ kind: "updated-at", value: truncate2(update.updatedAt ?? "", 128) });
83371
+ for (const incoming of reasoningWireUpdates(notification.update)) {
83372
+ const externalized = await externalizer.update(options.sessionId(), incoming, signal);
83373
+ signal.throwIfAborted();
83374
+ const update = externalized.agent;
83375
+ const payload = decodeAcpSessionUpdate(JSON.stringify(normalizeEvent(externalized.event)));
83376
+ let event;
83377
+ switch (update.sessionUpdate) {
83378
+ case "available_commands_update":
83379
+ event = {
83380
+ kind: "commands",
83381
+ payload,
83382
+ commands: update.availableCommands.slice(0, 500).map((command) => ({
83383
+ description: truncate2(command.description, 500),
83384
+ inputHint: truncate2(command.input?.hint ?? "", 255),
83385
+ name: truncate2(command.name, 128)
83386
+ })).filter((command) => command.name.length > 0)
83387
+ };
83388
+ break;
83389
+ case "config_option_update":
83390
+ event = {
83391
+ kind: "configuration",
83392
+ payload,
83393
+ configOptions: protocol.normalizeUpdate(options.configOptions(), update.configOptions)
83394
+ };
83395
+ break;
83396
+ case "current_mode_update":
83397
+ event = { kind: "mode", payload, modeId: update.currentModeId };
83398
+ break;
83399
+ case "session_info_update": {
83400
+ const changes = [];
83401
+ if (Object.hasOwn(update, "title")) {
83402
+ changes.push({ kind: "title", value: truncate2(update.title ?? "", 500) });
83403
+ }
83404
+ if (Object.hasOwn(update, "updatedAt")) {
83405
+ changes.push({ kind: "updated-at", value: truncate2(update.updatedAt ?? "", 128) });
83406
+ }
83407
+ event = { kind: "info", payload, changes };
83408
+ break;
83039
83409
  }
83040
- event = { kind: "info", payload, changes };
83041
- break;
83410
+ case "user_message_chunk":
83411
+ case "agent_message_chunk":
83412
+ case "agent_thought_chunk":
83413
+ case "tool_call":
83414
+ case "tool_call_update":
83415
+ case "plan":
83416
+ case "plan_update":
83417
+ case "plan_removed":
83418
+ event = { kind: "content", payload };
83419
+ break;
83420
+ default:
83421
+ event = { kind: "other", payload };
83042
83422
  }
83043
- case "user_message_chunk":
83044
- case "agent_message_chunk":
83045
- case "agent_thought_chunk":
83046
- case "tool_call":
83047
- case "tool_call_update":
83048
- case "plan":
83049
- case "plan_update":
83050
- case "plan_removed":
83051
- event = { kind: "content", payload };
83052
- break;
83053
- default:
83054
- event = { kind: "other", payload };
83423
+ await options.onEvent(event);
83055
83424
  }
83056
- await options.onEvent(event);
83057
83425
  });
83058
83426
  this.events = this.#updates;
83059
83427
  const client2 = {
@@ -83100,10 +83468,12 @@ var init_session_events = __esm({
83100
83468
  };
83101
83469
  AcpSessionConnector = class {
83102
83470
  #externalizer;
83103
- constructor(externalizer) {
83471
+ #normalizeEvent;
83472
+ constructor(externalizer, normalizeEvent = (event) => event) {
83104
83473
  this.#externalizer = externalizer;
83474
+ this.#normalizeEvent = normalizeEvent;
83105
83475
  }
83106
- connectSession = (options) => new AdapterSessionConnection(options, this.#externalizer);
83476
+ connectSession = (options) => new AdapterSessionConnection(options, this.#externalizer, this.#normalizeEvent);
83107
83477
  connectQuerySession = (options) => {
83108
83478
  const rejectInteraction = async () => {
83109
83479
  throw new AcpExecutionError(
@@ -83121,7 +83491,8 @@ var init_session_events = __esm({
83121
83491
  onElicitationComplete: rejectInteraction
83122
83492
  }
83123
83493
  },
83124
- this.#externalizer
83494
+ this.#externalizer,
83495
+ this.#normalizeEvent
83125
83496
  );
83126
83497
  };
83127
83498
  };
@@ -83151,1075 +83522,6 @@ var init_adapter = __esm({
83151
83522
  }
83152
83523
  });
83153
83524
 
83154
- // src/storage/files/local-files.ts
83155
- import { createReadStream as createReadStream2 } from "node:fs";
83156
- import { mkdir as mkdir3, open as open4, readdir as readdir4, readFile as readFile5, realpath as realpath7, stat as stat6 } from "node:fs/promises";
83157
- function entryKind(entry) {
83158
- if (entry.isDirectory()) {
83159
- return "directory";
83160
- }
83161
- if (entry.isFile()) {
83162
- return "file";
83163
- }
83164
- if (entry.isSymbolicLink()) {
83165
- return "symbolic-link";
83166
- }
83167
- if (entry.isBlockDevice() || entry.isCharacterDevice()) {
83168
- return "device";
83169
- }
83170
- if (entry.isFIFO()) {
83171
- return "fifo";
83172
- }
83173
- return entry.isSocket() ? "socket" : "unknown";
83174
- }
83175
- async function canonicalPath(path8) {
83176
- return await realpath7(path8);
83177
- }
83178
- async function readPathMetadata(path8) {
83179
- const metadata = await stat6(path8);
83180
- return {
83181
- kind: metadata.isDirectory() ? "directory" : metadata.isFile() ? "file" : "other",
83182
- modifiedAt: metadata.mtime,
83183
- modifiedMilliseconds: metadata.mtimeMs,
83184
- size: metadata.size
83185
- };
83186
- }
83187
- async function listDirectory(path8) {
83188
- const entries = await readdir4(path8, { withFileTypes: true });
83189
- return entries.map((entry) => ({ kind: entryKind(entry), name: entry.name }));
83190
- }
83191
- async function ensurePrivateDirectory(path8) {
83192
- await mkdir3(path8, { mode: 448, recursive: true });
83193
- }
83194
- async function ensureCanonicalDirectory(path8) {
83195
- await ensurePrivateDirectory(path8);
83196
- const resolved = await realpath7(path8);
83197
- return (await stat6(resolved)).isDirectory() ? resolved : null;
83198
- }
83199
- async function readFileStart(path8, byteLength) {
83200
- const bytes = new Uint8Array(byteLength);
83201
- const handle = await open4(path8, "r");
83202
- try {
83203
- await handle.read(bytes, 0, byteLength, 0);
83204
- } finally {
83205
- await handle.close();
83206
- }
83207
- return bytes;
83208
- }
83209
- async function readFileBytes(path8) {
83210
- return await readFile5(path8);
83211
- }
83212
- function readFileChunks(path8, chunkBytes, signal) {
83213
- return createReadStream2(path8, { highWaterMark: chunkBytes, signal });
83214
- }
83215
- var init_local_files = __esm({
83216
- "src/storage/files/local-files.ts"() {
83217
- "use strict";
83218
- }
83219
- });
83220
-
83221
- // src/acp/content/raster.ts
83222
- import { basename as basename5, isAbsolute as isAbsolute13, normalize } from "node:path";
83223
- import { fileURLToPath } from "node:url";
83224
- function startsWith(bytes, signature, offset = 0) {
83225
- if (bytes.byteLength < offset + signature.byteLength) {
83226
- return false;
83227
- }
83228
- return signature.every((value, index2) => bytes[offset + index2] === value);
83229
- }
83230
- function sniffRasterMime(bytes) {
83231
- if (startsWith(bytes, PNG_SIGNATURE)) {
83232
- return "image/png";
83233
- }
83234
- if (startsWith(bytes, JPEG_SIGNATURE)) {
83235
- return "image/jpeg";
83236
- }
83237
- if (startsWith(bytes, GIF87_SIGNATURE) || startsWith(bytes, GIF89_SIGNATURE)) {
83238
- return "image/gif";
83239
- }
83240
- if (startsWith(bytes, RIFF_SIGNATURE) && startsWith(bytes, WEBP_SIGNATURE, 8)) {
83241
- return "image/webp";
83242
- }
83243
- return null;
83244
- }
83245
- async function resolveCanonicalPath(requested, signal) {
83246
- signal.throwIfAborted();
83247
- if (!isAbsolute13(requested) || requested.includes("\0") || normalize(requested) !== requested) {
83248
- return null;
83249
- }
83250
- try {
83251
- const target = await canonicalPath(requested);
83252
- signal.throwIfAborted();
83253
- if (!isAbsolute13(target) || normalize(target) !== target) {
83254
- return null;
83255
- }
83256
- return target;
83257
- } catch (cause) {
83258
- signal.throwIfAborted();
83259
- if (cause instanceof Error && cause.name === "AbortError") {
83260
- throw cause;
83261
- }
83262
- return null;
83263
- }
83264
- }
83265
- function parseLocalImageUri(uri) {
83266
- const trimmed = uri.trim();
83267
- if (trimmed.length === 0 || trimmed.length > 2048 || trimmed.includes("\0")) {
83268
- return null;
83269
- }
83270
- if (trimmed.startsWith("data:")) {
83271
- return null;
83272
- }
83273
- if (trimmed.startsWith("file:")) {
83274
- try {
83275
- const url2 = new URL(trimmed);
83276
- if (url2.protocol !== "file:" || url2.host.length > 0) {
83277
- return null;
83278
- }
83279
- return fileURLToPath(url2);
83280
- } catch {
83281
- return null;
83282
- }
83283
- }
83284
- if (!isAbsolute13(trimmed) && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
83285
- return null;
83286
- }
83287
- return trimmed;
83288
- }
83289
- async function readLocalRaster(uri, signal) {
83290
- signal.throwIfAborted();
83291
- const requested = parseLocalImageUri(uri);
83292
- if (requested === null) {
83293
- return null;
83294
- }
83295
- const target = await resolveCanonicalPath(requested, signal);
83296
- if (target === null) {
83297
- return null;
83298
- }
83299
- const targetMetadata = await readPathMetadata(target);
83300
- signal.throwIfAborted();
83301
- if (targetMetadata.kind !== "file" || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
83302
- return null;
83303
- }
83304
- const header = await readFileStart(target, 12);
83305
- signal.throwIfAborted();
83306
- const mimeType = sniffRasterMime(header);
83307
- if (mimeType === null) {
83308
- return null;
83309
- }
83310
- return new LocalRasterImage(basename5(target) || "Image", mimeType, target);
83311
- }
83312
- var MAX_LOCAL_RASTER_BYTES, PNG_SIGNATURE, JPEG_SIGNATURE, GIF87_SIGNATURE, GIF89_SIGNATURE, RIFF_SIGNATURE, WEBP_SIGNATURE, LocalRasterImage;
83313
- var init_raster = __esm({
83314
- "src/acp/content/raster.ts"() {
83315
- "use strict";
83316
- init_local_files();
83317
- MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
83318
- PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
83319
- JPEG_SIGNATURE = Uint8Array.of(255, 216, 255);
83320
- GIF87_SIGNATURE = new TextEncoder().encode("GIF87a");
83321
- GIF89_SIGNATURE = new TextEncoder().encode("GIF89a");
83322
- RIFF_SIGNATURE = new TextEncoder().encode("RIFF");
83323
- WEBP_SIGNATURE = new TextEncoder().encode("WEBP");
83324
- LocalRasterImage = class {
83325
- mimeType;
83326
- name;
83327
- sourceUri;
83328
- constructor(name2, mimeType, sourceUri) {
83329
- this.mimeType = mimeType;
83330
- this.name = name2;
83331
- this.sourceUri = sourceUri;
83332
- }
83333
- base64 = async () => Buffer.from(await readFileBytes(this.sourceUri)).toString("base64");
83334
- };
83335
- }
83336
- });
83337
-
83338
- // src/acp/native-history/codex/history-images.ts
83339
- function isRasterMime(value) {
83340
- return value === "image/png" || value === "image/jpeg" || value === "image/gif" || value === "image/webp";
83341
- }
83342
- function parseNativeHistoryImage(uri) {
83343
- const header = DATA_IMAGE_HEADER.exec(uri);
83344
- if (header === null) {
83345
- return null;
83346
- }
83347
- const mimeType = header[1] ?? "";
83348
- const data = uri.slice(header[0].length);
83349
- if (!isRasterMime(mimeType) || data.length < 4 || data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
83350
- return null;
83351
- }
83352
- if (data.length % 4 !== 0 || !BASE_64.test(data)) {
83353
- return null;
83354
- }
83355
- return { data, mimeType, name: "" };
83356
- }
83357
- async function embedLocalHistoryImages(history, signal) {
83358
- if (history.status !== "available") {
83359
- return history;
83360
- }
83361
- const messages = [];
83362
- let imageCharacters = 0;
83363
- for (const message of history.messages) {
83364
- signal.throwIfAborted();
83365
- const resolved = await resolveMessageImages(message, imageCharacters, signal);
83366
- imageCharacters += (resolved.images ?? []).reduce((size, image) => size + image.data.length, 0);
83367
- messages.push(resolved);
83368
- }
83369
- return {
83370
- ...history,
83371
- messages
83372
- };
83373
- }
83374
- async function resolveMessageImages(message, usedCharacters, signal) {
83375
- const images = [...message.images ?? []];
83376
- let imageCharacters = images.reduce((size, image) => size + image.data.length, 0);
83377
- const text2 = await replaceImageMarkers(message.text, async (uri) => {
83378
- if (images.length >= 8 || usedCharacters + imageCharacters >= SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
83379
- return "[Image unavailable]";
83380
- }
83381
- const embedded = parseNativeHistoryImage(uri);
83382
- if (embedded !== null) {
83383
- if (usedCharacters + imageCharacters + embedded.data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
83384
- return "[Image unavailable]";
83385
- }
83386
- images.push({ ...embedded, name: `Image ${(images.length + 1).toString()}` });
83387
- imageCharacters += embedded.data.length;
83388
- return "";
83389
- }
83390
- const local = await readLocalRaster(uri, signal);
83391
- if (local === null) {
83392
- return "[Image unavailable]";
83393
- }
83394
- const data = await local.base64();
83395
- if (usedCharacters + imageCharacters + data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
83396
- return "[Image unavailable]";
83397
- }
83398
- images.push({
83399
- data,
83400
- mimeType: local.mimeType,
83401
- name: local.name
83402
- });
83403
- imageCharacters += data.length;
83404
- return "";
83405
- });
83406
- return {
83407
- ...message,
83408
- text: text2,
83409
- ...images.length > 0 ? { images } : {}
83410
- };
83411
- }
83412
- async function replaceImageMarkers(text2, replace) {
83413
- const matches = [...text2.matchAll(IMAGE_MARKER)];
83414
- if (matches.length === 0) {
83415
- return text2;
83416
- }
83417
- let cursor = 0;
83418
- let rewritten = "";
83419
- for (const match of matches) {
83420
- const index2 = match.index ?? 0;
83421
- rewritten += text2.slice(cursor, index2);
83422
- rewritten += await replace(match[1] ?? "");
83423
- cursor = index2 + match[0].length;
83424
- }
83425
- return `${rewritten}${text2.slice(cursor)}`;
83426
- }
83427
- var IMAGE_MARKER, DATA_IMAGE_HEADER, BASE_64, SESSION_HISTORY_IMAGE_CHARACTER_LIMIT, SESSION_HISTORY_PREVIEW_TURN_LIMIT;
83428
- var init_history_images = __esm({
83429
- "src/acp/native-history/codex/history-images.ts"() {
83430
- "use strict";
83431
- init_raster();
83432
- IMAGE_MARKER = /\[@image\]\(([^)\r\n]*)(?:\)|$)/g;
83433
- DATA_IMAGE_HEADER = /^data:(image\/[a-z+]+);base64,/;
83434
- BASE_64 = /^[A-Za-z0-9+/]*={0,2}$/;
83435
- SESSION_HISTORY_IMAGE_CHARACTER_LIMIT = 4e6;
83436
- SESSION_HISTORY_PREVIEW_TURN_LIMIT = 10;
83437
- }
83438
- });
83439
-
83440
- // src/acp/native-history/codex/codex-history.ts
83441
- import { spawn as spawn8 } from "node:child_process";
83442
- function bounded(value, maximum) {
83443
- return value.slice(0, maximum);
83444
- }
83445
- function activity(activityId, activityType, sequence, fields) {
83446
- return {
83447
- activityId: bounded(activityId, 128) || `history-${sequence.toString()}`,
83448
- activityType,
83449
- content: [],
83450
- input: bounded(fields.input, 1e5),
83451
- locations: fields.locations.filter((location) => location.length > 0).map((location) => bounded(location, 2048)).slice(0, 100),
83452
- name: bounded(fields.name, 128),
83453
- output: bounded(fields.output, 1e5),
83454
- sequence,
83455
- status: bounded(fields.status, 64),
83456
- title: bounded(fields.title, 500),
83457
- toolKind: bounded(fields.toolKind, 64)
83458
- };
83459
- }
83460
- function errorMessage(value) {
83461
- if (typeof value === "string") {
83462
- return value;
83463
- }
83464
- if (typeof value === "object" && value !== null) {
83465
- const message = Reflect.get(value, "message");
83466
- if (typeof message === "string") {
83467
- return message;
83468
- }
83469
- }
83470
- return JSON.stringify(value) ?? "Codex stopped before completing this turn.";
83471
- }
83472
- function formatted(value) {
83473
- if (value === void 0) {
83474
- return "";
83475
- }
83476
- if (typeof value === "string") {
83477
- return value;
83478
- }
83479
- return JSON.stringify(value) ?? "";
83480
- }
83481
- function toolStatus(status) {
83482
- return status === "inProgress" ? "running" : status === "completed" ? "completed" : "failed";
83483
- }
83484
- function diffContent(path8, newText) {
83485
- return { newText, path: path8, type: "diff" };
83486
- }
83487
- function messageSize(message) {
83488
- return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
83489
- }
83490
- function fitActivity(activity2, maximumCharacters) {
83491
- const truncate4 = (limit) => ({
83492
- ...activity2,
83493
- input: bounded(activity2.input, limit),
83494
- locations: activity2.locations.map((location) => bounded(location, Math.max(1, limit))),
83495
- name: bounded(activity2.name, limit),
83496
- output: bounded(activity2.output, limit),
83497
- title: bounded(activity2.title, limit),
83498
- toolKind: bounded(activity2.toolKind, limit)
83499
- });
83500
- let minimum = 1;
83501
- let maximum = 1e5;
83502
- let fitted = truncate4(0);
83503
- while (minimum <= maximum) {
83504
- const limit = Math.floor((minimum + maximum) / 2);
83505
- const candidate = truncate4(limit);
83506
- if (JSON.stringify(candidate).length <= maximumCharacters) {
83507
- fitted = candidate;
83508
- minimum = limit + 1;
83509
- } else {
83510
- maximum = limit - 1;
83511
- }
83512
- }
83513
- return fitted;
83514
- }
83515
- function fitActivities(activities, maximumCharacters) {
83516
- if (activities.length === 0) {
83517
- return activities;
83518
- }
83519
- const arrayCharacters = 2 + activities.length - 1;
83520
- const maximumActivityCharacters = Math.floor(Math.max(0, maximumCharacters - arrayCharacters) / activities.length);
83521
- return activities.map((activity2) => fitActivity(activity2, maximumActivityCharacters));
83522
- }
83523
- function fitHistoryMessage(message, maximumCharacters = SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT) {
83524
- const text2 = message.text.slice(-maximumCharacters);
83525
- if (message.role === "user") {
83526
- return {
83527
- message: { ...message, text: text2 },
83528
- truncated: text2.length < message.text.length
83529
- };
83530
- }
83531
- let activities = message.activities;
83532
- const content = message.content;
83533
- let fitted = { ...message, activities, content, text: text2 };
83534
- if (messageSize(fitted) > maximumCharacters && activities.length > 0) {
83535
- const maximumActivityCharacters = maximumCharacters - text2.length - JSON.stringify(content).length;
83536
- activities = fitActivities(activities, maximumActivityCharacters);
83537
- fitted = { ...fitted, activities };
83538
- }
83539
- const excess = Math.max(0, messageSize(fitted) - maximumCharacters);
83540
- if (excess > 0) {
83541
- const maximumTextLength = Math.max(0, fitted.text.length - excess);
83542
- fitted = {
83543
- ...fitted,
83544
- text: maximumTextLength === 0 ? "" : fitted.text.slice(-maximumTextLength)
83545
- };
83546
- }
83547
- return {
83548
- message: fitted,
83549
- truncated: fitted.text.length < message.text.length || JSON.stringify(activities).length < JSON.stringify(message.activities).length
83550
- };
83551
- }
83552
- function turnOutcome2(status) {
83553
- switch (status) {
83554
- case "completed":
83555
- return "succeeded";
83556
- case "interrupted":
83557
- return "cancelled";
83558
- case "failed":
83559
- return "failed";
83560
- case "inProgress":
83561
- return void 0;
83562
- default: {
83563
- const unhandled = status;
83564
- throw new Error(`Unknown Codex turn status: ${String(unhandled)}`);
83565
- }
83566
- }
83567
- }
83568
- function decodeHistory(thread, value, options) {
83569
- const page = turnsSchema.parse(value);
83570
- const nativeTurn = options.nativeTurn?.();
83571
- const coveredCommandIds = nativeTurn != null && page.data[0]?.id === nativeTurn.nativeTurnId ? [nativeTurn.commandId] : [];
83572
- const messages = [];
83573
- let characters = 0;
83574
- let truncated = page.nextCursor != null;
83575
- for (const turn of page.data.toReversed()) {
83576
- const outcome = turnOutcome2(turn.status);
83577
- const turnMessageCharacterLimit = Math.max(
83578
- 1,
83579
- Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / Math.max(1, turn.items.length + (turn.error == null ? 0 : 1)))
83580
- );
83581
- let sequence = 0;
83582
- let assistantMessageIndex = null;
83583
- const append = (message) => {
83584
- const fitted = fitHistoryMessage(message, turnMessageCharacterLimit);
83585
- if (fitted.message.text.length === 0 && (fitted.message.images?.length ?? 0) === 0 && (fitted.message.role === "user" || fitted.message.activities.length === 0 && fitted.message.content.length === 0)) {
83586
- return;
83587
- }
83588
- truncated ||= fitted.truncated;
83589
- messages.push(fitted.message);
83590
- if (fitted.message.role === "assistant") {
83591
- assistantMessageIndex = messages.length - 1;
83592
- }
83593
- characters += messageSize(fitted.message);
83594
- };
83595
- for (const item of turn.items) {
83596
- const decoded = historyItemSchema.safeParse(item);
83597
- if (!decoded.success) {
83598
- continue;
83599
- }
83600
- const historyItem = decoded.data;
83601
- if (historyItem.type === "userMessage") {
83602
- const text2 = historyItem.content.map((block) => {
83603
- const { type } = itemTypeSchema.parse(block);
83604
- if (type === "text") {
83605
- return textSchema.parse(block).text;
83606
- }
83607
- if (type === "image") {
83608
- return `[@image](${imageSchema.parse(block).url})`;
83609
- }
83610
- return "[Attachment]";
83611
- }).join("");
83612
- append({
83613
- role: "user",
83614
- text: text2
83615
- });
83616
- } else if (historyItem.type === "agentMessage") {
83617
- append({ activities: [], content: [], role: "assistant", text: historyItem.text });
83618
- } else if (historyItem.type === "reasoning") {
83619
- const output2 = (historyItem.content.length > 0 ? historyItem.content : historyItem.summary).join(
83620
- "\n\n"
83621
- );
83622
- if (output2.length > 0) {
83623
- append({
83624
- activities: [
83625
- activity(historyItem.id, "reasoning", sequence, {
83626
- input: "",
83627
- locations: [],
83628
- name: "",
83629
- output: output2,
83630
- status: "completed",
83631
- title: "Reasoning",
83632
- toolKind: ""
83633
- })
83634
- ],
83635
- content: [],
83636
- role: "assistant",
83637
- text: ""
83638
- });
83639
- sequence += 1;
83640
- }
83641
- } else if (historyItem.type === "commandExecution") {
83642
- const action = historyItem.commandActions[0]?.type ?? "execute";
83643
- append({
83644
- activities: [
83645
- activity(historyItem.id, "tool", sequence, {
83646
- input: JSON.stringify({ command: historyItem.command, cwd: historyItem.cwd }),
83647
- locations: [historyItem.cwd],
83648
- name: "",
83649
- output: JSON.stringify({
83650
- formatted_output: historyItem.aggregatedOutput ?? "",
83651
- ...historyItem.exitCode == null ? {} : { exit_code: historyItem.exitCode }
83652
- }),
83653
- status: toolStatus(historyItem.status),
83654
- title: historyItem.command,
83655
- toolKind: action
83656
- })
83657
- ],
83658
- content: [],
83659
- role: "assistant",
83660
- text: ""
83661
- });
83662
- sequence += 1;
83663
- } else if (historyItem.type === "fileChange") {
83664
- const paths = historyItem.changes.map((change) => change.path);
83665
- const content = historyItem.changes.map(
83666
- (change) => diffContent(change.path, change.diff)
83667
- );
83668
- append({
83669
- activities: [
83670
- activity(historyItem.id, "tool", sequence, {
83671
- input: JSON.stringify({ changes: paths }),
83672
- locations: paths,
83673
- name: "",
83674
- output: "",
83675
- status: toolStatus(historyItem.status),
83676
- title: paths.join(", "),
83677
- toolKind: "edit"
83678
- })
83679
- ].map((entry) => ({ ...entry, content })),
83680
- content: [],
83681
- role: "assistant",
83682
- text: ""
83683
- });
83684
- sequence += 1;
83685
- } else if (historyItem.type === "mcpToolCall") {
83686
- append({
83687
- activities: [
83688
- activity(historyItem.id, "tool", sequence, {
83689
- input: formatted(historyItem.arguments),
83690
- locations: [],
83691
- name: historyItem.tool,
83692
- output: formatted(historyItem.error ?? historyItem.result),
83693
- status: toolStatus(historyItem.status),
83694
- title: `${historyItem.server}/${historyItem.tool}`,
83695
- toolKind: "other"
83696
- })
83697
- ],
83698
- content: [],
83699
- role: "assistant",
83700
- text: ""
83701
- });
83702
- sequence += 1;
83703
- } else if (historyItem.type === "dynamicToolCall") {
83704
- append({
83705
- activities: [
83706
- activity(historyItem.id, "tool", sequence, {
83707
- input: formatted(historyItem.arguments),
83708
- locations: [],
83709
- name: historyItem.tool,
83710
- output: formatted(historyItem.contentItems),
83711
- status: toolStatus(historyItem.status),
83712
- title: historyItem.namespace == null ? historyItem.tool : `${historyItem.namespace}/${historyItem.tool}`,
83713
- toolKind: "other"
83714
- })
83715
- ],
83716
- content: [],
83717
- role: "assistant",
83718
- text: ""
83719
- });
83720
- sequence += 1;
83721
- } else if (historyItem.type === "plan") {
83722
- append({
83723
- activities: [
83724
- activity(historyItem.id, "plan", sequence, {
83725
- input: "",
83726
- locations: [],
83727
- name: "",
83728
- output: historyItem.text,
83729
- status: "completed",
83730
- title: "Plan",
83731
- toolKind: ""
83732
- })
83733
- ],
83734
- content: [],
83735
- role: "assistant",
83736
- text: ""
83737
- });
83738
- sequence += 1;
83739
- }
83740
- }
83741
- if (turn.error != null) {
83742
- append({
83743
- activities: [
83744
- activity(`agent-error-${sequence.toString()}`, "tool", sequence, {
83745
- input: "",
83746
- locations: [],
83747
- name: "",
83748
- output: errorMessage(turn.error),
83749
- status: "failed",
83750
- title: "Agent error",
83751
- toolKind: "other"
83752
- })
83753
- ],
83754
- content: [],
83755
- role: "assistant",
83756
- text: ""
83757
- });
83758
- }
83759
- if (assistantMessageIndex !== null) {
83760
- const assistant = messages[assistantMessageIndex];
83761
- if (assistant?.role === "assistant") {
83762
- characters -= messageSize(assistant);
83763
- const updated = {
83764
- ...assistant,
83765
- ...outcome === void 0 ? {} : { outcome }
83766
- };
83767
- const fitted = fitHistoryMessage(updated, turnMessageCharacterLimit);
83768
- truncated ||= fitted.truncated;
83769
- messages[assistantMessageIndex] = fitted.message;
83770
- characters += messageSize(fitted.message);
83771
- }
83772
- } else if (outcome !== void 0) {
83773
- const message = {
83774
- activities: [],
83775
- content: [],
83776
- role: "assistant",
83777
- ...outcome === void 0 ? {} : { outcome },
83778
- text: ""
83779
- };
83780
- const fitted = fitHistoryMessage(message, turnMessageCharacterLimit);
83781
- truncated ||= fitted.truncated;
83782
- messages.push(fitted.message);
83783
- characters += messageSize(fitted.message);
83784
- }
83785
- while (messages.length > SESSION_HISTORY_MESSAGE_LIMIT || characters > SESSION_HISTORY_CHARACTER_LIMIT) {
83786
- const removed = messages.shift();
83787
- if (removed !== void 0) {
83788
- characters -= messageSize(removed);
83789
- }
83790
- truncated = true;
83791
- }
83792
- }
83793
- return {
83794
- nativeSessionId: thread.id,
83795
- cwd: thread.cwd,
83796
- history: {
83797
- status: "available",
83798
- messages,
83799
- truncated,
83800
- coveredCommandIds,
83801
- coveredMessageIds: []
83802
- }
83803
- };
83804
- }
83805
- async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal, options) {
83806
- signal.throwIfAborted();
83807
- nativeSessionIdSchema.parse(nativeSessionId);
83808
- if (agent.id !== "codex" || !await revalidateExecutable(agent.agentIdentity)) {
83809
- throw new AcpExecutionError(
83810
- "The local Codex executable changed. Restart Mobius to discover it again.",
83811
- {},
83812
- "agent_executable_changed"
83813
- );
83814
- }
83815
- signal.throwIfAborted();
83816
- const launch = executableLaunch2(agent.agentIdentity.realPath, ["app-server"]);
83817
- const child = spawn8(launch.command, [...launch.arguments], {
83818
- cwd,
83819
- env: { ...process.env, ...agent.environment },
83820
- ...platformSpawnOptions,
83821
- shell: false,
83822
- stdio: ["pipe", "pipe", "ignore"]
83823
- });
83824
- const response = Promise.withResolvers();
83825
- let state = { kind: "initializing", requestId: 1 };
83826
- const seenCursors = /* @__PURE__ */ new Set();
83827
- let pendingBytes = 0;
83828
- let pendingFragments = [];
83829
- const fail = (cause) => response.reject(
83830
- cause instanceof AcpExecutionError ? cause : new AcpExecutionError(
83831
- "Saved Codex history could not be read.",
83832
- { cause },
83833
- "native_history_unavailable"
83834
- )
83835
- );
83836
- const send2 = (message) => {
83837
- child.stdin.write(`${JSON.stringify(message)}
83838
- `);
83839
- };
83840
- const onData = (chunk) => {
83841
- try {
83842
- let cursor = 0;
83843
- let newline = chunk.indexOf("\n");
83844
- while (newline >= 0) {
83845
- const fragment = chunk.slice(cursor, newline);
83846
- const lineBytes = pendingBytes + Buffer.byteLength(fragment);
83847
- if (lineBytes > 32 * 1024 * 1024) {
83848
- throw new AcpExecutionError(
83849
- "This saved conversation is too large to preview.",
83850
- {},
83851
- "native_history_too_large"
83852
- );
83853
- }
83854
- const line = pendingFragments.length === 0 ? fragment : [...pendingFragments, fragment].join("");
83855
- pendingBytes = 0;
83856
- pendingFragments = [];
83857
- cursor = newline + 1;
83858
- newline = chunk.indexOf("\n", cursor);
83859
- if (line.trim().length === 0) {
83860
- continue;
83861
- }
83862
- const value = JSON.parse(line);
83863
- const message = responseSchema.parse(value);
83864
- if (!("id" in message)) {
83865
- continue;
83866
- }
83867
- if (message.id !== state.requestId) {
83868
- throw new AcpExecutionError(
83869
- "Codex returned an invalid history response.",
83870
- {},
83871
- "invalid_native_session_response"
83872
- );
83873
- }
83874
- if ("error" in message) {
83875
- fail(
83876
- new AcpExecutionError(
83877
- "Saved Codex history could not be read.",
83878
- { cause: new CodexHistoryResponseError(message.error) },
83879
- "native_history_unavailable"
83880
- )
83881
- );
83882
- return;
83883
- }
83884
- switch (state.kind) {
83885
- case "initializing":
83886
- state = { kind: "metadata", requestId: 2 };
83887
- send2({ method: "initialized", params: {} });
83888
- send2({
83889
- id: state.requestId,
83890
- method: "thread/read",
83891
- params: { threadId: nativeSessionId, includeTurns: false }
83892
- });
83893
- break;
83894
- case "metadata": {
83895
- const { thread } = threadSchema.parse(message.result);
83896
- state = { kind: "turns", requestId: 3, thread, pages: [] };
83897
- send2({
83898
- id: state.requestId,
83899
- method: "thread/turns/list",
83900
- params: {
83901
- threadId: nativeSessionId,
83902
- limit: SESSION_HISTORY_PREVIEW_TURN_LIMIT,
83903
- sortDirection: "desc",
83904
- itemsView: "full"
83905
- }
83906
- });
83907
- break;
83908
- }
83909
- case "turns": {
83910
- const page = turnsSchema.parse(message.result);
83911
- const pages = [...state.pages, ...page.data];
83912
- const maxTurns = SESSION_HISTORY_MESSAGE_LIMIT;
83913
- if (page.nextCursor == null || pages.length >= maxTurns) {
83914
- response.resolve(
83915
- decodeHistory(
83916
- state.thread,
83917
- {
83918
- data: pages.slice(0, maxTurns),
83919
- nextCursor: page.nextCursor
83920
- },
83921
- options
83922
- )
83923
- );
83924
- return;
83925
- }
83926
- if (page.data.length === 0 || seenCursors.has(page.nextCursor)) {
83927
- throw new AcpExecutionError(
83928
- "Codex repeated a history page cursor.",
83929
- {},
83930
- "invalid_native_session_response"
83931
- );
83932
- }
83933
- seenCursors.add(page.nextCursor);
83934
- state = { kind: "turns", requestId: state.requestId + 1, thread: state.thread, pages };
83935
- send2({
83936
- id: state.requestId,
83937
- method: "thread/turns/list",
83938
- params: {
83939
- threadId: nativeSessionId,
83940
- cursor: page.nextCursor,
83941
- limit: Math.min(SESSION_HISTORY_PREVIEW_TURN_LIMIT, maxTurns - pages.length),
83942
- sortDirection: "desc",
83943
- itemsView: "full"
83944
- }
83945
- });
83946
- break;
83947
- }
83948
- default: {
83949
- const unhandled = state;
83950
- throw new Error(`Unknown history read state: ${String(unhandled)}`);
83951
- }
83952
- }
83953
- }
83954
- const remainder = chunk.slice(cursor);
83955
- if (remainder.length > 0) {
83956
- pendingBytes += Buffer.byteLength(remainder);
83957
- if (pendingBytes > 32 * 1024 * 1024) {
83958
- throw new AcpExecutionError(
83959
- "This saved conversation is too large to preview.",
83960
- {},
83961
- "native_history_too_large"
83962
- );
83963
- }
83964
- pendingFragments.push(remainder);
83965
- }
83966
- } catch (cause) {
83967
- fail(cause);
83968
- }
83969
- };
83970
- const abort = () => response.reject(signal.reason);
83971
- const onExit = () => fail(
83972
- new AcpExecutionError(
83973
- "Codex stopped before its saved history was available.",
83974
- {},
83975
- "native_history_unavailable"
83976
- )
83977
- );
83978
- const timeout = setTimeout(
83979
- () => fail(new AcpExecutionError("Reading saved Codex history timed out.", {}, "native_history_timeout")),
83980
- 6e4
83981
- );
83982
- child.stdout.setEncoding("utf8");
83983
- child.stdout.on("data", onData);
83984
- child.stdin.on("error", fail);
83985
- child.on("error", fail);
83986
- child.on("exit", onExit);
83987
- signal.addEventListener("abort", abort, { once: true });
83988
- try {
83989
- if (signal.aborted) {
83990
- abort();
83991
- } else {
83992
- send2({
83993
- id: 1,
83994
- method: "initialize",
83995
- params: { clientInfo: { name: "mobius_history", version: "1.0.0" } }
83996
- });
83997
- }
83998
- const snapshot = await response.promise;
83999
- return {
84000
- ...snapshot,
84001
- history: await embedLocalHistoryImages(snapshot.history, signal)
84002
- };
84003
- } finally {
84004
- clearTimeout(timeout);
84005
- signal.removeEventListener("abort", abort);
84006
- child.stdout.removeListener("data", onData);
84007
- if (child.pid !== void 0) {
84008
- await stopProcessTree(child);
84009
- }
84010
- child.stdin.removeListener("error", fail);
84011
- child.removeListener("error", fail);
84012
- child.removeListener("exit", onExit);
84013
- }
84014
- }
84015
- var responseSchema, threadSchema, turnsSchema, itemTypeSchema, userMessageSchema, textSchema, imageSchema, agentMessageSchema, reasoningSchema, commandExecutionSchema, fileChangeSchema, mcpToolCallSchema, dynamicToolCallSchema, planSchema, historyItemSchema, CodexHistoryResponseError, SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT, readCodexFullHistory;
84016
- var init_codex_history = __esm({
84017
- "src/acp/native-history/codex/codex-history.ts"() {
84018
- "use strict";
84019
- init_protocol();
84020
- init_zod();
84021
- init_executable();
84022
- init_acp_error();
84023
- init_native_session();
84024
- init_history_images();
84025
- responseSchema = external_exports.union([
84026
- external_exports.object({
84027
- id: external_exports.number(),
84028
- error: external_exports.object({ code: external_exports.number(), message: external_exports.string() })
84029
- }),
84030
- external_exports.object({ id: external_exports.number(), result: external_exports.unknown() }),
84031
- external_exports.object({ method: external_exports.string() })
84032
- ]);
84033
- threadSchema = external_exports.object({
84034
- thread: external_exports.object({
84035
- id: nativeSessionIdSchema,
84036
- cwd: external_exports.string().min(1).max(2048).refine((path8) => !path8.includes("\0"))
84037
- })
84038
- });
84039
- turnsSchema = external_exports.object({
84040
- data: external_exports.array(
84041
- external_exports.object({
84042
- id: external_exports.string().min(1),
84043
- status: external_exports.enum(["completed", "interrupted", "failed", "inProgress"]),
84044
- error: external_exports.unknown().nullish(),
84045
- items: external_exports.array(external_exports.unknown()).max(1e5)
84046
- })
84047
- ).max(SESSION_HISTORY_MESSAGE_LIMIT),
84048
- nextCursor: external_exports.string().nullish()
84049
- });
84050
- itemTypeSchema = external_exports.object({ type: external_exports.string().min(1).max(80) });
84051
- userMessageSchema = external_exports.object({
84052
- content: external_exports.array(external_exports.unknown()).max(1e4),
84053
- type: external_exports.literal("userMessage")
84054
- });
84055
- textSchema = external_exports.object({ text: external_exports.string() });
84056
- imageSchema = external_exports.object({ url: external_exports.string() });
84057
- agentMessageSchema = textSchema.extend({
84058
- id: external_exports.string().optional(),
84059
- phase: external_exports.string().nullish(),
84060
- type: external_exports.literal("agentMessage")
84061
- });
84062
- reasoningSchema = external_exports.object({
84063
- id: external_exports.string(),
84064
- summary: external_exports.array(external_exports.string()).max(1e4),
84065
- content: external_exports.array(external_exports.string()).max(1e4),
84066
- type: external_exports.literal("reasoning")
84067
- });
84068
- commandExecutionSchema = external_exports.object({
84069
- id: external_exports.string(),
84070
- command: external_exports.string(),
84071
- cwd: external_exports.string(),
84072
- status: external_exports.string(),
84073
- commandActions: external_exports.array(external_exports.object({ type: external_exports.string() }).passthrough()).max(100),
84074
- aggregatedOutput: external_exports.string().nullish(),
84075
- exitCode: external_exports.number().int().nullish(),
84076
- type: external_exports.literal("commandExecution")
84077
- });
84078
- fileChangeSchema = external_exports.object({
84079
- changes: external_exports.array(external_exports.object({ diff: external_exports.string(), path: external_exports.string() })).max(1e4),
84080
- id: external_exports.string(),
84081
- status: external_exports.string(),
84082
- type: external_exports.literal("fileChange")
84083
- });
84084
- mcpToolCallSchema = external_exports.object({
84085
- arguments: external_exports.unknown().optional(),
84086
- error: external_exports.unknown().nullish(),
84087
- id: external_exports.string(),
84088
- result: external_exports.unknown().nullish(),
84089
- server: external_exports.string(),
84090
- status: external_exports.string(),
84091
- tool: external_exports.string(),
84092
- type: external_exports.literal("mcpToolCall")
84093
- });
84094
- dynamicToolCallSchema = external_exports.object({
84095
- arguments: external_exports.unknown().optional(),
84096
- contentItems: external_exports.array(external_exports.unknown()).max(1e4).nullish(),
84097
- id: external_exports.string(),
84098
- namespace: external_exports.string().nullish(),
84099
- status: external_exports.string(),
84100
- tool: external_exports.string(),
84101
- type: external_exports.literal("dynamicToolCall")
84102
- });
84103
- planSchema = external_exports.object({ id: external_exports.string(), text: external_exports.string(), type: external_exports.literal("plan") });
84104
- historyItemSchema = external_exports.discriminatedUnion("type", [
84105
- userMessageSchema,
84106
- agentMessageSchema,
84107
- reasoningSchema,
84108
- commandExecutionSchema,
84109
- fileChangeSchema,
84110
- mcpToolCallSchema,
84111
- dynamicToolCallSchema,
84112
- planSchema
84113
- ]);
84114
- CodexHistoryResponseError = class extends Error {
84115
- code;
84116
- constructor(response) {
84117
- super(response.message);
84118
- this.code = response.code;
84119
- this.name = "CodexHistoryResponseError";
84120
- }
84121
- };
84122
- SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT = Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / 2);
84123
- readCodexFullHistory = async (agent, cwd, nativeSessionId, signal, nativeTurn) => await readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal, {
84124
- ...nativeTurn === void 0 ? {} : { nativeTurn }
84125
- });
84126
- }
84127
- });
84128
-
84129
- // src/acp/native-history/codex/native-history-events.ts
84130
- import { createHash as createHash2 } from "node:crypto";
84131
- function toolKind(value) {
84132
- switch (value) {
84133
- case "read":
84134
- case "edit":
84135
- case "delete":
84136
- case "move":
84137
- case "search":
84138
- case "execute":
84139
- case "think":
84140
- case "fetch":
84141
- case "switch_mode":
84142
- case "other":
84143
- return value;
84144
- default:
84145
- return "other";
84146
- }
84147
- }
84148
- function toolStatus2(value) {
84149
- switch (value) {
84150
- case "pending":
84151
- return "pending";
84152
- case "running":
84153
- case "in_progress":
84154
- return "in_progress";
84155
- case "completed":
84156
- return "completed";
84157
- default:
84158
- return "failed";
84159
- }
84160
- }
84161
- function activityEvent(activity2) {
84162
- if (activity2.activityType === "reasoning") {
84163
- return {
84164
- payload: {
84165
- content: { text: activity2.output, type: "text" },
84166
- messageId: activity2.activityId,
84167
- sessionUpdate: "agent_thought_chunk"
84168
- },
84169
- type: "acp"
84170
- };
84171
- }
84172
- return {
84173
- payload: {
84174
- content: activity2.content,
84175
- kind: toolKind(activity2.toolKind),
84176
- locations: activity2.locations.map((path8) => ({ path: path8 })),
84177
- rawInput: activity2.input,
84178
- rawOutput: activity2.output,
84179
- sessionUpdate: "tool_call",
84180
- status: toolStatus2(activity2.status),
84181
- title: activity2.title,
84182
- toolCallId: activity2.activityId,
84183
- ...activity2.name.length === 0 ? {} : { name: activity2.name }
84184
- },
84185
- type: "acp"
84186
- };
84187
- }
84188
- function contentEvent(sessionUpdate, messageId, content) {
84189
- return { payload: { content, messageId, sessionUpdate }, type: "acp" };
84190
- }
84191
- function historyEvents(history) {
84192
- return history.messages.flatMap((message, index2) => {
84193
- const messageId = `native-history-${index2.toString()}`;
84194
- const sessionUpdate = message.role === "user" ? "user_message_chunk" : "agent_message_chunk";
84195
- const images = (message.images ?? []).map(
84196
- (image) => contentEvent(sessionUpdate, messageId, {
84197
- data: image.data,
84198
- mimeType: image.mimeType,
84199
- type: "image"
84200
- })
84201
- );
84202
- const text2 = message.text.length === 0 ? [] : [contentEvent(sessionUpdate, messageId, { text: message.text, type: "text" })];
84203
- if (message.role === "user") {
84204
- return [...images, ...text2];
84205
- }
84206
- const activities = message.activities.map(activityEvent);
84207
- const content = message.content.map((block) => contentEvent(sessionUpdate, messageId, block));
84208
- return [...activities, ...content, ...images, ...text2];
84209
- });
84210
- }
84211
- function nativeHistoryEvents(sessionId, nativeSessionId, history, eventLimit, cursor, eventStore) {
84212
- const events = historyEvents(history);
84213
- const generationId = createHash2("sha256").update(nativeSessionId).update("\0").update(JSON.stringify(events)).digest("hex");
84214
- eventStore.materialize(sessionId, generationId, events);
84215
- return eventStore.page(sessionId, eventLimit, cursor);
84216
- }
84217
- var init_native_history_events = __esm({
84218
- "src/acp/native-history/codex/native-history-events.ts"() {
84219
- "use strict";
84220
- }
84221
- });
84222
-
84223
83525
  // src/generated/acp-session-store-migrations.ts
84224
83526
  var acpSessionStoreMigrations;
84225
83527
  var init_acp_session_store_migrations = __esm({
@@ -90035,23 +89337,108 @@ var init_preview_event_cache = __esm({
90035
89337
  }
90036
89338
  });
90037
89339
 
89340
+ // src/acp/adapter/codex/tool-event.ts
89341
+ function payloadText(value) {
89342
+ let text2;
89343
+ try {
89344
+ text2 = JSON.stringify(value) ?? "";
89345
+ } catch {
89346
+ text2 = "Tool payload could not be represented as JSON.";
89347
+ }
89348
+ return text2.slice(0, TRUNCATED_TOOL_PAYLOAD_CHARACTER_LIMIT);
89349
+ }
89350
+ function fitNesting(value, depth = 0) {
89351
+ if (typeof value !== "object" || value === null) {
89352
+ return value;
89353
+ }
89354
+ if (depth === MAX_TOOL_PAYLOAD_DEPTH && Object.keys(value).length > 0) {
89355
+ return `[truncated: nesting depth] ${payloadText(value)}`;
89356
+ }
89357
+ if (Array.isArray(value)) {
89358
+ return value.map((child) => fitNesting(child, depth + 1));
89359
+ }
89360
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, fitNesting(child, depth + 1)]));
89361
+ }
89362
+ function prepareCodexToolUpdate(update) {
89363
+ if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
89364
+ return update;
89365
+ }
89366
+ return {
89367
+ ...update,
89368
+ ...update.rawOutput === void 0 ? {} : { rawOutput: fitNesting(update.rawOutput) },
89369
+ ...update._meta == null ? {} : {
89370
+ _meta: Object.fromEntries(
89371
+ Object.entries(update._meta).map(([key, child]) => [key, fitNesting(child, 1)])
89372
+ )
89373
+ }
89374
+ };
89375
+ }
89376
+ function fitPayload(value) {
89377
+ if (value === void 0 || boundedJsonSchema.safeParse(value).success) {
89378
+ return value;
89379
+ }
89380
+ return { truncated: true, text: payloadText(value) };
89381
+ }
89382
+ function fitCodexToolEvent(event) {
89383
+ const decoded = toolEventSchema.safeParse(event);
89384
+ if (!decoded.success) {
89385
+ return event;
89386
+ }
89387
+ return {
89388
+ ...decoded.data,
89389
+ rawInput: fitPayload(decoded.data.rawInput),
89390
+ rawOutput: fitPayload(decoded.data.rawOutput)
89391
+ };
89392
+ }
89393
+ var toolEventSchema, TRUNCATED_TOOL_PAYLOAD_CHARACTER_LIMIT, MAX_TOOL_PAYLOAD_DEPTH;
89394
+ var init_tool_event = __esm({
89395
+ "src/acp/adapter/codex/tool-event.ts"() {
89396
+ "use strict";
89397
+ init_protocol();
89398
+ init_zod();
89399
+ toolEventSchema = external_exports.looseObject({
89400
+ sessionUpdate: external_exports.enum(["tool_call", "tool_call_update"]),
89401
+ rawInput: external_exports.unknown().optional(),
89402
+ rawOutput: external_exports.unknown().optional()
89403
+ });
89404
+ TRUNCATED_TOOL_PAYLOAD_CHARACTER_LIMIT = 32768;
89405
+ MAX_TOOL_PAYLOAD_DEPTH = 16;
89406
+ }
89407
+ });
89408
+
90038
89409
  // src/acp/adapter/codex/adapter.ts
89410
+ import { createHash as createHash4 } from "node:crypto";
90039
89411
  var CodexAdapter;
90040
89412
  var init_adapter2 = __esm({
90041
89413
  "src/acp/adapter/codex/adapter.ts"() {
90042
89414
  "use strict";
89415
+ init_protocol();
89416
+ init_executable();
90043
89417
  init_acp_error();
90044
- init_codex_history();
90045
- init_native_history_events();
89418
+ init_app_server_client();
89419
+ init_history();
89420
+ init_native_session();
90046
89421
  init_preview_event_cache();
90047
89422
  init_query_processes();
90048
89423
  init_session_events();
89424
+ init_tool_event();
90049
89425
  CodexAdapter = class {
90050
89426
  #queryProcesses;
90051
89427
  #connector;
89428
+ #dependencies;
89429
+ #contentExternalizer;
90052
89430
  #previewCache = null;
90053
89431
  constructor(dependencies) {
90054
- this.#connector = new AcpSessionConnector(dependencies.contentExternalizer);
89432
+ this.#dependencies = dependencies;
89433
+ this.#contentExternalizer = {
89434
+ update: async (sessionId, update, signal) => {
89435
+ signal.throwIfAborted();
89436
+ const prepared = prepareCodexToolUpdate(update);
89437
+ signal.throwIfAborted();
89438
+ return await dependencies.contentExternalizer.update(sessionId, prepared, signal);
89439
+ }
89440
+ };
89441
+ this.#connector = new AcpSessionConnector(this.#contentExternalizer, fitCodexToolEvent);
90055
89442
  this.#queryProcesses = new AgentQueryProcesses(dependencies.processes, this.#connector);
90056
89443
  }
90057
89444
  capabilities = async (query) => await this.#queryProcesses.capabilities(query);
@@ -90065,21 +89452,73 @@ var init_adapter2 = __esm({
90065
89452
  }
90066
89453
  };
90067
89454
  previewSessionEvents = async (query, request) => {
90068
- const { agent, cwd, signal } = query;
89455
+ const { agent, cwd } = query;
89456
+ const signal = AbortSignal.any([query.signal, AbortSignal.timeout(6e4)]);
90069
89457
  const { sessionId } = request;
90070
- this.#previewCache ??= openPreviewEventCache();
90071
- const snapshot = await readCodexFullHistory(agent, cwd, request.nativeSessionId, signal);
90072
- if (snapshot.history.status === "unavailable") {
90073
- throw new AcpExecutionError(snapshot.history.cause.message, {}, snapshot.history.cause.code);
89458
+ signal.throwIfAborted();
89459
+ nativeSessionIdSchema.parse(request.nativeSessionId);
89460
+ if (agent.id !== "codex") {
89461
+ throw new AcpExecutionError(
89462
+ "The Codex adapter cannot preview history for another agent.",
89463
+ {},
89464
+ "agent_adapter_mismatch"
89465
+ );
90074
89466
  }
90075
- return nativeHistoryEvents(
90076
- sessionId,
90077
- request.nativeSessionId,
90078
- snapshot.history,
90079
- request.eventLimit,
90080
- request.cursor,
90081
- this.#previewCache.events
89467
+ if (!await revalidateExecutable(agent.agentIdentity)) {
89468
+ throw new AcpExecutionError(
89469
+ "The local Codex executable changed. Restart Mobius to discover it again.",
89470
+ {},
89471
+ "agent_executable_changed"
89472
+ );
89473
+ }
89474
+ this.#previewCache ??= openPreviewEventCache();
89475
+ const events = [];
89476
+ await this.#dependencies.processes.runTransient(
89477
+ signal,
89478
+ async () => {
89479
+ const client2 = new CodexAppServerClient({
89480
+ command: agent.command,
89481
+ cwd,
89482
+ environment: agent.environment,
89483
+ handlers: {
89484
+ onNotification: async () => void 0,
89485
+ onServerRequest: async () => {
89486
+ throw new AcpExecutionError(
89487
+ "Unexpected request while reading saved history",
89488
+ {},
89489
+ "invalid_native_session_response"
89490
+ );
89491
+ }
89492
+ }
89493
+ });
89494
+ return {
89495
+ client: client2,
89496
+ closeProcess: async () => {
89497
+ client2.detach();
89498
+ await stopProcessTree(client2.child());
89499
+ }
89500
+ };
89501
+ },
89502
+ async ({ client: client2 }) => {
89503
+ await client2.initialize(signal);
89504
+ return await replayCodexHistory(
89505
+ client2,
89506
+ request.nativeSessionId,
89507
+ async (update) => {
89508
+ const externalized = await this.#contentExternalizer.update(sessionId, update, signal);
89509
+ events.push({
89510
+ type: "acp",
89511
+ payload: decodeAcpSessionUpdate(JSON.stringify(fitCodexToolEvent(externalized.event)))
89512
+ });
89513
+ },
89514
+ signal
89515
+ );
89516
+ },
89517
+ async (runtime) => await runtime.closeProcess()
90082
89518
  );
89519
+ const generationId = createHash4("sha256").update(request.nativeSessionId).update("\0").update(JSON.stringify(events)).digest("hex");
89520
+ this.#previewCache.events.materialize(sessionId, generationId, events);
89521
+ return this.#previewCache.events.page(sessionId, request.eventLimit, request.cursor);
90083
89522
  };
90084
89523
  };
90085
89524
  }
@@ -90137,17 +89576,6 @@ var init_registry = __esm({
90137
89576
  });
90138
89577
 
90139
89578
  // src/acp/content/content-externalizer.ts
90140
- function reasoningTail(text2) {
90141
- if (Buffer.byteLength(text2, "utf8") <= MAXIMUM_REASONING_CHUNK_BYTES) {
90142
- return text2;
90143
- }
90144
- const bytes = Buffer.from(text2, "utf8");
90145
- let start = bytes.length - MAXIMUM_REASONING_CHUNK_BYTES;
90146
- while (start < bytes.length && (bytes.readUInt8(start) & 192) === 128) {
90147
- start += 1;
90148
- }
90149
- return bytes.toString("utf8", start);
90150
- }
90151
89579
  function decodeBase64(data) {
90152
89580
  if (data.length > MAXIMUM_ENCODED_CONTENT_CHARACTERS || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)) {
90153
89581
  throw new Error("The ACP embedded content is not valid bounded base64");
@@ -90161,14 +89589,13 @@ function decodeBase64(data) {
90161
89589
  function isRecord6(value) {
90162
89590
  return typeof value === "object" && value !== null && !Array.isArray(value);
90163
89591
  }
90164
- var MAXIMUM_ENCODED_CONTENT_CHARACTERS, MAXIMUM_REASONING_CHUNK_BYTES, embeddedImageSchema, inlineImageUrlSchema, toolImageSchema, AcpContentExternalizer;
89592
+ var MAXIMUM_ENCODED_CONTENT_CHARACTERS, embeddedImageSchema, inlineImageUrlSchema, toolImageSchema, AcpContentExternalizer;
90165
89593
  var init_content_externalizer = __esm({
90166
89594
  "src/acp/content/content-externalizer.ts"() {
90167
89595
  "use strict";
90168
89596
  init_zod();
90169
89597
  init_raster();
90170
89598
  MAXIMUM_ENCODED_CONTENT_CHARACTERS = 4e6;
90171
- MAXIMUM_REASONING_CHUNK_BYTES = 24 * 1024;
90172
89599
  embeddedImageSchema = external_exports.looseObject({
90173
89600
  type: external_exports.literal("image"),
90174
89601
  data: external_exports.string(),
@@ -90351,24 +89778,7 @@ var init_content_externalizer = __esm({
90351
89778
  }
90352
89779
  update = async (sessionId, update, signal) => {
90353
89780
  switch (update.sessionUpdate) {
90354
- case "agent_thought_chunk": {
90355
- if (update.content.type === "text") {
90356
- const text2 = reasoningTail(update.content.text);
90357
- const bounded2 = { ...update, content: { ...update.content, text: text2 } };
90358
- return {
90359
- agent: bounded2,
90360
- event: {
90361
- ...bounded2,
90362
- ...text2 === update.content.text ? {} : { meta: { truncated: true } }
90363
- }
90364
- };
90365
- }
90366
- const content = await this.#content(sessionId, update.content, signal);
90367
- return {
90368
- agent: { ...update, content: content.agent },
90369
- event: { ...update, content: content.event }
90370
- };
90371
- }
89781
+ case "agent_thought_chunk":
90372
89782
  case "user_message_chunk":
90373
89783
  case "agent_message_chunk":
90374
89784
  case "compaction_summary_chunk": {
@@ -90565,7 +89975,7 @@ var init_node_error = __esm({
90565
89975
  });
90566
89976
 
90567
89977
  // src/storage/installation/installation-files.ts
90568
- import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
89978
+ import { createHash as createHash5, randomUUID as randomUUID9 } from "node:crypto";
90569
89979
  import { mkdir as mkdir4, open as open5, readdir as readdir5, rename as rename3, unlink as unlink3, writeFile } from "node:fs/promises";
90570
89980
  import { dirname as dirname9, join as join23 } from "node:path";
90571
89981
  function applicationDirectory(root, applicationId) {
@@ -90584,7 +89994,7 @@ function connectionFilePath(connectionDirectory2, connectionId2) {
90584
89994
  return join23(connectionDirectory2, `${connectionId2}.json`);
90585
89995
  }
90586
89996
  function channelIndexFilePath(installationDirectory2, channelId) {
90587
- return join23(installationDirectory2, "channels", `mci_${createHash4("sha256").update(channelId).digest("hex")}.json`);
89997
+ return join23(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
90588
89998
  }
90589
89999
  async function readInstallationFile(path8) {
90590
90000
  let handle;
@@ -91276,10 +90686,10 @@ var init_control_token = __esm({
91276
90686
  });
91277
90687
 
91278
90688
  // src/daemon/control/local-client.ts
91279
- import { createHash as createHash5 } from "node:crypto";
90689
+ import { createHash as createHash6 } from "node:crypto";
91280
90690
  import { createConnection } from "node:net";
91281
90691
  function controlSocketPath(stateDirectory, endpoint = "manager") {
91282
- const installationHash = createHash5("sha256").update(endpoint === "manager" ? stateDirectory : `${stateDirectory}:worker`).digest("hex").slice(0, 32);
90692
+ const installationHash = createHash6("sha256").update(endpoint === "manager" ? stateDirectory : `${stateDirectory}:worker`).digest("hex").slice(0, 32);
91283
90693
  return managerPlatform.controlSocketPath(installationHash);
91284
90694
  }
91285
90695
  async function readSocketMessage(socket, signal) {
@@ -92360,7 +91770,7 @@ var init_worker_lifecycle_log = __esm({
92360
91770
  });
92361
91771
 
92362
91772
  // src/daemon/lifecycle/worker-process.ts
92363
- import { spawn as spawn9 } from "node:child_process";
91773
+ import { spawn as spawn8 } from "node:child_process";
92364
91774
  import { isAbsolute as isAbsolute14 } from "node:path";
92365
91775
  async function decodeWorkerLaunch(value) {
92366
91776
  const { entry, executable, version: version2 } = workerLaunch.parse(value);
@@ -92409,7 +91819,7 @@ var init_worker_process = __esm({
92409
91819
  constructor(launch, signal, environment) {
92410
91820
  signal.throwIfAborted();
92411
91821
  this.launch = launch;
92412
- this.#child = spawn9(launch.executable, [launch.entry, "__worker"], {
91822
+ this.#child = spawn8(launch.executable, [launch.entry, "__worker"], {
92413
91823
  env: environment,
92414
91824
  windowsHide: true,
92415
91825
  stdio: ["ignore", "pipe", "pipe", "ipc"]
@@ -92927,9 +92337,9 @@ var init_package2 = __esm({
92927
92337
  });
92928
92338
 
92929
92339
  // src/daemon/lifecycle/manager-client.ts
92930
- import { spawn as spawn10 } from "node:child_process";
92340
+ import { spawn as spawn9 } from "node:child_process";
92931
92341
  async function spawnManager(launch) {
92932
- const child = spawn10(launch.executable, [launch.entry, "__manager"], {
92342
+ const child = spawn9(launch.executable, [launch.entry, "__manager"], {
92933
92343
  detached: true,
92934
92344
  windowsHide: true,
92935
92345
  env: process.env,
@@ -96780,7 +96190,7 @@ var init_prompt_lifecycle = __esm({
96780
96190
  });
96781
96191
 
96782
96192
  // src/session/turn/execution-receipts.ts
96783
- import { createHash as createHash6, randomUUID as randomUUID13 } from "node:crypto";
96193
+ import { createHash as createHash7, randomUUID as randomUUID13 } from "node:crypto";
96784
96194
  function isTerminal(state) {
96785
96195
  return state === "succeeded" || state === "failed" || state === "cancelled";
96786
96196
  }
@@ -96902,7 +96312,7 @@ var init_execution_receipts = __esm({
96902
96312
  ];
96903
96313
  });
96904
96314
  claimExecution = (commandId, sessionId, commandJson) => {
96905
- const commandHash = createHash6("sha256").update(commandJson).digest("hex");
96315
+ const commandHash = createHash7("sha256").update(commandJson).digest("hex");
96906
96316
  let existing = this.#executions.get(commandId);
96907
96317
  const previous = this.outcome(commandId);
96908
96318
  if (existing?.sessionId === sessionId && !existing.started && previous?.type === "lifecycle-metadata" && previous.payload.kind === "prompt.failed-before-start" && previous.payload.code === "runtime_restarted") {
@@ -97284,9 +96694,9 @@ var init_session_turns = __esm({
97284
96694
  #bySessionId = /* @__PURE__ */ new Map();
97285
96695
  #operations;
97286
96696
  #activity;
97287
- constructor(operations, activity2 = new RuntimeTurnActivity()) {
96697
+ constructor(operations, activity = new RuntimeTurnActivity()) {
97288
96698
  this.#operations = operations;
97289
- this.#activity = activity2;
96699
+ this.#activity = activity;
97290
96700
  }
97291
96701
  acceptsPrompts = () => this.#activity.acceptsPrompts();
97292
96702
  session = (sessionId) => {
@@ -97728,7 +97138,7 @@ var init_scratch_directory = __esm({
97728
97138
  });
97729
97139
 
97730
97140
  // src/session/content/external-content-store.ts
97731
- import { createHash as createHash7 } from "node:crypto";
97141
+ import { createHash as createHash8 } from "node:crypto";
97732
97142
  import { join as join34 } from "node:path";
97733
97143
  var contentRequest, CONTENT_LIFETIME_MILLISECONDS, metadataSchema, LocalExternalContentStore;
97734
97144
  var init_external_content_store = __esm({
@@ -97785,7 +97195,7 @@ var init_external_content_store = __esm({
97785
97195
  const active = AbortSignal.any([signal, this.#lifetime.signal]);
97786
97196
  active.throwIfAborted();
97787
97197
  const metadata = metadataSchema.parse({ kind, mediaType, name: name2 });
97788
- const key = createHash7("sha256").update(bytes).digest("hex");
97198
+ const key = createHash8("sha256").update(bytes).digest("hex");
97789
97199
  const request = `mobius-content:${kind}:${key}`;
97790
97200
  const existing = this.#entries.get(request);
97791
97201
  if (existing !== void 0 && existing.expiresAt > Date.now()) {
@@ -98703,7 +98113,7 @@ var init_agent_settings_adapter = __esm({
98703
98113
  });
98704
98114
 
98705
98115
  // src/session/settings/discover-agent-settings.ts
98706
- import { createHash as createHash8 } from "node:crypto";
98116
+ import { createHash as createHash9 } from "node:crypto";
98707
98117
  function agentSettingsFailureDetails(agentId, failure2) {
98708
98118
  const details = { agentId, code: operationErrorCode(failure2) };
98709
98119
  return failure2 instanceof AcpConfigurationValueUnavailableError ? {
@@ -98968,7 +98378,7 @@ function settingsRevision(agent, reportedAgentVersion, settings, modelEffort) {
98968
98378
  unsupportedModelIds: modelEffort.unsupportedModelIds,
98969
98379
  valuesByModel: {}
98970
98380
  };
98971
- return createHash8("sha256").update(
98381
+ return createHash9("sha256").update(
98972
98382
  JSON.stringify({
98973
98383
  adapterVersion: agent.kind === "acp-adapter-process" ? agent.adapterVersion : agent.agentVersion,
98974
98384
  agentId: agent.id,
@@ -99327,35 +98737,7 @@ var init_resolve_session_directories = __esm({
99327
98737
  });
99328
98738
 
99329
98739
  // src/runtime/command/registry/history.ts
99330
- function isAgentReasoning(event) {
99331
- return event?.type === "acp" && event.payload.sessionUpdate === "agent_thought_chunk";
99332
- }
99333
- function omitAgentReasoning(events) {
99334
- const retained = [];
99335
- let previousReasoningMessageId;
99336
- for (const positioned of events) {
99337
- const { event } = positioned;
99338
- if (event.type !== "acp" || event.payload.sessionUpdate !== "agent_thought_chunk") {
99339
- previousReasoningMessageId = void 0;
99340
- retained.push(positioned);
99341
- continue;
99342
- }
99343
- const messageId = event.payload.messageId ?? null;
99344
- if (previousReasoningMessageId === void 0 || previousReasoningMessageId !== messageId) {
99345
- retained.push({
99346
- ...positioned,
99347
- event: {
99348
- ...event,
99349
- mobiusMetadata: { omitted: true },
99350
- payload: { ...event.payload, content: { text: "", type: "text" } }
99351
- }
99352
- });
99353
- }
99354
- previousReasoningMessageId = messageId;
99355
- }
99356
- return retained;
99357
- }
99358
- async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoning, queuedPromptRequests, load) {
98740
+ async function loadHistoryPage(sessionId, eventLimit, initialCursor, queuedPromptRequests, load) {
99359
98741
  let cursor = initialCursor;
99360
98742
  let loaded = [];
99361
98743
  let sessionGenerationId = null;
@@ -99382,9 +98764,7 @@ async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoni
99382
98764
  });
99383
98765
  loaded = [...events, ...loaded];
99384
98766
  sourceNextCursor = replay.nextCursor;
99385
- const visible2 = omitReasoning ? omitAgentReasoning(loaded) : loaded;
99386
- const reasoningContinuesBeforePage = sourceNextCursor !== null && isAgentReasoning(loaded[0]?.event);
99387
- if (visible2.length >= eventLimit && !reasoningContinuesBeforePage) {
98767
+ if (loaded.length >= eventLimit) {
99388
98768
  break;
99389
98769
  }
99390
98770
  cursor = sourceNextCursor;
@@ -99392,8 +98772,7 @@ async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoni
99392
98772
  if (sessionGenerationId === null || throughPosition === null) {
99393
98773
  throw new SessionError("session_history_unavailable", "The Session history is unavailable");
99394
98774
  }
99395
- const visible = omitReasoning ? omitAgentReasoning(loaded) : loaded;
99396
- const orderedEvents = visible.slice(-eventLimit);
98775
+ const orderedEvents = loaded.slice(-eventLimit);
99397
98776
  const nextCursor = orderedEvents[0]?.cursor ?? null;
99398
98777
  return {
99399
98778
  events: {
@@ -99435,7 +98814,6 @@ async function executeSessionHistoryPageLoad(socket, command, config2, resolveAg
99435
98814
  command.sessionId,
99436
98815
  command.eventLimit,
99437
98816
  command.cursor,
99438
- command.omit?.includes("agent-reasoning") === true,
99439
98817
  recovery.queuedPromptRequests,
99440
98818
  async (eventLimit, cursor) => await sessions.loadSessionEvents(loadOptions, eventLimit, cursor)
99441
98819
  );
@@ -99482,7 +98860,6 @@ async function executeSessionPreviewHistoryPageLoad(socket, command, config2, re
99482
98860
  command.sessionId,
99483
98861
  command.eventLimit,
99484
98862
  command.cursor,
99485
- command.omit?.includes("agent-reasoning") === true,
99486
98863
  [],
99487
98864
  async (eventLimit, cursor) => await sessions.previewNativeSessionEvents(loadOptions, command.sessionId, eventLimit, cursor)
99488
98865
  );
@@ -99510,7 +98887,7 @@ async function executeSessionPreviewHistoryPageLoad(socket, command, config2, re
99510
98887
  }
99511
98888
  }
99512
98889
  var sessionHistoryPageLoadCommand, previewHistoryPageLoadCommand;
99513
- var init_history2 = __esm({
98890
+ var init_history3 = __esm({
99514
98891
  "src/runtime/command/registry/history.ts"() {
99515
98892
  "use strict";
99516
98893
  init_protocol();
@@ -100277,7 +99654,7 @@ var init_execute_prompt = __esm({
100277
99654
  });
100278
99655
 
100279
99656
  // src/runtime/relay/artifact-download.ts
100280
- import { createHash as createHash9 } from "node:crypto";
99657
+ import { createHash as createHash10 } from "node:crypto";
100281
99658
  import { fetch as fetch4 } from "undici";
100282
99659
  function downloadUrl(config2, artifact) {
100283
99660
  const url2 = relayHttpEndpoint(config2.relayUrl);
@@ -100364,7 +99741,7 @@ async function downloadPromptArtifact(config2, artifact, signal) {
100364
99741
  );
100365
99742
  }
100366
99743
  const bytes = await responseBytes(response, artifact.byteLength, requestSignal);
100367
- if (createHash9("sha256").update(bytes).digest("hex") !== artifact.sha256) {
99744
+ if (createHash10("sha256").update(bytes).digest("hex") !== artifact.sha256) {
100368
99745
  throw new PromptArtifactError(
100369
99746
  "artifact_integrity_failed",
100370
99747
  "The prompt artifact failed integrity validation"
@@ -100924,7 +100301,7 @@ var init_registry2 = __esm({
100924
100301
  init_agent_catalog();
100925
100302
  init_agent_settings();
100926
100303
  init_file_read();
100927
- init_history2();
100304
+ init_history3();
100928
100305
  init_interactions2();
100929
100306
  init_native_sessions();
100930
100307
  init_prompt2();
@@ -101963,11 +101340,11 @@ async function reportDaemonUpgradeAvailability(send2, signal) {
101963
101340
  send2({ ...base, kind: "runtime.upgrade.result", outcome: { status: "succeeded" } });
101964
101341
  }
101965
101342
  }
101966
- async function runDaemonReleaseUpgrades(signal, activity2) {
101343
+ async function runDaemonReleaseUpgrades(signal, activity) {
101967
101344
  try {
101968
101345
  for await (const _tick of setInterval2(36e5, void 0, { signal })) {
101969
101346
  try {
101970
- await checkDaemonReleaseUpgrade(signal, activity2);
101347
+ await checkDaemonReleaseUpgrade(signal, activity);
101971
101348
  } catch (cause) {
101972
101349
  signal.throwIfAborted();
101973
101350
  console.error("Daemon npm upgrade check failed", cause);
@@ -102029,7 +101406,7 @@ async function awaitDaemonReleaseSwitch(stateDirectory, id, signal) {
102029
101406
  }
102030
101407
  return outcome;
102031
101408
  }
102032
- async function checkDaemonReleaseUpgrade(signal, activity2) {
101409
+ async function checkDaemonReleaseUpgrade(signal, activity) {
102033
101410
  var _stack = [];
102034
101411
  try {
102035
101412
  const control = await openMobiusControlInstallation(signal, process.env);
@@ -102042,17 +101419,17 @@ async function checkDaemonReleaseUpgrade(signal, activity2) {
102042
101419
  return;
102043
101420
  }
102044
101421
  const launch = await installDaemonReleaseVersion(version2, signal);
102045
- if (activity2.count() > 0) {
101422
+ if (activity.count() > 0) {
102046
101423
  new RuntimeDiagnosticLog(control.stateDirectory).record(
102047
101424
  `Mobius daemon diagnostic ${JSON.stringify({
102048
101425
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
102049
101426
  event: "daemon_upgrade_deferred",
102050
101427
  version: version2,
102051
- activeTurns: activity2.count()
101428
+ activeTurns: activity.count()
102052
101429
  })}`
102053
101430
  );
102054
101431
  }
102055
- const _reservation = __using(_stack, await activity2.reserveWhenIdle(signal));
101432
+ const _reservation = __using(_stack, await activity.reserveWhenIdle(signal));
102056
101433
  signal.throwIfAborted();
102057
101434
  await requestInstalledDaemonReleaseSwitch(control.stateDirectory, launch, signal);
102058
101435
  await new Promise((resolve19) => {