Agent Toolkit state
The Agent Toolkit keeps structured state for the whole conversation. Tools return compact summaries and keep the
underlying data in state, so the next tool call — or the next turn — reads it instead of the model re-deriving or
inventing it. The model reads it back with recallState, which also returns summaries.
State slices
State is organized by feature area:
Slices flagged entries own an append-only history of results; the rest hold the map's shared modules. Entry slices
share one shape — entries, entryMode, setEntryMode(mode) — and each entry owns lazy SDK modules, created on first
display (see Entry mode).
| State slice | Entries | What it holds |
|---|---|---|
places |
Yes | Place entries — search results, single lookups, processed sets — with attached footprints and connections. getEntryPlacesModule(id, markerType) and getEntryGeometriesModule(id) return each entry's modules. |
routing |
Yes | Route entries, staged waypoint slots and the current route parameters; getEntryRoutingModule(id). |
ranges |
Yes | Reachable range (isochrone / isodistance) entries — origins, budgets, polygons. getEntryRangesModule(id) returns the bands' ReachableRangesModule, getEntryGeometriesModule(id) a plain GeometriesModule for polygons styled your own way, getEntryPlacesModule(id) the origin pins. |
customGeometries |
Yes | Polygons derived by processData (union, buffer, difference, h3 coverage, …), kept apart from places so their provenance (source ids, operation label) stays explicit; getEntryGeometriesModule(id). |
byod |
Yes | Your GeoJSON layers, each with an auto-detected BYODDataProfile; getEntryModule(id). |
trafficAreaAnalytics |
Yes | Area-analytics entries — request, result, display config; getEntryModule(id). |
trafficIncidents |
Yes | Fetched incident entries, focused subsets and the polling monitor that keeps them fresh; getEntryModule(id). |
baseMap |
— | The TomTomMap (ttMap) and its MapLibre map (mapLibreMap); getBaseMapModule(), getStylingFoundationsModule(), getTerrainModule(). |
mapPOIs |
— | The base-map POI layer; getPOIsModule(). |
trafficTiles |
— | Traffic flow and incident tile overlays; getTrafficFlowModule(), getTrafficIncidentsModule(). |
Beside the slices, agent.state holds every analyseData result (analyses), the trackers, and the sandbox that runs
generated code (codeExecution).
Sharing across tools
State is shared by all tools. A place resolved by locatePlace is available to addWaypointsToRoute without the model
passing it along — tools pass entry ids, not data, which avoids the error-prone "read then pass" pattern.
Tool results carry summaries, not the data. When a user asks "what were those places?" an hour into a session, the
model calls recallState instead of guessing.
Entry mode
Every entry slice has an entry mode: multiple (default) renders several entries side by side; single keeps only
the most recent one, and switching to it drops the older ones. The EntryModeSliceName union names these slices by
their keys on agent.state (routing, not routes; customGeometries, not geometries):
| Slice | Field |
|---|---|
places |
agent.state.places |
routing |
agent.state.routing |
ranges |
agent.state.ranges |
customGeometries |
agent.state.customGeometries |
byod |
agent.state.byod |
trafficAreaAnalytics |
agent.state.trafficAreaAnalytics |
trafficIncidents |
agent.state.trafficIncidents |
The model switches modes with the setEntryMode tool when the user asks to "only show one at a time" or "let me
overlay multiple". The state playground example shows every
slice's entries and mode live.
Defaults via createMapAgent
Set per-kind defaults with the dataEntries option; each kind accepts { enabled?, entryMode? }. Keys are data kinds
(routes, incidents), not slice names (routing, trafficIncidents).
import { createMapAgent } from '@tomtom-org/maps-sdk-plugin-agent-toolkit';
const agent = createMapAgent(map, {
model: openai('gpt-4o'),
dataEntries: {
routes: { entryMode: 'single' }, // only one route on the map
incidents: { entryMode: 'single' }, // each refresh replaces the previous snapshot
byod: { enabled: false }, // hide byod from analyse/process scope + drop addByodSource / setByodLayers / updateByodDisplay
},
});
Omitted kinds keep their defaults (enabled: true, entryMode: 'multiple'). enabled: false removes the kind from
the agent: it leaves the analyseData / processData inputs, and its fetch and display tools are dropped —
TOOLS_BY_DATA_ENTRY_KIND lists them per
kind. A tool you pass under one of those names in tools is kept.
Switch a mode at any time after construction:
await agent.state.customGeometries.setEntryMode('single');
Working with the union from your own code
EntryModeSliceName and its runtime list ENTRY_MODE_SLICE_NAMES let custom tools and dev UIs iterate every entry
slice without hard-coding names:
import {
ENTRY_MODE_SLICE_NAMES,
type EntryModeSliceName,
} from '@tomtom-org/maps-sdk-plugin-agent-toolkit';
for (const slice of ENTRY_MODE_SLICE_NAMES) {
console.log(slice, agent.state[slice].entryMode);
}
Inspecting state from your application
Read live state at any time:
agent.state.routing.currentRoutes; // most recent route results
agent.state.places.latestPlace; // places of the most recent entry
agent.state.places.shownEntryIds; // entries currently on the map
agent.state.places.entries; // full history of place entries
agent.state.trafficIncidents.entries; // fetched incident entries
agent.state.trafficAreaAnalytics.entries; // historical analytics entries
agent.state.customGeometries.entries; // derived polygon entries
agent.state.byod.entries; // bring-your-own-data layer entries
agent.state.baseMap.mapLibreMap; // raw MapLibre Map instance
Telling the model what the user changed
When your UI changes the map between turns — the user hides a layer, picks another route — the model doesn't know.
getStateDigest snapshots what is shown; formatStateDigestDiff turns two snapshots into a short note to prepend to the
next message, or null when nothing changed:
import { formatStateDigestDiff, getStateDigest } from '@tomtom-org/maps-sdk-plugin-agent-toolkit';
let baseline = getStateDigest(agent.state); // after each assistant reply
// … before sending the user's next message:
const diff = formatStateDigestDiff(baseline, getStateDigest(agent.state));
const content = diff ? `${diff}\n${userText}` : userText;
Custom state slices
If your custom tools need to share data across calls, extend ToolState with your own slice. Implement reset() to
take part in agent.destroy() cleanup, and give the model a tool that reads the slice back:
import type { ToolState, StateSlice } from '@tomtom-org/maps-sdk-plugin-agent-toolkit';
class FleetState implements StateSlice {
vehicles: Map<string, VehiclePosition> = new Map();
reset() { this.vehicles.clear(); }
}
interface MyState extends ToolState {
fleet: FleetState;
}
const agent = createMapAgent<MyState>(map, {
model: openai('gpt-4o'),
state: { fleet: new FleetState() },
tools: { getFleetVehicle: myFleetTool },
});
// Access live state from your application
agent.state.fleet.vehicles;
agent.state.routing.currentRoutes;
The site selection agent example adds a custom slice; the tool registry lists the tools that read and write the built-in ones.
State lives in the page, so everything in it is visible and editable by the person using your application. Securing your agent covers what follows from that.