Skip to content

Commit 2efe755

Browse files
committed
Merging work from various projects
1 parent c72129c commit 2efe755

16 files changed

+4808
-5
lines changed

ada/modules/ada.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from ada.modules.logging import logger, log_info, log_warning, log_error, log_tool_call, log_ws_event, log_runtime
22
from ada.modules.async_microphone import AsyncMicrophone
3-
from ada.modules.tools import function_map, tools
3+
from ada.modules.tools import tool_map, tools
44

55
import os
66
import sys
@@ -185,9 +185,9 @@ async def handle_function_call(self, event, websocket):
185185
await self.execute_function_call(function_name, call_id, args, websocket)
186186

187187
async def execute_function_call(self, function_name, call_id, args, websocket):
188-
if function_name in function_map:
188+
if function_name in tool_map:
189189
try:
190-
result = await function_map[function_name](**args)
190+
result = await tool_map[function_name](**args)
191191
log_tool_call(function_name, args, result)
192192
except Exception as e:
193193
error_message = f"Error executing function '{function_name}': {str(e)}"

ada/modules/tools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ async def open_browser():
7272

7373

7474
# Map function names to their corresponding functions
75-
function_map = {
75+
tool_map = {
7676
"get_current_time": get_current_time,
7777
"open_browser": open_browser,
7878
"start_program": start_program,
7979
}
8080

8181
# Tools array for session initialization
8282
tools = [
83-
{
83+
{
8484
"type": "function",
8585
"name": "get_current_time",
8686
"description": "Returns the current time.",

research/ada_research.ipynb

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"metadata": {
6+
"ExecuteTime": {
7+
"end_time": "2024-12-01T22:16:58.010394Z",
8+
"start_time": "2024-12-01T22:16:56.971463Z"
9+
}
10+
},
11+
"source": [
12+
"from langchain_community.document_loaders import WebBaseLoader\n",
13+
"from langchain_core.messages import AIMessage, BaseMessage, HumanMessage\n",
14+
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
15+
"from langchain_core.vectorstores import InMemoryVectorStore\n",
16+
"from langchain_openai import ChatOpenAI, OpenAIEmbeddings\n",
17+
"from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
18+
"from langchain.chains import create_history_aware_retriever, create_retrieval_chain\n",
19+
"from langchain.chains.combine_documents import create_stuff_documents_chain\n",
20+
"from langchain.tools.retriever import create_retriever_tool\n",
21+
"from langgraph.checkpoint.memory import MemorySaver\n",
22+
"from langgraph.graph import START, StateGraph\n",
23+
"from langgraph.graph.message import add_messages\n",
24+
"from langgraph.prebuilt import create_react_agent\n",
25+
"from typing import Sequence\n",
26+
"from typing_extensions import Annotated, TypedDict\n",
27+
"# import bs3\n",
28+
"import bs4\n",
29+
"from dotenv import load_dotenv"
30+
],
31+
"outputs": [
32+
{
33+
"name": "stderr",
34+
"output_type": "stream",
35+
"text": [
36+
"USER_AGENT environment variable not set, consider setting it to identify your requests.\n"
37+
]
38+
}
39+
],
40+
"execution_count": 1
41+
},
42+
{
43+
"cell_type": "code",
44+
"execution_count": null,
45+
"metadata": {
46+
"ExecuteTime": {
47+
"end_time": "2024-11-25T14:26:21.105936Z",
48+
"start_time": "2024-11-25T14:26:21.077429Z"
49+
}
50+
},
51+
"outputs": [],
52+
"source": [
53+
"load_dotenv()\n",
54+
"\n",
55+
"# Create the LLM\n",
56+
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)"
57+
]
58+
},
59+
{
60+
"cell_type": "code",
61+
"execution_count": null,
62+
"metadata": {
63+
"ExecuteTime": {
64+
"end_time": "2024-11-25T14:26:23.789087Z",
65+
"start_time": "2024-11-25T14:26:21.194275Z"
66+
}
67+
},
68+
"outputs": [],
69+
"source": [
70+
"### Construct retriever ###\n",
71+
"loader = WebBaseLoader(\n",
72+
" web_paths=(\"https://lilianweng.github.io/posts/2023-06-23-agent/\",),\n",
73+
" bs_kwargs=dict(\n",
74+
" parse_only=bs4.SoupStrainer(\n",
75+
" class_=(\"post-content\", \"post-title\", \"post-header\")\n",
76+
" )\n",
77+
" ),\n",
78+
")\n",
79+
"docs = loader.load()\n",
80+
"\n",
81+
"text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)\n",
82+
"splits = text_splitter.split_documents(docs)\n",
83+
"vectorstore = InMemoryVectorStore.from_documents(\n",
84+
" documents=splits, embedding=OpenAIEmbeddings()\n",
85+
")\n",
86+
"retriever = vectorstore.as_retriever()"
87+
]
88+
},
89+
{
90+
"cell_type": "code",
91+
"execution_count": null,
92+
"metadata": {
93+
"ExecuteTime": {
94+
"end_time": "2024-11-25T14:26:23.798581Z",
95+
"start_time": "2024-11-25T14:26:23.793658Z"
96+
}
97+
},
98+
"outputs": [],
99+
"source": [
100+
"### Contextualize question ###\n",
101+
"contextualize_q_system_prompt = (\n",
102+
" \"Given a chat history and the latest user question \"\n",
103+
" \"which might reference context in the chat history, \"\n",
104+
" \"formulate a standalone question which can be understood \"\n",
105+
" \"without the chat history. Do NOT answer the question, \"\n",
106+
" \"just reformulate it if needed and otherwise return it as is.\"\n",
107+
")\n",
108+
"contextualize_q_prompt = ChatPromptTemplate.from_messages(\n",
109+
" [\n",
110+
" (\"system\", contextualize_q_system_prompt),\n",
111+
" MessagesPlaceholder(\"chat_history\"),\n",
112+
" (\"human\", \"{input}\"),\n",
113+
" ]\n",
114+
")\n",
115+
"history_aware_retriever = create_history_aware_retriever(\n",
116+
" llm, retriever, contextualize_q_prompt\n",
117+
")\n",
118+
"\n",
119+
"\n",
120+
"### Answer question ###\n",
121+
"system_prompt = (\n",
122+
" \"You are an assistant for question-answering tasks. \"\n",
123+
" \"Use the following pieces of retrieved context to answer \"\n",
124+
" \"the question. If you don't know the answer, say that you \"\n",
125+
" \"don't know. Use three sentences maximum and keep the \"\n",
126+
" \"answer concise.\"\n",
127+
" \"\\n\\n\"\n",
128+
" \"{context}\"\n",
129+
")\n",
130+
"qa_prompt = ChatPromptTemplate.from_messages(\n",
131+
" [\n",
132+
" (\"system\", system_prompt),\n",
133+
" MessagesPlaceholder(\"chat_history\"),\n",
134+
" (\"human\", \"{input}\"),\n",
135+
" ]\n",
136+
")\n",
137+
"question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)\n",
138+
"\n",
139+
"rag_chain = create_retrieval_chain(history_aware_retriever, question_answer_chain)\n"
140+
]
141+
},
142+
{
143+
"cell_type": "code",
144+
"execution_count": null,
145+
"metadata": {
146+
"ExecuteTime": {
147+
"end_time": "2024-11-25T14:26:23.857963Z",
148+
"start_time": "2024-11-25T14:26:23.854315Z"
149+
}
150+
},
151+
"outputs": [],
152+
"source": [
153+
"### Statefully manage chat history ###\n",
154+
"class State(TypedDict):\n",
155+
" input: str\n",
156+
" chat_history: Annotated[Sequence[BaseMessage], add_messages]\n",
157+
" context: str\n",
158+
" answer: str\n",
159+
"\n",
160+
"\n",
161+
"def call_model(state: State):\n",
162+
" response = rag_chain.invoke(state)\n",
163+
" return {\n",
164+
" \"chat_history\": [\n",
165+
" HumanMessage(state[\"input\"]),\n",
166+
" AIMessage(response[\"answer\"]),\n",
167+
" ],\n",
168+
" \"context\": response[\"context\"],\n",
169+
" \"answer\": response[\"answer\"],\n",
170+
" }\n",
171+
"\n",
172+
"\n",
173+
"workflow = StateGraph(state_schema=State)\n",
174+
"workflow.add_edge(START, \"model\")\n",
175+
"workflow.add_node(\"model\", call_model)\n",
176+
"\n",
177+
"memory = MemorySaver()\n",
178+
"app = workflow.compile(checkpointer=memory)\n"
179+
]
180+
},
181+
{
182+
"cell_type": "code",
183+
"execution_count": null,
184+
"metadata": {
185+
"ExecuteTime": {
186+
"end_time": "2024-11-25T14:26:25.645801Z",
187+
"start_time": "2024-11-25T14:26:23.912690Z"
188+
}
189+
},
190+
"outputs": [],
191+
"source": [
192+
"config = {\"configurable\": {\"thread_id\": \"abc123\"}}\n",
193+
"\n",
194+
"result = app.invoke(\n",
195+
" {\"input\": \"What is Task Decomposition? Explain why you think your answer is correct.\"},\n",
196+
" config=config,\n",
197+
")\n",
198+
"print(result[\"answer\"])"
199+
]
200+
},
201+
{
202+
"cell_type": "code",
203+
"execution_count": null,
204+
"metadata": {
205+
"ExecuteTime": {
206+
"end_time": "2024-11-25T14:26:28.013347Z",
207+
"start_time": "2024-11-25T14:26:25.652388Z"
208+
}
209+
},
210+
"outputs": [],
211+
"source": [
212+
"result = app.invoke(\n",
213+
" {\"input\": \"What is one way of doing it?\"},\n",
214+
" config=config,\n",
215+
")\n",
216+
"print(result[\"answer\"])"
217+
]
218+
},
219+
{
220+
"cell_type": "code",
221+
"execution_count": null,
222+
"metadata": {
223+
"ExecuteTime": {
224+
"end_time": "2024-11-25T14:26:28.060282Z",
225+
"start_time": "2024-11-25T14:26:28.025528Z"
226+
}
227+
},
228+
"outputs": [],
229+
"source": [
230+
"### Build retriever tool ###\n",
231+
"tool = create_retriever_tool(\n",
232+
" retriever,\n",
233+
" \"blog_post_retriever\",\n",
234+
" \"Searches and returns excerpts from the Autonomous Agents blog post.\",\n",
235+
")\n",
236+
"tools = [tool]\n",
237+
"\n",
238+
"\n",
239+
"agent_executor = create_react_agent(llm, tools, checkpointer=memory)\n"
240+
]
241+
},
242+
{
243+
"cell_type": "code",
244+
"execution_count": null,
245+
"metadata": {
246+
"ExecuteTime": {
247+
"end_time": "2024-11-25T14:26:28.516905Z",
248+
"start_time": "2024-11-25T14:26:28.063034Z"
249+
}
250+
},
251+
"outputs": [],
252+
"source": [
253+
"config = {\"configurable\": {\"thread_id\": \"abc123\"}}\n",
254+
"\n",
255+
"for event in agent_executor.stream(\n",
256+
" {\"messages\": [HumanMessage(content=\"Hi! I'm bob\")]},\n",
257+
" config=config,\n",
258+
" stream_mode=\"values\",\n",
259+
"):\n",
260+
" event[\"messages\"][-1].pretty_print()"
261+
]
262+
},
263+
{
264+
"cell_type": "code",
265+
"execution_count": null,
266+
"metadata": {
267+
"ExecuteTime": {
268+
"end_time": "2024-11-25T14:26:33.938879Z",
269+
"start_time": "2024-11-25T14:26:28.523887Z"
270+
}
271+
},
272+
"outputs": [],
273+
"source": [
274+
"query = \"What is Task Decomposition?\"\n",
275+
"\n",
276+
"for event in agent_executor.stream(\n",
277+
" {\"messages\": [HumanMessage(content=query)]},\n",
278+
" config=config,\n",
279+
" stream_mode=\"values\",\n",
280+
"):\n",
281+
" event[\"messages\"][-1].pretty_print()"
282+
]
283+
},
284+
{
285+
"cell_type": "code",
286+
"execution_count": null,
287+
"metadata": {
288+
"ExecuteTime": {
289+
"end_time": "2024-11-25T14:26:37.288568Z",
290+
"start_time": "2024-11-25T14:26:33.947002Z"
291+
}
292+
},
293+
"outputs": [],
294+
"source": [
295+
"query = \"What according to the blog post are common ways of doing it? redo the search\"\n",
296+
"\n",
297+
"for event in agent_executor.stream(\n",
298+
" {\"messages\": [HumanMessage(content=query)]},\n",
299+
" config=config,\n",
300+
" stream_mode=\"values\",\n",
301+
"):\n",
302+
" event[\"messages\"][-1].pretty_print()"
303+
]
304+
}
305+
],
306+
"metadata": {
307+
"kernelspec": {
308+
"display_name": "venv",
309+
"language": "python",
310+
"name": "python3"
311+
},
312+
"language_info": {
313+
"codemirror_mode": {
314+
"name": "ipython",
315+
"version": 3
316+
},
317+
"file_extension": ".py",
318+
"mimetype": "text/x-python",
319+
"name": "python",
320+
"nbconvert_exporter": "python",
321+
"pygments_lexer": "ipython3",
322+
"version": "3.11.8"
323+
}
324+
},
325+
"nbformat": 4,
326+
"nbformat_minor": 2
327+
}

0 commit comments

Comments
 (0)