Skip to content

@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):

  • CameraflyTo, cameraSetView, cameraLookAtTransform, cameraOrbit, cameraGetPosition, cameraSetControllerOptions
  • EntityentityAdd (a discriminated-union tool: the model picks type — point, billboard, label, model, polygon, and more), entityList, entityRemove
  • AnimationanimationCreate, animationRemove, animationListActive, animationUpdatePath, animationCameraTracking, clockControl, globeSetLighting
  • ImageryimageryAdd, 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 /schemas or /names from 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.