small refactor of the structure
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""
|
||||
Tools adapter — bridges the existing skill/tool system with LangGraph's ToolNode.
|
||||
|
||||
LangGraph's ToolNode expects callable tools (typically @tool-decorated functions).
|
||||
This module wraps our skill-based tool definitions and async executors so
|
||||
ToolNode can invoke them without any changes to the skills/ layer.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from langchain_core.tools import tool
|
||||
|
||||
from agents.skills import get_all_tools, execute_tool
|
||||
|
||||
|
||||
def build_langgraph_tools(skill_names: list[str]) -> list:
|
||||
"""
|
||||
Convert the registered skill tool definitions into LangChain-compatible
|
||||
@tool-decorated functions that ToolNode can call.
|
||||
|
||||
Each tool wraps the existing `execute_tool()` pipeline, so the skill
|
||||
system's ToolResult + httpx session handling is fully preserved.
|
||||
"""
|
||||
tool_defs = get_all_tools(skill_names)
|
||||
wrapped: list = []
|
||||
|
||||
for td in tool_defs:
|
||||
fn_def = td.get("function", {})
|
||||
fn_name = fn_def.get("name", "")
|
||||
fn_desc = fn_def.get("description", "")
|
||||
|
||||
# Create a unique factory so each closure captures the right fn_name
|
||||
def _make_tool(name: str, desc: str, skills: list[str]):
|
||||
@tool(name, description=desc)
|
||||
async def _wrapped(**kwargs: Any) -> str:
|
||||
"""Execute the tool via the skill system and return its content."""
|
||||
result = await execute_tool(skills, name, kwargs)
|
||||
if result is None:
|
||||
return f"Tool '{name}' is not available."
|
||||
return result.content
|
||||
|
||||
# Stash the original OpenAI schema so LangGraph can use it
|
||||
_wrapped.metadata = fn_def
|
||||
return _wrapped
|
||||
|
||||
wrapped.append(_make_tool(fn_name, fn_desc, skill_names))
|
||||
|
||||
return wrapped
|
||||
Reference in New Issue
Block a user