fix(tools): say when a breakdown's field is missing from the feed

OpenSky, the default civil feed, reports no operator or type code, so a
breakdown by either put every aircraft under unknown while the summary said
nothing. The summary now says "no operator reported" in that case, and
otherwise appends the unknown count after the largest groups.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
quanticsoul4772andClaude Opus 5.5 committed 2026-10-10 20:35:42 -07:00
1 parent 2110d06e36
commit 603f428397
6 files changed
+29 -9

No files matched your search

+3 -2
View File
@@ -96,8 +96,9 @@ shared `area` argument (place name, bounding box, or point and radius) and cap
lists at 25 rows by default. `aircraft_in_area` and `vessels_in_area` can also
count every match by a field (`group_by`: operator, country or type for
aircraft; type or destination for ships; the ten largest groups, then other and
unknown counts) and summarize airborne altitude and speed (`stats`: count, min,
median, mean, max). Both cover all matches, not just the rows returned. Voice offers the same queries next to its app
unknown counts; the summary says when a feed reports none of the field) and
summarize airborne altitude and speed (`stats`: count, min, median, mean, max).
Both cover all matches, not just the rows returned. Voice offers the same queries next to its app
actions: the session lists them, and the browser runs them through the same
catalog, loaded on first use. See [tools and the MCP server](TOOLS.md).
+3 -1
View File
@@ -105,7 +105,9 @@ export const aircraftInArea = defineTool({
group_by: {
type: 'string',
enum: Object.keys(GROUP_LABELS),
description: 'Count matched aircraft by this field, largest first.',
description:
'Count matched aircraft by this field, largest first. Feeds that do not ' +
'report the field count those aircraft as unknown.',
},
stats: {
type: 'boolean',
+1 -1
View File
@@ -409,7 +409,7 @@ test('aircraft in an area can be counted by operator over every match', async ()
});
assert.equal(
result.summary,
'4 aircraft in 60 km around 37.600, -122.300; most by operator: United (2), Delta (1).',
'4 aircraft in 60 km around 37.600, -122.300; most by operator: United (2), Delta (1); 1 unknown.',
);
assert.equal(result.data.returned, 1);
assert.deepEqual(result.data.breakdown, {
+1 -1
View File
@@ -237,7 +237,7 @@ test('vessels in an area can be counted by destination with a speed summary', as
});
assert.equal(
result.summary,
'2 vessels in 20 km around 37.780, -122.400; most by destination: OAKLAND (1).',
'2 vessels in 20 km around 37.780, -122.400; most by destination: OAKLAND (1); 1 unknown.',
);
assert.deepEqual(result.data.breakdown, {
field: 'destination',
+10 -3
View File
@@ -78,13 +78,20 @@ export function numericSummary(rows, field) {
};
}
/** "; most by operator: Delta (12), United (9), American (7)" or "". */
/**
* "; most by operator: Delta (12), United (9), American (7); 4 unknown", or
* "; no operator reported" when no row carries the field.
*/
export function breakdownPhrase(result, label) {
if (!result.groups.length) return '';
if (!result.groups.length)
return result.unknown_count ? `; no ${label} reported` : '';
const top = result.groups
.slice(0, 3)
.map((group) => `${group.value} (${group.count})`);
return `; most by ${label}: ${top.join(', ')}`;
const unknown = result.unknown_count
? `; ${result.unknown_count} unknown`
: '';
return `; most by ${label}: ${top.join(', ')}${unknown}`;
}
function sum(values) {
+11 -1
View File
@@ -63,6 +63,7 @@ test('a numeric summary skips missing values', () => {
test('the breakdown phrase names the three largest groups', () => {
const result = {
unknown_count: 0,
groups: [
{ value: 'A', count: 4 },
{ value: 'B', count: 3 },
@@ -74,5 +75,14 @@ test('the breakdown phrase names the three largest groups', () => {
breakdownPhrase(result, 'type'),
'; most by type: A (4), B (3), C (2)',
);
assert.equal(breakdownPhrase({ groups: [] }, 'type'), '');
assert.equal(
breakdownPhrase({ ...result, unknown_count: 5 }, 'type'),
'; most by type: A (4), B (3), C (2); 5 unknown',
);
// A feed that never reports the field says so instead of staying silent.
assert.equal(
breakdownPhrase({ groups: [], unknown_count: 236 }, 'operator'),
'; no operator reported',
);
assert.equal(breakdownPhrase({ groups: [], unknown_count: 0 }, 'type'), '');
});