mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
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:
1 parent
54750a01e5
commit
f967218a04
10 files changed
+232
-80
No files matched your search
@@ -1,7 +1,11 @@
|
||||
/** Composite queries that combine other tools' answers for one area. */
|
||||
|
||||
import { suggestView } from '../views.js';
|
||||
import { feedProvenanceEnvelope } from '../../data/layerSnapshot.js';
|
||||
import {
|
||||
feedProvenanceEnvelope,
|
||||
hudSummaryMatchesProvenance,
|
||||
provenanceTag,
|
||||
} from '../../data/layerSnapshot.js';
|
||||
import { defineTool, ToolError } from '../catalog.js';
|
||||
import {
|
||||
AREA_SCHEMA,
|
||||
@@ -232,6 +236,7 @@ export const getHudCaption = defineTool({
|
||||
feedState: sectionFeedState(brief[key]),
|
||||
}),
|
||||
);
|
||||
const feedProvenance = feedProvenanceEnvelope(layers);
|
||||
const response = await context.services.summary.summarize(
|
||||
{
|
||||
placeLabels: [area.label],
|
||||
@@ -244,16 +249,29 @@ export const getHudCaption = defineTool({
|
||||
name,
|
||||
feedState,
|
||||
})),
|
||||
feedProvenance: feedProvenanceEnvelope(layers),
|
||||
feedProvenance,
|
||||
},
|
||||
{ signal: context.signal },
|
||||
);
|
||||
const caption = response?.data?.summary;
|
||||
if (!response?.ok || typeof caption !== 'string' || !caption)
|
||||
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.
|
||||
const tag = provenanceTag(feedProvenance);
|
||||
const text = hudSummaryMatchesProvenance(response.data, feedProvenance)
|
||||
? words
|
||||
: area.label;
|
||||
const caption = tag
|
||||
? `${text} | ${[tag.state, ...tag.names].join(' ').toUpperCase()}`
|
||||
: text;
|
||||
return {
|
||||
summary: caption,
|
||||
data: { area: area.label, caption },
|
||||
data: {
|
||||
area: area.label,
|
||||
caption,
|
||||
feedState: feedProvenance.overall,
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
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.
|
||||
async function staleCaption(reply) {
|
||||
const conditions = {
|
||||
observedAt: '2026-10-01T19:15:00.000Z',
|
||||
temperatureC: 26.3,
|
||||
apparentTemperatureC: 32,
|
||||
precipitationMm: 0,
|
||||
cloudCoverPct: 100,
|
||||
windKph: 5.4,
|
||||
windDirectionDeg: 318,
|
||||
visibilityM: 15400,
|
||||
weatherCode: 3,
|
||||
};
|
||||
const places = {
|
||||
resolve: async (name) =>
|
||||
name === 'Austin'
|
||||
? {
|
||||
name: 'Austin, Texas',
|
||||
bounds: { west: -97.94, south: 30.1, east: -97.56, north: 30.52 },
|
||||
}
|
||||
: null,
|
||||
};
|
||||
const staleWeather = {
|
||||
getConditions: async () => ({ status: 'stale', weather: conditions }),
|
||||
};
|
||||
let sent = null;
|
||||
const summary = {
|
||||
async summarize(context) {
|
||||
sent = context;
|
||||
return { ok: true, status: 200, data: { error: null, ...reply } };
|
||||
},
|
||||
};
|
||||
const catalog = composeCatalog({
|
||||
tools: coreTools,
|
||||
services: { weather: staleWeather, summary, places },
|
||||
});
|
||||
const result = await catalog.call('get_hud_caption', {
|
||||
area: { place: 'Austin' },
|
||||
});
|
||||
assert.equal(sent.feedProvenance.overall, 'stale');
|
||||
return result.data;
|
||||
}
|
||||
|
||||
test('get_hud_caption keeps the canonical feed state of a stale view', async () => {
|
||||
const data = await staleCaption({
|
||||
summary: 'Austin weather across the area',
|
||||
feedState: 'stale',
|
||||
});
|
||||
assert.equal(data.feedState, 'stale');
|
||||
assert.equal(data.caption, 'Austin weather across the area | STALE WEATHER');
|
||||
});
|
||||
|
||||
test('get_hud_caption drops words whose feed state is not the app one', async () => {
|
||||
const data = await staleCaption({
|
||||
summary: 'Austin live weather looks fine',
|
||||
feedState: 'nominal',
|
||||
});
|
||||
assert.equal(data.feedState, 'stale');
|
||||
assert.equal(data.caption, 'Austin, Texas | STALE WEATHER');
|
||||
});
|
||||
Reference in new issue
Block a user