Quickstart

Define an agent, run it, read the result. 10 minutes.

This tutorial runs a tiny agent end-to-end against OpenRouter. By the end you’ll have a working agent that fetches a question, replies with valid JSON, and reports its tokens + cost.

Prerequisites

  1. Bun runtime

    drover runs on Bun 1.3+. No Node-only deps assumed.

  2. OpenRouter API key

    Default model aliases route through OpenRouter. Set it once:

    bash
    export OPENROUTER_API_KEY=sk-or-v1-...

    See @drover/model for using a different provider.

Install

bun
bash
bun add @drover/core @drover/facade @drover/sandbox

Define + run an agent

quickstart.ts
ts
import { Type } from "@sinclair/typebox";
import { defineAgent } from "@drover/core";
import { runAgent } from "@drover/facade";

const echo = defineAgent({
  id: "echo",
  systemPrompt:
    "Reply with a JSON object matching the outputSchema. No prose.",
  inputSchema: Type.Object({ word: Type.String() }),
  outputSchema: Type.Object({
    upper: Type.String(),
    length: Type.Integer(),
  }),
  model: "cheap",       // alias for gemini-3.1-flash-lite-preview
  tools: [],
  quota: { maxTurns: 2 },
});

const handle = runAgent(echo, { word: "drover" });
for await (const e of handle.events) {
  if (e.kind === "assistant_text") console.log("[text]", e.text);
}
const result = await handle.result;
console.log("status:", result.status);
console.log("output:", result.output);
console.log("tokens:", result.usage.inputTokens + "/" + result.usage.outputTokens);

Run it:

bash
bun quickstart.ts

Expected output:

[text] {"upper":"DROVER","length":6}
status: success
output: { upper: "DROVER", length: 6 }
tokens: 179/24

What happened

  1. Input validation

    drover decoded { word: "drover" } against your inputSchema before calling the model. Validation failure short-circuits with an InputValidationError — the model never sees malformed input.

  2. Model dispatch

    "cheap" resolved through the alias map to google/gemini-3.1-flash-lite-preview on OpenRouter. The harness wrapped pi-agent-core’s runAgentLoop and streamed events as they fired.

  3. Output validation

    The model’s final text was decoded against outputSchema. If it had failed, drover would have fed back a corrective message and retried up to outputRetries times (default 2).

  4. Terminal status

    result.status is one of success, quota, cancelled, paused, or error. result.error populates on the error path — the Promise never rejects.

Next

Type to search…

↑↓ navigate open esc close