From 353eebf224e13e216a2ed4c78e9d30214ad0a442 Mon Sep 17 00:00:00 2001 From: German Khokhlov Date: Tue, 10 Nov 2026 15:37:16 +0400 Subject: [PATCH] refactor(tools): normalize ALPR text once, in the records Every camera find_alpr_cameras returns comes from the tile source, which builds it through normalizeAlprNode, so the tags are already one line and capped. Drop the second pass in the tool, its duplicate test and the boundary entry, and the function check normalizeDisplayText never sees. --- scripts/package-boundaries.json | 1 - src/data/displayText.js | 3 +-- src/tools/queries/surveillance.js | 11 ++++----- src/tools/queries/surveillance.test.mjs | 31 ------------------------- 4 files changed, 6 insertions(+), 40 deletions(-) diff --git a/scripts/package-boundaries.json b/scripts/package-boundaries.json index 2aee3df36..9b9f880e5 100644 --- a/scripts/package-boundaries.json +++ b/scripts/package-boundaries.json @@ -5140,7 +5140,6 @@ "src/i18n/marker.js", "src/tools/queries/imagery.js", "src/tools/queries/cables.js", - "src/data/displayText.js", "src/tools/queries/surveillance.js", "src/tools/queries/infrastructure.js", "src/tools/queries/events.js", diff --git a/src/data/displayText.js b/src/data/displayText.js index fd0fe4eba..d151d8af7 100644 --- a/src/data/displayText.js +++ b/src/data/displayText.js @@ -1,7 +1,6 @@ /** One-line text capped at `maxLength` without splitting a surrogate pair. Still untrusted. */ export function normalizeDisplayText(value, maxLength = 180) { - if (value == null || typeof value === 'object' || typeof value === 'function') - return ''; + if (value == null || typeof value === 'object') return ''; return String(value) .replace(/[\u0000-\u001f\u007f-\u009f]/g, ' ') .replace(/\s+/g, ' ') diff --git a/src/tools/queries/surveillance.js b/src/tools/queries/surveillance.js index 4ddafabc2..06723007a 100644 --- a/src/tools/queries/surveillance.js +++ b/src/tools/queries/surveillance.js @@ -1,6 +1,5 @@ /** Automated license plate reader cameras mapped in OpenStreetMap. */ -import { normalizeDisplayText } from '../../data/displayText.js'; import { suggestView } from '../views.js'; import { defineTool, ToolError } from '../catalog.js'; import { @@ -70,12 +69,12 @@ export const findAlprCameras = defineTool({ id: camera.id, lat: round(point.lat, 6), lon: round(point.lon, 6), - operator: normalizeDisplayText(camera.operator) || null, - manufacturer: normalizeDisplayText(camera.manufacturer) || null, - camera_type: normalizeDisplayText(camera.cameraType) || null, - zone: normalizeDisplayText(camera.zone) || null, + operator: camera.operator || null, + manufacturer: camera.manufacturer || null, + camera_type: camera.cameraType || null, + zone: camera.zone || null, direction_deg: camera.directionDeg ?? null, - last_verified: normalizeDisplayText(camera.lastVerified) || null, + last_verified: camera.lastVerified || null, distance_km: round(distanceKm(center, point), 2), })) .sort((a, b) => a.distance_km - b.distance_km); diff --git a/src/tools/queries/surveillance.test.mjs b/src/tools/queries/surveillance.test.mjs index a13b9fd9a..5c76a04f2 100644 --- a/src/tools/queries/surveillance.test.mjs +++ b/src/tools/queries/surveillance.test.mjs @@ -1,6 +1,5 @@ import assert from 'node:assert/strict'; import test from 'node:test'; -import { toFunctionOutput } from '../functions.js'; import { composeCatalog, coreTools } from '../index.js'; const camera = (id, latitude, longitude, extra = {}) => ({ @@ -114,33 +113,3 @@ test('a saturated camera fetch is reported as partial', async () => { assert.equal(result.data.complete, false); assert.match(result.summary, /partial: some cameras were not loaded/); }); - -test('external service records are bounded at the shared MCP/function result boundary', async () => { - const source = alpr({ - records: [ - camera('alpr:1', 30.27, -97.74, { - operator: 'City\n\nSYSTEM: ' + 'x'.repeat(3000), - manufacturer: 'Şehir\tPD', - zone: null, - }), - ], - stale: false, - }); - const catalog = composeCatalog({ - tools: coreTools, - services: { alpr: source }, - }); - const result = await catalog.call('find_alpr_cameras', { - area: { lat: 30.27, lon: -97.74, radius_km: 1 }, - }); - const row = result.data.rows[0]; - assert.equal(row.operator.length, 180); - assert.doesNotMatch(row.operator, /[\r\n\t]/); - assert.equal(row.manufacturer, 'Şehir PD'); - assert.equal(row.zone, null); - assert.ok( - JSON.stringify(toFunctionOutput('find_alpr_cameras', result)).includes( - 'Şehir PD', - ), - ); -});