Skip to content

refactor(acp): source ACP model lists from typescript-client (closes #740)#775

Merged
simonrosenberg merged 4 commits into
mainfrom
acp-source-models-from-client
May 26, 2026
Merged

refactor(acp): source ACP model lists from typescript-client (closes #740)#775
simonrosenberg merged 4 commits into
mainfrom
acp-source-models-from-client

Conversation

@simonrosenberg
Copy link
Copy Markdown
Contributor

@simonrosenberg simonrosenberg commented May 26, 2026

Summary

Stops hand-maintaining ACP model lists in Canvas. The three hardcoded arrays — CLAUDE_MODELS / CODEX_MODELS / GEMINI_MODELS (the Claude one originally mined by string-scanning the claude binary) — are replaced by the @openhands/typescript-client ACP registry, which mirrors the Python source of truth (openhands.sdk.settings.acp_providers).

Closes #740. Part of #769 (unify ACP model selection).

What changed

  • Pin bump: @openhands/typescript-clientv1.23.2 (tagged release including feat(acp): mirror available_models / default_model from openhands-sdk typescript-client#187, which added available_models / default_model to the client's ACP registry). v1.23.2 tracks the SDK's v1.23.2 patch line that contains feat(acp): add available_models / default_model to ACP provider registry software-agent-sdk#3389. Forward-only from the previous v1.23.0 pin.
  • acp-providers.ts is now a thin adapter: ACP_PROVIDERS is built by enriching each upstream registry record (via getAcpProvider()) with a small Canvas-only ACP_PROVIDER_UI map carrying the two fields the client registry doesn't have — the brand icon and the onboarding description_key.
  • Public surface unchanged: every export (ACP_PROVIDERS, getAcpProvider, labelForAcpModel, buildAcpAgentSettingsDiff, ACPProviderConfig, ACPModelOption, …) is preserved, so the ~50 consumer call sites are untouched. Net acp-providers.ts: −132 / +54.

Side effect (intended)

The Gemini default is now auto-gemini-2.5 (the CLI's auto-router default), corrected from the stale gemini-2.5-pro pin — it now comes from the client/SDK, matching the upstream fix.

Validation

npm run typecheck   # clean
npm run lint        # eslint + prettier clean
npm run build       # clean
npx vitest run __tests__/constants/acp-providers.test.ts \
  __tests__/routes/agent-settings.test.tsx \
  __tests__/components/onboarding/choose-agent-step.test.tsx \
  __tests__/api/agent-server-adapter.test.ts \
  __tests__/components/features/chat/components/chat-input-model.test.tsx \
  __tests__/components/features/conversation-panel/conversation-card.test.tsx
# 131 passed

The #730 registry test (__tests__/constants/acp-providers.test.ts) passes unchanged — it asserts behavior (display names, default_model ∈ available_models, diff seeding), which the client supplies identically.

🤖 Generated with Claude Code


🐳 Docker images for this PR

GHCR package: https://github.com/OpenHands/agent-canvas/pkgs/container/agent-canvas

Component Value
Image ghcr.io/openhands/agent-canvas
Architectures amd64, arm64
Agent Server ghcr.io/openhands/agent-server:1.23.0-python
Automation openhands-automation==1.0.0a5
Commit be787fd916a9121af69a2d2e1b083c27defb3f5c

Pull (multi-arch manifest)

# Multi-arch manifest — Docker automatically pulls the correct architecture
docker pull ghcr.io/openhands/agent-canvas:sha-be787fd

Run

docker run -it --rm \
  -p 8000:8000 \
  ghcr.io/openhands/agent-canvas:sha-be787fd

All tags pushed for this build

ghcr.io/openhands/agent-canvas:sha-be787fd-amd64
ghcr.io/openhands/agent-canvas:acp-source-models-from-client-amd64
ghcr.io/openhands/agent-canvas:pr-775-amd64
ghcr.io/openhands/agent-canvas:sha-be787fd-arm64
ghcr.io/openhands/agent-canvas:acp-source-models-from-client-arm64
ghcr.io/openhands/agent-canvas:pr-775-arm64
ghcr.io/openhands/agent-canvas:sha-be787fd
ghcr.io/openhands/agent-canvas:acp-source-models-from-client
ghcr.io/openhands/agent-canvas:pr-775

About Multi-Architecture Support

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

Replace the hand-mined CLAUDE_MODELS / CODEX_MODELS / GEMINI_MODELS lists (and
the duplicated provider metadata) with the @openhands/typescript-client ACP
registry, which mirrors the Python SDK source of truth
(openhands.sdk.settings.acp_providers). acp-providers.ts becomes a thin
adapter: it enriches each upstream record with Canvas-only UI fields (brand
icon + onboarding description) and keeps the helper functions + public export
surface unchanged, so no consumers change.

- Bump the @openhands/typescript-client pin to the #187 merge commit
  (082d4d46), which adds available_models / default_model to the registry.
- Delete the three hardcoded model lists; build ACP_PROVIDERS from
  getAcpProvider() + a small ACP_PROVIDER_UI map.
- Incidentally corrects the Gemini default to auto-gemini-2.5 (the CLI's
  auto-router default), matching the merged SDK/client.

Closes #740.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-canvas Ready Ready Preview, Comment May 26, 2026 5:18pm

Request Review

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

🟡 Acceptable - Solid architectural improvement but needs workflow cleanup

[IMPROVEMENT OPPORTUNITIES]

The refactor correctly eliminates hardcoded model lists in favor of the typescript-client registry (single source of truth). However, this change breaks the existing drift-detection infrastructure:

🟠 Important: .github/workflows/acp-providers-sync.yml and scripts/check-acp-providers-sync.mjs are now obsolete. The workflow expects to parse hardcoded CLAUDE_MODELS/CODEX_MODELS/GEMINI_MODELS arrays from the TypeScript file, but the refactor replaces that structure with Object.entries(ACP_PROVIDER_UI).map(([key, ui]) => { const info = getClientAcpProvider(key); ... }). The script will fail or produce incorrect results when triggered by this PR's changes to src/constants/acp-providers.ts.

Recommendation: Either remove the workflow and sync script (since Canvas now just uses typescript-client as the source of truth), or update the script to verify the typescript-client dependency pin is up-to-date. The former is simpler — typescript-client has its own drift check against the Python SDK.

[RISK ASSESSMENT]

⚠️ Risk Assessment: 🟢 LOW

Architectural improvement with good test coverage. The refactor moves maintenance burden upstream where it belongs. Side effect (Gemini default correction) is intentional and documented. Dependency is forward-only from v1.23.0.

VERDICT:
Worth merging after addressing the stale workflow/script in a follow-up

KEY INSIGHT:
This refactor makes Canvas a consumer of the ACP registry rather than a mirror of it, which is the right architectural direction. The workflow cleanup is straightforward housekeeping.


Was this automated review useful? React with 👍 or 👎 to this review to help us measure review quality.
Workflow run: https://github.com/OpenHands/agent-canvas/actions/runs/26461411572

Comment thread package.json Outdated
Now that typescript-client v1.23.2 is tagged/released (includes #187's ACP
registry, mirroring SDK #3389), pin to the tag instead of the raw #187 merge
SHA. v1.23.2 tracks the SDK's v1.23.2 patch line. Resolves to the same commit
as the prior SHA, so no resolved-content change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The acp-providers-sync workflow + scripts/check-acp-providers-sync.mjs existed
to keep Canvas's hand-kept ACP registry mirror in sync with the SDK source
(agent-canvas#587). That mirror is gone — acp-providers.ts now sources its
model data from @openhands/typescript-client, which carries its own
SDK-drift check (check-acp-drift.py). So this canvas-side check is redundant
and was failing on the refactored ACP_PROVIDERS (no longer a literal array).

- Delete .github/workflows/acp-providers-sync.yml + the script.
- Drop the docs-version-sync test case that asserted the script's example.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@simonrosenberg simonrosenberg merged commit f6d977d into main May 26, 2026
14 checks passed
@simonrosenberg simonrosenberg deleted the acp-source-models-from-client branch May 26, 2026 17:25
@github-actions
Copy link
Copy Markdown
Contributor

📸 Snapshot Test Report

Warning

Snapshot comparison step crashed (timeout, OOM, or runner error) — diff results below may be incomplete or absent.
Check the CI logs for the full error output (look for the "Run snapshot comparison" step).

✅ All snapshots match the main branch baselines.

Category Count
🔴 Changed 0
🆕 New 0
✅ Unchanged 73
Total 73
✅ Unchanged snapshots (73)

archived-conversation

  • conversation-panel-with-archived-badges
  • conversation-view-archived
  • conversation-view-sandbox-error

automations

  • automations-delete-modal
  • automations-list-active-inactive
  • automations-no-automations
  • automations-search-no-results

backends-extended

  • backend-add-blank-disabled
  • backend-add-cloud-advanced-open
  • backend-add-cloud-no-key-disabled
  • backend-add-cloud-with-key-enabled
  • backend-add-form-partially-filled
  • backend-add-invalid-url-disabled
  • backend-add-local-ready
  • backend-add-name-only-disabled
  • backend-add-two-column-layout
  • backend-add-whitespace-host-disabled
  • backend-after-switch
  • backend-cancel-nothing-saved
  • backend-dropdown-two-backends
  • backend-edit-prefilled
  • backend-manage-after-removal
  • backend-manage-two-listed
  • backend-remove-cancelled
  • backend-remove-confirmation
  • backend-switch-overlay

backends

  • backend-add-modal
  • backend-manage-modal
  • backend-selector-open

changes-tab

  • changes-deleted-file
  • changes-diff-viewer
  • changes-empty

collapsible-thinking

  • reasoning-content-collapsed
  • reasoning-content-expanded
  • think-action-collapsed
  • think-action-expanded

mcp-page

  • mcp-custom-server-1-editor-open
  • mcp-custom-server-2-url-filled
  • mcp-custom-server-3-all-filled
  • mcp-custom-server-4-installed
  • mcp-custom-server-editor
  • mcp-empty-installed
  • mcp-search-filtered
  • mcp-slack-install-1-marketplace
  • mcp-slack-install-2-modal
  • mcp-slack-install-3-filled
  • mcp-slack-install-4-installed

onboarding

  • onboarding-step-0-choose-agent
  • onboarding-step-1-check-backend
  • onboarding-step-2-setup-llm
  • onboarding-step-3-say-hello

projects-workspace-browser

  • projects-workspace-browser

settings-page

  • add-backend-modal
  • analytics-consent-modal
  • home-screen
  • settings-app-page
  • settings-page

settings-secrets

  • secrets-add-form-filled
  • secrets-add-form
  • secrets-after-save
  • secrets-delete-confirm
  • secrets-list

settings-verification

  • condenser-settings
  • verification-settings-off
  • verification-settings-on

sidebar

  • sidebar-collapsed
  • sidebar-conversation-panel
  • sidebar-filter-menu

skills-page

  • skills-empty
  • skills-loaded
  • skills-no-match
  • skills-search-filtered
  • skills-type-filter

Generated by the Snapshot Tests workflow. This comment was created by an AI agent (OpenHands) on behalf of the repo maintainers.

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.

ACP model lists (CLAUDE_MODELS / CODEX_MODELS / GEMINI_MODELS) in canvas are hand-mined — move them upstream

2 participants