Skip to content

feat: add --remap-developer-role flag for developer→system translation#2

Closed
marksverdhei wants to merge 4 commits into
htfrom
fix/developer-role-to-system
Closed

feat: add --remap-developer-role flag for developer→system translation#2
marksverdhei wants to merge 4 commits into
htfrom
fix/developer-role-to-system

Conversation

@marksverdhei

Copy link
Copy Markdown

Summary

  • Adds --remap-developer-role server flag (env: LLAMA_ARG_REMAP_DEVELOPER_ROLE) that translates OpenAI's "developer" role to "system" before chat templates are applied
  • Fixes Qwen3.5 MoE and other models whose Jinja templates crash on unknown roles
  • In the Responses API path, also merges developer/system messages with the instructions-derived system message to avoid duplicate system message errors
  • Without the flag, behavior is unchanged

Test plan

  • POST /v1/chat/completions with role: "developer" + tools → 200 (was 500)
  • POST /v1/responses with instructions + developer role + tools → 200 (was 500)
  • Codex CLI v0.107.0 works end-to-end with Qwen3.5-35B-A3B
  • Without flag, developer role passes through unchanged (backwards compatible)

marksverdhei and others added 4 commits March 3, 2026 08:45
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a server flag --remap-developer-role (env: LLAMA_ARG_REMAP_DEVELOPER_ROLE)
that translates OpenAI's "developer" role to "system" before applying
chat templates. This fixes models whose Jinja templates reject unknown
roles (e.g. Qwen3.5 MoE crashes with "Unexpected message role").

When enabled:
- Chat completions: remaps developer→system on raw JSON messages
- Responses API: remaps developer→system and merges with any existing
  system message from the "instructions" field to prevent duplicate
  system messages

Without the flag, behavior is unchanged (developer role passes through).

Tested with Codex CLI + Qwen3.5-35B-A3B-UD end-to-end.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@marksverdhei

Copy link
Copy Markdown
Author

Squash merged into ht branch manually.

@marksverdhei marksverdhei deleted the fix/developer-role-to-system branch March 4, 2026 07:14
marksverdhei added a commit that referenced this pull request Mar 7, 2026
- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 7, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 8, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 9, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 10, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 11, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 25, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 25, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 25, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 29, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 31, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Mar 31, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Apr 5, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
marksverdhei added a commit that referenced this pull request Apr 7, 2026
* webui: add cancel button for in-progress model loading

Allow users to cancel a model that is stuck loading or taking too long
in the router mode model selector. The cancel button appears next to
the loading spinner in both the model selector dropdown/sheet trigger
and within individual model option rows.

Uses the existing /models/unload endpoint which already supports
unloading models in LOADING state. The frontend polling loop is
interrupted via AbortController to prevent stale error toasts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* webui: add cancelling state indicator and fix cancel polling

- Show orange "Cancelling" indicator with spinner while cancel is in progress
- Poll until server confirms model is no longer in LOADING state before
  clearing the cancelling indicator
- Guard against redundant unload calls on already-unloaded models
- Keep loadingModelId alive during cancel so selector trigger shows
  the cancelling state correctly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(webui): color-coded spinners for model load/unload/cancel states

- Loading: green spinner, clockwise
- Unloading: red spinner, reverse direction with "Unloading" label
- Cancelling: orange spinner, reverse direction
- Track unloading state separately in models store

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(webui): address PR review feedback for cancel model loading

- Remove duplicated cancel logic from ModelsSelector and ModelsSelectorSheet
  by deriving loading/cancelling state from the store (issue #1)
- Fix race condition: no longer set isLoadingModel=false before cancel
  completes, preventing brief UI flash (issue #2)
- Add MAX_CANCEL_POLL_ATTEMPTS (60) timeout to cancel polling loop
  to prevent infinite polling if server never transitions (issue #3)
- Replace div cancel buttons with proper <button> elements for
  keyboard accessibility and screen reader support (issue #4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant