fix(hud): ask the model only with a place label, catch flush English echoes

- Skip the model when the view has layers but no place, street or nearby
  label: with layers alone it invented a place.
- The English-echo check treats only Latin letters as part of a word, so
  ids flush against kana or Han and hyphenated names are caught; it skips
  nominal, state words a locale keeps in English and names inside place
  labels.
- Outside English, per-layer state ids are left out of the request.
- The ja/zh cap steps back to the start of a Latin word, not the last space.
- Fold the CJK cap cases into hudSummaryResponse.test.mjs.
This commit is contained in:
German Khokhlov committed 2026-10-30 20:53:31 +04:00
1 parent 7713fb8ae8
commit dbfbfcceb9
7 files changed
+150 -107

No files matched your search

+3 -3
View File
@@ -5255,10 +5255,10 @@ and unreachable upstream (502/504) separately from road geometry.
### AI HUD Summary (June 2026)
- HUD `SUMMARY` readout requests a five-word intelligence-style summary from `/api/openai/hud-summary` (model `OPENAI_HUD_SUMMARY_MODEL`, default `gpt-5-nano`, minimal reasoning).
- Input is the live basemap label context (place/street/nearby-place labels + enabled layers) and `feedProvenance`, with every layer name as the user sees it; outside English the narration note is left out, since a small model copies its English words. The model is instructed not to infer from coordinates. A view with no labels and no enabled layer is not sent: the deterministic line is shown.
- Input is the live basemap label context (place/street/nearby-place labels + enabled layers) and `feedProvenance`, with every layer name as the user sees it; outside English the narration note and the per-layer state ids are left out (`overall` still carries the state), since a small model copies English words. The model is instructed not to infer from coordinates. A view with no place, street or nearby-place label is not sent, since with layers alone the model invents a place: the deterministic line is shown.
- Language (October 2026): the HUD sends `locale`, which is part of the dedupe signature. The proxy keeps a shipped locale (English otherwise) and names the language in the instructions and at the start of the input; Japanese and Chinese get a 20-character phrase instead of five words.
- The reply is structured (`text.format` JSON schema): `{summary, feedState}`, `feedState` being the snapshot state or `none`. For a view that is not nominal, a missing or different `feedState` falls back to the deterministic line. An accepted summary and the deterministic line carry the HUD's own translated state: the state word leads and the layer names trail (`STALE | … | LIVE FLIGHTS`), so the one-line readout never clips the warning; the text and then the layer names may be cut off on narrow layouts. Outside English a reply that echoes a feed-state id or an English layer name the UI translates falls back too. `get_hud_caption` builds its caption the same way and returns `feedState`.
- Output is sanitized to five words, or for a Japanese or Chinese request locale to 20 characters (stepping back to a space rather than splitting a Latin word); falls back to the deterministic telemetry summary on error/timeout (5s abort); typewriter animation on update; a camera move during typing shows the deterministic line instead of the fragment.
- The reply is structured (`text.format` JSON schema): `{summary, feedState}`, `feedState` being the snapshot state or `none`. For a view that is not nominal, a missing or different `feedState` falls back to the deterministic line. An accepted summary and the deterministic line carry the HUD's own translated state: the state word leads and the layer names trail (`STALE | … | LIVE FLIGHTS`), so the one-line readout never clips the warning; the text and then the layer names may be cut off on narrow layouts. Outside English a reply that echoes a feed-state id or an English layer name the UI translates falls back too, even written flush against kana or Han; a state word the locale itself keeps in English (de `FALLBACK`) and a name inside a place label do not count. `get_hud_caption` builds its caption the same way and returns `feedState`.
- Output is sanitized to five words, or for a Japanese or Chinese request locale to 20 characters (stepping back to the start of a Latin word rather than splitting it); falls back to the deterministic telemetry summary on error/timeout (5s abort); typewriter animation on update; a camera move during typing shows the deterministic line instead of the fragment.
- `partial` is a feed state of its own, ranked between `fallback` and `nominal`, so one partial layer no longer reads as off and partial plus nominal reads partial (HUD, voice view state, `analyst_query`, `brief`, the agent world packet). Its narration note says coverage is incomplete rather than not live.
- A summary asked for before the camera starts moving never paints over the next view: `moveStart` marks the summary dirty and bumps its revision, as `moveEnd` does, aborts the request in flight and stops a reply still typing; neither a reply nor a fallback line (on an error, the 5 s timeout, the abort, or a failed context build) paints once the revision has moved. A dropped request forgets its signature and a timeout counts as a failure, so the next 15 s tick asks again even over the same place. An interrupted typewriter reply also forgets its signature; fully displayed answers remain reusable.