Skip to content

fix(verify-openhands): point the default agent profile at the preset's model - #18209

Merged
enyst merged 3 commits into
mainfrom
claude/confident-bohr-da1zye
Oct 9, 2026
Merged

enyst merged 3 commits into
mainfrom
claude/confident-bohr-da1zye

Conversation

@enyst

@enyst enyst commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

HUMAN:
This PR fixes a tricky case with the openhands agent cli when the default agent profile had an llm and another llm profile is activated - allow the cli to give the agents an easy way to change the active llm of an agent profile.


AGENT:

I'm an AI agent (Claude Code) helping Engel Nyst (@enyst) with project maintenance. This is a follow-up to #18191: a harness gap that the DeepSeek runs exposed.

Why

On a local backend, onboarding points the default agent profile at the LLM profile it creates. control-openhands llm preset deepseek activated deepseek-flash but left that pointer where it was. The result:

  • the Agents page still showed the onboarding model on default;
  • deleting the onboarding profile answered 409 LLM profile is referenced by 1 agent profile(s): default.

The F01 recipe worked around this with five UI steps in Settings → Agents before its cleanup could run.

Summary

  • llm preset now also points default at the profile it activates (deepseek-flash). It does this only when default is an OpenHands profile that references another LLM profile that exists. The output then carries "repointed": {"agentProfile": "default", "from": …, "to": "deepseek-flash"}. The save keeps every stored field and drops only id, name and revision, as the Agents editor does. The profile keeps its id and stays active.
  • Three cases are left alone on purpose:
    • A fresh run's seed. There, default references a profile named default that does not exist. The app already falls back to the active LLM profile for it, and F13.stale-llm-ref drives that state after the preset.
    • Named agent profiles. They are deliberate picks.
    • llm set. F05.profile-identity and F27.terminal-waiting activate throwaway profiles with it and then delete them, which would answer 409 if default followed.
  • F01's Restore step and Gotcha now use the preset instead of the manual repoint. The --help text for llm says when it happens. The decision is a pure helper (scripts/lib/agent-profile-repoint.mjs) with unit tests.

Issue Number

Part of #17872: harness follow-up from the DeepSeek runs documented there. This PR changes no product code.

How to Test

Static checks:

export PATH="$PWD/.agents/skills/verify-openhands/scripts:$PATH"
npx vitest run .agents/skills/verify-openhands   # 45 passed
control-openhands map check                       # ok, 27 files, 740 ids
control-openhands map testids                     # ok, unresolved []

Live, on one fresh run of main @ ff1a1d6 (agent-server 1.53.0, Node 24.21.0). main's CLI ran from a worktree as the before case:

fresh run, this branch: llm preset deepseek
  → no "repointed"; agent profiles: [('default', 'default')]          # F13.stale-llm-ref precondition intact

onboarding through the UI with openai/deepseek-chat + https://api.deepseek.com/v1
  → agent profiles: [('default', 'deepseek-chat')]

BEFORE, main's CLI: llm preset deepseek
  → agent profiles: [('default', 'deepseek-chat')]
  → DELETE /api/profiles/deepseek-chat: 409 "LLM profile is referenced by 1 agent profile(s): default"

AFTER, this branch: llm preset deepseek
  → "repointed": {"agentProfile": "default", "from": "deepseek-chat", "to": "deepseek-flash"}
  → same id e387d785-…, still active, revision bumped, condenser / tool_concurrency_limit unchanged
  → DELETE /api/profiles/deepseek-chat: 200 "Profile 'deepseek-chat' deleted"
  → a second preset run reports no "repointed"

llm set --profile qa-zeta … (activates): default stays on deepseek-flash; DELETE qa-zeta: 200

A conversation started afterwards from the home composer finished with the reply qa-preset-ok.

Video/Screenshots

Settings → Agents on the same run, right after onboarding pinned default to deepseek-chat. Screenshots by control-openhands, under .pr/ (removed on approval); no key field is on this page.

Before, after main's llm preset deepseek. default still names deepseek-chat:

Agents page: default names deepseek-chat``

After, with this branch's preset. default names deepseek-flash:

Agents page: default names deepseek-flash``

Both files are in the .pr folder at 82f1c51.

Design Doc

Not included; the change is confined to .agents/skills/verify-openhands/ and .pr/.

Type

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

Notes

  • Only the preset's own activation moves the pointer. Activating a profile in Settings → LLM stays pointer-only, which is the product's behavior and unchanged here.

🐳 Docker images for this PR

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

Component Value
Image ghcr.io/openhands/agent-canvas
Architectures amd64, arm64
Agent Server ghcr.io/openhands/agent-server:1.53.0-python
Automation openhands-automation==1.19.0
Commit 51a79d4dd59090bb21421e306227bd167314e8a8

Pull (multi-arch manifest)

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

Run

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

All tags pushed for this build

ghcr.io/openhands/agent-canvas:sha-51a79d4-amd64
ghcr.io/openhands/agent-canvas:claude-confident-bohr-da1zye-amd64
ghcr.io/openhands/agent-canvas:pr-18209-amd64
ghcr.io/openhands/agent-canvas:sha-51a79d4-arm64
ghcr.io/openhands/agent-canvas:claude-confident-bohr-da1zye-arm64
ghcr.io/openhands/agent-canvas:pr-18209-arm64
ghcr.io/openhands/agent-canvas:sha-51a79d4
ghcr.io/openhands/agent-canvas:claude-confident-bohr-da1zye
ghcr.io/openhands/agent-canvas:pr-18209

About Multi-Architecture Support

  • Each tag (e.g., sha-51a79d4) 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-51a79d4-amd64) are also available if needed

…s model

Onboarding on a local backend pins the `default` agent profile to the LLM
profile it creates. `llm preset deepseek` activated deepseek-flash but left
that pin, so the Agents page still showed the onboarding model and deleting
the onboarding profile answered 409 until `default` was edited by hand.

The preset now moves `default` to deepseek-flash when it references another
LLM profile that exists, and reports `repointed`. A fresh run's reference to
the missing `default` profile (F13.stale-llm-ref), named agent profiles and
`llm set` stay as they are. F01's Restore and Gotcha now use the preset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018aWx8ibVJKrze1ckEXNwx1
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

PR Artifacts Cleaned Up

The .pr/ directory is no longer present.

@github-actions github-actions Bot added the type: fix A bug fix label Oct 9, 2026

@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.

Reviewed the diff: the change is confined to the verify-openhands skill harness and .pr/, adds a small pure helper (lib/agent-profile-repoint.mjs) with unit tests, and wires it into llm preset only (leaving llm set, named profiles, ACP profiles, and missing refs alone). CI is green and the helper's behavior matches my own sanity runs. No major issues — approving.

This review was generated by an AI agent (OpenHands) on behalf of the OpenHands maintainers.

@enyst
enyst enabled auto-merge (squash) October 9, 2026 02:07
…-da1zye

# Conflicts:
#	.agents/skills/verify-openhands/scripts/control-openhands.test.mjs
@enyst
enyst merged commit e726c06 into main Oct 9, 2026
15 checks passed
@enyst
enyst deleted the claude/confident-bohr-da1zye branch October 9, 2026 02:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants