OpenRath v2.0.0 API Reference#
The Stable 2.0.0 release adds public packages for workflow definition,
durable execution, governed adapters, artifacts, deployment revisions,
evaluation, observability, security, and the Agent Server. Stability
classifications and compatibility commitments are governed by the
v2 API policy.
Package map#
Package |
Primary contracts |
|---|---|
|
|
|
|
|
Stable |
|
Immutable |
|
Governed Provider, Tool, Sandbox, and Memory executors and resource specifications |
|
Tenant-scoped |
|
Content-identified |
|
Versioned datasets, evaluators, experiments, persistence, and regression gates |
|
Telemetry spans/counters, OpenTelemetry bridge, structured logs, and redaction |
|
|
|
Principal and tenant context, policies, authorization, secret references, structured audit |
|
|
|
Synchronous |
The retained v1-compatible packages remain documented in the general API Reference.
Definition and plan compilation#
Surface |
Contract |
|---|---|
|
Marks a checkpointable execution method. |
|
Marks a pure router with an explicit successor allowlist. |
|
Compiles explicit v2 nodes into an |
|
Validates entrypoint, successors, schemas, effect declarations, and durable compatibility. |
|
Classifies no-effect, read-only, idempotent, or non-idempotent work for retry and reconciliation. |
|
Declares the Provider, Tool, Sandbox, and Memory resources required by a plan. |
Non-idempotent retries require an explicit idempotency key. For timeout-controlled execution, use an async handler or isolated executor.
Request context#
Surface |
Contract |
|---|---|
|
Principal, tenant, optional project, action grants, and trusted attributes. |
|
Security, revision, request, trace, and optional deadline identity propagated through a Run. |
|
Creates W3C-compatible trace and span identifiers. |
|
Returns the bounded time remaining for a deadline. |
|
Raises |
Durable runtime#
Method |
Behavior |
|---|---|
|
Compiles and registers the executable plan for a revision. |
|
Creates a durable queued Run with session, context, state, priority, and optional idempotency key. |
|
Claims one Run under a lease/fencing token and advances it from the latest committed checkpoint. |
|
Persists local Run state, events, checkpoints, interrupts, and leases. |
|
Provides the production durable store; migrations are a separate operator action. |
|
Records dispatch and outcome state for external side effects. |
|
Carries wake, cancel, and fanout signals without replacing durable Run state. |
|
Classifies stale Tool invocations for retry, failure, or operator review. |
The durable state model includes Run, RunEvent, Checkpoint, Interrupt,
ResourceLease, ToolInvocation, and their explicit status enums.
Governed adapters#
Surface |
Contract |
|---|---|
|
Reduced Run, security, trace, deadline, and policy context supplied to an adapter call. |
|
Applies policy and schema constraints around Provider calls. |
|
Applies approval, output-size, policy, and schema checks around Tool calls. |
|
Applies isolation and policy constraints around Sandbox calls. |
|
Applies namespace and policy constraints around Memory operations. |
|
Explicit resource declarations for governed calls. |
|
Carries and validates an approval before controlled work. |
Adapter handlers receive only the context and resource specification needed for their operation. See the threat model for the corresponding trust boundaries.
Supporting runtime planes#
Package |
Contract |
|---|---|
|
Content-addressed, tenant-scoped payload storage with bounded reads and SHA-256 verification. |
|
Immutable revision identity derived from code and a canonical deployment manifest. |
|
Offline dataset execution, per-evaluator results, revision-bound experiments, and regression decisions. |
|
Trace-correlated spans, counters, redacted structured logs, and an OpenTelemetry SDK bridge. |
See Evaluation, Observability, and Artifacts for executable examples.
Security#
Surface |
Contract |
|---|---|
|
Makes explicit allow, deny, or approval decisions over actions and resources. |
|
References credentials without persisting raw secrets in Run state. |
|
Receives redacted, correlated security and control-plane events. |
|
Emits redacted newline-delimited JSON audit records. |
|
Allows explicitly trusted embedded workflows. |
|
Provides a fail-closed policy default. |
Authentication alone grants no action. Service tokens need explicit grants, and object access is filtered by tenant and project scope.
Agent Server and clients#
Surface |
Contract |
|---|---|
|
Creates the tenant-scoped HTTP/SSE service over a |
|
Registers a workflow template under an immutable revision ID. |
|
Reference bearer-token authentication for self-hosted deployments and tests. |
|
Async authentication protocol for integrated identity systems. |
|
Synchronous Session, Assistant, Run, Interrupt, Feedback, Event, and Memory operations. |
|
Native-async form of the same client surface. |
RemoteClient and AsyncRemoteClient expose:
Operation group |
Methods |
|---|---|
Assistants |
|
Sessions |
|
Runs |
|
Events |
|
Interrupts |
|
Feedback |
|
Governed Memory |
`store(“put” |
Lifecycle |
|
See Agent Server and Remote Client for a complete executable path and the OpenAPI document for HTTP request and response schemas.
Events#
OpenRath exposes two related event contracts:
Surface |
Purpose |
|---|---|
|
Durable, monotonically sequenced events attached to one Run and replayed by the Agent Server. |
|
Deeply immutable Session/lineage event with producer, trust, provenance, and trace identity. |
|
Immutable ordered Session event view with parent Session identities. |
Machine-readable errors#
RathError carries a stable code, message, retryable flag, and JSON-safe
details. RathError.to_dict() returns the transport representation.
|
Meaning |
|---|---|
|
A request or argument failed validation. |
|
Authentication did not produce a principal. |
|
The principal lacks the required action or scope. |
|
The policy requires an explicit approval. |
|
Policy evaluation failed. |
|
The requested state change conflicts with durable state. |
|
The scoped resource is not visible or does not exist. |
|
The Run or operation exceeded its deadline. |
|
The operation was cancelled. |
|
A required runtime dependency is unavailable. |
|
An unexpected internal error occurred. |
The Agent Server can additionally return resource.exhausted with HTTP 429
when a configured tenant queue or request bound is reached. The OpenAPI
document is the contract source for endpoint response codes.
Command-line entry points#
Command |
Arguments and environment |
|---|---|
|
|
|
|
|
|
openrath-server uses one process worker; service deployments scale through
container or pod replicas. openrath-worker resolves its application
reference to an AgentServer. openrath-migrate --check verifies the schema
without applying changes.
Source#
Module |
Source |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Autodoc#
Public workflow definition, compiler, and execution-plan contracts.
- exception rath.definition.DefinitionError[source]#
Workflow declaration cannot produce a safe deterministic plan.
- class rath.definition.EffectClass(value)[source]#
An enumeration.
- NONE = 'none'#
- READ_ONLY = 'read_only'#
- IDEMPOTENT = 'idempotent'#
- NON_IDEMPOTENT = 'non_idempotent'#
- class rath.definition.ExecutionPlan(id: 'UUID', definition_hash: 'str', revision_id: 'UUID', definition: 'WorkflowDefinition', nodes: 'tuple[NodeSpec, ...]', resources: 'ResourceManifestV2', policy_manifest: 'Mapping[str, JSONValue]', durable: 'bool', compatibility_issues: 'tuple[str, ...]' = ())[source]#
-
- definition: WorkflowDefinition#
- resources: ResourceManifestV2#
- class rath.definition.NodeKind(value)[source]#
An enumeration.
- STEP = 'step'#
- ROUTER = 'router'#
- OPAQUE = 'opaque'#
- class rath.definition.NodeSpec(id: 'str', kind: 'NodeKind', handler: 'str', is_async: 'bool', implementation_hash: 'str | None' = None, retry: 'RetryPolicy' = <factory>, effects: 'EffectClass' = <EffectClass.NON_IDEMPOTENT: 'non_idempotent'>, idempotency_key: 'str | None' = None, timeout_seconds: 'float | None' = None, checkpoint: 'bool' = True, successors: 'tuple[str, ...]' = ())[source]#
-
- retry: RetryPolicy#
- effects: EffectClass#
- class rath.definition.ProviderResource(path: 'str', provider_kind: 'str', model: 'str | None', has_memory: 'bool')[source]#
- class rath.definition.ResourceManifestV2(providers: 'tuple[ProviderResource, ...]' = ())[source]#
- providers: tuple[ProviderResource, ...]#
- class rath.definition.RetryPolicy(max_attempts: 'int' = 1, base_seconds: 'float' = 0.25, max_seconds: 'float' = 30.0)[source]#
- rath.definition.router(*, successors: tuple[str, ...], entry: bool = False) Callable[[F], F][source]#
Mark a pure routing method with an explicit successor allowlist.
- rath.definition.step(*, entry: bool = False, successors: tuple[str, ...] = (), retry: RetryPolicy | None = None, effects: EffectClass = EffectClass.NON_IDEMPOTENT, idempotency_key: str | None = None, timeout_seconds: float | None = None, checkpoint: bool = True) Callable[[F], F][source]#
Mark a method as a checkpointable execution step.
- class rath.definition.WorkflowCompiler[source]#
Compile explicit Python step boundaries without executing workflow code.
- compile(workflow: object, *, revision_id: UUID, production_durable: bool = False, input_schema: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]] | None = None, state_schema: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]] | None = None, policy_manifest: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]] | None = None) ExecutionPlan[source]#
- class rath.definition.WorkflowDefinition(id: 'UUID', name: 'str', version: 'str', entrypoint: 'str', nodes: 'tuple[NodeSpec, ...]', edges: 'tuple[EdgeSpec, ...]', input_schema: 'Mapping[str, JSONValue]' = <factory>, state_schema: 'Mapping[str, JSONValue]' = <factory>)[source]#
-
- input_schema: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
Request, trace, and durable run context contracts.
- class rath.context.RunContext(security: ~rath.security.context.SecurityContext, revision_id: ~uuid.UUID, request_id: ~uuid.UUID = <factory>, trace_context: ~rath.context.TraceContext = <factory>, deadline: ~datetime.datetime | None = None)[source]#
Explicit context propagated through runtime and adapter calls.
- security: SecurityContext#
- trace_context: TraceContext#
- class rath.context.TraceContext(trace_id: str, span_id: str, sampled: bool = True)[source]#
Minimal W3C-compatible trace correlation identifiers.
- classmethod new(*, sampled: bool = True) TraceContext[source]#
Stable machine-readable errors for OpenRath v2 public contracts.
- class rath.errors.ErrorCode(value)[source]#
Stable error identifiers; enum values are part of the public API.
- INVALID_ARGUMENT = 'request.invalid_argument'#
- UNAUTHENTICATED = 'security.unauthenticated'#
- FORBIDDEN = 'security.forbidden'#
- APPROVAL_REQUIRED = 'security.approval_required'#
- POLICY_ERROR = 'security.policy_error'#
- CONFLICT = 'resource.conflict'#
- NOT_FOUND = 'resource.not_found'#
- DEADLINE_EXCEEDED = 'runtime.deadline_exceeded'#
- CANCELLED = 'runtime.cancelled'#
- UNAVAILABLE = 'runtime.unavailable'#
- INTERNAL = 'internal.error'#
- exception rath.errors.RathError(code: ErrorCode, message: str, *, retryable: bool = False, details: Mapping[str, object] | None = None)[source]#
Base exception with a stable code and serialization contract.
Immutable session event and lineage-friendly event-log contracts.
- class rath.events.Event(id: UUID, session_id: UUID, sequence: int, kind: EventKind, payload: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]], producer: ProducerRef, trust: TrustLevel, provenance: Provenance, created_at: datetime, trace_context: TraceContext | None = None, schema_version: int = 1)[source]#
Deeply immutable event ordered within one Session.
- payload: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
- producer: ProducerRef#
- trust: TrustLevel#
- provenance: Provenance#
- trace_context: TraceContext | None#
- classmethod create(*, session_id: UUID, sequence: int, kind: EventKind, payload: Mapping[str, object], producer: ProducerRef, trust: TrustLevel, provenance: Provenance, trace_context: TraceContext | None = None) Event[source]#
- class rath.events.EventKind(value)[source]#
An enumeration.
- MESSAGE_CREATED = 'session.message.created'#
- SESSION_FORKED = 'session.forked'#
- SESSION_MERGED = 'session.merged'#
- RUN_STATE_CHANGED = 'run.state.changed'#
- NODE_STARTED = 'run.node.started'#
- NODE_COMPLETED = 'run.node.completed'#
- OUTPUT_DELTA = 'run.output.delta'#
- INTERRUPT_CREATED = 'run.interrupt.created'#
- TOOL_INVOCATION_CHANGED = 'run.tool_invocation.changed'#
- class rath.events.SessionEventLog(id: ~uuid.UUID = <factory>, events: tuple[~rath.events.Event, ...] = (), parent_session_ids: tuple[~uuid.UUID, ...] = ())[source]#
Immutable ordered Event view; live runtime state is intentionally absent.
- append(*, kind: EventKind, payload: Mapping[str, object], producer: ProducerRef, trust: TrustLevel, provenance: Provenance, trace_context: TraceContext | None = None) SessionEventLog[source]#
Shared v2 adapter contracts.
- class rath.adapters.AdapterRequestContext(run_id: 'UUID', node_id: 'str', tenant_id: 'str', deadline: 'datetime | None', trace_context: 'TraceContext', idempotency_key: 'str | None', policy_constraints: 'PolicyConstraints', checkpoint_sequence: 'int | None' = None)[source]#
-
- trace_context: TraceContext#
- policy_constraints: PolicyConstraints#
- class rath.adapters.ApprovalGrant(decision_id: 'UUID', run_id: 'UUID', node_id: 'str', tenant_id: 'str', tool_id: 'str', arguments_digest: 'str', actor_id: 'str')[source]#
- class rath.adapters.MemoryNamespace(tenant_id: 'str', user_id: 'str | None' = None, agent_id: 'str | None' = None, session_id: 'str | None' = None, trust: 'TrustLevel' = <TrustLevel.UNTRUSTED: 'untrusted'>)[source]#
-
- trust: TrustLevel#
- class rath.adapters.MemoryExecutor(policy: PolicyEngine)[source]#
- async execute(handler: MemoryHandler, operation: Literal['put', 'search', 'delete'], namespace: MemoryNamespace, payload: Mapping[str, object], *, adapter_context: AdapterRequestContext, run_context: RunContext, timeout_seconds: float = 30) object[source]#
- rath.adapters.merge_policy_constraints(declared: PolicyConstraints, decided: PolicyConstraints) PolicyConstraints[source]#
Combine caller and policy limits without weakening either side.
- class rath.adapters.ProviderCapability(value)[source]#
An enumeration.
- CHAT = 'chat'#
- STREAM = 'stream'#
- TOOLS = 'tools'#
- STRUCTURED_OUTPUT = 'structured_output'#
- EMBEDDING = 'embedding'#
- VISION = 'vision'#
- class rath.adapters.ProviderExecutor(policy: PolicyEngine)[source]#
- async execute(spec: ProviderSpec, handler: ProviderHandler, request: Mapping[str, object], *, capability: ProviderCapability, adapter_context: AdapterRequestContext, run_context: RunContext) object[source]#
- class rath.adapters.ProviderSpec(id: 'str', kind: 'str', model: 'str', credential: 'SecretRef | None' = None, capabilities: 'frozenset[ProviderCapability]' = <factory>, connect_timeout_seconds: 'float' = 10.0, read_timeout_seconds: 'float' = 60.0, total_timeout_seconds: 'float' = 120.0, max_concurrency: 'int' = 16)[source]#
-
- capabilities: frozenset[ProviderCapability]#
- class rath.adapters.SandboxIsolation(value)[source]#
An enumeration.
- TRUSTED_HOST = 'trusted_host'#
- LOCAL_CONTAINER = 'local_container'#
- REMOTE_CONTAINER = 'remote_container'#
- class rath.adapters.SandboxExecutor(policy: PolicyEngine)[source]#
- async execute(spec: SandboxSpec, handler: SandboxHandler, operation: str, payload: Mapping[str, object], *, adapter_context: AdapterRequestContext, run_context: RunContext, timeout_seconds: float = 60) object[source]#
- class rath.adapters.SandboxSpec(id: 'str', isolation: 'SandboxIsolation', image_digest: 'str | None' = None, cpu_limit: 'float | None' = None, memory_bytes: 'int | None' = None, disk_bytes: 'int | None' = None, process_limit: 'int | None' = None, network: "Literal['deny', 'allowlist', 'unrestricted']" = 'deny', allowed_hosts: 'frozenset[str]' = <factory>, ttl_seconds: 'int' = 900)[source]#
-
- isolation: SandboxIsolation#
- class rath.adapters.ToolExecutor(policy: PolicyEngine, *, effect_ledger: EffectLedger | None = None, artifact_store: ArtifactStore | None = None, approval_validator: ApprovalValidator | None = None)[source]#
- async execute(spec: ToolSpec, handler: ToolHandler, arguments: Mapping[str, object], *, adapter_context: AdapterRequestContext, run_context: RunContext, approval: ApprovalGrant | None = None, run_id: UUID | None = None, idempotency_key: str | None = None) object[source]#
- class rath.adapters.ToolSpec(name: 'str', version: 'str', input_schema: 'dict[str, object]', output_schema: 'dict[str, object] | None' = None, effects: 'EffectClass' = <EffectClass.NON_IDEMPOTENT: 'non_idempotent'>, risk: "Literal['low', 'medium', 'high', 'critical']" = 'high', timeout_seconds: 'float' = 30.0, max_output_bytes: 'int' = 1048576, requires_approval: 'bool' = False)[source]#
-
- effects: EffectClass#
- rath.adapters.validate_json(value: object, schema: Mapping[str, object], *, path: str = '$') None[source]#
- rath.adapters.with_policy_constraints(context: AdapterRequestContext, constraints: PolicyConstraints) AdapterRequestContext[source]#
Return the adapter context carrying the evaluated policy constraints.
Content-addressed artifact storage.
- class rath.artifacts.Artifact(tenant_id: 'str', digest: 'str', size: 'int', media_type: 'str', created_at: 'datetime', metadata: 'Mapping[str, JSONValue]' = <factory>)[source]#
- exception rath.artifacts.ArtifactNotFound[source]#
Raised when an artifact does not exist in the requested tenant.
- class rath.artifacts.ArtifactStore(*args, **kwargs)[source]#
- class rath.artifacts.LocalArtifactStore(root: str | Path, *, max_bytes: int = 134217728)[source]#
Atomic filesystem store intended for embedded and single-node operation.
- class rath.artifacts.S3ArtifactStore(bucket: str, *, prefix: str = 'openrath', client: object | None = None, max_bytes: int = 134217728, **client_options: object)[source]#
S3-compatible store; durable identity is the SHA-256 object key.
Immutable deployment revision contracts.
- class rath.deployment.DeploymentManifest(image_digest: 'str', plan_hash: 'str', python_version: 'str', dependencies_digest: 'str', resources: 'Mapping[str, JSONValue]' = <factory>)[source]#
- class rath.deployment.PostgresRevisionStore(run_store: PostgresRunStore)[source]#
- class rath.deployment.Revision(id: 'UUID', code_digest: 'str', manifest: 'DeploymentManifest', created_at: 'datetime')[source]#
-
- manifest: DeploymentManifest#
- classmethod create(*, code_digest: str, manifest: DeploymentManifest) Revision[source]#
- class rath.deployment.SQLiteRevisionStore(run_store: SQLiteRunStore)[source]#
- class rath.eval.Dataset(id: 'UUID', name: 'str', version: 'str', examples: 'tuple[Example, ...]')[source]#
- class rath.eval.EvaluationResult(evaluator: 'str', score: 'float', passed: 'bool', reason: 'str', metadata: 'Mapping[str, JSONValue]' = <factory>)[source]#
- class rath.eval.EvaluationStore(*args, **kwargs)[source]#
-
- save_experiment(experiment: Experiment) Experiment[source]#
- get_experiment(experiment_id: UUID) Experiment[source]#
- class rath.eval.Evaluator(*args, **kwargs)[source]#
-
- async evaluate(example: Example, run: Run) EvaluationResult[source]#
- class rath.eval.Example(id: 'UUID', inputs: 'Mapping[str, JSONValue]', expected: 'Mapping[str, JSONValue]')[source]#
-
- inputs: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
- class rath.eval.Experiment(id: 'UUID', dataset_id: 'UUID', revision_id: 'UUID', results: 'tuple[EvaluationResult, ...]')[source]#
-
- results: tuple[EvaluationResult, ...]#
- class rath.eval.PostgresEvaluationStore(run_store: PostgresRunStore)[source]#
-
- save_experiment(experiment: Experiment) Experiment[source]#
- get_experiment(experiment_id: UUID) Experiment[source]#
- class rath.eval.SQLiteEvaluationStore(run_store: SQLiteRunStore)[source]#
-
- save_experiment(experiment: Experiment) Experiment[source]#
- get_experiment(experiment_id: UUID) Experiment[source]#
- rath.eval.regression_gate(candidate: Experiment, *, baseline: Experiment, maximum_regression: float = 0.02, minimum_score: float = 0.8) GateDecision[source]#
- class rath.observability.InMemoryTelemetry[source]#
Reference exporter used by tests and embedded diagnostics.
- property spans: tuple[SpanRecord, ...]#
- class rath.observability.GuardedTelemetry(delegate: Telemetry)[source]#
Failure-isolating wrapper: exporter faults never change application results.
- class rath.observability.NoOpTelemetry[source]#
- class rath.observability.OpenTelemetry(*, service_name: str = 'openrath', tracer_provider: Any | None = None, meter_provider: Any | None = None)[source]#
Telemetry implementation backed by configured OpenTelemetry providers.
- class rath.observability.SpanRecord(name: 'str', trace_id: 'str', span_id: 'str', parent_span_id: 'str | None', started_at: 'datetime', ended_at: 'datetime', duration_ms: 'float', status: 'str', attributes: 'Mapping[str, JSONValue]' = <factory>)[source]#
- class rath.observability.StructuredLogger(sink: Callable[[str], None] | None = None)[source]#
Emit stable JSON records without ever failing the application path.
- class rath.observability.Telemetry(*args, **kwargs)[source]#
Public durable runtime state and persistence contracts.
- class rath.runtime.ApprovalDecision(kind: 'ApprovalDecisionKind', actor_id: 'str', reason: 'str', payload: 'Mapping[str, JSONValue]' = <factory>)[source]#
- kind: ApprovalDecisionKind#
- class rath.runtime.ApprovalDecisionKind(value)[source]#
An enumeration.
- APPROVE = 'approve'#
- EDIT = 'edit'#
- REJECT = 'reject'#
- RESPOND = 'respond'#
- class rath.runtime.Checkpoint(id: 'UUID', run_id: 'UUID', sequence: 'int', plan_hash: 'str', state: 'Mapping[str, JSONValue]', next_nodes: 'tuple[str, ...]', pending_interrupts: 'tuple[UUID, ...]', effect_watermark: 'int', created_at: 'datetime')[source]#
- class rath.runtime.ClaimedRun(run: 'Run', lease: 'ResourceLease')[source]#
-
- lease: ResourceLease#
- exception rath.runtime.ConflictError(message: str, *, details: Mapping[str, object] | None = None)[source]#
- class rath.runtime.EffectLedger(*args, **kwargs)[source]#
- prepare(*, run_id: UUID, tool_name: str, effect_class: EffectClass, arguments_digest: str, idempotency_key: str | None, node_id: str | None = None, checkpoint_sequence: int | None = None) ToolInvocation[source]#
- get(invocation_id: UUID) ToolInvocation[source]#
- mark_dispatched(invocation_id: UUID) ToolInvocation[source]#
- complete(invocation_id: UUID, result: object) ToolInvocation[source]#
- fail(invocation_id: UUID, error: str) ToolInvocation[source]#
- reconcile_stale(*, older_than: datetime) tuple[ToolInvocation, ...][source]#
- class rath.runtime.ExecutionServices(policy: PolicyEngine, tools: ToolExecutor, providers: ProviderExecutor, sandboxes: SandboxExecutor, memory: MemoryExecutor, effects: EffectLedger, audit: AuditSink)[source]#
Governed capabilities made available to a workflow step.
- policy: PolicyEngine#
- tools: ToolExecutor#
- providers: ProviderExecutor#
- sandboxes: SandboxExecutor#
- memory: MemoryExecutor#
- effects: EffectLedger#
- class rath.runtime.Interrupt(id: 'UUID', run_id: 'UUID', kind: 'InterruptKind', request: 'Mapping[str, JSONValue]', created_at: 'datetime', expires_at: 'datetime | None' = None, decision: 'ApprovalDecision | None' = None, decided_at: 'datetime | None' = None)[source]#
-
- kind: InterruptKind#
- request: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
- decision: ApprovalDecision | None#
- class rath.runtime.InterruptKind(value)[source]#
An enumeration.
- APPROVAL = 'approval'#
- INPUT = 'input'#
- REVIEW = 'review'#
- class rath.runtime.InvocationStatus(value)[source]#
An enumeration.
- PREPARED = 'prepared'#
- DISPATCHED = 'dispatched'#
- SUCCEEDED = 'succeeded'#
- FAILED = 'failed'#
- AMBIGUOUS = 'ambiguous'#
- class rath.runtime.GuardedSignalBus(inner: SignalBus)[source]#
Best-effort wrapper preserving database success when Redis is unavailable.
- class rath.runtime.LocalRuntime(store: RunStore, *, telemetry: Telemetry | None = None, structured_logger: StructuredLogger | None = None, effect_ledger: EffectLedger | None = None, production_mode: bool = False, execution_services: ExecutionServices | None = None, step_executor: StepExecutor | None = None)[source]#
Sync façade over the durable local worker engine.
- register(workflow: object, *, revision_id: UUID) ExecutionPlan[source]#
- submit(workflow: object, *, session_id: UUID, context: RunContext, state: Mapping[str, object] | None = None, idempotency_key: str | None = None, priority: int = 0) Run[source]#
- exception rath.runtime.PlanMismatchError[source]#
A durable checkpoint does not belong to the registered executable plan.
- class rath.runtime.PostgresRunStore(dsn: str, *, schema: str = 'openrath', auto_migrate: bool = False, pool_max_size: int = 20)[source]#
Transactional Postgres store using row locks and fencing tokens.
- connection() Iterator[Any][source]#
Borrow a schema-configured pooled connection for related stores.
- list_runs(*, tenant_id: str, after: UUID | None = None, limit: int | None = None, session_id: UUID | None = None, statuses: tuple[RunStatus, ...] | None = None) tuple[Run, ...][source]#
- transition_run(run_id: UUID, *, expected_version: int, target: RunStatus, state: Mapping[str, object] | None = None, next_nodes: tuple[str, ...] | None = None) Run[source]#
- list_run_events(run_id: UUID, *, after_sequence: int = 0, limit: int | None = None) tuple[RunEvent, ...][source]#
- append_checkpoint(checkpoint: Checkpoint) None[source]#
- latest_checkpoint(run_id: UUID) Checkpoint | None[source]#
- list_checkpoints(run_id: UUID) tuple[Checkpoint, ...][source]#
- commit_checkpoint(checkpoint: Checkpoint, *, worker_id: str, fencing_token: int, expected_run_version: int) Run[source]#
- finish_claim(run_id: UUID, *, worker_id: str, fencing_token: int, expected_run_version: int, target: RunStatus, event_type: str = 'run.execution.completed', event_data: Mapping[str, object] | None = None) Run[source]#
- decide_interrupt(interrupt_id: UUID, *, decision: ApprovalDecision, expected_run_version: int) Run[source]#
- claim_next(*, worker_id: str, lease_seconds: float, now: datetime | None = None) ClaimedRun | None[source]#
- class rath.runtime.PythonStepExecutor(store: RunStore)[source]#
Reference in-process executor for embedded and async durable steps.
- class rath.runtime.PostgresEffectLedger(dsn: str, *, schema: str = 'openrath')[source]#
Effect ledger sharing a production Postgres Run schema.
- prepare(*, run_id: UUID, tool_name: str, effect_class: EffectClass, arguments_digest: str, idempotency_key: str | None, node_id: str | None = None, checkpoint_sequence: int | None = None) ToolInvocation[source]#
- get(invocation_id: UUID) ToolInvocation[source]#
- mark_dispatched(invocation_id: UUID) ToolInvocation[source]#
- complete(invocation_id: UUID, result: object) ToolInvocation[source]#
- fail(invocation_id: UUID, error: str) ToolInvocation[source]#
- reconcile_stale(*, older_than: datetime) tuple[ToolInvocation, ...][source]#
- class rath.runtime.Reconciliation(retryable: 'tuple[UUID, ...]', needs_review: 'tuple[UUID, ...]')[source]#
- class rath.runtime.RedisSignalBus(url: str, *, namespace: str = 'openrath', client: object | None = None)[source]#
Redis list transport used only to reduce polling latency.
- class rath.runtime.Run(id: 'UUID', plan_id: 'UUID', revision_id: 'UUID', session_id: 'UUID', tenant_id: 'str', status: 'RunStatus', state: 'Mapping[str, JSONValue]', next_nodes: 'tuple[str, ...]', created_at: 'datetime', updated_at: 'datetime', version: 'int' = 0, idempotency_key: 'str | None' = None, context: 'Mapping[str, JSONValue]' = <factory>, priority: 'int' = 0)[source]#
-
- state: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
- context: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
- classmethod create(*, plan_id: UUID, revision_id: UUID, session_id: UUID, tenant_id: str, status: RunStatus = RunStatus.QUEUED, state: Mapping[str, object] | None = None, next_nodes: tuple[str, ...] = (), idempotency_key: str | None = None, context: Mapping[str, object] | None = None, priority: int = 0, id: UUID | None = None) Run[source]#
- class rath.runtime.RunEvent(run_id: 'UUID', sequence: 'int', type: 'str', data: 'Mapping[str, JSONValue]', created_at: 'datetime')[source]#
- class rath.runtime.RunStatus(value)[source]#
An enumeration.
- QUEUED = 'queued'#
- RUNNING = 'running'#
- WAITING = 'waiting'#
- SUCCEEDED = 'succeeded'#
- FAILED = 'failed'#
- CANCELLED = 'cancelled'#
- TIMED_OUT = 'timed_out'#
- NEEDS_REVIEW = 'needs_review'#
- class rath.runtime.RunSignal(kind: 'SignalKind', run_id: 'UUID', tenant_id: 'str', created_at: 'datetime')[source]#
- kind: SignalKind#
- class rath.runtime.ResourceLease(id: 'UUID', resource_type: 'str', resource_id: 'str', owner_run_id: 'UUID', holder_worker_id: 'str', expires_at: 'datetime', fencing_token: 'int', created_at: 'datetime', updated_at: 'datetime')[source]#
- class rath.runtime.RunStore(*args, **kwargs)[source]#
-
- list_runs(*, tenant_id: str, after: UUID | None = None, limit: int | None = None, session_id: UUID | None = None, statuses: tuple[RunStatus, ...] | None = None) tuple[Run, ...][source]#
- transition_run(run_id: UUID, *, expected_version: int, target: RunStatus, state: Mapping[str, object] | None = None, next_nodes: tuple[str, ...] | None = None) Run[source]#
- list_run_events(run_id: UUID, *, after_sequence: int = 0, limit: int | None = None) tuple[RunEvent, ...][source]#
- append_checkpoint(checkpoint: Checkpoint) None[source]#
- latest_checkpoint(run_id: UUID) Checkpoint | None[source]#
- list_checkpoints(run_id: UUID) tuple[Checkpoint, ...][source]#
- commit_checkpoint(checkpoint: Checkpoint, *, worker_id: str, fencing_token: int, expected_run_version: int) Run[source]#
- decide_interrupt(interrupt_id: UUID, *, decision: ApprovalDecision, expected_run_version: int) Run[source]#
- claim_next(*, worker_id: str, lease_seconds: float, now: datetime | None = None) ClaimedRun | None[source]#
- renew_lease(run_id: UUID, *, worker_id: str, fencing_token: int, lease_seconds: float, now: datetime | None = None) ResourceLease[source]#
- class rath.runtime.SQLiteRunStore(path: str | Path)[source]#
SQLite source of truth for local mode; every mutation is transactional.
- list_runs(*, tenant_id: str, after: UUID | None = None, limit: int | None = None, session_id: UUID | None = None, statuses: tuple[RunStatus, ...] | None = None) tuple[Run, ...][source]#
- transition_run(run_id: UUID, *, expected_version: int, target: RunStatus, state: Mapping[str, object] | None = None, next_nodes: tuple[str, ...] | None = None) Run[source]#
- list_run_events(run_id: UUID, *, after_sequence: int = 0, limit: int | None = None) tuple[RunEvent, ...][source]#
- append_checkpoint(checkpoint: Checkpoint) None[source]#
- latest_checkpoint(run_id: UUID) Checkpoint | None[source]#
- list_checkpoints(run_id: UUID) tuple[Checkpoint, ...][source]#
- commit_checkpoint(checkpoint: Checkpoint, *, worker_id: str, fencing_token: int, expected_run_version: int) Run[source]#
- finish_claim(run_id: UUID, *, worker_id: str, fencing_token: int, expected_run_version: int, target: RunStatus, event_type: str = 'run.execution.completed', event_data: Mapping[str, object] | None = None) Run[source]#
- decide_interrupt(interrupt_id: UUID, *, decision: ApprovalDecision, expected_run_version: int) Run[source]#
- claim_next(*, worker_id: str, lease_seconds: float, now: datetime | None = None) ClaimedRun | None[source]#
- class rath.runtime.SQLiteEffectLedger(path: str)[source]#
Effect ledger sharing the embedded runtime SQLite database.
- prepare(*, run_id: UUID, tool_name: str, effect_class: EffectClass, arguments_digest: str, idempotency_key: str | None, node_id: str | None = None, checkpoint_sequence: int | None = None) ToolInvocation[source]#
- get(invocation_id: UUID) ToolInvocation[source]#
- mark_dispatched(invocation_id: UUID) ToolInvocation[source]#
- complete(invocation_id: UUID, result: object) ToolInvocation[source]#
- fail(invocation_id: UUID, error: str) ToolInvocation[source]#
- reconcile_stale(*, older_than: datetime) tuple[ToolInvocation, ...][source]#
- class rath.runtime.StepContext(run_id: 'UUID', request: 'RunContext', worker_id: 'str', fencing_token: 'int', policy_manifest: 'Mapping[str, JSONValue]', services: 'ExecutionServices | None', _interrupt_handler: 'Callable[[InterruptKind, Mapping[str, object], float | None], ApprovalDecision]')[source]#
-
- request: RunContext#
- policy_manifest: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
- services: ExecutionServices | None#
- interrupt(kind: InterruptKind, request: Mapping[str, object], *, timeout_seconds: float | None = None) ApprovalDecision[source]#
Suspend durably on first call and return the decision after resume.
- class rath.runtime.StepExecutor(*args, **kwargs)[source]#
Execute one compiled node through the durable worker boundary.
- exception rath.runtime.StepSuspended[source]#
Internal control flow indicating a durable interrupt boundary.
- class rath.runtime.ToolInvocation(id: 'UUID', run_id: 'UUID', tool_name: 'str', effect_class: 'EffectClass', arguments_digest: 'str', status: 'InvocationStatus', created_at: 'datetime', updated_at: 'datetime', node_id: 'str | None' = None, checkpoint_sequence: 'int | None' = None, invocation_sequence: 'int | None' = None, idempotency_key: 'str | None' = None, result: 'JSONValue | None' = None, error: 'str | None' = None)[source]#
-
- effect_class: EffectClass#
- status: InvocationStatus#
- rath.runtime.reconcile_stale_effects(ledger: EffectLedger, run_store: RunStore, *, grace_seconds: float = 30.0, now: datetime | None = None) Reconciliation[source]#
Classify dispatched work after a worker crash.
Idempotent calls may be retried under their stable key. Non-idempotent calls are never replayed automatically and move their Run to NEEDS_REVIEW.
Public security contracts for identity, policy, secrets, and audit.
- exception rath.security.ApprovalRequiredError(decision: PolicyDecision)[source]#
- class rath.security.AuditEvent(id: 'UUID', kind: 'AuditKind', occurred_at: 'datetime', tenant_id: 'str', principal_id: 'str', request_id: 'UUID', trace_id: 'str', action: 'str', resource_kind: 'str', resource_id: 'str', outcome: 'str', reason: 'str', policy_id: 'str | None' = None, attributes: 'Mapping[str, JSONValue]' = <factory>)[source]#
-
- attributes: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
- classmethod for_policy_decision(*, kind: AuditKind, action: Action, resource: ResourceRef, context: RunContext, decision: PolicyDecision, attributes: Mapping[str, object] | None = None) AuditEvent[source]#
- class rath.security.AuditKind(value)[source]#
An enumeration.
- AUTHENTICATION = 'authentication'#
- POLICY_DECISION = 'policy_decision'#
- SECRET_RESOLUTION = 'secret_resolution'#
- TOOL_ACCESS = 'tool_access'#
- SANDBOX_ACCESS = 'sandbox_access'#
- MEMORY_ACCESS = 'memory_access'#
- RUN_CONTROL = 'run_control'#
- OPERATOR_OVERRIDE = 'operator_override'#
- exception rath.security.AuthorizationError(decision: PolicyDecision)[source]#
- async rath.security.authorize(engine: PolicyEngine, *, action: Action, resource: ResourceRef, context: RunContext) PolicyDecision[source]#
Evaluate a policy and turn non-allow effects into stable exceptions.
- class rath.security.DenyAllPolicy[source]#
Safe default for service and untrusted deployment profiles.
- async evaluate(action: Action, resource: ResourceRef, context: RunContext) PolicyDecision[source]#
- class rath.security.InMemoryAuditSink[source]#
Deterministic reference sink for embedded mode and contract tests.
- property events: tuple[AuditEvent, ...]#
- async emit(event: AuditEvent) None[source]#
- class rath.security.LocalTrustedPolicy[source]#
Explicit opt-in policy for the embedded trusted-process profile.
- async evaluate(action: Action, resource: ResourceRef, context: RunContext) PolicyDecision[source]#
- class rath.security.PolicyConstraints(timeout_seconds: 'float | None' = None, max_output_bytes: 'int | None' = None, allowed_network_hosts: 'frozenset[str]' = <factory>, filesystem_root: 'str | None' = None, read_only: 'bool' = False, redactions: 'frozenset[str]' = <factory>)[source]#
- class rath.security.PolicyDecision(effect: 'PolicyEffect', reason: 'str', policy_id: 'str', constraints: 'PolicyConstraints' = <factory>)[source]#
- effect: PolicyEffect#
- constraints: PolicyConstraints#
- class rath.security.PolicyEffect(value)[source]#
An enumeration.
- ALLOW = 'allow'#
- DENY = 'deny'#
- REQUIRE_APPROVAL = 'require_approval'#
- ALLOW_WITH_CONSTRAINTS = 'allow_with_constraints'#
- class rath.security.PolicyEngine(*args, **kwargs)[source]#
- async evaluate(action: Action, resource: ResourceRef, context: RunContext) PolicyDecision[source]#
- class rath.security.Principal(id: str, kind: ~rath.security.context.PrincipalKind, claims: ~collections.abc.Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | ~collections.abc.Mapping[str, JSONValue]] = <factory>)[source]#
Authenticated caller identity detached from transport concerns.
- kind: PrincipalKind#
- class rath.security.PrincipalKind(value)[source]#
An enumeration.
- USER = 'user'#
- SERVICE = 'service'#
- SYSTEM = 'system'#
- class rath.security.Provenance(source_type: str, source_id: str, producer: str | None = None, metadata: ~collections.abc.Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | ~collections.abc.Mapping[str, JSONValue]] = <factory>)[source]#
Origin metadata carried by untrusted and trusted content.
- class rath.security.ResolvedSecret(ref: SecretRef, value: str)[source]#
Short-lived secret value whose representation is always redacted.
- class rath.security.ResourceRef(kind: 'str', id: 'str', tenant_id: 'str | None' = None, attributes: 'Mapping[str, JSONValue]' = <factory>)[source]#
- class rath.security.SecretResolver(*args, **kwargs)[source]#
- async resolve(ref: SecretRef, *, context: RunContext) ResolvedSecret[source]#
- class rath.security.SecurityContext(principal: ~rath.security.context.Principal, tenant_id: str, project_id: str | None = None, grants: frozenset[str] = <factory>, attributes: ~collections.abc.Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | ~collections.abc.Mapping[str, JSONValue]] = <factory>)[source]#
Run-scoped identity and tenant boundary.
- attributes: Mapping[str, None | bool | int | float | str | tuple[JSONValue, ...] | Mapping[str, JSONValue]]#
- classmethod local(*, grants: Iterable[str] = ('trusted_host',)) SecurityContext[source]#
Create the explicit trusted-process context for embedded local mode.
- class rath.security.StructuredAuditSink(sink: Callable[[str], None] | None = None)[source]#
Emit redacted, newline-delimited JSON security audit records.
The default sink writes and flushes stdout so container log collectors can retain the security stream independently from diagnostic traces. Sink failures deliberately propagate: a production reference deployment must not silently discard an audit record.
- async emit(event: AuditEvent) None[source]#
- class rath.security.TrustLevel(value)[source]#
An enumeration.
- UNTRUSTED = 'untrusted'#
- TRUSTED = 'trusted'#
- SYSTEM = 'system'#
- class rath.server.AgentServer(store: RunStore, runtime: LocalRuntime, *, auth: AuthProvider, resources: ResourceStore | None = None, embedded_worker: bool = False, worker_id: str = 'agent-server', signals: SignalBus | None = None, worker_lease_seconds: float = 30.0, max_queued_runs_per_tenant: int = 1000, memory_executor: MemoryExecutor | None = None, memory_handler: MemoryHandler | None = None, audit_sink: AuditSink | None = None)[source]#
- class rath.server.AssistantRecord(id: 'str', tenant_id: 'str', template_id: 'str', revision_id: 'UUID', created_at: 'datetime')[source]#
- class rath.server.FeedbackRecord(id: 'UUID', tenant_id: 'str', run_id: 'UUID', key: 'str', score: 'float | None', value: 'str | None', created_at: 'datetime')[source]#
- class rath.server.InMemoryResourceStore[source]#
- create_assistant(*, tenant_id: str, id: str, template_id: str, revision_id: UUID) AssistantRecord[source]#
- get_assistant(tenant_id: str, id: str) AssistantRecord[source]#
- list_assistants(tenant_id: str) tuple[AssistantRecord, ...][source]#
- create_session(tenant_id: str) SessionRecord[source]#
- get_session(session_id: UUID) SessionRecord[source]#
- ensure_session(session: SessionRecord) SessionRecord[source]#
- class rath.server.PostgresResourceStore(run_store: PostgresRunStore)[source]#
Multi-replica resource store sharing the production Run schema.
- create_assistant(*, tenant_id: str, id: str, template_id: str, revision_id: UUID) AssistantRecord[source]#
- get_assistant(tenant_id: str, id: str) AssistantRecord[source]#
- list_assistants(tenant_id: str) tuple[AssistantRecord, ...][source]#
- create_session(tenant_id: str) SessionRecord[source]#
- get_session(session_id: UUID) SessionRecord[source]#
- ensure_session(session: SessionRecord) SessionRecord[source]#
- class rath.server.ResourceStore(*args, **kwargs)[source]#
- create_assistant(*, tenant_id: str, id: str, template_id: str, revision_id: UUID) AssistantRecord[source]#
- get_assistant(tenant_id: str, id: str) AssistantRecord[source]#
- list_assistants(tenant_id: str) tuple[AssistantRecord, ...][source]#
- create_session(tenant_id: str) SessionRecord[source]#
- get_session(session_id: UUID) SessionRecord[source]#
- ensure_session(session: SessionRecord) SessionRecord[source]#
- class rath.server.SQLiteResourceStore(run_store: SQLiteRunStore)[source]#
Resource store sharing the embedded Run database.
- create_assistant(*, tenant_id: str, id: str, template_id: str, revision_id: UUID) AssistantRecord[source]#
- get_assistant(tenant_id: str, id: str) AssistantRecord[source]#
- list_assistants(tenant_id: str) tuple[AssistantRecord, ...][source]#
- create_session(tenant_id: str) SessionRecord[source]#
- get_session(session_id: UUID) SessionRecord[source]#
- ensure_session(session: SessionRecord) SessionRecord[source]#
- class rath.server.StaticTokenAuth(tokens: dict[str, SecurityContext])[source]#
Reference bearer-token provider for self-hosted deployments and tests.
- rath.server.create_app(server: AgentServer) Starlette[source]#
- class rath.client.AsyncRemoteClient(base_url: str, *, token: str, timeout: float = 30.0)[source]#
- async create_run(*, assistant_id: str, session_id: str, state: dict[str, object] | None = None, idempotency_key: str | None = None) dict[str, Any][source]#
- async store(operation: str, payload: dict[str, object], *, user_id: str | None = None, agent_id: str | None = None, session_id: str | None = None) dict[str, Any][source]#
- async list_interrupts(*, pending_only: bool = True, limit: int = 50) tuple[dict[str, Any], ...][source]#
- async decide_interrupt(interrupt_id: str, *, kind: str, reason: str, payload: dict[str, object] | None = None) dict[str, Any][source]#
- class rath.client.RemoteClient(base_url: str, *, token: str, timeout: float = 30.0)[source]#
- create_run(*, assistant_id: str, session_id: str, state: dict[str, object] | None = None, idempotency_key: str | None = None) dict[str, Any][source]#
- store(operation: str, payload: dict[str, object], *, user_id: str | None = None, agent_id: str | None = None, session_id: str | None = None) dict[str, Any][source]#
- decide_interrupt(interrupt_id: str, *, kind: str, reason: str, payload: dict[str, object] | None = None) dict[str, Any][source]#