mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-09 13:25:11 +00:00
Allow iterative chat director to use python interpreter as a tool
This commit is contained in:
@@ -696,6 +696,7 @@ async def chat(
|
|||||||
pending_research = True
|
pending_research = True
|
||||||
researched_results = ""
|
researched_results = ""
|
||||||
online_results: Dict = dict()
|
online_results: Dict = dict()
|
||||||
|
code_results: Dict = dict()
|
||||||
## Extract Document References
|
## Extract Document References
|
||||||
compiled_references: List[Any] = []
|
compiled_references: List[Any] = []
|
||||||
inferred_queries: List[Any] = []
|
inferred_queries: List[Any] = []
|
||||||
@@ -721,7 +722,8 @@ async def chat(
|
|||||||
pending_research = False
|
pending_research = False
|
||||||
if research_result.onlineContext:
|
if research_result.onlineContext:
|
||||||
online_results.update(research_result.onlineContext)
|
online_results.update(research_result.onlineContext)
|
||||||
|
if research_result.codeContext:
|
||||||
|
code_results.update(research_result.codeContext)
|
||||||
if research_result.context:
|
if research_result.context:
|
||||||
compiled_references.extend(research_result.context)
|
compiled_references.extend(research_result.context)
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from khoj.database.models import Agent, KhojUser
|
|||||||
from khoj.processor.conversation import prompts
|
from khoj.processor.conversation import prompts
|
||||||
from khoj.processor.conversation.utils import remove_json_codeblock
|
from khoj.processor.conversation.utils import remove_json_codeblock
|
||||||
from khoj.processor.tools.online_search import read_webpages, search_online
|
from khoj.processor.tools.online_search import read_webpages, search_online
|
||||||
|
from khoj.processor.tools.run_code import run_code
|
||||||
from khoj.routers.api import extract_references_and_questions
|
from khoj.routers.api import extract_references_and_questions
|
||||||
from khoj.routers.helpers import (
|
from khoj.routers.helpers import (
|
||||||
ChatEvent,
|
ChatEvent,
|
||||||
@@ -36,12 +37,14 @@ class InformationCollectionIteration:
|
|||||||
query: str,
|
query: str,
|
||||||
context: Dict[str, Dict] = None,
|
context: Dict[str, Dict] = None,
|
||||||
onlineContext: dict = None,
|
onlineContext: dict = None,
|
||||||
|
codeContext: dict = None,
|
||||||
summarizedResult: str = None,
|
summarizedResult: str = None,
|
||||||
):
|
):
|
||||||
self.data_source = data_source
|
self.data_source = data_source
|
||||||
self.query = query
|
self.query = query
|
||||||
self.context = context
|
self.context = context
|
||||||
self.onlineContext = onlineContext
|
self.onlineContext = onlineContext
|
||||||
|
self.codeContext = codeContext
|
||||||
self.summarizedResult = summarizedResult
|
self.summarizedResult = summarizedResult
|
||||||
|
|
||||||
|
|
||||||
@@ -160,7 +163,7 @@ async def execute_information_collection(
|
|||||||
previous_iterations: List[InformationCollectionIteration] = []
|
previous_iterations: List[InformationCollectionIteration] = []
|
||||||
while current_iteration < MAX_ITERATIONS:
|
while current_iteration < MAX_ITERATIONS:
|
||||||
online_results: Dict = dict()
|
online_results: Dict = dict()
|
||||||
|
code_results: Dict = dict()
|
||||||
compiled_references: List[Any] = []
|
compiled_references: List[Any] = []
|
||||||
inferred_queries: List[Any] = []
|
inferred_queries: List[Any] = []
|
||||||
|
|
||||||
@@ -260,6 +263,30 @@ async def execute_information_collection(
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error reading webpages: {e}", exc_info=True)
|
logger.error(f"Error reading webpages: {e}", exc_info=True)
|
||||||
|
|
||||||
|
elif this_iteration.data_source == ConversationCommand.Code:
|
||||||
|
try:
|
||||||
|
async for result in run_code(
|
||||||
|
this_iteration.query,
|
||||||
|
conversation_history,
|
||||||
|
location,
|
||||||
|
user,
|
||||||
|
send_status_func,
|
||||||
|
uploaded_image_url=uploaded_image_url,
|
||||||
|
agent=agent,
|
||||||
|
):
|
||||||
|
if isinstance(result, dict) and ChatEvent.STATUS in result:
|
||||||
|
yield result[ChatEvent.STATUS]
|
||||||
|
else:
|
||||||
|
code_results: Dict[str, Dict] = result # type: ignore
|
||||||
|
this_iteration.codeContext = code_results
|
||||||
|
async for result in send_status_func(f"**Ran code snippets**: {len(this_iteration.codeContext)}"):
|
||||||
|
yield result
|
||||||
|
except ValueError as e:
|
||||||
|
logger.warning(
|
||||||
|
f"Failed to use code tool: {e}. Attempting to respond without code results",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
|
||||||
# TODO: Fix summarize later
|
# TODO: Fix summarize later
|
||||||
# elif this_iteration.data_source == ConversationCommand.Summarize:
|
# elif this_iteration.data_source == ConversationCommand.Summarize:
|
||||||
# response_log = ""
|
# response_log = ""
|
||||||
@@ -306,12 +333,14 @@ async def execute_information_collection(
|
|||||||
|
|
||||||
current_iteration += 1
|
current_iteration += 1
|
||||||
|
|
||||||
if compiled_references or online_results:
|
if compiled_references or online_results or code_results:
|
||||||
results_data = f"**Results**:\n"
|
results_data = f"**Results**:\n"
|
||||||
if compiled_references:
|
if compiled_references:
|
||||||
results_data += f"**Document References**: {compiled_references}\n"
|
results_data += f"**Document References**: {compiled_references}\n"
|
||||||
if online_results:
|
if online_results:
|
||||||
results_data += f"**Online Results**: {online_results}\n"
|
results_data += f"**Online Results**: {online_results}\n"
|
||||||
|
if code_results:
|
||||||
|
results_data += f"**Code Results**: {code_results}\n"
|
||||||
|
|
||||||
# intermediate_result = await extract_relevant_info(this_iteration.query, results_data, agent)
|
# intermediate_result = await extract_relevant_info(this_iteration.query, results_data, agent)
|
||||||
this_iteration.summarizedResult = results_data
|
this_iteration.summarizedResult = results_data
|
||||||
|
|||||||
@@ -352,6 +352,7 @@ function_calling_description_for_llm = {
|
|||||||
ConversationCommand.Notes: "To search the user's personal knowledge base. Especially helpful if the question expects context from the user's notes or documents.",
|
ConversationCommand.Notes: "To search the user's personal knowledge base. Especially helpful if the question expects context from the user's notes or documents.",
|
||||||
ConversationCommand.Online: "To search for the latest, up-to-date information from the internet.",
|
ConversationCommand.Online: "To search for the latest, up-to-date information from the internet.",
|
||||||
ConversationCommand.Webpage: "To use if the user has directly provided the webpage urls or you are certain of the webpage urls to read.",
|
ConversationCommand.Webpage: "To use if the user has directly provided the webpage urls or you are certain of the webpage urls to read.",
|
||||||
|
ConversationCommand.Code: "To run Python code in a Pyodide sandbox with no network access. Helpful when need to parse information, run complex calculations, create documents and charts for user. Matplotlib, bs4, pandas, numpy, etc. are available.",
|
||||||
}
|
}
|
||||||
|
|
||||||
mode_descriptions_for_llm = {
|
mode_descriptions_for_llm = {
|
||||||
|
|||||||
Reference in New Issue
Block a user