@moxt-ai/mobius 0.0.307 → 0.0.309

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 (51) 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 +728 -1349
  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 +666 -1289
  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/dist/util/filesystem/private-path.js +4 -2
  37. package/dist/util/filesystem/private-path.js.map +2 -2
  38. package/dist/util/platform/windows.d.ts.map +1 -1
  39. package/dist/util/platform/windows.js +6 -2
  40. package/dist/util/platform/windows.js.map +1 -1
  41. package/dist/util/process/executable.js +4 -2
  42. package/dist/util/process/executable.js.map +2 -2
  43. package/package.json +2 -2
  44. package/dist/acp/native-history/codex/codex-history.d.ts +0 -17
  45. package/dist/acp/native-history/codex/codex-history.d.ts.map +0 -1
  46. package/dist/acp/native-history/codex/codex-history.js +0 -661
  47. package/dist/acp/native-history/codex/codex-history.js.map +0 -1
  48. package/dist/acp/native-history/codex/native-history-events.d.ts +0 -8
  49. package/dist/acp/native-history/codex/native-history-events.d.ts.map +0 -1
  50. package/dist/acp/native-history/codex/native-history-events.js +0 -92
  51. 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.309",
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
  };
@@ -70244,8 +70244,8 @@ async function validatePathPermissions(path8, _directory, privateAccess, signal)
70244
70244
  MOBIUS_PERMISSION_PRIVATE: privateAccess ? "1" : "0"
70245
70245
  },
70246
70246
  windowsHide: true,
70247
- signal: AbortSignal.any([signal, AbortSignal.timeout(1e4)]),
70248
- timeout: 1e4,
70247
+ signal: AbortSignal.any([signal, AbortSignal.timeout(windowsPermissionsTimeoutMs)]),
70248
+ timeout: windowsPermissionsTimeoutMs,
70249
70249
  maxBuffer: 16384
70250
70250
  }
70251
70251
  );
@@ -70254,7 +70254,7 @@ async function validatePathPermissions(path8, _directory, privateAccess, signal)
70254
70254
  throw new LocalPathError("The local path permissions could not be secured", { cause });
70255
70255
  }
70256
70256
  }
70257
- var execute, windowsPermissions, windowsPlatform;
70257
+ var execute, windowsPermissions, windowsPermissionsTimeoutMs, windowsPlatform;
70258
70258
  var init_windows = __esm({
70259
70259
  "src/util/platform/windows.ts"() {
70260
70260
  "use strict";
@@ -70265,6 +70265,7 @@ var init_windows = __esm({
70265
70265
  execute = promisify2(execFile3);
70266
70266
  windowsPermissions = `
70267
70267
  $ErrorActionPreference = 'Stop'
70268
+ $ProgressPreference = 'SilentlyContinue'
70268
70269
  Import-Module (Join-Path $PSHOME 'Modules/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1')
70269
70270
  $item = Get-Item -LiteralPath $env:MOBIUS_PERMISSION_PATH -Force
70270
70271
  if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw 'Unsafe path' }
@@ -70286,6 +70287,7 @@ if ($env:MOBIUS_PERMISSION_PRIVATE -eq '1') {
70286
70287
  Set-Acl -LiteralPath $item.FullName -AclObject $private
70287
70288
  }
70288
70289
  `;
70290
+ windowsPermissionsTimeoutMs = 3e4;
70289
70291
  windowsPlatform = {
70290
70292
  controlSocketPath: (installationHash) => `\\\\.\\pipe\\mobius-${installationHash}`,
70291
70293
  prepareControlSocket: async () => {
@@ -71089,6 +71091,7 @@ var init_app_server_protocol = __esm({
71089
71091
  threadTurnSchema = external_exports.object({
71090
71092
  id: boundedText(256).optional(),
71091
71093
  status: turnStatusSchema.optional(),
71094
+ error: external_exports.object({ message: external_exports.string().transform((message) => message.slice(0, 4096)) }).nullish(),
71092
71095
  items: external_exports.array(external_exports.unknown()).max(1e5)
71093
71096
  });
71094
71097
  threadTurnsSchema = external_exports.array(threadTurnSchema).max(1e5);
@@ -71563,12 +71566,12 @@ function presentToolItem(item) {
71563
71566
  };
71564
71567
  }
71565
71568
  if (item.type === "collabAgentToolCall") {
71566
- const spawn11 = item.tool === "spawnAgent";
71569
+ const spawn10 = item.tool === "spawnAgent";
71567
71570
  return {
71568
71571
  content: [],
71569
71572
  kind: "other",
71570
71573
  locations: [],
71571
- rawInput: spawn11 ? {
71574
+ rawInput: spawn10 ? {
71572
71575
  model: item.model,
71573
71576
  prompt: item.prompt,
71574
71577
  reasoningEffort: item.reasoningEffort,
@@ -71576,10 +71579,10 @@ function presentToolItem(item) {
71576
71579
  } : { receiverThreadIds: item.receiverThreadIds, senderThreadId: item.senderThreadId },
71577
71580
  rawOutput: {
71578
71581
  agentsStates: item.agentsStates,
71579
- ...spawn11 ? { receiverThreadIds: item.receiverThreadIds } : {}
71582
+ ...spawn10 ? { receiverThreadIds: item.receiverThreadIds } : {}
71580
71583
  },
71581
71584
  status: collaborationStatus(item.status),
71582
- title: spawn11 ? "Dispatch subagent" : "Wait for subagent"
71585
+ title: spawn10 ? "Dispatch subagent" : "Wait for subagent"
71583
71586
  };
71584
71587
  }
71585
71588
  if (item.type === "subAgentActivity" && item.kind === "started") {
@@ -71912,6 +71915,291 @@ var init_borrowed_agent = __esm({
71912
71915
  }
71913
71916
  });
71914
71917
 
71918
+ // src/storage/files/local-files.ts
71919
+ import { createReadStream as createReadStream2 } from "node:fs";
71920
+ import { mkdir as mkdir3, open as open4, readdir as readdir4, readFile as readFile5, realpath as realpath6, stat as stat5 } from "node:fs/promises";
71921
+ function entryKind(entry) {
71922
+ if (entry.isDirectory()) {
71923
+ return "directory";
71924
+ }
71925
+ if (entry.isFile()) {
71926
+ return "file";
71927
+ }
71928
+ if (entry.isSymbolicLink()) {
71929
+ return "symbolic-link";
71930
+ }
71931
+ if (entry.isBlockDevice() || entry.isCharacterDevice()) {
71932
+ return "device";
71933
+ }
71934
+ if (entry.isFIFO()) {
71935
+ return "fifo";
71936
+ }
71937
+ return entry.isSocket() ? "socket" : "unknown";
71938
+ }
71939
+ async function canonicalPath(path8) {
71940
+ return await realpath6(path8);
71941
+ }
71942
+ async function readPathMetadata(path8) {
71943
+ const metadata = await stat5(path8);
71944
+ return {
71945
+ kind: metadata.isDirectory() ? "directory" : metadata.isFile() ? "file" : "other",
71946
+ modifiedAt: metadata.mtime,
71947
+ modifiedMilliseconds: metadata.mtimeMs,
71948
+ size: metadata.size
71949
+ };
71950
+ }
71951
+ async function listDirectory(path8) {
71952
+ const entries = await readdir4(path8, { withFileTypes: true });
71953
+ return entries.map((entry) => ({ kind: entryKind(entry), name: entry.name }));
71954
+ }
71955
+ async function ensurePrivateDirectory(path8) {
71956
+ await mkdir3(path8, { mode: 448, recursive: true });
71957
+ }
71958
+ async function ensureCanonicalDirectory(path8) {
71959
+ await ensurePrivateDirectory(path8);
71960
+ const resolved = await realpath6(path8);
71961
+ return (await stat5(resolved)).isDirectory() ? resolved : null;
71962
+ }
71963
+ async function readFileStart(path8, byteLength) {
71964
+ const bytes = new Uint8Array(byteLength);
71965
+ const handle = await open4(path8, "r");
71966
+ try {
71967
+ await handle.read(bytes, 0, byteLength, 0);
71968
+ } finally {
71969
+ await handle.close();
71970
+ }
71971
+ return bytes;
71972
+ }
71973
+ async function readFileBytes(path8) {
71974
+ return await readFile5(path8);
71975
+ }
71976
+ function readFileChunks(path8, chunkBytes, signal) {
71977
+ return createReadStream2(path8, { highWaterMark: chunkBytes, signal });
71978
+ }
71979
+ var init_local_files = __esm({
71980
+ "src/storage/files/local-files.ts"() {
71981
+ "use strict";
71982
+ }
71983
+ });
71984
+
71985
+ // src/acp/content/raster.ts
71986
+ import { basename as basename4, isAbsolute as isAbsolute9, normalize } from "node:path";
71987
+ import { fileURLToPath } from "node:url";
71988
+ function startsWith(bytes, signature, offset = 0) {
71989
+ if (bytes.byteLength < offset + signature.byteLength) {
71990
+ return false;
71991
+ }
71992
+ return signature.every((value, index2) => bytes[offset + index2] === value);
71993
+ }
71994
+ function sniffRasterMime(bytes) {
71995
+ if (startsWith(bytes, PNG_SIGNATURE)) {
71996
+ return "image/png";
71997
+ }
71998
+ if (startsWith(bytes, JPEG_SIGNATURE)) {
71999
+ return "image/jpeg";
72000
+ }
72001
+ if (startsWith(bytes, GIF87_SIGNATURE) || startsWith(bytes, GIF89_SIGNATURE)) {
72002
+ return "image/gif";
72003
+ }
72004
+ if (startsWith(bytes, RIFF_SIGNATURE) && startsWith(bytes, WEBP_SIGNATURE, 8)) {
72005
+ return "image/webp";
72006
+ }
72007
+ return null;
72008
+ }
72009
+ async function resolveCanonicalPath(requested, signal) {
72010
+ signal.throwIfAborted();
72011
+ if (!isAbsolute9(requested) || requested.includes("\0") || normalize(requested) !== requested) {
72012
+ return null;
72013
+ }
72014
+ try {
72015
+ const target = await canonicalPath(requested);
72016
+ signal.throwIfAborted();
72017
+ if (!isAbsolute9(target) || normalize(target) !== target) {
72018
+ return null;
72019
+ }
72020
+ return target;
72021
+ } catch (cause) {
72022
+ signal.throwIfAborted();
72023
+ if (cause instanceof Error && cause.name === "AbortError") {
72024
+ throw cause;
72025
+ }
72026
+ return null;
72027
+ }
72028
+ }
72029
+ function parseLocalImageUri(uri) {
72030
+ const trimmed = uri.trim();
72031
+ if (trimmed.length === 0 || trimmed.length > 2048 || trimmed.includes("\0")) {
72032
+ return null;
72033
+ }
72034
+ if (trimmed.startsWith("data:")) {
72035
+ return null;
72036
+ }
72037
+ if (trimmed.startsWith("file:")) {
72038
+ try {
72039
+ const url2 = new URL(trimmed);
72040
+ if (url2.protocol !== "file:" || url2.host.length > 0) {
72041
+ return null;
72042
+ }
72043
+ return fileURLToPath(url2);
72044
+ } catch {
72045
+ return null;
72046
+ }
72047
+ }
72048
+ if (!isAbsolute9(trimmed) && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
72049
+ return null;
72050
+ }
72051
+ return trimmed;
72052
+ }
72053
+ async function readLocalRaster(uri, signal) {
72054
+ signal.throwIfAborted();
72055
+ const requested = parseLocalImageUri(uri);
72056
+ if (requested === null) {
72057
+ return null;
72058
+ }
72059
+ const target = await resolveCanonicalPath(requested, signal);
72060
+ if (target === null) {
72061
+ return null;
72062
+ }
72063
+ const targetMetadata = await readPathMetadata(target);
72064
+ signal.throwIfAborted();
72065
+ if (targetMetadata.kind !== "file" || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
72066
+ return null;
72067
+ }
72068
+ const header = await readFileStart(target, 12);
72069
+ signal.throwIfAborted();
72070
+ const mimeType = sniffRasterMime(header);
72071
+ if (mimeType === null) {
72072
+ return null;
72073
+ }
72074
+ return new LocalRasterImage(basename4(target) || "Image", mimeType, target);
72075
+ }
72076
+ var MAX_LOCAL_RASTER_BYTES, PNG_SIGNATURE, JPEG_SIGNATURE, GIF87_SIGNATURE, GIF89_SIGNATURE, RIFF_SIGNATURE, WEBP_SIGNATURE, LocalRasterImage;
72077
+ var init_raster = __esm({
72078
+ "src/acp/content/raster.ts"() {
72079
+ "use strict";
72080
+ init_local_files();
72081
+ MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
72082
+ PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
72083
+ JPEG_SIGNATURE = Uint8Array.of(255, 216, 255);
72084
+ GIF87_SIGNATURE = new TextEncoder().encode("GIF87a");
72085
+ GIF89_SIGNATURE = new TextEncoder().encode("GIF89a");
72086
+ RIFF_SIGNATURE = new TextEncoder().encode("RIFF");
72087
+ WEBP_SIGNATURE = new TextEncoder().encode("WEBP");
72088
+ LocalRasterImage = class {
72089
+ mimeType;
72090
+ name;
72091
+ sourceUri;
72092
+ constructor(name2, mimeType, sourceUri) {
72093
+ this.mimeType = mimeType;
72094
+ this.name = name2;
72095
+ this.sourceUri = sourceUri;
72096
+ }
72097
+ base64 = async () => Buffer.from(await readFileBytes(this.sourceUri)).toString("base64");
72098
+ };
72099
+ }
72100
+ });
72101
+
72102
+ // src/acp/native-history/codex/history-images.ts
72103
+ function isRasterMime(value) {
72104
+ return value === "image/png" || value === "image/jpeg" || value === "image/gif" || value === "image/webp";
72105
+ }
72106
+ function parseNativeHistoryImage(uri) {
72107
+ const header = DATA_IMAGE_HEADER.exec(uri);
72108
+ if (header === null) {
72109
+ return null;
72110
+ }
72111
+ const mimeType = header[1] ?? "";
72112
+ const data = uri.slice(header[0].length);
72113
+ if (!isRasterMime(mimeType) || data.length < 4 || data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
72114
+ return null;
72115
+ }
72116
+ if (data.length % 4 !== 0 || !BASE_64.test(data)) {
72117
+ return null;
72118
+ }
72119
+ return { data, mimeType, name: "" };
72120
+ }
72121
+ async function embedLocalHistoryImages(history, signal) {
72122
+ if (history.status !== "available") {
72123
+ return history;
72124
+ }
72125
+ const messages = [];
72126
+ let imageCharacters = 0;
72127
+ for (const message of history.messages) {
72128
+ signal.throwIfAborted();
72129
+ const resolved = await resolveMessageImages(message, imageCharacters, signal);
72130
+ imageCharacters += (resolved.images ?? []).reduce((size, image) => size + image.data.length, 0);
72131
+ messages.push(resolved);
72132
+ }
72133
+ return {
72134
+ ...history,
72135
+ messages
72136
+ };
72137
+ }
72138
+ async function resolveMessageImages(message, usedCharacters, signal) {
72139
+ const images = [...message.images ?? []];
72140
+ let imageCharacters = images.reduce((size, image) => size + image.data.length, 0);
72141
+ const text2 = await replaceImageMarkers(message.text, async (uri) => {
72142
+ if (images.length >= 8 || usedCharacters + imageCharacters >= SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
72143
+ return "[Image unavailable]";
72144
+ }
72145
+ const embedded = parseNativeHistoryImage(uri);
72146
+ if (embedded !== null) {
72147
+ if (usedCharacters + imageCharacters + embedded.data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
72148
+ return "[Image unavailable]";
72149
+ }
72150
+ images.push({ ...embedded, name: `Image ${(images.length + 1).toString()}` });
72151
+ imageCharacters += embedded.data.length;
72152
+ return "";
72153
+ }
72154
+ const local = await readLocalRaster(uri, signal);
72155
+ if (local === null) {
72156
+ return "[Image unavailable]";
72157
+ }
72158
+ const data = await local.base64();
72159
+ if (usedCharacters + imageCharacters + data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
72160
+ return "[Image unavailable]";
72161
+ }
72162
+ images.push({
72163
+ data,
72164
+ mimeType: local.mimeType,
72165
+ name: local.name
72166
+ });
72167
+ imageCharacters += data.length;
72168
+ return "";
72169
+ });
72170
+ return {
72171
+ ...message,
72172
+ text: text2,
72173
+ ...images.length > 0 ? { images } : {}
72174
+ };
72175
+ }
72176
+ async function replaceImageMarkers(text2, replace) {
72177
+ const matches = [...text2.matchAll(IMAGE_MARKER)];
72178
+ if (matches.length === 0) {
72179
+ return text2;
72180
+ }
72181
+ let cursor = 0;
72182
+ let rewritten = "";
72183
+ for (const match of matches) {
72184
+ const index2 = match.index ?? 0;
72185
+ rewritten += text2.slice(cursor, index2);
72186
+ rewritten += await replace(match[1] ?? "");
72187
+ cursor = index2 + match[0].length;
72188
+ }
72189
+ return `${rewritten}${text2.slice(cursor)}`;
72190
+ }
72191
+ var IMAGE_MARKER, DATA_IMAGE_HEADER, BASE_64, SESSION_HISTORY_IMAGE_CHARACTER_LIMIT;
72192
+ var init_history_images = __esm({
72193
+ "src/acp/native-history/codex/history-images.ts"() {
72194
+ "use strict";
72195
+ init_raster();
72196
+ IMAGE_MARKER = /\[@image\]\(([^)\r\n]*)(?:\)|$)/g;
72197
+ DATA_IMAGE_HEADER = /^data:(image\/[a-z+]+);base64,/;
72198
+ BASE_64 = /^[A-Za-z0-9+/]*={0,2}$/;
72199
+ SESSION_HISTORY_IMAGE_CHARACTER_LIMIT = 4e6;
72200
+ }
72201
+ });
72202
+
71915
72203
  // src/acp/harness/codex/owned-agent.ts
71916
72204
  import { randomUUID as randomUUID5 } from "node:crypto";
71917
72205
  import { setTimeout as delay } from "node:timers/promises";
@@ -72574,6 +72862,126 @@ var init_owned_agent = __esm({
72574
72862
  }
72575
72863
  });
72576
72864
 
72865
+ // src/acp/harness/codex/history.ts
72866
+ import { createHash } from "node:crypto";
72867
+ async function replayCodexHistory(client2, threadId, emit, signal) {
72868
+ const deadline = AbortSignal.any([signal, AbortSignal.timeout(6e4)]);
72869
+ const seenCursors = /* @__PURE__ */ new Set();
72870
+ let cursor = null;
72871
+ let turnIndex = 0;
72872
+ for (; ; ) {
72873
+ deadline.throwIfAborted();
72874
+ const page = threadTurnsPageSchema.parse(
72875
+ await client2.request(
72876
+ "thread/turns/list",
72877
+ {
72878
+ threadId,
72879
+ limit: CODEX_HISTORY_TURN_PAGE_LIMIT,
72880
+ sortDirection: "asc",
72881
+ itemsView: "full",
72882
+ ...cursor === null ? {} : { cursor }
72883
+ },
72884
+ deadline
72885
+ )
72886
+ );
72887
+ for (const turn of page.data) {
72888
+ for (const rawItem of turn.items) {
72889
+ deadline.throwIfAborted();
72890
+ const item = decodeThreadItem(rawItem);
72891
+ if (item === null) {
72892
+ continue;
72893
+ }
72894
+ if (item.type === "userMessage") {
72895
+ const text2 = item.content.flatMap((content) => {
72896
+ if (typeof content !== "object" || content === null) {
72897
+ return [];
72898
+ }
72899
+ const type = Reflect.get(content, "type");
72900
+ const text3 = Reflect.get(content, "text");
72901
+ const url2 = Reflect.get(content, "url");
72902
+ if (type === "image" && typeof url2 === "string") {
72903
+ return [`[@image](${url2})`];
72904
+ }
72905
+ return type === "text" && typeof text3 === "string" ? [text3] : [];
72906
+ }).join("");
72907
+ const history = await embedLocalHistoryImages(
72908
+ { status: "available", truncated: false, messages: [{ role: "user", text: text2 }] },
72909
+ deadline
72910
+ );
72911
+ if (history.status !== "available") {
72912
+ continue;
72913
+ }
72914
+ const message = history.messages[0];
72915
+ for (const image of message?.images ?? []) {
72916
+ await emit({
72917
+ content: { type: "image", data: image.data, mimeType: image.mimeType },
72918
+ messageId: item.id,
72919
+ sessionUpdate: "user_message_chunk"
72920
+ });
72921
+ }
72922
+ const restoredText = message?.text ?? "";
72923
+ if (restoredText.length > 0) {
72924
+ await emit({
72925
+ content: { text: restoredText, type: "text" },
72926
+ messageId: item.id,
72927
+ sessionUpdate: "user_message_chunk"
72928
+ });
72929
+ }
72930
+ } else if (item.type === "agentMessage") {
72931
+ await emit(agentMessageUpdate(item.id, item.text));
72932
+ } else if (item.type === "reasoning") {
72933
+ const text2 = reasoningText(item);
72934
+ if (text2 !== null && text2.length > 0) {
72935
+ await emit({
72936
+ content: { text: text2, type: "text" },
72937
+ messageId: item.id,
72938
+ sessionUpdate: "agent_thought_chunk"
72939
+ });
72940
+ }
72941
+ } else if (item.type === "contextCompaction") {
72942
+ await emit({ compactionId: item.id, sessionUpdate: "compaction_update", status: "completed" });
72943
+ } else {
72944
+ const update = toolCallUpdate(item, "snapshot");
72945
+ if (update !== null) {
72946
+ await emit({ ...update, sessionUpdate: "tool_call" });
72947
+ }
72948
+ }
72949
+ }
72950
+ if (turn.error != null) {
72951
+ const identity2 = createHash("sha256").update(threadId).update("\0").update(turn.id ?? turnIndex.toString()).digest("hex");
72952
+ await emit({
72953
+ sessionUpdate: "tool_call",
72954
+ toolCallId: `agent-error-${identity2}`,
72955
+ title: "Agent error",
72956
+ kind: "other",
72957
+ status: "failed",
72958
+ rawOutput: { message: turn.error.message },
72959
+ content: [{ type: "content", content: { type: "text", text: turn.error.message } }]
72960
+ });
72961
+ }
72962
+ turnIndex += 1;
72963
+ }
72964
+ if (page.nextCursor == null) {
72965
+ return;
72966
+ }
72967
+ if (page.data.length === 0 || seenCursors.has(page.nextCursor)) {
72968
+ throw new AcpExecutionError("Codex repeated a history page cursor", {}, "invalid_native_session_response");
72969
+ }
72970
+ seenCursors.add(page.nextCursor);
72971
+ cursor = page.nextCursor;
72972
+ }
72973
+ }
72974
+ var init_history = __esm({
72975
+ "src/acp/harness/codex/history.ts"() {
72976
+ "use strict";
72977
+ init_acp_error();
72978
+ init_history_images();
72979
+ init_app_server_protocol();
72980
+ init_items();
72981
+ init_owned_agent();
72982
+ }
72983
+ });
72984
+
72577
72985
  // ../mobius-sdk/src/protocol/platform/mobius-api.ts
72578
72986
  function parseMobiusApiPrefix(value) {
72579
72987
  if (typeof value !== "string" || !API_PREFIX_PATTERN.test(value)) {
@@ -73856,7 +74264,7 @@ function decode3(schema, encoded) {
73856
74264
  throw new ProtocolMessageError("Invalid native session message", { cause });
73857
74265
  }
73858
74266
  }
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;
74267
+ 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
74268
  var init_native = __esm({
73861
74269
  "../mobius-sdk/src/protocol/session/native/index.ts"() {
73862
74270
  "use strict";
@@ -73871,8 +74279,6 @@ var init_native = __esm({
73871
74279
  NATIVE_SESSION_REQUEST_KIND = "native.session.request";
73872
74280
  NATIVE_SESSION_RESULT_KIND = "native.session.result";
73873
74281
  NATIVE_SESSION_CANCEL_KIND = "native.session.cancel";
73874
- SESSION_HISTORY_CHARACTER_LIMIT = 256e3;
73875
- SESSION_HISTORY_MESSAGE_LIMIT = 1e3;
73876
74282
  envelope = {
73877
74283
  requestId: identifierStringSchema,
73878
74284
  sessionId: identifierStringSchema
@@ -74362,6 +74768,7 @@ var init_event_log = __esm({
74362
74768
  nativeEventPageRequestSchema = external_exports.object({
74363
74769
  cursor: external_exports.string().min(1).max(512).nullable(),
74364
74770
  eventLimit: external_exports.number().int().min(1).max(1e4),
74771
+ // Legacy callers may still send this option; readers must ignore it.
74365
74772
  omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional()
74366
74773
  }).readonly();
74367
74774
  queuedPromptRequestEventLogSchema = external_exports.object({
@@ -74391,7 +74798,7 @@ function decode5(schema, encoded) {
74391
74798
  }
74392
74799
  }
74393
74800
  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({
74801
+ var init_history2 = __esm({
74395
74802
  "../mobius-sdk/src/protocol/session/observability/history.ts"() {
74396
74803
  "use strict";
74397
74804
  init_zod();
@@ -74406,6 +74813,7 @@ var init_history = __esm({
74406
74813
  pageRequestFields = {
74407
74814
  cursor: external_exports.string().min(1).max(512).nullable(),
74408
74815
  eventLimit: external_exports.number().int().min(1).max(1e4),
74816
+ // Decode old clients without rejecting their request; omission has no effect.
74409
74817
  omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional(),
74410
74818
  requestId: identifierStringSchema,
74411
74819
  sessionId: identifierStringSchema
@@ -74912,7 +75320,7 @@ var init_daemon_transport = __esm({
74912
75320
  init_lifecycle();
74913
75321
  init_native();
74914
75322
  init_event_log();
74915
- init_history();
75323
+ init_history2();
74916
75324
  init_commands();
74917
75325
  init_workspace();
74918
75326
  init_message_codec();
@@ -75178,7 +75586,7 @@ var init_protocol = __esm({
75178
75586
  init_lifecycle();
75179
75587
  init_native();
75180
75588
  init_event_log();
75181
- init_history();
75589
+ init_history2();
75182
75590
  init_commands();
75183
75591
  init_usage();
75184
75592
  init_turn_history();
@@ -75651,11 +76059,10 @@ var init_agent = __esm({
75651
76059
  "use strict";
75652
76060
  init_zod();
75653
76061
  init_executable();
75654
- init_acp_error();
75655
76062
  init_app_server_client();
75656
76063
  init_app_server_protocol();
75657
76064
  init_borrowed_agent();
75658
- init_items();
76065
+ init_history();
75659
76066
  init_owned_agent();
75660
76067
  init_settings3();
75661
76068
  APPROVAL_TIMEOUT_MILLISECONDS3 = 36e5;
@@ -75885,83 +76292,7 @@ var init_agent = __esm({
75885
76292
  // ACP load requires chronological replay. Resume only restores execution;
75886
76293
  // native pages supply history without a single full-transcript response.
75887
76294
  #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
- }
76295
+ await replayCodexHistory(this.#appServer, this.#nativeSessionId, this.#emit, signal);
75965
76296
  };
75966
76297
  /** Announces the manual compact command after every session entry point —
75967
76298
  * new, load, resume, and fork — so clients on restored sessions discover
@@ -76567,7 +76898,7 @@ var init_pi_commands = __esm({
76567
76898
 
76568
76899
  // src/acp/harness/pi/upstream/dist/acp/pi-sessions.js
76569
76900
  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";
76901
+ import { isAbsolute as isAbsolute10, join as join14, resolve as resolve9 } from "node:path";
76571
76902
  function getPiAgentDir(environment) {
76572
76903
  const configured = environment["PI_CODING_AGENT_DIR"];
76573
76904
  return configured ? resolve9(configured) : join14(environmentHome(environment), ".pi", "agent");
@@ -76587,7 +76918,7 @@ function readSessionDirFromSettings(agentDir) {
76587
76918
  if (typeof sessionDir !== "string" || !sessionDir.trim()) {
76588
76919
  return null;
76589
76920
  }
76590
- return isAbsolute9(sessionDir) ? sessionDir : resolve9(agentDir, sessionDir);
76921
+ return isAbsolute10(sessionDir) ? sessionDir : resolve9(agentDir, sessionDir);
76591
76922
  } catch {
76592
76923
  return null;
76593
76924
  }
@@ -77438,7 +77769,7 @@ var init_pi_tools = __esm({
77438
77769
  // src/acp/harness/pi/upstream/dist/acp/session.js
77439
77770
  import { randomUUID as randomUUID6 } from "node:crypto";
77440
77771
  import { readFileSync as readFileSync7 } from "node:fs";
77441
- import { isAbsolute as isAbsolute10, resolve as resolvePath } from "node:path";
77772
+ import { isAbsolute as isAbsolute11, resolve as resolvePath } from "node:path";
77442
77773
  import { RequestError as RequestError6 } from "@agentclientprotocol/sdk";
77443
77774
  function toUsageUpdate(stats) {
77444
77775
  const used = stats?.contextUsage?.tokens;
@@ -77534,7 +77865,7 @@ function toToolCallLocations(args, cwd, line) {
77534
77865
  if (!path8) {
77535
77866
  return void 0;
77536
77867
  }
77537
- const resolvedPath = isAbsolute10(path8) ? path8 : resolvePath(cwd, path8);
77868
+ const resolvedPath = isAbsolute11(path8) ? path8 : resolvePath(cwd, path8);
77538
77869
  return [{ path: resolvedPath, ...typeof line === "number" ? { line } : {} }];
77539
77870
  }
77540
77871
  function stringProp(source, key) {
@@ -78102,7 +78433,7 @@ var init_session = __esm({
78102
78433
  const p = getToolPath(args);
78103
78434
  if (p) {
78104
78435
  try {
78105
- const abs = isAbsolute10(p) ? p : resolvePath(this.cwd, p);
78436
+ const abs = isAbsolute11(p) ? p : resolvePath(this.cwd, p);
78106
78437
  snapshotOldText = readFileSync7(abs, "utf8");
78107
78438
  this.fileSnapshots.set(toolCallId, { path: p, oldText: snapshotOldText });
78108
78439
  if (toolName === "edit") {
@@ -78185,7 +78516,7 @@ var init_session = __esm({
78185
78516
  let hasStructuredDiff = false;
78186
78517
  if (!isError && snapshot) {
78187
78518
  try {
78188
- const abs = isAbsolute10(snapshot.path) ? snapshot.path : resolvePath(this.cwd, snapshot.path);
78519
+ const abs = isAbsolute11(snapshot.path) ? snapshot.path : resolvePath(this.cwd, snapshot.path);
78189
78520
  const newText = readFileSync7(abs, "utf8");
78190
78521
  if (snapshot.oldText === null || newText !== snapshot.oldText) {
78191
78522
  hasStructuredDiff = true;
@@ -78364,7 +78695,7 @@ var init_prompt = __esm({
78364
78695
  import { spawnSync } from "node:child_process";
78365
78696
  import { randomUUID as randomUUID7 } from "node:crypto";
78366
78697
  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";
78698
+ import { basename as basename5, dirname as dirname7, isAbsolute as isAbsolute12, join as join17 } from "node:path";
78368
78699
  import { RequestError as RequestError7 } from "@agentclientprotocol/sdk";
78369
78700
  function thinkingLevelName(id) {
78370
78701
  return id.split(/[_-]/u).map((part) => part.length === 0 ? part : `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
@@ -78703,7 +79034,7 @@ function buildStartupInfo(opts) {
78703
79034
  try {
78704
79035
  const prompts = readdirSync6(promptsDir).filter((f) => f.endsWith(".md"));
78705
79036
  for (const f of prompts) {
78706
- promptsItems.push(`/${basename4(f, ".md")}`);
79037
+ promptsItems.push(`/${basename5(f, ".md")}`);
78707
79038
  }
78708
79039
  } catch {
78709
79040
  }
@@ -78922,7 +79253,7 @@ var init_agent2 = __esm({
78922
79253
  };
78923
79254
  }
78924
79255
  async newSession(params) {
78925
- if (!isAbsolute11(params.cwd)) {
79256
+ if (!isAbsolute12(params.cwd)) {
78926
79257
  throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
78927
79258
  }
78928
79259
  this.lastSessionCwd = params.cwd;
@@ -79519,7 +79850,7 @@ ${JSON.stringify(stats, null, 2)}`;
79519
79850
  return { sessions, nextCursor, _meta: {} };
79520
79851
  }
79521
79852
  async forkSession(params) {
79522
- if (!isAbsolute11(params.cwd)) {
79853
+ if (!isAbsolute12(params.cwd)) {
79523
79854
  throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
79524
79855
  }
79525
79856
  const source = this.findStoredSession(params.sessionId);
@@ -79585,7 +79916,7 @@ ${JSON.stringify(stats, null, 2)}`;
79585
79916
  return { sessionId: session.sessionId, configOptions, modes };
79586
79917
  }
79587
79918
  async resumeSession(params) {
79588
- if (!isAbsolute11(params.cwd)) {
79919
+ if (!isAbsolute12(params.cwd)) {
79589
79920
  throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
79590
79921
  }
79591
79922
  this.sessions.close(params.sessionId);
@@ -79656,7 +79987,7 @@ ${JSON.stringify(stats, null, 2)}`;
79656
79987
  return response;
79657
79988
  }
79658
79989
  async loadSession(params) {
79659
- if (!isAbsolute11(params.cwd)) {
79990
+ if (!isAbsolute12(params.cwd)) {
79660
79991
  throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
79661
79992
  }
79662
79993
  this.sessions.close(params.sessionId);
@@ -80025,7 +80356,7 @@ var init_agent_probe_error = __esm({
80025
80356
  });
80026
80357
 
80027
80358
  // src/agent/specification/vendors/pi-agent.ts
80028
- import { createHash } from "node:crypto";
80359
+ import { createHash as createHash2 } from "node:crypto";
80029
80360
  import { join as join19 } from "node:path";
80030
80361
  import {
80031
80362
  methods as methods6
@@ -80046,7 +80377,7 @@ var init_pi_agent = __esm({
80046
80377
  // The Pi ACP fork inlines embedded prompt resources into the turn message, so Mobius
80047
80378
  // keeps the adapter's opt-in capability flag enabled for every launch it owns.
80048
80379
  createLaunchEnvironment = async (_agent, context) => {
80049
- const workspaceHash = createHash("sha256").update(context.defaultWorkspace).digest("hex").slice(0, 24);
80380
+ const workspaceHash = createHash2("sha256").update(context.defaultWorkspace).digest("hex").slice(0, 24);
80050
80381
  const sessionDirectory = join19(
80051
80382
  readStateDirectory(context.environment),
80052
80383
  "agents",
@@ -80253,7 +80584,7 @@ var init_agent_discovery = __esm({
80253
80584
 
80254
80585
  // src/util/process/local-executable.ts
80255
80586
  import { realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
80256
- import { realpath as realpath6, stat as stat5 } from "node:fs/promises";
80587
+ import { realpath as realpath7, stat as stat6 } from "node:fs/promises";
80257
80588
  function readExecutableIdentity(path8) {
80258
80589
  const resolvedPath = realpathSync4(path8);
80259
80590
  const metadata = statSync4(resolvedPath);
@@ -80267,9 +80598,9 @@ function readExecutableIdentity(path8) {
80267
80598
  );
80268
80599
  }
80269
80600
  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()) {
80601
+ const resolvedEntry = await realpath7(entry);
80602
+ const resolvedExecutable = await realpath7(executable);
80603
+ if (!(await stat6(resolvedEntry)).isFile() || !(await stat6(resolvedExecutable)).isFile()) {
80273
80604
  return null;
80274
80605
  }
80275
80606
  return { entry: resolvedEntry, executable: resolvedExecutable };
@@ -80787,11 +81118,11 @@ var init_agent_version = __esm({
80787
81118
  });
80788
81119
 
80789
81120
  // src/agent/discovery/executable-discovery.ts
80790
- import { isAbsolute as isAbsolute12 } from "node:path";
81121
+ import { isAbsolute as isAbsolute13 } from "node:path";
80791
81122
  async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, context) {
80792
81123
  const override = context.environment[overrideVariable];
80793
81124
  if (override !== void 0) {
80794
- if (override.length === 0 || !isAbsolute12(override)) {
81125
+ if (override.length === 0 || !isAbsolute13(override)) {
80795
81126
  return [];
80796
81127
  }
80797
81128
  const executable = await resolveExecutablePath(override, context.platform);
@@ -81366,8 +81697,26 @@ var init_adapter_registry = __esm({
81366
81697
  });
81367
81698
 
81368
81699
  // src/session/history/session-event-history-projection.ts
81700
+ function boundReasoning(payload) {
81701
+ if (payload.content.type !== "text" || Buffer.byteLength(payload.content.text, "utf8") <= MAXIMUM_PROJECTED_REASONING_BYTES) {
81702
+ return payload;
81703
+ }
81704
+ const bytes = Buffer.from(payload.content.text, "utf8");
81705
+ let start = bytes.length - MAXIMUM_PROJECTED_REASONING_BYTES;
81706
+ while (start < bytes.length && (bytes.readUInt8(start) & 192) === 128) {
81707
+ start += 1;
81708
+ }
81709
+ return {
81710
+ ...payload,
81711
+ content: { ...payload.content, text: bytes.toString("utf8", start) },
81712
+ meta: { ...payload.meta, truncated: true }
81713
+ };
81714
+ }
81369
81715
  function projectNewEvent(liveEvent2, eventId) {
81370
81716
  const { position: _position, eventId: _liveEventId, ...event } = liveEvent2;
81717
+ if (event.type === "acp" && event.payload.sessionUpdate === "agent_thought_chunk") {
81718
+ return { ...event, eventId, payload: boundReasoning(event.payload) };
81719
+ }
81371
81720
  return { ...event, eventId };
81372
81721
  }
81373
81722
  function replaceAcpPayload(event, payload) {
@@ -81418,18 +81767,19 @@ function mergeTextChunk(previous, incoming) {
81418
81767
  }
81419
81768
  const content = { text: `${previous.content.text}${incoming.content.text}`, type: "text" };
81420
81769
  if (previous.sessionUpdate === "agent_thought_chunk" && incoming.sessionUpdate === "agent_thought_chunk") {
81421
- return {
81770
+ return boundReasoning({
81422
81771
  ...previous,
81423
81772
  content,
81424
81773
  ...previous.meta?.truncated === true || incoming.meta?.truncated === true ? { meta: { ...previous.meta, ...incoming.meta, truncated: true } } : {}
81425
- };
81774
+ });
81426
81775
  }
81427
81776
  return { ...previous, content };
81428
81777
  }
81429
- var SessionEventHistoryProjection;
81778
+ var MAXIMUM_PROJECTED_REASONING_BYTES, SessionEventHistoryProjection;
81430
81779
  var init_session_event_history_projection = __esm({
81431
81780
  "src/session/history/session-event-history-projection.ts"() {
81432
81781
  "use strict";
81782
+ MAXIMUM_PROJECTED_REASONING_BYTES = 24 * 1024;
81433
81783
  SessionEventHistoryProjection = class {
81434
81784
  #toolCallEventIds = /* @__PURE__ */ new Map();
81435
81785
  #latestEvent = null;
@@ -82979,7 +83329,24 @@ var init_session_config_protocol = __esm({
82979
83329
 
82980
83330
  // src/acp/adapter/session-events.ts
82981
83331
  import { setImmediate as yieldToRuntime2 } from "node:timers/promises";
82982
- var AdapterSessionConnection, AcpSessionConnector;
83332
+ function* reasoningWireUpdates(update) {
83333
+ if (update.sessionUpdate !== "agent_thought_chunk" || update.content.type !== "text" || update.content.text.length <= MAXIMUM_REASONING_UPDATE_CHARACTERS) {
83334
+ yield update;
83335
+ return;
83336
+ }
83337
+ const text2 = update.content.text;
83338
+ for (let start = 0; start < text2.length; ) {
83339
+ let end = Math.min(start + MAXIMUM_REASONING_UPDATE_CHARACTERS, text2.length);
83340
+ const last = text2.charCodeAt(end - 1);
83341
+ const next = text2.charCodeAt(end);
83342
+ if (last >= 55296 && last <= 56319 && next >= 56320 && next <= 57343) {
83343
+ end -= 1;
83344
+ }
83345
+ yield { ...update, content: { ...update.content, text: text2.slice(start, end) } };
83346
+ start = end;
83347
+ }
83348
+ }
83349
+ var MAXIMUM_REASONING_UPDATE_CHARACTERS, AdapterSessionConnection, AcpSessionConnector;
82983
83350
  var init_session_events = __esm({
82984
83351
  "src/acp/adapter/session-events.ts"() {
82985
83352
  "use strict";
@@ -82989,12 +83356,13 @@ var init_session_events = __esm({
82989
83356
  init_agent_connection();
82990
83357
  init_agent_update_stream();
82991
83358
  init_session_config_protocol();
83359
+ MAXIMUM_REASONING_UPDATE_CHARACTERS = 1e6;
82992
83360
  AdapterSessionConnection = class {
82993
83361
  #connection;
82994
83362
  #updates;
82995
83363
  #lifetime = new AbortController();
82996
83364
  events;
82997
- constructor(options, externalizer) {
83365
+ constructor(options, externalizer, normalizeEvent) {
82998
83366
  const protocol = sessionConfigProtocolForAgent(options.agent.id);
82999
83367
  this.#updates = new AgentUpdateStream(async (notification) => {
83000
83368
  this.#lifetime.signal.throwIfAborted();
@@ -83002,58 +83370,60 @@ var init_session_events = __esm({
83002
83370
  throw new AcpExecutionError("ACP agent referenced an unknown session", {}, "invalid_agent_session");
83003
83371
  }
83004
83372
  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) });
83373
+ for (const incoming of reasoningWireUpdates(notification.update)) {
83374
+ const externalized = await externalizer.update(options.sessionId(), incoming, signal);
83375
+ signal.throwIfAborted();
83376
+ const update = externalized.agent;
83377
+ const payload = decodeAcpSessionUpdate(JSON.stringify(normalizeEvent(externalized.event)));
83378
+ let event;
83379
+ switch (update.sessionUpdate) {
83380
+ case "available_commands_update":
83381
+ event = {
83382
+ kind: "commands",
83383
+ payload,
83384
+ commands: update.availableCommands.slice(0, 500).map((command) => ({
83385
+ description: truncate2(command.description, 500),
83386
+ inputHint: truncate2(command.input?.hint ?? "", 255),
83387
+ name: truncate2(command.name, 128)
83388
+ })).filter((command) => command.name.length > 0)
83389
+ };
83390
+ break;
83391
+ case "config_option_update":
83392
+ event = {
83393
+ kind: "configuration",
83394
+ payload,
83395
+ configOptions: protocol.normalizeUpdate(options.configOptions(), update.configOptions)
83396
+ };
83397
+ break;
83398
+ case "current_mode_update":
83399
+ event = { kind: "mode", payload, modeId: update.currentModeId };
83400
+ break;
83401
+ case "session_info_update": {
83402
+ const changes = [];
83403
+ if (Object.hasOwn(update, "title")) {
83404
+ changes.push({ kind: "title", value: truncate2(update.title ?? "", 500) });
83405
+ }
83406
+ if (Object.hasOwn(update, "updatedAt")) {
83407
+ changes.push({ kind: "updated-at", value: truncate2(update.updatedAt ?? "", 128) });
83408
+ }
83409
+ event = { kind: "info", payload, changes };
83410
+ break;
83039
83411
  }
83040
- event = { kind: "info", payload, changes };
83041
- break;
83412
+ case "user_message_chunk":
83413
+ case "agent_message_chunk":
83414
+ case "agent_thought_chunk":
83415
+ case "tool_call":
83416
+ case "tool_call_update":
83417
+ case "plan":
83418
+ case "plan_update":
83419
+ case "plan_removed":
83420
+ event = { kind: "content", payload };
83421
+ break;
83422
+ default:
83423
+ event = { kind: "other", payload };
83042
83424
  }
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 };
83425
+ await options.onEvent(event);
83055
83426
  }
83056
- await options.onEvent(event);
83057
83427
  });
83058
83428
  this.events = this.#updates;
83059
83429
  const client2 = {
@@ -83100,10 +83470,12 @@ var init_session_events = __esm({
83100
83470
  };
83101
83471
  AcpSessionConnector = class {
83102
83472
  #externalizer;
83103
- constructor(externalizer) {
83473
+ #normalizeEvent;
83474
+ constructor(externalizer, normalizeEvent = (event) => event) {
83104
83475
  this.#externalizer = externalizer;
83476
+ this.#normalizeEvent = normalizeEvent;
83105
83477
  }
83106
- connectSession = (options) => new AdapterSessionConnection(options, this.#externalizer);
83478
+ connectSession = (options) => new AdapterSessionConnection(options, this.#externalizer, this.#normalizeEvent);
83107
83479
  connectQuerySession = (options) => {
83108
83480
  const rejectInteraction = async () => {
83109
83481
  throw new AcpExecutionError(
@@ -83121,7 +83493,8 @@ var init_session_events = __esm({
83121
83493
  onElicitationComplete: rejectInteraction
83122
83494
  }
83123
83495
  },
83124
- this.#externalizer
83496
+ this.#externalizer,
83497
+ this.#normalizeEvent
83125
83498
  );
83126
83499
  };
83127
83500
  };
@@ -83151,1075 +83524,6 @@ var init_adapter = __esm({
83151
83524
  }
83152
83525
  });
83153
83526
 
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
83527
  // src/generated/acp-session-store-migrations.ts
84224
83528
  var acpSessionStoreMigrations;
84225
83529
  var init_acp_session_store_migrations = __esm({
@@ -90035,23 +89339,108 @@ var init_preview_event_cache = __esm({
90035
89339
  }
90036
89340
  });
90037
89341
 
89342
+ // src/acp/adapter/codex/tool-event.ts
89343
+ function payloadText(value) {
89344
+ let text2;
89345
+ try {
89346
+ text2 = JSON.stringify(value) ?? "";
89347
+ } catch {
89348
+ text2 = "Tool payload could not be represented as JSON.";
89349
+ }
89350
+ return text2.slice(0, TRUNCATED_TOOL_PAYLOAD_CHARACTER_LIMIT);
89351
+ }
89352
+ function fitNesting(value, depth = 0) {
89353
+ if (typeof value !== "object" || value === null) {
89354
+ return value;
89355
+ }
89356
+ if (depth === MAX_TOOL_PAYLOAD_DEPTH && Object.keys(value).length > 0) {
89357
+ return `[truncated: nesting depth] ${payloadText(value)}`;
89358
+ }
89359
+ if (Array.isArray(value)) {
89360
+ return value.map((child) => fitNesting(child, depth + 1));
89361
+ }
89362
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, fitNesting(child, depth + 1)]));
89363
+ }
89364
+ function prepareCodexToolUpdate(update) {
89365
+ if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
89366
+ return update;
89367
+ }
89368
+ return {
89369
+ ...update,
89370
+ ...update.rawOutput === void 0 ? {} : { rawOutput: fitNesting(update.rawOutput) },
89371
+ ...update._meta == null ? {} : {
89372
+ _meta: Object.fromEntries(
89373
+ Object.entries(update._meta).map(([key, child]) => [key, fitNesting(child, 1)])
89374
+ )
89375
+ }
89376
+ };
89377
+ }
89378
+ function fitPayload(value) {
89379
+ if (value === void 0 || boundedJsonSchema.safeParse(value).success) {
89380
+ return value;
89381
+ }
89382
+ return { truncated: true, text: payloadText(value) };
89383
+ }
89384
+ function fitCodexToolEvent(event) {
89385
+ const decoded = toolEventSchema.safeParse(event);
89386
+ if (!decoded.success) {
89387
+ return event;
89388
+ }
89389
+ return {
89390
+ ...decoded.data,
89391
+ rawInput: fitPayload(decoded.data.rawInput),
89392
+ rawOutput: fitPayload(decoded.data.rawOutput)
89393
+ };
89394
+ }
89395
+ var toolEventSchema, TRUNCATED_TOOL_PAYLOAD_CHARACTER_LIMIT, MAX_TOOL_PAYLOAD_DEPTH;
89396
+ var init_tool_event = __esm({
89397
+ "src/acp/adapter/codex/tool-event.ts"() {
89398
+ "use strict";
89399
+ init_protocol();
89400
+ init_zod();
89401
+ toolEventSchema = external_exports.looseObject({
89402
+ sessionUpdate: external_exports.enum(["tool_call", "tool_call_update"]),
89403
+ rawInput: external_exports.unknown().optional(),
89404
+ rawOutput: external_exports.unknown().optional()
89405
+ });
89406
+ TRUNCATED_TOOL_PAYLOAD_CHARACTER_LIMIT = 32768;
89407
+ MAX_TOOL_PAYLOAD_DEPTH = 16;
89408
+ }
89409
+ });
89410
+
90038
89411
  // src/acp/adapter/codex/adapter.ts
89412
+ import { createHash as createHash4 } from "node:crypto";
90039
89413
  var CodexAdapter;
90040
89414
  var init_adapter2 = __esm({
90041
89415
  "src/acp/adapter/codex/adapter.ts"() {
90042
89416
  "use strict";
89417
+ init_protocol();
89418
+ init_executable();
90043
89419
  init_acp_error();
90044
- init_codex_history();
90045
- init_native_history_events();
89420
+ init_app_server_client();
89421
+ init_history();
89422
+ init_native_session();
90046
89423
  init_preview_event_cache();
90047
89424
  init_query_processes();
90048
89425
  init_session_events();
89426
+ init_tool_event();
90049
89427
  CodexAdapter = class {
90050
89428
  #queryProcesses;
90051
89429
  #connector;
89430
+ #dependencies;
89431
+ #contentExternalizer;
90052
89432
  #previewCache = null;
90053
89433
  constructor(dependencies) {
90054
- this.#connector = new AcpSessionConnector(dependencies.contentExternalizer);
89434
+ this.#dependencies = dependencies;
89435
+ this.#contentExternalizer = {
89436
+ update: async (sessionId, update, signal) => {
89437
+ signal.throwIfAborted();
89438
+ const prepared = prepareCodexToolUpdate(update);
89439
+ signal.throwIfAborted();
89440
+ return await dependencies.contentExternalizer.update(sessionId, prepared, signal);
89441
+ }
89442
+ };
89443
+ this.#connector = new AcpSessionConnector(this.#contentExternalizer, fitCodexToolEvent);
90055
89444
  this.#queryProcesses = new AgentQueryProcesses(dependencies.processes, this.#connector);
90056
89445
  }
90057
89446
  capabilities = async (query) => await this.#queryProcesses.capabilities(query);
@@ -90065,21 +89454,73 @@ var init_adapter2 = __esm({
90065
89454
  }
90066
89455
  };
90067
89456
  previewSessionEvents = async (query, request) => {
90068
- const { agent, cwd, signal } = query;
89457
+ const { agent, cwd } = query;
89458
+ const signal = AbortSignal.any([query.signal, AbortSignal.timeout(6e4)]);
90069
89459
  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);
89460
+ signal.throwIfAborted();
89461
+ nativeSessionIdSchema.parse(request.nativeSessionId);
89462
+ if (agent.id !== "codex") {
89463
+ throw new AcpExecutionError(
89464
+ "The Codex adapter cannot preview history for another agent.",
89465
+ {},
89466
+ "agent_adapter_mismatch"
89467
+ );
90074
89468
  }
90075
- return nativeHistoryEvents(
90076
- sessionId,
90077
- request.nativeSessionId,
90078
- snapshot.history,
90079
- request.eventLimit,
90080
- request.cursor,
90081
- this.#previewCache.events
89469
+ if (!await revalidateExecutable(agent.agentIdentity)) {
89470
+ throw new AcpExecutionError(
89471
+ "The local Codex executable changed. Restart Mobius to discover it again.",
89472
+ {},
89473
+ "agent_executable_changed"
89474
+ );
89475
+ }
89476
+ this.#previewCache ??= openPreviewEventCache();
89477
+ const events = [];
89478
+ await this.#dependencies.processes.runTransient(
89479
+ signal,
89480
+ async () => {
89481
+ const client2 = new CodexAppServerClient({
89482
+ command: agent.command,
89483
+ cwd,
89484
+ environment: agent.environment,
89485
+ handlers: {
89486
+ onNotification: async () => void 0,
89487
+ onServerRequest: async () => {
89488
+ throw new AcpExecutionError(
89489
+ "Unexpected request while reading saved history",
89490
+ {},
89491
+ "invalid_native_session_response"
89492
+ );
89493
+ }
89494
+ }
89495
+ });
89496
+ return {
89497
+ client: client2,
89498
+ closeProcess: async () => {
89499
+ client2.detach();
89500
+ await stopProcessTree(client2.child());
89501
+ }
89502
+ };
89503
+ },
89504
+ async ({ client: client2 }) => {
89505
+ await client2.initialize(signal);
89506
+ return await replayCodexHistory(
89507
+ client2,
89508
+ request.nativeSessionId,
89509
+ async (update) => {
89510
+ const externalized = await this.#contentExternalizer.update(sessionId, update, signal);
89511
+ events.push({
89512
+ type: "acp",
89513
+ payload: decodeAcpSessionUpdate(JSON.stringify(fitCodexToolEvent(externalized.event)))
89514
+ });
89515
+ },
89516
+ signal
89517
+ );
89518
+ },
89519
+ async (runtime) => await runtime.closeProcess()
90082
89520
  );
89521
+ const generationId = createHash4("sha256").update(request.nativeSessionId).update("\0").update(JSON.stringify(events)).digest("hex");
89522
+ this.#previewCache.events.materialize(sessionId, generationId, events);
89523
+ return this.#previewCache.events.page(sessionId, request.eventLimit, request.cursor);
90083
89524
  };
90084
89525
  };
90085
89526
  }
@@ -90137,17 +89578,6 @@ var init_registry = __esm({
90137
89578
  });
90138
89579
 
90139
89580
  // 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
89581
  function decodeBase64(data) {
90152
89582
  if (data.length > MAXIMUM_ENCODED_CONTENT_CHARACTERS || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)) {
90153
89583
  throw new Error("The ACP embedded content is not valid bounded base64");
@@ -90161,14 +89591,13 @@ function decodeBase64(data) {
90161
89591
  function isRecord6(value) {
90162
89592
  return typeof value === "object" && value !== null && !Array.isArray(value);
90163
89593
  }
90164
- var MAXIMUM_ENCODED_CONTENT_CHARACTERS, MAXIMUM_REASONING_CHUNK_BYTES, embeddedImageSchema, inlineImageUrlSchema, toolImageSchema, AcpContentExternalizer;
89594
+ var MAXIMUM_ENCODED_CONTENT_CHARACTERS, embeddedImageSchema, inlineImageUrlSchema, toolImageSchema, AcpContentExternalizer;
90165
89595
  var init_content_externalizer = __esm({
90166
89596
  "src/acp/content/content-externalizer.ts"() {
90167
89597
  "use strict";
90168
89598
  init_zod();
90169
89599
  init_raster();
90170
89600
  MAXIMUM_ENCODED_CONTENT_CHARACTERS = 4e6;
90171
- MAXIMUM_REASONING_CHUNK_BYTES = 24 * 1024;
90172
89601
  embeddedImageSchema = external_exports.looseObject({
90173
89602
  type: external_exports.literal("image"),
90174
89603
  data: external_exports.string(),
@@ -90351,24 +89780,7 @@ var init_content_externalizer = __esm({
90351
89780
  }
90352
89781
  update = async (sessionId, update, signal) => {
90353
89782
  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
- }
89783
+ case "agent_thought_chunk":
90372
89784
  case "user_message_chunk":
90373
89785
  case "agent_message_chunk":
90374
89786
  case "compaction_summary_chunk": {
@@ -90565,7 +89977,7 @@ var init_node_error = __esm({
90565
89977
  });
90566
89978
 
90567
89979
  // src/storage/installation/installation-files.ts
90568
- import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
89980
+ import { createHash as createHash5, randomUUID as randomUUID9 } from "node:crypto";
90569
89981
  import { mkdir as mkdir4, open as open5, readdir as readdir5, rename as rename3, unlink as unlink3, writeFile } from "node:fs/promises";
90570
89982
  import { dirname as dirname9, join as join23 } from "node:path";
90571
89983
  function applicationDirectory(root, applicationId) {
@@ -90584,7 +89996,7 @@ function connectionFilePath(connectionDirectory2, connectionId2) {
90584
89996
  return join23(connectionDirectory2, `${connectionId2}.json`);
90585
89997
  }
90586
89998
  function channelIndexFilePath(installationDirectory2, channelId) {
90587
- return join23(installationDirectory2, "channels", `mci_${createHash4("sha256").update(channelId).digest("hex")}.json`);
89999
+ return join23(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
90588
90000
  }
90589
90001
  async function readInstallationFile(path8) {
90590
90002
  let handle;
@@ -91276,10 +90688,10 @@ var init_control_token = __esm({
91276
90688
  });
91277
90689
 
91278
90690
  // src/daemon/control/local-client.ts
91279
- import { createHash as createHash5 } from "node:crypto";
90691
+ import { createHash as createHash6 } from "node:crypto";
91280
90692
  import { createConnection } from "node:net";
91281
90693
  function controlSocketPath(stateDirectory, endpoint = "manager") {
91282
- const installationHash = createHash5("sha256").update(endpoint === "manager" ? stateDirectory : `${stateDirectory}:worker`).digest("hex").slice(0, 32);
90694
+ const installationHash = createHash6("sha256").update(endpoint === "manager" ? stateDirectory : `${stateDirectory}:worker`).digest("hex").slice(0, 32);
91283
90695
  return managerPlatform.controlSocketPath(installationHash);
91284
90696
  }
91285
90697
  async function readSocketMessage(socket, signal) {
@@ -92360,7 +91772,7 @@ var init_worker_lifecycle_log = __esm({
92360
91772
  });
92361
91773
 
92362
91774
  // src/daemon/lifecycle/worker-process.ts
92363
- import { spawn as spawn9 } from "node:child_process";
91775
+ import { spawn as spawn8 } from "node:child_process";
92364
91776
  import { isAbsolute as isAbsolute14 } from "node:path";
92365
91777
  async function decodeWorkerLaunch(value) {
92366
91778
  const { entry, executable, version: version2 } = workerLaunch.parse(value);
@@ -92409,7 +91821,7 @@ var init_worker_process = __esm({
92409
91821
  constructor(launch, signal, environment) {
92410
91822
  signal.throwIfAborted();
92411
91823
  this.launch = launch;
92412
- this.#child = spawn9(launch.executable, [launch.entry, "__worker"], {
91824
+ this.#child = spawn8(launch.executable, [launch.entry, "__worker"], {
92413
91825
  env: environment,
92414
91826
  windowsHide: true,
92415
91827
  stdio: ["ignore", "pipe", "pipe", "ipc"]
@@ -92927,9 +92339,9 @@ var init_package2 = __esm({
92927
92339
  });
92928
92340
 
92929
92341
  // src/daemon/lifecycle/manager-client.ts
92930
- import { spawn as spawn10 } from "node:child_process";
92342
+ import { spawn as spawn9 } from "node:child_process";
92931
92343
  async function spawnManager(launch) {
92932
- const child = spawn10(launch.executable, [launch.entry, "__manager"], {
92344
+ const child = spawn9(launch.executable, [launch.entry, "__manager"], {
92933
92345
  detached: true,
92934
92346
  windowsHide: true,
92935
92347
  env: process.env,
@@ -96780,7 +96192,7 @@ var init_prompt_lifecycle = __esm({
96780
96192
  });
96781
96193
 
96782
96194
  // src/session/turn/execution-receipts.ts
96783
- import { createHash as createHash6, randomUUID as randomUUID13 } from "node:crypto";
96195
+ import { createHash as createHash7, randomUUID as randomUUID13 } from "node:crypto";
96784
96196
  function isTerminal(state) {
96785
96197
  return state === "succeeded" || state === "failed" || state === "cancelled";
96786
96198
  }
@@ -96902,7 +96314,7 @@ var init_execution_receipts = __esm({
96902
96314
  ];
96903
96315
  });
96904
96316
  claimExecution = (commandId, sessionId, commandJson) => {
96905
- const commandHash = createHash6("sha256").update(commandJson).digest("hex");
96317
+ const commandHash = createHash7("sha256").update(commandJson).digest("hex");
96906
96318
  let existing = this.#executions.get(commandId);
96907
96319
  const previous = this.outcome(commandId);
96908
96320
  if (existing?.sessionId === sessionId && !existing.started && previous?.type === "lifecycle-metadata" && previous.payload.kind === "prompt.failed-before-start" && previous.payload.code === "runtime_restarted") {
@@ -97284,9 +96696,9 @@ var init_session_turns = __esm({
97284
96696
  #bySessionId = /* @__PURE__ */ new Map();
97285
96697
  #operations;
97286
96698
  #activity;
97287
- constructor(operations, activity2 = new RuntimeTurnActivity()) {
96699
+ constructor(operations, activity = new RuntimeTurnActivity()) {
97288
96700
  this.#operations = operations;
97289
- this.#activity = activity2;
96701
+ this.#activity = activity;
97290
96702
  }
97291
96703
  acceptsPrompts = () => this.#activity.acceptsPrompts();
97292
96704
  session = (sessionId) => {
@@ -97728,7 +97140,7 @@ var init_scratch_directory = __esm({
97728
97140
  });
97729
97141
 
97730
97142
  // src/session/content/external-content-store.ts
97731
- import { createHash as createHash7 } from "node:crypto";
97143
+ import { createHash as createHash8 } from "node:crypto";
97732
97144
  import { join as join34 } from "node:path";
97733
97145
  var contentRequest, CONTENT_LIFETIME_MILLISECONDS, metadataSchema, LocalExternalContentStore;
97734
97146
  var init_external_content_store = __esm({
@@ -97785,7 +97197,7 @@ var init_external_content_store = __esm({
97785
97197
  const active = AbortSignal.any([signal, this.#lifetime.signal]);
97786
97198
  active.throwIfAborted();
97787
97199
  const metadata = metadataSchema.parse({ kind, mediaType, name: name2 });
97788
- const key = createHash7("sha256").update(bytes).digest("hex");
97200
+ const key = createHash8("sha256").update(bytes).digest("hex");
97789
97201
  const request = `mobius-content:${kind}:${key}`;
97790
97202
  const existing = this.#entries.get(request);
97791
97203
  if (existing !== void 0 && existing.expiresAt > Date.now()) {
@@ -98703,7 +98115,7 @@ var init_agent_settings_adapter = __esm({
98703
98115
  });
98704
98116
 
98705
98117
  // src/session/settings/discover-agent-settings.ts
98706
- import { createHash as createHash8 } from "node:crypto";
98118
+ import { createHash as createHash9 } from "node:crypto";
98707
98119
  function agentSettingsFailureDetails(agentId, failure2) {
98708
98120
  const details = { agentId, code: operationErrorCode(failure2) };
98709
98121
  return failure2 instanceof AcpConfigurationValueUnavailableError ? {
@@ -98968,7 +98380,7 @@ function settingsRevision(agent, reportedAgentVersion, settings, modelEffort) {
98968
98380
  unsupportedModelIds: modelEffort.unsupportedModelIds,
98969
98381
  valuesByModel: {}
98970
98382
  };
98971
- return createHash8("sha256").update(
98383
+ return createHash9("sha256").update(
98972
98384
  JSON.stringify({
98973
98385
  adapterVersion: agent.kind === "acp-adapter-process" ? agent.adapterVersion : agent.agentVersion,
98974
98386
  agentId: agent.id,
@@ -99327,35 +98739,7 @@ var init_resolve_session_directories = __esm({
99327
98739
  });
99328
98740
 
99329
98741
  // 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) {
98742
+ async function loadHistoryPage(sessionId, eventLimit, initialCursor, queuedPromptRequests, load) {
99359
98743
  let cursor = initialCursor;
99360
98744
  let loaded = [];
99361
98745
  let sessionGenerationId = null;
@@ -99382,9 +98766,7 @@ async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoni
99382
98766
  });
99383
98767
  loaded = [...events, ...loaded];
99384
98768
  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) {
98769
+ if (loaded.length >= eventLimit) {
99388
98770
  break;
99389
98771
  }
99390
98772
  cursor = sourceNextCursor;
@@ -99392,8 +98774,7 @@ async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoni
99392
98774
  if (sessionGenerationId === null || throughPosition === null) {
99393
98775
  throw new SessionError("session_history_unavailable", "The Session history is unavailable");
99394
98776
  }
99395
- const visible = omitReasoning ? omitAgentReasoning(loaded) : loaded;
99396
- const orderedEvents = visible.slice(-eventLimit);
98777
+ const orderedEvents = loaded.slice(-eventLimit);
99397
98778
  const nextCursor = orderedEvents[0]?.cursor ?? null;
99398
98779
  return {
99399
98780
  events: {
@@ -99435,7 +98816,6 @@ async function executeSessionHistoryPageLoad(socket, command, config2, resolveAg
99435
98816
  command.sessionId,
99436
98817
  command.eventLimit,
99437
98818
  command.cursor,
99438
- command.omit?.includes("agent-reasoning") === true,
99439
98819
  recovery.queuedPromptRequests,
99440
98820
  async (eventLimit, cursor) => await sessions.loadSessionEvents(loadOptions, eventLimit, cursor)
99441
98821
  );
@@ -99482,7 +98862,6 @@ async function executeSessionPreviewHistoryPageLoad(socket, command, config2, re
99482
98862
  command.sessionId,
99483
98863
  command.eventLimit,
99484
98864
  command.cursor,
99485
- command.omit?.includes("agent-reasoning") === true,
99486
98865
  [],
99487
98866
  async (eventLimit, cursor) => await sessions.previewNativeSessionEvents(loadOptions, command.sessionId, eventLimit, cursor)
99488
98867
  );
@@ -99510,7 +98889,7 @@ async function executeSessionPreviewHistoryPageLoad(socket, command, config2, re
99510
98889
  }
99511
98890
  }
99512
98891
  var sessionHistoryPageLoadCommand, previewHistoryPageLoadCommand;
99513
- var init_history2 = __esm({
98892
+ var init_history3 = __esm({
99514
98893
  "src/runtime/command/registry/history.ts"() {
99515
98894
  "use strict";
99516
98895
  init_protocol();
@@ -100277,7 +99656,7 @@ var init_execute_prompt = __esm({
100277
99656
  });
100278
99657
 
100279
99658
  // src/runtime/relay/artifact-download.ts
100280
- import { createHash as createHash9 } from "node:crypto";
99659
+ import { createHash as createHash10 } from "node:crypto";
100281
99660
  import { fetch as fetch4 } from "undici";
100282
99661
  function downloadUrl(config2, artifact) {
100283
99662
  const url2 = relayHttpEndpoint(config2.relayUrl);
@@ -100364,7 +99743,7 @@ async function downloadPromptArtifact(config2, artifact, signal) {
100364
99743
  );
100365
99744
  }
100366
99745
  const bytes = await responseBytes(response, artifact.byteLength, requestSignal);
100367
- if (createHash9("sha256").update(bytes).digest("hex") !== artifact.sha256) {
99746
+ if (createHash10("sha256").update(bytes).digest("hex") !== artifact.sha256) {
100368
99747
  throw new PromptArtifactError(
100369
99748
  "artifact_integrity_failed",
100370
99749
  "The prompt artifact failed integrity validation"
@@ -100924,7 +100303,7 @@ var init_registry2 = __esm({
100924
100303
  init_agent_catalog();
100925
100304
  init_agent_settings();
100926
100305
  init_file_read();
100927
- init_history2();
100306
+ init_history3();
100928
100307
  init_interactions2();
100929
100308
  init_native_sessions();
100930
100309
  init_prompt2();
@@ -101963,11 +101342,11 @@ async function reportDaemonUpgradeAvailability(send2, signal) {
101963
101342
  send2({ ...base, kind: "runtime.upgrade.result", outcome: { status: "succeeded" } });
101964
101343
  }
101965
101344
  }
101966
- async function runDaemonReleaseUpgrades(signal, activity2) {
101345
+ async function runDaemonReleaseUpgrades(signal, activity) {
101967
101346
  try {
101968
101347
  for await (const _tick of setInterval2(36e5, void 0, { signal })) {
101969
101348
  try {
101970
- await checkDaemonReleaseUpgrade(signal, activity2);
101349
+ await checkDaemonReleaseUpgrade(signal, activity);
101971
101350
  } catch (cause) {
101972
101351
  signal.throwIfAborted();
101973
101352
  console.error("Daemon npm upgrade check failed", cause);
@@ -102029,7 +101408,7 @@ async function awaitDaemonReleaseSwitch(stateDirectory, id, signal) {
102029
101408
  }
102030
101409
  return outcome;
102031
101410
  }
102032
- async function checkDaemonReleaseUpgrade(signal, activity2) {
101411
+ async function checkDaemonReleaseUpgrade(signal, activity) {
102033
101412
  var _stack = [];
102034
101413
  try {
102035
101414
  const control = await openMobiusControlInstallation(signal, process.env);
@@ -102042,17 +101421,17 @@ async function checkDaemonReleaseUpgrade(signal, activity2) {
102042
101421
  return;
102043
101422
  }
102044
101423
  const launch = await installDaemonReleaseVersion(version2, signal);
102045
- if (activity2.count() > 0) {
101424
+ if (activity.count() > 0) {
102046
101425
  new RuntimeDiagnosticLog(control.stateDirectory).record(
102047
101426
  `Mobius daemon diagnostic ${JSON.stringify({
102048
101427
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
102049
101428
  event: "daemon_upgrade_deferred",
102050
101429
  version: version2,
102051
- activeTurns: activity2.count()
101430
+ activeTurns: activity.count()
102052
101431
  })}`
102053
101432
  );
102054
101433
  }
102055
- const _reservation = __using(_stack, await activity2.reserveWhenIdle(signal));
101434
+ const _reservation = __using(_stack, await activity.reserveWhenIdle(signal));
102056
101435
  signal.throwIfAborted();
102057
101436
  await requestInstalledDaemonReleaseSwitch(control.stateDirectory, launch, signal);
102058
101437
  await new Promise((resolve19) => {