Merge remote-tracking branch 'upstream/main'

This commit is contained in:
Braelyn Boynton
2024-05-06 11:50:31 -07:00
11 changed files with 187 additions and 3635 deletions

View File

@@ -41,6 +41,7 @@ class Crew(BaseModel):
tasks: List of tasks assigned to the crew.
agents: List of agents part of this crew.
manager_llm: The language model that will run manager agent.
manager_agent: Custom agent that will be used as manager.
memory: Whether the crew should use memory to store memories of it's execution.
manager_callbacks: The callback handlers to be executed by the manager agent when hierarchical process is used
cache: Whether the crew should use a cache to store the results of the tools execution.
@@ -175,14 +176,23 @@ class Crew(BaseModel):
@model_validator(mode="after")
def check_manager_llm(self):
"""Validates that the language model is set when using hierarchical process."""
if self.process == Process.hierarchical and (
not self.manager_llm and not self.manager_agent
):
raise PydanticCustomError(
"missing_manager_llm",
"Attribute `manager_llm` is required when using hierarchical process.",
{},
)
if self.process == Process.hierarchical:
if not self.manager_llm and not self.manager_agent:
raise PydanticCustomError(
"missing_manager_llm_or_manager_agent",
"Attribute `manager_llm` or `manager_agent` is required when using hierarchical process.",
{},
)
if (self.manager_agent is not None) and (
self.agents.count(self.manager_agent) > 0
):
raise PydanticCustomError(
"manager_agent_in_agents",
"Manager agent should not be included in agents list.",
{},
)
return self
@model_validator(mode="after")
@@ -316,12 +326,13 @@ class Crew(BaseModel):
"""Creates and assigns a manager agent to make sure the crew completes the tasks."""
i18n = I18N(prompt_file=self.prompt_file)
try:
self.manager_agent.allow_delegation = (
True # Forcing Allow delegation to the manager
)
if self.manager_agent is not None:
self.manager_agent.allow_delegation = True
manager = self.manager_agent
except:
if len(manager.tools) > 0:
raise Exception("Manager agent should not have tools")
manager.tools = AgentTools(agents=self.agents).tools()
else:
manager = Agent(
role=i18n.retrieve("hierarchical_manager_agent", "role"),
goal=i18n.retrieve("hierarchical_manager_agent", "goal"),

View File

@@ -1,14 +1,28 @@
tasks_order = []
def memoize(func):
cache = {}
def memoized_func(*args, **kwargs):
key = (args, tuple(kwargs.items()))
if key not in cache:
cache[key] = func(*args, **kwargs)
return cache[key]
return memoized_func
def task(func):
func.is_task = True
tasks_order.append(func.__name__)
func = memoize(func)
return func
def agent(func):
func.is_agent = True
func = memoize(func)
return func

View File

@@ -1,7 +1,7 @@
import ast
from difflib import SequenceMatcher
from textwrap import dedent
from typing import Any, List, Union
from difflib import SequenceMatcher
from langchain_core.tools import BaseTool
from langchain_openai import ChatOpenAI
@@ -330,7 +330,7 @@ class ToolUsage:
return calling
def _validate_tool_input(self, tool_input: str) -> dict:
def _validate_tool_input(self, tool_input: str) -> str:
try:
ast.literal_eval(tool_input)
return tool_input
@@ -351,13 +351,17 @@ class ToolUsage:
continue # Skip malformed entries
key, value = entry.split(":", 1)
key = key.strip().strip(
'"'
) # Remove extraneous white spaces and quotes
# Remove extraneous white spaces and quotes, replace single quotes
key = key.strip().strip('"').replace("'", '"')
value = value.strip()
# Check and format the value based on its type
if value.isdigit(): # Check if value is a digit, hence integer
# Handle replacement of single quotes at the start and end of the value string
if value.startswith("'") and value.endswith("'"):
value = value[1:-1] # Remove single quotes
value = (
'"' + value.replace('"', '\\"') + '"'
) # Re-encapsulate with double quotes
elif value.isdigit(): # Check if value is a digit, hence integer
formatted_value = value
elif value.lower() in [
"true",
@@ -367,7 +371,7 @@ class ToolUsage:
formatted_value = value.lower()
else:
# Assume the value is a string and needs quotes
formatted_value = '"' + value.strip('"').replace('"', '\\"') + '"'
formatted_value = '"' + value.replace('"', '\\"') + '"'
# Rebuild the entry with proper quoting
formatted_entry = f'"{key}": {formatted_value}'