@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.
- package/dist/acp/adapter/codex/adapter.d.ts.map +1 -1
- package/dist/acp/adapter/codex/adapter.js +66 -9
- package/dist/acp/adapter/codex/adapter.js.map +1 -1
- package/dist/acp/adapter/codex/tool-event.d.ts +6 -0
- package/dist/acp/adapter/codex/tool-event.d.ts.map +1 -0
- package/dist/acp/adapter/codex/tool-event.js +66 -0
- package/dist/acp/adapter/codex/tool-event.js.map +1 -0
- package/dist/acp/adapter/session-events.d.ts +2 -2
- package/dist/acp/adapter/session-events.d.ts.map +1 -1
- package/dist/acp/adapter/session-events.js +81 -56
- package/dist/acp/adapter/session-events.js.map +1 -1
- package/dist/acp/content/content-externalizer.d.ts.map +1 -1
- package/dist/acp/content/content-externalizer.js +1 -31
- package/dist/acp/content/content-externalizer.js.map +1 -1
- package/dist/acp/harness/codex/agent.d.ts.map +1 -1
- package/dist/acp/harness/codex/agent.js +4 -75
- package/dist/acp/harness/codex/agent.js.map +1 -1
- package/dist/acp/harness/codex/app-server-protocol.d.ts +9 -0
- package/dist/acp/harness/codex/app-server-protocol.d.ts.map +1 -1
- package/dist/acp/harness/codex/app-server-protocol.js +1 -0
- package/dist/acp/harness/codex/app-server-protocol.js.map +1 -1
- package/dist/acp/harness/codex/history.d.ts +5 -0
- package/dist/acp/harness/codex/history.d.ts.map +1 -0
- package/dist/acp/harness/codex/history.js +116 -0
- package/dist/acp/harness/codex/history.js.map +1 -0
- package/dist/cli.js +728 -1349
- package/dist/cli.js.map +4 -4
- package/dist/runtime/command/registry/history.d.ts.map +1 -1
- package/dist/runtime/command/registry/history.js +5 -36
- package/dist/runtime/command/registry/history.js.map +1 -1
- package/dist/runtime.js +666 -1289
- package/dist/runtime.js.map +4 -4
- package/dist/session/history/session-event-history-projection.d.ts.map +1 -1
- package/dist/session/history/session-event-history-projection.js +23 -2
- package/dist/session/history/session-event-history-projection.js.map +1 -1
- package/dist/util/filesystem/private-path.js +4 -2
- package/dist/util/filesystem/private-path.js.map +2 -2
- package/dist/util/platform/windows.d.ts.map +1 -1
- package/dist/util/platform/windows.js +6 -2
- package/dist/util/platform/windows.js.map +1 -1
- package/dist/util/process/executable.js +4 -2
- package/dist/util/process/executable.js.map +2 -2
- package/package.json +2 -2
- package/dist/acp/native-history/codex/codex-history.d.ts +0 -17
- package/dist/acp/native-history/codex/codex-history.d.ts.map +0 -1
- package/dist/acp/native-history/codex/codex-history.js +0 -661
- package/dist/acp/native-history/codex/codex-history.js.map +0 -1
- package/dist/acp/native-history/codex/native-history-events.d.ts +0 -8
- package/dist/acp/native-history/codex/native-history-events.d.ts.map +0 -1
- package/dist/acp/native-history/codex/native-history-events.js +0 -92
- package/dist/acp/native-history/codex/native-history-events.js.map +0 -1
package/dist/runtime.js
CHANGED
|
@@ -499,6 +499,7 @@ function terminateProcess2(child, signal) {
|
|
|
499
499
|
}
|
|
500
500
|
var windowsPermissions = `
|
|
501
501
|
$ErrorActionPreference = 'Stop'
|
|
502
|
+
$ProgressPreference = 'SilentlyContinue'
|
|
502
503
|
Import-Module (Join-Path $PSHOME 'Modules/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1')
|
|
503
504
|
$item = Get-Item -LiteralPath $env:MOBIUS_PERMISSION_PATH -Force
|
|
504
505
|
if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw 'Unsafe path' }
|
|
@@ -520,6 +521,7 @@ if ($env:MOBIUS_PERMISSION_PRIVATE -eq '1') {
|
|
|
520
521
|
Set-Acl -LiteralPath $item.FullName -AclObject $private
|
|
521
522
|
}
|
|
522
523
|
`;
|
|
524
|
+
var windowsPermissionsTimeoutMs = 3e4;
|
|
523
525
|
async function validatePathPermissions(path7, _directory, privateAccess, signal) {
|
|
524
526
|
signal.throwIfAborted();
|
|
525
527
|
const systemRoot = environmentValue(process.env, "SystemRoot");
|
|
@@ -543,8 +545,8 @@ async function validatePathPermissions(path7, _directory, privateAccess, signal)
|
|
|
543
545
|
MOBIUS_PERMISSION_PRIVATE: privateAccess ? "1" : "0"
|
|
544
546
|
},
|
|
545
547
|
windowsHide: true,
|
|
546
|
-
signal: AbortSignal.any([signal, AbortSignal.timeout(
|
|
547
|
-
timeout:
|
|
548
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(windowsPermissionsTimeoutMs)]),
|
|
549
|
+
timeout: windowsPermissionsTimeoutMs,
|
|
548
550
|
maxBuffer: 16384
|
|
549
551
|
}
|
|
550
552
|
);
|
|
@@ -21783,8 +21785,6 @@ function encodeSessionPromptDispositionCommand(message) {
|
|
|
21783
21785
|
var NATIVE_SESSION_REQUEST_KIND = "native.session.request";
|
|
21784
21786
|
var NATIVE_SESSION_RESULT_KIND = "native.session.result";
|
|
21785
21787
|
var NATIVE_SESSION_CANCEL_KIND = "native.session.cancel";
|
|
21786
|
-
var SESSION_HISTORY_CHARACTER_LIMIT = 256e3;
|
|
21787
|
-
var SESSION_HISTORY_MESSAGE_LIMIT = 1e3;
|
|
21788
21788
|
var envelope = {
|
|
21789
21789
|
requestId: identifierStringSchema,
|
|
21790
21790
|
sessionId: identifierStringSchema
|
|
@@ -22247,6 +22247,7 @@ var sessionEventOmissionSchema = external_exports.literal("agent-reasoning");
|
|
|
22247
22247
|
var nativeEventPageRequestSchema = external_exports.object({
|
|
22248
22248
|
cursor: external_exports.string().min(1).max(512).nullable(),
|
|
22249
22249
|
eventLimit: external_exports.number().int().min(1).max(1e4),
|
|
22250
|
+
// Legacy callers may still send this option; readers must ignore it.
|
|
22250
22251
|
omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional()
|
|
22251
22252
|
}).readonly();
|
|
22252
22253
|
var queuedPromptRequestEventLogSchema = external_exports.object({
|
|
@@ -22294,6 +22295,7 @@ var SESSION_PREVIEW_HISTORY_PAGE_LOADED_KIND = "session.preview-history.page.loa
|
|
|
22294
22295
|
var pageRequestFields = {
|
|
22295
22296
|
cursor: external_exports.string().min(1).max(512).nullable(),
|
|
22296
22297
|
eventLimit: external_exports.number().int().min(1).max(1e4),
|
|
22298
|
+
// Decode old clients without rejecting their request; omission has no effect.
|
|
22297
22299
|
omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional(),
|
|
22298
22300
|
requestId: identifierStringSchema,
|
|
22299
22301
|
sessionId: identifierStringSchema
|
|
@@ -22691,7 +22693,7 @@ import { fetch as fetch3 } from "undici";
|
|
|
22691
22693
|
// package.json
|
|
22692
22694
|
var package_default = {
|
|
22693
22695
|
name: "@moxt-ai/mobius",
|
|
22694
|
-
version: "0.0.
|
|
22696
|
+
version: "0.0.309",
|
|
22695
22697
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
22696
22698
|
type: "module",
|
|
22697
22699
|
bin: {
|
|
@@ -62173,11 +62175,11 @@ var SessionModeManager = class {
|
|
|
62173
62175
|
}
|
|
62174
62176
|
return modes;
|
|
62175
62177
|
}
|
|
62176
|
-
async trySyncMode(query, mode,
|
|
62178
|
+
async trySyncMode(query, mode, errorMessage) {
|
|
62177
62179
|
try {
|
|
62178
62180
|
await query.setPermissionMode(mode);
|
|
62179
62181
|
} catch (error62) {
|
|
62180
|
-
this.options.logError(
|
|
62182
|
+
this.options.logError(errorMessage, error62);
|
|
62181
62183
|
}
|
|
62182
62184
|
}
|
|
62183
62185
|
};
|
|
@@ -66838,6 +66840,9 @@ import {
|
|
|
66838
66840
|
PROTOCOL_VERSION
|
|
66839
66841
|
} from "@agentclientprotocol/sdk";
|
|
66840
66842
|
|
|
66843
|
+
// src/acp/harness/codex/app-server-client.ts
|
|
66844
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
66845
|
+
|
|
66841
66846
|
// src/infra/operation-error.ts
|
|
66842
66847
|
var OperationError = class extends Error {
|
|
66843
66848
|
code;
|
|
@@ -66875,9 +66880,6 @@ var AcpConfigurationValueUnavailableError = class extends AcpExecutionError {
|
|
|
66875
66880
|
}
|
|
66876
66881
|
};
|
|
66877
66882
|
|
|
66878
|
-
// src/acp/harness/codex/app-server-client.ts
|
|
66879
|
-
import { spawn as spawn4 } from "node:child_process";
|
|
66880
|
-
|
|
66881
66883
|
// src/acp/agent/in-process-endpoint.ts
|
|
66882
66884
|
function acpEndpointTerminationError(termination) {
|
|
66883
66885
|
switch (termination.kind) {
|
|
@@ -67129,6 +67131,7 @@ var threadStartResponseSchema = external_exports.object({
|
|
|
67129
67131
|
var threadTurnSchema = external_exports.object({
|
|
67130
67132
|
id: boundedText(256).optional(),
|
|
67131
67133
|
status: turnStatusSchema.optional(),
|
|
67134
|
+
error: external_exports.object({ message: external_exports.string().transform((message) => message.slice(0, 4096)) }).nullish(),
|
|
67132
67135
|
items: external_exports.array(external_exports.unknown()).max(1e5)
|
|
67133
67136
|
});
|
|
67134
67137
|
var threadTurnsSchema = external_exports.array(threadTurnSchema).max(1e5);
|
|
@@ -67596,12 +67599,12 @@ function presentToolItem(item) {
|
|
|
67596
67599
|
};
|
|
67597
67600
|
}
|
|
67598
67601
|
if (item.type === "collabAgentToolCall") {
|
|
67599
|
-
const
|
|
67602
|
+
const spawn8 = item.tool === "spawnAgent";
|
|
67600
67603
|
return {
|
|
67601
67604
|
content: [],
|
|
67602
67605
|
kind: "other",
|
|
67603
67606
|
locations: [],
|
|
67604
|
-
rawInput:
|
|
67607
|
+
rawInput: spawn8 ? {
|
|
67605
67608
|
model: item.model,
|
|
67606
67609
|
prompt: item.prompt,
|
|
67607
67610
|
reasoningEffort: item.reasoningEffort,
|
|
@@ -67609,10 +67612,10 @@ function presentToolItem(item) {
|
|
|
67609
67612
|
} : { receiverThreadIds: item.receiverThreadIds, senderThreadId: item.senderThreadId },
|
|
67610
67613
|
rawOutput: {
|
|
67611
67614
|
agentsStates: item.agentsStates,
|
|
67612
|
-
...
|
|
67615
|
+
...spawn8 ? { receiverThreadIds: item.receiverThreadIds } : {}
|
|
67613
67616
|
},
|
|
67614
67617
|
status: collaborationStatus(item.status),
|
|
67615
|
-
title:
|
|
67618
|
+
title: spawn8 ? "Dispatch subagent" : "Wait for subagent"
|
|
67616
67619
|
};
|
|
67617
67620
|
}
|
|
67618
67621
|
if (item.type === "subAgentActivity" && item.kind === "started") {
|
|
@@ -67922,6 +67925,277 @@ var CodexBorrowedAcpAgent = class {
|
|
|
67922
67925
|
};
|
|
67923
67926
|
};
|
|
67924
67927
|
|
|
67928
|
+
// src/acp/harness/codex/history.ts
|
|
67929
|
+
import { createHash } from "node:crypto";
|
|
67930
|
+
|
|
67931
|
+
// src/acp/content/raster.ts
|
|
67932
|
+
import { basename as basename4, isAbsolute as isAbsolute9, normalize } from "node:path";
|
|
67933
|
+
import { fileURLToPath } from "node:url";
|
|
67934
|
+
|
|
67935
|
+
// src/storage/files/local-files.ts
|
|
67936
|
+
import { createReadStream as createReadStream2 } from "node:fs";
|
|
67937
|
+
import { mkdir as mkdir3, open as open4, readdir as readdir4, readFile as readFile5, realpath as realpath6, stat as stat5 } from "node:fs/promises";
|
|
67938
|
+
function entryKind(entry) {
|
|
67939
|
+
if (entry.isDirectory()) {
|
|
67940
|
+
return "directory";
|
|
67941
|
+
}
|
|
67942
|
+
if (entry.isFile()) {
|
|
67943
|
+
return "file";
|
|
67944
|
+
}
|
|
67945
|
+
if (entry.isSymbolicLink()) {
|
|
67946
|
+
return "symbolic-link";
|
|
67947
|
+
}
|
|
67948
|
+
if (entry.isBlockDevice() || entry.isCharacterDevice()) {
|
|
67949
|
+
return "device";
|
|
67950
|
+
}
|
|
67951
|
+
if (entry.isFIFO()) {
|
|
67952
|
+
return "fifo";
|
|
67953
|
+
}
|
|
67954
|
+
return entry.isSocket() ? "socket" : "unknown";
|
|
67955
|
+
}
|
|
67956
|
+
async function canonicalPath(path7) {
|
|
67957
|
+
return await realpath6(path7);
|
|
67958
|
+
}
|
|
67959
|
+
async function readPathMetadata(path7) {
|
|
67960
|
+
const metadata = await stat5(path7);
|
|
67961
|
+
return {
|
|
67962
|
+
kind: metadata.isDirectory() ? "directory" : metadata.isFile() ? "file" : "other",
|
|
67963
|
+
modifiedAt: metadata.mtime,
|
|
67964
|
+
modifiedMilliseconds: metadata.mtimeMs,
|
|
67965
|
+
size: metadata.size
|
|
67966
|
+
};
|
|
67967
|
+
}
|
|
67968
|
+
async function listDirectory(path7) {
|
|
67969
|
+
const entries = await readdir4(path7, { withFileTypes: true });
|
|
67970
|
+
return entries.map((entry) => ({ kind: entryKind(entry), name: entry.name }));
|
|
67971
|
+
}
|
|
67972
|
+
async function ensurePrivateDirectory(path7) {
|
|
67973
|
+
await mkdir3(path7, { mode: 448, recursive: true });
|
|
67974
|
+
}
|
|
67975
|
+
async function ensureCanonicalDirectory(path7) {
|
|
67976
|
+
await ensurePrivateDirectory(path7);
|
|
67977
|
+
const resolved = await realpath6(path7);
|
|
67978
|
+
return (await stat5(resolved)).isDirectory() ? resolved : null;
|
|
67979
|
+
}
|
|
67980
|
+
async function readFileStart(path7, byteLength) {
|
|
67981
|
+
const bytes = new Uint8Array(byteLength);
|
|
67982
|
+
const handle = await open4(path7, "r");
|
|
67983
|
+
try {
|
|
67984
|
+
await handle.read(bytes, 0, byteLength, 0);
|
|
67985
|
+
} finally {
|
|
67986
|
+
await handle.close();
|
|
67987
|
+
}
|
|
67988
|
+
return bytes;
|
|
67989
|
+
}
|
|
67990
|
+
async function readFileBytes(path7) {
|
|
67991
|
+
return await readFile5(path7);
|
|
67992
|
+
}
|
|
67993
|
+
function readFileChunks(path7, chunkBytes, signal) {
|
|
67994
|
+
return createReadStream2(path7, { highWaterMark: chunkBytes, signal });
|
|
67995
|
+
}
|
|
67996
|
+
|
|
67997
|
+
// src/acp/content/raster.ts
|
|
67998
|
+
var MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
|
|
67999
|
+
var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
|
|
68000
|
+
var JPEG_SIGNATURE = Uint8Array.of(255, 216, 255);
|
|
68001
|
+
var GIF87_SIGNATURE = new TextEncoder().encode("GIF87a");
|
|
68002
|
+
var GIF89_SIGNATURE = new TextEncoder().encode("GIF89a");
|
|
68003
|
+
var RIFF_SIGNATURE = new TextEncoder().encode("RIFF");
|
|
68004
|
+
var WEBP_SIGNATURE = new TextEncoder().encode("WEBP");
|
|
68005
|
+
var LocalRasterImage = class {
|
|
68006
|
+
mimeType;
|
|
68007
|
+
name;
|
|
68008
|
+
sourceUri;
|
|
68009
|
+
constructor(name2, mimeType, sourceUri) {
|
|
68010
|
+
this.mimeType = mimeType;
|
|
68011
|
+
this.name = name2;
|
|
68012
|
+
this.sourceUri = sourceUri;
|
|
68013
|
+
}
|
|
68014
|
+
base64 = async () => Buffer.from(await readFileBytes(this.sourceUri)).toString("base64");
|
|
68015
|
+
};
|
|
68016
|
+
function startsWith(bytes, signature, offset = 0) {
|
|
68017
|
+
if (bytes.byteLength < offset + signature.byteLength) {
|
|
68018
|
+
return false;
|
|
68019
|
+
}
|
|
68020
|
+
return signature.every((value, index2) => bytes[offset + index2] === value);
|
|
68021
|
+
}
|
|
68022
|
+
function sniffRasterMime(bytes) {
|
|
68023
|
+
if (startsWith(bytes, PNG_SIGNATURE)) {
|
|
68024
|
+
return "image/png";
|
|
68025
|
+
}
|
|
68026
|
+
if (startsWith(bytes, JPEG_SIGNATURE)) {
|
|
68027
|
+
return "image/jpeg";
|
|
68028
|
+
}
|
|
68029
|
+
if (startsWith(bytes, GIF87_SIGNATURE) || startsWith(bytes, GIF89_SIGNATURE)) {
|
|
68030
|
+
return "image/gif";
|
|
68031
|
+
}
|
|
68032
|
+
if (startsWith(bytes, RIFF_SIGNATURE) && startsWith(bytes, WEBP_SIGNATURE, 8)) {
|
|
68033
|
+
return "image/webp";
|
|
68034
|
+
}
|
|
68035
|
+
return null;
|
|
68036
|
+
}
|
|
68037
|
+
async function resolveCanonicalPath(requested, signal) {
|
|
68038
|
+
signal.throwIfAborted();
|
|
68039
|
+
if (!isAbsolute9(requested) || requested.includes("\0") || normalize(requested) !== requested) {
|
|
68040
|
+
return null;
|
|
68041
|
+
}
|
|
68042
|
+
try {
|
|
68043
|
+
const target = await canonicalPath(requested);
|
|
68044
|
+
signal.throwIfAborted();
|
|
68045
|
+
if (!isAbsolute9(target) || normalize(target) !== target) {
|
|
68046
|
+
return null;
|
|
68047
|
+
}
|
|
68048
|
+
return target;
|
|
68049
|
+
} catch (cause) {
|
|
68050
|
+
signal.throwIfAborted();
|
|
68051
|
+
if (cause instanceof Error && cause.name === "AbortError") {
|
|
68052
|
+
throw cause;
|
|
68053
|
+
}
|
|
68054
|
+
return null;
|
|
68055
|
+
}
|
|
68056
|
+
}
|
|
68057
|
+
function parseLocalImageUri(uri) {
|
|
68058
|
+
const trimmed = uri.trim();
|
|
68059
|
+
if (trimmed.length === 0 || trimmed.length > 2048 || trimmed.includes("\0")) {
|
|
68060
|
+
return null;
|
|
68061
|
+
}
|
|
68062
|
+
if (trimmed.startsWith("data:")) {
|
|
68063
|
+
return null;
|
|
68064
|
+
}
|
|
68065
|
+
if (trimmed.startsWith("file:")) {
|
|
68066
|
+
try {
|
|
68067
|
+
const url2 = new URL(trimmed);
|
|
68068
|
+
if (url2.protocol !== "file:" || url2.host.length > 0) {
|
|
68069
|
+
return null;
|
|
68070
|
+
}
|
|
68071
|
+
return fileURLToPath(url2);
|
|
68072
|
+
} catch {
|
|
68073
|
+
return null;
|
|
68074
|
+
}
|
|
68075
|
+
}
|
|
68076
|
+
if (!isAbsolute9(trimmed) && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
|
|
68077
|
+
return null;
|
|
68078
|
+
}
|
|
68079
|
+
return trimmed;
|
|
68080
|
+
}
|
|
68081
|
+
async function readLocalRaster(uri, signal) {
|
|
68082
|
+
signal.throwIfAborted();
|
|
68083
|
+
const requested = parseLocalImageUri(uri);
|
|
68084
|
+
if (requested === null) {
|
|
68085
|
+
return null;
|
|
68086
|
+
}
|
|
68087
|
+
const target = await resolveCanonicalPath(requested, signal);
|
|
68088
|
+
if (target === null) {
|
|
68089
|
+
return null;
|
|
68090
|
+
}
|
|
68091
|
+
const targetMetadata = await readPathMetadata(target);
|
|
68092
|
+
signal.throwIfAborted();
|
|
68093
|
+
if (targetMetadata.kind !== "file" || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
|
|
68094
|
+
return null;
|
|
68095
|
+
}
|
|
68096
|
+
const header = await readFileStart(target, 12);
|
|
68097
|
+
signal.throwIfAborted();
|
|
68098
|
+
const mimeType = sniffRasterMime(header);
|
|
68099
|
+
if (mimeType === null) {
|
|
68100
|
+
return null;
|
|
68101
|
+
}
|
|
68102
|
+
return new LocalRasterImage(basename4(target) || "Image", mimeType, target);
|
|
68103
|
+
}
|
|
68104
|
+
|
|
68105
|
+
// src/acp/native-history/codex/history-images.ts
|
|
68106
|
+
var IMAGE_MARKER = /\[@image\]\(([^)\r\n]*)(?:\)|$)/g;
|
|
68107
|
+
var DATA_IMAGE_HEADER = /^data:(image\/[a-z+]+);base64,/;
|
|
68108
|
+
var BASE_64 = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
68109
|
+
var SESSION_HISTORY_IMAGE_CHARACTER_LIMIT = 4e6;
|
|
68110
|
+
function isRasterMime(value) {
|
|
68111
|
+
return value === "image/png" || value === "image/jpeg" || value === "image/gif" || value === "image/webp";
|
|
68112
|
+
}
|
|
68113
|
+
function parseNativeHistoryImage(uri) {
|
|
68114
|
+
const header = DATA_IMAGE_HEADER.exec(uri);
|
|
68115
|
+
if (header === null) {
|
|
68116
|
+
return null;
|
|
68117
|
+
}
|
|
68118
|
+
const mimeType = header[1] ?? "";
|
|
68119
|
+
const data = uri.slice(header[0].length);
|
|
68120
|
+
if (!isRasterMime(mimeType) || data.length < 4 || data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
68121
|
+
return null;
|
|
68122
|
+
}
|
|
68123
|
+
if (data.length % 4 !== 0 || !BASE_64.test(data)) {
|
|
68124
|
+
return null;
|
|
68125
|
+
}
|
|
68126
|
+
return { data, mimeType, name: "" };
|
|
68127
|
+
}
|
|
68128
|
+
async function embedLocalHistoryImages(history, signal) {
|
|
68129
|
+
if (history.status !== "available") {
|
|
68130
|
+
return history;
|
|
68131
|
+
}
|
|
68132
|
+
const messages = [];
|
|
68133
|
+
let imageCharacters = 0;
|
|
68134
|
+
for (const message of history.messages) {
|
|
68135
|
+
signal.throwIfAborted();
|
|
68136
|
+
const resolved = await resolveMessageImages(message, imageCharacters, signal);
|
|
68137
|
+
imageCharacters += (resolved.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
68138
|
+
messages.push(resolved);
|
|
68139
|
+
}
|
|
68140
|
+
return {
|
|
68141
|
+
...history,
|
|
68142
|
+
messages
|
|
68143
|
+
};
|
|
68144
|
+
}
|
|
68145
|
+
async function resolveMessageImages(message, usedCharacters, signal) {
|
|
68146
|
+
const images = [...message.images ?? []];
|
|
68147
|
+
let imageCharacters = images.reduce((size, image) => size + image.data.length, 0);
|
|
68148
|
+
const text2 = await replaceImageMarkers(message.text, async (uri) => {
|
|
68149
|
+
if (images.length >= 8 || usedCharacters + imageCharacters >= SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
68150
|
+
return "[Image unavailable]";
|
|
68151
|
+
}
|
|
68152
|
+
const embedded = parseNativeHistoryImage(uri);
|
|
68153
|
+
if (embedded !== null) {
|
|
68154
|
+
if (usedCharacters + imageCharacters + embedded.data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
68155
|
+
return "[Image unavailable]";
|
|
68156
|
+
}
|
|
68157
|
+
images.push({ ...embedded, name: `Image ${(images.length + 1).toString()}` });
|
|
68158
|
+
imageCharacters += embedded.data.length;
|
|
68159
|
+
return "";
|
|
68160
|
+
}
|
|
68161
|
+
const local = await readLocalRaster(uri, signal);
|
|
68162
|
+
if (local === null) {
|
|
68163
|
+
return "[Image unavailable]";
|
|
68164
|
+
}
|
|
68165
|
+
const data = await local.base64();
|
|
68166
|
+
if (usedCharacters + imageCharacters + data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
68167
|
+
return "[Image unavailable]";
|
|
68168
|
+
}
|
|
68169
|
+
images.push({
|
|
68170
|
+
data,
|
|
68171
|
+
mimeType: local.mimeType,
|
|
68172
|
+
name: local.name
|
|
68173
|
+
});
|
|
68174
|
+
imageCharacters += data.length;
|
|
68175
|
+
return "";
|
|
68176
|
+
});
|
|
68177
|
+
return {
|
|
68178
|
+
...message,
|
|
68179
|
+
text: text2,
|
|
68180
|
+
...images.length > 0 ? { images } : {}
|
|
68181
|
+
};
|
|
68182
|
+
}
|
|
68183
|
+
async function replaceImageMarkers(text2, replace) {
|
|
68184
|
+
const matches = [...text2.matchAll(IMAGE_MARKER)];
|
|
68185
|
+
if (matches.length === 0) {
|
|
68186
|
+
return text2;
|
|
68187
|
+
}
|
|
68188
|
+
let cursor = 0;
|
|
68189
|
+
let rewritten = "";
|
|
68190
|
+
for (const match of matches) {
|
|
68191
|
+
const index2 = match.index ?? 0;
|
|
68192
|
+
rewritten += text2.slice(cursor, index2);
|
|
68193
|
+
rewritten += await replace(match[1] ?? "");
|
|
68194
|
+
cursor = index2 + match[0].length;
|
|
68195
|
+
}
|
|
68196
|
+
return `${rewritten}${text2.slice(cursor)}`;
|
|
68197
|
+
}
|
|
68198
|
+
|
|
67925
68199
|
// src/acp/harness/codex/owned-agent.ts
|
|
67926
68200
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
67927
68201
|
import { setTimeout as delay } from "node:timers/promises";
|
|
@@ -68574,6 +68848,115 @@ var CodexOwnedAcpAgent = class {
|
|
|
68574
68848
|
};
|
|
68575
68849
|
};
|
|
68576
68850
|
|
|
68851
|
+
// src/acp/harness/codex/history.ts
|
|
68852
|
+
async function replayCodexHistory(client2, threadId, emit, signal) {
|
|
68853
|
+
const deadline = AbortSignal.any([signal, AbortSignal.timeout(6e4)]);
|
|
68854
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
68855
|
+
let cursor = null;
|
|
68856
|
+
let turnIndex = 0;
|
|
68857
|
+
for (; ; ) {
|
|
68858
|
+
deadline.throwIfAborted();
|
|
68859
|
+
const page = threadTurnsPageSchema.parse(
|
|
68860
|
+
await client2.request(
|
|
68861
|
+
"thread/turns/list",
|
|
68862
|
+
{
|
|
68863
|
+
threadId,
|
|
68864
|
+
limit: CODEX_HISTORY_TURN_PAGE_LIMIT,
|
|
68865
|
+
sortDirection: "asc",
|
|
68866
|
+
itemsView: "full",
|
|
68867
|
+
...cursor === null ? {} : { cursor }
|
|
68868
|
+
},
|
|
68869
|
+
deadline
|
|
68870
|
+
)
|
|
68871
|
+
);
|
|
68872
|
+
for (const turn of page.data) {
|
|
68873
|
+
for (const rawItem of turn.items) {
|
|
68874
|
+
deadline.throwIfAborted();
|
|
68875
|
+
const item = decodeThreadItem(rawItem);
|
|
68876
|
+
if (item === null) {
|
|
68877
|
+
continue;
|
|
68878
|
+
}
|
|
68879
|
+
if (item.type === "userMessage") {
|
|
68880
|
+
const text2 = item.content.flatMap((content) => {
|
|
68881
|
+
if (typeof content !== "object" || content === null) {
|
|
68882
|
+
return [];
|
|
68883
|
+
}
|
|
68884
|
+
const type = Reflect.get(content, "type");
|
|
68885
|
+
const text3 = Reflect.get(content, "text");
|
|
68886
|
+
const url2 = Reflect.get(content, "url");
|
|
68887
|
+
if (type === "image" && typeof url2 === "string") {
|
|
68888
|
+
return [`[@image](${url2})`];
|
|
68889
|
+
}
|
|
68890
|
+
return type === "text" && typeof text3 === "string" ? [text3] : [];
|
|
68891
|
+
}).join("");
|
|
68892
|
+
const history = await embedLocalHistoryImages(
|
|
68893
|
+
{ status: "available", truncated: false, messages: [{ role: "user", text: text2 }] },
|
|
68894
|
+
deadline
|
|
68895
|
+
);
|
|
68896
|
+
if (history.status !== "available") {
|
|
68897
|
+
continue;
|
|
68898
|
+
}
|
|
68899
|
+
const message = history.messages[0];
|
|
68900
|
+
for (const image of message?.images ?? []) {
|
|
68901
|
+
await emit({
|
|
68902
|
+
content: { type: "image", data: image.data, mimeType: image.mimeType },
|
|
68903
|
+
messageId: item.id,
|
|
68904
|
+
sessionUpdate: "user_message_chunk"
|
|
68905
|
+
});
|
|
68906
|
+
}
|
|
68907
|
+
const restoredText = message?.text ?? "";
|
|
68908
|
+
if (restoredText.length > 0) {
|
|
68909
|
+
await emit({
|
|
68910
|
+
content: { text: restoredText, type: "text" },
|
|
68911
|
+
messageId: item.id,
|
|
68912
|
+
sessionUpdate: "user_message_chunk"
|
|
68913
|
+
});
|
|
68914
|
+
}
|
|
68915
|
+
} else if (item.type === "agentMessage") {
|
|
68916
|
+
await emit(agentMessageUpdate(item.id, item.text));
|
|
68917
|
+
} else if (item.type === "reasoning") {
|
|
68918
|
+
const text2 = reasoningText(item);
|
|
68919
|
+
if (text2 !== null && text2.length > 0) {
|
|
68920
|
+
await emit({
|
|
68921
|
+
content: { text: text2, type: "text" },
|
|
68922
|
+
messageId: item.id,
|
|
68923
|
+
sessionUpdate: "agent_thought_chunk"
|
|
68924
|
+
});
|
|
68925
|
+
}
|
|
68926
|
+
} else if (item.type === "contextCompaction") {
|
|
68927
|
+
await emit({ compactionId: item.id, sessionUpdate: "compaction_update", status: "completed" });
|
|
68928
|
+
} else {
|
|
68929
|
+
const update = toolCallUpdate(item, "snapshot");
|
|
68930
|
+
if (update !== null) {
|
|
68931
|
+
await emit({ ...update, sessionUpdate: "tool_call" });
|
|
68932
|
+
}
|
|
68933
|
+
}
|
|
68934
|
+
}
|
|
68935
|
+
if (turn.error != null) {
|
|
68936
|
+
const identity2 = createHash("sha256").update(threadId).update("\0").update(turn.id ?? turnIndex.toString()).digest("hex");
|
|
68937
|
+
await emit({
|
|
68938
|
+
sessionUpdate: "tool_call",
|
|
68939
|
+
toolCallId: `agent-error-${identity2}`,
|
|
68940
|
+
title: "Agent error",
|
|
68941
|
+
kind: "other",
|
|
68942
|
+
status: "failed",
|
|
68943
|
+
rawOutput: { message: turn.error.message },
|
|
68944
|
+
content: [{ type: "content", content: { type: "text", text: turn.error.message } }]
|
|
68945
|
+
});
|
|
68946
|
+
}
|
|
68947
|
+
turnIndex += 1;
|
|
68948
|
+
}
|
|
68949
|
+
if (page.nextCursor == null) {
|
|
68950
|
+
return;
|
|
68951
|
+
}
|
|
68952
|
+
if (page.data.length === 0 || seenCursors.has(page.nextCursor)) {
|
|
68953
|
+
throw new AcpExecutionError("Codex repeated a history page cursor", {}, "invalid_native_session_response");
|
|
68954
|
+
}
|
|
68955
|
+
seenCursors.add(page.nextCursor);
|
|
68956
|
+
cursor = page.nextCursor;
|
|
68957
|
+
}
|
|
68958
|
+
}
|
|
68959
|
+
|
|
68577
68960
|
// src/acp/harness/codex/settings.ts
|
|
68578
68961
|
var APPROVAL_TIMEOUT_MILLISECONDS2 = 36e5;
|
|
68579
68962
|
var MODEL_SETTING_ID = "model";
|
|
@@ -69240,83 +69623,7 @@ var CodexAcpAgent = class {
|
|
|
69240
69623
|
// ACP load requires chronological replay. Resume only restores execution;
|
|
69241
69624
|
// native pages supply history without a single full-transcript response.
|
|
69242
69625
|
#replaySavedHistory = async (signal) => {
|
|
69243
|
-
|
|
69244
|
-
const seenCursors = /* @__PURE__ */ new Set();
|
|
69245
|
-
let cursor = null;
|
|
69246
|
-
for (; ; ) {
|
|
69247
|
-
deadline.throwIfAborted();
|
|
69248
|
-
const page = threadTurnsPageSchema.parse(
|
|
69249
|
-
await this.#appServer.request(
|
|
69250
|
-
"thread/turns/list",
|
|
69251
|
-
{
|
|
69252
|
-
threadId: this.#nativeSessionId,
|
|
69253
|
-
limit: CODEX_HISTORY_TURN_PAGE_LIMIT,
|
|
69254
|
-
sortDirection: "asc",
|
|
69255
|
-
itemsView: "full",
|
|
69256
|
-
...cursor === null ? {} : { cursor }
|
|
69257
|
-
},
|
|
69258
|
-
deadline
|
|
69259
|
-
)
|
|
69260
|
-
);
|
|
69261
|
-
await this.#replayHistory(page.data, deadline);
|
|
69262
|
-
if (page.nextCursor == null) {
|
|
69263
|
-
return;
|
|
69264
|
-
}
|
|
69265
|
-
if (page.data.length === 0 || seenCursors.has(page.nextCursor)) {
|
|
69266
|
-
throw new AcpExecutionError(
|
|
69267
|
-
"Codex repeated a history page cursor",
|
|
69268
|
-
{},
|
|
69269
|
-
"invalid_native_session_response"
|
|
69270
|
-
);
|
|
69271
|
-
}
|
|
69272
|
-
seenCursors.add(page.nextCursor);
|
|
69273
|
-
cursor = page.nextCursor;
|
|
69274
|
-
}
|
|
69275
|
-
};
|
|
69276
|
-
#replayHistory = async (turns, signal) => {
|
|
69277
|
-
for (const turn of turns) {
|
|
69278
|
-
for (const rawItem of turn.items) {
|
|
69279
|
-
signal.throwIfAborted();
|
|
69280
|
-
const item = decodeThreadItem(rawItem);
|
|
69281
|
-
if (item === null) {
|
|
69282
|
-
continue;
|
|
69283
|
-
}
|
|
69284
|
-
if (item.type === "userMessage") {
|
|
69285
|
-
const text2 = item.content.flatMap((content) => {
|
|
69286
|
-
if (typeof content !== "object" || content === null) {
|
|
69287
|
-
return [];
|
|
69288
|
-
}
|
|
69289
|
-
const type = Reflect.get(content, "type");
|
|
69290
|
-
const text3 = Reflect.get(content, "text");
|
|
69291
|
-
return type === "text" && typeof text3 === "string" ? [text3] : [];
|
|
69292
|
-
}).join("");
|
|
69293
|
-
if (text2.length > 0) {
|
|
69294
|
-
await this.#emit({
|
|
69295
|
-
content: { text: text2, type: "text" },
|
|
69296
|
-
messageId: item.id,
|
|
69297
|
-
sessionUpdate: "user_message_chunk"
|
|
69298
|
-
});
|
|
69299
|
-
}
|
|
69300
|
-
continue;
|
|
69301
|
-
}
|
|
69302
|
-
if (item.type === "agentMessage") {
|
|
69303
|
-
await this.#emit(agentMessageUpdate(item.id, item.text));
|
|
69304
|
-
continue;
|
|
69305
|
-
}
|
|
69306
|
-
if (item.type === "contextCompaction") {
|
|
69307
|
-
await this.#emit({
|
|
69308
|
-
compactionId: item.id,
|
|
69309
|
-
sessionUpdate: "compaction_update",
|
|
69310
|
-
status: "completed"
|
|
69311
|
-
});
|
|
69312
|
-
continue;
|
|
69313
|
-
}
|
|
69314
|
-
const update = toolCallUpdate(item, "snapshot");
|
|
69315
|
-
if (update !== null) {
|
|
69316
|
-
await this.#emit({ ...update, sessionUpdate: "tool_call" });
|
|
69317
|
-
}
|
|
69318
|
-
}
|
|
69319
|
-
}
|
|
69626
|
+
await replayCodexHistory(this.#appServer, this.#nativeSessionId, this.#emit, signal);
|
|
69320
69627
|
};
|
|
69321
69628
|
/** Announces the manual compact command after every session entry point —
|
|
69322
69629
|
* new, load, resume, and fork — so clients on restored sessions discover
|
|
@@ -69364,7 +69671,7 @@ var CodexAgentSpecification = class extends InProcessAcpAgentSpecification {
|
|
|
69364
69671
|
};
|
|
69365
69672
|
|
|
69366
69673
|
// src/agent/specification/vendors/pi-agent.ts
|
|
69367
|
-
import { createHash } from "node:crypto";
|
|
69674
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
69368
69675
|
import { join as join19 } from "node:path";
|
|
69369
69676
|
import {
|
|
69370
69677
|
methods as methods6
|
|
@@ -69377,7 +69684,7 @@ import { agent as createAgentApp2, methods as methods5 } from "@agentclientproto
|
|
|
69377
69684
|
import { spawnSync } from "node:child_process";
|
|
69378
69685
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
69379
69686
|
import { existsSync as existsSync7, readdirSync as readdirSync6, readFileSync as readFileSync8, realpathSync as realpathSync4, statSync as statSync4, unlinkSync as unlinkSync2 } from "node:fs";
|
|
69380
|
-
import { basename as
|
|
69687
|
+
import { basename as basename5, dirname as dirname7, isAbsolute as isAbsolute12, join as join17 } from "node:path";
|
|
69381
69688
|
import { RequestError as RequestError7 } from "@agentclientprotocol/sdk";
|
|
69382
69689
|
|
|
69383
69690
|
// src/acp/harness/pi/upstream/dist/pi-rpc/process.js
|
|
@@ -69893,7 +70200,7 @@ function toAvailableCommandsFromPiGetCommands(data, opts) {
|
|
|
69893
70200
|
|
|
69894
70201
|
// src/acp/harness/pi/upstream/dist/acp/pi-sessions.js
|
|
69895
70202
|
import { closeSync as closeSync2, existsSync as existsSync4, openSync as openSync2, readdirSync as readdirSync4, readFileSync as readFileSync3, readSync as readSync2, statSync as statSync3 } from "node:fs";
|
|
69896
|
-
import { isAbsolute as
|
|
70203
|
+
import { isAbsolute as isAbsolute10, join as join14, resolve as resolve9 } from "node:path";
|
|
69897
70204
|
var DEFAULT_TAIL_BYTES = 256 * 1024;
|
|
69898
70205
|
var DEFAULT_HEAD_BYTES = 64 * 1024;
|
|
69899
70206
|
function getPiAgentDir(environment) {
|
|
@@ -69915,7 +70222,7 @@ function readSessionDirFromSettings(agentDir) {
|
|
|
69915
70222
|
if (typeof sessionDir !== "string" || !sessionDir.trim()) {
|
|
69916
70223
|
return null;
|
|
69917
70224
|
}
|
|
69918
|
-
return
|
|
70225
|
+
return isAbsolute10(sessionDir) ? sessionDir : resolve9(agentDir, sessionDir);
|
|
69919
70226
|
} catch {
|
|
69920
70227
|
return null;
|
|
69921
70228
|
}
|
|
@@ -70286,7 +70593,7 @@ function getQuietStartup(cwd, environment = process.env) {
|
|
|
70286
70593
|
// src/acp/harness/pi/upstream/dist/acp/session.js
|
|
70287
70594
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
70288
70595
|
import { readFileSync as readFileSync7 } from "node:fs";
|
|
70289
|
-
import { isAbsolute as
|
|
70596
|
+
import { isAbsolute as isAbsolute11, resolve as resolvePath } from "node:path";
|
|
70290
70597
|
import { RequestError as RequestError6 } from "@agentclientprotocol/sdk";
|
|
70291
70598
|
|
|
70292
70599
|
// src/acp/harness/pi/upstream/dist/acp/extension-questions.js
|
|
@@ -70819,7 +71126,7 @@ function toToolCallLocations(args, cwd, line) {
|
|
|
70819
71126
|
if (!path7) {
|
|
70820
71127
|
return void 0;
|
|
70821
71128
|
}
|
|
70822
|
-
const resolvedPath =
|
|
71129
|
+
const resolvedPath = isAbsolute11(path7) ? path7 : resolvePath(cwd, path7);
|
|
70823
71130
|
return [{ path: resolvedPath, ...typeof line === "number" ? { line } : {} }];
|
|
70824
71131
|
}
|
|
70825
71132
|
var SessionManager = class {
|
|
@@ -71359,7 +71666,7 @@ var PiAcpSession = class {
|
|
|
71359
71666
|
const p = getToolPath(args);
|
|
71360
71667
|
if (p) {
|
|
71361
71668
|
try {
|
|
71362
|
-
const abs =
|
|
71669
|
+
const abs = isAbsolute11(p) ? p : resolvePath(this.cwd, p);
|
|
71363
71670
|
snapshotOldText = readFileSync7(abs, "utf8");
|
|
71364
71671
|
this.fileSnapshots.set(toolCallId, { path: p, oldText: snapshotOldText });
|
|
71365
71672
|
if (toolName === "edit") {
|
|
@@ -71442,7 +71749,7 @@ var PiAcpSession = class {
|
|
|
71442
71749
|
let hasStructuredDiff = false;
|
|
71443
71750
|
if (!isError && snapshot) {
|
|
71444
71751
|
try {
|
|
71445
|
-
const abs =
|
|
71752
|
+
const abs = isAbsolute11(snapshot.path) ? snapshot.path : resolvePath(this.cwd, snapshot.path);
|
|
71446
71753
|
const newText = readFileSync7(abs, "utf8");
|
|
71447
71754
|
if (snapshot.oldText === null || newText !== snapshot.oldText) {
|
|
71448
71755
|
hasStructuredDiff = true;
|
|
@@ -71836,7 +72143,7 @@ var PiAcpAgent = class {
|
|
|
71836
72143
|
};
|
|
71837
72144
|
}
|
|
71838
72145
|
async newSession(params) {
|
|
71839
|
-
if (!
|
|
72146
|
+
if (!isAbsolute12(params.cwd)) {
|
|
71840
72147
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
71841
72148
|
}
|
|
71842
72149
|
this.lastSessionCwd = params.cwd;
|
|
@@ -72433,7 +72740,7 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
72433
72740
|
return { sessions, nextCursor, _meta: {} };
|
|
72434
72741
|
}
|
|
72435
72742
|
async forkSession(params) {
|
|
72436
|
-
if (!
|
|
72743
|
+
if (!isAbsolute12(params.cwd)) {
|
|
72437
72744
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
72438
72745
|
}
|
|
72439
72746
|
const source = this.findStoredSession(params.sessionId);
|
|
@@ -72499,7 +72806,7 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
72499
72806
|
return { sessionId: session.sessionId, configOptions, modes };
|
|
72500
72807
|
}
|
|
72501
72808
|
async resumeSession(params) {
|
|
72502
|
-
if (!
|
|
72809
|
+
if (!isAbsolute12(params.cwd)) {
|
|
72503
72810
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
72504
72811
|
}
|
|
72505
72812
|
this.sessions.close(params.sessionId);
|
|
@@ -72570,7 +72877,7 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
72570
72877
|
return response;
|
|
72571
72878
|
}
|
|
72572
72879
|
async loadSession(params) {
|
|
72573
|
-
if (!
|
|
72880
|
+
if (!isAbsolute12(params.cwd)) {
|
|
72574
72881
|
throw RequestError7.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
72575
72882
|
}
|
|
72576
72883
|
this.sessions.close(params.sessionId);
|
|
@@ -73064,7 +73371,7 @@ function buildStartupInfo(opts) {
|
|
|
73064
73371
|
try {
|
|
73065
73372
|
const prompts = readdirSync6(promptsDir).filter((f) => f.endsWith(".md"));
|
|
73066
73373
|
for (const f of prompts) {
|
|
73067
|
-
promptsItems.push(`/${
|
|
73374
|
+
promptsItems.push(`/${basename5(f, ".md")}`);
|
|
73068
73375
|
}
|
|
73069
73376
|
} catch {
|
|
73070
73377
|
}
|
|
@@ -73244,7 +73551,7 @@ var PiAgentSpecification = class extends InProcessAcpAgentSpecification {
|
|
|
73244
73551
|
// The Pi ACP fork inlines embedded prompt resources into the turn message, so Mobius
|
|
73245
73552
|
// keeps the adapter's opt-in capability flag enabled for every launch it owns.
|
|
73246
73553
|
createLaunchEnvironment = async (_agent, context) => {
|
|
73247
|
-
const workspaceHash =
|
|
73554
|
+
const workspaceHash = createHash2("sha256").update(context.defaultWorkspace).digest("hex").slice(0, 24);
|
|
73248
73555
|
const sessionDirectory = join19(
|
|
73249
73556
|
readStateDirectory(context.environment),
|
|
73250
73557
|
"agents",
|
|
@@ -73760,11 +74067,11 @@ function isAgentVersionSupported(reportedVersion, minimumSupportedVersion) {
|
|
|
73760
74067
|
}
|
|
73761
74068
|
|
|
73762
74069
|
// src/agent/discovery/executable-discovery.ts
|
|
73763
|
-
import { isAbsolute as
|
|
74070
|
+
import { isAbsolute as isAbsolute13 } from "node:path";
|
|
73764
74071
|
async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, context) {
|
|
73765
74072
|
const override = context.environment[overrideVariable];
|
|
73766
74073
|
if (override !== void 0) {
|
|
73767
|
-
if (override.length === 0 || !
|
|
74074
|
+
if (override.length === 0 || !isAbsolute13(override)) {
|
|
73768
74075
|
return [];
|
|
73769
74076
|
}
|
|
73770
74077
|
const executable = await resolveExecutablePath(override, context.platform);
|
|
@@ -74272,8 +74579,27 @@ var AdapterRegistry = class {
|
|
|
74272
74579
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
74273
74580
|
|
|
74274
74581
|
// src/session/history/session-event-history-projection.ts
|
|
74582
|
+
var MAXIMUM_PROJECTED_REASONING_BYTES = 24 * 1024;
|
|
74583
|
+
function boundReasoning(payload) {
|
|
74584
|
+
if (payload.content.type !== "text" || Buffer.byteLength(payload.content.text, "utf8") <= MAXIMUM_PROJECTED_REASONING_BYTES) {
|
|
74585
|
+
return payload;
|
|
74586
|
+
}
|
|
74587
|
+
const bytes = Buffer.from(payload.content.text, "utf8");
|
|
74588
|
+
let start = bytes.length - MAXIMUM_PROJECTED_REASONING_BYTES;
|
|
74589
|
+
while (start < bytes.length && (bytes.readUInt8(start) & 192) === 128) {
|
|
74590
|
+
start += 1;
|
|
74591
|
+
}
|
|
74592
|
+
return {
|
|
74593
|
+
...payload,
|
|
74594
|
+
content: { ...payload.content, text: bytes.toString("utf8", start) },
|
|
74595
|
+
meta: { ...payload.meta, truncated: true }
|
|
74596
|
+
};
|
|
74597
|
+
}
|
|
74275
74598
|
function projectNewEvent(liveEvent2, eventId) {
|
|
74276
74599
|
const { position: _position, eventId: _liveEventId, ...event } = liveEvent2;
|
|
74600
|
+
if (event.type === "acp" && event.payload.sessionUpdate === "agent_thought_chunk") {
|
|
74601
|
+
return { ...event, eventId, payload: boundReasoning(event.payload) };
|
|
74602
|
+
}
|
|
74277
74603
|
return { ...event, eventId };
|
|
74278
74604
|
}
|
|
74279
74605
|
function replaceAcpPayload(event, payload) {
|
|
@@ -74324,11 +74650,11 @@ function mergeTextChunk(previous, incoming) {
|
|
|
74324
74650
|
}
|
|
74325
74651
|
const content = { text: `${previous.content.text}${incoming.content.text}`, type: "text" };
|
|
74326
74652
|
if (previous.sessionUpdate === "agent_thought_chunk" && incoming.sessionUpdate === "agent_thought_chunk") {
|
|
74327
|
-
return {
|
|
74653
|
+
return boundReasoning({
|
|
74328
74654
|
...previous,
|
|
74329
74655
|
content,
|
|
74330
74656
|
...previous.meta?.truncated === true || incoming.meta?.truncated === true ? { meta: { ...previous.meta, ...incoming.meta, truncated: true } } : {}
|
|
74331
|
-
};
|
|
74657
|
+
});
|
|
74332
74658
|
}
|
|
74333
74659
|
return { ...previous, content };
|
|
74334
74660
|
}
|
|
@@ -75792,12 +76118,30 @@ function sessionConfigProtocolForAgent(_agentId) {
|
|
|
75792
76118
|
}
|
|
75793
76119
|
|
|
75794
76120
|
// src/acp/adapter/session-events.ts
|
|
76121
|
+
var MAXIMUM_REASONING_UPDATE_CHARACTERS = 1e6;
|
|
76122
|
+
function* reasoningWireUpdates(update) {
|
|
76123
|
+
if (update.sessionUpdate !== "agent_thought_chunk" || update.content.type !== "text" || update.content.text.length <= MAXIMUM_REASONING_UPDATE_CHARACTERS) {
|
|
76124
|
+
yield update;
|
|
76125
|
+
return;
|
|
76126
|
+
}
|
|
76127
|
+
const text2 = update.content.text;
|
|
76128
|
+
for (let start = 0; start < text2.length; ) {
|
|
76129
|
+
let end = Math.min(start + MAXIMUM_REASONING_UPDATE_CHARACTERS, text2.length);
|
|
76130
|
+
const last = text2.charCodeAt(end - 1);
|
|
76131
|
+
const next = text2.charCodeAt(end);
|
|
76132
|
+
if (last >= 55296 && last <= 56319 && next >= 56320 && next <= 57343) {
|
|
76133
|
+
end -= 1;
|
|
76134
|
+
}
|
|
76135
|
+
yield { ...update, content: { ...update.content, text: text2.slice(start, end) } };
|
|
76136
|
+
start = end;
|
|
76137
|
+
}
|
|
76138
|
+
}
|
|
75795
76139
|
var AdapterSessionConnection = class {
|
|
75796
76140
|
#connection;
|
|
75797
76141
|
#updates;
|
|
75798
76142
|
#lifetime = new AbortController();
|
|
75799
76143
|
events;
|
|
75800
|
-
constructor(options, externalizer) {
|
|
76144
|
+
constructor(options, externalizer, normalizeEvent) {
|
|
75801
76145
|
const protocol = sessionConfigProtocolForAgent(options.agent.id);
|
|
75802
76146
|
this.#updates = new AgentUpdateStream(async (notification) => {
|
|
75803
76147
|
this.#lifetime.signal.throwIfAborted();
|
|
@@ -75805,58 +76149,60 @@ var AdapterSessionConnection = class {
|
|
|
75805
76149
|
throw new AcpExecutionError("ACP agent referenced an unknown session", {}, "invalid_agent_session");
|
|
75806
76150
|
}
|
|
75807
76151
|
const signal = AbortSignal.any([this.#lifetime.signal, AbortSignal.timeout(3e4)]);
|
|
75808
|
-
const
|
|
75809
|
-
|
|
75810
|
-
|
|
75811
|
-
|
|
75812
|
-
|
|
75813
|
-
|
|
75814
|
-
|
|
75815
|
-
|
|
75816
|
-
|
|
75817
|
-
|
|
75818
|
-
|
|
75819
|
-
|
|
75820
|
-
|
|
75821
|
-
|
|
75822
|
-
|
|
75823
|
-
|
|
75824
|
-
|
|
75825
|
-
|
|
75826
|
-
|
|
75827
|
-
|
|
75828
|
-
|
|
75829
|
-
|
|
75830
|
-
|
|
75831
|
-
|
|
75832
|
-
|
|
75833
|
-
|
|
75834
|
-
|
|
75835
|
-
|
|
75836
|
-
|
|
75837
|
-
|
|
75838
|
-
|
|
75839
|
-
|
|
75840
|
-
|
|
75841
|
-
|
|
76152
|
+
for (const incoming of reasoningWireUpdates(notification.update)) {
|
|
76153
|
+
const externalized = await externalizer.update(options.sessionId(), incoming, signal);
|
|
76154
|
+
signal.throwIfAborted();
|
|
76155
|
+
const update = externalized.agent;
|
|
76156
|
+
const payload = decodeAcpSessionUpdate(JSON.stringify(normalizeEvent(externalized.event)));
|
|
76157
|
+
let event;
|
|
76158
|
+
switch (update.sessionUpdate) {
|
|
76159
|
+
case "available_commands_update":
|
|
76160
|
+
event = {
|
|
76161
|
+
kind: "commands",
|
|
76162
|
+
payload,
|
|
76163
|
+
commands: update.availableCommands.slice(0, 500).map((command) => ({
|
|
76164
|
+
description: truncate(command.description, 500),
|
|
76165
|
+
inputHint: truncate(command.input?.hint ?? "", 255),
|
|
76166
|
+
name: truncate(command.name, 128)
|
|
76167
|
+
})).filter((command) => command.name.length > 0)
|
|
76168
|
+
};
|
|
76169
|
+
break;
|
|
76170
|
+
case "config_option_update":
|
|
76171
|
+
event = {
|
|
76172
|
+
kind: "configuration",
|
|
76173
|
+
payload,
|
|
76174
|
+
configOptions: protocol.normalizeUpdate(options.configOptions(), update.configOptions)
|
|
76175
|
+
};
|
|
76176
|
+
break;
|
|
76177
|
+
case "current_mode_update":
|
|
76178
|
+
event = { kind: "mode", payload, modeId: update.currentModeId };
|
|
76179
|
+
break;
|
|
76180
|
+
case "session_info_update": {
|
|
76181
|
+
const changes = [];
|
|
76182
|
+
if (Object.hasOwn(update, "title")) {
|
|
76183
|
+
changes.push({ kind: "title", value: truncate(update.title ?? "", 500) });
|
|
76184
|
+
}
|
|
76185
|
+
if (Object.hasOwn(update, "updatedAt")) {
|
|
76186
|
+
changes.push({ kind: "updated-at", value: truncate(update.updatedAt ?? "", 128) });
|
|
76187
|
+
}
|
|
76188
|
+
event = { kind: "info", payload, changes };
|
|
76189
|
+
break;
|
|
75842
76190
|
}
|
|
75843
|
-
|
|
75844
|
-
|
|
76191
|
+
case "user_message_chunk":
|
|
76192
|
+
case "agent_message_chunk":
|
|
76193
|
+
case "agent_thought_chunk":
|
|
76194
|
+
case "tool_call":
|
|
76195
|
+
case "tool_call_update":
|
|
76196
|
+
case "plan":
|
|
76197
|
+
case "plan_update":
|
|
76198
|
+
case "plan_removed":
|
|
76199
|
+
event = { kind: "content", payload };
|
|
76200
|
+
break;
|
|
76201
|
+
default:
|
|
76202
|
+
event = { kind: "other", payload };
|
|
75845
76203
|
}
|
|
75846
|
-
|
|
75847
|
-
case "agent_message_chunk":
|
|
75848
|
-
case "agent_thought_chunk":
|
|
75849
|
-
case "tool_call":
|
|
75850
|
-
case "tool_call_update":
|
|
75851
|
-
case "plan":
|
|
75852
|
-
case "plan_update":
|
|
75853
|
-
case "plan_removed":
|
|
75854
|
-
event = { kind: "content", payload };
|
|
75855
|
-
break;
|
|
75856
|
-
default:
|
|
75857
|
-
event = { kind: "other", payload };
|
|
76204
|
+
await options.onEvent(event);
|
|
75858
76205
|
}
|
|
75859
|
-
await options.onEvent(event);
|
|
75860
76206
|
});
|
|
75861
76207
|
this.events = this.#updates;
|
|
75862
76208
|
const client2 = {
|
|
@@ -75903,10 +76249,12 @@ var AdapterSessionConnection = class {
|
|
|
75903
76249
|
};
|
|
75904
76250
|
var AcpSessionConnector = class {
|
|
75905
76251
|
#externalizer;
|
|
75906
|
-
|
|
76252
|
+
#normalizeEvent;
|
|
76253
|
+
constructor(externalizer, normalizeEvent = (event) => event) {
|
|
75907
76254
|
this.#externalizer = externalizer;
|
|
76255
|
+
this.#normalizeEvent = normalizeEvent;
|
|
75908
76256
|
}
|
|
75909
|
-
connectSession = (options) => new AdapterSessionConnection(options, this.#externalizer);
|
|
76257
|
+
connectSession = (options) => new AdapterSessionConnection(options, this.#externalizer, this.#normalizeEvent);
|
|
75910
76258
|
connectQuerySession = (options) => {
|
|
75911
76259
|
const rejectInteraction = async () => {
|
|
75912
76260
|
throw new AcpExecutionError(
|
|
@@ -75924,7 +76272,8 @@ var AcpSessionConnector = class {
|
|
|
75924
76272
|
onElicitationComplete: rejectInteraction
|
|
75925
76273
|
}
|
|
75926
76274
|
},
|
|
75927
|
-
this.#externalizer
|
|
76275
|
+
this.#externalizer,
|
|
76276
|
+
this.#normalizeEvent
|
|
75928
76277
|
);
|
|
75929
76278
|
};
|
|
75930
76279
|
};
|
|
@@ -75944,1042 +76293,8 @@ var ClaudeAdapter = class {
|
|
|
75944
76293
|
close = async () => await this.#queryProcesses.close();
|
|
75945
76294
|
};
|
|
75946
76295
|
|
|
75947
|
-
// src/acp/
|
|
75948
|
-
import {
|
|
75949
|
-
|
|
75950
|
-
// src/acp/content/raster.ts
|
|
75951
|
-
import { basename as basename5, isAbsolute as isAbsolute13, normalize } from "node:path";
|
|
75952
|
-
import { fileURLToPath } from "node:url";
|
|
75953
|
-
|
|
75954
|
-
// src/storage/files/local-files.ts
|
|
75955
|
-
import { createReadStream as createReadStream2 } from "node:fs";
|
|
75956
|
-
import { mkdir as mkdir3, open as open4, readdir as readdir4, readFile as readFile5, realpath as realpath6, stat as stat5 } from "node:fs/promises";
|
|
75957
|
-
function entryKind(entry) {
|
|
75958
|
-
if (entry.isDirectory()) {
|
|
75959
|
-
return "directory";
|
|
75960
|
-
}
|
|
75961
|
-
if (entry.isFile()) {
|
|
75962
|
-
return "file";
|
|
75963
|
-
}
|
|
75964
|
-
if (entry.isSymbolicLink()) {
|
|
75965
|
-
return "symbolic-link";
|
|
75966
|
-
}
|
|
75967
|
-
if (entry.isBlockDevice() || entry.isCharacterDevice()) {
|
|
75968
|
-
return "device";
|
|
75969
|
-
}
|
|
75970
|
-
if (entry.isFIFO()) {
|
|
75971
|
-
return "fifo";
|
|
75972
|
-
}
|
|
75973
|
-
return entry.isSocket() ? "socket" : "unknown";
|
|
75974
|
-
}
|
|
75975
|
-
async function canonicalPath(path7) {
|
|
75976
|
-
return await realpath6(path7);
|
|
75977
|
-
}
|
|
75978
|
-
async function readPathMetadata(path7) {
|
|
75979
|
-
const metadata = await stat5(path7);
|
|
75980
|
-
return {
|
|
75981
|
-
kind: metadata.isDirectory() ? "directory" : metadata.isFile() ? "file" : "other",
|
|
75982
|
-
modifiedAt: metadata.mtime,
|
|
75983
|
-
modifiedMilliseconds: metadata.mtimeMs,
|
|
75984
|
-
size: metadata.size
|
|
75985
|
-
};
|
|
75986
|
-
}
|
|
75987
|
-
async function listDirectory(path7) {
|
|
75988
|
-
const entries = await readdir4(path7, { withFileTypes: true });
|
|
75989
|
-
return entries.map((entry) => ({ kind: entryKind(entry), name: entry.name }));
|
|
75990
|
-
}
|
|
75991
|
-
async function ensurePrivateDirectory(path7) {
|
|
75992
|
-
await mkdir3(path7, { mode: 448, recursive: true });
|
|
75993
|
-
}
|
|
75994
|
-
async function ensureCanonicalDirectory(path7) {
|
|
75995
|
-
await ensurePrivateDirectory(path7);
|
|
75996
|
-
const resolved = await realpath6(path7);
|
|
75997
|
-
return (await stat5(resolved)).isDirectory() ? resolved : null;
|
|
75998
|
-
}
|
|
75999
|
-
async function readFileStart(path7, byteLength) {
|
|
76000
|
-
const bytes = new Uint8Array(byteLength);
|
|
76001
|
-
const handle = await open4(path7, "r");
|
|
76002
|
-
try {
|
|
76003
|
-
await handle.read(bytes, 0, byteLength, 0);
|
|
76004
|
-
} finally {
|
|
76005
|
-
await handle.close();
|
|
76006
|
-
}
|
|
76007
|
-
return bytes;
|
|
76008
|
-
}
|
|
76009
|
-
async function readFileBytes(path7) {
|
|
76010
|
-
return await readFile5(path7);
|
|
76011
|
-
}
|
|
76012
|
-
function readFileChunks(path7, chunkBytes, signal) {
|
|
76013
|
-
return createReadStream2(path7, { highWaterMark: chunkBytes, signal });
|
|
76014
|
-
}
|
|
76015
|
-
|
|
76016
|
-
// src/acp/content/raster.ts
|
|
76017
|
-
var MAX_LOCAL_RASTER_BYTES = 128 * 1024 * 1024;
|
|
76018
|
-
var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
|
|
76019
|
-
var JPEG_SIGNATURE = Uint8Array.of(255, 216, 255);
|
|
76020
|
-
var GIF87_SIGNATURE = new TextEncoder().encode("GIF87a");
|
|
76021
|
-
var GIF89_SIGNATURE = new TextEncoder().encode("GIF89a");
|
|
76022
|
-
var RIFF_SIGNATURE = new TextEncoder().encode("RIFF");
|
|
76023
|
-
var WEBP_SIGNATURE = new TextEncoder().encode("WEBP");
|
|
76024
|
-
var LocalRasterImage = class {
|
|
76025
|
-
mimeType;
|
|
76026
|
-
name;
|
|
76027
|
-
sourceUri;
|
|
76028
|
-
constructor(name2, mimeType, sourceUri) {
|
|
76029
|
-
this.mimeType = mimeType;
|
|
76030
|
-
this.name = name2;
|
|
76031
|
-
this.sourceUri = sourceUri;
|
|
76032
|
-
}
|
|
76033
|
-
base64 = async () => Buffer.from(await readFileBytes(this.sourceUri)).toString("base64");
|
|
76034
|
-
};
|
|
76035
|
-
function startsWith(bytes, signature, offset = 0) {
|
|
76036
|
-
if (bytes.byteLength < offset + signature.byteLength) {
|
|
76037
|
-
return false;
|
|
76038
|
-
}
|
|
76039
|
-
return signature.every((value, index2) => bytes[offset + index2] === value);
|
|
76040
|
-
}
|
|
76041
|
-
function sniffRasterMime(bytes) {
|
|
76042
|
-
if (startsWith(bytes, PNG_SIGNATURE)) {
|
|
76043
|
-
return "image/png";
|
|
76044
|
-
}
|
|
76045
|
-
if (startsWith(bytes, JPEG_SIGNATURE)) {
|
|
76046
|
-
return "image/jpeg";
|
|
76047
|
-
}
|
|
76048
|
-
if (startsWith(bytes, GIF87_SIGNATURE) || startsWith(bytes, GIF89_SIGNATURE)) {
|
|
76049
|
-
return "image/gif";
|
|
76050
|
-
}
|
|
76051
|
-
if (startsWith(bytes, RIFF_SIGNATURE) && startsWith(bytes, WEBP_SIGNATURE, 8)) {
|
|
76052
|
-
return "image/webp";
|
|
76053
|
-
}
|
|
76054
|
-
return null;
|
|
76055
|
-
}
|
|
76056
|
-
async function resolveCanonicalPath(requested, signal) {
|
|
76057
|
-
signal.throwIfAborted();
|
|
76058
|
-
if (!isAbsolute13(requested) || requested.includes("\0") || normalize(requested) !== requested) {
|
|
76059
|
-
return null;
|
|
76060
|
-
}
|
|
76061
|
-
try {
|
|
76062
|
-
const target = await canonicalPath(requested);
|
|
76063
|
-
signal.throwIfAborted();
|
|
76064
|
-
if (!isAbsolute13(target) || normalize(target) !== target) {
|
|
76065
|
-
return null;
|
|
76066
|
-
}
|
|
76067
|
-
return target;
|
|
76068
|
-
} catch (cause) {
|
|
76069
|
-
signal.throwIfAborted();
|
|
76070
|
-
if (cause instanceof Error && cause.name === "AbortError") {
|
|
76071
|
-
throw cause;
|
|
76072
|
-
}
|
|
76073
|
-
return null;
|
|
76074
|
-
}
|
|
76075
|
-
}
|
|
76076
|
-
function parseLocalImageUri(uri) {
|
|
76077
|
-
const trimmed = uri.trim();
|
|
76078
|
-
if (trimmed.length === 0 || trimmed.length > 2048 || trimmed.includes("\0")) {
|
|
76079
|
-
return null;
|
|
76080
|
-
}
|
|
76081
|
-
if (trimmed.startsWith("data:")) {
|
|
76082
|
-
return null;
|
|
76083
|
-
}
|
|
76084
|
-
if (trimmed.startsWith("file:")) {
|
|
76085
|
-
try {
|
|
76086
|
-
const url2 = new URL(trimmed);
|
|
76087
|
-
if (url2.protocol !== "file:" || url2.host.length > 0) {
|
|
76088
|
-
return null;
|
|
76089
|
-
}
|
|
76090
|
-
return fileURLToPath(url2);
|
|
76091
|
-
} catch {
|
|
76092
|
-
return null;
|
|
76093
|
-
}
|
|
76094
|
-
}
|
|
76095
|
-
if (!isAbsolute13(trimmed) && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
|
|
76096
|
-
return null;
|
|
76097
|
-
}
|
|
76098
|
-
return trimmed;
|
|
76099
|
-
}
|
|
76100
|
-
async function readLocalRaster(uri, signal) {
|
|
76101
|
-
signal.throwIfAborted();
|
|
76102
|
-
const requested = parseLocalImageUri(uri);
|
|
76103
|
-
if (requested === null) {
|
|
76104
|
-
return null;
|
|
76105
|
-
}
|
|
76106
|
-
const target = await resolveCanonicalPath(requested, signal);
|
|
76107
|
-
if (target === null) {
|
|
76108
|
-
return null;
|
|
76109
|
-
}
|
|
76110
|
-
const targetMetadata = await readPathMetadata(target);
|
|
76111
|
-
signal.throwIfAborted();
|
|
76112
|
-
if (targetMetadata.kind !== "file" || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
|
|
76113
|
-
return null;
|
|
76114
|
-
}
|
|
76115
|
-
const header = await readFileStart(target, 12);
|
|
76116
|
-
signal.throwIfAborted();
|
|
76117
|
-
const mimeType = sniffRasterMime(header);
|
|
76118
|
-
if (mimeType === null) {
|
|
76119
|
-
return null;
|
|
76120
|
-
}
|
|
76121
|
-
return new LocalRasterImage(basename5(target) || "Image", mimeType, target);
|
|
76122
|
-
}
|
|
76123
|
-
|
|
76124
|
-
// src/acp/native-history/codex/history-images.ts
|
|
76125
|
-
var IMAGE_MARKER = /\[@image\]\(([^)\r\n]*)(?:\)|$)/g;
|
|
76126
|
-
var DATA_IMAGE_HEADER = /^data:(image\/[a-z+]+);base64,/;
|
|
76127
|
-
var BASE_64 = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
76128
|
-
var SESSION_HISTORY_IMAGE_CHARACTER_LIMIT = 4e6;
|
|
76129
|
-
var SESSION_HISTORY_PREVIEW_TURN_LIMIT = 10;
|
|
76130
|
-
function isRasterMime(value) {
|
|
76131
|
-
return value === "image/png" || value === "image/jpeg" || value === "image/gif" || value === "image/webp";
|
|
76132
|
-
}
|
|
76133
|
-
function parseNativeHistoryImage(uri) {
|
|
76134
|
-
const header = DATA_IMAGE_HEADER.exec(uri);
|
|
76135
|
-
if (header === null) {
|
|
76136
|
-
return null;
|
|
76137
|
-
}
|
|
76138
|
-
const mimeType = header[1] ?? "";
|
|
76139
|
-
const data = uri.slice(header[0].length);
|
|
76140
|
-
if (!isRasterMime(mimeType) || data.length < 4 || data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
76141
|
-
return null;
|
|
76142
|
-
}
|
|
76143
|
-
if (data.length % 4 !== 0 || !BASE_64.test(data)) {
|
|
76144
|
-
return null;
|
|
76145
|
-
}
|
|
76146
|
-
return { data, mimeType, name: "" };
|
|
76147
|
-
}
|
|
76148
|
-
async function embedLocalHistoryImages(history, signal) {
|
|
76149
|
-
if (history.status !== "available") {
|
|
76150
|
-
return history;
|
|
76151
|
-
}
|
|
76152
|
-
const messages = [];
|
|
76153
|
-
let imageCharacters = 0;
|
|
76154
|
-
for (const message of history.messages) {
|
|
76155
|
-
signal.throwIfAborted();
|
|
76156
|
-
const resolved = await resolveMessageImages(message, imageCharacters, signal);
|
|
76157
|
-
imageCharacters += (resolved.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
76158
|
-
messages.push(resolved);
|
|
76159
|
-
}
|
|
76160
|
-
return {
|
|
76161
|
-
...history,
|
|
76162
|
-
messages
|
|
76163
|
-
};
|
|
76164
|
-
}
|
|
76165
|
-
async function resolveMessageImages(message, usedCharacters, signal) {
|
|
76166
|
-
const images = [...message.images ?? []];
|
|
76167
|
-
let imageCharacters = images.reduce((size, image) => size + image.data.length, 0);
|
|
76168
|
-
const text2 = await replaceImageMarkers(message.text, async (uri) => {
|
|
76169
|
-
if (images.length >= 8 || usedCharacters + imageCharacters >= SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
76170
|
-
return "[Image unavailable]";
|
|
76171
|
-
}
|
|
76172
|
-
const embedded = parseNativeHistoryImage(uri);
|
|
76173
|
-
if (embedded !== null) {
|
|
76174
|
-
if (usedCharacters + imageCharacters + embedded.data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
76175
|
-
return "[Image unavailable]";
|
|
76176
|
-
}
|
|
76177
|
-
images.push({ ...embedded, name: `Image ${(images.length + 1).toString()}` });
|
|
76178
|
-
imageCharacters += embedded.data.length;
|
|
76179
|
-
return "";
|
|
76180
|
-
}
|
|
76181
|
-
const local = await readLocalRaster(uri, signal);
|
|
76182
|
-
if (local === null) {
|
|
76183
|
-
return "[Image unavailable]";
|
|
76184
|
-
}
|
|
76185
|
-
const data = await local.base64();
|
|
76186
|
-
if (usedCharacters + imageCharacters + data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
76187
|
-
return "[Image unavailable]";
|
|
76188
|
-
}
|
|
76189
|
-
images.push({
|
|
76190
|
-
data,
|
|
76191
|
-
mimeType: local.mimeType,
|
|
76192
|
-
name: local.name
|
|
76193
|
-
});
|
|
76194
|
-
imageCharacters += data.length;
|
|
76195
|
-
return "";
|
|
76196
|
-
});
|
|
76197
|
-
return {
|
|
76198
|
-
...message,
|
|
76199
|
-
text: text2,
|
|
76200
|
-
...images.length > 0 ? { images } : {}
|
|
76201
|
-
};
|
|
76202
|
-
}
|
|
76203
|
-
async function replaceImageMarkers(text2, replace) {
|
|
76204
|
-
const matches = [...text2.matchAll(IMAGE_MARKER)];
|
|
76205
|
-
if (matches.length === 0) {
|
|
76206
|
-
return text2;
|
|
76207
|
-
}
|
|
76208
|
-
let cursor = 0;
|
|
76209
|
-
let rewritten = "";
|
|
76210
|
-
for (const match of matches) {
|
|
76211
|
-
const index2 = match.index ?? 0;
|
|
76212
|
-
rewritten += text2.slice(cursor, index2);
|
|
76213
|
-
rewritten += await replace(match[1] ?? "");
|
|
76214
|
-
cursor = index2 + match[0].length;
|
|
76215
|
-
}
|
|
76216
|
-
return `${rewritten}${text2.slice(cursor)}`;
|
|
76217
|
-
}
|
|
76218
|
-
|
|
76219
|
-
// src/acp/native-history/codex/codex-history.ts
|
|
76220
|
-
var responseSchema = external_exports.union([
|
|
76221
|
-
external_exports.object({
|
|
76222
|
-
id: external_exports.number(),
|
|
76223
|
-
error: external_exports.object({ code: external_exports.number(), message: external_exports.string() })
|
|
76224
|
-
}),
|
|
76225
|
-
external_exports.object({ id: external_exports.number(), result: external_exports.unknown() }),
|
|
76226
|
-
external_exports.object({ method: external_exports.string() })
|
|
76227
|
-
]);
|
|
76228
|
-
var threadSchema = external_exports.object({
|
|
76229
|
-
thread: external_exports.object({
|
|
76230
|
-
id: nativeSessionIdSchema,
|
|
76231
|
-
cwd: external_exports.string().min(1).max(2048).refine((path7) => !path7.includes("\0"))
|
|
76232
|
-
})
|
|
76233
|
-
});
|
|
76234
|
-
var turnsSchema = external_exports.object({
|
|
76235
|
-
data: external_exports.array(
|
|
76236
|
-
external_exports.object({
|
|
76237
|
-
id: external_exports.string().min(1),
|
|
76238
|
-
status: external_exports.enum(["completed", "interrupted", "failed", "inProgress"]),
|
|
76239
|
-
error: external_exports.unknown().nullish(),
|
|
76240
|
-
items: external_exports.array(external_exports.unknown()).max(1e5)
|
|
76241
|
-
})
|
|
76242
|
-
).max(SESSION_HISTORY_MESSAGE_LIMIT),
|
|
76243
|
-
nextCursor: external_exports.string().nullish()
|
|
76244
|
-
});
|
|
76245
|
-
var itemTypeSchema = external_exports.object({ type: external_exports.string().min(1).max(80) });
|
|
76246
|
-
var userMessageSchema = external_exports.object({
|
|
76247
|
-
content: external_exports.array(external_exports.unknown()).max(1e4),
|
|
76248
|
-
type: external_exports.literal("userMessage")
|
|
76249
|
-
});
|
|
76250
|
-
var textSchema = external_exports.object({ text: external_exports.string() });
|
|
76251
|
-
var imageSchema = external_exports.object({ url: external_exports.string() });
|
|
76252
|
-
var agentMessageSchema = textSchema.extend({
|
|
76253
|
-
id: external_exports.string().optional(),
|
|
76254
|
-
phase: external_exports.string().nullish(),
|
|
76255
|
-
type: external_exports.literal("agentMessage")
|
|
76256
|
-
});
|
|
76257
|
-
var reasoningSchema = external_exports.object({
|
|
76258
|
-
id: external_exports.string(),
|
|
76259
|
-
summary: external_exports.array(external_exports.string()).max(1e4),
|
|
76260
|
-
content: external_exports.array(external_exports.string()).max(1e4),
|
|
76261
|
-
type: external_exports.literal("reasoning")
|
|
76262
|
-
});
|
|
76263
|
-
var commandExecutionSchema = external_exports.object({
|
|
76264
|
-
id: external_exports.string(),
|
|
76265
|
-
command: external_exports.string(),
|
|
76266
|
-
cwd: external_exports.string(),
|
|
76267
|
-
status: external_exports.string(),
|
|
76268
|
-
commandActions: external_exports.array(external_exports.object({ type: external_exports.string() }).passthrough()).max(100),
|
|
76269
|
-
aggregatedOutput: external_exports.string().nullish(),
|
|
76270
|
-
exitCode: external_exports.number().int().nullish(),
|
|
76271
|
-
type: external_exports.literal("commandExecution")
|
|
76272
|
-
});
|
|
76273
|
-
var fileChangeSchema = external_exports.object({
|
|
76274
|
-
changes: external_exports.array(external_exports.object({ diff: external_exports.string(), path: external_exports.string() })).max(1e4),
|
|
76275
|
-
id: external_exports.string(),
|
|
76276
|
-
status: external_exports.string(),
|
|
76277
|
-
type: external_exports.literal("fileChange")
|
|
76278
|
-
});
|
|
76279
|
-
var mcpToolCallSchema = external_exports.object({
|
|
76280
|
-
arguments: external_exports.unknown().optional(),
|
|
76281
|
-
error: external_exports.unknown().nullish(),
|
|
76282
|
-
id: external_exports.string(),
|
|
76283
|
-
result: external_exports.unknown().nullish(),
|
|
76284
|
-
server: external_exports.string(),
|
|
76285
|
-
status: external_exports.string(),
|
|
76286
|
-
tool: external_exports.string(),
|
|
76287
|
-
type: external_exports.literal("mcpToolCall")
|
|
76288
|
-
});
|
|
76289
|
-
var dynamicToolCallSchema = external_exports.object({
|
|
76290
|
-
arguments: external_exports.unknown().optional(),
|
|
76291
|
-
contentItems: external_exports.array(external_exports.unknown()).max(1e4).nullish(),
|
|
76292
|
-
id: external_exports.string(),
|
|
76293
|
-
namespace: external_exports.string().nullish(),
|
|
76294
|
-
status: external_exports.string(),
|
|
76295
|
-
tool: external_exports.string(),
|
|
76296
|
-
type: external_exports.literal("dynamicToolCall")
|
|
76297
|
-
});
|
|
76298
|
-
var planSchema = external_exports.object({ id: external_exports.string(), text: external_exports.string(), type: external_exports.literal("plan") });
|
|
76299
|
-
var historyItemSchema = external_exports.discriminatedUnion("type", [
|
|
76300
|
-
userMessageSchema,
|
|
76301
|
-
agentMessageSchema,
|
|
76302
|
-
reasoningSchema,
|
|
76303
|
-
commandExecutionSchema,
|
|
76304
|
-
fileChangeSchema,
|
|
76305
|
-
mcpToolCallSchema,
|
|
76306
|
-
dynamicToolCallSchema,
|
|
76307
|
-
planSchema
|
|
76308
|
-
]);
|
|
76309
|
-
var CodexHistoryResponseError = class extends Error {
|
|
76310
|
-
code;
|
|
76311
|
-
constructor(response) {
|
|
76312
|
-
super(response.message);
|
|
76313
|
-
this.code = response.code;
|
|
76314
|
-
this.name = "CodexHistoryResponseError";
|
|
76315
|
-
}
|
|
76316
|
-
};
|
|
76317
|
-
function bounded(value, maximum) {
|
|
76318
|
-
return value.slice(0, maximum);
|
|
76319
|
-
}
|
|
76320
|
-
function activity(activityId, activityType, sequence, fields) {
|
|
76321
|
-
return {
|
|
76322
|
-
activityId: bounded(activityId, 128) || `history-${sequence.toString()}`,
|
|
76323
|
-
activityType,
|
|
76324
|
-
content: [],
|
|
76325
|
-
input: bounded(fields.input, 1e5),
|
|
76326
|
-
locations: fields.locations.filter((location) => location.length > 0).map((location) => bounded(location, 2048)).slice(0, 100),
|
|
76327
|
-
name: bounded(fields.name, 128),
|
|
76328
|
-
output: bounded(fields.output, 1e5),
|
|
76329
|
-
sequence,
|
|
76330
|
-
status: bounded(fields.status, 64),
|
|
76331
|
-
title: bounded(fields.title, 500),
|
|
76332
|
-
toolKind: bounded(fields.toolKind, 64)
|
|
76333
|
-
};
|
|
76334
|
-
}
|
|
76335
|
-
function errorMessage(value) {
|
|
76336
|
-
if (typeof value === "string") {
|
|
76337
|
-
return value;
|
|
76338
|
-
}
|
|
76339
|
-
if (typeof value === "object" && value !== null) {
|
|
76340
|
-
const message = Reflect.get(value, "message");
|
|
76341
|
-
if (typeof message === "string") {
|
|
76342
|
-
return message;
|
|
76343
|
-
}
|
|
76344
|
-
}
|
|
76345
|
-
return JSON.stringify(value) ?? "Codex stopped before completing this turn.";
|
|
76346
|
-
}
|
|
76347
|
-
function formatted(value) {
|
|
76348
|
-
if (value === void 0) {
|
|
76349
|
-
return "";
|
|
76350
|
-
}
|
|
76351
|
-
if (typeof value === "string") {
|
|
76352
|
-
return value;
|
|
76353
|
-
}
|
|
76354
|
-
return JSON.stringify(value) ?? "";
|
|
76355
|
-
}
|
|
76356
|
-
function toolStatus(status) {
|
|
76357
|
-
return status === "inProgress" ? "running" : status === "completed" ? "completed" : "failed";
|
|
76358
|
-
}
|
|
76359
|
-
function diffContent(path7, newText) {
|
|
76360
|
-
return { newText, path: path7, type: "diff" };
|
|
76361
|
-
}
|
|
76362
|
-
function messageSize(message) {
|
|
76363
|
-
return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
|
|
76364
|
-
}
|
|
76365
|
-
var SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT = Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / 2);
|
|
76366
|
-
function fitActivity(activity2, maximumCharacters) {
|
|
76367
|
-
const truncate4 = (limit) => ({
|
|
76368
|
-
...activity2,
|
|
76369
|
-
input: bounded(activity2.input, limit),
|
|
76370
|
-
locations: activity2.locations.map((location) => bounded(location, Math.max(1, limit))),
|
|
76371
|
-
name: bounded(activity2.name, limit),
|
|
76372
|
-
output: bounded(activity2.output, limit),
|
|
76373
|
-
title: bounded(activity2.title, limit),
|
|
76374
|
-
toolKind: bounded(activity2.toolKind, limit)
|
|
76375
|
-
});
|
|
76376
|
-
let minimum = 1;
|
|
76377
|
-
let maximum = 1e5;
|
|
76378
|
-
let fitted = truncate4(0);
|
|
76379
|
-
while (minimum <= maximum) {
|
|
76380
|
-
const limit = Math.floor((minimum + maximum) / 2);
|
|
76381
|
-
const candidate = truncate4(limit);
|
|
76382
|
-
if (JSON.stringify(candidate).length <= maximumCharacters) {
|
|
76383
|
-
fitted = candidate;
|
|
76384
|
-
minimum = limit + 1;
|
|
76385
|
-
} else {
|
|
76386
|
-
maximum = limit - 1;
|
|
76387
|
-
}
|
|
76388
|
-
}
|
|
76389
|
-
return fitted;
|
|
76390
|
-
}
|
|
76391
|
-
function fitActivities(activities, maximumCharacters) {
|
|
76392
|
-
if (activities.length === 0) {
|
|
76393
|
-
return activities;
|
|
76394
|
-
}
|
|
76395
|
-
const arrayCharacters = 2 + activities.length - 1;
|
|
76396
|
-
const maximumActivityCharacters = Math.floor(Math.max(0, maximumCharacters - arrayCharacters) / activities.length);
|
|
76397
|
-
return activities.map((activity2) => fitActivity(activity2, maximumActivityCharacters));
|
|
76398
|
-
}
|
|
76399
|
-
function fitHistoryMessage(message, maximumCharacters = SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT) {
|
|
76400
|
-
const text2 = message.text.slice(-maximumCharacters);
|
|
76401
|
-
if (message.role === "user") {
|
|
76402
|
-
return {
|
|
76403
|
-
message: { ...message, text: text2 },
|
|
76404
|
-
truncated: text2.length < message.text.length
|
|
76405
|
-
};
|
|
76406
|
-
}
|
|
76407
|
-
let activities = message.activities;
|
|
76408
|
-
const content = message.content;
|
|
76409
|
-
let fitted = { ...message, activities, content, text: text2 };
|
|
76410
|
-
if (messageSize(fitted) > maximumCharacters && activities.length > 0) {
|
|
76411
|
-
const maximumActivityCharacters = maximumCharacters - text2.length - JSON.stringify(content).length;
|
|
76412
|
-
activities = fitActivities(activities, maximumActivityCharacters);
|
|
76413
|
-
fitted = { ...fitted, activities };
|
|
76414
|
-
}
|
|
76415
|
-
const excess = Math.max(0, messageSize(fitted) - maximumCharacters);
|
|
76416
|
-
if (excess > 0) {
|
|
76417
|
-
const maximumTextLength = Math.max(0, fitted.text.length - excess);
|
|
76418
|
-
fitted = {
|
|
76419
|
-
...fitted,
|
|
76420
|
-
text: maximumTextLength === 0 ? "" : fitted.text.slice(-maximumTextLength)
|
|
76421
|
-
};
|
|
76422
|
-
}
|
|
76423
|
-
return {
|
|
76424
|
-
message: fitted,
|
|
76425
|
-
truncated: fitted.text.length < message.text.length || JSON.stringify(activities).length < JSON.stringify(message.activities).length
|
|
76426
|
-
};
|
|
76427
|
-
}
|
|
76428
|
-
function turnOutcome2(status) {
|
|
76429
|
-
switch (status) {
|
|
76430
|
-
case "completed":
|
|
76431
|
-
return "succeeded";
|
|
76432
|
-
case "interrupted":
|
|
76433
|
-
return "cancelled";
|
|
76434
|
-
case "failed":
|
|
76435
|
-
return "failed";
|
|
76436
|
-
case "inProgress":
|
|
76437
|
-
return void 0;
|
|
76438
|
-
default: {
|
|
76439
|
-
const unhandled = status;
|
|
76440
|
-
throw new Error(`Unknown Codex turn status: ${String(unhandled)}`);
|
|
76441
|
-
}
|
|
76442
|
-
}
|
|
76443
|
-
}
|
|
76444
|
-
function decodeHistory(thread, value, options) {
|
|
76445
|
-
const page = turnsSchema.parse(value);
|
|
76446
|
-
const nativeTurn = options.nativeTurn?.();
|
|
76447
|
-
const coveredCommandIds = nativeTurn != null && page.data[0]?.id === nativeTurn.nativeTurnId ? [nativeTurn.commandId] : [];
|
|
76448
|
-
const messages = [];
|
|
76449
|
-
let characters = 0;
|
|
76450
|
-
let truncated = page.nextCursor != null;
|
|
76451
|
-
for (const turn of page.data.toReversed()) {
|
|
76452
|
-
const outcome = turnOutcome2(turn.status);
|
|
76453
|
-
const turnMessageCharacterLimit = Math.max(
|
|
76454
|
-
1,
|
|
76455
|
-
Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / Math.max(1, turn.items.length + (turn.error == null ? 0 : 1)))
|
|
76456
|
-
);
|
|
76457
|
-
let sequence = 0;
|
|
76458
|
-
let assistantMessageIndex = null;
|
|
76459
|
-
const append = (message) => {
|
|
76460
|
-
const fitted = fitHistoryMessage(message, turnMessageCharacterLimit);
|
|
76461
|
-
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)) {
|
|
76462
|
-
return;
|
|
76463
|
-
}
|
|
76464
|
-
truncated ||= fitted.truncated;
|
|
76465
|
-
messages.push(fitted.message);
|
|
76466
|
-
if (fitted.message.role === "assistant") {
|
|
76467
|
-
assistantMessageIndex = messages.length - 1;
|
|
76468
|
-
}
|
|
76469
|
-
characters += messageSize(fitted.message);
|
|
76470
|
-
};
|
|
76471
|
-
for (const item of turn.items) {
|
|
76472
|
-
const decoded = historyItemSchema.safeParse(item);
|
|
76473
|
-
if (!decoded.success) {
|
|
76474
|
-
continue;
|
|
76475
|
-
}
|
|
76476
|
-
const historyItem = decoded.data;
|
|
76477
|
-
if (historyItem.type === "userMessage") {
|
|
76478
|
-
const text2 = historyItem.content.map((block) => {
|
|
76479
|
-
const { type } = itemTypeSchema.parse(block);
|
|
76480
|
-
if (type === "text") {
|
|
76481
|
-
return textSchema.parse(block).text;
|
|
76482
|
-
}
|
|
76483
|
-
if (type === "image") {
|
|
76484
|
-
return `[@image](${imageSchema.parse(block).url})`;
|
|
76485
|
-
}
|
|
76486
|
-
return "[Attachment]";
|
|
76487
|
-
}).join("");
|
|
76488
|
-
append({
|
|
76489
|
-
role: "user",
|
|
76490
|
-
text: text2
|
|
76491
|
-
});
|
|
76492
|
-
} else if (historyItem.type === "agentMessage") {
|
|
76493
|
-
append({ activities: [], content: [], role: "assistant", text: historyItem.text });
|
|
76494
|
-
} else if (historyItem.type === "reasoning") {
|
|
76495
|
-
const output2 = (historyItem.content.length > 0 ? historyItem.content : historyItem.summary).join(
|
|
76496
|
-
"\n\n"
|
|
76497
|
-
);
|
|
76498
|
-
if (output2.length > 0) {
|
|
76499
|
-
append({
|
|
76500
|
-
activities: [
|
|
76501
|
-
activity(historyItem.id, "reasoning", sequence, {
|
|
76502
|
-
input: "",
|
|
76503
|
-
locations: [],
|
|
76504
|
-
name: "",
|
|
76505
|
-
output: output2,
|
|
76506
|
-
status: "completed",
|
|
76507
|
-
title: "Reasoning",
|
|
76508
|
-
toolKind: ""
|
|
76509
|
-
})
|
|
76510
|
-
],
|
|
76511
|
-
content: [],
|
|
76512
|
-
role: "assistant",
|
|
76513
|
-
text: ""
|
|
76514
|
-
});
|
|
76515
|
-
sequence += 1;
|
|
76516
|
-
}
|
|
76517
|
-
} else if (historyItem.type === "commandExecution") {
|
|
76518
|
-
const action = historyItem.commandActions[0]?.type ?? "execute";
|
|
76519
|
-
append({
|
|
76520
|
-
activities: [
|
|
76521
|
-
activity(historyItem.id, "tool", sequence, {
|
|
76522
|
-
input: JSON.stringify({ command: historyItem.command, cwd: historyItem.cwd }),
|
|
76523
|
-
locations: [historyItem.cwd],
|
|
76524
|
-
name: "",
|
|
76525
|
-
output: JSON.stringify({
|
|
76526
|
-
formatted_output: historyItem.aggregatedOutput ?? "",
|
|
76527
|
-
...historyItem.exitCode == null ? {} : { exit_code: historyItem.exitCode }
|
|
76528
|
-
}),
|
|
76529
|
-
status: toolStatus(historyItem.status),
|
|
76530
|
-
title: historyItem.command,
|
|
76531
|
-
toolKind: action
|
|
76532
|
-
})
|
|
76533
|
-
],
|
|
76534
|
-
content: [],
|
|
76535
|
-
role: "assistant",
|
|
76536
|
-
text: ""
|
|
76537
|
-
});
|
|
76538
|
-
sequence += 1;
|
|
76539
|
-
} else if (historyItem.type === "fileChange") {
|
|
76540
|
-
const paths = historyItem.changes.map((change) => change.path);
|
|
76541
|
-
const content = historyItem.changes.map(
|
|
76542
|
-
(change) => diffContent(change.path, change.diff)
|
|
76543
|
-
);
|
|
76544
|
-
append({
|
|
76545
|
-
activities: [
|
|
76546
|
-
activity(historyItem.id, "tool", sequence, {
|
|
76547
|
-
input: JSON.stringify({ changes: paths }),
|
|
76548
|
-
locations: paths,
|
|
76549
|
-
name: "",
|
|
76550
|
-
output: "",
|
|
76551
|
-
status: toolStatus(historyItem.status),
|
|
76552
|
-
title: paths.join(", "),
|
|
76553
|
-
toolKind: "edit"
|
|
76554
|
-
})
|
|
76555
|
-
].map((entry) => ({ ...entry, content })),
|
|
76556
|
-
content: [],
|
|
76557
|
-
role: "assistant",
|
|
76558
|
-
text: ""
|
|
76559
|
-
});
|
|
76560
|
-
sequence += 1;
|
|
76561
|
-
} else if (historyItem.type === "mcpToolCall") {
|
|
76562
|
-
append({
|
|
76563
|
-
activities: [
|
|
76564
|
-
activity(historyItem.id, "tool", sequence, {
|
|
76565
|
-
input: formatted(historyItem.arguments),
|
|
76566
|
-
locations: [],
|
|
76567
|
-
name: historyItem.tool,
|
|
76568
|
-
output: formatted(historyItem.error ?? historyItem.result),
|
|
76569
|
-
status: toolStatus(historyItem.status),
|
|
76570
|
-
title: `${historyItem.server}/${historyItem.tool}`,
|
|
76571
|
-
toolKind: "other"
|
|
76572
|
-
})
|
|
76573
|
-
],
|
|
76574
|
-
content: [],
|
|
76575
|
-
role: "assistant",
|
|
76576
|
-
text: ""
|
|
76577
|
-
});
|
|
76578
|
-
sequence += 1;
|
|
76579
|
-
} else if (historyItem.type === "dynamicToolCall") {
|
|
76580
|
-
append({
|
|
76581
|
-
activities: [
|
|
76582
|
-
activity(historyItem.id, "tool", sequence, {
|
|
76583
|
-
input: formatted(historyItem.arguments),
|
|
76584
|
-
locations: [],
|
|
76585
|
-
name: historyItem.tool,
|
|
76586
|
-
output: formatted(historyItem.contentItems),
|
|
76587
|
-
status: toolStatus(historyItem.status),
|
|
76588
|
-
title: historyItem.namespace == null ? historyItem.tool : `${historyItem.namespace}/${historyItem.tool}`,
|
|
76589
|
-
toolKind: "other"
|
|
76590
|
-
})
|
|
76591
|
-
],
|
|
76592
|
-
content: [],
|
|
76593
|
-
role: "assistant",
|
|
76594
|
-
text: ""
|
|
76595
|
-
});
|
|
76596
|
-
sequence += 1;
|
|
76597
|
-
} else if (historyItem.type === "plan") {
|
|
76598
|
-
append({
|
|
76599
|
-
activities: [
|
|
76600
|
-
activity(historyItem.id, "plan", sequence, {
|
|
76601
|
-
input: "",
|
|
76602
|
-
locations: [],
|
|
76603
|
-
name: "",
|
|
76604
|
-
output: historyItem.text,
|
|
76605
|
-
status: "completed",
|
|
76606
|
-
title: "Plan",
|
|
76607
|
-
toolKind: ""
|
|
76608
|
-
})
|
|
76609
|
-
],
|
|
76610
|
-
content: [],
|
|
76611
|
-
role: "assistant",
|
|
76612
|
-
text: ""
|
|
76613
|
-
});
|
|
76614
|
-
sequence += 1;
|
|
76615
|
-
}
|
|
76616
|
-
}
|
|
76617
|
-
if (turn.error != null) {
|
|
76618
|
-
append({
|
|
76619
|
-
activities: [
|
|
76620
|
-
activity(`agent-error-${sequence.toString()}`, "tool", sequence, {
|
|
76621
|
-
input: "",
|
|
76622
|
-
locations: [],
|
|
76623
|
-
name: "",
|
|
76624
|
-
output: errorMessage(turn.error),
|
|
76625
|
-
status: "failed",
|
|
76626
|
-
title: "Agent error",
|
|
76627
|
-
toolKind: "other"
|
|
76628
|
-
})
|
|
76629
|
-
],
|
|
76630
|
-
content: [],
|
|
76631
|
-
role: "assistant",
|
|
76632
|
-
text: ""
|
|
76633
|
-
});
|
|
76634
|
-
}
|
|
76635
|
-
if (assistantMessageIndex !== null) {
|
|
76636
|
-
const assistant = messages[assistantMessageIndex];
|
|
76637
|
-
if (assistant?.role === "assistant") {
|
|
76638
|
-
characters -= messageSize(assistant);
|
|
76639
|
-
const updated = {
|
|
76640
|
-
...assistant,
|
|
76641
|
-
...outcome === void 0 ? {} : { outcome }
|
|
76642
|
-
};
|
|
76643
|
-
const fitted = fitHistoryMessage(updated, turnMessageCharacterLimit);
|
|
76644
|
-
truncated ||= fitted.truncated;
|
|
76645
|
-
messages[assistantMessageIndex] = fitted.message;
|
|
76646
|
-
characters += messageSize(fitted.message);
|
|
76647
|
-
}
|
|
76648
|
-
} else if (outcome !== void 0) {
|
|
76649
|
-
const message = {
|
|
76650
|
-
activities: [],
|
|
76651
|
-
content: [],
|
|
76652
|
-
role: "assistant",
|
|
76653
|
-
...outcome === void 0 ? {} : { outcome },
|
|
76654
|
-
text: ""
|
|
76655
|
-
};
|
|
76656
|
-
const fitted = fitHistoryMessage(message, turnMessageCharacterLimit);
|
|
76657
|
-
truncated ||= fitted.truncated;
|
|
76658
|
-
messages.push(fitted.message);
|
|
76659
|
-
characters += messageSize(fitted.message);
|
|
76660
|
-
}
|
|
76661
|
-
while (messages.length > SESSION_HISTORY_MESSAGE_LIMIT || characters > SESSION_HISTORY_CHARACTER_LIMIT) {
|
|
76662
|
-
const removed = messages.shift();
|
|
76663
|
-
if (removed !== void 0) {
|
|
76664
|
-
characters -= messageSize(removed);
|
|
76665
|
-
}
|
|
76666
|
-
truncated = true;
|
|
76667
|
-
}
|
|
76668
|
-
}
|
|
76669
|
-
return {
|
|
76670
|
-
nativeSessionId: thread.id,
|
|
76671
|
-
cwd: thread.cwd,
|
|
76672
|
-
history: {
|
|
76673
|
-
status: "available",
|
|
76674
|
-
messages,
|
|
76675
|
-
truncated,
|
|
76676
|
-
coveredCommandIds,
|
|
76677
|
-
coveredMessageIds: []
|
|
76678
|
-
}
|
|
76679
|
-
};
|
|
76680
|
-
}
|
|
76681
|
-
async function readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal, options) {
|
|
76682
|
-
signal.throwIfAborted();
|
|
76683
|
-
nativeSessionIdSchema.parse(nativeSessionId);
|
|
76684
|
-
if (agent.id !== "codex" || !await revalidateExecutable(agent.agentIdentity)) {
|
|
76685
|
-
throw new AcpExecutionError(
|
|
76686
|
-
"The local Codex executable changed. Restart Mobius to discover it again.",
|
|
76687
|
-
{},
|
|
76688
|
-
"agent_executable_changed"
|
|
76689
|
-
);
|
|
76690
|
-
}
|
|
76691
|
-
signal.throwIfAborted();
|
|
76692
|
-
const launch = executableLaunch2(agent.agentIdentity.realPath, ["app-server"]);
|
|
76693
|
-
const child = spawn8(launch.command, [...launch.arguments], {
|
|
76694
|
-
cwd,
|
|
76695
|
-
env: { ...process.env, ...agent.environment },
|
|
76696
|
-
...platformSpawnOptions,
|
|
76697
|
-
shell: false,
|
|
76698
|
-
stdio: ["pipe", "pipe", "ignore"]
|
|
76699
|
-
});
|
|
76700
|
-
const response = Promise.withResolvers();
|
|
76701
|
-
let state = { kind: "initializing", requestId: 1 };
|
|
76702
|
-
const seenCursors = /* @__PURE__ */ new Set();
|
|
76703
|
-
let pendingBytes = 0;
|
|
76704
|
-
let pendingFragments = [];
|
|
76705
|
-
const fail = (cause) => response.reject(
|
|
76706
|
-
cause instanceof AcpExecutionError ? cause : new AcpExecutionError(
|
|
76707
|
-
"Saved Codex history could not be read.",
|
|
76708
|
-
{ cause },
|
|
76709
|
-
"native_history_unavailable"
|
|
76710
|
-
)
|
|
76711
|
-
);
|
|
76712
|
-
const send2 = (message) => {
|
|
76713
|
-
child.stdin.write(`${JSON.stringify(message)}
|
|
76714
|
-
`);
|
|
76715
|
-
};
|
|
76716
|
-
const onData = (chunk) => {
|
|
76717
|
-
try {
|
|
76718
|
-
let cursor = 0;
|
|
76719
|
-
let newline = chunk.indexOf("\n");
|
|
76720
|
-
while (newline >= 0) {
|
|
76721
|
-
const fragment = chunk.slice(cursor, newline);
|
|
76722
|
-
const lineBytes = pendingBytes + Buffer.byteLength(fragment);
|
|
76723
|
-
if (lineBytes > 32 * 1024 * 1024) {
|
|
76724
|
-
throw new AcpExecutionError(
|
|
76725
|
-
"This saved conversation is too large to preview.",
|
|
76726
|
-
{},
|
|
76727
|
-
"native_history_too_large"
|
|
76728
|
-
);
|
|
76729
|
-
}
|
|
76730
|
-
const line = pendingFragments.length === 0 ? fragment : [...pendingFragments, fragment].join("");
|
|
76731
|
-
pendingBytes = 0;
|
|
76732
|
-
pendingFragments = [];
|
|
76733
|
-
cursor = newline + 1;
|
|
76734
|
-
newline = chunk.indexOf("\n", cursor);
|
|
76735
|
-
if (line.trim().length === 0) {
|
|
76736
|
-
continue;
|
|
76737
|
-
}
|
|
76738
|
-
const value = JSON.parse(line);
|
|
76739
|
-
const message = responseSchema.parse(value);
|
|
76740
|
-
if (!("id" in message)) {
|
|
76741
|
-
continue;
|
|
76742
|
-
}
|
|
76743
|
-
if (message.id !== state.requestId) {
|
|
76744
|
-
throw new AcpExecutionError(
|
|
76745
|
-
"Codex returned an invalid history response.",
|
|
76746
|
-
{},
|
|
76747
|
-
"invalid_native_session_response"
|
|
76748
|
-
);
|
|
76749
|
-
}
|
|
76750
|
-
if ("error" in message) {
|
|
76751
|
-
fail(
|
|
76752
|
-
new AcpExecutionError(
|
|
76753
|
-
"Saved Codex history could not be read.",
|
|
76754
|
-
{ cause: new CodexHistoryResponseError(message.error) },
|
|
76755
|
-
"native_history_unavailable"
|
|
76756
|
-
)
|
|
76757
|
-
);
|
|
76758
|
-
return;
|
|
76759
|
-
}
|
|
76760
|
-
switch (state.kind) {
|
|
76761
|
-
case "initializing":
|
|
76762
|
-
state = { kind: "metadata", requestId: 2 };
|
|
76763
|
-
send2({ method: "initialized", params: {} });
|
|
76764
|
-
send2({
|
|
76765
|
-
id: state.requestId,
|
|
76766
|
-
method: "thread/read",
|
|
76767
|
-
params: { threadId: nativeSessionId, includeTurns: false }
|
|
76768
|
-
});
|
|
76769
|
-
break;
|
|
76770
|
-
case "metadata": {
|
|
76771
|
-
const { thread } = threadSchema.parse(message.result);
|
|
76772
|
-
state = { kind: "turns", requestId: 3, thread, pages: [] };
|
|
76773
|
-
send2({
|
|
76774
|
-
id: state.requestId,
|
|
76775
|
-
method: "thread/turns/list",
|
|
76776
|
-
params: {
|
|
76777
|
-
threadId: nativeSessionId,
|
|
76778
|
-
limit: SESSION_HISTORY_PREVIEW_TURN_LIMIT,
|
|
76779
|
-
sortDirection: "desc",
|
|
76780
|
-
itemsView: "full"
|
|
76781
|
-
}
|
|
76782
|
-
});
|
|
76783
|
-
break;
|
|
76784
|
-
}
|
|
76785
|
-
case "turns": {
|
|
76786
|
-
const page = turnsSchema.parse(message.result);
|
|
76787
|
-
const pages = [...state.pages, ...page.data];
|
|
76788
|
-
const maxTurns = SESSION_HISTORY_MESSAGE_LIMIT;
|
|
76789
|
-
if (page.nextCursor == null || pages.length >= maxTurns) {
|
|
76790
|
-
response.resolve(
|
|
76791
|
-
decodeHistory(
|
|
76792
|
-
state.thread,
|
|
76793
|
-
{
|
|
76794
|
-
data: pages.slice(0, maxTurns),
|
|
76795
|
-
nextCursor: page.nextCursor
|
|
76796
|
-
},
|
|
76797
|
-
options
|
|
76798
|
-
)
|
|
76799
|
-
);
|
|
76800
|
-
return;
|
|
76801
|
-
}
|
|
76802
|
-
if (page.data.length === 0 || seenCursors.has(page.nextCursor)) {
|
|
76803
|
-
throw new AcpExecutionError(
|
|
76804
|
-
"Codex repeated a history page cursor.",
|
|
76805
|
-
{},
|
|
76806
|
-
"invalid_native_session_response"
|
|
76807
|
-
);
|
|
76808
|
-
}
|
|
76809
|
-
seenCursors.add(page.nextCursor);
|
|
76810
|
-
state = { kind: "turns", requestId: state.requestId + 1, thread: state.thread, pages };
|
|
76811
|
-
send2({
|
|
76812
|
-
id: state.requestId,
|
|
76813
|
-
method: "thread/turns/list",
|
|
76814
|
-
params: {
|
|
76815
|
-
threadId: nativeSessionId,
|
|
76816
|
-
cursor: page.nextCursor,
|
|
76817
|
-
limit: Math.min(SESSION_HISTORY_PREVIEW_TURN_LIMIT, maxTurns - pages.length),
|
|
76818
|
-
sortDirection: "desc",
|
|
76819
|
-
itemsView: "full"
|
|
76820
|
-
}
|
|
76821
|
-
});
|
|
76822
|
-
break;
|
|
76823
|
-
}
|
|
76824
|
-
default: {
|
|
76825
|
-
const unhandled = state;
|
|
76826
|
-
throw new Error(`Unknown history read state: ${String(unhandled)}`);
|
|
76827
|
-
}
|
|
76828
|
-
}
|
|
76829
|
-
}
|
|
76830
|
-
const remainder = chunk.slice(cursor);
|
|
76831
|
-
if (remainder.length > 0) {
|
|
76832
|
-
pendingBytes += Buffer.byteLength(remainder);
|
|
76833
|
-
if (pendingBytes > 32 * 1024 * 1024) {
|
|
76834
|
-
throw new AcpExecutionError(
|
|
76835
|
-
"This saved conversation is too large to preview.",
|
|
76836
|
-
{},
|
|
76837
|
-
"native_history_too_large"
|
|
76838
|
-
);
|
|
76839
|
-
}
|
|
76840
|
-
pendingFragments.push(remainder);
|
|
76841
|
-
}
|
|
76842
|
-
} catch (cause) {
|
|
76843
|
-
fail(cause);
|
|
76844
|
-
}
|
|
76845
|
-
};
|
|
76846
|
-
const abort = () => response.reject(signal.reason);
|
|
76847
|
-
const onExit = () => fail(
|
|
76848
|
-
new AcpExecutionError(
|
|
76849
|
-
"Codex stopped before its saved history was available.",
|
|
76850
|
-
{},
|
|
76851
|
-
"native_history_unavailable"
|
|
76852
|
-
)
|
|
76853
|
-
);
|
|
76854
|
-
const timeout = setTimeout(
|
|
76855
|
-
() => fail(new AcpExecutionError("Reading saved Codex history timed out.", {}, "native_history_timeout")),
|
|
76856
|
-
6e4
|
|
76857
|
-
);
|
|
76858
|
-
child.stdout.setEncoding("utf8");
|
|
76859
|
-
child.stdout.on("data", onData);
|
|
76860
|
-
child.stdin.on("error", fail);
|
|
76861
|
-
child.on("error", fail);
|
|
76862
|
-
child.on("exit", onExit);
|
|
76863
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
76864
|
-
try {
|
|
76865
|
-
if (signal.aborted) {
|
|
76866
|
-
abort();
|
|
76867
|
-
} else {
|
|
76868
|
-
send2({
|
|
76869
|
-
id: 1,
|
|
76870
|
-
method: "initialize",
|
|
76871
|
-
params: { clientInfo: { name: "mobius_history", version: "1.0.0" } }
|
|
76872
|
-
});
|
|
76873
|
-
}
|
|
76874
|
-
const snapshot = await response.promise;
|
|
76875
|
-
return {
|
|
76876
|
-
...snapshot,
|
|
76877
|
-
history: await embedLocalHistoryImages(snapshot.history, signal)
|
|
76878
|
-
};
|
|
76879
|
-
} finally {
|
|
76880
|
-
clearTimeout(timeout);
|
|
76881
|
-
signal.removeEventListener("abort", abort);
|
|
76882
|
-
child.stdout.removeListener("data", onData);
|
|
76883
|
-
if (child.pid !== void 0) {
|
|
76884
|
-
await stopProcessTree(child);
|
|
76885
|
-
}
|
|
76886
|
-
child.stdin.removeListener("error", fail);
|
|
76887
|
-
child.removeListener("error", fail);
|
|
76888
|
-
child.removeListener("exit", onExit);
|
|
76889
|
-
}
|
|
76890
|
-
}
|
|
76891
|
-
var readCodexFullHistory = async (agent, cwd, nativeSessionId, signal, nativeTurn) => await readCodexHistoryWithOptions(agent, cwd, nativeSessionId, signal, {
|
|
76892
|
-
...nativeTurn === void 0 ? {} : { nativeTurn }
|
|
76893
|
-
});
|
|
76894
|
-
|
|
76895
|
-
// src/acp/native-history/codex/native-history-events.ts
|
|
76896
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
76897
|
-
function toolKind(value) {
|
|
76898
|
-
switch (value) {
|
|
76899
|
-
case "read":
|
|
76900
|
-
case "edit":
|
|
76901
|
-
case "delete":
|
|
76902
|
-
case "move":
|
|
76903
|
-
case "search":
|
|
76904
|
-
case "execute":
|
|
76905
|
-
case "think":
|
|
76906
|
-
case "fetch":
|
|
76907
|
-
case "switch_mode":
|
|
76908
|
-
case "other":
|
|
76909
|
-
return value;
|
|
76910
|
-
default:
|
|
76911
|
-
return "other";
|
|
76912
|
-
}
|
|
76913
|
-
}
|
|
76914
|
-
function toolStatus2(value) {
|
|
76915
|
-
switch (value) {
|
|
76916
|
-
case "pending":
|
|
76917
|
-
return "pending";
|
|
76918
|
-
case "running":
|
|
76919
|
-
case "in_progress":
|
|
76920
|
-
return "in_progress";
|
|
76921
|
-
case "completed":
|
|
76922
|
-
return "completed";
|
|
76923
|
-
default:
|
|
76924
|
-
return "failed";
|
|
76925
|
-
}
|
|
76926
|
-
}
|
|
76927
|
-
function activityEvent(activity2) {
|
|
76928
|
-
if (activity2.activityType === "reasoning") {
|
|
76929
|
-
return {
|
|
76930
|
-
payload: {
|
|
76931
|
-
content: { text: activity2.output, type: "text" },
|
|
76932
|
-
messageId: activity2.activityId,
|
|
76933
|
-
sessionUpdate: "agent_thought_chunk"
|
|
76934
|
-
},
|
|
76935
|
-
type: "acp"
|
|
76936
|
-
};
|
|
76937
|
-
}
|
|
76938
|
-
return {
|
|
76939
|
-
payload: {
|
|
76940
|
-
content: activity2.content,
|
|
76941
|
-
kind: toolKind(activity2.toolKind),
|
|
76942
|
-
locations: activity2.locations.map((path7) => ({ path: path7 })),
|
|
76943
|
-
rawInput: activity2.input,
|
|
76944
|
-
rawOutput: activity2.output,
|
|
76945
|
-
sessionUpdate: "tool_call",
|
|
76946
|
-
status: toolStatus2(activity2.status),
|
|
76947
|
-
title: activity2.title,
|
|
76948
|
-
toolCallId: activity2.activityId,
|
|
76949
|
-
...activity2.name.length === 0 ? {} : { name: activity2.name }
|
|
76950
|
-
},
|
|
76951
|
-
type: "acp"
|
|
76952
|
-
};
|
|
76953
|
-
}
|
|
76954
|
-
function contentEvent(sessionUpdate, messageId, content) {
|
|
76955
|
-
return { payload: { content, messageId, sessionUpdate }, type: "acp" };
|
|
76956
|
-
}
|
|
76957
|
-
function historyEvents(history) {
|
|
76958
|
-
return history.messages.flatMap((message, index2) => {
|
|
76959
|
-
const messageId = `native-history-${index2.toString()}`;
|
|
76960
|
-
const sessionUpdate = message.role === "user" ? "user_message_chunk" : "agent_message_chunk";
|
|
76961
|
-
const images = (message.images ?? []).map(
|
|
76962
|
-
(image) => contentEvent(sessionUpdate, messageId, {
|
|
76963
|
-
data: image.data,
|
|
76964
|
-
mimeType: image.mimeType,
|
|
76965
|
-
type: "image"
|
|
76966
|
-
})
|
|
76967
|
-
);
|
|
76968
|
-
const text2 = message.text.length === 0 ? [] : [contentEvent(sessionUpdate, messageId, { text: message.text, type: "text" })];
|
|
76969
|
-
if (message.role === "user") {
|
|
76970
|
-
return [...images, ...text2];
|
|
76971
|
-
}
|
|
76972
|
-
const activities = message.activities.map(activityEvent);
|
|
76973
|
-
const content = message.content.map((block) => contentEvent(sessionUpdate, messageId, block));
|
|
76974
|
-
return [...activities, ...content, ...images, ...text2];
|
|
76975
|
-
});
|
|
76976
|
-
}
|
|
76977
|
-
function nativeHistoryEvents(sessionId, nativeSessionId, history, eventLimit, cursor, eventStore) {
|
|
76978
|
-
const events = historyEvents(history);
|
|
76979
|
-
const generationId = createHash2("sha256").update(nativeSessionId).update("\0").update(JSON.stringify(events)).digest("hex");
|
|
76980
|
-
eventStore.materialize(sessionId, generationId, events);
|
|
76981
|
-
return eventStore.page(sessionId, eventLimit, cursor);
|
|
76982
|
-
}
|
|
76296
|
+
// src/acp/adapter/codex/adapter.ts
|
|
76297
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
76983
76298
|
|
|
76984
76299
|
// src/storage/session/temporary-session-event-cache.ts
|
|
76985
76300
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
@@ -82189,13 +81504,85 @@ function openPreviewEventCache() {
|
|
|
82189
81504
|
}
|
|
82190
81505
|
}
|
|
82191
81506
|
|
|
81507
|
+
// src/acp/adapter/codex/tool-event.ts
|
|
81508
|
+
var toolEventSchema = external_exports.looseObject({
|
|
81509
|
+
sessionUpdate: external_exports.enum(["tool_call", "tool_call_update"]),
|
|
81510
|
+
rawInput: external_exports.unknown().optional(),
|
|
81511
|
+
rawOutput: external_exports.unknown().optional()
|
|
81512
|
+
});
|
|
81513
|
+
var TRUNCATED_TOOL_PAYLOAD_CHARACTER_LIMIT = 32768;
|
|
81514
|
+
var MAX_TOOL_PAYLOAD_DEPTH = 16;
|
|
81515
|
+
function payloadText(value) {
|
|
81516
|
+
let text2;
|
|
81517
|
+
try {
|
|
81518
|
+
text2 = JSON.stringify(value) ?? "";
|
|
81519
|
+
} catch {
|
|
81520
|
+
text2 = "Tool payload could not be represented as JSON.";
|
|
81521
|
+
}
|
|
81522
|
+
return text2.slice(0, TRUNCATED_TOOL_PAYLOAD_CHARACTER_LIMIT);
|
|
81523
|
+
}
|
|
81524
|
+
function fitNesting(value, depth = 0) {
|
|
81525
|
+
if (typeof value !== "object" || value === null) {
|
|
81526
|
+
return value;
|
|
81527
|
+
}
|
|
81528
|
+
if (depth === MAX_TOOL_PAYLOAD_DEPTH && Object.keys(value).length > 0) {
|
|
81529
|
+
return `[truncated: nesting depth] ${payloadText(value)}`;
|
|
81530
|
+
}
|
|
81531
|
+
if (Array.isArray(value)) {
|
|
81532
|
+
return value.map((child) => fitNesting(child, depth + 1));
|
|
81533
|
+
}
|
|
81534
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, fitNesting(child, depth + 1)]));
|
|
81535
|
+
}
|
|
81536
|
+
function prepareCodexToolUpdate(update) {
|
|
81537
|
+
if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
|
|
81538
|
+
return update;
|
|
81539
|
+
}
|
|
81540
|
+
return {
|
|
81541
|
+
...update,
|
|
81542
|
+
...update.rawOutput === void 0 ? {} : { rawOutput: fitNesting(update.rawOutput) },
|
|
81543
|
+
...update._meta == null ? {} : {
|
|
81544
|
+
_meta: Object.fromEntries(
|
|
81545
|
+
Object.entries(update._meta).map(([key, child]) => [key, fitNesting(child, 1)])
|
|
81546
|
+
)
|
|
81547
|
+
}
|
|
81548
|
+
};
|
|
81549
|
+
}
|
|
81550
|
+
function fitPayload(value) {
|
|
81551
|
+
if (value === void 0 || boundedJsonSchema.safeParse(value).success) {
|
|
81552
|
+
return value;
|
|
81553
|
+
}
|
|
81554
|
+
return { truncated: true, text: payloadText(value) };
|
|
81555
|
+
}
|
|
81556
|
+
function fitCodexToolEvent(event) {
|
|
81557
|
+
const decoded = toolEventSchema.safeParse(event);
|
|
81558
|
+
if (!decoded.success) {
|
|
81559
|
+
return event;
|
|
81560
|
+
}
|
|
81561
|
+
return {
|
|
81562
|
+
...decoded.data,
|
|
81563
|
+
rawInput: fitPayload(decoded.data.rawInput),
|
|
81564
|
+
rawOutput: fitPayload(decoded.data.rawOutput)
|
|
81565
|
+
};
|
|
81566
|
+
}
|
|
81567
|
+
|
|
82192
81568
|
// src/acp/adapter/codex/adapter.ts
|
|
82193
81569
|
var CodexAdapter = class {
|
|
82194
81570
|
#queryProcesses;
|
|
82195
81571
|
#connector;
|
|
81572
|
+
#dependencies;
|
|
81573
|
+
#contentExternalizer;
|
|
82196
81574
|
#previewCache = null;
|
|
82197
81575
|
constructor(dependencies) {
|
|
82198
|
-
this.#
|
|
81576
|
+
this.#dependencies = dependencies;
|
|
81577
|
+
this.#contentExternalizer = {
|
|
81578
|
+
update: async (sessionId, update, signal) => {
|
|
81579
|
+
signal.throwIfAborted();
|
|
81580
|
+
const prepared = prepareCodexToolUpdate(update);
|
|
81581
|
+
signal.throwIfAborted();
|
|
81582
|
+
return await dependencies.contentExternalizer.update(sessionId, prepared, signal);
|
|
81583
|
+
}
|
|
81584
|
+
};
|
|
81585
|
+
this.#connector = new AcpSessionConnector(this.#contentExternalizer, fitCodexToolEvent);
|
|
82199
81586
|
this.#queryProcesses = new AgentQueryProcesses(dependencies.processes, this.#connector);
|
|
82200
81587
|
}
|
|
82201
81588
|
capabilities = async (query) => await this.#queryProcesses.capabilities(query);
|
|
@@ -82209,21 +81596,73 @@ var CodexAdapter = class {
|
|
|
82209
81596
|
}
|
|
82210
81597
|
};
|
|
82211
81598
|
previewSessionEvents = async (query, request) => {
|
|
82212
|
-
const { agent, cwd
|
|
81599
|
+
const { agent, cwd } = query;
|
|
81600
|
+
const signal = AbortSignal.any([query.signal, AbortSignal.timeout(6e4)]);
|
|
82213
81601
|
const { sessionId } = request;
|
|
82214
|
-
|
|
82215
|
-
|
|
82216
|
-
if (
|
|
82217
|
-
throw new AcpExecutionError(
|
|
81602
|
+
signal.throwIfAborted();
|
|
81603
|
+
nativeSessionIdSchema.parse(request.nativeSessionId);
|
|
81604
|
+
if (agent.id !== "codex") {
|
|
81605
|
+
throw new AcpExecutionError(
|
|
81606
|
+
"The Codex adapter cannot preview history for another agent.",
|
|
81607
|
+
{},
|
|
81608
|
+
"agent_adapter_mismatch"
|
|
81609
|
+
);
|
|
82218
81610
|
}
|
|
82219
|
-
|
|
82220
|
-
|
|
82221
|
-
|
|
82222
|
-
|
|
82223
|
-
|
|
82224
|
-
|
|
82225
|
-
|
|
81611
|
+
if (!await revalidateExecutable(agent.agentIdentity)) {
|
|
81612
|
+
throw new AcpExecutionError(
|
|
81613
|
+
"The local Codex executable changed. Restart Mobius to discover it again.",
|
|
81614
|
+
{},
|
|
81615
|
+
"agent_executable_changed"
|
|
81616
|
+
);
|
|
81617
|
+
}
|
|
81618
|
+
this.#previewCache ??= openPreviewEventCache();
|
|
81619
|
+
const events = [];
|
|
81620
|
+
await this.#dependencies.processes.runTransient(
|
|
81621
|
+
signal,
|
|
81622
|
+
async () => {
|
|
81623
|
+
const client2 = new CodexAppServerClient({
|
|
81624
|
+
command: agent.command,
|
|
81625
|
+
cwd,
|
|
81626
|
+
environment: agent.environment,
|
|
81627
|
+
handlers: {
|
|
81628
|
+
onNotification: async () => void 0,
|
|
81629
|
+
onServerRequest: async () => {
|
|
81630
|
+
throw new AcpExecutionError(
|
|
81631
|
+
"Unexpected request while reading saved history",
|
|
81632
|
+
{},
|
|
81633
|
+
"invalid_native_session_response"
|
|
81634
|
+
);
|
|
81635
|
+
}
|
|
81636
|
+
}
|
|
81637
|
+
});
|
|
81638
|
+
return {
|
|
81639
|
+
client: client2,
|
|
81640
|
+
closeProcess: async () => {
|
|
81641
|
+
client2.detach();
|
|
81642
|
+
await stopProcessTree(client2.child());
|
|
81643
|
+
}
|
|
81644
|
+
};
|
|
81645
|
+
},
|
|
81646
|
+
async ({ client: client2 }) => {
|
|
81647
|
+
await client2.initialize(signal);
|
|
81648
|
+
return await replayCodexHistory(
|
|
81649
|
+
client2,
|
|
81650
|
+
request.nativeSessionId,
|
|
81651
|
+
async (update) => {
|
|
81652
|
+
const externalized = await this.#contentExternalizer.update(sessionId, update, signal);
|
|
81653
|
+
events.push({
|
|
81654
|
+
type: "acp",
|
|
81655
|
+
payload: decodeAcpSessionUpdate(JSON.stringify(fitCodexToolEvent(externalized.event)))
|
|
81656
|
+
});
|
|
81657
|
+
},
|
|
81658
|
+
signal
|
|
81659
|
+
);
|
|
81660
|
+
},
|
|
81661
|
+
async (runtime) => await runtime.closeProcess()
|
|
82226
81662
|
);
|
|
81663
|
+
const generationId = createHash4("sha256").update(request.nativeSessionId).update("\0").update(JSON.stringify(events)).digest("hex");
|
|
81664
|
+
this.#previewCache.events.materialize(sessionId, generationId, events);
|
|
81665
|
+
return this.#previewCache.events.page(sessionId, request.eventLimit, request.cursor);
|
|
82227
81666
|
};
|
|
82228
81667
|
};
|
|
82229
81668
|
|
|
@@ -82262,18 +81701,6 @@ var harnessAdapters = (agent, dependencies) => {
|
|
|
82262
81701
|
|
|
82263
81702
|
// src/acp/content/content-externalizer.ts
|
|
82264
81703
|
var MAXIMUM_ENCODED_CONTENT_CHARACTERS = 4e6;
|
|
82265
|
-
var MAXIMUM_REASONING_CHUNK_BYTES = 24 * 1024;
|
|
82266
|
-
function reasoningTail(text2) {
|
|
82267
|
-
if (Buffer.byteLength(text2, "utf8") <= MAXIMUM_REASONING_CHUNK_BYTES) {
|
|
82268
|
-
return text2;
|
|
82269
|
-
}
|
|
82270
|
-
const bytes = Buffer.from(text2, "utf8");
|
|
82271
|
-
let start = bytes.length - MAXIMUM_REASONING_CHUNK_BYTES;
|
|
82272
|
-
while (start < bytes.length && (bytes.readUInt8(start) & 192) === 128) {
|
|
82273
|
-
start += 1;
|
|
82274
|
-
}
|
|
82275
|
-
return bytes.toString("utf8", start);
|
|
82276
|
-
}
|
|
82277
81704
|
function decodeBase64(data) {
|
|
82278
81705
|
if (data.length > MAXIMUM_ENCODED_CONTENT_CHARACTERS || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)) {
|
|
82279
81706
|
throw new Error("The ACP embedded content is not valid bounded base64");
|
|
@@ -82469,24 +81896,7 @@ var AcpContentExternalizer = class {
|
|
|
82469
81896
|
}
|
|
82470
81897
|
update = async (sessionId, update, signal) => {
|
|
82471
81898
|
switch (update.sessionUpdate) {
|
|
82472
|
-
case "agent_thought_chunk":
|
|
82473
|
-
if (update.content.type === "text") {
|
|
82474
|
-
const text2 = reasoningTail(update.content.text);
|
|
82475
|
-
const bounded2 = { ...update, content: { ...update.content, text: text2 } };
|
|
82476
|
-
return {
|
|
82477
|
-
agent: bounded2,
|
|
82478
|
-
event: {
|
|
82479
|
-
...bounded2,
|
|
82480
|
-
...text2 === update.content.text ? {} : { meta: { truncated: true } }
|
|
82481
|
-
}
|
|
82482
|
-
};
|
|
82483
|
-
}
|
|
82484
|
-
const content = await this.#content(sessionId, update.content, signal);
|
|
82485
|
-
return {
|
|
82486
|
-
agent: { ...update, content: content.agent },
|
|
82487
|
-
event: { ...update, content: content.event }
|
|
82488
|
-
};
|
|
82489
|
-
}
|
|
81899
|
+
case "agent_thought_chunk":
|
|
82490
81900
|
case "user_message_chunk":
|
|
82491
81901
|
case "agent_message_chunk":
|
|
82492
81902
|
case "compaction_summary_chunk": {
|
|
@@ -82648,7 +82058,7 @@ import { randomUUID as randomUUID10 } from "node:crypto";
|
|
|
82648
82058
|
import { resolve as resolve14 } from "node:path";
|
|
82649
82059
|
|
|
82650
82060
|
// src/storage/installation/installation-files.ts
|
|
82651
|
-
import { createHash as
|
|
82061
|
+
import { createHash as createHash5, randomUUID as randomUUID9 } from "node:crypto";
|
|
82652
82062
|
import { mkdir as mkdir4, open as open5, readdir as readdir5, rename as rename3, unlink as unlink3, writeFile } from "node:fs/promises";
|
|
82653
82063
|
import { dirname as dirname9, join as join23 } from "node:path";
|
|
82654
82064
|
|
|
@@ -82675,7 +82085,7 @@ function connectionFilePath(connectionDirectory2, connectionId2) {
|
|
|
82675
82085
|
return join23(connectionDirectory2, `${connectionId2}.json`);
|
|
82676
82086
|
}
|
|
82677
82087
|
function channelIndexFilePath(installationDirectory2, channelId) {
|
|
82678
|
-
return join23(installationDirectory2, "channels", `mci_${
|
|
82088
|
+
return join23(installationDirectory2, "channels", `mci_${createHash5("sha256").update(channelId).digest("hex")}.json`);
|
|
82679
82089
|
}
|
|
82680
82090
|
async function readInstallationFile(path7) {
|
|
82681
82091
|
let handle;
|
|
@@ -86984,7 +86394,7 @@ async function settleAbandonedTurn(projection, operations, cancellation) {
|
|
|
86984
86394
|
}
|
|
86985
86395
|
|
|
86986
86396
|
// src/session/turn/execution-receipts.ts
|
|
86987
|
-
import { createHash as
|
|
86397
|
+
import { createHash as createHash6, randomUUID as randomUUID12 } from "node:crypto";
|
|
86988
86398
|
var MAX_TERMINAL_RECEIPTS = 1024;
|
|
86989
86399
|
function isTerminal(state) {
|
|
86990
86400
|
return state === "succeeded" || state === "failed" || state === "cancelled";
|
|
@@ -87100,7 +86510,7 @@ var ExecutionReceipts = class {
|
|
|
87100
86510
|
];
|
|
87101
86511
|
});
|
|
87102
86512
|
claimExecution = (commandId, sessionId, commandJson) => {
|
|
87103
|
-
const commandHash =
|
|
86513
|
+
const commandHash = createHash6("sha256").update(commandJson).digest("hex");
|
|
87104
86514
|
let existing = this.#executions.get(commandId);
|
|
87105
86515
|
const previous = this.outcome(commandId);
|
|
87106
86516
|
if (existing?.sessionId === sessionId && !existing.started && previous?.type === "lifecycle-metadata" && previous.payload.kind === "prompt.failed-before-start" && previous.payload.code === "runtime_restarted") {
|
|
@@ -87453,9 +86863,9 @@ var SessionTurns = class {
|
|
|
87453
86863
|
#bySessionId = /* @__PURE__ */ new Map();
|
|
87454
86864
|
#operations;
|
|
87455
86865
|
#activity;
|
|
87456
|
-
constructor(operations,
|
|
86866
|
+
constructor(operations, activity = new RuntimeTurnActivity()) {
|
|
87457
86867
|
this.#operations = operations;
|
|
87458
|
-
this.#activity =
|
|
86868
|
+
this.#activity = activity;
|
|
87459
86869
|
}
|
|
87460
86870
|
acceptsPrompts = () => this.#activity.acceptsPrompts();
|
|
87461
86871
|
session = (sessionId) => {
|
|
@@ -87788,7 +87198,7 @@ function buildSessionLayer(options) {
|
|
|
87788
87198
|
}
|
|
87789
87199
|
|
|
87790
87200
|
// src/session/content/external-content-store.ts
|
|
87791
|
-
import { createHash as
|
|
87201
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
87792
87202
|
import { join as join27 } from "node:path";
|
|
87793
87203
|
|
|
87794
87204
|
// src/storage/files/scratch-directory.ts
|
|
@@ -87912,7 +87322,7 @@ var LocalExternalContentStore = class {
|
|
|
87912
87322
|
const active = AbortSignal.any([signal, this.#lifetime.signal]);
|
|
87913
87323
|
active.throwIfAborted();
|
|
87914
87324
|
const metadata = metadataSchema.parse({ kind, mediaType, name: name2 });
|
|
87915
|
-
const key =
|
|
87325
|
+
const key = createHash7("sha256").update(bytes).digest("hex");
|
|
87916
87326
|
const request = `mobius-content:${kind}:${key}`;
|
|
87917
87327
|
const existing = this.#entries.get(request);
|
|
87918
87328
|
if (existing !== void 0 && existing.expiresAt > Date.now()) {
|
|
@@ -88777,7 +88187,7 @@ var SessionError = class extends OperationError {
|
|
|
88777
88187
|
};
|
|
88778
88188
|
|
|
88779
88189
|
// src/session/settings/discover-agent-settings.ts
|
|
88780
|
-
import { createHash as
|
|
88190
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
88781
88191
|
|
|
88782
88192
|
// src/agent/settings/agent-settings-base.ts
|
|
88783
88193
|
var AgentSettingsLaunchSelectionResult = class {
|
|
@@ -89095,7 +88505,7 @@ function settingsRevision(agent, reportedAgentVersion, settings, modelEffort) {
|
|
|
89095
88505
|
unsupportedModelIds: modelEffort.unsupportedModelIds,
|
|
89096
88506
|
valuesByModel: {}
|
|
89097
88507
|
};
|
|
89098
|
-
return
|
|
88508
|
+
return createHash8("sha256").update(
|
|
89099
88509
|
JSON.stringify({
|
|
89100
88510
|
adapterVersion: agent.kind === "acp-adapter-process" ? agent.adapterVersion : agent.agentVersion,
|
|
89101
88511
|
agentId: agent.id,
|
|
@@ -89404,35 +88814,7 @@ async function resolveSessionDirectories(directories, bindingId, directoryId, ad
|
|
|
89404
88814
|
}
|
|
89405
88815
|
|
|
89406
88816
|
// src/runtime/command/registry/history.ts
|
|
89407
|
-
function
|
|
89408
|
-
return event?.type === "acp" && event.payload.sessionUpdate === "agent_thought_chunk";
|
|
89409
|
-
}
|
|
89410
|
-
function omitAgentReasoning(events) {
|
|
89411
|
-
const retained = [];
|
|
89412
|
-
let previousReasoningMessageId;
|
|
89413
|
-
for (const positioned of events) {
|
|
89414
|
-
const { event } = positioned;
|
|
89415
|
-
if (event.type !== "acp" || event.payload.sessionUpdate !== "agent_thought_chunk") {
|
|
89416
|
-
previousReasoningMessageId = void 0;
|
|
89417
|
-
retained.push(positioned);
|
|
89418
|
-
continue;
|
|
89419
|
-
}
|
|
89420
|
-
const messageId = event.payload.messageId ?? null;
|
|
89421
|
-
if (previousReasoningMessageId === void 0 || previousReasoningMessageId !== messageId) {
|
|
89422
|
-
retained.push({
|
|
89423
|
-
...positioned,
|
|
89424
|
-
event: {
|
|
89425
|
-
...event,
|
|
89426
|
-
mobiusMetadata: { omitted: true },
|
|
89427
|
-
payload: { ...event.payload, content: { text: "", type: "text" } }
|
|
89428
|
-
}
|
|
89429
|
-
});
|
|
89430
|
-
}
|
|
89431
|
-
previousReasoningMessageId = messageId;
|
|
89432
|
-
}
|
|
89433
|
-
return retained;
|
|
89434
|
-
}
|
|
89435
|
-
async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoning, queuedPromptRequests, load) {
|
|
88817
|
+
async function loadHistoryPage(sessionId, eventLimit, initialCursor, queuedPromptRequests, load) {
|
|
89436
88818
|
let cursor = initialCursor;
|
|
89437
88819
|
let loaded = [];
|
|
89438
88820
|
let sessionGenerationId = null;
|
|
@@ -89459,9 +88841,7 @@ async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoni
|
|
|
89459
88841
|
});
|
|
89460
88842
|
loaded = [...events, ...loaded];
|
|
89461
88843
|
sourceNextCursor = replay.nextCursor;
|
|
89462
|
-
|
|
89463
|
-
const reasoningContinuesBeforePage = sourceNextCursor !== null && isAgentReasoning(loaded[0]?.event);
|
|
89464
|
-
if (visible2.length >= eventLimit && !reasoningContinuesBeforePage) {
|
|
88844
|
+
if (loaded.length >= eventLimit) {
|
|
89465
88845
|
break;
|
|
89466
88846
|
}
|
|
89467
88847
|
cursor = sourceNextCursor;
|
|
@@ -89469,8 +88849,7 @@ async function loadHistoryPage(sessionId, eventLimit, initialCursor, omitReasoni
|
|
|
89469
88849
|
if (sessionGenerationId === null || throughPosition === null) {
|
|
89470
88850
|
throw new SessionError("session_history_unavailable", "The Session history is unavailable");
|
|
89471
88851
|
}
|
|
89472
|
-
const
|
|
89473
|
-
const orderedEvents = visible.slice(-eventLimit);
|
|
88852
|
+
const orderedEvents = loaded.slice(-eventLimit);
|
|
89474
88853
|
const nextCursor = orderedEvents[0]?.cursor ?? null;
|
|
89475
88854
|
return {
|
|
89476
88855
|
events: {
|
|
@@ -89512,7 +88891,6 @@ async function executeSessionHistoryPageLoad(socket, command, config2, resolveAg
|
|
|
89512
88891
|
command.sessionId,
|
|
89513
88892
|
command.eventLimit,
|
|
89514
88893
|
command.cursor,
|
|
89515
|
-
command.omit?.includes("agent-reasoning") === true,
|
|
89516
88894
|
recovery.queuedPromptRequests,
|
|
89517
88895
|
async (eventLimit, cursor) => await sessions.loadSessionEvents(loadOptions, eventLimit, cursor)
|
|
89518
88896
|
);
|
|
@@ -89559,7 +88937,6 @@ async function executeSessionPreviewHistoryPageLoad(socket, command, config2, re
|
|
|
89559
88937
|
command.sessionId,
|
|
89560
88938
|
command.eventLimit,
|
|
89561
88939
|
command.cursor,
|
|
89562
|
-
command.omit?.includes("agent-reasoning") === true,
|
|
89563
88940
|
[],
|
|
89564
88941
|
async (eventLimit, cursor) => await sessions.previewNativeSessionEvents(loadOptions, command.sessionId, eventLimit, cursor)
|
|
89565
88942
|
);
|
|
@@ -90292,7 +89669,7 @@ async function executePrompt({
|
|
|
90292
89669
|
}
|
|
90293
89670
|
|
|
90294
89671
|
// src/runtime/relay/artifact-download.ts
|
|
90295
|
-
import { createHash as
|
|
89672
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
90296
89673
|
import { fetch as fetch4 } from "undici";
|
|
90297
89674
|
var ARTIFACT_DOWNLOAD_TIMEOUT_MILLISECONDS = 2e4;
|
|
90298
89675
|
function downloadUrl(config2, artifact) {
|
|
@@ -90380,7 +89757,7 @@ async function downloadPromptArtifact(config2, artifact, signal) {
|
|
|
90380
89757
|
);
|
|
90381
89758
|
}
|
|
90382
89759
|
const bytes = await responseBytes(response, artifact.byteLength, requestSignal);
|
|
90383
|
-
if (
|
|
89760
|
+
if (createHash9("sha256").update(bytes).digest("hex") !== artifact.sha256) {
|
|
90384
89761
|
throw new PromptArtifactError(
|
|
90385
89762
|
"artifact_integrity_failed",
|
|
90386
89763
|
"The prompt artifact failed integrity validation"
|