Skip to content

Architecture ​

bread turns a directory of agent folders into a running, observable HTTP service. This page maps the moving parts.

Packages ​

PackageResponsibility
@breadai/coreSDK: defineAgent/defineTool/…, the runner, sessions, KG/documents, checkpoints, plugins, types
@breadai/serverFile-system loader + Hono server (importable library)
@breadai/cliThe bread binary
@breadai/runtime-bun, @breadai/runtime-nodeListen adapters (Bun.serve / @hono/node-server); CLI selects via --runtime / config.server.runtime
@breadai/store-postgres, @breadai/store-sqlite, @breadai/store-memoryBreadStore backends — see store.md
@breadai/provider-llmThe 21 language-model providers as a ProviderRegistry. @breadai/provider-catalog re-exports it — see providers.md
@breadai/provider-decisionsSystem One hosts as a DecisionRegistry for config.decisions — see decisions.md
@breadai/otel, @breadai/protocol-ag-ui, @breadai/protocol-a2a-server, @breadai/a2ui, @breadai/protocol-mcp-client, @breadai/protocol-mcp-serverPlugins
@breadai/auth-api-key, @breadai/auth-jwt, @breadai/auth-oauth2, @breadai/auth-trustedStandalone BreadAuthStrategy/BreadSigner factories — not plugins themselves; wrap with @breadai/server's authPlugin() to attach — see auth.md
@breadai/transport-http-chunked, @breadai/transport-http-sseHTTP ingress BreadTransports — mount() the four streaming routes + remoteAgent() for config.remoteAgents (transports/http-chunked, transports/http-sse) — see transports.md
@breadai/transport-redisRedis Streams BreadTransport — cross-replica crumb fan-out, no mount (transports/redis)
@breadai/transport-stdoutTerminal-rendering BreadTransport (sink) for bread chat/bread invoke (transports/stdout)

Package families ​

Beyond packages/* (core/server/cli), everything installable lives in one of five workspace folders, each with its own @breadai/* npm prefix:

Foldernpm packagesCovers
stores/@breadai/store-postgres, @breadai/store-sqlite, @breadai/store-memoryBreadStore backends — see store.md
providers/@breadai/provider-llm, @breadai/provider-catalog, @breadai/provider-decisionsLanguage-model registries, plus the System One DecisionRegistry. provider-catalog re-exports provider-llm — see providers.md and decisions.md
protocols/@breadai/protocol-ag-ui, @breadai/protocol-a2a-server, @breadai/protocol-mcp-client, @breadai/protocol-mcp-serverWire-protocol adapters (BreadPlugins)
extensions/@breadai/otel, @breadai/a2ui (attach as BreadPlugins); @breadai/auth-api-key, @breadai/auth-jwt, @breadai/auth-oauth2, @breadai/auth-trusted (standalone auth factories, see auth.md)Observability, UI generation, auth strategies/signers
transports/@breadai/transport-http-chunked, @breadai/transport-http-sse, @breadai/transport-redis, @breadai/transport-stdoutBreadTransport implementations — see transports.md

Protocols and most extensions plug in through the same BreadPlugin mechanism (see plugins.md) — the folder split is a naming/discovery convention, not a second plugin system. The four @breadai/auth-* extensions are the one exception: they're standalone BreadAuthStrategy/BreadSigner factories, not BreadPlugins — see auth.md.

From folder to running service ​

The loader reads each agents/<id>/ folder, attaches prompt.md, tools/, and skills/ metadata onto the agent's config as private fields (_systemPrompt, _tools, _humanTools, _skills, _agentDir), and builds an AgentRegistry (Map<string, AgentDefinition>). createBread(config, agents, tasks) returns a BreadInstance; the server wraps it.

One crumb stream: the choke point ​

Every public stream (run, resume, runPipeline, sync mode) passes through one per-run choke point inside the instance. As each crumb is yielded it gets its per-run monotonic seq, is appended to the durable crumb log (text:deltas aggregated into windows), reaches local bread.on('crumb'/'human:required') listeners, and is published to the transport (config.transport — the embedded Stream by default, @breadai/transport-redis for multi-replica deployments). Nothing below the choke point emits anywhere, so the plugin view, the transport view, the log, and the NDJSON stream are the same well-defined stream. The store is truth (replay/Last-Event-ID catch-up); the transport is liveness. See transports.md.

Crumbs ​

A run is a stream of typed crumbs (the project lexicon — Crumb, Plugin — is defined in the glossary):

agent:run:start · text:delta · reasoning:delta · file:generated · tool:call · tool:input:start · tool:input:delta · tool:input:end · tool:result · tool:result:partial · tool:error · human:required · human:resumed · subagent:run:start · subagent:run:end · pipeline:step:start · pipeline:step:end · loop:start · loop:iteration:start · loop:iteration:end · loop:end · task:start · task:end · agent:run:end · agent:error.

A run that calls a human tool ends its stream at human:required; resume replays it from the store and returns the continuation starting with human:resumed.

The public instance surface ​

Ingresses (the HTTP server, @breadai/protocol-mcp-server, or your own) consume only the public BreadInstance API: run / resume / runPipeline / runTask, the bus and store getters, and the agents / tasks / pluginTools / credentials registries. The internal RunnerContext is exactly that — internal (@internal export for the CLI loader and tests only). See the "bring your own ingress" guide in transports.md.

Plugin lifecycle ​

See plugins.md for the BreadPlugin interface.

Storage ​

All state — sessions, HITL checkpoints, the knowledge graph, documents, and task-run audit records — persists through a single BreadStore interface, set as config.store. PostgreSQL is the recommended backend (@breadai/store-postgres's store() reads DATABASE_URL itself); SQLite (@breadai/store-sqlite, bun:sqlite) and in-memory implementations ship as alternatives, and any custom backend can be passed as store. Neither core nor the CLI bundles a driver, and nothing is wired implicitly — an unset store throws STORE_NOT_CONFIGURED. See store.md.

Released under the MIT License.