adelevett's picture
Deploy ELBench-live dashboard
5db30ac verified
Raw History Blame Contribute Delete
3.1 kB
import asyncio
from typing import Dict, Any, Tuple, Optional
from uuid import uuid4
from langgraph.graph.state import CompiledStateGraph
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt.chat_agent_executor import AgentState
from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
import aiosqlite
from elbench.basic_education_runtime.entity import AgentConfig
from elbench.basic_education_runtime.router import * # noqa: F403
from elbench.basic_education_runtime.config import CONFIG
def add_node_to_graph(graph: StateGraph, node_id: str, node_instance: Any) -> None:
if node_id not in graph.nodes:
graph.add_node(node_id, node_instance)
else:
pass
async def apply_agent_direction_from_dict(
agent_map: Dict[str, Tuple[CompiledStateGraph, AgentConfig]],
memory_id: Optional[str] = None,
task: Optional[Dict[str, str]] = None,
) -> Tuple[CompiledStateGraph, str]:
if memory_id is None:
memory_id = str(uuid4())
directions = CONFIG.directions
graph = StateGraph(AgentState)
for node_id, node_instance in agent_map.items():
graph.add_node(node_id, node_instance[0])
for direction in directions:
start_node, end_node = (i.strip() for i in direction.split("->"))
if start_node == "START":
start_node = START
if end_node.startswith("router:"):
function_call = end_node[len("router:") :]
route, path_map = eval(function_call)
end_node = end_node.replace(":", "_")
graph.add_conditional_edges(start_node, route, path_map)
continue
# add_node_to_graph(graph, end_node, route)
elif end_node == "END":
end_node = END
else:
agent_config = agent_map[end_node][1]
pregel_instance = agent_map[end_node][0]
if not pregel_instance or not agent_config:
raise ValueError(f"Invalid configuration for {end_node}.")
graph.add_edge(start_node, end_node)
CONFIG.globals.memory.path.mkdir(parents=True, exist_ok=True)
path = CONFIG.globals.memory.path / f"{memory_id}.db"
# conn = sqlite3.connect(f"{memory_id}.db", check_same_thread=False)
if task is not None:
async with aiosqlite.connect(path) as conn:
sql = "create table task (key TEXT, value TEXT)"
await conn.execute(sql)
sql = "insert into task (key, value) values (?, ?)"
for key, value in task.items():
await conn.execute(sql, (key, value))
await conn.commit()
# await conn.close()
conn = aiosqlite.connect(path, check_same_thread=False)
if not hasattr(conn, "is_alive"):
conn.is_alive = lambda: bool( # type: ignore[attr-defined]
getattr(conn, "_running", False) and getattr(conn, "_connection", None) is not None
)
CONFIG.context.conns.append(conn)
memory = AsyncSqliteSaver(conn)
return graph.compile(checkpointer=memory), memory_id
apply_agent_direction = apply_agent_direction_from_dict