learning / src /agent /custom_agent.py
Ankit93's picture
Modification
916b2a2
Raw
History Blame Contribute Delete
4.12 kB
import re, ast
import logging
import re
import json
import logging
from typing import List, Dict
from llama_index.core.tools.types import ToolOutput
from src.agent.agenttools import ChatBotFunctionTools
class LearningAgent:
def __init__(self, llm_value: str):
tool_builder = ChatBotFunctionTools(llm_type=llm_value)
self.llm = tool_builder.generator
self.tools = tool_builder.get_tools()
self.chat_history: List[Dict[str, str]] = []
self.max_history = 20
def extract_json_from_markdown(self, markdown_text: str):
try:
match = re.search(r"```json\s*(\{.*?\})\s*```", markdown_text, re.DOTALL)
if not match:
raise ValueError("No JSON block found in markdown")
return json.loads(match.group(1))
except Exception as e:
logging.error(f"Could not parse JSON: {e}")
return None
def determine_tools(self, query: str):
previous_questions = "\n".join(
[msg["content"] for msg in self.chat_history if msg["role"] == "user"]
) if self.chat_history else "No previous questions"
prompt = f"""Analyze this learning query and select appropriate tools also form the condensed query based on
previous_questions and Query:
For Choosing tool properly analyze the condensed query and then decide. Choose multiple if its necessary based on condensed query
Its mandatory to select to atleast 1 tool.
If asked for any query related to code generation dont include theory rather give code and its explaination
Query: {query}
Previous Query: {previous_questions}
Available Tools: {list(self.tools.keys())}
Return dictionary of tool names and condensed query as dictionary in the below format:
```json
{{
"condensed_query": condensed query considering chat history and user query as string,
"tool_names": tool names as comma-separated list
}}
```
Do Not add additional text"""
response = self.llm.complete(prompt)
try:
response = response.text
except:
response = response
parsed = self.extract_json_from_markdown(response)
condensed_query = parsed["condensed_query"]
tools = [t.strip() for t in parsed['tool_names'].split(",") if t.strip() in self.tools]
return tools if tools else ['llm_query'], condensed_query
def execute_tools(self, tools: List[str], query: str) -> tuple[str, str]:
tool_results, content_results = [], []
for tool in tools:
try:
tool_output = self.tools[tool](query)
content = tool_output.content if isinstance(tool_output, ToolOutput) else str(tool_output)
tool_results.append(tool)
content_results.append(content)
except Exception as e:
logging.error(f"Tool {tool} failed: {str(e)}")
tool_results.append(tool)
content_results.append(f"Error: {str(e)}")
if len(tool_results) > 1:
combined = "\n\n".join(f"**{t}**:\n{c}" for t, c in zip(tool_results, content_results))
explanation = self.tools["concept_combiner"](content_results)
return "multiple", f"{combined}\n\n**Combined Analysis**:\n{explanation}"
return tool_results[0], content_results[0]
def process_query(self, query: str) -> tuple[List[Dict[str, str]], str, str]:
tools, condensed_query = self.determine_tools(query)
tool_used, response = self.execute_tools(tools, condensed_query)
self.chat_history += [{"role": "user", "content": query}, {"role": "assistant", "content": response}]
self.chat_history = self.chat_history[-(self.max_history * 2):]
return self.chat_history, tool_used, response