windlass.agent¶
agent
¶
Agents — models that use tools to accomplish goals.
Start with :func:windlass.Windlass.agent, which returns an
:class:~windlass.agent.builder.AgentBuilder::
from windlass import Windlass, tool
@tool
def search(query: str) -> list[str]:
'''Search the knowledge base.'''
return kb.search(query)
agent = Windlass.agent().llm("openai").tool(search).memory()
print(agent.run("What changed in the API last quarter?"))
The pieces:
- :class:
~windlass.agent.builder.AgentBuilder— the fluent API. - :class:
~windlass.agent.runtime.AgentRuntime— the built-in reason/act loop, with no dependencies. - :class:
~windlass.agent.graph.LangGraphRuntime— LangGraph-backed execution, for conditional routing and subgraphs. - :class:
~windlass.agent.supervisor.Supervisor— multi-agent delegation. - :mod:
~windlass.agent.checkpoint— durable state for resume and human-in-the-loop.
AgentBuilder
¶
Fluent builder for an agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container
|
Container | None
|
Dependency container. Defaults to a child of the process root. |
None
|
Example
Level 1 — a working agent in two lines, no dependencies::
agent = Windlass.agent().llm("fake", responses=["Hello!"])
print(agent.run("Say hello"))
Level 2 — a real agent::
agent = (Windlass.agent()
.llm("anthropic", model="claude-sonnet-4-5")
.tool(search).tool(calculator)
.system("You are a research assistant. Cite your sources.")
.memory("summary")
.guardrails(pii=True, on_violation="redact")
.checkpoint("sqlite", path="./state.db")
.max_iterations(15)
.observe("langfuse"))
Level 3 — a graph you control::
agent = Windlass.agent().llm("openai").tool(search).graph()
graph = agent.native_graph()
graph.add_node("critic", critic_fn)
graph.add_edge("tools", "critic")
agent.recompile()
Source code in src\windlass\agent\builder.py
llm
¶
Choose the reasoning model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Provider options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Example
from windlass import Windlass _ = Windlass.agent().llm("gpt-4o-mini", temperature=0)
Source code in src\windlass\agent\builder.py
tool
¶
Bind one or more tools.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*tools
|
Any
|
:class: |
()
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
When an argument cannot be interpreted as a tool. |
Example
from windlass import Windlass, tool @tool ... def now() -> str: ... '''Return the current time.''' ... return "12:00" _ = Windlass.agent().tool(now)
Source code in src\windlass\agent\builder.py
tools
¶
mcp
¶
Connect an MCP server and bind its tools.
Call it repeatedly to connect several servers; their tools are namespaced by server name so identically-named tools do not collide.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Transport options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Example
from windlass import Windlass _ = Windlass.agent().mcp(server="fs", command="npx", ... args=["-y", "@modelcontextprotocol/server-filesystem", "."])
Source code in src\windlass\agent\builder.py
memory
¶
Attach conversation memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Memory options. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\agent\builder.py
guardrails
¶
Enable input and output guardrails.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Policy options. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\agent\builder.py
observe
¶
Enable tracing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Tracer options. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\agent\builder.py
checkpoint
¶
Enable durable state, resume and human-in-the-loop approval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Checkpointer options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Note
Approval interrupts require a checkpointer, since a paused run has to be stored somewhere before it can be resumed.
Source code in src\windlass\agent\builder.py
agent
¶
Add a specialist, turning this into a supervisor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name the supervisor uses to delegate. |
required |
worker
|
Any
|
An agent, builder, or anything with |
required |
description
|
str
|
What the specialist is good at. The supervisor routes on this text. |
''
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Example
from windlass import Windlass _ = (Windlass.agent().llm("fake") ... .agent("researcher", Windlass.agent().llm("fake"), ... "Finds and summarises source material."))
Source code in src\windlass\agent\builder.py
system
¶
Set the system prompt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt
|
str
|
Instructions prepended to every run. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
name
¶
max_iterations
¶
Set the reason/act step budget.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int
|
Maximum cycles before
:class: |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src\windlass\agent\builder.py
tool_call_retries
¶
Set how often a run may recover from an unparseable tool call.
Models occasionally emit a tool call the provider cannot parse — most often by nesting one call inside another's arguments, which the tool-calling protocol has no way to express. Windlass shows the model the problem and lets it retry, the same way it handles an invented tool name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int
|
Maximum corrections per run. Each one costs an iteration from
:meth: |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
from windlass import Windlass _ = Windlass.agent().llm("fake").tool_call_retries(3)
Source code in src\windlass\agent\builder.py
parallel_tools
¶
Control whether simultaneous tool calls run concurrently.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enabled
|
bool
|
False forces serial execution — occasionally necessary when tools share mutable state. |
True
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\agent\builder.py
human_in_the_loop
¶
Require human approval before every tool call.
Individual tools can require approval on their own with
@tool(requires_approval=True); this turns it on globally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enabled
|
bool
|
True to pause before every tool call. |
True
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Note
Implies a checkpointer, since a paused run has to be stored. One is enabled automatically if you have not chosen one.
Source code in src\windlass\agent\builder.py
graph
¶
Use the LangGraph runtime instead of the built-in loop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enabled
|
bool
|
True to compile the agent into a LangGraph state machine. |
True
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Raises:
| Type | Description |
|---|---|
MissingDependencyError
|
At build time, when |
Source code in src\windlass\agent\builder.py
bind
¶
Bind an arbitrary dependency into this builder's container.
Source code in src\windlass\agent\builder.py
build
¶
Resolve every component and construct the runtime.
Called automatically on first use.
Returns:
| Name | Type | Description |
|---|---|---|
An |
AgentRuntime
|
class: |
AgentRuntime
|
class: |
|
AgentRuntime
|
class: |
|
AgentRuntime
|
configuration describes. |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
When a component cannot be constructed. |
MissingDependencyError
|
When a chosen provider's extra is missing. |
Source code in src\windlass\agent\builder.py
run
¶
arun
async
¶
stream
¶
Stream the run. See :meth:~windlass.agent.runtime.AgentRuntime.stream.
astream
¶
astream_text
¶
resume
¶
aresume
async
¶
pending_approvals
¶
state
¶
history
¶
broadcast
¶
Run every specialist on the same task (supervisor only).
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
When no specialists are configured. |
Source code in src\windlass\agent\builder.py
pipeline
¶
Chain specialists in sequence (supervisor only).
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
When no specialists are configured. |
Source code in src\windlass\agent\builder.py
native_llm
¶
native_graph
¶
Return the LangGraph StateGraph.
Raises:
| Type | Description |
|---|---|
AgentError
|
When the agent was not built with :meth: |
recompile
¶
Recompile the graph after editing it.
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
When the agent is not graph-backed. |
Source code in src\windlass\agent\builder.py
describe
¶
Checkpointer
¶
Bases: ABC
Stores and retrieves agent state by thread.
Implementations must be safe to use from multiple threads, since one agent instance typically serves many concurrent conversations.
put
abstractmethod
¶
Save a state snapshot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thread_id
|
str
|
Conversation / run identifier. |
required |
state
|
dict[str, Any]
|
JSON-serialisable state. |
required |
Raises:
| Type | Description |
|---|---|
SerializationError
|
When the state cannot be stored. |
Source code in src\windlass\agent\checkpoint.py
get
abstractmethod
¶
history
abstractmethod
¶
Return recent snapshots, newest first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thread_id
|
str
|
Conversation identifier. |
required |
limit
|
int
|
Maximum snapshots to return. |
20
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
Snapshots, newest first. |
Source code in src\windlass\agent\checkpoint.py
delete
abstractmethod
¶
MemoryCheckpointer
¶
Bases: Checkpointer
Keeps checkpoints in a dict.
Fast and dependency-free, but per-process and lost on restart. Right for tests, notebooks and single-process services; wrong for anything that needs a resumed run to survive a deploy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_history
|
int
|
Snapshots retained per thread. Older ones are dropped. |
50
|
Example
saver = MemoryCheckpointer() saver.put("t", {"step": 1}) saver.put("t", {"step": 2}) saver.get("t")["step"], len(saver.history("t")) (2, 2)
Source code in src\windlass\agent\checkpoint.py
put
¶
Append a snapshot, trimming the oldest beyond max_history.
Source code in src\windlass\agent\checkpoint.py
get
¶
Return the newest snapshot, or None.
history
¶
Return recent snapshots, newest first.
delete
¶
SQLiteCheckpointer
¶
Bases: Checkpointer
Persists checkpoints to a SQLite database.
Survives restarts and is shared between processes on one machine — enough for a single-node deployment, and it needs nothing beyond the standard library.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Database file. Parent directories are created. |
'.windlass/checkpoints.db'
|
max_history
|
int
|
Snapshots retained per thread. |
50
|
Raises:
| Type | Description |
|---|---|
SerializationError
|
When the database cannot be opened. |
Note
Each call opens its own connection. That costs a little per write and buys thread safety without a connection pool — the right trade at the rate an agent checkpoints.
Example
import tempfile, pathlib db = pathlib.Path(tempfile.mkdtemp()) / "state.db" saver = SQLiteCheckpointer(db) saver.put("t", {"step": 7}) SQLiteCheckpointer(db).get("t")["step"] 7
Source code in src\windlass\agent\checkpoint.py
put
¶
Insert a snapshot and prune old ones.
Raises:
| Type | Description |
|---|---|
SerializationError
|
When the state is not JSON-serialisable or the write fails. |
Source code in src\windlass\agent\checkpoint.py
get
¶
history
¶
Return recent snapshots, newest first.
Source code in src\windlass\agent\checkpoint.py
delete
¶
Discard a thread's snapshots.
Source code in src\windlass\agent\checkpoint.py
threads
¶
Return the known thread ids.
Source code in src\windlass\agent\checkpoint.py
close
¶
AgentRuntime
¶
AgentRuntime(
*,
llm: LLM,
tools: ToolRegistry | Sequence[Any] | None = None,
system_prompt: str | None = None,
max_iterations: int = 10,
memory: Memory | None = None,
guardrail: Guardrail | None = None,
checkpointer: Checkpointer | None = None,
tracer: Tracer | None = None,
parallel_tools: bool = True,
require_approval: bool = False,
max_tool_call_retries: int = 2,
name: str = "agent"
)
A tool-calling agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
llm
|
LLM
|
The reasoning model. Must support tool calling if tools are bound. |
required |
tools
|
ToolRegistry | Sequence[Any] | None
|
Tools the agent may call. |
None
|
system_prompt
|
str | None
|
Instructions prepended to every run. |
None
|
max_iterations
|
int
|
Ceiling on reason/act cycles. Prevents a confused agent from looping until your budget runs out. |
10
|
memory
|
Memory | None
|
Optional conversation memory, keyed by |
None
|
guardrail
|
Guardrail | None
|
Optional input/output policy. |
None
|
checkpointer
|
Checkpointer | None
|
Optional durable state, enabling resume and time travel. |
None
|
tracer
|
Tracer | None
|
Observability backend. |
None
|
parallel_tools
|
bool
|
Execute simultaneous tool calls concurrently. |
True
|
require_approval
|
bool
|
Pause before every tool call, not just those whose
tools declare |
False
|
max_tool_call_retries
|
int
|
How many times a run may recover from the model
emitting an unparseable tool call before giving up. Each recovery
costs one iteration from |
2
|
name
|
str
|
Agent name, used in traces and multi-agent routing. |
'agent'
|
Attributes:
| Name | Type | Description |
|---|---|---|
tools |
The bound :class: |
|
name |
The agent's name. |
Raises:
| Type | Description |
|---|---|
AgentError
|
When tools are bound to a model that cannot call them. |
Source code in src\windlass\agent\runtime.py
arun
async
¶
arun(
prompt: Any,
*,
thread_id: str | None = None,
max_iterations: int | None = None,
**llm_kwargs: Any
) -> AgentResponse
Run the agent to completion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt
|
Any
|
A string, a message, or a full transcript. |
required |
thread_id
|
str | None
|
Conversation thread. Required to use memory or checkpointing across calls; generated when omitted. |
None
|
max_iterations
|
int | None
|
Override for the step budget. |
None
|
**llm_kwargs
|
Any
|
Per-call model overrides. |
{}
|
Returns:
| Type | Description |
|---|---|
AgentResponse
|
The answer, transcript, per-step trace and aggregate usage. |
Raises:
| Type | Description |
|---|---|
MaxIterationsExceeded
|
When the budget runs out before an answer. |
InterruptedError_
|
When a tool needs human approval. Resume with
:meth: |
GuardrailViolation
|
When a guardrail blocks the input or output. |
AgentError
|
When the run cannot proceed. |
Performance
One model call per iteration, plus tool time. Independent tool calls in the same turn run concurrently, which is usually where the wall clock is won.
Example
import asyncio from windlass import Windlass agent = Windlass.agent().llm("fake", responses=["Done."]) asyncio.run(agent.arun("Say done.")).output 'Done.'
Source code in src\windlass\agent\runtime.py
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | |
run
¶
run(
prompt: Any,
*,
thread_id: str | None = None,
max_iterations: int | None = None,
**llm_kwargs: Any
) -> AgentResponse
Blocking :meth:arun.
Source code in src\windlass\agent\runtime.py
astream
async
¶
astream(
prompt: Any, *, thread_id: str | None = None, **llm_kwargs: Any
) -> AsyncIterator[StreamEvent]
Stream the agent's work as it happens.
You get text deltas as the model produces them, tool_call events
when it decides to act, and a final done. That is what a live agent
UI needs: users tolerate latency far better when they can see progress.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt
|
Any
|
A string, a message, or a full transcript. |
required |
thread_id
|
str | None
|
Conversation thread. |
None
|
**llm_kwargs
|
Any
|
Per-call model overrides. |
{}
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[StreamEvent]
|
class: |
Raises:
| Type | Description |
|---|---|
MaxIterationsExceeded
|
When the budget runs out. |
Source code in src\windlass\agent\runtime.py
stream
¶
astream_text
async
¶
Stream only the assistant's text — the common case for a chat UI.
Source code in src\windlass\agent\runtime.py
aresume
async
¶
aresume(
thread_id: str,
*,
approved: bool = True,
feedback: str = "",
edited_arguments: dict[str, dict[str, Any]] | None = None,
**llm_kwargs: Any
) -> AgentResponse
Resume a run that paused for human approval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thread_id
|
str
|
The thread reported on the :class: |
required |
approved
|
bool
|
True to execute the pending calls, False to reject them. |
True
|
feedback
|
str
|
Message shown to the model when rejecting, so it can try a different approach instead of simply repeating itself. |
''
|
edited_arguments
|
dict[str, dict[str, Any]] | None
|
Replacement arguments keyed by tool-call id. This is the "human edits the action" case — approve the intent, fix the parameters. |
None
|
**llm_kwargs
|
Any
|
Per-call model overrides. |
{}
|
Returns:
| Type | Description |
|---|---|
AgentResponse
|
The completed run. |
Raises:
| Type | Description |
|---|---|
AgentError
|
When there is no checkpoint, or nothing was pending. |
Example
from windlass import Windlass, tool, AgentInterrupt @tool(requires_approval=True) ... def deploy(env: str) -> str: ... '''Deploy to an environment.''' ... return f"deployed to {env}" agent = (Windlass.agent() ... .llm("fake", responses=["", "Deployed."], ... tool_calls=[[ToolCall(name="deploy", ... arguments={"env": "prod"})], []]) ... .tool(deploy).checkpoint()) try: ... agent.run("Deploy to prod", thread_id="t1") ... except AgentInterrupt as pause: ... resumed = agent.resume("t1", approved=True) resumed.output 'Deployed.'
Source code in src\windlass\agent\runtime.py
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | |
resume
¶
pending_approvals
¶
Return the tool calls awaiting approval on a thread.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thread_id
|
str
|
The thread to inspect. |
required |
Returns:
| Type | Description |
|---|---|
list[ToolCall]
|
The pending calls, or |
Source code in src\windlass\agent\runtime.py
state
¶
history
¶
Return recent checkpoints for a thread, newest first.
native_llm
¶
native_graph
¶
Return the underlying execution graph.
The built-in runtime has no graph — it is a loop. Use .graph() on the
agent builder to get a LangGraph-backed runtime whose native_graph()
returns a real StateGraph you can add nodes and edges to.
Raises:
| Type | Description |
|---|---|
AgentError
|
Always, explaining how to get a real graph. |
Source code in src\windlass\agent\runtime.py
describe
¶
Return a JSON-safe description of the agent's configuration.
Source code in src\windlass\agent\runtime.py
aclose
async
¶
Release resources held by the model and any MCP connections.
Source code in src\windlass\agent\runtime.py
AgentTool
¶
Bases: Tool
Exposes an agent as a tool the supervisor can call.
This is what makes delegation work with ordinary tool calling: the supervisor does not need a special routing mechanism, because a worker is a tool from its point of view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent
|
Any
|
The worker agent, or anything with an |
required |
name
|
str
|
Tool name the supervisor sees. Should say what the worker is for. |
required |
description
|
str
|
What this specialist is good at. The supervisor routes on this text, so it deserves the same care as a prompt. |
''
|
**config
|
Any
|
Forwarded to :class: |
{}
|
Example
from windlass import Windlass worker = Windlass.agent().llm("fake", responses=["done"]) t = AgentTool(worker, name="helper", description="Does small jobs.") t.run(task="tidy up").content 'done'
Source code in src\windlass\agent\supervisor.py
acall
async
¶
Run the worker agent on the delegated task.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Any
|
Must contain |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
The worker's output text. |
Raises:
| Type | Description |
|---|---|
AgentError
|
When the worker fails. |
Source code in src\windlass\agent\supervisor.py
Supervisor
¶
Supervisor(
*,
llm: LLM,
agents: dict[str, Any] | None = None,
descriptions: dict[str, str] | None = None,
system_prompt: str | None = None,
max_iterations: int = 10,
tools: list[Any] | None = None,
tracer: Tracer | None = None,
**kwargs: Any
)
Bases: AgentRuntime
An agent that delegates to specialist agents.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
llm
|
LLM
|
The coordinating model. It only routes and summarises, so a mid-sized model is usually the right call. |
required |
agents
|
dict[str, Any] | None
|
Workers, keyed by the name the supervisor will use. Values may
be :class: |
None
|
descriptions
|
dict[str, str] | None
|
What each worker is for, keyed by the same names. Falls back to the worker's own description. |
None
|
system_prompt
|
str | None
|
Override for the routing instructions. |
None
|
max_iterations
|
int
|
Ceiling on routing rounds. |
10
|
tools
|
list[Any] | None
|
Tools the supervisor may call itself, alongside its workers. |
None
|
tracer
|
Tracer | None
|
Observability backend. |
None
|
**kwargs
|
Any
|
Forwarded to :class: |
{}
|
Raises:
| Type | Description |
|---|---|
AgentError
|
When no workers are supplied. |
Performance
Workers requested in the same turn run concurrently, so a supervisor that fans out to three specialists waits for the slowest, not the sum.
Source code in src\windlass\agent\supervisor.py
add_agent
¶
Add a specialist after construction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name the supervisor will use. |
required |
agent
|
Any
|
The worker. |
required |
description
|
str
|
What it is good at. |
''
|
Returns:
| Type | Description |
|---|---|
Supervisor
|
|
Source code in src\windlass\agent\supervisor.py
abroadcast
async
¶
Run every specialist on the same task, concurrently.
Useful for ensembling — ask three specialists the same question and compare — and for fan-out work where every worker has something to contribute.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
str
|
The task to send to every worker. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, AgentResponse]
|
A |
dict[str, AgentResponse]
|
reported as an error response rather than raising, so one failure |
dict[str, AgentResponse]
|
does not lose the others' work. |
Example
import asyncio from windlass import Windlass boss = Supervisor( ... llm=Windlass.llm("fake"), ... agents={"a": Windlass.agent().llm("fake", responses=["A"])}, ... ) asyncio.run(boss.abroadcast("go"))["a"].output 'A'
Source code in src\windlass\agent\supervisor.py
broadcast
¶
apipeline
async
¶
Chain specialists in sequence, each seeing the previous output.
The other multi-agent shape: research → draft → edit, where each stage genuinely depends on the last.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
str
|
The initial task. |
required |
order
|
list[str]
|
Worker names, in execution order. |
required |
Returns:
| Type | Description |
|---|---|
AgentResponse
|
The final worker's response, with every stage recorded in |
AgentResponse
|
attr: |
Raises:
| Type | Description |
|---|---|
AgentError
|
When a named worker does not exist. |
Example
import asyncio from windlass import Windlass boss = Supervisor( ... llm=Windlass.llm("fake"), ... agents={ ... "draft": Windlass.agent().llm("fake", responses=["a draft"]), ... "edit": Windlass.agent().llm("fake", responses=["an edit"]), ... }, ... ) asyncio.run(boss.apipeline("write", ["draft", "edit"])).output 'an edit'
Source code in src\windlass\agent\supervisor.py
pipeline
¶
describe
¶
Return a JSON-safe description including the roster.