@agentclientprotocol/codex-acp 1.10.1-preview.1 → 1.10.1-preview.3

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 +1 -0
  2. package/dist/index.js +74 -42
  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.
package/dist/index.js CHANGED
@@ -23660,16 +23660,37 @@ var AIR_SESSION_FAILURE_KEY = "sessionFailure";
23660
23660
  var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
23661
23661
  var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
23662
23662
  var AIR_ASYNC_TASKS_KEY = "asyncTasks";
23663
+ var AIR_RECOMMENDED_CONFIG_VALUE_KEY = "recommendedValue";
23663
23664
  var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
23664
23665
  var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
23665
23666
  var AIR_EXTENSION_VERSION = 1;
23667
+ function withAirMeta(meta3, key, value) {
23668
+ const root = asRecord(meta3);
23669
+ const jetbrains = asRecord(root[JETBRAINS_META_KEY]);
23670
+ const air = asRecord(jetbrains[AIR_META_KEY]);
23671
+ return {
23672
+ ...root,
23673
+ [JETBRAINS_META_KEY]: {
23674
+ ...jetbrains,
23675
+ [AIR_META_KEY]: {
23676
+ ...air,
23677
+ [AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
23678
+ [key]: value
23679
+ }
23680
+ }
23681
+ };
23682
+ }
23666
23683
  function clientSupportsAirCapability(capabilities, capability) {
23667
- const jetbrains = capabilities?._meta?.[JETBRAINS_META_KEY];
23668
- const air = jetbrains?.[AIR_META_KEY];
23669
- const version2 = air?.[AIR_EXTENSION_VERSION_KEY];
23670
- const supported = air?.[AIR_EXTENSION_CAPABILITIES_KEY];
23684
+ const meta3 = asRecord(capabilities?._meta);
23685
+ const jetbrains = asRecord(meta3[JETBRAINS_META_KEY]);
23686
+ const air = asRecord(jetbrains[AIR_META_KEY]);
23687
+ const version2 = air[AIR_EXTENSION_VERSION_KEY];
23688
+ const supported = air[AIR_EXTENSION_CAPABILITIES_KEY];
23671
23689
  return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
23672
23690
  }
23691
+ function asRecord(value) {
23692
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
23693
+ }
23673
23694
 
23674
23695
  // src/subagents/CodexAgentPath.ts
23675
23696
  function normalizeAgentPath(path9) {
@@ -27339,7 +27360,7 @@ var package_default = {
27339
27360
  publishConfig: {
27340
27361
  access: "public"
27341
27362
  },
27342
- version: "1.10.1-preview.1",
27363
+ version: "1.10.1-preview.3",
27343
27364
  description: "",
27344
27365
  main: "dist/index.js",
27345
27366
  bin: {
@@ -27402,7 +27423,7 @@ var package_default = {
27402
27423
  },
27403
27424
  dependencies: {
27404
27425
  "@agentclientprotocol/sdk": "^1.4.0",
27405
- "@openai/codex": "^0.153.3",
27426
+ "@openai/codex": "^0.153.4",
27406
27427
  diff: "^9.0.0",
27407
27428
  open: "^11.0.1",
27408
27429
  "vscode-jsonrpc": "^9.0.1",
@@ -27535,9 +27556,9 @@ Working directory: ${JSON.stringify(workspace.cwd)}
27535
27556
  Additional allowed directories: ${JSON.stringify(workspace.additionalDirectories)}`;
27536
27557
  }
27537
27558
  function parseAgentFileChangeReportRequest(meta3) {
27538
- const jetbrains = asRecord(meta3?.[JETBRAINS_META_KEY]);
27539
- const air = asRecord(jetbrains?.[AIR_META_KEY]);
27540
- const request = asRecord(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
27559
+ const jetbrains = asRecord2(meta3?.[JETBRAINS_META_KEY]);
27560
+ const air = asRecord2(jetbrains?.[AIR_META_KEY]);
27561
+ const request = asRecord2(air?.[AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY]);
27541
27562
  if (request === null || !hasOnlyKeys(request, ["version", "requestId"]) || request["version"] !== AGENT_FILE_CHANGE_REPORT_VERSION) {
27542
27563
  return null;
27543
27564
  }
@@ -27604,7 +27625,7 @@ function parseModelFileChangeReport(turn) {
27604
27625
  } catch {
27605
27626
  throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned invalid JSON");
27606
27627
  }
27607
- const report = asRecord(value);
27628
+ const report = asRecord2(value);
27608
27629
  if (report === null || !hasOnlyKeys(report, ["paths", "complete", "uncertainty"])) {
27609
27630
  throw new AgentFileChangeReportError("invalidOutput", "The audit turn returned an invalid object");
27610
27631
  }
@@ -27781,7 +27802,7 @@ function isWindowsAbsolutePath2(value) {
27781
27802
  function isValidPathText(value) {
27782
27803
  return value.length > 0 && !/[\u0000-\u001F\u007F-\u009F]/.test(value);
27783
27804
  }
27784
- function asRecord(value) {
27805
+ function asRecord2(value) {
27785
27806
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
27786
27807
  }
27787
27808
  function hasOnlyKeys(value, allowed) {
@@ -30007,6 +30028,10 @@ function extractTurnRouting(notification) {
30007
30028
  // src/ModelConfigOption.ts
30008
30029
  var MODEL_CONFIG_ID = "model";
30009
30030
  var REASONING_EFFORT_CONFIG_ID = "reasoning_effort";
30031
+ function formatModelDisplayName(displayName) {
30032
+ if (!/^gpt-/i.test(displayName)) return displayName;
30033
+ return displayName.replace(/^gpt-/i, "").split(/[-/]+/).filter(Boolean).map(capitalize).join(" ");
30034
+ }
30010
30035
  function capitalize(value) {
30011
30036
  return value.charAt(0).toUpperCase() + value.slice(1);
30012
30037
  }
@@ -30014,19 +30039,20 @@ function findSupportedEffort(options, effort) {
30014
30039
  if (!effort) return void 0;
30015
30040
  return options.find((o) => o.reasoningEffort === effort)?.reasoningEffort;
30016
30041
  }
30017
- function createModelConfigOption(availableModels, currentBaseModelId) {
30042
+ function createModelConfigOption(availableModels, currentBaseModelId, recommendedModelId) {
30018
30043
  const options = availableModels.map((model) => ({
30019
30044
  value: model.id,
30020
- name: model.displayName,
30045
+ name: formatModelDisplayName(model.displayName),
30021
30046
  description: model.description
30022
30047
  }));
30023
30048
  if (!availableModels.some((model) => model.id === currentBaseModelId)) {
30024
30049
  options.unshift({
30025
30050
  value: currentBaseModelId,
30026
- name: currentBaseModelId,
30051
+ name: formatModelDisplayName(currentBaseModelId),
30027
30052
  description: null
30028
30053
  });
30029
30054
  }
30055
+ const recommendation = recommendedModelId && options.some((option) => option.value === recommendedModelId) ? recommendedModelId : void 0;
30030
30056
  return {
30031
30057
  id: MODEL_CONFIG_ID,
30032
30058
  name: "Model",
@@ -30034,10 +30060,12 @@ function createModelConfigOption(availableModels, currentBaseModelId) {
30034
30060
  category: "model",
30035
30061
  type: "select",
30036
30062
  currentValue: currentBaseModelId,
30037
- options
30063
+ options,
30064
+ ...recommendation ? { _meta: withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, recommendation) } : {}
30038
30065
  };
30039
30066
  }
30040
- function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort) {
30067
+ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort, recommendedEffort) {
30068
+ const recommendation = findSupportedEffort(supportedReasoningEfforts, recommendedEffort);
30041
30069
  return {
30042
30070
  id: REASONING_EFFORT_CONFIG_ID,
30043
30071
  name: "Reasoning effort",
@@ -30049,7 +30077,8 @@ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEff
30049
30077
  value: option.reasoningEffort,
30050
30078
  name: capitalize(option.reasoningEffort),
30051
30079
  description: option.description
30052
- }))
30080
+ })),
30081
+ ...recommendation ? { _meta: withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, recommendation) } : {}
30053
30082
  };
30054
30083
  }
30055
30084
 
@@ -30749,14 +30778,14 @@ function parseJsonRecord(line) {
30749
30778
  }
30750
30779
  try {
30751
30780
  const value = JSON.parse(line);
30752
- return asRecord2(value);
30781
+ return asRecord3(value);
30753
30782
  } catch {
30754
30783
  return null;
30755
30784
  }
30756
30785
  }
30757
30786
  function extractResponseItem(record2) {
30758
30787
  if (record2["type"] === "response_item") {
30759
- return asRecord2(record2["payload"]);
30788
+ return asRecord3(record2["payload"]);
30760
30789
  }
30761
30790
  const itemType = record2["type"];
30762
30791
  if (typeof itemType === "string" && isLegacyResponseItemType(itemType)) {
@@ -30790,7 +30819,7 @@ function createEventMsgUpdates(record2) {
30790
30819
  if (record2["type"] !== "event_msg") {
30791
30820
  return null;
30792
30821
  }
30793
- const payload = asRecord2(record2["payload"]);
30822
+ const payload = asRecord3(record2["payload"]);
30794
30823
  if (!payload) {
30795
30824
  return [];
30796
30825
  }
@@ -30834,7 +30863,7 @@ function imageBlocks(images) {
30834
30863
  if (typeof image === "string") {
30835
30864
  return [{ type: "text", text: `[@image](${image})` }];
30836
30865
  }
30837
- const record2 = asRecord2(image);
30866
+ const record2 = asRecord3(image);
30838
30867
  const path9 = record2 ? stringValue(record2["path"]) ?? stringValue(record2["url"]) : null;
30839
30868
  return path9 ? [{ type: "text", text: `[@image](${path9})` }] : [];
30840
30869
  });
@@ -30844,7 +30873,7 @@ function contentBlocksFromResponseContent(content) {
30844
30873
  return [];
30845
30874
  }
30846
30875
  return content.flatMap((entry) => {
30847
- const record2 = asRecord2(entry);
30876
+ const record2 = asRecord3(entry);
30848
30877
  if (!record2) {
30849
30878
  return [];
30850
30879
  }
@@ -30877,7 +30906,7 @@ function textParts(value) {
30877
30906
  if (typeof entry === "string") {
30878
30907
  return entry.length > 0 ? [entry] : [];
30879
30908
  }
30880
- const record2 = asRecord2(entry);
30909
+ const record2 = asRecord3(entry);
30881
30910
  if (!record2) {
30882
30911
  return [];
30883
30912
  }
@@ -30969,7 +30998,7 @@ function parseFunctionArguments(value) {
30969
30998
  }
30970
30999
  function rawInputForFunctionCall(name, args) {
30971
31000
  if (name === "exec_command") {
30972
- const record2 = asRecord2(args);
31001
+ const record2 = asRecord3(args);
30973
31002
  if (record2) {
30974
31003
  return {
30975
31004
  command: stringValue(record2["cmd"]) ?? stringValue(record2["command"]),
@@ -31016,14 +31045,14 @@ function functionCallUsesTerminal(item) {
31016
31045
  return item["name"] === "exec_command";
31017
31046
  }
31018
31047
  function commandFromFunctionArguments(args) {
31019
- const record2 = asRecord2(args);
31048
+ const record2 = asRecord3(args);
31020
31049
  if (!record2) {
31021
31050
  return null;
31022
31051
  }
31023
31052
  return stringValue(record2["cmd"]) ?? stringValue(record2["command"]);
31024
31053
  }
31025
31054
  function cwdFromFunctionArguments(args) {
31026
- const record2 = asRecord2(args);
31055
+ const record2 = asRecord3(args);
31027
31056
  if (!record2) {
31028
31057
  return "";
31029
31058
  }
@@ -31495,7 +31524,7 @@ function outputText(output) {
31495
31524
  return "";
31496
31525
  }
31497
31526
  return output.flatMap((entry) => {
31498
- const record2 = asRecord2(entry);
31527
+ const record2 = asRecord3(entry);
31499
31528
  if (!record2) {
31500
31529
  return [];
31501
31530
  }
@@ -31511,7 +31540,7 @@ function outputText(output) {
31511
31540
  }).join("\n");
31512
31541
  }
31513
31542
  function parseExitCode(rawOutput, output) {
31514
- const record2 = asRecord2(rawOutput);
31543
+ const record2 = asRecord3(rawOutput);
31515
31544
  if (record2) {
31516
31545
  const exitCode2 = numberValue(record2["exit_code"]) ?? numberValue(record2["exitCode"]);
31517
31546
  if (exitCode2 !== null) {
@@ -31542,7 +31571,7 @@ function looksLikeCommandFailure(output) {
31542
31571
  }
31543
31572
  return /(^|\n)(Error|Failed|Command failed|Sandbox error|No such file or directory|Permission denied|Operation not permitted|ENOENT|EACCES)(:|\b)/i.test(trimmed);
31544
31573
  }
31545
- function asRecord2(value) {
31574
+ function asRecord3(value) {
31546
31575
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
31547
31576
  return null;
31548
31577
  }
@@ -32192,12 +32221,7 @@ function clientSupportsTypedSessionFailures(capabilities) {
32192
32221
  function clientSupportsAgentFileChangeReports(capabilities) {
32193
32222
  return clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY);
32194
32223
  }
32195
- var CodexAcpServer = class _CodexAcpServer {
32196
- static MODEL_NAME_TOKEN_OVERRIDES = {
32197
- gpt: "GPT",
32198
- mini: "Mini",
32199
- codex: "Codex"
32200
- };
32224
+ var CodexAcpServer = class {
32201
32225
  codexAcpClient;
32202
32226
  connection;
32203
32227
  defaultAuthRequest;
@@ -32324,7 +32348,8 @@ var CodexAcpServer = class _CodexAcpServer {
32324
32348
  AIR_SESSION_FAILURE_KEY,
32325
32349
  AIR_AGENT_FILE_CHANGE_REPORT_KEY,
32326
32350
  AIR_NATIVE_SUBAGENT_SESSIONS_KEY,
32327
- AIR_ASYNC_TASKS_KEY
32351
+ AIR_ASYNC_TASKS_KEY,
32352
+ AIR_RECOMMENDED_CONFIG_VALUE_KEY
32328
32353
  ]
32329
32354
  }
32330
32355
  }
@@ -33485,14 +33510,24 @@ Check ${configPath} and project .codex directories, especially their config.toml
33485
33510
  }
33486
33511
  createSessionConfigOptions(sessionState) {
33487
33512
  const currentModelId = ModelId.fromString(sessionState.currentModelId);
33513
+ const useRecommendedValue = clientSupportsAirCapability(
33514
+ this.clientCapabilities,
33515
+ AIR_RECOMMENDED_CONFIG_VALUE_KEY
33516
+ );
33517
+ const currentModel = this.findCurrentModel(sessionState.availableModels, sessionState.currentModelId);
33518
+ const recommendedModelId = useRecommendedValue ? sessionState.availableModels.find((model) => model.isDefault)?.id : void 0;
33488
33519
  const configOptions = [
33489
33520
  sessionState.agentMode.toConfigOption(),
33490
33521
  createCollaborationModeConfigOption(sessionState.collaborationMode),
33491
- createModelConfigOption(sessionState.availableModels, currentModelId.model)
33522
+ createModelConfigOption(sessionState.availableModels, currentModelId.model, recommendedModelId)
33492
33523
  ];
33493
33524
  if (sessionState.supportedReasoningEfforts.length > 0) {
33494
33525
  configOptions.push(
33495
- createReasoningEffortConfigOption(sessionState.supportedReasoningEfforts, currentModelId.effort)
33526
+ createReasoningEffortConfigOption(
33527
+ sessionState.supportedReasoningEfforts,
33528
+ currentModelId.effort,
33529
+ useRecommendedValue ? currentModel?.defaultReasoningEffort : void 0
33530
+ )
33496
33531
  );
33497
33532
  }
33498
33533
  if (sessionState.currentModelSupportsFast) {
@@ -33569,14 +33604,11 @@ Check ${configPath} and project .codex directories, especially their config.toml
33569
33604
  const modelId = ModelId.fromString(currentModelId);
33570
33605
  return models.find((m) => m.id === modelId.model);
33571
33606
  }
33572
- normalizeModelDisplayName(displayName) {
33573
- return displayName.split("-").map((token) => _CodexAcpServer.MODEL_NAME_TOKEN_OVERRIDES[token.toLowerCase()] ?? token).join("-");
33574
- }
33575
33607
  createModelState(availableModels, selectedModelId) {
33576
33608
  const allowedModels = availableModels.flatMap(
33577
33609
  (model) => model.supportedReasoningEfforts.map((effort) => ({
33578
33610
  modelId: ModelId.fromComponents(model, effort.reasoningEffort).toString(),
33579
- name: `${this.normalizeModelDisplayName(model.displayName)} (${effort.reasoningEffort})`,
33611
+ name: `${formatModelDisplayName(model.displayName)} (${effort.reasoningEffort})`,
33580
33612
  description: `${model.description} ${effort.description}`
33581
33613
  }))
33582
33614
  );
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.10.1-preview.1",
6
+ "version": "1.10.1-preview.3",
7
7
  "description": "",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@agentclientprotocol/sdk": "^1.4.0",
69
- "@openai/codex": "^0.153.3",
69
+ "@openai/codex": "^0.153.4",
70
70
  "diff": "^9.0.0",
71
71
  "open": "^11.0.1",
72
72
  "vscode-jsonrpc": "^9.0.1",