fix(hud): lead with the state tag, keep feedState in get_hud_caption

Review fixes for the HUD summary language change:

- The translated feed-state tag now leads the one-line summary and the
  fallback line, so the readout's ellipsis cannot hide it.
- get_hud_caption checks the reply's feedState, returns it and appends the
  state tag; a reply naming another state keeps only the place.
- The model gets the layer names the user sees (localizeLayerName).
- Japanese and Chinese summaries are capped at 20 characters; pt, zh-CN and
  zh-Hant get explicit language names.
- A partial view is narrated as incomplete coverage, not as not live.
- provenanceTag and hudSummaryMatchesProvenance move to layerSnapshot.js so
  the tools package can use them without browser globals.
- docs/CURRENT-STATE.md, changelog and comments updated; redundant tests
  trimmed.
This commit is contained in:
German Khokhlov committed 2026-10-30 13:06:53 +04:00
1 parent 54750a01e5
commit f967218a04
10 files changed
+232 -80

No files matched your search

+12 -2
View File
@@ -1,5 +1,6 @@
import {
HUD_SUMMARY_FEED_STATES,
HUD_SUMMARY_MAX_UNSPACED_CHARS,
HUD_SUMMARY_RESPONSE_FORMAT,
hudSummaryInput,
hudSummaryInstructions,
@@ -21,7 +22,7 @@ function extractOpenAiResponseText(data) {
.trim();
}
/** The structured reply, or nulls when the model did not follow the format. */
/** Parse the summary and normalize the canonical feed state. */
function parseHudSummaryReply(text) {
let reply = null;
try {
@@ -39,13 +40,22 @@ function parseHudSummaryReply(text) {
}
function toFiveWordHudSummary(value) {
return String(value || '')
const words = String(value || '')
.replace(/[^\p{L}\p{N}\s-]/gu, ' ')
.trim()
.split(/\s+/)
.filter(Boolean)
.slice(0, 5)
.join(' ');
// Japanese and Chinese have no spaces to count words by: cap characters.
if (!/[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u.test(words))
return words;
const graphemes = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
return [...graphemes.segment(words)]
.slice(0, HUD_SUMMARY_MAX_UNSPACED_CHARS)
.map(({ segment }) => segment)
.join('')
.trim();
}
async function handleHudSummary(req, res) {