Update Codex adapter GPT-5.6 defaults (#9352)

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Codex local is the adapter subsystem that exposes OpenAI Codex CLI
model choices to agents and issue overrides.
> - OpenAI has GPT-5.6 Codex-capable models that should appear in
Paperclip's built-in Codex model list and refresh behavior.
> - Paperclip's server model listing falls back to the adapter metadata
and merges OpenAI refresh results with known Codex defaults.
> - This pull request updates the Codex default model metadata to
include GPT-5.6 options and adds regression coverage for fallback and
refresh paths.
> - The benefit is that operators can select the new Codex models
without relying on manual model IDs, and refresh behavior keeps known
GPT-5.6 options visible.

## Linked Issues or Issue Description

Refs #9322.
Refs #9342.
Refs #9346.

### Agent or provider

Codex CLI (OpenAI).

### Why this adapter is useful

OpenAI's GPT-5.6 Codex-capable models should be available in Paperclip's
Codex adapter defaults and model refresh path.

### How the agent is invoked

`codex`

## What Changed

- Changed the `codex_local` default model metadata from `gpt-5.5` to
`gpt-5.6`.
- Added `gpt-5.6-sol`, `gpt-5.6-terra`, and `gpt-5.6-luna` to the
built-in Codex adapter model list.
- Updated adapter and server model-listing tests to cover GPT-5.6
fallback and refresh behavior.
- Aligned Codex Fast mode support and helper text with the new `gpt-5.6`
default, while preserving GPT-5.5, GPT-5.4, and manual model ID support.

## Verification

- `git diff --check origin/master...HEAD`
- `pnpm exec vitest run packages/adapters/codex-local/src/index.test.ts
packages/adapters/codex-local/src/server/codex-args.test.ts
server/src/__tests__/adapter-models.test.ts
server/src/__tests__/adapter-model-refresh-routes.test.ts`
- `pnpm check:token-gates`
- `pnpm --filter @paperclipai/adapter-codex-local typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`

## Risks

Medium risk because changing `DEFAULT_CODEX_LOCAL_MODEL` from `gpt-5.5`
to `gpt-5.6` changes the adapter's default model selection for new blank
configurations. The model-list additions are otherwise low risk and
covered by adapter/server metadata tests. This PR intentionally overlaps
related PRs #9342 and #9346, so reviewers may prefer to close or fold it
into one of those branches.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex coding agent based on GPT-5, with shell, git, GitHub CLI,
and repository editing tool use. Exact served model ID and context
window were not exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta 2026-07-10 09:20:13 -05:00 committed by GitHub
parent 953b315dfb
commit a02fe8d575
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 31 additions and 16 deletions

View File

@ -1,9 +1,18 @@
import { describe, expect, it } from "vitest";
import { DEFAULT_CODEX_LOCAL_MODEL, models } from "./index.js";
import { DEFAULT_CODEX_LOCAL_MODEL, isCodexLocalFastModeSupported, models } from "./index.js";
describe("codex local adapter metadata", () => {
it("does not advertise the ChatGPT-unsupported gpt-5.3-codex model as a default option", () => {
expect(DEFAULT_CODEX_LOCAL_MODEL).toBe("gpt-5.5");
expect(models.map((model) => model.id)).not.toContain("gpt-5.3-codex");
it("advertises current GPT-5.6 Codex-capable OpenAI models by default", () => {
const modelIds = models.map((model) => model.id);
expect(DEFAULT_CODEX_LOCAL_MODEL).toBe("gpt-5.6");
expect(modelIds.slice(0, 4)).toEqual([
"gpt-5.6",
"gpt-5.6-sol",
"gpt-5.6-terra",
"gpt-5.6-luna",
]);
expect(isCodexLocalFastModeSupported(DEFAULT_CODEX_LOCAL_MODEL)).toBe(true);
expect(modelIds).not.toContain("gpt-5.3-codex");
});
});

View File

@ -5,9 +5,9 @@ export const label = "Codex";
export const SANDBOX_INSTALL_COMMAND = "npm install -g @openai/codex";
export const DEFAULT_CODEX_LOCAL_MODEL = "gpt-5.5";
export const DEFAULT_CODEX_LOCAL_MODEL = "gpt-5.6";
export const DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX = true;
export const CODEX_LOCAL_FAST_MODE_SUPPORTED_MODELS = ["gpt-5.5", "gpt-5.4"] as const;
export const CODEX_LOCAL_FAST_MODE_SUPPORTED_MODELS = ["gpt-5.6", "gpt-5.5", "gpt-5.4"] as const;
function normalizeModelId(model: string | null | undefined): string {
return typeof model === "string" ? model.trim() : "";
@ -28,9 +28,8 @@ export function isCodexLocalFastModeSupported(model: string | null | undefined):
if (isCodexLocalManualModel(model)) return true;
const normalizedModel = typeof model === "string" ? model.trim() : "";
// Empty means we're omitting --model so the Codex CLI picks its own default.
// On subscription auth that's gpt-5.5 (fast-mode capable); manual model IDs
// are also treated as supported. Match that policy: pass the fast-mode
// overrides through and let the CLI reject them if the chosen model can't use them.
// Manual model IDs are also treated as supported: pass the fast-mode overrides
// through and let the CLI reject them if the chosen model can't use them.
if (!normalizedModel) return true;
return CODEX_LOCAL_FAST_MODE_SUPPORTED_MODELS.includes(
normalizedModel as (typeof CODEX_LOCAL_FAST_MODE_SUPPORTED_MODELS)[number],
@ -39,6 +38,9 @@ export function isCodexLocalFastModeSupported(model: string | null | undefined):
export const models = [
{ id: DEFAULT_CODEX_LOCAL_MODEL, label: DEFAULT_CODEX_LOCAL_MODEL },
{ id: "gpt-5.6-sol", label: "gpt-5.6-sol" },
{ id: "gpt-5.6-terra", label: "gpt-5.6-terra" },
{ id: "gpt-5.6-luna", label: "gpt-5.6-luna" },
{ id: "gpt-5.4", label: "gpt-5.4" },
{ id: "gpt-5.4-mini", label: "gpt-5.4-mini" },
{ id: "gpt-5.3-codex-spark", label: "gpt-5.3-codex-spark" },
@ -77,7 +79,7 @@ Core fields:
- modelReasoningEffort (string, optional): reasoning effort override (minimal|low|medium|high|xhigh) passed via -c model_reasoning_effort=...
- promptTemplate (string, optional): run prompt template
- search (boolean, optional): run codex with --search
- fastMode (boolean, optional): enable Codex Fast mode; supported on GPT-5.5, GPT-5.4 and passed through for manual model IDs
- fastMode (boolean, optional): enable Codex Fast mode; supported on GPT-5.6, GPT-5.5, GPT-5.4 and passed through for manual model IDs
- dangerouslyBypassApprovalsAndSandbox (boolean, optional): run with bypass flag
- command (string, optional): defaults to "codex"
- extraArgs (string[], optional): additional CLI args
@ -102,7 +104,7 @@ Notes:
- Paperclip injects desired local skills into the effective CODEX_HOME/skills/ directory at execution time so Codex can discover "$paperclip" and related skills without polluting the project working directory. For new and updated agents, Paperclip assigns an isolated managed home at ~/.paperclip/instances/<id>/companies/<companyId>/agents/<agentId>/codex-home/skills/; when CODEX_HOME is explicitly overridden in adapter config, that override is used instead.
- New and updated codex_local agents persist an empty OPENAI_API_KEY override by default so a host-level OPENAI_API_KEY cannot leak into Codex runs through process inheritance. Explicit CODEX_HOME overrides must not point at the shared company codex-home, $CODEX_HOME, or ~/.codex.
- Some model/tool combinations reject certain effort levels (for example minimal with web search enabled).
- Fast mode is supported on GPT-5.5, GPT-5.4 and manual model IDs. When enabled for those models, Paperclip applies \`service_tier="fast"\` and \`features.fast_mode=true\`.
- Fast mode is supported on GPT-5.6, GPT-5.5, GPT-5.4 and manual model IDs. When enabled for those models, Paperclip applies \`service_tier="fast"\` and \`features.fast_mode=true\`.
- When Paperclip realizes a workspace/runtime for a run, it injects PAPERCLIP_WORKSPACE_* and PAPERCLIP_RUNTIME_* env vars for agent-side tooling.
- Codex ACP is the preferred auto lane when Node >=22.13.0 and the Codex ACP server are available. It reuses shared ACP prompt/runtime guidance, selected skill materialization into CODEX_HOME/skills, model/reasoning/fast-mode session config, and existing quota-window reporting. Auto selection falls back to CLI when ACP prerequisites are unavailable; explicit engine="acp" fails loudly.
`;

View File

@ -98,7 +98,7 @@ describe("buildCodexExecArgs", () => {
expect(result.fastModeRequested).toBe(true);
expect(result.fastModeApplied).toBe(false);
expect(result.fastModeIgnoredReason).toContain(
"currently only supported on gpt-5.5, gpt-5.4 or manually configured model IDs",
"currently only supported on gpt-5.6, gpt-5.5, gpt-5.4 or manually configured model IDs",
);
expect(result.args).toEqual([
"exec",

View File

@ -48,7 +48,10 @@ describe("adapter model listing", () => {
const models = await listAdapterModels("codex_local");
expect(models).toEqual(codexFallbackModels);
expect(models.some((model) => model.id === "gpt-5.5")).toBe(true);
expect(models.some((model) => model.id === "gpt-5.6")).toBe(true);
expect(models.some((model) => model.id === "gpt-5.6-sol")).toBe(true);
expect(models.some((model) => model.id === "gpt-5.6-terra")).toBe(true);
expect(models.some((model) => model.id === "gpt-5.6-luna")).toBe(true);
expect(fetchSpy).not.toHaveBeenCalled();
});
@ -155,7 +158,7 @@ describe("adapter model listing", () => {
.mockResolvedValueOnce({
ok: true,
json: async () => ({
data: [{ id: "gpt-5.5" }],
data: [{ id: "gpt-5.6-terra" }],
}),
} as Response);
@ -164,7 +167,8 @@ describe("adapter model listing", () => {
expect(fetchSpy).toHaveBeenCalledTimes(2);
expect(initial.some((model) => model.id === "gpt-5")).toBe(true);
expect(refreshed.some((model) => model.id === "gpt-5.5")).toBe(true);
expect(refreshed.some((model) => model.id === "gpt-5.6-terra")).toBe(true);
expect(refreshed.some((model) => model.id === "gpt-5.6-luna")).toBe(true);
});
it("falls back to static codex models when OpenAI model discovery fails", async () => {

View File

@ -34,7 +34,7 @@ export const help: Record<string, string> = {
dangerouslySkipPermissions: "Run unattended by auto-approving adapter permission prompts when supported.",
dangerouslyBypassSandbox: "Run Codex without sandbox restrictions. Required for filesystem/network access.",
search: "Enable Codex web search capability during runs.",
fastMode: "Enable Codex Fast mode. This burns credits/tokens much faster and is supported on GPT-5.4 and manual Codex model IDs.",
fastMode: "Enable Codex Fast mode. This burns credits/tokens much faster and is supported on GPT-5.6, GPT-5.5, GPT-5.4, and manual Codex model IDs.",
workspaceStrategy: "How Paperclip should realize an execution workspace for this agent. Keep project_primary for normal cwd execution, or use git_worktree for issue-scoped isolated checkouts.",
workspaceBaseRef: "Base git ref used when creating a worktree branch. Leave blank to use the resolved workspace ref or HEAD.",
workspaceBranchTemplate: "Template for naming derived branches. Supports {{issue.identifier}}, {{issue.title}}, {{agent.name}}, {{project.id}}, {{workspace.repoRef}}, and {{slug}}.",