From ef255ce42faf5524167bb42a08b1e45dd514960d Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 08:00:00 -0400 Subject: [PATCH 01/52] Parallel websearch --- agixt/Interactions.py | 49 +++++++++++++++++++++-------- agixt/Websearch.py | 5 --- agixt/prompts/Default/WebSearch.txt | 15 +++++++++ 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index 0bfba19ebb6..4fa8de765db 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -6,6 +6,7 @@ import logging import base64 import uuid +import asyncio from datetime import datetime from readers.file import FileReader from Websearch import Websearch @@ -230,10 +231,6 @@ async def format_prompt( timestamp = datetime.now().strftime( "%B %d, %Y %I:%M %p" ) - c.log_interaction( - role=self.agent_name, - message=f"[ACTIVITY] Looking at image `{file_name}`.", - ) vision_response = await self.agent.inference( prompt=user_input, images=images ) @@ -526,6 +523,7 @@ async def run( summarize_content=False, conversation_name=conversation_name, ) + async_tasks = [] if websearch: if browse_links != False: await self.websearch.scrape_websites( @@ -564,7 +562,7 @@ async def run( role=self.agent_name, message=f"[ACTIVITY] Searching the web.", ) - search_string = await self.run( + search_strings = await self.run( prompt_name="WebSearch", prompt_category="Default", user_input=user_input, @@ -576,13 +574,37 @@ async def run( websearch=False, tts=False, ) - await self.websearch.websearch_agent( - user_input=user_input, - search_string=search_string, - websearch_depth=websearch_depth, - websearch_timeout=websearch_timeout, - conversation_name=conversation_name, - ) + if "```json" in search_strings: + search_strings = ( + search_strings.split("```json")[1].split("```")[0].strip() + ) + elif "```" in search_strings: + search_strings = search_strings.split("```")[1].strip() + try: + search_suggestions = json.loads(search_strings) + except: + search_suggestions = [] + search_strings = [] + if search_suggestions != []: + if "search_string_suggestion_1" in search_suggestions: + search_string = search_strings["search_string_suggestion_1"] + search_strings.append(search_string) + if "search_string_suggestion_2" in search_strings: + search_string = search_strings["search_string_suggestion_2"] + search_strings.append(search_string) + if "search_string_suggestion_3" in search_strings: + search_string = search_strings["search_string_suggestion_3"] + search_strings.append(search_string) + search_task = asyncio.create_task( + self.websearch.websearch_agent( + user_input=user_input, + search_string=search_string, + websearch_depth=websearch_depth, + websearch_timeout=websearch_timeout, + conversation_name=conversation_name, + ) + ) + async_tasks.append(search_task) else: c.log_interaction( role=self.agent_name, @@ -612,10 +634,11 @@ async def run( except Exception as e: c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY] Unable to view image.", + message=f"[ACTIVITY][ERROR] Unable to view image.", ) logging.error(f"Error getting vision response: {e}") logging.warning("Failed to get vision response.") + await asyncio.gather(*async_tasks) formatted_prompt, unformatted_prompt, tokens = await self.format_prompt( user_input=user_input, top_results=int(context_results), diff --git a/agixt/Websearch.py b/agixt/Websearch.py index b774331df1e..2be9cd518f4 100644 --- a/agixt/Websearch.py +++ b/agixt/Websearch.py @@ -536,11 +536,6 @@ async def websearch_agent( websearch_timeout = 0 if websearch_depth > 0: if len(user_input) > 0: - keywords = extract_keywords(text=search_string, limit=5) - if keywords: - search_string = " ".join(keywords) - # add month and year to the end of the search string - search_string += f" {datetime.now().strftime('%B %Y')}" c = Conversations(conversation_name=conversation_name, user=self.user) conversation_id = c.get_conversation_id() if conversation_name != "" and conversation_name is not None: diff --git a/agixt/prompts/Default/WebSearch.txt b/agixt/prompts/Default/WebSearch.txt index 3a10659a522..811f3288ca3 100644 --- a/agixt/prompts/Default/WebSearch.txt +++ b/agixt/prompts/Default/WebSearch.txt @@ -5,3 +5,18 @@ Today's date is {date}. User's input: {user_input} The assistant is a web search suggestion agent. Suggest a good web search string for the user's input. Attempt to make suggestions that will ensure top results are recent information and from reputable information sources and give proper keywords to maximize the chance of finding the information for the user's input. **Respond only with the search string and nothing else. Be concise and only rephrase the user's input to create an optimal search string that will be used directly in Google search!** + +The assistant can provide up to 10 search string suggestions but should provide a minimum of 3 suggestions. + +Respond only with JSON in a properly formatted markdown code block, no explanations. Make your best assumptions based on data to try to fill in information to match the schema provided. + +Respond in the following following schema: +```json +{ + "search_string_suggestion_1": "search string 1, for example: top security vulnerabilities {date} ", + "search_string_suggestion_2": "search string 2", + "search_string_suggestion_3": "search string 3" +} +``` + +JSON Structured Output: From 9464fcf97746e38df669801d81a361a93c084195 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 08:13:00 -0400 Subject: [PATCH 02/52] use vision inference --- agixt/Interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index 4fa8de765db..cb8e9ca1d7b 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -231,7 +231,7 @@ async def format_prompt( timestamp = datetime.now().strftime( "%B %d, %Y %I:%M %p" ) - vision_response = await self.agent.inference( + vision_response = await self.agent.vision_inference( prompt=user_input, images=images ) await conversation_memories.write_text_to_memory( From eca88be5e1f842f518a39fe2c2ee112add37e0b9 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 08:40:07 -0400 Subject: [PATCH 03/52] extract keywords if unable to decode --- agixt/Interactions.py | 43 ++++++++++++++++++++++++------------------- agixt/Websearch.py | 1 - 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index cb8e9ca1d7b..71dea8d958a 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -11,6 +11,7 @@ from readers.file import FileReader from Websearch import Websearch from Extensions import Extensions +from Memories import extract_keywords from ApiClient import ( Agent, Prompts, @@ -583,27 +584,31 @@ async def run( try: search_suggestions = json.loads(search_strings) except: - search_suggestions = [] + keywords = extract_keywords(text=search_string, limit=5) + if keywords: + search_string = " ".join(keywords) + # add month and year to the end of the search string + search_string += f" {datetime.now().strftime('%B %Y')}" + search_suggestions = [ + {"search_string_suggestion_1": search_string} + ] search_strings = [] if search_suggestions != []: - if "search_string_suggestion_1" in search_suggestions: - search_string = search_strings["search_string_suggestion_1"] - search_strings.append(search_string) - if "search_string_suggestion_2" in search_strings: - search_string = search_strings["search_string_suggestion_2"] - search_strings.append(search_string) - if "search_string_suggestion_3" in search_strings: - search_string = search_strings["search_string_suggestion_3"] - search_strings.append(search_string) - search_task = asyncio.create_task( - self.websearch.websearch_agent( - user_input=user_input, - search_string=search_string, - websearch_depth=websearch_depth, - websearch_timeout=websearch_timeout, - conversation_name=conversation_name, - ) - ) + for i in range(1, int(websearch_depth) + 1): + if f"search_string_suggestion_{i}" in search_suggestions: + search_string = search_suggestions[ + f"search_string_suggestion_{i}" + ] + search_strings.append(search_string) + search_task = asyncio.create_task( + self.websearch.websearch_agent( + user_input=user_input, + search_string=search_string, + websearch_depth=websearch_depth, + websearch_timeout=websearch_timeout, + conversation_name=conversation_name, + ) + ) async_tasks.append(search_task) else: c.log_interaction( diff --git a/agixt/Websearch.py b/agixt/Websearch.py index 2be9cd518f4..db74faa0c08 100644 --- a/agixt/Websearch.py +++ b/agixt/Websearch.py @@ -14,7 +14,6 @@ from Globals import getenv, get_tokens from readers.youtube import YoutubeReader from datetime import datetime -from Memories import extract_keywords from googleapiclient.discovery import build logging.basicConfig( From 8a41cdc9766a10279064560c752e97f4009a76ab Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 08:42:22 -0400 Subject: [PATCH 04/52] fix tab --- agixt/Interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index 71dea8d958a..b63d6bec44e 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -609,7 +609,7 @@ async def run( conversation_name=conversation_name, ) ) - async_tasks.append(search_task) + async_tasks.append(search_task) else: c.log_interaction( role=self.agent_name, From 7926d1f0c12e34e3c9943f119e826ee0cbdfd402 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 08:50:59 -0400 Subject: [PATCH 05/52] async browse links in input --- agixt/Interactions.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index b63d6bec44e..a9f46d9d3b4 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -517,22 +517,28 @@ async def run( websearch_timeout = 0 else: websearch_timeout = 0 - if browse_links != False and websearch == False: - await self.websearch.scrape_websites( - user_input=user_input, - search_depth=websearch_depth, - summarize_content=False, - conversation_name=conversation_name, - ) async_tasks = [] - if websearch: - if browse_links != False: - await self.websearch.scrape_websites( + if browse_links != False and websearch == False: + task = asyncio.create_task( + self.websearch.scrape_websites( user_input=user_input, search_depth=websearch_depth, summarize_content=False, conversation_name=conversation_name, ) + ) + async_tasks.append(task) + if websearch: + if browse_links != False: + task = asyncio.create_task( + self.websearch.scrape_websites( + user_input=user_input, + search_depth=websearch_depth, + summarize_content=False, + conversation_name=conversation_name, + ) + ) + async_tasks.append(task) if user_input == "": if "primary_objective" in kwargs and "task" in kwargs: user_input = f"Primary Objective: {kwargs['primary_objective']}\n\nTask: {kwargs['task']}" @@ -642,7 +648,6 @@ async def run( message=f"[ACTIVITY][ERROR] Unable to view image.", ) logging.error(f"Error getting vision response: {e}") - logging.warning("Failed to get vision response.") await asyncio.gather(*async_tasks) formatted_prompt, unformatted_prompt, tokens = await self.format_prompt( user_input=user_input, @@ -660,7 +665,6 @@ async def run( if user_input != "" and persist_context_in_history == False else formatted_prompt ) - if log_user_input: c.log_interaction( role="USER", @@ -675,8 +679,8 @@ async def run( error = "" for err in e: error += f"{err.args}\n{err.name}\n{err.msg}\n" + logging.warning(f"TOKENS: {tokens} PROMPT CONTENT: {formatted_prompt}") logging.error(f"{self.agent.PROVIDER} Error: {error}") - logging.info(f"TOKENS: {tokens} PROMPT CONTENT: {formatted_prompt}") c.log_interaction( role=self.agent_name, message=f"[ACTIVITY][ERROR] Unable to generate response.", @@ -735,7 +739,6 @@ async def run( c.log_interaction( role=self.agent_name, message=tts_response ) - except Exception as e: logging.warning(f"Failed to get TTS response: {e}") if disable_memory != True: From 003e5c2b41e931bee120edfdfab5149d6daa9d85 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 08:54:56 -0400 Subject: [PATCH 06/52] remove duplicate word in prompt --- agixt/prompts/Default/WebSearch.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agixt/prompts/Default/WebSearch.txt b/agixt/prompts/Default/WebSearch.txt index 811f3288ca3..5e8877d4234 100644 --- a/agixt/prompts/Default/WebSearch.txt +++ b/agixt/prompts/Default/WebSearch.txt @@ -10,7 +10,7 @@ The assistant can provide up to 10 search string suggestions but should provide Respond only with JSON in a properly formatted markdown code block, no explanations. Make your best assumptions based on data to try to fill in information to match the schema provided. -Respond in the following following schema: +Respond in the following schema: ```json { "search_string_suggestion_1": "search string 1, for example: top security vulnerabilities {date} ", From c66b38eca2d159009f2c24a027979f129fdd240c Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 09:32:18 -0400 Subject: [PATCH 07/52] add search guidelines --- agixt/Interactions.py | 3 ++- agixt/prompts/Default/WebSearch Decision.txt | 14 +++++++++++++- agixt/prompts/Default/WebSearch.txt | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index a9f46d9d3b4..49efc9ecbf9 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -553,7 +553,8 @@ async def run( prompt_name="WebSearch Decision", prompt_category="Default", user_input=user_input, - context_results=context_results, + context_results=10, + conversation_results=4, conversation_name=conversation_name, log_user_input=False, log_output=False, diff --git a/agixt/prompts/Default/WebSearch Decision.txt b/agixt/prompts/Default/WebSearch Decision.txt index 836d13365ec..ddac71f002b 100644 --- a/agixt/prompts/Default/WebSearch Decision.txt +++ b/agixt/prompts/Default/WebSearch Decision.txt @@ -1,11 +1,23 @@ +## Context {context} +Recent conversation history for context: + {conversation_history} + Today's date is {date}. User's input: {user_input} The assistant needs to decide if the user's input merits searching the web to assist them before responding, or if the assistant can respond directly. +To help guide decision making, the assistant should consider the following: +- Only search the web to build more context around the users input to respond with a more informed answer. +- If sufficient context is already available and the user did not directly indicate that a web search must happen, one is not needed. +- If the user's input is relevant to recent events or news, a web search may be necessary to provide the most up-to-date information. +- If the user's input is a question that requires a factual answer, a web search may be necessary to provide the most accurate information if enough context is not available. + If the assistant decides to search the web, say `Yes`. If the assistant decides not to search the web, say `No`. -**The assistant responds only with Yes or No.** \ No newline at end of file +**The assistant responds only with Yes or No.** + +Should the assistant search the web to assist the user based on the requirements listed? Yes or No? \ No newline at end of file diff --git a/agixt/prompts/Default/WebSearch.txt b/agixt/prompts/Default/WebSearch.txt index 5e8877d4234..f784929e713 100644 --- a/agixt/prompts/Default/WebSearch.txt +++ b/agixt/prompts/Default/WebSearch.txt @@ -1,11 +1,28 @@ +## Context {context} +Recent conversation history for context: + {conversation_history} + Today's date is {date}. User's input: {user_input} The assistant is a web search suggestion agent. Suggest a good web search string for the user's input. Attempt to make suggestions that will ensure top results are recent information and from reputable information sources and give proper keywords to maximize the chance of finding the information for the user's input. **Respond only with the search string and nothing else. Be concise and only rephrase the user's input to create an optimal search string that will be used directly in Google search!** +Additional guidance for optimal search string suggestions: +- Use today's date in the search string to get the most up to date information if relevant. +- If the user's input is scientific related, add "ar5iv" to a search string to get scientific papers. +- For broader academic queries, adding "PDF" or "site" along with "Google Scholar" or specific university names can help locate educational resources, academic papers, or books. +- For health or medical information, include terms like "site:.edu" along with "PubMed" or specific terms like "clinical trials" to focus on academic and clinically validated information, ensuring reliability in medical searches. +- For legal or government information, use "site:.gov" for government-related information or specify domains like "site.gov" for legal documents, which can help target official publications and legal documents +- For patent searches, include "site.gov" or "Google Patents" when searching for inventions and patents, which can directly lead to patent registries and related documents. +- For product reviews, add "review" and "amazon" or other reputable review sites to find product reviews and ratings. +- For travel information, include specific locations, dates, and travel-related terms to get the most relevant travel information. +- For job and career-related searches, include specific job titles, companies, or job boards to find job listings, career advice, or company information. Include sites like "linkedin", "jobot", or "indeed" for job searches. +- For real estate and housing market data, include specific real estate websites like "Zillow" or "Realtor.com" or add "MLS listings" when searching for housing market information, prices, or property details. +- For stock market data, include specific stock symbols where possible, financial terms, or stock market websites like "Yahoo Finance", "Google Finance", "MarketWatch", or "Bloomberg" to get the latest stock market information, stock prices, and financial news. + The assistant can provide up to 10 search string suggestions but should provide a minimum of 3 suggestions. Respond only with JSON in a properly formatted markdown code block, no explanations. Make your best assumptions based on data to try to fill in information to match the schema provided. From 724c6ccd0f6b7f46e0fcf1cd26cb73c16cea7019 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 09:41:24 -0400 Subject: [PATCH 08/52] add searching bool to avoid visual recall during websearch --- agixt/Interactions.py | 6 ++++++ agixt/Websearch.py | 3 +++ 2 files changed, 9 insertions(+) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index 49efc9ecbf9..7549b0801e2 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -111,6 +111,7 @@ async def format_prompt( prompt="", conversation_name="", vision_response: str = "", + searching: bool = False, **kwargs, ): if "user_input" in kwargs and user_input == "": @@ -216,6 +217,7 @@ async def format_prompt( vision_provider != "None" and vision_provider != "" and vision_provider != None + and searching == False ): for memory in conversation_context: # If the memory starts with "Sourced from image", get a new vision response to add and inject @@ -447,6 +449,7 @@ async def run( browse_links: bool = False, persist_context_in_history: bool = False, images: list = [], + searching: bool = False, log_user_input: bool = True, log_output: bool = True, **kwargs, @@ -561,6 +564,7 @@ async def run( browse_links=False, websearch=False, tts=False, + searching=True, ) to_search = re.search( r"\byes\b", str(to_search_or_not_to_search).lower() @@ -581,6 +585,7 @@ async def run( browse_links=False, websearch=False, tts=False, + searching=True, ) if "```json" in search_strings: search_strings = ( @@ -657,6 +662,7 @@ async def run( prompt_category=prompt_category, conversation_name=conversation_name, websearch=websearch, + searching=searching, vision_response=vision_response, **kwargs, ) diff --git a/agixt/Websearch.py b/agixt/Websearch.py index db74faa0c08..72727b17cba 100644 --- a/agixt/Websearch.py +++ b/agixt/Websearch.py @@ -97,6 +97,7 @@ async def summarize_web_content(self, url, content): "disable_memory": True, "conversation_name": "AGiXT Terminal", "tts": "false", + "searching": True, }, ) chunks = await self.agent_memory.chunk_content( @@ -115,6 +116,7 @@ async def summarize_web_content(self, url, content): "disable_memory": True, "conversation_name": "AGiXT Terminal", "tts": "false", + "searching": True, }, ) ) @@ -300,6 +302,7 @@ async def recursive_browsing( "user_input": user_input, "context_results": 0, "tts": False, + "searching": True, "conversation_name": "Link selection", }, ) From 6c2b129ee24ab7c4d405ecf2a095a3e3197d128d Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 09:55:16 -0400 Subject: [PATCH 09/52] improve prompt --- agixt/prompts/Default/WebSearch.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agixt/prompts/Default/WebSearch.txt b/agixt/prompts/Default/WebSearch.txt index f784929e713..1999920cc0a 100644 --- a/agixt/prompts/Default/WebSearch.txt +++ b/agixt/prompts/Default/WebSearch.txt @@ -23,7 +23,7 @@ Additional guidance for optimal search string suggestions: - For real estate and housing market data, include specific real estate websites like "Zillow" or "Realtor.com" or add "MLS listings" when searching for housing market information, prices, or property details. - For stock market data, include specific stock symbols where possible, financial terms, or stock market websites like "Yahoo Finance", "Google Finance", "MarketWatch", or "Bloomberg" to get the latest stock market information, stock prices, and financial news. -The assistant can provide up to 10 search string suggestions but should provide a minimum of 3 suggestions. +The assistant can provide up to 10 search string suggestions but should provide a minimum of 1 suggestion. Respond only with JSON in a properly formatted markdown code block, no explanations. Make your best assumptions based on data to try to fill in information to match the schema provided. From d46a90ed13cc4a28bd449a3dcdfde288d52eb353 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 10:19:17 -0400 Subject: [PATCH 10/52] improve history injection --- agixt/Interactions.py | 5 +---- agixt/Websearch.py | 9 ++++++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index 7549b0801e2..522838fe2ad 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -284,9 +284,6 @@ async def format_prompt( activities = [] for activity in activity_history: if "audio response" not in activity["message"]: - activity["message"] = str(activity["message"]).replace( - "[ACTIVITY]", "" - ) activities.append(activity) if len(activity_history) > 5: activity_history = activity_history[-5:] @@ -319,7 +316,7 @@ async def format_prompt( for activity in activity_history: timestamp = activity["timestamp"] role = activity["role"] - message = activity["message"] + message = str(activity["message"]).replace("[ACTIVITY]", "") conversation_history += f"{timestamp} {role}: {message} \n " persona = "" if "persona" in prompt_args: diff --git a/agixt/Websearch.py b/agixt/Websearch.py index 72727b17cba..14fec3d9c4b 100644 --- a/agixt/Websearch.py +++ b/agixt/Websearch.py @@ -229,6 +229,10 @@ async def get_web_content( async def recursive_browsing( self, user_input, links, conversation_name: str = "", conversation_id="1" ): + logging.info(f"Recursive browsing: {links}") + logging.info( + f"Conversation ID: {conversation_id} Conversation Name: {conversation_name}" + ) c = Conversations(conversation_name=conversation_name, user=self.user) try: words = links.split() @@ -268,7 +272,7 @@ async def recursive_browsing( if conversation_name != "" and conversation_name is not None: c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY] Browsing {url} .", + message=f"[ACTIVITY][SUB] Browsing {url} .", ) ( collected_data, @@ -540,6 +544,9 @@ async def websearch_agent( if len(user_input) > 0: c = Conversations(conversation_name=conversation_name, user=self.user) conversation_id = c.get_conversation_id() + logging.info( + f"Websearch Agent: Conversation ID: {conversation_id} Conversation Name: {conversation_name}" + ) if conversation_name != "" and conversation_name is not None: c.log_interaction( role=self.agent_name, From c91fd96ba785543a2584c3fbdc6e2a307ab74c61 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 10:22:13 -0400 Subject: [PATCH 11/52] add browsing activity --- agixt/Websearch.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/agixt/Websearch.py b/agixt/Websearch.py index 14fec3d9c4b..1822e310193 100644 --- a/agixt/Websearch.py +++ b/agixt/Websearch.py @@ -252,6 +252,11 @@ async def recursive_browsing( url = link url = re.sub(r"^.*?(http)", r"http", url) if self.verify_link(link=url): + if conversation_name != "" and conversation_name is not None: + c.log_interaction( + role=self.agent_name, + message=f"[ACTIVITY][SUB] Browsing {url} .", + ) ( collected_data, link_list, @@ -550,7 +555,7 @@ async def websearch_agent( if conversation_name != "" and conversation_name is not None: c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY] Searching for `{search_string}`.", + message=f"[ACTIVITY][SUB] Searching for `{search_string}`.", ) google_api_key = ( self.agent_settings["GOOGLE_API_KEY"] From b20823c46bf09c54beb64128b4a6d320b552f546 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 10:48:54 -0400 Subject: [PATCH 12/52] add subactivities --- agixt/Conversations.py | 2 ++ agixt/Interactions.py | 5 ++-- agixt/Websearch.py | 67 +++++++++++++++++++++++------------------- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/agixt/Conversations.py b/agixt/Conversations.py index 18eb2bc6163..37b9ecd947e 100644 --- a/agixt/Conversations.py +++ b/agixt/Conversations.py @@ -256,6 +256,8 @@ def log_interaction(self, role, message): logging.error(f"{role}: {message}") else: logging.info(f"{role}: {message}") + message_id = str(new_message.id) + return message_id def delete_conversation(self): session = get_session() diff --git a/agixt/Interactions.py b/agixt/Interactions.py index 522838fe2ad..551cc8a579c 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -547,7 +547,7 @@ async def run( if user_input != "": c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY] Searching for information.", + message=f"[ACTIVITY] Deciding if additional research is required.", ) to_search_or_not_to_search = await self.run( prompt_name="WebSearch Decision", @@ -567,7 +567,7 @@ async def run( r"\byes\b", str(to_search_or_not_to_search).lower() ) if to_search: - c.log_interaction( + searching_activity_id = c.log_interaction( role=self.agent_name, message=f"[ACTIVITY] Searching the web.", ) @@ -616,6 +616,7 @@ async def run( websearch_depth=websearch_depth, websearch_timeout=websearch_timeout, conversation_name=conversation_name, + activity_id=searching_activity_id, ) ) async_tasks.append(search_task) diff --git a/agixt/Websearch.py b/agixt/Websearch.py index 1822e310193..244bf8ee77f 100644 --- a/agixt/Websearch.py +++ b/agixt/Websearch.py @@ -227,7 +227,12 @@ async def get_web_content( return None, None async def recursive_browsing( - self, user_input, links, conversation_name: str = "", conversation_id="1" + self, + user_input, + links, + conversation_name: str = "", + conversation_id="1", + activity_id="", ): logging.info(f"Recursive browsing: {links}") logging.info( @@ -255,7 +260,7 @@ async def recursive_browsing( if conversation_name != "" and conversation_name is not None: c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY][SUB] Browsing {url} .", + message=f"[SUBACTIVITY][{activity_id}] Browsing {url} .", ) ( collected_data, @@ -277,7 +282,7 @@ async def recursive_browsing( if conversation_name != "" and conversation_name is not None: c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY][SUB] Browsing {url} .", + message=f"[SUBACTIVITY][{activity_id}] Browsing {url} .", ) ( collected_data, @@ -295,7 +300,7 @@ async def recursive_browsing( ): c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY] Found {len(link_list)} links on {url} . Choosing one to browse next.", + message=f"[SUBACTIVITY][{activity_id}] Found {len(link_list)} links on {url} . Choosing one to browse next.", ) try: pick_a_link = self.ApiClient.prompt_agent( @@ -324,6 +329,7 @@ async def recursive_browsing( links=pick_a_link, conversation_name=conversation_name, conversation_id=conversation_id, + activity_id=activity_id, ) except: logging.info(f"Issues reading {url}. Moving on...") @@ -333,7 +339,7 @@ async def recursive_browsing( ): c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY][ERROR] Issues reading {url}. Moving on.", + message=f"[SUBACTIVITY][{activity_id}][ERROR] Issues reading {url}. Moving on.", ) async def scrape_websites( @@ -348,29 +354,27 @@ async def scrape_websites( links = re.findall(r"(?Phttps?://[^\s]+)", user_input) if len(links) < 1: return "" - if conversation_name != "" and conversation_name is not None: - c = Conversations(conversation_name=conversation_name, user=self.user) - conversation_id = c.get_conversation_id() - self.agent_memory = YoutubeReader( - agent_name=self.agent_name, - agent_config=self.agent.AGENT_CONFIG, - collection_number=conversation_id, - ApiClient=self.ApiClient, - user=self.user, - ) - c.log_interaction( - role=self.agent_name, - message=f"[ACTIVITY] Researching online.", - ) + c = Conversations(conversation_name=conversation_name, user=self.user) + conversation_id = c.get_conversation_id() + self.agent_memory = YoutubeReader( + agent_name=self.agent_name, + agent_config=self.agent.AGENT_CONFIG, + collection_number=conversation_id, + ApiClient=self.ApiClient, + user=self.user, + ) + activity_id = c.log_interaction( + role=self.agent_name, + message=f"[ACTIVITY] Browsing {links[0]} and collecting data from it to learn more.", + ) scraped_links = [] if links is not None and len(links) > 0: for link in links: if self.verify_link(link=link): - if conversation_name != "" and conversation_name is not None: - c.log_interaction( - role=self.agent_name, - message=f"[ACTIVITY] Browsing {link} .", - ) + c.log_interaction( + role=self.agent_name, + message=f"[SUBACTIVITY][{activity_id}] Browsing {link} .", + ) text_content, link_list = await self.get_web_content( url=link, summarize_content=summarize_content ) @@ -391,7 +395,7 @@ async def scrape_websites( ): c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY] Browsing {sublink[1]} .", + message=f"[SUBACTIVITY][{activity_id}] Browsing {sublink[1]} .", ) ( text_content, @@ -407,7 +411,7 @@ async def scrape_websites( if conversation_name != "" and conversation_name is not None: c.log_interaction( role=self.agent_name, - message=f"[ACTIVITY] {message}", + message=f"[SUBACTIVITY][{activity_id}] {message}", ) return message @@ -536,6 +540,7 @@ async def websearch_agent( websearch_depth: int = 0, websearch_timeout: int = 0, conversation_name: str = "", + activity_id: str = "", ): try: websearch_depth = int(websearch_depth) @@ -552,11 +557,10 @@ async def websearch_agent( logging.info( f"Websearch Agent: Conversation ID: {conversation_id} Conversation Name: {conversation_name}" ) - if conversation_name != "" and conversation_name is not None: - c.log_interaction( - role=self.agent_name, - message=f"[ACTIVITY][SUB] Searching for `{search_string}`.", - ) + new_activity_id = c.log_interaction( + role=self.agent_name, + message=f"[SUBACTIVITY][{activity_id}] Searching for `{search_string}`.", + ) google_api_key = ( self.agent_settings["GOOGLE_API_KEY"] if "GOOGLE_API_KEY" in self.agent_settings @@ -599,6 +603,7 @@ async def websearch_agent( links=links, conversation_name=conversation_name, conversation_id=conversation_id, + activity_id=new_activity_id, ) ) self.tasks.append(task) From 97f178dd5bae70f4c103e932582d9f9fc7d2519d Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 10:58:34 -0400 Subject: [PATCH 13/52] add extra if --- agixt/XT.py | 3 ++- agixt/endpoints/Conversation.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/agixt/XT.py b/agixt/XT.py index 31338fc1fae..e5508ac1020 100644 --- a/agixt/XT.py +++ b/agixt/XT.py @@ -1749,7 +1749,8 @@ async def analyze_csv( likely_files = [] for activity in activities: if ".csv" in activity["message"]: - likely_files.append(activity["message"].split("`")[1]) + if "`" in activity["message"]: + likely_files.append(activity["message"].split("`")[1]) if len(likely_files) == 0: return "" elif len(likely_files) == 1: diff --git a/agixt/endpoints/Conversation.py b/agixt/endpoints/Conversation.py index 2bd58d4d568..074124a0976 100644 --- a/agixt/endpoints/Conversation.py +++ b/agixt/endpoints/Conversation.py @@ -163,7 +163,7 @@ async def rename_conversation( user=Depends(verify_api_key), authorization: str = Header(None), ): - if rename.new_conversation_name == "/": + if rename.new_conversation_name == "-": agixt = AGiXT(user=user, agent_name=rename.agent_name, api_key=authorization) response = await agixt.inference( prompt_name="Name Conversation", From 904aed2077b5453b4d4fc6aec2fc70058a25f034 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 11:09:22 -0400 Subject: [PATCH 14/52] fix default --- agixt/Models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agixt/Models.py b/agixt/Models.py index 94c94458d6e..342be22673e 100644 --- a/agixt/Models.py +++ b/agixt/Models.py @@ -244,7 +244,7 @@ class ConversationHistoryModel(BaseModel): class RenameConversationModel(BaseModel): agent_name: str conversation_name: str - new_conversation_name: Optional[str] = "/" + new_conversation_name: Optional[str] = "-" class TTSInput(BaseModel): From 794024c33c3f41755fcc09076daf81789b1711a1 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 11:22:41 -0400 Subject: [PATCH 15/52] break down line items --- agixt/XT.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/agixt/XT.py b/agixt/XT.py index e5508ac1020..13c0e049400 100644 --- a/agixt/XT.py +++ b/agixt/XT.py @@ -848,11 +848,21 @@ async def learn_from_file( if os.path.normpath(file_path).startswith(self.agent_workspace): with open(file_path, "r") as f: file_content = f.read() - await file_reader.write_text_to_memory( - user_input=user_input, - text=f"Content from file uploaded named `{file_name}` at {timestamp}:\n{file_content}", - external_source=f"file {file_path}", - ) + # Check how many lines are in the file content + lines = file_content.split("\n") + if len(lines) > 1: + for line_number, line in enumerate(lines): + await file_reader.write_text_to_memory( + user_input=user_input, + text=f"Content from file uploaded named `{file_name}` at {timestamp} on line number {line_number + 1}:\n{line}", + external_source=f"file {file_path}", + ) + else: + await file_reader.write_text_to_memory( + user_input=user_input, + text=f"Content from file uploaded named `{file_name}` at {timestamp}:\n{file_content}", + external_source=f"file {file_path}", + ) response = f"Read the content of the file called [{file_name}]({file_url}) into memory." else: response = ( From 0852608117bf48d9341005ffce5399c36f86969d Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 11:37:34 -0400 Subject: [PATCH 16/52] change default conversation name to - --- agixt/Conversations.py | 8 ++++---- agixt/Interactions.py | 27 +++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/agixt/Conversations.py b/agixt/Conversations.py index 37b9ecd947e..ab532a1a700 100644 --- a/agixt/Conversations.py +++ b/agixt/Conversations.py @@ -26,7 +26,7 @@ def export_conversation(self): user_data = session.query(User).filter(User.email == self.user).first() user_id = user_data.id if not self.conversation_name: - self.conversation_name = f"{str(datetime.now())} Conversation" + self.conversation_name = "-" conversation = ( session.query(Conversation) .filter( @@ -85,7 +85,7 @@ def get_conversation(self, limit=100, page=1): user_data = session.query(User).filter(User.email == self.user).first() user_id = user_data.id if not self.conversation_name: - self.conversation_name = f"{str(datetime.now())} Conversation" + self.conversation_name = "-" conversation = ( session.query(Conversation) .filter( @@ -146,7 +146,7 @@ def get_activities(self, limit=100, page=1): user_data = session.query(User).filter(User.email == self.user).first() user_id = user_data.id if not self.conversation_name: - self.conversation_name = f"{str(datetime.now())} Conversation" + self.conversation_name = "-" conversation = ( session.query(Conversation) .filter( @@ -264,7 +264,7 @@ def delete_conversation(self): user_data = session.query(User).filter(User.email == self.user).first() user_id = user_data.id if not self.conversation_name: - self.conversation_name = f"{str(datetime.now())} Conversation" + self.conversation_name = "-" conversation = ( session.query(Conversation) .filter( diff --git a/agixt/Interactions.py b/agixt/Interactions.py index 551cc8a579c..ff0a5681eb1 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -134,7 +134,7 @@ async def format_prompt( if "conversation_name" in kwargs: conversation_name = kwargs["conversation_name"] if conversation_name == "": - conversation_name = f"{str(datetime.now())} Conversation" + conversation_name = "-" c = Conversations(conversation_name=conversation_name, user=self.user) conversation = c.get_conversation() if top_results == 0: @@ -208,6 +208,29 @@ async def format_prompt( limit=top_results, min_relevance_score=min_relevance_score, ) + if len(conversation_context) == int(top_results): + conversational_context_tokens = get_tokens( + " ".join(conversation_context) + ) + if int(conversational_context_tokens) < 4000: + conversational_results = top_results * 2 + conversation_context = await conversation_memories.get_memories( + user_input=user_input, + limit=conversational_results, + min_relevance_score=min_relevance_score, + ) + conversational_context_tokens = get_tokens( + " ".join(conversation_context) + ) + if int(conversational_context_tokens) < 4000: + conversational_results = conversational_results * 2 + conversation_context = ( + await conversation_memories.get_memories( + user_input=user_input, + limit=conversational_results, + min_relevance_score=min_relevance_score, + ) + ) context += conversation_context if "vision_provider" in self.agent.AGENT_CONFIG["settings"]: vision_provider = self.agent.AGENT_CONFIG["settings"][ @@ -508,7 +531,7 @@ async def run( if "conversation_name" in kwargs: conversation_name = kwargs["conversation_name"] if conversation_name == "": - conversation_name = datetime.now().strftime("%Y-%m-%d") + conversation_name = "-" c = Conversations(conversation_name=conversation_name, user=self.user) if "WEBSEARCH_TIMEOUT" in kwargs: try: From e1bddf3f0539cd86696829c08985c6983e0a5632 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 11:40:52 -0400 Subject: [PATCH 17/52] fix error --- agixt/endpoints/Conversation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/agixt/endpoints/Conversation.py b/agixt/endpoints/Conversation.py index 074124a0976..2096f2b1225 100644 --- a/agixt/endpoints/Conversation.py +++ b/agixt/endpoints/Conversation.py @@ -166,6 +166,7 @@ async def rename_conversation( if rename.new_conversation_name == "-": agixt = AGiXT(user=user, agent_name=rename.agent_name, api_key=authorization) response = await agixt.inference( + user_input=f"Rename conversation", prompt_name="Name Conversation", conversation_name=rename.conversation_name, log_user_input=False, From 8d96383b1457613727f31f0892ad2069b8da99e5 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 11:54:23 -0400 Subject: [PATCH 18/52] dont browse on rename --- agixt/endpoints/Conversation.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/agixt/endpoints/Conversation.py b/agixt/endpoints/Conversation.py index 2096f2b1225..252058015b1 100644 --- a/agixt/endpoints/Conversation.py +++ b/agixt/endpoints/Conversation.py @@ -169,6 +169,9 @@ async def rename_conversation( user_input=f"Rename conversation", prompt_name="Name Conversation", conversation_name=rename.conversation_name, + websearch=False, + browse_links=False, + voice_response=False, log_user_input=False, log_output=False, ) From 04203456e0c99621ef0483c0475b70a7763b5325 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 11:56:16 -0400 Subject: [PATCH 19/52] add activity for renaming conversation --- agixt/endpoints/Conversation.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/agixt/endpoints/Conversation.py b/agixt/endpoints/Conversation.py index 252058015b1..6bcc333ea37 100644 --- a/agixt/endpoints/Conversation.py +++ b/agixt/endpoints/Conversation.py @@ -185,7 +185,10 @@ async def rename_conversation( except: new_name = datetime.now().strftime("Conversation Created %Y-%m-%d %I:%M %p") rename.new_conversation_name = new_name - Conversations( - conversation_name=rename.conversation_name, user=user - ).rename_conversation(new_name=rename.new_conversation_name) + c = Conversations(conversation_name=rename.conversation_name, user=user) + c.rename_conversation(new_name=rename.new_conversation_name) + c.log_interaction( + message=f"[ACTIVITY][INFO] Conversation renamed to `{rename.new_conversation_name}`.", + role=rename.agent_name, + ) return {"conversation_name": rename.new_conversation_name} From f682cfc0543bf50a54f5690245948401404b462e Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 12:01:28 -0400 Subject: [PATCH 20/52] add existing conversations --- agixt/endpoints/Conversation.py | 4 +++- agixt/prompts/Default/Name Conversation.txt | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/agixt/endpoints/Conversation.py b/agixt/endpoints/Conversation.py index 6bcc333ea37..43156f98432 100644 --- a/agixt/endpoints/Conversation.py +++ b/agixt/endpoints/Conversation.py @@ -163,12 +163,15 @@ async def rename_conversation( user=Depends(verify_api_key), authorization: str = Header(None), ): + c = Conversations(conversation_name=rename.conversation_name, user=user) if rename.new_conversation_name == "-": agixt = AGiXT(user=user, agent_name=rename.agent_name, api_key=authorization) + conversation_list = c.get_conversations() response = await agixt.inference( user_input=f"Rename conversation", prompt_name="Name Conversation", conversation_name=rename.conversation_name, + conversation_list="\n".join(conversation_list), websearch=False, browse_links=False, voice_response=False, @@ -185,7 +188,6 @@ async def rename_conversation( except: new_name = datetime.now().strftime("Conversation Created %Y-%m-%d %I:%M %p") rename.new_conversation_name = new_name - c = Conversations(conversation_name=rename.conversation_name, user=user) c.rename_conversation(new_name=rename.new_conversation_name) c.log_interaction( message=f"[ACTIVITY][INFO] Conversation renamed to `{rename.new_conversation_name}`.", diff --git a/agixt/prompts/Default/Name Conversation.txt b/agixt/prompts/Default/Name Conversation.txt index ce0a49078f1..d36196d5701 100644 --- a/agixt/prompts/Default/Name Conversation.txt +++ b/agixt/prompts/Default/Name Conversation.txt @@ -1,5 +1,8 @@ ## Conversation History -{conversation_history} + {conversation_history} + +**Existing conversation names to NOT use:** + {conversation_list} Act as a JSON converter that converts any text into the desired JSON format based on the schema provided. Respond only with JSON in a properly formatted markdown code block, no explanations. Make your best assumptions based on data to try to fill in information to match the schema provided. **DO NOT ADD FIELDS TO THE MODEL OR CHANGE TYPES OF FIELDS, FOLLOW THE PYDANTIC SCHEMA!** From 2a81bf8f95d7459910470332621160dd7e97e9a1 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 12:35:58 -0400 Subject: [PATCH 21/52] fix log --- agixt/endpoints/Conversation.py | 1 + agixt/prompts/Default/Name Conversation.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/agixt/endpoints/Conversation.py b/agixt/endpoints/Conversation.py index 43156f98432..c879a89f89e 100644 --- a/agixt/endpoints/Conversation.py +++ b/agixt/endpoints/Conversation.py @@ -189,6 +189,7 @@ async def rename_conversation( new_name = datetime.now().strftime("Conversation Created %Y-%m-%d %I:%M %p") rename.new_conversation_name = new_name c.rename_conversation(new_name=rename.new_conversation_name) + c = Conversations(conversation_name=rename.new_conversation_name, user=user) c.log_interaction( message=f"[ACTIVITY][INFO] Conversation renamed to `{rename.new_conversation_name}`.", role=rename.agent_name, diff --git a/agixt/prompts/Default/Name Conversation.txt b/agixt/prompts/Default/Name Conversation.txt index d36196d5701..74dc10c734d 100644 --- a/agixt/prompts/Default/Name Conversation.txt +++ b/agixt/prompts/Default/Name Conversation.txt @@ -8,7 +8,7 @@ Act as a JSON converter that converts any text into the desired JSON format base **DO NOT ADD FIELDS TO THE MODEL OR CHANGE TYPES OF FIELDS, FOLLOW THE PYDANTIC SCHEMA!** **Reformat the following information into a structured format according to the schema provided:** -Based on the conversation history, suggest a name for the conversation in the `suggested_conversation_name` as a string. +Based on the conversation history, suggest a name for the conversation in the `suggested_conversation_name` as a string. Use something unique, not generic and something that is not already existing. ## Pydantic Schema: suggested_conversation_name: From 187b4e993daf8b6dd298e5f907b76b0b38788c29 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 14:00:22 -0400 Subject: [PATCH 22/52] improve renaming --- agixt/Websearch.py | 15 ++++++++----- agixt/endpoints/Conversation.py | 25 ++++++++++++++++++++- agixt/prompts/Default/Name Conversation.txt | 11 +++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/agixt/Websearch.py b/agixt/Websearch.py index 244bf8ee77f..03ea6bc7378 100644 --- a/agixt/Websearch.py +++ b/agixt/Websearch.py @@ -324,13 +324,16 @@ async def recursive_browsing( logging.info( f"AI has decided to click: {pick_a_link}" ) - await self.recursive_browsing( - user_input=user_input, - links=pick_a_link, - conversation_name=conversation_name, - conversation_id=conversation_id, - activity_id=activity_id, + task = asyncio.create_task( + self.recursive_browsing( + user_input=user_input, + links=pick_a_link, + conversation_name=conversation_name, + conversation_id=conversation_id, + activity_id=activity_id, + ) ) + self.tasks.append(task) except: logging.info(f"Issues reading {url}. Moving on...") if ( diff --git a/agixt/endpoints/Conversation.py b/agixt/endpoints/Conversation.py index c879a89f89e..718e747f5cb 100644 --- a/agixt/endpoints/Conversation.py +++ b/agixt/endpoints/Conversation.py @@ -185,9 +185,32 @@ async def rename_conversation( try: response = json.loads(response) new_name = response["suggested_conversation_name"] + if new_name in conversation_list: + # Do not use {new_name}! + response = await agixt.inference( + user_input=f"**Do not use {new_name}!**", + prompt_name="Name Conversation", + conversation_name=rename.conversation_name, + conversation_list="\n".join(conversation_list), + websearch=False, + browse_links=False, + voice_response=False, + log_user_input=False, + log_output=False, + ) + if "```json" in response: + response = response.split("```json")[1].split("```")[0].strip() + elif "```" in response: + response = response.split("```")[1].strip() + response = json.loads(response) + new_name = response["suggested_conversation_name"] + if new_name in conversation_list: + new_name = datetime.now().strftime( + "Conversation Created %Y-%m-%d %I:%M %p" + ) except: new_name = datetime.now().strftime("Conversation Created %Y-%m-%d %I:%M %p") - rename.new_conversation_name = new_name + rename.new_conversation_name = new_name.replace("_", " ") c.rename_conversation(new_name=rename.new_conversation_name) c = Conversations(conversation_name=rename.new_conversation_name, user=user) c.log_interaction( diff --git a/agixt/prompts/Default/Name Conversation.txt b/agixt/prompts/Default/Name Conversation.txt index 74dc10c734d..910f129cc3e 100644 --- a/agixt/prompts/Default/Name Conversation.txt +++ b/agixt/prompts/Default/Name Conversation.txt @@ -8,9 +8,16 @@ Act as a JSON converter that converts any text into the desired JSON format base **DO NOT ADD FIELDS TO THE MODEL OR CHANGE TYPES OF FIELDS, FOLLOW THE PYDANTIC SCHEMA!** **Reformat the following information into a structured format according to the schema provided:** -Based on the conversation history, suggest a name for the conversation in the `suggested_conversation_name` as a string. Use something unique, not generic and something that is not already existing. +Based on the conversation history, suggest a name for the conversation in the `suggested_conversation_name` as a string. + +Rules to follow: +- Do not use the same name as an existing conversation. +- Use spaces in the name, not underscores. +- Use a unique name that is meaningfully based on the conversation, not something generic. + +{user_input} ## Pydantic Schema: suggested_conversation_name: -JSON Structured Output: +JSON Structured Output: \ No newline at end of file From 51f34dc180020ad9e84231613cd22c165e82e3b0 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Fri, 21 Jun 2024 14:19:53 -0400 Subject: [PATCH 23/52] dont include subactivity --- agixt/Interactions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/agixt/Interactions.py b/agixt/Interactions.py index ff0a5681eb1..7a18837a533 100644 --- a/agixt/Interactions.py +++ b/agixt/Interactions.py @@ -303,6 +303,7 @@ async def format_prompt( interaction for interaction in conversation["interactions"] if str(interaction["message"]).startswith("[ACTIVITY]") + or str(interaction["message"]).startswith("[SUBACTIVITY]") ] activities = [] for activity in activity_history: @@ -314,6 +315,8 @@ async def format_prompt( interaction for interaction in conversation["interactions"] if not str(interaction["message"]).startswith("[ACTIVITY]") + and not str(interaction["message"]).startswith("