Runtime
A runtime is the executable harness instance created from a validated RuntimeSpec. It is required whenever you want agents to do work: the spec is pure configuration, while the...
A runtime is the executable harness instance created from a validated
RuntimeSpec. It is required whenever you want agents to do work: the spec is
pure configuration, while the runtime owns the live Rust orchestration engine,
provider routing, approval gates, plan lifecycle, reference storage, eval
execution, callbacks, and built-in toolkit dispatch.
The usual lifecycle is:
| Step | API | Result |
|---|---|---|
| Describe the application | define_runtime(...) | A frozen RuntimeSpec value. |
| Attach live callbacks and storage | create_runtime(...) | A native Runtime handle. |
| Run work | Runtime methods such as query(...), run_eval(...), and serve_mcp_http(...) | Streams, eval artifacts, references, approvals, traces, or MCP servers. |
Model constructors use Python field names, and Pydantic accepts both
snake_case and camelCase aliases unless noted. Fields marked
Python-only are used by the Python facade and excluded from the Rust wire
spec.
Runtime Handle
Runtime is the public Python alias for the native handle returned by
create_runtime(...). Do not construct it directly; build a RuntimeSpec,
then call create_runtime(...).
| Method | Use | Related docs |
|---|---|---|
query(prompt, thread_id, resume=None) | Run a coordinator turn and receive an async runtime event stream. | Runtime events, Streaming events |
run_specialist(specialist, prompt, thread_id=None) | Dispatch one registered specialist directly, bypassing the coordinator. | Agents |
run_eval(eval_request) | Run an eval to completion and return an eval artifact. | Evals, Write evals |
stream_eval(eval_request) | Run an eval and stream progress event envelopes. | Evals |
get_trace(trace_id) / list_traces(...) | Inspect traces recorded by evals or runtime runs. | Evals |
create_reference(...), resolve_reference(...), reference_glimpse(...) | Store, resolve, and preview typed references. | References, References & glimpses |
respond_to_approval(...) | Resolve a pending approval gate with approve, reject, or revise. | Require approvals |
list_mcp_tools(...), serve_mcp_stdio(...), serve_mcp_http(...) | Expose one runtime agent's tools over MCP. | MCP, Expose tools over MCP |
define_runtime
define_runtime(tenant: 'TenantIdentity | Mapping[str, Any]', *, agents: 'list[AgentSpec | Mapping[str, Any]] | None' = None, references: 'list[ReferenceSpec | Mapping[str, Any]] | None' = None, plans: 'list[PlanSpec | Mapping[str, Any]] | None' = None, toolkits: 'list[ToolkitSpec | Mapping[str, Any]] | None' = None, approval_policies: 'ApprovalPolicies | Mapping[str, Any] | None' = None, approval_overrides: 'ApprovalOverrides | Mapping[str, Any] | None' = None, storage_factories: 'StorageFactories | Mapping[str, Any] | None' = None, providers: 'Mapping[str, Any] | None' = None, tool_bindings: 'list[ToolSpec] | None' = None) -> 'RuntimeSpec'
| Parameter | Type | Default |
|---|---|---|
tenant | TenantIdentity | Mapping[str, Any] | required |
agents | list[AgentSpec | Mapping[str, Any]] | None | None |
references | list[ReferenceSpec | Mapping[str, Any]] | None | None |
plans | list[PlanSpec | Mapping[str, Any]] | None | None |
toolkits | list[ToolkitSpec | Mapping[str, Any]] | None | None |
approval_policies | ApprovalPolicies | Mapping[str, Any] | None | None |
approval_overrides | ApprovalOverrides | Mapping[str, Any] | None | None |
storage_factories | StorageFactories | Mapping[str, Any] | None | None |
providers | Mapping[str, Any] | None | None |
tool_bindings | list[ToolSpec] | None | None |
Returns: RuntimeSpec
Create a validated Flow AI runtime spec value.
Collects tenant identity, agents, references, plans, toolkits, approval policy, storage descriptors, and provider config into one pure data spec. Plans, toolkits, and tool bindings declared on agents are auto-attached, and toolkit/agent tool rows are merged into each agent's prompt.
Args:
tenant: TenantIdentity or mapping with resource_id and
version.
agents: AgentSpec values or mappings validated as such.
references: ReferenceSpec values or mappings.
plans: PlanSpec values or mappings. Plans attached to agents are
appended automatically when not listed.
toolkits: ToolkitSpec values or mappings. Toolkit ids referenced
by agents are appended automatically when not listed.
approval_policies: Runtime-wide approval floor. When omitted, it is
derived from the coordinator's approval patch applied on top
of the defaults (plans always, tools never).
approval_overrides: Per-agent/per-tool approval overrides. When
omitted, they are collected from each agent's approval and
tool_approvals declarations.
storage_factories: Host-provided store factory descriptors.
providers: Provider configuration keyed by provider name.
tool_bindings: Runtime-level ToolSpec bindings. Agent-attached
tools are appended automatically.
Returns:
A frozen, validated RuntimeSpec.
Raises:
pydantic.ValidationError: On duplicate agent names, more than one
coordinator, unknown / duplicate / self-referencing routes,
approval overrides naming unknown agents, or more than one
coordinator supplying approval_policies.
create_runtime
create_runtime(spec: 'RuntimeSpec | Mapping[str, Any]', *, tool_bindings: 'list[ToolSpec] | None' = None, services: 'Mapping[str, Any] | None' = None, approval_predicates: 'Mapping[str, Callable[..., bool]] | None' = None, action_dispatcher: 'Callable[..., Any] | None' = None, event_hooks: 'list[Callable[..., Any]] | None' = None, data_environment: 'DataEnvironmentConfig | Mapping[str, Any] | None' = None, target_database_url: 'str | None' = None, testing: 'TestingConfig | None' = None, interpreter: "Literal['noop', 'scripted', 'anthropic']" = 'noop') -> 'Runtime'
| Parameter | Type | Default |
|---|---|---|
spec | RuntimeSpec | Mapping[str, Any] | required |
tool_bindings | list[ToolSpec] | None | None |
services | Mapping[str, Any] | None | None |
approval_predicates | Mapping[str, Callable[..., bool]] | None | None |
action_dispatcher | Callable[..., Any] | None | None |
event_hooks | list[Callable[..., Any]] | None | None |
data_environment | DataEnvironmentConfig | Mapping[str, Any] | None | None |
target_database_url | str | None | None |
testing | TestingConfig | None | None |
interpreter | Literal['noop', 'scripted', 'anthropic'] | 'noop' |
Returns: Runtime
Create an executable runtime handle from a validated spec.
Call this after define_runtime(...) when the runtime should start
handling work. The returned Runtime is the live object used to stream
coordinator responses, run specialists, execute evals, manage references
and approvals, inspect traces, and expose agent tools over MCP.
The optional arguments attach host capabilities to this runtime instance:
Python tool handlers, host services available to tool callbacks, dynamic
approval predicates, an action dispatcher, event hooks, data-environment
storage/query backends, and deterministic testing behavior. The runtime
executes under spec.tenant.resource_id; there is no per-call tenant
override.
Args:
spec: RuntimeSpec or mapping validated as one.
tool_bindings: Additional ToolSpec values with Python handlers.
Agent-attached tools are registered automatically; every tool
bound to an agent must carry a handler.
services: Host service objects exposed to Python tool handlers via
the tool context (ctx.<name>, ctx["<name>"]). Keys must
be non-empty strings and must not use the reserved names
tool_use_id, services, or references.
approval_predicates: Dynamic approval predicates keyed by predicate
id, for tools whose approval is {"kind": "dynamic"} without
an attached approval_handler.
action_dispatcher: Callable that receives executor business actions
for host-side dispatch.
event_hooks: Callables invoked for each runtime event during
streaming.
data_environment: Rust-owned data dependencies (kv store, target
database, catalog, catalog search) consumed by built-in
toolkits. See
DataEnvironmentConfig.
target_database_url: Shorthand for
data_environment["target_database_url"]. Conflicts with an
explicit target_database descriptor or a differing
target_database_url value.
testing: TestingConfig with mock_response. See
TestingConfig.
Runs the deterministic mock interpreter; mutually exclusive with
a non-default interpreter.
interpreter: Model interpreter key: "noop" (default, no
provider), "scripted" (deterministic scripted replay), or
"anthropic" (live provider).
Returns: Native handle returned by the Rust extension. Use the handle to start coordinator or specialist runs, run or stream evals, create and resolve references, respond to approval gates, inspect traces, and expose runtime tools over MCP. See Runtime Handle.
Raises:
ValueError: If a dynamic approval predicate is not registered, an
agent tool binding has no Python handler, testing is combined
with a non-default interpreter, the testing config is
malformed, target_database_url conflicts with
data_environment, or a service key is reserved.
TypeError: If services or data-environment values have invalid
types.
pydantic.ValidationError: If spec or data_environment fail
validation.
normalize_data_environment
normalize_data_environment(data_environment: 'DataEnvironmentConfig | Mapping[str, Any] | None', target_database_url: 'str | None' = None, *, runtime_resource_id: 'str') -> 'dict[str, Any] | None'
| Parameter | Type | Default |
|---|---|---|
data_environment | DataEnvironmentConfig | Mapping[str, Any] | None | required |
target_database_url | str | None | None |
runtime_resource_id | str | required |
Returns: dict[str, Any] | None
Validate and normalize a data environment without constructing a runtime.
Args:
data_environment: DataEnvironmentConfig or mapping; snake_case
and camelCase keys are both accepted. See
DataEnvironmentConfig.
target_database_url: Shorthand for
data_environment["target_database_url"].
runtime_resource_id: The runtime tenant the environment must agree
with; a data environment that pins a different tenant_id is
rejected.
Returns:
CamelCase mapping passed to the Rust runtime, or None when no
environment data is supplied. When present, the mapping can contain
tenantId, workspaceId, kv, targetDatabase,
targetDatabaseUrl, targetDatabaseSchema, catalog, and
catalogSearch. See the
DataEnvironmentConfig
table for key meanings.
Raises:
ValueError: If target_database_url conflicts with the data
environment, tenant_id does not match
runtime_resource_id, or a storage descriptor has an
unsupported kind.
TypeError: If a value has an invalid type.
Runtime Spec Models
These models are user-facing whenever you build specs directly or inspect the
objects returned by helper constructors. Helper functions such as
define_runtime(...), define_coordinator(...), and define_specialist(...)
create these same model objects for you.
RuntimeSpec
RuntimeSpec(*, tenant: flowai_harness.tenant.TenantIdentity, agents: list[AgentSpec] = <factory>, references: list[flowai_harness.references.ReferenceSpec] = <factory>, plans: list[flowai_harness.plans.PlanSpec] = <factory>, toolkits: list[ToolkitSpec] = <factory>, approvalPolicies: ApprovalPolicies = <factory>, approvalOverrides: ApprovalOverrides = <factory>, storageFactories: StorageFactories = <factory>, providers: dict[str, typing.Any] = <factory>, toolBindings: tuple[flowai_harness.tools.ToolSpec, ...] = <factory>) -> None
| Parameter | Type | Default |
|---|---|---|
tenant | flowai_harness.tenant.TenantIdentity | required |
agents | list[flowai_harness.runtime.AgentSpec] | <factory> |
references | list[flowai_harness.references.ReferenceSpec] | <factory> |
plans | list[flowai_harness.plans.PlanSpec] | <factory> |
toolkits | list[flowai_harness.runtime.ToolkitSpec] | <factory> |
approvalPolicies | flowai_harness.runtime.ApprovalPolicies | <factory> |
approvalOverrides | flowai_harness.runtime.ApprovalOverrides | <factory> |
storageFactories | flowai_harness.runtime.StorageFactories | <factory> |
providers | dict[str, Any] | <factory> |
toolBindings | tuple[flowai_harness.tools.ToolSpec, ...] | <factory> |
Returns: None
Canonical pure runtime specification consumed by flowai-runtime.
| Parameter | Type | Default | Description |
|---|---|---|---|
tenant | TenantIdentity | required | Tenant identity the runtime executes under. |
agents | list[AgentSpec] | [] | Registered agents. Names must be unique; at most one coordinator. |
references | list[ReferenceSpec] | [] | Named typed reference declarations available to the runtime. |
plans | list[PlanSpec] | [] | Plan schemas. Plans declared on agents are auto-attached. |
toolkits | list[ToolkitSpec] | [] | Built-in toolkit declarations. Toolkit ids referenced by agents are auto-attached. |
approval_policies | ApprovalPolicies | <factory> | Runtime-wide approval floor for the plans and tools channels. |
approval_overrides | ApprovalOverrides | <factory> | Per-agent and per-tool approval overrides layered on the floor. |
storage_factories | StorageFactories | <factory> | Host-provided store factory descriptors for kv, plans, and memory. |
providers | dict[str, Any] | {} | Provider configuration keyed by provider name, e.g. {"anthropic": {"apiKeyEnv": "ANTHROPIC_API_KEY"}}. |
tool_bindings | tuple[ToolSpec, ...] | () | Runtime-level tool bindings with Python handlers. Excluded from the wire spec. |
AgentSpec
AgentSpec(*, name: Annotated[str, MinLen(min_length=1)], role: Literal['coordinator', 'planner', 'executor', 'specialist'], stateful: bool, model: ModelSpec, systemPrompt: str, routes: list[str] = <factory>, toolkits: list[str] = <factory>, maxTurns: Annotated[int | None, Ge(ge=1)] = None, plan: flowai_harness.plans.PlanSpec | None = None, tools: tuple[flowai_harness.tools.ToolSpec, ...] = <factory>, approvalPolicies: ApprovalPolicyPatch | None = None, toolApprovalPolicies: dict[str, dict[str, typing.Any]] = <factory>, promptCacheKey: str | None = None) -> None
| Parameter | Type | Default |
|---|---|---|
name | str | required |
role | Literal['coordinator', 'planner', 'executor', 'specialist'] | required |
stateful | bool | required |
model | flowai_harness.runtime.ModelSpec | required |
systemPrompt | str | required |
routes | list[str] | <factory> |
toolkits | list[str] | <factory> |
maxTurns | int | None | None |
plan | flowai_harness.plans.PlanSpec | None | None |
tools | tuple[flowai_harness.tools.ToolSpec, ...] | <factory> |
approvalPolicies | flowai_harness.runtime.ApprovalPolicyPatch | None | None |
toolApprovalPolicies | dict[str, dict[str, Any]] | <factory> |
promptCacheKey | str | None | None |
Returns: None
Agent registration compiled by flowai-runtime into an orchestrator agent.
| Parameter | Type | Default | Description |
|---|---|---|---|
name | str | required | Unique agent name within the runtime spec. |
role | Literal['coordinator', 'planner', 'executor', 'specialist'] | required | Agent role: coordinator, planner, executor, or specialist. |
stateful | bool | required | Whether the agent keeps thread state across turns. Defaults by role: true for coordinator and planner, false otherwise. |
model | ModelSpec | required | Model selection. A plain model id string is coerced to ModelSpec. |
system_prompt | str | required | System prompt text. Toolkit and bound-tool rows are merged into its # Tools section at assembly. |
routes | list[str] | [] | Agent names this agent can hand off to. Coordinators require at least one. |
toolkits | list[str] | [] | Built-in toolkit ids attached to this agent. |
max_turns | int | None | None | Maximum orchestration turns, or None for the runtime default. |
plan | PlanSpec | None | None | Plan schema for planner/executor agents. Auto-attached to the runtime spec; excluded from the wire spec. |
tools | tuple[ToolSpec, ...] | () | Tool bindings attached directly to this agent. Excluded from the wire spec. |
approval_policies | ApprovalPolicyPatch | None | None | Agent-level approval override collected into RuntimeSpec.approval_overrides. Excluded from the wire spec. |
tool_approval_policies | dict[str, dict[str, Any]] | {} | Per-tool approval rules keyed by tool name. Excluded from the wire spec. |
prompt_cache_key | str | None | None | Deterministic SHA-256 fingerprint of the rendered prompt, used for prompt change detection and traceability. Excluded from the wire spec. |
ModelSpec
ModelSpec(*, id: str, provider: str | None = None) -> None
| Parameter | Type | Default |
|---|---|---|
id | str | required |
provider | str | None | None |
Returns: None
Per-agent model selection.
A plain model id string is accepted anywhere a ModelSpec is expected
and is coerced to ModelSpec(id=...).
| Parameter | Type | Default | Description |
|---|---|---|---|
id | str | required | Provider model identifier, e.g. a model id string. |
provider | str | None | None | Provider name from the runtime providers mapping. None routes to the default provider. |
ToolkitSpec
ToolkitSpec(*, id: Annotated[str, MinLen(min_length=1)], config: typing.Any | None = None) -> None
| Parameter | Type | Default |
|---|---|---|
id | str | required |
config | Any | None | None |
Returns: None
Toolkit declaration by stable identifier.
| Parameter | Type | Default | Description |
|---|---|---|---|
id | str | required | Stable built-in toolkit identifier, e.g. 'agents', 'plans', 'references', 'catalog'. |
config | Any | None | None | Optional toolkit-specific configuration value. |
ApprovalPolicies
ApprovalPolicies(*, plans: dict[str, typing.Any] = <factory>, tools: dict[str, typing.Any] = <factory>) -> None
| Parameter | Type | Default |
|---|---|---|
plans | dict[str, Any] | <factory> |
tools | dict[str, Any] | <factory> |
Returns: None
Runtime-level approval policy floor.
Each channel accepts "never", "always", or
{"kind": "dynamic", "value": predicate_id} and is normalized to the
wire shape {"kind": ...}.
| Parameter | Type | Default | Description |
|---|---|---|---|
plans | dict[str, Any] | <factory> | Approval rule for plan approval gates. Defaults to {"kind": "always"}. |
tools | dict[str, Any] | <factory> | Approval rule for tool-call approval gates. Defaults to {"kind": "never"}. |
Approval rules accept "never", "always", or
{"kind": "dynamic", "value": "<predicate_id>"}. They normalize to the Rust
wire shape {"kind": ...}.
ApprovalPolicyPatch
ApprovalPolicyPatch(*, plans: dict[str, typing.Any] | None = None, tools: dict[str, typing.Any] | None = None) -> None
| Parameter | Type | Default |
|---|---|---|
plans | dict[str, Any] | None | None |
tools | dict[str, Any] | None | None |
Returns: None
Partial agent-level approval override.
Missing channels inherit from the runtime-level approval policy. Each
channel accepts "never", "always", or
{"kind": "dynamic", "value": predicate_id}.
| Parameter | Type | Default | Description |
|---|---|---|---|
plans | dict[str, Any] | None | None | Approval rule override for plan approval gates. None inherits the runtime floor. |
tools | dict[str, Any] | None | None | Approval rule override for tool-call approval gates. None inherits the runtime floor. |
ApprovalOverrides
ApprovalOverrides(*, agents: dict[str, ApprovalPolicyPatch] = <factory>, tools: dict[str, dict[str, dict[str, typing.Any]]] = <factory>) -> None
| Parameter | Type | Default |
|---|---|---|
agents | dict[str, flowai_harness.runtime.ApprovalPolicyPatch] | <factory> |
tools | dict[str, dict[str, dict[str, Any]]] | <factory> |
Returns: None
Hierarchical approval overrides scoped by agent and tool.
Every agent named in agents or tools must be registered in the
same runtime spec; RuntimeSpec validation rejects unknown names.
| Parameter | Type | Default | Description |
|---|---|---|---|
agents | dict[str, ApprovalPolicyPatch] | {} | Per-agent approval policy patches keyed by agent name. |
tools | dict[str, dict[str, dict[str, Any]]] | {} | Per-tool approval rules keyed by agent name, then tool name. Each rule is normalized to the wire shape {'kind': ...}. |
StorageFactorySpec
StorageFactorySpec(*, kind: str, config: typing.Any | None = None) -> None
| Parameter | Type | Default |
|---|---|---|
kind | str | required |
config | Any | None | None |
Returns: None
Host-provided store factory descriptor.
| Parameter | Type | Default | Description |
|---|---|---|---|
kind | str | required | Store factory implementation identifier supplied by the host. |
config | Any | None | None | Optional factory-specific configuration passed to the store implementation. |
StorageFactories
StorageFactories(*, kv: StorageFactorySpec | None = None, plans: StorageFactorySpec | None = None, memory: StorageFactorySpec | None = None) -> None
| Parameter | Type | Default |
|---|---|---|
kv | flowai_harness.runtime.StorageFactorySpec | None | None |
plans | flowai_harness.runtime.StorageFactorySpec | None | None |
memory | flowai_harness.runtime.StorageFactorySpec | None | None |
Returns: None
Store factory descriptions supplied by the host language facade.
| Parameter | Type | Default | Description |
|---|---|---|---|
kv | StorageFactorySpec | None | None | Factory for runtime KV state such as references, plans, approval audit, and caches. |
plans | StorageFactorySpec | None | None | Factory for plan lifecycle storage when supplied separately from the runtime KV store. |
memory | StorageFactorySpec | None | None | Factory for persisted agent memory when supplied by the host runtime. |
Testing Config
TestingConfig is a TypedDict used only with
create_runtime(..., testing=...).
| Key | Type | Required | Description |
|---|---|---|---|
mock_response | str | yes | Text emitted by the deterministic mock interpreter for every model turn. Used with create_runtime(..., testing={"mock_response": "..."}). |
DataEnvironmentConfig
DataEnvironmentConfig is the optional TypedDict accepted by
create_runtime(..., data_environment=...) and
normalize_data_environment(...). It attaches Rust-owned data dependencies
for built-in toolkit dispatch. All keys are optional and accept snake_case
or camelCase spelling.
| Key | Type | Required | Description |
|---|---|---|---|
tenant_id / tenantId | str | no | Tenant id the environment is pinned to. When set, it must match the runtime tenant resource_id. |
workspace_id / workspaceId | str | no | Workspace id used to scope stored data. |
kv | descriptor | no | KV store descriptor. Supported kinds are memory, sqlite, postgres, and redis. |
target_database / targetDatabase | descriptor | no | Target database descriptor for agent data queries. Supported kinds are sqlite and postgres. Mutually exclusive with target_database_url. |
target_database_url / targetDatabaseUrl | str | no | Connection URL shorthand for the target database. |
target_database_schema / targetDatabaseSchema | str | no | Schema name used with target database introspection. |
catalog | descriptor | no | Data catalog store descriptor. Supported kinds are empty, inline, sqlite, and postgres. |
catalog_search / catalogSearch | descriptor | no | Catalog fuzzy-search index configuration with index_path and optional rebuild/write-through flags. |
normalize_data_environment(...) returns None for an empty environment. For
a non-empty environment, it returns the camelCase wire dictionary passed to the
Rust runtime. The dictionary contains the normalized versions of the keys in
the table above.
Data Environment Descriptors
The top-level tenant_id, when set, must match the runtime tenant
resource_id. target_database and target_database_url are mutually
exclusive.
kv
| Kind | Required fields | Optional fields |
|---|---|---|
memory | none | none |
sqlite | url | ensure_schema |
postgres | url or url_env | table, ensure_schema |
redis | url or url_env | prefix |
target_database
| Kind | Required fields | Optional fields |
|---|---|---|
sqlite | url | none |
postgres | url or url_env | schema |
target_database_url is a shorthand for a target database URL. Use
target_database_schema when the shorthand needs an explicit schema name.
catalog
| Kind | Required fields | Optional fields |
|---|---|---|
empty | none | none |
inline | none | entries |
sqlite | url | ensure_schema |
postgres | url or url_env | ensure_schema |
catalog_search
| Required fields | Optional fields |
|---|---|
index_path | rebuild_on_start, write_through |
For task-oriented setup, see Configure a data environment and Knowledge and documents.
Reference
API reference for the flowai_harness public surface. Most pages render the exported classes, functions, and type aliases directly from their docstrings; some pages add contract...
Studio
Studio apps are local registries of one or more workspace runtime bindings. The CLI imports a FlowAIApp and serves the Studio UI and API from the same Python process.
