Merge branch 'main' into feat/improve-yaml-extraction

This commit is contained in:
Lorenze Jay
2025-03-21 17:12:35 -07:00
committed by GitHub
10 changed files with 171 additions and 34 deletions

View File

@@ -491,7 +491,7 @@ In this section, you'll find detailed examples that help you select, configure,
<Accordion title="Ollama (Local LLMs)"> <Accordion title="Ollama (Local LLMs)">
1. Install Ollama: [ollama.ai](https://ollama.ai/) 1. Install Ollama: [ollama.ai](https://ollama.ai/)
2. Run a model: `ollama run llama2` 2. Run a model: `ollama run llama3`
3. Configure: 3. Configure:
```python Code ```python Code
@@ -786,5 +786,10 @@ Learn how to get the most out of your LLM configuration:
<Tip> <Tip>
Use larger context models for extensive tasks Use larger context models for extensive tasks
</Tip> </Tip>
```python
# Large context model
llm = LLM(model="openai/gpt-4o") # 128K tokens
```
</Tab> </Tab>
</Tabs> </Tabs>

View File

@@ -300,7 +300,7 @@ email_summarizer:
``` ```
<Tip> <Tip>
Note how we use the same name for the agent in the `tasks.yaml` (`email_summarizer_task`) file as the method name in the `crew.py` (`email_summarizer_task`) file. Note how we use the same name for the task in the `tasks.yaml` (`email_summarizer_task`) file as the method name in the `crew.py` (`email_summarizer_task`) file.
</Tip> </Tip>
```yaml tasks.yaml ```yaml tasks.yaml

View File

@@ -17,9 +17,9 @@ dependencies = [
"pdfplumber>=0.11.4", "pdfplumber>=0.11.4",
"regex>=2024.9.11", "regex>=2024.9.11",
# Telemetry and Monitoring # Telemetry and Monitoring
"opentelemetry-api>=1.22.0", "opentelemetry-api>=1.30.0",
"opentelemetry-sdk>=1.22.0", "opentelemetry-sdk>=1.30.0",
"opentelemetry-exporter-otlp-proto-http>=1.22.0", "opentelemetry-exporter-otlp-proto-http>=1.30.0",
# Data Handling # Data Handling
"chromadb>=0.5.23", "chromadb>=0.5.23",
"openpyxl>=3.1.5", "openpyxl>=3.1.5",

View File

@@ -136,7 +136,7 @@ class CrewAgentParser:
def _clean_action(self, text: str) -> str: def _clean_action(self, text: str) -> str:
"""Clean action string by removing non-essential formatting characters.""" """Clean action string by removing non-essential formatting characters."""
return re.sub(r"^\s*\*+\s*|\s*\*+\s*$", "", text).strip() return text.strip().strip("*").strip()
def _safe_repair_json(self, tool_input: str) -> str: def _safe_repair_json(self, tool_input: str) -> str:
UNABLE_TO_REPAIR_JSON_RESULTS = ['""', "{}"] UNABLE_TO_REPAIR_JSON_RESULTS = ['""', "{}"]

View File

@@ -1,4 +1,5 @@
import subprocess import subprocess
from functools import lru_cache
class Repository: class Repository:
@@ -35,6 +36,7 @@ class Repository:
encoding="utf-8", encoding="utf-8",
).strip() ).strip()
@lru_cache(maxsize=None)
def is_git_repo(self) -> bool: def is_git_repo(self) -> bool:
"""Check if the current directory is a git repository.""" """Check if the current directory is a git repository."""
try: try:

View File

@@ -114,6 +114,60 @@ LLM_CONTEXT_WINDOW_SIZES = {
"Llama-3.2-11B-Vision-Instruct": 16384, "Llama-3.2-11B-Vision-Instruct": 16384,
"Meta-Llama-3.2-3B-Instruct": 4096, "Meta-Llama-3.2-3B-Instruct": 4096,
"Meta-Llama-3.2-1B-Instruct": 16384, "Meta-Llama-3.2-1B-Instruct": 16384,
# bedrock
"us.amazon.nova-pro-v1:0": 300000,
"us.amazon.nova-micro-v1:0": 128000,
"us.amazon.nova-lite-v1:0": 300000,
"us.anthropic.claude-3-5-sonnet-20240620-v1:0": 200000,
"us.anthropic.claude-3-5-haiku-20241022-v1:0": 200000,
"us.anthropic.claude-3-5-sonnet-20241022-v2:0": 200000,
"us.anthropic.claude-3-7-sonnet-20250219-v1:0": 200000,
"us.anthropic.claude-3-sonnet-20240229-v1:0": 200000,
"us.anthropic.claude-3-opus-20240229-v1:0": 200000,
"us.anthropic.claude-3-haiku-20240307-v1:0": 200000,
"us.meta.llama3-2-11b-instruct-v1:0": 128000,
"us.meta.llama3-2-3b-instruct-v1:0": 131000,
"us.meta.llama3-2-90b-instruct-v1:0": 128000,
"us.meta.llama3-2-1b-instruct-v1:0": 131000,
"us.meta.llama3-1-8b-instruct-v1:0": 128000,
"us.meta.llama3-1-70b-instruct-v1:0": 128000,
"us.meta.llama3-3-70b-instruct-v1:0": 128000,
"us.meta.llama3-1-405b-instruct-v1:0": 128000,
"eu.anthropic.claude-3-5-sonnet-20240620-v1:0": 200000,
"eu.anthropic.claude-3-sonnet-20240229-v1:0": 200000,
"eu.anthropic.claude-3-haiku-20240307-v1:0": 200000,
"eu.meta.llama3-2-3b-instruct-v1:0": 131000,
"eu.meta.llama3-2-1b-instruct-v1:0": 131000,
"apac.anthropic.claude-3-5-sonnet-20240620-v1:0": 200000,
"apac.anthropic.claude-3-5-sonnet-20241022-v2:0": 200000,
"apac.anthropic.claude-3-sonnet-20240229-v1:0": 200000,
"apac.anthropic.claude-3-haiku-20240307-v1:0": 200000,
"amazon.nova-pro-v1:0": 300000,
"amazon.nova-micro-v1:0": 128000,
"amazon.nova-lite-v1:0": 300000,
"anthropic.claude-3-5-sonnet-20240620-v1:0": 200000,
"anthropic.claude-3-5-haiku-20241022-v1:0": 200000,
"anthropic.claude-3-5-sonnet-20241022-v2:0": 200000,
"anthropic.claude-3-7-sonnet-20250219-v1:0": 200000,
"anthropic.claude-3-sonnet-20240229-v1:0": 200000,
"anthropic.claude-3-opus-20240229-v1:0": 200000,
"anthropic.claude-3-haiku-20240307-v1:0": 200000,
"anthropic.claude-v2:1": 200000,
"anthropic.claude-v2": 100000,
"anthropic.claude-instant-v1": 100000,
"meta.llama3-1-405b-instruct-v1:0": 128000,
"meta.llama3-1-70b-instruct-v1:0": 128000,
"meta.llama3-1-8b-instruct-v1:0": 128000,
"meta.llama3-70b-instruct-v1:0": 8000,
"meta.llama3-8b-instruct-v1:0": 8000,
"amazon.titan-text-lite-v1": 4000,
"amazon.titan-text-express-v1": 8000,
"cohere.command-text-v14": 4000,
"ai21.j2-mid-v1": 8191,
"ai21.j2-ultra-v1": 8191,
"ai21.jamba-instruct-v1:0": 256000,
"mistral.mistral-7b-instruct-v0:2": 32000,
"mistral.mixtral-8x7b-instruct-v0:1": 32000,
# mistral # mistral
"mistral-tiny": 32768, "mistral-tiny": 32768,
"mistral-small-latest": 32768, "mistral-small-latest": 32768,

View File

@@ -1,7 +1,7 @@
import os import os
from typing import Any, Dict, List from typing import Any, Dict, List
from mem0 import MemoryClient from mem0 import Memory, MemoryClient
from crewai.memory.storage.interface import Storage from crewai.memory.storage.interface import Storage
@@ -32,13 +32,16 @@ class Mem0Storage(Storage):
mem0_org_id = config.get("org_id") mem0_org_id = config.get("org_id")
mem0_project_id = config.get("project_id") mem0_project_id = config.get("project_id")
# Initialize MemoryClient with available parameters # Initialize MemoryClient or Memory based on the presence of the mem0_api_key
if mem0_api_key:
if mem0_org_id and mem0_project_id: if mem0_org_id and mem0_project_id:
self.memory = MemoryClient( self.memory = MemoryClient(
api_key=mem0_api_key, org_id=mem0_org_id, project_id=mem0_project_id api_key=mem0_api_key, org_id=mem0_org_id, project_id=mem0_project_id
) )
else: else:
self.memory = MemoryClient(api_key=mem0_api_key) self.memory = MemoryClient(api_key=mem0_api_key)
else:
self.memory = Memory() # Fallback to Memory if no Mem0 API key is provided
def _sanitize_role(self, role: str) -> str: def _sanitize_role(self, role: str) -> str:
""" """

View File

@@ -281,8 +281,16 @@ class Telemetry:
return self._safe_telemetry_operation(operation) return self._safe_telemetry_operation(operation)
def task_ended(self, span: Span, task: Task, crew: Crew): def task_ended(self, span: Span, task: Task, crew: Crew):
"""Records task execution in a crew.""" """Records the completion of a task execution in a crew.
Args:
span (Span): The OpenTelemetry span tracking the task execution
task (Task): The task that was completed
crew (Crew): The crew context in which the task was executed
Note:
If share_crew is enabled, this will also record the task output
"""
def operation(): def operation():
if crew.share_crew: if crew.share_crew:
self._add_attribute( self._add_attribute(
@@ -297,8 +305,13 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def tool_repeated_usage(self, llm: Any, tool_name: str, attempts: int): def tool_repeated_usage(self, llm: Any, tool_name: str, attempts: int):
"""Records the repeated usage 'error' of a tool by an agent.""" """Records when a tool is used repeatedly, which might indicate an issue.
Args:
llm (Any): The language model being used
tool_name (str): Name of the tool being repeatedly used
attempts (int): Number of attempts made with this tool
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Tool Repeated Usage") span = tracer.start_span("Tool Repeated Usage")
@@ -317,8 +330,13 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def tool_usage(self, llm: Any, tool_name: str, attempts: int): def tool_usage(self, llm: Any, tool_name: str, attempts: int):
"""Records the usage of a tool by an agent.""" """Records the usage of a tool by an agent.
Args:
llm (Any): The language model being used
tool_name (str): Name of the tool being used
attempts (int): Number of attempts made with this tool
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Tool Usage") span = tracer.start_span("Tool Usage")
@@ -337,8 +355,11 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def tool_usage_error(self, llm: Any): def tool_usage_error(self, llm: Any):
"""Records the usage of a tool by an agent.""" """Records when a tool usage results in an error.
Args:
llm (Any): The language model being used when the error occurred
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Tool Usage Error") span = tracer.start_span("Tool Usage Error")
@@ -357,6 +378,14 @@ class Telemetry:
def individual_test_result_span( def individual_test_result_span(
self, crew: Crew, quality: float, exec_time: int, model_name: str self, crew: Crew, quality: float, exec_time: int, model_name: str
): ):
"""Records individual test results for a crew execution.
Args:
crew (Crew): The crew being tested
quality (float): Quality score of the execution
exec_time (int): Execution time in seconds
model_name (str): Name of the model used
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Crew Individual Test Result") span = tracer.start_span("Crew Individual Test Result")
@@ -383,6 +412,14 @@ class Telemetry:
inputs: dict[str, Any] | None, inputs: dict[str, Any] | None,
model_name: str, model_name: str,
): ):
"""Records the execution of a test suite for a crew.
Args:
crew (Crew): The crew being tested
iterations (int): Number of test iterations
inputs (dict[str, Any] | None): Input parameters for the test
model_name (str): Name of the model used in testing
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Crew Test Execution") span = tracer.start_span("Crew Test Execution")
@@ -408,6 +445,7 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def deploy_signup_error_span(self): def deploy_signup_error_span(self):
"""Records when an error occurs during the deployment signup process."""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Deploy Signup Error") span = tracer.start_span("Deploy Signup Error")
@@ -417,6 +455,11 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def start_deployment_span(self, uuid: Optional[str] = None): def start_deployment_span(self, uuid: Optional[str] = None):
"""Records the start of a deployment process.
Args:
uuid (Optional[str]): Unique identifier for the deployment
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Start Deployment") span = tracer.start_span("Start Deployment")
@@ -428,6 +471,7 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def create_crew_deployment_span(self): def create_crew_deployment_span(self):
"""Records the creation of a new crew deployment."""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Create Crew Deployment") span = tracer.start_span("Create Crew Deployment")
@@ -437,6 +481,12 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def get_crew_logs_span(self, uuid: Optional[str], log_type: str = "deployment"): def get_crew_logs_span(self, uuid: Optional[str], log_type: str = "deployment"):
"""Records the retrieval of crew logs.
Args:
uuid (Optional[str]): Unique identifier for the crew
log_type (str, optional): Type of logs being retrieved. Defaults to "deployment".
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Get Crew Logs") span = tracer.start_span("Get Crew Logs")
@@ -449,6 +499,11 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def remove_crew_span(self, uuid: Optional[str] = None): def remove_crew_span(self, uuid: Optional[str] = None):
"""Records the removal of a crew.
Args:
uuid (Optional[str]): Unique identifier for the crew being removed
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Remove Crew") span = tracer.start_span("Remove Crew")
@@ -574,6 +629,11 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def flow_creation_span(self, flow_name: str): def flow_creation_span(self, flow_name: str):
"""Records the creation of a new flow.
Args:
flow_name (str): Name of the flow being created
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Flow Creation") span = tracer.start_span("Flow Creation")
@@ -584,6 +644,12 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def flow_plotting_span(self, flow_name: str, node_names: list[str]): def flow_plotting_span(self, flow_name: str, node_names: list[str]):
"""Records flow visualization/plotting activity.
Args:
flow_name (str): Name of the flow being plotted
node_names (list[str]): List of node names in the flow
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Flow Plotting") span = tracer.start_span("Flow Plotting")
@@ -595,6 +661,12 @@ class Telemetry:
self._safe_telemetry_operation(operation) self._safe_telemetry_operation(operation)
def flow_execution_span(self, flow_name: str, node_names: list[str]): def flow_execution_span(self, flow_name: str, node_names: list[str]):
"""Records the execution of a flow.
Args:
flow_name (str): Name of the flow being executed
node_names (list[str]): List of nodes being executed in the flow
"""
def operation(): def operation():
tracer = trace.get_tracer("crewai.telemetry") tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Flow Execution") span = tracer.start_span("Flow Execution")

View File

@@ -455,7 +455,7 @@ class ToolUsage:
# Attempt 4: Repair JSON # Attempt 4: Repair JSON
try: try:
repaired_input = repair_json(tool_input) repaired_input = repair_json(tool_input, skip_json_loads=True)
self._printer.print( self._printer.print(
content=f"Repaired JSON: {repaired_input}", color="blue" content=f"Repaired JSON: {repaired_input}", color="blue"
) )

View File

@@ -96,6 +96,10 @@ class CrewPlanner:
tasks_summary = [] tasks_summary = []
for idx, task in enumerate(self.tasks): for idx, task in enumerate(self.tasks):
knowledge_list = self._get_agent_knowledge(task) knowledge_list = self._get_agent_knowledge(task)
agent_tools = (
f"[{', '.join(str(tool) for tool in task.agent.tools)}]" if task.agent and task.agent.tools else '"agent has no tools"',
f',\n "agent_knowledge": "[\\"{knowledge_list[0]}\\"]"' if knowledge_list and str(knowledge_list) != "None" else ""
)
task_summary = f""" task_summary = f"""
Task Number {idx + 1} - {task.description} Task Number {idx + 1} - {task.description}
"task_description": {task.description} "task_description": {task.description}
@@ -103,10 +107,7 @@ class CrewPlanner:
"agent": {task.agent.role if task.agent else "None"} "agent": {task.agent.role if task.agent else "None"}
"agent_goal": {task.agent.goal if task.agent else "None"} "agent_goal": {task.agent.goal if task.agent else "None"}
"task_tools": {task.tools} "task_tools": {task.tools}
"agent_tools": %s%s""" % ( "agent_tools": {"".join(agent_tools)}"""
f"[{', '.join(str(tool) for tool in task.agent.tools)}]" if task.agent and task.agent.tools else '"agent has no tools"',
f',\n "agent_knowledge": "[\\"{knowledge_list[0]}\\"]"' if knowledge_list and str(knowledge_list) != "None" else ""
)
tasks_summary.append(task_summary) tasks_summary.append(task_summary)
return " ".join(tasks_summary) return " ".join(tasks_summary)