Skip to content

fix(dash): chat /v1 404 + Esc closes a running serve modal - #68

Merged
michaelroy-amd merged 2 commits into
retire-legacy-tuifrom
fix-dash-chat-404-serve-modal
Jul 1, 2026
Merged

fix(dash): chat /v1 404 + Esc closes a running serve modal#68
michaelroy-amd merged 2 commits into
retire-legacy-tuifrom
fix-dash-chat-404-serve-modal

Conversation

@michaelroy-amd

@michaelroy-amd michaelroy-amd commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

Two dash chat usability bugs hit when serving a model and then chatting:

  1. Chat completions 404 (completion error, http error, 404 detail not found).
    The Rig OpenAI client builds the request URL as base_url + "/" + "chat/completions",
    so base_url must end in /v1. Every endpoint carried it (VLLM_ENDPOINT,
    LEMONADE_ENDPOINT, the managed-service endpoint_url) except the probed
    default DEFAULT_CHAT_BASE_URL = "http://127.0.0.1:8000". So when the dash
    probed a vLLM already listening on :8000 and fell back to that default, it POSTed
    to /chat/completions and the server answered 404 {"detail":"Not Found"}.
    Fix: add the /v1 suffix so it matches the other endpoints.

  2. Serve modal felt stuck. A managed serve blocks for up to 45s in its HTTP
    readiness wait (wait_for_service_http_ready). During that window the job console
    is Running, where Esc/Enter were swallowed and only q closed — but the
    footer advertised only Ctrl+C cancel, so there was no visible exit and it
    looked frozen. Fix: Esc now closes the overlay while a job is running (the
    job keeps running in the background, same as q already did), and the footer
    says so. Finished-job Esc/Enter still dismiss the console back to the screen
    body; Enter stays inert while running to avoid accidental dismissal.

Scope of the Esc-while-running change

The change lives in the shared job_console::on_console_key, so it applies to
every overlay that hosts a job console — 12 callers in total: serve, examine,
engine, runtime, install, update, config, logs, command, automations, services,
and onboarding.

Behavior change worth flagging: Esc on a running onboarding step
(onboarding.rs:180, *ob = None) now closes the whole onboarding wizard. This
is consistent with what q already did there, and it's a deliberate decision —
a running step keeps running in the background. Every caller's Unhandled arm was
checked; none branch on Esc, so nothing screen-specific is silently intercepted.

Changes

  • llm.rs: DEFAULT_CHAT_BASE_URLhttp://127.0.0.1:8000/v1 (+ rationale doc),
    plus a revert-proof regression test asserting the resolved base_url ends in /v1.
  • ui/job_console.rs: Esc on a running job → Closed; updated footer hint.
  • ui/serve_wizard.rs, ui/examine_manager.rs: updated tests to the new contract.

Test plan

  • cargo test -p rocm-dash-tui --lib -- --test-threads=1 → 461 passed
  • cargo clippy -p rocm-dash-tui --all-targets → clean
  • Verified the new 404 guard fails when the /v1 suffix is reverted
  • Manual: probe a vLLM on :8000, open dash chat, confirm a completion returns (no 404)
  • Manual: serve a managed vLLM recipe, press Esc during readiness wait, confirm modal closes and the server keeps coming up in the background, then chat works

Stacked on #67 (retire-legacy-tui).

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

Both bugs are real and fixed at the correct layer — nice, focused change. One blocking item plus a couple of things to tighten before this is ready.

Blocking: the 404 fix has no regression test

probed_default_used_when_nothing_configured_but_reachable asserts r.base_url == DEFAULT_CHAT_BASE_URL, which is tautological — both sides are the same constant. I reverted the /v1 suffix locally and the entire llm test suite still passed, so nothing guards the actual fix. The Esc change is well covered, but the headline bug needs a test that fails on revert, e.g.:

assert!(DEFAULT_CHAT_BASE_URL.ends_with("/v1"), "Rig appends chat/completions to base_url");

or assert the resolved base_url ends in /v1.

Please address

  • Scope of the Esc change is wider than the description says. The summary lists 6 overlays, but on_console_key is the shared seam for 12. The unlisted ones include onboarding: Esc on a running onboarding step now closes the whole onboarding wizard (onboarding.rs:180, *ob = None). It's consistent with what q already did, but it's an unmentioned behavior change in a guided flow — worth calling out so it's a deliberate decision. (For what it's worth, I checked every caller's Unhandled arm and none branch on Esc, so nothing screen-specific gets silently intercepted.)
  • Stacked PR isn't a draft, and CI hasn't run. It's correctly noted as stacked on #67 and targets retire-legacy-tui, but it's marked ready with no checks reported yet, so the test/clippy results are local-only at this point.

Nit

  • The doc comment says the new value "Mirrors ... VLLM_ENDPOINT / LEMONADE_ENDPOINT", but those use localhost while this uses 127.0.0.1 — they share the /v1 suffix and port, not the host. 127.0.0.1 is the right pick (unambiguous IPv4 loopback, and it matches the live test in agent.rs); just consider softening the wording to "matches the /v1 convention of ...".

michaelroy-amd added a commit that referenced this pull request Jul 1, 2026
Address review on #68:
- probed_default_used_when_nothing_configured_but_reachable only asserted
  base_url == DEFAULT_CHAT_BASE_URL, which is tautological w.r.t. the /v1
  fix. Add an assertion that the *resolved* base_url ends in /v1 — it fails
  when the suffix is reverted (verified), so it actually guards the 404 fix.
- Soften the const doc: VLLM_ENDPOINT / LEMONADE_ENDPOINT share the /v1
  convention and port, not the host (they use localhost, this uses the
  unambiguous IPv4 loopback 127.0.0.1).

Signed-off-by: Michael Roy <michael.roy@amd.com>
@michaelroy-amd

Copy link
Copy Markdown
Member Author

Thanks @rominf — all three addressed in a1fa5f7 + a description update.

  • Regression test (blocking): probed_default_used_when_nothing_configured_but_reachable now asserts the resolved base_url ends in /v1. I confirmed it fails on revert (reverted the suffix locally → the test panics; restored). No longer tautological.
  • Scope: rewrote the description — the shared on_console_key seam has 12 callers, not 6, and I now explicitly call out the onboarding behavior change (Esc on a running step closes the wizard, consistent with q) as a deliberate decision. Thanks for checking the Unhandled arms.
  • Nit: softened the doc to "matches the /v1 convention of VLLM_ENDPOINT / LEMONADE_ENDPOINT" and noted those use localhost while this uses 127.0.0.1 (unambiguous IPv4 loopback, matches the live test in agent.rs).

On the CI/draft note: it targets retire-legacy-tui (#67), so checks trail the stack; results are local for now (461 tests + clippy clean). Re-review when you have a moment?

… job console

Two dash chat usability fixes surfaced when serving a model then chatting:

1. 404 on chat completions. The Rig OpenAI client builds the request URL as
   `base_url + "/" + "chat/completions"`, so `base_url` must end in `/v1`.
   Every endpoint carried it (VLLM_ENDPOINT, LEMONADE_ENDPOINT, managed
   `endpoint_url`) except the probed default `DEFAULT_CHAT_BASE_URL`, so a
   vLLM probed on :8000 was POSTed to `/chat/completions` and answered
   `404 {"detail":"Not Found"}`. Add the `/v1` suffix.

2. Serve modal felt stuck. A managed serve blocks for up to 45s in its HTTP
   readiness wait; during that window the job console is Running, where Esc/Enter
   were swallowed and only `q` closed — but the footer advertised only Ctrl+C, so
   the user had no visible exit. Esc now closes the overlay while a job runs (the
   job keeps running in the background); the footer says so. Finished-job Esc/Enter
   still dismiss back to the screen body. Enter stays inert while running to avoid
   accidental dismissal.

Signed-off-by: Michael Roy <michael.roy@amd.com>
Address review on #68:
- probed_default_used_when_nothing_configured_but_reachable only asserted
  base_url == DEFAULT_CHAT_BASE_URL, which is tautological w.r.t. the /v1
  fix. Add an assertion that the *resolved* base_url ends in /v1 — it fails
  when the suffix is reverted (verified), so it actually guards the 404 fix.
- Soften the const doc: VLLM_ENDPOINT / LEMONADE_ENDPOINT share the /v1
  convention and port, not the host (they use localhost, this uses the
  unambiguous IPv4 loopback 127.0.0.1).

Signed-off-by: Michael Roy <michael.roy@amd.com>
@michaelroy-amd
michaelroy-amd force-pushed the fix-dash-chat-404-serve-modal branch from a1fa5f7 to c44eb10 Compare July 1, 2026 14:35
@michaelroy-amd
michaelroy-amd merged commit 86896af into retire-legacy-tui Jul 1, 2026
@michaelroy-amd
michaelroy-amd deleted the fix-dash-chat-404-serve-modal branch July 1, 2026 14:41
michaelroy-amd added a commit that referenced this pull request Jul 1, 2026
* fix(dash): add /v1 to default chat base url + let Esc leave a running job console

Two dash chat usability fixes surfaced when serving a model then chatting:

1. 404 on chat completions. The Rig OpenAI client builds the request URL as
   `base_url + "/" + "chat/completions"`, so `base_url` must end in `/v1`.
   Every endpoint carried it (VLLM_ENDPOINT, LEMONADE_ENDPOINT, managed
   `endpoint_url`) except the probed default `DEFAULT_CHAT_BASE_URL`, so a
   vLLM probed on :8000 was POSTed to `/chat/completions` and answered
   `404 {"detail":"Not Found"}`. Add the `/v1` suffix.

2. Serve modal felt stuck. A managed serve blocks for up to 45s in its HTTP
   readiness wait; during that window the job console is Running, where Esc/Enter
   were swallowed and only `q` closed — but the footer advertised only Ctrl+C, so
   the user had no visible exit. Esc now closes the overlay while a job runs (the
   job keeps running in the background); the footer says so. Finished-job Esc/Enter
   still dismiss back to the screen body. Enter stays inert while running to avoid
   accidental dismissal.

Signed-off-by: Michael Roy <michael.roy@amd.com>

* fix(dash): guard the /v1 default with a revert-proof test + soften doc

Address review on #68:
- probed_default_used_when_nothing_configured_but_reachable only asserted
  base_url == DEFAULT_CHAT_BASE_URL, which is tautological w.r.t. the /v1
  fix. Add an assertion that the *resolved* base_url ends in /v1 — it fails
  when the suffix is reverted (verified), so it actually guards the 404 fix.
- Soften the const doc: VLLM_ENDPOINT / LEMONADE_ENDPOINT share the /v1
  convention and port, not the host (they use localhost, this uses the
  unambiguous IPv4 loopback 127.0.0.1).

Signed-off-by: Michael Roy <michael.roy@amd.com>

---------

Signed-off-by: Michael Roy <michael.roy@amd.com>
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.

2 participants