clean-postman-32056
07/30/2026, 4:58 PMcalm-artist-7206
07/30/2026, 5:10 PMcalm-artist-7206
07/30/2026, 5:14 PMclean-postman-32056
07/30/2026, 5:18 PMclean-postman-32056
07/30/2026, 5:18 PMcalm-artist-7206
07/30/2026, 5:19 PMclean-postman-32056
07/30/2026, 5:19 PMclean-postman-32056
07/30/2026, 5:20 PMcalm-artist-7206
07/30/2026, 5:22 PMclean-postman-32056
07/30/2026, 5:22 PMclean-postman-32056
07/30/2026, 5:22 PMclean-postman-32056
07/30/2026, 5:23 PMclean-postman-32056
07/30/2026, 5:24 PMcalm-artist-7206
07/30/2026, 5:24 PMclean-postman-32056
07/30/2026, 5:25 PMclean-postman-32056
07/30/2026, 5:25 PMclean-postman-32056
07/30/2026, 5:27 PMcalm-artist-7206
07/30/2026, 5:30 PMcalm-artist-7206
07/30/2026, 5:36 PMclean-postman-32056
07/30/2026, 5:39 PMcalm-artist-7206
07/30/2026, 5:39 PMclean-postman-32056
07/30/2026, 5:39 PMclean-postman-32056
07/30/2026, 5:40 PMcalm-artist-7206
07/30/2026, 5:41 PMbland-bear-604
07/30/2026, 5:50 PMmain (1.8.0, on a throwaway branch so your fix/llm-profile-duplicate-attributes-all-tab WIP is untouched), and I restarted the agent-canvas stack from odie on port 8790 (kept it off 8788 so it doesn't collide with my own agent-server). Added two distinct test profiles β neal-test-a (Sonnet-4.5) and neal-test-b (gpt-5.6) β so a switch is unambiguous. Now reproducing (1) the mid-conversation profile switch and (2) file creation + recovery. Will report what I actually observe.clean-postman-32056
07/30/2026, 5:59 PMclean-postman-32056
07/30/2026, 5:59 PMbland-bear-604
07/30/2026, 6:01 PMmain, v1.8.0), two distinct profiles: neal-test-a = Sonnet-4.5, neal-test-b = gpt-5.6.
(1) Mid-conversation LLM switch β I could NOT reproduce the stuck-model bug on 1.8.0. In one conversation: asked "what model are you?" on profile A β it behaved as Anthropic/Sonnet. Switched to neal-test-b via the chat dropdown β the pill updated, and the next turn answered "I'm GPT-5.6, provided by OpenAI." So the live swap worked end-to-end for me on current main. Two caveats worth flagging: (a) a model's self-report is unreliable β my Sonnet turn literally called itself "Claude 3.7 Sonnet," so "ask it what model it is" isn't proof of anything, Neal may have hit exactly that confusion; (b) Neal was switching provider + account (DeepSeek β opencode-zen) and saw DeepSeek usage keep growing, which points more at a specific provider/base_url/profile-resolution case than the generic switch. @clean-postman-32056 β can you share the two exact profiles (models + base URLs) and the OH version/build you're on? I'd like to repro your precise combo rather than a generic one.
(2) Getting the created file β reproduced the friction. I told the agent to create `hello.txt`; it did, at ~/.openhands/agent-canvas/workspaces/<conversationId>/hello.txt, and it shows in the Files tab. But there is no per-file "Download" button there β the only affordance is "Open in new window", which points at /api/conversations/{id}/workspace/<file> (raw file β browser Save As). So the file's recoverable, but the "download" path is non-obvious β matches Neal not finding it. Neal's agent trying to "start a web server to serve it" is the LLM improvising around that missing button. Two real gaps: a first-class per-file Download/Save-As in the Files tab, and the "zip finished, where is it?" case (a produced artifact should be surfaced/downloadable, not left for the agent to serve). There's also a per-conversation trajectory/export, but that's not the same as grabbing a workspace artifact.
Net: bug (1) I can't confirm on latest main yet β need Neal's exact setup; bug (2) is a genuine UX gap (no workspace-file download control). Want me to file (2) and, once Neal shares his profiles, chase (1)? πΎbland-bear-604
07/30/2026, 6:06 PMlatest docker tag, and it's automatic, but only for stable releases.
The logic lives in .github/workflows/docker.yml. On every push of a v* git tag it builds <http://ghcr.io/openhands/agent-canvas|ghcr.io/openhands/agent-canvas> and, only when the version is a clean stable release (no `-rc`/pre-release or +build suffix), it auto-adds the abbreviated + latest tags:
β’ full X.Y.Z (e.g. 1.8.0)
β’ X.Y (1.8)
β’ X (1)
β’ latest
Pre-releases get only the exact version tag β never latest. And pushes to main are built too but deliberately not aliased to latest (there's an explicit comment: latest always points at the highest stable tagged release, not main).
Verified against the live registry just now: latest, 1.8.0, 1.8, and 1 all resolve, and latest and 1.8.0 share the same digest (sha256:714d6ce1β¦) β so latest == the newest stable release right now.
So to Neal's "pin or follow latest?": both are supported. :latest auto-tracks the newest stable (what you want for "just keep me current" β force-pull to update). Pin :1.8.0 (or :1.8) if you want reproducibility/no surprise upgrades. The stale one you started from last night was almost certainly a pinned older version in the compose file, not latest. πΎclean-postman-32056
07/30/2026, 6:07 PMclean-postman-32056
07/30/2026, 6:07 PMclean-postman-32056
07/30/2026, 6:08 PMclean-postman-32056
07/30/2026, 6:08 PMcalm-artist-7206
07/30/2026, 6:13 PMbland-bear-604
07/30/2026, 6:14 PMbig-pickle profile: model openai/big-pickle, base_url <https://opencode.ai/zen/v1> (OpenCode Zen's OpenAI-compatible endpoint), key in Keychain. Then in the same running test conversation β already mid-conversation, having switched Sonnet β gpt-5.6 earlier β I opened the chat profile dropdown and switched to big-pickle. The pill updated, and the next turn was served by it: agent-server logged model=openai/big-pickle base_url=<https://opencode.ai/zen/v1>, and the agent replied PICKLE-OK. So a third live mid-conversation swap, to a brand-new provider, worked cleanly.
Two small notes: (1) litellm prints a harmless warning Cost calculation failed: This model isn't mapped yet (big-pickle) β cosmetic, and Big Pickle is free anyway; (2) the model list in the dropdown is fetched at page load, so a profile created after the page was open only appeared after a refresh β expected, not the switch bug.
Net across all three: on latest main, mid-conversation profile switching (Anthropic β OpenAI β opencode-zen) is solid for me. Still can't reproduce Neal's stuck-on-DeepSeek behavior β his exact profiles/base-urls/version would let me chase the specific case. πΎclean-postman-32056
07/30/2026, 7:10 PMmodel=openai/big-pickle base_url=<https://opencode.ai/zen/v1>, and the agent replied PICKLE-OK"clean-postman-32056
07/30/2026, 7:10 PMclean-postman-32056
07/30/2026, 7:10 PMclean-postman-32056
07/30/2026, 7:12 PMcalm-artist-7206
07/30/2026, 7:13 PMclean-postman-32056
07/30/2026, 7:13 PMcalm-artist-7206
07/30/2026, 7:14 PMcalm-artist-7206
07/30/2026, 7:14 PMcalm-artist-7206
07/30/2026, 7:14 PMclean-postman-32056
07/30/2026, 7:14 PMclean-postman-32056
07/30/2026, 7:17 PMclean-postman-32056
07/30/2026, 7:17 PMclean-postman-32056
07/30/2026, 7:19 PMclean-postman-32056
07/30/2026, 7:24 PMcalm-artist-7206
07/30/2026, 7:27 PMcalm-artist-7206
07/30/2026, 7:28 PMclean-postman-32056
07/30/2026, 7:31 PMclean-postman-32056
07/30/2026, 7:32 PMcalm-artist-7206
07/30/2026, 7:32 PMcalm-artist-7206
07/30/2026, 7:32 PM