@nyssance/codex-acp-v2 0.7.5 → 0.7.7
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/CHANGELOG.md +26 -0
- package/dist/index.js +287 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.7 — 2026-10-09
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Independent read-only history APIs: `_codex/session_history` for paginated turns and
|
|
8
|
+
`_codex/session_history_items` for paginated items, advertised through the version 2
|
|
9
|
+
`sessionHistory` capability.
|
|
10
|
+
- Browse mode for live history and export mode with optimistic consistency checks,
|
|
11
|
+
bounded response sizes, scoped cursors, cancellation, and structured errors.
|
|
12
|
+
- History projections preserve media references and text annotations, with optional
|
|
13
|
+
native records and explicit omission metadata for archival and export consumers.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Session listing includes custom-provider conversations by clearing the native
|
|
18
|
+
default model-provider filter.
|
|
19
|
+
|
|
20
|
+
## 0.7.6 — 2026-10-08
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- The `_meta` of a `session/prompt` is echoed once on the `user_message` reported under the same receipt id
|
|
25
|
+
(`_meta.alwith.messageId`), merged with the adapter's own `_meta.codex`. A host can therefore attach its own
|
|
26
|
+
per-message metadata (canvas references, attachments, a skill name) and get it back from the live stream and
|
|
27
|
+
from the Runtime's session event log on replay. Codex's own history snapshots (`session/load`) do not carry it.
|
|
28
|
+
|
|
3
29
|
## 0.7.5 — 2026-10-08
|
|
4
30
|
|
|
5
31
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -22046,7 +22046,7 @@ var package_default = {
|
|
|
22046
22046
|
publishConfig: {
|
|
22047
22047
|
access: "public"
|
|
22048
22048
|
},
|
|
22049
|
-
version: "0.7.
|
|
22049
|
+
version: "0.7.7",
|
|
22050
22050
|
description: "Native ACP v2 agent for the OpenAI Codex app-server",
|
|
22051
22051
|
packageManager: "bun@1.4.0",
|
|
22052
22052
|
engines: {
|
|
@@ -23896,6 +23896,7 @@ class EventBridge {
|
|
|
23896
23896
|
openToolCalls = new Set;
|
|
23897
23897
|
announcedTools = new Set;
|
|
23898
23898
|
messagePhases = new Map;
|
|
23899
|
+
promptMeta = new Map;
|
|
23899
23900
|
reasoningWithDeltas = new Set;
|
|
23900
23901
|
terminalItems = new Set;
|
|
23901
23902
|
imageGenerations = new Set;
|
|
@@ -23911,6 +23912,9 @@ class EventBridge {
|
|
|
23911
23912
|
this.client = client;
|
|
23912
23913
|
this.session = session;
|
|
23913
23914
|
}
|
|
23915
|
+
rememberPromptMeta(messageId, meta) {
|
|
23916
|
+
this.promptMeta.set(messageId, meta);
|
|
23917
|
+
}
|
|
23914
23918
|
beginTurn() {
|
|
23915
23919
|
this.lastError = null;
|
|
23916
23920
|
this.completedPlan = null;
|
|
@@ -24192,7 +24196,12 @@ ${details}` : summary)];
|
|
|
24192
24196
|
return [compactionUpdate(item.id, "in_progress")];
|
|
24193
24197
|
case "userMessage": {
|
|
24194
24198
|
const content = item.content.flatMap(fromUserInput);
|
|
24195
|
-
|
|
24199
|
+
if (content.length === 0)
|
|
24200
|
+
return [];
|
|
24201
|
+
const messageId = item.clientId ?? item.id;
|
|
24202
|
+
const meta = this.promptMeta.get(messageId);
|
|
24203
|
+
this.promptMeta.delete(messageId);
|
|
24204
|
+
return [{ sessionUpdate: "user_message", messageId, content, ...meta ? { _meta: meta } : {} }];
|
|
24196
24205
|
}
|
|
24197
24206
|
case "hookPrompt":
|
|
24198
24207
|
case "functionCallOutput":
|
|
@@ -26879,6 +26888,255 @@ function firstLine(text2) {
|
|
|
26879
26888
|
return line.length > 120 ? `${line.slice(0, 117)}...` : line;
|
|
26880
26889
|
}
|
|
26881
26890
|
|
|
26891
|
+
// src/agent/historyProtocol.ts
|
|
26892
|
+
import { createHash } from "crypto";
|
|
26893
|
+
function historyError(reason, message, retryable, extra = {}, code = -32600) {
|
|
26894
|
+
return new RequestError(code, message, { reason, retryable, ...extra });
|
|
26895
|
+
}
|
|
26896
|
+
function invalid(message) {
|
|
26897
|
+
throw historyError("history_invalid_params", message, false, {}, -32602);
|
|
26898
|
+
}
|
|
26899
|
+
function parse5(raw, items) {
|
|
26900
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
26901
|
+
invalid("History params must be an object");
|
|
26902
|
+
const p = raw;
|
|
26903
|
+
const allowed = new Set(["sessionId", "cursor", "limit", "mode", "sortDirection", "maxBytes", "includeNative", "_meta", ...items ? ["turnId", "anchorItemId"] : ["itemsView"]]);
|
|
26904
|
+
for (const key of Object.keys(p))
|
|
26905
|
+
if (!allowed.has(key))
|
|
26906
|
+
invalid(`Unknown history parameter: ${key}`);
|
|
26907
|
+
if (typeof p["sessionId"] !== "string" || !p["sessionId"].trim())
|
|
26908
|
+
invalid("sessionId must be a non-empty string");
|
|
26909
|
+
if (p["cursor"] != null && (typeof p["cursor"] !== "string" || !p["cursor"] || p["cursor"].length > 65536))
|
|
26910
|
+
invalid("cursor must be a non-empty history cursor or null");
|
|
26911
|
+
for (const [key, min, max] of [["limit", 1, 100], ["maxBytes", 1024, 16 * 1024 * 1024]]) {
|
|
26912
|
+
if (p[key] !== undefined && (typeof p[key] !== "number" || !Number.isInteger(p[key]) || p[key] < min || p[key] > max))
|
|
26913
|
+
invalid(`${key} must be an integer between ${min} and ${max}`);
|
|
26914
|
+
}
|
|
26915
|
+
if (p["mode"] !== undefined && p["mode"] !== "browse" && p["mode"] !== "export")
|
|
26916
|
+
invalid("mode must be browse or export");
|
|
26917
|
+
if (p["sortDirection"] !== undefined && p["sortDirection"] !== "asc" && p["sortDirection"] !== "desc")
|
|
26918
|
+
invalid("sortDirection must be asc or desc");
|
|
26919
|
+
if (p["includeNative"] !== undefined && typeof p["includeNative"] !== "boolean")
|
|
26920
|
+
invalid("includeNative must be a boolean");
|
|
26921
|
+
if (!items && p["itemsView"] !== undefined && p["itemsView"] !== "summary" && p["itemsView"] !== "full")
|
|
26922
|
+
invalid("itemsView must be summary or full");
|
|
26923
|
+
if (!items && p["includeNative"] === true && p["itemsView"] !== "full")
|
|
26924
|
+
invalid("includeNative requires itemsView: full; use the items endpoint for details");
|
|
26925
|
+
for (const key of ["turnId", "anchorItemId"]) {
|
|
26926
|
+
if (p[key] !== undefined && (typeof p[key] !== "string" || !p[key].trim()))
|
|
26927
|
+
invalid(`${key} must be a non-empty string`);
|
|
26928
|
+
}
|
|
26929
|
+
if (p["anchorItemId"] !== undefined && (p["turnId"] === undefined || p["cursor"] != null))
|
|
26930
|
+
invalid("anchorItemId requires turnId and cannot be combined with cursor");
|
|
26931
|
+
return p;
|
|
26932
|
+
}
|
|
26933
|
+
function parseSessionHistoryParams(raw) {
|
|
26934
|
+
return parse5(raw, false);
|
|
26935
|
+
}
|
|
26936
|
+
function parseSessionHistoryItemsParams(raw) {
|
|
26937
|
+
return parse5(raw, true);
|
|
26938
|
+
}
|
|
26939
|
+
function sourceError(error40) {
|
|
26940
|
+
if (error40 instanceof RequestError)
|
|
26941
|
+
return error40;
|
|
26942
|
+
const e = error40 && typeof error40 === "object" ? error40 : {};
|
|
26943
|
+
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
26944
|
+
const native = { code: e["code"] ?? null, data: e["data"] ?? null };
|
|
26945
|
+
const code = typeof e["code"] === "number" ? e["code"] : -32603;
|
|
26946
|
+
if (/thread not found|no rollout found for thread|unknown thread/i.test(message))
|
|
26947
|
+
return historyError("history_not_found", message, false, { native }, code);
|
|
26948
|
+
if (code === -32602 && /cursor/i.test(message))
|
|
26949
|
+
return historyError("history_invalid_cursor", message, false, { native }, code);
|
|
26950
|
+
if (code === -32602)
|
|
26951
|
+
return historyError("history_invalid_params", message, false, { native }, code);
|
|
26952
|
+
if (code === -32601)
|
|
26953
|
+
return historyError("history_unsupported", message, false, { native }, code);
|
|
26954
|
+
if (["ECONNRESET", "EPIPE", "ETIMEDOUT", "ECONNREFUSED"].includes(String(e["code"])))
|
|
26955
|
+
return historyError("history_unavailable", message, true, { native }, code);
|
|
26956
|
+
return historyError("history_source_error", message, null, { native }, code);
|
|
26957
|
+
}
|
|
26958
|
+
|
|
26959
|
+
class HistoryRead {
|
|
26960
|
+
codex;
|
|
26961
|
+
params;
|
|
26962
|
+
signal;
|
|
26963
|
+
direction;
|
|
26964
|
+
mode;
|
|
26965
|
+
after;
|
|
26966
|
+
binding;
|
|
26967
|
+
previous;
|
|
26968
|
+
constructor(codex, params, scope, signal) {
|
|
26969
|
+
this.codex = codex;
|
|
26970
|
+
this.params = params;
|
|
26971
|
+
this.signal = signal;
|
|
26972
|
+
this.direction = params.sortDirection ?? "asc";
|
|
26973
|
+
this.mode = params.mode ?? "browse";
|
|
26974
|
+
this.binding = JSON.stringify({ sessionId: params.sessionId, mode: this.mode, sortDirection: this.direction, includeNative: params.includeNative ?? false, ...scope });
|
|
26975
|
+
this.previous = this.decode(params.cursor);
|
|
26976
|
+
this.after = this.previous?.after ?? null;
|
|
26977
|
+
}
|
|
26978
|
+
decode(raw) {
|
|
26979
|
+
if (raw == null)
|
|
26980
|
+
return null;
|
|
26981
|
+
try {
|
|
26982
|
+
const v = JSON.parse(Buffer.from(raw, "base64url").toString("utf8"));
|
|
26983
|
+
if (!v || v.version !== 2 || v.binding !== this.binding || typeof v.after !== "string" || !v.after || (this.mode === "browse" ? v.revision !== null : typeof v.revision !== "string" || !/^[a-f0-9]{64}$/.test(v.revision)))
|
|
26984
|
+
throw new Error("cursor mismatch");
|
|
26985
|
+
return v;
|
|
26986
|
+
} catch {
|
|
26987
|
+
throw historyError("history_invalid_cursor", "Invalid history cursor or changed query options; restart without a cursor", false, {}, -32602);
|
|
26988
|
+
}
|
|
26989
|
+
}
|
|
26990
|
+
async call(operation) {
|
|
26991
|
+
const check2 = () => {
|
|
26992
|
+
if (this.signal?.aborted)
|
|
26993
|
+
throw historyError("history_cancelled", "History request cancelled", false);
|
|
26994
|
+
};
|
|
26995
|
+
check2();
|
|
26996
|
+
try {
|
|
26997
|
+
const result = this.signal ? await abortable(operation(), this.signal) : await operation();
|
|
26998
|
+
check2();
|
|
26999
|
+
return result;
|
|
27000
|
+
} catch (error40) {
|
|
27001
|
+
check2();
|
|
27002
|
+
throw sourceError(error40);
|
|
27003
|
+
}
|
|
27004
|
+
}
|
|
27005
|
+
async start() {
|
|
27006
|
+
const boundary = await this.boundary();
|
|
27007
|
+
if (this.previous && this.previous.revision !== boundary.revision)
|
|
27008
|
+
this.changed();
|
|
27009
|
+
return boundary;
|
|
27010
|
+
}
|
|
27011
|
+
async boundary() {
|
|
27012
|
+
const { thread } = await this.call(() => this.codex.threadRead({ threadId: this.params.sessionId, includeTurns: false }));
|
|
27013
|
+
if (this.mode === "browse")
|
|
27014
|
+
return { thread, revision: null };
|
|
27015
|
+
if (thread.status.type === "active")
|
|
27016
|
+
this.busy();
|
|
27017
|
+
if (thread.status.type === "systemError")
|
|
27018
|
+
throw historyError("history_unavailable", "Codex reports a session error; retry when it is resolved", true);
|
|
27019
|
+
const tail = await this.call(() => this.codex.threadTurnsList({ threadId: this.params.sessionId, limit: 1, sortDirection: "desc", itemsView: "summary" }));
|
|
27020
|
+
this.checkTurns(tail.data);
|
|
27021
|
+
const revision = createHash("sha256").update(JSON.stringify({ id: thread.id, cwd: thread.cwd, name: thread.name, preview: thread.preview, createdAt: thread.createdAt, updatedAt: thread.updatedAt, forkedFromId: thread.forkedFromId, tail: tail.data[0] ?? null })).digest("hex");
|
|
27022
|
+
return { thread, revision };
|
|
27023
|
+
}
|
|
27024
|
+
checkTurns(turns) {
|
|
27025
|
+
if (this.mode === "export" && turns.some((turn) => turn.status === "inProgress"))
|
|
27026
|
+
this.busy();
|
|
27027
|
+
}
|
|
27028
|
+
busy() {
|
|
27029
|
+
throw historyError("history_busy", "Session history is still running; retry after the turn finishes", true);
|
|
27030
|
+
}
|
|
27031
|
+
changed() {
|
|
27032
|
+
throw historyError("history_changed", "Session history changed; discard collected pages and restart without a cursor", true);
|
|
27033
|
+
}
|
|
27034
|
+
async finish(start, next, count) {
|
|
27035
|
+
if (next !== null && (!next || next === this.after || count === 0))
|
|
27036
|
+
throw historyError("history_invalid_page", "Codex history pagination made no progress; restart the read", false, {}, -32603);
|
|
27037
|
+
if (this.mode === "export" && start.revision !== (await this.boundary()).revision)
|
|
27038
|
+
this.changed();
|
|
27039
|
+
const nextCursor = next === null ? null : Buffer.from(JSON.stringify({ version: 2, binding: this.binding, revision: start.revision, after: next })).toString("base64url");
|
|
27040
|
+
const t = start.thread;
|
|
27041
|
+
return { sessionId: this.params.sessionId, cwd: t.cwd, title: t.name?.trim() || t.preview.trim() || null, createdAt: t.createdAt, updatedAt: t.updatedAt, forkedFromId: t.forkedFromId, running: t.status.type === "active" ? true : t.status.type === "idle" ? false : null, revision: start.revision, consistency: this.mode === "export" ? "optimistic" : "live", nextCursor, complete: nextCursor === null };
|
|
27042
|
+
}
|
|
27043
|
+
bounded(page) {
|
|
27044
|
+
const bytes = Buffer.byteLength(JSON.stringify(page));
|
|
27045
|
+
const maxBytes = this.params.maxBytes ?? 1024 * 1024;
|
|
27046
|
+
if (bytes > maxBytes)
|
|
27047
|
+
throw historyError("history_page_too_large", "History page exceeds maxBytes; retry the same cursor with a smaller limit or larger maxBytes, or start a new summary/item traversal", true, { bytes, maxBytes }, -32600);
|
|
27048
|
+
return page;
|
|
27049
|
+
}
|
|
27050
|
+
}
|
|
27051
|
+
|
|
27052
|
+
// src/agent/historyProjection.ts
|
|
27053
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
27054
|
+
function inputBlock(input) {
|
|
27055
|
+
switch (input.type) {
|
|
27056
|
+
case "text":
|
|
27057
|
+
return { type: "text", text: input.text, ...input.text_elements.length ? { _meta: { codex: { textElements: input.text_elements } } } : {} };
|
|
27058
|
+
case "image":
|
|
27059
|
+
return { type: "resource_link", name: "Image", uri: "url" in input ? input.url : `codex-file:${encodeURIComponent(input.fileId)}`, _meta: { codex: { inputType: input.type, ...input.detail ? { detail: input.detail } : {}, ..."fileId" in input ? { fileId: input.fileId } : {} } } };
|
|
27060
|
+
case "audio":
|
|
27061
|
+
return { type: "resource_link", name: "Audio", uri: input.url, _meta: { codex: { inputType: input.type } } };
|
|
27062
|
+
case "localImage":
|
|
27063
|
+
case "localAudio":
|
|
27064
|
+
return { type: "resource_link", name: input.type === "localImage" ? "Image" : "Audio", uri: input.path.startsWith("file://") ? input.path : pathToFileURL2(input.path).href, _meta: { codex: { inputType: input.type, ..."detail" in input && input.detail ? { detail: input.detail } : {} } } };
|
|
27065
|
+
case "skill":
|
|
27066
|
+
case "mention":
|
|
27067
|
+
return { type: "resource_link", name: input.name, uri: input.path.startsWith("file://") ? input.path : pathToFileURL2(input.path).href, _meta: { codex: { inputType: input.type } } };
|
|
27068
|
+
}
|
|
27069
|
+
}
|
|
27070
|
+
function projectHistoryItem(item, turnId, startedAt) {
|
|
27071
|
+
const omissions = [];
|
|
27072
|
+
let updates;
|
|
27073
|
+
if (item.type === "userMessage") {
|
|
27074
|
+
updates = [{ sessionUpdate: "user_message", messageId: item.clientId ?? item.id, content: item.content.map(inputBlock) }];
|
|
27075
|
+
} else {
|
|
27076
|
+
updates = itemSnapshot(item);
|
|
27077
|
+
if (!updates.length)
|
|
27078
|
+
omissions.push({ itemId: item.id, field: "*", reason: "no_acp_representation" });
|
|
27079
|
+
if (item.type === "reasoning" && item.summary.length && item.content.length)
|
|
27080
|
+
omissions.push({ itemId: item.id, field: "content", reason: "summary_selected" });
|
|
27081
|
+
if (item.type === "agentMessage") {
|
|
27082
|
+
for (const field of ["memoryCitation", "delivery", "questions"]) {
|
|
27083
|
+
if (item[field] !== null)
|
|
27084
|
+
omissions.push({ itemId: item.id, field, reason: "no_acp_representation" });
|
|
27085
|
+
}
|
|
27086
|
+
}
|
|
27087
|
+
}
|
|
27088
|
+
return { updates: updates.map((update) => withTurnId(update, turnId, startedAt)), omissions };
|
|
27089
|
+
}
|
|
27090
|
+
|
|
27091
|
+
// src/agent/sessionHistory.ts
|
|
27092
|
+
async function readSessionHistory(codex, raw, signal) {
|
|
27093
|
+
const params = parseSessionHistoryParams(raw);
|
|
27094
|
+
const view = params.itemsView ?? "summary";
|
|
27095
|
+
const read = new HistoryRead(codex, params, { endpoint: "turns", itemsView: view }, signal);
|
|
27096
|
+
const start = await read.start();
|
|
27097
|
+
const page = await read.call(() => codex.threadTurnsList({ threadId: params.sessionId, cursor: read.after, limit: params.limit ?? 50, sortDirection: read.direction, itemsView: view }));
|
|
27098
|
+
read.checkTurns(page.data);
|
|
27099
|
+
if (view === "full" && page.data.some((turn) => turn.itemsView !== "full"))
|
|
27100
|
+
throw historyError("history_incomplete", "Codex did not return full history items; update Codex and retry", false, {}, -32603);
|
|
27101
|
+
const result = await read.finish(start, page.nextCursor, page.data.length);
|
|
27102
|
+
return read.bounded({ ...result, running: page.data.some((turn) => turn.status === "inProgress") ? true : result.running, turns: page.data.map((turn) => {
|
|
27103
|
+
const projections = view === "full" ? turn.items.map((item) => projectHistoryItem(item, turn.id, turn.startedAt)) : [];
|
|
27104
|
+
return {
|
|
27105
|
+
turnId: turn.id,
|
|
27106
|
+
status: turn.status,
|
|
27107
|
+
error: turn.error,
|
|
27108
|
+
startedAt: turn.startedAt,
|
|
27109
|
+
completedAt: turn.completedAt,
|
|
27110
|
+
durationMs: turn.durationMs,
|
|
27111
|
+
itemsView: view === "summary" ? "summary" : turn.itemsView,
|
|
27112
|
+
updates: projections.flatMap((p) => p.updates),
|
|
27113
|
+
omissions: projections.flatMap((p) => p.omissions),
|
|
27114
|
+
...params.includeNative ? { _meta: { codex: { items: turn.items } } } : {}
|
|
27115
|
+
};
|
|
27116
|
+
}) });
|
|
27117
|
+
}
|
|
27118
|
+
async function readSessionHistoryItems(codex, raw, signal) {
|
|
27119
|
+
const params = parseSessionHistoryItemsParams(raw);
|
|
27120
|
+
const read = new HistoryRead(codex, params, { endpoint: "items", turnId: params.turnId ?? null }, signal);
|
|
27121
|
+
const start = await read.start();
|
|
27122
|
+
const page = await read.call(() => codex.threadItemsList({
|
|
27123
|
+
threadId: params.sessionId,
|
|
27124
|
+
turnId: params.turnId ?? null,
|
|
27125
|
+
cursor: read.after ?? (params.anchorItemId ? { type: "item", itemId: params.anchorItemId } : null),
|
|
27126
|
+
limit: params.limit ?? 50,
|
|
27127
|
+
sortDirection: read.direction
|
|
27128
|
+
}));
|
|
27129
|
+
const result = await read.finish(start, page.nextCursor, page.data.length);
|
|
27130
|
+
return read.bounded({ ...result, items: page.data.map((entry) => ({
|
|
27131
|
+
turnId: entry.turnId,
|
|
27132
|
+
itemId: entry.item.id,
|
|
27133
|
+
startedAtMs: entry.startedAtMs,
|
|
27134
|
+
completedAtMs: entry.completedAtMs,
|
|
27135
|
+
...projectHistoryItem(entry.item, entry.turnId),
|
|
27136
|
+
...params.includeNative ? { _meta: { codex: { item: entry.item } } } : {}
|
|
27137
|
+
})) });
|
|
27138
|
+
}
|
|
27139
|
+
|
|
26882
27140
|
// src/agent/forkIndex.ts
|
|
26883
27141
|
import { createReadStream } from "fs";
|
|
26884
27142
|
import { readdir, realpath } from "fs/promises";
|
|
@@ -27108,7 +27366,7 @@ class CodexAgent {
|
|
|
27108
27366
|
additionalDirectories: {}
|
|
27109
27367
|
},
|
|
27110
27368
|
providers: {},
|
|
27111
|
-
_meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { forkAtTurn: true, sessionLineage: true, archive: true, seedHistory: true, skills: true, plugins: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
|
|
27369
|
+
_meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { forkAtTurn: true, sessionLineage: true, archive: true, sessionHistory: { version: 2, items: true, modes: ["browse", "export"] }, seedHistory: true, skills: true, plugins: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
|
|
27112
27370
|
},
|
|
27113
27371
|
authMethods: authMethods(this.capabilities, this.env)
|
|
27114
27372
|
};
|
|
@@ -27660,6 +27918,7 @@ class CodexAgent {
|
|
|
27660
27918
|
cursor,
|
|
27661
27919
|
...cwd ? { cwd } : {},
|
|
27662
27920
|
sourceKinds: ["cli", "vscode", "exec", "appServer", "unknown"],
|
|
27921
|
+
modelProviders: [],
|
|
27663
27922
|
...archived ? { archived: true } : {}
|
|
27664
27923
|
}));
|
|
27665
27924
|
const response = await list(params.cursor ?? null);
|
|
@@ -27713,6 +27972,25 @@ class CodexAgent {
|
|
|
27713
27972
|
await this.withCodex(() => this.codex.threadDelete({ threadId: params.sessionId }));
|
|
27714
27973
|
return {};
|
|
27715
27974
|
}
|
|
27975
|
+
async sessionHistory(params, signal) {
|
|
27976
|
+
this.requireInitialized("_codex/session_history");
|
|
27977
|
+
this.checkHistoryIdle(params);
|
|
27978
|
+
const response = await readSessionHistory(this.codex, params, signal);
|
|
27979
|
+
this.checkHistoryIdle(params);
|
|
27980
|
+
return { ...response, running: this.sessions.get(params.sessionId)?.session.activeTurn ? true : response.running };
|
|
27981
|
+
}
|
|
27982
|
+
async sessionHistoryItems(params, signal) {
|
|
27983
|
+
this.requireInitialized("_codex/session_history_items");
|
|
27984
|
+
this.checkHistoryIdle(params);
|
|
27985
|
+
const response = await readSessionHistoryItems(this.codex, params, signal);
|
|
27986
|
+
this.checkHistoryIdle(params);
|
|
27987
|
+
return { ...response, running: this.sessions.get(params.sessionId)?.session.activeTurn ? true : response.running };
|
|
27988
|
+
}
|
|
27989
|
+
checkHistoryIdle(params) {
|
|
27990
|
+
if (params.mode === "export" && this.sessions.get(params.sessionId)?.session.activeTurn) {
|
|
27991
|
+
throw historyError("history_busy", "Session history is still running; retry after the turn finishes", true);
|
|
27992
|
+
}
|
|
27993
|
+
}
|
|
27716
27994
|
async archiveSession(params) {
|
|
27717
27995
|
return await this.admission(() => this.archiveSessionInternal(params), params.sessionId);
|
|
27718
27996
|
}
|
|
@@ -27925,6 +28203,8 @@ class CodexAgent {
|
|
|
27925
28203
|
throw RequestError.invalidParams(undefined, "prompt must contain at least one content block");
|
|
27926
28204
|
}
|
|
27927
28205
|
const { session } = runtime;
|
|
28206
|
+
if (params._meta && typeof params._meta === "object")
|
|
28207
|
+
runtime.bridge.rememberPromptMeta(messageId, params._meta);
|
|
27928
28208
|
this.providers.upstreamModel(session.model.model);
|
|
27929
28209
|
const model = findModel(session.catalog, session.model.model);
|
|
27930
28210
|
if (!modelSupportsImages(model) && params.prompt.some((block) => block.type === "image")) {
|
|
@@ -28515,7 +28795,7 @@ function createAgentApp(options) {
|
|
|
28515
28795
|
};
|
|
28516
28796
|
return agent({ name: options.info.name }).onConnect((connection) => {
|
|
28517
28797
|
agent2 = new CodexAgent(connection.client, options);
|
|
28518
|
-
}).onRequest(methods.agent.initialize, (ctx) => current().initialize(ctx.params)).onRequest(methods.agent.auth.login, (ctx) => current().login(ctx.params, ctx.requestId)).onRequest(methods.agent.auth.logout, (ctx) => current().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => current().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => current().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => current().disableProvider(ctx.params)).onRequest(methods.agent.session.new, (ctx) => current().newSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.resume, (ctx) => current().resumeSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.fork, (ctx) => current().forkSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.list, (ctx) => current().listSessions(ctx.params)).onRequest(methods.agent.session.close, (ctx) => current().closeSession(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => current().deleteSession(ctx.params)).onRequest("_codex/session_archive", { parse: parseSessionIdParams }, (ctx) => current().archiveSession(ctx.params)).onRequest("_codex/session_unarchive", { parse: parseSessionIdParams }, (ctx) => current().unarchiveSession(ctx.params)).onRequest("_codex/skills_list", { parse: objectParams() }, (ctx) => current().skillsList(ctx.params)).onRequest("_codex/skills_config_write", { parse: objectParams() }, (ctx) => current().skillsConfigWrite(ctx.params)).onRequest("_codex/plugin_list", { parse: objectParams() }, (ctx) => current().pluginList(ctx.params)).onRequest("_codex/plugin_installed", { parse: objectParams() }, (ctx) => current().pluginInstalled(ctx.params)).onRequest("_codex/plugin_install", { parse: objectParams() }, (ctx) => current().pluginInstall(ctx.params)).onRequest("_codex/plugin_uninstall", { parse: objectParams() }, (ctx) => current().pluginUninstall(ctx.params)).onRequest("_codex/plugin_read", { parse: objectParams() }, (ctx) => current().pluginRead(ctx.params)).onRequest("_codex/marketplace_add", { parse: objectParams() }, (ctx) => current().marketplaceAdd(ctx.params)).onRequest("_codex/marketplace_remove", { parse: objectParams() }, (ctx) => current().marketplaceRemove(ctx.params)).onRequest("_codex/marketplace_upgrade", { parse: objectParams() }, (ctx) => current().marketplaceUpgrade(ctx.params)).onRequest("_codex/session_rename", { parse: parseSessionRenameParams }, (ctx) => current().sessionRename(ctx.params)).onRequest("_codex/account_read", { parse: objectParams() }, () => current().accountRead()).onRequest("_codex/rate_limits", { parse: objectParams() }, () => current().rateLimits()).onRequest("_codex/fuzzy_file_search", { parse: parseFuzzyFileSearchParams }, (ctx) => current().fuzzyFileSearch(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => current().setSessionConfigOption(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => current().prompt(ctx.params)).onNotification(methods.agent.session.cancel, (ctx) => current().cancel(ctx.params));
|
|
28798
|
+
}).onRequest(methods.agent.initialize, (ctx) => current().initialize(ctx.params)).onRequest(methods.agent.auth.login, (ctx) => current().login(ctx.params, ctx.requestId)).onRequest(methods.agent.auth.logout, (ctx) => current().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => current().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => current().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => current().disableProvider(ctx.params)).onRequest(methods.agent.session.new, (ctx) => current().newSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.resume, (ctx) => current().resumeSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.fork, (ctx) => current().forkSession(ctx.params, ctx.signal)).onRequest(methods.agent.session.list, (ctx) => current().listSessions(ctx.params)).onRequest(methods.agent.session.close, (ctx) => current().closeSession(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => current().deleteSession(ctx.params)).onRequest("_codex/session_history", { parse: parseSessionHistoryParams }, (ctx) => current().sessionHistory(ctx.params, ctx.signal)).onRequest("_codex/session_history_items", { parse: parseSessionHistoryItemsParams }, (ctx) => current().sessionHistoryItems(ctx.params, ctx.signal)).onRequest("_codex/session_archive", { parse: parseSessionIdParams }, (ctx) => current().archiveSession(ctx.params)).onRequest("_codex/session_unarchive", { parse: parseSessionIdParams }, (ctx) => current().unarchiveSession(ctx.params)).onRequest("_codex/skills_list", { parse: objectParams() }, (ctx) => current().skillsList(ctx.params)).onRequest("_codex/skills_config_write", { parse: objectParams() }, (ctx) => current().skillsConfigWrite(ctx.params)).onRequest("_codex/plugin_list", { parse: objectParams() }, (ctx) => current().pluginList(ctx.params)).onRequest("_codex/plugin_installed", { parse: objectParams() }, (ctx) => current().pluginInstalled(ctx.params)).onRequest("_codex/plugin_install", { parse: objectParams() }, (ctx) => current().pluginInstall(ctx.params)).onRequest("_codex/plugin_uninstall", { parse: objectParams() }, (ctx) => current().pluginUninstall(ctx.params)).onRequest("_codex/plugin_read", { parse: objectParams() }, (ctx) => current().pluginRead(ctx.params)).onRequest("_codex/marketplace_add", { parse: objectParams() }, (ctx) => current().marketplaceAdd(ctx.params)).onRequest("_codex/marketplace_remove", { parse: objectParams() }, (ctx) => current().marketplaceRemove(ctx.params)).onRequest("_codex/marketplace_upgrade", { parse: objectParams() }, (ctx) => current().marketplaceUpgrade(ctx.params)).onRequest("_codex/session_rename", { parse: parseSessionRenameParams }, (ctx) => current().sessionRename(ctx.params)).onRequest("_codex/account_read", { parse: objectParams() }, () => current().accountRead()).onRequest("_codex/rate_limits", { parse: objectParams() }, () => current().rateLimits()).onRequest("_codex/fuzzy_file_search", { parse: parseFuzzyFileSearchParams }, (ctx) => current().fuzzyFileSearch(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => current().setSessionConfigOption(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => current().prompt(ctx.params)).onNotification(methods.agent.session.cancel, (ctx) => current().cancel(ctx.params));
|
|
28519
28799
|
}
|
|
28520
28800
|
|
|
28521
28801
|
// src/codex/AppServerClient.ts
|
|
@@ -28832,6 +29112,9 @@ class AppServerClient {
|
|
|
28832
29112
|
threadTurnsList(params) {
|
|
28833
29113
|
return this.send({ method: "thread/turns/list", params });
|
|
28834
29114
|
}
|
|
29115
|
+
threadItemsList(params) {
|
|
29116
|
+
return this.send({ method: "thread/items/list", params });
|
|
29117
|
+
}
|
|
28835
29118
|
threadArchive(params) {
|
|
28836
29119
|
return this.send({ method: "thread/archive", params });
|
|
28837
29120
|
}
|