This repository has been archived on 2026-04-03. You can view files and clone it, but cannot push or open issues or pull requests.
agent-runtime/agent/node_pool.py
Nico ae2338e70a Implement NodePool + contextvar HUD for Phase 2 shared nodes
- agent/node_pool.py: NodePool class creates shared stateless node instances,
  excludes stateful roles (sensor, memorizer, ui)
- agent/nodes/base.py: _current_hud contextvar for per-task HUD isolation,
  Node.hud() checks contextvar first, falls back to instance callback
- 15/15 engine tests green (4 new Phase 2 tests pass)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:36:46 +02:00

51 lines
1.6 KiB
Python

"""NodePool: shared stateless node instances across all sessions.
Stateless nodes (InputNode, PANode, ExpertNode, etc.) hold no per-session
state — only config (model, system prompt). They can safely serve multiple
concurrent sessions. Session-specific HUD routing uses contextvars.
Stateful nodes (SensorNode, MemorizerNode, UINode) hold conversational
state and must be created per-session.
"""
import logging
from .engine import load_graph, instantiate_nodes
log = logging.getLogger("runtime")
# Roles that hold per-session state — always created fresh per Runtime
STATEFUL_ROLES = frozenset({"sensor", "memorizer", "ui"})
async def _noop_hud(data: dict):
"""Placeholder HUD — shared nodes use contextvars for session routing."""
pass
class NodePool:
"""Shared node instances for stateless LLM nodes.
Usage:
pool = NodePool("v4-eras")
# Shared nodes (one instance, all sessions):
input_node = pool.shared["input"]
# Stateful nodes must be created per-session (not in pool)
"""
def __init__(self, graph_name: str = "v4-eras"):
self.graph = load_graph(graph_name)
self.graph_name = graph_name
# Instantiate all nodes with noop HUD (shared nodes use contextvars)
all_nodes = instantiate_nodes(self.graph, send_hud=_noop_hud)
# Split: shared (stateless) vs excluded (stateful)
self.shared = {
role: node for role, node in all_nodes.items()
if role not in STATEFUL_ROLES
}
log.info(f"[pool] created for graph '{graph_name}': "
f"{len(self.shared)} shared, {len(STATEFUL_ROLES)} stateful")