@agentconnect.md/codex-acp 1.10.0-agentconnect.2 → 1.11.0-agentconnect.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +11 -0
  2. package/dist/index.js +147 -62
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -10,6 +10,7 @@ Use [OpenAI Codex](https://github.com/openai/codex) from [Agent Client Protocol]
10
10
 
11
11
  - ChatGPT, API key, and client-provided custom gateway authentication.
12
12
  - Model, reasoning effort, fast mode, approval, and sandbox mode configuration.
13
+ - Concrete recommended model and reasoning-effort values through the opt-in [AIR recommended config values](docs/recommended-config-values-extension.md) capability.
13
14
  - Text prompts, embedded context, images, resource links, and additional workspace directories.
14
15
  - Shell command, file change, [permission request](docs/permission-extension.md), MCP tool call, terminal output, reasoning, plan, web search, image generation, image view, token usage, and review events.
15
16
  - [Native ACP subagent sessions](docs/subagent-sessions.md) (after capability negotiation) with separate child histories and root-routed permissions; a legacy tool-call fallback otherwise.
@@ -40,6 +41,16 @@ The npm package includes a compatible `@openai/codex` dependency. Set `CODEX_PAT
40
41
  CODEX_PATH=/path/to/codex npx -y @agentclientprotocol/codex-acp
41
42
  ```
42
43
 
44
+ To try changes that have landed on `main` but are not released yet, install from the
45
+ `preview` channel. Pushes to `main` trigger preview publishing without waiting
46
+ for CI or release-please; release commits are excluded, and newer pushes can
47
+ replace queued previews. See
48
+ [docs/RELEASES.md](docs/RELEASES.md#preview-releases).
49
+
50
+ ```bash
51
+ npx -y @agentclientprotocol/codex-acp@preview
52
+ ```
53
+
43
54
  ## Authentication
44
55
 
45
56
  The adapter advertises ACP auth methods during initialization. Clients can authenticate with:
package/dist/index.js CHANGED
@@ -23670,16 +23670,37 @@ var AIR_SESSION_FAILURE_KEY = "sessionFailure";
23670
23670
  var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
23671
23671
  var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
23672
23672
  var AIR_ASYNC_TASKS_KEY = "asyncTasks";
23673
+ var AIR_RECOMMENDED_CONFIG_VALUE_KEY = "recommendedValue";
23673
23674
  var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
23674
23675
  var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
23675
23676
  var AIR_EXTENSION_VERSION = 1;
23677
+ function withAirMeta(meta3, key, value) {
23678
+ const root = asRecord(meta3);
23679
+ const jetbrains = asRecord(root[JETBRAINS_META_KEY]);
23680
+ const air = asRecord(jetbrains[AIR_META_KEY]);
23681
+ return {
23682
+ ...root,
23683
+ [JETBRAINS_META_KEY]: {
23684
+ ...jetbrains,
23685
+ [AIR_META_KEY]: {
23686
+ ...air,
23687
+ [AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
23688
+ [key]: value
23689
+ }
23690
+ }
23691
+ };
23692
+ }
23676
23693
  function clientSupportsAirCapability(capabilities, capability) {
23677
- const jetbrains = capabilities?._meta?.[JETBRAINS_META_KEY];
23678
- const air = jetbrains?.[AIR_META_KEY];
23679
- const version2 = air?.[AIR_EXTENSION_VERSION_KEY];
23680
- const supported = air?.[AIR_EXTENSION_CAPABILITIES_KEY];
23694
+ const meta3 = asRecord(capabilities?._meta);
23695
+ const jetbrains = asRecord(meta3[JETBRAINS_META_KEY]);
23696
+ const air = asRecord(jetbrains[AIR_META_KEY]);
23697
+ const version2 = air[AIR_EXTENSION_VERSION_KEY];
23698
+ const supported = air[AIR_EXTENSION_CAPABILITIES_KEY];
23681
23699
  return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
23682
23700
  }
23701
+ function asRecord(value) {
23702
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
23703
+ }
23683
23704
 
23684
23705
  // src/subagents/CodexAgentPath.ts
23685
23706
  function normalizeAgentPath(path9) {
@@ -25969,8 +25990,9 @@ function buildMcpPermissionRequest(sessionId, params, context, nextStandaloneToo
25969
25990
  toolCallId: nextStandaloneToolCallId(),
25970
25991
  kind: context.isToolApproval ? "execute" : "other",
25971
25992
  status: "pending",
25993
+ title: context.isToolApproval ? "MCP tool call approval" : "Question from MCP server",
25972
25994
  content: [messageContent],
25973
- rawInput: { serverName: params.serverName, schema: params.requestedSchema }
25995
+ rawInput: { serverName: params.serverName, description: params.message, schema: params.requestedSchema }
25974
25996
  },
25975
25997
  ...context.isToolApproval ? { _meta: { is_mcp_tool_approval: true } } : {},
25976
25998
  options
@@ -25988,8 +26010,9 @@ function buildMcpPermissionRequest(sessionId, params, context, nextStandaloneToo
25988
26010
  toolCallId: `elicitation-${params.elicitationId}`,
25989
26011
  kind: "fetch",
25990
26012
  status: "pending",
26013
+ title: "MCP server requests to open a URL",
25991
26014
  content: [messageContent],
25992
- rawInput: { serverName: params.serverName, url: params.url }
26015
+ rawInput: { serverName: params.serverName, description: params.message, url: params.url }
25993
26016
  },
25994
26017
  options
25995
26018
  },
@@ -26166,11 +26189,29 @@ var CodexElicitationHandler = class {
26166
26189
  context.isToolApproval,
26167
26190
  context.persistOptions
26168
26191
  );
26169
- if (correlatedCallId !== void 0 && result.action === "accept") {
26170
- await this.connection.notify(methods.client.session.update, {
26171
- sessionId: params.threadId,
26172
- update: { sessionUpdate: "tool_call_update", toolCallId: correlatedCallId, status: "in_progress" }
26173
- });
26192
+ if (correlatedCallId !== void 0) {
26193
+ if (result.action === "accept") {
26194
+ await this.connection.notify(methods.client.session.update, {
26195
+ sessionId: params.threadId,
26196
+ update: { sessionUpdate: "tool_call_update", toolCallId: correlatedCallId, status: "in_progress" }
26197
+ });
26198
+ }
26199
+ } else {
26200
+ try {
26201
+ await this.connection.notify(methods.client.session.update, {
26202
+ sessionId: params.threadId,
26203
+ update: {
26204
+ sessionUpdate: "tool_call_update",
26205
+ toolCallId: request.toolCall.toolCallId,
26206
+ status: "completed",
26207
+ title: request.toolCall.title,
26208
+ content: request.toolCall.content,
26209
+ rawOutput: { action: result.action }
26210
+ }
26211
+ });
26212
+ } catch (error51) {
26213
+ logger.error("Failed to finalize standalone MCP elicitation tool call", error51);
26214
+ }
26174
26215
  }
26175
26216
  return result;
26176
26217
  } catch (error51) {
@@ -27330,7 +27371,7 @@ var package_default = {
27330
27371
  publishConfig: {
27331
27372
  access: "public"
27332
27373
  },
27333
- version: "1.10.0-agentconnect.2",
27374
+ version: "1.11.0-agentconnect.1",
27334
27375
  description: "",
27335
27376
  main: "dist/index.js",
27336
27377
  bin: {
@@ -27392,7 +27433,7 @@ var package_default = {
27392
27433
  },
27393
27434
  dependencies: {
27394
27435
  "@agentclientprotocol/sdk": "^1.4.0",
27395
- "@openai/codex": "^0.153.3",
27436
+ "@openai/codex": "^0.153.4",
27396
27437
  diff: "^9.0.0",
27397
27438
  open: "^11.0.1",
27398
27439
  "vscode-jsonrpc": "^9.0.1",
@@ -27525,9 +27566,9 @@ Working directory: ${JSON.stringify(workspace.cwd)}
27525
27566
  Additional allowed directories: ${JSON.stringify(workspace.additionalDirectories)}`;
27526
27567
  }
27527
27568
  function parseAgentFileChangeReportRequest(meta3) {
27528
- const jetbrains = asRecord(meta3?.[JETBRAINS_META_KEY]);
27529
- const air = asRecord(jetbrains?.[AIR_META_KEY]);
27530
- const request = asRecord(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
27569
+ const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
27570
+ const air = asRecord2(jetbrains?.[AIR_META_KEY]);
27571
+ const request = asRecord2(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
27531
27572
  if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
27532
27573
  return null;
27533
27574
  }
@@ -27594,7 +27635,7 @@ function parseModelFileChangeReport(turn) {
27594
27635
  } catch {
27595
27636
  throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned invalid JSON");
27596
27637
  }
27597
- const report = asRecord(value);
27638
+ const report = asRecord2(value);
27598
27639
  if (report === null || !hasOnlyKeys(report, ["paths", "complete", "uncertainty"])) {
27599
27640
  throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned an invalid object");
27600
27641
  }
@@ -27771,7 +27812,7 @@ function isWindowsAbsolutePath2(value) {
27771
27812
  function isValidPathText(value) {
27772
27813
  return value.length > 0 && !/[\u0000-\u001F\u007F-\u009F]/.test(value);
27773
27814
  }
27774
- function asRecord(value) {
27815
+ function asRecord2(value) {
27775
27816
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
27776
27817
  }
27777
27818
  function hasOnlyKeys(value, allowed) {
@@ -27900,6 +27941,7 @@ async function forkSession(request, additionalDirectories, dependencies) {
27900
27941
  const lastTurnId = await resolveForkTurnId(request, dependencies.codexClient);
27901
27942
  const prepared = await dependencies.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
27902
27943
  const response = await dependencies.codexClient.threadFork({
27944
+ excludeTurns: true,
27903
27945
  config: prepared.config,
27904
27946
  cwd: request.cwd,
27905
27947
  ...lastTurnId !== void 0 && { lastTurnId },
@@ -27922,10 +27964,7 @@ async function forkSession(request, additionalDirectories, dependencies) {
27922
27964
  async function resolveForkTurnId(request, codexClient) {
27923
27965
  const forkPoint = readAirForkPoint(request._meta);
27924
27966
  if (!forkPoint) return void 0;
27925
- const history = await codexClient.threadRead({
27926
- threadId: request.sessionId,
27927
- includeTurns: true
27928
- });
27967
+ const history = await codexClient.threadReadWithHistory(request.sessionId);
27929
27968
  const candidateIds = airForkMessageIdCandidates(forkPoint.messageId);
27930
27969
  const itemTurnId = candidateIds.map((candidateId) => history.thread.turns.find((turn) => turn.items.some((item) => item.id === candidateId))?.id).find((turnId) => turnId !== void 0);
27931
27970
  if (itemTurnId) return itemTurnId;
@@ -28380,6 +28419,7 @@ var CodexAcpClient = class {
28380
28419
  const prepared = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
28381
28420
  await this.restrictResumedHttpMcpServers(request.sessionId, prepared);
28382
28421
  const response = await this.codexClient.threadResume({
28422
+ excludeTurns: true,
28383
28423
  config: prepared.config,
28384
28424
  cwd: request.cwd,
28385
28425
  modelProvider: await this.getResumeModelProvider(),
@@ -28419,6 +28459,7 @@ var CodexAcpClient = class {
28419
28459
  const prepared = await this.createSessionConfig(request.cwd, additionalDirectories, request.mcpServers ?? []);
28420
28460
  await this.restrictResumedHttpMcpServers(request.sessionId, prepared);
28421
28461
  const response = await this.codexClient.threadResume({
28462
+ excludeTurns: true,
28422
28463
  config: prepared.config,
28423
28464
  cwd: request.cwd,
28424
28465
  modelProvider: await this.getResumeModelProvider(),
@@ -28426,10 +28467,10 @@ var CodexAcpClient = class {
28426
28467
  ...this.permissionProfileSelection(initialAgentMode, request.cwd, additionalDirectories)
28427
28468
  });
28428
28469
  onSubscribed?.();
28429
- const historyResponse = await this.codexClient.threadRead({
28430
- threadId: response.thread.id,
28431
- includeTurns: true
28432
- });
28470
+ const thread = response.thread.historyMode === "paginated" ? {
28471
+ ...response.thread,
28472
+ turns: response.turnsBackwardsCursor === null ? [] : await this.codexClient.threadReadHistory(response.thread.id, response.turnsBackwardsCursor)
28473
+ } : (await this.codexClient.threadReadWithHistory(response.thread.id)).thread;
28433
28474
  const codexModels = await this.fetchAvailableModels();
28434
28475
  const currentModelId = this.createModelId(codexModels, response.model, response.reasoningEffort).toString();
28435
28476
  return {
@@ -28439,16 +28480,13 @@ var CodexAcpClient = class {
28439
28480
  collaborationMode: this.getCollaborationMode(response.thread.id),
28440
28481
  modelProvider: response.modelProvider,
28441
28482
  currentServiceTier: response.serviceTier ?? null,
28442
- thread: historyResponse.thread,
28483
+ thread,
28443
28484
  additionalDirectories,
28444
28485
  fullAccessHttpMcpServers: prepared.fullAccessHttpMcpServers
28445
28486
  };
28446
28487
  }
28447
28488
  async readSessionThread(sessionId) {
28448
- return (await this.codexClient.threadRead({
28449
- threadId: sessionId,
28450
- includeTurns: true
28451
- })).thread;
28489
+ return (await this.codexClient.threadReadWithHistory(sessionId)).thread;
28452
28490
  }
28453
28491
  async newSession(request) {
28454
28492
  const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
@@ -28761,6 +28799,7 @@ var CodexAcpClient = class {
28761
28799
  let lateStopReason = null;
28762
28800
  try {
28763
28801
  const forkPromise = this.codexClient.threadFork({
28802
+ excludeTurns: true,
28764
28803
  threadId: params.sessionId,
28765
28804
  lastTurnId: params.turnId,
28766
28805
  cwd: params.workspace.cwd,
@@ -29607,6 +29646,41 @@ var CodexAppServerClient = class {
29607
29646
  async threadRead(params) {
29608
29647
  return await this.sendRequest({ method: "thread/read", params });
29609
29648
  }
29649
+ async threadTurnsList(params) {
29650
+ return await this.sendRequest({ method: "thread/turns/list", params });
29651
+ }
29652
+ async threadReadWithHistory(threadId) {
29653
+ const response = await this.threadRead({ threadId });
29654
+ if (response.thread.historyMode === "legacy") {
29655
+ return await this.threadRead({ threadId, includeTurns: true });
29656
+ }
29657
+ const turns = await this.threadReadHistory(threadId);
29658
+ return { ...response, thread: { ...response.thread, turns } };
29659
+ }
29660
+ async threadReadHistory(threadId, initialCursor = null) {
29661
+ const turns = [];
29662
+ const seenCursors = /* @__PURE__ */ new Set();
29663
+ if (initialCursor !== null) seenCursors.add(initialCursor);
29664
+ let cursor = initialCursor;
29665
+ do {
29666
+ const page = await this.threadTurnsList({
29667
+ threadId,
29668
+ cursor,
29669
+ limit: 50,
29670
+ sortDirection: "desc",
29671
+ itemsView: "full"
29672
+ });
29673
+ turns.push(...page.data);
29674
+ cursor = page.nextCursor;
29675
+ if (cursor !== null) {
29676
+ if (seenCursors.has(cursor)) {
29677
+ throw new Error("Codex returned a repeated thread history cursor");
29678
+ }
29679
+ seenCursors.add(cursor);
29680
+ }
29681
+ } while (cursor !== null);
29682
+ return turns.reverse();
29683
+ }
29610
29684
  async threadArchive(params) {
29611
29685
  return await this.sendRequest({ method: "thread/archive", params });
29612
29686
  }
@@ -30045,6 +30119,10 @@ function extractTurnRouting(notification) {
30045
30119
  // src/ModelConfigOption.ts
30046
30120
  var MODEL_CONFIG_ID = "model";
30047
30121
  var REASONING_EFFORT_CONFIG_ID = "reasoning_effort";
30122
+ function formatModelDisplayName(displayName) {
30123
+ if (!/^gpt-/i.test(displayName)) return displayName;
30124
+ return displayName.replace(/^gpt-/i, "").split(/[-/]+/).filter(Boolean).map(capitalize).join(" ");
30125
+ }
30048
30126
  function capitalize(value) {
30049
30127
  return value.charAt(0).toUpperCase() + value.slice(1);
30050
30128
  }
@@ -30052,19 +30130,20 @@ function findSupportedEffort(options, effort) {
30052
30130
  if (!effort) return void 0;
30053
30131
  return options.find((o) => o.reasoningEffort === effort)?.reasoningEffort;
30054
30132
  }
30055
- function createModelConfigOption(availableModels, currentBaseModelId) {
30133
+ function createModelConfigOption(availableModels, currentBaseModelId, recommendedModelId) {
30056
30134
  const options = availableModels.map((model) => ({
30057
30135
  value: model.id,
30058
- name: model.displayName,
30136
+ name: formatModelDisplayName(model.displayName),
30059
30137
  description: model.description
30060
30138
  }));
30061
30139
  if (!availableModels.some((model) => model.id === currentBaseModelId)) {
30062
30140
  options.unshift({
30063
30141
  value: currentBaseModelId,
30064
- name: currentBaseModelId,
30142
+ name: formatModelDisplayName(currentBaseModelId),
30065
30143
  description: null
30066
30144
  });
30067
30145
  }
30146
+ const recommendation = recommendedModelId && options.some((option) => option.value === recommendedModelId) ? recommendedModelId : void 0;
30068
30147
  return {
30069
30148
  id: MODEL_CONFIG_ID,
30070
30149
  name: "Model",
@@ -30072,10 +30151,12 @@ function createModelConfigOption(availableModels, currentBaseModelId) {
30072
30151
  category: "model",
30073
30152
  type: "select",
30074
30153
  currentValue: currentBaseModelId,
30075
- options
30154
+ options,
30155
+ ...recommendation ? { _meta: withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, recommendation) } : {}
30076
30156
  };
30077
30157
  }
30078
- function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort) {
30158
+ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort, recommendedEffort) {
30159
+ const recommendation = findSupportedEffort(supportedReasoningEfforts, recommendedEffort);
30079
30160
  return {
30080
30161
  id: REASONING_EFFORT_CONFIG_ID,
30081
30162
  name: "Reasoning effort",
@@ -30087,7 +30168,8 @@ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEff
30087
30168
  value: option.reasoningEffort,
30088
30169
  name: capitalize(option.reasoningEffort),
30089
30170
  description: option.description
30090
- }))
30171
+ })),
30172
+ ...recommendation ? { _meta: withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, recommendation) } : {}
30091
30173
  };
30092
30174
  }
30093
30175
 
@@ -30787,14 +30869,14 @@ function parseJsonRecord(line) {
30787
30869
  }
30788
30870
  try {
30789
30871
  const value = JSON.parse(line);
30790
- return asRecord2(value);
30872
+ return asRecord3(value);
30791
30873
  } catch {
30792
30874
  return null;
30793
30875
  }
30794
30876
  }
30795
30877
  function extractResponseItem(record2) {
30796
30878
  if (record2["type"] === "response_item") {
30797
- return asRecord2(record2["payload"]);
30879
+ return asRecord3(record2["payload"]);
30798
30880
  }
30799
30881
  const itemType = record2["type"];
30800
30882
  if (typeof itemType === "string" && isLegacyResponseItemType(itemType)) {
@@ -30828,7 +30910,7 @@ function createEventMsgUpdates(record2) {
30828
30910
  if (record2["type"] !== "event_msg") {
30829
30911
  return null;
30830
30912
  }
30831
- const payload = asRecord2(record2["payload"]);
30913
+ const payload = asRecord3(record2["payload"]);
30832
30914
  if (!payload) {
30833
30915
  return [];
30834
30916
  }
@@ -30872,7 +30954,7 @@ function imageBlocks(images) {
30872
30954
  if (typeof image === "string") {
30873
30955
  return [{ type: "text", text: `[@image](${image})` }];
30874
30956
  }
30875
- const record2 = asRecord2(image);
30957
+ const record2 = asRecord3(image);
30876
30958
  const path9 = record2 ? stringValue(record2["path"]) ?? stringValue(record2["url"]) : null;
30877
30959
  return path9 ? [{ type: "text", text: `[@image](${path9})` }] : [];
30878
30960
  });
@@ -30882,7 +30964,7 @@ function contentBlocksFromResponseContent(content) {
30882
30964
  return [];
30883
30965
  }
30884
30966
  return content.flatMap((entry) => {
30885
- const record2 = asRecord2(entry);
30967
+ const record2 = asRecord3(entry);
30886
30968
  if (!record2) {
30887
30969
  return [];
30888
30970
  }
@@ -30915,7 +30997,7 @@ function textParts(value) {
30915
30997
  if (typeof entry === "string") {
30916
30998
  return entry.length > 0 ? [entry] : [];
30917
30999
  }
30918
- const record2 = asRecord2(entry);
31000
+ const record2 = asRecord3(entry);
30919
31001
  if (!record2) {
30920
31002
  return [];
30921
31003
  }
@@ -31007,7 +31089,7 @@ function parseFunctionArguments(value) {
31007
31089
  }
31008
31090
  function rawInputForFunctionCall(name, args) {
31009
31091
  if (name === "exec_command") {
31010
- const record2 = asRecord2(args);
31092
+ const record2 = asRecord3(args);
31011
31093
  if (record2) {
31012
31094
  return {
31013
31095
  command: stringValue(record2["cmd"]) ?? stringValue(record2["command"]),
@@ -31054,14 +31136,14 @@ function functionCallUsesTerminal(item) {
31054
31136
  return item["name"] === "exec_command";
31055
31137
  }
31056
31138
  function commandFromFunctionArguments(args) {
31057
- const record2 = asRecord2(args);
31139
+ const record2 = asRecord3(args);
31058
31140
  if (!record2) {
31059
31141
  return null;
31060
31142
  }
31061
31143
  return stringValue(record2["cmd"]) ?? stringValue(record2["command"]);
31062
31144
  }
31063
31145
  function cwdFromFunctionArguments(args) {
31064
- const record2 = asRecord2(args);
31146
+ const record2 = asRecord3(args);
31065
31147
  if (!record2) {
31066
31148
  return "";
31067
31149
  }
@@ -31533,7 +31615,7 @@ function outputText(output) {
31533
31615
  return "";
31534
31616
  }
31535
31617
  return output.flatMap((entry) => {
31536
- const record2 = asRecord2(entry);
31618
+ const record2 = asRecord3(entry);
31537
31619
  if (!record2) {
31538
31620
  return [];
31539
31621
  }
@@ -31549,7 +31631,7 @@ function outputText(output) {
31549
31631
  }).join("\n");
31550
31632
  }
31551
31633
  function parseExitCode(rawOutput, output) {
31552
- const record2 = asRecord2(rawOutput);
31634
+ const record2 = asRecord3(rawOutput);
31553
31635
  if (record2) {
31554
31636
  const exitCode2 = numberValue(record2["exit_code"]) ?? numberValue(record2["exitCode"]);
31555
31637
  if (exitCode2 !== null) {
@@ -31580,7 +31662,7 @@ function looksLikeCommandFailure(output) {
31580
31662
  }
31581
31663
  return /(^|\n)(Error|Failed|Command failed|Sandbox error|No such file or directory|Permission denied|Operation not permitted|ENOENT|EACCES)(:|\b)/i.test(trimmed);
31582
31664
  }
31583
- function asRecord2(value) {
31665
+ function asRecord3(value) {
31584
31666
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
31585
31667
  return null;
31586
31668
  }
@@ -32230,12 +32312,7 @@ function clientSupportsTypedSessionFailures(capabilities) {
32230
32312
  function clientSupportsAgentFileChangeReports(capabilities) {
32231
32313
  return clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY);
32232
32314
  }
32233
- var CodexAcpServer = class _CodexAcpServer {
32234
- static MODEL_NAME_TOKEN_OVERRIDES = {
32235
- gpt: "GPT",
32236
- mini: "Mini",
32237
- codex: "Codex"
32238
- };
32315
+ var CodexAcpServer = class {
32239
32316
  codexAcpClient;
32240
32317
  connection;
32241
32318
  defaultAuthRequest;
@@ -32362,7 +32439,8 @@ var CodexAcpServer = class _CodexAcpServer {
32362
32439
  AIR_SESSION_FAILURE_KEY,
32363
32440
  AIR_AGENT_FILE_CHANGE_REPORT_KEY,
32364
32441
  AIR_NATIVE_SUBAGENT_SESSIONS_KEY,
32365
- AIR_ASYNC_TASKS_KEY
32442
+ AIR_ASYNC_TASKS_KEY,
32443
+ AIR_RECOMMENDED_CONFIG_VALUE_KEY
32366
32444
  ]
32367
32445
  }
32368
32446
  }
@@ -33535,14 +33613,24 @@ Check ${configPath} and project .codex directories, especially their config.toml
33535
33613
  }
33536
33614
  createSessionConfigOptions(sessionState) {
33537
33615
  const currentModelId = ModelId.fromString(sessionState.currentModelId);
33616
+ const useRecommendedValue = clientSupportsAirCapability(
33617
+ this.clientCapabilities,
33618
+ AIR_RECOMMENDED_CONFIG_VALUE_KEY
33619
+ );
33620
+ const currentModel = this.findCurrentModel(sessionState.availableModels, sessionState.currentModelId);
33621
+ const recommendedModelId = useRecommendedValue ? sessionState.availableModels.find((model) => model.isDefault)?.id : void 0;
33538
33622
  const configOptions = [
33539
33623
  sessionState.agentMode.toConfigOption(),
33540
33624
  createCollaborationModeConfigOption(sessionState.collaborationMode),
33541
- createModelConfigOption(sessionState.availableModels, currentModelId.model)
33625
+ createModelConfigOption(sessionState.availableModels, currentModelId.model, recommendedModelId)
33542
33626
  ];
33543
33627
  if (sessionState.supportedReasoningEfforts.length > 0) {
33544
33628
  configOptions.push(
33545
- createReasoningEffortConfigOption(sessionState.supportedReasoningEfforts, currentModelId.effort)
33629
+ createReasoningEffortConfigOption(
33630
+ sessionState.supportedReasoningEfforts,
33631
+ currentModelId.effort,
33632
+ useRecommendedValue ? currentModel?.defaultReasoningEffort : void 0
33633
+ )
33546
33634
  );
33547
33635
  }
33548
33636
  if (sessionState.currentModelSupportsFast) {
@@ -33619,14 +33707,11 @@ Check ${configPath} and project .codex directories, especially their config.toml
33619
33707
  const modelId = ModelId.fromString(currentModelId);
33620
33708
  return models.find((m) => m.id === modelId.model);
33621
33709
  }
33622
- normalizeModelDisplayName(displayName) {
33623
- return displayName.split("-").map((token) => _CodexAcpServer.MODEL_NAME_TOKEN_OVERRIDES[token.toLowerCase()] ?? token).join("-");
33624
- }
33625
33710
  createModelState(availableModels, selectedModelId) {
33626
33711
  const allowedModels = availableModels.flatMap(
33627
33712
  (model) => model.supportedReasoningEfforts.map((effort) => ({
33628
33713
  modelId: ModelId.fromComponents(model, effort.reasoningEffort).toString(),
33629
- name: `${this.normalizeModelDisplayName(model.displayName)} (${effort.reasoningEffort})`,
33714
+ name: `${formatModelDisplayName(model.displayName)} (${effort.reasoningEffort})`,
33630
33715
  description: `${model.description} ${effort.description}`
33631
33716
  }))
33632
33717
  );
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.10.0-agentconnect.2",
6
+ "version": "1.11.0-agentconnect.1",
7
7
  "description": "",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
@@ -65,7 +65,7 @@
65
65
  },
66
66
  "dependencies": {
67
67
  "@agentclientprotocol/sdk": "^1.4.0",
68
- "@openai/codex": "^0.153.3",
68
+ "@openai/codex": "^0.153.4",
69
69
  "diff": "^9.0.0",
70
70
  "open": "^11.0.1",
71
71
  "vscode-jsonrpc": "^9.0.1",