-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve: Research Agent Regex Parsing #469
Open
hjamet
wants to merge
7
commits into
stitionai:main
Choose a base branch
from
hjamet:AgentRegexParsing
base: main
Could not load branches
Branch not found: {{ refName }}
Could not load tags
Nothing to show
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+278
−98
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
c937166
ci: :see_no_evil: Add vscode to gitignore
hjamet 6e00978
feat: :construction: better validate_response
hjamet cb276b6
fix: :zap: Agent template working for researcher
hjamet 041ff4b
refactor: :recycle: Small improvment in code structure
hjamet 6fc6bce
fix: :adhesive_bandage: Limit the LLM to 3 search
hjamet 843d471
feat: :twisted_rightwards_arrows: Fix merge conflicts
hjamet 03b92bf
fix: :bug: Small improvment
hjamet File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -160,4 +160,10 @@ cython_debug/ | |
.idea/ | ||
|
||
notes.md | ||
data/ | ||
|
||
# Local installation | ||
data/ | ||
ui/ | ||
|
||
# Vscode | ||
.vscode/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
from .agent import Agent | ||
from .agents import Agents | ||
from .agent_template import AgentTemplate | ||
|
||
from .planner import Planner | ||
from .internal_monologue import InternalMonologue | ||
from .researcher import Researcher | ||
from .formatter import Formatter | ||
from .coder import Coder | ||
from .action import Action | ||
from .runner import Runner | ||
from .runner import Runner |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. THE MAIN MODIFICATION The parent class of all agents uses regex to efficiently parse LLM responses |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import json | ||
import re | ||
import os | ||
import inspect | ||
|
||
from jinja2 import BaseLoader, Environment | ||
from src.logger import Logger | ||
|
||
logger = Logger() | ||
|
||
|
||
class AgentTemplate: | ||
""" " | ||
This class is the parent class of all the agents. It defines the methods and attributes common to all agents. | ||
""" | ||
|
||
def __init__(self): | ||
pass | ||
|
||
def render(self, *args, **kwargs) -> str: | ||
""" | ||
This method renders the prompt template of the child class with the provided arguments. | ||
|
||
Args: | ||
*args: SHOULD NOT BE USED. | ||
**kwargs: The arguments to provide to the prompt template. | ||
|
||
Returns: | ||
str: The rendered prompt. | ||
""" | ||
# Display a warning if args are provided | ||
if args: | ||
logger.warning( | ||
f"INTERNAL ERROR : The render method of the AgentTemplate class should only be called with kwargs. Received args: {args}" | ||
) | ||
|
||
# Load the prompt template of the child class | ||
env = Environment(loader=BaseLoader()) | ||
template_path = os.path.join( | ||
os.path.dirname(inspect.getfile(self.__class__)), "prompt.jinja2" | ||
) | ||
with open(template_path, "r") as f: | ||
template_string = f.read() | ||
template = env.from_string(template_string) | ||
|
||
# Check if all the variables in the template are provided | ||
required_variables = re.findall(r"{{ (.*?) }}", template_string) | ||
for variable in required_variables: | ||
if variable not in kwargs: | ||
raise ValueError(f"Missing variable {variable} in the render method.") | ||
|
||
return template.render(**kwargs) | ||
|
||
def parse_answer(self, response: str) -> dict | bool: | ||
""" | ||
This method try to parse the response from the model to a dict based on the prompt structure. | ||
If it fails, it returns False. | ||
|
||
Args: | ||
response (str): The raw response from the model. | ||
|
||
Returns: | ||
dict | bool: The parsed response or False. | ||
""" | ||
try: | ||
final_json = self.find_json_blocks(response) | ||
except Exception as _: | ||
return False | ||
|
||
try: | ||
final_json = json.loads(final_json) | ||
except Exception as _: | ||
return False | ||
|
||
# Get required fields from the response | ||
with open( | ||
os.path.join( | ||
os.path.dirname(inspect.getfile(self.__class__)), "prompt.jinja2" | ||
), | ||
"r", | ||
) as f: | ||
template = f.read() | ||
template_json = self.find_json_blocks(template) | ||
required_fields = list(json.loads(template_json).keys()) | ||
|
||
# Check if all the required fields are present in the response | ||
for field in required_fields: | ||
if field not in final_json: | ||
logger.warning(f"Missing field {field} in the response.") | ||
return False | ||
|
||
return {field: final_json[field] for field in required_fields} | ||
|
||
def find_json_blocks(self, text: str) -> str: | ||
""" | ||
This method extracts the JSON blocks from the text. | ||
|
||
Args: | ||
text (str): The text to extract the JSON blocks from. | ||
|
||
Returns: | ||
str: The extracted JSON blocks as a string that can be parsed using `json.loads`. | ||
|
||
Raises: | ||
Exception: If the JSON blocks cannot be parsed. | ||
""" | ||
# Remove eventually unrendered jinja2 blocks and extract JSON blocks | ||
json_blocks = re.findall(r"{(.*?)}", re.sub(r"{{.*?}}", "", text), re.DOTALL) | ||
|
||
try: | ||
parsed_json_results = [] | ||
for block in json_blocks: | ||
cleaned_block = block.replace("\n", "").replace("```\n\n```", "") | ||
parsed_block = json.loads("{" + cleaned_block + "}") | ||
parsed_json_results.append(parsed_block) | ||
except Exception as e: | ||
logger.warning(f"Error while parsing JSON blocks: {e}") | ||
raise e | ||
|
||
# Try to merge all the JSON blocks into a single JSON dict | ||
try: | ||
final_json = {} | ||
for parsed_block in parsed_json_results: | ||
for key, value in parsed_block.items(): | ||
if key in final_json: | ||
final_json[key] += value | ||
else: | ||
final_json[key] = value | ||
|
||
final_json = json.dumps(final_json, indent=4) | ||
except Exception as e: | ||
logger.warning(f"Error while merging JSON blocks: {e}") | ||
raise e | ||
|
||
return final_json |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ONLY BETTER FORMATTING : NO MODIFICATIONS