Skip to content

fix: support GPT-5.6 across Codex authentication - #4056

Merged
neubig merged 5 commits into
mainfrom
fix/codex-acp-gpt-5-6
Jul 10, 2026
Merged

neubig merged 5 commits into
mainfrom
fix/codex-acp-gpt-5-6

Conversation

@neubig

@neubig neubig commented Jul 9, 2026 •

Copy link
Copy Markdown
Member

HUMAN:

I have tested this in the agent canvas, and GPT-5.6 Sol is displayed and works.

Screenshot 2026-07-10 at 7 25 52 AM

AGENT:

Why

Agent Server and Canvas pinned @zed-industries/codex-acp@0.16.0, whose embedded Codex does not support the GPT-5.6 model family. The ordinary LLM picker also omitted GPT-5.6 because Canvas assigns bare LiteLLM model IDs to providers through the SDK's verified-model registry.

Summary

  • replace the retired Zed adapter with @agentclientprotocol/codex-acp@1.1.2 and use its current auth, session-mode, model-config, and CODEX_CONFIG contracts
  • expose GPT-5.6, Sol, Terra, and Luna through the Codex ACP registry, ChatGPT subscription endpoint, and verified OpenAI model list
  • remove legacy Codex adapter and subscription-model fallbacks, and update focused SDK/Agent Server coverage

Issue Number

N/A

How to Test

  • uv run pytest -q tests/sdk/agent/test_acp_agent.py tests/sdk/settings/test_acp_providers.py tests/sdk/llm/auth/test_openai.py tests/sdk/llm/test_model_list.py tests/sdk/test_settings.py tests/agent_server/test_llm_router.py (626 passed)
  • uv run pre-commit run --all-files --show-diff-on-failure (passed)
  • uv run pyright openhands-sdk/openhands/sdk/agent/acp_agent.py openhands-sdk/openhands/sdk/llm/auth/openai.py openhands-sdk/openhands/sdk/llm/llm.py openhands-sdk/openhands/sdk/llm/utils/verified_models.py openhands-sdk/openhands/sdk/settings/acp_providers.py (0 errors)
  • verified src/models/acp-providers.json in the companion TypeScript client branch matches ACP_PROVIDERS
  • live QA: started Agent Server from this branch, selected gpt-5.6-sol through Codex ACP, and received the exact response ACP_GPT56_MODERN_OK in conversation 5f900271. Server state reported @agentclientprotocol/codex-acp 1.1.2, agent-full-access, and gpt-5.6-sol via configOptions.

Live evidence

Setup: local checkout of fix/codex-acp-gpt-5-6 at cfb13d06f0b24e0cab79e6bf077ec62a0571f473 after make build; Node v22.23.1 / npm 10.9.8. The live GPT-5.6 run used the existing CODEX_HOME/auth.json ChatGPT-format auth file, with OPENAI_API_KEY, OPENAI_BASE_URL, CODEX_API_KEY, and CODEX_CONFIG unset so Codex ACP selected subscription auth.

Commands and observed results:

  • uv run pytest -q tests/sdk/agent/test_acp_agent.py -k ExtractTokenUsage -> 6 passed.
  • uv run pytest -q tests/sdk/llm/test_model_list.py::test_gpt_5_6_models_are_verified_for_openai -> 1 passed.
  • uv run pytest -q tests/agent_server/test_llm_router.py -> 16 passed.
  • uv run pre-commit run --files openhands-sdk/openhands/sdk/agent/acp_agent.py tests/sdk/agent/test_acp_agent.py -> passed Ruff format/lint, pycodestyle, Pyright, import rules, and tool registration checks.
  • uv run pre-commit run --files openhands-sdk/openhands/sdk/llm/utils/verified_models.py -> passed after resolving the main merge conflict.
  • uv run pre-commit run --files openhands-agent-server/openhands/agent_server/llm_router.py -> passed after fixing the provider-filter CI failure.
  • ACP_PROMPT_MAX_RETRIES=1 OPENHANDS_SUPPRESS_BANNER=1 uv run python ... launched ACPAgent(acp_command=["npx", "-y", "@agentclientprotocol/codex-acp@1.1.2"], acp_server="codex", acp_model="gpt-5.6-sol") and sent Reply exactly ACP_PR4056_CHATGPT_GPT56_SOL_FINAL_OK. Do not include any other text.

Observed live ACP result:

  • initialized @agentclientprotocol/codex-acp 1.1.2
  • authenticated with ACP method chat-gpt
  • set session mode agent-full-access
  • applied the model through config options: current_model_id="gpt-5.6-sol", model_override_applied=true, model_via_config_option=true
  • reported GPT-5.6 Sol/Terra/Luna plus GPT-5.5/GPT-5.4/GPT-5.4 Mini as available models
  • finished in 4.17s with exact final response ACP_PR4056_CHATGPT_GPT56_SOL_FINAL_OK and accumulated cost 0.015305000000000001

Additional API-key probe: using LLM_API_KEY_EVAL with OPENAI_BASE_URL=https://llm-proxy.eval.all-hands.dev, the same adapter completed a gpt-5.5 control run and returned ACP_PR4056_GPT55_CONTROL_OK. The eval proxy currently has no healthy gpt-5.6-sol deployment, so that API-key path returns the proxy's 400 error for gpt-5.6-sol; after this PR's usage-accounting fix, the conversation reaches FINISHED with the proxy error instead of crashing in SDK token parsing.

Video/Screenshots

Not applicable; the live conversation link above records the end-to-end result.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

Companion TypeScript client PR: OpenHands/typescript-client#272

LiteLLM was not upgraded: both the pinned 1.84.1 and current 1.91.1 already contain metadata for all four GPT-5.6 IDs.


Agent Server images for this PR

• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:cfb13d0-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-cfb13d0-python \
  ghcr.io/openhands/agent-server:cfb13d0-python

All tags pushed for this build

ghcr.io/openhands/agent-server:cfb13d0-golang-amd64
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-golang-amd64
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-golang-amd64
ghcr.io/openhands/agent-server:cfb13d0-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:cfb13d0-golang-arm64
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-golang-arm64
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-golang-arm64
ghcr.io/openhands/agent-server:cfb13d0-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:cfb13d0-java-amd64
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-java-amd64
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-java-amd64
ghcr.io/openhands/agent-server:cfb13d0-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:cfb13d0-java-arm64
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-java-arm64
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-java-arm64
ghcr.io/openhands/agent-server:cfb13d0-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:cfb13d0-python-amd64
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-python-amd64
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-python-amd64
ghcr.io/openhands/agent-server:cfb13d0-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-amd64
ghcr.io/openhands/agent-server:cfb13d0-python-arm64
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-python-arm64
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-python-arm64
ghcr.io/openhands/agent-server:cfb13d0-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-arm64
ghcr.io/openhands/agent-server:cfb13d0-golang
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-golang
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-golang
ghcr.io/openhands/agent-server:cfb13d0-golang_tag_1.21-bookworm
ghcr.io/openhands/agent-server:cfb13d0-java
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-java
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-java
ghcr.io/openhands/agent-server:cfb13d0-eclipse-temurin_tag_17-jdk
ghcr.io/openhands/agent-server:cfb13d0-python
ghcr.io/openhands/agent-server:cfb13d06f0b24e0cab79e6bf077ec62a0571f473-python
ghcr.io/openhands/agent-server:fix-codex-acp-gpt-5-6-python
ghcr.io/openhands/agent-server:cfb13d0-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim

About Multi-Architecture Support

  • Each variant tag (e.g., cfb13d0-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., cfb13d0-python-amd64) are also available if needed

Closes #4060

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions

github-actions Bot commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor

Python API breakage checks — ✅ PASSED

Result: ✅ PASSED

Action log

@github-actions

github-actions Bot commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor

REST API breakage checks (OpenAPI) — ✅ PASSED

Result: ✅ PASSED

Action log

@github-actions

github-actions Bot commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-agent-server/openhands/agent_server
   llm_router.py130993%97, 103, 111, 177–178, 219–221, 244
openhands-sdk/openhands/sdk/agent
   acp_agent.py123610591%388, 573, 579, 656, 696, 911–913, 956–957, 1259–1260, 1303, 1305, 1309, 1313, 1339, 1402–1403, 1408, 1475, 1767, 1770–1771, 1788–1789, 1805, 1822, 1827, 1935, 1940, 2512–2515, 2519–2521, 2524–2528, 2530, 2778, 2792–2793, 2796–2798, 2806, 2810, 2821–2822, 2830, 2834–2835, 2838, 2886, 2890–2892, 2896–2897, 2929, 3016, 3203–3205, 3208–3209, 3249, 3395, 3403–3405, 3443–3444, 3447, 3455–3457, 3459, 3461, 3465, 3468, 3477–3479, 3481, 3517–3518, 3536–3539, 3542, 3546–3548, 3550, 3554–3555, 3785–3786
openhands-sdk/openhands/sdk/llm
   llm.py10258991%591, 607, 646–647, 652, 738, 754, 945, 985–987, 1021, 1028, 1175, 1303, 1502, 1506–1507, 1616, 1620–1621, 1681, 1688, 1699, 1763, 1767–1768, 1837, 1844, 1854, 1861, 1872, 1970, 1972, 1974, 2000, 2002, 2011–2012, 2084, 2297, 2453–2454, 2795–2796, 2805, 2823, 2850–2851, 2853, 2855, 2857, 2865, 2868, 2870, 2872, 2883–2884, 2892, 2895, 2898–2899, 2910–2912, 2916, 2920–2921, 2926, 2936, 2941, 3005, 3007, 3009–3012, 3014–3017, 3022–3025, 3040, 3051, 3111, 3113
openhands-sdk/openhands/sdk/llm/auth
   openai.py38712966%137, 184–185, 189–191, 244–246, 270–271, 282–284, 306–307, 311, 321–322, 325, 356, 372, 377–378, 387–389, 394–395, 404–406, 517–519, 521–522, 524–526, 558–559, 561–564, 567, 570, 572–573, 575–579, 584–589, 595–599, 605–606, 609–615, 621, 623–625, 627–632, 638, 640, 642–644, 646, 650–651, 654–655, 659, 662, 668–670, 673, 677, 686–689, 720–721, 802, 804, 813, 877–878, 882, 885–889, 892–894, 897–898, 910, 914, 919, 958, 997
TOTAL35846723179% 

Co-authored-by: openhands <openhands@all-hands.dev>

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ QA Report: FAIL

The model-list and subscription surfaces now expose GPT-5.6, but a real Codex ACP run with the newly exposed GPT-5.6 models did not complete while the same path with GPT-5.5 did.

Does this PR achieve its stated goal?

No, not yet based on functional QA. The PR does update the SDK and Agent Server surfaces from the old Codex package/IDs to @agentclientprotocol/codex-acp@1.1.2, api-key, agent-full-access, and GPT-5.6 model entries. However, when I exercised the actual Codex ACP adapter with configured LLM credentials, gpt-5.5 returned the expected response, while gpt-5.6/gpt-5.6-sol failed before producing the requested answer.

Phase Result
Environment Setup ✅ make build completed on the PR checkout and isolated origin/main worktree
CI Status 🟡 34 checks successful; qa-changes was still in progress; cleanup-on-approval skipped
Functional Verification ❌ SDK/API exposure works, but real Codex ACP GPT-5.6 execution failed
Functional Verification

Test 1: SDK subscription and ACP provider surfaces before/after

Step 1 — Establish baseline on origin/main:
Ran cd /tmp/oh-qa-main && uv run python /tmp/oh_qa_sdk_probe.py:

{
  "codex_default_command": ["npx", "-y", "@zed-industries/codex-acp@0.16.0"],
  "codex_default_session_mode": "full-access",
  "codex_gpt56_models": [],
  "subscription_gpt56_models": [],
  "create_subscription_llm_gpt56": {
    "ok": false,
    "error_type": "ValueError",
    "error": "Model 'gpt-5.6' is not supported for subscription access..."
  }
}

This confirms the old behavior: GPT-5.6 was not exposed through the Codex provider or subscription helper.

Step 2 — Apply the PR changes:
Used the PR checkout at fix/codex-acp-gpt-5-6 / e1db501883efebee4be67249c4b705aa6f7a729d.

Step 3 — Re-run with the fix in place:
Ran uv run python /tmp/oh_qa_sdk_probe.py:

{
  "codex_default_command": ["npx", "-y", "@agentclientprotocol/codex-acp@1.1.2"],
  "codex_default_session_mode": "agent-full-access",
  "codex_gpt56_models": ["gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"],
  "subscription_gpt56_models": ["gpt-5.6", "gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra"],
  "create_subscription_llm_gpt56": {
    "ok": true,
    "model": "openai/gpt-5.6",
    "auth_type": "subscription"
  }
}

This confirms the SDK-facing registry/subscription behavior changed as intended.

Test 2: Agent Server model endpoints before/after

Step 1 — Establish baseline on origin/main:
Started uv run agent-server --host 127.0.0.1 --port 8766, then called:

  • GET /api/llm/models?provider=openai
  • GET /api/llm/models/verified
  • GET /api/llm/subscription/openai/models

Observed:

{"gpt56_models": [], "legacy_codex": ["gpt-5.1-codex-mini"]}
{"openai_gpt56_models": [], "openai_has_gpt55": true}
{"gpt56_models": [], "legacy_codex": ["gpt-5.1-codex-max", "gpt-5.1-codex-mini", "gpt-5.2", "gpt-5.2-codex", "gpt-5.3-codex"]}

This confirms the server did not expose GPT-5.6 before the PR.

Step 2 — Apply the PR changes:
Started the PR server with uv run agent-server --host 127.0.0.1 --port 8765.

Step 3 — Re-run with the fix in place:
Called the same endpoints on port 8765 and observed:

{"gpt56_models": ["gpt-5.6", "gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra"], "count": 25}
{"openai_gpt56_models": ["gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"], "openai_has_gpt55": true}
{"gpt56_models": ["gpt-5.6", "gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra"], "has_gpt55": true}

This confirms the Agent Server HTTP surfaces now include the new GPT-5.6 entries.

Test 3: Real Codex ACP conversation execution

Step 1 — Establish a working control path:
Using the PR checkout, configured Codex ACP with the available LLM_API_KEY/LLM_BASE_URL as OPENAI_API_KEY/OPENAI_BASE_URL, then ran a real conversation through @agentclientprotocol/codex-acp@1.1.2 with acp_model="gpt-5.5":

ACP server initialized: agent_name='@agentclientprotocol/codex-acp', agent_version='1.1.2'
Authenticating with ACP method: api-key
Setting ACP session mode: agent-full-access
ACP_QA_CONTROL_OK
{
  "attempted_model": "gpt-5.5",
  "current_model_id": "gpt-5.5",
  "run_completed": true
}

This proves the Codex ACP adapter, API-key auth, base-url routing, and the available credentials can complete a real conversation for the existing model.

Step 2 — Exercise the new GPT-5.6 entries:
Ran the same flow with acp_model="gpt-5.6" and prompt Reply exactly ACP_QA_GPT56_OK:

ACP server initialized: agent_name='@agentclientprotocol/codex-acp', agent_version='1.1.2'
Authenticating with ACP method: api-key
Could not set model 'gpt-5.6' on ACP server @agentclientprotocol/codex-acp (Invalid params); the session will use the server default
ACP prompt failed: 'NoneType' object has no attribute 'get'
{
  "attempted_model": "gpt-5.6",
  "current_model_id": "gpt-5.6-sol",
  "error_type": "ConversationRunError",
  "run_completed": false
}

I also ran the same flow with acp_model="gpt-5.6-sol":

ACP server initialized: agent_name='@agentclientprotocol/codex-acp', agent_version='1.1.2'
Authenticating with ACP method: api-key
Setting ACP session mode: agent-full-access
ACP prompt failed: 'NoneType' object has no attribute 'get'
{
  "attempted_model": "gpt-5.6-sol",
  "current_model_id": "gpt-5.6-sol",
  "error_type": "ConversationRunError",
  "run_completed": false
}

This shows the newly exposed GPT-5.6 path did not produce the requested response in the same environment where the GPT-5.5 Codex ACP control succeeded.

Unable to Verify

I did not have a local ChatGPT/Codex subscription auth file (~/.codex/auth.json was absent), so I could not independently verify the chat-gpt OAuth/subscription auth path or Canvas UI selection. I verified the API-key ACP path and the HTTP/SDK model surfaces instead.

Issues Found

  • 🟠 Issue: Real Codex ACP execution with the newly exposed GPT-5.6 models failed. gpt-5.5 completed successfully through the same adapter/credentials, but gpt-5.6 was rejected as Invalid params and gpt-5.6-sol failed with ConversationRunError: 'NoneType' object has no attribute 'get' before returning the requested text.

This review was created by an AI agent (OpenHands) on behalf of the user.

Comment thread openhands-sdk/openhands/sdk/settings/acp_providers.py

@VascoSch92 VascoSch92 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neubig LGTM just one thing: _LEGACY_OPENAI_CODEX_MODELS is removed, i.e., it is a breaking change. Is that ok?

Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
@neubig

neubig commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

I think it's OK to remove that as it's a private member, thanks!

@neubig
neubig merged commit dc20998 into main Jul 10, 2026
36 checks passed
@neubig
neubig deleted the fix/codex-acp-gpt-5-6 branch July 10, 2026 12:56
VascoSch92 pushed a commit that referenced this pull request Jul 10, 2026
Co-authored-by: Graham Neubig <gneubig@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support GPT-5.6 across Codex authentication

5 participants