@cesium-ai/tools-schemas
Zod-schemed CesiumJS viewer tool definitions for the AI SDK — schemas only, no execute. The AI SDK streams tool calls to the browser, which runs them against the live Viewer and posts results back to the agent loop.
Supported viewer tools
The model-facing catalogue currently contains 19 tools (CESIUM_TOOL_NAMES):
- Camera —
flyTo,cameraSetView,cameraLookAtTransform,cameraOrbit,cameraGetPosition,cameraSetControllerOptions - Entity —
entityAdd(a discriminated-union tool: the model pickstype— point, billboard, label, model, polygon, and more),entityList,entityRemove - Animation —
animationCreate,animationRemove,animationListActive,animationUpdatePath,animationCameraTracking,clockControl,globeSetLighting - Imagery —
imageryAdd,imageryRemove,imageryList
Every tool follows the exact same shape as flyTo (see below): a <toolName>.schema.ts with no description text, a <toolName>.ts with the default description/field hints and a create<ToolName> factory, an entry in CESIUM_TOOL_NAMES, and a corresponding key on CesiumToolsConfig. entityAdd's per-variant payload shapes (entityAddPoint, entityAddBillboard, and others) still exist as internal schema modules under src/tools/ and are re-exported from the /schemas subpath, but are no longer separately registered CESIUM_TOOL_NAMES entries or model-facing tools. entityAdd's type field is the single model entry point for all entity variants.
See the Tool Catalogue for what each tool does, per-field.
Usage
import { createCesiumTools } from "@cesium-ai/tools-schemas";
import { createChatRouter } from "@cesium-ai/server";
createChatRouter({
model,
tools: createCesiumTools(),
});
Entry points
| Subpath | Exports | Who imports it |
|---|---|---|
@cesium-ai/tools-schemas |
Everything below — full tool definitions, incl. model-facing descriptions | Backend only. Never import the root entry point from client code — it pulls in the human-readable descriptions the LLM reads, which should not ship in the client bundle. |
@cesium-ai/tools-schemas/names |
CESIUM_TOOL_NAMES, CesiumToolName |
Both. Schema-free — safe for the frontend to key its tool-call executors off of. |
@cesium-ai/tools-schemas/schemas |
All *InputShape/*Input exports (for every tool, e.g. flyToInputShape, entityAddInputShape) |
Both. Structural shapes only, no .describe() hints — safe for the frontend to validate untrusted tool-call args against. |
Security
Tool call args are attacker-influenceable: the model produces them, they stream unauthenticated, and the client hands them to a live Viewer. Two rules follow:
- Validate before executing. Re-validate every tool call against
flyToInputShape(via/schemas) before acting on it. - Keep descriptions server-side. Import only
/schemasor/namesfrom frontend code, never the package root.
Configuring tools
Enable a subset
createCesiumTools({ enabled: ["flyTo"] });
// or disable a specific tool:
createCesiumTools({ flyTo: false });
Override descriptions or field hints
createCesiumTools({
flyTo: {
description: "Move the camera to a named place on the globe.",
fieldDescriptions: {
altitude: "Height above the ground in metres.",
},
},
});
description replaces the default wholesale. fieldDescriptions is shallow-merged over defaults. inputSchema fully replaces the model-facing schema.
The defaults are exported so you can extend rather than replace:
import {
DEFAULT_FLY_TO_DESCRIPTION,
DEFAULT_FLY_TO_FIELD_DESCRIPTIONS,
} from "@cesium-ai/tools-schemas";
Extend the validated args contract
To add fields and keep both sides in sync, build one shared shape and import it from both server and client — the way shared/src/flyto-schema.ts does:
// shared module
import { z } from "zod";
import { flyToInputShape } from "@cesium-ai/tools-schemas/schemas";
export const flyToShape = z.object({
...flyToInputShape.shape,
duration: z.number().positive().optional(),
});
// server — layer .describe() hints, pass as inputSchema
createCesiumTools({ flyTo: { inputSchema: extendedSchemaWithDescriptions } });
// client
flyToShape.safeParse(rawArgs);
Why executeCesiumCode isn't here
This package is for tools whose args are bounded, typed data a client can validate and pass directly to a Viewer method. executeCesiumCode takes a natural-language intent that generates arbitrary code — it needs its own generation, verification, and runtime isolation pipeline. See @cesium-ai/codegen-cesium.