feat(tools): count and summarize every match in the area tools

aircraft_in_area and vessels_in_area return at most 200 rows, so a client
asked which operators dominate an area, or the average altitude there, could
only estimate from a truncated sample. Both tools now take an optional
group_by (aircraft: operator, origin_country, type_code; ships: type,
destination) and stats (airborne altitude and speed for aircraft, speed for
ships). Each is computed over every match before rows are capped. Breakdowns
list the ten largest groups plus other and unknown counts, and the summary
names the three largest.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
quanticsoul4772andClaude Opus 5.5 committed 2026-10-10 20:32:45 -07:00
1 parent 591f299d11
commit 2110d06e36
10 files changed
+299 -5

No files matched your search

+36 -1
View File
@@ -11,9 +11,12 @@ import {
} from '../area.js';
import {
LIMIT_SCHEMA,
breakdown,
breakdownPhrase,
capRows,
countNoun,
isoTime,
numericSummary,
thinEvenly,
} from '../results.js';
@@ -32,6 +35,11 @@ const MILITARY_SCHEMA = Object.freeze({
description: 'Use the military aircraft feed instead of the general feed.',
});
const MAX_TRACK_POINTS = 200;
const GROUP_LABELS = Object.freeze({
operator: 'operator',
origin_country: 'country',
type_code: 'type',
});
const round = (value, digits) =>
Number.isFinite(value) ? Number(value.toFixed(digits)) : null;
@@ -82,7 +90,10 @@ export const aircraftInArea = defineTool({
title: 'Aircraft in an area',
description:
'Aircraft currently reported inside an area, nearest the center first. ' +
'Optionally military aircraft only, airborne only, or within an altitude band.',
'Optionally military aircraft only, airborne only, or within an altitude band. ' +
'group_by counts every matched aircraft by operator, country or type, and ' +
'stats summarizes airborne altitude and speed; both cover all matches, not ' +
'just the rows returned.',
inputSchema: {
type: 'object',
properties: {
@@ -91,6 +102,16 @@ export const aircraftInArea = defineTool({
airborne_only: { type: 'boolean' },
min_altitude_m: { type: 'number', minimum: -500, maximum: 30000 },
max_altitude_m: { type: 'number', minimum: -500, maximum: 30000 },
group_by: {
type: 'string',
enum: Object.keys(GROUP_LABELS),
description: 'Count matched aircraft by this field, largest first.',
},
stats: {
type: 'boolean',
description:
'Summarize airborne altitude and speed over matched aircraft.',
},
limit: LIMIT_SCHEMA,
},
required: ['area'],
@@ -126,9 +147,11 @@ export const aircraftInArea = defineTool({
...(regional ? [`regional feed: ${snapshot.coverage}`] : []),
...(snapshot.freshness === 'stale' ? ['data may be stale'] : []),
];
const groups = args.group_by ? breakdown(rows, args.group_by) : null;
return {
summary:
`${rows.length} ${kind} in ${area.label}` +
(groups ? breakdownPhrase(groups, GROUP_LABELS[args.group_by]) : '') +
(notes.length ? ` (${notes.join('; ')}).` : '.'),
data: {
view: suggestView(services, {
@@ -136,6 +159,18 @@ export const aircraftInArea = defineTool({
layers: [args.military ? 'military' : 'flights'],
}),
...capRows(rows, args.limit),
...(groups ? { breakdown: groups } : {}),
...(args.stats
? {
stats: {
altitude_m: numericSummary(
rows.filter((row) => !row.on_ground),
'altitude_m',
),
speed_mps: numericSummary(rows, 'speed_mps'),
},
}
: {}),
...snapshotInfo(snapshot),
},
};