langgraph-agent-toolkit 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. langgraph_agent_toolkit/__init__.py +7 -0
  2. langgraph_agent_toolkit/agents/__init__.py +0 -0
  3. langgraph_agent_toolkit/agents/agent.py +14 -0
  4. langgraph_agent_toolkit/agents/agent_executor.py +415 -0
  5. langgraph_agent_toolkit/agents/blueprints/__init__.py +0 -0
  6. langgraph_agent_toolkit/agents/blueprints/bg_task_agent/__init__.py +0 -0
  7. langgraph_agent_toolkit/agents/blueprints/bg_task_agent/agent.py +69 -0
  8. langgraph_agent_toolkit/agents/blueprints/bg_task_agent/task.py +52 -0
  9. langgraph_agent_toolkit/agents/blueprints/bg_task_agent/utils.py +17 -0
  10. langgraph_agent_toolkit/agents/blueprints/chatbot/__init__.py +0 -0
  11. langgraph_agent_toolkit/agents/blueprints/chatbot/agent.py +34 -0
  12. langgraph_agent_toolkit/agents/blueprints/command_agent/__init__.py +0 -0
  13. langgraph_agent_toolkit/agents/blueprints/command_agent/agent.py +54 -0
  14. langgraph_agent_toolkit/agents/blueprints/interrupt_agent/__init__.py +0 -0
  15. langgraph_agent_toolkit/agents/blueprints/interrupt_agent/agent.py +140 -0
  16. langgraph_agent_toolkit/agents/blueprints/react/__init__.py +0 -0
  17. langgraph_agent_toolkit/agents/blueprints/react/agent.py +67 -0
  18. langgraph_agent_toolkit/agents/blueprints/react_so/__init__.py +0 -0
  19. langgraph_agent_toolkit/agents/blueprints/react_so/agent.py +39 -0
  20. langgraph_agent_toolkit/agents/blueprints/supervisor_agent/__init__.py +0 -0
  21. langgraph_agent_toolkit/agents/blueprints/supervisor_agent/agent.py +44 -0
  22. langgraph_agent_toolkit/agents/components/__init__.py +0 -0
  23. langgraph_agent_toolkit/agents/components/creators/__init__.py +4 -0
  24. langgraph_agent_toolkit/agents/components/creators/create_react_agent.py +459 -0
  25. langgraph_agent_toolkit/agents/components/tools.py +13 -0
  26. langgraph_agent_toolkit/agents/components/utils.py +42 -0
  27. langgraph_agent_toolkit/client/__init__.py +4 -0
  28. langgraph_agent_toolkit/client/client.py +344 -0
  29. langgraph_agent_toolkit/core/__init__.py +5 -0
  30. langgraph_agent_toolkit/core/memory/__init__.py +0 -0
  31. langgraph_agent_toolkit/core/memory/base.py +33 -0
  32. langgraph_agent_toolkit/core/memory/factory.py +30 -0
  33. langgraph_agent_toolkit/core/memory/postgres.py +76 -0
  34. langgraph_agent_toolkit/core/memory/sqlite.py +21 -0
  35. langgraph_agent_toolkit/core/memory/types.py +6 -0
  36. langgraph_agent_toolkit/core/models/__init__.py +5 -0
  37. langgraph_agent_toolkit/core/models/chat_openai.py +21 -0
  38. langgraph_agent_toolkit/core/models/factory.py +118 -0
  39. langgraph_agent_toolkit/core/models/fake.py +25 -0
  40. langgraph_agent_toolkit/core/observability/__init__.py +10 -0
  41. langgraph_agent_toolkit/core/observability/base.py +331 -0
  42. langgraph_agent_toolkit/core/observability/empty.py +67 -0
  43. langgraph_agent_toolkit/core/observability/factory.py +43 -0
  44. langgraph_agent_toolkit/core/observability/langfuse.py +118 -0
  45. langgraph_agent_toolkit/core/observability/langsmith.py +131 -0
  46. langgraph_agent_toolkit/core/observability/types.py +34 -0
  47. langgraph_agent_toolkit/core/prompts/__init__.py +0 -0
  48. langgraph_agent_toolkit/core/prompts/chat_prompt_template.py +528 -0
  49. langgraph_agent_toolkit/core/settings.py +164 -0
  50. langgraph_agent_toolkit/helper/__init__.py +0 -0
  51. langgraph_agent_toolkit/helper/constants.py +10 -0
  52. langgraph_agent_toolkit/helper/logging.py +111 -0
  53. langgraph_agent_toolkit/helper/types.py +7 -0
  54. langgraph_agent_toolkit/helper/utils.py +80 -0
  55. langgraph_agent_toolkit/run_agent.py +68 -0
  56. langgraph_agent_toolkit/run_client.py +55 -0
  57. langgraph_agent_toolkit/run_service.py +19 -0
  58. langgraph_agent_toolkit/schema/__init__.py +28 -0
  59. langgraph_agent_toolkit/schema/models.py +25 -0
  60. langgraph_agent_toolkit/schema/schema.py +210 -0
  61. langgraph_agent_toolkit/schema/task_data.py +72 -0
  62. langgraph_agent_toolkit/service/__init__.py +0 -0
  63. langgraph_agent_toolkit/service/exception_handlers.py +46 -0
  64. langgraph_agent_toolkit/service/factory.py +213 -0
  65. langgraph_agent_toolkit/service/handler.py +122 -0
  66. langgraph_agent_toolkit/service/middleware.py +18 -0
  67. langgraph_agent_toolkit/service/routes.py +169 -0
  68. langgraph_agent_toolkit/service/types.py +8 -0
  69. langgraph_agent_toolkit/service/utils.py +136 -0
  70. langgraph_agent_toolkit/streamlit_app.py +368 -0
  71. langgraph_agent_toolkit-0.1.0.dist-info/METADATA +424 -0
  72. langgraph_agent_toolkit-0.1.0.dist-info/RECORD +74 -0
  73. langgraph_agent_toolkit-0.1.0.dist-info/WHEEL +4 -0
  74. langgraph_agent_toolkit-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,140 @@
1
+ from datetime import datetime
2
+ from typing import Any, cast
3
+
4
+ from langchain.prompts import SystemMessagePromptTemplate
5
+ from langchain_core.language_models.chat_models import BaseChatModel
6
+ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
7
+ from langchain_core.runnables import RunnableConfig, RunnableLambda, RunnableSerializable
8
+ from langgraph.checkpoint.memory import MemorySaver
9
+ from langgraph.graph import END, MessagesState, StateGraph
10
+ from langgraph.types import interrupt
11
+ from pydantic import BaseModel, Field
12
+
13
+ from langgraph_agent_toolkit.agents.agent import Agent
14
+ from langgraph_agent_toolkit.core import settings
15
+ from langgraph_agent_toolkit.core.models.factory import ModelFactory
16
+
17
+
18
+ class AgentState(MessagesState, total=False):
19
+ """`total=False` is PEP589 specs.
20
+
21
+ documentation: https://typing.readthedocs.io/en/latest/spec/typeddict.html#totality
22
+ """
23
+
24
+ birthdate: datetime | None
25
+
26
+
27
+ def wrap_model(model: BaseChatModel, system_prompt: BaseMessage) -> RunnableSerializable[Any, BaseMessage]:
28
+ preprocessor = RunnableLambda(
29
+ lambda state: [system_prompt] + state["messages"],
30
+ name="StateModifier",
31
+ )
32
+ return preprocessor | model
33
+
34
+
35
+ background_prompt = SystemMessagePromptTemplate.from_template("""
36
+ You are a helpful assistant that tells users there zodiac sign.
37
+ Provide a one paragraph summary of the origin of zodiac signs.
38
+ Don't tell the user what their sign is, you are just demonstrating your knowledge on the topic.
39
+ """)
40
+
41
+
42
+ async def background(state: AgentState, config: RunnableConfig) -> AgentState:
43
+ """Demonstrate doing work before the interrupt."""
44
+ m = ModelFactory.create(config["configurable"].get("model", settings.DEFAULT_MODEL))
45
+ model_runnable = wrap_model(m, background_prompt.format())
46
+ response = await model_runnable.ainvoke(state, config)
47
+
48
+ return {"messages": [AIMessage(content=response.content)]}
49
+
50
+
51
+ birthdate_extraction_prompt = SystemMessagePromptTemplate.from_template("""
52
+ You are an expert at extracting birthdates from conversational text.
53
+
54
+ Rules for extraction:
55
+ - Look for user messages that mention birthdates
56
+ - Consider various date formats (MM/DD/YYYY, YYYY-MM-DD, Month Day, Year)
57
+ - Validate that the date is reasonable (not in the future)
58
+ - If no clear birthdate was provided by the user, return None
59
+ """)
60
+
61
+
62
+ class BirthdateExtraction(BaseModel):
63
+ birthdate: str | None = Field(
64
+ description="The extracted birthdate in YYYY-MM-DD format. If no birthdate is found, this should be None."
65
+ )
66
+ reasoning: str = Field(description="Explanation of how the birthdate was extracted or why no birthdate was found")
67
+
68
+
69
+ async def determine_birthdate(state: AgentState, config: RunnableConfig) -> AgentState:
70
+ """Examine the conversation history to determine user's birthdate.
71
+
72
+ If no birthdate is found, it will perform an interrupt before proceeding.
73
+ """
74
+ m = ModelFactory.create(config["configurable"].get("model", settings.DEFAULT_MODEL))
75
+ model_runnable = wrap_model(
76
+ m.with_structured_output(BirthdateExtraction),
77
+ birthdate_extraction_prompt.format(),
78
+ ).with_config(tags=["skip_stream"])
79
+ response = await model_runnable.ainvoke(state, config)
80
+ response = cast(BirthdateExtraction, response)
81
+
82
+ # If no birthdate found, interrupt
83
+ if response.birthdate is None:
84
+ birthdate_input = interrupt(f"{response.reasoning}\nPlease tell me your birthdate?")
85
+ # Re-run extraction with the new input
86
+ state["messages"].append(HumanMessage(birthdate_input))
87
+ return await determine_birthdate(state, config)
88
+
89
+ # Birthdate found - convert string to datetime
90
+ try:
91
+ birthdate = datetime.fromisoformat(response.birthdate)
92
+ except ValueError:
93
+ # If parsing fails, ask for clarification
94
+ birthdate_input = interrupt(
95
+ "I couldn't understand the date format. Please provide your birthdate in YYYY-MM-DD format."
96
+ )
97
+ state["messages"].append(HumanMessage(birthdate_input))
98
+ return await determine_birthdate(state, config)
99
+
100
+ # Birthdate found
101
+ return {
102
+ "birthdate": birthdate,
103
+ }
104
+
105
+
106
+ sign_prompt = SystemMessagePromptTemplate.from_template("""
107
+ You are a helpful assistant that tells users there zodiac sign.
108
+ What is the sign of somebody born on {birthdate}?
109
+ """)
110
+
111
+
112
+ async def determine_sign(state: AgentState, config: RunnableConfig) -> AgentState:
113
+ """Determine the zodiac sign of the user based on their birthdate."""
114
+ if not state.get("birthdate"):
115
+ raise ValueError("No birthdate found in state")
116
+
117
+ m = ModelFactory.create(config["configurable"].get("model", settings.DEFAULT_MODEL))
118
+ model_runnable = wrap_model(m, sign_prompt.format(birthdate=state["birthdate"].strftime("%Y-%m-%d")))
119
+ response = await model_runnable.ainvoke(state, config)
120
+
121
+ return {"messages": [AIMessage(content=response.content)]}
122
+
123
+
124
+ # Define the graph
125
+ agent = StateGraph(AgentState)
126
+ agent.add_node("background", background)
127
+ agent.add_node("determine_birthdate", determine_birthdate)
128
+ agent.add_node("determine_sign", determine_sign)
129
+
130
+ agent.set_entry_point("background")
131
+ agent.add_edge("background", "determine_birthdate")
132
+ agent.add_edge("determine_birthdate", "determine_sign")
133
+ agent.add_edge("determine_sign", END)
134
+
135
+ interrupt_agent = Agent(
136
+ name="interrupt-agent",
137
+ description="An agent the uses interrupts.",
138
+ graph=agent.compile(checkpointer=MemorySaver()),
139
+ )
140
+ interrupt_agent.graph.name = "interrupt-agent"
@@ -0,0 +1,67 @@
1
+ from langchain_community.tools import DuckDuckGoSearchResults
2
+ from langgraph.checkpoint.memory import MemorySaver
3
+
4
+ from langgraph_agent_toolkit.agents.agent import Agent
5
+ from langgraph_agent_toolkit.agents.components.creators.create_react_agent import create_react_agent
6
+ from langgraph_agent_toolkit.agents.components.tools import add, multiply
7
+ from langgraph_agent_toolkit.agents.components.utils import AgentStateWithRemainingSteps, pre_model_hook_standard
8
+ from langgraph_agent_toolkit.core.models.factory import ModelFactory
9
+ from langgraph_agent_toolkit.core.observability.factory import ObservabilityFactory
10
+ from langgraph_agent_toolkit.core.observability.types import ChatMessageDict, MessageRole, ObservabilityBackend
11
+ from langgraph_agent_toolkit.core.prompts.chat_prompt_template import ObservabilityChatPromptTemplate
12
+ from langgraph_agent_toolkit.core.settings import settings
13
+
14
+
15
+ PROMPT_NAME = "react-assistant"
16
+
17
+
18
+ # observability = ObservabilityFactory.create(settings.OBSERVABILITY_BACKEND)
19
+ observability = ObservabilityFactory.create(ObservabilityBackend.LANGFUSE)
20
+
21
+ # Push the prompt template to the observability platform first
22
+ observability.push_prompt(
23
+ name=PROMPT_NAME,
24
+ prompt_template=[
25
+ ChatMessageDict(
26
+ role=MessageRole.SYSTEM,
27
+ content=(
28
+ "You are a team support agent that can perform calculations and search the web. "
29
+ "You can use the tools provided to help you with your tasks. "
30
+ "You can also ask clarifying questions to the user. "
31
+ ),
32
+ ),
33
+ ChatMessageDict(
34
+ role=MessageRole.PLACEHOLDER,
35
+ content="messages",
36
+ ),
37
+ ],
38
+ create_new_version=True,
39
+ )
40
+
41
+ print(observability.pull_prompt(name=PROMPT_NAME))
42
+
43
+ # Create ObservabilityChatPromptTemplate that will load from observability platform at runtime
44
+ prompt = ObservabilityChatPromptTemplate.from_observability_platform(
45
+ prompt_name=PROMPT_NAME,
46
+ observability_platform=observability,
47
+ load_at_runtime=True,
48
+ template_format="jinja2",
49
+ input_variables=["messages"],
50
+ )
51
+
52
+ react_agent = Agent(
53
+ name="react-agent",
54
+ description="A react agent.",
55
+ graph=create_react_agent(
56
+ model=ModelFactory.create(settings.DEFAULT_MODEL),
57
+ tools=[add, multiply, DuckDuckGoSearchResults()],
58
+ prompt=prompt,
59
+ pre_model_hook=pre_model_hook_standard,
60
+ state_schema=AgentStateWithRemainingSteps,
61
+ checkpointer=MemorySaver(),
62
+ immediate_step_threshold=5,
63
+ ),
64
+ observability=observability,
65
+ )
66
+
67
+ __all__ = ["react_agent"]
@@ -0,0 +1,39 @@
1
+ from langchain_community.tools import DuckDuckGoSearchResults
2
+ from langgraph.checkpoint.memory import MemorySaver
3
+ from pydantic import BaseModel, Field
4
+
5
+ from langgraph_agent_toolkit.agents.agent import Agent
6
+ from langgraph_agent_toolkit.agents.components.creators.create_react_agent import create_react_agent
7
+ from langgraph_agent_toolkit.agents.components.tools import add, multiply
8
+ from langgraph_agent_toolkit.agents.components.utils import AgentStateWithRemainingSteps, pre_model_hook_standard
9
+ from langgraph_agent_toolkit.core import settings
10
+ from langgraph_agent_toolkit.core.models.factory import ModelFactory
11
+
12
+
13
+ class ResponseSchema(BaseModel):
14
+ response: list[str] = Field(
15
+ description="The response on user query.",
16
+ )
17
+ alternative_response: str = Field(
18
+ description="The alternative response on user query.",
19
+ )
20
+
21
+
22
+ react_agent_so = Agent(
23
+ name="react-agent-so",
24
+ description="A react agent with structured output.",
25
+ graph=create_react_agent(
26
+ model=ModelFactory.create(settings.DEFAULT_MODEL),
27
+ tools=[add, multiply, DuckDuckGoSearchResults()],
28
+ prompt=(
29
+ "You are a team support agent that can perform calculations and search the web. "
30
+ "You can use the tools provided to help you with your tasks. "
31
+ "You can also ask clarifying questions to the user. "
32
+ ),
33
+ pre_model_hook=pre_model_hook_standard,
34
+ response_format=ResponseSchema,
35
+ state_schema=AgentStateWithRemainingSteps,
36
+ checkpointer=MemorySaver(),
37
+ immediate_step_threshold=5,
38
+ ),
39
+ )
@@ -0,0 +1,44 @@
1
+ from langchain_community.tools import DuckDuckGoSearchResults
2
+ from langgraph.checkpoint.memory import MemorySaver
3
+ from langgraph.prebuilt import create_react_agent
4
+ from langgraph_supervisor import create_supervisor
5
+
6
+ from langgraph_agent_toolkit.agents.agent import Agent
7
+ from langgraph_agent_toolkit.agents.components.tools import add, multiply
8
+ from langgraph_agent_toolkit.core import settings
9
+ from langgraph_agent_toolkit.core.models.factory import ModelFactory
10
+
11
+
12
+ model = ModelFactory.create(settings.DEFAULT_MODEL)
13
+
14
+ math_agent = create_react_agent(
15
+ model=model,
16
+ tools=[add, multiply],
17
+ name="math_expert",
18
+ prompt="You are a math expert. Always use one tool at a time.",
19
+ ).with_config(tags=["skip_stream"])
20
+
21
+ research_agent = create_react_agent(
22
+ model=model,
23
+ tools=[DuckDuckGoSearchResults()],
24
+ name="research_expert",
25
+ prompt="You are a world class researcher with access to web search. Do not do any math.",
26
+ ).with_config(tags=["skip_stream"])
27
+
28
+ # Create supervisor workflow
29
+ workflow = create_supervisor(
30
+ [research_agent, math_agent],
31
+ model=model,
32
+ prompt=(
33
+ "You are a team supervisor managing a research expert and a math expert. "
34
+ "For current events, use research_agent. "
35
+ "For math problems, use math_agent."
36
+ ),
37
+ add_handoff_back_messages=False,
38
+ )
39
+
40
+ supervisor_agent = Agent(
41
+ name="supervisor-agent",
42
+ description="A langgraph supervisor agent",
43
+ graph=workflow.compile(checkpointer=MemorySaver()),
44
+ )
File without changes
@@ -0,0 +1,4 @@
1
+ from langgraph_agent_toolkit.agents.components.creators.create_react_agent import create_react_agent
2
+
3
+
4
+ __all__ = ["create_react_agent"]