fix(hud): state word first, layer names last; CJK cap by locale

Follow-up review fixes:

- The HUD line is STATE | text | LAYERS for the AI summary and the
  fallback line, so the narrow minimal and cyber layouts show both the
  warning and the summary. get_hud_caption builds its caption the same
  way. The unused "{state} {layers}" key is pruned from the catalogs.
- The 20-character cap applies only when the request locale is Japanese
  or Chinese; other languages keep five words around a Han place name.
- enabledLayers names are localized too, and the instructions name layers
  only from enabledLayerLabels, never from feedProvenance or its note.
- The keyless test restores GEV_RATELIMIT_OPENAI_PER_MIN again; comments
  and docs updated.
This commit is contained in:
German Khokhlov committed 2026-10-30 14:27:59 +04:00
1 parent f967218a04
commit 7b223d7d7b
17 files changed
+80 -51

No files matched your search

+5 -3
View File
@@ -256,14 +256,16 @@ export const getHudCaption = defineTool({
const words = response?.data?.summary;
if (!response?.ok || typeof words !== 'string' || !words)
throw new ToolError('unavailable', 'The caption service did not answer');
// As on the HUD: the warning is the app's own state tag, and a reply that
// names another state than the app's keeps only the place.
// As on the HUD: the app's own state leads and its layers trail, and a
// reply that names another state than the app's keeps only the place.
const tag = provenanceTag(feedProvenance);
const text = hudSummaryMatchesProvenance(response.data, feedProvenance)
? words
: area.label;
const caption = tag
? `${text} | ${[tag.state, ...tag.names].join(' ').toUpperCase()}`
? [tag.state.toUpperCase(), text, tag.names.join('/').toUpperCase()]
.filter(Boolean)
.join(' | ')
: text;
return {
summary: caption,
@@ -2,9 +2,7 @@ import assert from 'node:assert/strict';
import test from 'node:test';
import { composeCatalog, coreTools } from '../index.js';
// The proxy returns the feed state as its own field ({ summary, feedState });
// the five words no longer carry STALE, so get_hud_caption adds the app's own
// state tag and keeps only the place when the reply names another state.
// get_hud_caption shows the app's own feed state, not the model's words.
async function staleCaption(reply) {
const conditions = {
observedAt: '2026-10-01T19:15:00.000Z',
@@ -53,7 +51,10 @@ test('get_hud_caption keeps the canonical feed state of a stale view', async ()
feedState: 'stale',
});
assert.equal(data.feedState, 'stale');
assert.equal(data.caption, 'Austin weather across the area | STALE WEATHER');
assert.equal(
data.caption,
'STALE | Austin weather across the area | WEATHER',
);
});
test('get_hud_caption drops words whose feed state is not the app one', async () => {
@@ -62,5 +63,5 @@ test('get_hud_caption drops words whose feed state is not the app one', async ()
feedState: 'nominal',
});
assert.equal(data.feedState, 'stale');
assert.equal(data.caption, 'Austin, Texas | STALE WEATHER');
assert.equal(data.caption, 'STALE | Austin, Texas | WEATHER');
});