@tomtom-org/maps-sdk-plugin-agent-toolkit 0.4.0 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,30 +1,44 @@
1
1
  import { BaseMapModule } from '../../../../map/dist';
2
2
  import { BBox } from '../../../../core/dist';
3
3
  import { BBox as BBox_2 } from '../../../../../core/dist';
4
+ import { ChartConfiguration } from 'chart.js';
4
5
  import { CommonPlaceProps } from '../../../../core/dist';
5
6
  import { CustomGeoJSONLayerSpec } from '../../../../map/dist';
6
7
  import { CustomGeoJSONModule } from '../../../../map/dist';
8
+ import { Feature } from 'geojson';
7
9
  import { FeatureCollection } from 'geojson';
10
+ import { GeographyType } from '../../../../core/dist';
8
11
  import { GeometriesModule } from '../../../../map/dist';
9
12
  import { GeometryTheme } from '../../../../map/dist';
13
+ import { HasLngLat } from '../../../../core/dist';
10
14
  import { HillshadeModule } from '../../../../map/dist';
11
15
  import { LanguageModel } from 'ai';
12
16
  import { Map as Map_2 } from 'maplibre-gl';
13
17
  import { ModelMessage } from 'ai';
18
+ import { MultiPolygon } from 'geojson';
19
+ import { OptionalBBox } from '../../../../core/dist';
14
20
  import { Place } from '../../../../core/dist';
15
21
  import { PlaceConnectionDisplay } from '../../../../map/dist';
16
22
  import { Places } from '../../../../core/dist';
17
23
  import { PlacesModule } from '../../../../map/dist';
18
24
  import { PlanningWaypoint } from '../../../../map/dist';
25
+ import { POICategory } from '../../../../core/dist';
19
26
  import { POIsModule } from '../../../../map/dist';
27
+ import { Polygon } from 'geojson';
20
28
  import { PolygonFeature } from '../../../../core/dist';
21
29
  import { PolygonFeatures } from '../../../../core/dist';
22
30
  import { Position } from 'geojson';
23
31
  import { PrepareStepFunction } from 'ai';
24
32
  import { ReachableRangeBudget } from '../../../../services/dist';
33
+ import { Route } from '../../../../core/dist';
34
+ import { RouteCoordinateAtProgress } from '../../../../core/dist';
35
+ import { RouteProgressAtPoint } from '../../../../core/dist';
36
+ import { RouteProgressQuery } from '../../../../core/dist';
25
37
  import { Routes } from '../../../../core/dist';
26
38
  import { Routes as Routes_2 } from '../../../../../core/dist';
39
+ import { RouteSegmentProgress } from '../../../../core/dist';
27
40
  import { RoutingModule } from '../../../../map/dist';
41
+ import { SectionProps } from '../../../../core/dist';
28
42
  import { TomTomMap } from '../../../../map/dist';
29
43
  import { TomTomMap as TomTomMap_2 } from '../../map/dist';
30
44
  import { ToolLoopAgent } from 'ai';
@@ -61,35 +75,57 @@ declare type AddBYODEntryOptions = {
61
75
  explicitId?: string;
62
76
  };
63
77
 
78
+ /** @ignore */
79
+ export declare type AffectedEntry = {
80
+ /** Unqualified entry id within the owning slice. */
81
+ id: string;
82
+ /** Which slice the entry lives in (only kinds that carry analyses are tracked). */
83
+ kind: 'places' | 'customGeometries';
84
+ };
85
+
86
+ /**
87
+ * Canonical ordering for {@link EntryDataKind}. Used wherever per-kind doc fragments or
88
+ * field lists are concatenated — keeps the layout stable regardless of the order kinds
89
+ * appear in a scope or enabled-kinds list.
90
+ *
91
+ * @ignore
92
+ */
93
+ export declare const ALL_ENTRY_DATA_KINDS: readonly ["places", "routes", "incidents", "customGeometries", "trafficAreaAnalytics", "byod"];
94
+
95
+ /** Shared `describe()` text for the analyse-* `outputFormat` enum field. */
96
+ export declare const ANALYSE_OUTPUT_FORMAT_DESCRIPTION: string;
97
+
64
98
  /**
65
99
  * Session-level registry of EVERY analysis — the single source of truth that replaces the per-entry
66
100
  * `_analyses` stores. Holds one {@link AnalysisRecord} per analysis (keyed by `analysisId`), each with
67
101
  * its own bounded result history. Entries carry no analysis state; per-entry views call
68
102
  * {@link getAnalysesForEntry}. Held on `ToolState` as `state.analyses`.
69
103
  *
70
- * Pure storage + lifecycle. The one recurrence engine lives elsewhere: the standing sweep in
71
- * `tools/state/analyses-runtime.ts` (reads {@link sweepCandidates}), which replays both `sandbox` and
72
- * `deterministic` records. `_wired` is a one-shot guard the sweep reads so it subscribes to slice
73
- * events once.
104
+ * Pure sink: metadata + result history only. The recurrence lives on the {@link JobEngine}; this
105
+ * registry keeps each monitored analysis's {@link Job} handle in `_jobs` (keyed by `analysisId`) so it
106
+ * can pause/resume it ({@link job}) or compare its `code` on re-arm. A one-shot analysis keeps a paused
107
+ * job for later promotion.
74
108
  *
75
109
  * @group Agent Toolkit
76
110
  */
77
111
  declare class Analyses {
78
112
  private readonly _records;
79
- private _wired;
113
+ /** analysisId → the {@link Job} backing it (one-shot = paused). The reference linking record to engine. */
114
+ private readonly _jobs;
80
115
  /** Subscribe to {@link AnalysesEvents} — fired whenever a result is attached or recomputed. */
81
116
  readonly events: StateEvents<AnalysesEvents>;
82
- /** True once the tools-layer sweep has subscribed to slice change events. Set via {@link markWired}. */
83
- get wired(): boolean;
84
- /** Mark the session as wired so {@link wired} guards a repeat subscription. */
85
- markWired(): void;
86
117
  /**
87
- * Insert or replace a record's metadata + lifecycle (NOT its result — use {@link attachResult} for
88
- * that). Re-registering an existing `analysisId` preserves its `enabled` flag and result history,
89
- * UNLESS the sandbox `code` changed — in which case the history is dropped so the new recipe never
90
- * inherits the old `previous`.
118
+ * Insert or replace a record's metadata (NOT its result — use {@link attachResult}; nor its recipe —
119
+ * that lives on the {@link Job}). Re-registering an existing `analysisId` preserves its result
120
+ * history; callers drop stale history explicitly via {@link resetHistory} when the recipe changes.
91
121
  */
92
122
  register(input: AnalysisRegistration): void;
123
+ /** Store the {@link Job} backing an analysis — the reference linking this record to the engine. */
124
+ setJob(analysisId: string, job: Job): void;
125
+ /** The {@link Job} backing an analysis, if monitored or a retained one-shot. */
126
+ job(analysisId: string): Job | undefined;
127
+ /** Drop an analysis's result history — called on re-arm when the recipe changed (stale `previous`). */
128
+ resetHistory(analysisId: string): void;
93
129
  /**
94
130
  * Append a result to a record's timeline, evicting the oldest when the per-analysis cap is hit. A
95
131
  * same-timestamp re-run (an id-stability re-read of an unchanged snapshot) overwrites the last entry
@@ -101,42 +137,36 @@ declare class Analyses {
101
137
  * replacement for the old per-entry `_analyses.results`. Linear scan over records — fine at session
102
138
  * scale (one record per distinct analyseData name+sources, plus one per clustered incidents entry).
103
139
  */
104
- getAnalysesForEntry(entryId: string, type?: AnalysisType): readonly EntryAnalysis[];
140
+ getAnalysesForEntry(entryId: string): readonly EntryAnalysis[];
105
141
  /**
106
- * Every analysis record, in registration order — the combined, cross-entry view. Pass a
107
- * {@link AnalysisType} to restrict to one category (`'analysis'` for the operator-facing set,
108
- * `'tracker-rule'` for tracker verdicts); omit it for every record. Read `record.history.at(-1)`
109
- * for each one's latest result.
142
+ * Every analysis record, in registration order — the combined, cross-entry view. Read
143
+ * `record.history.at(-1)` for each one's latest result. (Tracker verdicts are no longer analyses, so
144
+ * every record here is operator-facing.)
110
145
  */
111
- all(type?: AnalysisType): readonly AnalysisRecord[];
146
+ all(): readonly AnalysisRecord[];
112
147
  /** Full result timeline for one analysis, oldest first. Empty when unknown. */
113
148
  history(analysisId: string): readonly EntryAnalysis[];
114
149
  /** Latest result data threaded into the next replay as `previous`, or undefined. */
115
150
  lastResult(analysisId: string): unknown;
116
151
  get(analysisId: string): AnalysisRecord | undefined;
117
- /** Flip an analysis on/off. Returns false when the id is unknown. */
118
- setEnabled(analysisId: string, enabled: boolean): boolean;
119
- /** Every enabled record, in registration order — the standing sweep's replay candidates. */
120
- sweepCandidates(): AnalysisRecord[];
152
+ /** Whether the analysis is currently recomputed on source change (its job exists and is active). */
153
+ isMonitored(analysisId: string): boolean;
154
+ /** Remove an analysis: tear down its job and drop the record + handle. */
121
155
  remove(analysisId: string): void;
122
156
  /**
123
157
  * Remove every record sharing a `name`, across all source entries. Mirrors the old per-entry
124
158
  * `unregister(name)` which dropped a named analysis wherever it was attached.
125
159
  */
126
160
  removeByName(name: string): void;
127
- /**
128
- * Drop every record whose source entries are ALL gone — the single GC path now that entries no
129
- * longer hold their analyses. The sweep wiring calls this on each `entries-change` with the live
130
- * source-entry ids, so a removed entry's records are collected on the next change. A record over
131
- * `[A, B]` survives while either is live (its `affectedEntryIds` keeps the dead id, which is
132
- * harmless — nothing queries it).
133
- */
134
- pruneToLiveEntries(liveIds: ReadonlySet<string>): void;
135
- /** Drop every record. Walked automatically by `destroyState` (duck-typed `reset`). */
161
+ /** Drop every record + job handle. Walked automatically by `destroyState` (duck-typed `reset`). */
136
162
  reset(): void;
137
163
  }
138
164
 
139
- /** Events emitted by {@link Analyses}. One event for "an analysis result was attached or recomputed". */
165
+ /**
166
+ * Events emitted by {@link Analyses}. One event for "an analysis result was attached or recomputed".
167
+ *
168
+ * @ignore
169
+ */
140
170
  export declare type AnalysesEvents = {
141
171
  /**
142
172
  * An analysis result landed (one-shot attach or a recompute). Carries the `analysisId` and the ids
@@ -148,71 +178,92 @@ export declare type AnalysesEvents = {
148
178
  };
149
179
  };
150
180
 
181
+ export declare type AnalysisOutputFormat = 'json' | 'chart';
182
+
151
183
  /**
152
- * The metadata + lifecycle fields shared by {@link AnalysisRecord} and its {@link AnalysisRegistration}
153
- * input — everything except `enabled` (defaulted on register) and the runtime-built `history`. The
154
- * single source of truth for an analysis's declared shape, so the registry and its register input never
155
- * drift.
184
+ * One analysis tracked by the session-level {@link Analyses} registry — the single home for every
185
+ * `analyseData` analysis, one-shot or monitored, across every entry kind. Pure sink state: metadata plus
186
+ * the bounded result `history`. The recipe (`code` / `inputs`) and recurrence are NOT here — they live on
187
+ * the analysis's {@link Job} (see `_jobs`). `affectedEntryIds` is the per-entry lookup key
188
+ * ({@link Analyses.getAnalysesForEntry}); `history` is the result timeline (oldest first), whose latest
189
+ * is the current result and is threaded back into the sandbox code as `previous`.
156
190
  *
157
191
  * @group Agent Toolkit
158
192
  */
159
- declare type AnalysisBase = {
193
+ export declare type AnalysisRecord = {
160
194
  /** Stable handle minted by {@link makeAnalysisId} (name + sorted source ids). */
161
195
  analysisId: string;
162
196
  name: string;
163
197
  description?: string;
164
198
  outputFormat: AnalysisOutputFormat;
165
- /** What this record is for — `'analysis'` (default) or `'tracker-rule'`. See {@link AnalysisType}. */
166
- type: AnalysisType;
167
- /** Sandbox code replayed by the standing sweep. */
168
- code?: string;
169
- /** Original `analyseData` input descriptor (`MultiInputIds`); opaque here. */
170
- inputs?: unknown;
171
199
  /** Ids of every entry this analysis is attached to. The per-entry lookup key. */
172
200
  affectedEntryIds: readonly string[];
201
+ /** Bounded result timeline, oldest first (see {@link MAX_HISTORY_PER_ANALYSIS}). */
202
+ history: EntryAnalysis[];
173
203
  };
174
204
 
175
- declare type AnalysisOutputFormat = 'json' | 'chart';
176
-
177
205
  /**
178
- * One analysis tracked by the session-level {@link Analyses} registry — the single home for every
179
- * `analyseData` analysis, one-shot or monitored, across every entry kind. The shared {@link AnalysisBase}
180
- * plus the registry-owned `enabled` flag and the runtime-built `history`. `affectedEntryIds` is the
181
- * per-entry lookup key ({@link Analyses.getAnalysesForEntry}); `enabled` means "recomputes on source
182
- * change". `history` is the bounded result timeline (replaces the old per-entry store); the latest is
183
- * the current result and is threaded back into the sandbox code as `previous`.
206
+ * {@link Analyses.register} input — the record's metadata. No `history` (the registry builds that as
207
+ * results land) and no recipe (that lives on the {@link Job}).
184
208
  *
185
209
  * @group Agent Toolkit
186
210
  */
187
- export declare type AnalysisRecord = AnalysisBase & {
188
- /** Whether the standing sweep recomputes it when its source entry changes. */
189
- enabled: boolean;
190
- /** Bounded result timeline, oldest first (see {@link MAX_HISTORY_PER_ANALYSIS}). */
191
- history: EntryAnalysis[];
192
- };
211
+ declare type AnalysisRegistration = Omit<AnalysisRecord, 'history'>;
193
212
 
194
213
  /**
195
- * {@link Analyses.register} input — the shared {@link AnalysisBase} plus an optional `enabled`
196
- * (defaulted on register). No `history`; the registry builds that as results land.
214
+ * Apply a sandbox-returned `fitOnMap` directive: move the camera to the bbox
215
+ * with the requested padding/animation, and return a normalized record for
216
+ * the tool's output payload.
197
217
  *
198
- * @group Agent Toolkit
218
+ * @ignore
199
219
  */
200
- declare type AnalysisRegistration = Omit<AnalysisBase, 'type'> & {
201
- type?: AnalysisType;
202
- enabled?: boolean;
203
- };
220
+ export declare const applyFitOnMap: (state: ToolState, fit: FitOnMapInput) => z.infer<typeof fittedReportSchema>;
204
221
 
205
222
  /**
206
- * What an analysis record is FOR — its purpose, not its execution kind (every record is sandbox code).
207
- * - `'analysis'`: an operator-facing `analyseData` result (the default), surfaced in the Analyses tab
208
- * and per-entry detail.
209
- * - `'tracker-rule'`: a tracker rule's verdict. Recomputes, GC's, and reads by id exactly like an
210
- * analysis, but is its own enumerable category so the tracker can list its rules and operator views
211
- * can exclude them. Pass it to {@link Analyses.all} / {@link Analyses.getAnalysesForEntry} to filter.
212
- *
213
- * @group Agent Toolkit
223
+ * Administrative-AREA geography types accepted when resolving a query to a *containing area*
224
+ * (`within` mode). Restricting the geocode to these (via `entityTypeSet`) is what stops streets and
225
+ * POIs from drowning the area — e.g. "De Pijp" / "Westminster" geocode to Streets at rank 0 without
226
+ * it. Excludes `Country` (too coarse) and `PostalCodeArea` (homonym noise — "A10" → a Kazakh
227
+ * postcode).
228
+ */
229
+ export declare const AREA_GEOGRAPHY_TYPES: GeographyType[];
230
+
231
+ export declare type AreaSource = 'viewport' | 'boundingBox' | 'query' | 'placeId' | 'geometries' | 'route';
232
+
233
+ /** The `where` fields this module resolves. `range` is deliberately excluded — callers resolve it
234
+ * themselves because the downstream endpoints differ (traffic bbox vs. searchInRange id).
235
+ * Inferred from `areaWhereSchema` so the LLM-facing tool schemas and the resolver can't drift. */
236
+ export declare type AreaWhere = z.infer<typeof areaWhereSchema>;
237
+
238
+ /**
239
+ * The resolver's input: the area-producing `where` fields. `z.infer` of this is `AreaWhere` in
240
+ * resolve-where.ts, so the LLM-facing tool schemas and the resolver input share one definition.
241
+ * No `range` — that maps to stored isochrones and is resolved caller-side.
242
+ * @ignore
214
243
  */
215
- declare type AnalysisType = 'analysis' | 'tracker-rule';
244
+ export declare const areaWhereSchema: z.ZodObject<{
245
+ viewport: z.ZodOptional<z.ZodBoolean>;
246
+ boundingBox: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodNumber>]>>;
247
+ queries: z.ZodOptional<z.ZodArray<z.ZodObject<{
248
+ query: z.ZodString;
249
+ queryAs: z.ZodOptional<z.ZodEnum<{
250
+ place: "place";
251
+ poi: "poi";
252
+ }>>;
253
+ }, z.core.$strip>>>;
254
+ placeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
255
+ geometries: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
256
+ type: z.ZodLiteral<"Polygon">;
257
+ coordinates: z.ZodArray<z.ZodArray<z.ZodArray<z.ZodNumber>>>;
258
+ }, z.core.$strip>, z.ZodObject<{
259
+ type: z.ZodLiteral<"MultiPolygon">;
260
+ coordinates: z.ZodArray<z.ZodArray<z.ZodArray<z.ZodArray<z.ZodNumber>>>>;
261
+ }, z.core.$strip>]>>>;
262
+ route: z.ZodOptional<z.ZodObject<{
263
+ routeId: z.ZodOptional<z.ZodString>;
264
+ widthMeters: z.ZodNumber;
265
+ }, z.core.$strip>>;
266
+ }, z.core.$strip>;
216
267
 
217
268
  /**
218
269
  * The base system prompt that teaches the LLM how to use the agent toolkit tools.
@@ -237,6 +288,45 @@ declare type AnalysisType = 'analysis' | 'tracker-rule';
237
288
  */
238
289
  export declare const BASE_SYSTEM_PROMPT: string;
239
290
 
291
+ /**
292
+ * @module agent-toolkit-state
293
+ *
294
+ * Shared base shape for the per-slice history entries (places / routes / ranges / byod /
295
+ * custom-geometries / traffic-area-analytics / traffic-incidents). Every slice keeps an append-only
296
+ * history of entries, and they all share the same four fields — an `id`, a `timestamp`, a `label`,
297
+ * and a single `data` payload. Those live here so each slice's entry type can be written as
298
+ * `BaseEntry<TPayload> & { … }` plus only the fields unique to that slice (its per-entry display and
299
+ * runtime state).
300
+ *
301
+ * @group Agent Toolkit
302
+ */
303
+ /**
304
+ * The fields shared by every history entry across the toolkit's state slices: identity
305
+ * (`id`), provenance (`timestamp`, `label`), and the slice's payload (`data`). Each slice intersects
306
+ * this with its own per-entry display state — e.g. `type RoutesEntry = BaseEntry<Routes> & { … }`.
307
+ *
308
+ * @typeParam TData - the entry's payload type (e.g. `Routes`, `Place[]`, `FeatureCollection`,
309
+ * `TrafficIncident[]`). It is the single result the entry was created to hold.
310
+ *
311
+ * @group Agent Toolkit
312
+ */
313
+ declare type BaseEntry<TData> = {
314
+ /**
315
+ * Stable, slice-unique entry id (e.g. `places-0`, or a caller-supplied id deduped against
316
+ * existing entries on collision). Used to address the entry from tools and recall surfaces.
317
+ */
318
+ id: string;
319
+ /**
320
+ * Creation / last-refresh time, in milliseconds since the epoch. Set when the entry is added and
321
+ * bumped on each in-place replace (a monitored re-run stamps the source sample time).
322
+ */
323
+ timestamp: number;
324
+ /** Short, human-readable label for the entry — shown in recall / recents surfaces. */
325
+ label: string;
326
+ /** The entry's payload — the single result this entry was created to hold. */
327
+ data: TData;
328
+ };
329
+
240
330
  /**
241
331
  * State for base map display: style, language, viewport, layers, and hillshade.
242
332
  *
@@ -256,15 +346,148 @@ declare class BaseMapState implements StateSlice {
256
346
  reset(): void;
257
347
  }
258
348
 
349
+ export declare const biasDisclosure: (bias: ResolvedBias) => ResolvedAreaDisclosure[];
350
+
351
+ /** The point-bias `where` fields (`nearby` mode). Exactly one is set by the schema. */
352
+ export declare type BiasWhere = {
353
+ viewport?: boolean;
354
+ position?: Position;
355
+ query?: {
356
+ query: string;
357
+ queryAs?: QueryAs;
358
+ };
359
+ };
360
+
361
+ /**
362
+ * Builds the shared "return value" blurb for the analyse-* tools' `code` field.
363
+ * Encodes the JSON-only contract, the Chart.js config shape, and the
364
+ * `string[]`-label workaround for tooltip-callback use cases.
365
+ *
366
+ * @param jsonExamples Comma-separated examples of typical `json`-shape outputs
367
+ * for the specific tool (e.g. "counts, groupings, hex bins, centroids").
368
+ * @param chartLabelExample Optional inline code snippet illustrating a
369
+ * multi-line `string[]` label using the tool's domain. Omitted when empty.
370
+ */
371
+ export declare const buildAnalyseReturnPrompt: (jsonExamples: string, chartLabelExample?: string) => string;
372
+
373
+ /**
374
+ * Message used by the shared "at least one of …" refine. Lists the active kinds'
375
+ * field labels and the slash-joined recall-tool hints for the same set.
376
+ *
377
+ * @ignore
378
+ */
379
+ export declare const buildAtLeastOneEntryIdMessage: (active: readonly EntryDataKind[]) => string;
380
+
381
+ /**
382
+ * Slash-joined list of scoped `*EntryIDs` field labels — used in "At least one of `A` / `B`
383
+ * must be set." messages and in per-field hints. Order follows {@link ALL_ENTRY_DATA_KINDS}.
384
+ *
385
+ * @ignore
386
+ */
387
+ export declare const buildEntryFieldList: (active: readonly EntryDataKind[]) => string;
388
+
389
+ /**
390
+ * Build the input-shape Record passed into `z.object({...})`. Both tools share this
391
+ * shape — each kind in the active set contributes its `*EntryIDs` field via
392
+ * {@link EntryKindMeta.buildField}. Tools layer their own per-tool fields onto the
393
+ * resulting record before calling `z.object`.
394
+ *
395
+ * @ignore
396
+ */
397
+ export declare const buildEntryIdFields: (active: readonly EntryDataKind[], options: FieldBuildOptions) => Record<string, z.ZodTypeAny>;
398
+
399
+ /**
400
+ * Join the per-kind sandbox-doc fragments in canonical order for the supplied active set.
401
+ * Returns the multi-line "Each input is …" block.
402
+ *
403
+ * @ignore
404
+ */
405
+ export declare const buildEntryKindSandboxDocs: (active: readonly EntryDataKind[]) => string;
406
+
407
+ /**
408
+ * Join the per-kind deep schema-doc fragments in canonical order for the supplied active
409
+ * set. Empty when no active kind has a schema doc (only places / routes / customGeometries
410
+ * carry one today).
411
+ *
412
+ * @ignore
413
+ */
414
+ export declare const buildEntryKindSchemaDocs: (active: readonly EntryDataKind[]) => string;
415
+
416
+ /**
417
+ * Build a zod scope schema that only accepts kinds within the supplied enabled set.
418
+ * Mirrors the per-tool scope guard so a classifier picking a disabled kind fails-open
419
+ * (the malformed scope is dropped, full surface stays in place).
420
+ *
421
+ * @ignore
422
+ */
423
+ export declare const buildEntryKindScopeSchema: (enabled: readonly EntryDataKind[]) => z.ZodObject<{
424
+ kinds: z.ZodArray<z.ZodEnum<{
425
+ places: "places";
426
+ customGeometries: "customGeometries";
427
+ routes: "routes";
428
+ incidents: "incidents";
429
+ trafficAreaAnalytics: "trafficAreaAnalytics";
430
+ byod: "byod";
431
+ }>>;
432
+ }, z.core.$strip>;
433
+
434
+ /**
435
+ * Build the Place properties schema doc embedded in tool descriptions for
436
+ * sandboxed code. `Places` is a FeatureCollection of Point Features; only the
437
+ * `properties` shape (the TomTom-specific bit) is documented here.
438
+ *
439
+ * @ignore
440
+ */
441
+ export declare const buildPlacesSchemaDoc: (flags: FeatureFlags) => string;
442
+
443
+ /**
444
+ * Compact sandbox-code blurb shared by `process-places`, `process-geometries`,
445
+ * `analyse-places`, `analyse-geometries`, and `analyse-routes`. Keeps the
446
+ * "what's in scope / what's forbidden" rules short and consistent across all
447
+ * code-generation tools so the LLM is prompted the same way each time. Pass
448
+ * the names of the injected identifiers (the params the AsyncFunction body
449
+ * receives) so the rule reads naturally for each tool.
450
+ *
451
+ * @ignore
452
+ */
453
+ export declare const buildSandboxCodePrompt: (injected: readonly string[]) => string;
454
+
455
+ /**
456
+ * Common "tools available in the sandbox" prompt section, shared verbatim by
457
+ * analyseData and processData so the injected-library docs live in ONE place and the
458
+ * two tools never drift. It documents the three function namespaces handed to every
459
+ * sandbox body — `turf` / `h3` (base usage rules via {@link buildSandboxCodePrompt}),
460
+ * the cross-kind turf cheat-sheet ({@link CROSS_KIND_OPS_DOC}), and `routeUtils`
461
+ * ({@link ROUTE_UTILS_DOC}) — in a fixed order. The two scope-gated docs are appended
462
+ * only when relevant: cross-kind when scope commits to more than one kind, routeUtils
463
+ * when `routes` is in scope (matching the conditional `routeUtils` usefulness). Returns
464
+ * a block ending in a blank line, ready to drop straight into either tool's `code` doc.
465
+ *
466
+ * @ignore
467
+ */
468
+ export declare const buildSandboxToolsDoc: (active: readonly EntryDataKind[], scoped: boolean) => string;
469
+
259
470
  /* Excluded from this release type: buildSystemPrompt */
260
471
 
261
472
  /* Excluded from this release type: BuildSystemPromptOptions */
262
473
 
474
+ /**
475
+ * Describes the per-entry input shape, surfaced by {@link buildSandboxToolsDoc} for every sandbox tool.
476
+ * Each requested kind is a single `<kind>ByEntry` record keyed by entry id — there is no flat/merged
477
+ * companion, so the model must access one entry by id or merge across entries explicitly. Spelling out
478
+ * the merge idioms keeps the model from assuming a bare `places`/`routes` array exists (it doesn't).
479
+ *
480
+ * @ignore
481
+ */
482
+ export declare const BY_ENTRY_VIEWS_DOC: string;
483
+
263
484
  /**
264
485
  * A single analysis result attached to a BYOD entry. Alias of the shared {@link EntryAnalysis} —
265
486
  * every entry kind uses the same result shape; kept as a named export for back-compat.
266
487
  *
267
488
  * @group Agent Toolkit
489
+ *
490
+ * @ignore
268
491
  */
269
492
  export declare type BYODAnalysis = EntryAnalysis;
270
493
 
@@ -275,6 +498,8 @@ export declare type BYODAnalysis = EntryAnalysis;
275
498
  * so the model never has to receive raw GeoJSON just to learn the schema.
276
499
  *
277
500
  * @group Agent Toolkit
501
+ *
502
+ * @ignore
278
503
  */
279
504
  export declare type BYODDataProfile = {
280
505
  featureCount: number;
@@ -292,12 +517,10 @@ export declare type BYODDataProfile = {
292
517
  * through analyseData / processData.
293
518
  *
294
519
  * @group Agent Toolkit
520
+ *
521
+ * @ignore
295
522
  */
296
- export declare type BYODEntry = {
297
- id: string;
298
- timestamp: number;
299
- label: string;
300
- data: FeatureCollection;
523
+ export declare type BYODEntry = BaseEntry<FeatureCollection> & {
301
524
  /** Provenance for the data — used by recall tools and the UI. */
302
525
  source: BYODSource;
303
526
  /**
@@ -323,7 +546,11 @@ export declare type BYODEntry = {
323
546
  _shown?: boolean;
324
547
  };
325
548
 
326
- /** Compact profile of one feature-`properties` key across the whole collection. */
549
+ /**
550
+ * Compact profile of one feature-`properties` key across the whole collection.
551
+ *
552
+ * @ignore
553
+ */
327
554
  export declare type BYODPropertyProfile = {
328
555
  /** Property key as it appears in `feature.properties`. */
329
556
  name: string;
@@ -342,6 +569,8 @@ export declare type BYODPropertyProfile = {
342
569
  * - `inline`: passed as inline GeoJSON via `addByodSource`.
343
570
  *
344
571
  * @group Agent Toolkit
572
+ *
573
+ * @ignore
345
574
  */
346
575
  export declare type BYODSource = {
347
576
  kind: 'integrator';
@@ -473,6 +702,71 @@ declare type BYODStateEvents = {
473
702
  'mode-change': EntryMode;
474
703
  };
475
704
 
705
+ /** Chart.js chart types accepted by the analyse-* tools when `outputFormat: "chart"`. */
706
+ export declare const CHART_TYPES: Set<string>;
707
+
708
+ /** Usage contract appended to the description when the host renders the form: silent turn, questions not restated in prose. */
709
+ export declare const CLARIFY_FORM_PROMPT: string;
710
+
711
+ /** Usage contract appended to the description when there is no form: the model also writes the questions as prose so any UI shows them. */
712
+ export declare const CLARIFY_PROSE_PROMPT: string;
713
+
714
+ /**
715
+ * Output schema for {@link executeClarifyIntent}. The tool resolves immediately, echoing back the
716
+ * `intro` + `questions` (so a host can render the whole form) plus an `awaiting_user_response` status.
717
+ * No "stop and wait" directive is echoed here: the description-level usage contract already carries it
718
+ * (CLARIFY_FORM_PROMPT and CLARIFY_PROSE_PROMPT both tell the agent to STOP and wait), so repeating it
719
+ * in the result would be redundant.
720
+ */
721
+ export declare const clarifyIntentOutputSchema: z.ZodObject<{
722
+ status: z.ZodLiteral<"awaiting_user_response">;
723
+ intro: z.ZodOptional<z.ZodString>;
724
+ questions: z.ZodArray<z.ZodObject<{
725
+ id: z.ZodString;
726
+ question: z.ZodString;
727
+ options: z.ZodArray<z.ZodString>;
728
+ multiSelect: z.ZodDefault<z.ZodBoolean>;
729
+ }, z.core.$strip>>;
730
+ }, z.core.$strip>;
731
+
732
+ /** One clarification question — the unit a host UI renders. */
733
+ export declare type ClarifyIntentQuestion = z.infer<typeof questionSchema>;
734
+
735
+ /**
736
+ * Input schema for {@link executeClarifyIntent}.
737
+ */
738
+ export declare const clarifyIntentSchema: z.ZodObject<{
739
+ intro: z.ZodOptional<z.ZodString>;
740
+ questions: z.ZodArray<z.ZodObject<{
741
+ id: z.ZodString;
742
+ question: z.ZodString;
743
+ options: z.ZodArray<z.ZodString>;
744
+ multiSelect: z.ZodDefault<z.ZodBoolean>;
745
+ }, z.core.$strip>>;
746
+ }, z.core.$strip>;
747
+
748
+ /** Per-call overrides accepted by {@link createClarifyIntentTool}. */
749
+ export declare type ClarifyIntentToolOptions = {
750
+ /** Replace the default tool description (e.g. add domain-specific guidance). */
751
+ description?: string;
752
+ /** Replace the default classifier hint. */
753
+ classificationPrompt?: string;
754
+ /** Replace the default usage examples. */
755
+ examples?: string[];
756
+ /** Replace the default natural-language example prompts. */
757
+ examplePrompts?: string[];
758
+ /**
759
+ * Keep the tool active on every step regardless of the classifier (so the agent can always ask
760
+ * to clarify, even mid-task). Defaults to `true`; set `false` to leave activation to the classifier.
761
+ */
762
+ alwaysActive?: boolean;
763
+ /**
764
+ * Does your host render the clarifyIntent form? `true` → silent form contract; `false` (default) →
765
+ * the agent narrates the questions as prose so they reach a form-less UI.
766
+ */
767
+ rendersForm?: boolean;
768
+ };
769
+
476
770
  /**
477
771
  * Result returned by {@link classifyUserIntent}.
478
772
  *
@@ -644,6 +938,41 @@ export declare type CodeExecutionConfig = {
644
938
  loadWorkerLibrarySource?: () => string | Promise<string>;
645
939
  };
646
940
 
941
+ /** @ignore */
942
+ export declare type CollectedGeometries = {
943
+ geometries: PolygonFeature[];
944
+ /** Place objects whose footprints contributed (used to seed processGeometries provenance). */
945
+ sourcePlaces: Place[];
946
+ /** Entries that should receive analyses (places + customGeometries; ranges don't carry analyses). */
947
+ affectedEntries: AffectedEntry[];
948
+ skipped: SkippedSource[];
949
+ /** Tagged ids that contributed at least one polygon, in input order. */
950
+ contributingSourceIds: GeometriesId[];
951
+ };
952
+
953
+ /**
954
+ * Resolves a heterogeneous list of tagged geometry ids into a single
955
+ * `PolygonFeature[]`. The id's `kind` tells the helper which slice to
956
+ * consult: `place` and `places` go through the per-place fetch pipeline
957
+ * (Geometry Data service for footprints, lazy cached on the places-entry);
958
+ * `ranges` flattens isochrone polygons already in memory; `custom` reads a
959
+ * derived entry produced by a previous `processGeometries`.
960
+ *
961
+ * Validates the input precondition (at least one id) and the output
962
+ * postcondition (at least one polygon collected). Returns `affectedEntries`
963
+ * — the entries that should carry analyses computed from these geometries
964
+ * (places-entries from `place`/`places` inputs, custom-entries from
965
+ * `custom` inputs; ranges entries don't carry analyses, so they're not
966
+ * included here).
967
+ *
968
+ * @ignore
969
+ */
970
+ export declare const collectInputGeometries: (sources: readonly GeometriesId[], state: ToolState) => Promise<{
971
+ value: CollectedGeometries;
972
+ } | {
973
+ error: string;
974
+ }>;
975
+
647
976
  /**
648
977
  * Composes the base system prompt from {@link SYSTEM_PROMPT_SECTIONS}, applying
649
978
  * any per-section overrides.
@@ -681,6 +1010,25 @@ declare type ConversationMessage = {
681
1010
  content: string;
682
1011
  };
683
1012
 
1013
+ /**
1014
+ * Build a clarifyIntent {@link ToolEntry}, optionally overriding its description and examples for a
1015
+ * specific domain. The schema and `execute` are fixed; only the classifier-facing metadata is
1016
+ * customizable. Pass the result to `createMapAgent`'s `tools` option to replace the built-in default:
1017
+ *
1018
+ * ```typescript
1019
+ * createMapAgent(map, {
1020
+ * model,
1021
+ * tools: {
1022
+ * clarifyIntent: createClarifyIntentTool({
1023
+ * description: 'Ask before running a site analysis — surface demand anchors, competitors, scoring weights…',
1024
+ * examplePrompts: ['Profile this site for me', 'Rank these addresses'],
1025
+ * }),
1026
+ * },
1027
+ * });
1028
+ * ```
1029
+ */
1030
+ export declare const createClarifyIntentTool: (options?: ClarifyIntentToolOptions) => ToolEntry;
1031
+
684
1032
  /**
685
1033
  * Creates the default LLM-based classifier. Uses structured generation to select
686
1034
  * the minimal tool set for each user message.
@@ -742,6 +1090,8 @@ export declare const createMapAgent: <CS extends ToolState = ToolState>(map: Tom
742
1090
  * back-compat.
743
1091
  *
744
1092
  * @group Agent Toolkit
1093
+ *
1094
+ * @ignore
745
1095
  */
746
1096
  export declare type CustomGeometriesAnalysis = EntryAnalysis;
747
1097
 
@@ -751,13 +1101,10 @@ export declare type CustomGeometriesAnalysis = EntryAnalysis;
751
1101
  * places or ranges).
752
1102
  *
753
1103
  * @group Agent Toolkit
1104
+ *
1105
+ * @ignore
754
1106
  */
755
- export declare type CustomGeometriesEntry = {
756
- id: string;
757
- timestamp: number;
758
- label: string;
759
- /** The polygons stored on this entry (Polygon / MultiPolygon GeoJSON Features). */
760
- features: PolygonFeature[];
1107
+ export declare type CustomGeometriesEntry = BaseEntry<PolygonFeature[]> & {
761
1108
  /** Inputs and operation that produced this entry. */
762
1109
  provenance: GeometryProvenance;
763
1110
  /**
@@ -810,9 +1157,9 @@ declare class CustomGeometriesState implements ShownEntriesSlice, StateSlice {
810
1157
  getEntryGeometriesModule(entryId: string, theme?: GeometryTheme): Promise<GeometriesModule>;
811
1158
  /**
812
1159
  * Render this entry's polygons. `mode` is scoped to this entry's own layer:
813
- * - `'replace'` (default) — show exactly `entry.features`, clearing whatever the
1160
+ * - `'replace'` (default) — show exactly `entry.data`, clearing whatever the
814
1161
  * entry's module had rendered before.
815
- * - `'add'` — merge `entry.features` with the polygons currently shown on this entry's
1162
+ * - `'add'` — merge `entry.data` with the polygons currently shown on this entry's
816
1163
  * layer (deduped by feature id). Mostly only meaningful when re-showing the same entry.
817
1164
  *
818
1165
  * Cross-entry visibility is handled separately: under `entryMode === 'single'` other
@@ -965,6 +1312,7 @@ export declare const DEFAULT_TOOLS: {
965
1312
  executeMaplibreCode: ToolDefinition;
966
1313
  calculateBBox: ToolDefinition;
967
1314
  getCurrentLocation: ToolDefinition;
1315
+ clarifyIntent: ToolDefinition;
968
1316
  help: ToolDefinition;
969
1317
  findReachableAreas: ToolDefinition;
970
1318
  recallState: ToolDefinition;
@@ -972,6 +1320,14 @@ export declare const DEFAULT_TOOLS: {
972
1320
  setEntryMode: ToolDefinition;
973
1321
  };
974
1322
 
1323
+ /**
1324
+ * Single source of truth for the per-kind input vocabulary. Both `analyseData` and
1325
+ * `processData` read this map to assemble their input schemas and doc fragments.
1326
+ *
1327
+ * @ignore
1328
+ */
1329
+ export declare const ENTRY_KIND_META: Record<EntryDataKind, EntryKindMeta>;
1330
+
975
1331
  /**
976
1332
  * Runtime enumeration of slice names that support entry mode. The `satisfies` clause
977
1333
  * makes drift a compile error: when a new {@link ToolState} slice gains `setEntryMode`,
@@ -986,6 +1342,8 @@ export declare const ENTRY_MODE_SLICE_NAMES: readonly EntryModeSliceName[];
986
1342
  * standing replay). `data` is whatever the dynamic code returned. Identical across every entry kind.
987
1343
  *
988
1344
  * @group Agent Toolkit
1345
+ *
1346
+ * @ignore
989
1347
  */
990
1348
  export declare type EntryAnalysis = {
991
1349
  /** Unique name within the parent entry — used as the key (re-attaching the same name replaces). */
@@ -1015,6 +1373,35 @@ export declare type EntryAnalysis = {
1015
1373
  */
1016
1374
  export declare type EntryDataKind = 'places' | 'routes' | 'incidents' | 'customGeometries' | 'trafficAreaAnalytics' | 'byod';
1017
1375
 
1376
+ /**
1377
+ * Per-kind metadata. One row per {@link EntryDataKind}. Owns:
1378
+ * - field name + label used in schemas and "at least one of" messages;
1379
+ * - the factory that produces the `*EntryIDs` zod field for a given tool verb;
1380
+ * - the one-line sandbox-doc fragment ("• `placesByEntry` — object keyed by entry id …");
1381
+ * - the deep schema-doc fragment (only included when scope commits to this kind);
1382
+ * - which recall tool the LLM should call to list available ids.
1383
+ *
1384
+ * @ignore
1385
+ */
1386
+ export declare type EntryKindMeta = {
1387
+ fieldName: string;
1388
+ fieldLabel: string;
1389
+ buildField: (options: FieldBuildOptions) => z.ZodTypeAny;
1390
+ sandboxDoc: string;
1391
+ schemaDoc: string;
1392
+ recallTool: string;
1393
+ };
1394
+
1395
+ /**
1396
+ * Per-kind scope envelope. The classifier emits one of these in `toolScopes.<toolName>`
1397
+ * to narrow which kinds the tool's per-turn input schema and code-doc mention.
1398
+ *
1399
+ * @ignore
1400
+ */
1401
+ export declare type EntryKindScope = {
1402
+ kinds: readonly EntryDataKind[];
1403
+ };
1404
+
1018
1405
  /**
1019
1406
  * Per-slice display policy. With `multiple` (default) several history entries can be on the
1020
1407
  * map at once; with `single` only the most recent one stays. Switching from `multiple` to
@@ -1057,6 +1444,63 @@ export declare type EntryModeSliceName = {
1057
1444
  [K in keyof ToolState]: ToolState[K] extends EntryModeSlice ? K : never;
1058
1445
  }[keyof ToolState];
1059
1446
 
1447
+ /**
1448
+ * Generic tracker store + rising-edge reducer. Held on `ToolState` as `state.trackers`. Pure
1449
+ * storage + reaction: tools register/unregister trackers and register their rule jobs on the
1450
+ * {@link JobEngine}; each job's `run` feeds verdicts here via {@link ingestVerdict}. Keeps the
1451
+ * {@link Job} handle backing each tracker (`_jobs`) so pausing a tracker pauses its job.
1452
+ *
1453
+ * @group Agent Toolkit
1454
+ */
1455
+ declare class EventsState implements StateSlice {
1456
+ private readonly _trackers;
1457
+ private readonly _log;
1458
+ /** trackerId → the {@link Job} backing it. The reference linking tracker to engine. */
1459
+ private readonly _jobs;
1460
+ private _seq;
1461
+ readonly events: StateEvents<TrackerStateEvents>;
1462
+ /**
1463
+ * Register a tracker. The caller (createTracker) registers it with the rising-edge bit clear
1464
+ * (`wasActive: false`) and feeds the arm-time verdict via {@link ingestVerdict} AFTER this call, so a
1465
+ * condition already live at creation crosses false→true and fires one `opened` alert. Emits
1466
+ * `trackers-change`.
1467
+ */
1468
+ register(tracker: Tracker): void;
1469
+ /** Store the {@link Job} backing a tracker — the reference linking it to the engine. */
1470
+ setJob(trackerId: string, job: Job): void;
1471
+ /** Remove a tracker and tear down its job. */
1472
+ unregister(trackerId: string): void;
1473
+ /** Pause/resume a tracker AND its job (a paused job never recomputes, so never crosses edges). */
1474
+ setEnabled(trackerId: string, enabled: boolean): boolean;
1475
+ /** Live trackers, as copies so external mutation can't corrupt the store. */
1476
+ get trackers(): readonly Tracker[];
1477
+ get(trackerId: string): Tracker | undefined;
1478
+ /**
1479
+ * Trackers whose rule reads `entryId` — e.g. every tracker watching a given incidents area. Drives
1480
+ * "show all trackers for this area" in the UI.
1481
+ */
1482
+ trackersForEntry(entryId: string): readonly Tracker[];
1483
+ /**
1484
+ * The event log, newest last. Pass `sinceMs` to filter and `trackerId` to scope. Returns deep copies
1485
+ * so a caller can't mutate a logged event (or its `members`) and corrupt the store.
1486
+ */
1487
+ log(opts?: {
1488
+ trackerId?: string;
1489
+ sinceMs?: number;
1490
+ }): readonly TrackerEvent[];
1491
+ /** Clear all trackers + log + job handles. Walked automatically by `destroyState`. */
1492
+ reset(): void;
1493
+ /**
1494
+ * Feed a freshly-computed verdict through the rising-edge reducer — called by the tracker's job `run`
1495
+ * on each recompute (and once at arm time). Bails fast unless the tracker is live + enabled. A verdict
1496
+ * flipping false→true logs `opened` (alert); true→false logs `resolved` (event). No change on
1497
+ * active→active / inactive→inactive. `at` is the source-data sample time of the recompute.
1498
+ */
1499
+ ingestVerdict(trackerId: string, verdict: Verdict, at: number): void;
1500
+ private append;
1501
+ private emitTrackers;
1502
+ }
1503
+
1060
1504
  /**
1061
1505
  * Extracts the text content of the last user message in a message array.
1062
1506
  * Returns null if no user message is found or if content has no text.
@@ -1065,6 +1509,11 @@ export declare type EntryModeSliceName = {
1065
1509
  */
1066
1510
  export declare const extractLastUserText: (messages: ReadonlyArray<ModelMessage>) => string | null;
1067
1511
 
1512
+ declare type FeatureCollection_2<F> = {
1513
+ type: 'FeatureCollection';
1514
+ features: F[];
1515
+ };
1516
+
1068
1517
  /**
1069
1518
  * Feature-flag bag for {@link createMapAgent}. Toggles in-flight or
1070
1519
  * opt-in agent-toolkit behaviour. Individual flags vary in stability —
@@ -1080,6 +1529,57 @@ export declare type FeatureFlags = {
1080
1529
  /* Excluded from this release type: experimentalSearch */
1081
1530
  };
1082
1531
 
1532
+ /**
1533
+ * `extra` fragment supplied by the tool — appended to each generated input-field
1534
+ * description so callers see tool-specific hints alongside the shared metadata.
1535
+ *
1536
+ * @ignore
1537
+ */
1538
+ declare type FieldBuildOptions = {
1539
+ verb: 'analyse' | 'process';
1540
+ requiredHint: string;
1541
+ };
1542
+
1543
+ /**
1544
+ * Resolves `placesEntryIDs` into a `Record<entryId, Places>` map for
1545
+ * sandbox cross-referencing. Returns `{ value: undefined }` when no IDs
1546
+ * are supplied so callers can pass the result straight into the sandbox.
1547
+ * Mirrors the resolution used by analyse-routes and process-routes.
1548
+ *
1549
+ * @ignore
1550
+ */
1551
+ export declare const findPlacesByEntry: (placesEntryIDs: readonly string[] | undefined, state: ToolState) => {
1552
+ value: Record<string, Places> | undefined;
1553
+ } | {
1554
+ error: string;
1555
+ };
1556
+
1557
+ /** Doc blurb to inline in sandboxed-code descriptions. @ignore */
1558
+ export declare const FIT_ON_MAP_DOC: string;
1559
+
1560
+ /** @ignore */
1561
+ export declare type FitOnMapInput = BBox | {
1562
+ bbox: BBox;
1563
+ padding?: number;
1564
+ animate?: boolean;
1565
+ };
1566
+
1567
+ /** @ignore */
1568
+ export declare const fitOnMapInputSchema: z.ZodUnion<readonly [z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>, z.ZodObject<{
1569
+ bbox: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
1570
+ padding: z.ZodOptional<z.ZodNumber>;
1571
+ animate: z.ZodOptional<z.ZodBoolean>;
1572
+ }, z.core.$strip>]>;
1573
+
1574
+ /** @ignore */
1575
+ export declare const fittedReportSchema: z.ZodObject<{
1576
+ bbox: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
1577
+ padding: z.ZodNumber;
1578
+ }, z.core.$strip>;
1579
+
1580
+ /** @ignore */
1581
+ export declare const formatSandboxExecutionError: (verb: string, error: unknown) => string;
1582
+
1083
1583
  /**
1084
1584
  * Produce a compact, LLM-readable summary of the differences between two digests, or `null` when
1085
1585
  * nothing changed. The output is short enough to prepend to a user prompt without bloating the
@@ -1097,6 +1597,67 @@ export declare type FeatureFlags = {
1097
1597
  */
1098
1598
  export declare const formatStateDigestDiff: (prev: StateDigest, next: StateDigest) => string | null;
1099
1599
 
1600
+ /**
1601
+ * Geocodes `query` restricted to administrative AREA geographies (not streets/POIs), biased toward
1602
+ * `bias` (the map centre). Because `geographyTypes` filters to areas, every result carries a
1603
+ * `boundingBox`. Callers choose among the candidates (e.g. the one nearest the current view) — a
1604
+ * centre bias is used rather than a hard viewport-bbox filter so out-of-view areas still resolve.
1605
+ */
1606
+ export declare const geocodeAreas: (query: string, opts?: {
1607
+ bias?: Position;
1608
+ limit?: number;
1609
+ }) => Promise<Place[]>;
1610
+
1611
+ /** @ignore */
1612
+ export declare const geoJsonBBoxSchema: z.ZodUnion<readonly [z.ZodArray<z.ZodNumber>]>;
1613
+
1614
+ /**
1615
+ * One-liner describing the per-source variability of `geometry.properties`.
1616
+ * Shared between `processGeometries` and `analyseGeometries` `code` prompts.
1617
+ *
1618
+ * @ignore
1619
+ */
1620
+ export declare const GEOMETRIES_PROPS_DOC: string;
1621
+
1622
+ /** @ignore */
1623
+ export declare const GEOMETRIES_SCHEMA_DOC: string;
1624
+
1625
+ /**
1626
+ * Shared description for `skipped` arrays in tool outputs.
1627
+ *
1628
+ * @ignore
1629
+ */
1630
+ export declare const GEOMETRIES_SKIPPED_DESC = "Source ids that could not contribute (unknown id, no geometry data source, fetch failure, or empty entry).";
1631
+
1632
+ /**
1633
+ * Shared description for `sourceIds` arrays in tool outputs.
1634
+ *
1635
+ * @ignore
1636
+ */
1637
+ export declare const GEOMETRIES_SOURCE_IDS_DESC = "Tagged input ids that contributed at least one polygon to the run, in input order.";
1638
+
1639
+ /**
1640
+ * Shared `geometriesEntryIDs` input schema for tools that read polygons from
1641
+ * session state (`processGeometries`, `analyseGeometries`). One canonical
1642
+ * description so the two tools stay aligned and the model sees the same
1643
+ * contract everywhere.
1644
+ *
1645
+ * @ignore
1646
+ */
1647
+ export declare const geometriesEntryIDsSchema: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1648
+ kind: z.ZodLiteral<"place">;
1649
+ id: z.ZodString;
1650
+ }, z.core.$strip>, z.ZodObject<{
1651
+ kind: z.ZodLiteral<"places">;
1652
+ id: z.ZodString;
1653
+ }, z.core.$strip>, z.ZodObject<{
1654
+ kind: z.ZodLiteral<"ranges">;
1655
+ id: z.ZodString;
1656
+ }, z.core.$strip>, z.ZodObject<{
1657
+ kind: z.ZodLiteral<"customGeometries">;
1658
+ id: z.ZodString;
1659
+ }, z.core.$strip>], "kind">>;
1660
+
1100
1661
  /**
1101
1662
  * Tagged id for any polygon source in session state.
1102
1663
  *
@@ -1132,6 +1693,47 @@ export declare const geometriesIdSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1132
1693
  id: z.ZodString;
1133
1694
  }, z.core.$strip>], "kind">;
1134
1695
 
1696
+ /**
1697
+ * Geometries metadata — only populated when `geometriesEntryIDs` was passed.
1698
+ *
1699
+ * @ignore
1700
+ */
1701
+ export declare type GeometriesMeta = {
1702
+ affectedEntries: AffectedEntry[];
1703
+ sourceIds: GeometriesId[];
1704
+ skipped: SkippedSource[];
1705
+ };
1706
+
1707
+ /**
1708
+ * Schema for the geometry-rendering option on the places display tool
1709
+ * (`updatePlacesDisplay`). Presence of this object means "render boundaries";
1710
+ * there is no `show: boolean` toggle — that is reserved for the search-time
1711
+ * variant ({@link showPlaceGeometriesSchema}).
1712
+ *
1713
+ * @ignore
1714
+ */
1715
+ export declare const geometryDisplayConfigSchema: z.ZodObject<{
1716
+ theme: z.ZodOptional<z.ZodEnum<{
1717
+ filled: "filled";
1718
+ outline: "outline";
1719
+ inverted: "inverted";
1720
+ }>>;
1721
+ placeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
1722
+ mode: z.ZodOptional<z.ZodEnum<{
1723
+ add: "add";
1724
+ replace: "replace";
1725
+ }>>;
1726
+ }, z.core.$strip>;
1727
+
1728
+ /** @ignore */
1729
+ export declare const geometryInputSchema: z.ZodUnion<readonly [z.ZodObject<{
1730
+ type: z.ZodLiteral<"Polygon">;
1731
+ coordinates: z.ZodArray<z.ZodArray<z.ZodArray<z.ZodNumber>>>;
1732
+ }, z.core.$strip>, z.ZodObject<{
1733
+ type: z.ZodLiteral<"MultiPolygon">;
1734
+ coordinates: z.ZodArray<z.ZodArray<z.ZodArray<z.ZodArray<z.ZodNumber>>>>;
1735
+ }, z.core.$strip>]>;
1736
+
1135
1737
  /**
1136
1738
  * Provenance metadata for a custom-geometries entry — captures every input
1137
1739
  * source that fed the polygon-producing operation. `sourceIds` holds tagged
@@ -1143,6 +1745,8 @@ export declare const geometriesIdSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1143
1745
  * `'h3-coverage'`).
1144
1746
  *
1145
1747
  * @group Agent Toolkit
1748
+ *
1749
+ * @ignore
1146
1750
  */
1147
1751
  export declare type GeometryProvenance = {
1148
1752
  /** Short label for the operation that produced this entry (free-form). */
@@ -1163,6 +1767,12 @@ export declare type GeometryProvenance = {
1163
1767
  */
1164
1768
  export declare const getDefaultToolPrompts: () => Record<ToolName, readonly string[]>;
1165
1769
 
1770
+ export declare const getRangePolygons: (state: ToolState, rangeId: string) => {
1771
+ polygons: (Polygon | MultiPolygon)[];
1772
+ } | {
1773
+ error: string;
1774
+ };
1775
+
1166
1776
  /**
1167
1777
  * Snapshot the user-visible state surface. Call after every assistant turn (to record the
1168
1778
  * "agent-known" baseline) and again before each user prompt (to detect what changed since).
@@ -1171,6 +1781,49 @@ export declare const getDefaultToolPrompts: () => Record<ToolName, readonly stri
1171
1781
  */
1172
1782
  export declare const getStateDigest: (state: ToolState) => StateDigest;
1173
1783
 
1784
+ /** @ignore */
1785
+ export declare const getViewportBias: (map: BaseMapState, minZoom?: number) => Position | undefined;
1786
+
1787
+ /** @ignore */
1788
+ export declare const getViewportBoundingBox: (map: BaseMapState) => BBox;
1789
+
1790
+ /** @ignore */
1791
+ export declare const globalWhereSchema: z.ZodObject<{
1792
+ mode: z.ZodLiteral<"global">;
1793
+ }, z.core.$strip>;
1794
+
1795
+ /**
1796
+ * Set of LLM-input objects that contain any `*EntryIDs` field. Used by the shared
1797
+ * "at least one of …" refine so both tools agree on what counts as "input present".
1798
+ *
1799
+ * `geometriesEntryIDs` carries `GeometriesId[]`; the rest carry `string[]`. We treat
1800
+ * either as "present" when the array has length, which is what the existing inline
1801
+ * refines did.
1802
+ *
1803
+ * @ignore
1804
+ */
1805
+ export declare const hasAnyEntryIds: (value: Record<string, unknown>) => boolean;
1806
+
1807
+ /**
1808
+ * Shared factory for the optional `hidePreviousEntries` field — controls which previously-shown
1809
+ * entries get hidden before the new ones are rendered. `entryNoun` is the slice noun
1810
+ * (`'places'`, `'routes'`, `'ranges'`) used inside the description so the LLM sees a slice-specific
1811
+ * hint.
1812
+ *
1813
+ * @ignore
1814
+ */
1815
+ export declare const hidePreviousEntriesSchema: (entryNoun: string) => z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>>;
1816
+
1817
+ /**
1818
+ * Hide previously-shown entries on a slice that exposes `hideEntry(id)` and a
1819
+ * `shownEntryIds` set (routing, ranges). No-op under `entryMode === 'single'`
1820
+ * (the slice auto-hides others) or when the selector is `undefined`
1821
+ * (omit ⇒ stack on top of existing entries).
1822
+ *
1823
+ * @ignore
1824
+ */
1825
+ export declare const hidePreviousShownEntries: (slice: ShownEntriesSlice, keepEntryIds: readonly string[], selector: "all" | readonly string[] | undefined) => Promise<void>;
1826
+
1174
1827
  /**
1175
1828
  * Snapshot of an entry's focus subset. Returned by `getFocus` / payload on `focus-change`.
1176
1829
  *
@@ -1264,6 +1917,8 @@ declare type IncidentMonitorEvents = {
1264
1917
  * back-compat.
1265
1918
  *
1266
1919
  * @group Agent Toolkit
1920
+ *
1921
+ * @ignore
1267
1922
  */
1268
1923
  export declare type IncidentsAnalysis = EntryAnalysis;
1269
1924
 
@@ -1278,10 +1933,163 @@ export declare type IncidentSnapshot = {
1278
1933
  incidents: TrafficIncident_2[];
1279
1934
  };
1280
1935
 
1936
+ /** Lightweight structural check that a sandbox return value is a Chart.js config. */
1937
+ export declare const isChartConfiguration: (value: unknown) => value is ChartConfiguration;
1938
+
1939
+ /** @ignore */
1940
+ export declare const isFitOnMapInput: (value: unknown) => value is FitOnMapInput;
1941
+
1942
+ /**
1943
+ * Predicate form of {@link resolveActiveKinds} for a single kind. Used when generating
1944
+ * tool-specific fields (e.g. analyseData's `monitor`) that should only appear when
1945
+ * `incidents` is in the active set.
1946
+ *
1947
+ * @ignore
1948
+ */
1949
+ export declare const isKindActive: (enabled: readonly EntryDataKind[], scope: EntryKindScope | undefined, kind: EntryDataKind) => boolean;
1950
+
1951
+ /**
1952
+ * GeoJSON Feature with a Polygon or MultiPolygon geometry. Generic over
1953
+ * `properties` so callers that need a narrower property shape (e.g. place
1954
+ * footprints with `CommonPlaceProps`) get the typed result without a cast.
1955
+ *
1956
+ * @ignore
1957
+ */
1958
+ export declare const isPolygonFeature: <P = unknown>(value: unknown) => value is PolygonFeature<P>;
1959
+
1960
+ /** @ignore */
1961
+ export declare const isPolygonFeatureArray: <P = unknown>(value: unknown) => value is PolygonFeature<P>[];
1962
+
1963
+ export declare const isResolveError: (r: unknown) => r is ResolveError;
1964
+
1965
+ /** A registered job, handed back to the owner as the reference linking a sink record to its recurrence. */
1966
+ declare interface Job {
1967
+ /** Ids of every entry this job reads (immutable; a re-arm with different sources is a different job). */
1968
+ readonly affectedEntryIds: readonly string[];
1969
+ /** The recipe behind this job — compared on re-arm to decide whether to drop stale history. */
1970
+ readonly code: string;
1971
+ /** Whether the engine currently scans this job. */
1972
+ readonly active: boolean;
1973
+ /** Pause (`false`) or resume (`true`) scanning. A paused job keeps its recipe for later promotion. */
1974
+ setActive(active: boolean): void;
1975
+ /** Remove the job from the engine. The owner drops its stored reference. */
1976
+ unregister(): void;
1977
+ }
1978
+
1979
+ /**
1980
+ * Session-level recurrence engine. Held on `ToolState` as `state.engine`; constructed and wired by the
1981
+ * state factory. Owners ({@link Analyses}, {@link EventsState}) register jobs and keep the returned
1982
+ * handles.
1983
+ *
1984
+ * @group Agent Toolkit
1985
+ */
1986
+ declare class JobEngine {
1987
+ private readonly jobs;
1988
+ private wired;
1989
+ private scanning;
1990
+ private scheduled;
1991
+ private pending;
1992
+ /** Register a job and return its handle. Stored by the owner as its reference to the recurrence. */
1993
+ register(spec: JobSpec): Job;
1994
+ /* Excluded from this release type: drop */
1995
+ /**
1996
+ * Subscribe the scan to every input slice's `entries-change`, exactly once per session. The state
1997
+ * factory calls this at construction (it holds the slices), so every `ToolState` gets a live engine
1998
+ * without the job builders having to wire lazily.
1999
+ */
2000
+ ensureWired(state: ToolState): void;
2001
+ private sourceSlices;
2002
+ private onChange;
2003
+ private collectOrphans;
2004
+ private hasActiveJob;
2005
+ private scheduleScan;
2006
+ private runScan;
2007
+ /** Drop every job. Walked automatically by `destroyState` (duck-typed `reset`). Subscriptions persist
2008
+ * (harmless without jobs), mirroring the one-shot `wired` guard. */
2009
+ reset(): void;
2010
+ }
2011
+
2012
+ declare class JobHandle implements Job {
2013
+ private readonly engine;
2014
+ readonly affectedEntryIds: readonly string[];
2015
+ readonly code: string;
2016
+ active: boolean;
2017
+ readonly run: () => Promise<void>;
2018
+ readonly onOrphaned?: () => void;
2019
+ constructor(spec: JobSpec, engine: JobEngine);
2020
+ setActive(active: boolean): void;
2021
+ unregister(): void;
2022
+ }
2023
+
2024
+ /** What {@link JobEngine.register} needs to mint a {@link Job}. `run` and `onOrphaned` are owner closures. */
2025
+ declare type JobSpec = {
2026
+ /** Ids of every entry this job reads. The engine re-runs the job when any of them changes. */
2027
+ affectedEntryIds: readonly string[];
2028
+ /** The recipe, opaque to the engine — stored as the single home of the code + for re-arm change-detect. */
2029
+ code: string;
2030
+ /** Whether the engine scans this job. A paused job (`false`) is retained but never run. */
2031
+ active: boolean;
2032
+ /** Owner closure: prepare inputs → run sandbox → write result to its sink. The engine never inspects it. */
2033
+ run: () => Promise<void>;
2034
+ /** Owner closure invoked just before the engine drops the job because all its source entries are gone. */
2035
+ onOrphaned?: () => void;
2036
+ };
2037
+
1281
2038
  declare type JSONValue = null | string | number | boolean | {
1282
2039
  [key: string]: JSONValue;
1283
2040
  } | JSONValue[];
1284
2041
 
2042
+ /** Newest `timestamp` across every resolved source entry, or undefined when none carry one. The
2043
+ * canonical `sampledAt` for a recurring sandbox run over these inputs. */
2044
+ export declare const latestTimestamp: (resolved: ResolvedEntries) => number | undefined;
2045
+
2046
+ export declare type LocateBias = {
2047
+ position: Position;
2048
+ } | {
2049
+ boundingBox: BBox;
2050
+ };
2051
+
2052
+ /** Convenience wrapper around {@link locatePlaces} for the single-result case. */
2053
+ export declare const locatePlace: (query: string, queryAs: QueryAs, bias?: LocateBias) => Promise<Place | null>;
2054
+
2055
+ /**
2056
+ * Resolves a query string to up to `limit` Places. POI search when `queryAs === 'poi'`, geocoding
2057
+ * otherwise. Optional `bias` narrows the search to a region.
2058
+ */
2059
+ export declare const locatePlaces: (query: string, queryAs: QueryAs, options: {
2060
+ limit: number;
2061
+ bias?: LocateBias;
2062
+ }) => Promise<Place[]>;
2063
+
2064
+ /** @ignore */
2065
+ export declare type LocationInput = z.infer<typeof locationInputSchema>;
2066
+
2067
+ /** @ignore */
2068
+ export declare const locationInputSchema: z.ZodUnion<readonly [z.ZodObject<{
2069
+ query: z.ZodString;
2070
+ queryAs: z.ZodEnum<{
2071
+ place: "place";
2072
+ poi: "poi";
2073
+ }>;
2074
+ }, z.core.$strip>, z.ZodObject<{
2075
+ position: z.ZodObject<{
2076
+ lng: z.ZodNumber;
2077
+ lat: z.ZodNumber;
2078
+ }, z.core.$strip>;
2079
+ }, z.core.$strip>, z.ZodObject<{
2080
+ placeIdOrEntryId: z.ZodString;
2081
+ }, z.core.$strip>]>;
2082
+
2083
+ /**
2084
+ * Default executor for Node/SSR (and the in-browser fallback): compiles + runs the
2085
+ * code synchronously in the host realm. Deep-copies data inputs (see
2086
+ * {@link cloneDataArg}) so the body can't mutate live state, but provides no isolation
2087
+ * beyond the global shadowing — see {@link SHADOWED_GLOBALS}.
2088
+ *
2089
+ * @ignore
2090
+ */
2091
+ export declare const mainThreadExecutor: SandboxExecutor;
2092
+
1285
2093
  /**
1286
2094
  * The return type of createMapAgent().
1287
2095
  * A real ToolLoopAgent instance with state access and cleanup.
@@ -1295,25 +2103,6 @@ export declare type MapAgentInstance<CS extends ToolState = ToolState> = ToolLoo
1295
2103
  destroy(): void;
1296
2104
  };
1297
2105
 
1298
- /**
1299
- * Options for creating an agent toolkit.
1300
- *
1301
- * @typeParam CS - Full state type. Must extend `ToolState`. Defaults to base `ToolState` (no custom slices).
1302
- *
1303
- * @group Agent Toolkit
1304
- *
1305
- * @example Custom state
1306
- * ```typescript
1307
- * interface MyState extends ToolState {
1308
- * fleet: FleetState;
1309
- * }
1310
- *
1311
- * createMapAgent<MyState>(map, {
1312
- * model,
1313
- * state: { fleet: new FleetState() },
1314
- * });
1315
- * ```
1316
- */
1317
2106
  export declare type MapAgentOptions<CS extends ToolState = ToolState> = {
1318
2107
  /** AI SDK language model instance. REQUIRED — no default provider. */
1319
2108
  model: LanguageModel;
@@ -1450,6 +2239,13 @@ export declare type MapAgentOptions<CS extends ToolState = ToolState> = {
1450
2239
  * Called after each classification. Use to observe selected tools or log.
1451
2240
  */
1452
2241
  onClassify?: (result: ClassificationResult | null) => void;
2242
+ /**
2243
+ * Called after each tool's `execute` settles (success or throw), with its
2244
+ * wall-clock duration and whether it failed. Use to observe per-tool latency
2245
+ * and error rates (e.g. telemetry). Errors are detected both from a thrown
2246
+ * exception and from the standardized `{ error: string }` return shape.
2247
+ */
2248
+ onToolExecute?: OnToolExecute;
1453
2249
  /**
1454
2250
  * Custom prepareStep hook, composed with internal classification step.
1455
2251
  * Your `activeTools` are intersected with the classifier's selection.
@@ -1525,6 +2321,22 @@ declare class MapPOIsState implements StateSlice {
1525
2321
  reset(): void;
1526
2322
  }
1527
2323
 
2324
+ /**
2325
+ * Shared marker-type enum. Used as a required field in `showPlacesSchema` (the
2326
+ * nested `show` object for discover/filter/search tools) and as an optional
2327
+ * top-level field in `showPlaces` itself.
2328
+ *
2329
+ * @ignore
2330
+ */
2331
+ export declare const markerTypeSchema: z.ZodEnum<{
2332
+ none: "none";
2333
+ "base-map": "base-map";
2334
+ pin: "pin";
2335
+ "pin-clustered": "pin-clustered";
2336
+ }>;
2337
+
2338
+ export declare const matchedAreasLabel: (resolvedAreas: ResolvedAreaDisclosure[] | undefined) => string | undefined;
2339
+
1528
2340
  /**
1529
2341
  * The features within ONE source entry that matched the rule — the per-entry unit of a {@link Verdict}.
1530
2342
  * `featureIds` is the matched SUBSET, not the whole entry: a rule selects features by arbitrary sandbox
@@ -1537,6 +2349,9 @@ export declare type MemberRef = {
1537
2349
  featureIds: string[];
1538
2350
  };
1539
2351
 
2352
+ /** @ignore */
2353
+ export declare const MIN_VIEWPORT_BIAS_ZOOM = 6;
2354
+
1540
2355
  /**
1541
2356
  * The geographic area a {@link TrafficIncidentsEntry} monitor is polling, captured at
1542
2357
  * monitor-start time and replayed on every tick.
@@ -1549,11 +2364,88 @@ export declare type MonitoredArea = {
1549
2364
  label?: string;
1550
2365
  };
1551
2366
 
2367
+ /**
2368
+ * Names injected into the sandbox by analyseData / processData, in fixed order.
2369
+ *
2370
+ * @ignore
2371
+ */
2372
+ export declare const MULTI_INPUT_SANDBOX_PARAMS: readonly ["placesByEntry", "routesByEntry", "incidentsByEntry", "geometriesByEntry", "trafficAreaAnalyticsByEntry", "byodByEntry", "h3", "turf", "routeUtils", "cluster"];
2373
+
2374
+ /**
2375
+ * Inputs the LLM passes through the tool schema. All optional, but at least one must be set.
2376
+ *
2377
+ * @ignore
2378
+ */
2379
+ export declare type MultiInputIds = {
2380
+ placesEntryIDs?: readonly string[];
2381
+ routesEntryIDs?: readonly string[];
2382
+ incidentsEntryIDs?: readonly string[];
2383
+ geometriesEntryIDs?: readonly GeometriesId[];
2384
+ trafficAreaAnalyticsEntryIDs?: readonly string[];
2385
+ byodEntryIDs?: readonly string[];
2386
+ };
2387
+
2388
+ /** @ignore */
2389
+ export declare const multiPolygonInputSchema: z.ZodObject<{
2390
+ type: z.ZodLiteral<"MultiPolygon">;
2391
+ coordinates: z.ZodArray<z.ZodArray<z.ZodArray<z.ZodArray<z.ZodNumber>>>>;
2392
+ }, z.core.$strip>;
2393
+
2394
+ /** @ignore */
2395
+ export declare const nearbyWhereSchema: z.ZodObject<{
2396
+ mode: z.ZodLiteral<"nearby">;
2397
+ position: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
2398
+ viewport: z.ZodOptional<z.ZodLiteral<true>>;
2399
+ query: z.ZodOptional<z.ZodString>;
2400
+ queryAs: z.ZodOptional<z.ZodEnum<{
2401
+ place: "place";
2402
+ poi: "poi";
2403
+ }>>;
2404
+ radiusMeters: z.ZodOptional<z.ZodNumber>;
2405
+ }, z.core.$strip>;
2406
+
2407
+ /** Observer invoked after each tool's `execute` settles. */
2408
+ export declare type OnToolExecute = (info: ToolExecutionInfo) => void;
2409
+
2410
+ /**
2411
+ * Pack `prepared.sandbox` into the positional argument array expected by
2412
+ * `runSandboxedFn`, in the same order as {@link MULTI_INPUT_SANDBOX_PARAMS}.
2413
+ *
2414
+ * The merged / per-entry views are shallow — their feature objects are the SAME
2415
+ * references held in the entry slices — so sandbox code must not mutate them in
2416
+ * place or it would corrupt live app state. We do NOT deep-copy here: the copy is
2417
+ * the executor's job, done exactly once and only where needed — the main-thread
2418
+ * executor `structuredClone`s the data args itself, while the iframe-worker
2419
+ * executor gets a copy for free as `postMessage` clones them across the worker
2420
+ * boundary. Cloning here too would be redundant double-work. Trailing `h3` / `turf` /
2421
+ * `routeUtils` / `cluster` are read-only function references, passed through untouched —
2422
+ * `routeUtils` is the shared {@link routeUtils} set and `cluster` is the
2423
+ * {@link clusterIncidents} primitive; both are injected into both tools. (In the
2424
+ * iframe-worker path these positions are dropped and refilled from the worker's own
2425
+ * globals — see {@link WORKER_PROVIDED_PARAMS} — so they must stay function references here.)
2426
+ *
2427
+ * @ignore
2428
+ */
2429
+ export declare const packSandboxArgs: (sandbox: SandboxInputs, libs: {
2430
+ h3: unknown;
2431
+ turf: unknown;
2432
+ }) => readonly unknown[];
2433
+
2434
+ /**
2435
+ * Default-flag (`experimentalSearch: false`) Places schema doc — preserved as a
2436
+ * named constant so non-flag-aware tools keep working.
2437
+ *
2438
+ * @ignore
2439
+ */
2440
+ export declare const PLACES_SCHEMA_DOC: string;
2441
+
1552
2442
  /**
1553
2443
  * A single analysis result attached to a places entry. Alias of the shared {@link EntryAnalysis} —
1554
2444
  * every entry kind uses the same result shape; kept as a named export for back-compat.
1555
2445
  *
1556
2446
  * @group Agent Toolkit
2447
+ *
2448
+ * @ignore
1557
2449
  */
1558
2450
  export declare type PlacesAnalysis = EntryAnalysis;
1559
2451
 
@@ -1561,12 +2453,10 @@ export declare type PlacesAnalysis = EntryAnalysis;
1561
2453
  * A single entry in the place search history.
1562
2454
  *
1563
2455
  * @group Agent Toolkit
2456
+ *
2457
+ * @ignore
1564
2458
  */
1565
- export declare type PlacesEntry = {
1566
- id: string;
1567
- timestamp: number;
1568
- label: string;
1569
- places: Place[];
2459
+ export declare type PlacesEntry = BaseEntry<Place[]> & {
1570
2460
  /** Connections (lines between places) produced alongside this entry, rendered via PlacesModule.showConnections. */
1571
2461
  connections?: PlaceConnectionDisplay[];
1572
2462
  /**
@@ -1594,6 +2484,29 @@ export declare type PlacesEntry = {
1594
2484
  _shownAs?: 'pin' | 'base-map' | 'pin-clustered';
1595
2485
  };
1596
2486
 
2487
+ /**
2488
+ * Optional semantic id for a new places entry. Encourages the LLM to derive a compact,
2489
+ * memorable identifier from the user's prompt so later tool calls can reference the entry
2490
+ * without scanning a numeric history. The id is auto-suffixed (`-2`, `-3`, ...) on collision,
2491
+ * so the LLM never has to track uniqueness across calls itself.
2492
+ *
2493
+ * @ignore
2494
+ */
2495
+ export declare const placesEntryIdHintSchema: z.ZodOptional<z.ZodString>;
2496
+
2497
+ /**
2498
+ * Shared factory for the optional `placesEntryIDs` input field — one or more
2499
+ * existing places-entry IDs that a tool should operate on. Each caller supplies
2500
+ * a `verb` (filter/analyse/display/…) and optional follow-up text so the LLM
2501
+ * sees a description tailored to that tool.
2502
+ *
2503
+ * @ignore
2504
+ */
2505
+ export declare const placesEntryIDsSchema: ({ verb, extra }: {
2506
+ verb: string;
2507
+ extra?: string;
2508
+ }) => z.ZodOptional<z.ZodArray<z.ZodString>>;
2509
+
1597
2510
  /** How an entry is rendered on the map: as individual pins, base-map POIs, or clustered pins. */
1598
2511
  declare type PlacesMarkerType = 'pin' | 'base-map' | 'pin-clustered';
1599
2512
 
@@ -1650,6 +2563,7 @@ declare class PlacesState implements StateSlice {
1650
2563
  place: Place;
1651
2564
  entryId: string;
1652
2565
  } | undefined;
2566
+ geometryPlaceIdsForEntry(entryId: string): string[] | undefined;
1653
2567
  /**
1654
2568
  * Returns the cached boundary polygon for a place id, or undefined if no geometry has been
1655
2569
  * fetched for it yet. Builds a lazy place-id → feature index per entry on first lookup.
@@ -1743,8 +2657,8 @@ declare type PlacesStateEvents = {
1743
2657
  /**
1744
2658
  * History changed — entry added, replaced, or cleared via `reset()`. `entries` is the full
1745
2659
  * snapshot after the change; `changedIds` lists the ids of the entries this specific change
1746
- * added, replaced in place, or removed (the standing-analysis sweep matches these against each
1747
- * record's `affectedEntryIds`).
2660
+ * added, replaced in place, or removed (the {@link JobEngine} matches these against each job's
2661
+ * `affectedEntryIds`).
1748
2662
  */
1749
2663
  'entries-change': {
1750
2664
  entries: readonly PlacesEntry[];
@@ -1765,25 +2679,74 @@ declare type PlacesStateEvents = {
1765
2679
  * Lifecycle state of a per-entry incidents monitor. `stopped-error` indicates the last
1766
2680
  * poll failed and the timer has been cleared — start the monitor again to retry.
1767
2681
  *
1768
- * @group Agent Toolkit
2682
+ * @group Agent Toolkit
2683
+ */
2684
+ export declare type PollingStatus = 'idle' | 'running' | 'stopped-error';
2685
+
2686
+ /** @ignore */
2687
+ export declare const polygonInputSchema: z.ZodObject<{
2688
+ type: z.ZodLiteral<"Polygon">;
2689
+ coordinates: z.ZodArray<z.ZodArray<z.ZodArray<z.ZodNumber>>>;
2690
+ }, z.core.$strip>;
2691
+
2692
+ /**
2693
+ * Internal result of {@link prepareMultiInputs} — the resolved entries, the sandbox-facing views, and
2694
+ * the geometries metadata, bundled for the analyse / process tools.
2695
+ *
2696
+ * @ignore
2697
+ */
2698
+ export declare type PreparedInputs = {
2699
+ resolved: ResolvedEntries;
2700
+ sandbox: SandboxInputs;
2701
+ geometries: GeometriesMeta;
2702
+ };
2703
+
2704
+ /**
2705
+ * Resolve every requested input kind, build the sandbox views, and surface the resolved entries to the
2706
+ * caller. The caller (analyseData / processData) enforces "at least one input must be set" via the zod
2707
+ * schema; this helper enforces it again as a safety net.
2708
+ *
2709
+ * @ignore
1769
2710
  */
1770
- export declare type PollingStatus = 'idle' | 'running' | 'stopped-error';
2711
+ export declare const prepareMultiInputs: (ids: MultiInputIds, state: ToolState) => Promise<{
2712
+ value: PreparedInputs;
2713
+ } | {
2714
+ error: string;
2715
+ }>;
1771
2716
 
1772
2717
  declare type ProviderOptions = Record<string, Record<string, JSONValue | undefined>>;
1773
2718
 
2719
+ export declare type QueryAs = 'poi' | 'place';
2720
+
2721
+ /**
2722
+ * `queryAs` — what kind of thing the paired `query` string is. Drives whether resolution uses
2723
+ * POI search (venues/landmarks/businesses) or geocoding (addresses, cities, neighborhoods, parks,
2724
+ * postal codes, etc.). Optional everywhere; defaults to `'place'`.
2725
+ * @ignore
2726
+ */
2727
+ export declare const queryAsSchema: z.ZodOptional<z.ZodEnum<{
2728
+ place: "place";
2729
+ poi: "poi";
2730
+ }>>;
2731
+
2732
+ /** A single clarification question shown to the user. Exported so a host can type its form state. */
2733
+ export declare const questionSchema: z.ZodObject<{
2734
+ id: z.ZodString;
2735
+ question: z.ZodString;
2736
+ options: z.ZodArray<z.ZodString>;
2737
+ multiSelect: z.ZodDefault<z.ZodBoolean>;
2738
+ }, z.core.$strip>;
2739
+
1774
2740
  /**
1775
2741
  * A single entry in the reachable range history. Holds one or more
1776
2742
  * {@link ReachableRange} results that were computed together — typically
1777
2743
  * one per origin in a multi-origin call to `findReachableAreas`.
1778
2744
  *
1779
2745
  * @group Agent Toolkit
2746
+ *
2747
+ * @ignore
1780
2748
  */
1781
- export declare type RangesEntry = {
1782
- id: string;
1783
- timestamp: number;
1784
- label: string;
1785
- /** One or more ranges sharing this entry — typically one per origin. */
1786
- ranges: ReachableRange[];
2749
+ export declare type RangesEntry = BaseEntry<ReachableRange[]> & {
1787
2750
  /**
1788
2751
  * Per-entry display modules. Each entry owns a dedicated GeometriesModule (for the
1789
2752
  * isochrone polygons) and PlacesModule (for the origin pin(s)), so display state lives
@@ -1897,6 +2860,8 @@ declare type RangeStateEvents = {
1897
2860
  * coverage from several origins under the same query.
1898
2861
  *
1899
2862
  * @group Agent Toolkit
2863
+ *
2864
+ * @ignore
1900
2865
  */
1901
2866
  export declare type ReachableRange = {
1902
2867
  origin: {
@@ -1908,6 +2873,118 @@ export declare type ReachableRange = {
1908
2873
  polygon?: PolygonFeatures;
1909
2874
  };
1910
2875
 
2876
+ /**
2877
+ * Resolve the set of kinds active for a single per-turn build: the intersection of
2878
+ * the agent's enabled kinds and the classifier's per-turn scope. `scope === undefined`
2879
+ * means "no per-turn narrowing — every enabled kind stays in scope".
2880
+ *
2881
+ * @ignore
2882
+ */
2883
+ export declare const resolveActiveKinds: (enabled: readonly EntryDataKind[], scope: EntryKindScope | undefined) => readonly EntryDataKind[];
2884
+
2885
+ export declare const resolveAreas: (where: AreaWhere, ctx: WhereContext, opts?: ResolveAreasOptions) => Promise<ResolvedArea[] | ResolveError>;
2886
+
2887
+ export declare type ResolveAreasOptions = {
2888
+ /** Resolve `queries` to the top geocode candidate's own bbox only — skip the boundary-polygon
2889
+ * fetch and the geometry-source preference. For callers that consume only bboxes (traffic
2890
+ * incidents), this avoids an unnecessary Geometry Data call and the risk of a lower-ranked
2891
+ * area-with-a-boundary displacing the top result. Callers that need precise polygon filters
2892
+ * (discover-places) leave this off. */
2893
+ bboxOnlyQueries?: boolean;
2894
+ };
2895
+
2896
+ export declare const resolveBiasPoint: (where: BiasWhere, ctx: WhereContext) => Promise<ResolvedBias>;
2897
+
2898
+ /** A resolved geographic area. `bbox` is always present; `polygon` is present when a precise
2899
+ * boundary was available (a Geography boundary or a buffered route corridor). */
2900
+ export declare type ResolvedArea = {
2901
+ bbox: BBox;
2902
+ polygon?: Polygon | MultiPolygon;
2903
+ /** The GROUNDED match label — `freeformAddress, <countryCode>` for a `query` area — i.e. what the
2904
+ * data was actually loaded for, NOT the query echo. Lets a consumer surface where a query really
2905
+ * resolved. */
2906
+ label?: string;
2907
+ source: AreaSource;
2908
+ /** The input query text for a `query` area, echoed so a consumer can pair "asked" with the
2909
+ * grounded `label` ("matched"). Absent for non-query sources. */
2910
+ query?: string;
2911
+ };
2912
+
2913
+ /** The grounded resolution of a named `where` query — `matched` is the place the data was actually
2914
+ * loaded for (NOT the query echo). Surfaced so the agent knows where a query resolved and can
2915
+ * detect/correct a wrong same-name match. */
2916
+ export declare type ResolvedAreaDisclosure = {
2917
+ query?: string;
2918
+ matched: string;
2919
+ };
2920
+
2921
+ export declare const resolvedAreasDisclosure: (areas: ResolvedArea[]) => ResolvedAreaDisclosure[];
2922
+
2923
+ /** A resolved point bias for a `nearby`-mode search. `position` is the bias point (absent when the
2924
+ * input was unresolvable — a tolerant no-bias widening, never an error). `query` + `label` are set
2925
+ * ONLY for the `query` sub-case — the grounded-resolution signal, identical in spirit to
2926
+ * {@link ResolvedArea}'s fields: a bias landing on a same-named place elsewhere silently skews
2927
+ * results to the wrong locale (e.g. "coffee near Springfield"). Consumers surface it via
2928
+ * {@link biasDisclosure}. */
2929
+ export declare type ResolvedBias = {
2930
+ position?: Position;
2931
+ label?: string;
2932
+ query?: string;
2933
+ };
2934
+
2935
+ /**
2936
+ * Resolved entries, kept for the attach step in analyseData. Empty arrays for kinds the caller didn't request.
2937
+ *
2938
+ * @ignore
2939
+ */
2940
+ export declare type ResolvedEntries = {
2941
+ places: PlacesEntry[];
2942
+ routes: RoutesEntry[];
2943
+ incidents: TrafficIncidentsEntry[];
2944
+ trafficAreaAnalytics: TrafficAreaAnalyticsEntry[];
2945
+ byod: BYODEntry[];
2946
+ };
2947
+
2948
+ /** @ignore */
2949
+ export declare type ResolvedLocation = {
2950
+ /** Resolved place: a Place (with address metadata) or a bare [lng, lat] tuple. */
2951
+ place: WaypointLike;
2952
+ position: Position;
2953
+ name: string;
2954
+ /** Original query string, when the input was resolved from text. */
2955
+ query?: string;
2956
+ };
2957
+
2958
+ /** Outcome of {@link resolvePoiCategories}. @ignore */
2959
+ export declare type ResolvedPoiCategories = {
2960
+ /** Final search filter — known codes plus codes resolved from natural-language synonyms. */
2961
+ resolved: POICategory[] | undefined;
2962
+ /** Inputs that matched neither an exact code nor any synonym. */
2963
+ unresolved: string[];
2964
+ };
2965
+
2966
+ export declare type ResolveError = {
2967
+ error: string;
2968
+ };
2969
+
2970
+ export declare const resolveNearbyPosition: (where: {
2971
+ viewport?: true;
2972
+ position?: Position;
2973
+ query?: string;
2974
+ queryAs?: QueryAs;
2975
+ }, ctx: WhereContext) => Promise<ResolvedBias>;
2976
+
2977
+ /**
2978
+ * Resolve a mixed list of POI inputs to canonical {@link POICategory} codes.
2979
+ *
2980
+ * Each input is either an exact catalog code (kept as-is) or a natural-language term that is
2981
+ * resolved via the POI categories service. Inputs that produce zero matches are reported in
2982
+ * `unresolved` so callers can surface a precise error.
2983
+ *
2984
+ * @ignore
2985
+ */
2986
+ export declare const resolvePoiCategories: (poiCategories: string[] | undefined) => Promise<ResolvedPoiCategories>;
2987
+
1911
2988
  /**
1912
2989
  * Merges default tools with user overrides.
1913
2990
  *
@@ -1927,6 +3004,15 @@ export declare type ReachableRange = {
1927
3004
  */
1928
3005
  export declare const resolveTools: <S extends ToolState>(defaults: Record<string, ToolDefinition<S>>, overrides?: { [K in ToolNameHint]?: ToolEntry<S> | false | undefined; }) => Record<string, ToolDefinition<S>>;
1929
3006
 
3007
+ export declare const resolveWithinAreas: (where: AreaWhere, ctx: WhereContext, opts?: ResolveAreasOptions) => Promise<ResolveWithinResult | ResolveError>;
3008
+
3009
+ export declare type ResolveWithinResult = {
3010
+ areas: ResolvedArea[];
3011
+ /** Display label of the route corridor, when the `where` resolved one — surfaced by callers
3012
+ * that build a human-readable scope label (traffic's defaultLabel, discover's entry label). */
3013
+ routeLabel?: string;
3014
+ };
3015
+
1930
3016
  /**
1931
3017
  * One-shot polling loop that recalculates a single route on an interval. Owns its timer, status, and
1932
3018
  * error. Re-starting after `stop()` is allowed and resets all state.
@@ -1998,6 +3084,8 @@ declare type RouteMonitorEvents = {
1998
3084
  * Consumed by setRoute, addWaypointsToRoute, removeWaypointsFromRoute, and replaceWaypointInRoute.
1999
3085
  *
2000
3086
  * @group Agent Toolkit
3087
+ *
3088
+ * @ignore
2001
3089
  */
2002
3090
  export declare type RouteParams = {
2003
3091
  maxAlternatives?: number;
@@ -2021,11 +3109,16 @@ export declare type RouteParams = {
2021
3109
  */
2022
3110
  declare type RoutePollingStatus = 'idle' | 'running' | 'stopped-error';
2023
3111
 
3112
+ /** @ignore */
3113
+ export declare const ROUTES_SCHEMA_DOC: string;
3114
+
2024
3115
  /**
2025
3116
  * A single analysis result attached to a routes entry. Alias of the shared {@link EntryAnalysis} —
2026
3117
  * every entry kind uses the same result shape; kept as a named export for back-compat.
2027
3118
  *
2028
3119
  * @group Agent Toolkit
3120
+ *
3121
+ * @ignore
2029
3122
  */
2030
3123
  export declare type RoutesAnalysis = EntryAnalysis;
2031
3124
 
@@ -2033,12 +3126,10 @@ export declare type RoutesAnalysis = EntryAnalysis;
2033
3126
  * A single entry in the route calculation history.
2034
3127
  *
2035
3128
  * @group Agent Toolkit
3129
+ *
3130
+ * @ignore
2036
3131
  */
2037
- export declare type RoutesEntry = {
2038
- id: string;
2039
- timestamp: number;
2040
- label: string;
2041
- data: Routes;
3132
+ export declare type RoutesEntry = BaseEntry<Routes> & {
2042
3133
  waypoints: WaypointLike[];
2043
3134
  params: RouteParams;
2044
3135
  /**
@@ -2064,6 +3155,17 @@ export declare type RoutesEntry = {
2064
3155
  _tick?: number;
2065
3156
  };
2066
3157
 
3158
+ /**
3159
+ * Shared factory for the optional `routesEntryIDs` input field — one or more existing routes-entry
3160
+ * IDs that a tool should operate on. Mirrors `placesEntryIDsSchema` for routes.
3161
+ *
3162
+ * @ignore
3163
+ */
3164
+ export declare const routesEntryIDsSchema: ({ verb, extra }: {
3165
+ verb: string;
3166
+ extra?: string;
3167
+ }) => z.ZodOptional<z.ZodArray<z.ZodString>>;
3168
+
2067
3169
  /**
2068
3170
  * A freshly recalculated route from a single monitor tick, with the moment it was sampled.
2069
3171
  * Payload of {@link RoutingStateEvents.monitor-tick}.
@@ -2075,6 +3177,18 @@ declare type RouteSnapshot = {
2075
3177
  routes: Routes_2;
2076
3178
  };
2077
3179
 
3180
+ /**
3181
+ * @ignore
3182
+ */
3183
+ export declare const routeUtils: {
3184
+ readonly calculateProgressAtRoutePoint: (route: Route, pathIndex: number) => RouteProgressAtPoint | undefined;
3185
+ readonly getCoordinateAtRouteProgress: (route: Route, query: RouteProgressQuery) => RouteCoordinateAtProgress | undefined;
3186
+ readonly getProgressAtNearestRoutePoint: (route: Route, point: HasLngLat) => RouteCoordinateAtProgress | undefined;
3187
+ readonly getRouteProgressBetween: (route: Route, startPathIndex: number, endPathIndex: number) => RouteSegmentProgress | undefined;
3188
+ readonly getRouteProgressForSection: (route: Route, section: SectionProps) => RouteSegmentProgress | undefined;
3189
+ readonly getSectionBBox: (route: Route, section: SectionProps) => OptionalBBox;
3190
+ };
3191
+
2078
3192
  /**
2079
3193
  * State for route calculation, waypoint management, and route planning parameters.
2080
3194
  *
@@ -2250,6 +3364,35 @@ declare type RoutingStateEvents = {
2250
3364
  };
2251
3365
  };
2252
3366
 
3367
+ /**
3368
+ * Compiles `code` as the body of an `async` function that takes the named
3369
+ * `paramNames`, sanitises injected redeclarations, runs it with `args`, and
3370
+ * returns either `{ value }` or `{ error }`. Centralises the AsyncFunction
3371
+ * dance shared by every sandbox-running tool (analyse-* and process-*) so
3372
+ * each callsite only owns its inputs and result handling.
3373
+ *
3374
+ * In addition to the caller's `paramNames`, a fixed set of network / storage /
3375
+ * DOM globals ({@link SHADOWED_GLOBALS}) is appended as `undefined` parameters
3376
+ * so the body cannot reach them by name. This is defense-in-depth, not a
3377
+ * sandbox: it surfaces accidental/undesired global access as an error rather
3378
+ * than containing a hostile escape (see the note on `SHADOWED_GLOBALS`).
3379
+ *
3380
+ * Injected-redeclaration sanitising happens HERE, once, before dispatch — so every
3381
+ * executor (main-thread and iframe-worker alike) runs identically de-fanged code
3382
+ * and an LLM `const turf = require(...)` can't compile in one realm but throw in
3383
+ * another. `executor` is REQUIRED (no implicit main-thread default): callers must
3384
+ * choose the realm explicitly — `state.codeExecution` for the env-resolved sandbox,
3385
+ * or `mainThreadExecutor` to opt into host-realm execution on purpose. `verb` is the
3386
+ * human-readable action used in the error prefix (e.g. `"Analysis"`).
3387
+ *
3388
+ * @ignore
3389
+ */
3390
+ export declare const runSandboxedFn: <Result = unknown>(code: string, paramNames: readonly string[], args: readonly unknown[], verb: string, executor: SandboxExecutor) => Promise<{
3391
+ value: Result;
3392
+ } | {
3393
+ error: string;
3394
+ }>;
3395
+
2253
3396
  /**
2254
3397
  * {@link runClustering} output plus the moment it was computed. The extra `sampledAt` lets the sandbox
2255
3398
  * `cluster()` primitive thread the trend window forward without the caller juggling timestamps: it is
@@ -2261,6 +3404,9 @@ declare type SandboxClusteringOutput = ClusteringOutput & {
2261
3404
  sampledAt?: number;
2262
3405
  };
2263
3406
 
3407
+ /** @ignore */
3408
+ export declare const sandboxedGlobalShadows: readonly ["fetch", "XMLHttpRequest", "WebSocket", "EventSource", "localStorage", "sessionStorage", "indexedDB", "document", "window", "globalThis", "self", "navigator", "importScripts", "process"];
3409
+
2264
3410
  /**
2265
3411
  * Pluggable strategy for executing sandbox code. The default
2266
3412
  * {@link mainThreadExecutor} compiles + runs in the host realm; an alternative
@@ -2282,6 +3428,140 @@ export declare type SandboxExecutor = {
2282
3428
  destroy?(): void;
2283
3429
  };
2284
3430
 
3431
+ /**
3432
+ * Sandbox-facing inputs. Each kind is exposed as a single `<kind>ByEntry` record keyed by the entry id
3433
+ * the caller passed in `<kind>EntryIDs`; the field is `undefined` when its kind wasn't requested. There
3434
+ * is no flat/merged companion — code accesses one entry by id (`placesByEntry["places-2"]`) or merges
3435
+ * across entries explicitly with `Object.values(...)`, so it always stays aware of which entries it spans.
3436
+ *
3437
+ * @ignore
3438
+ */
3439
+ export declare type SandboxInputs = {
3440
+ /**
3441
+ * Per-entry places, keyed by entry id. Each value is a FeatureCollection of that one entry's places.
3442
+ */
3443
+ placesByEntry: Record<string, FeatureCollection_2<Place>> | undefined;
3444
+ /**
3445
+ * Per-entry routes, keyed by entry id. Each value is a FeatureCollection of that one entry's routes.
3446
+ */
3447
+ routesByEntry: Record<string, FeatureCollection_2<Route>> | undefined;
3448
+ /**
3449
+ * Per-entry incidents, keyed by entry id. Each value is a plain array of that one entry's incidents.
3450
+ */
3451
+ incidentsByEntry: Record<string, TrafficIncident[]> | undefined;
3452
+ /**
3453
+ * Per-source polygons collected from every requested source (place / places / ranges / customGeometries).
3454
+ * Keyed by the tagged source `${kind}:${id}` (NOT a bare id: the same id can recur across kinds, e.g. a
3455
+ * `place` vs a `customGeometries` entry), so the kind stays unambiguous. Each feature also self-describes
3456
+ * its origin in `properties._source` (`{ kind, id }`).
3457
+ */
3458
+ geometriesByEntry: Record<string, PolygonFeature[]> | undefined;
3459
+ /**
3460
+ * Per-entry TrafficAreaAnalytics, keyed by entry id. Each value is a full FeatureCollection whose features
3461
+ * are tile/hex regions carrying the SDK metric properties (`congestionLevel`, `speed`, `travelTime`, …)
3462
+ * and whose collection-level `properties` (metrics list, date range) stay intact per entry.
3463
+ */
3464
+ trafficAreaAnalyticsByEntry: Record<string, TrafficAreaAnalytics> | undefined;
3465
+ /**
3466
+ * Per-entry BYOD, keyed by entry id. Each value is a FeatureCollection; mixed geometry types are normal
3467
+ * (BYOD layers can be Point / LineString / Polygon).
3468
+ */
3469
+ byodByEntry: Record<string, FeatureCollection> | undefined;
3470
+ };
3471
+
3472
+ /**
3473
+ * The multi-region `within` field block shared by discoverPlaces and getTrafficIncidents.
3474
+ * Spread into each tool's `z.object({...})` alongside any tool-specific fields.
3475
+ * @ignore
3476
+ */
3477
+ export declare const sharedWithinFields: {
3478
+ queries: z.ZodOptional<z.ZodArray<z.ZodObject<{
3479
+ query: z.ZodString;
3480
+ queryAs: z.ZodOptional<z.ZodEnum<{
3481
+ place: "place";
3482
+ poi: "poi";
3483
+ }>>;
3484
+ }, z.core.$strip>>>;
3485
+ placeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
3486
+ geometries: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
3487
+ type: z.ZodLiteral<"Polygon">;
3488
+ coordinates: z.ZodArray<z.ZodArray<z.ZodArray<z.ZodNumber>>>;
3489
+ }, z.core.$strip>, z.ZodObject<{
3490
+ type: z.ZodLiteral<"MultiPolygon">;
3491
+ coordinates: z.ZodArray<z.ZodArray<z.ZodArray<z.ZodArray<z.ZodNumber>>>>;
3492
+ }, z.core.$strip>]>>>;
3493
+ range: z.ZodOptional<z.ZodString>;
3494
+ route: z.ZodOptional<z.ZodObject<{
3495
+ routeId: z.ZodOptional<z.ZodString>;
3496
+ widthMeters: z.ZodNumber;
3497
+ }, z.core.$strip>>;
3498
+ mode: z.ZodLiteral<"within">;
3499
+ viewport: z.ZodOptional<z.ZodLiteral<true>>;
3500
+ };
3501
+
3502
+ /**
3503
+ * Render a BYOD entry on the map per the tool's `show` options: hide
3504
+ * previously-shown entries (per `hidePreviousEntries`), show the new entry, then
3505
+ * optionally fit the camera to every shown BYOD entry. Sequential by design —
3506
+ * map mutations must not race (see ENGINEERING-GUIDELINES §6).
3507
+ *
3508
+ * @ignore
3509
+ */
3510
+ export declare const showByodOnMap: (state: ToolState, byodEntryId: string, show: z.infer<typeof showByodSchema>) => Promise<z.infer<typeof shownByodSchema>>;
3511
+
3512
+ /**
3513
+ * BYOD `show` options. Mirrors {@link showPlacesSchema} but WITHOUT `markerType`
3514
+ * — BYOD entries render through their own geometry-typed MapLibre layers, so
3515
+ * there is no marker style to pick. Presence of this object means "render now";
3516
+ * omit it to store the entry hidden. `zoomMode` drives the camera and
3517
+ * `hidePreviousEntries` controls which already-shown BYOD entries to clear first.
3518
+ *
3519
+ * @ignore
3520
+ */
3521
+ export declare const showByodSchema: z.ZodObject<{
3522
+ zoomMode: z.ZodEnum<{
3523
+ none: "none";
3524
+ auto: "auto";
3525
+ }>;
3526
+ hidePreviousEntries: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>>;
3527
+ }, z.core.$strip>;
3528
+
3529
+ /**
3530
+ * Fetch boundary polygons for every place in an entry that has a geometry data source,
3531
+ * cache them on the entry, and optionally render them via the entry's GeometriesModule.
3532
+ *
3533
+ * Shared by tools that produce a single places entry (discoverPlaces, locatePlace) — they
3534
+ * differ only in how they shape the result into their output schemas.
3535
+ *
3536
+ * @ignore
3537
+ */
3538
+ export declare const showEntryGeometries: (state: ToolState, placesEntryId: string, config: NonNullable<z.infer<typeof showPlaceGeometriesSchema>>) => Promise<ShowEntryGeometriesResult>;
3539
+
3540
+ /** @ignore */
3541
+ export declare type ShowEntryGeometriesResult = {
3542
+ fetched: number;
3543
+ shown: boolean;
3544
+ };
3545
+
3546
+ /**
3547
+ * Reusable `mode` field for show-on-map options that render polygons into an entry's
3548
+ * own `GeometriesModule`. Controls how the new polygons combine with what is **already
3549
+ * rendered on that single entry's layer** — intra-entry only. Cross-entry visibility
3550
+ * (hiding *other* entries before this one comes up) is a separate concern handled by
3551
+ * `hidePreviousEntries`.
3552
+ *
3553
+ * @ignore
3554
+ */
3555
+ export declare const showModeSchema: z.ZodOptional<z.ZodEnum<{
3556
+ add: "add";
3557
+ replace: "replace";
3558
+ }>>;
3559
+
3560
+ /** @ignore */
3561
+ export declare const shownByodSchema: z.ZodObject<{
3562
+ zoomMode: z.ZodBoolean;
3563
+ }, z.core.$strip>;
3564
+
2285
3565
  /**
2286
3566
  * State slice that owns a set of "entries" (routes, ranges) where each entry can be hidden
2287
3567
  * individually by id and the slice exposes the currently-shown set. Implemented by
@@ -2299,6 +3579,71 @@ declare interface ShownEntriesSlice extends StateSlice {
2299
3579
  hideEntry(entryId: string): Promise<void>;
2300
3580
  }
2301
3581
 
3582
+ /** @ignore */
3583
+ export declare const shownSchema: z.ZodObject<{
3584
+ markerType: z.ZodBoolean;
3585
+ zoomMode: z.ZodBoolean;
3586
+ }, z.core.$strip>;
3587
+
3588
+ /**
3589
+ * Shared schema for the geometry-rendering option on tools that produce a places entry
3590
+ * (discoverPlaces, locatePlace, ...). When provided, the tool batch-fetches boundary
3591
+ * polygons via the Geometry Data service, caches them on the entry, and optionally renders.
3592
+ *
3593
+ * @ignore
3594
+ */
3595
+ export declare const showPlaceGeometriesSchema: z.ZodOptional<z.ZodObject<{
3596
+ show: z.ZodOptional<z.ZodBoolean>;
3597
+ mode: z.ZodOptional<z.ZodEnum<{
3598
+ add: "add";
3599
+ replace: "replace";
3600
+ }>>;
3601
+ theme: z.ZodOptional<z.ZodEnum<{
3602
+ filled: "filled";
3603
+ outline: "outline";
3604
+ inverted: "inverted";
3605
+ }>>;
3606
+ }, z.core.$strip>>;
3607
+
3608
+ /** @ignore */
3609
+ export declare const showPlacesSchema: z.ZodObject<{
3610
+ markerType: z.ZodEnum<{
3611
+ none: "none";
3612
+ "base-map": "base-map";
3613
+ pin: "pin";
3614
+ "pin-clustered": "pin-clustered";
3615
+ }>;
3616
+ zoomMode: z.ZodEnum<{
3617
+ none: "none";
3618
+ auto: "auto";
3619
+ }>;
3620
+ hidePreviousEntries: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>>;
3621
+ }, z.core.$strip>;
3622
+
3623
+ /** @ignore */
3624
+ export declare const showResultsOnMap: (state: ToolState, placesEntryIds: readonly string[], show: z.infer<typeof showPlacesSchema>) => Promise<z.infer<typeof shownSchema>>;
3625
+
3626
+ /** @ignore */
3627
+ export declare type SkippedSource = z.infer<typeof skippedSourceSchema>;
3628
+
3629
+ /** @ignore */
3630
+ export declare const skippedSourceSchema: z.ZodObject<{
3631
+ source: z.ZodDiscriminatedUnion<[z.ZodObject<{
3632
+ kind: z.ZodLiteral<"place">;
3633
+ id: z.ZodString;
3634
+ }, z.core.$strip>, z.ZodObject<{
3635
+ kind: z.ZodLiteral<"places">;
3636
+ id: z.ZodString;
3637
+ }, z.core.$strip>, z.ZodObject<{
3638
+ kind: z.ZodLiteral<"ranges">;
3639
+ id: z.ZodString;
3640
+ }, z.core.$strip>, z.ZodObject<{
3641
+ kind: z.ZodLiteral<"customGeometries">;
3642
+ id: z.ZodString;
3643
+ }, z.core.$strip>], "kind">;
3644
+ reason: z.ZodString;
3645
+ }, z.core.$strip>;
3646
+
2302
3647
  /**
2303
3648
  * Compact snapshot of the user-visible parts of `ToolState`. Designed to be diffable: every field
2304
3649
  * is serialisable to JSON and stable for `===` comparison when the underlying state hasn't changed.
@@ -2409,6 +3754,9 @@ export declare interface StateSlice {
2409
3754
  reset(): void;
2410
3755
  }
2411
3756
 
3757
+ /** @ignore */
3758
+ export declare const stripInjectedRedeclarations: (code: string, identifiers: readonly string[]) => string;
3759
+
2412
3760
  /**
2413
3761
  * The default body text for each base-prompt section — heading excluded.
2414
3762
  *
@@ -2493,6 +3841,13 @@ export declare type SystemPromptSection = 'identity' | 'capabilities' | 'rejecti
2493
3841
  */
2494
3842
  export declare type SystemPromptSectionOverrides = Partial<Record<SystemPromptSection, string>>;
2495
3843
 
3844
+ /** Splits resolved areas into precise polygon filters and coarse bbox filters — the shape
3845
+ * discover-places' search endpoints consume. */
3846
+ export declare const toMultiFilters: (areas: ResolvedArea[]) => {
3847
+ geometries: (Polygon | MultiPolygon)[];
3848
+ boundingBoxes: BBox[];
3849
+ };
3850
+
2496
3851
  /**
2497
3852
  * All valid default tool names, derived from {@link DEFAULT_TOOLS}.
2498
3853
  *
@@ -2579,6 +3934,22 @@ export declare type ToolEntry<S extends ToolState = ToolState, Scope = unknown>
2579
3934
  relatedTools?: string[];
2580
3935
  /** Tool names that must run before this one. */
2581
3936
  dependsOn?: string[];
3937
+ /**
3938
+ * Keep this tool active on every step regardless of the classifier's selection. Its name is
3939
+ * unioned into the per-turn `activeTools` set, so the model can always reach it. Use sparingly —
3940
+ * for tools that may be needed to set up *any* request (e.g. asking the user to clarify intent).
3941
+ * Has no effect on the fail-open path (when classification is skipped, every tool is active).
3942
+ */
3943
+ alwaysActive?: boolean;
3944
+ /**
3945
+ * Halt the agent loop on the SAME step that calls this tool, with no trailing step. Use for tools
3946
+ * whose turn must be a single silent tool call (e.g. clarifyIntent rendering a form). Leave unset to
3947
+ * let the model take one more step after the tool returns — e.g. to present the tool's result as text
3948
+ * before the loop stops naturally on a no-tool-call step. A tool that semantically awaits the user
3949
+ * conveys that through its own result (e.g. clarifyIntent's `status: 'awaiting_user_response'`), not
3950
+ * this flag.
3951
+ */
3952
+ endsTurnOnCall?: boolean;
2582
3953
  /**
2583
3954
  * Optional per-tool scope schema. When set, the classifier may emit a
2584
3955
  * scope value (validated against this schema) and `prepareStep` will
@@ -2610,6 +3981,37 @@ export declare type ToolEntry<S extends ToolState = ToolState, Scope = unknown>
2610
3981
  */
2611
3982
  export declare type ToolEntryBuilder<S extends ToolState = ToolState, Scope = unknown> = (options: ToolBuildOptions<Scope>) => ToolEntry<S, Scope>;
2612
3983
 
3984
+ /**
3985
+ * Options for creating an agent toolkit.
3986
+ *
3987
+ * @typeParam CS - Full state type. Must extend `ToolState`. Defaults to base `ToolState` (no custom slices).
3988
+ *
3989
+ * @group Agent Toolkit
3990
+ *
3991
+ * @example Custom state
3992
+ * ```typescript
3993
+ * interface MyState extends ToolState {
3994
+ * fleet: FleetState;
3995
+ * }
3996
+ *
3997
+ * createMapAgent<MyState>(map, {
3998
+ * model,
3999
+ * state: { fleet: new FleetState() },
4000
+ * });
4001
+ * ```
4002
+ */
4003
+ /** Per-tool execution outcome reported to {@link MapAgentOptions.onToolExecute}. */
4004
+ export declare type ToolExecutionInfo = {
4005
+ /** Registered tool name (the `defaultTools` key). */
4006
+ toolName: string;
4007
+ /** Wall-clock duration of `execute`, in milliseconds (includes any network/IO). */
4008
+ durationMs: number;
4009
+ /** True if the tool threw or returned the standardized `{ error: string }` shape. */
4010
+ isError: boolean;
4011
+ /** Error message when `isError` is true (the thrown message or the returned `error`). */
4012
+ errorMessage?: string;
4013
+ };
4014
+
2613
4015
  /**
2614
4016
  * Metadata for an agent toolkit tool.
2615
4017
  *
@@ -2632,6 +4034,10 @@ export declare type ToolMetadata = {
2632
4034
  relatedTools?: ToolNameHint[];
2633
4035
  /** Tool names that must run before this one. */
2634
4036
  dependsOn?: ToolNameHint[];
4037
+ /** Keep this tool active on every step regardless of the classifier's selection. */
4038
+ alwaysActive?: boolean;
4039
+ /** Halt the agent loop on the step that calls this tool (no trailing step) — e.g. clarifyIntent rendering a form. */
4040
+ endsTurnOnCall?: boolean;
2635
4041
  /** When set, the classifier may emit `toolScopes[name]` for this tool to narrow per-turn. */
2636
4042
  scopePrompt?: string;
2637
4043
  };
@@ -2712,33 +4118,43 @@ export declare type ToolState = {
2712
4118
  * to select where sandbox code runs.
2713
4119
  */
2714
4120
  codeExecution: SandboxExecutor;
4121
+ /**
4122
+ * The single recurrence engine. Owners (`analyses`, `trackers`) register entry-anchored jobs and keep
4123
+ * the returned handles; the engine re-runs each active job when its source entries change. Generic —
4124
+ * it never interprets a job's recipe (the tools layer builds the run closure). See {@link JobEngine}.
4125
+ */
4126
+ engine: JobEngine;
2715
4127
  /**
2716
4128
  * Single session-level registry of every analysis (one-shot + recurring) across all entry kinds.
2717
- * Replaces the old per-entry `_analyses` stores: results live here, and per-entry views read them
2718
- * on demand via {@link Analyses.getAnalysesForEntry}. `analyseData` registers; `monitorAnalysis`
2719
- * toggles `enabled`.
4129
+ * Results live here, and per-entry views read them on demand via {@link Analyses.getAnalysesForEntry}.
4130
+ * `analyseData` registers a record + a job on {@link JobEngine}; `monitorAnalysis` toggles the job's
4131
+ * active flag.
2720
4132
  */
2721
4133
  analyses: Analyses;
2722
4134
  /**
2723
- * Generic trackers — thin rising-edge reducers over `type: 'tracker-rule'` analyses. A tracker fires
2724
- * an alert/event when its rule's {@link Verdict} crosses an edge. Reacts to `analysis-change`; owns
2725
- * the durable {@link TrackerEvent} log.
4135
+ * Generic trackers — rising-edge reducers fed by their own {@link JobEngine} jobs. A tracker fires an
4136
+ * alert/event when its rule's {@link Verdict} crosses an edge (`ingestVerdict`); owns the durable
4137
+ * {@link TrackerEvent} log.
2726
4138
  */
2727
- trackers: TrackerState;
4139
+ trackers: EventsState;
2728
4140
  };
2729
4141
 
4142
+ /** Adapts the live `ToolState` to the narrow `WhereContext` the resolver depends on. Keeping this
4143
+ * mapping in one place is what lets resolveAreas stay testable without a ToolState. */
4144
+ export declare const toolStateToWhereContext: (state: ToolState) => WhereContext;
4145
+
2730
4146
  /**
2731
- * One tracker = one rule: an NL condition compiled to a `tracker-rule` analysis, plus its rising-edge
2732
- * state. Inputs are NOT stored — read `analyses.get(analysisId)?.affectedEntryIds` for the entries the
2733
- * rule watches, and a verdict's `members` for the ones that matched.
4147
+ * One tracker = one rule: an NL condition plus its rising-edge state. The compiled code lives on the
4148
+ * tracker's {@link Job}, not here. `affectedEntryIds` are the entries the rule watches; a verdict's
4149
+ * `members` are the ones that matched.
2734
4150
  */
2735
4151
  export declare type Tracker = {
2736
4152
  id: string;
2737
4153
  name: string;
2738
- /** Natural-language condition (LLM-readable); the compiled code lives on the analysis record. */
4154
+ /** Natural-language condition (LLM-readable); the compiled code lives on the tracker's job. */
2739
4155
  rule: string;
2740
- /** The `type: 'tracker-rule'` analysis whose `data` is this tracker's {@link Verdict}. */
2741
- analysisId: string;
4156
+ /** Ids of every entry the rule reads — the per-entry lookup key ({@link EventsState.trackersForEntry}). */
4157
+ affectedEntryIds: readonly string[];
2742
4158
  enabled: boolean;
2743
4159
  /** The one bit of memory: was the verdict active at the last recompute (rising-edge detection). */
2744
4160
  wasActive: boolean;
@@ -2767,62 +4183,7 @@ export declare type TrackerEventStatus = 'opened' | 'resolved';
2767
4183
  /** Toast-worthy (`alert`) vs quietly-logged (`event`). One store; the type discriminates. */
2768
4184
  export declare type TrackerEventType = 'alert' | 'event';
2769
4185
 
2770
- /**
2771
- * Generic tracker store + rising-edge reducer. Held on `ToolState` as `state.trackers`. Pure
2772
- * storage + reaction: tools register/unregister trackers and register their rule analyses in
2773
- * {@link Analyses}; this slice maps analysis → tracker and reacts to `analysis-change`.
2774
- *
2775
- * @group Agent Toolkit
2776
- */
2777
- declare class TrackerState implements StateSlice {
2778
- private readonly analyses;
2779
- private readonly _trackers;
2780
- private readonly _log;
2781
- /** analysisId → tracker id, so the reducer ignores non-tracker analyses in O(1). */
2782
- private readonly _trackerByAnalysis;
2783
- private _seq;
2784
- readonly events: StateEvents<TrackerStateEvents>;
2785
- /**
2786
- * Subscribe the rising-edge reducer to the analyses registry for the slice's lifetime. The
2787
- * subscription is never torn down (it no-ops without trackers); `reset()` only clears data.
2788
- */
2789
- constructor(analyses: Analyses);
2790
- /**
2791
- * Register a tracker and index its analysis. The caller (createTracker) registers it with the
2792
- * rising-edge bit clear (`wasActive: false`) and attaches the arm-time verdict AFTER this call, so a
2793
- * condition already live at creation crosses false→true through the reducer and fires one `opened`
2794
- * alert. Emits `trackers-change`.
2795
- */
2796
- register(tracker: Tracker): void;
2797
- /** Remove a tracker and drop its analysis index entry. Returns the analysis id it freed, if any. */
2798
- unregister(trackerId: string): string | undefined;
2799
- /** Pause/resume a tracker. A paused tracker never crosses edges. Emits `trackers-change`. */
2800
- setEnabled(trackerId: string, enabled: boolean): boolean;
2801
- /** Live trackers, as copies so external mutation can't corrupt the store. */
2802
- get trackers(): readonly Tracker[];
2803
- get(trackerId: string): Tracker | undefined;
2804
- /**
2805
- * Trackers whose rule reads `entryId` — e.g. every tracker watching a given incidents area. Derived
2806
- * from each rule's analysis `affectedEntryIds` (the inputs are NOT duplicated onto the tracker), so it
2807
- * stays correct if a rule's inputs change. Drives "show all trackers for this area" in the UI.
2808
- */
2809
- trackersForEntry(entryId: string): readonly Tracker[];
2810
- /**
2811
- * The event log, newest last. Pass `sinceMs` to filter and `trackerId` to scope. Returns deep copies
2812
- * so a caller can't mutate a logged event (or its `members`) and corrupt the store.
2813
- */
2814
- log(opts?: {
2815
- trackerId?: string;
2816
- sinceMs?: number;
2817
- }): readonly TrackerEvent[];
2818
- /** Clear all trackers + log. The analyses subscription persists (no-ops without trackers). */
2819
- reset(): void;
2820
- private onAnalysisChange;
2821
- private append;
2822
- private emitTrackers;
2823
- }
2824
-
2825
- /** Events emitted by {@link TrackerState}. */
4186
+ /** Events emitted by {@link EventsState}. */
2826
4187
  export declare type TrackerStateEvents = {
2827
4188
  /** The tracker set or a tracker's live state changed (create / clear / enable / edge crossed). */
2828
4189
  'trackers-change': readonly Tracker[];
@@ -2836,6 +4197,8 @@ export declare type TrackerStateEvents = {
2836
4197
  * back-compat.
2837
4198
  *
2838
4199
  * @group Agent Toolkit
4200
+ *
4201
+ * @ignore
2839
4202
  */
2840
4203
  export declare type TrafficAreaAnalyticsAnalysis = EntryAnalysis;
2841
4204
 
@@ -2846,13 +4209,10 @@ export declare type TrafficAreaAnalyticsAnalysis = EntryAnalysis;
2846
4209
  * `TrafficAreaAnalyticsModule`, lazy-initialised on first show.
2847
4210
  *
2848
4211
  * @group Agent Toolkit
4212
+ *
4213
+ * @ignore
2849
4214
  */
2850
- export declare type TrafficAreaAnalyticsEntry = {
2851
- id: string;
2852
- timestamp: number;
2853
- label: string;
2854
- /** The aggregated FeatureCollection result. */
2855
- data: TrafficAreaAnalytics;
4215
+ export declare type TrafficAreaAnalyticsEntry = BaseEntry<TrafficAreaAnalytics> & {
2856
4216
  /** Request parameters that produced this entry — provenance only, opaque to consumers. */
2857
4217
  params: TrafficAreaAnalyticsParams;
2858
4218
  /**
@@ -2875,6 +4235,8 @@ export declare type TrafficAreaAnalyticsEntry = {
2875
4235
  * enough context for `recall` / `digest` tools.
2876
4236
  *
2877
4237
  * @group Agent Toolkit
4238
+ *
4239
+ * @ignore
2878
4240
  */
2879
4241
  export declare type TrafficAreaAnalyticsParams = Record<string, unknown>;
2880
4242
 
@@ -2960,12 +4322,10 @@ declare type TrafficAreaAnalyticsStateEvents = {
2960
4322
  * incidents state, kept in the slice's `clusters` map keyed by entry id (see {@link ClustersRecord}).
2961
4323
  *
2962
4324
  * @group Agent Toolkit
4325
+ *
4326
+ * @ignore
2963
4327
  */
2964
- export declare type TrafficIncidentsEntry = {
2965
- id: string;
2966
- timestamp: number;
2967
- label: string;
2968
- data: TrafficIncident[];
4328
+ export declare type TrafficIncidentsEntry = BaseEntry<TrafficIncident[]> & {
2969
4329
  /**
2970
4330
  * The captured query that produced this entry. Replayed by the monitor on each tick so
2971
4331
  * polling stays in the same slice the entry was loaded with. Reuses the loader's own
@@ -3053,9 +4413,9 @@ declare class TrafficIncidentsState implements StateSlice {
3053
4413
  * Used by the per-entry monitor tick so incident geometries and any open detail
3054
4414
  * panel stay in sync with the freshest snapshot. `sampledAt` is the canonical moment
3055
4415
  * for this update — propagated to the entry timestamp before the `entries-change` emit.
3056
- * That emit is what drives analysis replay: the session-level standing sweep
3057
- * (`tools/state/analyses-runtime.ts`) re-runs every analysis bound to this entry off the
3058
- * change, ASYNCHRONOUSLY (a microtask later) — the slice itself owns no analysis logic.
4416
+ * That emit is what drives analysis replay: the session-level {@link JobEngine} re-runs every
4417
+ * job bound to this entry off the change, ASYNCHRONOUSLY (a microtask later) — the slice itself
4418
+ * owns no analysis logic.
3059
4419
  * Returns true on success, false when the entry is unknown.
3060
4420
  */
3061
4421
  replaceEntryData(entryId: TrafficIncidentsEntry['id'], data: TrafficIncident[], sampledAt: number): Promise<boolean>;
@@ -3162,7 +4522,7 @@ declare type TrafficIncidentsStateEvents = {
3162
4522
  /**
3163
4523
  * History changed — entry added, replaced, removed, or cleared via `reset()`. `entries` is the
3164
4524
  * full snapshot after the change; `changedIds` lists the ids of the entries this specific change
3165
- * added, replaced in place, or removed. The standing-analysis sweep and the clustering re-run
4525
+ * added, replaced in place, or removed. The {@link JobEngine} and the clustering re-run
3166
4526
  * match these against the entries they depend on.
3167
4527
  */
3168
4528
  'entries-change': {
@@ -3236,6 +4596,24 @@ declare class TrafficTilesState implements StateSlice {
3236
4596
  reset(): void;
3237
4597
  }
3238
4598
 
4599
+ /** Assumes a non-empty array — callers must guard against empty input before calling. */
4600
+ export declare const unionBBox: (bboxes: BBox[]) => BBox;
4601
+
4602
+ /**
4603
+ * Validates the value returned by analyse-* sandboxed code: rejects
4604
+ * `undefined`, JSON-normalizes via `toJsonSafe`, and — when
4605
+ * `outputFormat: "chart"` — checks the result is a Chart.js
4606
+ * `ChartConfiguration`. Centralises the contract shared by analyse-places,
4607
+ * analyse-routes, and analyse-geometries.
4608
+ *
4609
+ * @ignore
4610
+ */
4611
+ export declare const validateAnalysisResult: (analysis: unknown, outputFormat: AnalysisOutputFormat) => {
4612
+ value: unknown;
4613
+ } | {
4614
+ error: string;
4615
+ };
4616
+
3239
4617
  /**
3240
4618
  * What a tracker's sandboxed `evaluateCode` returns — stored verbatim as the rule analysis's `data`
3241
4619
  * and read back by the reducer. `members` groups matches by source entry so a verdict can span
@@ -3248,6 +4626,83 @@ export declare type Verdict = {
3248
4626
  summary: string;
3249
4627
  };
3250
4628
 
4629
+ /** Everything `resolveAreas` needs from the host, as a narrow port. `ToolState` satisfies this in
4630
+ * prod (see tool-state-where-context.ts); tests pass literal fakes. */
4631
+ export declare type WhereContext = {
4632
+ viewportBBox(): BBox | undefined;
4633
+ viewportCenter(): Position | undefined;
4634
+ findPlaceById(id: string): Place | undefined;
4635
+ geometryPlaceIdsForEntry(id: string): string[] | undefined;
4636
+ fetchPlaceGeometry(id: string): Promise<Feature | undefined>;
4637
+ geocodeArea(query: string, queryAs: QueryAs, bias?: Position): Promise<Place[]>;
4638
+ geocodeAreas(query: string, bias?: Position): Promise<Place[]>;
4639
+ fetchAreaPolygon(place: Place): Promise<Feature<Polygon | MultiPolygon> | undefined>;
4640
+ getRoute(routeId?: string): {
4641
+ features: Feature[];
4642
+ label: string;
4643
+ } | {
4644
+ error: string;
4645
+ };
4646
+ };
4647
+
4648
+ /**
4649
+ * locatePlace's `where` schema — `within` (singular fields), `nearby`, or `global`.
4650
+ * discoverPlaces builds its own union in discover-places.ts using the plural-form within schema.
4651
+ * @ignore
4652
+ */
4653
+ export declare const whereSchema: z.ZodUnion<readonly [z.ZodObject<{
4654
+ boundingBox: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodNumber>]>>;
4655
+ query: z.ZodOptional<z.ZodString>;
4656
+ queryAs: z.ZodOptional<z.ZodEnum<{
4657
+ place: "place";
4658
+ poi: "poi";
4659
+ }>>;
4660
+ placeId: z.ZodOptional<z.ZodString>;
4661
+ mode: z.ZodLiteral<"within">;
4662
+ viewport: z.ZodOptional<z.ZodLiteral<true>>;
4663
+ }, z.core.$strip>, z.ZodObject<{
4664
+ mode: z.ZodLiteral<"nearby">;
4665
+ position: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
4666
+ viewport: z.ZodOptional<z.ZodLiteral<true>>;
4667
+ query: z.ZodOptional<z.ZodString>;
4668
+ queryAs: z.ZodOptional<z.ZodEnum<{
4669
+ place: "place";
4670
+ poi: "poi";
4671
+ }>>;
4672
+ radiusMeters: z.ZodOptional<z.ZodNumber>;
4673
+ }, z.core.$strip>, z.ZodObject<{
4674
+ mode: z.ZodLiteral<"global">;
4675
+ }, z.core.$strip>]>;
4676
+
4677
+ /**
4678
+ * Fields shared by both locatePlace's and discoverPlaces' `within` schemas — `mode` and the
4679
+ * `viewport` flag. Spread into each consumer's `z.object({...})`.
4680
+ * @ignore
4681
+ */
4682
+ export declare const withinSharedFields: {
4683
+ mode: z.ZodLiteral<"within">;
4684
+ viewport: z.ZodOptional<z.ZodLiteral<true>>;
4685
+ };
4686
+
4687
+ /**
4688
+ * locatePlace's `within` schema — exactly one of viewport / boundingBox / query / placeId.
4689
+ * @ignore
4690
+ */
4691
+ export declare const withinWhereSchema: z.ZodObject<{
4692
+ boundingBox: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodNumber>]>>;
4693
+ query: z.ZodOptional<z.ZodString>;
4694
+ queryAs: z.ZodOptional<z.ZodEnum<{
4695
+ place: "place";
4696
+ poi: "poi";
4697
+ }>>;
4698
+ placeId: z.ZodOptional<z.ZodString>;
4699
+ mode: z.ZodLiteral<"within">;
4700
+ viewport: z.ZodOptional<z.ZodLiteral<true>>;
4701
+ }, z.core.$strip>;
4702
+
4703
+ /** @ignore */
4704
+ export declare const WORKER_PROVIDED_PARAMS: readonly ["turf", "h3", "routeUtils", "log", "cluster"];
4705
+
3251
4706
  export { }
3252
4707
 
3253
4708