@nyssance/codex-acp-v2 0.7.0 → 0.7.2
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 +28 -0
- package/README.md +1 -1
- package/dist/index.js +47 -12
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.2 — 2026-09-29
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Turn correlation v2 (`capabilities._meta.alwith.turns = {version: 2}`): `session/prompt`
|
|
8
|
+
accepts a host-named receipt in `_meta.alwith.messageId`, and every `state_update` of a
|
|
9
|
+
prompted turn carries `_meta.alwith.messageId`. A stale `idle` of an older turn is dropped
|
|
10
|
+
once a newer prompt owns the session.
|
|
11
|
+
|
|
12
|
+
## 0.7.1 — 2026-09-29
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Generated against Codex 0.158.0 (`@openai/codex` `^0.158.0`); the version floor follows.
|
|
17
|
+
- MCP `openai/userVerification` elicitations (signed device challenges) are declined with
|
|
18
|
+
`cancelled`: ACP has no surface for them and enrollment stays inside Codex.
|
|
19
|
+
- `codexErrorInfo` `flexUnavailable` classifies as `flex_unavailable`, retryable.
|
|
20
|
+
- Replayed `image` user input renders `image:<fileId>` when Codex stored an uploaded file
|
|
21
|
+
instead of a URL.
|
|
22
|
+
|
|
23
|
+
## 0.7.0 — 2026-09-29
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- `session/prompt` returns `{messageId}` (ACP v2, sdk 1.5.1). The id is passed to Codex as
|
|
28
|
+
`clientUserMessageId`; `user_message` echoes and replays report it as `messageId`
|
|
29
|
+
(`userMessage.clientId ?? id`). Steering returns `{messageId, _meta.codex.steered}`.
|
|
30
|
+
|
|
3
31
|
## 0.6.0 — 2026-09-11
|
|
4
32
|
|
|
5
33
|
### Added
|
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ See [`docs/protocol.md`](docs/protocol.md) for the exact wire contract.
|
|
|
59
59
|
|
|
60
60
|
## Requirements
|
|
61
61
|
|
|
62
|
-
- Codex CLI **0.
|
|
62
|
+
- Codex CLI **0.158.0 or newer** — the app-server types under `src/app-server` are generated
|
|
63
63
|
from the `@openai/codex` release named in `optionalDependencies`, and the agent checks
|
|
64
64
|
`codex --version` before starting the server; an older Codex fails at startup with an
|
|
65
65
|
upgrade hint.
|
package/dist/index.js
CHANGED
|
@@ -21844,7 +21844,7 @@ var package_default = {
|
|
|
21844
21844
|
publishConfig: {
|
|
21845
21845
|
access: "public"
|
|
21846
21846
|
},
|
|
21847
|
-
version: "0.7.
|
|
21847
|
+
version: "0.7.2",
|
|
21848
21848
|
description: "Native ACP v2 agent for the OpenAI Codex app-server",
|
|
21849
21849
|
packageManager: "bun@1.4.0",
|
|
21850
21850
|
engines: {
|
|
@@ -21916,7 +21916,7 @@ var package_default = {
|
|
|
21916
21916
|
"vscode-jsonrpc": "^9.0.2"
|
|
21917
21917
|
},
|
|
21918
21918
|
optionalDependencies: {
|
|
21919
|
-
"@openai/codex": "^0.
|
|
21919
|
+
"@openai/codex": "^0.158.0"
|
|
21920
21920
|
}
|
|
21921
21921
|
};
|
|
21922
21922
|
|
|
@@ -22084,6 +22084,8 @@ function classifyTurnError(info) {
|
|
|
22084
22084
|
return failure2("rate_limit", true);
|
|
22085
22085
|
case "serverOverloaded":
|
|
22086
22086
|
return failure2("overloaded", true);
|
|
22087
|
+
case "flexUnavailable":
|
|
22088
|
+
return failure2("flex_unavailable", true);
|
|
22087
22089
|
case "internalServerError":
|
|
22088
22090
|
return failure2("internal", true);
|
|
22089
22091
|
case "unauthorized":
|
|
@@ -23556,7 +23558,7 @@ function fromUserInput(input) {
|
|
|
23556
23558
|
case "text":
|
|
23557
23559
|
return input.text.length > 0 ? [{ type: "text", text: input.text }] : [];
|
|
23558
23560
|
case "image":
|
|
23559
|
-
return [{ type: "text", text: formatUriAsLink("image", input.url) }];
|
|
23561
|
+
return [{ type: "text", text: "url" in input ? formatUriAsLink("image", input.url) : `image:${input.fileId}` }];
|
|
23560
23562
|
case "localImage":
|
|
23561
23563
|
return [{ type: "text", text: formatUriAsLink(null, toFileUri(input.path)) }];
|
|
23562
23564
|
case "skill":
|
|
@@ -23904,6 +23906,8 @@ ${details}` : summary)];
|
|
|
23904
23906
|
case "mcpServer/event/stream/notification":
|
|
23905
23907
|
case "account/updated":
|
|
23906
23908
|
case "account/login/completed":
|
|
23909
|
+
case "account/gatewayOAuth/changed":
|
|
23910
|
+
case "thread/attachment/updated":
|
|
23907
23911
|
case "app/list/updated":
|
|
23908
23912
|
case "remoteControl/status/changed":
|
|
23909
23913
|
case "externalAgentConfig/import/progress":
|
|
@@ -24892,6 +24896,10 @@ class CodexElicitationHandler {
|
|
|
24892
24896
|
}
|
|
24893
24897
|
async handleElicitation(params) {
|
|
24894
24898
|
try {
|
|
24899
|
+
if (params.mode === "openai/userVerification") {
|
|
24900
|
+
logger.log("MCP user verification is not supported over ACP", { server: params.serverName });
|
|
24901
|
+
return cancelled();
|
|
24902
|
+
}
|
|
24895
24903
|
const context = this.mcpContext(params);
|
|
24896
24904
|
const messageOnly = isMessageOnlyForm(params);
|
|
24897
24905
|
if (!messageOnly && this.useAcpElicitation(params)) {
|
|
@@ -25955,6 +25963,7 @@ class ClientSession {
|
|
|
25955
25963
|
disposed = false;
|
|
25956
25964
|
output = new AbortController;
|
|
25957
25965
|
terminalAttempted = false;
|
|
25966
|
+
messageId;
|
|
25958
25967
|
get signal() {
|
|
25959
25968
|
return this.output.signal;
|
|
25960
25969
|
}
|
|
@@ -25998,26 +26007,36 @@ class ClientSession {
|
|
|
25998
26007
|
return;
|
|
25999
26008
|
await abortable(this.link.notify(methods.client.elicitation.complete, { elicitationId }), this.output.signal);
|
|
26000
26009
|
}
|
|
26001
|
-
reportRunning() {
|
|
26010
|
+
reportRunning(messageId) {
|
|
26011
|
+
this.messageId = messageId;
|
|
26002
26012
|
this.terminalAttempted = false;
|
|
26003
26013
|
this.turnGeneration += 1;
|
|
26004
26014
|
this.turnActive = true;
|
|
26005
26015
|
this.waiting = 0;
|
|
26006
26016
|
this.state({ sessionUpdate: "state_update", state: "running" });
|
|
26007
26017
|
}
|
|
26008
|
-
async reportIdle(stopReason, extra) {
|
|
26018
|
+
async reportIdle(stopReason, extra, messageId = this.messageId) {
|
|
26019
|
+
if (messageId !== this.messageId)
|
|
26020
|
+
return;
|
|
26009
26021
|
if (this.terminalAttempted)
|
|
26010
26022
|
return;
|
|
26011
26023
|
this.terminalAttempted = true;
|
|
26012
26024
|
this.turnActive = false;
|
|
26013
26025
|
this.waiting = 0;
|
|
26014
|
-
await this.update({
|
|
26026
|
+
await this.update(this.correlated({
|
|
26015
26027
|
sessionUpdate: "state_update",
|
|
26016
26028
|
state: "idle",
|
|
26017
26029
|
stopReason,
|
|
26018
26030
|
...extra?.usage === undefined ? {} : { usage: extra.usage },
|
|
26019
26031
|
...extra?._meta === undefined ? {} : { _meta: extra._meta }
|
|
26020
|
-
});
|
|
26032
|
+
}));
|
|
26033
|
+
}
|
|
26034
|
+
correlated(update) {
|
|
26035
|
+
if (this.messageId === undefined)
|
|
26036
|
+
return update;
|
|
26037
|
+
const meta = update._meta;
|
|
26038
|
+
const alwith = meta?.["alwith"];
|
|
26039
|
+
return { ...update, _meta: { ...meta, alwith: { ...alwith, messageId: this.messageId } } };
|
|
26021
26040
|
}
|
|
26022
26041
|
async waitingOnClient(operation, signal) {
|
|
26023
26042
|
if (this.disposed)
|
|
@@ -26038,7 +26057,7 @@ class ClientSession {
|
|
|
26038
26057
|
}
|
|
26039
26058
|
async state(update) {
|
|
26040
26059
|
try {
|
|
26041
|
-
await this.update(update);
|
|
26060
|
+
await this.update(this.correlated(update));
|
|
26042
26061
|
} catch (error40) {
|
|
26043
26062
|
logger.error("Failed to publish session state", error40, { sessionId: this.sessionId });
|
|
26044
26063
|
}
|
|
@@ -26623,6 +26642,7 @@ function gatewayModel(model, isDefault, template, entry) {
|
|
|
26623
26642
|
additionalSpeedTiers: [],
|
|
26624
26643
|
serviceTiers: [],
|
|
26625
26644
|
defaultServiceTier: null,
|
|
26645
|
+
availableAccessPrograms: null,
|
|
26626
26646
|
isDefault
|
|
26627
26647
|
};
|
|
26628
26648
|
}
|
|
@@ -26767,7 +26787,7 @@ class CodexAgent {
|
|
|
26767
26787
|
additionalDirectories: {}
|
|
26768
26788
|
},
|
|
26769
26789
|
providers: {},
|
|
26770
|
-
_meta: { alwith: { tools: { version: 1 } }, codex: { archive: true, seedHistory: true, skills: true, plugins: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
|
|
26790
|
+
_meta: { alwith: { tools: { version: 1 }, turns: { version: 2 } }, codex: { archive: true, seedHistory: true, skills: true, plugins: true, providerCatalog: true, rename: true, account: true, fuzzyFileSearch: true } }
|
|
26771
26791
|
},
|
|
26772
26792
|
authMethods: authMethods(this.capabilities, this.env)
|
|
26773
26793
|
};
|
|
@@ -27524,7 +27544,7 @@ class CodexAgent {
|
|
|
27524
27544
|
return runtime;
|
|
27525
27545
|
}
|
|
27526
27546
|
async prompt(params) {
|
|
27527
|
-
return await this.promptInternal(params, false, crypto.randomUUID());
|
|
27547
|
+
return await this.promptInternal(params, false, requestedMessageId(params) ?? crypto.randomUUID());
|
|
27528
27548
|
}
|
|
27529
27549
|
async promptInternal(params, allowReentry, messageId) {
|
|
27530
27550
|
this.assertRoutingAvailable();
|
|
@@ -27548,7 +27568,7 @@ class CodexAgent {
|
|
|
27548
27568
|
}
|
|
27549
27569
|
const turn = createActiveTurn(session.id, messageId);
|
|
27550
27570
|
session.activeTurn = turn;
|
|
27551
|
-
runtime.client.reportRunning();
|
|
27571
|
+
runtime.client.reportRunning(messageId);
|
|
27552
27572
|
this.runPrompt(runtime, turn, params);
|
|
27553
27573
|
return { messageId };
|
|
27554
27574
|
}
|
|
@@ -27772,7 +27792,7 @@ class CodexAgent {
|
|
|
27772
27792
|
await runtime.bridge.finishOpenToolCalls(reason === "cancelled" ? "cancelled" : reason === "end_turn" ? "completed" : "failed");
|
|
27773
27793
|
if (runtime.session.activeTurn === turn)
|
|
27774
27794
|
runtime.session.activeTurn = null;
|
|
27775
|
-
await runtime.client.reportIdle(reason, extra);
|
|
27795
|
+
await runtime.client.reportIdle(reason, extra, turn.clientUserMessageId ?? undefined);
|
|
27776
27796
|
}
|
|
27777
27797
|
async reportTurnFailure(runtime, turn, error40) {
|
|
27778
27798
|
const { stopReason, ...classification } = classifyTurnError(error40.codexErrorInfo);
|
|
@@ -27957,6 +27977,15 @@ ${stderr}` : ""}`);
|
|
|
27957
27977
|
function mcpServerNames(servers) {
|
|
27958
27978
|
return servers.flatMap((server) => typeof server.name === "string" ? [sanitizeMcpServerName(server.name)] : []);
|
|
27959
27979
|
}
|
|
27980
|
+
function requestedMessageId(params) {
|
|
27981
|
+
const alwith = params._meta?.["alwith"];
|
|
27982
|
+
if (alwith?.messageId === undefined)
|
|
27983
|
+
return;
|
|
27984
|
+
if (typeof alwith.messageId !== "string" || alwith.messageId.length === 0) {
|
|
27985
|
+
throw RequestError.invalidParams(undefined, "_meta.alwith.messageId must be a non-empty string");
|
|
27986
|
+
}
|
|
27987
|
+
return alwith.messageId;
|
|
27988
|
+
}
|
|
27960
27989
|
function agentMessage(messageId, text2) {
|
|
27961
27990
|
return { sessionUpdate: "agent_message_chunk", messageId, content: { type: "text", text: text2 } };
|
|
27962
27991
|
}
|
|
@@ -28026,12 +28055,18 @@ function readOnlyThread(thread, cwd) {
|
|
|
28026
28055
|
model: thread.model ?? "",
|
|
28027
28056
|
modelProvider: thread.modelProvider,
|
|
28028
28057
|
serviceTier: null,
|
|
28058
|
+
disabledPluginIds: [],
|
|
28029
28059
|
cwd,
|
|
28060
|
+
runtimeWorkspaceRoots: [],
|
|
28030
28061
|
instructionSources: [],
|
|
28031
28062
|
approvalPolicy: "on-request",
|
|
28032
28063
|
approvalsReviewer: "user",
|
|
28033
28064
|
sandbox: { type: "readOnly", networkAccess: false },
|
|
28065
|
+
activePermissionProfile: null,
|
|
28034
28066
|
reasoningEffort: thread.reasoningEffort,
|
|
28067
|
+
collaborationMode: null,
|
|
28068
|
+
multiAgentMode: "explicitRequestOnly",
|
|
28069
|
+
initialTurnsPage: null,
|
|
28035
28070
|
turnsBackwardsCursor: null,
|
|
28036
28071
|
itemsBackwardsCursor: null
|
|
28037
28072
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.7.
|
|
6
|
+
"version": "0.7.2",
|
|
7
7
|
"description": "Native ACP v2 agent for the OpenAI Codex app-server",
|
|
8
8
|
"packageManager": "bun@1.4.0",
|
|
9
9
|
"engines": {
|
|
@@ -75,6 +75,6 @@
|
|
|
75
75
|
"vscode-jsonrpc": "^9.0.2"
|
|
76
76
|
},
|
|
77
77
|
"optionalDependencies": {
|
|
78
|
-
"@openai/codex": "^0.
|
|
78
|
+
"@openai/codex": "^0.158.0"
|
|
79
79
|
}
|
|
80
80
|
}
|