Autonomy API¶
autonomy ¶
Runtime agent spawning and tool discovery.
The autonomy module enables the orchestrator to design and spawn new agents at runtime. An LLM produces an AgentSpec (structured output describing an agent), and the AgentFactory hydrates it into a live BaseAgent. The ToolRegistry provides discoverable tools.
AgentFactory ¶
AgentFactory(
registry: ToolRegistry | None = None,
default_model: str = "openai:gpt-4.1",
api_key: str = "",
*,
tool_factory: DynamicToolFactory | None = None,
)
Creates live agents from AgentSpec definitions.
The factory resolves tools from the ToolRegistry and constructs Pydantic output models from JSON Schema at runtime.
Initialize with an optional registry, default model, and API key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
ToolRegistry | None
|
Optional :class: |
None
|
default_model
|
str
|
Fallback model when |
'openai:gpt-4.1'
|
api_key
|
str
|
API key used when spawning agents from a model string. |
''
|
tool_factory
|
DynamicToolFactory | None
|
Optional :class: |
None
|
Source code in orqest/autonomy/factory.py
spawn ¶
Hydrate an AgentSpec into a runnable DynamicAgent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
AgentSpec
|
The agent specification to hydrate. |
required |
model
|
Model | None
|
Optional pre-built Model instance. When provided, the factory uses it directly instead of resolving from spec.model. This is the recommended way to inject TestModel in tests. |
None
|
Source code in orqest/autonomy/factory.py
DynamicAgent ¶
DynamicAgent(
agent_name: str,
system_prompt: str,
output_type: type[OutputT],
*,
model: Model | str,
api_key: str | None = None,
retries: int = 3,
tools: list[Tool] | None = None,
toolsets: list[Any] | None = None,
truncated_history: int = 100,
history_processors: list | None = None,
result_budget: int | None = 20000,
context_manager: ContextManager | None = None,
model_settings: ModelSettings | None = None,
reasoning: ReasoningEffort | None = None,
confidence_protocol: Any = None,
)
An agent created at runtime from an AgentSpec.
Unlike user-defined agents, DynamicAgent's _run_implementation is generic: it takes the latest user message and calls call_model.
Source code in orqest/agents/base_agent.py
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 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | |
ExecutionResult ¶
Result of executing the full goal.
MetaOrchestrator ¶
MetaOrchestrator(
planner: BaseAgent,
factory: Any,
registry: Any,
*,
memory: Any | None = None,
hooks: HookRunner | None = None,
max_subtasks: int = 10,
max_spawn_depth: int = 3,
metacognition: Any = None,
bus: EventBus | None = None,
)
Orchestrator that decomposes goals and spawns agents as needed.
The MetaOrchestrator: 1. Takes a high-level goal from the user 2. Uses a planner agent to decompose it into subtasks 3. For each subtask, finds an existing agent or spawns a new one 4. Executes the subtasks sequentially (v1) 5. Collects results and produces a summary 6. Persists each spawned agent spec to memory (at spawn time) for reuse
Initialize the MetaOrchestrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
planner
|
BaseAgent
|
Agent that decomposes goals into TaskDecomposition. |
required |
factory
|
Any
|
AgentFactory that spawns agents from AgentSpec. |
required |
registry
|
Any
|
ToolRegistry for tool lookup. |
required |
memory
|
Any | None
|
Optional MemoryStore for persisting learned specs. |
None
|
hooks
|
HookRunner | None
|
Optional HookRunner for lifecycle events. |
None
|
max_subtasks
|
int
|
Upper bound on subtasks per goal. |
10
|
max_spawn_depth
|
int
|
Maximum nesting depth for spawned agents. |
3
|
metacognition
|
Any
|
Optional :class: |
None
|
bus
|
EventBus | None
|
Optional :class: |
None
|
Source code in orqest/autonomy/meta.py
spawned_agents
property
¶
Access the cache of dynamically spawned agents.
solve
async
¶
Decompose a goal into subtasks, spawn agents, and execute.
When :class:MetacognitionConfig is configured, low-confidence
subtask results trigger re-decomposition of the remaining
subtasks (bounded by max_redecompositions).
Source code in orqest/autonomy/meta.py
135 136 137 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 | |
SubTask ¶
A single subtask derived from goal decomposition.
SubTaskResult ¶
Result of a single subtask execution.
was_spawned
instance-attribute
¶
True when the agent was newly created this turn (planner emitted
a fresh AgentSpec and the factory hydrated it). False when the
agent was already in the per-run cache or rehydrated from a memory
hit — telemetry/UI use this to distinguish "we built something new"
from "we reused what we had".
TaskDecomposition ¶
Output of the goal decomposition step.
ToolInfo
dataclass
¶
Metadata about a registered tool.
ToolRegistry ¶
Central registry of available tools.
Agents and the MetaOrchestrator discover tools here. Tools can be pre-registered by developers or added dynamically.
Initialize an empty registry.
Source code in orqest/autonomy/registry.py
register ¶
Register a tool. Uses tool.name as the key.
Source code in orqest/autonomy/registry.py
get ¶
get_or_discover
async
¶
get_or_discover(
name: str,
*,
discovery: MCPDiscovery | None = None,
manager: MCPServerManager | None = None,
permission: PermissionGate | None = None,
audit_bus: EventBus | None = None,
max_servers: int = 3,
) -> Tool | None
Get a tool by name; if missing, fall back to MCP discovery.
On a registry miss, searches for an MCP server advertising the
tool, gates the request through permission (default
:class:DenyAll), connects via manager, and registers the
discovered tools transparently. Returns the matching tool if
found, otherwise None.
Audit-log events emitted via audit_bus (when supplied):
discovery.requested— a missing tool triggered discovery.discovery.denied— :class:PermissionGaterejected the request.discovery.connected— a discovered tool was registered (one per tool).discovery.failed— search/connect raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Requested tool name. |
required |
discovery
|
MCPDiscovery | None
|
Optional :class: |
None
|
manager
|
MCPServerManager | None
|
Optional :class: |
None
|
permission
|
PermissionGate | None
|
Gate to require explicit approval. Default
:class: |
None
|
audit_bus
|
EventBus | None
|
Optional event bus for the audit trail. |
None
|
max_servers
|
int
|
Maximum number of discovered servers to try before giving up. |
3
|
Source code in orqest/autonomy/registry.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 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 | |
search ¶
Search tools by keyword matching in name and description.
Source code in orqest/autonomy/registry.py
list_all ¶
remove ¶
__len__ ¶
AgentSpec ¶
Everything needed to spawn an agent at runtime.
An LLM produces this as structured output. The AgentFactory hydrates it into a live BaseAgent.
Output shape is declared via exactly one of:
output_schema: a JSON Schema dict (the wire-format option — LLMs can emit this, and it survives serialization/persistence).output_type: a PydanticBaseModelsubclass (the code-side ergonomic option — terser than authoring JSON Schema by hand; not serializable, so use this for in-process construction).
A validator enforces "exactly one of" — neither raises, both raises.
output_schema
class-attribute
instance-attribute
¶
JSON Schema dict describing the agent's structured output. Use this
when the spec is emitted by an LLM or persisted across processes. Pair
with the properties/required shape that
:meth:AgentFactory._schema_to_model expects.
output_type
class-attribute
instance-attribute
¶
A Pydantic BaseModel subclass. Use this when constructing the spec
in code — it's terser than authoring JSON Schema by hand and you get
static-typing of the output. Not serializable; the JSON Schema path is
the wire-format option.
tools
class-attribute
instance-attribute
¶
Mixed list — pre-registered tool references (:class:ToolSpec) and
runtime-generated tools (:class:GeneratedToolSpec). Pydantic v2
smart-union dispatches by structure: the implementation field
on :class:GeneratedToolSpec is the disambiguator.
GeneratedToolSpec ¶
A tool the LLM defines AT RUNTIME — implementation included.
The companion to :class:ToolSpec for cases where the agent needs a
capability that does NOT yet exist in :class:ToolRegistry. The
implementation string is the body of the tool function:
- It receives a single
argsdict (matchingparameters) - It must
returna JSON-serializable value - It executes inside the configured :class:
orqest.sandbox.Sandbox
Hydration is performed by :class:orqest.autonomy.DynamicToolFactory,
which validates the implementation (AST check + allowed-imports
allowlist) before producing the runnable pydantic_ai.Tool.
The presence of implementation is the structural discriminator that
distinguishes :class:GeneratedToolSpec from :class:ToolSpec in the
:attr:AgentSpec.tools smart-union — Pydantic v2 picks this variant
when implementation is present in the input dict.
implementation
instance-attribute
¶
Python source — the body of a function that takes args (dict)
and returns a JSON-serializable value. Use return for the result.
Example::
"import re\n"
"matches = re.findall(r'\\d+', args['text'])\n"
"return {'matches': matches}\n"
allowed_imports
class-attribute
instance-attribute
¶
Top-level module names the implementation may import. Empty set
rejects any import statement at validate time. Use sparingly —
every entry is a safety surface.
dependencies
class-attribute
instance-attribute
¶
Optional pip specifiers (e.g. ["pandas>=2.0", "httpx"]) required
by the implementation. Tier-2 :class:DockerSandbox installs them
into the agent's per-agent .venv on first invocation, gated by the
sandbox's allowed_packages allowlist (default-deny). Tier-0 / Tier-1
sandboxes ignore — they have no per-agent venv concept. Empty default
keeps the field backward-compatible.
timeout_s
class-attribute
instance-attribute
¶
Per-invocation wall-clock cap inside the sandbox.
memory_mb
class-attribute
instance-attribute
¶
Per-invocation memory cap (RLIMIT_AS on POSIX). Ignored on Windows.
ToolSpec ¶
Description of a tool an agent needs.
The name is resolved against :class:ToolRegistry at spawn time.
parameters is a JSON-Schema-shaped dict carried for the LLM's
benefit (it never reaches the registered tool — that contract lives
on the tool itself).
DynamicToolFactory ¶
DynamicToolFactory(
sandbox: Sandbox,
*,
bus: EventBus | None = None,
default_timeout_s: float = 5.0,
default_memory_mb: int = 128,
)
Spawn :class:pydantic_ai.Tool objects from :class:GeneratedToolSpec.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sandbox
|
Sandbox
|
Required :class: |
required |
bus
|
EventBus | None
|
Optional :class: |
None
|
default_timeout_s
|
float
|
Fallback timeout when a spec doesn't override. |
5.0
|
default_memory_mb
|
int
|
Fallback memory cap when a spec doesn't override. |
128
|
Source code in orqest/autonomy/tool_factory.py
spawn
async
¶
Validate the spec, return a runnable :class:pydantic_ai.Tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
GeneratedToolSpec
|
The :class: |
required |
agent_id
|
str | None
|
Optional agent identifier — Tier-2
:class: |
None
|
Raises:
| Type | Description |
|---|---|
ValidationError
|
When the implementation fails static checks (disallowed import, forbidden built-in, syntax error). |
Source code in orqest/autonomy/tool_factory.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 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 | |