Skip to content
Go To Dashboard

Build

An agent project exports exactly one defineAgent({ name, entry, steps }) from index.ts. Each defineStep runs ordinary asynchronous TypeScript and returns a directive such as goto(...), terminate(...), fail(...), retry(...), or pauseUntilSignal(...).

This guide builds the one-step Hello Agent that was verified from the live template.

Replace index.ts in an installed agent project with:

import { defineAgent, defineStep, terminate } from "@sapiom/agent";
import { z } from "zod/v4";
const entryInput = z.object({
name: z.string().default("world").describe("Who to greet."),
});
const greet = defineStep({
name: "greet",
inputSchema: entryInput,
next: [],
terminal: true,
async run(input, ctx) {
ctx.logger.info("greeting", { name: input.name });
return terminate({ greeting: `Hello, ${input.name}!` });
},
});
export const agent = defineAgent({
name: "hello-agent",
entry: "greet",
steps: { greet },
});

The entry step’s inputSchema is the agent’s public runtime-input contract. Its descriptions and defaults feed the dashboard Run form and generated invocation snippets; local and cloud step dispatch both parse the inbound value through the author schema before calling run. A z.object(...) also strips undeclared keys by default.

Open the project and make sure the intended session is bound to it. Ask Claude to read AGENTS.md, implement the definition above, run npm run typecheck, and call sapiom_dev_agents_check for the bound project. Review the terminal diff and check output before accepting further edits.

Visualize is useful for refreshing Canvas directly, but the full authoring check is the gate: Visualize can skip TypeScript for speed while sapiom_dev_agents_check runs it.

  1. npm run typecheck verifies the source against the exact installed packages. It catches missing capability namespaces, wrong handle methods, invalid directives, and undeclared goto targets before bundling strips TypeScript types.

  2. sapiom_dev_agents_check typechecks, bundles and imports index.ts, finds exactly one agent definition, derives and validates its manifest, and validates the graph.

    For the definition above, the stable result fields are:

    {
    "name": "hello-agent",
    "stepCount": 1,
    "warnings": []
    }

    The response also contains the full manifest and a build-specific artifact hash. Do not compare the hash byte-for-byte.

The check needs no Sapiom account or Sapiom service call. It does import your bundled definition, so top-level code in index.ts and imported modules still runs on your machine. Keep network calls, file writes, environment reads, and process launches inside step bodies unless import-time behavior is intentional.

  • the agent’s entry names a real step;
  • every goto target is declared in that step’s next list;
  • terminal and failure directives match terminal and canFail declarations;
  • pause declarations name a signal and resume step;
  • the manifest is serializable and structurally valid.

No entry inputSchema is still legal, but the check warns because the dashboard and callers then have no declared input fields. Type errors, bundle/import errors, missing or multiple definitions, malformed manifests, and invalid graphs fail the check.