Agents and Orchestration
Choose the right SDK agent class, understand delegation boundaries, and wire orchestration surfaces safely in @namzu/sdk.
@namzu/sdk does not ship one monolithic "agent framework". It ships a small set of execution shapes that all sit on the same runtime primitives. The important design choice is to pick the smallest orchestration surface that matches your problem.
1. The Mental Model
Think about the public agent surfaces in two layers:
| Layer | Owns | Main exports |
|---|---|---|
| Agent class | how one run is executed | ReactiveAgent, PipelineAgent, RouterAgent, SupervisorAgent, defineAgent() |
| Orchestration runtime | how child work is provisioned, tracked, and persisted | AgentManager, LocalTaskGateway, invocation state, session hierarchy |
The classes are intentionally different:
ReactiveAgentis the default LLM-plus-tools loop.PipelineAgentis deterministic staged code, not iterative reasoning.RouterAgentselects a downstream route.SupervisorAgentlaunches and coordinates sub-agent tasks.
2. Which Agent Should You Start With?
| Surface | Best for | Requires |
|---|---|---|
ReactiveAgent | most apps, tool use, model-driven iteration | provider, tools, model, runtime IDs |
PipelineAgent | deterministic stages, validation, rollback | step functions, optional provider |
RouterAgent | one input must be routed to one target agent | provider, routes, compatible child-agent config shape |
SupervisorAgent | multi-agent task launch and coordination | provider plus either gateway or agentManager |
defineAgent() | custom wrappers around the SDK result contract | you own the entire run() implementation |
If you are unsure, start with ReactiveAgent. Move up only when the runtime has a real routing or task-delegation requirement.
3. Minimal ReactiveAgent Example
This example is intentionally offline-friendly. It uses MockLLMProvider, so it proves agent wiring without requiring a provider package:
Important boundary:
ReactiveAgent.run()is the high-level entrypoint.- If you need
verificationGate,sandboxProvider, custom event streaming, or other query-only fields, drop to Low-Level Runtime.
4. PipelineAgent Is for Deterministic Stages
PipelineAgent is the right fit when the execution graph is known ahead of time and you do not want an LLM deciding whether to call tools:
Use PipelineAgent when:
- you need validation and optional rollback per step
- you want deterministic ordering
- "agent reasoning" would only introduce noise
5. defineAgent() Is the Escape Hatch
Use defineAgent() when none of the built-in agent classes matches your runtime shape:
Use this surface carefully: once you choose defineAgent(), you own the run semantics and result assembly yourself.
6. RouterAgent and SupervisorAgent Need More Intentional Wiring
These two classes are powerful, but they are not the first step.
RouterAgent selection flow:
- build a route list
- ask a provider to choose an
agentId - fall back if parsing or confidence fails
- forward the current config into the chosen child agent
That last step matters. From the current implementation, RouterAgent forwards the config object it received to the selected child agent after updating invocationState. In practice, this means route targets should share a compatible config shape or be wrapped behind a factory/manager layer that normalizes config before delegation.
SupervisorAgent coordination flow:
- create coordinator tools
- launch child tasks through a
gatewayoragentManager - keep task handles and launched-task metadata
- run the parent loop through
drainQuery() - collect child task results into the final supervisor result
Current hard requirements:
SupervisorAgentrequiressessionId,projectId, andtenantId- it also requires either
gatewayoragentManager - if you want managed child spawning, pass
agentManager
7. What AgentManager Actually Owns
AgentManager is not just a task list. It owns the boring but critical orchestration work:
- child task creation and cancellation
- budget partitioning across spawned tasks
- lineage and sub-session provisioning
- event fan-out to listeners
- waiting, continuation, and cleanup
This is why SupervisorAgent becomes much more useful once a real AgentManager is present. The manager is where the orchestration runtime turns from "one run" into "an accountable hierarchy of runs".
8. Invocation State Is for Runtime Context, Not Prompt Text
InvocationState flows through agent hierarchies and is not shown to the model. Use it for:
- tenant-scoped services
- caches or database clients
- correlation IDs
- parent agent chains for tracing
Do not confuse it with persona or system prompt text. Prompt composition belongs in Skills and Personas.
9. Common Mistakes
| Mistake | Why it hurts |
|---|---|
reaching for SupervisorAgent too early | you inherit manager, gateway, and child-task concerns before you need them |
assuming RouterAgent builds child config for you | it routes; it does not magically normalize incompatible child-agent configs |
| putting hidden runtime data into the prompt | use InvocationState for internal runtime context instead |
expecting ReactiveAgent.run() to expose every kernel feature | query-only controls live in Low-Level Runtime |
treating defineAgent() as a shortcut | it is flexible, but you must assemble the full result contract correctly |