fix(dash): discover served model for configured chat endpoint - #97
Conversation
A configured chat URL (OPENAI_BASE_URL / --chat-url) with no explicit model resolved to the "local-model" placeholder, which 404s on servers that register the model under its real id. Query /v1/models on startup to adopt the served model, mirroring the managed-service path. Gated on a reachable probe so an unreachable endpoint adds no fetch timeout to launch, and an explicit --chat-model/config value still wins. Signed-off-by: Eugene Volen <Eugene.Volen@amd.com>
034e4e1 to
f8c2da1
Compare
|
🔴 Automated review · pr-review-watcher · f8c2da1 SummaryFixes the broken 🚫 Blocking (must fix before merge)None. Non-blocking
|
Reconcile PR #97 (configured-endpoint served-model discovery) with main's PR #100 startup local-first detection (EAI-7347). Conflicts in crates/rocm-dash-tui/src/app/{chat.rs,mod.rs} resolved as a union that keeps both behaviors: - Preserve main's local-engine detection: should_detect_local_chat, StartupChatOutcome/startup_chat_outcome, detect_local_chat_with_probe, and the #89 Press-only overlay key gate (is_actionable_key). - Port PR #97's /v1/models discovery for a *configured* chat endpoint into a new helper, chat::discover_configured_chat_model, wired only on the StartupChatOutcome::Configured path. Startup matrix (verified by unit tests in app::chat::tests): - Configured URL + no explicit model + reachable -> adopt served /v1/models id. - Configured URL + explicit model -> config precedence, never overridden. - Configured URL + unreachable -> never probed, never replaced (no fetch timeout; an unreachable explicit CLI/env URL is left untouched). - Local detected / OAuth paths unchanged from main. RED before the port: configured_endpoint_adopts_served_model_when_no_model_set failed against the merged-main stub (got "local-model", expected served id); GREEN after wiring the helper. Full workspace tests, clippy -D warnings, and scripts/smoke_local.py all pass. Signed-off-by: Michael Roy <michael.roy@amd.com>
…ale chat_url recovery) Layer PR #105's stale persisted-URL recovery onto PR #97's configured-endpoint model discovery (which already includes current main). Manually resolve the chat.rs/mod.rs conflicts, preserving both behaviors: - PR #97: discover_configured_chat_model() adopts a served /v1/models id for a reachable configured endpoint that has no explicit model (probe_ok path). - PR #105 (EAI-7360): stale_chat_url_replacement() swaps a dead persisted tui.chat_url for a genuinely-different live local engine on the Configured + !probe_ok path, emits a "server changed" notice pointing at `/detect save`, and normalize_base_url() treats trailing slash and /v1 formatting as the same endpoint. Gated on chat_url.is_some() + no api_key/auth_header so env URLs and authenticated remote gateways are never silently replaced. The two paths are mutually exclusive on the Configured branch's probe_ok, so they compose without interference; resolve_llm_config's CLI>config>env>probe precedence is untouched. Matrix verified: no URL/model -> local detection; reachable configured -> /v1/models discovery; stale persisted -> live replacement + notice; unreachable env/explicit URL -> fail honestly; explicit auth -> no silent fallback. Signed-off-by: Michael Roy <michael.roy@amd.com>
| // carries a `/v1/models`-discovered model from `detect_local_chat`, and | ||
| // `OAuth` has no config. Discovery is gated inside the helper on | ||
| // `probe_ok` (an unreachable endpoint is never probed nor replaced) and | ||
| // on the absence of an explicit model (config precedence wins). |
There was a problem hiding this comment.
This is quite verbose, would suggest a small cleanup to keep comments at a reasonable size.
|
@volen-silo lgtm once the tests and any other ci failures are taken care of. Approved. |
Final refresh: main advanced 9830e57 -> 8308450 via #104 (decouple vLLM Prometheus scraping from enable_docker) and #97 (discover served model for configured chat endpoint). Clean auto-merge (runner.rs only), no conflicts. Preserves the startup-phase / Ready composition (InstanceStatus::Starting { phase }, PROTOCOL_VERSION = 2, phase-aware registry mapping, and the Starting -> Ready scrape-success promotion in runner.rs) alongside #104's scraping-decouple changes, plus the CodeQL test-path fix (rocmd tests use the CARGO_MANIFEST_DIR-rooted unique_test_root helper, not env::temp_dir()). Signed-off-by: Michael Roy <michael.roy@amd.com>
Final refresh: bring PR #92 up to main 8308450 (adds #104 decouple vLLM Prometheus scraping from enable_docker, and #97 discover served model for the configured chat endpoint). Clean auto-merge with no conflicts — merge-tree predicted clean and only crates/rocm-dash-tui/src/app/mod.rs was auto-merged (the #97 chat-endpoint change; scrollbar hit-testing code untouched). The scrollbar + braille spinner feature is unchanged: job_console.rs, ui/panel.rs and ui/spinner.rs are byte-identical to the prior branch head. Signed-off-by: Michael Roy <michael.roy@amd.com>
Summary
/v1/modelsat startup to discover the served model name when a chat endpoint is configured viaOPENAI_BASE_URL/--chat-urlbut no model is set.rocm serve … && OPENAI_BASE_URL=… rocmflow was broken — sending a message returned404 Not Found: The model 'local-model' does not exist, making chat unusable out of the box.resolve_llm_config'sDEFAULT_CHAT_MODEL = "local-model"placeholder and built the agent with it. Accepting the consent prompt doesn't rebuild, so the placeholder reached the first request./v1/modelsand adopt the served id (via the existingfetch_first_model/pick_first_modelhelpers), mirroring the managed-service path.Non-obvious decisions
probe_ok) so an unreachable configured endpoint never adds the 3s fetch timeout to startup.--chat-model/ config value always wins — discovery only fills the placeholder (enforced by the purewith_discovered_modelhelper).local-modelfallback when/v1/modelscan't be read — some endpoints ignore the model field or don't expose the listing.Test plan
cargo test -p rocm-dash-tui --lib— 549 passed (3 new unit tests forwith_discovered_model: placeholder replaced, explicit model preserved, failed discovery keeps fallback).cargo clippy -p rocm-dash-tui --all-targets— clean.rocm serve Qwen/Qwen2.5-1.5B-Instruct --engine vllm, thenOPENAI_BASE_URL=http://127.0.0.1:11435/v1 rocm, accept the endpoint in the Chat tab, send a message → expect a normal reply and nolocal-model404.Risk
Low — additive best-effort discovery on a single startup path; existing precedence and the neutral fallback are preserved.