Services
The three entry points: the Tier-1 one-liner, the Tier-2 typed builder, and the base class for custom agents.
Korch
Korch(
*,
settings: Settings | None = None,
model_gateway: IModelGateway | None = None,
runtime: IDurableRuntime | None = None,
router: BaseRouter | None = None,
repository: GraphRepository | None = None,
middleware: Sequence[Middleware] = (),
connectors: Sequence[Connector]
| ConnectorRegistry
| None = None,
)
The one-liner entry point to durable multi-agent execution.
Constructing Korch wires the object graph: each collaborator is taken as given, or resolved
from Settings once, here. With no arguments and no environment it runs locally with MockLM,
the in-process runtime, and in-memory persistence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings | None
|
Explicit settings; resolved from the environment when omitted. |
None
|
model_gateway
|
IModelGateway | None
|
The gateway to inject; resolved from config when omitted. |
None
|
runtime
|
IDurableRuntime | None
|
The durable runtime to inject; resolved from config when omitted. |
None
|
router
|
BaseRouter | None
|
The model router to inject; resolved from config when omitted. |
None
|
repository
|
GraphRepository | None
|
The graph repository to inject; resolved from config when omitted. |
None
|
middleware
|
Sequence[Middleware]
|
Middleware fired around each superstep, in registration order. |
()
|
connectors
|
Sequence[Connector] | ConnectorRegistry | None
|
Tools available to the Architect's plan (ADR 0015) — a
:class: |
None
|
Example
from korchestrator import Korch korch = Korch() korch.run("Summarize durable agent execution") # doctest: +SKIP
Store the (optionally injected) collaborators; resolution happens on first use.
cancel
cancel(run_id: str) -> None
Cancel run_id; it terminates with RunStatus.CANCELLED.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On the local runtime. |
MissingExtraError
|
If the Temporal runtime is selected without the |
edit_resume
edit_resume(
run_id: str,
*,
updates: Mapping[str, JSONValue] | None = None,
trust_delta: float = 0.0,
) -> None
Apply an operator's context/trust edit to a paused run, then resume it.
Goes through the same reducer discipline the barrier itself uses (last-value merge for
updates, a clamped fold for trust_delta) — an edit is as replayable and auditable
as an agent's own update.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
The paused run to edit and resume. |
required |
updates
|
Mapping[str, JSONValue] | None
|
Context-channel values to merge into the paused state. |
None
|
trust_delta
|
float
|
Folded into |
0.0
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On the local runtime. |
MissingExtraError
|
If the Temporal runtime is selected without the |
on
on(event: str, handler: EventHandler) -> Self
Register handler for event (e.g. "superstep"); returns self.
pause
pause(run_id: str) -> None
Signal run_id to pause for human review (durable HITL, spec 06 §7).
A paused run consumes no compute while it awaits resume, edit_resume, or
cancel, bounded by a 24h deadline after which it times out. Governance also triggers
this automatically when trust drops below the configured threshold — this method is for an
operator-initiated pause.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On the local runtime, which is synchronous and has no in-flight
run to pause. Use |
MissingExtraError
|
If the Temporal runtime is selected without the |
resume
resume(run_id: str) -> None
Lift a pause and let run_id continue from its checkpointed state.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On the local runtime. |
MissingExtraError
|
If the Temporal runtime is selected without the |
run
run(
objective: str, *, max_supersteps: int = 10
) -> RunResult
Run a swarm against objective and return the terminal :class:RunResult.
Classifies the objective, has the Architect plan a team of agents, and drives the plan through the kernel and the configured runtime.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
objective
|
str
|
The goal, at least 10 characters. |
required |
max_supersteps
|
int
|
Hard halt bound. Defaults to 10. |
10
|
Returns:
| Type | Description |
|---|---|
RunResult
|
The terminal :class: |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If |
MissingExtraError
|
If reasoning is used without the |
Example
from korchestrator import Korch Korch().run("Summarize durable agent execution") # doctest: +SKIP
Swarm
Swarm(
objective: str,
*,
settings: Settings | None = None,
model_gateway: IModelGateway | None = None,
runtime: IDurableRuntime | None = None,
router: BaseRouter | None = None,
repository: GraphRepository | None = None,
middleware: Sequence[Middleware] = (),
connectors: Sequence[Connector]
| ConnectorRegistry
| None = None,
)
A typed, explicitly constructed agent swarm.
Build the topology with :meth:add and :meth:edges (both return Self so chaining
type-checks), then :meth:run it. Collaborators are optional and resolved from Settings
at the composition root when omitted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
objective
|
str
|
The goal, at least 10 characters. |
required |
settings
|
Settings | None
|
Explicit settings; resolved from the environment when omitted. |
None
|
model_gateway
|
IModelGateway | None
|
The gateway to inject; resolved from config when omitted. |
None
|
runtime
|
IDurableRuntime | None
|
The durable runtime to inject; resolved from config when omitted. |
None
|
router
|
BaseRouter | None
|
The model router to inject; resolved from config when omitted. |
None
|
repository
|
GraphRepository | None
|
The graph repository to inject; resolved from config when omitted. |
None
|
middleware
|
Sequence[Middleware]
|
Middleware fired around each superstep, in registration order. |
()
|
connectors
|
Sequence[Connector] | ConnectorRegistry | None
|
Tools available to agents in this swarm (ADR 0015) — a
:class: |
None
|
Example
from korchestrator import Agent, Swarm swarm = ( ... Swarm(objective="Review this PR for security and performance") ... .add(Agent(id="security", role="security-reviewer")) ... .add(Agent(id="lead", role="review-lead")) ... .edges([("security", "lead")]) ... ) swarm.size 2
Start an empty swarm for objective; store optionally injected collaborators.
size
property
size: int
The number of agents added to the swarm.
add
add(agent: Agent) -> Self
Add an agent to the swarm and return self for chaining.
Raises:
| Type | Description |
|---|---|
ValidationError
|
If an agent with this |
cancel
cancel(run_id: str) -> None
Cancel run_id; it terminates with RunStatus.CANCELLED.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On the local runtime. |
MissingExtraError
|
If the Temporal runtime is selected without the |
edges
edges(edges: list[tuple[str, str]]) -> Self
Declare directed edges (from_id, to_id) and return self for chaining.
edit_resume
edit_resume(
run_id: str,
*,
updates: Mapping[str, JSONValue] | None = None,
trust_delta: float = 0.0,
) -> None
Apply an operator's context/trust edit to a paused run, then resume it.
Goes through the same reducer discipline the barrier itself uses (last-value merge for
updates, a clamped fold for trust_delta) — an edit is as replayable and auditable
as an agent's own update.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
The paused run to edit and resume. |
required |
updates
|
Mapping[str, JSONValue] | None
|
Context-channel values to merge into the paused state. |
None
|
trust_delta
|
float
|
Folded into |
0.0
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On the local runtime. |
MissingExtraError
|
If the Temporal runtime is selected without the |
on
on(event: str, handler: EventHandler) -> Self
Register handler for event (e.g. "superstep"); returns self.
pause
pause(run_id: str) -> None
Signal run_id to pause for human review (durable HITL, spec 06 §7).
A paused run consumes no compute while it awaits resume, edit_resume, or
cancel, bounded by a 24h deadline after which it times out. Governance also triggers
this automatically when trust drops below the configured threshold — this method is for an
operator-initiated pause.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On the local runtime, which is synchronous and has no in-flight
run to pause. Use |
MissingExtraError
|
If the Temporal runtime is selected without the |
resume
resume(run_id: str) -> None
Lift a pause and let run_id continue from its checkpointed state.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On the local runtime. |
MissingExtraError
|
If the Temporal runtime is selected without the |
run
run(*, max_supersteps: int = 10) -> RunResult
Run the swarm's declared topology to a terminal :class:RunResult.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_supersteps
|
int
|
Hard halt bound. Defaults to 10. |
10
|
Returns:
| Type | Description |
|---|---|
RunResult
|
The terminal :class: |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If the objective is too short, |
MissingExtraError
|
If reasoning is used without the |
Example
from korchestrator import Agent, Swarm swarm = Swarm(objective="Summarize the design").add(Agent(id="lead", role="lead")) swarm.run(max_supersteps=5) # doctest: +SKIP
Agent
Agent(
id: str,
*,
role: str,
model: str | None = None,
tools: tuple[str, ...] = (),
goal: str = "",
backstory: str = "",
max_react_steps: int = 3,
hitl_threshold: float | None = None,
timeout_seconds: float = 120.0,
)
A single agent in a swarm — declarative by default, subclassable for custom behaviour.
Construct it declaratively and the framework supplies the reasoning::
Agent(id="security", role="security-reviewer", model="gpt-4o")
or subclass it and override :meth:think for a fully custom agent::
class WordCountAgent(Agent):
async def think(self, state: AgentState) -> StateUpdate:
...
Frozen-snapshot contract (spec 06 §5): :meth:think MUST NOT mutate state (it is a frozen
model, so mutation raises), MUST NOT call datetime.now() — use :attr:clock — MUST NOT read
another agent's output from the same superstep, and MUST return within timeout_seconds.
Returning halt=True permanently deactivates the node.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id
|
str
|
The agent's identifier, matching |
required |
role
|
str
|
The persona's role, e.g. |
required |
model
|
str | None
|
The model to route this agent to, or |
None
|
tools
|
tuple[str, ...]
|
Names of tools mounted on this agent. |
()
|
goal
|
str
|
The persona's goal. |
''
|
backstory
|
str
|
The persona's backstory. |
''
|
max_react_steps
|
int
|
Bound on the ReAct loop, 0-10. |
3
|
hitl_threshold
|
float | None
|
Per-agent trust threshold for human-in-the-loop, 0.0-1.0, or |
None
|
timeout_seconds
|
float
|
Per-agent wall-clock budget. |
120.0
|
Raises:
| Type | Description |
|---|---|
ValidationError
|
If any input fails validation (e.g. an |
Example
from korchestrator import Agent agent = Agent(id="lead", role="review-lead") agent.id 'lead' agent.config.persona.role 'review-lead'
Validate the inputs into an immutable :class:AgentConfig; start with no clock bound.
clock
property
clock: _BoundClock
The injected replay-safe clock; use self.clock.now() inside :meth:think.
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
If no clock has been bound. The runtime binds one via :meth: |
config
property
config: AgentConfig
The immutable :class:AgentConfig this agent was validated into.
id
property
id: str
The agent's identifier.
persona
property
persona: AgentPersona
The agent's static persona.
bind
bind(
*,
clock: Clock,
gateway: IModelGateway | None = None,
tool_invoker: IToolInvoker | None = None,
) -> Self
Inject the replay-safe clock and optional collaborators; return self.
Called by the composition root before a run. The clock is the same injected
Callable[[], datetime] the kernel uses, so an agent's timestamps stay replay-safe. The
gateway is used by reasoning agents (e.g. :class:~korchestrator.agents.WorkerAgent);
tool_invoker is used by a reasoning agent with AgentConfig.tools mounted (P10.2).
Agents that do not need either ignore them.
is_complete
is_complete(state: AgentState) -> bool
Whether this agent considers its work finished, given state.
The default is False; reasoning agents override it to signal they have reached a final
answer and should halt. It never mutates state.
think
async
think(state: AgentState) -> StateUpdate
Turn a frozen state snapshot into this agent's :class:StateUpdate delta.
The base implementation raises — a declaratively-constructed agent has no reasoning of its own until the façade supplies the default reasoning agent (P4.9), and a custom agent must override this method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
AgentState
|
An immutable snapshot of the shared state. MUST NOT be mutated. |
required |
Returns:
| Type | Description |
|---|---|
StateUpdate
|
This agent's :class: |
to_node
to_node() -> Node
Materialise this agent as a kernel :class:~korchestrator.core.graph.Node.
Returns:
| Name | Type | Description |
|---|---|---|
A |
Node
|
class: |
Node
|
ready to place in an :class: |