Skip to content

Quickstart

This guide takes an existing agent-side tool and adds an independent verification step.

1. Install Actaro

Actaro supports Node.js 20 and newer.

bash
npm install actaro-sdk zod

2. Define an action

execute performs the side effect. verify reads the resulting state independently. The tool response from execute is not treated as proof.

ts
import { actaro, createActaro, defineAction } from "actaro-sdk";
import { z } from "zod";

const action = defineAction({
  name: "create-task",
  description: "Create a task and verify that it is visible",
  input: z.object({ title: z.string().min(1) }),
  execute: ({ title }) => taskApi.create({ title }),
  verify: async ({ title }) => {
    const task = await taskApi.findByTitle(title);

    return task
      ? { status: "verified", evidence: { id: task.id, state: task.state } }
      : { status: "pending", reason: "Task is not visible yet" };
  },
});

const receipt = await actaro.run(action, {
  title: "Publish release notes",
});

if (receipt.status === "verified") {
  console.log("The task was verified:", receipt.evidence);
}

3. Handle the receipt

Treat only verified as completion. A pending result is retried according to the configured policy; a failed result contains the reason or execution error.

ts
const client = createActaro({
  verification: {
    retries: 3,
    delayMs: 500,
    timeoutMs: 5_000,
  },
});

const receipt = await client.run(action, { title: "Publish release notes" });

For an LLM tool response, use toAgentResult(receipt). It returns a text message and a canClaimCompletion boolean that is true only for a verified receipt.

4. Prevent duplicate execution

Provide an idempotency key when a repeated request must refer to the same real-world operation:

ts
const payment = defineAction({
  name: "process-payment",
  input: z.object({ orderId: z.string() }),
  idempotencyKey: ({ orderId }) => `order:${orderId}`,
  execute: ({ orderId }) => payments.capture(orderId),
  verify: ({ orderId }) =>
    payments.wasCaptured(orderId)
      ? { status: "verified", evidence: { orderId } }
      : { status: "pending", reason: "Payment is still processing" },
});

5. Try a runnable example

From the repository root:

bash
npx tsx examples/memory-task.ts
npx tsx examples/eventual-consistency.ts
npx tsx examples/local-mcp-style.ts

Continue with the integration guide or the production guide.

Released under the MIT License.