Skip to main content

Overview

The Runtime class is the core interface agents use to record their behavior. It captures decisions, outcomes, and problems in a structured format that the Builder LLM can analyze to improve agent performance.

Class: Runtime

from framework import Runtime

runtime = Runtime("/path/to/storage")

Constructor

storage_path
str | Path
required
Path to the storage directory for run data

Run Lifecycle

start_run()

Start a new run for a goal.
run_id = runtime.start_run(
    goal_id="goal_123",
    goal_description="Qualify sales leads",
    input_data={"lead_name": "Acme Corp"}
)
goal_id
str
required
The ID of the goal being pursued
goal_description
str
default:""
Human-readable description of the goal
input_data
dict[str, Any] | None
default:"None"
Initial input data for the run
run_id
str
Unique identifier for this run (format: run_YYYYMMDD_HHMMSS_hash)

end_run()

End the current run and save results.
runtime.end_run(
    success=True,
    narrative="Qualified 10 leads successfully",
    output_data={"qualified_count": 10}
)
success
bool
required
Whether the run achieved its goal
narrative
str
default:""
Human-readable summary of what happened
output_data
dict[str, Any] | None
default:"None"
Final output of the run

set_node()

Set the current node context for subsequent decisions.
runtime.set_node("lead-qualifier")
node_id
str
required
ID of the node being executed

Decision Recording

decide()

Record a decision the agent made. This is the primary method for capturing agent behavior.
decision_id = runtime.decide(
    intent="Determine if lead has budget",
    options=[
        {
            "id": "ask",
            "description": "Ask the lead directly",
            "action_type": "tool_call",
            "action_params": {"tool": "send_email"},
            "pros": ["Direct answer"],
            "cons": ["Might be awkward"],
            "confidence": 0.6
        },
        {
            "id": "infer",
            "description": "Infer from company size",
            "action_type": "generate",
            "pros": ["Fast", "Non-intrusive"],
            "cons": ["Less accurate"],
            "confidence": 0.8
        }
    ],
    chosen="infer",
    reasoning="Company data is available, asking would be slower",
    node_id="lead-qualifier",
    decision_type=DecisionType.TOOL_SELECTION,
    constraints=["no_spam", "under_5_seconds"],
    context={"company_size": 500, "industry": "tech"}
)
intent
str
required
What the agent was trying to accomplish
options
list[dict[str, Any]]
required
List of options considered. Each option should have:
  • id (str): Unique identifier
  • description (str): What this option does
  • action_type (str): β€œtool_call”, β€œgenerate”, β€œdelegate”, etc.
  • action_params (dict, optional): Parameters for the action
  • pros (list[str], optional): Why this might be good
  • cons (list[str], optional): Why this might be bad
  • confidence (float, optional): Agent’s confidence (0-1)
chosen
str
required
ID of the chosen option
reasoning
str
required
Why the agent chose this option
node_id
str | None
default:"None"
Which node made this decision (uses current if not set)
decision_type
DecisionType
default:"DecisionType.CUSTOM"
Type of decision: TOOL_SELECTION, PARAMETER_CHOICE, PATH_CHOICE, OUTPUT_FORMAT, RETRY_STRATEGY, DELEGATION, TERMINATION, CUSTOM
constraints
list[str] | None
default:"None"
Active constraints that influenced the decision
context
dict[str, Any] | None
default:"None"
Additional context available when deciding
decision_id
str
The decision ID (use to record outcome later)

record_outcome()

Record the outcome of a decision after executing the action.
runtime.record_outcome(
    decision_id=decision_id,
    success=True,
    result={"has_budget": True, "estimated": "$50k"},
    summary="Inferred budget of $50k from company revenue",
    state_changes={"lead_qualified": True},
    tokens_used=150,
    latency_ms=420
)
decision_id
str
required
ID returned from decide()
success
bool
required
Whether the action succeeded
result
Any
default:"None"
The actual result/output
error
str | None
default:"None"
Error message if failed
summary
str
default:""
Human-readable summary of what happened
state_changes
dict[str, Any] | None
default:"None"
What state changed as a result
tokens_used
int
default:"0"
LLM tokens consumed
latency_ms
int
default:"0"
Time taken in milliseconds

Problem Reporting

report_problem()

Report a problem that occurred during execution.
problem_id = runtime.report_problem(
    severity="warning",
    description="API rate limit approaching",
    decision_id=decision_id,
    root_cause="Too many requests in short time",
    suggested_fix="Implement exponential backoff"
)
severity
str
required
Problem severity: β€œcritical”, β€œwarning”, or β€œminor”
description
str
required
What went wrong
decision_id
str | None
default:"None"
Which decision caused this (if known)
root_cause
str | None
default:"None"
Why it went wrong (if known)
suggested_fix
str | None
default:"None"
What might fix it (if known)
problem_id
str
The problem ID

Convenience Methods

decide_and_execute()

Record a decision and immediately execute it.
decision_id, result = runtime.decide_and_execute(
    intent="Calculate tax",
    options=[{"id": "calc", "description": "Run calculator"}],
    chosen="calc",
    reasoning="Standard calculation",
    executor=lambda: calculate_tax(amount)
)
executor
Callable
required
Function to call to execute the action
tuple
tuple[str, Any]
Tuple of (decision_id, result)

quick_decision()

Record a simple decision with a single action (no alternatives).
decision_id = runtime.quick_decision(
    intent="Format output",
    action="Convert to JSON",
    reasoning="Standard format",
    node_id="formatter"
)
intent
str
required
What the agent is trying to do
action
str
required
What it’s doing
reasoning
str
required
Why
node_id
str | None
default:"None"
Node making the decision
decision_id
str
The decision ID

Properties

current_run

Get the current run object for inspection.
run = runtime.current_run
if run:
    print(f"Run ID: {run.id}")
    print(f"Decisions: {len(run.decisions)}")
current_run
Run | None
The current Run object, or None if no run is active

execution_id

Get the current execution ID for trace correlation.
exec_id = runtime.execution_id
execution_id
str
The execution ID (32-character hex string)

Example Usage

from framework import Runtime
from framework.schemas.decision import DecisionType

# Initialize runtime
runtime = Runtime("/tmp/agent-storage")

# Start a run
run_id = runtime.start_run(
    goal_id="qualify-leads",
    goal_description="Qualify incoming sales leads",
    input_data={"lead_name": "Acme Corp"}
)

# Set node context
runtime.set_node("budget-checker")

# Record a decision
decision_id = runtime.decide(
    intent="Check if lead has budget",
    options=[
        {"id": "ask", "description": "Ask directly"},
        {"id": "infer", "description": "Infer from company size"}
    ],
    chosen="infer",
    reasoning="Company data available",
    decision_type=DecisionType.PATH_CHOICE
)

# Execute and record outcome
try:
    result = check_budget_from_company_data()
    runtime.record_outcome(
        decision_id=decision_id,
        success=True,
        result=result,
        summary=f"Estimated budget: {result['budget']}"
    )
except Exception as e:
    runtime.record_outcome(
        decision_id=decision_id,
        success=False,
        error=str(e)
    )
    runtime.report_problem(
        severity="critical",
        description="Budget check failed",
        decision_id=decision_id
    )

# End the run
runtime.end_run(
    success=True,
    narrative="Lead qualified with estimated budget",
    output_data={"qualified": True, "budget": "$50k"}
)

Build docs developers (and LLMs) love