Spaces:
Sleeping
Sleeping
Commit ·
d8a070a
0
Parent(s):
Clean initial commit without secrets
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .dockerignore +14 -0
- .gitattributes +5 -0
- .gitignore +6 -0
- .here +0 -0
- Dockerfile +13 -0
- LICENSE +21 -0
- Notebooks/Tools/RAG_tool_step_by_step/rag_tool.ipynb +474 -0
- Notebooks/Tools/sql_agents/sql_agent_chain_for_large_db.ipynb +680 -0
- Notebooks/Tools/sql_agents/sql_agent_chain_steps.ipynb +323 -0
- Notebooks/Tools/sql_agents/sql_agent_steps.ipynb +163 -0
- Notebooks/Tools/tavily/tavily_search.ipynb +117 -0
- Notebooks/custom_agent/groq_function_calling.ipynb +401 -0
- Notebooks/explore_databases/explore_chinook.ipynb +209 -0
- Notebooks/explore_databases/explore_traveldb.ipynb +152 -0
- Notebooks/full_graph.ipynb +828 -0
- Notebooks/python_tip_automatic_docstring/automatic_docstring.ipynb +76 -0
- Notebooks/test_groq_models/Llama.ipynb +178 -0
- Notebooks/test_groq_models/Mixtral.ipynb +103 -0
- Notebooks/test_groq_models/image.png +3 -0
- README.md +150 -0
- configs/project_config.yml +6 -0
- configs/tools_config.yml +46 -0
- data/Chinook.db +3 -0
- data/airline_policy_vectordb/chroma.sqlite3 +3 -0
- data/airline_policy_vectordb/f2b436bc-82cd-4d2c-8bab-689ae4da5759/data_level0.bin +3 -0
- data/airline_policy_vectordb/f2b436bc-82cd-4d2c-8bab-689ae4da5759/header.bin +3 -0
- data/airline_policy_vectordb/f2b436bc-82cd-4d2c-8bab-689ae4da5759/length.bin +3 -0
- data/airline_policy_vectordb/f2b436bc-82cd-4d2c-8bab-689ae4da5759/link_lists.bin +0 -0
- data/stories_vectordb/483f4fb1-0512-4ef0-9c4e-890073f4fe17/data_level0.bin +3 -0
- data/stories_vectordb/483f4fb1-0512-4ef0-9c4e-890073f4fe17/header.bin +3 -0
- data/stories_vectordb/483f4fb1-0512-4ef0-9c4e-890073f4fe17/length.bin +3 -0
- data/stories_vectordb/483f4fb1-0512-4ef0-9c4e-890073f4fe17/link_lists.bin +0 -0
- data/stories_vectordb/chroma.sqlite3 +3 -0
- data/travel.sqlite +0 -0
- data/unstructured_docs/stories/stories.pdf +3 -0
- data/unstructured_docs/swiss_airline_policy/swiss_faq.pdf +3 -0
- images/AI_RT.png +3 -0
- images/UI.png +3 -0
- images/chat_icon.png +3 -0
- images/detailed_schema.png +3 -0
- images/graph_image.png +3 -0
- images/high-level.png +3 -0
- images/langsmith_Screenshot.png +3 -0
- images/large_db_strategy.png +3 -0
- images/question2_answer_Screenshot .png +3 -0
- images/question3_answer_Screenshot.png +3 -0
- images/question4_answer_Screenshot.png +3 -0
- images/question_answer_screenshot.png +3 -0
- memory/2024-09-16.csv +16 -0
- memory/2024-09-17.csv +16 -0
.dockerignore
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
| 2 |
+
*.pyc
|
| 3 |
+
*.pyo
|
| 4 |
+
*.pyd
|
| 5 |
+
.env
|
| 6 |
+
.git
|
| 7 |
+
.gitignore
|
| 8 |
+
notebooks/
|
| 9 |
+
.ipynb_checkpoints/
|
| 10 |
+
wandb/
|
| 11 |
+
.cache/
|
| 12 |
+
*.log
|
| 13 |
+
*.tmp
|
| 14 |
+
.DS_Store
|
.gitattributes
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.png filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.pdf filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.db filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.sqlite3 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
querymind/
|
| 2 |
+
venv/
|
| 3 |
+
.venv/
|
| 4 |
+
__pycache__/
|
| 5 |
+
*.pyc
|
| 6 |
+
.env
|
.here
ADDED
|
File without changes
|
Dockerfile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.11-slim
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
|
| 5 |
+
COPY requirements.txt .
|
| 6 |
+
|
| 7 |
+
RUN pip install -r requirements.txt
|
| 8 |
+
|
| 9 |
+
COPY . .
|
| 10 |
+
|
| 11 |
+
EXPOSE 7860
|
| 12 |
+
|
| 13 |
+
CMD ["python", "src\app.py"]
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Beshoy Arnest
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
Notebooks/Tools/RAG_tool_step_by_step/rag_tool.ipynb
ADDED
|
@@ -0,0 +1,474 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [
|
| 8 |
+
{
|
| 9 |
+
"data": {
|
| 10 |
+
"text/plain": [
|
| 11 |
+
"True"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
"execution_count": 1,
|
| 15 |
+
"metadata": {},
|
| 16 |
+
"output_type": "execute_result"
|
| 17 |
+
}
|
| 18 |
+
],
|
| 19 |
+
"source": [
|
| 20 |
+
"from langchain_chroma import Chroma\n",
|
| 21 |
+
"import os\n",
|
| 22 |
+
"from pyprojroot import here\n",
|
| 23 |
+
"from langchain_huggingface import HuggingFaceEmbeddings\n",
|
| 24 |
+
"from groq import Groq\n",
|
| 25 |
+
"from dotenv import load_dotenv\n",
|
| 26 |
+
"from pprint import pprint\n",
|
| 27 |
+
"load_dotenv()"
|
| 28 |
+
]
|
| 29 |
+
},
|
| 30 |
+
{
|
| 31 |
+
"cell_type": "markdown",
|
| 32 |
+
"metadata": {},
|
| 33 |
+
"source": [
|
| 34 |
+
"**Load environment variables and configs**"
|
| 35 |
+
]
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"cell_type": "code",
|
| 39 |
+
"execution_count": 2,
|
| 40 |
+
"metadata": {},
|
| 41 |
+
"outputs": [],
|
| 42 |
+
"source": [
|
| 43 |
+
"os.environ['GROQ_API_KEY'] = os.getenv(\"GROQ_API_KEY\")\n",
|
| 44 |
+
"\n",
|
| 45 |
+
"EMBEDDING_MODEL = \"all-MiniLM-L6-v2\"\n",
|
| 46 |
+
"VECTORDB_DIR = \"data/airline_policy_vectordb\"\n",
|
| 47 |
+
"K=2"
|
| 48 |
+
]
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"cell_type": "markdown",
|
| 52 |
+
"metadata": {},
|
| 53 |
+
"source": [
|
| 54 |
+
"**Load the vectorDB**"
|
| 55 |
+
]
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"cell_type": "code",
|
| 59 |
+
"execution_count": 3,
|
| 60 |
+
"metadata": {},
|
| 61 |
+
"outputs": [
|
| 62 |
+
{
|
| 63 |
+
"name": "stderr",
|
| 64 |
+
"output_type": "stream",
|
| 65 |
+
"text": [
|
| 66 |
+
"f:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
| 67 |
+
" from .autonotebook import tqdm as notebook_tqdm\n",
|
| 68 |
+
"Loading weights: 100%|██████████| 103/103 [00:00<00:00, 6866.51it/s]\n",
|
| 69 |
+
"Failed to send telemetry event ClientStartEvent: capture() takes 1 positional argument but 3 were given\n",
|
| 70 |
+
"Failed to send telemetry event ClientCreateCollectionEvent: capture() takes 1 positional argument but 3 were given\n"
|
| 71 |
+
]
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"name": "stdout",
|
| 75 |
+
"output_type": "stream",
|
| 76 |
+
"text": [
|
| 77 |
+
"Number of vectors in vectordb: 22 \n",
|
| 78 |
+
"\n",
|
| 79 |
+
"\n"
|
| 80 |
+
]
|
| 81 |
+
}
|
| 82 |
+
],
|
| 83 |
+
"source": [
|
| 84 |
+
"vectordb = Chroma(\n",
|
| 85 |
+
" collection_name=\"rag-chroma\",\n",
|
| 86 |
+
" persist_directory=str(here(VECTORDB_DIR)),\n",
|
| 87 |
+
" embedding_function=HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL)\n",
|
| 88 |
+
")\n",
|
| 89 |
+
"print(\"Number of vectors in vectordb:\",\n",
|
| 90 |
+
" vectordb._collection.count(), \"\\n\\n\")\n",
|
| 91 |
+
"\n"
|
| 92 |
+
]
|
| 93 |
+
},
|
| 94 |
+
{
|
| 95 |
+
"cell_type": "markdown",
|
| 96 |
+
"metadata": {},
|
| 97 |
+
"source": [
|
| 98 |
+
"**Sample Query**"
|
| 99 |
+
]
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"cell_type": "code",
|
| 103 |
+
"execution_count": 4,
|
| 104 |
+
"metadata": {},
|
| 105 |
+
"outputs": [],
|
| 106 |
+
"source": [
|
| 107 |
+
"message = \"What is the cancelation rule for a flight ticket at swiss airline policy?\""
|
| 108 |
+
]
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"cell_type": "markdown",
|
| 112 |
+
"metadata": {},
|
| 113 |
+
"source": [
|
| 114 |
+
"**Perform the vector Search**"
|
| 115 |
+
]
|
| 116 |
+
},
|
| 117 |
+
{
|
| 118 |
+
"cell_type": "code",
|
| 119 |
+
"execution_count": 5,
|
| 120 |
+
"metadata": {},
|
| 121 |
+
"outputs": [
|
| 122 |
+
{
|
| 123 |
+
"name": "stderr",
|
| 124 |
+
"output_type": "stream",
|
| 125 |
+
"text": [
|
| 126 |
+
"Failed to send telemetry event CollectionQueryEvent: capture() takes 1 positional argument but 3 were given\n"
|
| 127 |
+
]
|
| 128 |
+
}
|
| 129 |
+
],
|
| 130 |
+
"source": [
|
| 131 |
+
"docs = vectordb.similarity_search(message, k=K)"
|
| 132 |
+
]
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"cell_type": "code",
|
| 136 |
+
"execution_count": 6,
|
| 137 |
+
"metadata": {},
|
| 138 |
+
"outputs": [
|
| 139 |
+
{
|
| 140 |
+
"data": {
|
| 141 |
+
"text/plain": [
|
| 142 |
+
"[Document(metadata={'page': 8, 'source': 'F:\\\\end_to_end_AI_Projects\\\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\\\data\\\\unstructured_docs\\\\swiss_airline_policy\\\\swiss_faq.pdf'}, page_content=\"How to Cancel a Swiss Air Flight: 877-\\n5O7-7341 Step-by-Step Guide\\nSwiss Air is a premium airline based in Switzerland that of fers a range of domestic and international flights to\\npassengers. However , sometimes situations arise where passengers may need to cancel their flights. In such cases, it is\\nimportant to understand the Swiss Air Cancellation Policy to avoid any confusion or additional charges.\\nSwiss International Airlines Cancellation Policy In this article, we will provide you with everything you need to know about\\nthe Swiss Air Cancellation Policy , including how to cancel a Swiss Air flight, the fees associated with cancelling a flight,\\nand the refund policy .\\nIf you have booked a flight with Swiss Airlines but need to cancel it, it's important to understand their cancellation policy\\nto avoid any unnecessary fees or charges. Swiss Airlines of fers dif ferent fare types, each with their own specific\\ncancellation terms and conditions. The most flexible fare types such as Flex and Business Flex allow you to cancel your\\nflight up to 24 hours before departure without any penalty . For other fare types, cancellation fees may apply . If you cancel\\nyour Swiss Airlines flight outside of the 24-hour window , cancellation fees will be charged depending on your fare type\\nand the time of cancellation. For example, if you cancel a non-flexible economy class ticket, a cancellation fee will be\\ncharged. The closer you cancel to the departure date, the higher the cancellation fee. In some cases, Swiss Airlines may\\nallow you to make changes to your flight instead of cancelling it outright. However , these changes may also come with\\nfees or penalties depending on your fare type and the type of change requested. If Swiss Airlines cancels your flight, you\\nmay be entitled to a full refund or rebooking on another flight. However , if the cancellation is due to extraordinary\\ncircumstances such as bad weather or political unrest, Swiss Airlines may not be obligated to of fer any compensation. In\\nsummary , Swiss Airlines' cancellation policy varies depending on your fare type and the time of cancellation. T o avoid any\\nunnecessary fees or charges, it's important to familiarise yourself with the terms and conditions of your ticket and to\\ncontact Swiss Airlines as soon as possible if you need to make changes or cancel your flight.\"),\n",
|
| 143 |
+
" Document(metadata={'page': 9, 'source': 'F:\\\\end_to_end_AI_Projects\\\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\\\data\\\\unstructured_docs\\\\swiss_airline_policy\\\\swiss_faq.pdf'}, page_content=\"for a refund or may only be able to receive a partial refund. If you booked your flight through a third-party website or\\ntravel agent, you may need to contact them directly to cancel your flight. Always check the terms and conditions of your\\nticket to make sure you understand the cancellation policy and any associated fees or penalties. If you're cancelling your\\nflight due to unforeseen circumstances such as a medical emergency or a natural disaster , Swiss Air may of fer you\\nspecial exemptions or accommodations. What is Swiss Airlines 24 Hour Cancellation Policy? Swiss Airlines has a 24\")]"
|
| 144 |
+
]
|
| 145 |
+
},
|
| 146 |
+
"execution_count": 6,
|
| 147 |
+
"metadata": {},
|
| 148 |
+
"output_type": "execute_result"
|
| 149 |
+
}
|
| 150 |
+
],
|
| 151 |
+
"source": [
|
| 152 |
+
"docs"
|
| 153 |
+
]
|
| 154 |
+
},
|
| 155 |
+
{
|
| 156 |
+
"cell_type": "markdown",
|
| 157 |
+
"metadata": {},
|
| 158 |
+
"source": [
|
| 159 |
+
"**Prepare the prompt for the Groq model**"
|
| 160 |
+
]
|
| 161 |
+
},
|
| 162 |
+
{
|
| 163 |
+
"cell_type": "code",
|
| 164 |
+
"execution_count": 7,
|
| 165 |
+
"metadata": {},
|
| 166 |
+
"outputs": [],
|
| 167 |
+
"source": [
|
| 168 |
+
"question = \"# User new question:\\n\" + message\n",
|
| 169 |
+
"retrieved_content = \"\"\n",
|
| 170 |
+
"for doc in docs:\n",
|
| 171 |
+
" retrieved_content += f\"{doc.page_content}\\n\\n\"\n",
|
| 172 |
+
"prompt = f\"# Content:\\n{retrieved_content}\\n\\n{question}\""
|
| 173 |
+
]
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"cell_type": "markdown",
|
| 177 |
+
"metadata": {},
|
| 178 |
+
"source": [
|
| 179 |
+
"Prepared prompt"
|
| 180 |
+
]
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"cell_type": "code",
|
| 184 |
+
"execution_count": 8,
|
| 185 |
+
"metadata": {},
|
| 186 |
+
"outputs": [
|
| 187 |
+
{
|
| 188 |
+
"name": "stdout",
|
| 189 |
+
"output_type": "stream",
|
| 190 |
+
"text": [
|
| 191 |
+
"('# Content:\\n'\n",
|
| 192 |
+
" 'How to Cancel a Swiss Air Flight: 877-\\n'\n",
|
| 193 |
+
" '5O7-7341 Step-by-Step Guide\\n'\n",
|
| 194 |
+
" 'Swiss Air is a premium airline based in Switzerland that of fers a range of '\n",
|
| 195 |
+
" 'domestic and international flights to\\n'\n",
|
| 196 |
+
" 'passengers. However , sometimes situations arise where passengers may need '\n",
|
| 197 |
+
" 'to cancel their flights. In such cases, it is\\n'\n",
|
| 198 |
+
" 'important to understand the Swiss Air Cancellation Policy to avoid any '\n",
|
| 199 |
+
" 'confusion or additional charges.\\n'\n",
|
| 200 |
+
" 'Swiss International Airlines Cancellation Policy In this article, we will '\n",
|
| 201 |
+
" 'provide you with everything you need to know about\\n'\n",
|
| 202 |
+
" 'the Swiss Air Cancellation Policy , including how to cancel a Swiss Air '\n",
|
| 203 |
+
" 'flight, the fees associated with cancelling a flight,\\n'\n",
|
| 204 |
+
" 'and the refund policy .\\n'\n",
|
| 205 |
+
" \"If you have booked a flight with Swiss Airlines but need to cancel it, it's \"\n",
|
| 206 |
+
" 'important to understand their cancellation policy\\n'\n",
|
| 207 |
+
" 'to avoid any unnecessary fees or charges. Swiss Airlines of fers dif ferent '\n",
|
| 208 |
+
" 'fare types, each with their own specific\\n'\n",
|
| 209 |
+
" 'cancellation terms and conditions. The most flexible fare types such as Flex '\n",
|
| 210 |
+
" 'and Business Flex allow you to cancel your\\n'\n",
|
| 211 |
+
" 'flight up to 24 hours before departure without any penalty . For other fare '\n",
|
| 212 |
+
" 'types, cancellation fees may apply . If you cancel\\n'\n",
|
| 213 |
+
" 'your Swiss Airlines flight outside of the 24-hour window , cancellation fees '\n",
|
| 214 |
+
" 'will be charged depending on your fare type\\n'\n",
|
| 215 |
+
" 'and the time of cancellation. For example, if you cancel a non-flexible '\n",
|
| 216 |
+
" 'economy class ticket, a cancellation fee will be\\n'\n",
|
| 217 |
+
" 'charged. The closer you cancel to the departure date, the higher the '\n",
|
| 218 |
+
" 'cancellation fee. In some cases, Swiss Airlines may\\n'\n",
|
| 219 |
+
" 'allow you to make changes to your flight instead of cancelling it outright. '\n",
|
| 220 |
+
" 'However , these changes may also come with\\n'\n",
|
| 221 |
+
" 'fees or penalties depending on your fare type and the type of change '\n",
|
| 222 |
+
" 'requested. If Swiss Airlines cancels your flight, you\\n'\n",
|
| 223 |
+
" 'may be entitled to a full refund or rebooking on another flight. However , '\n",
|
| 224 |
+
" 'if the cancellation is due to extraordinary\\n'\n",
|
| 225 |
+
" 'circumstances such as bad weather or political unrest, Swiss Airlines may '\n",
|
| 226 |
+
" 'not be obligated to of fer any compensation. In\\n'\n",
|
| 227 |
+
" \"summary , Swiss Airlines' cancellation policy varies depending on your fare \"\n",
|
| 228 |
+
" 'type and the time of cancellation. T o avoid any\\n'\n",
|
| 229 |
+
" \"unnecessary fees or charges, it's important to familiarise yourself with the \"\n",
|
| 230 |
+
" 'terms and conditions of your ticket and to\\n'\n",
|
| 231 |
+
" 'contact Swiss Airlines as soon as possible if you need to make changes or '\n",
|
| 232 |
+
" 'cancel your flight.\\n'\n",
|
| 233 |
+
" '\\n'\n",
|
| 234 |
+
" 'for a refund or may only be able to receive a partial refund. If you booked '\n",
|
| 235 |
+
" 'your flight through a third-party website or\\n'\n",
|
| 236 |
+
" 'travel agent, you may need to contact them directly to cancel your flight. '\n",
|
| 237 |
+
" 'Always check the terms and conditions of your\\n'\n",
|
| 238 |
+
" 'ticket to make sure you understand the cancellation policy and any '\n",
|
| 239 |
+
" \"associated fees or penalties. If you're cancelling your\\n\"\n",
|
| 240 |
+
" 'flight due to unforeseen circumstances such as a medical emergency or a '\n",
|
| 241 |
+
" 'natural disaster , Swiss Air may of fer you\\n'\n",
|
| 242 |
+
" 'special exemptions or accommodations. What is Swiss Airlines 24 Hour '\n",
|
| 243 |
+
" 'Cancellation Policy? Swiss Airlines has a 24\\n'\n",
|
| 244 |
+
" '\\n'\n",
|
| 245 |
+
" '\\n'\n",
|
| 246 |
+
" '\\n'\n",
|
| 247 |
+
" '# User new question:\\n'\n",
|
| 248 |
+
" 'What is the cancelation rule for a flight ticket at swiss airline policy?')\n"
|
| 249 |
+
]
|
| 250 |
+
}
|
| 251 |
+
],
|
| 252 |
+
"source": [
|
| 253 |
+
"pprint(prompt)"
|
| 254 |
+
]
|
| 255 |
+
},
|
| 256 |
+
{
|
| 257 |
+
"cell_type": "markdown",
|
| 258 |
+
"metadata": {},
|
| 259 |
+
"source": [
|
| 260 |
+
"**Pass the prompt to the GPT model and get the response**"
|
| 261 |
+
]
|
| 262 |
+
},
|
| 263 |
+
{
|
| 264 |
+
"cell_type": "code",
|
| 265 |
+
"execution_count": 10,
|
| 266 |
+
"metadata": {},
|
| 267 |
+
"outputs": [],
|
| 268 |
+
"source": [
|
| 269 |
+
"client = Groq()\n",
|
| 270 |
+
"response = client.chat.completions.create(\n",
|
| 271 |
+
" model=\"llama-3.3-70b-versatile\",\n",
|
| 272 |
+
" messages=[\n",
|
| 273 |
+
" {\"role\": \"system\", \"content\": \"You will receive a user's query and possible content where the answer might be. If the answer is found, provide it, if not, state that the answer does not exist.\"},\n",
|
| 274 |
+
" {\"role\": \"user\", \"content\": prompt}\n",
|
| 275 |
+
" ]\n",
|
| 276 |
+
")"
|
| 277 |
+
]
|
| 278 |
+
},
|
| 279 |
+
{
|
| 280 |
+
"cell_type": "markdown",
|
| 281 |
+
"metadata": {},
|
| 282 |
+
"source": [
|
| 283 |
+
"Printing the response"
|
| 284 |
+
]
|
| 285 |
+
},
|
| 286 |
+
{
|
| 287 |
+
"cell_type": "code",
|
| 288 |
+
"execution_count": 62,
|
| 289 |
+
"metadata": {},
|
| 290 |
+
"outputs": [
|
| 291 |
+
{
|
| 292 |
+
"name": "stdout",
|
| 293 |
+
"output_type": "stream",
|
| 294 |
+
"text": [
|
| 295 |
+
"('Swiss Airlines allows passengers to cancel their flights based on the type '\n",
|
| 296 |
+
" 'of ticket purchased. Here are the cancellation rules:\\n'\n",
|
| 297 |
+
" '\\n'\n",
|
| 298 |
+
" '1. **Flex Ticket**: You can cancel your flight without incurring any fees '\n",
|
| 299 |
+
" 'and receive a full refund.\\n'\n",
|
| 300 |
+
" '\\n'\n",
|
| 301 |
+
" '2. **Standard Ticket**: \\n'\n",
|
| 302 |
+
" ' - If you cancel within 24 hours of booking, you can receive a full '\n",
|
| 303 |
+
" 'refund.\\n'\n",
|
| 304 |
+
" ' - If you cancel after 24 hours, you may be charged a cancellation fee '\n",
|
| 305 |
+
" '(ranging from 100 to 250 CHF) and receive a partial refund.\\n'\n",
|
| 306 |
+
" '\\n'\n",
|
| 307 |
+
" '3. **Economy Ticket**: \\n'\n",
|
| 308 |
+
" ' - If you cancel within 24 hours of booking, you can receive a full '\n",
|
| 309 |
+
" 'refund.\\n'\n",
|
| 310 |
+
" ' - If you cancel after 24 hours, you may be charged a cancellation fee '\n",
|
| 311 |
+
" '(ranging from 150 to 350 CHF) and receive a partial refund.\\n'\n",
|
| 312 |
+
" '\\n'\n",
|
| 313 |
+
" \"It's important to check the terms and conditions of your specific ticket, as \"\n",
|
| 314 |
+
" 'fees and refund eligibility may vary. Additionally, if you cancel your '\n",
|
| 315 |
+
" 'flight outside of the 24-hour window, cancellation fees apply.')\n"
|
| 316 |
+
]
|
| 317 |
+
}
|
| 318 |
+
],
|
| 319 |
+
"source": [
|
| 320 |
+
"pprint(response.choices[0].message.content)"
|
| 321 |
+
]
|
| 322 |
+
},
|
| 323 |
+
{
|
| 324 |
+
"cell_type": "markdown",
|
| 325 |
+
"metadata": {},
|
| 326 |
+
"source": [
|
| 327 |
+
"**RAG Tool design using LangChain**"
|
| 328 |
+
]
|
| 329 |
+
},
|
| 330 |
+
{
|
| 331 |
+
"cell_type": "code",
|
| 332 |
+
"execution_count": 11,
|
| 333 |
+
"metadata": {},
|
| 334 |
+
"outputs": [],
|
| 335 |
+
"source": [
|
| 336 |
+
"from langchain_core.tools import tool\n",
|
| 337 |
+
"\n",
|
| 338 |
+
"@tool\n",
|
| 339 |
+
"def lookup_swiss_airline_policy(query: str)->str:\n",
|
| 340 |
+
" \"\"\"Search within the Swiss Airline's company policies to check whether certain options are permitted. Input should be a search query.\"\"\"\n",
|
| 341 |
+
" vectordb = Chroma(\n",
|
| 342 |
+
" collection_name=\"rag-chroma\",\n",
|
| 343 |
+
" persist_directory=str(here(VECTORDB_DIR)),\n",
|
| 344 |
+
" embedding_function=HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL)\n",
|
| 345 |
+
" )\n",
|
| 346 |
+
" docs = vectordb.similarity_search(query, k=K)\n",
|
| 347 |
+
" return \"\\n\\n\".join([doc.page_content for doc in docs])"
|
| 348 |
+
]
|
| 349 |
+
},
|
| 350 |
+
{
|
| 351 |
+
"cell_type": "code",
|
| 352 |
+
"execution_count": 12,
|
| 353 |
+
"metadata": {},
|
| 354 |
+
"outputs": [
|
| 355 |
+
{
|
| 356 |
+
"name": "stdout",
|
| 357 |
+
"output_type": "stream",
|
| 358 |
+
"text": [
|
| 359 |
+
"lookup_swiss_airline_policy\n",
|
| 360 |
+
"{'query': {'title': 'Query', 'type': 'string'}}\n",
|
| 361 |
+
"Search within the Swiss Airline's company policies to check whether certain options are permitted. Input should be a search query.\n"
|
| 362 |
+
]
|
| 363 |
+
}
|
| 364 |
+
],
|
| 365 |
+
"source": [
|
| 366 |
+
"print(lookup_swiss_airline_policy.name)\n",
|
| 367 |
+
"print(lookup_swiss_airline_policy.args)\n",
|
| 368 |
+
"print(lookup_swiss_airline_policy.description)"
|
| 369 |
+
]
|
| 370 |
+
},
|
| 371 |
+
{
|
| 372 |
+
"cell_type": "code",
|
| 373 |
+
"execution_count": 13,
|
| 374 |
+
"metadata": {},
|
| 375 |
+
"outputs": [
|
| 376 |
+
{
|
| 377 |
+
"name": "stderr",
|
| 378 |
+
"output_type": "stream",
|
| 379 |
+
"text": [
|
| 380 |
+
"Loading weights: 100%|██████████| 103/103 [00:00<00:00, 2156.99it/s]\n",
|
| 381 |
+
"Failed to send telemetry event ClientStartEvent: capture() takes 1 positional argument but 3 were given\n",
|
| 382 |
+
"Failed to send telemetry event ClientCreateCollectionEvent: capture() takes 1 positional argument but 3 were given\n"
|
| 383 |
+
]
|
| 384 |
+
},
|
| 385 |
+
{
|
| 386 |
+
"name": "stdout",
|
| 387 |
+
"output_type": "stream",
|
| 388 |
+
"text": [
|
| 389 |
+
"('hour cancellation policy that allows passengers to cancel their flights '\n",
|
| 390 |
+
" 'within 24 hours of booking at +1-877-507-7341\\n'\n",
|
| 391 |
+
" 'without penalty . This policy applies to all fare types, including '\n",
|
| 392 |
+
" 'non-refundable tickets. If you cancel your Swiss Airlines\\n'\n",
|
| 393 |
+
" \"flight within 24 hours of booking, you'll receive a full refund of your \"\n",
|
| 394 |
+
" 'ticket price.\\n'\n",
|
| 395 |
+
" 'How to Cancel Swiss Airlines Flight within 24 Hours? If you need to cancel '\n",
|
| 396 |
+
" 'your Swiss Airlines flight within 24 hours of\\n'\n",
|
| 397 |
+
" 'booking, you can do so easily online. Here are the steps to follow:\\n'\n",
|
| 398 |
+
" 'Go to Swiss Airlines\\' website and click on the \"Manage your bookings\" tab. '\n",
|
| 399 |
+
" 'Enter your booking reference number and last\\n'\n",
|
| 400 |
+
" 'name to access your booking. Select the flight you want to cancel and click '\n",
|
| 401 |
+
" 'on \"Cancel flight.\" Confirm your cancellation\\n'\n",
|
| 402 |
+
" \"and you'll receive a full refund of your ticket price. If you booked your \"\n",
|
| 403 |
+
" \"Swiss Airlines flight through a travel agent, you'll\\n\"\n",
|
| 404 |
+
" 'need to contact them directly to cancel your flight within 24 hours.\\n'\n",
|
| 405 |
+
" 'Important Things to Keep in Mind for Swiss Airlines 24 Hour Cancellation '\n",
|
| 406 |
+
" 'Here are some important things to keep in mind\\n'\n",
|
| 407 |
+
" 'when cancelling your Swiss Airlines flight within 24 hours:\\n'\n",
|
| 408 |
+
" \"Swiss Airlines' 24 hour cancellation policy only applies to flights booked \"\n",
|
| 409 |
+
" 'directly through Swiss Airlines. If you booked\\n'\n",
|
| 410 |
+
" \"your flight through a travel agent or third-party website, you'll need to \"\n",
|
| 411 |
+
" 'check their cancellation policy . If you cancel your\\n'\n",
|
| 412 |
+
" 'Swiss Airlines flight after the 24 hour window , you may be subject to '\n",
|
| 413 |
+
" 'cancellation fees or penalties. If you have a non-\\n'\n",
|
| 414 |
+
" \"refundable ticket and cancel your flight within 24 hours of booking, you'll \"\n",
|
| 415 |
+
" 'receive a full refund of your ticket price.\\n'\n",
|
| 416 |
+
" 'However , if you cancel your flight after the 24 hour window , you may not '\n",
|
| 417 |
+
" \"be eligible for a refund. Swiss Airlines' 24 hour\\n\"\n",
|
| 418 |
+
" 'cancellation policy allows passengers to cancel their flights within 24 '\n",
|
| 419 |
+
" 'hours of booking without penalty . If you need to\\n'\n",
|
| 420 |
+
" 'cancel your Swiss Airlines flight within 24 hours, you can do so easily '\n",
|
| 421 |
+
" 'online. Just remember to check the terms and\\n'\n",
|
| 422 |
+
" \"conditions of your ticket to make sure you're eligible for a refund.\\n\"\n",
|
| 423 |
+
" 'Swiss Air Cancellation Fees The cancellation fees for Swiss Air flights may '\n",
|
| 424 |
+
" 'vary depending on the type of ticket you have\\n'\n",
|
| 425 |
+
" 'purchased. The airline of fers three dif ferent types of tickets, which '\n",
|
| 426 |
+
" 'are:\\n'\n",
|
| 427 |
+
" '\\n'\n",
|
| 428 |
+
" 'for a refund or may only be able to receive a partial refund. If you booked '\n",
|
| 429 |
+
" 'your flight through a third-party website or\\n'\n",
|
| 430 |
+
" 'travel agent, you may need to contact them directly to cancel your flight. '\n",
|
| 431 |
+
" 'Always check the terms and conditions of your\\n'\n",
|
| 432 |
+
" 'ticket to make sure you understand the cancellation policy and any '\n",
|
| 433 |
+
" \"associated fees or penalties. If you're cancelling your\\n\"\n",
|
| 434 |
+
" 'flight due to unforeseen circumstances such as a medical emergency or a '\n",
|
| 435 |
+
" 'natural disaster , Swiss Air may of fer you\\n'\n",
|
| 436 |
+
" 'special exemptions or accommodations. What is Swiss Airlines 24 Hour '\n",
|
| 437 |
+
" 'Cancellation Policy? Swiss Airlines has a 24')\n"
|
| 438 |
+
]
|
| 439 |
+
}
|
| 440 |
+
],
|
| 441 |
+
"source": [
|
| 442 |
+
"pprint(lookup_swiss_airline_policy.invoke(\"can I cancel my ticket?\"))"
|
| 443 |
+
]
|
| 444 |
+
},
|
| 445 |
+
{
|
| 446 |
+
"cell_type": "code",
|
| 447 |
+
"execution_count": null,
|
| 448 |
+
"metadata": {},
|
| 449 |
+
"outputs": [],
|
| 450 |
+
"source": []
|
| 451 |
+
}
|
| 452 |
+
],
|
| 453 |
+
"metadata": {
|
| 454 |
+
"kernelspec": {
|
| 455 |
+
"display_name": "querymind (3.12.10)",
|
| 456 |
+
"language": "python",
|
| 457 |
+
"name": "python3"
|
| 458 |
+
},
|
| 459 |
+
"language_info": {
|
| 460 |
+
"codemirror_mode": {
|
| 461 |
+
"name": "ipython",
|
| 462 |
+
"version": 3
|
| 463 |
+
},
|
| 464 |
+
"file_extension": ".py",
|
| 465 |
+
"mimetype": "text/x-python",
|
| 466 |
+
"name": "python",
|
| 467 |
+
"nbconvert_exporter": "python",
|
| 468 |
+
"pygments_lexer": "ipython3",
|
| 469 |
+
"version": "3.12.10"
|
| 470 |
+
}
|
| 471 |
+
},
|
| 472 |
+
"nbformat": 4,
|
| 473 |
+
"nbformat_minor": 2
|
| 474 |
+
}
|
Notebooks/Tools/sql_agents/sql_agent_chain_for_large_db.ipynb
ADDED
|
@@ -0,0 +1,680 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"**Reference: https://python.langchain.com/v0.1/docs/use_cases/sql/large_db/**"
|
| 8 |
+
]
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"cell_type": "markdown",
|
| 12 |
+
"metadata": {},
|
| 13 |
+
"source": [
|
| 14 |
+
"What happens in this notebook:\n",
|
| 15 |
+
"\n",
|
| 16 |
+
"### **Table Model Definition**\n",
|
| 17 |
+
" - **`Table` Class**: This is a simple Pydantic model representing a SQL table. It has one attribute, `name`, which is a string and is described as \"Name of table in SQL database.\"\n",
|
| 18 |
+
" - This model is used in the extraction process to match relevant SQL tables based on the user's query.\n",
|
| 19 |
+
"\n",
|
| 20 |
+
"### **Helper Function - `get_tables`**\n",
|
| 21 |
+
" - **`get_tables`**: This function takes a list of `Table` objects (i.e., categories such as \"Music\" or \"Business\") and returns a list of corresponding SQL table names based on the category.\n",
|
| 22 |
+
" - For example, if the category is `\"Music\"`, the tables `\"Album\"`, `\"Artist\"`, `\"Genre\"`, etc., are added to the result.\n",
|
| 23 |
+
" - Similarly, for `\"Business\"`, the corresponding tables like `\"Customer\"`, `\"Employee\"`, etc., are included.\n",
|
| 24 |
+
"\n",
|
| 25 |
+
"### **Designing the agent for the large DB**\n",
|
| 26 |
+
"\n",
|
| 27 |
+
"- **Step 1: Initialize LLM (`sql_agent_llm`)**: The LLM is instantiated with a given model (e.g., `\"gpt-3.5-turbo\"`) and temperature. The temperature controls how creative/random the model's responses are.\n",
|
| 28 |
+
"- **Step 2: Connect to the SQL Database (`db`)**: The connection to the Chinook SQLite database is established. The database URI is constructed using the `sqldb_directory` provided.\n",
|
| 29 |
+
"- **Step 3: Define Category Chain (`category_chain`)**: The `category_chain_system` is defined, which is a string explaining the categories available (like \"Music\" and \"Business\"). This chain determines which SQL tables are relevant to the user query based on the category.\n",
|
| 30 |
+
"- **Step 4: Chain Creation**:\n",
|
| 31 |
+
"- **`category_chain`**: This uses the `create_extraction_chain_pydantic` function, which creates an extraction chain that identifies relevant SQL tables from the user's question using the `Table` Pydantic model and the LLM.\n",
|
| 32 |
+
"- **`table_chain`**: A chain is formed by combining the output from `category_chain` with the `get_tables` function, so it maps categories to the actual SQL tables.\n",
|
| 33 |
+
"- **Step 5: Query Chain (`query_chain`)**: This creates a SQL query chain using the LLM and the database (`self.db`). It takes the SQL tables and constructs a query.\n",
|
| 34 |
+
"- **Step 6: Table Chain Input Handling**: The `\"question\"` key from the user input is mapped to the `\"input\"` key expected by the `table_chain`. This enables the chain to process user queries correctly.\n",
|
| 35 |
+
"- **Step 7: Full Chain Construction**: Finally, the full chain (`full_chain`) is created by combining:\n",
|
| 36 |
+
"1. **`RunnablePassthrough.assign`**: This sets up a step that assigns the `table_names_to_use` using the result of the `table_chain`.\n",
|
| 37 |
+
"2. **`query_chain`**: Executes the SQL query once the relevant tables are identified."
|
| 38 |
+
]
|
| 39 |
+
},
|
| 40 |
+
{
|
| 41 |
+
"cell_type": "code",
|
| 42 |
+
"execution_count": 21,
|
| 43 |
+
"metadata": {},
|
| 44 |
+
"outputs": [
|
| 45 |
+
{
|
| 46 |
+
"data": {
|
| 47 |
+
"text/plain": [
|
| 48 |
+
"True"
|
| 49 |
+
]
|
| 50 |
+
},
|
| 51 |
+
"execution_count": 21,
|
| 52 |
+
"metadata": {},
|
| 53 |
+
"output_type": "execute_result"
|
| 54 |
+
}
|
| 55 |
+
],
|
| 56 |
+
"source": [
|
| 57 |
+
"import os\n",
|
| 58 |
+
"from dotenv import load_dotenv\n",
|
| 59 |
+
"from pyprojroot import here\n",
|
| 60 |
+
"from typing import List\n",
|
| 61 |
+
"from langchain_community.utilities import SQLDatabase\n",
|
| 62 |
+
"from langchain_groq import ChatGroq\n",
|
| 63 |
+
"from pprint import pprint\n",
|
| 64 |
+
"from langchain_core.prompts import ChatPromptTemplate\n",
|
| 65 |
+
"from pydantic import BaseModel, Field\n",
|
| 66 |
+
"from typing import List\n",
|
| 67 |
+
"\n",
|
| 68 |
+
"load_dotenv()"
|
| 69 |
+
]
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"cell_type": "markdown",
|
| 73 |
+
"metadata": {},
|
| 74 |
+
"source": [
|
| 75 |
+
"**Set the environment variables and load the LLM**"
|
| 76 |
+
]
|
| 77 |
+
},
|
| 78 |
+
{
|
| 79 |
+
"cell_type": "code",
|
| 80 |
+
"execution_count": 22,
|
| 81 |
+
"metadata": {},
|
| 82 |
+
"outputs": [],
|
| 83 |
+
"source": [
|
| 84 |
+
"os.environ['GROQ_API_KEY'] = os.getenv(\"GROQ_API_KEY\")\n",
|
| 85 |
+
"\n",
|
| 86 |
+
"\n",
|
| 87 |
+
"sql_agent_llm = ChatGroq(model=\"openai/gpt-oss-120b\", temperature=0)\n",
|
| 88 |
+
"table_extractor_llm = ChatGroq(model=\"openai/gpt-oss-120b\", temperature=0)\n",
|
| 89 |
+
"# llm = ChatGroq(model=\"llama3-70b-8192\")"
|
| 90 |
+
]
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"cell_type": "code",
|
| 94 |
+
"execution_count": 23,
|
| 95 |
+
"metadata": {},
|
| 96 |
+
"outputs": [
|
| 97 |
+
{
|
| 98 |
+
"name": "stdout",
|
| 99 |
+
"output_type": "stream",
|
| 100 |
+
"text": [
|
| 101 |
+
"sqlite\n",
|
| 102 |
+
"['Album', 'Artist', 'Customer', 'Employee', 'Genre', 'Invoice', 'InvoiceLine', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track']\n"
|
| 103 |
+
]
|
| 104 |
+
},
|
| 105 |
+
{
|
| 106 |
+
"data": {
|
| 107 |
+
"text/plain": [
|
| 108 |
+
"\"[(1, 'AC/DC'), (2, 'Accept'), (3, 'Aerosmith'), (4, 'Alanis Morissette'), (5, 'Alice In Chains'), (6, 'Antônio Carlos Jobim'), (7, 'Apocalyptica'), (8, 'Audioslave'), (9, 'BackBeat'), (10, 'Billy Cobham')]\""
|
| 109 |
+
]
|
| 110 |
+
},
|
| 111 |
+
"execution_count": 23,
|
| 112 |
+
"metadata": {},
|
| 113 |
+
"output_type": "execute_result"
|
| 114 |
+
}
|
| 115 |
+
],
|
| 116 |
+
"source": [
|
| 117 |
+
"sqldb_directory = here(\"data/Chinook.db\")\n",
|
| 118 |
+
"db = SQLDatabase.from_uri(f\"sqlite:///{sqldb_directory}\")\n",
|
| 119 |
+
"print(db.dialect)\n",
|
| 120 |
+
"print(db.get_usable_table_names())\n",
|
| 121 |
+
"db.run(\"SELECT * FROM Artist LIMIT 10;\")"
|
| 122 |
+
]
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"cell_type": "markdown",
|
| 126 |
+
"metadata": {},
|
| 127 |
+
"source": [
|
| 128 |
+
"**Prepare the `Table` class**"
|
| 129 |
+
]
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"cell_type": "code",
|
| 133 |
+
"execution_count": 24,
|
| 134 |
+
"metadata": {},
|
| 135 |
+
"outputs": [],
|
| 136 |
+
"source": [
|
| 137 |
+
"from langchain_core.pydantic_v1 import BaseModel, Field\n",
|
| 138 |
+
"\n",
|
| 139 |
+
"# class Table(BaseModel):\n",
|
| 140 |
+
"# \"\"\"\n",
|
| 141 |
+
"# Represents a table in the SQL database.\n",
|
| 142 |
+
"\n",
|
| 143 |
+
"# Attributes:\n",
|
| 144 |
+
"# name (str): The name of the table in the SQL database.\n",
|
| 145 |
+
"# \"\"\"\n",
|
| 146 |
+
"# name: str = Field(description=\"Name of table in SQL database.\")\n",
|
| 147 |
+
"class Table(BaseModel):\n",
|
| 148 |
+
" \"\"\"Table in SQL database.\"\"\"\n",
|
| 149 |
+
" name: str = Field(description=\"Name of table in SQL database.\")\n",
|
| 150 |
+
"\n",
|
| 151 |
+
"class Tables(BaseModel):\n",
|
| 152 |
+
" \"\"\"Extract all relevant tables.\"\"\"\n",
|
| 153 |
+
" tables: List[Table] = Field(description=\"List of relevant tables.\")\n"
|
| 154 |
+
]
|
| 155 |
+
},
|
| 156 |
+
{
|
| 157 |
+
"cell_type": "markdown",
|
| 158 |
+
"metadata": {},
|
| 159 |
+
"source": [
|
| 160 |
+
"### **Strategy A:**"
|
| 161 |
+
]
|
| 162 |
+
},
|
| 163 |
+
{
|
| 164 |
+
"cell_type": "code",
|
| 165 |
+
"execution_count": 25,
|
| 166 |
+
"metadata": {},
|
| 167 |
+
"outputs": [
|
| 168 |
+
{
|
| 169 |
+
"name": "stdout",
|
| 170 |
+
"output_type": "stream",
|
| 171 |
+
"text": [
|
| 172 |
+
"('Album\\n'\n",
|
| 173 |
+
" 'Artist\\n'\n",
|
| 174 |
+
" 'Customer\\n'\n",
|
| 175 |
+
" 'Employee\\n'\n",
|
| 176 |
+
" 'Genre\\n'\n",
|
| 177 |
+
" 'Invoice\\n'\n",
|
| 178 |
+
" 'InvoiceLine\\n'\n",
|
| 179 |
+
" 'MediaType\\n'\n",
|
| 180 |
+
" 'Playlist\\n'\n",
|
| 181 |
+
" 'PlaylistTrack\\n'\n",
|
| 182 |
+
" 'Track')\n"
|
| 183 |
+
]
|
| 184 |
+
}
|
| 185 |
+
],
|
| 186 |
+
"source": [
|
| 187 |
+
"table_names = \"\\n\".join(db.get_usable_table_names())\n",
|
| 188 |
+
"pprint(table_names)"
|
| 189 |
+
]
|
| 190 |
+
},
|
| 191 |
+
{
|
| 192 |
+
"cell_type": "code",
|
| 193 |
+
"execution_count": 28,
|
| 194 |
+
"metadata": {},
|
| 195 |
+
"outputs": [
|
| 196 |
+
{
|
| 197 |
+
"name": "stdout",
|
| 198 |
+
"output_type": "stream",
|
| 199 |
+
"text": [
|
| 200 |
+
"[Table(name='Artist'), Table(name='Track'), Table(name='Genre'), Table(name='Album')]\n"
|
| 201 |
+
]
|
| 202 |
+
}
|
| 203 |
+
],
|
| 204 |
+
"source": [
|
| 205 |
+
"system = f\"\"\"Return the names of ALL the SQL tables that MIGHT be relevant to the user question. \\\n",
|
| 206 |
+
"The tables are:\n",
|
| 207 |
+
"\n",
|
| 208 |
+
"{table_names}\n",
|
| 209 |
+
"\n",
|
| 210 |
+
"Remember to include ALL POTENTIALLY RELEVANT tables, even if you're not sure that they're needed.\"\"\"\n",
|
| 211 |
+
"\n",
|
| 212 |
+
"prompt = ChatPromptTemplate.from_messages([\n",
|
| 213 |
+
" (\"system\", system),\n",
|
| 214 |
+
" (\"human\", \"{input}\")\n",
|
| 215 |
+
"])\n",
|
| 216 |
+
"\n",
|
| 217 |
+
"# This works with Groq, OpenAI, Anthropic, etc.\n",
|
| 218 |
+
"table_chain = prompt | table_extractor_llm.with_structured_output(Tables)\n",
|
| 219 |
+
"\n",
|
| 220 |
+
"result = table_chain.invoke({\"input\": \"What are all the genres of Alanis Morisette songs\"})\n",
|
| 221 |
+
"print(result.tables)"
|
| 222 |
+
]
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"cell_type": "markdown",
|
| 226 |
+
"metadata": {},
|
| 227 |
+
"source": [
|
| 228 |
+
"### **Strategy B:**"
|
| 229 |
+
]
|
| 230 |
+
},
|
| 231 |
+
{
|
| 232 |
+
"cell_type": "markdown",
|
| 233 |
+
"metadata": {},
|
| 234 |
+
"source": [
|
| 235 |
+
"Music:\n",
|
| 236 |
+
"\n",
|
| 237 |
+
"- \"Album\"\n",
|
| 238 |
+
"- \"Artist\"\n",
|
| 239 |
+
"- \"Genre\"\n",
|
| 240 |
+
"- \"MediaType\"\n",
|
| 241 |
+
"- \"Playlist\"\n",
|
| 242 |
+
"- \"PlaylistTrack\"\n",
|
| 243 |
+
"- \"Track\"\n",
|
| 244 |
+
"\n",
|
| 245 |
+
"Business:\n",
|
| 246 |
+
"\n",
|
| 247 |
+
"- \"Customer\"\n",
|
| 248 |
+
"- \"Employee\"\n",
|
| 249 |
+
"- \"Invoice\"\n",
|
| 250 |
+
"- \"InvoiceLine\""
|
| 251 |
+
]
|
| 252 |
+
},
|
| 253 |
+
{
|
| 254 |
+
"cell_type": "code",
|
| 255 |
+
"execution_count": 31,
|
| 256 |
+
"metadata": {},
|
| 257 |
+
"outputs": [
|
| 258 |
+
{
|
| 259 |
+
"name": "stdout",
|
| 260 |
+
"output_type": "stream",
|
| 261 |
+
"text": [
|
| 262 |
+
"[Table(name='Album'), Table(name='Artist'), Table(name='Genre'), Table(name='MediaType'), Table(name='Playlist'), Table(name='PlaylistTrack'), Table(name='Track')]\n",
|
| 263 |
+
"['Album', 'Artist', 'Genre', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track']\n"
|
| 264 |
+
]
|
| 265 |
+
}
|
| 266 |
+
],
|
| 267 |
+
"source": [
|
| 268 |
+
"system = \"\"\"You will receive a question.\n",
|
| 269 |
+
"\n",
|
| 270 |
+
"If the question is about **Music**, return **ALL** these tables:\n",
|
| 271 |
+
" - \"Album\"\n",
|
| 272 |
+
" - \"Artist\"\n",
|
| 273 |
+
" - \"Genre\"\n",
|
| 274 |
+
" - \"MediaType\"\n",
|
| 275 |
+
" - \"Playlist\"\n",
|
| 276 |
+
" - \"PlaylistTrack\"\n",
|
| 277 |
+
" - \"Track\"\n",
|
| 278 |
+
"\n",
|
| 279 |
+
"If the question is about **Business**, return **ALL** these tables:\n",
|
| 280 |
+
" - \"Customer\"\n",
|
| 281 |
+
" - \"Employee\"\n",
|
| 282 |
+
" - \"Invoice\"\n",
|
| 283 |
+
" - \"InvoiceLine\"\n",
|
| 284 |
+
"\n",
|
| 285 |
+
"If you are unsure, return the full list of all available tables for both Music and Business categories.\"\"\"\n",
|
| 286 |
+
"\n",
|
| 287 |
+
"prompt = ChatPromptTemplate.from_messages([\n",
|
| 288 |
+
" (\"system\", system),\n",
|
| 289 |
+
" (\"human\", \"{input}\")\n",
|
| 290 |
+
"])\n",
|
| 291 |
+
"\n",
|
| 292 |
+
"table_chain = prompt | table_extractor_llm.with_structured_output(Tables)\n",
|
| 293 |
+
"\n",
|
| 294 |
+
"# Test it\n",
|
| 295 |
+
"result = table_chain.invoke({\"input\": \"What are all the genres of Alanis Morisette songs\"})\n",
|
| 296 |
+
"print(result.tables)\n",
|
| 297 |
+
"\n",
|
| 298 |
+
"# To get just the table names as a list\n",
|
| 299 |
+
"table_names = [t.name for t in result.tables]\n",
|
| 300 |
+
"print(table_names)"
|
| 301 |
+
]
|
| 302 |
+
},
|
| 303 |
+
{
|
| 304 |
+
"cell_type": "markdown",
|
| 305 |
+
"metadata": {},
|
| 306 |
+
"source": [
|
| 307 |
+
"### **Strategy C:**\n",
|
| 308 |
+
"\n",
|
| 309 |
+
"- **Step 1: Define the category**"
|
| 310 |
+
]
|
| 311 |
+
},
|
| 312 |
+
{
|
| 313 |
+
"cell_type": "code",
|
| 314 |
+
"execution_count": 33,
|
| 315 |
+
"metadata": {},
|
| 316 |
+
"outputs": [
|
| 317 |
+
{
|
| 318 |
+
"name": "stdout",
|
| 319 |
+
"output_type": "stream",
|
| 320 |
+
"text": [
|
| 321 |
+
"[Table(name='Music')]\n",
|
| 322 |
+
"['Music']\n"
|
| 323 |
+
]
|
| 324 |
+
}
|
| 325 |
+
],
|
| 326 |
+
"source": [
|
| 327 |
+
"system = \"\"\"Return the names of the SQL tables that are relevant to the user question. \\\n",
|
| 328 |
+
"The tables are:\n",
|
| 329 |
+
"\n",
|
| 330 |
+
"Music\n",
|
| 331 |
+
"Business\"\"\"\n",
|
| 332 |
+
"\n",
|
| 333 |
+
"prompt = ChatPromptTemplate.from_messages([\n",
|
| 334 |
+
" (\"system\", system),\n",
|
| 335 |
+
" (\"human\", \"{input}\")\n",
|
| 336 |
+
"])\n",
|
| 337 |
+
"\n",
|
| 338 |
+
"category_chain = prompt | table_extractor_llm.with_structured_output(Tables)\n",
|
| 339 |
+
"\n",
|
| 340 |
+
"# Test it\n",
|
| 341 |
+
"result = category_chain.invoke({\"input\": \"What are all the genres of Alanis Morisette songs\"})\n",
|
| 342 |
+
"print(result.tables)\n",
|
| 343 |
+
"\n",
|
| 344 |
+
"# To get just the category names as a list\n",
|
| 345 |
+
"category_names = [t.name for t in result.tables]\n",
|
| 346 |
+
"print(category_names)"
|
| 347 |
+
]
|
| 348 |
+
},
|
| 349 |
+
{
|
| 350 |
+
"cell_type": "code",
|
| 351 |
+
"execution_count": 34,
|
| 352 |
+
"metadata": {},
|
| 353 |
+
"outputs": [
|
| 354 |
+
{
|
| 355 |
+
"data": {
|
| 356 |
+
"text/plain": [
|
| 357 |
+
"Tables(tables=[Table(name='Music')])"
|
| 358 |
+
]
|
| 359 |
+
},
|
| 360 |
+
"execution_count": 34,
|
| 361 |
+
"metadata": {},
|
| 362 |
+
"output_type": "execute_result"
|
| 363 |
+
}
|
| 364 |
+
],
|
| 365 |
+
"source": [
|
| 366 |
+
"category_chain.invoke({\"input\": \"What are all the genres of Alanis Morisette songs\"})"
|
| 367 |
+
]
|
| 368 |
+
},
|
| 369 |
+
{
|
| 370 |
+
"cell_type": "markdown",
|
| 371 |
+
"metadata": {},
|
| 372 |
+
"source": [
|
| 373 |
+
"- **Step 2: Execute the python function**"
|
| 374 |
+
]
|
| 375 |
+
},
|
| 376 |
+
{
|
| 377 |
+
"cell_type": "code",
|
| 378 |
+
"execution_count": 37,
|
| 379 |
+
"metadata": {},
|
| 380 |
+
"outputs": [
|
| 381 |
+
{
|
| 382 |
+
"name": "stdout",
|
| 383 |
+
"output_type": "stream",
|
| 384 |
+
"text": [
|
| 385 |
+
"['Album', 'Artist', 'Genre', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track']\n"
|
| 386 |
+
]
|
| 387 |
+
}
|
| 388 |
+
],
|
| 389 |
+
"source": [
|
| 390 |
+
"from langchain_core.runnables import RunnableLambda\n",
|
| 391 |
+
"\n",
|
| 392 |
+
"def get_tables(result: Tables) -> List[str]:\n",
|
| 393 |
+
" \"\"\"Maps category names to corresponding SQL table names.\n",
|
| 394 |
+
"\n",
|
| 395 |
+
" Args:\n",
|
| 396 |
+
" result (Tables): A `Tables` object containing a list of `Table` objects\n",
|
| 397 |
+
" representing the relevant categories (e.g., Music, Business).\n",
|
| 398 |
+
"\n",
|
| 399 |
+
" Returns:\n",
|
| 400 |
+
" List[str]: A list of SQL table names corresponding to the provided categories.\n",
|
| 401 |
+
" \"\"\"\n",
|
| 402 |
+
" tables = []\n",
|
| 403 |
+
" for category in result.tables: # ← extract .tables from the Tables object\n",
|
| 404 |
+
" if category.name == \"Music\":\n",
|
| 405 |
+
" tables.extend([\n",
|
| 406 |
+
" \"Album\",\n",
|
| 407 |
+
" \"Artist\", \n",
|
| 408 |
+
" \"Genre\",\n",
|
| 409 |
+
" \"MediaType\",\n",
|
| 410 |
+
" \"Playlist\",\n",
|
| 411 |
+
" \"PlaylistTrack\",\n",
|
| 412 |
+
" \"Track\",\n",
|
| 413 |
+
" ])\n",
|
| 414 |
+
" elif category.name == \"Business\":\n",
|
| 415 |
+
" tables.extend([\"Customer\", \"Employee\", \"Invoice\", \"InvoiceLine\"])\n",
|
| 416 |
+
" return tables\n",
|
| 417 |
+
"\n",
|
| 418 |
+
"table_chain = category_chain | RunnableLambda(get_tables)\n",
|
| 419 |
+
"\n",
|
| 420 |
+
"# Test\n",
|
| 421 |
+
"result = table_chain.invoke({\"input\": \"What are all the genres of Alanis Morisette songs\"})\n",
|
| 422 |
+
"print(result)"
|
| 423 |
+
]
|
| 424 |
+
},
|
| 425 |
+
{
|
| 426 |
+
"cell_type": "markdown",
|
| 427 |
+
"metadata": {},
|
| 428 |
+
"source": [
|
| 429 |
+
"### **Final step:**\n",
|
| 430 |
+
"\n",
|
| 431 |
+
"**Attach the desired strategy to your SQL agent**"
|
| 432 |
+
]
|
| 433 |
+
},
|
| 434 |
+
{
|
| 435 |
+
"cell_type": "code",
|
| 436 |
+
"execution_count": 53,
|
| 437 |
+
"metadata": {},
|
| 438 |
+
"outputs": [],
|
| 439 |
+
"source": [
|
| 440 |
+
"from langchain_core.runnables import RunnablePassthrough, RunnableLambda\n",
|
| 441 |
+
"from langchain.chains import create_sql_query_chain\n",
|
| 442 |
+
"from operator import itemgetter\n",
|
| 443 |
+
"import re\n",
|
| 444 |
+
"\n",
|
| 445 |
+
"def extract_sql(llm_response: str) -> str:\n",
|
| 446 |
+
" \"\"\"Extracts clean SQL query from LLM response.\n",
|
| 447 |
+
"\n",
|
| 448 |
+
" Args:\n",
|
| 449 |
+
" llm_response (str): The full LLM response containing the SQL query\n",
|
| 450 |
+
" possibly wrapped in markdown code blocks and prefixed\n",
|
| 451 |
+
" with 'Question:' and 'SQLQuery:' labels.\n",
|
| 452 |
+
"\n",
|
| 453 |
+
" Returns:\n",
|
| 454 |
+
" str: The clean SQL query string ready to be executed.\n",
|
| 455 |
+
" \"\"\"\n",
|
| 456 |
+
" match = re.search(r\"```sql\\s*(.*?)\\s*```\", llm_response, re.DOTALL)\n",
|
| 457 |
+
" if match:\n",
|
| 458 |
+
" return match.group(1).strip()\n",
|
| 459 |
+
" match = re.search(r\"SQLQuery:\\s*(.*)\", llm_response, re.DOTALL)\n",
|
| 460 |
+
" if match:\n",
|
| 461 |
+
" return match.group(1).strip()\n",
|
| 462 |
+
" return llm_response.strip()\n",
|
| 463 |
+
"\n",
|
| 464 |
+
"\n",
|
| 465 |
+
"# table_chain: categories → table names\n",
|
| 466 |
+
"_table_mapper = category_chain | RunnableLambda(get_tables)\n",
|
| 467 |
+
"\n",
|
| 468 |
+
"# Wire \"question\" → \"input\" expected by category_chain\n",
|
| 469 |
+
"_table_chain_with_key = {\"input\": itemgetter(\"question\")} | _table_mapper\n",
|
| 470 |
+
"\n",
|
| 471 |
+
"# Full chain\n",
|
| 472 |
+
"query_chain = create_sql_query_chain(sql_agent_llm, db)\n",
|
| 473 |
+
"\n",
|
| 474 |
+
"full_chain = (\n",
|
| 475 |
+
" RunnablePassthrough.assign(table_names_to_use=_table_chain_with_key)\n",
|
| 476 |
+
" | query_chain\n",
|
| 477 |
+
" | RunnableLambda(extract_sql)\n",
|
| 478 |
+
")\n"
|
| 479 |
+
]
|
| 480 |
+
},
|
| 481 |
+
{
|
| 482 |
+
"cell_type": "markdown",
|
| 483 |
+
"metadata": {},
|
| 484 |
+
"source": [
|
| 485 |
+
"**Test the agent**"
|
| 486 |
+
]
|
| 487 |
+
},
|
| 488 |
+
{
|
| 489 |
+
"cell_type": "code",
|
| 490 |
+
"execution_count": 54,
|
| 491 |
+
"metadata": {},
|
| 492 |
+
"outputs": [
|
| 493 |
+
{
|
| 494 |
+
"ename": "APITimeoutError",
|
| 495 |
+
"evalue": "Request timed out.",
|
| 496 |
+
"output_type": "error",
|
| 497 |
+
"traceback": [
|
| 498 |
+
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
| 499 |
+
"\u001b[31mConnectTimeout\u001b[39m Traceback (most recent call last)",
|
| 500 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpx\\_transports\\default.py:101\u001b[39m, in \u001b[36mmap_httpcore_exceptions\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 100\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m101\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m\n\u001b[32m 102\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n",
|
| 501 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpx\\_transports\\default.py:250\u001b[39m, in \u001b[36mHTTPTransport.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 249\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m map_httpcore_exceptions():\n\u001b[32m--> \u001b[39m\u001b[32m250\u001b[39m resp = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_pool\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mhandle_request\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mreq\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 252\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(resp.stream, typing.Iterable)\n",
|
| 502 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpcore\\_sync\\connection_pool.py:256\u001b[39m, in \u001b[36mConnectionPool.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 255\u001b[39m \u001b[38;5;28mself\u001b[39m._close_connections(closing)\n\u001b[32m--> \u001b[39m\u001b[32m256\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m exc \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 258\u001b[39m \u001b[38;5;66;03m# Return the response. Note that in this case we still have to manage\u001b[39;00m\n\u001b[32m 259\u001b[39m \u001b[38;5;66;03m# the point at which the response is closed.\u001b[39;00m\n",
|
| 503 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpcore\\_sync\\connection_pool.py:236\u001b[39m, in \u001b[36mConnectionPool.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 234\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 235\u001b[39m \u001b[38;5;66;03m# Send the request on the assigned connection.\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m236\u001b[39m response = \u001b[30;43mconnection\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mhandle_request\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 237\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mpool_request\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\n\u001b[32m 238\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 239\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m ConnectionNotAvailable:\n\u001b[32m 240\u001b[39m \u001b[38;5;66;03m# In some cases a connection may initially be available to\u001b[39;00m\n\u001b[32m 241\u001b[39m \u001b[38;5;66;03m# handle a request, but then become unavailable.\u001b[39;00m\n\u001b[32m 242\u001b[39m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[32m 243\u001b[39m \u001b[38;5;66;03m# In this case we clear the connection and try again.\u001b[39;00m\n",
|
| 504 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpcore\\_sync\\connection.py:101\u001b[39m, in \u001b[36mHTTPConnection.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 100\u001b[39m \u001b[38;5;28mself\u001b[39m._connect_failed = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m101\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m exc\n\u001b[32m 103\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._connection.handle_request(request)\n",
|
| 505 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpcore\\_sync\\connection.py:78\u001b[39m, in \u001b[36mHTTPConnection.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 77\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._connection \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m78\u001b[39m stream = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_connect\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 80\u001b[39m ssl_object = stream.get_extra_info(\u001b[33m\"\u001b[39m\u001b[33mssl_object\u001b[39m\u001b[33m\"\u001b[39m)\n",
|
| 506 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpcore\\_sync\\connection.py:156\u001b[39m, in \u001b[36mHTTPConnection._connect\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 155\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m Trace(\u001b[33m\"\u001b[39m\u001b[33mstart_tls\u001b[39m\u001b[33m\"\u001b[39m, logger, request, kwargs) \u001b[38;5;28;01mas\u001b[39;00m trace:\n\u001b[32m--> \u001b[39m\u001b[32m156\u001b[39m stream = \u001b[30;43mstream\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mstart_tls\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 157\u001b[39m trace.return_value = stream\n",
|
| 507 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpcore\\_backends\\sync.py:154\u001b[39m, in \u001b[36mSyncStream.start_tls\u001b[39m\u001b[34m(self, ssl_context, server_hostname, timeout)\u001b[39m\n\u001b[32m 150\u001b[39m exc_map: ExceptionMapping = {\n\u001b[32m 151\u001b[39m socket.timeout: ConnectTimeout,\n\u001b[32m 152\u001b[39m \u001b[38;5;167;01mOSError\u001b[39;00m: ConnectError,\n\u001b[32m 153\u001b[39m }\n\u001b[32m--> \u001b[39m\u001b[32m154\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m map_exceptions(exc_map):\n\u001b[32m 155\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
| 508 |
+
"\u001b[36mFile \u001b[39m\u001b[32mC:\\Program Files\\Python312\\Lib\\contextlib.py:158\u001b[39m, in \u001b[36m_GeneratorContextManager.__exit__\u001b[39m\u001b[34m(self, typ, value, traceback)\u001b[39m\n\u001b[32m 157\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m158\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mgen\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mthrow\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mvalue\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 159\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 160\u001b[39m \u001b[38;5;66;03m# Suppress StopIteration *unless* it's the same exception that\u001b[39;00m\n\u001b[32m 161\u001b[39m \u001b[38;5;66;03m# was passed to throw(). This prevents a StopIteration\u001b[39;00m\n\u001b[32m 162\u001b[39m \u001b[38;5;66;03m# raised inside the \"with\" statement from being suppressed.\u001b[39;00m\n",
|
| 509 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpcore\\_exceptions.py:14\u001b[39m, in \u001b[36mmap_exceptions\u001b[39m\u001b[34m(map)\u001b[39m\n\u001b[32m 13\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(exc, from_exc):\n\u001b[32m---> \u001b[39m\u001b[32m14\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m to_exc(exc) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mexc\u001b[39;00m\n\u001b[32m 15\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m\n",
|
| 510 |
+
"\u001b[31mConnectTimeout\u001b[39m: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond",
|
| 511 |
+
"\nThe above exception was the direct cause of the following exception:\n",
|
| 512 |
+
"\u001b[31mConnectTimeout\u001b[39m Traceback (most recent call last)",
|
| 513 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\groq\\_base_client.py:980\u001b[39m, in \u001b[36mSyncAPIClient.request\u001b[39m\u001b[34m(self, cast_to, options, stream, stream_cls)\u001b[39m\n\u001b[32m 979\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m980\u001b[39m response = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_client\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43msend\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 981\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 982\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mor\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_should_stream_response_body\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 983\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 984\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 985\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m httpx.TimeoutException \u001b[38;5;28;01mas\u001b[39;00m err:\n",
|
| 514 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpx\\_client.py:914\u001b[39m, in \u001b[36mClient.send\u001b[39m\u001b[34m(self, request, stream, auth, follow_redirects)\u001b[39m\n\u001b[32m 912\u001b[39m auth = \u001b[38;5;28mself\u001b[39m._build_request_auth(request, auth)\n\u001b[32m--> \u001b[39m\u001b[32m914\u001b[39m response = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_send_handling_auth\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 915\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 916\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mauth\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mauth\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 917\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mfollow_redirects\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mfollow_redirects\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 918\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mhistory\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 919\u001b[39m \u001b[30;43m\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 920\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
| 515 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpx\\_client.py:942\u001b[39m, in \u001b[36mClient._send_handling_auth\u001b[39m\u001b[34m(self, request, auth, follow_redirects, history)\u001b[39m\n\u001b[32m 941\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m942\u001b[39m response = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_send_handling_redirects\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 943\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 944\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mfollow_redirects\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mfollow_redirects\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 945\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mhistory\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mhistory\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 946\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 947\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
| 516 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpx\\_client.py:979\u001b[39m, in \u001b[36mClient._send_handling_redirects\u001b[39m\u001b[34m(self, request, follow_redirects, history)\u001b[39m\n\u001b[32m 977\u001b[39m hook(request)\n\u001b[32m--> \u001b[39m\u001b[32m979\u001b[39m response = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_send_single_request\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 980\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
|
| 517 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpx\\_client.py:1014\u001b[39m, in \u001b[36mClient._send_single_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 1013\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m request_context(request=request):\n\u001b[32m-> \u001b[39m\u001b[32m1014\u001b[39m response = \u001b[30;43mtransport\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mhandle_request\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1016\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(response.stream, SyncByteStream)\n",
|
| 518 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpx\\_transports\\default.py:249\u001b[39m, in \u001b[36mHTTPTransport.handle_request\u001b[39m\u001b[34m(self, request)\u001b[39m\n\u001b[32m 237\u001b[39m req = httpcore.Request(\n\u001b[32m 238\u001b[39m method=request.method,\n\u001b[32m 239\u001b[39m url=httpcore.URL(\n\u001b[32m (...)\u001b[39m\u001b[32m 247\u001b[39m extensions=request.extensions,\n\u001b[32m 248\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m249\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m map_httpcore_exceptions():\n\u001b[32m 250\u001b[39m resp = \u001b[38;5;28mself\u001b[39m._pool.handle_request(req)\n",
|
| 519 |
+
"\u001b[36mFile \u001b[39m\u001b[32mC:\\Program Files\\Python312\\Lib\\contextlib.py:158\u001b[39m, in \u001b[36m_GeneratorContextManager.__exit__\u001b[39m\u001b[34m(self, typ, value, traceback)\u001b[39m\n\u001b[32m 157\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m158\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mgen\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mthrow\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mvalue\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 159\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 160\u001b[39m \u001b[38;5;66;03m# Suppress StopIteration *unless* it's the same exception that\u001b[39;00m\n\u001b[32m 161\u001b[39m \u001b[38;5;66;03m# was passed to throw(). This prevents a StopIteration\u001b[39;00m\n\u001b[32m 162\u001b[39m \u001b[38;5;66;03m# raised inside the \"with\" statement from being suppressed.\u001b[39;00m\n",
|
| 520 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\httpx\\_transports\\default.py:118\u001b[39m, in \u001b[36mmap_httpcore_exceptions\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 117\u001b[39m message = \u001b[38;5;28mstr\u001b[39m(exc)\n\u001b[32m--> \u001b[39m\u001b[32m118\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m mapped_exc(message) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mexc\u001b[39;00m\n",
|
| 521 |
+
"\u001b[31mConnectTimeout\u001b[39m: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond",
|
| 522 |
+
"\nThe above exception was the direct cause of the following exception:\n",
|
| 523 |
+
"\u001b[31mAPITimeoutError\u001b[39m Traceback (most recent call last)",
|
| 524 |
+
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[54]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# ── Test ─────────────────────────────────────────────────────────────────────\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m query = full_chain.invoke({\u001b[33m\"question\"\u001b[39m: \u001b[33m\"What is the most popular genre by number of tracks?\"\u001b[39m})\n\u001b[32m 3\u001b[39m print(\u001b[33m\"Clean SQL:\\n\"\u001b[39m, query)\n\u001b[32m 4\u001b[39m \n\u001b[32m 5\u001b[39m result = db.run(query)\n",
|
| 525 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\base.py:2876\u001b[39m, in \u001b[36mRunnableSequence.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m 2874\u001b[39m context.run(_set_config_context, config)\n\u001b[32m 2875\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m i == \u001b[32m0\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m2876\u001b[39m \u001b[38;5;28minput\u001b[39m = \u001b[30;43mcontext\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrun\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mstep\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43minvoke\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 2877\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 2878\u001b[39m \u001b[38;5;28minput\u001b[39m = context.run(step.invoke, \u001b[38;5;28minput\u001b[39m, config)\n",
|
| 526 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\passthrough.py:495\u001b[39m, in \u001b[36mRunnableAssign.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m 489\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34minvoke\u001b[39m(\n\u001b[32m 490\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 491\u001b[39m \u001b[38;5;28minput\u001b[39m: Dict[\u001b[38;5;28mstr\u001b[39m, Any],\n\u001b[32m 492\u001b[39m config: Optional[RunnableConfig] = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 493\u001b[39m **kwargs: Any,\n\u001b[32m 494\u001b[39m ) -> Dict[\u001b[38;5;28mstr\u001b[39m, Any]:\n\u001b[32m--> \u001b[39m\u001b[32m495\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_call_with_config\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_invoke\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
|
| 527 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\base.py:1785\u001b[39m, in \u001b[36mRunnable._call_with_config\u001b[39m\u001b[34m(self, func, input, config, run_type, **kwargs)\u001b[39m\n\u001b[32m 1781\u001b[39m context = copy_context()\n\u001b[32m 1782\u001b[39m context.run(_set_config_context, child_config)\n\u001b[32m 1783\u001b[39m output = cast(\n\u001b[32m 1784\u001b[39m Output,\n\u001b[32m-> \u001b[39m\u001b[32m1785\u001b[39m \u001b[30;43mcontext\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrun\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 1786\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcall_func_with_variable_args\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;03m# type: ignore[arg-type]\u001b[39;49;00m\n\u001b[32m 1787\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mfunc\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;03m# type: ignore[arg-type]\u001b[39;49;00m\n\u001b[32m 1788\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;03m# type: ignore[arg-type]\u001b[39;49;00m\n\u001b[32m 1789\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1790\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrun_manager\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1791\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1792\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m,\n\u001b[32m 1793\u001b[39m )\n\u001b[32m 1794\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m 1795\u001b[39m run_manager.on_chain_error(e)\n",
|
| 528 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\config.py:398\u001b[39m, in \u001b[36mcall_func_with_variable_args\u001b[39m\u001b[34m(func, input, config, run_manager, **kwargs)\u001b[39m\n\u001b[32m 396\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m run_manager \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m accepts_run_manager(func):\n\u001b[32m 397\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mrun_manager\u001b[39m\u001b[33m\"\u001b[39m] = run_manager\n\u001b[32m--> \u001b[39m\u001b[32m398\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mfunc\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
|
| 529 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\passthrough.py:482\u001b[39m, in \u001b[36mRunnableAssign._invoke\u001b[39m\u001b[34m(self, input, run_manager, config, **kwargs)\u001b[39m\n\u001b[32m 469\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_invoke\u001b[39m(\n\u001b[32m 470\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 471\u001b[39m \u001b[38;5;28minput\u001b[39m: Dict[\u001b[38;5;28mstr\u001b[39m, Any],\n\u001b[32m (...)\u001b[39m\u001b[32m 474\u001b[39m **kwargs: Any,\n\u001b[32m 475\u001b[39m ) -> Dict[\u001b[38;5;28mstr\u001b[39m, Any]:\n\u001b[32m 476\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(\n\u001b[32m 477\u001b[39m \u001b[38;5;28minput\u001b[39m, \u001b[38;5;28mdict\u001b[39m\n\u001b[32m 478\u001b[39m ), \u001b[33m\"\u001b[39m\u001b[33mThe input to RunnablePassthrough.assign() must be a dict.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 480\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m {\n\u001b[32m 481\u001b[39m **\u001b[38;5;28minput\u001b[39m,\n\u001b[32m--> \u001b[39m\u001b[32m482\u001b[39m **\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mmapper\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43minvoke\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 483\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 484\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mpatch_config\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcallbacks\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mrun_manager\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mget_child\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 485\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 486\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m,\n\u001b[32m 487\u001b[39m }\n",
|
| 530 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\base.py:3579\u001b[39m, in \u001b[36mRunnableParallel.invoke\u001b[39m\u001b[34m(self, input, config)\u001b[39m\n\u001b[32m 3574\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m get_executor_for_config(config) \u001b[38;5;28;01mas\u001b[39;00m executor:\n\u001b[32m 3575\u001b[39m futures = [\n\u001b[32m 3576\u001b[39m executor.submit(_invoke_step, step, \u001b[38;5;28minput\u001b[39m, config, key)\n\u001b[32m 3577\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m key, step \u001b[38;5;129;01min\u001b[39;00m steps.items()\n\u001b[32m 3578\u001b[39m ]\n\u001b[32m-> \u001b[39m\u001b[32m3579\u001b[39m output = {key: \u001b[30;43mfuture\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mresult\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m \u001b[38;5;28;01mfor\u001b[39;00m key, future \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(steps, futures)}\n\u001b[32m 3580\u001b[39m \u001b[38;5;66;03m# finish the root run\u001b[39;00m\n\u001b[32m 3581\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
|
| 531 |
+
"\u001b[36mFile \u001b[39m\u001b[32mC:\\Program Files\\Python312\\Lib\\concurrent\\futures\\_base.py:456\u001b[39m, in \u001b[36mFuture.result\u001b[39m\u001b[34m(self, timeout)\u001b[39m\n\u001b[32m 454\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CancelledError()\n\u001b[32m 455\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._state == FINISHED:\n\u001b[32m--> \u001b[39m\u001b[32m456\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m__get_result\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 457\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 458\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTimeoutError\u001b[39;00m()\n",
|
| 532 |
+
"\u001b[36mFile \u001b[39m\u001b[32mC:\\Program Files\\Python312\\Lib\\concurrent\\futures\\_base.py:401\u001b[39m, in \u001b[36mFuture.__get_result\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 399\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._exception:\n\u001b[32m 400\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m401\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m._exception\n\u001b[32m 402\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 403\u001b[39m \u001b[38;5;66;03m# Break a reference cycle with the exception in self._exception\u001b[39;00m\n\u001b[32m 404\u001b[39m \u001b[38;5;28mself\u001b[39m = \u001b[38;5;28;01mNone\u001b[39;00m\n",
|
| 533 |
+
"\u001b[36mFile \u001b[39m\u001b[32mC:\\Program Files\\Python312\\Lib\\concurrent\\futures\\thread.py:59\u001b[39m, in \u001b[36m_WorkItem.run\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 56\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m 58\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m59\u001b[39m result = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mfn\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 60\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m 61\u001b[39m \u001b[38;5;28mself\u001b[39m.future.set_exception(exc)\n",
|
| 534 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\base.py:3563\u001b[39m, in \u001b[36mRunnableParallel.invoke.<locals>._invoke_step\u001b[39m\u001b[34m(step, input, config, key)\u001b[39m\n\u001b[32m 3561\u001b[39m context = copy_context()\n\u001b[32m 3562\u001b[39m context.run(_set_config_context, child_config)\n\u001b[32m-> \u001b[39m\u001b[32m3563\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mcontext\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrun\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 3564\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstep\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43minvoke\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 3565\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 3566\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mchild_config\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 3567\u001b[39m \u001b[30;43m\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
|
| 535 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\base.py:2878\u001b[39m, in \u001b[36mRunnableSequence.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m 2876\u001b[39m \u001b[38;5;28minput\u001b[39m = context.run(step.invoke, \u001b[38;5;28minput\u001b[39m, config, **kwargs)\n\u001b[32m 2877\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m2878\u001b[39m \u001b[38;5;28minput\u001b[39m = \u001b[30;43mcontext\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrun\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mstep\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43minvoke\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 2879\u001b[39m \u001b[38;5;66;03m# finish the root run\u001b[39;00m\n\u001b[32m 2880\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
|
| 536 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\runnables\\base.py:5092\u001b[39m, in \u001b[36mRunnableBindingBase.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m 5086\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34minvoke\u001b[39m(\n\u001b[32m 5087\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 5088\u001b[39m \u001b[38;5;28minput\u001b[39m: Input,\n\u001b[32m 5089\u001b[39m config: Optional[RunnableConfig] = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 5090\u001b[39m **kwargs: Optional[Any],\n\u001b[32m 5091\u001b[39m ) -> Output:\n\u001b[32m-> \u001b[39m\u001b[32m5092\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mbound\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43minvoke\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 5093\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 5094\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_merge_configs\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 5095\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m{\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m}\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 5096\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
|
| 537 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:277\u001b[39m, in \u001b[36mBaseChatModel.invoke\u001b[39m\u001b[34m(self, input, config, stop, **kwargs)\u001b[39m\n\u001b[32m 266\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34minvoke\u001b[39m(\n\u001b[32m 267\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 268\u001b[39m \u001b[38;5;28minput\u001b[39m: LanguageModelInput,\n\u001b[32m (...)\u001b[39m\u001b[32m 272\u001b[39m **kwargs: Any,\n\u001b[32m 273\u001b[39m ) -> BaseMessage:\n\u001b[32m 274\u001b[39m config = ensure_config(config)\n\u001b[32m 275\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(\n\u001b[32m 276\u001b[39m ChatGeneration,\n\u001b[32m--> \u001b[39m\u001b[32m277\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mgenerate_prompt\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 278\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_convert_input\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43minput\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 279\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 280\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcallbacks\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mget\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mcallbacks\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 281\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mtags\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mget\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mtags\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 282\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mmetadata\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mget\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mmetadata\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 283\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrun_name\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mget\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mrun_name\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 284\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrun_id\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mconfig\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mpop\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mrun_id\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mNone\u001b[39;49;00m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 285\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 286\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m.generations[\u001b[32m0\u001b[39m][\u001b[32m0\u001b[39m],\n\u001b[32m 287\u001b[39m ).message\n",
|
| 538 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:777\u001b[39m, in \u001b[36mBaseChatModel.generate_prompt\u001b[39m\u001b[34m(self, prompts, stop, callbacks, **kwargs)\u001b[39m\n\u001b[32m 769\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mgenerate_prompt\u001b[39m(\n\u001b[32m 770\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 771\u001b[39m prompts: List[PromptValue],\n\u001b[32m (...)\u001b[39m\u001b[32m 774\u001b[39m **kwargs: Any,\n\u001b[32m 775\u001b[39m ) -> LLMResult:\n\u001b[32m 776\u001b[39m prompt_messages = [p.to_messages() \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m prompts]\n\u001b[32m--> \u001b[39m\u001b[32m777\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mgenerate\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mprompt_messages\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcallbacks\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mcallbacks\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
|
| 539 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:634\u001b[39m, in \u001b[36mBaseChatModel.generate\u001b[39m\u001b[34m(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)\u001b[39m\n\u001b[32m 632\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m run_managers:\n\u001b[32m 633\u001b[39m run_managers[i].on_llm_error(e, response=LLMResult(generations=[]))\n\u001b[32m--> \u001b[39m\u001b[32m634\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[32m 635\u001b[39m flattened_outputs = [\n\u001b[32m 636\u001b[39m LLMResult(generations=[res.generations], llm_output=res.llm_output) \u001b[38;5;66;03m# type: ignore[list-item]\u001b[39;00m\n\u001b[32m 637\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m res \u001b[38;5;129;01min\u001b[39;00m results\n\u001b[32m 638\u001b[39m ]\n\u001b[32m 639\u001b[39m llm_output = \u001b[38;5;28mself\u001b[39m._combine_llm_outputs([res.llm_output \u001b[38;5;28;01mfor\u001b[39;00m res \u001b[38;5;129;01min\u001b[39;00m results])\n",
|
| 540 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:624\u001b[39m, in \u001b[36mBaseChatModel.generate\u001b[39m\u001b[34m(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)\u001b[39m\n\u001b[32m 621\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i, m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(messages):\n\u001b[32m 622\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 623\u001b[39m results.append(\n\u001b[32m--> \u001b[39m\u001b[32m624\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_generate_with_cache\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 625\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mm\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 626\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 627\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mrun_manager\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mrun_managers\u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43mi\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mif\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43mrun_managers\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01melse\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mNone\u001b[39;49;00m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 628\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 629\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 630\u001b[39m )\n\u001b[32m 631\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m 632\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m run_managers:\n",
|
| 541 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_core\\language_models\\chat_models.py:846\u001b[39m, in \u001b[36mBaseChatModel._generate_with_cache\u001b[39m\u001b[34m(self, messages, stop, run_manager, **kwargs)\u001b[39m\n\u001b[32m 844\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 845\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m inspect.signature(\u001b[38;5;28mself\u001b[39m._generate).parameters.get(\u001b[33m\"\u001b[39m\u001b[33mrun_manager\u001b[39m\u001b[33m\"\u001b[39m):\n\u001b[32m--> \u001b[39m\u001b[32m846\u001b[39m result = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_generate\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 847\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mmessages\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mrun_manager\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mrun_manager\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\n\u001b[32m 848\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 849\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 850\u001b[39m result = \u001b[38;5;28mself\u001b[39m._generate(messages, stop=stop, **kwargs)\n",
|
| 542 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\langchain_groq\\chat_models.py:472\u001b[39m, in \u001b[36mChatGroq._generate\u001b[39m\u001b[34m(self, messages, stop, run_manager, **kwargs)\u001b[39m\n\u001b[32m 467\u001b[39m message_dicts, params = \u001b[38;5;28mself\u001b[39m._create_message_dicts(messages, stop)\n\u001b[32m 468\u001b[39m params = {\n\u001b[32m 469\u001b[39m **params,\n\u001b[32m 470\u001b[39m **kwargs,\n\u001b[32m 471\u001b[39m }\n\u001b[32m--> \u001b[39m\u001b[32m472\u001b[39m response = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mclient\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mcreate\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mmessages\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mmessage_dicts\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mparams\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 473\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._create_chat_result(response)\n",
|
| 543 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\groq\\resources\\chat\\completions.py:461\u001b[39m, in \u001b[36mCompletions.create\u001b[39m\u001b[34m(self, messages, model, citation_options, compound_custom, disable_tool_validation, documents, exclude_domains, frequency_penalty, function_call, functions, include_domains, include_reasoning, logit_bias, logprobs, max_completion_tokens, max_tokens, metadata, n, parallel_tool_calls, presence_penalty, reasoning_effort, reasoning_format, response_format, search_settings, seed, service_tier, stop, store, stream, temperature, tool_choice, tools, top_logprobs, top_p, user, extra_headers, extra_query, extra_body, timeout)\u001b[39m\n\u001b[32m 241\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate\u001b[39m(\n\u001b[32m 242\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 243\u001b[39m *,\n\u001b[32m (...)\u001b[39m\u001b[32m 300\u001b[39m timeout: \u001b[38;5;28mfloat\u001b[39m | httpx.Timeout | \u001b[38;5;28;01mNone\u001b[39;00m | NotGiven = not_given,\n\u001b[32m 301\u001b[39m ) -> ChatCompletion | Stream[ChatCompletionChunk]:\n\u001b[32m 302\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 303\u001b[39m \u001b[33;03m Creates a model response for the given chat conversation.\u001b[39;00m\n\u001b[32m 304\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 459\u001b[39m \u001b[33;03m timeout: Override the client-level default timeout for this request, in seconds\u001b[39;00m\n\u001b[32m 460\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m461\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_post\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 462\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m/openai/v1/chat/completions\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 463\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mbody\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mmaybe_transform\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 464\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m{\u001b[39;49m\n\u001b[32m 465\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mmessages\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mmessages\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 466\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mmodel\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mmodel\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 467\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mcitation_options\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcitation_options\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 468\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mcompound_custom\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mcompound_custom\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 469\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mdisable_tool_validation\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mdisable_tool_validation\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 470\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mdocuments\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mdocuments\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 471\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mexclude_domains\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mexclude_domains\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 472\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mfrequency_penalty\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mfrequency_penalty\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 473\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mfunction_call\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mfunction_call\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 474\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mfunctions\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mfunctions\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 475\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43minclude_domains\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43minclude_domains\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 476\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43minclude_reasoning\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43minclude_reasoning\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 477\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mlogit_bias\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mlogit_bias\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 478\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mlogprobs\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mlogprobs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 479\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mmax_completion_tokens\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mmax_completion_tokens\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 480\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mmax_tokens\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mmax_tokens\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 481\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mmetadata\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mmetadata\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 482\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mn\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mn\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 483\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mparallel_tool_calls\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mparallel_tool_calls\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 484\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mpresence_penalty\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mpresence_penalty\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 485\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mreasoning_effort\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mreasoning_effort\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 486\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mreasoning_format\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mreasoning_format\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 487\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mresponse_format\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mresponse_format\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 488\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43msearch_settings\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43msearch_settings\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 489\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mseed\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mseed\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 490\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mservice_tier\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mservice_tier\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 491\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mstop\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 492\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mstore\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mstore\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 493\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 494\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mtemperature\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mtemperature\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 495\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mtool_choice\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mtool_choice\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 496\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mtools\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mtools\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 497\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mtop_logprobs\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mtop_logprobs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 498\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mtop_p\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mtop_p\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 499\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43muser\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43muser\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 500\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m}\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 501\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcompletion_create_params\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mCompletionCreateParams\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 502\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 503\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43moptions\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mmake_request_options\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 504\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mextra_headers\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mextra_headers\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mextra_query\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mextra_query\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mextra_body\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mextra_body\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mtimeout\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mtimeout\u001b[39;49m\n\u001b[32m 505\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 506\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcast_to\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mChatCompletion\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 507\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mor\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mFalse\u001b[39;49;00m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 508\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mstream_cls\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mStream\u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43mChatCompletionChunk\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 509\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
|
| 544 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\groq\\_base_client.py:1242\u001b[39m, in \u001b[36mSyncAPIClient.post\u001b[39m\u001b[34m(self, path, cast_to, body, options, files, stream, stream_cls)\u001b[39m\n\u001b[32m 1228\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mpost\u001b[39m(\n\u001b[32m 1229\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 1230\u001b[39m path: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 1237\u001b[39m stream_cls: \u001b[38;5;28mtype\u001b[39m[_StreamT] | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 1238\u001b[39m ) -> ResponseT | _StreamT:\n\u001b[32m 1239\u001b[39m opts = FinalRequestOptions.construct(\n\u001b[32m 1240\u001b[39m method=\u001b[33m\"\u001b[39m\u001b[33mpost\u001b[39m\u001b[33m\"\u001b[39m, url=path, json_data=body, files=to_httpx_files(files), **options\n\u001b[32m 1241\u001b[39m )\n\u001b[32m-> \u001b[39m\u001b[32m1242\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m cast(ResponseT, \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mcast_to\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mopts\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mstream\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mstream_cls\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mstream_cls\u001b[39;49m\u001b[30;43m)\u001b[39;49m)\n",
|
| 545 |
+
"\u001b[36mFile \u001b[39m\u001b[32mf:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\groq\\_base_client.py:998\u001b[39m, in \u001b[36mSyncAPIClient.request\u001b[39m\u001b[34m(self, cast_to, options, stream, stream_cls)\u001b[39m\n\u001b[32m 995\u001b[39m \u001b[38;5;28;01mcontinue\u001b[39;00m\n\u001b[32m 997\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mRaising timeout error\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m998\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m APITimeoutError(request=request) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01merr\u001b[39;00m\n\u001b[32m 999\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[32m 1000\u001b[39m log.debug(\u001b[33m\"\u001b[39m\u001b[33mEncountered Exception\u001b[39m\u001b[33m\"\u001b[39m, exc_info=\u001b[38;5;28;01mTrue\u001b[39;00m)\n",
|
| 546 |
+
"\u001b[31mAPITimeoutError\u001b[39m: Request timed out."
|
| 547 |
+
]
|
| 548 |
+
}
|
| 549 |
+
],
|
| 550 |
+
"source": [
|
| 551 |
+
"# ── Test ─────────────────────────────────────────────────────────────────────\n",
|
| 552 |
+
"query = full_chain.invoke({\"question\": \"What is the most popular genre by number of tracks?\"})\n",
|
| 553 |
+
"print(\"Clean SQL:\\n\", query)\n",
|
| 554 |
+
"\n",
|
| 555 |
+
"result = db.run(query)\n",
|
| 556 |
+
"print(\"Result:\\n\", result)"
|
| 557 |
+
]
|
| 558 |
+
},
|
| 559 |
+
{
|
| 560 |
+
"cell_type": "code",
|
| 561 |
+
"execution_count": 52,
|
| 562 |
+
"metadata": {},
|
| 563 |
+
"outputs": [
|
| 564 |
+
{
|
| 565 |
+
"data": {
|
| 566 |
+
"text/plain": [
|
| 567 |
+
"'[(18,)]'"
|
| 568 |
+
]
|
| 569 |
+
},
|
| 570 |
+
"execution_count": 52,
|
| 571 |
+
"metadata": {},
|
| 572 |
+
"output_type": "execute_result"
|
| 573 |
+
}
|
| 574 |
+
],
|
| 575 |
+
"source": [
|
| 576 |
+
"db.run(query)"
|
| 577 |
+
]
|
| 578 |
+
},
|
| 579 |
+
{
|
| 580 |
+
"cell_type": "markdown",
|
| 581 |
+
"metadata": {},
|
| 582 |
+
"source": [
|
| 583 |
+
"**Prepare the tool (Don't run the following cell)**"
|
| 584 |
+
]
|
| 585 |
+
},
|
| 586 |
+
{
|
| 587 |
+
"cell_type": "code",
|
| 588 |
+
"execution_count": null,
|
| 589 |
+
"metadata": {},
|
| 590 |
+
"outputs": [],
|
| 591 |
+
"source": [
|
| 592 |
+
"class ChinookSQLAgent:\n",
|
| 593 |
+
" \"\"\"\n",
|
| 594 |
+
" A specialized SQL agent that interacts with the Chinook SQL database using an LLM (Large Language Model).\n",
|
| 595 |
+
"\n",
|
| 596 |
+
" The agent handles SQL queries by mapping user questions to relevant SQL tables based on categories like \"Music\"\n",
|
| 597 |
+
" and \"Business\". It uses an extraction chain to determine relevant tables based on the question and then\n",
|
| 598 |
+
" executes queries against the database using the appropriate tables.\n",
|
| 599 |
+
"\n",
|
| 600 |
+
" Attributes:\n",
|
| 601 |
+
" sql_agent_llm (ChatOpenAI): The language model used for interpreting and interacting with the database.\n",
|
| 602 |
+
" db (SQLDatabase): The SQL database object, representing the Chinook database.\n",
|
| 603 |
+
" full_chain (Runnable): A chain of operations that maps user questions to SQL tables and executes queries.\n",
|
| 604 |
+
"\n",
|
| 605 |
+
" Methods:\n",
|
| 606 |
+
" __init__: Initializes the agent by setting up the LLM, connecting to the SQL database, and creating query chains.\n",
|
| 607 |
+
"\n",
|
| 608 |
+
" Args:\n",
|
| 609 |
+
" sqldb_directory (str): The directory where the Chinook SQLite database file is located.\n",
|
| 610 |
+
" llm (str): The name of the LLM model to use (e.g., \"gpt-3.5-turbo\").\n",
|
| 611 |
+
" llm_temperature (float): The temperature setting for the LLM, controlling the randomness of responses.\n",
|
| 612 |
+
" \"\"\"\n",
|
| 613 |
+
"\n",
|
| 614 |
+
" def __init__(self, sqldb_directory: str, llm: str, llm_temerature: float) -> None:\n",
|
| 615 |
+
" \"\"\"Initializes the ChinookSQLAgent with the LLM and database connection.\n",
|
| 616 |
+
"\n",
|
| 617 |
+
" Args:\n",
|
| 618 |
+
" sqldb_directory (str): The directory path to the SQLite database file.\n",
|
| 619 |
+
" llm (str): The LLM model identifier (e.g., \"gpt-3.5-turbo\").\n",
|
| 620 |
+
" llm_temerature (float): The temperature value for the LLM, determining the randomness of the model's output.\n",
|
| 621 |
+
" \"\"\"\n",
|
| 622 |
+
" self.sql_agent_llm = ChatGroq(\n",
|
| 623 |
+
" model=llm, temperature=llm_temerature)\n",
|
| 624 |
+
"\n",
|
| 625 |
+
" self.db = SQLDatabase.from_uri(f\"sqlite:///{sqldb_directory}\")\n",
|
| 626 |
+
" print(self.db.get_usable_table_names())\n",
|
| 627 |
+
" category_chain_system = \"\"\"Return the names of the SQL tables that are relevant to the user question. \\\n",
|
| 628 |
+
" The tables are:\n",
|
| 629 |
+
"\n",
|
| 630 |
+
" Music\n",
|
| 631 |
+
" Business\"\"\"\n",
|
| 632 |
+
" category_chain = create_extraction_chain_pydantic(\n",
|
| 633 |
+
" Table, self.sql_agent_llm, system_message=category_chain_system)\n",
|
| 634 |
+
" table_chain = category_chain | get_tables # noqa\n",
|
| 635 |
+
" query_chain = create_sql_query_chain(self.sql_agent_llm, self.db)\n",
|
| 636 |
+
" # Convert \"question\" key to the \"input\" key expected by current table_chain.\n",
|
| 637 |
+
" table_chain = {\"input\": itemgetter(\"question\")} | table_chain\n",
|
| 638 |
+
" # Set table_names_to_use using table_chain.\n",
|
| 639 |
+
" self.full_chain = RunnablePassthrough.assign(\n",
|
| 640 |
+
" table_names_to_use=table_chain) | query_chain\n",
|
| 641 |
+
"\n",
|
| 642 |
+
"\n",
|
| 643 |
+
"@tool\n",
|
| 644 |
+
"def query_chinook_sqldb(query: str) -> str:\n",
|
| 645 |
+
" \"\"\"Query the Chinook SQL Database. Input should be a search query.\"\"\"\n",
|
| 646 |
+
" # Create an instance of ChinookSQLAgent\n",
|
| 647 |
+
" agent = ChinookSQLAgent(\n",
|
| 648 |
+
" sqldb_directory=TOOLS_CFG.chinook_sqldb_directory,\n",
|
| 649 |
+
" llm=TOOLS_CFG.chinook_sqlagent_llm,\n",
|
| 650 |
+
" llm_temerature=TOOLS_CFG.chinook_sqlagent_llm_temperature\n",
|
| 651 |
+
" )\n",
|
| 652 |
+
"\n",
|
| 653 |
+
" query = agent.full_chain.invoke({\"question\": query})\n",
|
| 654 |
+
"\n",
|
| 655 |
+
" return agent.db.run(query)"
|
| 656 |
+
]
|
| 657 |
+
}
|
| 658 |
+
],
|
| 659 |
+
"metadata": {
|
| 660 |
+
"kernelspec": {
|
| 661 |
+
"display_name": "querymind (3.12.10)",
|
| 662 |
+
"language": "python",
|
| 663 |
+
"name": "python3"
|
| 664 |
+
},
|
| 665 |
+
"language_info": {
|
| 666 |
+
"codemirror_mode": {
|
| 667 |
+
"name": "ipython",
|
| 668 |
+
"version": 3
|
| 669 |
+
},
|
| 670 |
+
"file_extension": ".py",
|
| 671 |
+
"mimetype": "text/x-python",
|
| 672 |
+
"name": "python",
|
| 673 |
+
"nbconvert_exporter": "python",
|
| 674 |
+
"pygments_lexer": "ipython3",
|
| 675 |
+
"version": "3.12.10"
|
| 676 |
+
}
|
| 677 |
+
},
|
| 678 |
+
"nbformat": 4,
|
| 679 |
+
"nbformat_minor": 2
|
| 680 |
+
}
|
Notebooks/Tools/sql_agents/sql_agent_chain_steps.ipynb
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [
|
| 8 |
+
{
|
| 9 |
+
"data": {
|
| 10 |
+
"text/plain": [
|
| 11 |
+
"True"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
"execution_count": 1,
|
| 15 |
+
"metadata": {},
|
| 16 |
+
"output_type": "execute_result"
|
| 17 |
+
}
|
| 18 |
+
],
|
| 19 |
+
"source": [
|
| 20 |
+
"from pyprojroot import here\n",
|
| 21 |
+
"from langchain_community.utilities import SQLDatabase\n",
|
| 22 |
+
"from langchain.chains import create_sql_query_chain\n",
|
| 23 |
+
"from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool\n",
|
| 24 |
+
"from langchain_core.prompts import PromptTemplate\n",
|
| 25 |
+
"from langchain_core.output_parsers import StrOutputParser\n",
|
| 26 |
+
"from langchain_core.runnables import RunnablePassthrough\n",
|
| 27 |
+
"from operator import itemgetter\n",
|
| 28 |
+
"from langchain_groq import ChatGroq\n",
|
| 29 |
+
"import os\n",
|
| 30 |
+
"from dotenv import load_dotenv\n",
|
| 31 |
+
"load_dotenv()"
|
| 32 |
+
]
|
| 33 |
+
},
|
| 34 |
+
{
|
| 35 |
+
"cell_type": "markdown",
|
| 36 |
+
"metadata": {},
|
| 37 |
+
"source": [
|
| 38 |
+
"**Set the environment variables and load the LLM**"
|
| 39 |
+
]
|
| 40 |
+
},
|
| 41 |
+
{
|
| 42 |
+
"cell_type": "code",
|
| 43 |
+
"execution_count": 2,
|
| 44 |
+
"metadata": {},
|
| 45 |
+
"outputs": [],
|
| 46 |
+
"source": [
|
| 47 |
+
"os.environ['GROQ_API_KEY'] = os.getenv(\"GROQ_API_KEY\")\n",
|
| 48 |
+
"\n",
|
| 49 |
+
"llm = ChatGroq(model=\"openai/gpt-oss-120b\")\n",
|
| 50 |
+
"# llm = ChatGroq(model=\"llama3-8b-8192\")\n",
|
| 51 |
+
"# llm = ChatGroq(model=\"mixtral-8x7b-32768\")"
|
| 52 |
+
]
|
| 53 |
+
},
|
| 54 |
+
{
|
| 55 |
+
"cell_type": "markdown",
|
| 56 |
+
"metadata": {},
|
| 57 |
+
"source": [
|
| 58 |
+
"**Load and test the sqlite db**"
|
| 59 |
+
]
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"cell_type": "code",
|
| 63 |
+
"execution_count": 3,
|
| 64 |
+
"metadata": {},
|
| 65 |
+
"outputs": [
|
| 66 |
+
{
|
| 67 |
+
"name": "stdout",
|
| 68 |
+
"output_type": "stream",
|
| 69 |
+
"text": [
|
| 70 |
+
"sqlite\n",
|
| 71 |
+
"['Album', 'Artist', 'Customer', 'Employee', 'Genre', 'Invoice', 'InvoiceLine', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track']\n"
|
| 72 |
+
]
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"data": {
|
| 76 |
+
"text/plain": [
|
| 77 |
+
"\"[('Album',), ('Artist',), ('Customer',), ('Employee',), ('Genre',), ('Invoice',), ('InvoiceLine',), ('MediaType',), ('Playlist',), ('PlaylistTrack',), ('Track',)]\""
|
| 78 |
+
]
|
| 79 |
+
},
|
| 80 |
+
"execution_count": 3,
|
| 81 |
+
"metadata": {},
|
| 82 |
+
"output_type": "execute_result"
|
| 83 |
+
}
|
| 84 |
+
],
|
| 85 |
+
"source": [
|
| 86 |
+
"sqldb_directory = here(\"data/Chinook.db\")\n",
|
| 87 |
+
"db = SQLDatabase.from_uri(\n",
|
| 88 |
+
" f\"sqlite:///{sqldb_directory}\")\n",
|
| 89 |
+
"\n",
|
| 90 |
+
"print(db.dialect)\n",
|
| 91 |
+
"print(db.get_usable_table_names())\n",
|
| 92 |
+
"db.run(\"\"\" SELECT name\n",
|
| 93 |
+
"FROM sqlite_master\n",
|
| 94 |
+
"WHERE type='table'\n",
|
| 95 |
+
"AND name NOT LIKE 'sqlite_%'; \"\"\")\n",
|
| 96 |
+
"\n",
|
| 97 |
+
"# from sqlalchemy import create_engine, inspect\n",
|
| 98 |
+
"# from sqlalchemy.orm import sessionmaker\n",
|
| 99 |
+
"# engine = create_engine(db_path)\n",
|
| 100 |
+
"\n",
|
| 101 |
+
"# # Create a session\n",
|
| 102 |
+
"# Session = sessionmaker(bind=engine)\n",
|
| 103 |
+
"# session = Session()\n",
|
| 104 |
+
"\n",
|
| 105 |
+
"# # Use SQLAlchemy's Inspector to get database information\n",
|
| 106 |
+
"# inspector = inspect(engine)\n",
|
| 107 |
+
"\n",
|
| 108 |
+
"# # Get table names\n",
|
| 109 |
+
"# tables = inspector.get_table_names()\n",
|
| 110 |
+
"# print(\"Tables in the database:\", tables)\n",
|
| 111 |
+
"# print(len(tables))"
|
| 112 |
+
]
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"cell_type": "markdown",
|
| 116 |
+
"metadata": {},
|
| 117 |
+
"source": [
|
| 118 |
+
"**Create the SQL agent chain and run a test query**"
|
| 119 |
+
]
|
| 120 |
+
},
|
| 121 |
+
{
|
| 122 |
+
"cell_type": "code",
|
| 123 |
+
"execution_count": 4,
|
| 124 |
+
"metadata": {},
|
| 125 |
+
"outputs": [],
|
| 126 |
+
"source": [
|
| 127 |
+
"system_role = \"\"\"Given the following user question, corresponding SQL query, and SQL result, answer the user question.\\n\n",
|
| 128 |
+
" Question: {question}\\n\n",
|
| 129 |
+
" SQL Query: {query}\\n\n",
|
| 130 |
+
" SQL Result: {result}\\n\n",
|
| 131 |
+
" Answer:\n",
|
| 132 |
+
" \"\"\"\n",
|
| 133 |
+
"\n",
|
| 134 |
+
"execute_query = QuerySQLDataBaseTool(db=db)\n",
|
| 135 |
+
"write_query = create_sql_query_chain(\n",
|
| 136 |
+
" llm, db)\n",
|
| 137 |
+
"answer_prompt = PromptTemplate.from_template(\n",
|
| 138 |
+
" system_role)\n",
|
| 139 |
+
"answer = answer_prompt | llm | StrOutputParser()\n",
|
| 140 |
+
"chain = (\n",
|
| 141 |
+
" RunnablePassthrough.assign(query=write_query).assign(\n",
|
| 142 |
+
" result=itemgetter(\"query\") | execute_query\n",
|
| 143 |
+
" )\n",
|
| 144 |
+
" | answer\n",
|
| 145 |
+
")"
|
| 146 |
+
]
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
"cell_type": "code",
|
| 150 |
+
"execution_count": 5,
|
| 151 |
+
"metadata": {},
|
| 152 |
+
"outputs": [
|
| 153 |
+
{
|
| 154 |
+
"data": {
|
| 155 |
+
"text/plain": [
|
| 156 |
+
"'I’m sorry, but there’s no SQL result provided, so I can’t determine how many tables are in your database or what their names are. If you can share the query output (e.g., a list of table names), I’ll be happy to give you the answer.'"
|
| 157 |
+
]
|
| 158 |
+
},
|
| 159 |
+
"execution_count": 5,
|
| 160 |
+
"metadata": {},
|
| 161 |
+
"output_type": "execute_result"
|
| 162 |
+
}
|
| 163 |
+
],
|
| 164 |
+
"source": [
|
| 165 |
+
"message = \"How many tables do I have in the database? and what are their names?\"\n",
|
| 166 |
+
"response = chain.invoke({\"question\": message})\n",
|
| 167 |
+
"response"
|
| 168 |
+
]
|
| 169 |
+
},
|
| 170 |
+
{
|
| 171 |
+
"cell_type": "markdown",
|
| 172 |
+
"metadata": {},
|
| 173 |
+
"source": [
|
| 174 |
+
"**Travel SQL-agent Tool Design**"
|
| 175 |
+
]
|
| 176 |
+
},
|
| 177 |
+
{
|
| 178 |
+
"cell_type": "code",
|
| 179 |
+
"execution_count": 6,
|
| 180 |
+
"metadata": {},
|
| 181 |
+
"outputs": [],
|
| 182 |
+
"source": [
|
| 183 |
+
"from langchain_core.tools import tool\n",
|
| 184 |
+
"from langchain_community.utilities import SQLDatabase\n",
|
| 185 |
+
"from langchain.chains import create_sql_query_chain\n",
|
| 186 |
+
"from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool\n",
|
| 187 |
+
"from langchain_core.prompts import PromptTemplate\n",
|
| 188 |
+
"from langchain_core.output_parsers import StrOutputParser\n",
|
| 189 |
+
"from langchain_core.runnables import RunnablePassthrough\n",
|
| 190 |
+
"from operator import itemgetter\n",
|
| 191 |
+
"from langchain_openai import ChatOpenAI\n",
|
| 192 |
+
"\n",
|
| 193 |
+
"\n",
|
| 194 |
+
"class TravelSQLAgentTool:\n",
|
| 195 |
+
" \"\"\"\n",
|
| 196 |
+
" A tool for interacting with a travel-related SQL database using an LLM (Language Model) to generate and execute SQL queries.\n",
|
| 197 |
+
"\n",
|
| 198 |
+
" This tool enables users to ask travel-related questions, which are transformed into SQL queries by a language model.\n",
|
| 199 |
+
" The SQL queries are executed on the provided SQLite database, and the results are processed by the language model to\n",
|
| 200 |
+
" generate a final answer for the user.\n",
|
| 201 |
+
"\n",
|
| 202 |
+
" Attributes:\n",
|
| 203 |
+
" sql_agent_llm (ChatOpenAI): An instance of a ChatOpenAI language model used to generate and process SQL queries.\n",
|
| 204 |
+
" system_role (str): A system prompt template that guides the language model in answering user questions based on SQL query results.\n",
|
| 205 |
+
" db (SQLDatabase): An instance of the SQL database used to execute queries.\n",
|
| 206 |
+
" chain (RunnablePassthrough): A chain of operations that creates SQL queries, executes them, and generates a response.\n",
|
| 207 |
+
"\n",
|
| 208 |
+
" Methods:\n",
|
| 209 |
+
" __init__: Initializes the TravelSQLAgentTool by setting up the language model, SQL database, and query-answering pipeline.\n",
|
| 210 |
+
" \"\"\"\n",
|
| 211 |
+
"\n",
|
| 212 |
+
" def __init__(self, llm: str, sqldb_directory: str, llm_temerature: float) -> None:\n",
|
| 213 |
+
" \"\"\"\n",
|
| 214 |
+
" Initializes the TravelSQLAgentTool with the necessary configurations.\n",
|
| 215 |
+
"\n",
|
| 216 |
+
" Args:\n",
|
| 217 |
+
" llm (str): The name of the language model to be used for generating and interpreting SQL queries.\n",
|
| 218 |
+
" sqldb_directory (str): The directory path where the SQLite database is stored.\n",
|
| 219 |
+
" llm_temerature (float): The temperature setting for the language model, controlling response randomness.\n",
|
| 220 |
+
" \"\"\"\n",
|
| 221 |
+
" self.sql_agent_llm = ChatGroq(\n",
|
| 222 |
+
" model=llm, temperature=llm_temerature)\n",
|
| 223 |
+
" self.system_role = \"\"\"Given the following user question, corresponding SQL query, and SQL result, answer the user question.\\n\n",
|
| 224 |
+
" Question: {question}\\n\n",
|
| 225 |
+
" SQL Query: {query}\\n\n",
|
| 226 |
+
" SQL Result: {result}\\n\n",
|
| 227 |
+
" Answer:\n",
|
| 228 |
+
" \"\"\"\n",
|
| 229 |
+
" self.db = SQLDatabase.from_uri(\n",
|
| 230 |
+
" f\"sqlite:///{sqldb_directory}\")\n",
|
| 231 |
+
" print(self.db.get_usable_table_names())\n",
|
| 232 |
+
"\n",
|
| 233 |
+
" execute_query = QuerySQLDataBaseTool(db=self.db)\n",
|
| 234 |
+
" write_query = create_sql_query_chain(\n",
|
| 235 |
+
" self.sql_agent_llm, self.db)\n",
|
| 236 |
+
" answer_prompt = PromptTemplate.from_template(\n",
|
| 237 |
+
" self.system_role)\n",
|
| 238 |
+
"\n",
|
| 239 |
+
" answer = answer_prompt | self.sql_agent_llm | StrOutputParser()\n",
|
| 240 |
+
" self.chain = (\n",
|
| 241 |
+
" RunnablePassthrough.assign(query=write_query).assign(\n",
|
| 242 |
+
" result=itemgetter(\"query\") | execute_query\n",
|
| 243 |
+
" )\n",
|
| 244 |
+
" | answer\n",
|
| 245 |
+
" )"
|
| 246 |
+
]
|
| 247 |
+
},
|
| 248 |
+
{
|
| 249 |
+
"cell_type": "code",
|
| 250 |
+
"execution_count": 7,
|
| 251 |
+
"metadata": {},
|
| 252 |
+
"outputs": [
|
| 253 |
+
{
|
| 254 |
+
"name": "stderr",
|
| 255 |
+
"output_type": "stream",
|
| 256 |
+
"text": [
|
| 257 |
+
"<>:3: SyntaxWarning: invalid escape sequence '\\e'\n",
|
| 258 |
+
"<>:3: SyntaxWarning: invalid escape sequence '\\e'\n",
|
| 259 |
+
"C:\\Users\\AL-MASA\\AppData\\Local\\Temp\\ipykernel_13496\\1650904972.py:3: SyntaxWarning: invalid escape sequence '\\e'\n",
|
| 260 |
+
" sys.path.insert(0, os.path.abspath('F:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases')) # or the full path to your project root\n"
|
| 261 |
+
]
|
| 262 |
+
}
|
| 263 |
+
],
|
| 264 |
+
"source": [
|
| 265 |
+
"import sys\n",
|
| 266 |
+
"import os\n",
|
| 267 |
+
"sys.path.insert(0, os.path.abspath('F:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases')) # or the full path to your project root\n",
|
| 268 |
+
"\n",
|
| 269 |
+
"from src.agent_graph.load_tools_config import LoadToolsConfig"
|
| 270 |
+
]
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"cell_type": "code",
|
| 274 |
+
"execution_count": 8,
|
| 275 |
+
"metadata": {},
|
| 276 |
+
"outputs": [],
|
| 277 |
+
"source": [
|
| 278 |
+
"from src.agent_graph.load_tools_config import LoadToolsConfig\n",
|
| 279 |
+
"\n",
|
| 280 |
+
"TOOLS_CFG = LoadToolsConfig()\n",
|
| 281 |
+
"\n",
|
| 282 |
+
"@tool\n",
|
| 283 |
+
"def query_travel_sqldb(query: str) -> str:\n",
|
| 284 |
+
" \"\"\"Query the Swiss Airline SQL Database and access all the company's information. Input should be a search query.\"\"\"\n",
|
| 285 |
+
" agent = TravelSQLAgentTool(\n",
|
| 286 |
+
" llm=TOOLS_CFG.travel_sqlagent_llm,\n",
|
| 287 |
+
" sqldb_directory=TOOLS_CFG.travel_sqldb_directory,\n",
|
| 288 |
+
" llm_temperature=TOOLS_CFG.travel_sqlagent_llm_temperature\n",
|
| 289 |
+
" )\n",
|
| 290 |
+
" response = agent.chain.invoke({\"question\": query})\n",
|
| 291 |
+
" return response"
|
| 292 |
+
]
|
| 293 |
+
},
|
| 294 |
+
{
|
| 295 |
+
"cell_type": "code",
|
| 296 |
+
"execution_count": null,
|
| 297 |
+
"metadata": {},
|
| 298 |
+
"outputs": [],
|
| 299 |
+
"source": []
|
| 300 |
+
}
|
| 301 |
+
],
|
| 302 |
+
"metadata": {
|
| 303 |
+
"kernelspec": {
|
| 304 |
+
"display_name": "querymind (3.12.10)",
|
| 305 |
+
"language": "python",
|
| 306 |
+
"name": "python3"
|
| 307 |
+
},
|
| 308 |
+
"language_info": {
|
| 309 |
+
"codemirror_mode": {
|
| 310 |
+
"name": "ipython",
|
| 311 |
+
"version": 3
|
| 312 |
+
},
|
| 313 |
+
"file_extension": ".py",
|
| 314 |
+
"mimetype": "text/x-python",
|
| 315 |
+
"name": "python",
|
| 316 |
+
"nbconvert_exporter": "python",
|
| 317 |
+
"pygments_lexer": "ipython3",
|
| 318 |
+
"version": "3.12.10"
|
| 319 |
+
}
|
| 320 |
+
},
|
| 321 |
+
"nbformat": 4,
|
| 322 |
+
"nbformat_minor": 2
|
| 323 |
+
}
|
Notebooks/Tools/sql_agents/sql_agent_steps.ipynb
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 2,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [
|
| 8 |
+
{
|
| 9 |
+
"data": {
|
| 10 |
+
"text/plain": [
|
| 11 |
+
"True"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
"execution_count": 2,
|
| 15 |
+
"metadata": {},
|
| 16 |
+
"output_type": "execute_result"
|
| 17 |
+
}
|
| 18 |
+
],
|
| 19 |
+
"source": [
|
| 20 |
+
"import os\n",
|
| 21 |
+
"from dotenv import load_dotenv\n",
|
| 22 |
+
"from pyprojroot import here\n",
|
| 23 |
+
"from langchain.chains import create_sql_query_chain\n",
|
| 24 |
+
"from langchain_community.agent_toolkits import create_sql_agent\n",
|
| 25 |
+
"from langchain_openai import ChatOpenAI\n",
|
| 26 |
+
"from langchain_community.agent_toolkits.sql.toolkit import SQLDatabaseToolkit\n",
|
| 27 |
+
"from langchain_community.utilities import SQLDatabase\n",
|
| 28 |
+
"\n",
|
| 29 |
+
"load_dotenv()"
|
| 30 |
+
]
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"cell_type": "markdown",
|
| 34 |
+
"metadata": {},
|
| 35 |
+
"source": [
|
| 36 |
+
"**Set the environment variable and load the LLM**"
|
| 37 |
+
]
|
| 38 |
+
},
|
| 39 |
+
{
|
| 40 |
+
"cell_type": "code",
|
| 41 |
+
"execution_count": 3,
|
| 42 |
+
"metadata": {},
|
| 43 |
+
"outputs": [],
|
| 44 |
+
"source": [
|
| 45 |
+
"os.environ['OPENAI_API_KEY'] = os.getenv(\"OPEN_AI_API_KEY\")\n",
|
| 46 |
+
"\n",
|
| 47 |
+
"\n",
|
| 48 |
+
"llm = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0)\n",
|
| 49 |
+
"# llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0)\n",
|
| 50 |
+
"# llm = ChatOpenAI(model=\"gpt-4o\")"
|
| 51 |
+
]
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"cell_type": "markdown",
|
| 55 |
+
"metadata": {},
|
| 56 |
+
"source": [
|
| 57 |
+
"**Load and test the sqlite db**"
|
| 58 |
+
]
|
| 59 |
+
},
|
| 60 |
+
{
|
| 61 |
+
"cell_type": "code",
|
| 62 |
+
"execution_count": 5,
|
| 63 |
+
"metadata": {},
|
| 64 |
+
"outputs": [
|
| 65 |
+
{
|
| 66 |
+
"name": "stdout",
|
| 67 |
+
"output_type": "stream",
|
| 68 |
+
"text": [
|
| 69 |
+
"sqlite\n",
|
| 70 |
+
"['aircrafts_data', 'airports_data', 'boarding_passes', 'bookings', 'car_rentals', 'flights', 'hotels', 'seats', 'ticket_flights', 'tickets', 'trip_recommendations']\n"
|
| 71 |
+
]
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"data": {
|
| 75 |
+
"text/plain": [
|
| 76 |
+
"\"[('773', 'Boeing 777-300', 11100), ('763', 'Boeing 767-300', 7900), ('SU9', 'Sukhoi Superjet-100', 3000), ('320', 'Airbus A320-200', 5700), ('321', 'Airbus A321-200', 5600), ('319', 'Airbus A319-100', 6700), ('733', 'Boeing 737-300', 4200), ('CN1', 'Cessna 208 Caravan', 1200), ('CR2', 'Bombardier CRJ-200', 2700)]\""
|
| 77 |
+
]
|
| 78 |
+
},
|
| 79 |
+
"execution_count": 5,
|
| 80 |
+
"metadata": {},
|
| 81 |
+
"output_type": "execute_result"
|
| 82 |
+
}
|
| 83 |
+
],
|
| 84 |
+
"source": [
|
| 85 |
+
"sqldb_directory = here(\"data/travel.sqlite\")\n",
|
| 86 |
+
"db = SQLDatabase.from_uri(f\"sqlite:///{sqldb_directory}\")\n",
|
| 87 |
+
"print(db.dialect)\n",
|
| 88 |
+
"print(db.get_usable_table_names())\n",
|
| 89 |
+
"db.run(\"SELECT * FROM aircrafts_data LIMIT 10;\")"
|
| 90 |
+
]
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"cell_type": "markdown",
|
| 94 |
+
"metadata": {},
|
| 95 |
+
"source": [
|
| 96 |
+
"**Create the SQL agent and run a test query**"
|
| 97 |
+
]
|
| 98 |
+
},
|
| 99 |
+
{
|
| 100 |
+
"cell_type": "code",
|
| 101 |
+
"execution_count": 6,
|
| 102 |
+
"metadata": {},
|
| 103 |
+
"outputs": [
|
| 104 |
+
{
|
| 105 |
+
"data": {
|
| 106 |
+
"text/plain": [
|
| 107 |
+
"'SELECT COUNT(*) AS total_rows FROM aircrafts_data;'"
|
| 108 |
+
]
|
| 109 |
+
},
|
| 110 |
+
"execution_count": 6,
|
| 111 |
+
"metadata": {},
|
| 112 |
+
"output_type": "execute_result"
|
| 113 |
+
}
|
| 114 |
+
],
|
| 115 |
+
"source": [
|
| 116 |
+
"chain = create_sql_query_chain(llm, db)\n",
|
| 117 |
+
"response = chain.invoke({\"question\": \"How many rows are there in the aircrafts_data table?\"})\n",
|
| 118 |
+
"response"
|
| 119 |
+
]
|
| 120 |
+
},
|
| 121 |
+
{
|
| 122 |
+
"cell_type": "code",
|
| 123 |
+
"execution_count": 7,
|
| 124 |
+
"metadata": {},
|
| 125 |
+
"outputs": [
|
| 126 |
+
{
|
| 127 |
+
"data": {
|
| 128 |
+
"text/plain": [
|
| 129 |
+
"'[(9,)]'"
|
| 130 |
+
]
|
| 131 |
+
},
|
| 132 |
+
"execution_count": 7,
|
| 133 |
+
"metadata": {},
|
| 134 |
+
"output_type": "execute_result"
|
| 135 |
+
}
|
| 136 |
+
],
|
| 137 |
+
"source": [
|
| 138 |
+
"db.run(response)"
|
| 139 |
+
]
|
| 140 |
+
}
|
| 141 |
+
],
|
| 142 |
+
"metadata": {
|
| 143 |
+
"kernelspec": {
|
| 144 |
+
"display_name": "rag-sqlagent",
|
| 145 |
+
"language": "python",
|
| 146 |
+
"name": "python3"
|
| 147 |
+
},
|
| 148 |
+
"language_info": {
|
| 149 |
+
"codemirror_mode": {
|
| 150 |
+
"name": "ipython",
|
| 151 |
+
"version": 3
|
| 152 |
+
},
|
| 153 |
+
"file_extension": ".py",
|
| 154 |
+
"mimetype": "text/x-python",
|
| 155 |
+
"name": "python",
|
| 156 |
+
"nbconvert_exporter": "python",
|
| 157 |
+
"pygments_lexer": "ipython3",
|
| 158 |
+
"version": "3.11.9"
|
| 159 |
+
}
|
| 160 |
+
},
|
| 161 |
+
"nbformat": 4,
|
| 162 |
+
"nbformat_minor": 2
|
| 163 |
+
}
|
Notebooks/Tools/tavily/tavily_search.ipynb
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [
|
| 8 |
+
{
|
| 9 |
+
"data": {
|
| 10 |
+
"text/plain": [
|
| 11 |
+
"True"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
"execution_count": 1,
|
| 15 |
+
"metadata": {},
|
| 16 |
+
"output_type": "execute_result"
|
| 17 |
+
}
|
| 18 |
+
],
|
| 19 |
+
"source": [
|
| 20 |
+
"import os\n",
|
| 21 |
+
"from dotenv import load_dotenv\n",
|
| 22 |
+
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
|
| 23 |
+
"\n",
|
| 24 |
+
"load_dotenv()"
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"cell_type": "code",
|
| 29 |
+
"execution_count": 2,
|
| 30 |
+
"metadata": {},
|
| 31 |
+
"outputs": [],
|
| 32 |
+
"source": [
|
| 33 |
+
"os.environ['TAVILY_API_KEY'] = os.getenv(\"TAVILY_API_KEY\")"
|
| 34 |
+
]
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"cell_type": "code",
|
| 38 |
+
"execution_count": 3,
|
| 39 |
+
"metadata": {},
|
| 40 |
+
"outputs": [],
|
| 41 |
+
"source": [
|
| 42 |
+
"search_tool = TavilySearchResults(max_results=2)"
|
| 43 |
+
]
|
| 44 |
+
},
|
| 45 |
+
{
|
| 46 |
+
"cell_type": "code",
|
| 47 |
+
"execution_count": 4,
|
| 48 |
+
"metadata": {},
|
| 49 |
+
"outputs": [
|
| 50 |
+
{
|
| 51 |
+
"data": {
|
| 52 |
+
"text/plain": [
|
| 53 |
+
"'A search engine optimized for comprehensive, accurate, and trusted results. Useful for when you need to answer questions about current events. Input should be a search query.'"
|
| 54 |
+
]
|
| 55 |
+
},
|
| 56 |
+
"execution_count": 4,
|
| 57 |
+
"metadata": {},
|
| 58 |
+
"output_type": "execute_result"
|
| 59 |
+
}
|
| 60 |
+
],
|
| 61 |
+
"source": [
|
| 62 |
+
"search_tool.description"
|
| 63 |
+
]
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"cell_type": "code",
|
| 67 |
+
"execution_count": 5,
|
| 68 |
+
"metadata": {},
|
| 69 |
+
"outputs": [
|
| 70 |
+
{
|
| 71 |
+
"data": {
|
| 72 |
+
"text/plain": [
|
| 73 |
+
"[{'url': 'https://www.ibm.com/think/topics/langgraph',\n",
|
| 74 |
+
" 'content': 'Nodes: In LangGraph, nodes represent individual components or agents within an AI workflow. Nodes can be thought of as “actors” that interact with each other in a specific way. For example,to add nodes for tool calling, one can use the ToolNode. Another example, the next node, refers to the node that will be executed following the current one.\\n\\nEdges: Edges are a function within Python that determines which node to execute next based on the current state. Edges can be conditional branches or fixed transitions.\\n\\n#### Tools\\n\\nRAG: Retrieval-augmented generation (RAG) combines the power of LLMs with contextual information from external sources by retrieving relevant documents, which are then used as input for answer generation. [...] Workflows: Workflows are the sequences of node interactions that define an AI workflow. By arranging nodes into a workflow, users can create more complex and dynamic workflows that use the strengths of individual components.\\n\\nAPIs: LangGraph provides a set of APIs that enable users to interact with its components in a programmatic way. Users can use an API key, add new nodes, modify existing workflows and retrieve data from an AI workflow.\\n\\nLangSmith: LangSmith is a specialized API for building and managing LLMs within LangGraph. It provides tools for initializing LLMs, adding conditional edges and optimizing performance. By combining these components in innovative ways, users can build more sophisticated AI workflows that use the strengths of individual components. [...] #### Graph architecture\\n\\nStateful graphs: A concept where each node in the graph represents a step in the computation, essentially devising a state graph. This stateful approach allows the graph to retain information about the previous steps, enabling continuous and contextual processing of information as the computation unfolds. Users can manage all LangGraph’s stateful graphs with its APIs.\\n\\nCyclical graph: A cyclical graph is any graph that contains at least one cycle and is essential for agent runtimes. This means that there exists a path that starts and ends at the same node, forming a loop within the graph. Complex workflows often involve cyclic dependencies, where the outcome of one step depends on previous steps in the loop.'},\n",
|
| 75 |
+
" {'url': 'https://dev.to/raunaklallala/understanding-core-concepts-of-langgraph-deep-dive-1d7h',\n",
|
| 76 |
+
" 'content': '### 1. Nodes: The Execution Units\\n\\nA Node is basically “a single action.” Imagine breaking your workday into steps: checking email, making coffee, writing code, or scheduling a meeting. Each of those is a Node.\\n\\nIn LangGraph, a Node can be many things:\\n\\nEach Node is like a worker with a simple contract: it takes an input, does its piece of the job, and pushes out an output.\\n\\nEveryday example: \\n \\nThink about ordering food on a delivery app.\\n\\nAnalogy: Nodes are like “stations” on a metro map. The passenger (your data) steps off at every station, something happens to them, and then they move along.\\n\\n### 2.Edges: The Flow of Control\\n\\nNodes mean nothing without connections. That’s where Edges come in—they define how data flows between steps. [...] DEV Community\\n\\n## DEV Community\\n\\nCover image for Understanding Core Concepts of LangGraph (Deep Dive)\\nRaunak ALI\\n\\nPosted on Sep 16, 2025\\n\\n# Understanding Core Concepts of LangGraph (Deep Dive)\\n\\n## Single Agent Workflow — From LLMs to LangGraph (2 Part Series)\\n\\n# Understanding Core Concepts of LangGraph (Deep Dive)\\n\\nIn the last chapter, we talked about why LangGraph feels like a shift compared to traditional “linear chains.” Now, let’s slow down and zoom into its DNA. At the core, LangGraph has three simple but powerful building blocks: Nodes, Edges, and State.\\n\\nIf those names sound abstract, don’t worry, by the end of this chapter, you’ll see them the same way you see apps on your phone or stops on a subway map. They’re pieces you already know, just arranged in a smarter way.'}]"
|
| 77 |
+
]
|
| 78 |
+
},
|
| 79 |
+
"execution_count": 5,
|
| 80 |
+
"metadata": {},
|
| 81 |
+
"output_type": "execute_result"
|
| 82 |
+
}
|
| 83 |
+
],
|
| 84 |
+
"source": [
|
| 85 |
+
"search_tool.invoke(\"What's a 'node' in LangGraph?\")"
|
| 86 |
+
]
|
| 87 |
+
},
|
| 88 |
+
{
|
| 89 |
+
"cell_type": "code",
|
| 90 |
+
"execution_count": null,
|
| 91 |
+
"metadata": {},
|
| 92 |
+
"outputs": [],
|
| 93 |
+
"source": []
|
| 94 |
+
}
|
| 95 |
+
],
|
| 96 |
+
"metadata": {
|
| 97 |
+
"kernelspec": {
|
| 98 |
+
"display_name": "querymind (3.12.10)",
|
| 99 |
+
"language": "python",
|
| 100 |
+
"name": "python3"
|
| 101 |
+
},
|
| 102 |
+
"language_info": {
|
| 103 |
+
"codemirror_mode": {
|
| 104 |
+
"name": "ipython",
|
| 105 |
+
"version": 3
|
| 106 |
+
},
|
| 107 |
+
"file_extension": ".py",
|
| 108 |
+
"mimetype": "text/x-python",
|
| 109 |
+
"name": "python",
|
| 110 |
+
"nbconvert_exporter": "python",
|
| 111 |
+
"pygments_lexer": "ipython3",
|
| 112 |
+
"version": "3.12.10"
|
| 113 |
+
}
|
| 114 |
+
},
|
| 115 |
+
"nbformat": 4,
|
| 116 |
+
"nbformat_minor": 2
|
| 117 |
+
}
|
Notebooks/custom_agent/groq_function_calling.ipynb
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 2,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [
|
| 8 |
+
{
|
| 9 |
+
"name": "stdout",
|
| 10 |
+
"output_type": "stream",
|
| 11 |
+
"text": [
|
| 12 |
+
"True\n"
|
| 13 |
+
]
|
| 14 |
+
}
|
| 15 |
+
],
|
| 16 |
+
"source": [
|
| 17 |
+
"import os\n",
|
| 18 |
+
"from dotenv import load_dotenv\n",
|
| 19 |
+
"from groq import Groq\n",
|
| 20 |
+
"from pydantic import create_model\n",
|
| 21 |
+
"import inspect, json\n",
|
| 22 |
+
"from inspect import Parameter\n",
|
| 23 |
+
"\n",
|
| 24 |
+
"print(load_dotenv())\n",
|
| 25 |
+
"\n",
|
| 26 |
+
"os.environ['GROQ_API_KEY'] = os.getenv(\"GROQ_API_KEY\")"
|
| 27 |
+
]
|
| 28 |
+
},
|
| 29 |
+
{
|
| 30 |
+
"cell_type": "markdown",
|
| 31 |
+
"metadata": {},
|
| 32 |
+
"source": [
|
| 33 |
+
"## **Custom agent**"
|
| 34 |
+
]
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"cell_type": "markdown",
|
| 38 |
+
"metadata": {},
|
| 39 |
+
"source": [
|
| 40 |
+
"**Define the functions**"
|
| 41 |
+
]
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"cell_type": "code",
|
| 45 |
+
"execution_count": 3,
|
| 46 |
+
"metadata": {},
|
| 47 |
+
"outputs": [],
|
| 48 |
+
"source": [
|
| 49 |
+
"def abc(num1:int, num2:int)->int:\n",
|
| 50 |
+
" \"Compute abc between two numbers\"\n",
|
| 51 |
+
" return 2*(num1) - 2*(num2)"
|
| 52 |
+
]
|
| 53 |
+
},
|
| 54 |
+
{
|
| 55 |
+
"cell_type": "code",
|
| 56 |
+
"execution_count": 4,
|
| 57 |
+
"metadata": {},
|
| 58 |
+
"outputs": [
|
| 59 |
+
{
|
| 60 |
+
"data": {
|
| 61 |
+
"text/plain": [
|
| 62 |
+
"-2"
|
| 63 |
+
]
|
| 64 |
+
},
|
| 65 |
+
"execution_count": 4,
|
| 66 |
+
"metadata": {},
|
| 67 |
+
"output_type": "execute_result"
|
| 68 |
+
}
|
| 69 |
+
],
|
| 70 |
+
"source": [
|
| 71 |
+
"abc(2, 3)"
|
| 72 |
+
]
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"cell_type": "code",
|
| 76 |
+
"execution_count": 5,
|
| 77 |
+
"metadata": {},
|
| 78 |
+
"outputs": [],
|
| 79 |
+
"source": [
|
| 80 |
+
"def jsonschema(f):\n",
|
| 81 |
+
" \"\"\"\n",
|
| 82 |
+
" Generate a JSON schema for the input parameters of the given function.\n",
|
| 83 |
+
"\n",
|
| 84 |
+
" Parameters:\n",
|
| 85 |
+
" f (FunctionType): The function for which to generate the JSON schema.\n",
|
| 86 |
+
"\n",
|
| 87 |
+
" Returns:\n",
|
| 88 |
+
" Dict: A dictionary containing the function name, description, and parameters schema.\n",
|
| 89 |
+
" \"\"\"\n",
|
| 90 |
+
" kw = {n: (o.annotation, ... if o.default == Parameter.empty else o.default)\n",
|
| 91 |
+
" for n, o in inspect.signature(f).parameters.items()}\n",
|
| 92 |
+
" s = create_model(f'Input for `{f.__name__}`', **kw).schema()\n",
|
| 93 |
+
" return dict(name=f.__name__, description=f.__doc__, parameters=s)"
|
| 94 |
+
]
|
| 95 |
+
},
|
| 96 |
+
{
|
| 97 |
+
"cell_type": "code",
|
| 98 |
+
"execution_count": 6,
|
| 99 |
+
"metadata": {},
|
| 100 |
+
"outputs": [
|
| 101 |
+
{
|
| 102 |
+
"data": {
|
| 103 |
+
"text/plain": [
|
| 104 |
+
"{'name': 'abc',\n",
|
| 105 |
+
" 'description': 'Compute abc between two numbers',\n",
|
| 106 |
+
" 'parameters': {'properties': {'num1': {'title': 'Num1', 'type': 'integer'},\n",
|
| 107 |
+
" 'num2': {'title': 'Num2', 'type': 'integer'}},\n",
|
| 108 |
+
" 'required': ['num1', 'num2'],\n",
|
| 109 |
+
" 'title': 'Input for `abc`',\n",
|
| 110 |
+
" 'type': 'object'}}"
|
| 111 |
+
]
|
| 112 |
+
},
|
| 113 |
+
"execution_count": 6,
|
| 114 |
+
"metadata": {},
|
| 115 |
+
"output_type": "execute_result"
|
| 116 |
+
}
|
| 117 |
+
],
|
| 118 |
+
"source": [
|
| 119 |
+
"abc_json = jsonschema(abc)\n",
|
| 120 |
+
"abc_json"
|
| 121 |
+
]
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"cell_type": "code",
|
| 125 |
+
"execution_count": 7,
|
| 126 |
+
"metadata": {},
|
| 127 |
+
"outputs": [],
|
| 128 |
+
"source": [
|
| 129 |
+
"model_name = \"llama-3.3-70b-versatile\""
|
| 130 |
+
]
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
"cell_type": "markdown",
|
| 134 |
+
"metadata": {},
|
| 135 |
+
"source": [
|
| 136 |
+
"**Ask Groq**"
|
| 137 |
+
]
|
| 138 |
+
},
|
| 139 |
+
{
|
| 140 |
+
"cell_type": "code",
|
| 141 |
+
"execution_count": 8,
|
| 142 |
+
"metadata": {},
|
| 143 |
+
"outputs": [],
|
| 144 |
+
"source": [
|
| 145 |
+
"client = Groq()\n",
|
| 146 |
+
"\n",
|
| 147 |
+
"response = client.chat.completions.create(\n",
|
| 148 |
+
" model= model_name,\n",
|
| 149 |
+
" messages=[\n",
|
| 150 |
+
" {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n",
|
| 151 |
+
" {\"role\": \"user\", \"content\": \"compute abc between 2 and 3\"},\n",
|
| 152 |
+
" ],\n",
|
| 153 |
+
")"
|
| 154 |
+
]
|
| 155 |
+
},
|
| 156 |
+
{
|
| 157 |
+
"cell_type": "code",
|
| 158 |
+
"execution_count": 9,
|
| 159 |
+
"metadata": {},
|
| 160 |
+
"outputs": [
|
| 161 |
+
{
|
| 162 |
+
"data": {
|
| 163 |
+
"text/plain": [
|
| 164 |
+
"'To compute the absolute difference, also known as the absolute value of the difference, between 2 and 3:\\n\\n|2 - 3| = |-1| = 1\\n\\nSo the absolute difference between 2 and 3 is 1.'"
|
| 165 |
+
]
|
| 166 |
+
},
|
| 167 |
+
"execution_count": 9,
|
| 168 |
+
"metadata": {},
|
| 169 |
+
"output_type": "execute_result"
|
| 170 |
+
}
|
| 171 |
+
],
|
| 172 |
+
"source": [
|
| 173 |
+
"response.choices[0].message.content"
|
| 174 |
+
]
|
| 175 |
+
},
|
| 176 |
+
{
|
| 177 |
+
"cell_type": "code",
|
| 178 |
+
"execution_count": 15,
|
| 179 |
+
"metadata": {},
|
| 180 |
+
"outputs": [],
|
| 181 |
+
"source": [
|
| 182 |
+
"messages= [\n",
|
| 183 |
+
" {\"role\": \"user\", \"content\": \"Compute abc between 2 and 3\"}\n",
|
| 184 |
+
"]\n",
|
| 185 |
+
"\n",
|
| 186 |
+
"# Pass th function to groq model\n",
|
| 187 |
+
"response = client.chat.completions.create(\n",
|
| 188 |
+
" model=model_name,\n",
|
| 189 |
+
" messages=messages,\n",
|
| 190 |
+
" functions=[abc_json],\n",
|
| 191 |
+
" function_call=\"auto\",\n",
|
| 192 |
+
" temperature=0\n",
|
| 193 |
+
")"
|
| 194 |
+
]
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"cell_type": "code",
|
| 198 |
+
"execution_count": 11,
|
| 199 |
+
"metadata": {},
|
| 200 |
+
"outputs": [
|
| 201 |
+
{
|
| 202 |
+
"data": {
|
| 203 |
+
"text/plain": [
|
| 204 |
+
"ChatCompletion(id='chatcmpl-e37ef9c8-5015-4811-91c8-6373640bb737', choices=[Choice(finish_reason='function_call', index=0, logprobs=None, message=ChatCompletionMessage(content=None, role='assistant', annotations=None, executed_tools=None, function_call=FunctionCall(arguments='{\"num1\":2,\"num2\":3}', name='abc'), reasoning=None, tool_calls=None))], created=1778583530, model='llama-3.3-70b-versatile', object='chat.completion', mcp_list_tools=None, service_tier='on_demand', system_fingerprint='fp_ce7bc1685b', usage=CompletionUsage(completion_tokens=21, prompt_tokens=237, total_tokens=258, completion_time=0.047009754, completion_tokens_details=None, prompt_time=0.013427763, prompt_tokens_details=None, queue_time=0.048241546, total_time=0.060437517), usage_breakdown=None, x_groq=XGroq(id='req_01krdxdtkmeghva26epfsabw0m', debug=None, seed=1357225914, usage=None))"
|
| 205 |
+
]
|
| 206 |
+
},
|
| 207 |
+
"execution_count": 11,
|
| 208 |
+
"metadata": {},
|
| 209 |
+
"output_type": "execute_result"
|
| 210 |
+
}
|
| 211 |
+
],
|
| 212 |
+
"source": [
|
| 213 |
+
"response"
|
| 214 |
+
]
|
| 215 |
+
},
|
| 216 |
+
{
|
| 217 |
+
"cell_type": "markdown",
|
| 218 |
+
"metadata": {},
|
| 219 |
+
"source": [
|
| 220 |
+
"**Executing the function by extracting the info from the output of the model**"
|
| 221 |
+
]
|
| 222 |
+
},
|
| 223 |
+
{
|
| 224 |
+
"cell_type": "code",
|
| 225 |
+
"execution_count": 12,
|
| 226 |
+
"metadata": {},
|
| 227 |
+
"outputs": [
|
| 228 |
+
{
|
| 229 |
+
"name": "stdout",
|
| 230 |
+
"output_type": "stream",
|
| 231 |
+
"text": [
|
| 232 |
+
"FunctionCall(arguments='{\"num1\":2,\"num2\":3}', name='abc')\n",
|
| 233 |
+
"{\"num1\":2,\"num2\":3}\n",
|
| 234 |
+
"<class 'str'>\n"
|
| 235 |
+
]
|
| 236 |
+
}
|
| 237 |
+
],
|
| 238 |
+
"source": [
|
| 239 |
+
"print(response.choices[0].message.function_call)\n",
|
| 240 |
+
"print(response.choices[0].message.function_call.arguments)\n",
|
| 241 |
+
"print(type(response.choices[0].message.function_call.arguments))"
|
| 242 |
+
]
|
| 243 |
+
},
|
| 244 |
+
{
|
| 245 |
+
"cell_type": "code",
|
| 246 |
+
"execution_count": 13,
|
| 247 |
+
"metadata": {},
|
| 248 |
+
"outputs": [
|
| 249 |
+
{
|
| 250 |
+
"name": "stdout",
|
| 251 |
+
"output_type": "stream",
|
| 252 |
+
"text": [
|
| 253 |
+
"Function name: abc\n",
|
| 254 |
+
"Function arguments: {'num1': 2, 'num2': 3}\n",
|
| 255 |
+
"<class 'dict'>\n"
|
| 256 |
+
]
|
| 257 |
+
}
|
| 258 |
+
],
|
| 259 |
+
"source": [
|
| 260 |
+
"func_name = response.choices[0].message.function_call.name\n",
|
| 261 |
+
"func_args = json.loads(response.choices[0].message.function_call.arguments)\n",
|
| 262 |
+
"print(\"Function name:\", func_name)\n",
|
| 263 |
+
"print(\"Function arguments:\", func_args)\n",
|
| 264 |
+
"print(type(func_args))"
|
| 265 |
+
]
|
| 266 |
+
},
|
| 267 |
+
{
|
| 268 |
+
"cell_type": "code",
|
| 269 |
+
"execution_count": 14,
|
| 270 |
+
"metadata": {},
|
| 271 |
+
"outputs": [
|
| 272 |
+
{
|
| 273 |
+
"name": "stdout",
|
| 274 |
+
"output_type": "stream",
|
| 275 |
+
"text": [
|
| 276 |
+
"-2\n"
|
| 277 |
+
]
|
| 278 |
+
}
|
| 279 |
+
],
|
| 280 |
+
"source": [
|
| 281 |
+
"if func_name == 'abc':\n",
|
| 282 |
+
" result = abc(**func_args)\n",
|
| 283 |
+
"print(result)"
|
| 284 |
+
]
|
| 285 |
+
},
|
| 286 |
+
{
|
| 287 |
+
"cell_type": "markdown",
|
| 288 |
+
"metadata": {},
|
| 289 |
+
"source": [
|
| 290 |
+
"## **Using Langchain**"
|
| 291 |
+
]
|
| 292 |
+
},
|
| 293 |
+
{
|
| 294 |
+
"cell_type": "code",
|
| 295 |
+
"execution_count": 16,
|
| 296 |
+
"metadata": {},
|
| 297 |
+
"outputs": [],
|
| 298 |
+
"source": [
|
| 299 |
+
"from langchain_core.tools import tool\n",
|
| 300 |
+
"\n",
|
| 301 |
+
"@tool\n",
|
| 302 |
+
"def abc(num1:int, num2:int)->int:\n",
|
| 303 |
+
" \"Compute abc between two numbers\"\n",
|
| 304 |
+
" return 2*(num1) - 2*(num2)"
|
| 305 |
+
]
|
| 306 |
+
},
|
| 307 |
+
{
|
| 308 |
+
"cell_type": "code",
|
| 309 |
+
"execution_count": 17,
|
| 310 |
+
"metadata": {},
|
| 311 |
+
"outputs": [
|
| 312 |
+
{
|
| 313 |
+
"data": {
|
| 314 |
+
"text/plain": [
|
| 315 |
+
"'Compute abc between two numbers'"
|
| 316 |
+
]
|
| 317 |
+
},
|
| 318 |
+
"execution_count": 17,
|
| 319 |
+
"metadata": {},
|
| 320 |
+
"output_type": "execute_result"
|
| 321 |
+
}
|
| 322 |
+
],
|
| 323 |
+
"source": [
|
| 324 |
+
"abc.description"
|
| 325 |
+
]
|
| 326 |
+
},
|
| 327 |
+
{
|
| 328 |
+
"cell_type": "code",
|
| 329 |
+
"execution_count": 18,
|
| 330 |
+
"metadata": {},
|
| 331 |
+
"outputs": [],
|
| 332 |
+
"source": [
|
| 333 |
+
"from langchain_groq import ChatGroq \n",
|
| 334 |
+
"llm = ChatGroq(model=\"llama-3.3-70b-versatile\", temperature=0)"
|
| 335 |
+
]
|
| 336 |
+
},
|
| 337 |
+
{
|
| 338 |
+
"cell_type": "code",
|
| 339 |
+
"execution_count": 19,
|
| 340 |
+
"metadata": {},
|
| 341 |
+
"outputs": [],
|
| 342 |
+
"source": [
|
| 343 |
+
"tools = [abc]\n",
|
| 344 |
+
"\n",
|
| 345 |
+
"llm_with_tools = llm.bind_tools(tools)"
|
| 346 |
+
]
|
| 347 |
+
},
|
| 348 |
+
{
|
| 349 |
+
"cell_type": "code",
|
| 350 |
+
"execution_count": 20,
|
| 351 |
+
"metadata": {},
|
| 352 |
+
"outputs": [],
|
| 353 |
+
"source": [
|
| 354 |
+
"response = llm_with_tools.invoke(\"Compute abc between 2 and 3\")"
|
| 355 |
+
]
|
| 356 |
+
},
|
| 357 |
+
{
|
| 358 |
+
"cell_type": "code",
|
| 359 |
+
"execution_count": 21,
|
| 360 |
+
"metadata": {},
|
| 361 |
+
"outputs": [
|
| 362 |
+
{
|
| 363 |
+
"data": {
|
| 364 |
+
"text/plain": [
|
| 365 |
+
"{'tool_calls': [{'id': 'rjae3mfkg',\n",
|
| 366 |
+
" 'function': {'arguments': '{\"num1\":2,\"num2\":3}', 'name': 'abc'},\n",
|
| 367 |
+
" 'type': 'function'}]}"
|
| 368 |
+
]
|
| 369 |
+
},
|
| 370 |
+
"execution_count": 21,
|
| 371 |
+
"metadata": {},
|
| 372 |
+
"output_type": "execute_result"
|
| 373 |
+
}
|
| 374 |
+
],
|
| 375 |
+
"source": [
|
| 376 |
+
"response.additional_kwargs"
|
| 377 |
+
]
|
| 378 |
+
}
|
| 379 |
+
],
|
| 380 |
+
"metadata": {
|
| 381 |
+
"kernelspec": {
|
| 382 |
+
"display_name": "querymind (3.12.10)",
|
| 383 |
+
"language": "python",
|
| 384 |
+
"name": "python3"
|
| 385 |
+
},
|
| 386 |
+
"language_info": {
|
| 387 |
+
"codemirror_mode": {
|
| 388 |
+
"name": "ipython",
|
| 389 |
+
"version": 3
|
| 390 |
+
},
|
| 391 |
+
"file_extension": ".py",
|
| 392 |
+
"mimetype": "text/x-python",
|
| 393 |
+
"name": "python",
|
| 394 |
+
"nbconvert_exporter": "python",
|
| 395 |
+
"pygments_lexer": "ipython3",
|
| 396 |
+
"version": "3.12.10"
|
| 397 |
+
}
|
| 398 |
+
},
|
| 399 |
+
"nbformat": 4,
|
| 400 |
+
"nbformat_minor": 2
|
| 401 |
+
}
|
Notebooks/explore_databases/explore_chinook.ipynb
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [],
|
| 8 |
+
"source": [
|
| 9 |
+
"import sqlite3\n",
|
| 10 |
+
"import pandas as pd\n",
|
| 11 |
+
"from pyprojroot import here"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"cell_type": "code",
|
| 16 |
+
"execution_count": 2,
|
| 17 |
+
"metadata": {},
|
| 18 |
+
"outputs": [],
|
| 19 |
+
"source": [
|
| 20 |
+
"# Connect to SQLite database\n",
|
| 21 |
+
"db_path = here('data/Chinook.db')\n",
|
| 22 |
+
"conn = sqlite3.connect(db_path)"
|
| 23 |
+
]
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"cell_type": "code",
|
| 27 |
+
"execution_count": 3,
|
| 28 |
+
"metadata": {},
|
| 29 |
+
"outputs": [
|
| 30 |
+
{
|
| 31 |
+
"data": {
|
| 32 |
+
"text/html": [
|
| 33 |
+
"<div>\n",
|
| 34 |
+
"<style scoped>\n",
|
| 35 |
+
" .dataframe tbody tr th:only-of-type {\n",
|
| 36 |
+
" vertical-align: middle;\n",
|
| 37 |
+
" }\n",
|
| 38 |
+
"\n",
|
| 39 |
+
" .dataframe tbody tr th {\n",
|
| 40 |
+
" vertical-align: top;\n",
|
| 41 |
+
" }\n",
|
| 42 |
+
"\n",
|
| 43 |
+
" .dataframe thead th {\n",
|
| 44 |
+
" text-align: right;\n",
|
| 45 |
+
" }\n",
|
| 46 |
+
"</style>\n",
|
| 47 |
+
"<table border=\"1\" class=\"dataframe\">\n",
|
| 48 |
+
" <thead>\n",
|
| 49 |
+
" <tr style=\"text-align: right;\">\n",
|
| 50 |
+
" <th></th>\n",
|
| 51 |
+
" <th>name</th>\n",
|
| 52 |
+
" </tr>\n",
|
| 53 |
+
" </thead>\n",
|
| 54 |
+
" <tbody>\n",
|
| 55 |
+
" <tr>\n",
|
| 56 |
+
" <th>0</th>\n",
|
| 57 |
+
" <td>Album</td>\n",
|
| 58 |
+
" </tr>\n",
|
| 59 |
+
" <tr>\n",
|
| 60 |
+
" <th>1</th>\n",
|
| 61 |
+
" <td>Artist</td>\n",
|
| 62 |
+
" </tr>\n",
|
| 63 |
+
" <tr>\n",
|
| 64 |
+
" <th>2</th>\n",
|
| 65 |
+
" <td>Customer</td>\n",
|
| 66 |
+
" </tr>\n",
|
| 67 |
+
" <tr>\n",
|
| 68 |
+
" <th>3</th>\n",
|
| 69 |
+
" <td>Employee</td>\n",
|
| 70 |
+
" </tr>\n",
|
| 71 |
+
" <tr>\n",
|
| 72 |
+
" <th>4</th>\n",
|
| 73 |
+
" <td>Genre</td>\n",
|
| 74 |
+
" </tr>\n",
|
| 75 |
+
" <tr>\n",
|
| 76 |
+
" <th>5</th>\n",
|
| 77 |
+
" <td>Invoice</td>\n",
|
| 78 |
+
" </tr>\n",
|
| 79 |
+
" <tr>\n",
|
| 80 |
+
" <th>6</th>\n",
|
| 81 |
+
" <td>InvoiceLine</td>\n",
|
| 82 |
+
" </tr>\n",
|
| 83 |
+
" <tr>\n",
|
| 84 |
+
" <th>7</th>\n",
|
| 85 |
+
" <td>MediaType</td>\n",
|
| 86 |
+
" </tr>\n",
|
| 87 |
+
" <tr>\n",
|
| 88 |
+
" <th>8</th>\n",
|
| 89 |
+
" <td>Playlist</td>\n",
|
| 90 |
+
" </tr>\n",
|
| 91 |
+
" <tr>\n",
|
| 92 |
+
" <th>9</th>\n",
|
| 93 |
+
" <td>PlaylistTrack</td>\n",
|
| 94 |
+
" </tr>\n",
|
| 95 |
+
" <tr>\n",
|
| 96 |
+
" <th>10</th>\n",
|
| 97 |
+
" <td>Track</td>\n",
|
| 98 |
+
" </tr>\n",
|
| 99 |
+
" </tbody>\n",
|
| 100 |
+
"</table>\n",
|
| 101 |
+
"</div>"
|
| 102 |
+
],
|
| 103 |
+
"text/plain": [
|
| 104 |
+
" name\n",
|
| 105 |
+
"0 Album\n",
|
| 106 |
+
"1 Artist\n",
|
| 107 |
+
"2 Customer\n",
|
| 108 |
+
"3 Employee\n",
|
| 109 |
+
"4 Genre\n",
|
| 110 |
+
"5 Invoice\n",
|
| 111 |
+
"6 InvoiceLine\n",
|
| 112 |
+
"7 MediaType\n",
|
| 113 |
+
"8 Playlist\n",
|
| 114 |
+
"9 PlaylistTrack\n",
|
| 115 |
+
"10 Track"
|
| 116 |
+
]
|
| 117 |
+
},
|
| 118 |
+
"execution_count": 3,
|
| 119 |
+
"metadata": {},
|
| 120 |
+
"output_type": "execute_result"
|
| 121 |
+
}
|
| 122 |
+
],
|
| 123 |
+
"source": [
|
| 124 |
+
"# Get list of all tables\n",
|
| 125 |
+
"query = \"SELECT name FROM sqlite_master WHERE type='table';\"\n",
|
| 126 |
+
"tables = pd.read_sql(query, conn)\n",
|
| 127 |
+
"tables"
|
| 128 |
+
]
|
| 129 |
+
},
|
| 130 |
+
{
|
| 131 |
+
"cell_type": "code",
|
| 132 |
+
"execution_count": 5,
|
| 133 |
+
"metadata": {},
|
| 134 |
+
"outputs": [
|
| 135 |
+
{
|
| 136 |
+
"data": {
|
| 137 |
+
"text/html": [
|
| 138 |
+
"<div>\n",
|
| 139 |
+
"<style scoped>\n",
|
| 140 |
+
" .dataframe tbody tr th:only-of-type {\n",
|
| 141 |
+
" vertical-align: middle;\n",
|
| 142 |
+
" }\n",
|
| 143 |
+
"\n",
|
| 144 |
+
" .dataframe tbody tr th {\n",
|
| 145 |
+
" vertical-align: top;\n",
|
| 146 |
+
" }\n",
|
| 147 |
+
"\n",
|
| 148 |
+
" .dataframe thead th {\n",
|
| 149 |
+
" text-align: right;\n",
|
| 150 |
+
" }\n",
|
| 151 |
+
"</style>\n",
|
| 152 |
+
"<table border=\"1\" class=\"dataframe\">\n",
|
| 153 |
+
" <thead>\n",
|
| 154 |
+
" <tr style=\"text-align: right;\">\n",
|
| 155 |
+
" <th></th>\n",
|
| 156 |
+
" <th>Title</th>\n",
|
| 157 |
+
" </tr>\n",
|
| 158 |
+
" </thead>\n",
|
| 159 |
+
" <tbody>\n",
|
| 160 |
+
" <tr>\n",
|
| 161 |
+
" <th>0</th>\n",
|
| 162 |
+
" <td>Jagged Little Pill</td>\n",
|
| 163 |
+
" </tr>\n",
|
| 164 |
+
" </tbody>\n",
|
| 165 |
+
"</table>\n",
|
| 166 |
+
"</div>"
|
| 167 |
+
],
|
| 168 |
+
"text/plain": [
|
| 169 |
+
" Title\n",
|
| 170 |
+
"0 Jagged Little Pill"
|
| 171 |
+
]
|
| 172 |
+
},
|
| 173 |
+
"execution_count": 5,
|
| 174 |
+
"metadata": {},
|
| 175 |
+
"output_type": "execute_result"
|
| 176 |
+
}
|
| 177 |
+
],
|
| 178 |
+
"source": [
|
| 179 |
+
"query = \"\"\"SELECT Album.Title\n",
|
| 180 |
+
"FROM Album\n",
|
| 181 |
+
"JOIN Artist ON Album.ArtistId = Artist.ArtistId\n",
|
| 182 |
+
"WHERE Artist.Name = 'Alanis Morissette';\"\"\"\n",
|
| 183 |
+
"tables = pd.read_sql(query, conn)\n",
|
| 184 |
+
"tables"
|
| 185 |
+
]
|
| 186 |
+
}
|
| 187 |
+
],
|
| 188 |
+
"metadata": {
|
| 189 |
+
"kernelspec": {
|
| 190 |
+
"display_name": "rag-sqlagent",
|
| 191 |
+
"language": "python",
|
| 192 |
+
"name": "python3"
|
| 193 |
+
},
|
| 194 |
+
"language_info": {
|
| 195 |
+
"codemirror_mode": {
|
| 196 |
+
"name": "ipython",
|
| 197 |
+
"version": 3
|
| 198 |
+
},
|
| 199 |
+
"file_extension": ".py",
|
| 200 |
+
"mimetype": "text/x-python",
|
| 201 |
+
"name": "python",
|
| 202 |
+
"nbconvert_exporter": "python",
|
| 203 |
+
"pygments_lexer": "ipython3",
|
| 204 |
+
"version": "3.11.9"
|
| 205 |
+
}
|
| 206 |
+
},
|
| 207 |
+
"nbformat": 4,
|
| 208 |
+
"nbformat_minor": 2
|
| 209 |
+
}
|
Notebooks/explore_databases/explore_traveldb.ipynb
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 3,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [],
|
| 8 |
+
"source": [
|
| 9 |
+
"import sqlite3\n",
|
| 10 |
+
"import pandas as pd\n",
|
| 11 |
+
"from pyprojroot import here"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"cell_type": "code",
|
| 16 |
+
"execution_count": 4,
|
| 17 |
+
"metadata": {},
|
| 18 |
+
"outputs": [],
|
| 19 |
+
"source": [
|
| 20 |
+
"# Connect to SQLite database\n",
|
| 21 |
+
"db_path = here('data/travel.sqlite')\n",
|
| 22 |
+
"conn = sqlite3.connect(db_path)"
|
| 23 |
+
]
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"cell_type": "code",
|
| 27 |
+
"execution_count": 5,
|
| 28 |
+
"metadata": {},
|
| 29 |
+
"outputs": [
|
| 30 |
+
{
|
| 31 |
+
"data": {
|
| 32 |
+
"text/html": [
|
| 33 |
+
"<div>\n",
|
| 34 |
+
"<style scoped>\n",
|
| 35 |
+
" .dataframe tbody tr th:only-of-type {\n",
|
| 36 |
+
" vertical-align: middle;\n",
|
| 37 |
+
" }\n",
|
| 38 |
+
"\n",
|
| 39 |
+
" .dataframe tbody tr th {\n",
|
| 40 |
+
" vertical-align: top;\n",
|
| 41 |
+
" }\n",
|
| 42 |
+
"\n",
|
| 43 |
+
" .dataframe thead th {\n",
|
| 44 |
+
" text-align: right;\n",
|
| 45 |
+
" }\n",
|
| 46 |
+
"</style>\n",
|
| 47 |
+
"<table border=\"1\" class=\"dataframe\">\n",
|
| 48 |
+
" <thead>\n",
|
| 49 |
+
" <tr style=\"text-align: right;\">\n",
|
| 50 |
+
" <th></th>\n",
|
| 51 |
+
" <th>name</th>\n",
|
| 52 |
+
" </tr>\n",
|
| 53 |
+
" </thead>\n",
|
| 54 |
+
" <tbody>\n",
|
| 55 |
+
" <tr>\n",
|
| 56 |
+
" <th>0</th>\n",
|
| 57 |
+
" <td>aircrafts_data</td>\n",
|
| 58 |
+
" </tr>\n",
|
| 59 |
+
" <tr>\n",
|
| 60 |
+
" <th>1</th>\n",
|
| 61 |
+
" <td>airports_data</td>\n",
|
| 62 |
+
" </tr>\n",
|
| 63 |
+
" <tr>\n",
|
| 64 |
+
" <th>2</th>\n",
|
| 65 |
+
" <td>boarding_passes</td>\n",
|
| 66 |
+
" </tr>\n",
|
| 67 |
+
" <tr>\n",
|
| 68 |
+
" <th>3</th>\n",
|
| 69 |
+
" <td>bookings</td>\n",
|
| 70 |
+
" </tr>\n",
|
| 71 |
+
" <tr>\n",
|
| 72 |
+
" <th>4</th>\n",
|
| 73 |
+
" <td>flights</td>\n",
|
| 74 |
+
" </tr>\n",
|
| 75 |
+
" <tr>\n",
|
| 76 |
+
" <th>5</th>\n",
|
| 77 |
+
" <td>seats</td>\n",
|
| 78 |
+
" </tr>\n",
|
| 79 |
+
" <tr>\n",
|
| 80 |
+
" <th>6</th>\n",
|
| 81 |
+
" <td>ticket_flights</td>\n",
|
| 82 |
+
" </tr>\n",
|
| 83 |
+
" <tr>\n",
|
| 84 |
+
" <th>7</th>\n",
|
| 85 |
+
" <td>tickets</td>\n",
|
| 86 |
+
" </tr>\n",
|
| 87 |
+
" <tr>\n",
|
| 88 |
+
" <th>8</th>\n",
|
| 89 |
+
" <td>car_rentals</td>\n",
|
| 90 |
+
" </tr>\n",
|
| 91 |
+
" <tr>\n",
|
| 92 |
+
" <th>9</th>\n",
|
| 93 |
+
" <td>hotels</td>\n",
|
| 94 |
+
" </tr>\n",
|
| 95 |
+
" <tr>\n",
|
| 96 |
+
" <th>10</th>\n",
|
| 97 |
+
" <td>trip_recommendations</td>\n",
|
| 98 |
+
" </tr>\n",
|
| 99 |
+
" </tbody>\n",
|
| 100 |
+
"</table>\n",
|
| 101 |
+
"</div>"
|
| 102 |
+
],
|
| 103 |
+
"text/plain": [
|
| 104 |
+
" name\n",
|
| 105 |
+
"0 aircrafts_data\n",
|
| 106 |
+
"1 airports_data\n",
|
| 107 |
+
"2 boarding_passes\n",
|
| 108 |
+
"3 bookings\n",
|
| 109 |
+
"4 flights\n",
|
| 110 |
+
"5 seats\n",
|
| 111 |
+
"6 ticket_flights\n",
|
| 112 |
+
"7 tickets\n",
|
| 113 |
+
"8 car_rentals\n",
|
| 114 |
+
"9 hotels\n",
|
| 115 |
+
"10 trip_recommendations"
|
| 116 |
+
]
|
| 117 |
+
},
|
| 118 |
+
"execution_count": 5,
|
| 119 |
+
"metadata": {},
|
| 120 |
+
"output_type": "execute_result"
|
| 121 |
+
}
|
| 122 |
+
],
|
| 123 |
+
"source": [
|
| 124 |
+
"# Get list of all tables\n",
|
| 125 |
+
"query = \"SELECT name FROM sqlite_master WHERE type='table';\"\n",
|
| 126 |
+
"tables = pd.read_sql(query, conn)\n",
|
| 127 |
+
"tables"
|
| 128 |
+
]
|
| 129 |
+
}
|
| 130 |
+
],
|
| 131 |
+
"metadata": {
|
| 132 |
+
"kernelspec": {
|
| 133 |
+
"display_name": "rag-sqlagent",
|
| 134 |
+
"language": "python",
|
| 135 |
+
"name": "python3"
|
| 136 |
+
},
|
| 137 |
+
"language_info": {
|
| 138 |
+
"codemirror_mode": {
|
| 139 |
+
"name": "ipython",
|
| 140 |
+
"version": 3
|
| 141 |
+
},
|
| 142 |
+
"file_extension": ".py",
|
| 143 |
+
"mimetype": "text/x-python",
|
| 144 |
+
"name": "python",
|
| 145 |
+
"nbconvert_exporter": "python",
|
| 146 |
+
"pygments_lexer": "ipython3",
|
| 147 |
+
"version": "3.11.9"
|
| 148 |
+
}
|
| 149 |
+
},
|
| 150 |
+
"nbformat": 4,
|
| 151 |
+
"nbformat_minor": 2
|
| 152 |
+
}
|
Notebooks/full_graph.ipynb
ADDED
|
@@ -0,0 +1,828 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"**In this Notebook we will design the full graph using 3 tools: search_tool, RAG tool, and SQL-agent for travel database**"
|
| 8 |
+
]
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"cell_type": "code",
|
| 12 |
+
"execution_count": 1,
|
| 13 |
+
"metadata": {},
|
| 14 |
+
"outputs": [
|
| 15 |
+
{
|
| 16 |
+
"data": {
|
| 17 |
+
"text/plain": [
|
| 18 |
+
"True"
|
| 19 |
+
]
|
| 20 |
+
},
|
| 21 |
+
"execution_count": 1,
|
| 22 |
+
"metadata": {},
|
| 23 |
+
"output_type": "execute_result"
|
| 24 |
+
}
|
| 25 |
+
],
|
| 26 |
+
"source": [
|
| 27 |
+
"import os\n",
|
| 28 |
+
"from dotenv import load_dotenv\n",
|
| 29 |
+
"from pyprojroot import here\n",
|
| 30 |
+
"load_dotenv()"
|
| 31 |
+
]
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"cell_type": "markdown",
|
| 35 |
+
"metadata": {},
|
| 36 |
+
"source": [
|
| 37 |
+
"Set the environment variables"
|
| 38 |
+
]
|
| 39 |
+
},
|
| 40 |
+
{
|
| 41 |
+
"cell_type": "code",
|
| 42 |
+
"execution_count": 2,
|
| 43 |
+
"metadata": {},
|
| 44 |
+
"outputs": [],
|
| 45 |
+
"source": [
|
| 46 |
+
"os.environ['GROQ_API_KEY'] = os.getenv(\"GROQ_API_KEY\")\n",
|
| 47 |
+
"os.environ['TAVILY_API_KEY'] = os.getenv(\"TAVILY_API_KEY\")"
|
| 48 |
+
]
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"cell_type": "markdown",
|
| 52 |
+
"metadata": {},
|
| 53 |
+
"source": [
|
| 54 |
+
"### **1. initialize the Tools**"
|
| 55 |
+
]
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"cell_type": "markdown",
|
| 59 |
+
"metadata": {},
|
| 60 |
+
"source": [
|
| 61 |
+
"**1.1 RAG tool design**"
|
| 62 |
+
]
|
| 63 |
+
},
|
| 64 |
+
{
|
| 65 |
+
"cell_type": "code",
|
| 66 |
+
"execution_count": 3,
|
| 67 |
+
"metadata": {},
|
| 68 |
+
"outputs": [
|
| 69 |
+
{
|
| 70 |
+
"name": "stdout",
|
| 71 |
+
"output_type": "stream",
|
| 72 |
+
"text": [
|
| 73 |
+
"name='lookup_policy' description='Consult the company policies to check whether certain options are permitted.' args_schema=<class 'pydantic.v1.main.lookup_policySchema'> func=<function lookup_policy at 0x0000029B15CC5620>\n"
|
| 74 |
+
]
|
| 75 |
+
}
|
| 76 |
+
],
|
| 77 |
+
"source": [
|
| 78 |
+
"from langchain_chroma import Chroma\n",
|
| 79 |
+
"from langchain_huggingface import HuggingFaceEmbeddings\n",
|
| 80 |
+
"from langchain_core.tools import tool\n",
|
| 81 |
+
"\n",
|
| 82 |
+
"EMBEDDING_MODEL = \"all-MiniLM-L6-v2\"\n",
|
| 83 |
+
"VECTORDB_DIR = \"data/airline_policy_vectordb\"\n",
|
| 84 |
+
"K = 2\n",
|
| 85 |
+
"\n",
|
| 86 |
+
"@tool\n",
|
| 87 |
+
"def lookup_policy(query: str)->str:\n",
|
| 88 |
+
" \"\"\"Consult the company policies to check whether certain options are permitted.\"\"\"\n",
|
| 89 |
+
" vectordb = Chroma(\n",
|
| 90 |
+
" collection_name=\"rag-chroma\",\n",
|
| 91 |
+
" persist_directory=str(here(VECTORDB_DIR)),\n",
|
| 92 |
+
" embedding_function=HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL)\n",
|
| 93 |
+
" )\n",
|
| 94 |
+
" docs = vectordb.similarity_search(query, k=K)\n",
|
| 95 |
+
" return \"\\n\\n\".join([doc.page_content for doc in docs])\n",
|
| 96 |
+
"\n",
|
| 97 |
+
"print(lookup_policy)"
|
| 98 |
+
]
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"cell_type": "markdown",
|
| 102 |
+
"metadata": {},
|
| 103 |
+
"source": [
|
| 104 |
+
"Test the RAG tool"
|
| 105 |
+
]
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"cell_type": "code",
|
| 109 |
+
"execution_count": 4,
|
| 110 |
+
"metadata": {},
|
| 111 |
+
"outputs": [
|
| 112 |
+
{
|
| 113 |
+
"name": "stderr",
|
| 114 |
+
"output_type": "stream",
|
| 115 |
+
"text": [
|
| 116 |
+
"f:\\end_to_end_AI_Projects\\QueryMind _ AI_Powered_Natural_Language_Interface_for_SQL_&_Vector_Databases\\querymind\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
| 117 |
+
" from .autonotebook import tqdm as notebook_tqdm\n",
|
| 118 |
+
"Loading weights: 100%|██████████| 103/103 [00:00<00:00, 2527.99it/s]\n",
|
| 119 |
+
"Failed to send telemetry event ClientStartEvent: capture() takes 1 positional argument but 3 were given\n",
|
| 120 |
+
"Failed to send telemetry event ClientCreateCollectionEvent: capture() takes 1 positional argument but 3 were given\n",
|
| 121 |
+
"Failed to send telemetry event CollectionQueryEvent: capture() takes 1 positional argument but 3 were given\n"
|
| 122 |
+
]
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"data": {
|
| 126 |
+
"text/plain": [
|
| 127 |
+
"'hour cancellation policy that allows passengers to cancel their flights within 24 hours of booking at +1-877-507-7341\\nwithout penalty . This policy applies to all fare types, including non-refundable tickets. If you cancel your Swiss Airlines\\nflight within 24 hours of booking, you\\'ll receive a full refund of your ticket price.\\nHow to Cancel Swiss Airlines Flight within 24 Hours? If you need to cancel your Swiss Airlines flight within 24 hours of\\nbooking, you can do so easily online. Here are the steps to follow:\\nGo to Swiss Airlines\\' website and click on the \"Manage your bookings\" tab. Enter your booking reference number and last\\nname to access your booking. Select the flight you want to cancel and click on \"Cancel flight.\" Confirm your cancellation\\nand you\\'ll receive a full refund of your ticket price. If you booked your Swiss Airlines flight through a travel agent, you\\'ll\\nneed to contact them directly to cancel your flight within 24 hours.\\nImportant Things to Keep in Mind for Swiss Airlines 24 Hour Cancellation Here are some important things to keep in mind\\nwhen cancelling your Swiss Airlines flight within 24 hours:\\nSwiss Airlines\\' 24 hour cancellation policy only applies to flights booked directly through Swiss Airlines. If you booked\\nyour flight through a travel agent or third-party website, you\\'ll need to check their cancellation policy . If you cancel your\\nSwiss Airlines flight after the 24 hour window , you may be subject to cancellation fees or penalties. If you have a non-\\nrefundable ticket and cancel your flight within 24 hours of booking, you\\'ll receive a full refund of your ticket price.\\nHowever , if you cancel your flight after the 24 hour window , you may not be eligible for a refund. Swiss Airlines\\' 24 hour\\ncancellation policy allows passengers to cancel their flights within 24 hours of booking without penalty . If you need to\\ncancel your Swiss Airlines flight within 24 hours, you can do so easily online. Just remember to check the terms and\\nconditions of your ticket to make sure you\\'re eligible for a refund.\\nSwiss Air Cancellation Fees The cancellation fees for Swiss Air flights may vary depending on the type of ticket you have\\npurchased. The airline of fers three dif ferent types of tickets, which are:\\n\\nfor a refund or may only be able to receive a partial refund. If you booked your flight through a third-party website or\\ntravel agent, you may need to contact them directly to cancel your flight. Always check the terms and conditions of your\\nticket to make sure you understand the cancellation policy and any associated fees or penalties. If you\\'re cancelling your\\nflight due to unforeseen circumstances such as a medical emergency or a natural disaster , Swiss Air may of fer you\\nspecial exemptions or accommodations. What is Swiss Airlines 24 Hour Cancellation Policy? Swiss Airlines has a 24'"
|
| 128 |
+
]
|
| 129 |
+
},
|
| 130 |
+
"execution_count": 4,
|
| 131 |
+
"metadata": {},
|
| 132 |
+
"output_type": "execute_result"
|
| 133 |
+
}
|
| 134 |
+
],
|
| 135 |
+
"source": [
|
| 136 |
+
"lookup_policy.invoke(\"can I cancel my ticket?\")"
|
| 137 |
+
]
|
| 138 |
+
},
|
| 139 |
+
{
|
| 140 |
+
"cell_type": "markdown",
|
| 141 |
+
"metadata": {},
|
| 142 |
+
"source": [
|
| 143 |
+
"**1.2 Search tool design**"
|
| 144 |
+
]
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"cell_type": "code",
|
| 148 |
+
"execution_count": 5,
|
| 149 |
+
"metadata": {},
|
| 150 |
+
"outputs": [],
|
| 151 |
+
"source": [
|
| 152 |
+
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
|
| 153 |
+
"\n",
|
| 154 |
+
"search_tool = TavilySearchResults(max_results=2)"
|
| 155 |
+
]
|
| 156 |
+
},
|
| 157 |
+
{
|
| 158 |
+
"cell_type": "markdown",
|
| 159 |
+
"metadata": {},
|
| 160 |
+
"source": [
|
| 161 |
+
"Test the Search Tool"
|
| 162 |
+
]
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"cell_type": "code",
|
| 166 |
+
"execution_count": null,
|
| 167 |
+
"metadata": {},
|
| 168 |
+
"outputs": [],
|
| 169 |
+
"source": [
|
| 170 |
+
"search_tool.invoke(\"What's a 'node' in LangGraph?\")"
|
| 171 |
+
]
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"cell_type": "markdown",
|
| 175 |
+
"metadata": {},
|
| 176 |
+
"source": [
|
| 177 |
+
"**1.3 SQL agent tool design**"
|
| 178 |
+
]
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
+
"cell_type": "code",
|
| 182 |
+
"execution_count": 6,
|
| 183 |
+
"metadata": {},
|
| 184 |
+
"outputs": [],
|
| 185 |
+
"source": [
|
| 186 |
+
"from langchain_community.utilities import SQLDatabase\n",
|
| 187 |
+
"from langchain.chains import create_sql_query_chain\n",
|
| 188 |
+
"from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool\n",
|
| 189 |
+
"from langchain_core.prompts import PromptTemplate\n",
|
| 190 |
+
"from langchain_core.output_parsers import StrOutputParser\n",
|
| 191 |
+
"from langchain_core.runnables import RunnablePassthrough\n",
|
| 192 |
+
"from operator import itemgetter\n",
|
| 193 |
+
"from langchain_groq import ChatGroq"
|
| 194 |
+
]
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"cell_type": "markdown",
|
| 198 |
+
"metadata": {},
|
| 199 |
+
"source": [
|
| 200 |
+
"**SQL agent chain**"
|
| 201 |
+
]
|
| 202 |
+
},
|
| 203 |
+
{
|
| 204 |
+
"cell_type": "code",
|
| 205 |
+
"execution_count": 7,
|
| 206 |
+
"metadata": {},
|
| 207 |
+
"outputs": [],
|
| 208 |
+
"source": [
|
| 209 |
+
"sqldb_directory = here(\"data/travel.sqlite\")\n",
|
| 210 |
+
"\n",
|
| 211 |
+
"sql_llm = ChatGroq(model=\"openai/gpt-oss-120b\", temperature=0)\n",
|
| 212 |
+
"# llm = ChatGroq(model=\"llama-3.3-70b-versatile\")\n",
|
| 213 |
+
"system_role = \"\"\"Given the following user question, corresponding SQL query, and SQL result, answer the user question.\\n\n",
|
| 214 |
+
" Question: {question}\\n\n",
|
| 215 |
+
" SQL Query: {query}\\n\n",
|
| 216 |
+
" SQL Result: {result}\\n\n",
|
| 217 |
+
" Answer:\n",
|
| 218 |
+
" \"\"\"\n",
|
| 219 |
+
"db = SQLDatabase.from_uri(\n",
|
| 220 |
+
" f\"sqlite:///{sqldb_directory}\")\n",
|
| 221 |
+
"\n",
|
| 222 |
+
"execute_query = QuerySQLDataBaseTool(db=db)\n",
|
| 223 |
+
"write_query = create_sql_query_chain(\n",
|
| 224 |
+
" sql_llm, db)\n",
|
| 225 |
+
"answer_prompt = PromptTemplate.from_template(\n",
|
| 226 |
+
" system_role)\n",
|
| 227 |
+
"\n",
|
| 228 |
+
"\n",
|
| 229 |
+
"answer = answer_prompt | sql_llm | StrOutputParser()\n",
|
| 230 |
+
"chain = (\n",
|
| 231 |
+
" RunnablePassthrough.assign(query=write_query).assign(\n",
|
| 232 |
+
" result=itemgetter(\"query\") | execute_query\n",
|
| 233 |
+
" )\n",
|
| 234 |
+
" | answer\n",
|
| 235 |
+
")\n",
|
| 236 |
+
"# Test the chain\n",
|
| 237 |
+
"# message = \"How many tables do I have in the database? and what are their names?\"\n",
|
| 238 |
+
"# response = chain.invoke({\"question\": message})\n",
|
| 239 |
+
"\n",
|
| 240 |
+
"@tool\n",
|
| 241 |
+
"def query_sqldb(query):\n",
|
| 242 |
+
" \"\"\"Query the Swiss Airline SQL Database and access all the company's information. Input should be a search query.\"\"\"\n",
|
| 243 |
+
" response = chain.invoke({\"question\": query})\n",
|
| 244 |
+
" return response"
|
| 245 |
+
]
|
| 246 |
+
},
|
| 247 |
+
{
|
| 248 |
+
"cell_type": "code",
|
| 249 |
+
"execution_count": null,
|
| 250 |
+
"metadata": {},
|
| 251 |
+
"outputs": [],
|
| 252 |
+
"source": [
|
| 253 |
+
"message = \"How many tables do I have in the database? and what are their names?\"\n",
|
| 254 |
+
"response = query_sqldb.invoke(message)\n",
|
| 255 |
+
"print(response)"
|
| 256 |
+
]
|
| 257 |
+
},
|
| 258 |
+
{
|
| 259 |
+
"cell_type": "markdown",
|
| 260 |
+
"metadata": {},
|
| 261 |
+
"source": [
|
| 262 |
+
"**Wrap up the tools into a list**"
|
| 263 |
+
]
|
| 264 |
+
},
|
| 265 |
+
{
|
| 266 |
+
"cell_type": "code",
|
| 267 |
+
"execution_count": 8,
|
| 268 |
+
"metadata": {},
|
| 269 |
+
"outputs": [],
|
| 270 |
+
"source": [
|
| 271 |
+
"tools = [search_tool, lookup_policy, query_sqldb]"
|
| 272 |
+
]
|
| 273 |
+
},
|
| 274 |
+
{
|
| 275 |
+
"cell_type": "markdown",
|
| 276 |
+
"metadata": {},
|
| 277 |
+
"source": [
|
| 278 |
+
"#### **Load the LLM for the primary agent and bind it with the tools**"
|
| 279 |
+
]
|
| 280 |
+
},
|
| 281 |
+
{
|
| 282 |
+
"cell_type": "code",
|
| 283 |
+
"execution_count": 9,
|
| 284 |
+
"metadata": {},
|
| 285 |
+
"outputs": [],
|
| 286 |
+
"source": [
|
| 287 |
+
"llm = ChatGroq(model=\"openai/gpt-oss-120b\", temperature=0)\n",
|
| 288 |
+
"# Tell the LLM which tools it can call\n",
|
| 289 |
+
"llm_with_tools = llm.bind_tools(tools)"
|
| 290 |
+
]
|
| 291 |
+
},
|
| 292 |
+
{
|
| 293 |
+
"cell_type": "markdown",
|
| 294 |
+
"metadata": {},
|
| 295 |
+
"source": [
|
| 296 |
+
"### **2. Initialize the Graph State**\n",
|
| 297 |
+
"\n",
|
| 298 |
+
"Define our StateGraph's state as a typed dictionary containing an append-only list of messages. These messages form the chat history, which is all the state our chatbot needs."
|
| 299 |
+
]
|
| 300 |
+
},
|
| 301 |
+
{
|
| 302 |
+
"cell_type": "code",
|
| 303 |
+
"execution_count": 10,
|
| 304 |
+
"metadata": {},
|
| 305 |
+
"outputs": [],
|
| 306 |
+
"source": [
|
| 307 |
+
"from typing import Annotated\n",
|
| 308 |
+
"from typing_extensions import TypedDict\n",
|
| 309 |
+
"from langgraph.graph import StateGraph, START\n",
|
| 310 |
+
"from langgraph.graph.message import add_messages\n",
|
| 311 |
+
"\n",
|
| 312 |
+
"\n",
|
| 313 |
+
"class State(TypedDict):\n",
|
| 314 |
+
" messages: Annotated[list, add_messages]\n",
|
| 315 |
+
"\n",
|
| 316 |
+
"\n",
|
| 317 |
+
"graph_builder = StateGraph(State)"
|
| 318 |
+
]
|
| 319 |
+
},
|
| 320 |
+
{
|
| 321 |
+
"cell_type": "markdown",
|
| 322 |
+
"metadata": {},
|
| 323 |
+
"source": [
|
| 324 |
+
"### **3. Define the Graph Nodes**"
|
| 325 |
+
]
|
| 326 |
+
},
|
| 327 |
+
{
|
| 328 |
+
"cell_type": "markdown",
|
| 329 |
+
"metadata": {},
|
| 330 |
+
"source": [
|
| 331 |
+
"**3.1 First node: chatbot**"
|
| 332 |
+
]
|
| 333 |
+
},
|
| 334 |
+
{
|
| 335 |
+
"cell_type": "code",
|
| 336 |
+
"execution_count": 11,
|
| 337 |
+
"metadata": {},
|
| 338 |
+
"outputs": [],
|
| 339 |
+
"source": [
|
| 340 |
+
"def chatbot(state: State):\n",
|
| 341 |
+
" return {\"messages\": [llm_with_tools.invoke(state[\"messages\"])]}\n",
|
| 342 |
+
"\n",
|
| 343 |
+
"\n",
|
| 344 |
+
"graph_builder.add_node(\"chatbot\", chatbot)"
|
| 345 |
+
]
|
| 346 |
+
},
|
| 347 |
+
{
|
| 348 |
+
"cell_type": "markdown",
|
| 349 |
+
"metadata": {},
|
| 350 |
+
"source": [
|
| 351 |
+
"Next, we need to create a function that will run the tools when they are needed. To do this, we'll add the tools to a new node.\n",
|
| 352 |
+
"\n",
|
| 353 |
+
"In the example below, we'll build a BasicToolNode. This node will check the latest message and, if it contains a request to use a tool, it will run the appropriate tool. This works because many language models (like Anthropic, OpenAI, and Google Gemini) support tool usage."
|
| 354 |
+
]
|
| 355 |
+
},
|
| 356 |
+
{
|
| 357 |
+
"cell_type": "markdown",
|
| 358 |
+
"metadata": {},
|
| 359 |
+
"source": [
|
| 360 |
+
"**3.2 Second node: BasicToolNode that runs the appropriate tool based on the primary agent's output**"
|
| 361 |
+
]
|
| 362 |
+
},
|
| 363 |
+
{
|
| 364 |
+
"cell_type": "code",
|
| 365 |
+
"execution_count": 12,
|
| 366 |
+
"metadata": {},
|
| 367 |
+
"outputs": [],
|
| 368 |
+
"source": [
|
| 369 |
+
"import json\n",
|
| 370 |
+
"from langchain_core.messages import ToolMessage\n",
|
| 371 |
+
"\n",
|
| 372 |
+
"\n",
|
| 373 |
+
"class BasicToolNode:\n",
|
| 374 |
+
" \"\"\"A node that runs the tools requested in the last AIMessage.\"\"\"\n",
|
| 375 |
+
"\n",
|
| 376 |
+
" def __init__(self, tools: list) -> None:\n",
|
| 377 |
+
" self.tools_by_name = {tool.name: tool for tool in tools}\n",
|
| 378 |
+
"\n",
|
| 379 |
+
" def __call__(self, inputs: dict):\n",
|
| 380 |
+
" if messages := inputs.get(\"messages\", []):\n",
|
| 381 |
+
" message = messages[-1]\n",
|
| 382 |
+
" else:\n",
|
| 383 |
+
" raise ValueError(\"No message found in input\")\n",
|
| 384 |
+
" outputs = []\n",
|
| 385 |
+
" for tool_call in message.tool_calls:\n",
|
| 386 |
+
" tool_result = self.tools_by_name[tool_call[\"name\"]].invoke(\n",
|
| 387 |
+
" tool_call[\"args\"]\n",
|
| 388 |
+
" )\n",
|
| 389 |
+
" outputs.append(\n",
|
| 390 |
+
" ToolMessage(\n",
|
| 391 |
+
" content=json.dumps(tool_result),\n",
|
| 392 |
+
" name=tool_call[\"name\"],\n",
|
| 393 |
+
" tool_call_id=tool_call[\"id\"],\n",
|
| 394 |
+
" )\n",
|
| 395 |
+
" )\n",
|
| 396 |
+
" return {\"messages\": outputs}\n",
|
| 397 |
+
"\n",
|
| 398 |
+
"\n",
|
| 399 |
+
"tool_node = BasicToolNode(tools=[search_tool, lookup_policy, query_sqldb])\n",
|
| 400 |
+
"graph_builder.add_node(\"tools\", tool_node)"
|
| 401 |
+
]
|
| 402 |
+
},
|
| 403 |
+
{
|
| 404 |
+
"cell_type": "markdown",
|
| 405 |
+
"metadata": {},
|
| 406 |
+
"source": [
|
| 407 |
+
"### **4. Define the entry point and graph edges**"
|
| 408 |
+
]
|
| 409 |
+
},
|
| 410 |
+
{
|
| 411 |
+
"cell_type": "markdown",
|
| 412 |
+
"metadata": {},
|
| 413 |
+
"source": [
|
| 414 |
+
"**Aproach 1**"
|
| 415 |
+
]
|
| 416 |
+
},
|
| 417 |
+
{
|
| 418 |
+
"cell_type": "code",
|
| 419 |
+
"execution_count": null,
|
| 420 |
+
"metadata": {},
|
| 421 |
+
"outputs": [],
|
| 422 |
+
"source": [
|
| 423 |
+
"from typing import Literal\n",
|
| 424 |
+
"\n",
|
| 425 |
+
"\n",
|
| 426 |
+
"def route_tools(\n",
|
| 427 |
+
" state: State,\n",
|
| 428 |
+
") -> Literal[\"tools\", \"__end__\"]:\n",
|
| 429 |
+
" \"\"\"\n",
|
| 430 |
+
" Use in the conditional_edge to route to the ToolNode if the last message\n",
|
| 431 |
+
" has tool calls. Otherwise, route to the end.\n",
|
| 432 |
+
" \"\"\"\n",
|
| 433 |
+
" if isinstance(state, list):\n",
|
| 434 |
+
" ai_message = state[-1]\n",
|
| 435 |
+
" elif messages := state.get(\"messages\", []):\n",
|
| 436 |
+
" ai_message = messages[-1]\n",
|
| 437 |
+
" else:\n",
|
| 438 |
+
" raise ValueError(f\"No messages found in input state to tool_edge: {state}\")\n",
|
| 439 |
+
" if hasattr(ai_message, \"tool_calls\") and len(ai_message.tool_calls) > 0:\n",
|
| 440 |
+
" return \"tools\"\n",
|
| 441 |
+
" return \"__end__\"\n",
|
| 442 |
+
"\n",
|
| 443 |
+
"\n",
|
| 444 |
+
"\n",
|
| 445 |
+
"graph_builder.add_conditional_edges(\n",
|
| 446 |
+
" \"chatbot\",\n",
|
| 447 |
+
" route_tools,\n",
|
| 448 |
+
" \n",
|
| 449 |
+
" {\"tools\": \"tools\", \"__end__\": \"__end__\"},\n",
|
| 450 |
+
")\n",
|
| 451 |
+
"# Any time a tool is called, we return to the chatbot to decide the next step\n",
|
| 452 |
+
"graph_builder.add_edge(\"tools\", \"chatbot\")\n",
|
| 453 |
+
"graph_builder.add_edge(START, \"chatbot\")"
|
| 454 |
+
]
|
| 455 |
+
},
|
| 456 |
+
{
|
| 457 |
+
"cell_type": "markdown",
|
| 458 |
+
"metadata": {},
|
| 459 |
+
"source": [
|
| 460 |
+
"**Approach 2**"
|
| 461 |
+
]
|
| 462 |
+
},
|
| 463 |
+
{
|
| 464 |
+
"cell_type": "code",
|
| 465 |
+
"execution_count": 14,
|
| 466 |
+
"metadata": {},
|
| 467 |
+
"outputs": [],
|
| 468 |
+
"source": [
|
| 469 |
+
"from langgraph.graph import END, MessagesState\n",
|
| 470 |
+
"from typing import Literal\n",
|
| 471 |
+
"\n",
|
| 472 |
+
"# Define the function that determines whether to continue or not\n",
|
| 473 |
+
"def should_continue(state: MessagesState) -> Literal[\"tools\", END]:\n",
|
| 474 |
+
" messages = state['messages']\n",
|
| 475 |
+
" last_message = messages[-1]\n",
|
| 476 |
+
" # If the LLM makes a tool call, then we route to the \"tools\" node\n",
|
| 477 |
+
" if last_message.tool_calls:\n",
|
| 478 |
+
" return \"tools\"\n",
|
| 479 |
+
" # Otherwise, we stop (reply to the user)\n",
|
| 480 |
+
" return END\n",
|
| 481 |
+
"\n",
|
| 482 |
+
"graph_builder.add_conditional_edges(\n",
|
| 483 |
+
" \"chatbot\",\n",
|
| 484 |
+
" should_continue,\n",
|
| 485 |
+
" [\"tools\", END],\n",
|
| 486 |
+
")\n",
|
| 487 |
+
"# Any time a tool is called, we return to the chatbot to decide the next step\n",
|
| 488 |
+
"graph_builder.add_edge(\"tools\", \"chatbot\")\n",
|
| 489 |
+
"graph_builder.add_edge(START, \"chatbot\")"
|
| 490 |
+
]
|
| 491 |
+
},
|
| 492 |
+
{
|
| 493 |
+
"cell_type": "markdown",
|
| 494 |
+
"metadata": {},
|
| 495 |
+
"source": [
|
| 496 |
+
"### **5. Compile the graph**\n",
|
| 497 |
+
"\n",
|
| 498 |
+
"- In this step, we can add a memory to our graph as well."
|
| 499 |
+
]
|
| 500 |
+
},
|
| 501 |
+
{
|
| 502 |
+
"cell_type": "code",
|
| 503 |
+
"execution_count": 15,
|
| 504 |
+
"metadata": {},
|
| 505 |
+
"outputs": [],
|
| 506 |
+
"source": [
|
| 507 |
+
"from langgraph.checkpoint.memory import MemorySaver\n",
|
| 508 |
+
"\n",
|
| 509 |
+
"memory = MemorySaver()\n",
|
| 510 |
+
"graph = graph_builder.compile(checkpointer=memory)"
|
| 511 |
+
]
|
| 512 |
+
},
|
| 513 |
+
{
|
| 514 |
+
"cell_type": "markdown",
|
| 515 |
+
"metadata": {},
|
| 516 |
+
"source": [
|
| 517 |
+
"**5.1 Plot the compiled graph**"
|
| 518 |
+
]
|
| 519 |
+
},
|
| 520 |
+
{
|
| 521 |
+
"cell_type": "code",
|
| 522 |
+
"execution_count": 16,
|
| 523 |
+
"metadata": {},
|
| 524 |
+
"outputs": [
|
| 525 |
+
{
|
| 526 |
+
"data": {
|
| 527 |
+
"image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAD5ALYDASIAAhEBAxEB/8QAHQABAAMAAwEBAQAAAAAAAAAAAAUGBwMECAIBCf/EAE0QAAEDBAADAwUKCgcHBQAAAAECAwQABQYRBxIhEyIxCBQVQbMXMjdRVmFxdZXSFiMzNkJSVJGTsiVydIGhwtMJGCZXZYOxJ2OClKP/xAAbAQEAAgMBAQAAAAAAAAAAAAAAAQIDBAUGB//EADsRAAIBAgEGCgcJAQEAAAAAAAABAgMRBBIhMVFhkRMUQUJScYGhsdEFIjNTksHwFSMyNHKCstLhJGL/2gAMAwEAAhEDEQA/AP6p0pSgFKUoBSlcM2Yxbob8uU6hiMw2p111w6ShCRtSifUAATUpNuyBzVEXTLrFZHyxcb1boDwAJblS221aPh0URVcFon8SGWpdylTLTjjqedi0x1FiRJbUkaVJcSrmAO1aaSR0I5yTtKZKLwtw6GwhlrFrPyJATtcFtajr41EEk/OTutvg6NPNVk76l5vy7S1ktJy+6TiPypsv2iz96vz3ScR+VVl+0WfvV++5viXyWsv2ez92nub4l8lrL9ns/dq3/J/67ifVA4kYko6GU2Un4hcGfvVPRpLMxhD8d1D7Lg5kONqCkqHxgjxqB9zbEev/AAtZev8A09n7tRcvhLZo7y5mOc+JXTXdk2gBtpRAOg4x+TcTs7IKd9OhHjUOOGlmjJrrSa7s/j1EeqXelVzGsndnTH7NdkNRMhiNpceZaJ7OQ0ToPs76lBIIIPVCu6d91SrHWrOEqbyZENWFKUqhApSlAKUpQClKUApSlAKUpQClKUAqh8SHBd75iOLODcW6TVSZaShK0uMRk9r2agR4Kc7IH5tj11fKoWcbt/EXALm4tDcMvy7ctazrTjzIU2P71M6+kj463MJ7W/KlJrrUW13lo6S+1jOReVPjdiye/WeNj+VZA3YHkR7vcrJaTJiwnVAEIWQoLURsb5Eq1WzV4w428Cs5yLiHlN2xPAZlkyWY+hdszbGcsTAZWkJACpsdauZSh1CuzQeYHW/XWmVNS/3mJ6/KgPDRvFLiuxt2QXB25iOkLStTqQJBJdATFCCUklPPz9OUAbMhiPlb4dl+WWKytWzIraxkDz8ezXi5W7sYVycZ3zpaXzFQPTpzpTvw8elUm9cNuKdg8odjL7Va2b76SwNONyL43LYZRBuAcC/OFtOEKWjmSFaQk+++asus3AXjSbhwvym92W83u/4veTJurF3zBMwzQtR27GbW52LCEJA2kEKVzAa7vUDZpnlsWGfjWaXHHMOy28PYw3MExabc35sw4wdHtHe15Qk9V6BKuRCjyg8oOjeT1xPuPGHhLYMou1lkWS4TI7anm3Wg208otpUXWB2iz2Kio8pUebodiso4TcDcts3k98Z8Rultbtl6yi5X1y3ockNLS43KYDbLilNqUEgn1HqAOoFaX5MNsybHuCeM2DLcccxm72SI1bDHXMZk9uhptADwU0pSQFHY5Sdjl+cUBN8Uj6GRYsnQ4lly0XBpD6zvvRX1pZeRodD75C+vrbFXmqFxqaRccNZspUpL95uUOCyUp3ol9C1E/MENrV/8avtblTPh6bem8l2Zmu9ss9CFKUrTKilKUApSlAKUpQClKUApSlAKUpQConKsdZyuwyra845HLgCmpLKilxh1JCm3UkEd5KwlQ+jr0qWpVoycJKUdKGgquNZiX5ibFfQ1b8mbT1YBIamAJ2XY5V79Ot7T75BBB8Ao2qo2/wCOWvKrcqBd4LFwiKPN2b6N8qtEcyT4pUATpQ0Rvoaqb/CFrnIh5bldtY0AiPHupWhsDwCe0Ssgf31tWoVM7eS+q67OXst2lszL9Ss89yB75e5l9ot/6VVXB8LuOTXPMGJOc5Yhu0XpVujlqegFTYjR3Nr22dq5nVjY0NAdPEmeBoe97mLLWbbXRvd8t+OW164XSYzBhtDa3n1BKR8w+Mn1AdT6qpfuQOka/DzMvtFv/SqVsvC+xWmbHnvplXu6R08rdwvMpct1He2CjnJSg79aAn/zUcHh453NvqXn/vULLWfNrtL+TZPHya4NPRosNpTdpgvo5HEc405IdSRtK1DSUoPVKd7AUspTb6UrBUqOo1qWZbF9d5DdxSlKxEClKUApSlAKUpQClKUApSlAKUpQClKUApSlAKzvhB3p/ENf6+UyP8GI6f8ALWiVnfBrvIzZf6+Uz/8AApT/AJaA0SlKUApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQClKUApSlAKzvgvrzHLhogjKLnvZ/98n/AMarRKzvg33fw5R+plM7/HkV/moDRKUpQClKUApSlAKUpQClKUApSlAKUpQClKUApSlAKVnEnO8lyNKpGIQLS5a0rUhuddpLgEnlPKpTaG0khIUFAFR72tga0T1vTXFL9lxD+PK+5XQWCqc5pPU2rlsk1ClZf6a4pfsmIfx5X3KemuKX7LiH8eV9yp4jPpR3oZO0t/EHM2eHeFXjJZFun3aNa46pT0S2IQuQptPvylK1oSeVO1Hah0SdbPSvM/kq+WDiXFXiNkOLWWx5GmXebpKvDUmTFYDEZjsWx+OUl5RSSpBSNAjak9ep1szt14nvtLbchYc42sFKkKelEKB8QRydaxvgP5NuQ+T3kGT3fHI2NPSb44OkuRIV5oyFFXYtkNg8uyN7JJ5U/FTiM+lHeMnaet6Vl/pril+y4h/Hlfcp6a4pfsmIfx5X3KcRn0o70MnaahSsv9NcUv2XEP48r7lfTN74nh1Jdh4kpvfeSiRKBI+Y8h1+6nEp9KO9DJ2mnUqCxPK2soivhTCoNzhrDM6A4oKVHc5QodR0UlQIUlQ8QfUQQJ2tGcJU5OMlnIeYUpSqEClKUApSlAKUpQClKUApSlAZfwkO+GOMH/p7X8oq21UuEnwY4x9Xs/yirbXbxPt59b8S0tLFKVEYrldqzWzIutlleewFvPRw92a29radW04NKAPRbaxvWjrY2CDWsVJelKhMkzWx4lbrvOutyZjM2mF6RnJBLjrEbv8A40tpBXyns3ANDqUKA2QaAm6Vxx325Udp5pXM04kLQrWtgjYNclSBSuvCuMS5JeVElMyksuqYdLLgWEOJOlIVrwUD0IPUV2KAqfDhRPFbiON9Am2aH/ZXWn1l/Df4WOJH9W2exXWoVTH+2/bD+ES0tIpSlc8qKUpQClKUApSlAKUpQClKUBl/CP4McX+r2f5RVtqpcJPgxxj6vZ/lFW2u3ifbz634lpfiZ584RR5+aYzjfEa6Z5dbVd7hdXRIguzv6OcQJTrKYKYqlBtKtJSgKSO05hvZNZ5jUC44rwKt+cW7I71GuETMHWGoLU1aIJju5Ath1pyODyOcwccVzqBUCoAEAAV6Ki8C8HhZZ+EjNjCLmJSp6U+dPmMiSrfM+mMV9ilw7J5wgK2Sd7O67/uUYr+BwxX0X/QImekBE84d/L+ded8/Pzc35fv63r1a5elaeSyp5z405Zkq4PEzM8Wn3lmJi0lyOmfNyVcKKxIYQ2FtMQGmVIkJ5zo9uUlSlKAUBo1xcYLLHl3/AMoC6qeuHnCeH8R5LRuUgsAuNzgoFrn5CkcoISU6SSpSQCpRO/3jgNgt/n3iVPsZf9Mc5nxfPJCYshakcinVRw4Gu15ena8vOPEKB6183PgJhF6A8+tcqSr0SqxuLcuksrfhkLHZOq7Xbug4vSllSk8xIINRksGYTJl24WZTw6mW/IbvkAv1ouBuEGdMU9HfWxBEht1lrfKz30BOmwBp0D4q6Nnm3ixYRwcz1vKr1db3lNztbV1jyri45CkonI26hEYns2uy5ipPZpSQG+u+tbXjHB3EsPvaLta7Y43OaYVFjqkTX5CIjKiCpthDi1JYQSB3WwkdPCurj3ArB8VvUW6WyyliREccehsrmSHY0NawQtTEdbhaZJClDbaU9CfjqclgqXksWRiz41mQZenPby+8s7mz35R5W5jiE9XVq66A5leKj1USetbVUFjeEWXEZt5lWiGYbt3lKnTQHnFIcfV75YQpRSgqPU8oGz1OzU7VkrKwKlw3+FjiR/VtnsV1qFZfw3+FjiR/VtnsV1qFRj/bfth/CJaWkUpSueVFKUoBSlKAUpSgFKUoBSlKAy/hJ8GOL/V7P8oq21ToFpyfh/GRZIFgcya0xgRCmMTGWXUtE91p1Lik95I6cyTogA6B2K+blmWT2mL5xJ4f3QNc7bf4qZFdUVLWEJHKlwn3yh1108ToAmu/VgqtSVSEo2bb/FFadjdy7V3cudKqqshy1IJPD+4AAbJNyhdP/wBa6lozXJb5bWJ8Ph/dFRX08zanZkVoqG/HlW4Do+IOuo0R0IrFwL6Ufij5kZLLrSqr+EGXf8vrh9pQv9WofMOJ92wDGLjkN/wudbrNbmi9KlLnxFBtA6b5UuEnqQNAEndOBfSj8UfMZLNCpVMteZ5He7ZEuNvwaZMgy2USI8hm5wlIdbUkKSpJ7XqCCCPprjtWcZHem5C4mA3NYjyHIrqXJsVtSXEKKVApU4DrpsHWlJKVJJSoEuBfSj8UfMZLLvSqt+EGXf8AL64faUL/AFa4JuVZZBhSJK+HlzWlltThS3OiuKIAJ0EocUpR6eCQSfUCacC+lH4o+YyWffDf4WOJH9W2exXWoVS+G9kWwi5X+Wto3O9qZfeaY5uWO2lpIaa73UqCTskhOys9ANVdK0sZONSteL0KK3RSfehLSKUpWkVFKUoBSlKAUpSgFKUoBSlRV5ursVxuDCZLt0lMvLjFxtZjoKEjq6sDup5lIGvfHm6AgKIA7FyurVsVDQ42+6uXITHaSw0V94gqJUR0SkJSolRIHTXUkA9Ky2V1t5m6XXsnr8qMI7rkdbnYNp5ysoaSo6T1IBWAFL5Ec3vUhPYtNkatr0iWo9vcpaWvO5RKvxhQgJASkqPZo8SEJ7oK1q98pRPBkd5VBbZgQn2Gr3cQ41b0yGXHWw4lBUVuJR1DaQOpJSCSlHMFLTsDhu6Xr7ck2psSmILfK9KuEOYlpSXEqQpMfSdr7yTtR7vdIAJ5iBP10rTaI1miqZjMNMlxxT7ymmwjtXVHa3FAeKlHZJNd2gFefvLiwTOuJ3Ax/F8CtXpe4XGewmYx50yxqMnmcJ26tKT30NjW99fDxI9A0oDyr/s+sT4lYZwlZhZc7bXsad53bSyiWtybBUHVJcZcRycnISCocrhKTsEd48vo24oftV/j3FoXKczM7OC9FZcSpiMAVqTIKD3h1VyKKD4FJKSE7TWODH9HxswsJ6Gz5LPQE/qokqTOQPoCZiQPmHzVernbYt6tsu3zmESoUtlbD7Dg2lxtSSlSSPiIJFAdqlQeOTVsOP2aYuK3Nh9WWW5hfdXEJKWXlhffBPKpJKt7UhXeNTlAQlwxlC5Uifa3UWm7SVsGRMaZSsyENE6bcB98ClS07BCgD0I0K+YuUIansW+7tIs9wlyX2ILLr6Vialsc4U0R6y3tRQQFDkc0ClBWZ2uN9huSy4y6kLbcSUKSfAgjRFAclKq7guGFw1KZRJvVihQm224qO0k3MLSvSlF1xwl8dmQdH8ZttXV1TgCbFGmx5od83faf7JwtOdksK5FjxSdeBHrFAc1KUoBSlKAUpSgFKUoCEvVzlKleiLYQzdHWO3TJkMqUw22HEJWdjXMvSlFKd+Ke9oEb71ss8OzpkiI12ZkyFynlqWpa3HFnZUpSiSemkgb0lKUpTpKQBGZelyJHhXdoXV9Vsf7dUG1KBVKQpKm1IW2ejiUhfaco0rmbTyn1KsFAfK1BCFKOyAN9Bs/uqHxtiU+hy7Tkzokq4ttOKtcx9DggAI/JAN9zm2VFZCl7USAtSEo12Mliidjt1jGIqeHojrZiIc7MvbQRyBf6JO9b9W91+46yY+P2xoxFQCiK0kxFudopnSAOQr/SI8N+vW6AkaUpQClKqebZTMhOxrDYEtP5RcUkx+2SVswmgdLlPAEEoRvogEFxZSgFIKloAiMWSYnGrPGWNOw5MG2S3VtnYbl6fbcbXr3quxbiqAPUhQPhreh1D4pi0PELOiBDU68StT0iXJUFPynlHa3nVAAFaj1OgAOgACQAJigIXIYTyVxbpDU0zKhKJdWYfnDj0Y9XWU674KtJUOX9JtGwodDJwJzFzhMS4y+0jvIC0K0RsH5j1B+Y9RXPUBOS5jk5+5NlTtukuB24mXOKW4aENkds0lQIA7qOdIUhOgpYBUVc4E/SuOPIalx2n2HUPMOpC23G1BSVpI2CCOhBHrrkoBURLx1pya3MhPrtckykSZK4qEDzzlR2fI9tJ5hy6G+ihyI0dDVS9KAgbDkapcv0RdEx4mRMxxKfhxnVOoDSnHG0OJUUp2FdmTojY8D8Znqrrdx/9Qn4HpdCv6LbfFp820pP45aS/wBr6weieT1cu/XVioBSlKAUpSgFKVWr/wAScVxaYYl2yC3wZY1zMOvp7ROwCNp8RsEEb8ayQpzqPJgm3sJSvoLGtCXEKQtIWhQ0UqGwR8RqtYzIbxiwJt9xQq0w7bIbtcN+4z0vmU2ShuOrtVHmK3CtCNL75X07xIUqO93DAvlXbf41fze4tcM72PKlxnI5meHiNjki8RnheH5AU7AYD/OppxsaS2hBUojswG9HYCSSkZ+J4n3ctzJyZaj+pl6jiXZ5zBYMoOsOILCV8hc2kjlCvVvw36t11sSjmJitmYMFdrLUJlBguPdsqPpsDsyv9Mp8Ob163Xljy3bZgfH3g7IZtuQ2yRlNlUZ1q06OZw606yCf10gfSpCKg/8AZ/2vEOB3CiXNv9+g2/KMifS/Miuu6Wwy1zJZbUPUe84r/uAeIpxPE+7luYyZaj2zSqP7uGBfKu2/xq69w4+YBboEiUrJob4ZbU4Wo6i44vQ3pKR1JPqFOJ4n3ctzGTLUWDMstRikBktxlXG6zXfNrdbW1cq5T5BITvR5UgBSlL0QlKVK660eLCcScxyPKl3GSm5ZFclh+5XAJ5Q4ob5Wm0knkZbB5UI2dDalFS1rWqocLcjsuXXx6/zL3bZuVzGSyxbmJSHPRsTYX5u0N95RKUqdcTvnUlI3yNthOqVgnTnTeTNNPaQ1bSKUpWMgUpSgIFCX8duIQlMmZa5ryUtttNNBu2ab6+HKotqUkepakrWdkI1yT1cUqKzOjPRpLLciO8gtuNOpCkLSRopUD0II6EGoOE8cYmM22QptNsfcQxawxHd/EAN9Wnl7UkdUq5VnkB5ko1zAFYFhpSlAV0XHXEMwPS6OtrD4tPm3e/Lcpf7X4uoTyf31Yqyp3j3w9azVCVcU8WRD9HqJgmfH5eftE/jO359A6Ouz3s73rpWq0ApSlAKUpQERmF0eseJXu4x9dvDgvyG+YbHMhtShsfSKpvDaCxFwmzvtpJfmxWpkl9ZKnH3nEBS3FqPVSiSep+jwAqzcSfg7yn6qlexVUBw+/MLGvqyN7JNdahmwza5ZfItzSfpSlUKilKUApSlAVbibEadwi8zCkpl2+I9MiSGzyuMPNoKkrQodUnaR4eI2D0Jq+2C4Lu9hts5xKUOSozb6kp8AVJBIH76pHEn4O8p+qpXsVVbMK/M2w/2CP7NNWr58NFvkk/BFuaTVKUrlFRSlKAVU+K8rIofDm/uYnZmsgyLzUohW96WYqHFqITsuAgjlBK9JUknl0FJJChbKoHFTiOrEWo9rtpbcv09tam+cgiK0OhfUn194gJSdcx310DWehQniKip01dslK54a8kTifxGwDykb7H4xSMhjG62pTTz9+LpaZLS1Os8vNtIT3nwgJ6bdOvfV7bV5RfD1J16fUfogySPZ1jSYKFTnZ8lbk65Onbs6UrtHl9Ne+PgNAAJGgPUBXYr19P0Hh1H72Tb2WS70xeJ5YvfAPCZXlds3diaj3K5Er0vIUIroDa+q1ROz5AvSnBoEAgJV47Ff0FT5RXD1Z0L+R86oMkD95brIaVl+xMHrlvX9ReOr63HpKwZRZ8pimRZ7nEubI1zKivJc5NjYCgD3T8x0alK8oCCY1xbudveXbLs0dtzovdcHh0V6lpOtFKgQRW98M+IQzmBIZlMCJeoHKmWygHs1BW+R1sn9BXKroTtJSpJ3oE8LH+i5YSPC03ePLrX+bRmedF0pSlcEgrnEn4O8p+qpXsVVAcPvzCxr6sjeyTU/xJ+DvKfqqV7FVQHD78wsa+rI3sk11qP5V/q+RbmkzNXIRDfVEaaflBtRZaecLaFr13QpYSopBOtkJOvHR8KwThrx4yq5cNcMkXOyQ7xl+Uy5LVsix7h2TTjTRWtx19fYAMpbSnl0lLhV3PEqIT6BrzzjXA7N8TsWFGG/YH7zhU6Ym3B2S+li4wZKVBaXlBoqYd7yCCkOAFHr5tDC73zFSyOeUI5BiXG3z8aWzm0S9R7EiwsTQ40+/Ia7ZlaZBQkdkWgtZUUBSQ2scpIANX4u8Xr6eHfEGyTYS8PzCzRoM1tdruan0OxnpKUJdZfCGle+Q4hQKUkfODXduHAjKbs/Py1+fZ2c8cyKHfo0Zsuqt7SI0cxkRlOFIcUFNOPEucg7ywQjSev5mHA/LuIkDObneH7JCyS+2+DaYUOJIediRI0eQXzzvKaStalqWs9GwBpI+M1X1gWORxvuk3NMhsmPYo3fG8fltxJ6Dd2o89ZU224pbEVSfxiEpdHeUtHMQQneq1usB4t8Ecq4mXS5suQMQKXHQq05YS/HvFnRoe8S22e1UkjaT2yAem09Ou+oSUoSCoqIGio+J+erq/KCu8Sfg7yn6qlexVVswr8zbD/YI/s01U+JPwd5T9VSvYqq2YV+Zth/sEf2aayV/wAsv1PwRbmk1SlK5RUUpSgFeX79dXb/AJ9lk94r23PVbmkKUSlDTA5AEj1bUXFfSs16grzBkFpcx/P8rgOhe3ZxuLS1JIC23xzbT8elhxO/jSa9N6CyeFqX02+av8ieRldzfLoOBYndMguPOYcBkurS2AVL9QSN9NkkAfTVHx7jbKmXFq333GHbBNm2td2tqTNQ+iU0hPMpClJSChYBBIIPTfWrZxOwhviPgV6xtx/zYT2ORD3LzdmsEKQoj1gKSNj4qzLh7wMu2PSVPXG1Ybb3GLc5DZfssRzt33VIKO1W4pI5NgnaUhW9n6K9HWlXVVKn+H6v3aNHaUPqyeUxJuNqxC9TMMkwLBkM5NtTcPPkOdk+pSkjSOUKUjaVd48vvVaB6bjuKPHK73LHuIkPG7BNNusSHYEjIo09LTjEkDRLbYAUQhXioK2B11XcTwHv44PYBinnlt9I4/eWbjKd7VzsVtocdUQg8myrTiehAHQ9a6t74G5swjiHZ8fuljbx3LH3ZpXO7bzlh1wbWgBKSnlUdDm2SB1AJrSk8W4Wd861K98nR1X7doNc4Yy37hw1xOVKeckyX7REcdeeWVrcWWUFSlKPUkkkkmrtg1wVZOJ+NykuBpuap22SByAlxK0FaBv5nGk/vPxmqng9kfxrCsftEpbbkm32+PEdUySUFbbaUqKSQCRsHWwPoq24Jb1XvifjkVLYdagl25yDzAFCUILaDr53HE/uPxGuhVSWFmqnRd9312lo6T0pSlK+ZgrnEj4O8p+qpXsVVAcPvzCxr6sjeyTVsy61O33FL1bWCkPzIT8dsqOgFLbUkb/vNUvhvcI8rDbTFbc1LgRGYsuMscrsd1CAlSFpPVJBSfEdfEbBBrrUM+GaXJL5FuaWelKVQqKUpQClKUBXOJPwd5T9VSvYqq2YV+Zth/sEf2aapnEyayjDLvb+btJ9xhvRIkRvvOvuLQUhKE+J6qBOvAbJ6A1frBb12ixW6C4oLXFjNsKUnwJSkAkfuq1fNhop8rfgi3NO/SlK5RUUpSgFUPihw5GYMsXGB2bN+goUGVrGhIbI2WFn1AnRCuvKeuiCoG+UrPRrTw9RVKbs0ToPKKpyY9yetsxtdvujKilyDKAQ6D8YG9KBHUKSSCOoNdivSV+xez5THSxeLXDubSd8iZbKXOTfQlJI7p+cdapa/J14eLUVHHEgn9WW+B+4OV66n6coOP3sWnss/FoWiZDStd/3c+HfydH/ANyR/qV9N+Tvw8bVzDHEH5lyn1D9xXqsv23hNUty/sLR1/W8xduYqfcBbbWwu7XZXvYUTvKHUDaz4NpBI2pRAFb3wy4e/gLbZDkqQJl6nlK5j6NhscoPI02D+gnmVonqSpROt6FjsmO2rGopjWi2xLZHJ5i3EZS0lR1rZCQNn5zUjXCx/pSWLjwVNZMe9/WoZlmQpSlcIgVA3jAsZyGWqVdMetdwlK0FPyYbbjh0NDaiN+FT1KvCcqbvB2ewm9ip+5JhHyRsn2e192nuSYR8kbJ9ntfdq2UrNxmv03vZOU9ZU/ckwj5I2T7Pa+7T3JMI+SNk+z2vu1bKU4zX6b3sZT1lT9yTCPkjZPs9r7tPckwj5I2T7Pa+7VspTjNfpvexlPWQVmwTG8dlCTa7BbLdJAID0WG22sA+I5gN6qdpSsMpym7zd2Re4pSlUIFKUoBSlKAUpSgFKUoBSlKAUpSgP//Z",
|
| 528 |
+
"text/plain": [
|
| 529 |
+
"<IPython.core.display.Image object>"
|
| 530 |
+
]
|
| 531 |
+
},
|
| 532 |
+
"metadata": {},
|
| 533 |
+
"output_type": "display_data"
|
| 534 |
+
}
|
| 535 |
+
],
|
| 536 |
+
"source": [
|
| 537 |
+
"from IPython.display import Image, display\n",
|
| 538 |
+
"\n",
|
| 539 |
+
"try:\n",
|
| 540 |
+
" display(Image(graph.get_graph().draw_mermaid_png()))\n",
|
| 541 |
+
"except Exception:\n",
|
| 542 |
+
" pass"
|
| 543 |
+
]
|
| 544 |
+
},
|
| 545 |
+
{
|
| 546 |
+
"cell_type": "markdown",
|
| 547 |
+
"metadata": {},
|
| 548 |
+
"source": [
|
| 549 |
+
"**Save the graph image**"
|
| 550 |
+
]
|
| 551 |
+
},
|
| 552 |
+
{
|
| 553 |
+
"cell_type": "code",
|
| 554 |
+
"execution_count": 17,
|
| 555 |
+
"metadata": {},
|
| 556 |
+
"outputs": [],
|
| 557 |
+
"source": [
|
| 558 |
+
"save = False\n",
|
| 559 |
+
"\n",
|
| 560 |
+
"if save:\n",
|
| 561 |
+
" from PIL import Image as PILImage\n",
|
| 562 |
+
" import io\n",
|
| 563 |
+
" # Assuming graph.get_graph().draw_mermaid_png() returns PNG binary data\n",
|
| 564 |
+
" try:\n",
|
| 565 |
+
" # Generate the PNG image from the graph\n",
|
| 566 |
+
" png_data = graph.get_graph().draw_mermaid_png()\n",
|
| 567 |
+
" \n",
|
| 568 |
+
" # Convert the binary data into an image\n",
|
| 569 |
+
" img = PILImage.open(io.BytesIO(png_data))\n",
|
| 570 |
+
" \n",
|
| 571 |
+
" # Save the image locally with 300 DPI\n",
|
| 572 |
+
" img.save('output_image.png', 'PNG', dpi=(300, 300))\n",
|
| 573 |
+
" \n",
|
| 574 |
+
" print(\"Image saved successfully with 300 DPI.\")\n",
|
| 575 |
+
" except Exception as e:\n",
|
| 576 |
+
" print(f\"Error: {e}\")"
|
| 577 |
+
]
|
| 578 |
+
},
|
| 579 |
+
{
|
| 580 |
+
"cell_type": "markdown",
|
| 581 |
+
"metadata": {},
|
| 582 |
+
"source": [
|
| 583 |
+
"### **6. Execute the graph**"
|
| 584 |
+
]
|
| 585 |
+
},
|
| 586 |
+
{
|
| 587 |
+
"cell_type": "code",
|
| 588 |
+
"execution_count": 18,
|
| 589 |
+
"metadata": {},
|
| 590 |
+
"outputs": [],
|
| 591 |
+
"source": [
|
| 592 |
+
"config = {\"configurable\": {\"thread_id\": \"1\"}}"
|
| 593 |
+
]
|
| 594 |
+
},
|
| 595 |
+
{
|
| 596 |
+
"cell_type": "markdown",
|
| 597 |
+
"metadata": {},
|
| 598 |
+
"source": [
|
| 599 |
+
"**First query**"
|
| 600 |
+
]
|
| 601 |
+
},
|
| 602 |
+
{
|
| 603 |
+
"cell_type": "markdown",
|
| 604 |
+
"metadata": {},
|
| 605 |
+
"source": [
|
| 606 |
+
"Approach 1: Print all the steps the the system goes through it to get the final output"
|
| 607 |
+
]
|
| 608 |
+
},
|
| 609 |
+
{
|
| 610 |
+
"cell_type": "code",
|
| 611 |
+
"execution_count": null,
|
| 612 |
+
"metadata": {},
|
| 613 |
+
"outputs": [
|
| 614 |
+
{
|
| 615 |
+
"name": "stdout",
|
| 616 |
+
"output_type": "stream",
|
| 617 |
+
"text": [
|
| 618 |
+
"================================\u001b[1m Human Message \u001b[0m=================================\n",
|
| 619 |
+
"\n",
|
| 620 |
+
"Hi there! My name is Farzad.\n"
|
| 621 |
+
]
|
| 622 |
+
}
|
| 623 |
+
],
|
| 624 |
+
"source": [
|
| 625 |
+
"user_input = \"Hi there! My name is Farzad.\"\n",
|
| 626 |
+
"\n",
|
| 627 |
+
"# The config is the **second positional argument** to stream() or invoke()!\n",
|
| 628 |
+
"events = graph.stream(\n",
|
| 629 |
+
" {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n",
|
| 630 |
+
")\n",
|
| 631 |
+
"for event in events:\n",
|
| 632 |
+
" event[\"messages\"][-1].pretty_print()"
|
| 633 |
+
]
|
| 634 |
+
},
|
| 635 |
+
{
|
| 636 |
+
"cell_type": "markdown",
|
| 637 |
+
"metadata": {},
|
| 638 |
+
"source": [
|
| 639 |
+
"Approach 2: Just print the final output"
|
| 640 |
+
]
|
| 641 |
+
},
|
| 642 |
+
{
|
| 643 |
+
"cell_type": "code",
|
| 644 |
+
"execution_count": 55,
|
| 645 |
+
"metadata": {},
|
| 646 |
+
"outputs": [
|
| 647 |
+
{
|
| 648 |
+
"data": {
|
| 649 |
+
"text/plain": [
|
| 650 |
+
"'Hello again, Farzad! How can I help you today?'"
|
| 651 |
+
]
|
| 652 |
+
},
|
| 653 |
+
"execution_count": 55,
|
| 654 |
+
"metadata": {},
|
| 655 |
+
"output_type": "execute_result"
|
| 656 |
+
}
|
| 657 |
+
],
|
| 658 |
+
"source": [
|
| 659 |
+
"from langchain_core.messages import HumanMessage\n",
|
| 660 |
+
"user_input = \"Hi there! My name is Farzad.\"\n",
|
| 661 |
+
"\n",
|
| 662 |
+
"# Use the Runnable\n",
|
| 663 |
+
"final_state = graph.invoke(\n",
|
| 664 |
+
" {\"messages\": [HumanMessage(content=user_input)]},\n",
|
| 665 |
+
" config=config\n",
|
| 666 |
+
")\n",
|
| 667 |
+
"final_state[\"messages\"][-1].content"
|
| 668 |
+
]
|
| 669 |
+
},
|
| 670 |
+
{
|
| 671 |
+
"cell_type": "markdown",
|
| 672 |
+
"metadata": {},
|
| 673 |
+
"source": [
|
| 674 |
+
"**Second query**"
|
| 675 |
+
]
|
| 676 |
+
},
|
| 677 |
+
{
|
| 678 |
+
"cell_type": "code",
|
| 679 |
+
"execution_count": 56,
|
| 680 |
+
"metadata": {},
|
| 681 |
+
"outputs": [
|
| 682 |
+
{
|
| 683 |
+
"name": "stdout",
|
| 684 |
+
"output_type": "stream",
|
| 685 |
+
"text": [
|
| 686 |
+
"================================\u001b[1m Human Message \u001b[0m=================================\n",
|
| 687 |
+
"\n",
|
| 688 |
+
"Can I cancel my ticket 10 hours before the flight?\n",
|
| 689 |
+
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
|
| 690 |
+
"Tool Calls:\n",
|
| 691 |
+
" lookup_policy (call_PnEdkdZICkTDuytncfiYhJo2)\n",
|
| 692 |
+
" Call ID: call_PnEdkdZICkTDuytncfiYhJo2\n",
|
| 693 |
+
" Args:\n",
|
| 694 |
+
" query: ticket cancellation policy\n",
|
| 695 |
+
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
|
| 696 |
+
"Name: lookup_policy\n",
|
| 697 |
+
"\n",
|
| 698 |
+
"\"for a refund or may only be able to receive a partial refund. If you booked your flight through a third-party website or\\ntravel agent, you may need to contact them directly to cancel your flight. Always check the terms and conditions of your\\nticket to make sure you understand the cancellation policy and any associated fees or penalties. If you're cancelling your\\nflight due to unforeseen circumstances such as a medical emergency or a natural disaster , Swiss Air may of fer you\\nspecial exemptions or accommodations. What is Swiss Airlines 24 Hour Cancellation Policy? Swiss Airlines has a 24\\n\\nhour cancellation policy that allows passengers to cancel their flights within 24 hours of booking at +1-877-507-7341\\nwithout penalty . This policy applies to all fare types, including non-refundable tickets. If you cancel your Swiss Airlines\\nflight within 24 hours of booking, you'll receive a full refund of your ticket price.\\nHow to Cancel Swiss Airlines Flight within 24 Hours? If you need to cancel your Swiss Airlines flight within 24 hours of\\nbooking, you can do so easily online. Here are the steps to follow:\\nGo to Swiss Airlines' website and click on the \\\"Manage your bookings\\\" tab. Enter your booking reference number and last\\nname to access your booking. Select the flight you want to cancel and click on \\\"Cancel flight.\\\" Confirm your cancellation\\nand you'll receive a full refund of your ticket price. If you booked your Swiss Airlines flight through a travel agent, you'll\\nneed to contact them directly to cancel your flight within 24 hours.\\nImportant Things to Keep in Mind for Swiss Airlines 24 Hour Cancellation Here are some important things to keep in mind\\nwhen cancelling your Swiss Airlines flight within 24 hours:\\nSwiss Airlines' 24 hour cancellation policy only applies to flights booked directly through Swiss Airlines. If you booked\\nyour flight through a travel agent or third-party website, you'll need to check their cancellation policy . If you cancel your\\nSwiss Airlines flight after the 24 hour window , you may be subject to cancellation fees or penalties. If you have a non-\\nrefundable ticket and cancel your flight within 24 hours of booking, you'll receive a full refund of your ticket price.\\nHowever , if you cancel your flight after the 24 hour window , you may not be eligible for a refund. Swiss Airlines' 24 hour\\ncancellation policy allows passengers to cancel their flights within 24 hours of booking without penalty . If you need to\\ncancel your Swiss Airlines flight within 24 hours, you can do so easily online. Just remember to check the terms and\\nconditions of your ticket to make sure you're eligible for a refund.\\nSwiss Air Cancellation Fees The cancellation fees for Swiss Air flights may vary depending on the type of ticket you have\\npurchased. The airline of fers three dif ferent types of tickets, which are:\"\n",
|
| 699 |
+
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
|
| 700 |
+
"\n",
|
| 701 |
+
"You can cancel your ticket with Swiss Airlines, but the ability to receive a refund or avoid penalties depends on the timing and the type of ticket you purchased. Here are some key points regarding ticket cancellation:\n",
|
| 702 |
+
"\n",
|
| 703 |
+
"1. **24-Hour Cancellation Policy**: If you booked your flight directly through Swiss Airlines, you can cancel your flight within 24 hours of booking without penalty and receive a full refund.\n",
|
| 704 |
+
"\n",
|
| 705 |
+
"2. **Cancellation 10 Hours Before Flight**: If you are looking to cancel your ticket 10 hours before the flight, you may be subject to cancellation fees or penalties, especially if you have a non-refundable ticket. The specific fees can vary based on the type of ticket you purchased.\n",
|
| 706 |
+
"\n",
|
| 707 |
+
"3. **Contacting Third Parties**: If you booked your flight through a third-party website or travel agent, you will need to contact them directly to cancel your flight.\n",
|
| 708 |
+
"\n",
|
| 709 |
+
"4. **Special Exemptions**: In cases of unforeseen circumstances (like medical emergencies), Swiss Airlines may offer special exemptions or accommodations.\n",
|
| 710 |
+
"\n",
|
| 711 |
+
"It's always best to check the terms and conditions of your specific ticket for detailed information on cancellation policies and any associated fees.\n"
|
| 712 |
+
]
|
| 713 |
+
}
|
| 714 |
+
],
|
| 715 |
+
"source": [
|
| 716 |
+
"user_input = \"Can I cancel my ticket 10 hours before the flight?\"\n",
|
| 717 |
+
"\n",
|
| 718 |
+
"events = graph.stream(\n",
|
| 719 |
+
" {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n",
|
| 720 |
+
")\n",
|
| 721 |
+
"for event in events:\n",
|
| 722 |
+
" event[\"messages\"][-1].pretty_print()"
|
| 723 |
+
]
|
| 724 |
+
},
|
| 725 |
+
{
|
| 726 |
+
"cell_type": "markdown",
|
| 727 |
+
"metadata": {},
|
| 728 |
+
"source": [
|
| 729 |
+
"**Third query**"
|
| 730 |
+
]
|
| 731 |
+
},
|
| 732 |
+
{
|
| 733 |
+
"cell_type": "code",
|
| 734 |
+
"execution_count": 57,
|
| 735 |
+
"metadata": {},
|
| 736 |
+
"outputs": [
|
| 737 |
+
{
|
| 738 |
+
"name": "stdout",
|
| 739 |
+
"output_type": "stream",
|
| 740 |
+
"text": [
|
| 741 |
+
"================================\u001b[1m Human Message \u001b[0m=================================\n",
|
| 742 |
+
"\n",
|
| 743 |
+
"Right now Harris vs. Trump Presidential Debate is being boradcasted. I want the youtube link to this debate\n",
|
| 744 |
+
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
|
| 745 |
+
"Tool Calls:\n",
|
| 746 |
+
" tavily_search_results_json (call_1jy65jCBXDpiaiDrn9n93HBC)\n",
|
| 747 |
+
" Call ID: call_1jy65jCBXDpiaiDrn9n93HBC\n",
|
| 748 |
+
" Args:\n",
|
| 749 |
+
" query: Harris Trump Presidential Debate YouTube link\n",
|
| 750 |
+
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
|
| 751 |
+
"Name: tavily_search_results_json\n",
|
| 752 |
+
"\n",
|
| 753 |
+
"[{\"url\": \"https://www.pbs.org/newshour/politics/watch-live-harris-and-trump-debate-pbs-news-simulcast-of-abcs-2024-presidential-debate\", \"content\": \"WATCH: Harris and Trump debate \\u2014 PBS News simulcast of ABC\\u2019s 2024 Presidential Debate Vice President Kamala Harris and former President Donald Trump faced off Tuesday night for their first and possibly only debate before Election Day. The state of the race as they meet in Philadelphia is starkly different than it was just more than two months ago, when Trump debated President Joe Biden in a performance that accelerated calls for Biden to leave the race. WATCH: What to watch in the ABC Harris-Trump debate Watch PBS News\\u2019 special coverage here and the\\u00a0ABC Presidential Debate in the player above. This year\\u2019s presidential race is a genuine contest of ideas between Harris and Trump \\u2014 with clear differences on taxes, abortion, immigration, global alliances, climate change and democracy itself. LIVE FACT CHECK: Trump and Harris meet for presidential debate\"}, {\"url\": \"https://abcnews.go.com/Politics/watch-full-abc-news-presidential-debate/story?id=113470583\", \"content\": \"MORE: READ: Harris-Trump presidential debate transcript Democratic presidential nominee Vice President Kamala Harris shakes hands with former President Donald Trump, during a presidential debate ...\"}]\n",
|
| 754 |
+
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
|
| 755 |
+
"\n",
|
| 756 |
+
"You can watch the Harris vs. Trump Presidential Debate through the following links:\n",
|
| 757 |
+
"\n",
|
| 758 |
+
"1. [PBS News Simulcast of the Debate](https://www.pbs.org/newshour/politics/watch-live-harris-and-trump-debate-pbs-news-simulcast-of-abcs-2024-presidential-debate)\n",
|
| 759 |
+
"2. [ABC News Full Debate Coverage](https://abcnews.go.com/Politics/watch-full-abc-news-presidential-debate/story?id=113470583)\n",
|
| 760 |
+
"\n",
|
| 761 |
+
"Feel free to check them out!\n"
|
| 762 |
+
]
|
| 763 |
+
}
|
| 764 |
+
],
|
| 765 |
+
"source": [
|
| 766 |
+
"user_input = \"Right now Harris vs. Trump Presidential Debate is being boradcasted. I want the youtube link to this debate\"\n",
|
| 767 |
+
"\n",
|
| 768 |
+
"events = graph.stream(\n",
|
| 769 |
+
" {\"messages\": [(\"user\", user_input)]}, config, stream_mode=\"values\"\n",
|
| 770 |
+
")\n",
|
| 771 |
+
"for event in events:\n",
|
| 772 |
+
" event[\"messages\"][-1].pretty_print()"
|
| 773 |
+
]
|
| 774 |
+
},
|
| 775 |
+
{
|
| 776 |
+
"cell_type": "code",
|
| 777 |
+
"execution_count": 58,
|
| 778 |
+
"metadata": {},
|
| 779 |
+
"outputs": [
|
| 780 |
+
{
|
| 781 |
+
"data": {
|
| 782 |
+
"text/plain": [
|
| 783 |
+
"{'messages': [HumanMessage(content='Hi there! My name is Farzad.', id='5aa78bed-a259-4d29-91c0-0e00d4113895'),\n",
|
| 784 |
+
" AIMessage(content='Hello Farzad! How can I assist you today?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 12, 'prompt_tokens': 149, 'total_tokens': 161, 'prompt_tokens_details': {'cached_tokens': 0}, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_f85bea6784', 'finish_reason': 'stop', 'logprobs': None}, id='run-6a8c7f6f-0647-4569-a1ff-58747953ad59-0', usage_metadata={'input_tokens': 149, 'output_tokens': 12, 'total_tokens': 161}),\n",
|
| 785 |
+
" HumanMessage(content='Hi there! My name is Farzad.', id='45b30b4e-7aca-45f7-945d-48f4f3f738f0'),\n",
|
| 786 |
+
" AIMessage(content='Hello again, Farzad! How can I help you today?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 177, 'total_tokens': 191, 'prompt_tokens_details': {'cached_tokens': 0}, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_f85bea6784', 'finish_reason': 'stop', 'logprobs': None}, id='run-632913bf-ab5b-4ddb-8806-aa609e10086c-0', usage_metadata={'input_tokens': 177, 'output_tokens': 14, 'total_tokens': 191}),\n",
|
| 787 |
+
" HumanMessage(content='Can I cancel my ticket 10 hours before the flight?', id='5a4cd448-96ea-4d6a-b865-ba9aa7661136'),\n",
|
| 788 |
+
" AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_PnEdkdZICkTDuytncfiYhJo2', 'function': {'arguments': '{\"query\":\"ticket cancellation policy\"}', 'name': 'lookup_policy'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 210, 'total_tokens': 226, 'prompt_tokens_details': {'cached_tokens': 0}, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_f85bea6784', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-dc4bc2d4-19a5-4ee6-b163-a7fc7e533489-0', tool_calls=[{'name': 'lookup_policy', 'args': {'query': 'ticket cancellation policy'}, 'id': 'call_PnEdkdZICkTDuytncfiYhJo2', 'type': 'tool_call'}], usage_metadata={'input_tokens': 210, 'output_tokens': 16, 'total_tokens': 226}),\n",
|
| 789 |
+
" ToolMessage(content='\"for a refund or may only be able to receive a partial refund. If you booked your flight through a third-party website or\\\\ntravel agent, you may need to contact them directly to cancel your flight. Always check the terms and conditions of your\\\\nticket to make sure you understand the cancellation policy and any associated fees or penalties. If you\\'re cancelling your\\\\nflight due to unforeseen circumstances such as a medical emergency or a natural disaster , Swiss Air may of fer you\\\\nspecial exemptions or accommodations. What is Swiss Airlines 24 Hour Cancellation Policy? Swiss Airlines has a 24\\\\n\\\\nhour cancellation policy that allows passengers to cancel their flights within 24 hours of booking at +1-877-507-7341\\\\nwithout penalty . This policy applies to all fare types, including non-refundable tickets. If you cancel your Swiss Airlines\\\\nflight within 24 hours of booking, you\\'ll receive a full refund of your ticket price.\\\\nHow to Cancel Swiss Airlines Flight within 24 Hours? If you need to cancel your Swiss Airlines flight within 24 hours of\\\\nbooking, you can do so easily online. Here are the steps to follow:\\\\nGo to Swiss Airlines\\' website and click on the \\\\\"Manage your bookings\\\\\" tab. Enter your booking reference number and last\\\\nname to access your booking. Select the flight you want to cancel and click on \\\\\"Cancel flight.\\\\\" Confirm your cancellation\\\\nand you\\'ll receive a full refund of your ticket price. If you booked your Swiss Airlines flight through a travel agent, you\\'ll\\\\nneed to contact them directly to cancel your flight within 24 hours.\\\\nImportant Things to Keep in Mind for Swiss Airlines 24 Hour Cancellation Here are some important things to keep in mind\\\\nwhen cancelling your Swiss Airlines flight within 24 hours:\\\\nSwiss Airlines\\' 24 hour cancellation policy only applies to flights booked directly through Swiss Airlines. If you booked\\\\nyour flight through a travel agent or third-party website, you\\'ll need to check their cancellation policy . If you cancel your\\\\nSwiss Airlines flight after the 24 hour window , you may be subject to cancellation fees or penalties. If you have a non-\\\\nrefundable ticket and cancel your flight within 24 hours of booking, you\\'ll receive a full refund of your ticket price.\\\\nHowever , if you cancel your flight after the 24 hour window , you may not be eligible for a refund. Swiss Airlines\\' 24 hour\\\\ncancellation policy allows passengers to cancel their flights within 24 hours of booking without penalty . If you need to\\\\ncancel your Swiss Airlines flight within 24 hours, you can do so easily online. Just remember to check the terms and\\\\nconditions of your ticket to make sure you\\'re eligible for a refund.\\\\nSwiss Air Cancellation Fees The cancellation fees for Swiss Air flights may vary depending on the type of ticket you have\\\\npurchased. The airline of fers three dif ferent types of tickets, which are:\"', name='lookup_policy', id='306a3eb2-1d47-48cb-baa3-1a721072a1df', tool_call_id='call_PnEdkdZICkTDuytncfiYhJo2'),\n",
|
| 790 |
+
" AIMessage(content=\"You can cancel your ticket with Swiss Airlines, but the ability to receive a refund or avoid penalties depends on the timing and the type of ticket you purchased. Here are some key points regarding ticket cancellation:\\n\\n1. **24-Hour Cancellation Policy**: If you booked your flight directly through Swiss Airlines, you can cancel your flight within 24 hours of booking without penalty and receive a full refund.\\n\\n2. **Cancellation 10 Hours Before Flight**: If you are looking to cancel your ticket 10 hours before the flight, you may be subject to cancellation fees or penalties, especially if you have a non-refundable ticket. The specific fees can vary based on the type of ticket you purchased.\\n\\n3. **Contacting Third Parties**: If you booked your flight through a third-party website or travel agent, you will need to contact them directly to cancel your flight.\\n\\n4. **Special Exemptions**: In cases of unforeseen circumstances (like medical emergencies), Swiss Airlines may offer special exemptions or accommodations.\\n\\nIt's always best to check the terms and conditions of your specific ticket for detailed information on cancellation policies and any associated fees.\", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 226, 'prompt_tokens': 819, 'total_tokens': 1045, 'prompt_tokens_details': {'cached_tokens': 0}, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_f85bea6784', 'finish_reason': 'stop', 'logprobs': None}, id='run-c83ed911-1952-4ece-b16f-41c9d515b6f3-0', usage_metadata={'input_tokens': 819, 'output_tokens': 226, 'total_tokens': 1045}),\n",
|
| 791 |
+
" HumanMessage(content='Right now Harris vs. Trump Presidential Debate is being boradcasted. I want the youtube link to this debate', id='4706cd31-61e5-4a67-bb17-c4eb3e17b0e1'),\n",
|
| 792 |
+
" AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_1jy65jCBXDpiaiDrn9n93HBC', 'function': {'arguments': '{\"query\":\"Harris Trump Presidential Debate YouTube link\"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 25, 'prompt_tokens': 1075, 'total_tokens': 1100, 'prompt_tokens_details': {'cached_tokens': 0}, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_f85bea6784', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-c25bda9e-c897-4e44-b7c6-94c9f32933e9-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'Harris Trump Presidential Debate YouTube link'}, 'id': 'call_1jy65jCBXDpiaiDrn9n93HBC', 'type': 'tool_call'}], usage_metadata={'input_tokens': 1075, 'output_tokens': 25, 'total_tokens': 1100}),\n",
|
| 793 |
+
" ToolMessage(content='[{\"url\": \"https://www.pbs.org/newshour/politics/watch-live-harris-and-trump-debate-pbs-news-simulcast-of-abcs-2024-presidential-debate\", \"content\": \"WATCH: Harris and Trump debate \\\\u2014 PBS News simulcast of ABC\\\\u2019s 2024 Presidential Debate Vice President Kamala Harris and former President Donald Trump faced off Tuesday night for their first and possibly only debate before Election Day. The state of the race as they meet in Philadelphia is starkly different than it was just more than two months ago, when Trump debated President Joe Biden in a performance that accelerated calls for Biden to leave the race. WATCH: What to watch in the ABC Harris-Trump debate Watch PBS News\\\\u2019 special coverage here and the\\\\u00a0ABC Presidential Debate in the player above. This year\\\\u2019s presidential race is a genuine contest of ideas between Harris and Trump \\\\u2014 with clear differences on taxes, abortion, immigration, global alliances, climate change and democracy itself. LIVE FACT CHECK: Trump and Harris meet for presidential debate\"}, {\"url\": \"https://abcnews.go.com/Politics/watch-full-abc-news-presidential-debate/story?id=113470583\", \"content\": \"MORE: READ: Harris-Trump presidential debate transcript Democratic presidential nominee Vice President Kamala Harris shakes hands with former President Donald Trump, during a presidential debate ...\"}]', name='tavily_search_results_json', id='45c00f98-cf0e-4e5b-b19a-c3da9ec63434', tool_call_id='call_1jy65jCBXDpiaiDrn9n93HBC'),\n",
|
| 794 |
+
" AIMessage(content='You can watch the Harris vs. Trump Presidential Debate through the following links:\\n\\n1. [PBS News Simulcast of the Debate](https://www.pbs.org/newshour/politics/watch-live-harris-and-trump-debate-pbs-news-simulcast-of-abcs-2024-presidential-debate)\\n2. [ABC News Full Debate Coverage](https://abcnews.go.com/Politics/watch-full-abc-news-presidential-debate/story?id=113470583)\\n\\nFeel free to check them out!', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 106, 'prompt_tokens': 1405, 'total_tokens': 1511, 'prompt_tokens_details': {'cached_tokens': 1024}, 'completion_tokens_details': {'reasoning_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_f85bea6784', 'finish_reason': 'stop', 'logprobs': None}, id='run-c011a865-0f6e-47f3-aae6-f139aeba11ca-0', usage_metadata={'input_tokens': 1405, 'output_tokens': 106, 'total_tokens': 1511})]}"
|
| 795 |
+
]
|
| 796 |
+
},
|
| 797 |
+
"execution_count": 58,
|
| 798 |
+
"metadata": {},
|
| 799 |
+
"output_type": "execute_result"
|
| 800 |
+
}
|
| 801 |
+
],
|
| 802 |
+
"source": [
|
| 803 |
+
"event"
|
| 804 |
+
]
|
| 805 |
+
}
|
| 806 |
+
],
|
| 807 |
+
"metadata": {
|
| 808 |
+
"kernelspec": {
|
| 809 |
+
"display_name": "querymind (3.12.10)",
|
| 810 |
+
"language": "python",
|
| 811 |
+
"name": "python3"
|
| 812 |
+
},
|
| 813 |
+
"language_info": {
|
| 814 |
+
"codemirror_mode": {
|
| 815 |
+
"name": "ipython",
|
| 816 |
+
"version": 3
|
| 817 |
+
},
|
| 818 |
+
"file_extension": ".py",
|
| 819 |
+
"mimetype": "text/x-python",
|
| 820 |
+
"name": "python",
|
| 821 |
+
"nbconvert_exporter": "python",
|
| 822 |
+
"pygments_lexer": "ipython3",
|
| 823 |
+
"version": "3.12.10"
|
| 824 |
+
}
|
| 825 |
+
},
|
| 826 |
+
"nbformat": 4,
|
| 827 |
+
"nbformat_minor": 2
|
| 828 |
+
}
|
Notebooks/python_tip_automatic_docstring/automatic_docstring.ipynb
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 2,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [],
|
| 8 |
+
"source": [
|
| 9 |
+
"from langchain_core.tools import tool"
|
| 10 |
+
]
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
"cell_type": "code",
|
| 14 |
+
"execution_count": 3,
|
| 15 |
+
"metadata": {},
|
| 16 |
+
"outputs": [
|
| 17 |
+
{
|
| 18 |
+
"name": "stdout",
|
| 19 |
+
"output_type": "stream",
|
| 20 |
+
"text": [
|
| 21 |
+
"Old docstring:\n",
|
| 22 |
+
"Tool that can operate on any number of inputs.\n",
|
| 23 |
+
"\n",
|
| 24 |
+
"Updated docstring:\n",
|
| 25 |
+
"This function now queries a different database and returns updated results.\n"
|
| 26 |
+
]
|
| 27 |
+
}
|
| 28 |
+
],
|
| 29 |
+
"source": [
|
| 30 |
+
"class YourClass:\n",
|
| 31 |
+
" @tool\n",
|
| 32 |
+
" def query_sqldb(self, query):\n",
|
| 33 |
+
" \"\"\"Query the Swiss Airline SQL Database and access all the company's information. Input should be a search query.\"\"\"\n",
|
| 34 |
+
" response = self.chain.invoke({\"question\": query})\n",
|
| 35 |
+
" return response\n",
|
| 36 |
+
"\n",
|
| 37 |
+
" def update_description(self, new_description):\n",
|
| 38 |
+
" \"\"\"Updates the description (docstring) of the query_sqldb function.\"\"\"\n",
|
| 39 |
+
" self.query_sqldb.__doc__ = new_description\n",
|
| 40 |
+
"\n",
|
| 41 |
+
"# Usage examples\n",
|
| 42 |
+
"your_object = YourClass()\n",
|
| 43 |
+
"print(\"Old docstring:\")\n",
|
| 44 |
+
"print(your_object.query_sqldb.__doc__)\n",
|
| 45 |
+
"\n",
|
| 46 |
+
"# Update the description\n",
|
| 47 |
+
"new_description = \"This function now queries a different database and returns updated results.\"\n",
|
| 48 |
+
"your_object.update_description(new_description)\n",
|
| 49 |
+
"\n",
|
| 50 |
+
"print(\"\\nUpdated docstring:\")\n",
|
| 51 |
+
"print(your_object.query_sqldb.__doc__)"
|
| 52 |
+
]
|
| 53 |
+
}
|
| 54 |
+
],
|
| 55 |
+
"metadata": {
|
| 56 |
+
"kernelspec": {
|
| 57 |
+
"display_name": "rag-sqlagent",
|
| 58 |
+
"language": "python",
|
| 59 |
+
"name": "python3"
|
| 60 |
+
},
|
| 61 |
+
"language_info": {
|
| 62 |
+
"codemirror_mode": {
|
| 63 |
+
"name": "ipython",
|
| 64 |
+
"version": 3
|
| 65 |
+
},
|
| 66 |
+
"file_extension": ".py",
|
| 67 |
+
"mimetype": "text/x-python",
|
| 68 |
+
"name": "python",
|
| 69 |
+
"nbconvert_exporter": "python",
|
| 70 |
+
"pygments_lexer": "ipython3",
|
| 71 |
+
"version": "3.11.9"
|
| 72 |
+
}
|
| 73 |
+
},
|
| 74 |
+
"nbformat": 4,
|
| 75 |
+
"nbformat_minor": 2
|
| 76 |
+
}
|
Notebooks/test_groq_models/Llama.ipynb
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [
|
| 8 |
+
{
|
| 9 |
+
"data": {
|
| 10 |
+
"text/plain": [
|
| 11 |
+
"True"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
"execution_count": 1,
|
| 15 |
+
"metadata": {},
|
| 16 |
+
"output_type": "execute_result"
|
| 17 |
+
}
|
| 18 |
+
],
|
| 19 |
+
"source": [
|
| 20 |
+
"import os\n",
|
| 21 |
+
"from dotenv import load_dotenv\n",
|
| 22 |
+
"import base64\n",
|
| 23 |
+
"from openai import OpenAI\n",
|
| 24 |
+
"load_dotenv()"
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"cell_type": "code",
|
| 29 |
+
"execution_count": 2,
|
| 30 |
+
"metadata": {},
|
| 31 |
+
"outputs": [],
|
| 32 |
+
"source": [
|
| 33 |
+
"os.environ['OPENAI_API_KEY'] = os.getenv(\"OPEN_AI_API_KEY\")\n",
|
| 34 |
+
"client = OpenAI(api_key=os.environ[\"OPENAI_API_KEY\"])"
|
| 35 |
+
]
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"cell_type": "code",
|
| 39 |
+
"execution_count": 3,
|
| 40 |
+
"metadata": {},
|
| 41 |
+
"outputs": [],
|
| 42 |
+
"source": [
|
| 43 |
+
"# Define the model name\n",
|
| 44 |
+
"model = \"gpt-4o\""
|
| 45 |
+
]
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"cell_type": "code",
|
| 49 |
+
"execution_count": 4,
|
| 50 |
+
"metadata": {},
|
| 51 |
+
"outputs": [],
|
| 52 |
+
"source": [
|
| 53 |
+
"# Function to perform text-based inference\n",
|
| 54 |
+
"def text_inference(prompt:str)->str:\n",
|
| 55 |
+
" \"\"\"\n",
|
| 56 |
+
" Sends a text prompt to the AI model for inference and returns the model's response.\n",
|
| 57 |
+
"\n",
|
| 58 |
+
" Args:\n",
|
| 59 |
+
" prompt (str): The text prompt or question to be sent to the AI model.\n",
|
| 60 |
+
"\n",
|
| 61 |
+
" Returns:\n",
|
| 62 |
+
" str: The model's response based on the given text prompt.\n",
|
| 63 |
+
" \"\"\"\n",
|
| 64 |
+
" response = client.chat.completions.create(\n",
|
| 65 |
+
" model=model,\n",
|
| 66 |
+
" messages=[\n",
|
| 67 |
+
" {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n",
|
| 68 |
+
" {\"role\": \"user\", \"content\": prompt}\n",
|
| 69 |
+
" ]\n",
|
| 70 |
+
" )\n",
|
| 71 |
+
" return response.choices[0].message.content\n",
|
| 72 |
+
"\n",
|
| 73 |
+
"# Function to perform image-based inference\n",
|
| 74 |
+
"def image_inference(image_path:str, prompt:str)->str:\n",
|
| 75 |
+
" \"\"\"\n",
|
| 76 |
+
" Sends a text prompt and an image to the AI model for inference, returning the model's response.\n",
|
| 77 |
+
"\n",
|
| 78 |
+
" Args:\n",
|
| 79 |
+
" image_path (str): The file path to the image to be sent to the AI model.\n",
|
| 80 |
+
" prompt (str): The text prompt or question accompanying the image.\n",
|
| 81 |
+
"\n",
|
| 82 |
+
" Returns:\n",
|
| 83 |
+
" str: The model's response based on the given text prompt and image.\n",
|
| 84 |
+
" \"\"\"\n",
|
| 85 |
+
" with open(image_path, \"rb\") as image_file:\n",
|
| 86 |
+
" base64_image = base64.b64encode(image_file.read()).decode('utf-8')\n",
|
| 87 |
+
" \n",
|
| 88 |
+
" response = client.chat.completions.create(\n",
|
| 89 |
+
" model=model,\n",
|
| 90 |
+
" messages=[\n",
|
| 91 |
+
" {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n",
|
| 92 |
+
" {\n",
|
| 93 |
+
" \"role\": \"user\",\n",
|
| 94 |
+
" \"content\": [\n",
|
| 95 |
+
" {\"type\": \"text\", \"text\": prompt},\n",
|
| 96 |
+
" {\"type\": \"image_url\", \"image_url\": {\"url\": f\"data:image/jpeg;base64,{base64_image}\"}}\n",
|
| 97 |
+
" ]\n",
|
| 98 |
+
" }\n",
|
| 99 |
+
" ]\n",
|
| 100 |
+
" )\n",
|
| 101 |
+
" return response.choices[0].message.content"
|
| 102 |
+
]
|
| 103 |
+
},
|
| 104 |
+
{
|
| 105 |
+
"cell_type": "markdown",
|
| 106 |
+
"metadata": {},
|
| 107 |
+
"source": [
|
| 108 |
+
"**Model input: Only text**"
|
| 109 |
+
]
|
| 110 |
+
},
|
| 111 |
+
{
|
| 112 |
+
"cell_type": "code",
|
| 113 |
+
"execution_count": 5,
|
| 114 |
+
"metadata": {},
|
| 115 |
+
"outputs": [
|
| 116 |
+
{
|
| 117 |
+
"name": "stdout",
|
| 118 |
+
"output_type": "stream",
|
| 119 |
+
"text": [
|
| 120 |
+
"Hello! I'm here and ready to help you. How can I assist you today?\n"
|
| 121 |
+
]
|
| 122 |
+
}
|
| 123 |
+
],
|
| 124 |
+
"source": [
|
| 125 |
+
"# Example usage\n",
|
| 126 |
+
"text_prompt = \"\"\"Hello there. How are you today?\"\"\"\n",
|
| 127 |
+
"print(text_inference(text_prompt))"
|
| 128 |
+
]
|
| 129 |
+
},
|
| 130 |
+
{
|
| 131 |
+
"cell_type": "markdown",
|
| 132 |
+
"metadata": {},
|
| 133 |
+
"source": [
|
| 134 |
+
"**Model input: Text and Image**"
|
| 135 |
+
]
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"cell_type": "code",
|
| 139 |
+
"execution_count": 5,
|
| 140 |
+
"metadata": {},
|
| 141 |
+
"outputs": [
|
| 142 |
+
{
|
| 143 |
+
"name": "stdout",
|
| 144 |
+
"output_type": "stream",
|
| 145 |
+
"text": [
|
| 146 |
+
"The image features a stack of ice cubes with a translucent, green hue. Each cube is glistening with water droplets that enhance their icy appearance. Surrounding the cubes are fresh green leaves, adding a natural touch to the composition. The background is a soft gradient of green, creating a refreshing and cool atmosphere. The overall effect is vibrant and inviting, evoking a sense of chill and freshness.\n"
|
| 147 |
+
]
|
| 148 |
+
}
|
| 149 |
+
],
|
| 150 |
+
"source": [
|
| 151 |
+
"image_path = \"image.png\"\n",
|
| 152 |
+
"image_prompt = \"You are an AI expert. Answer this question.\"\n",
|
| 153 |
+
"print(image_inference(image_path, image_prompt))"
|
| 154 |
+
]
|
| 155 |
+
}
|
| 156 |
+
],
|
| 157 |
+
"metadata": {
|
| 158 |
+
"kernelspec": {
|
| 159 |
+
"display_name": "huge-env",
|
| 160 |
+
"language": "python",
|
| 161 |
+
"name": "python3"
|
| 162 |
+
},
|
| 163 |
+
"language_info": {
|
| 164 |
+
"codemirror_mode": {
|
| 165 |
+
"name": "ipython",
|
| 166 |
+
"version": 3
|
| 167 |
+
},
|
| 168 |
+
"file_extension": ".py",
|
| 169 |
+
"mimetype": "text/x-python",
|
| 170 |
+
"name": "python",
|
| 171 |
+
"nbconvert_exporter": "python",
|
| 172 |
+
"pygments_lexer": "ipython3",
|
| 173 |
+
"version": "3.11.9"
|
| 174 |
+
}
|
| 175 |
+
},
|
| 176 |
+
"nbformat": 4,
|
| 177 |
+
"nbformat_minor": 2
|
| 178 |
+
}
|
Notebooks/test_groq_models/Mixtral.ipynb
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"**Test your GPT models before integrating them into the project to ensure they can be called successfully.**"
|
| 8 |
+
]
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"cell_type": "code",
|
| 12 |
+
"execution_count": 1,
|
| 13 |
+
"metadata": {},
|
| 14 |
+
"outputs": [
|
| 15 |
+
{
|
| 16 |
+
"data": {
|
| 17 |
+
"text/plain": [
|
| 18 |
+
"True"
|
| 19 |
+
]
|
| 20 |
+
},
|
| 21 |
+
"execution_count": 1,
|
| 22 |
+
"metadata": {},
|
| 23 |
+
"output_type": "execute_result"
|
| 24 |
+
}
|
| 25 |
+
],
|
| 26 |
+
"source": [
|
| 27 |
+
"from dotenv import load_dotenv\n",
|
| 28 |
+
"import os\n",
|
| 29 |
+
"load_dotenv()"
|
| 30 |
+
]
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"cell_type": "code",
|
| 34 |
+
"execution_count": 2,
|
| 35 |
+
"metadata": {},
|
| 36 |
+
"outputs": [],
|
| 37 |
+
"source": [
|
| 38 |
+
"os.environ['OPENAI_API_KEY'] = os.getenv(\"OPEN_AI_API_KEY\")"
|
| 39 |
+
]
|
| 40 |
+
},
|
| 41 |
+
{
|
| 42 |
+
"cell_type": "code",
|
| 43 |
+
"execution_count": null,
|
| 44 |
+
"metadata": {},
|
| 45 |
+
"outputs": [],
|
| 46 |
+
"source": [
|
| 47 |
+
"from openai import OpenAI\n",
|
| 48 |
+
"client = OpenAI()\n",
|
| 49 |
+
"\n",
|
| 50 |
+
"response = client.chat.completions.create(\n",
|
| 51 |
+
" model=\"Mixtral 8x7B\",\n",
|
| 52 |
+
" messages=[\n",
|
| 53 |
+
" {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n",
|
| 54 |
+
" {\"role\": \"user\", \"content\": \"Who won the world series in 2020?\"},\n",
|
| 55 |
+
" {\"role\": \"assistant\", \"content\": \"The Los Angeles Dodgers won the World Series in 2020.\"},\n",
|
| 56 |
+
" {\"role\": \"user\", \"content\": \"Where was it played?\"}\n",
|
| 57 |
+
" ]\n",
|
| 58 |
+
")"
|
| 59 |
+
]
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"cell_type": "code",
|
| 63 |
+
"execution_count": 3,
|
| 64 |
+
"metadata": {},
|
| 65 |
+
"outputs": [
|
| 66 |
+
{
|
| 67 |
+
"data": {
|
| 68 |
+
"text/plain": [
|
| 69 |
+
"'The 2020 World Series was played at Globe Life Field in Arlington, Texas.'"
|
| 70 |
+
]
|
| 71 |
+
},
|
| 72 |
+
"execution_count": 3,
|
| 73 |
+
"metadata": {},
|
| 74 |
+
"output_type": "execute_result"
|
| 75 |
+
}
|
| 76 |
+
],
|
| 77 |
+
"source": [
|
| 78 |
+
"response.choices[0].message.content"
|
| 79 |
+
]
|
| 80 |
+
}
|
| 81 |
+
],
|
| 82 |
+
"metadata": {
|
| 83 |
+
"kernelspec": {
|
| 84 |
+
"display_name": "playaround",
|
| 85 |
+
"language": "python",
|
| 86 |
+
"name": "python3"
|
| 87 |
+
},
|
| 88 |
+
"language_info": {
|
| 89 |
+
"codemirror_mode": {
|
| 90 |
+
"name": "ipython",
|
| 91 |
+
"version": 3
|
| 92 |
+
},
|
| 93 |
+
"file_extension": ".py",
|
| 94 |
+
"mimetype": "text/x-python",
|
| 95 |
+
"name": "python",
|
| 96 |
+
"nbconvert_exporter": "python",
|
| 97 |
+
"pygments_lexer": "ipython3",
|
| 98 |
+
"version": "3.11.9"
|
| 99 |
+
}
|
| 100 |
+
},
|
| 101 |
+
"nbformat": 4,
|
| 102 |
+
"nbformat_minor": 2
|
| 103 |
+
}
|
Notebooks/test_groq_models/image.png
ADDED
|
Git LFS Details
|
README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
---
|
| 3 |
+
|
| 4 |
+
# AgentGraph: Intelligent SQL-agent Q&A and RAG System for Chatting with Multiple Databases
|
| 5 |
+
|
| 6 |
+
This project demonstrates how to build an agentic system using Large Language Models (LLMs) that can interact with multiple databases and utilize various tools. It highlights the use of SQL agents to efficiently query large databases. The key frameworks used in this project include OpenAI, LangChain, LangGraph, LangSmith, and Gradio. The end product is an end-to-end chatbot, designed to perform these tasks, with LangSmith used to monitor the performance of the agents.
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
## Video Explanation:
|
| 11 |
+
A detailed explanation of the project is available in the following YouTube video:
|
| 12 |
+
|
| 13 |
+
Automating LLM Agents to Chat with Multiple/Large Databases (Combining RAG and SQL Agents): [Link](https://youtu.be/xsCedrNP9w8?si=v-3k-BoDky_1IRsg)
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## Requirements
|
| 18 |
+
|
| 19 |
+
- **Operating System:** Linux or Windows (Tested on Windows 11 with Python 3.9.11)
|
| 20 |
+
- **OpenAI API Key:** Required for GPT functionality.
|
| 21 |
+
- **Tavily Credentials:** Required for search tools (Free from your Tavily profile).
|
| 22 |
+
- **LangChain Credentials:** Required for LangSmith (Free from your LangChain profile).
|
| 23 |
+
- **Dependencies:** The necessary libraries are provided in `requirements.txt` file.
|
| 24 |
+
---
|
| 25 |
+
|
| 26 |
+
## Installation and Execution
|
| 27 |
+
|
| 28 |
+
To set up the project, follow these steps:
|
| 29 |
+
|
| 30 |
+
1. Clone the repository:
|
| 31 |
+
```bash
|
| 32 |
+
git clone <repo_address>
|
| 33 |
+
```
|
| 34 |
+
2. Install Python and create a virtual environment:
|
| 35 |
+
```bash
|
| 36 |
+
python -m venv venv
|
| 37 |
+
```
|
| 38 |
+
3. Activate the virtual environment:
|
| 39 |
+
- On Windows:
|
| 40 |
+
```bash
|
| 41 |
+
venv\Scripts\activate
|
| 42 |
+
```
|
| 43 |
+
- On Linux/macOS:
|
| 44 |
+
```bash
|
| 45 |
+
source venv/bin/activate
|
| 46 |
+
```
|
| 47 |
+
4. Install the required dependencies:
|
| 48 |
+
```bash
|
| 49 |
+
pip install -r requirements.txt
|
| 50 |
+
```
|
| 51 |
+
5. Download the travel sql database from this link and paste it into the `data` folder.
|
| 52 |
+
|
| 53 |
+
6. Download the chinook SQL database from this link and paste it into the `data` folder.
|
| 54 |
+
|
| 55 |
+
7. Prepare the `.env` file and add your `OPEN_AI_API_KEY`, `TAVILY_API_KEY`, and `LANGCHAIN_API_KEY`.
|
| 56 |
+
|
| 57 |
+
8. Run `prepare_vector_db.py` module once to prepare both vector databases.
|
| 58 |
+
```bash
|
| 59 |
+
python src\prepare_vector_db.py
|
| 60 |
+
```
|
| 61 |
+
9. Run the app:
|
| 62 |
+
```bash
|
| 63 |
+
python src\app.py
|
| 64 |
+
```
|
| 65 |
+
Open the Gradio URL generated in the terminal and start chatting.
|
| 66 |
+
|
| 67 |
+
*Sample questions are available in `sample_questions.txt`.*
|
| 68 |
+
|
| 69 |
+
---
|
| 70 |
+
|
| 71 |
+
### Using Your Own Database
|
| 72 |
+
|
| 73 |
+
To use your own data:
|
| 74 |
+
1. Place your data in the `data` folder.
|
| 75 |
+
2. Update the configurations in `tools_config.yml`.
|
| 76 |
+
3. Load the configurations in `src\agent_graph\load_tools_config.py`.
|
| 77 |
+
|
| 78 |
+
For unstructured data using Retrieval-Augmented Generation (RAG):
|
| 79 |
+
1. Run the following command with your data directory's configuration:
|
| 80 |
+
```bash
|
| 81 |
+
python src\prepare_vector_db.py
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
All configurations are managed through YAML files in the `configs` folder, loaded by `src\chatbot\load_config.py` and `src\agent_graph\load_tools_config.py`. These modules are used for a clean distribution of configurations throughout the project.
|
| 85 |
+
|
| 86 |
+
Once your databases are ready, you can either connect the current agents to the databases or create new agents. More details can be found in the accompanying YouTube video.
|
| 87 |
+
|
| 88 |
+
---
|
| 89 |
+
|
| 90 |
+
## Project Schemas
|
| 91 |
+
|
| 92 |
+
### High-level overview
|
| 93 |
+
|
| 94 |
+
<div align="center">
|
| 95 |
+
<img src="images/high-level.png" alt="high-level">
|
| 96 |
+
</div>
|
| 97 |
+
|
| 98 |
+
### Detailed Schema
|
| 99 |
+
|
| 100 |
+
<div align="center">
|
| 101 |
+
<img src="images/detailed_schema.png" alt="detailed_schema">
|
| 102 |
+
</div>
|
| 103 |
+
|
| 104 |
+
### Graph Schema
|
| 105 |
+
|
| 106 |
+
<div align="center">
|
| 107 |
+
<img src="images/graph_image.png" alt="graph_image">
|
| 108 |
+
</div>
|
| 109 |
+
|
| 110 |
+
### SQL-agent for large databases strategies
|
| 111 |
+
|
| 112 |
+
<div align="center">
|
| 113 |
+
<img src="images/large_db_strategy.png" alt="large_db_strategy">
|
| 114 |
+
</div>
|
| 115 |
+
|
| 116 |
+
---
|
| 117 |
+
|
| 118 |
+
## Chatbot User Interface
|
| 119 |
+
|
| 120 |
+
<div align="center">
|
| 121 |
+
<img src="images/UI.png" alt="ChatBot UI">
|
| 122 |
+
</div>
|
| 123 |
+
|
| 124 |
+
---
|
| 125 |
+
|
| 126 |
+
## LangSmith Monitoring System
|
| 127 |
+
|
| 128 |
+
<div align="center">
|
| 129 |
+
<img src="images/langsmith.png" alt="langsmith">
|
| 130 |
+
</div>
|
| 131 |
+
|
| 132 |
+
---
|
| 133 |
+
|
| 134 |
+
## Databases Used
|
| 135 |
+
|
| 136 |
+
- **Travel SQL Database:** [Kaggle Link](https://www.kaggle.com/code/mpwolke/airlines-sqlite)
|
| 137 |
+
- **Chinook SQL Database:** [Sample Database](https://database.guide/2-sample-databases-sqlite/)
|
| 138 |
+
- **stories VectorDB**
|
| 139 |
+
- **Airline Policy FAQ VectorDB**
|
| 140 |
+
---
|
| 141 |
+
|
| 142 |
+
## Key Frameworks and Libraries
|
| 143 |
+
|
| 144 |
+
- **LangChain:** [Introduction](https://python.langchain.com/docs/get_started/introduction)
|
| 145 |
+
- **LangGraph**
|
| 146 |
+
- **LangSmith**
|
| 147 |
+
- **Gradio:** [Documentation](https://www.gradio.app/docs/interface)
|
| 148 |
+
- **OpenAI:** [Developer Quickstart](https://platform.openai.com/docs/quickstart?context=python)
|
| 149 |
+
- **Tavily Search**
|
| 150 |
+
---
|
configs/project_config.yml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
langsmith:
|
| 2 |
+
tracing: "true"
|
| 3 |
+
project_name: "RAG & SQL Agents"
|
| 4 |
+
|
| 5 |
+
memory:
|
| 6 |
+
directory: memory
|
configs/tools_config.yml
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
primary_agent:
|
| 2 |
+
llm: openai/gpt-oss-120b
|
| 3 |
+
llm_temperature: 0.0
|
| 4 |
+
|
| 5 |
+
swiss_airline_policy_rag:
|
| 6 |
+
unstructured_docs: "data/unstructured_docs/swiss_airline_policy"
|
| 7 |
+
vectordb: "data/airline_policy_vectordb"
|
| 8 |
+
collection_name: rag-chroma
|
| 9 |
+
llm: openai/gpt-oss-120b
|
| 10 |
+
llm_temperature: 0.0
|
| 11 |
+
embedding_model: all-MiniLM-L6-v2
|
| 12 |
+
chunk_size: 500
|
| 13 |
+
chunk_overlap: 100
|
| 14 |
+
k: 2
|
| 15 |
+
|
| 16 |
+
stories_rag:
|
| 17 |
+
unstructured_docs: "data/unstructured_docs/stories"
|
| 18 |
+
vectordb: "data/stories_vectordb"
|
| 19 |
+
collection_name: stories-rag-chroma
|
| 20 |
+
llm: openai/gpt-oss-120b
|
| 21 |
+
llm_temperature: 0.0
|
| 22 |
+
embedding_model: all-MiniLM-L6-v2
|
| 23 |
+
chunk_size: 500
|
| 24 |
+
chunk_overlap: 100
|
| 25 |
+
k: 2
|
| 26 |
+
|
| 27 |
+
travel_sqlagent_configs:
|
| 28 |
+
travel_sqldb_dir: "data/travel.sqlite"
|
| 29 |
+
llm: "openai/gpt-oss-120b"
|
| 30 |
+
llm_temperature: 0.0
|
| 31 |
+
|
| 32 |
+
chinook_sqlagent_configs:
|
| 33 |
+
chinook_sqldb_dir: "data/Chinook.db"
|
| 34 |
+
llm: "openai/gpt-oss-120b"
|
| 35 |
+
llm_temperature: 0.0
|
| 36 |
+
|
| 37 |
+
langsmith:
|
| 38 |
+
tracing: "true"
|
| 39 |
+
project_name: "rag_sqlagent_project"
|
| 40 |
+
|
| 41 |
+
tavily_search_api:
|
| 42 |
+
tavily_search_max_results: 2
|
| 43 |
+
|
| 44 |
+
graph_configs:
|
| 45 |
+
thread_id: 1 # This can be adjusted to assign a unique value for each user session, so it's easier to access data later on.
|
| 46 |
+
|
data/Chinook.db
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9bd892696e956e57c8cfabd90fcf1675d583ba8e961e968ec53c8da7c08c2669
|
| 3 |
+
size 1007616
|
data/airline_policy_vectordb/chroma.sqlite3
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:655d90cbf27df7db4b1eb1351dc3f02d4a317133b367ad2f612d70352f6c1a9f
|
| 3 |
+
size 548864
|
data/airline_policy_vectordb/f2b436bc-82cd-4d2c-8bab-689ae4da5759/data_level0.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d3c9fd302f000d7790aa403c2d0d8fec363fe46f30b07d53020b6e33b22435a9
|
| 3 |
+
size 1676000
|
data/airline_policy_vectordb/f2b436bc-82cd-4d2c-8bab-689ae4da5759/header.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e87a1dc8bcae6f2c4bea6d5dd5005454d4dace8637dae29bff3c037ea771411e
|
| 3 |
+
size 100
|
data/airline_policy_vectordb/f2b436bc-82cd-4d2c-8bab-689ae4da5759/length.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ea0d08e65dd9d026a96c9353a211aab455c26de1c3844d6b03bafee746fd2396
|
| 3 |
+
size 4000
|
data/airline_policy_vectordb/f2b436bc-82cd-4d2c-8bab-689ae4da5759/link_lists.bin
ADDED
|
File without changes
|
data/stories_vectordb/483f4fb1-0512-4ef0-9c4e-890073f4fe17/data_level0.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d3c9fd302f000d7790aa403c2d0d8fec363fe46f30b07d53020b6e33b22435a9
|
| 3 |
+
size 1676000
|
data/stories_vectordb/483f4fb1-0512-4ef0-9c4e-890073f4fe17/header.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e87a1dc8bcae6f2c4bea6d5dd5005454d4dace8637dae29bff3c037ea771411e
|
| 3 |
+
size 100
|
data/stories_vectordb/483f4fb1-0512-4ef0-9c4e-890073f4fe17/length.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:17ddd8ba7342a60f29345c3078eb4a12057fa3f88dd31ae3690fa4bef4155140
|
| 3 |
+
size 4000
|
data/stories_vectordb/483f4fb1-0512-4ef0-9c4e-890073f4fe17/link_lists.bin
ADDED
|
File without changes
|
data/stories_vectordb/chroma.sqlite3
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e76231a9270897228d62b369b8edd4f0bf325078a0b6bca22052642edf52d364
|
| 3 |
+
size 258048
|
data/travel.sqlite
ADDED
|
File without changes
|
data/unstructured_docs/stories/stories.pdf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9da1a7de23d1c52a5ea2c4243e71ba616fe21c602496fd78fc868957d6a69e81
|
| 3 |
+
size 427362
|
data/unstructured_docs/swiss_airline_policy/swiss_faq.pdf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9ecf417e39093e931f75f851bdc7ae9c6410af3463bd5878b67e2a61ad075fad
|
| 3 |
+
size 67566
|
images/AI_RT.png
ADDED
|
Git LFS Details
|
images/UI.png
ADDED
|
Git LFS Details
|
images/chat_icon.png
ADDED
|
|
Git LFS Details
|
images/detailed_schema.png
ADDED
|
Git LFS Details
|
images/graph_image.png
ADDED
|
Git LFS Details
|
images/high-level.png
ADDED
|
Git LFS Details
|
images/langsmith_Screenshot.png
ADDED
|
Git LFS Details
|
images/large_db_strategy.png
ADDED
|
Git LFS Details
|
images/question2_answer_Screenshot .png
ADDED
|
|
Git LFS Details
|
images/question3_answer_Screenshot.png
ADDED
|
Git LFS Details
|
images/question4_answer_Screenshot.png
ADDED
|
Git LFS Details
|
images/question_answer_screenshot.png
ADDED
|
Git LFS Details
|
memory/2024-09-16.csv
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
thread_id,timestamp,user_query,response
|
| 2 |
+
1,16:41:38,hello,Hello! How can I assist you today?
|
| 3 |
+
1,16:42:15,hi there,Hello! How can I assist you today?
|
| 4 |
+
1,16:42:25,"In the stories, who is fred?
|
| 5 |
+
","In the stories, Fred is a small red fish who lives in a vibrant coral reef in the ocean. His scales sparkle like rubies, and he is known for his curiosity and adventurous spirit. Fred comes from a loving family, with a wise mother named Coraline and a daring father named Marlin, who shares tales of his explorations.
|
| 6 |
+
|
| 7 |
+
Fred's best friend is a playful dolphin named Delphi, and together they embark on an exciting adventure after discovering a treasure map in a bottle. Their journey takes them through various underwater wonders and challenges, including evading a hungry octopus and navigating a storm. Ultimately, they find a sunken pirate ship filled with treasure, but Fred realizes that the true treasure lies in the experiences and memories created during their adventure.
|
| 8 |
+
|
| 9 |
+
Fred returns home to share his stories with his family, having grown and learned that home is defined by the love that awaits him there."
|
| 10 |
+
1,16:42:48,"Give me the link of Trump and Harris debate on youtube
|
| 11 |
+
","Here are two links to the Trump and Harris debate on YouTube:
|
| 12 |
+
|
| 13 |
+
1. [Watch live coverage of the presidential debate](https://m.youtube.com/watch?v=SGRydccYp0c) hosted by ABC News.
|
| 14 |
+
2. [Highlights from the first 2024 presidential debate](https://m.youtube.com/watch?v=BVlI0vcf5T8) in Philadelphia.
|
| 15 |
+
|
| 16 |
+
Feel free to check them out!"
|
memory/2024-09-17.csv
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
thread_id,timestamp,user_query,response
|
| 2 |
+
1,20:27:35,"In chinook DB, list the total sales per country. Which country's customers spent the most?","Here are the total sales per country from the Chinook database:
|
| 3 |
+
|
| 4 |
+
1. **USA**: $523.06
|
| 5 |
+
2. **Canada**: $303.96
|
| 6 |
+
3. **France**: $195.10
|
| 7 |
+
4. **Brazil**: $190.10
|
| 8 |
+
5. **Germany**: $156.48
|
| 9 |
+
|
| 10 |
+
The country whose customers spent the most is the **USA** with total sales of **$523.06**."
|
| 11 |
+
1,20:27:54,What are all the genres of Alanis Morisette songs?,The genre of Alanis Morissette's songs in the Chinook database is **Rock**.
|
| 12 |
+
1,20:28:02,"In the stories, who is fred?","Fred is a small red fish who lives in the vast ocean. His scales sparkle like rubies, and he is known for his curiosity and adventurous spirit. Fred lives in a cozy coral reef with his loving family, including his wise mother, Coraline, and his daring father, Marlin, who shares tales of his explorations.
|
| 13 |
+
|
| 14 |
+
Fred's best friend is a playful dolphin named Delphi, and together they embark on exciting adventures. One day, they discover a treasure map in a bottle, leading them on a journey filled with wonders and dangers. They encounter various marine life, swim through kelp forests, and even face a storm.
|
| 15 |
+
|
| 16 |
+
Ultimately, they find a sunken pirate ship filled with treasure, but Fred realizes that the true treasure lies in the experiences and memories created during their adventure. He returns home to share his stories, having grown and learned that home is defined by the love that awaits him there. Fred lives happily ever after, always ready for the next adventure."
|