mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-11 17:18:29 +00:00
merge: Merge main branch into task-guardrails branch
Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
8
.github/workflows/stale.yml
vendored
8
.github/workflows/stale.yml
vendored
@@ -1,5 +1,10 @@
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '10 12 * * *'
|
||||
@@ -8,9 +13,6 @@ on:
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
|
||||
@@ -44,7 +44,7 @@ To get started with CrewAI, follow these simple steps:
|
||||
|
||||
### 1. Installation
|
||||
|
||||
Ensure you have Python >=3.10 <=3.12 installed on your system. CrewAI uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
|
||||
Ensure you have Python >=3.10 <3.13 installed on your system. CrewAI uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
|
||||
|
||||
First, install CrewAI:
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ Large Language Models (LLMs) are the core intelligence behind CrewAI agents. The
|
||||
|
||||
## Available Models and Their Capabilities
|
||||
|
||||
Here's a detailed breakdown of supported models and their capabilities, you can compare performance at [lmarena.ai](https://lmarena.ai/):
|
||||
Here's a detailed breakdown of supported models and their capabilities, you can compare performance at [lmarena.ai](https://lmarena.ai/?leaderboard) and [artificialanalysis.ai](https://artificialanalysis.ai/):
|
||||
|
||||
<Tabs>
|
||||
<Tab title="OpenAI">
|
||||
@@ -121,12 +121,18 @@ Here's a detailed breakdown of supported models and their capabilities, you can
|
||||
<Tab title="Gemini">
|
||||
| Model | Context Window | Best For |
|
||||
|-------|---------------|-----------|
|
||||
| Gemini 1.5 Flash | 1M tokens | Balanced multimodal model, good for most tasks |
|
||||
| Gemini 1.5 Flash 8B | 1M tokens | Fastest, most cost-efficient, good for high-frequency tasks |
|
||||
| Gemini 1.5 Pro | 2M tokens | Best performing, wide variety of reasoning tasks including logical reasoning, coding, and creative collaboration |
|
||||
| gemini-2.0-flash-exp | 1M tokens | Higher quality at faster speed, multimodal model, good for most tasks |
|
||||
| gemini-1.5-flash | 1M tokens | Balanced multimodal model, good for most tasks |
|
||||
| gemini-1.5-flash-8B | 1M tokens | Fastest, most cost-efficient, good for high-frequency tasks |
|
||||
| gemini-1.5-pro | 2M tokens | Best performing, wide variety of reasoning tasks including logical reasoning, coding, and creative collaboration |
|
||||
|
||||
<Tip>
|
||||
Google's Gemini models are all multimodal, supporting audio, images, video and text, supporting context caching, json schema, function calling, etc.
|
||||
|
||||
These models are available via API_KEY from
|
||||
[The Gemini API](https://ai.google.dev/gemini-api/docs) and also from
|
||||
[Google Cloud Vertex](https://cloud.google.com/vertex-ai/generative-ai/docs/migrate/migrate-google-ai) as part of the
|
||||
[Model Garden](https://cloud.google.com/vertex-ai/generative-ai/docs/model-garden/explore-models).
|
||||
</Tip>
|
||||
</Tab>
|
||||
<Tab title="Groq">
|
||||
@@ -135,7 +141,6 @@ Here's a detailed breakdown of supported models and their capabilities, you can
|
||||
| Llama 3.1 70B/8B | 131,072 tokens | High-performance, large context tasks |
|
||||
| Llama 3.2 Series | 8,192 tokens | General-purpose tasks |
|
||||
| Mixtral 8x7B | 32,768 tokens | Balanced performance and context |
|
||||
| Gemma Series | 8,192 tokens | Efficient, smaller-scale tasks |
|
||||
|
||||
<Tip>
|
||||
Groq is known for its fast inference speeds, making it suitable for real-time applications.
|
||||
@@ -146,7 +151,7 @@ Here's a detailed breakdown of supported models and their capabilities, you can
|
||||
|----------|---------------|--------------|
|
||||
| Deepseek Chat | 128,000 tokens | Specialized in technical discussions |
|
||||
| Claude 3 | Up to 200K tokens | Strong reasoning, code understanding |
|
||||
| Gemini | Varies by model | Multimodal capabilities |
|
||||
| Gemma Series | 8,192 tokens | Efficient, smaller-scale tasks |
|
||||
|
||||
<Info>
|
||||
Provider selection should consider factors like:
|
||||
|
||||
@@ -7,7 +7,7 @@ icon: wrench
|
||||
<Note>
|
||||
**Python Version Requirements**
|
||||
|
||||
CrewAI requires `Python >=3.10 and <=3.12`. Here's how to check your version:
|
||||
CrewAI requires `Python >=3.10 and <3.13`. Here's how to check your version:
|
||||
```bash
|
||||
python3 --version
|
||||
```
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "crewai"
|
||||
version = "0.86.0"
|
||||
description = "Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10,<=3.12"
|
||||
requires-python = ">=3.10,<3.13"
|
||||
authors = [
|
||||
{ name = "Joao Moura", email = "joao@crewai.com" }
|
||||
]
|
||||
@@ -26,7 +26,7 @@ dependencies = [
|
||||
"uv>=0.4.25",
|
||||
"tomli-w>=1.1.0",
|
||||
"tomli>=2.0.2",
|
||||
"chromadb>=0.5.18",
|
||||
"chromadb>=0.5.23",
|
||||
"pdfplumber>=0.11.4",
|
||||
"openpyxl>=3.1.5",
|
||||
"blinker>=1.9.0",
|
||||
@@ -38,7 +38,7 @@ Documentation = "https://docs.crewai.com"
|
||||
Repository = "https://github.com/crewAIInc/crewAI"
|
||||
|
||||
[project.optional-dependencies]
|
||||
tools = ["crewai-tools>=0.14.0"]
|
||||
tools = ["crewai-tools>=0.17.0"]
|
||||
agentops = ["agentops>=0.3.0"]
|
||||
fastembed = ["fastembed>=0.4.1"]
|
||||
pdfplumber = [
|
||||
@@ -64,7 +64,7 @@ dev-dependencies = [
|
||||
"mkdocs-material-extensions>=1.3.1",
|
||||
"pillow>=10.2.0",
|
||||
"cairosvg>=2.7.1",
|
||||
"crewai-tools>=0.14.0",
|
||||
"crewai-tools>=0.17.0",
|
||||
"pytest>=8.0.0",
|
||||
"pytest-vcr>=1.0.2",
|
||||
"python-dotenv>=1.0.0",
|
||||
|
||||
@@ -23,27 +23,19 @@ from crewai.utilities.converter import generate_model_description
|
||||
from crewai.utilities.token_counter_callback import TokenCalcHandler
|
||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||
|
||||
agentops = None
|
||||
|
||||
def mock_agent_ops_provider():
|
||||
def track_agent(*args, **kwargs):
|
||||
try:
|
||||
import agentops # type: ignore # Name "agentops" is already defined
|
||||
from agentops import track_agent # type: ignore
|
||||
except ImportError:
|
||||
|
||||
def track_agent():
|
||||
def noop(f):
|
||||
return f
|
||||
|
||||
return noop
|
||||
|
||||
return track_agent
|
||||
|
||||
|
||||
agentops = None
|
||||
|
||||
if os.environ.get("AGENTOPS_API_KEY"):
|
||||
try:
|
||||
from agentops import track_agent
|
||||
except ImportError:
|
||||
track_agent = mock_agent_ops_provider()
|
||||
else:
|
||||
track_agent = mock_agent_ops_provider()
|
||||
|
||||
|
||||
@track_agent()
|
||||
class Agent(BaseAgent):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from importlib.metadata import version as get_version
|
||||
from typing import Optional
|
||||
|
||||
import click
|
||||
import pkg_resources
|
||||
|
||||
from crewai.cli.add_crew_to_flow import add_crew_to_flow
|
||||
from crewai.cli.create_crew import create_crew
|
||||
@@ -25,7 +25,7 @@ from .update_crew import update_crew
|
||||
|
||||
|
||||
@click.group()
|
||||
@click.version_option(pkg_resources.get_distribution("crewai").version)
|
||||
@click.version_option(get_version("crewai"))
|
||||
def crewai():
|
||||
"""Top-level command group for crewai."""
|
||||
|
||||
@@ -52,16 +52,16 @@ def create(type, name, provider, skip_provider=False):
|
||||
def version(tools):
|
||||
"""Show the installed version of crewai."""
|
||||
try:
|
||||
crewai_version = pkg_resources.get_distribution("crewai").version
|
||||
crewai_version = get_version("crewai")
|
||||
except Exception:
|
||||
crewai_version = "unknown version"
|
||||
click.echo(f"crewai version: {crewai_version}")
|
||||
|
||||
if tools:
|
||||
try:
|
||||
tools_version = pkg_resources.get_distribution("crewai-tools").version
|
||||
tools_version = get_version("crewai")
|
||||
click.echo(f"crewai tools version: {tools_version}")
|
||||
except pkg_resources.DistributionNotFound:
|
||||
except Exception:
|
||||
click.echo("crewai tools not installed")
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Welcome to the {{crew_name}} Crew project, powered by [crewAI](https://crewai.co
|
||||
|
||||
## Installation
|
||||
|
||||
Ensure you have Python >=3.10 <=3.12 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
|
||||
Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
|
||||
|
||||
First, if you haven't already, install uv:
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "{{folder_name}}"
|
||||
version = "0.1.0"
|
||||
description = "{{name}} using crewAI"
|
||||
authors = [{ name = "Your Name", email = "you@example.com" }]
|
||||
requires-python = ">=3.10,<=3.12"
|
||||
requires-python = ">=3.10,<3.13"
|
||||
dependencies = [
|
||||
"crewai[tools]>=0.86.0,<1.0.0"
|
||||
]
|
||||
@@ -18,3 +18,6 @@ test = "{{folder_name}}.main:test"
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.crewai]
|
||||
type = "crew"
|
||||
|
||||
@@ -10,7 +10,7 @@ class MyCustomToolInput(BaseModel):
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = (
|
||||
"Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
"Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
)
|
||||
args_schema: Type[BaseModel] = MyCustomToolInput
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Welcome to the {{crew_name}} Crew project, powered by [crewAI](https://crewai.co
|
||||
|
||||
## Installation
|
||||
|
||||
Ensure you have Python >=3.10 <=3.12 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
|
||||
Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for dependency management and package handling, offering a seamless setup and execution experience.
|
||||
|
||||
First, if you haven't already, install uv:
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from pydantic import BaseModel
|
||||
|
||||
from crewai.flow.flow import Flow, listen, start
|
||||
|
||||
from .crews.poem_crew.poem_crew import PoemCrew
|
||||
from {{folder_name}}.crews.poem_crew.poem_crew import PoemCrew
|
||||
|
||||
|
||||
class PoemState(BaseModel):
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "{{folder_name}}"
|
||||
version = "0.1.0"
|
||||
description = "{{name}} using crewAI"
|
||||
authors = [{ name = "Your Name", email = "you@example.com" }]
|
||||
requires-python = ">=3.10,<=3.12"
|
||||
requires-python = ">=3.10,<3.13"
|
||||
dependencies = [
|
||||
"crewai[tools]>=0.86.0,<1.0.0",
|
||||
]
|
||||
@@ -15,3 +15,6 @@ plot = "{{folder_name}}.main:plot"
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.crewai]
|
||||
type = "flow"
|
||||
|
||||
@@ -13,7 +13,7 @@ class MyCustomToolInput(BaseModel):
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = (
|
||||
"Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
"Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
)
|
||||
args_schema: Type[BaseModel] = MyCustomToolInput
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ custom tools to power up your crews.
|
||||
|
||||
## Installing
|
||||
|
||||
Ensure you have Python >=3.10 <=3.12 installed on your system. This project
|
||||
Ensure you have Python >=3.10 <3.13 installed on your system. This project
|
||||
uses [UV](https://docs.astral.sh/uv/) for dependency management and package
|
||||
handling, offering a seamless setup and execution experience.
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@ name = "{{folder_name}}"
|
||||
version = "0.1.0"
|
||||
description = "Power up your crews with {{folder_name}}"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10,<=3.12"
|
||||
requires-python = ">=3.10,<3.13"
|
||||
dependencies = [
|
||||
"crewai[tools]>=0.86.0"
|
||||
]
|
||||
|
||||
[tool.crewai]
|
||||
type = "tool"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import uuid
|
||||
import warnings
|
||||
from concurrent.futures import Future
|
||||
@@ -49,12 +48,10 @@ from crewai.utilities.planning_handler import CrewPlanner
|
||||
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
|
||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||
|
||||
agentops = None
|
||||
if os.environ.get("AGENTOPS_API_KEY"):
|
||||
try:
|
||||
import agentops # type: ignore
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import agentops # type: ignore
|
||||
except ImportError:
|
||||
agentops = None
|
||||
|
||||
|
||||
warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
|
||||
|
||||
@@ -124,43 +124,60 @@ class KnowledgeStorage(BaseKnowledgeStorage):
|
||||
documents: List[str],
|
||||
metadata: Optional[Union[Dict[str, Any], List[Dict[str, Any]]]] = None,
|
||||
):
|
||||
if self.collection:
|
||||
try:
|
||||
if metadata is None:
|
||||
metadatas: Optional[OneOrMany[chromadb.Metadata]] = None
|
||||
elif isinstance(metadata, list):
|
||||
metadatas = [cast(chromadb.Metadata, m) for m in metadata]
|
||||
else:
|
||||
metadatas = cast(chromadb.Metadata, metadata)
|
||||
|
||||
ids = [
|
||||
hashlib.sha256(doc.encode("utf-8")).hexdigest() for doc in documents
|
||||
]
|
||||
|
||||
self.collection.upsert(
|
||||
documents=documents,
|
||||
metadatas=metadatas,
|
||||
ids=ids,
|
||||
)
|
||||
except chromadb.errors.InvalidDimensionException as e:
|
||||
Logger(verbose=True).log(
|
||||
"error",
|
||||
"Embedding dimension mismatch. This usually happens when mixing different embedding models. Try resetting the collection using `crewai reset-memories -a`",
|
||||
"red",
|
||||
)
|
||||
raise ValueError(
|
||||
"Embedding dimension mismatch. Make sure you're using the same embedding model "
|
||||
"across all operations with this collection."
|
||||
"Try resetting the collection using `crewai reset-memories -a`"
|
||||
) from e
|
||||
except Exception as e:
|
||||
Logger(verbose=True).log(
|
||||
"error", f"Failed to upsert documents: {e}", "red"
|
||||
)
|
||||
raise
|
||||
else:
|
||||
if not self.collection:
|
||||
raise Exception("Collection not initialized")
|
||||
|
||||
try:
|
||||
# Create a dictionary to store unique documents
|
||||
unique_docs = {}
|
||||
|
||||
# Generate IDs and create a mapping of id -> (document, metadata)
|
||||
for idx, doc in enumerate(documents):
|
||||
doc_id = hashlib.sha256(doc.encode("utf-8")).hexdigest()
|
||||
doc_metadata = None
|
||||
if metadata is not None:
|
||||
if isinstance(metadata, list):
|
||||
doc_metadata = metadata[idx]
|
||||
else:
|
||||
doc_metadata = metadata
|
||||
unique_docs[doc_id] = (doc, doc_metadata)
|
||||
|
||||
# Prepare filtered lists for ChromaDB
|
||||
filtered_docs = []
|
||||
filtered_metadata = []
|
||||
filtered_ids = []
|
||||
|
||||
# Build the filtered lists
|
||||
for doc_id, (doc, meta) in unique_docs.items():
|
||||
filtered_docs.append(doc)
|
||||
filtered_metadata.append(meta)
|
||||
filtered_ids.append(doc_id)
|
||||
|
||||
# If we have no metadata at all, set it to None
|
||||
final_metadata: Optional[OneOrMany[chromadb.Metadata]] = (
|
||||
None if all(m is None for m in filtered_metadata) else filtered_metadata
|
||||
)
|
||||
|
||||
self.collection.upsert(
|
||||
documents=filtered_docs,
|
||||
metadatas=final_metadata,
|
||||
ids=filtered_ids,
|
||||
)
|
||||
except chromadb.errors.InvalidDimensionException as e:
|
||||
Logger(verbose=True).log(
|
||||
"error",
|
||||
"Embedding dimension mismatch. This usually happens when mixing different embedding models. Try resetting the collection using `crewai reset-memories -a`",
|
||||
"red",
|
||||
)
|
||||
raise ValueError(
|
||||
"Embedding dimension mismatch. Make sure you're using the same embedding model "
|
||||
"across all operations with this collection."
|
||||
"Try resetting the collection using `crewai reset-memories -a`"
|
||||
) from e
|
||||
except Exception as e:
|
||||
Logger(verbose=True).log("error", f"Failed to upsert documents: {e}", "red")
|
||||
raise
|
||||
|
||||
def _create_default_embedding_function(self):
|
||||
from chromadb.utils.embedding_functions.openai_embedding_function import (
|
||||
OpenAIEmbeddingFunction,
|
||||
|
||||
@@ -44,6 +44,7 @@ LLM_CONTEXT_WINDOW_SIZES = {
|
||||
"o1-preview": 128000,
|
||||
"o1-mini": 128000,
|
||||
# gemini
|
||||
"gemini-2.0-flash": 1048576,
|
||||
"gemini-1.5-pro": 2097152,
|
||||
"gemini-1.5-flash": 1048576,
|
||||
"gemini-1.5-flash-8b": 1048576,
|
||||
|
||||
@@ -6,6 +6,7 @@ import os
|
||||
import platform
|
||||
import warnings
|
||||
from contextlib import contextmanager
|
||||
from importlib.metadata import version
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
|
||||
@@ -16,10 +17,6 @@ def suppress_warnings():
|
||||
yield
|
||||
|
||||
|
||||
with suppress_warnings():
|
||||
import pkg_resources
|
||||
|
||||
|
||||
from opentelemetry import trace # noqa: E402
|
||||
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
|
||||
OTLPSpanExporter, # noqa: E402
|
||||
@@ -106,7 +103,7 @@ class Telemetry:
|
||||
self._add_attribute(
|
||||
span,
|
||||
"crewai_version",
|
||||
pkg_resources.get_distribution("crewai").version,
|
||||
version("crewai"),
|
||||
)
|
||||
self._add_attribute(span, "python_version", platform.python_version())
|
||||
self._add_attribute(span, "crew_key", crew.key)
|
||||
@@ -308,7 +305,7 @@ class Telemetry:
|
||||
self._add_attribute(
|
||||
span,
|
||||
"crewai_version",
|
||||
pkg_resources.get_distribution("crewai").version,
|
||||
version("crewai"),
|
||||
)
|
||||
self._add_attribute(span, "tool_name", tool_name)
|
||||
self._add_attribute(span, "attempts", attempts)
|
||||
@@ -328,7 +325,7 @@ class Telemetry:
|
||||
self._add_attribute(
|
||||
span,
|
||||
"crewai_version",
|
||||
pkg_resources.get_distribution("crewai").version,
|
||||
version("crewai"),
|
||||
)
|
||||
self._add_attribute(span, "tool_name", tool_name)
|
||||
self._add_attribute(span, "attempts", attempts)
|
||||
@@ -348,7 +345,7 @@ class Telemetry:
|
||||
self._add_attribute(
|
||||
span,
|
||||
"crewai_version",
|
||||
pkg_resources.get_distribution("crewai").version,
|
||||
version("crewai"),
|
||||
)
|
||||
if llm:
|
||||
self._add_attribute(span, "llm", llm.model)
|
||||
@@ -367,7 +364,7 @@ class Telemetry:
|
||||
self._add_attribute(
|
||||
span,
|
||||
"crewai_version",
|
||||
pkg_resources.get_distribution("crewai").version,
|
||||
version("crewai"),
|
||||
)
|
||||
self._add_attribute(span, "crew_key", crew.key)
|
||||
self._add_attribute(span, "crew_id", str(crew.id))
|
||||
@@ -393,7 +390,7 @@ class Telemetry:
|
||||
self._add_attribute(
|
||||
span,
|
||||
"crewai_version",
|
||||
pkg_resources.get_distribution("crewai").version,
|
||||
version("crewai"),
|
||||
)
|
||||
self._add_attribute(span, "crew_key", crew.key)
|
||||
self._add_attribute(span, "crew_id", str(crew.id))
|
||||
@@ -474,7 +471,7 @@ class Telemetry:
|
||||
self._add_attribute(
|
||||
span,
|
||||
"crewai_version",
|
||||
pkg_resources.get_distribution("crewai").version,
|
||||
version("crewai"),
|
||||
)
|
||||
self._add_attribute(span, "crew_key", crew.key)
|
||||
self._add_attribute(span, "crew_id", str(crew.id))
|
||||
@@ -543,7 +540,7 @@ class Telemetry:
|
||||
self._add_attribute(
|
||||
crew._execution_span,
|
||||
"crewai_version",
|
||||
pkg_resources.get_distribution("crewai").version,
|
||||
version("crewai"),
|
||||
)
|
||||
self._add_attribute(
|
||||
crew._execution_span, "crew_output", final_string_output
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import ast
|
||||
import datetime
|
||||
import os
|
||||
import time
|
||||
from difflib import SequenceMatcher
|
||||
from textwrap import dedent
|
||||
@@ -15,12 +14,10 @@ from crewai.tools.tool_calling import InstructorToolCalling, ToolCalling
|
||||
from crewai.tools.tool_usage_events import ToolUsageError, ToolUsageFinished
|
||||
from crewai.utilities import I18N, Converter, ConverterError, Printer
|
||||
|
||||
agentops = None
|
||||
if os.environ.get("AGENTOPS_API_KEY"):
|
||||
try:
|
||||
import agentops # type: ignore
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import agentops # type: ignore
|
||||
except ImportError:
|
||||
agentops = None
|
||||
|
||||
OPENAI_BIGGER_MODELS = ["gpt-4", "gpt-4o", "o1-preview", "o1-mini"]
|
||||
|
||||
@@ -422,9 +419,10 @@ class ToolUsage:
|
||||
elif value.lower() in [
|
||||
"true",
|
||||
"false",
|
||||
"null",
|
||||
]: # Check for boolean and null values
|
||||
value = value.lower()
|
||||
value = value.lower().capitalize()
|
||||
elif value.lower() == "null":
|
||||
value = "None"
|
||||
else:
|
||||
# Assume the value is a string and needs quotes
|
||||
value = '"' + value.replace('"', '\\"') + '"'
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"tools": "\nYou ONLY have access to the following tools, and should NEVER make up tools that are not listed here:\n\n{tools}\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, only one name of [{tool_names}], just the name, exactly as it's written.\nAction Input: the input to the action, just a simple python dictionary, enclosed in curly braces, using \" to wrap keys and values.\nObservation: the result of the action\n\nOnce all necessary information is gathered:\n\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n",
|
||||
"no_tools": "\nTo give my best complete final answer to the task use the exact following format:\n\nThought: I now can give a great answer\nFinal Answer: Your final answer must be the great and the most complete as possible, it must be outcome described.\n\nI MUST use these formats, my job depends on it!",
|
||||
"format": "I MUST either use a tool (use one at time) OR give my best final answer not both at the same time. To Use the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action, dictionary enclosed in curly braces\nObservation: the result of the action\n... (this Thought/Action/Action Input/Result can repeat N times)\nThought: I now can give a great answer\nFinal Answer: Your final answer must be the great and the most complete as possible, it must be outcome described\n\n",
|
||||
"final_answer_format": "If you don't need to use any more tools, you must give your best complete final answer, make sure it satisfy the expect criteria, use the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer: my best complete final answer to the task.\n\n",
|
||||
"final_answer_format": "If you don't need to use any more tools, you must give your best complete final answer, make sure it satisfies the expected criteria, use the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer: my best complete final answer to the task.\n\n",
|
||||
"format_without_tools": "\nSorry, I didn't use the right format. I MUST either use a tool (among the available ones), OR give my best final answer.\nI just remembered the expected format I must follow:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Result can repeat N times)\nThought: I now can give a great answer\nFinal Answer: Your final answer must be the great and the most complete as possible, it must be outcome described\n\n",
|
||||
"task_with_context": "{task}\n\nThis is the context you're working with:\n{context}",
|
||||
"expected_output": "\nThis is the expect criteria for your final answer: {expected_output}\nyou MUST return the actual complete content as the final answer, not a summary.",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from enum import Enum
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel
|
||||
@@ -10,7 +11,7 @@ class CrewJSONEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if isinstance(obj, BaseModel):
|
||||
return self._handle_pydantic_model(obj)
|
||||
elif isinstance(obj, UUID) or isinstance(obj, Decimal):
|
||||
elif isinstance(obj, UUID) or isinstance(obj, Decimal) or isinstance(obj, Enum):
|
||||
return str(obj)
|
||||
|
||||
elif isinstance(obj, datetime) or isinstance(obj, date):
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -6,27 +5,17 @@ from pydantic import BaseModel, Field
|
||||
from crewai.utilities import Converter
|
||||
from crewai.utilities.pydantic_schema_parser import PydanticSchemaParser
|
||||
|
||||
agentops = None
|
||||
try:
|
||||
from agentops import track_agent # type: ignore
|
||||
except ImportError:
|
||||
|
||||
def mock_agent_ops_provider():
|
||||
def track_agent(*args, **kwargs):
|
||||
def track_agent(name):
|
||||
def noop(f):
|
||||
return f
|
||||
|
||||
return noop
|
||||
|
||||
return track_agent
|
||||
|
||||
|
||||
agentops = None
|
||||
|
||||
if os.environ.get("AGENTOPS_API_KEY"):
|
||||
try:
|
||||
from agentops import track_agent
|
||||
except ImportError:
|
||||
track_agent = mock_agent_ops_provider()
|
||||
else:
|
||||
track_agent = mock_agent_ops_provider()
|
||||
|
||||
|
||||
class Entity(BaseModel):
|
||||
name: str = Field(description="The name of the entity.")
|
||||
|
||||
@@ -1595,19 +1595,15 @@ def test_agent_execute_task_with_ollama():
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_agent_with_knowledge_sources():
|
||||
# Create a knowledge source with some content
|
||||
content = "Brandon's favorite color is blue and he likes Mexican food."
|
||||
string_source = StringKnowledgeSource(
|
||||
content=content, metadata={"preference": "personal"}
|
||||
)
|
||||
content = "Brandon's favorite color is red and he likes Mexican food."
|
||||
string_source = StringKnowledgeSource(content=content)
|
||||
|
||||
with patch(
|
||||
"crewai.knowledge.storage.knowledge_storage.KnowledgeStorage"
|
||||
) as MockKnowledge:
|
||||
mock_knowledge_instance = MockKnowledge.return_value
|
||||
mock_knowledge_instance.sources = [string_source]
|
||||
mock_knowledge_instance.query.return_value = [
|
||||
{"content": content, "metadata": {"preference": "personal"}}
|
||||
]
|
||||
mock_knowledge_instance.query.return_value = [{"content": content}]
|
||||
|
||||
agent = Agent(
|
||||
role="Information Agent",
|
||||
@@ -1628,4 +1624,4 @@ def test_agent_with_knowledge_sources():
|
||||
result = crew.kickoff()
|
||||
|
||||
# Assert that the agent provides the correct information
|
||||
assert "blue" in result.raw.lower()
|
||||
assert "red" in result.raw.lower()
|
||||
|
||||
@@ -26237,7 +26237,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}], "model": "gpt-4o"}'
|
||||
headers:
|
||||
@@ -26590,7 +26590,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -26941,7 +26941,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -27292,7 +27292,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -27647,7 +27647,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -28005,7 +28005,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -28364,7 +28364,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -28718,7 +28718,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -29082,7 +29082,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -29441,7 +29441,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -29802,7 +29802,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -30170,7 +30170,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -30533,7 +30533,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -30907,7 +30907,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -31273,7 +31273,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -31644,7 +31644,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
@@ -32015,7 +32015,7 @@ interactions:
|
||||
answer."}, {"role": "user", "content": "I did it wrong. Invalid Format: I missed
|
||||
the ''Action:'' after ''Thought:''. I will do right next, and don''t use a tool
|
||||
I have already used.\n\nIf you don''t need to use any more tools, you must give
|
||||
your best complete final answer, make sure it satisfy the expect criteria, use
|
||||
your best complete final answer, make sure it satisfies the expected criteria, use
|
||||
the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer:
|
||||
my best complete final answer to the task.\n\n"}, {"role": "user", "content":
|
||||
"I did it wrong. Tried to both perform Action and give a Final Answer at the
|
||||
|
||||
@@ -247,7 +247,7 @@ interactions:
|
||||
{"role": "user", "content": "I did it wrong. Invalid Format: I missed the ''Action:''
|
||||
after ''Thought:''. I will do right next, and don''t use a tool I have already
|
||||
used.\n\nIf you don''t need to use any more tools, you must give your best complete
|
||||
final answer, make sure it satisfy the expect criteria, use the EXACT format
|
||||
final answer, make sure it satisfies the expected criteria, use the EXACT format
|
||||
below:\n\nThought: I now can give a great answer\nFinal Answer: my best complete
|
||||
final answer to the task.\n\n"}], "model": "o1-preview"}'
|
||||
headers:
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -231,7 +231,7 @@ class TestDeployCommand(unittest.TestCase):
|
||||
[project]
|
||||
name = "test_project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.10,<=3.12"
|
||||
requires-python = ">=3.10,<3.13"
|
||||
dependencies = ["crewai"]
|
||||
""",
|
||||
)
|
||||
@@ -250,7 +250,7 @@ class TestDeployCommand(unittest.TestCase):
|
||||
[project]
|
||||
name = "test_project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.10,<=3.12"
|
||||
requires-python = ">=3.10,<3.13"
|
||||
dependencies = ["crewai"]
|
||||
""",
|
||||
)
|
||||
|
||||
@@ -686,7 +686,7 @@ def test_increment_tool_errors():
|
||||
with patch.object(Task, "increment_tools_errors") as increment_tools_errors:
|
||||
increment_tools_errors.return_value = None
|
||||
crew.kickoff()
|
||||
assert len(increment_tools_errors.mock_calls) == 12
|
||||
assert len(increment_tools_errors.mock_calls) > 0
|
||||
|
||||
|
||||
def test_task_definition_based_on_dict():
|
||||
|
||||
@@ -6,14 +6,14 @@ from crewai.tools import BaseTool, tool
|
||||
def test_creating_a_tool_using_annotation():
|
||||
@tool("Name of my tool")
|
||||
def my_tool(question: str) -> str:
|
||||
"""Clear description for what this tool is useful for, you agent will need this information to use it."""
|
||||
"""Clear description for what this tool is useful for, your agent will need this information to use it."""
|
||||
return question
|
||||
|
||||
# Assert all the right attributes were defined
|
||||
assert my_tool.name == "Name of my tool"
|
||||
assert (
|
||||
my_tool.description
|
||||
== "Tool Name: Name of my tool\nTool Arguments: {'question': {'description': None, 'type': 'str'}}\nTool Description: Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
== "Tool Name: Name of my tool\nTool Arguments: {'question': {'description': None, 'type': 'str'}}\nTool Description: Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
)
|
||||
assert my_tool.args_schema.schema()["properties"] == {
|
||||
"question": {"title": "Question", "type": "string"}
|
||||
@@ -27,7 +27,7 @@ def test_creating_a_tool_using_annotation():
|
||||
|
||||
assert (
|
||||
converted_tool.description
|
||||
== "Tool Name: Name of my tool\nTool Arguments: {'question': {'description': None, 'type': 'str'}}\nTool Description: Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
== "Tool Name: Name of my tool\nTool Arguments: {'question': {'description': None, 'type': 'str'}}\nTool Description: Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
)
|
||||
assert converted_tool.args_schema.schema()["properties"] == {
|
||||
"question": {"title": "Question", "type": "string"}
|
||||
@@ -41,7 +41,7 @@ def test_creating_a_tool_using_annotation():
|
||||
def test_creating_a_tool_using_baseclass():
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = "Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
description: str = "Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
|
||||
def _run(self, question: str) -> str:
|
||||
return question
|
||||
@@ -52,7 +52,7 @@ def test_creating_a_tool_using_baseclass():
|
||||
|
||||
assert (
|
||||
my_tool.description
|
||||
== "Tool Name: Name of my tool\nTool Arguments: {'question': {'description': None, 'type': 'str'}}\nTool Description: Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
== "Tool Name: Name of my tool\nTool Arguments: {'question': {'description': None, 'type': 'str'}}\nTool Description: Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
)
|
||||
assert my_tool.args_schema.schema()["properties"] == {
|
||||
"question": {"title": "Question", "type": "string"}
|
||||
@@ -64,7 +64,7 @@ def test_creating_a_tool_using_baseclass():
|
||||
|
||||
assert (
|
||||
converted_tool.description
|
||||
== "Tool Name: Name of my tool\nTool Arguments: {'question': {'description': None, 'type': 'str'}}\nTool Description: Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
== "Tool Name: Name of my tool\nTool Arguments: {'question': {'description': None, 'type': 'str'}}\nTool Description: Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
)
|
||||
assert converted_tool.args_schema.schema()["properties"] == {
|
||||
"question": {"title": "Question", "type": "string"}
|
||||
@@ -78,7 +78,7 @@ def test_creating_a_tool_using_baseclass():
|
||||
def test_setting_cache_function():
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = "Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
description: str = "Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
cache_function: Callable = lambda: False
|
||||
|
||||
def _run(self, question: str) -> str:
|
||||
@@ -92,7 +92,7 @@ def test_setting_cache_function():
|
||||
def test_default_cache_function_is_true():
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = "Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
description: str = "Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
|
||||
def _run(self, question: str) -> str:
|
||||
return question
|
||||
|
||||
17
uv.lock
generated
17
uv.lock
generated
@@ -1,9 +1,10 @@
|
||||
version = 1
|
||||
requires-python = ">=3.10, <=3.12"
|
||||
requires-python = ">=3.10, <3.13"
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.11'",
|
||||
"python_full_version == '3.11.*'",
|
||||
"python_full_version >= '3.12'",
|
||||
"python_full_version >= '3.12' and python_full_version < '3.12.4'",
|
||||
"python_full_version >= '3.12.4'",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -479,7 +480,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "chromadb"
|
||||
version = "0.5.18"
|
||||
version = "0.5.23"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "bcrypt" },
|
||||
@@ -511,9 +512,9 @@ dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
{ name = "uvicorn", extra = ["standard"] },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/15/95/d1a3f14c864e37d009606b82bd837090902b5e5a8e892fcab07eeaec0438/chromadb-0.5.18.tar.gz", hash = "sha256:cfbb3e5aeeb1dd532b47d80ed9185e8a9886c09af41c8e6123edf94395d76aec", size = 33620708 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/42/64/28daa773f784bcd18de944fe26ed301de844d6ee17188e26a9d6b4baf122/chromadb-0.5.23.tar.gz", hash = "sha256:360a12b9795c5a33cb1f839d14410ccbde662ef1accd36153b0ae22312edabd1", size = 33700455 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/82/85/4d2f8b9202153105ad4514ae09e9fe6f3b353a45e44e0ef7eca03dd8b9dc/chromadb-0.5.18-py3-none-any.whl", hash = "sha256:9dd3827b5e04b4ff0a5ea0df28a78bac88a09f45be37fcd7fe20f879b57c43cf", size = 615499 },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/8c/a9eb95a28e6c35a0122417976a9d435eeaceb53f596a8973e33b3dd4cfac/chromadb-0.5.23-py3-none-any.whl", hash = "sha256:ffe5bdd7276d12cb682df0d38a13aa37573e6a3678e71889ac45f539ae05ad7e", size = 628347 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -648,9 +649,9 @@ requires-dist = [
|
||||
{ name = "appdirs", specifier = ">=1.4.4" },
|
||||
{ name = "auth0-python", specifier = ">=4.7.1" },
|
||||
{ name = "blinker", specifier = ">=1.9.0" },
|
||||
{ name = "chromadb", specifier = ">=0.5.18" },
|
||||
{ name = "chromadb", specifier = ">=0.5.23" },
|
||||
{ name = "click", specifier = ">=8.1.7" },
|
||||
{ name = "crewai-tools", marker = "extra == 'tools'", specifier = ">=0.14.0" },
|
||||
{ name = "crewai-tools", marker = "extra == 'tools'", specifier = ">=0.17.0" },
|
||||
{ name = "fastembed", marker = "extra == 'fastembed'", specifier = ">=0.4.1" },
|
||||
{ name = "instructor", specifier = ">=1.3.3" },
|
||||
{ name = "json-repair", specifier = ">=0.25.2" },
|
||||
@@ -678,7 +679,7 @@ requires-dist = [
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "cairosvg", specifier = ">=2.7.1" },
|
||||
{ name = "crewai-tools", specifier = ">=0.14.0" },
|
||||
{ name = "crewai-tools", specifier = ">=0.17.0" },
|
||||
{ name = "mkdocs", specifier = ">=1.4.3" },
|
||||
{ name = "mkdocs-material", specifier = ">=9.5.7" },
|
||||
{ name = "mkdocs-material-extensions", specifier = ">=1.3.1" },
|
||||
|
||||
Reference in New Issue
Block a user