@nyssance/codex-acp-v2 0.7.12 → 0.7.13

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.13 — 2026-10-13
4
+
5
+ ### Fixed
6
+
7
+ - Match gateway model capabilities by upstream model, including hidden native models,
8
+ and omit reasoning effort settings when the model declares no supported levels.
9
+ - Normalize unsupported reasoning efforts when selecting a model.
10
+ - Recognize local commands after leading file attachments and preserve attachments
11
+ when `/plan <task>` starts a turn.
12
+
3
13
  ## 0.7.12 — 2026-10-13
4
14
 
5
15
  ### Added
package/dist/index.js CHANGED
@@ -22168,7 +22168,7 @@ var package_default = {
22168
22168
  publishConfig: {
22169
22169
  access: "public"
22170
22170
  },
22171
- version: "0.7.12",
22171
+ version: "0.7.13",
22172
22172
  description: "Native ACP v2 agent for the OpenAI Codex app-server",
22173
22173
  packageManager: "bun@1.4.0",
22174
22174
  engines: {
@@ -25390,7 +25390,7 @@ class AppServerClient {
25390
25390
  const cursors = new Set;
25391
25391
  let cursor = null;
25392
25392
  do {
25393
- const page = await this.modelList({ cursor, limit: null });
25393
+ const page = await this.modelList({ cursor, limit: null, includeHidden: true });
25394
25394
  models.push(...page.data);
25395
25395
  cursor = page.nextCursor;
25396
25396
  if (cursor) {
@@ -25805,12 +25805,12 @@ class ProviderRouting {
25805
25805
  if (first.mode === "route") {
25806
25806
  if (first.models.length === 0)
25807
25807
  return codexCatalog;
25808
- return first.models.map((model, index) => gatewayModel(model, index === 0, codexCatalog[0], first.catalogEntries.get(model.id)));
25808
+ return first.models.map((model, index) => gatewayModel(model, index === 0, codexCatalog.find((entry) => entry.model === model.id), first.catalogEntries.get(model.id)));
25809
25809
  }
25810
25810
  const own = [];
25811
25811
  for (const gateway of this.gateways.values()) {
25812
25812
  for (const model of gateway.models)
25813
- own.push({ ...gatewayModel(model, false, codexCatalog[0], gateway.catalogEntries.get(model.id)), id: gatewayModelId(gateway.id, model.id) });
25813
+ own.push({ ...gatewayModel(model, false, codexCatalog.find((entry) => entry.model === model.id), gateway.catalogEntries.get(model.id)), id: gatewayModelId(gateway.id, model.id) });
25814
25814
  }
25815
25815
  return [...codexCatalog, ...own];
25816
25816
  }
@@ -25917,7 +25917,7 @@ function readCatalogFile(catalogPath) {
25917
25917
  return entries;
25918
25918
  }
25919
25919
  function gatewayModel(model, isDefault, template, entry) {
25920
- const efforts = entry && entry.efforts.length > 0 ? entry.efforts : template?.supportedReasoningEfforts ?? [];
25920
+ const efforts = entry ? entry.efforts : template?.supportedReasoningEfforts ?? [];
25921
25921
  const defaultEffort = entry?.defaultEffort ?? template?.defaultReasoningEffort ?? "medium";
25922
25922
  return {
25923
25923
  id: model.id,
@@ -25952,13 +25952,13 @@ var FAST_SERVICE_TIER = "fast";
25952
25952
  function resolveModelSelection(catalog, modelId, effort) {
25953
25953
  const listed = modelId === null ? undefined : catalog.find((model) => model.id === modelId);
25954
25954
  if (listed)
25955
- return { model: listed.id, effort: effort ?? listed.defaultReasoningEffort };
25955
+ return { model: listed.id, effort: coerceEffort(listed, effort ?? listed.defaultReasoningEffort) };
25956
25956
  if (modelId)
25957
25957
  return { model: modelId, effort: effort ?? DEFAULT_EFFORT };
25958
25958
  const fallback = catalog.find((model) => model.isDefault) ?? catalog[0];
25959
25959
  if (!fallback)
25960
25960
  throw new Error("Codex did not return any models");
25961
- return { model: fallback.id, effort: effort ?? fallback.defaultReasoningEffort };
25961
+ return { model: fallback.id, effort: coerceEffort(fallback, effort ?? fallback.defaultReasoningEffort) };
25962
25962
  }
25963
25963
  function findModel(catalog, modelId) {
25964
25964
  return catalog.find((model) => model.id === modelId);
@@ -27814,7 +27814,7 @@ var BUILTIN_COMMANDS = [
27814
27814
  { name: "logout", description: "Sign out of the Codex account" }
27815
27815
  ];
27816
27816
  function parseCommand(prompt) {
27817
- const first = prompt[0];
27817
+ const first = prompt.find(ContentBlock.isText);
27818
27818
  if (!first || first.type !== "text")
27819
27819
  return null;
27820
27820
  const text2 = first.text.trim();
@@ -27899,7 +27899,7 @@ function statusMessage(session, rateLimits) {
27899
27899
  "**Session**",
27900
27900
  `**Session ID:** ${session.id}`,
27901
27901
  `**Working directory:** ${session.cwd}`,
27902
- `**Model:** ${session.model.model} (${session.model.effort})`,
27902
+ `**Model:** ${session.model.model}${supportedEfforts(findModel(session.catalog, session.model.model)).length > 0 ? ` (${session.model.effort})` : ""}`,
27903
27903
  `**Mode:** ${session.mode.name}`,
27904
27904
  `**Collaboration:** ${session.collaborationMode}`,
27905
27905
  `**Fast mode:** ${session.fastMode ? "on" : "off"}`,
@@ -27962,7 +27962,7 @@ function sessionConfigOptions(session) {
27962
27962
  const options = [
27963
27963
  modeConfigOption(session.mode),
27964
27964
  modelConfigOption(session.catalog, session.model.model, session.gatewayGroups),
27965
- effortConfigOption(supportedEfforts(model), session.model.effort),
27965
+ ...supportedEfforts(model).length > 0 ? [effortConfigOption(supportedEfforts(model), session.model.effort)] : [],
27966
27966
  collaborationModeConfigOption(session.collaborationMode)
27967
27967
  ];
27968
27968
  if (modelSupportsFast(model))
@@ -27990,7 +27990,7 @@ async function applyConfigOption(session, codex, request) {
27990
27990
  const effort = stringValue(request);
27991
27991
  const model = findModel(session.catalog, session.model.model);
27992
27992
  const efforts = supportedEfforts(model);
27993
- if (efforts.length > 0 && !efforts.some((option) => option.reasoningEffort === effort)) {
27993
+ if (!efforts.some((option) => option.reasoningEffort === effort)) {
27994
27994
  throw RequestError.invalidParams({ configId: request.configId }, `Model ${session.model.model} does not support effort "${effort}"`);
27995
27995
  }
27996
27996
  session.model = { ...session.model, effort };
@@ -28014,7 +28014,7 @@ async function applyConfigOption(session, codex, request) {
28014
28014
  threadId: session.id,
28015
28015
  collaborationMode: {
28016
28016
  mode,
28017
- settings: { model: findModel(session.catalog, session.model.model)?.model ?? session.model.model, reasoning_effort: session.model.effort, developer_instructions: null }
28017
+ settings: { model: findModel(session.catalog, session.model.model)?.model ?? session.model.model, reasoning_effort: supportedEfforts(findModel(session.catalog, session.model.model)).length > 0 ? session.model.effort : null, developer_instructions: null }
28018
28018
  }
28019
28019
  });
28020
28020
  session.collaborationMode = mode;
@@ -29664,7 +29664,9 @@ class CodexAgent {
29664
29664
  case "config":
29665
29665
  await this.setSessionConfigOption({ sessionId: session.id, configId: outcome.configId, type: "id", value: outcome.value });
29666
29666
  if (outcome.promptText) {
29667
- completed = await this.runCodexTurn(runtime, turn, [{ type: "text", text: outcome.promptText }, ...params.prompt.slice(1)]);
29667
+ const promptText = outcome.promptText;
29668
+ const commandText = params.prompt.find(ContentBlock.isText);
29669
+ completed = await this.runCodexTurn(runtime, turn, params.prompt.map((block) => block === commandText ? { ...block, type: "text", text: promptText } : block));
29668
29670
  } else {
29669
29671
  await client.update(agentMessage(`command:${turn.clientUserMessageId}`, `Plan mode ${outcome.value === PLAN_COLLABORATION_MODE ? "enabled" : "disabled"}.`));
29670
29672
  }
@@ -29717,7 +29719,7 @@ class CodexAgent {
29717
29719
  approvalsReviewer: session.mode.approvalsReviewer,
29718
29720
  sandboxPolicy: withWritableRoots(session.mode.sandboxPolicy, session.additionalDirectories),
29719
29721
  model: this.providers.upstreamModel(session.model.model),
29720
- effort: session.model.effort,
29722
+ effort: supportedEfforts(model).length > 0 ? session.model.effort : null,
29721
29723
  summary: disableSummary ? "none" : "auto",
29722
29724
  serviceTier: session.fastMode ? FAST_SERVICE_TIER : null
29723
29725
  }, (turnId) => {
package/docs/protocol.md CHANGED
@@ -309,7 +309,7 @@ perform the separate reversible `_codex/session_archive` operation.
309
309
  | --- | --- | --- | --- |
310
310
  | `mode` | `mode` | select | `read-only`, `agent`, `agent-full-access` |
311
311
  | `model` | `model` | select | Codex catalog ids (the current id is always listed) |
312
- | `effort` | `thought_level` | select | efforts supported by the current model |
312
+ | `effort` | `thought_level` | select | efforts supported by the current model; omitted when no levels are declared |
313
313
  | `collaboration_mode` | `model_config` | select | `default`, `plan` |
314
314
  | `fast_mode` | `model_config` | boolean | only when the model offers the `fast` service tier |
315
315
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.7.12",
6
+ "version": "0.7.13",
7
7
  "description": "Native ACP v2 agent for the OpenAI Codex app-server",
8
8
  "packageManager": "bun@1.4.0",
9
9
  "engines": {