Get started

Build your first agent

Define a base agent, a skill, a workflow, and an approval gate.

This walkthrough uses the TypeScript SDK against a local runtime (lybo serve). The identical calls work on-device through the Expo module.

  1. 1

    Start a client

    import { LyboClient, NodeTransport } from "@lyboai/runtime";
    
    const lybo = new LyboClient(await NodeTransport.spawn({
      binary: "./target/debug/lybo",
      dataDir: "/tmp/my-agent",
    }));
  2. 2

    Give the agent local knowledge

    await lybo.installKnowledge({
      doc_id: "handbook",
      title: "Team Handbook",
      body: "Support tickets must be answered within 24 hours…",
      scope: "app",
    });
  3. 3

    Define a retrieval skill

    Triggers feed the intent router; the pattern decides execution.

    await lybo.registerSkill({
      skill_id: "app.ask",
      name: "Ask the handbook",
      description: "Answer questions from the handbook",
      pack_id: "app",
      triggers: ["what does the handbook say"],
      keywords: ["handbook", "policy"],
      execution: { kind: "pattern", pattern: "retrieval" },
    });
  4. 4

    Add a workflow with an approval gate

    Workflows are declarative JSON graphs — extract → confirm → tool call. The confirm step pauses the run until the user decides.

    await lybo.registerWorkflow({
      workflow_id: "wf.note", version: "1", pack_id: "app",
      description: "Save a note after approval",
      initial_state: "confirm", max_steps: 16, auto_checkpoint: true,
      states: {
        confirm: {
          step: { kind: "confirm", message_template: "Save \"{{input}}\"?" },
          transitions: [
            { when: { kind: "approved" }, to: "save" },
            { when: { kind: "rejected" }, to: "done_cancelled" }],
        },
        save: {
          step: { kind: "tool_call", tool_id: "create_note",
            args_template: { title: "Note", body: "{{input}}" },
            output_field: "note" },
          transitions: [{ when: { kind: "tool_ok" }, to: "done" }],
        },
        done: { step: { kind: "end", output_template: { status: "saved", note: "$note" } }, transitions: [] },
        done_cancelled: { step: { kind: "end", output_template: { status: "cancelled" } }, transitions: [] },
      },
    });
    
    await lybo.registerSkill({
      skill_id: "app.note", name: "Save note", description: "",
      pack_id: "app", triggers: ["save a note"], keywords: ["note", "save"],
      execution: { kind: "workflow", workflow_id: "wf.note" },
    });
  5. 5

    Run the loop

    const session = await lybo.startSession();
    
    let out = await lybo.submitInput(session, "save a note: call the supplier tomorrow");
    if (out.state === "awaiting_approval") {
      // render your approval UI, then:
      out = await lybo.resolveApproval(out.approval_id, true);
    }
    console.log(out); // { state: "completed", output: { status: "saved", … } }
Everything above also works packaged as a signed capability pack so you can ship it over the air after release — see *Capability packs*.