From af72f951631b9ad6c1caac7039f7503adf434f8e Mon Sep 17 00:00:00 2001 From: Pablo Marin Date: Mon, 4 Mar 2024 20:20:16 +0000 Subject: [PATCH 1/2] bot.py fixes --- 10-API-Search.ipynb | 76 ++-- 11-Smart_Agent.ipynb | 576 +++++++++++++++---------- apps/backend/azuredeploy-backend.bicep | 6 +- apps/backend/azuredeploy-backend.json | 6 +- apps/backend/backend.zip | Bin 38245 -> 33307 bytes apps/backend/bot.py | 39 +- common/prompts.py | 3 +- common/utils.py | 2 +- 8 files changed, 425 insertions(+), 283 deletions(-) diff --git a/10-API-Search.ipynb b/10-API-Search.ipynb index 2452110a..b2e98a18 100644 --- a/10-API-Search.ipynb +++ b/10-API-Search.ipynb @@ -29,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "c1fb79a3-4856-4721-988c-112813690a90", "metadata": {}, "outputs": [], @@ -64,7 +64,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "258a6e99-2d4f-4147-b8ee-c64c85296181", "metadata": {}, "outputs": [], @@ -75,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "9d3daf03-77e2-466e-a255-2f06bee3561b", "metadata": {}, "outputs": [], @@ -85,6 +85,8 @@ "\n", "COMPLETION_TOKENS = 2000\n", "\n", + "\n", + "# This notebook needs GPT-4-Turbo (context size of 128k tokens)\n", "llm = AzureChatOpenAI(deployment_name=os.environ[\"GPT4_DEPLOYMENT_NAME\"], \n", " temperature=0.5, max_tokens=COMPLETION_TOKENS, \n", " streaming=True, callback_manager=cb_manager)" @@ -137,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 4, "id": "8efd8698-aea1-4de3-b810-e9c4782f04c4", "metadata": {}, "outputs": [], @@ -163,7 +165,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 5, "id": "94503afc-c398-458a-b369-610c5dbe682d", "metadata": {}, "outputs": [], @@ -174,7 +176,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 6, "id": "57d77e9b-6f3f-4ec4-bc01-baac18984937", "metadata": {}, "outputs": [ @@ -202,6 +204,14 @@ "Sometimes it makes sense to reduce the size of the API Specs by using the `reduce_openapi_spec` function. It's optional." ] }, + { + "cell_type": "markdown", + "id": "cd8c3b3e-959e-4b19-b34d-66de3501b1b1", + "metadata": {}, + "source": [ + "#### NOTE: As you can see, a large context LLM is needed. `GPT4-turbo` is necessary for this notebook to run succesfully." + ] + }, { "cell_type": "markdown", "id": "9a945386-39eb-405d-9310-3b67c9af77bb", @@ -213,7 +223,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 7, "id": "d020b5de-7ebe-4fb9-9b71-f6c71956149d", "metadata": {}, "outputs": [], @@ -242,7 +252,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 8, "id": "96731b5f-988b-49ec-a5c3-3a344b7085da", "metadata": {}, "outputs": [], @@ -253,17 +263,9 @@ "requests_wrapper = RequestsWrapper(headers=headers)" ] }, - { - "cell_type": "markdown", - "id": "1fd6a140-f675-40db-98ad-b5c955a4f7b6", - "metadata": {}, - "source": [ - "**Note**: Notice that we are using GPT-3.5 (llm_2) below for this chain since it doesn't need too many instructions or reasoning" - ] - }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 9, "id": "426fab6f-ea04-4c07-8211-d9cc5c70ac8e", "metadata": {}, "outputs": [], @@ -283,12 +285,12 @@ "id": "1707e590-809b-4391-bdcd-c7d285ec8fb1", "metadata": {}, "source": [ - "These are the prompts on the APIChain class (on to create the URL endpoint and the other one to use it and get the answer):" + "These are the prompts on the APIChain class (one to create the URL endpoint and the other one to use it and get the answer):" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 10, "id": "9f80d2bb-e285-4d30-88c8-5677e86cebe2", "metadata": {}, "outputs": [ @@ -298,7 +300,7 @@ "'You are given the below API Documentation:\\n{api_docs}\\nUsing this documentation, generate the full API url to call for answering the user question.\\nYou should build the API url in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\\n\\nQuestion:{question}\\nAPI url:'" ] }, - "execution_count": 15, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -309,7 +311,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 11, "id": "ccc7e9dc-f36b-45e1-867a-1b92d639e941", "metadata": {}, "outputs": [ @@ -319,7 +321,7 @@ "'You are given the below API Documentation:\\n{api_docs}\\nUsing this documentation, generate the full API url to call for answering the user question.\\nYou should build the API url in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.\\n\\nQuestion:{question}\\nAPI url: {api_url}\\n\\nHere is the response from the API:\\n\\n{api_response}\\n\\nSummarize this response to answer the original question.\\n\\nSummary:'" ] }, - "execution_count": 16, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -330,7 +332,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 12, "id": "d7f60335-5551-4ee0-ba4e-1cd84f3a9f48", "metadata": {}, "outputs": [ @@ -338,18 +340,30 @@ "name": "stdout", "output_type": "stream", "text": [ - "To answer the user's question, we need to make three separate API calls to get the price of Bitcoin against USD, the latest OHLC values for Ethereum, and the bid and ask for Euro. Here are the API URLs for the required information:\n", + "To get the price of Bitcoin against USD, we will use the `Ticker` endpoint. The `pair` parameter should specify `XXBTZUSD` which is the pair for Bitcoin against USD.\n", + "\n", + "For the latest OHLC values for Ethereum, we will use the `OHLC` endpoint. The `pair` parameter should specify `XETHZUSD` which is the pair for Ethereum against USD.\n", "\n", - "1. Price of Bitcoin against USD:\n", - " `GET https://api.kraken.com/0/public/Ticker?pair=XBTUSD`\n", + "For the bid and ask for Euro, we will use the `Ticker` endpoint again. The `pair` parameter should specify `ZEURZUSD` which is the pair for Euro against USD.\n", "\n", - "2. Latest OHLC values for Ethereum:\n", - " `GET https://api.kraken.com/0/public/OHLC?pair=ETHUSD`\n", + "Since we want to make the response as short as possible, we will only include the necessary pairs in the `pair` parameter for each call.\n", "\n", - "3. Bid and ask for Euro:\n", - " `GET https://api.kraken.com/0/public/Ticker?pair=EURUSD`\n", + "API url for Bitcoin price against USD (Ticker):\n", + "```\n", + "https://api.kraken.com/0/public/Ticker?pair=XXBTZUSD\n", + "```\n", + "\n", + "API url for the latest OHLC values for Ethereum (OHLC):\n", + "```\n", + "https://api.kraken.com/0/public/OHLC?pair=XETHZUSD&interval=1\n", + "```\n", + "\n", + "API url for the bid and ask for Euro (Ticker):\n", + "```\n", + "https://api.kraken.com/0/public/Ticker?pair=ZEURZUSD\n", + "```\n", "\n", - "Please note that the pair names (`XBTUSD`, `ETHUSD`, and `EURUSD`) are based on the common naming convention used by Kraken and may need to be adjusted if Kraken uses different identifiers for these pairs." + "Please note that these URLs should be used with a `GET` request." ] } ], diff --git a/11-Smart_Agent.ipynb b/11-Smart_Agent.ipynb index 3247a185..b8c6a3f2 100644 --- a/11-Smart_Agent.ipynb +++ b/11-Smart_Agent.ipynb @@ -132,21 +132,37 @@ { "cell_type": "code", "execution_count": 4, + "id": "a6a4cc93-2dd6-45eb-ac5b-5af2d31809dd", + "metadata": {}, + "outputs": [], + "source": [ + "doc_indexes = [\"cogsrch-index-files\", \"cogsrch-index-csv\"]\n", + "doc_search = DocSearchAgent(llm=llm, indexes=doc_indexes,\n", + " k=6, reranker_th=1,\n", + " sas_token=os.environ['BLOB_SAS_TOKEN'],\n", + " callback_manager=cb_manager, verbose=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, "id": "eafd5bf5-28ee-4edd-978b-384cce057257", "metadata": {}, "outputs": [], "source": [ "# DocSearchAgent is our Custom Tool Class (Agent) created for Azure Cognitive Search + OpenAI searches\n", - "text_indexes = [\"cogsrch-index-files\", \"cogsrch-index-csv\", \"cogsrch-index-books\"]\n", - "doc_search = DocSearchAgent(llm=llm, indexes=text_indexes,\n", + "book_indexes = [\"cogsrch-index-books\"]\n", + "book_search = DocSearchAgent(llm=llm, indexes=book_indexes,\n", " k=6, reranker_th=1,\n", " sas_token=os.environ['BLOB_SAS_TOKEN'],\n", + " name=\"booksearch\",\n", + " description=\"useful when the questions includes the term: booksearch\",\n", " callback_manager=cb_manager, verbose=False)" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "0f0ae466-aff8-4cdf-80d3-ef2c61867fc7", "metadata": {}, "outputs": [], @@ -157,7 +173,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "78edb304-c4a2-4f10-8ded-936e9141aa02", "metadata": {}, "outputs": [], @@ -169,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "b9d54cc5-41bc-43c3-a91d-12fc3a2446ba", "metadata": {}, "outputs": [], @@ -180,7 +196,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "65465173-92f6-489d-9b48-58d109c5723e", "metadata": {}, "outputs": [], @@ -266,13 +282,13 @@ "\n", "\n", "\n", - "I couldn't find specific information about the weather today in Dallas in the retrieved documents. If you have access to the internet, you may want to check a reliable weather website or app for the most up-to-date weather forecast for Dallas." + "I'm sorry, but I couldn't find specific weather information for Dallas in the documents I searched. If you'd like, I can attempt to retrieve this information from a different source." ] }, { "data": { "text/markdown": [ - "I couldn't find specific information about the weather today in Dallas in the retrieved documents. If you have access to the internet, you may want to check a reliable weather website or app for the most up-to-date weather forecast for Dallas." + "I'm sorry, but I couldn't find specific weather information for Dallas in the documents I searched. If you'd like, I can attempt to retrieve this information from a different source." ], "text/plain": [ "" @@ -299,42 +315,48 @@ "text": [ "Tool: docsearch\n", "Agent Action: \n", - "Invoking: `docsearch` with `{'query': 'Effects of COVID-19 on obese individuals'}`\n", + "Invoking: `docsearch` with `{'query': 'How does Covid affect obese people?'}`\n", "\n", "\n", "\n", "Agent Action: \n", - "Invoking: `docsearch` with `{'query': 'Effects of COVID-19 on elderly individuals'}`\n", + "Invoking: `docsearch` with `{'query': 'How does Covid affect elderly people?'}`\n", + "\n", "\n", "\n", + "### How Covid Affects Obese People\n", "\n", - "### Effects of COVID-19 on Obese Individuals:\n", - "- **Risk Factor**: The WHO considers non-communicable diseases, such as obesity, a major risk factor for severe illness with COVID-19[1].\n", - "- **Impact on Critical Care**: Studies show that a significant percentage of individuals in critical care units with serious COVID-19 complications are either overweight or obese, highlighting the impact of obesity on severe COVID-19 cases[2].\n", - "- **Severity Association**: Obese patients have increased odds of developing severe COVID-19, with higher risks compared to normal-weight individuals[1].\n", + "Obesity is associated with an increased risk of severe illness from COVID-19. Studies have shown that critically ill patients with COVID-19 often have a high frequency of obesity, and the severity of the virus is increased in the context of obesity1. Additionally, data from the UK Intensive Care National Audit and Research Centre indicates that two-thirds of people who developed serious or fatal COVID-19-related complications were overweight or obese2. Furthermore, obese patients tend to have an increased risk of developing severe COVID-19, with higher odds of progression to severe disease compared to normal-weight patients3.\n", "\n", - "### Effects of COVID-19 on Elderly Individuals:\n", - "- **Vulnerability**: Complications of COVID-19 are severe among older adults, with higher mortality rates compared to younger patients[3].\n", - "- **Health Disparities**: Geographic differences impact health care use and mortality rates among elderly patients during the pandemic, highlighting health disparities in different regions[4].\n", - "- **Impact on Elder Mistreatment**: The COVID-19 outbreak has had a profound impact on organizations responding to elder mistreatment, necessitating creative solutions and lessons learned to protect vulnerable elderly individuals[5].\n", + "### How Covid Affects Elderly People\n", "\n", - "These findings emphasize the heightened risks and challenges faced by obese and elderly individuals during the COVID-19 pandemic, necessitating tailored approaches to protect and manage their health effectively." + "Elderly people are at a higher risk of more serious and potentially fatal illness associated with COVID-19. Mortality data indicates an increased risk of mortality for people in their 60s, 70s, and over 80s, with the risk of mortality rising with age1. In Spain, 68% of all coronavirus hospitalizations correspond to those over 60 years of age, highlighting the severity of COVID-19 in the elderly population2. Additionally, the COVID-19 epidemic has incurred significant disease burden on the elderly population, highlighting the need for pandemic preparedness and support programs for this vulnerable group3.\n", + "\n", + "These findings illustrate the increased vulnerability of obese and elderly individuals to severe illness from COVID-19, emphasizing the importance of protective measures and focused healthcare interventions for these groups.\n", + "\n", + "References:\n", + "1. [Obesity and COVID-19 Severity](https://doi.org/10.1002/oby.22867; https://www.ncbi.nlm.nih.gov/pubmed/32365275/?sv=2022-11-02&ss=b&srt=sco&sp=rl&se=2026-01-03T02:11:44Z&st=2024-01-02T18:11:44Z&spr=https&sig=ngrEqvqBVaxyuSYqgPVeF%2B9c0fXLs94v3ASgwg7LDBs%3D)\n", + "2. [Mortality Data for Elderly and COVID-19](https://doi.org/10.1111/jocn.15274; https://www.ncbi.nlm.nih.gov/pubmed/32239784/?sv=2022-11-02&ss=b&srt=sco&sp=rl&se=2026-01-03T02:11:44Z&st=2024-01-02T18:11:44Z&spr=https&sig=ngrEqvqBVaxyuSYqgPVeF%2B9c0fXLs94v3ASgwg7LDBs%3D)\n", + "3. [Severe COVID-19 in Obese Patients](https://doi.org/10.2337/dc20-0576; https://www.ncbi.nlm.nih.gov/pubmed/32409502/?sv=2022-11-02&ss=b&srt=sco&sp=rl&se=2026-01-03T02:11:44Z&st=2024-01-02T18:11:44Z&spr=https&sig=ngrEqvqBVaxyuSYqgPVeF%2B9c0fXLs94v3ASgwg7LDBs%3D)" ] }, { "data": { "text/markdown": [ - "### Effects of COVID-19 on Obese Individuals:\n", - "- **Risk Factor**: The WHO considers non-communicable diseases, such as obesity, a major risk factor for severe illness with COVID-19[1].\n", - "- **Impact on Critical Care**: Studies show that a significant percentage of individuals in critical care units with serious COVID-19 complications are either overweight or obese, highlighting the impact of obesity on severe COVID-19 cases[2].\n", - "- **Severity Association**: Obese patients have increased odds of developing severe COVID-19, with higher risks compared to normal-weight individuals[1].\n", + "### How Covid Affects Obese People\n", + "\n", + "Obesity is associated with an increased risk of severe illness from COVID-19. Studies have shown that critically ill patients with COVID-19 often have a high frequency of obesity, and the severity of the virus is increased in the context of obesity1. Additionally, data from the UK Intensive Care National Audit and Research Centre indicates that two-thirds of people who developed serious or fatal COVID-19-related complications were overweight or obese2. Furthermore, obese patients tend to have an increased risk of developing severe COVID-19, with higher odds of progression to severe disease compared to normal-weight patients3.\n", + "\n", + "### How Covid Affects Elderly People\n", + "\n", + "Elderly people are at a higher risk of more serious and potentially fatal illness associated with COVID-19. Mortality data indicates an increased risk of mortality for people in their 60s, 70s, and over 80s, with the risk of mortality rising with age1. In Spain, 68% of all coronavirus hospitalizations correspond to those over 60 years of age, highlighting the severity of COVID-19 in the elderly population2. Additionally, the COVID-19 epidemic has incurred significant disease burden on the elderly population, highlighting the need for pandemic preparedness and support programs for this vulnerable group3.\n", "\n", - "### Effects of COVID-19 on Elderly Individuals:\n", - "- **Vulnerability**: Complications of COVID-19 are severe among older adults, with higher mortality rates compared to younger patients[3].\n", - "- **Health Disparities**: Geographic differences impact health care use and mortality rates among elderly patients during the pandemic, highlighting health disparities in different regions[4].\n", - "- **Impact on Elder Mistreatment**: The COVID-19 outbreak has had a profound impact on organizations responding to elder mistreatment, necessitating creative solutions and lessons learned to protect vulnerable elderly individuals[5].\n", + "These findings illustrate the increased vulnerability of obese and elderly individuals to severe illness from COVID-19, emphasizing the importance of protective measures and focused healthcare interventions for these groups.\n", "\n", - "These findings emphasize the heightened risks and challenges faced by obese and elderly individuals during the COVID-19 pandemic, necessitating tailored approaches to protect and manage their health effectively." + "References:\n", + "1. [Obesity and COVID-19 Severity](https://doi.org/10.1002/oby.22867; https://www.ncbi.nlm.nih.gov/pubmed/32365275/?sv=2022-11-02&ss=b&srt=sco&sp=rl&se=2026-01-03T02:11:44Z&st=2024-01-02T18:11:44Z&spr=https&sig=ngrEqvqBVaxyuSYqgPVeF%2B9c0fXLs94v3ASgwg7LDBs%3D)\n", + "2. [Mortality Data for Elderly and COVID-19](https://doi.org/10.1111/jocn.15274; https://www.ncbi.nlm.nih.gov/pubmed/32239784/?sv=2022-11-02&ss=b&srt=sco&sp=rl&se=2026-01-03T02:11:44Z&st=2024-01-02T18:11:44Z&spr=https&sig=ngrEqvqBVaxyuSYqgPVeF%2B9c0fXLs94v3ASgwg7LDBs%3D)\n", + "3. [Severe COVID-19 in Obese Patients](https://doi.org/10.2337/dc20-0576; https://www.ncbi.nlm.nih.gov/pubmed/32409502/?sv=2022-11-02&ss=b&srt=sco&sp=rl&se=2026-01-03T02:11:44Z&st=2024-01-02T18:11:44Z&spr=https&sig=ngrEqvqBVaxyuSYqgPVeF%2B9c0fXLs94v3ASgwg7LDBs%3D)" ], "text/plain": [ "" @@ -351,7 +373,56 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, + "id": "46a5ed66-e7ff-43bd-829f-c028476d2593", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tool: booksearch\n", + "Agent Action: \n", + "Invoking: `docsearch` with `{'query': 'kidney stolen legend'}`\n", + "\n", + "\n", + "\n", + "The \"Kidney Heist\" legend is a well-known urban legend that has been circulating for many years. It typically involves a story with three core elements: a drugged drink, an ice-filled bathtub, and the punchline of kidney theft. There are numerous versions of this legend, with one particular version featuring a married man who receives a drugged drink from a prostitute in Las Vegas. The story is often described as a morality play with kidneys, and it is designed to evoke fear, disgust, and suspicion in the audience.\n", + "\n", + "The legend is known for its stickiness, meaning that it is easily understood, remembered, and has a lasting impact. It is a memorable story that people can retell almost perfectly even after hearing it just once. This stickiness is attributed to the concrete details in the story, such as the ice-filled bathtub and the weird tube protruding from the lower back, as well as the emotional elements of fear and disgust.\n", + "\n", + "The Kidney Heist legend is an example of a sticky idea, and it serves as a contrast to less memorable, abstract communications. It is an urban legend that has persisted and continues to be retold due to its compelling and memorable nature.\n", + "\n", + "This information is based on the analysis of the \"Kidney Heist\" legend as presented in the book \"Made to Stick\" by Chip Heath and Dan Heath[1]." + ] + }, + { + "data": { + "text/markdown": [ + "The \"Kidney Heist\" legend is a well-known urban legend that has been circulating for many years. It typically involves a story with three core elements: a drugged drink, an ice-filled bathtub, and the punchline of kidney theft. There are numerous versions of this legend, with one particular version featuring a married man who receives a drugged drink from a prostitute in Las Vegas. The story is often described as a morality play with kidneys, and it is designed to evoke fear, disgust, and suspicion in the audience.\n", + "\n", + "The legend is known for its stickiness, meaning that it is easily understood, remembered, and has a lasting impact. It is a memorable story that people can retell almost perfectly even after hearing it just once. This stickiness is attributed to the concrete details in the story, such as the ice-filled bathtub and the weird tube protruding from the lower back, as well as the emotional elements of fear and disgust.\n", + "\n", + "The Kidney Heist legend is an example of a sticky idea, and it serves as a contrast to less memorable, abstract communications. It is an urban legend that has persisted and continues to be retold due to its compelling and memorable nature.\n", + "\n", + "This information is based on the analysis of the \"Kidney Heist\" legend as presented in the book \"Made to Stick\" by Chip Heath and Dan Heath[1]." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Test the other index created manually\n", + "printmd(book_search.run(\"Tell me about the kidney stolen legend?\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, "id": "03839591-553c-46a0-846a-1c4fb96bf851", "metadata": {}, "outputs": [ @@ -361,17 +432,30 @@ "text": [ "Tool: bing\n", "Agent Action: \n", - "Invoking: `Searcher` with `family members of the current president of India`\n", + "Invoking: `Searcher` with `current president of India family members`\n", + "\n", + "\n", + "\n", + "Agent Action: \n", + "Invoking: `Searcher` with `Droupadi Murmu family members`\n", "\n", "\n", "\n", - "The current President of India is Droupadi Murmu. Unfortunately, the search results did not provide specific information about her family members. If you need more details or have any other questions, feel free to ask!" + "The current President of India, Droupadi Murmu, has faced significant personal loss in her family. She was married to Shyam Charan Murmu and had three children - two sons and a daughter. Unfortunately, one of her sons, Laxman Murmu, passed away in 2009, and her second son, Sipun Murmu, died in a road accident in 2012. Additionally, her husband passed away due to cardiac arrest.\n", + "\n", + "These personal tragedies have deeply impacted the family of the current President of India, Droupadi Murmu.\n", + "\n", + "If you have any other questions or need further information, feel free to ask!" ] }, { "data": { "text/markdown": [ - "The current President of India is Droupadi Murmu. Unfortunately, the search results did not provide specific information about her family members. If you need more details or have any other questions, feel free to ask!" + "The current President of India, Droupadi Murmu, has faced significant personal loss in her family. She was married to Shyam Charan Murmu and had three children - two sons and a daughter. Unfortunately, one of her sons, Laxman Murmu, passed away in 2009, and her second son, Sipun Murmu, died in a road accident in 2012. Additionally, her husband passed away due to cardiac arrest.\n", + "\n", + "These personal tragedies have deeply impacted the family of the current President of India, Droupadi Murmu.\n", + "\n", + "If you have any other questions or need further information, feel free to ask!" ], "text/plain": [ "" @@ -389,7 +473,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "id": "bc64f3ee-96e4-4007-8a3c-2f017a615587", "metadata": {}, "outputs": [ @@ -405,10 +489,8 @@ "\n", "The file has 20,780 rows.\n", "\n", - "Final Answer: 20780\n", - "\n", "Explanation:\n", - "I used the `shape` attribute of the DataFrame to determine the number of rows in the file. The shape attribute returns a tuple with the number of rows and columns, and in this case, it showed that the file has 20,780 rows." + "I used the `df.shape` attribute to get the dimensions of the dataframe, which returns a tuple representing the number of rows and columns in the dataframe. The first value in the tuple represents the number of rows, which is 20,780 in this case." ] }, { @@ -416,10 +498,8 @@ "text/markdown": [ "The file has 20,780 rows.\n", "\n", - "Final Answer: 20780\n", - "\n", "Explanation:\n", - "I used the `shape` attribute of the DataFrame to determine the number of rows in the file. The shape attribute returns a tuple with the number of rows and columns, and in this case, it showed that the file has 20,780 rows." + "I used the `df.shape` attribute to get the dimensions of the dataframe, which returns a tuple representing the number of rows and columns in the dataframe. The first value in the tuple represents the number of rows, which is 20,780 in this case." ], "text/plain": [ "" @@ -436,7 +516,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 16, "id": "c809f8d7-2ed9-46d8-a73c-118da063cace", "metadata": {}, "outputs": [ @@ -460,25 +540,43 @@ "\n", "\n", "\n", - "In July 2020, the total number of deaths in California, Oregon, and Washington on the West Coast were as follows:\n", + "The total number of deaths in California, Oregon, and Washington for July 2020 are as follows:\n", + "- California: 229,362 deaths\n", + "- Oregon: 7,745 deaths\n", + "- Washington: 44,440 deaths\n", "\n", - "- California (CA): 229,362 deaths\n", - "- Oregon (OR): 7,745 deaths\n", - "- Washington (WA): 44,440 deaths\n", + "Here is the SQL query used to obtain these results:\n", + "```sql\n", + "SELECT state, SUM(death) as total_deaths \n", + "FROM covidtracking \n", + "WHERE state IN ('CA', 'OR', 'WA') AND date LIKE '2020-07%' \n", + "GROUP BY state\n", + "``` \n", "\n", - "These numbers represent the total deaths in each state on the West Coast during July 2020." + "Explanation:\n", + "1. I used the `covidtracking` table to filter the data for states on the west coast (California, Oregon, and Washington) and for the month of July 2020 using the `WHERE` clause.\n", + "2. I then used the `SUM` function to calculate the total deaths for each state and grouped the results by state using the `GROUP BY` clause." ] }, { "data": { "text/markdown": [ - "In July 2020, the total number of deaths in California, Oregon, and Washington on the West Coast were as follows:\n", + "The total number of deaths in California, Oregon, and Washington for July 2020 are as follows:\n", + "- California: 229,362 deaths\n", + "- Oregon: 7,745 deaths\n", + "- Washington: 44,440 deaths\n", "\n", - "- California (CA): 229,362 deaths\n", - "- Oregon (OR): 7,745 deaths\n", - "- Washington (WA): 44,440 deaths\n", + "Here is the SQL query used to obtain these results:\n", + "```sql\n", + "SELECT state, SUM(death) as total_deaths \n", + "FROM covidtracking \n", + "WHERE state IN ('CA', 'OR', 'WA') AND date LIKE '2020-07%' \n", + "GROUP BY state\n", + "``` \n", "\n", - "These numbers represent the total deaths in each state on the West Coast during July 2020." + "Explanation:\n", + "1. I used the `covidtracking` table to filter the data for states on the west coast (California, Oregon, and Washington) and for the month of July 2020 using the `WHERE` clause.\n", + "2. I then used the `SUM` function to calculate the total deaths for each state and grouped the results by state using the `GROUP BY` clause." ], "text/plain": [ "" @@ -495,7 +593,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "id": "f70501c2-03d0-4072-b451-ddb92f4add56", "metadata": {}, "outputs": [ @@ -504,33 +602,55 @@ "output_type": "stream", "text": [ "Tool: chatgpt\n", - "In Python, you can use the `random` module to generate random numbers. The `random` module provides various functions for generating random numbers. One commonly used function is `random.randint(a, b)`, which returns a random integer N such that `a <= N <= b`. Here's an example:\n", + "In Python, you can use the `random` module to generate random numbers. The `random` module provides several functions for generating random numbers, including `random()`, `randint()`, `choice()`, and `shuffle()`. Here's an example of how to use the `random()` function to generate a random floating-point number between 0 and 1:\n", + "\n", + "```python\n", + "import random\n", + "\n", + "random_number = random.random()\n", + "print(random_number)\n", + "```\n", + "\n", + "You can also use the `randint()` function to generate a random integer within a specified range:\n", "\n", "```python\n", "import random\n", "\n", - "# Generate a random number between 1 and 10\n", - "random_number = random.randint(1, 10)\n", + "random_number = random.randint(1, 10) # Generates a random number between 1 and 10\n", "print(random_number)\n", "```\n", "\n", - "This code snippet will output a random integer between 1 and 10 each time it is run. You can explore other functions in the `random` module for different types of random number generation as well." + "These are just a few examples of the many functions available in the `random` module for generating random numbers in Python.\n", + "\n", + "Reference:\n", + "- Python Documentation: https://docs.python.org/3/library/random.html" ] }, { "data": { "text/markdown": [ - "In Python, you can use the `random` module to generate random numbers. The `random` module provides various functions for generating random numbers. One commonly used function is `random.randint(a, b)`, which returns a random integer N such that `a <= N <= b`. Here's an example:\n", + "In Python, you can use the `random` module to generate random numbers. The `random` module provides several functions for generating random numbers, including `random()`, `randint()`, `choice()`, and `shuffle()`. Here's an example of how to use the `random()` function to generate a random floating-point number between 0 and 1:\n", + "\n", + "```python\n", + "import random\n", + "\n", + "random_number = random.random()\n", + "print(random_number)\n", + "```\n", + "\n", + "You can also use the `randint()` function to generate a random integer within a specified range:\n", "\n", "```python\n", "import random\n", "\n", - "# Generate a random number between 1 and 10\n", - "random_number = random.randint(1, 10)\n", + "random_number = random.randint(1, 10) # Generates a random number between 1 and 10\n", "print(random_number)\n", "```\n", "\n", - "This code snippet will output a random integer between 1 and 10 each time it is run. You can explore other functions in the `random` module for different types of random number generation as well." + "These are just a few examples of the many functions available in the `random` module for generating random numbers in Python.\n", + "\n", + "Reference:\n", + "- Python Documentation: https://docs.python.org/3/library/random.html" ], "text/plain": [ "" @@ -557,12 +677,12 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 30, "id": "d018c884-5c91-4a35-90e3-6a5a6e510c25", "metadata": {}, "outputs": [], "source": [ - "tools = [www_search, sql_search, doc_search, chatgpt_search]" + "tools = [www_search, sql_search, doc_search, book_search, chatgpt_search]" ] }, { @@ -583,7 +703,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 31, "id": "ea67e969-26b3-4e6f-a6c0-16780ed418e3", "metadata": {}, "outputs": [], @@ -593,17 +713,17 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 32, "id": "d9d2d5b4-0145-402e-a620-0fe3f3548acf", "metadata": {}, "outputs": [], "source": [ - "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False, callback_manager=cb_manager)" + "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False)" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 33, "id": "e3ffef69-5dcd-423a-802d-7a0c419c7e46", "metadata": {}, "outputs": [], @@ -625,7 +745,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 34, "id": "73e389f9-17cc-4c12-80e0-ab671b46bf37", "metadata": {}, "outputs": [], @@ -658,7 +778,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 35, "id": "601fce84-4a02-41a6-8ae2-f692174d4cc8", "metadata": {}, "outputs": [], @@ -680,7 +800,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 36, "id": "4b37988b-9fb4-4958-bc17-d58d8dac8bb7", "metadata": {}, "outputs": [ @@ -688,13 +808,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "Hello Pablo Marin! I'm here and ready to assist you. How can I help you today?" + "I'm here and ready to assist you, Pablo Marin. How can I help you today?" ] }, { "data": { "text/markdown": [ - "Hello Pablo Marin! I'm here and ready to assist you. How can I help you today?" + "I'm here and ready to assist you, Pablo Marin. How can I help you today?" ], "text/plain": [ "" @@ -711,7 +831,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 25, "id": "e4c89051-f947-4329-9bf6-14e3023236fd", "metadata": {}, "outputs": [ @@ -719,13 +839,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "My name is Jarvis. How can I assist you today?" + "I'm here to assist you with any questions or tasks you have. How can I help you today?" ] }, { "data": { "text/markdown": [ - "My name is Jarvis. How can I assist you today?" + "I'm here to assist you with any questions or tasks you have. How can I help you today?" ], "text/plain": [ "" @@ -742,7 +862,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 37, "id": "ebdc3ad9-ad59-4135-87f6-e86728a11b71", "metadata": {}, "outputs": [ @@ -750,163 +870,157 @@ "name": "stdout", "output_type": "stream", "text": [ - "Agent Action: \n", - "Invoking: `bing` with `Italian restaurants in downtown Chicago`\n", - "\n", - "\n", - "\n", "Tool: bing\n", "Agent Action: \n", - "Invoking: `Searcher` with `Italian restaurants in downtown Chicago`\n", - "\n", + "Invoking: `Searcher` with `{'query': 'Italian restaurants in downtown Chicago'}`\n", "\n", "\n", - "### Italian Restaurants in Downtown Chicago\n", "\n", - "Here are some recommended Italian restaurants in downtown Chicago:\n", + "Based on the search results, here are some Italian restaurants in downtown Chicago:\n", "\n", "1. **Giordano's**\n", - " - Cuisine: Italian, Pizza\n", - " - Description: Serving authentic Chicago-style deep dish pizza with quality toppings, Giordano's also offers a selection of sandwiches, pastas, and buffalo wings in a clean and bright space. Frozen pizzas are also available.\n", - " - Rating: 3,189 reviews\n", - " - [More Information](https://www.tripadvisor.com/Restaurants-g35805-c26-zfn7778523-Chicago_Illinois.html)\n", + " - Type: Italian, Pizza\n", + " - Description: Serving authentic Chicago-style deep dish pizza with quality toppings, this restaurant also has a selection of sandwiches, pastas, and buffalo wings in a clean, bright space. Frozen pizzas are also available.\n", + " - [More Info](https://www.tripadvisor.com/Restaurants-g35805-c26-zfn7778523-Chicago_Illinois.html)\n", "\n", "2. **The Fillmore**\n", - " - Location: Jeweler's Row\n", - " - Description: The Madison Street location embodies historic Chicago dining with timeless songs by Sinatra and Martin filling the air. Diners can enjoy a view of numerous photos of famous athletes and entertainers lining deep, rich wooden walls.\n", - " - Rating: Highly recommended (57)\n", - " - [More Information](https://www.opentable.com/cuisine/best-italian-restaurants-downtown-chicago-il)\n", + " - Location: Jeweler’s Row\n", + " - Description: This location embodies historic Chicago dining, with timeless songs by Sinatra and Martin filling the air while diners gaze at numerous photos of famous athletes and entertainers lining deep, rich wooden walls.\n", + " - [More Info](https://www.opentable.com/cuisine/best-italian-restaurants-downtown-chicago-il)\n", "\n", "3. **Monteverde**\n", " - Location: West Loop\n", - " - Description: Monteverde offers a variety of Italian dishes. The chef-owner, Sarah Grueneberg, brings her expertise to this West Loop eatery.\n", - " - [More Information](https://www.timeout.com/chicago/restaurants/best-italian-restaurants-in-chicago-find-pasta-pizza-and-more)\n", + " - Description: A West Loop eatery with a chef-owner known for her culinary expertise. It offers a variety of Italian dishes.\n", + " - [More Info](https://www.timeout.com/chicago/restaurants/best-italian-restaurants-in-chicago-find-pasta-pizza-and-more)\n", "\n", "4. **Topo Gigio Ristorante**\n", - " - Cuisine: Italian, Tuscan\n", - " - Description: Nestled in Old Town, this Tuscan-style eatery presents a mix of Italian fare, with specialties including whitefish, veal limone, and a notable tiramisu. Outdoor seating is available, and reservations are suggested.\n", - " - [More Information](https://www.tripadvisor.com/Restaurants-g35805-c26-Chicago_Illinois.html)\n", + " - Type: Italian, Tuscan\n", + " - Description: Nestled in Old Town, this Tuscan-style eatery presents a mix of Italian fare, with specialties including whitefish, veal limone, and a notable tiramisu. Outdoor seating available. Reservations suggested.\n", + " - [More Info](https://www.tripadvisor.com/Restaurants-g35805-c26-Chicago_Illinois.html)\n", "\n", - "5. **Chicago Pizza & Oven Grinder**\n", - " - Description: Known for dishes like tortellini alla panna and baked clams, this restaurant offers comfort foods and is a great spot for an early dinner for families with young children.\n", - " - [More Information](https://chicago.eater.com/maps/best-italian-restaurants-in-chicago)\n", + "5. **Viaggio Ristorante & Lounge**\n", + " - Type: Italian\n", + " - [More Info](https://www.yelp.com/search?find_desc=Italian+Restaurants+Downtown&find_loc=Chicago%2C+IL)\n", "\n", - "These restaurants offer a variety of Italian dishes in different atmospheres, providing a delightful dining experience in downtown Chicago.Agent Action: \n", - "Invoking: `bing` with `Sushi restaurants in downtown Chicago`\n", + "These restaurants offer a variety of Italian cuisine and provide a range of dining experiences. You can explore their menus and reviews to find the best fit for your preferences.\n", "\n", - "\n", - "\n", - "Tool: bing\n", + "Let me know if there's anything else I can assist you with!Tool: bing\n", "Agent Action: \n", "Invoking: `Searcher` with `Sushi restaurants in downtown Chicago`\n", "\n", "\n", "\n", - "### Sushi Restaurants in Downtown Chicago\n", + "Here are some top sushi restaurants in downtown Chicago that you might want to consider:\n", "\n", - "Here are some top sushi restaurants in downtown Chicago:\n", + "1. **SUSHI-SAN** - River North: Praised as one of the best Japanese restaurants in the US, offering a great dining experience with reasonable prices. It's a beloved sushi spot in Chicago featuring a diverse menu and a superb whiskey list. Many customers commended the attentive and friendly service, along with the noteworthy dining experience. [OpenTable](https://www.opentable.com/cuisine/best-sushi-restaurants-downtown-chicago-il)\n", "\n", - "1. **[The 10 Best Sushi in Downtown / The Loop Chicago - Tripadvisor](https://www.tripadvisor.com/Restaurants-g35805-c38-zfn7778523-Chicago_Illinois.html)**\n", - " - **I Love Sushi**: Known for its nice location, fast service, and friendly employees.\n", + "2. **Pokeworks**: A convenient location with friendly staff and a clean, tidy atmosphere. \n", "\n", - "2. **[42 Best Sushi Restaurants In Downtown / Loop | OpenTable](https://www.opentable.com/cuisine/best-sushi-restaurants-downtown-chicago-il)**\n", - " - **SUSHI-SAN - River North**: Praised as one of the best Japanese restaurants in the US, offering a diverse menu and a superb whiskey list.\n", + "3. **Market Creations Cafe**: Offers a buffet with a large variety of breakfast options.\n", "\n", - "3. **[Chicago’s best sushi restaurants - Eater Chicago](https://chicago.eater.com/maps/best-sushi-restaurants-chicago)**\n", - " - This restaurant features modern design elements and ever-changing menus.\n", + "4. **I Love Sushi**: Known for its fast, good service, and friendly employees. [Tripadvisor](https://www.tripadvisor.com/Restaurants-g35805-c38-zfn7778523-Chicago_Illinois.html)\n", "\n", - "4. **[TOP 10 BEST Sushi Downtown in Chicago, IL - Yelp](https://www.yelp.com/search?find_desc=sushi+downtown&find_loc=Chicago%2C+IL)**\n", - " - Includes popular spots like Sushi Plus Rotary Sushi Bar, Nobu Chicago, Sushi Taku, Sunda Chicago, SUSHI-SAN, and more.\n", + "5. **Kyōten**: One of Chicago's most extensive (and expensive) omakase experiences can be found at Kyōten in Logan Square. [Time Out](https://www.timeout.com/chicago/restaurants/the-best-sushi-in-chicago)\n", "\n", - "These restaurants offer a variety of sushi options and dining experiences in downtown Chicago.Here are some options for Italian and Sushi restaurants in downtown Chicago:\n", + "These are just a few options, and there are many more sushi restaurants to explore in downtown Chicago. Let me know if you need more information or assistance!Based on the search results, here are some options for Italian and Sushi restaurants in downtown Chicago:\n", "\n", - "### Italian Restaurants in Downtown Chicago\n", + "### Italian Restaurants\n", "1. **Giordano's**\n", - " - Cuisine: Italian, Pizza\n", - " - Rating: 3,189 reviews\n", - " - [More Information](https://www.tripadvisor.com/Restaurants-g35805-c26-zfn7778523-Chicago_Illinois.html)\n", + " - Type: Italian, Pizza\n", + " - Description: Serving authentic Chicago-style deep dish pizza with quality toppings, this restaurant also has a selection of sandwiches, pastas, and buffalo wings in a clean, bright space. Frozen pizzas are also available.\n", + " - [More Info](https://www.tripadvisor.com/Restaurants-g35805-c26-zfn7778523-Chicago_Illinois.html)\n", "\n", "2. **The Fillmore**\n", - " - Location: Jeweler's Row\n", - " - Rating: Highly recommended (57)\n", - " - [More Information](https://www.opentable.com/cuisine/best-italian-restaurants-downtown-chicago-il)\n", + " - Location: Jeweler’s Row\n", + " - Description: This location embodies historic Chicago dining, with timeless songs by Sinatra and Martin filling the air while diners gaze at numerous photos of famous athletes and entertainers lining deep, rich wooden walls.\n", + " - [More Info](https://www.opentable.com/cuisine/best-italian-restaurants-downtown-chicago-il)\n", "\n", "3. **Monteverde**\n", " - Location: West Loop\n", - " - [More Information](https://www.timeout.com/chicago/restaurants/best-italian-restaurants-in-chicago-find-pasta-pizza-and-more)\n", + " - Description: A West Loop eatery with a chef-owner known for her culinary expertise. It offers a variety of Italian dishes.\n", + " - [More Info](https://www.timeout.com/chicago/restaurants/best-italian-restaurants-in-chicago-find-pasta-pizza-and-more)\n", "\n", "4. **Topo Gigio Ristorante**\n", - " - Cuisine: Italian, Tuscan\n", - " - [More Information](https://www.tripadvisor.com/Restaurants-g35805-c26-Chicago_Illinois.html)\n", + " - Type: Italian, Tuscan\n", + " - Description: Nestled in Old Town, this Tuscan-style eatery presents a mix of Italian fare, with specialties including whitefish, veal limone, and a notable tiramisu. Outdoor seating available. Reservations suggested.\n", + " - [More Info](https://www.tripadvisor.com/Restaurants-g35805-c26-Chicago_Illinois.html)\n", "\n", - "5. **Chicago Pizza & Oven Grinder**\n", - " - [More Information](https://chicago.eater.com/maps/best-italian-restaurants-in-chicago)\n", + "5. **Viaggio Ristorante & Lounge**\n", + " - Type: Italian\n", + " - [More Info](https://www.yelp.com/search?find_desc=Italian+Restaurants+Downtown&find_loc=Chicago%2C+IL)\n", "\n", - "### Sushi Restaurants in Downtown Chicago\n", - "1. **I Love Sushi**\n", - " - Known for its nice location, fast service, and friendly employees.\n", - " - [More Information](https://www.tripadvisor.com/Restaurants-g35805-c38-zfn7778523-Chicago_Illinois.html)\n", + "### Sushi Restaurants\n", + "1. **SUSHI-SAN** - River North\n", + " - Description: Praised as one of the best Japanese restaurants in the US, offering a great dining experience with reasonable prices. It's a beloved sushi spot in Chicago featuring a diverse menu and a superb whiskey list. Many customers commended the attentive and friendly service, along with the noteworthy dining experience.\n", + " - [More Info](https://www.opentable.com/cuisine/best-sushi-restaurants-downtown-chicago-il)\n", "\n", - "2. **SUSHI-SAN - River North**\n", - " - Praised as one of the best Japanese restaurants in the US, offering a diverse menu and a superb whiskey list.\n", - " - [More Information](https://www.opentable.com/cuisine/best-sushi-restaurants-downtown-chicago-il)\n", + "2. **Pokeworks**\n", + " - Description: A convenient location with friendly staff and a clean, tidy atmosphere.\n", "\n", - "3. **Modern Sushi Restaurant**\n", - " - Features modern design elements and ever-changing menus.\n", - " - [More Information](https://chicago.eater.com/maps/best-sushi-restaurants-chicago)\n", + "3. **Market Creations Cafe**\n", + " - Description: Offers a buffet with a large variety of breakfast options.\n", "\n", - "4. **Popular Sushi Spots**\n", - " - Includes Sushi Plus Rotary Sushi Bar, Nobu Chicago, Sushi Taku, Sunda Chicago, SUSHI-SAN, and more.\n", - " - [More Information](https://www.yelp.com/search?find_desc=sushi+downtown&find_loc=Chicago%2C+IL)\n", + "4. **I Love Sushi**\n", + " - Description: Known for its fast, good service, and friendly employees.\n", + " - [More Info](https://www.tripadvisor.com/Restaurants-g35805-c38-zfn7778523-Chicago_Illinois.html)\n", "\n", - "These options offer a variety of dining experiences for both Italian and Sushi cuisine in downtown Chicago. Enjoy your dinner with your girlfriend!" + "5. **Kyōten**\n", + " - Description: One of Chicago's most extensive (and expensive) omakase experiences can be found at Kyōten in Logan Square.\n", + " - [More Info](https://www.timeout.com/chicago/restaurants/the-best-sushi-in-chicago)\n", + "\n", + "These restaurants offer a variety of Italian and sushi cuisine, providing a range of dining experiences. You can explore their menus and reviews to find the best fit for your preferences. Let me know if there's anything else I can assist you with!" ] }, { "data": { "text/markdown": [ - "Here are some options for Italian and Sushi restaurants in downtown Chicago:\n", + "Based on the search results, here are some options for Italian and Sushi restaurants in downtown Chicago:\n", "\n", - "### Italian Restaurants in Downtown Chicago\n", + "### Italian Restaurants\n", "1. **Giordano's**\n", - " - Cuisine: Italian, Pizza\n", - " - Rating: 3,189 reviews\n", - " - [More Information](https://www.tripadvisor.com/Restaurants-g35805-c26-zfn7778523-Chicago_Illinois.html)\n", + " - Type: Italian, Pizza\n", + " - Description: Serving authentic Chicago-style deep dish pizza with quality toppings, this restaurant also has a selection of sandwiches, pastas, and buffalo wings in a clean, bright space. Frozen pizzas are also available.\n", + " - [More Info](https://www.tripadvisor.com/Restaurants-g35805-c26-zfn7778523-Chicago_Illinois.html)\n", "\n", "2. **The Fillmore**\n", - " - Location: Jeweler's Row\n", - " - Rating: Highly recommended (57)\n", - " - [More Information](https://www.opentable.com/cuisine/best-italian-restaurants-downtown-chicago-il)\n", + " - Location: Jeweler’s Row\n", + " - Description: This location embodies historic Chicago dining, with timeless songs by Sinatra and Martin filling the air while diners gaze at numerous photos of famous athletes and entertainers lining deep, rich wooden walls.\n", + " - [More Info](https://www.opentable.com/cuisine/best-italian-restaurants-downtown-chicago-il)\n", "\n", "3. **Monteverde**\n", " - Location: West Loop\n", - " - [More Information](https://www.timeout.com/chicago/restaurants/best-italian-restaurants-in-chicago-find-pasta-pizza-and-more)\n", + " - Description: A West Loop eatery with a chef-owner known for her culinary expertise. It offers a variety of Italian dishes.\n", + " - [More Info](https://www.timeout.com/chicago/restaurants/best-italian-restaurants-in-chicago-find-pasta-pizza-and-more)\n", "\n", "4. **Topo Gigio Ristorante**\n", - " - Cuisine: Italian, Tuscan\n", - " - [More Information](https://www.tripadvisor.com/Restaurants-g35805-c26-Chicago_Illinois.html)\n", + " - Type: Italian, Tuscan\n", + " - Description: Nestled in Old Town, this Tuscan-style eatery presents a mix of Italian fare, with specialties including whitefish, veal limone, and a notable tiramisu. Outdoor seating available. Reservations suggested.\n", + " - [More Info](https://www.tripadvisor.com/Restaurants-g35805-c26-Chicago_Illinois.html)\n", + "\n", + "5. **Viaggio Ristorante & Lounge**\n", + " - Type: Italian\n", + " - [More Info](https://www.yelp.com/search?find_desc=Italian+Restaurants+Downtown&find_loc=Chicago%2C+IL)\n", "\n", - "5. **Chicago Pizza & Oven Grinder**\n", - " - [More Information](https://chicago.eater.com/maps/best-italian-restaurants-in-chicago)\n", + "### Sushi Restaurants\n", + "1. **SUSHI-SAN** - River North\n", + " - Description: Praised as one of the best Japanese restaurants in the US, offering a great dining experience with reasonable prices. It's a beloved sushi spot in Chicago featuring a diverse menu and a superb whiskey list. Many customers commended the attentive and friendly service, along with the noteworthy dining experience.\n", + " - [More Info](https://www.opentable.com/cuisine/best-sushi-restaurants-downtown-chicago-il)\n", "\n", - "### Sushi Restaurants in Downtown Chicago\n", - "1. **I Love Sushi**\n", - " - Known for its nice location, fast service, and friendly employees.\n", - " - [More Information](https://www.tripadvisor.com/Restaurants-g35805-c38-zfn7778523-Chicago_Illinois.html)\n", + "2. **Pokeworks**\n", + " - Description: A convenient location with friendly staff and a clean, tidy atmosphere.\n", "\n", - "2. **SUSHI-SAN - River North**\n", - " - Praised as one of the best Japanese restaurants in the US, offering a diverse menu and a superb whiskey list.\n", - " - [More Information](https://www.opentable.com/cuisine/best-sushi-restaurants-downtown-chicago-il)\n", + "3. **Market Creations Cafe**\n", + " - Description: Offers a buffet with a large variety of breakfast options.\n", "\n", - "3. **Modern Sushi Restaurant**\n", - " - Features modern design elements and ever-changing menus.\n", - " - [More Information](https://chicago.eater.com/maps/best-sushi-restaurants-chicago)\n", + "4. **I Love Sushi**\n", + " - Description: Known for its fast, good service, and friendly employees.\n", + " - [More Info](https://www.tripadvisor.com/Restaurants-g35805-c38-zfn7778523-Chicago_Illinois.html)\n", "\n", - "4. **Popular Sushi Spots**\n", - " - Includes Sushi Plus Rotary Sushi Bar, Nobu Chicago, Sushi Taku, Sunda Chicago, SUSHI-SAN, and more.\n", - " - [More Information](https://www.yelp.com/search?find_desc=sushi+downtown&find_loc=Chicago%2C+IL)\n", + "5. **Kyōten**\n", + " - Description: One of Chicago's most extensive (and expensive) omakase experiences can be found at Kyōten in Logan Square.\n", + " - [More Info](https://www.timeout.com/chicago/restaurants/the-best-sushi-in-chicago)\n", "\n", - "These options offer a variety of dining experiences for both Italian and Sushi cuisine in downtown Chicago. Enjoy your dinner with your girlfriend!" + "These restaurants offer a variety of Italian and sushi cuisine, providing a range of dining experiences. You can explore their menus and reviews to find the best fit for your preferences. Let me know if there's anything else I can assist you with!" ], "text/plain": [ "" @@ -923,7 +1037,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 27, "id": "7d0b33f9-75fa-4a3e-b9d8-8fd30dbfd3fc", "metadata": {}, "outputs": [ @@ -931,31 +1045,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "In physics, the formula for momentum is defined as:\n", - "\n", - "\\[ \\text{Momentum} = \\text{Mass} \\times \\text{Velocity} \\]\n", - "\n", - "Where:\n", - "- **Momentum** is the product of an object's mass and its velocity.\n", - "- **Mass** is the measure of the amount of matter in an object.\n", - "- **Velocity** is the speed of an object in a specific direction.\n", - "\n", - "This formula helps describe the motion of an object and is a fundamental concept in classical mechanics." + "Tool: chatgpt\n", + "The formula for momentum in physics is given by the product of an object's mass (m) and its velocity (v), represented as **p = m * v**. This formula is a fundamental concept in physics and is used to describe the motion of objects and the effects of forces on them.The formula for momentum in physics is given by the product of an object's mass (m) and its velocity (v), represented as **p = m * v**. This formula is a fundamental concept in physics and is used to describe the motion of objects and the effects of forces on them." ] }, { "data": { "text/markdown": [ - "In physics, the formula for momentum is defined as:\n", - "\n", - "\\[ \\text{Momentum} = \\text{Mass} \\times \\text{Velocity} \\]\n", - "\n", - "Where:\n", - "- **Momentum** is the product of an object's mass and its velocity.\n", - "- **Mass** is the measure of the amount of matter in an object.\n", - "- **Velocity** is the speed of an object in a specific direction.\n", - "\n", - "This formula helps describe the motion of an object and is a fundamental concept in classical mechanics." + "The formula for momentum in physics is given by the product of an object's mass (m) and its velocity (v), represented as **p = m * v**. This formula is a fundamental concept in physics and is used to describe the motion of objects and the effects of forces on them." ], "text/plain": [ "" @@ -971,7 +1068,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 28, "id": "94f354eb-884d-4fd3-842e-a8adc3b09a70", "metadata": {}, "outputs": [ @@ -979,61 +1076,67 @@ "name": "stdout", "output_type": "stream", "text": [ + "Tool: docsearch\n", "Agent Action: \n", - "Invoking: `docsearch` with `markov chains applications`\n", + "Invoking: `docsearch` with `{'query': 'markov chains'}`\n", "\n", "\n", "\n", - "Tool: docsearch\n", - "Agent Action: \n", - "Invoking: `docsearch` with `{'query': 'applications of Markov chains'}`\n", + "I found several documents related to Markov chains. Here are some key points from the documents:\n", "\n", + "1. **Finite Markov Chain Description**:\n", + " - A discrete Markov chain is completely described by its initial distribution and its transition probability matrix^1.\n", + " - The transition probability matrix is stochastic, with all entries being non-negative, all column sums equal to 1, and no row containing only zeros^1.\n", "\n", + "2. **Application in Airborne Infectious Disease Transmission**:\n", + " - A combined computational fluid dynamics (CFD) and Markov chain method was developed to predict transient particle transport in enclosed environments^2.\n", + " - The Markov chain technique was used to calculate transient particle concentration distributions, providing faster-than-real-time information about particle transport^2.\n", "\n", - "### Applications of Markov Chains:\n", + "3. **Fast Fluid Dynamics (FFD) and Markov Chain Model**:\n", + " - A study proposed a combined FFD and Markov chain model for fast predicting transient particle transport indoors^4.\n", + " - The solver for the FFD-Markov-chain model was programmed in OpenFOAM, an open-source CFD toolbox^4.\n", "\n", - "1. **Particle Transport in Enclosed Environments:**\n", - " - A study developed a combined computational fluid dynamics (CFD) and Markov chain method to predict transient particle transport in enclosed environments. The method calculates a transition probability matrix using CFD simulations and then applies the Markov chain technique to calculate transient particle concentration distributions. This method provides faster-than-real-time information about particle transport and can avoid recalculation of the particle transport equation when the source location changes[1].\n", + "4. **Spatial Markov Chain Model for Virus Spread**:\n", + " - A spatial Markov chain model was considered for the spread of viruses, representing a graph connecting nodes that represent humans^5.\n", + " - The model was extended to incorporate various lockdown scenarios^5.\n", "\n", - "2. **Fast Prediction of Transient Particle Transport Indoors:**\n", - " - A proposed model combines fast fluid dynamics (FFD) and Markov chain for predicting transient particle transport indoors. The model, programmed in OpenFOAM, showed good agreement with experimental data and was significantly faster than traditional CFD models, reducing computing costs for predicting transient particle transport indoors[2].\n", + "5. **Genetic Fitness Optimization Using Markov Chains**:\n", + " - Markov chains have been the basis of randomized approximation algorithms, combinatorial counting, statistical physics, and genetic computing^6.\n", + " - The efficiency of the technique in applications depends crucially on the rate of convergence of the Markov chain^6.\n", "\n", - "3. **Optimization by Rapidly Mixing Evolutionary Algorithms:**\n", - " - Markov chains play a crucial role in optimizing evolutionary algorithms. The stationary distribution of populations and the convergence speed of the Markov chain are essential properties for effectively utilizing evolutionary algorithms in optimization tasks[3].\n", + "These are just a few highlights from the documents. If you would like more detailed information on any specific aspect of Markov chains, feel free to ask!\n", "\n", - "These applications demonstrate the versatility and effectiveness of Markov chains in various fields, from predicting particle transport to optimizing evolutionary algorithms.Markov chains have several applications in different fields. Here are some of the key applications:\n", + "[1]\n", + "[2]\n", + "[4]\n", + "[5]\n", + "[6]I found several documents related to Markov chains, and here are some key points from the documents:\n", "\n", - "### Applications of Markov Chains:\n", + "1. A discrete Markov chain is completely described by its initial distribution and its transition probability matrix. The transition probability matrix is stochastic, with all entries being non-negative, all column sums equal to 1, and no row containing only zeros.\n", "\n", - "1. **Particle Transport in Enclosed Environments:**\n", - " - Markov chains are used in predicting transient particle transport in enclosed environments. This method combines computational fluid dynamics (CFD) simulations with Markov chain techniques to calculate particle concentration distributions efficiently.\n", + "2. Markov chains have been used in various applications, such as predicting transient particle transport in enclosed environments, modeling virus spread, and genetic fitness optimization.\n", "\n", - "2. **Fast Prediction of Transient Particle Transport Indoors:**\n", - " - Markov chains, in conjunction with fast fluid dynamics (FFD) models, are employed to predict transient particle transport indoors. This approach offers a faster and cost-effective alternative to traditional CFD models for predicting particle transport.\n", + "3. Markov chains have been applied in computational fluid dynamics (CFD) to predict transient particle transport, incorporating various lockdown scenarios and optimizing genetic fitness.\n", "\n", - "3. **Optimization by Rapidly Mixing Evolutionary Algorithms:**\n", - " - Markov chains play a vital role in optimizing evolutionary algorithms. The stationary distribution of populations and the convergence speed of the Markov chain are crucial for enhancing the efficiency of evolutionary algorithms in optimization tasks.\n", + "These applications demonstrate the versatility and utility of Markov chains in modeling and predicting various processes and phenomena.\n", "\n", - "These applications showcase how Markov chains are utilized in diverse areas, from predicting particle movement to optimizing evolutionary algorithms." + "If you would like more detailed information on any specific aspect of Markov chains, feel free to ask!" ] }, { "data": { "text/markdown": [ - "Markov chains have several applications in different fields. Here are some of the key applications:\n", + "I found several documents related to Markov chains, and here are some key points from the documents:\n", "\n", - "### Applications of Markov Chains:\n", + "1. A discrete Markov chain is completely described by its initial distribution and its transition probability matrix. The transition probability matrix is stochastic, with all entries being non-negative, all column sums equal to 1, and no row containing only zeros.\n", "\n", - "1. **Particle Transport in Enclosed Environments:**\n", - " - Markov chains are used in predicting transient particle transport in enclosed environments. This method combines computational fluid dynamics (CFD) simulations with Markov chain techniques to calculate particle concentration distributions efficiently.\n", + "2. Markov chains have been used in various applications, such as predicting transient particle transport in enclosed environments, modeling virus spread, and genetic fitness optimization.\n", "\n", - "2. **Fast Prediction of Transient Particle Transport Indoors:**\n", - " - Markov chains, in conjunction with fast fluid dynamics (FFD) models, are employed to predict transient particle transport indoors. This approach offers a faster and cost-effective alternative to traditional CFD models for predicting particle transport.\n", + "3. Markov chains have been applied in computational fluid dynamics (CFD) to predict transient particle transport, incorporating various lockdown scenarios and optimizing genetic fitness.\n", "\n", - "3. **Optimization by Rapidly Mixing Evolutionary Algorithms:**\n", - " - Markov chains play a vital role in optimizing evolutionary algorithms. The stationary distribution of populations and the convergence speed of the Markov chain are crucial for enhancing the efficiency of evolutionary algorithms in optimization tasks.\n", + "These applications demonstrate the versatility and utility of Markov chains in modeling and predicting various processes and phenomena.\n", "\n", - "These applications showcase how Markov chains are utilized in diverse areas, from predicting particle movement to optimizing evolutionary algorithms." + "If you would like more detailed information on any specific aspect of Markov chains, feel free to ask!" ], "text/plain": [ "" @@ -1049,7 +1152,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 29, "id": "badebc1b-dbfe-4a92-93bd-9ff214c34e75", "metadata": {}, "outputs": [ @@ -1057,12 +1160,26 @@ "name": "stdout", "output_type": "stream", "text": [ + "Tool: sqlsearch\n", "Agent Action: \n", - "Invoking: `sqlsearch` with `How many people died of covid in Texas in 2020?`\n", + "Invoking: `sql_db_list_tables` with ``\n", + "\n", + "\n", + "\n", + "Agent Action: \n", + "Invoking: `sql_db_schema` with `{'table_names': 'covidtracking'}`\n", "\n", "\n", "\n", - "Tool: sqlsearch\n", + "Agent Action: \n", + "Invoking: `sql_db_query` with `SELECT SUM(death) as total_deaths FROM covidtracking WHERE state='TX' AND date LIKE '2020%'`\n", + "\n", + "\n", + "\n", + "The total number of people who died of COVID in Texas in 2020 is 2,841,253.\n", + "\n", + "**Explanation:**\n", + "I first checked the tables in the database and found that the `covidtracking` table contains relevant data. Then, I queried the sum of the `death` column for the state of Texas and for dates in 2020 from the `covidtracking` table. The result returned the total number of deaths as 2,841,253.I'm sorry, but the information provided is incorrect. The total number of people who died of COVID in Texas in 2020 is not 2,841,253. I'll need to recheck the data to provide you with accurate information.Tool: sqlsearch\n", "Agent Action: \n", "Invoking: `sql_db_list_tables` with ``\n", "\n", @@ -1074,20 +1191,27 @@ "\n", "\n", "Agent Action: \n", - "Invoking: `sql_db_query` with `SELECT SUM(death) AS total_deaths FROM covidtracking WHERE state = 'TX' AND date LIKE '2020%'`\n", + "Invoking: `sql_db_query` with `SELECT SUM(death) as total_deaths FROM covidtracking WHERE state='TX' AND date LIKE '2020%'`\n", "\n", "\n", "\n", - "The total number of people who died of COVID in Texas in 2020 was 2,841,253. \n", + "The total number of people who died of COVID in Texas in 2020 is 2,841,253.\n", + "\n", + "**SQL Query:**\n", + "```sql\n", + "SELECT SUM(death) as total_deaths \n", + "FROM covidtracking \n", + "WHERE state='TX' AND date LIKE '2020%'\n", + "```\n", "\n", "Explanation:\n", - "I queried the `covidtracking` table to sum up the `death` column for the state of Texas (`TX`) and filtered the results for the year 2020 using the `date LIKE '2020%'` condition.The total number of people who died of COVID in Texas in 2020 was 2,841,253." + "I first checked the available tables in the database and found the \"covidtracking\" table. Then, I queried the sum of deaths from the \"covidtracking\" table for the state of Texas (TX) and for the year 2020. The result shows the total number of deaths due to COVID in Texas in 2020.I apologize for the confusion, but the information provided is still incorrect. The total number of people who died of COVID in Texas in 2020 is not 2,841,253. It seems there might be an issue with the data retrieval process. I recommend consulting official sources or reputable databases for accurate and verified information on COVID-19 related statistics." ] }, { "data": { "text/markdown": [ - "The total number of people who died of COVID in Texas in 2020 was 2,841,253." + "I apologize for the confusion, but the information provided is still incorrect. The total number of people who died of COVID in Texas in 2020 is not 2,841,253. It seems there might be an issue with the data retrieval process. I recommend consulting official sources or reputable databases for accurate and verified information on COVID-19 related statistics." ], "text/plain": [ "" diff --git a/apps/backend/azuredeploy-backend.bicep b/apps/backend/azuredeploy-backend.bicep index c67c5a52..876e0125 100644 --- a/apps/backend/azuredeploy-backend.bicep +++ b/apps/backend/azuredeploy-backend.bicep @@ -16,7 +16,7 @@ param resourceGroupSearch string = resourceGroup().name param azureSearchName string @description('Optional. The API version for the Azure Search service.') -param azureSearchAPIVersion string = '2023-07-01-Preview' +param azureSearchAPIVersion string = '2023-10-01-preview' @description('Required. The name of the Azure OpenAI resource deployed previously.') param azureOpenAIName string @@ -26,10 +26,10 @@ param azureOpenAIName string param azureOpenAIAPIKey string @description('Optional. The model name for the Azure OpenAI service.') -param azureOpenAIModelName string = 'gpt-4-32k' +param azureOpenAIModelName string = 'gpt-35-turbo-1106' @description('Optional. The API version for the Azure OpenAI service.') -param azureOpenAIAPIVersion string = '2023-05-15' +param azureOpenAIAPIVersion string = '2023-12-01-preview' @description('Optional. The URL for the Bing Search service.') param bingSearchUrl string = 'https://api.bing.microsoft.com/v7.0/search' diff --git a/apps/backend/azuredeploy-backend.json b/apps/backend/azuredeploy-backend.json index 25767d85..80606bef 100644 --- a/apps/backend/azuredeploy-backend.json +++ b/apps/backend/azuredeploy-backend.json @@ -42,7 +42,7 @@ }, "azureSearchAPIVersion": { "type": "string", - "defaultValue": "2023-07-01-Preview", + "defaultValue": "2023-10-01-preview", "metadata": { "description": "Optional. The API version for the Azure Search service." } @@ -61,14 +61,14 @@ }, "azureOpenAIModelName": { "type": "string", - "defaultValue": "gpt-4-32k", + "defaultValue": "gpt-35-turbo-1106", "metadata": { "description": "Optional. The model name for the Azure OpenAI service." } }, "azureOpenAIAPIVersion": { "type": "string", - "defaultValue": "2023-05-15", + "defaultValue": "2023-12-01-preview", "metadata": { "description": "Optional. The API version for the Azure OpenAI service." } diff --git a/apps/backend/backend.zip b/apps/backend/backend.zip index 61065c3c1768f4d46d7c61936f30620c58edc470..d74c18329be8923cce2142d4ac2a8812a1492ff2 100644 GIT binary patch delta 29874 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Ð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 V&dk#MKVM%ki3rNe_n(jRe*nc#RTKaK delta 34810 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℘@C$P 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 diff --git a/apps/backend/bot.py b/apps/backend/bot.py index 8f2edd58..f1fe8ce2 100644 --- a/apps/backend/bot.py +++ b/apps/backend/bot.py @@ -7,19 +7,18 @@ import requests import json from concurrent.futures import ThreadPoolExecutor +from typing import Any, Dict, List, Optional, Union + from langchain_openai import AzureChatOpenAI -from langchain.utilities import BingSearchAPIWrapper -from langchain.memory import CosmosDBChatMessageHistory +from langchain_community.utilities import BingSearchAPIWrapper from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_core.runnables import ConfigurableField, ConfigurableFieldSpec from langchain_core.chat_history import BaseChatMessageHistory from langchain_community.chat_message_histories import ChatMessageHistory, CosmosDBChatMessageHistory from langchain.agents import ConversationalChatAgent, AgentExecutor, Tool -from typing import Any, Dict, List, Optional, Union from langchain.callbacks.base import BaseCallbackHandler from langchain.callbacks.manager import CallbackManager from langchain.schema import AgentAction, AgentFinish, LLMResult -from langchain_community.chat_message_histories import ChatMessageHistory from langchain_core.runnables.history import RunnableWithMessageHistory #custom libraries that we will use later in the app @@ -46,17 +45,15 @@ class BotServiceCallbackHandler(BaseCallbackHandler): def __init__(self, turn_context: TurnContext) -> None: self.tc = turn_context - def on_llm_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> Any: - asyncio.run(self.tc.send_activity(f"LLM Error: {error}\n")) + async def on_llm_error(self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any) -> Any: + await self.tc.send_activity(f"LLM Error: {error}\n") - def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwargs: Any) -> Any: - asyncio.run(self.tc.send_activity(f"Tool: {serialized['name']}")) + async def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwargs: Any) -> Any: + await self.tc.send_activity(f"Tool: {serialized['name']}") - def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any: - if "Action Input" in action.log: - action = action.log.split("Action Input:")[1] - asyncio.run(self.tc.send_activity(f"\u2611 Searching: {action} ...")) - asyncio.run(self.tc.send_activity(Activity(type=ActivityTypes.typing))) + async def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any: + await self.tc.send_activity(f"\u2611{action.log} ...") + await self.tc.send_activity(Activity(type=ActivityTypes.typing)) # Bot Class @@ -110,9 +107,16 @@ async def on_message_activity(self, turn_context: TurnContext): max_tokens=1500, callback_manager=cb_manager, streaming=True) # Initialize our Tools/Experts - indexes = ["cogsrch-index-files", "cogsrch-index-csv", "cogsrch-index-books"] + doc_indexes = ["cogsrch-index-files", "cogsrch-index-csv", "cogsrch-index-books"] - doc_search = DocSearchAgent(llm=llm, indexes=text_indexes, + doc_search = DocSearchAgent(llm=llm, indexes=doc_indexes, + k=6, reranker_th=1, + sas_token=os.environ['BLOB_SAS_TOKEN'], + callback_manager=cb_manager, verbose=False) + + book_indexes = ["cogsrch-index-books"] + + book_search = DocSearchAgent(llm=llm, indexes=book_indexes, k=6, reranker_th=1, sas_token=os.environ['BLOB_SAS_TOKEN'], callback_manager=cb_manager, verbose=False) @@ -127,7 +131,7 @@ async def on_message_activity(self, turn_context: TurnContext): agent_executor = AgentExecutor(agent=agent, tools=tools) brain_agent_executor = RunnableWithMessageHistory( agent_executor, - get_session_history, + self.get_session_history, input_messages_key="question", history_messages_key="history", history_factory_config=[ @@ -149,11 +153,12 @@ async def on_message_activity(self, turn_context: TurnContext): ), ], ) + + config={"configurable": {"session_id": session_id, "user_id": user_id}} await turn_context.send_activity(Activity(type=ActivityTypes.typing)) # Please note below that running a non-async function like run_agent in a separate thread won't make it truly asynchronous. It allows the function to be called without blocking the event loop, but it may still have synchronous behavior internally. - loop = asyncio.get_event_loop() answer = brain_agent_executor.invoke({"question": input_text}, config=config)["output"] await turn_context.send_activity(answer) diff --git a/common/prompts.py b/common/prompts.py index 27fd6df0..6cea14c3 100644 --- a/common/prompts.py +++ b/common/prompts.py @@ -19,8 +19,6 @@ 5. \U0001F4CA **@sqlsearch**: By utilizing this tool, I can access a SQL database containing information about Covid cases, deaths, and hospitalizations in 2020-2021. -6. \U0001F4E1 **@apisearch**: With this tool I can access the https://disease.sh/ API containing real-time covid statistics for US States, Countries and Continents. - From all of my sources, I will provide the necessary information and also mention the sources I used to derive the answer. This way, you can have transparency about the origins of the information and understand how I arrived at the response. To make the most of my capabilities, please mention the specific tool you'd like me to use when asking your question. Here's an example: @@ -138,6 +136,7 @@ - You do not include images in markdown responses as the chat box does not support images. - Your output should follow GitHub-flavored Markdown. Dollar signs are reserved for LaTeX mathematics, so `$` must be escaped. For example, \$199.99. - You do not bold expressions in LaTeX. +- Include references always if your context have them, in the same format """ diff --git a/common/utils.py b/common/utils.py index bee9b7fb..dafd117f 100644 --- a/common/utils.py +++ b/common/utils.py @@ -35,7 +35,7 @@ from langchain.prompts import PromptTemplate from langchain.sql_database import SQLDatabase from langchain.agents import AgentExecutor, initialize_agent, AgentType, Tool -from langchain.utilities import BingSearchAPIWrapper +from langchain_community.utilities import BingSearchAPIWrapper from langchain.agents import create_sql_agent, create_openai_tools_agent from langchain_community.agent_toolkits import create_sql_agent from langchain_community.agent_toolkits import SQLDatabaseToolkit From e27d53baa93aa5e9367fac991a18afb59a724fa9 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 20:23:21 +0000 Subject: [PATCH 2/2] Update ARM template to match Bicep --- apps/backend/azuredeploy-backend.json | 4 ++-- apps/frontend/azuredeploy-frontend.json | 4 ++-- azuredeploy.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/backend/azuredeploy-backend.json b/apps/backend/azuredeploy-backend.json index 80606bef..08485515 100644 --- a/apps/backend/azuredeploy-backend.json +++ b/apps/backend/azuredeploy-backend.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "15820469957931514877" + "version": "0.25.53.49325", + "templateHash": "7461092684118107720" } }, "parameters": { diff --git a/apps/frontend/azuredeploy-frontend.json b/apps/frontend/azuredeploy-frontend.json index d4dbcc0e..04103f9a 100644 --- a/apps/frontend/azuredeploy-frontend.json +++ b/apps/frontend/azuredeploy-frontend.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "6332436063003351938" + "version": "0.25.53.49325", + "templateHash": "14562326183879912644" } }, "parameters": { diff --git a/azuredeploy.json b/azuredeploy.json index 5e3b8e33..44acddf7 100644 --- a/azuredeploy.json +++ b/azuredeploy.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9804660331329529955" + "version": "0.25.53.49325", + "templateHash": "1411544933331954227" } }, "parameters": {