1. How it fits together
Browser ─► web/ (Next.js + CopilotKit, :3000)
│ GET /api/agents (which workflows exist — read from YAML)
│ POST /agui/{workflow} (AG-UI 1.0 over server-sent events)
▼
bo-app (Loco.rs, :8080) ── one binary: server, queue workers, scheduler, tasks
boot: config/agents/**.yaml ─► validate ─► compile into workflow graphs
run: parse ─► extract ─► validate ─► match ─► approval ─► post ─► done
│ │ │ │
docling-serve vLLM a person accounting connector
▼
PostgreSQL + pgvector: business data, checkpoints, approvals, hash-chained audit log, queue
- Behaviour is YAML. Workflows, prompts, extraction schemas, connectors, roles, policies and
per-tenant overrides live in
config/agents/. Changing a threshold or adding a workflow built from existing steps needs no Rust, only a restart. - Each step is a task kind, a small piece of Rust such as
llm.extractorhuman.approval, configured by the YAML node that uses it. - A mistake stops boot. A typo, an unknown step type, a reference to something that doesn't exist, a disallowed model license, or a payment reachable without approval each refuse to start the server, naming the file or node.