Skip to content

fix(chat): tell the assistant which machine it is running on - #321

Draft
volen-silo wants to merge 1 commit into
mainfrom
fix/ground-chat-assistant-in-host-facts
Draft

fix(chat): tell the assistant which machine it is running on#321
volen-silo wants to merge 1 commit into
mainfrom
fix/ground-chat-assistant-in-host-facts

Conversation

@volen-silo

Copy link
Copy Markdown
Collaborator

Draft. Fixes #287 in substance; see What this does not fix before treating the issue as closed.

The reported bug

Asked "What ROCm can do in windows?", the dashboard assistant replied that ROCm is not compatible with Windows and suggested CUDA/DirectX.

Root cause — not the model being wrong, the CLI telling it nothing

rocm-cli ships two chat implementations with different grounding, and the one users reach interactively has almost none. The dashboard's entire system message was:

You are the rocm-dash assistant, embedded in a terminal dashboard for AMD Instinct GPU telemetry and benchmarks. Use the provided tools (gpu_status, list_instances, bench_summary, tokens_per_watt) … Prefer short, direct answers.

Then the raw question. No OS, no WSL flag, no GPU, no runtime, no ROCm product knowledge. A 4B model answering from that is answering from pretraining, where "ROCm is Linux-only" was true for years. The observed reply is the predictable outcome, not an anomaly.

Three things made it worse:

  • A ~4000-char ROCm-aware prompt and a bundled SKILL.md already existed, reachable only from rocm chat --prompt … --tools. Nothing under crates/ could reference them.
  • Interactive rocm chat routes into the dashboard chat, so users who think they are using "the assistant" got the weak preamble.
  • That prompt would have misled this reporter anyway. It asserted, unconditionally, "Speak in simple English for non-technical Windows users" and "On native Windows, vLLM is skipped; use WSL/Linux". The reporter is on WSL — where vLLM is the supported path. Wiring it in unchanged would have traded one wrong answer for another.

What this does

Detect the host and say so, instead of letting either prompt guess. On this machine:

Facts about the machine you are running on, detected by ROCm CLI. Trust these over anything you remember about ROCm:
- Operating system: Linux running under WSL2 on a Windows host
- AMD GPU: <detected adapter / gfx target>
- Serving engines that run here: Lemonade and vLLM.
ROCm and ROCm CLI support this operating system. Never tell the user ROCm is unavailable on their platform, and never suggest CUDA, DirectML, or CPU fallback.

The bin is the only place holding both the ROCm knowledge and rocm-core, so it composes and the dashboard consumes — a fourth plain-data field on ResolvedArgs, alongside model_recipes / runtimes / automations, which already carry the comment "Adapted by the bin so this crate needs no rocm-core dep." No dash crate gained a rocm-core dependency; no dash Cargo.toml changed at all.

Also: the two unconditional Windows claims are gone; rocm chat --prompt --tools gets the grounded prompt too; and the dashboard gains an examine alias, because the prompt named a tool it did not register.

Non-obvious decisions

  • Detection must be cheap — it runs in resolved_args(), before the dashboard draws. Cheap getters only, never ExamineSummary::gather(). Measured here: 1.35 ms cold, 0.59 ms warm.
  • is_wsl_host() promoted pub(crate)pub (three fs/env reads, no subprocess). The only public alternative was gather(), whose WSL probe shells out to ldconfig -p.
  • rocm_chat_tool_system_prompt() is untouched; the grounded variant is a new function. The 22-substring contract test stays green with every assertion intact.
  • The scenario asserts the request, not the reply. A 4B model's wording is not deterministic; what broke was the CLI's side of the conversation.

Verification

cargo fmt = 0 · cargo clippy --workspace --all-targets -D warnings = 0 · cargo clippy -p e2e-cucumber --test e2e -D warnings = 0 · cargo test --workspace --all-targets = 0 · smoke_local.py = 0 · cargo xtask e2e = 0 (70 passed, 2 known WSL diagnose xfail, 0 unexpected).

MockAgentClient ignores the preamble entirely, so a mock-driven test can pass while proving nothing. The coverage was therefore mutation-tested:

Mutation Unit test Scenario
Facts injection removed from the composer FAIL (exit 101) FAILchat-assistant-is-told-which-machine-it-is-on … a regression
Wiring seam cut (chat_system_prompt: None) passes — correctly, it tests composition FAIL — same regression line

The second row is the useful one: it shows the scenario, not the unit test, is what covers the seam. I re-ran that mutation independently and confirmed both the failure and a byte-identical restore.

What this does not fix

Grounding narrows the failure; it does not cure it. A 4B model will still get some ROCm platform questions wrong, and no automated test judges answer quality — by design, since model wording is not deterministic. The scenario proves the assistant is told about the host, not that it answers correctly. Please read the green check accordingly.

rocm chat --prompt without --tools still sends no system message at all. Out of scope here; making the grounded prompt unconditional is a behaviour change affecting scripted callers and deserves its own decision.

Limitations of local verification

This box turned out not to be the gfx1151 Strix Halo host the issue reports: no /dev/dxg, no amdgpu sysfs node, a Ryzen 7 PRO 8840U, and rocm examine independently reports the WSL GPU plumbing missing. So the WSL/OS half of the block was verified against real detection, but the GPU-populated form was not — the e2e step covers both shapes, and the GPU lanes will exercise the second.

One correction to my own design note while implementing: detect_host_gpu_summary is not unconditionally process-free on native Windows — it shares the pnputil/PowerShell inventory path with gather(), just less of it. Still far cheaper, but worth stating rather than implying.

Asked what ROCm can do on Windows, the dashboard assistant answered that
ROCm is not compatible with Windows and suggested CUDA. It had no way to
know better. Its entire system prompt was four lines about Instinct
telemetry, so the answer came from pretraining, where ROCm was
Linux-only for years.

Two chats had drifted apart. A ROCm-aware prompt and a bundled skill file
already existed, but only `rocm chat --prompt --tools` could reach them —
and interactive `rocm chat` routes into the dashboard, so the users most
likely to ask were the least likely to be answered from it.

Detect the host and say so, rather than letting either prompt guess. The
bin is the only place holding both the ROCm knowledge and `rocm-core`, so
it composes and the dashboard consumes, as a plain-data field alongside
the recipes, runtimes and automations already adapted the same way. The
dash crates gain no `rocm-core` dependency.

That detection has to be cheap, because it runs before the dashboard
draws: the cheap getters only, never `ExamineSummary::gather()`, which
can spend seconds in PowerShell on Windows.

The prompt asserted twice that the user was on Windows, so wiring it in
unchanged would have traded one wrong answer for another — a WSL user
told that vLLM, the engine they can actually run, is unavailable. Those
claims are gone; the detected facts carry it now.

The prompt also named a tool the dashboard does not register. Neither
name was valid in both catalogs, so the dashboard gains an `examine`
alias and a test cross-checks the prompt against the schema.

The scenario asserts what the CLI sends, not what the model replies. A
4B model's wording is not deterministic, and what broke here was the
CLI's side of the conversation.

Refs: #287
Signed-off-by: Eugene Volen <Eugene.Volen@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.

[Issue]: Dashboard chat incorrectly states ROCm is not compatible with Windows

1 participant