Coverage for stackone_ai/integrations/langgraph.py: 0%

29 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-12-24 09:48 +0000

1"""LangGraph integration helpers. 

2 

3These utilities convert StackOne tools into LangGraph prebuilt components. 

4 

5Usage: 

6 from stackone_ai import StackOneToolSet 

7 from stackone_ai.integrations.langgraph import to_tool_node 

8 

9 toolset = StackOneToolSet() 

10 tools = toolset.fetch_tools(actions=["bamboohr_*"], account_ids=["..."]) 

11 node = to_tool_node(tools) # langgraph.prebuilt.ToolNode 

12""" 

13 

14from __future__ import annotations 

15 

16from collections.abc import Sequence 

17from typing import Any 

18 

19from langchain_core.tools import BaseTool 

20 

21from stackone_ai.models import Tools 

22 

23 

24def _ensure_langgraph() -> None: 

25 try: 

26 from langgraph import prebuilt as _ # noqa: F401 # ty: ignore[unresolved-import] 

27 except Exception as e: # pragma: no cover 

28 raise ImportError( 

29 "LangGraph is not installed. Install with `pip install langgraph` or " 

30 "`pip install 'stackone-ai[examples]'`" 

31 ) from e 

32 

33 

34def _to_langchain_tools(tools: Tools | Sequence[BaseTool]) -> Sequence[BaseTool]: 

35 if isinstance(tools, Tools): 

36 return tools.to_langchain() 

37 return tools 

38 

39 

40def to_tool_node(tools: Tools | Sequence[BaseTool], **kwargs: Any) -> Any: 

41 """Create a LangGraph `ToolNode` from StackOne tools or LangChain tools. 

42 

43 Accepts either a `Tools` collection from this SDK or an existing sequence of 

44 LangChain `BaseTool` instances and returns a LangGraph `ToolNode` suitable 

45 for inclusion in a graph. 

46 """ 

47 _ensure_langgraph() 

48 from langgraph.prebuilt import ToolNode # ty: ignore[unresolved-import] 

49 

50 langchain_tools = _to_langchain_tools(tools) 

51 return ToolNode(langchain_tools, **kwargs) 

52 

53 

54def to_tool_executor(tools: Tools | Sequence[BaseTool], **kwargs: Any) -> Any: 

55 """Create a LangGraph `ToolNode` from StackOne tools or LangChain tools. 

56 

57 Note: ToolExecutor has been deprecated in favor of ToolNode. 

58 This function now returns a ToolNode for compatibility. 

59 """ 

60 _ensure_langgraph() 

61 from langgraph.prebuilt import ToolNode # ty: ignore[unresolved-import] 

62 

63 langchain_tools = _to_langchain_tools(tools) 

64 return ToolNode(langchain_tools, **kwargs) 

65 

66 

67def bind_model_with_tools(model: Any, tools: Tools | Sequence[BaseTool]) -> Any: 

68 """Bind tools to an LLM that supports LangChain's `.bind_tools()` API. 

69 

70 This is a tiny helper that converts a `Tools` collection to LangChain tools 

71 and calls `model.bind_tools(...)`. 

72 """ 

73 langchain_tools = _to_langchain_tools(tools) 

74 return model.bind_tools(langchain_tools) 

75 

76 

77def create_react_agent(llm: Any, tools: Tools | Sequence[BaseTool], **kwargs: Any) -> Any: 

78 """Create a LangGraph ReAct agent using StackOne tools. 

79 

80 Thin wrapper around `langgraph.prebuilt.create_react_agent` that accepts a 

81 `Tools` collection from this SDK. 

82 """ 

83 _ensure_langgraph() 

84 from langgraph.prebuilt import create_react_agent as _create # ty: ignore[unresolved-import] 

85 

86 return _create(llm, _to_langchain_tools(tools), **kwargs)