mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-30 13:35:09 +02:00
71 KiB
71 KiB
In [1]:
# %%capture --no-stderr
# %pip install -U langgraph langchain langchain_openai langsmithIn [2]:
import getpass
import os
import uuid
def _set_if_undefined(var: str):
if not os.environ.get(var):
os.environ[var] = getpass(f"Please provide your {var}")
_set_if_undefined("OPENAI_API_KEY")
_set_if_undefined("LANGCHAIN_API_KEY")
_set_if_undefined("TAVILY_API_KEY")
# Optional, add tracing in LangSmith.
# This will help you visualize and debug the control flow
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "Multi-agent Collaboration"In [3]:
from typing import Any, Callable, List, Optional, TypedDict, Union
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import Runnable
from langchain_core.tools import BaseTool
from langchain_openai import ChatOpenAI
from langgraph.graph import END, StateGraph
def create_worker_agent(
graph_builder: StateGraph,
name: str,
llm: ChatOpenAI,
tools: list,
system_prompt: str,
prelude: Optional[Union[Runnable, Callable]] = None, # Optional required steps
) -> str:
"""Create a function-calling agent and add it to the graph."""
system_prompt += "\nYou are one of the following team members: {team_members}"
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
system_prompt,
),
MessagesPlaceholder(variable_name="messages"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)
agent = create_openai_functions_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools)
chain = executor | (
lambda x: {"messages": [HumanMessage(content=x["output"], name=name)]}
)
if prelude is not None:
chain = prelude | chain
graph_builder.add_node(name, chain)
return name
def create_team_supervisor(
graph_builder: StateGraph, llm: ChatOpenAI, system_prompt: str
) -> str:
"""An LLM-based router."""
supervisor_id = uuid.uuid4().hex[:4]
supervisor_name = f"supervisor - {supervisor_id}"
members = list(graph_builder.nodes)
options = ["FINISH"] + members
function_def = {
"name": "route",
"description": "Select the next role.",
"parameters": {
"title": "routeSchema",
"type": "object",
"properties": {
"next": {
"title": "Next",
"anyOf": [
{"enum": options},
],
}
},
"required": ["next"],
},
}
prompt = ChatPromptTemplate.from_messages(
[
("system", system_prompt),
MessagesPlaceholder(variable_name="messages"),
(
"system",
"Given the conversation above, who should act next?"
" Or should we FINISH? Select one of: {options}",
),
]
).partial(options=str(options), team_members=", ".join(members))
chain = (
prompt
| llm.bind_functions(functions=[function_def], function_call="route")
| JsonOutputFunctionsParser()
)
graph_builder.add_node(supervisor_name, chain)
conditional_map = {k: k for k in members}
conditional_map["FINISH"] = END
for member in members:
graph_builder.add_edge(member, supervisor_name)
graph_builder.add_conditional_edges(
supervisor_name, lambda x: x["next"], conditional_map
)
return supervisor_nameIn [4]:
from typing import Annotated, List, Tuple, Union
import matplotlib.pyplot as plt
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.tools import tool
from langsmith import trace
tavily_tool = TavilySearchResults(max_results=5)
@tool
def scrape_webpages(urls: List[str]) -> str:
"""Use requests and bs4 to scrape the provided web pages for detailed information."""
loader = WebBaseLoader(urls)
docs = loader.load()
return "\n\n".join(
[
f'<Document name="{doc.metadata["title"]}">\n{doc.page_content}\n</Document>'
for doc in docs
]
)In [5]:
import functools
import operator
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
from langchain_openai.chat_models import ChatOpenAI
# Research team graph state
class State(TypedDict):
# A message is added after each team member finishes
messages: Annotated[List[BaseMessage], operator.add]
# The team members are tracked so they are aware of
# the others' skill-sets
team_members: List[str]
# Used to route work. The supervisor calls a function
# that will update this every time it makes a decision
next: str
research_graph = StateGraph(State)
llm = ChatOpenAI(model="gpt-4-1106-preview")
create_worker_agent(
research_graph,
"Search",
llm,
[tavily_tool],
"You are a research assistant who can search for things using a search engine.",
)
create_worker_agent(
research_graph,
"Web Scraper",
llm,
[tavily_tool],
"You are a research assistant who can scrape specified urls for more detailed information.",
)
supervisor_node = create_team_supervisor(
research_graph,
llm,
"You are a supervisor tasked with managing a conversation between the"
" following workers: {team_members}. Given the following user request,"
" respond with the worker to act next. Each worker will perform a"
" task and respond with their results and status. When finished,"
" respond with FINISH.",
)
research_graph.set_entry_point(supervisor_node)
# The following functions interoperate between the top level graph state
# and the state of the research sub-graph
# this makes it so that the states of each graph don't get intermixed
def enter_chain(message: str, members: Optional[list] = None):
results = {
"messages": [HumanMessage(content=message)],
}
if members:
results["team_members"] = "\n".join(sorted(members))
return results
def return_final_response(state):
return {"final_response": state["messages"][-1]}
research_chain = (
functools.partial(enter_chain, members=research_graph.nodes)
| research_graph.compile()
| return_final_response
)In [10]:
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Dict
_TEMP_DIRECTORY = TemporaryDirectory()
WORKING_DIRECTORY = Path(_TEMP_DIRECTORY.name)
@tool
def create_outline(
points: Annotated[List[str], "List of main points or sections."],
file_name: Annotated[str, "File path to save the outline."],
) -> Annotated[str, "Path of the saved outline file."]:
"""Create and save an outline."""
if len(points) != len(subpoints):
raise ValueError("Each main point must have a corresponding list of subpoints.")
with (WORKING_DIRECTORY / file_name).open("w") as file:
for i, point in enumerate(points):
file.write(f"{i + 1}. {point}\n")
return f"Outline saved to {file_name}"
@tool
def read_document(
file_name: Annotated[str, "File path to save the document."],
start: Annotated[Optional[int], "The start line. Default is 0"] = None,
end: Annotated[Optional[int], "The end line. Default is None"] = None,
) -> str:
"""Read the specified document."""
with (WORKING_DIRECTORY / file_name).open("r") as file:
lines = file.readlines()
if start is not None:
start = 0
return "\n".join(lines[start:end])
@tool
def write_document(
content: Annotated[str, "Text content to be written into the document."],
file_name: Annotated[str, "File path to save the document."],
) -> Annotated[str, "Path of the saved document file."]:
"""Create and save a text document."""
with (WORKING_DIRECTORY / file_name).open("w") as file:
file.write(content)
return f"Document saved to {file_name}"
@tool
def edit_document(
file_name: Annotated[str, "Path of the document to be edited."],
inserts: Annotated[
Dict[int, str],
"Dictionary where key is the line number (1-indexed) and value is the text to be inserted at that line.",
],
) -> Annotated[str, "Path of the edited document file."]:
"""Edit a document by inserting text at specific line numbers."""
# Read the contents of the file
with (WORKING_DIRECTORY / file_name).open("r") as file:
lines = file.readlines()
# Adjust the line numbers for 0-indexing and sort
sorted_inserts = sorted(inserts.items())
# Perform the insertions
for line_number, text in sorted_inserts:
if 1 <= line_number <= len(lines) + 1:
# Insert the text at the specified line number
lines.insert(line_number - 1, text + "\n")
else:
return f"Error: Line number {line_number} is out of range."
# Write the modified content back to the file
with (WORKING_DIRECTORY / file_name).open("w") as file:
file.writelines(lines)
return f"Document edited and saved to {file_name}"
@tool
def create_plot(
data: Annotated[
Union[List[float], List[int]],
"Numerical values for bar heights or line points.",
],
file_name: Annotated[str, "File path to save the figure."],
labels: Annotated[
Union[List[str], None], "Bar or point labels, defaults to None."
] = None,
title: Annotated[str, "Title of the plot."] = "Plot",
xlabel: Annotated[str, "Label for the X-axis."] = "X",
ylabel: Annotated[str, "Label for the Y-axis."] = "Y",
color: Annotated[Union[str, List[str]], "Color(s) for the bars or line."] = "blue",
plot_type: Annotated[str, "Type of plot ('bar' or 'line')."] = "bar",
) -> Annotated[str, "Path of the saved figure file."]:
"""Create a line or bar chart."""
if plot_type not in ["bar", "line"]:
raise ValueError("Invalid plot_type. Expected 'bar' or 'line'.")
fig, ax = plt.subplots(figsize=(10, 6))
x_positions = range(len(data))
if labels and len(labels) == len(data):
plt.xticks(x_positions, labels)
if plot_type == "bar":
ax.bar(x_positions, data, color=color)
elif plot_type == "line":
ax.plot(x_positions, data, color=color, marker="o") # 'o' for circular markers
ax.set_title(title)
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
fig.savefig(str(WORKING_DIRECTORY / file_name))
plt.close(fig)
return f'Saved "{title}" plot to {file_name}'In [11]:
import operator
from pathlib import Path
# Document writing team graph state
class AuthoringState(TypedDict):
# This tracks the team's conversation internally
messages: Annotated[List[BaseMessage], operator.add]
# This provides each worker with context on the others' skill sets
team_members: str
# This is how the supervisor tells langgraph who to work next
next: str
# This tracks the shared directory state
current_files: str
# This will be run before each worker agent begins work
# It makes it so they are more aware of the current state
# of the working directory.
def prelude(state):
written_files = []
if not WORKING_DIRECTORY.exists():
WORKING_DIRECTORY.mkdir()
try:
written_files = [
f.relative_to(WORKING_DIRECTORY) for f in WORKING_DIRECTORY.rglob("*")
]
except:
pass
if not written_files:
return {**state, "current_files": "No files written."}
return {
**state,
"current_files": "\nBelow are files your team has written to the directory:\n"
+ "\n".join([f" - {f}" for f in written_files]),
}
# Create the graph here:
authoring_graph = StateGraph(AuthoringState)
llm = ChatOpenAI(model="gpt-4-1106-preview")
create_worker_agent(
authoring_graph,
"Author Docs",
llm,
[write_document, edit_document, read_document],
"You are an expert writing a research document.\n"
# The {current_files} value is populated automatically by the graph state
"Below are files currently in your directory:\n{current_files}",
prelude=prelude,
)
create_worker_agent(
authoring_graph,
"Outline + Notetaker",
llm,
[create_outline, read_document],
"You are an expert senior researcher tasked with writing a paper outline and"
" taking notes to craft a perfect paper.{current_files}",
prelude=prelude,
)
create_worker_agent(
authoring_graph,
"Generate Charts",
llm,
[read_document, create_plot],
"You are a data viz expert tasked with generating charts for a research project."
"{current_files}",
)
supervisor_node = create_team_supervisor(
authoring_graph,
llm,
"You are a supervisor tasked with managing a conversation between the"
" following workers: {team_members}. Given the following user request,"
" respond with the worker to act next. Each worker will perform a"
" task and respond with their results and status. When finished,"
" respond with FINISH.",
)
authoring_graph.set_entry_point(supervisor_node)
# We re-use the enter/exit functions to wrap the graph
authoring_chain = (
functools.partial(enter_chain, members=authoring_graph.nodes)
| authoring_graph.compile()
| return_final_response
)In [12]:
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
from langchain_openai.chat_models import ChatOpenAI
# Research team graph
class State(TypedDict):
messages: Annotated[List[BaseMessage], operator.add]
next: str
def get_last_message(state: State) -> str:
return state["messages"][-1].content
def join_graph(response: dict):
return {"messages": [response["final_response"]]}
super_graph = StateGraph(State)
super_graph.add_node("Research team", get_last_message | research_chain | join_graph)
super_graph.add_node(
"Paper writing team", get_last_message | authoring_chain | join_graph
)
llm = ChatOpenAI(model="gpt-4-1106-preview")
supervisor_node = create_team_supervisor(
super_graph,
llm,
"You are a supervisor tasked with managing a conversation between the"
" following teams: {team_members}. Given the following user request,"
" respond with the worker to act next. Each worker will perform a"
" task and respond with their results and status. When finished,"
" respond with FINISH.",
)
super_graph.set_entry_point(supervisor_node)
super_graph = enter_chain | super_graph.compile()In [13]:
results = super_graph.invoke(
"Research and write a report about the climate impacts"
" on crop yields in Bangladesh in 2023. Write the paper and include plots.",
{"recursion_limit": 150},
)
results["messages"][-1][0;31m---------------------------------------------------------------------------[0m [0;31mNameError[0m Traceback (most recent call last) Cell [0;32mIn[13], line 1[0m [0;32m----> 1[0m results [38;5;241m=[39m [43msuper_graph[49m[38;5;241;43m.[39;49m[43minvoke[49m[43m([49m [1;32m 2[0m [43m [49m[38;5;124;43m"[39;49m[38;5;124;43mResearch and write a report about the climate impacts[39;49m[38;5;124;43m"[39;49m [1;32m 3[0m [43m [49m[38;5;124;43m"[39;49m[38;5;124;43m on crop yields in Bangladesh in 2023. Write the paper and include plots.[39;49m[38;5;124;43m"[39;49m[43m,[49m [1;32m 4[0m [43m [49m[43m{[49m[38;5;124;43m"[39;49m[38;5;124;43mrecursion_limit[39;49m[38;5;124;43m"[39;49m[43m:[49m[43m [49m[38;5;241;43m150[39;49m[43m}[49m[43m,[49m [1;32m 5[0m [43m)[49m [1;32m 6[0m results[[38;5;124m"[39m[38;5;124mmessages[39m[38;5;124m"[39m][[38;5;241m-[39m[38;5;241m1[39m] File [0;32m~/code/lc/langchain/libs/core/langchain_core/runnables/base.py:2034[0m, in [0;36mRunnableSequence.invoke[0;34m(self, input, config)[0m [1;32m 2032[0m [38;5;28;01mtry[39;00m: [1;32m 2033[0m [38;5;28;01mfor[39;00m i, step [38;5;129;01min[39;00m [38;5;28menumerate[39m([38;5;28mself[39m[38;5;241m.[39msteps): [0;32m-> 2034[0m [38;5;28minput[39m [38;5;241m=[39m [43mstep[49m[38;5;241;43m.[39;49m[43minvoke[49m[43m([49m [1;32m 2035[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 2036[0m [43m [49m[38;5;66;43;03m# mark each step as a child run[39;49;00m [1;32m 2037[0m [43m [49m[43mpatch_config[49m[43m([49m [1;32m 2038[0m [43m [49m[43mconfig[49m[43m,[49m[43m [49m[43mcallbacks[49m[38;5;241;43m=[39;49m[43mrun_manager[49m[38;5;241;43m.[39;49m[43mget_child[49m[43m([49m[38;5;124;43mf[39;49m[38;5;124;43m"[39;49m[38;5;124;43mseq:step:[39;49m[38;5;132;43;01m{[39;49;00m[43mi[49m[38;5;241;43m+[39;49m[38;5;241;43m1[39;49m[38;5;132;43;01m}[39;49;00m[38;5;124;43m"[39;49m[43m)[49m [1;32m 2039[0m [43m [49m[43m)[49m[43m,[49m [1;32m 2040[0m [43m [49m[43m)[49m [1;32m 2041[0m [38;5;66;03m# finish the root run[39;00m [1;32m 2042[0m [38;5;28;01mexcept[39;00m [38;5;167;01mBaseException[39;00m [38;5;28;01mas[39;00m e: File [0;32m~/code/lc/langgraph/langgraph/pregel/__init__.py:531[0m, in [0;36mPregel.invoke[0;34m(self, input, config, output_keys, input_keys, **kwargs)[0m [1;32m 521[0m [38;5;28;01mdef[39;00m [38;5;21minvoke[39m( [1;32m 522[0m [38;5;28mself[39m, [1;32m 523[0m [38;5;28minput[39m: Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any], [0;32m (...)[0m [1;32m 528[0m [38;5;241m*[39m[38;5;241m*[39mkwargs: Any, [1;32m 529[0m ) [38;5;241m-[39m[38;5;241m>[39m Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any]: [1;32m 530[0m latest: Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any] [38;5;241m=[39m [38;5;28;01mNone[39;00m [0;32m--> 531[0m [43m [49m[38;5;28;43;01mfor[39;49;00m[43m [49m[43mchunk[49m[43m [49m[38;5;129;43;01min[39;49;00m[43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mstream[49m[43m([49m [1;32m 532[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 533[0m [43m [49m[43mconfig[49m[43m,[49m [1;32m 534[0m [43m [49m[43moutput_keys[49m[38;5;241;43m=[39;49m[43moutput_keys[49m[43m [49m[38;5;28;43;01mif[39;49;00m[43m [49m[43moutput_keys[49m[43m [49m[38;5;129;43;01mis[39;49;00m[43m [49m[38;5;129;43;01mnot[39;49;00m[43m [49m[38;5;28;43;01mNone[39;49;00m[43m [49m[38;5;28;43;01melse[39;49;00m[43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43moutput[49m[43m,[49m [1;32m 535[0m [43m [49m[43minput_keys[49m[38;5;241;43m=[39;49m[43minput_keys[49m[43m,[49m [1;32m 536[0m [43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mkwargs[49m[43m,[49m [1;32m 537[0m [43m [49m[43m)[49m[43m:[49m [1;32m 538[0m [43m [49m[43mlatest[49m[43m [49m[38;5;241;43m=[39;49m[43m [49m[43mchunk[49m [1;32m 539[0m [38;5;28;01mreturn[39;00m latest File [0;32m~/code/lc/langgraph/langgraph/pregel/__init__.py:567[0m, in [0;36mPregel.transform[0;34m(self, input, config, output_keys, input_keys, **kwargs)[0m [1;32m 558[0m [38;5;28;01mdef[39;00m [38;5;21mtransform[39m( [1;32m 559[0m [38;5;28mself[39m, [1;32m 560[0m [38;5;28minput[39m: Iterator[Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any]], [0;32m (...)[0m [1;32m 565[0m [38;5;241m*[39m[38;5;241m*[39mkwargs: Any, [1;32m 566[0m ) [38;5;241m-[39m[38;5;241m>[39m Iterator[Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any]]: [0;32m--> 567[0m [43m [49m[38;5;28;43;01mfor[39;49;00m[43m [49m[43mchunk[49m[43m [49m[38;5;129;43;01min[39;49;00m[43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_transform_stream_with_config[49m[43m([49m [1;32m 568[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 569[0m [43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_transform[49m[43m,[49m [1;32m 570[0m [43m [49m[43mconfig[49m[43m,[49m [1;32m 571[0m [43m [49m[43moutput_keys[49m[38;5;241;43m=[39;49m[43moutput_keys[49m[43m,[49m [1;32m 572[0m [43m [49m[43minput_keys[49m[38;5;241;43m=[39;49m[43minput_keys[49m[43m,[49m [1;32m 573[0m [43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mkwargs[49m[43m,[49m [1;32m 574[0m [43m [49m[43m)[49m[43m:[49m [1;32m 575[0m [43m [49m[38;5;28;43;01myield[39;49;00m[43m [49m[43mchunk[49m File [0;32m~/code/lc/langchain/libs/core/langchain_core/runnables/base.py:1486[0m, in [0;36mRunnable._transform_stream_with_config[0;34m(self, input, transformer, config, run_type, **kwargs)[0m [1;32m 1484[0m [38;5;28;01mtry[39;00m: [1;32m 1485[0m [38;5;28;01mwhile[39;00m [38;5;28;01mTrue[39;00m: [0;32m-> 1486[0m chunk: Output [38;5;241m=[39m context[38;5;241m.[39mrun([38;5;28mnext[39m, iterator) [38;5;66;03m# type: ignore[39;00m [1;32m 1487[0m [38;5;28;01myield[39;00m chunk [1;32m 1488[0m [38;5;28;01mif[39;00m final_output_supported: File [0;32m~/code/lc/langgraph/langgraph/pregel/__init__.py:342[0m, in [0;36mPregel._transform[0;34m(self, input, run_manager, config, input_keys, output_keys)[0m [1;32m 332[0m done, inflight [38;5;241m=[39m concurrent[38;5;241m.[39mfutures[38;5;241m.[39mwait( [1;32m 333[0m [ [1;32m 334[0m executor[38;5;241m.[39msubmit(proc[38;5;241m.[39minvoke, [38;5;28minput[39m, config) [0;32m (...)[0m [1;32m 338[0m timeout[38;5;241m=[39m[38;5;28mself[39m[38;5;241m.[39mstep_timeout, [1;32m 339[0m ) [1;32m 341[0m [38;5;66;03m# interrupt on failure or timeout[39;00m [0;32m--> 342[0m [43m_interrupt_or_proceed[49m[43m([49m[43mdone[49m[43m,[49m[43m [49m[43minflight[49m[43m,[49m[43m [49m[43mstep[49m[43m)[49m [1;32m 344[0m [38;5;66;03m# apply writes to channels[39;00m [1;32m 345[0m _apply_writes(checkpoint, channels, pending_writes, config, step [38;5;241m+[39m [38;5;241m1[39m) File [0;32m~/code/lc/langgraph/langgraph/pregel/__init__.py:650[0m, in [0;36m_interrupt_or_proceed[0;34m(done, inflight, step)[0m [1;32m 648[0m inflight[38;5;241m.[39mpop()[38;5;241m.[39mcancel() [1;32m 649[0m [38;5;66;03m# raise the exception[39;00m [0;32m--> 650[0m [38;5;28;01mraise[39;00m exc [1;32m 651[0m [38;5;66;03m# TODO this is where retry of an entire step would happen[39;00m [1;32m 653[0m [38;5;28;01mif[39;00m inflight: [1;32m 654[0m [38;5;66;03m# if we got here means we timed out[39;00m File [0;32m~/.pyenv/versions/3.11.2/lib/python3.11/concurrent/futures/thread.py:58[0m, in [0;36m_WorkItem.run[0;34m(self)[0m [1;32m 55[0m [38;5;28;01mreturn[39;00m [1;32m 57[0m [38;5;28;01mtry[39;00m: [0;32m---> 58[0m result [38;5;241m=[39m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mfn[49m[43m([49m[38;5;241;43m*[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43margs[49m[43m,[49m[43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mkwargs[49m[43m)[49m [1;32m 59[0m [38;5;28;01mexcept[39;00m [38;5;167;01mBaseException[39;00m [38;5;28;01mas[39;00m exc: [1;32m 60[0m [38;5;28mself[39m[38;5;241m.[39mfuture[38;5;241m.[39mset_exception(exc) File [0;32m~/code/lc/langchain/libs/core/langchain_core/runnables/base.py:3868[0m, in [0;36mRunnableBindingBase.invoke[0;34m(self, input, config, **kwargs)[0m [1;32m 3862[0m [38;5;28;01mdef[39;00m [38;5;21minvoke[39m( [1;32m 3863[0m [38;5;28mself[39m, [1;32m 3864[0m [38;5;28minput[39m: Input, [1;32m 3865[0m config: Optional[RunnableConfig] [38;5;241m=[39m [38;5;28;01mNone[39;00m, [1;32m 3866[0m [38;5;241m*[39m[38;5;241m*[39mkwargs: Optional[Any], [1;32m 3867[0m ) [38;5;241m-[39m[38;5;241m>[39m Output: [0;32m-> 3868[0m [38;5;28;01mreturn[39;00m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mbound[49m[38;5;241;43m.[39;49m[43minvoke[49m[43m([49m [1;32m 3869[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 3870[0m [43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_merge_configs[49m[43m([49m[43mconfig[49m[43m)[49m[43m,[49m [1;32m 3871[0m [43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43m{[49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mkwargs[49m[43m,[49m[43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mkwargs[49m[43m}[49m[43m,[49m [1;32m 3872[0m [43m [49m[43m)[49m File [0;32m~/code/lc/langchain/libs/core/langchain_core/runnables/base.py:2034[0m, in [0;36mRunnableSequence.invoke[0;34m(self, input, config)[0m [1;32m 2032[0m [38;5;28;01mtry[39;00m: [1;32m 2033[0m [38;5;28;01mfor[39;00m i, step [38;5;129;01min[39;00m [38;5;28menumerate[39m([38;5;28mself[39m[38;5;241m.[39msteps): [0;32m-> 2034[0m [38;5;28minput[39m [38;5;241m=[39m [43mstep[49m[38;5;241;43m.[39;49m[43minvoke[49m[43m([49m [1;32m 2035[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 2036[0m [43m [49m[38;5;66;43;03m# mark each step as a child run[39;49;00m [1;32m 2037[0m [43m [49m[43mpatch_config[49m[43m([49m [1;32m 2038[0m [43m [49m[43mconfig[49m[43m,[49m[43m [49m[43mcallbacks[49m[38;5;241;43m=[39;49m[43mrun_manager[49m[38;5;241;43m.[39;49m[43mget_child[49m[43m([49m[38;5;124;43mf[39;49m[38;5;124;43m"[39;49m[38;5;124;43mseq:step:[39;49m[38;5;132;43;01m{[39;49;00m[43mi[49m[38;5;241;43m+[39;49m[38;5;241;43m1[39;49m[38;5;132;43;01m}[39;49;00m[38;5;124;43m"[39;49m[43m)[49m [1;32m 2039[0m [43m [49m[43m)[49m[43m,[49m [1;32m 2040[0m [43m [49m[43m)[49m [1;32m 2041[0m [38;5;66;03m# finish the root run[39;00m [1;32m 2042[0m [38;5;28;01mexcept[39;00m [38;5;167;01mBaseException[39;00m [38;5;28;01mas[39;00m e: File [0;32m~/code/lc/langgraph/langgraph/pregel/__init__.py:531[0m, in [0;36mPregel.invoke[0;34m(self, input, config, output_keys, input_keys, **kwargs)[0m [1;32m 521[0m [38;5;28;01mdef[39;00m [38;5;21minvoke[39m( [1;32m 522[0m [38;5;28mself[39m, [1;32m 523[0m [38;5;28minput[39m: Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any], [0;32m (...)[0m [1;32m 528[0m [38;5;241m*[39m[38;5;241m*[39mkwargs: Any, [1;32m 529[0m ) [38;5;241m-[39m[38;5;241m>[39m Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any]: [1;32m 530[0m latest: Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any] [38;5;241m=[39m [38;5;28;01mNone[39;00m [0;32m--> 531[0m [43m [49m[38;5;28;43;01mfor[39;49;00m[43m [49m[43mchunk[49m[43m [49m[38;5;129;43;01min[39;49;00m[43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mstream[49m[43m([49m [1;32m 532[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 533[0m [43m [49m[43mconfig[49m[43m,[49m [1;32m 534[0m [43m [49m[43moutput_keys[49m[38;5;241;43m=[39;49m[43moutput_keys[49m[43m [49m[38;5;28;43;01mif[39;49;00m[43m [49m[43moutput_keys[49m[43m [49m[38;5;129;43;01mis[39;49;00m[43m [49m[38;5;129;43;01mnot[39;49;00m[43m [49m[38;5;28;43;01mNone[39;49;00m[43m [49m[38;5;28;43;01melse[39;49;00m[43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43moutput[49m[43m,[49m [1;32m 535[0m [43m [49m[43minput_keys[49m[38;5;241;43m=[39;49m[43minput_keys[49m[43m,[49m [1;32m 536[0m [43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mkwargs[49m[43m,[49m [1;32m 537[0m [43m [49m[43m)[49m[43m:[49m [1;32m 538[0m [43m [49m[43mlatest[49m[43m [49m[38;5;241;43m=[39;49m[43m [49m[43mchunk[49m [1;32m 539[0m [38;5;28;01mreturn[39;00m latest File [0;32m~/code/lc/langgraph/langgraph/pregel/__init__.py:567[0m, in [0;36mPregel.transform[0;34m(self, input, config, output_keys, input_keys, **kwargs)[0m [1;32m 558[0m [38;5;28;01mdef[39;00m [38;5;21mtransform[39m( [1;32m 559[0m [38;5;28mself[39m, [1;32m 560[0m [38;5;28minput[39m: Iterator[Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any]], [0;32m (...)[0m [1;32m 565[0m [38;5;241m*[39m[38;5;241m*[39mkwargs: Any, [1;32m 566[0m ) [38;5;241m-[39m[38;5;241m>[39m Iterator[Union[[38;5;28mdict[39m[[38;5;28mstr[39m, Any], Any]]: [0;32m--> 567[0m [43m [49m[38;5;28;43;01mfor[39;49;00m[43m [49m[43mchunk[49m[43m [49m[38;5;129;43;01min[39;49;00m[43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_transform_stream_with_config[49m[43m([49m [1;32m 568[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 569[0m [43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_transform[49m[43m,[49m [1;32m 570[0m [43m [49m[43mconfig[49m[43m,[49m [1;32m 571[0m [43m [49m[43moutput_keys[49m[38;5;241;43m=[39;49m[43moutput_keys[49m[43m,[49m [1;32m 572[0m [43m [49m[43minput_keys[49m[38;5;241;43m=[39;49m[43minput_keys[49m[43m,[49m [1;32m 573[0m [43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mkwargs[49m[43m,[49m [1;32m 574[0m [43m [49m[43m)[49m[43m:[49m [1;32m 575[0m [43m [49m[38;5;28;43;01myield[39;49;00m[43m [49m[43mchunk[49m File [0;32m~/code/lc/langchain/libs/core/langchain_core/runnables/base.py:1486[0m, in [0;36mRunnable._transform_stream_with_config[0;34m(self, input, transformer, config, run_type, **kwargs)[0m [1;32m 1484[0m [38;5;28;01mtry[39;00m: [1;32m 1485[0m [38;5;28;01mwhile[39;00m [38;5;28;01mTrue[39;00m: [0;32m-> 1486[0m chunk: Output [38;5;241m=[39m context[38;5;241m.[39mrun([38;5;28mnext[39m, iterator) [38;5;66;03m# type: ignore[39;00m [1;32m 1487[0m [38;5;28;01myield[39;00m chunk [1;32m 1488[0m [38;5;28;01mif[39;00m final_output_supported: File [0;32m~/code/lc/langgraph/langgraph/pregel/__init__.py:342[0m, in [0;36mPregel._transform[0;34m(self, input, run_manager, config, input_keys, output_keys)[0m [1;32m 332[0m done, inflight [38;5;241m=[39m concurrent[38;5;241m.[39mfutures[38;5;241m.[39mwait( [1;32m 333[0m [ [1;32m 334[0m executor[38;5;241m.[39msubmit(proc[38;5;241m.[39minvoke, [38;5;28minput[39m, config) [0;32m (...)[0m [1;32m 338[0m timeout[38;5;241m=[39m[38;5;28mself[39m[38;5;241m.[39mstep_timeout, [1;32m 339[0m ) [1;32m 341[0m [38;5;66;03m# interrupt on failure or timeout[39;00m [0;32m--> 342[0m [43m_interrupt_or_proceed[49m[43m([49m[43mdone[49m[43m,[49m[43m [49m[43minflight[49m[43m,[49m[43m [49m[43mstep[49m[43m)[49m [1;32m 344[0m [38;5;66;03m# apply writes to channels[39;00m [1;32m 345[0m _apply_writes(checkpoint, channels, pending_writes, config, step [38;5;241m+[39m [38;5;241m1[39m) File [0;32m~/code/lc/langgraph/langgraph/pregel/__init__.py:650[0m, in [0;36m_interrupt_or_proceed[0;34m(done, inflight, step)[0m [1;32m 648[0m inflight[38;5;241m.[39mpop()[38;5;241m.[39mcancel() [1;32m 649[0m [38;5;66;03m# raise the exception[39;00m [0;32m--> 650[0m [38;5;28;01mraise[39;00m exc [1;32m 651[0m [38;5;66;03m# TODO this is where retry of an entire step would happen[39;00m [1;32m 653[0m [38;5;28;01mif[39;00m inflight: [1;32m 654[0m [38;5;66;03m# if we got here means we timed out[39;00m File [0;32m~/.pyenv/versions/3.11.2/lib/python3.11/concurrent/futures/thread.py:58[0m, in [0;36m_WorkItem.run[0;34m(self)[0m [1;32m 55[0m [38;5;28;01mreturn[39;00m [1;32m 57[0m [38;5;28;01mtry[39;00m: [0;32m---> 58[0m result [38;5;241m=[39m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mfn[49m[43m([49m[38;5;241;43m*[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43margs[49m[43m,[49m[43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mkwargs[49m[43m)[49m [1;32m 59[0m [38;5;28;01mexcept[39;00m [38;5;167;01mBaseException[39;00m [38;5;28;01mas[39;00m exc: [1;32m 60[0m [38;5;28mself[39m[38;5;241m.[39mfuture[38;5;241m.[39mset_exception(exc) File [0;32m~/code/lc/langchain/libs/core/langchain_core/runnables/base.py:3868[0m, in [0;36mRunnableBindingBase.invoke[0;34m(self, input, config, **kwargs)[0m [1;32m 3862[0m [38;5;28;01mdef[39;00m [38;5;21minvoke[39m( [1;32m 3863[0m [38;5;28mself[39m, [1;32m 3864[0m [38;5;28minput[39m: Input, [1;32m 3865[0m config: Optional[RunnableConfig] [38;5;241m=[39m [38;5;28;01mNone[39;00m, [1;32m 3866[0m [38;5;241m*[39m[38;5;241m*[39mkwargs: Optional[Any], [1;32m 3867[0m ) [38;5;241m-[39m[38;5;241m>[39m Output: [0;32m-> 3868[0m [38;5;28;01mreturn[39;00m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mbound[49m[38;5;241;43m.[39;49m[43minvoke[49m[43m([49m [1;32m 3869[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 3870[0m [43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_merge_configs[49m[43m([49m[43mconfig[49m[43m)[49m[43m,[49m [1;32m 3871[0m [43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43m{[49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mkwargs[49m[43m,[49m[43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mkwargs[49m[43m}[49m[43m,[49m [1;32m 3872[0m [43m [49m[43m)[49m File [0;32m~/code/lc/langchain/libs/core/langchain_core/runnables/base.py:2034[0m, in [0;36mRunnableSequence.invoke[0;34m(self, input, config)[0m [1;32m 2032[0m [38;5;28;01mtry[39;00m: [1;32m 2033[0m [38;5;28;01mfor[39;00m i, step [38;5;129;01min[39;00m [38;5;28menumerate[39m([38;5;28mself[39m[38;5;241m.[39msteps): [0;32m-> 2034[0m [38;5;28minput[39m [38;5;241m=[39m [43mstep[49m[38;5;241;43m.[39;49m[43minvoke[49m[43m([49m [1;32m 2035[0m [43m [49m[38;5;28;43minput[39;49m[43m,[49m [1;32m 2036[0m [43m [49m[38;5;66;43;03m# mark each step as a child run[39;49;00m [1;32m 2037[0m [43m [49m[43mpatch_config[49m[43m([49m [1;32m 2038[0m [43m [49m[43mconfig[49m[43m,[49m[43m [49m[43mcallbacks[49m[38;5;241;43m=[39;49m[43mrun_manager[49m[38;5;241;43m.[39;49m[43mget_child[49m[43m([49m[38;5;124;43mf[39;49m[38;5;124;43m"[39;49m[38;5;124;43mseq:step:[39;49m[38;5;132;43;01m{[39;49;00m[43mi[49m[38;5;241;43m+[39;49m[38;5;241;43m1[39;49m[38;5;132;43;01m}[39;49;00m[38;5;124;43m"[39;49m[43m)[49m [1;32m 2039[0m [43m [49m[43m)[49m[43m,[49m [1;32m 2040[0m [43m [49m[43m)[49m [1;32m 2041[0m [38;5;66;03m# finish the root run[39;00m [1;32m 2042[0m [38;5;28;01mexcept[39;00m [38;5;167;01mBaseException[39;00m [38;5;28;01mas[39;00m e: File [0;32m~/.pyenv/versions/3.11.2/lib/python3.11/site-packages/langchain/chains/base.py:162[0m, in [0;36mChain.invoke[0;34m(self, input, config, **kwargs)[0m [1;32m 160[0m [38;5;28;01mexcept[39;00m [38;5;167;01mBaseException[39;00m [38;5;28;01mas[39;00m e: [1;32m 161[0m run_manager[38;5;241m.[39mon_chain_error(e) [0;32m--> 162[0m [38;5;28;01mraise[39;00m e [1;32m 163[0m run_manager[38;5;241m.[39mon_chain_end(outputs) [1;32m 164[0m final_outputs: Dict[[38;5;28mstr[39m, Any] [38;5;241m=[39m [38;5;28mself[39m[38;5;241m.[39mprep_outputs( [1;32m 165[0m inputs, outputs, return_only_outputs [1;32m 166[0m ) File [0;32m~/.pyenv/versions/3.11.2/lib/python3.11/site-packages/langchain/chains/base.py:156[0m, in [0;36mChain.invoke[0;34m(self, input, config, **kwargs)[0m [1;32m 149[0m run_manager [38;5;241m=[39m callback_manager[38;5;241m.[39mon_chain_start( [1;32m 150[0m dumpd([38;5;28mself[39m), [1;32m 151[0m inputs, [1;32m 152[0m name[38;5;241m=[39mrun_name, [1;32m 153[0m ) [1;32m 154[0m [38;5;28;01mtry[39;00m: [1;32m 155[0m outputs [38;5;241m=[39m ( [0;32m--> 156[0m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_call[49m[43m([49m[43minputs[49m[43m,[49m[43m [49m[43mrun_manager[49m[38;5;241;43m=[39;49m[43mrun_manager[49m[43m)[49m [1;32m 157[0m [38;5;28;01mif[39;00m new_arg_supported [1;32m 158[0m [38;5;28;01melse[39;00m [38;5;28mself[39m[38;5;241m.[39m_call(inputs) [1;32m 159[0m ) [1;32m 160[0m [38;5;28;01mexcept[39;00m [38;5;167;01mBaseException[39;00m [38;5;28;01mas[39;00m e: [1;32m 161[0m run_manager[38;5;241m.[39mon_chain_error(e) File [0;32m~/.pyenv/versions/3.11.2/lib/python3.11/site-packages/langchain/agents/agent.py:1376[0m, in [0;36mAgentExecutor._call[0;34m(self, inputs, run_manager)[0m [1;32m 1374[0m [38;5;66;03m# We now enter the agent loop (until it returns something).[39;00m [1;32m 1375[0m [38;5;28;01mwhile[39;00m [38;5;28mself[39m[38;5;241m.[39m_should_continue(iterations, time_elapsed): [0;32m-> 1376[0m next_step_output [38;5;241m=[39m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_take_next_step[49m[43m([49m [1;32m 1377[0m [43m [49m[43mname_to_tool_map[49m[43m,[49m [1;32m 1378[0m [43m [49m[43mcolor_mapping[49m[43m,[49m [1;32m 1379[0m [43m [49m[43minputs[49m[43m,[49m [1;32m 1380[0m [43m [49m[43mintermediate_steps[49m[43m,[49m [1;32m 1381[0m [43m [49m[43mrun_manager[49m[38;5;241;43m=[39;49m[43mrun_manager[49m[43m,[49m [1;32m 1382[0m [43m [49m[43m)[49m [1;32m 1383[0m [38;5;28;01mif[39;00m [38;5;28misinstance[39m(next_step_output, AgentFinish): [1;32m 1384[0m [38;5;28;01mreturn[39;00m [38;5;28mself[39m[38;5;241m.[39m_return( [1;32m 1385[0m next_step_output, intermediate_steps, run_manager[38;5;241m=[39mrun_manager [1;32m 1386[0m ) File [0;32m~/.pyenv/versions/3.11.2/lib/python3.11/site-packages/langchain/agents/agent.py:1102[0m, in [0;36mAgentExecutor._take_next_step[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)[0m [1;32m 1093[0m [38;5;28;01mdef[39;00m [38;5;21m_take_next_step[39m( [1;32m 1094[0m [38;5;28mself[39m, [1;32m 1095[0m name_to_tool_map: Dict[[38;5;28mstr[39m, BaseTool], [0;32m (...)[0m [1;32m 1099[0m run_manager: Optional[CallbackManagerForChainRun] [38;5;241m=[39m [38;5;28;01mNone[39;00m, [1;32m 1100[0m ) [38;5;241m-[39m[38;5;241m>[39m Union[AgentFinish, List[Tuple[AgentAction, [38;5;28mstr[39m]]]: [1;32m 1101[0m [38;5;28;01mreturn[39;00m [38;5;28mself[39m[38;5;241m.[39m_consume_next_step( [0;32m-> 1102[0m [43m[[49m [1;32m 1103[0m [43m [49m[43ma[49m [1;32m 1104[0m [43m [49m[38;5;28;43;01mfor[39;49;00m[43m [49m[43ma[49m[43m [49m[38;5;129;43;01min[39;49;00m[43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_iter_next_step[49m[43m([49m [1;32m 1105[0m [43m [49m[43mname_to_tool_map[49m[43m,[49m [1;32m 1106[0m [43m [49m[43mcolor_mapping[49m[43m,[49m [1;32m 1107[0m [43m [49m[43minputs[49m[43m,[49m [1;32m 1108[0m [43m [49m[43mintermediate_steps[49m[43m,[49m [1;32m 1109[0m [43m [49m[43mrun_manager[49m[43m,[49m [1;32m 1110[0m [43m [49m[43m)[49m [1;32m 1111[0m [43m [49m[43m][49m [1;32m 1112[0m ) File [0;32m~/.pyenv/versions/3.11.2/lib/python3.11/site-packages/langchain/agents/agent.py:1102[0m, in [0;36m<listcomp>[0;34m(.0)[0m [1;32m 1093[0m [38;5;28;01mdef[39;00m [38;5;21m_take_next_step[39m( [1;32m 1094[0m [38;5;28mself[39m, [1;32m 1095[0m name_to_tool_map: Dict[[38;5;28mstr[39m, BaseTool], [0;32m (...)[0m [1;32m 1099[0m run_manager: Optional[CallbackManagerForChainRun] [38;5;241m=[39m [38;5;28;01mNone[39;00m, [1;32m 1100[0m ) [38;5;241m-[39m[38;5;241m>[39m Union[AgentFinish, List[Tuple[AgentAction, [38;5;28mstr[39m]]]: [1;32m 1101[0m [38;5;28;01mreturn[39;00m [38;5;28mself[39m[38;5;241m.[39m_consume_next_step( [0;32m-> 1102[0m [43m[[49m [1;32m 1103[0m [43m [49m[43ma[49m [1;32m 1104[0m [43m [49m[38;5;28;43;01mfor[39;49;00m[43m [49m[43ma[49m[43m [49m[38;5;129;43;01min[39;49;00m[43m [49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_iter_next_step[49m[43m([49m [1;32m 1105[0m [43m [49m[43mname_to_tool_map[49m[43m,[49m [1;32m 1106[0m [43m [49m[43mcolor_mapping[49m[43m,[49m [1;32m 1107[0m [43m [49m[43minputs[49m[43m,[49m [1;32m 1108[0m [43m [49m[43mintermediate_steps[49m[43m,[49m [1;32m 1109[0m [43m [49m[43mrun_manager[49m[43m,[49m [1;32m 1110[0m [43m [49m[43m)[49m [1;32m 1111[0m [43m [49m[43m][49m [1;32m 1112[0m ) File [0;32m~/.pyenv/versions/3.11.2/lib/python3.11/site-packages/langchain/agents/agent.py:1198[0m, in [0;36mAgentExecutor._iter_next_step[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)[0m [1;32m 1196[0m tool_run_kwargs[[38;5;124m"[39m[38;5;124mllm_prefix[39m[38;5;124m"[39m] [38;5;241m=[39m [38;5;124m"[39m[38;5;124m"[39m [1;32m 1197[0m [38;5;66;03m# We then call the tool on the tool input to get an observation[39;00m [0;32m-> 1198[0m observation [38;5;241m=[39m [43mtool[49m[38;5;241;43m.[39;49m[43mrun[49m[43m([49m [1;32m 1199[0m [43m [49m[43magent_action[49m[38;5;241;43m.[39;49m[43mtool_input[49m[43m,[49m [1;32m 1200[0m [43m [49m[43mverbose[49m[38;5;241;43m=[39;49m[38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mverbose[49m[43m,[49m [1;32m 1201[0m [43m [49m[43mcolor[49m[38;5;241;43m=[39;49m[43mcolor[49m[43m,[49m [1;32m 1202[0m [43m [49m[43mcallbacks[49m[38;5;241;43m=[39;49m[43mrun_manager[49m[38;5;241;43m.[39;49m[43mget_child[49m[43m([49m[43m)[49m[43m [49m[38;5;28;43;01mif[39;49;00m[43m [49m[43mrun_manager[49m[43m [49m[38;5;28;43;01melse[39;49;00m[43m [49m[38;5;28;43;01mNone[39;49;00m[43m,[49m [1;32m 1203[0m [43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mtool_run_kwargs[49m[43m,[49m [1;32m 1204[0m [43m [49m[43m)[49m [1;32m 1205[0m [38;5;28;01melse[39;00m: [1;32m 1206[0m tool_run_kwargs [38;5;241m=[39m [38;5;28mself[39m[38;5;241m.[39magent[38;5;241m.[39mtool_run_logging_kwargs() File [0;32m~/code/lc/langchain/libs/core/langchain_core/tools.py:374[0m, in [0;36mBaseTool.run[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, **kwargs)[0m [1;32m 372[0m [38;5;28;01mexcept[39;00m ([38;5;167;01mException[39;00m, [38;5;167;01mKeyboardInterrupt[39;00m) [38;5;28;01mas[39;00m e: [1;32m 373[0m run_manager[38;5;241m.[39mon_tool_error(e) [0;32m--> 374[0m [38;5;28;01mraise[39;00m e [1;32m 375[0m [38;5;28;01melse[39;00m: [1;32m 376[0m run_manager[38;5;241m.[39mon_tool_end( [1;32m 377[0m [38;5;28mstr[39m(observation), color[38;5;241m=[39mcolor, name[38;5;241m=[39m[38;5;28mself[39m[38;5;241m.[39mname, [38;5;241m*[39m[38;5;241m*[39mkwargs [1;32m 378[0m ) File [0;32m~/code/lc/langchain/libs/core/langchain_core/tools.py:346[0m, in [0;36mBaseTool.run[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, **kwargs)[0m [1;32m 343[0m [38;5;28;01mtry[39;00m: [1;32m 344[0m tool_args, tool_kwargs [38;5;241m=[39m [38;5;28mself[39m[38;5;241m.[39m_to_args_and_kwargs(parsed_input) [1;32m 345[0m observation [38;5;241m=[39m ( [0;32m--> 346[0m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43m_run[49m[43m([49m[38;5;241;43m*[39;49m[43mtool_args[49m[43m,[49m[43m [49m[43mrun_manager[49m[38;5;241;43m=[39;49m[43mrun_manager[49m[43m,[49m[43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mtool_kwargs[49m[43m)[49m [1;32m 347[0m [38;5;28;01mif[39;00m new_arg_supported [1;32m 348[0m [38;5;28;01melse[39;00m [38;5;28mself[39m[38;5;241m.[39m_run([38;5;241m*[39mtool_args, [38;5;241m*[39m[38;5;241m*[39mtool_kwargs) [1;32m 349[0m ) [1;32m 350[0m [38;5;28;01mexcept[39;00m ToolException [38;5;28;01mas[39;00m e: [1;32m 351[0m [38;5;28;01mif[39;00m [38;5;129;01mnot[39;00m [38;5;28mself[39m[38;5;241m.[39mhandle_tool_error: File [0;32m~/code/lc/langchain/libs/core/langchain_core/tools.py:641[0m, in [0;36mStructuredTool._run[0;34m(self, run_manager, *args, **kwargs)[0m [1;32m 632[0m [38;5;28;01mif[39;00m [38;5;28mself[39m[38;5;241m.[39mfunc: [1;32m 633[0m new_argument_supported [38;5;241m=[39m signature([38;5;28mself[39m[38;5;241m.[39mfunc)[38;5;241m.[39mparameters[38;5;241m.[39mget([38;5;124m"[39m[38;5;124mcallbacks[39m[38;5;124m"[39m) [1;32m 634[0m [38;5;28;01mreturn[39;00m ( [1;32m 635[0m [38;5;28mself[39m[38;5;241m.[39mfunc( [1;32m 636[0m [38;5;241m*[39margs, [1;32m 637[0m callbacks[38;5;241m=[39mrun_manager[38;5;241m.[39mget_child() [38;5;28;01mif[39;00m run_manager [38;5;28;01melse[39;00m [38;5;28;01mNone[39;00m, [1;32m 638[0m [38;5;241m*[39m[38;5;241m*[39mkwargs, [1;32m 639[0m ) [1;32m 640[0m [38;5;28;01mif[39;00m new_argument_supported [0;32m--> 641[0m [38;5;28;01melse[39;00m [38;5;28;43mself[39;49m[38;5;241;43m.[39;49m[43mfunc[49m[43m([49m[38;5;241;43m*[39;49m[43margs[49m[43m,[49m[43m [49m[38;5;241;43m*[39;49m[38;5;241;43m*[39;49m[43mkwargs[49m[43m)[49m [1;32m 642[0m ) [1;32m 643[0m [38;5;28;01mraise[39;00m [38;5;167;01mNotImplementedError[39;00m([38;5;124m"[39m[38;5;124mTool does not support sync[39m[38;5;124m"[39m) Cell [0;32mIn[10], line 15[0m, in [0;36mcreate_outline[0;34m(points, file_name)[0m [1;32m 9[0m [38;5;129m@tool[39m [1;32m 10[0m [38;5;28;01mdef[39;00m [38;5;21mcreate_outline[39m( [1;32m 11[0m points: Annotated[List[[38;5;28mstr[39m], [38;5;124m"[39m[38;5;124mList of main points or sections.[39m[38;5;124m"[39m], [1;32m 12[0m file_name: Annotated[[38;5;28mstr[39m, [38;5;124m"[39m[38;5;124mFile path to save the outline.[39m[38;5;124m"[39m], [1;32m 13[0m ) [38;5;241m-[39m[38;5;241m>[39m Annotated[[38;5;28mstr[39m, [38;5;124m"[39m[38;5;124mPath of the saved outline file.[39m[38;5;124m"[39m]: [1;32m 14[0m [38;5;250m [39m[38;5;124;03m"""Create and save an outline."""[39;00m [0;32m---> 15[0m [38;5;28;01mif[39;00m [38;5;28mlen[39m(points) [38;5;241m!=[39m [38;5;28mlen[39m([43msubpoints[49m): [1;32m 16[0m [38;5;28;01mraise[39;00m [38;5;167;01mValueError[39;00m([38;5;124m"[39m[38;5;124mEach main point must have a corresponding list of subpoints.[39m[38;5;124m"[39m) [1;32m 18[0m [38;5;28;01mwith[39;00m (WORKING_DIRECTORY [38;5;241m/[39m file_name)[38;5;241m.[39mopen([38;5;124m"[39m[38;5;124mw[39m[38;5;124m"[39m) [38;5;28;01mas[39;00m file: [0;31mNameError[0m: name 'subpoints' is not defined
In [ ]:
