Skip to content

Commit 5106352

Browse files
committed
fall back to mock llm
1 parent 47c023e commit 5106352

1 file changed

Lines changed: 77 additions & 11 deletions

File tree

python/examples/langgraph_memory_example.py

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,84 @@ class ScratchpadState(TypedDict):
4848
messages: Annotated[List, add_messages]
4949

5050

51-
# Create OpenAI LLM with tools
51+
# Mock LLM for fallback when OpenAI key is not available
52+
class MockLLM:
53+
"""Mock LLM that simulates tool calls for demonstration."""
54+
55+
def invoke(self, messages):
56+
"""Mock LLM that generates tool calls based on message content."""
57+
last_message = messages[-1]
58+
59+
# If the last message is a ToolMessage, respond normally without tools
60+
if isinstance(last_message, ToolMessage):
61+
return AIMessage(content="Task completed successfully!")
62+
63+
# Only generate tool calls for HumanMessage
64+
if isinstance(last_message, HumanMessage):
65+
content = last_message.content.lower()
66+
67+
if "write" in content and "scratchpad" in content:
68+
# Extract content to write
69+
notes = content.split(":")[-1].strip() if ":" in content else content.replace("write to scratchpad", "").strip()
70+
return AIMessage(
71+
content="I'll write that to the scratchpad for you.",
72+
tool_calls=[{
73+
"name": "WriteToScratchpad",
74+
"args": {"notes": notes},
75+
"id": f"call_{datetime.now().timestamp()}"
76+
}]
77+
)
78+
elif "read" in content and "scratchpad" in content:
79+
return AIMessage(
80+
content="Let me read from the scratchpad.",
81+
tool_calls=[{
82+
"name": "ReadFromScratchpad",
83+
"args": {},
84+
"id": f"call_{datetime.now().timestamp()}"
85+
}]
86+
)
87+
elif "search" in content:
88+
# Mock search query
89+
query = content.replace("search", "").strip()
90+
return AIMessage(
91+
content=f"I'll search for: {query}",
92+
tool_calls=[{
93+
"name": "tavily_search",
94+
"args": {"query": query},
95+
"id": f"call_{datetime.now().timestamp()}"
96+
}]
97+
)
98+
99+
return AIMessage(content="I understand. How can I help you with writing to or reading from the scratchpad, or searching for information?")
100+
101+
102+
# Create LLM with tools (OpenAI or fallback to mock)
52103
def create_llm_with_tools():
53-
"""Create OpenAI LLM bound with tools."""
54-
llm = ChatOpenAI(
55-
model="gpt-4o-mini", # Use the more affordable mini model
56-
temperature=0.1,
57-
max_tokens=150
58-
)
59-
60-
# Bind tools to the LLM
61-
tools = [WriteToScratchpad, ReadFromScratchpad, tavily_search]
62-
return llm.bind_tools(tools)
104+
"""Create LLM bound with tools. Uses OpenAI if API key is available, otherwise falls back to mock."""
105+
import os
106+
107+
# Check if OpenAI API key is available
108+
if os.getenv("OPENAI_API_KEY"):
109+
try:
110+
llm = ChatOpenAI(
111+
model="gpt-4o-mini", # Use the more affordable mini model
112+
temperature=0.1,
113+
max_tokens=150
114+
)
115+
116+
# Bind tools to the LLM
117+
tools = [WriteToScratchpad, ReadFromScratchpad, tavily_search]
118+
print("🤖 Using OpenAI GPT-4o-mini")
119+
return llm.bind_tools(tools)
120+
except Exception as e:
121+
print(f"⚠️ OpenAI initialization failed: {e}")
122+
print("🔄 Falling back to mock LLM")
123+
else:
124+
print("⚠️ No OpenAI API key found (OPENAI_API_KEY environment variable)")
125+
print("🔄 Using mock LLM for demonstration")
126+
127+
# Fallback to mock LLM
128+
return MockLLM()
63129

64130

65131
# Mock tools for demonstration

0 commit comments

Comments
 (0)