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 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 SDK modules, which the toolkit creates lazily 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, with origins, budgets and polygons. getEntryRangesModule(id) returns the bands’ ReachableRangesModule. getEntryGeometriesModule(id) returns a plain GeometriesModule for polygons you style yourself, and getEntryPlacesModule(id) returns 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 with their request, result and 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(). |
The entry slices also hold the look of their modules as a SliceKnobs: routing.knobs, places.knobs and
places.geometriesKnobs, ranges.knobs, ranges.geometriesKnobs and ranges.placesKnobs, customGeometries.knobs,
trafficAreaAnalytics.knobs and trafficIncidents.knobs. set(id, value) takes an id of the module’s
knob catalogue and sets it on every module of that kind the slice holds, and on each one
it creates later. setMapStyling writes through them. For example, agent.state.routing.knobs.set('color', '#e11d48')
recolours every route, shown now or later.
Beside the slices, agent.state holds every analyseData result (analyses), the trackers and the sandbox that runs
generated code (codeExecution).
Sharing across tools
All tools share state. A place that locatePlace resolves 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, the 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. The kind drops out of the analyseData / processData inputs, and the agent drops its fetch and display tools.
TOOLS_BY_DATA_ENTRY_KIND lists them per
kind. The agent keeps a tool you pass under one of those names in tools.
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 resultsagent.state.places.latestPlace; // places of the most recent entryagent.state.places.shownEntryIds; // entries currently on the mapagent.state.places.entries; // full history of place entriesagent.state.trafficIncidents.entries; // fetched incident entriesagent.state.trafficAreaAnalytics.entries; // historical analytics entriesagent.state.customGeometries.entries; // derived polygon entriesagent.state.byod.entries; // bring-your-own-data layer entriesagent.state.baseMap.mapLibreMap; // raw MapLibre Map instanceTelling the model what the user changed
If your UI changes the map between turns, such as hiding a layer or picking 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 returns 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;What state holds, and how to wipe it
State lives in memory only. The toolkit writes nothing to browser storage. State holds every entry of the session, meaning the places, routes, ranges, BYOD layers, incidents, analyses and trackers the user produced, until one of these clears it:
- The
resetStatetool, which the agent calls when the user asks to start over. agent.destroy()from your code.
The chat history is not part of state. It lives in your chat component. To erase a user’s data, clear that history and call agent.destroy(). See What the agent sends, and where.
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 applicationagent.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 the person using your application can see and edit everything in it. Securing your agent covers what follows from that.