Skip to content
API Blog

Agent workspace

A Lobu agent has two parts:

  1. a workspace template containing prompt files, local skills, and evals
  2. an agent definition in lobu.config.ts containing providers, tools, guardrails, network policy, Nix packages, and chat platform bindings

Project-level lobu.config.ts also owns shared organization wiring such as connections, entity schemas, relationship schemas, connector source files, and automations.

lobu.config.ts
agents/
support/
IDENTITY.md
SOUL.md
USER.md
skills/internal-api/SKILL.md
evals/promptfooconfig.yaml

A single-agent project may use dir: ".". Multi-agent projects normally give each agent its own directory.

ConcernLocation
Name, role, concise identityIDENTITY.md
Standing instructions, workflows, tone, constraintsSOUL.md
Shared user, team, or deployment contextUSER.md
Reusable proceduresSKILL.md
Runtime regression testsevals/
Models, tool policy, guardrails, network, Nix packages, platform bindingsdefineAgent(...) in lobu.config.ts
Connections, auth profiles, entities, relationships, automations, connector filesproject-level defineConfig(...)

Keep operator policy in configuration rather than hiding it inside a prompt or skill.

import { defineAgent, skillFromFile } from "@lobu/cli/config";
const support = defineAgent({
id: "support",
name: "Support",
dir: "./agents/support",
skills: [
skillFromFile("./agents/support/skills/internal-api"),
],
providers: [
{ id: "openrouter", model: "anthropic/claude-sonnet-4" },
],
network: { allowed: ["api.example.com"] },
guardrails: ["secret-scan", "pii-scan"],
tools: {
allowed: ["Read", "Grep", "mcp__support__*"],
denied: ["Bash(rm:*)"],
},
});

The exact schema is in the lobu.config.ts reference.

Keep identity short and concrete.

You are Aria, Acme's customer support agent.
You specialize in billing, account access, and product troubleshooting.

Put durable automation here:

# Working rules
- Be concise and professional.
- Understand the problem before proposing an action.
- Confirm before cancellations, refunds, or account changes.
- Never invent account data.
- Escalate when the user requests a human.

Use this for shared context that should enter every turn:

# Deployment context
- Company: Acme
- Default timezone: Europe/London
- Support plan: Enterprise

Do not use USER.md as a substitute for live source data or shared entity memory.

  • Skills package reusable procedures as instruction text.
  • Tool policy controls visibility and MCP pre-approval patterns.
  • Guardrails inspect input, output, and tool calls independently of the prompt.
  • Network policy controls which domains the worker can reach.
  • Nix packages install native tools in the worker environment (agent config only).

Skills are instruction text only — they cannot grant themselves packages, network access, or authority. See Skills, Tool policy, and Guardrails.

The checked-in directory is a template. At runtime, each user, DM, channel, or task gets its own worker workspace.

  • New workspaces start from the same agent template.
  • Files created inside one workspace stay private to that workspace.
  • Durable knowledge belongs in shared memory.
  • Inference provider and execution environment are independent choices.

See Concepts and architecture.

Keep regression tests next to the agent and run them after changes to prompts, skills, model routing, retrieval, tools, or guardrails.

See Evaluations.

Send a prompt directly from your terminal:

Terminal window
npx @lobu/cli@latest chat "Hello, what can you do?"
npx @lobu/cli@latest chat "What's on my calendar?" --thread my-test
npx @lobu/cli@latest chat "Hello" --agent support --dry-run

Route through a connected platform with --user:

Terminal window
npx @lobu/cli@latest chat "Hello" --user telegram:12345
npx @lobu/cli@latest chat "Hello" --user slack:C0123ABCD

The response appears on the platform and streams to your terminal. See the lobu chat CLI reference for all flags.

@lobu/client is the typed TypeScript SDK. Create a session, send a message, stream the reply:

import { Lobu } from "@lobu/client";
const lobu = new Lobu({
baseUrl: "http://localhost:8787/lobu",
token: process.env.LOBU_API_TOKEN!,
});
const session = await lobu.sessions.create({ agentId: "my-agent" });
const { text } = await session.ask("What changed this week?");

For streaming, use session.send() + session.events() (an async iterable of SSE events). Mint sessions server-side — never let an untrusted browser pick worker config. See the SDK examples for full patterns including streaming, error handling, and long-lived sessions.