Agent Runtime
Unified execution system for all Hive agents. Every agent — single-entry or multi-entry, headless or dashboard — runs through the same runtime stack.
Topology
AgentRunner.load(agent_path)
|
AgentRunner
(factory + public API)
|
_setup_agent_runtime()
|
AgentRuntime
(lifecycle + orchestration)
/ | \
Stream A Stream B Stream C ← one per entry point
| | |
GraphExecutor GraphExecutor GraphExecutor
| | |
Node → Node → Node (graph traversal)
Single-entry agents get a "default" entry point automatically. There is no separate code path.
Components
| Component | File | Role |
|---|---|---|
AgentRunner |
runner/runner.py |
Load agents, configure tools/LLM, expose high-level API |
AgentRuntime |
runtime/agent_runtime.py |
Lifecycle management, entry point routing, event bus |
ExecutionStream |
runtime/execution_stream.py |
Per-entry-point execution queue, session persistence |
GraphExecutor |
graph/executor.py |
Node traversal, tool dispatch, checkpointing |
EventBus |
runtime/event_bus.py |
Pub/sub for execution events (streaming, I/O) |
SharedBufferManager |
runtime/shared_state.py |
Cross-stream state with isolation levels |
OutcomeAggregator |
runtime/outcome_aggregator.py |
Goal progress tracking across streams |
SessionStore |
storage/session_store.py |
Session state persistence (sessions/{id}/state.json) |
Programming Interface
AgentRunner (high-level)
from framework.runner import AgentRunner
# Load and run
runner = AgentRunner.load("exports/my_agent", model="anthropic/claude-sonnet-4-20250514")
result = await runner.run({"query": "hello"})
# Resume from paused session
result = await runner.run({"query": "continue"}, session_state=saved_state)
# Lifecycle
await runner.start() # Start the runtime
await runner.stop() # Stop the runtime
exec_id = await runner.trigger("default", {}) # Non-blocking trigger
entry_points = runner.get_entry_points() # List entry points
# Context manager
async with AgentRunner.load("exports/my_agent") as runner:
result = await runner.run({"query": "hello"})
# Cleanup
runner.cleanup() # Synchronous
await runner.cleanup_async() # Asynchronous
AgentRuntime (lower-level)
from framework.runtime.agent_runtime import AgentRuntime, create_agent_runtime
from framework.runtime.execution_stream import EntryPointSpec
# Create runtime with entry points
runtime = create_agent_runtime(
graph=graph,
goal=goal,
storage_path=Path("~/.hive/agents/my_agent"),
entry_points=[
EntryPointSpec(id="default", name="Default", entry_node="start", trigger_type="manual"),
],
llm=llm,
tools=tools,
tool_executor=tool_executor,
checkpoint_config=checkpoint_config,
)
# Lifecycle
await runtime.start()
await runtime.stop()
# Execution
exec_id = await runtime.trigger("default", {"query": "hello"}) # Non-blocking
result = await runtime.trigger_and_wait("default", {"query": "hello"}) # Blocking
result = await runtime.trigger_and_wait("default", {}, session_state=state) # Resume
# Client-facing node I/O
await runtime.inject_input(node_id="chat", content="user response")
# Events
sub_id = runtime.subscribe_to_events(
event_types=[EventType.CLIENT_OUTPUT_DELTA],
handler=my_handler,
)
runtime.unsubscribe_from_events(sub_id)
# Inspection
runtime.is_running # bool
runtime.event_bus # EventBus
runtime.state_manager # SharedBufferManager
runtime.get_stats() # Runtime statistics
Execution Flow
AgentRunner.run()callsAgentRuntime.trigger_and_wait()AgentRuntimeroutes to theExecutionStreamfor the entry pointExecutionStreamcreates aGraphExecutorand callsexecute()GraphExecutortraverses nodes, dispatches tools, manages checkpointsExecutionResultflows back up through the stackExecutionStreamwrites session state to disk
Session Resume
All execution paths support session resume:
# First run (agent pauses at a client-facing node)
result = await runner.run({"query": "start task"})
# result.paused_at = "review-node"
# result.session_state = {"memory": {...}, "paused_at": "review-node", ...}
# Resume
result = await runner.run({"input": "approved"}, session_state=result.session_state)
Session state flows: AgentRunner.run() → AgentRuntime.trigger_and_wait() → ExecutionStream.execute() → GraphExecutor.execute().
Checkpoints are saved at node boundaries (sessions/{id}/checkpoints/) for crash recovery.
Event Bus
The EventBus provides real-time execution visibility:
| Event | When |
|---|---|
NODE_STARTED |
Node begins execution |
NODE_COMPLETED |
Node finishes |
TOOL_CALL_STARTED |
Tool invocation begins |
TOOL_CALL_COMPLETED |
Tool invocation finishes |
CLIENT_OUTPUT_DELTA |
Agent streams text to user |
CLIENT_INPUT_REQUESTED |
Agent needs user input |
EXECUTION_COMPLETED |
Full execution finishes |
In headless mode, AgentRunner subscribes to CLIENT_OUTPUT_DELTA and CLIENT_INPUT_REQUESTED to print output and read stdin. The web dashboard subscribes to route events to the frontend.
Storage Layout
~/.hive/agents/{agent_name}/
sessions/
session_YYYYMMDD_HHMMSS_{uuid}/
state.json # Session state (status, memory, progress)
checkpoints/ # Node-boundary snapshots
logs/
summary.json # Execution summary
details.jsonl # Detailed event log
tool_logs.jsonl # Tool call log
runtime_logs/ # Cross-session runtime logs