codex-copilot-dx 0.4.26 → 0.4.27

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/README.md CHANGED
@@ -12,6 +12,8 @@ A single in-process adapter (port `2026`) exposes both APIs over your Copilot su
12
12
 
13
13
  Supports both HTTP SSE streaming and non-streaming.
14
14
 
15
+ Codex Auto-review requests use the hidden `codex-auto-review` model ID. The adapter maps it to Copilot's `gpt-5.4-mini` Responses model by default and logs both model IDs when the mapping is used.
16
+
15
17
  ## Prerequisites
16
18
 
17
19
  - GitHub Copilot subscription (Individual, Business, or Enterprise)
@@ -105,6 +107,7 @@ Environment variables:
105
107
  | `CCDX_STREAM_IDLE_TIMEOUT_MS` | `120000` | Maximum idle time between upstream streaming body chunks |
106
108
  | `CCDX_UPSTREAM_RETRIES` | `2` | Retries for transient Copilot upstream network errors; capped at `5` |
107
109
  | `CCDX_UPSTREAM_RETRY_DELAY_MS` | `300` | Initial upstream retry backoff in milliseconds; capped at `5000` |
110
+ | `CCDX_AUTO_REVIEW_MODEL` | `gpt-5.4-mini` | Copilot Responses model used for Codex Auto-review requests |
108
111
  | `CCDX_LOG_PATH` | unset | Mirror terminal logs to a file; set to `1` for `~/.local/share/codex-copilot-dx/debug.log` |
109
112
  | `CCDX_LOG_LEVEL` | `info` | Set to `debug` to include upstream request attempts, status codes, retry causes, and timings |
110
113
  | `CCDX_LOG_MAX_BYTES` | `16777216` | Rotate the debug log at this size, retaining one `.1` backup; set to `0` to disable rotation |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-copilot-dx",
3
- "version": "0.4.26",
3
+ "version": "0.4.27",
4
4
  "description": "Use Codex Desktop, Claude Code, and Claude App with GitHub Copilot",
5
5
  "type": "module",
6
6
  "bin": {
package/src/adapter.mjs CHANGED
@@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto";
3
3
  import { chatCompletions, listModels, responses as copilotResponses, responsesCompact as copilotResponsesCompact, getCachedModelEndpoints } from "./copilot.mjs";
4
4
  import { webStreamLines } from "./stream.mjs";
5
5
  import { anthropicToChat, chatToAnthropic, streamAnthropicFromLines, countTokens } from "./anthropic.mjs";
6
- import { claudeDesktopModelsResponse, resolveAnthropicModel, modelIsResponsesOnly, modelSupportsChatCompletions } from "./models.mjs";
6
+ import { CODEX_AUTO_REVIEW_MODEL, claudeDesktopModelsResponse, resolveAnthropicModel, resolveOpenAIModel, modelIsResponsesOnly, modelSupportsChatCompletions } from "./models.mjs";
7
7
  import { status } from "./status.mjs";
8
8
  import { recordAnthropicUsage, recordResponsesUsage } from "./usage.mjs";
9
9
  import { ADAPTER_HEALTH_PATH, adapterHealthPayload } from "./running-adapter.mjs";
@@ -673,6 +673,7 @@ export function createAdapterHandler(options = {}) {
673
673
  const responsesFn = options.responsesFn || copilotResponses;
674
674
  const responsesCompactFn = options.responsesCompactFn || copilotResponsesCompact;
675
675
  const listModelsFn = options.listModelsFn || listModels;
676
+ const openAIModelEnv = options.openAIModelEnv || process.env;
676
677
  const upstreamTimeoutMs = positiveInt(options.upstreamTimeoutMs, UPSTREAM_TIMEOUT_MS);
677
678
  const streamHandshakeTimeoutMs = positiveInt(options.streamHandshakeTimeoutMs, STREAM_HANDSHAKE_TIMEOUT_MS);
678
679
  const streamIdleTimeoutMs = positiveInt(options.streamIdleTimeoutMs, STREAM_IDLE_TIMEOUT_MS);
@@ -702,8 +703,11 @@ export function createAdapterHandler(options = {}) {
702
703
  const prepared = prepareResponsesRequest(parsed, { mutate: true });
703
704
  prepared.surface = "responses";
704
705
  const model = parsed.model || "unknown";
705
- console.log(status("info", `responses model=${model} stream=${!!parsed.stream}`));
706
- if (isResponsesOnlyModel(model)) {
706
+ const { requestedModel, upstreamModel } = resolveOpenAIModel(model, openAIModelEnv);
707
+ if (upstreamModel !== requestedModel) prepared.body.model = upstreamModel;
708
+ const upstreamLog = upstreamModel === requestedModel ? "" : ` upstream_model=${upstreamModel}`;
709
+ console.log(status("info", `responses model=${requestedModel}${upstreamLog} stream=${!!parsed.stream}`));
710
+ if (requestedModel === CODEX_AUTO_REVIEW_MODEL || isResponsesOnlyModel(upstreamModel)) {
707
711
  await proxyCopilotResponses(prepared, req, res, responsesFn, {
708
712
  signal: abort.signal,
709
713
  abort,
@@ -770,7 +774,10 @@ export function createAdapterHandler(options = {}) {
770
774
  const prepared = prepareResponsesRequest(parsed, { mutate: true });
771
775
  prepared.surface = "responses_compact";
772
776
  const model = parsed.model || "unknown";
773
- console.log(status("info", `responses compact model=${model} stream=${!!parsed.stream}`));
777
+ const { requestedModel, upstreamModel } = resolveOpenAIModel(model, openAIModelEnv);
778
+ if (upstreamModel !== requestedModel) prepared.body.model = upstreamModel;
779
+ const upstreamLog = upstreamModel === requestedModel ? "" : ` upstream_model=${upstreamModel}`;
780
+ console.log(status("info", `responses compact model=${requestedModel}${upstreamLog} stream=${!!parsed.stream}`));
774
781
  await proxyCopilotResponses(prepared, req, res, responsesCompactFn, {
775
782
  signal: abort.signal,
776
783
  abort,
package/src/models.mjs CHANGED
@@ -60,6 +60,9 @@ const DEFAULT_CLAUDE_MODEL_ALIAS_DEFS = [
60
60
  },
61
61
  ];
62
62
 
63
+ export const CODEX_AUTO_REVIEW_MODEL = "codex-auto-review";
64
+ export const DEFAULT_CODEX_AUTO_REVIEW_MODEL = "gpt-5.4-mini";
65
+
63
66
  function cleanList(value) {
64
67
  return String(value || "")
65
68
  .split(",")
@@ -209,6 +212,19 @@ export function resolveAnthropicModel(model, env = process.env, options = {}) {
209
212
  };
210
213
  }
211
214
 
215
+ export function resolveOpenAIModel(model, env = process.env) {
216
+ const requestedModel = String(model || "");
217
+ if (requestedModel !== CODEX_AUTO_REVIEW_MODEL) {
218
+ return { requestedModel, upstreamModel: requestedModel };
219
+ }
220
+
221
+ const configuredModel = String(env.CCDX_AUTO_REVIEW_MODEL || "").trim();
222
+ return {
223
+ requestedModel,
224
+ upstreamModel: configuredModel || DEFAULT_CODEX_AUTO_REVIEW_MODEL,
225
+ };
226
+ }
227
+
212
228
  export function anthropicModelInfo(model) {
213
229
  return {
214
230
  id: model.id,