Files
temp/features/steps/agent_langgraph_port_steps.py

480 lines
15 KiB
Python

"""Step definitions for actor-first agent and LangGraph port."""
import json
from behave import given, then, when
@given("the agent system is initialized with actor-first configuration")
def init_agent_system(context):
"""Initialize the agent system for actor-first operation."""
context.agent_system_initialized = True
context.agents = {}
context.graphs = {}
context.factories = {}
@given("I have a stateful LangGraph configuration:")
def create_stateful_graph_config(context):
"""Create stateful LangGraph configuration."""
config_text = context.text.strip()
context.graph_config = json.loads(config_text)
@when("I create the stateful graph")
def create_stateful_graph(context):
"""Create stateful graph from configuration."""
config = context.graph_config
# Simulate graph creation with actor
context.created_graph = {
"name": config["name"],
"actor": config.get("actor"),
"checkpointing": config.get("checkpointing", False),
"enable_time_travel": config.get("enable_time_travel", False),
"nodes": config.get("nodes", {}),
"edges": config.get("edges", []),
"state": {},
"state_history": [],
}
context.graphs[config["name"]] = context.created_graph
@then('the graph should be created with actor "{actor}"')
def verify_graph_actor(context, actor):
"""Verify graph uses specified actor."""
assert context.created_graph["actor"] == actor
@then("the graph state should be persisted")
def verify_graph_persistence(context):
"""Verify graph state persistence."""
assert context.created_graph["checkpointing"] is True
assert "state" in context.created_graph
assert "state_history" in context.created_graph
@then("time travel should be enabled")
def verify_time_travel(context):
"""Verify time travel is enabled."""
assert context.created_graph["enable_time_travel"] is True
@given("I have an agent configuration:")
def create_agent_config(context):
"""Create agent configuration."""
config_text = context.text.strip()
context.agent_config = json.loads(config_text)
@when("I create an agent from the configuration")
def create_agent(context):
"""Create agent from configuration."""
config = context.agent_config
# Simulate agent creation
context.created_agent = {
"name": config["name"],
"type": config["type"],
"actor": config.get("actor"),
"module_accessible": True,
}
context.agents[config["name"]] = context.created_agent
@then("the agent should be created successfully")
def verify_agent_creation(context):
"""Verify agent was created successfully."""
assert context.created_agent is not None
assert context.created_agent["name"] == context.agent_config["name"]
@then('the agent should use actor "{actor}"')
def verify_agent_actor(context, actor):
"""Verify agent uses specified actor."""
assert context.created_agent["actor"] == actor
@then("the agent module should be accessible")
def verify_agent_module(context):
"""Verify agent module is accessible."""
assert context.created_agent["module_accessible"] is True
@given("I have a chain agent configuration:")
def create_chain_config(context):
"""Create chain agent configuration."""
config_text = context.text.strip()
context.chain_config = json.loads(config_text)
@when("I create a chain agent from the configuration")
def create_chain_agent(context):
"""Create chain agent from configuration."""
config = context.chain_config
# Simulate chain agent creation
context.created_chain = {
"name": config["name"],
"type": config["type"],
"actor": config.get("actor"),
"steps": config.get("steps", []),
"prompt": config.get("prompt"),
}
context.agents[config["name"]] = context.created_chain
@then("the chain agent should be created successfully")
def verify_chain_creation(context):
"""Verify chain agent was created successfully."""
assert context.created_chain is not None
assert context.created_chain["name"] == context.chain_config["name"]
@then("the chain agent should have {count:d} steps")
def verify_chain_steps(context, count):
"""Verify chain agent has expected number of steps."""
assert len(context.created_chain["steps"]) == count
@then('the chain agent should use actor "{actor}"')
def verify_chain_actor(context, actor):
"""Verify chain agent uses specified actor."""
assert context.created_chain["actor"] == actor
@given('I have a chain agent with actor "{actor}"')
def create_chain_with_actor(context, actor):
"""Create chain agent with specific actor."""
context.chain_agent = {
"name": "test_chain",
"type": "chain",
"actor": actor,
"steps": [],
}
@given("the chain has steps {steps}")
def add_chain_steps(context, steps):
"""Add steps to chain agent."""
# Parse steps list from string like '["parse", "analyze", "format"]'
import ast
step_list = ast.literal_eval(steps)
context.chain_agent["steps"] = step_list
@when('I process the message "{message}"')
def process_message(context, message):
"""Process message through chain agent."""
agent = context.chain_agent
# Simulate message processing
result = f"Processed with {agent['actor']}: {message}"
for step in agent["steps"]:
result += f" -> {step}"
context.processing_result = result
@then("the chain should use the specified actor")
def verify_chain_uses_actor(context):
"""Verify chain uses specified actor."""
assert context.chain_agent["actor"] in context.processing_result
@then("the result should show processing through all steps")
def verify_all_steps_processed(context):
"""Verify all steps were processed."""
for step in context.chain_agent["steps"]:
assert step in context.processing_result
@given("I have a composite agent configuration:")
def create_composite_config(context):
"""Create composite agent configuration."""
config_text = context.text.strip()
context.composite_config = json.loads(config_text)
@when("I create a composite agent from the configuration")
def create_composite_agent(context):
"""Create composite agent from configuration."""
config = context.composite_config
# Simulate composite agent creation
context.created_composite = {
"name": config["name"],
"type": config["type"],
"agents": config.get("agents", []),
"parallel_enabled": True,
}
context.agents[config["name"]] = context.created_composite
@then("the composite agent should have {count:d} sub-agents")
def verify_subagent_count(context, count):
"""Verify composite agent has expected number of sub-agents."""
assert len(context.created_composite["agents"]) == count
@then("each sub-agent should use its configured actor")
def verify_subagent_actors(context):
"""Verify each sub-agent uses its configured actor."""
for agent in context.created_composite["agents"]:
assert "actor" in agent
assert agent["actor"] is not None
@then("parallel processing should work with all actors")
def verify_parallel_processing(context):
"""Verify parallel processing is enabled."""
assert context.created_composite["parallel_enabled"] is True
@given("I have a reactive agent configuration:")
def create_reactive_config(context):
"""Create reactive agent configuration."""
config_text = context.text.strip()
context.reactive_config = json.loads(config_text)
@when("I create a reactive agent from the configuration")
def create_reactive_agent(context):
"""Create reactive agent from configuration."""
config = context.reactive_config
# Simulate reactive agent creation
context.created_reactive = {
"name": config["name"],
"type": config["type"],
"actor": config.get("actor"),
"stream_config": config.get("stream_config", {}),
"supports_streaming": True,
}
context.agents[config["name"]] = context.created_reactive
@then("the agent should support reactive streaming")
def verify_reactive_streaming(context):
"""Verify agent supports reactive streaming."""
assert context.created_reactive["supports_streaming"] is True
@then('the stream should use actor "{actor}"')
def verify_stream_actor(context, actor):
"""Verify stream uses specified actor."""
assert context.created_reactive["actor"] == actor
@then("operators should transform data through the actor")
def verify_operators(context):
"""Verify operators are configured."""
stream_config = context.created_reactive.get("stream_config", {})
assert "operators" in stream_config
assert len(stream_config["operators"]) > 0
@given("I have a tool agent configuration:")
def create_tool_config(context):
"""Create tool agent configuration."""
config_text = context.text.strip()
context.tool_config = json.loads(config_text)
@when("I create a tool agent from the configuration")
def create_tool_agent(context):
"""Create tool agent from configuration."""
config = context.tool_config
# Simulate tool agent creation
context.created_tool = {
"name": config["name"],
"type": config["type"],
"actor": config.get("actor"),
"tools": config.get("tools", []),
}
context.agents[config["name"]] = context.created_tool
@then("the tool agent should have {count:d} tools available")
def verify_tool_count(context, count):
"""Verify tool agent has expected number of tools."""
assert len(context.created_tool["tools"]) == count
@then('the tool agent should use actor "{actor}"')
def verify_tool_agent_actor(context, actor):
"""Verify tool agent uses specified actor."""
assert context.created_tool["actor"] == actor
@then("tool calls should be routed through the actor")
def verify_tool_routing(context):
"""Verify tool calls are routed through actor."""
# In a real implementation, this would verify the routing mechanism
assert context.created_tool["actor"] is not None
assert len(context.created_tool["tools"]) > 0
@given("I have a complex LangGraph with multiple actors:")
def create_complex_graph(context):
"""Create complex LangGraph with multiple actors."""
config_text = context.text.strip()
context.visualization_config = json.loads(config_text)
@when("I visualize the graph")
def visualize_graph(context):
"""Visualize the graph."""
config = context.visualization_config
# Simulate graph visualization
context.visualization = {
"name": config["name"],
"nodes": [],
"edges": config.get("edges", []),
"actor_transitions": [],
}
# Extract node information with actors
for node_name, node_data in config["nodes"].items():
context.visualization["nodes"].append(
{
"name": node_name,
"type": node_data["type"],
"actor": node_data.get("actor"),
}
)
# Identify actor transitions
for edge in context.visualization["edges"]:
source_node = next(
n for n in context.visualization["nodes"] if n["name"] == edge["source"]
)
target_node = next(
n for n in context.visualization["nodes"] if n["name"] == edge["target"]
)
if source_node.get("actor") != target_node.get("actor"):
context.visualization["actor_transitions"].append(
{"from": source_node["actor"], "to": target_node["actor"], "edge": edge}
)
@then("the visualization should show all nodes with their actors")
def verify_visualization_nodes(context):
"""Verify visualization shows all nodes with actors."""
for node in context.visualization["nodes"]:
assert "actor" in node
assert node["actor"] is not None
@then("the edge flow should be clearly represented")
def verify_edge_flow(context):
"""Verify edge flow is represented."""
assert len(context.visualization["edges"]) > 0
# Verify all edges have source and target
for edge in context.visualization["edges"]:
assert "source" in edge
assert "target" in edge
@then("actor transitions should be highlighted")
def verify_actor_transitions(context):
"""Verify actor transitions are highlighted."""
assert len(context.visualization["actor_transitions"]) > 0
@given('I have an agent factory with default actor "{actor}"')
def create_agent_factory(context, actor):
"""Create agent factory with default actor."""
context.agent_factory = {"default_actor": actor, "created_agents": []}
@when("I create multiple agents using the factory:")
def create_multiple_agents(context):
"""Create multiple agents using factory."""
# Store table data for later verification
context.agent_table_data = []
# Parse table data
for row in context.table:
agent = {
"name": row["agent_name"],
"type": row["agent_type"],
"actor": context.agent_factory["default_actor"],
}
context.agent_factory["created_agents"].append(agent)
context.agents[agent["name"]] = agent
# Store table row for later verification
context.agent_table_data.append(
{"agent_name": row["agent_name"], "agent_type": row["agent_type"]}
)
@then('all agents should use the default actor "{actor}"')
def verify_default_actor(context, actor):
"""Verify all agents use default actor."""
for agent in context.agent_factory["created_agents"]:
assert agent["actor"] == actor
@then("each agent should have the correct type")
def verify_agent_types(context):
"""Verify each agent has correct type."""
for row in context.agent_table_data:
agent = context.agents[row["agent_name"]]
assert agent["type"] == row["agent_type"]
@given("I have a LangGraph with conditional routing:")
def create_conditional_graph(context):
"""Create LangGraph with conditional routing."""
config_text = context.text.strip()
context.conditional_config = json.loads(config_text)
@when("I route a request that needs vision")
def route_vision_request(context):
"""Route a request that needs vision."""
config = context.conditional_config
# Simulate routing decision
context.routing_context = {"needs_vision": True}
# Find router node
router_node = config["nodes"]["router"]
# Evaluate conditions
for condition in router_node["conditions"]:
if condition.get("if") == "needs_vision" and context.routing_context.get(
"needs_vision"
):
context.selected_route = {
"target": condition.get("then"),
"actor": condition.get("actor"),
}
break
@then('the request should be routed to "{actor}"')
def verify_routing_actor(context, actor):
"""Verify request is routed to correct actor."""
assert context.selected_route["actor"] == actor
@then("the routing decision should be based on actor capabilities")
def verify_capability_routing(context):
"""Verify routing is based on actor capabilities."""
# In a real implementation, this would check capability matching
assert context.selected_route is not None
assert "actor" in context.selected_route