diff --git a/src/khoj/processor/conversation/prompts.py b/src/khoj/processor/conversation/prompts.py index e77690f8..b0cec27b 100644 --- a/src/khoj/processor/conversation/prompts.py +++ b/src/khoj/processor/conversation/prompts.py @@ -735,7 +735,7 @@ Create a multi-step plan and intelligently iterate on the plan based on the retr - Ensure that all required context is passed to the tool AIs for successful execution. They only know the context provided in your query. - Think step by step to come up with creative strategies when the previous iteration did not yield useful results. - You are allowed upto {max_iterations} iterations to use the help of the provided tool AIs to answer the user's question. -- Stop when you have the required information by returning a JSON object with an empty "tool" field. E.g., {{scratchpad: "I have all I need", tool: "", query: ""}} +- Stop when you have the required information by returning a JSON object with the "tool" field set to "text" and "query" field empty. E.g., {{"scratchpad": "I have all I need", "tool": "text", "query": ""}} # Examples Assuming you can search the user's notes and the internet. diff --git a/src/khoj/routers/research.py b/src/khoj/routers/research.py index aab0949b..cc73686e 100644 --- a/src/khoj/routers/research.py +++ b/src/khoj/routers/research.py @@ -99,6 +99,7 @@ async def apick_next_tool( # Skip showing Notes tool as an option if user has no entries if tool == ConversationCommand.Notes and not user_has_entries: continue + # Add tool if agent does not have any tools defined or the tool is supported by the agent. if len(agent_tools) == 0 or tool.value in agent_tools: tool_options[tool.name] = tool.value tool_options_str += f'- "{tool.value}": "{description}"\n' @@ -170,7 +171,9 @@ async def apick_next_tool( # Only send client status updates if we'll execute this iteration elif send_status_func: determined_tool_message = "**Determined Tool**: " - determined_tool_message += f"{selected_tool}({generated_query})." if selected_tool else "respond." + determined_tool_message += ( + f"{selected_tool}({generated_query})." if selected_tool != ConversationCommand.Text else "respond." + ) determined_tool_message += f"\nReason: {scratchpad}" if scratchpad else "" async for event in send_status_func(f"{scratchpad}"): yield {ChatEvent.STATUS: event} @@ -237,8 +240,8 @@ async def execute_information_collection( if this_iteration.warning: logger.warning(f"Research mode: {this_iteration.warning}.") - # Terminate research if query, tool not set for next iteration - elif not this_iteration.query or not this_iteration.tool: + # Terminate research if selected text tool or query, tool not set for next iteration + elif not this_iteration.query or not this_iteration.tool or this_iteration.tool == ConversationCommand.Text: current_iteration = MAX_ITERATIONS elif this_iteration.tool == ConversationCommand.Notes: diff --git a/src/khoj/utils/helpers.py b/src/khoj/utils/helpers.py index c259dc20..c990b70b 100644 --- a/src/khoj/utils/helpers.py +++ b/src/khoj/utils/helpers.py @@ -389,6 +389,7 @@ function_calling_description_for_llm = { ConversationCommand.Online: "To search the internet for information. Useful to get a quick, broad overview from the internet. Provide all relevant context to ensure new searches, not in previous iterations, are performed.", ConversationCommand.Webpage: "To extract information from webpages. Useful for more detailed research from the internet. Usually used when you know the webpage links to refer to. Share the webpage links and information to extract in your query.", ConversationCommand.Code: e2b_tool_description if is_e2b_code_sandbox_enabled() else terrarium_tool_description, + ConversationCommand.Text: "To respond to the user once you've completed your research and have the required information.", } mode_descriptions_for_llm = {