From 9b59de17209e325b0ba82dbf7e266ae19a012287 Mon Sep 17 00:00:00 2001 From: Rip&Tear <84775494+theCyberTech@users.noreply.github.com> Date: Thu, 17 Oct 2024 22:05:07 +0800 Subject: [PATCH 01/19] feat/updated CLI to allow for model selection & submitting API keys (#1430) * updated CLI to allow for submitting API keys * updated click prompt to remove default number * removed all unnecessary comments * feat: implement crew creation CLI command - refactor code to multiple functions - Added ability for users to select provider and model when uing crewai create command and ave API key to .env * refactered select_choice function for early return * refactored select_provider to have an ealry return * cleanup of comments * refactor/Move functions into utils file, added new provider file and migrated fucntions thre, new constants file + general function refactor * small comment cleanup * fix unnecessary deps --------- Co-authored-by: Brandon Hancock (bhancock_ai) <109994880+bhancockio@users.noreply.github.com> Co-authored-by: Brandon Hancock --- src/crewai/cli/constants.py | 19 ++++ src/crewai/cli/create_crew.py | 84 +++++++++++++-- src/crewai/cli/provider.py | 186 ++++++++++++++++++++++++++++++++++ src/crewai/cli/utils.py | 74 ++++++++++++++ 4 files changed, 352 insertions(+), 11 deletions(-) create mode 100644 src/crewai/cli/constants.py create mode 100644 src/crewai/cli/provider.py diff --git a/src/crewai/cli/constants.py b/src/crewai/cli/constants.py new file mode 100644 index 000000000..9a0b36c39 --- /dev/null +++ b/src/crewai/cli/constants.py @@ -0,0 +1,19 @@ +ENV_VARS = { + 'openai': ['OPENAI_API_KEY'], + 'anthropic': ['ANTHROPIC_API_KEY'], + 'gemini': ['GEMINI_API_KEY'], + 'groq': ['GROQ_API_KEY'], + 'ollama': ['FAKE_KEY'], +} + +PROVIDERS = ['openai', 'anthropic', 'gemini', 'groq', 'ollama'] + +MODELS = { + 'openai': ['gpt-4', 'gpt-4o', 'gpt-4o-mini', 'o1-mini', 'o1-preview'], + 'anthropic': ['claude-3-5-sonnet-20240620', 'claude-3-sonnet-20240229', 'claude-3-opus-20240229', 'claude-3-haiku-20240307'], + 'gemini': ['gemini-1.5-flash', 'gemini-1.5-pro', 'gemini-gemma-2-9b-it', 'gemini-gemma-2-27b-it'], + 'groq': ['llama-3.1-8b-instant', 'llama-3.1-70b-versatile', 'llama-3.1-405b-reasoning', 'gemma2-9b-it', 'gemma-7b-it'], + 'ollama': ['llama3.1', 'mixtral'], +} + +JSON_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json" \ No newline at end of file diff --git a/src/crewai/cli/create_crew.py b/src/crewai/cli/create_crew.py index 510d4f431..23088cb58 100644 --- a/src/crewai/cli/create_crew.py +++ b/src/crewai/cli/create_crew.py @@ -1,12 +1,10 @@ from pathlib import Path - import click +from crewai.cli.utils import copy_template,load_env_vars, write_env_file +from crewai.cli.provider import get_provider_data, select_provider, select_model, PROVIDERS +from crewai.cli.constants import ENV_VARS -from crewai.cli.utils import copy_template - - -def create_crew(name, parent_folder=None): - """Create a new crew.""" +def create_folder_structure(name, parent_folder=None): folder_name = name.replace(" ", "_").replace("-", "_").lower() class_name = name.replace("_", " ").replace("-", " ").title().replace(" ", "") @@ -28,19 +26,83 @@ def create_crew(name, parent_folder=None): (folder_path / "src" / folder_name).mkdir(parents=True) (folder_path / "src" / folder_name / "tools").mkdir(parents=True) (folder_path / "src" / folder_name / "config").mkdir(parents=True) - with open(folder_path / ".env", "w") as file: - file.write("OPENAI_API_KEY=YOUR_API_KEY") else: click.secho( - f"\tFolder {folder_name} already exists. Please choose a different name.", - fg="red", + f"\tFolder {folder_name} already exists.", + fg="yellow", ) + + return folder_path, folder_name, class_name + + + +def copy_template_files(folder_path, name, class_name, parent_folder): + package_dir = Path(__file__).parent + templates_dir = package_dir / "templates" / "crew" + + root_template_files = ( + [".gitignore", "pyproject.toml", "README.md"] if not parent_folder else [] + ) + tools_template_files = ["tools/custom_tool.py", "tools/__init__.py"] + config_template_files = ["config/agents.yaml", "config/tasks.yaml"] + src_template_files = ( + ["__init__.py", "main.py", "crew.py"] if not parent_folder else ["crew.py"] + ) + + for file_name in root_template_files: + src_file = templates_dir / file_name + dst_file = folder_path / file_name + copy_template(src_file, dst_file, name, class_name, folder_path.name) + + src_folder = folder_path / "src" / folder_path.name if not parent_folder else folder_path + + for file_name in src_template_files: + src_file = templates_dir / file_name + dst_file = src_folder / file_name + copy_template(src_file, dst_file, name, class_name, folder_path.name) + + if not parent_folder: + for file_name in tools_template_files + config_template_files: + src_file = templates_dir / file_name + dst_file = src_folder / file_name + copy_template(src_file, dst_file, name, class_name, folder_path.name) + + +def create_crew(name, parent_folder=None): + folder_path, folder_name, class_name = create_folder_structure(name, parent_folder) + env_vars = load_env_vars(folder_path) + + provider_models = get_provider_data() + if not provider_models: return + selected_provider = select_provider(provider_models) + if not selected_provider: + return + provider = selected_provider + + selected_model = select_model(provider, provider_models) + if not selected_model: + return + model = selected_model + + if provider in PROVIDERS: + api_key_var = ENV_VARS[provider][0] + else: + api_key_var = click.prompt( + f"Enter the environment variable name for your {provider.capitalize()} API key", + type=str + ) + + env_vars = {api_key_var: "YOUR_API_KEY_HERE"} + write_env_file(folder_path, env_vars) + + env_vars['MODEL'] = model + click.secho(f"Selected model: {model}", fg="green") + package_dir = Path(__file__).parent templates_dir = package_dir / "templates" / "crew" - # List of template files to copy root_template_files = ( [".gitignore", "pyproject.toml", "README.md"] if not parent_folder else [] ) diff --git a/src/crewai/cli/provider.py b/src/crewai/cli/provider.py new file mode 100644 index 000000000..f829ca9fd --- /dev/null +++ b/src/crewai/cli/provider.py @@ -0,0 +1,186 @@ +import json +import time +import requests +from collections import defaultdict +import click +from pathlib import Path +from crewai.cli.constants import PROVIDERS, MODELS, JSON_URL + +def select_choice(prompt_message, choices): + """ + Presents a list of choices to the user and prompts them to select one. + + Args: + - prompt_message (str): The message to display to the user before presenting the choices. + - choices (list): A list of options to present to the user. + + Returns: + - str: The selected choice from the list, or None if the operation is aborted or an invalid selection is made. + """ + click.secho(prompt_message, fg="cyan") + for idx, choice in enumerate(choices, start=1): + click.secho(f"{idx}. {choice}", fg="cyan") + try: + selected_index = click.prompt("Enter the number of your choice", type=int) - 1 + except click.exceptions.Abort: + click.secho("Operation aborted by the user.", fg="red") + return None + if not (0 <= selected_index < len(choices)): + click.secho("Invalid selection.", fg="red") + return None + return choices[selected_index] + +def select_provider(provider_models): + """ + Presents a list of providers to the user and prompts them to select one. + + Args: + - provider_models (dict): A dictionary of provider models. + + Returns: + - str: The selected provider, or None if the operation is aborted or an invalid selection is made. + """ + predefined_providers = [p.lower() for p in PROVIDERS] + all_providers = sorted(set(predefined_providers + list(provider_models.keys()))) + + provider = select_choice("Select a provider to set up:", predefined_providers + ['other']) + if not provider: + return None + provider = provider.lower() + + if provider == 'other': + provider = select_choice("Select a provider from the full list:", all_providers) + if not provider: + return None + return provider + +def select_model(provider, provider_models): + """ + Presents a list of models for a given provider to the user and prompts them to select one. + + Args: + - provider (str): The provider for which to select a model. + - provider_models (dict): A dictionary of provider models. + + Returns: + - str: The selected model, or None if the operation is aborted or an invalid selection is made. + """ + predefined_providers = [p.lower() for p in PROVIDERS] + + if provider in predefined_providers: + available_models = MODELS.get(provider, []) + else: + available_models = provider_models.get(provider, []) + + if not available_models: + click.secho(f"No models available for provider '{provider}'.", fg="red") + return None + + selected_model = select_choice(f"Select a model to use for {provider.capitalize()}:", available_models) + return selected_model + +def load_provider_data(cache_file, cache_expiry): + """ + Loads provider data from a cache file if it exists and is not expired. If the cache is expired or corrupted, it fetches the data from the web. + + Args: + - cache_file (Path): The path to the cache file. + - cache_expiry (int): The cache expiry time in seconds. + + Returns: + - dict or None: The loaded provider data or None if the operation fails. + """ + current_time = time.time() + if cache_file.exists() and (current_time - cache_file.stat().st_mtime) < cache_expiry: + data = read_cache_file(cache_file) + if data: + return data + click.secho("Cache is corrupted. Fetching provider data from the web...", fg="yellow") + else: + click.secho("Cache expired or not found. Fetching provider data from the web...", fg="cyan") + return fetch_provider_data(cache_file) + +def read_cache_file(cache_file): + """ + Reads and returns the JSON content from a cache file. Returns None if the file contains invalid JSON. + + Args: + - cache_file (Path): The path to the cache file. + + Returns: + - dict or None: The JSON content of the cache file or None if the JSON is invalid. + """ + try: + with open(cache_file, "r") as f: + return json.load(f) + except json.JSONDecodeError: + return None + +def fetch_provider_data(cache_file): + """ + Fetches provider data from a specified URL and caches it to a file. + + Args: + - cache_file (Path): The path to the cache file. + + Returns: + - dict or None: The fetched provider data or None if the operation fails. + """ + try: + response = requests.get(JSON_URL, stream=True, timeout=10) + response.raise_for_status() + data = download_data(response) + with open(cache_file, "w") as f: + json.dump(data, f) + return data + except requests.RequestException as e: + click.secho(f"Error fetching provider data: {e}", fg="red") + except json.JSONDecodeError: + click.secho("Error parsing provider data. Invalid JSON format.", fg="red") + return None + +def download_data(response): + """ + Downloads data from a given HTTP response and returns the JSON content. + + Args: + - response (requests.Response): The HTTP response object. + + Returns: + - dict: The JSON content of the response. + """ + total_size = int(response.headers.get('content-length', 0)) + block_size = 8192 + data_chunks = [] + with click.progressbar(length=total_size, label='Downloading', show_pos=True) as progress_bar: + for chunk in response.iter_content(block_size): + if chunk: + data_chunks.append(chunk) + progress_bar.update(len(chunk)) + data_content = b''.join(data_chunks) + return json.loads(data_content.decode('utf-8')) + +def get_provider_data(): + """ + Retrieves provider data from a cache file, filters out models based on provider criteria, and returns a dictionary of providers mapped to their models. + + Returns: + - dict or None: A dictionary of providers mapped to their models or None if the operation fails. + """ + cache_dir = Path.home() / '.crewai' + cache_dir.mkdir(exist_ok=True) + cache_file = cache_dir / 'provider_cache.json' + cache_expiry = 24 * 3600 + + data = load_provider_data(cache_file, cache_expiry) + if not data: + return None + + provider_models = defaultdict(list) + for model_name, properties in data.items(): + provider = properties.get("litellm_provider", "").strip().lower() + if 'http' in provider or provider == 'other': + continue + if provider: + provider_models[provider].append(model_name) + return provider_models \ No newline at end of file diff --git a/src/crewai/cli/utils.py b/src/crewai/cli/utils.py index d8c048df8..c32113faa 100644 --- a/src/crewai/cli/utils.py +++ b/src/crewai/cli/utils.py @@ -9,6 +9,7 @@ import click from rich.console import Console from crewai.cli.authentication.utils import TokenManager +from crewai.cli.constants import ENV_VARS if sys.version_info >= (3, 11): import tomllib @@ -200,3 +201,76 @@ def tree_find_and_replace(directory, find, replace): new_dirpath = os.path.join(path, new_dirname) old_dirpath = os.path.join(path, dirname) os.rename(old_dirpath, new_dirpath) + + +def load_env_vars(folder_path): + """ + Loads environment variables from a .env file in the specified folder path. + + Args: + - folder_path (Path): The path to the folder containing the .env file. + + Returns: + - dict: A dictionary of environment variables. + """ + env_file_path = folder_path / ".env" + env_vars = {} + if env_file_path.exists(): + with open(env_file_path, "r") as file: + for line in file: + key, _, value = line.strip().partition("=") + if key and value: + env_vars[key] = value + return env_vars + + +def update_env_vars(env_vars, provider, model): + """ + Updates environment variables with the API key for the selected provider and model. + + Args: + - env_vars (dict): Environment variables dictionary. + - provider (str): Selected provider. + - model (str): Selected model. + + Returns: + - None + """ + api_key_var = ENV_VARS.get( + provider, + [ + click.prompt( + f"Enter the environment variable name for your {provider.capitalize()} API key", + type=str, + ) + ], + )[0] + + if api_key_var not in env_vars: + try: + env_vars[api_key_var] = click.prompt( + f"Enter your {provider.capitalize()} API key", type=str, hide_input=True + ) + except click.exceptions.Abort: + click.secho("Operation aborted by the user.", fg="red") + return None + else: + click.secho(f"API key already exists for {provider.capitalize()}.", fg="yellow") + + env_vars["MODEL"] = model + click.secho(f"Selected model: {model}", fg="green") + return env_vars + + +def write_env_file(folder_path, env_vars): + """ + Writes environment variables to a .env file in the specified folder. + + Args: + - folder_path (Path): The path to the folder where the .env file will be written. + - env_vars (dict): A dictionary of environment variables to write. + """ + env_file_path = folder_path / ".env" + with open(env_file_path, "w") as file: + for key, value in env_vars.items(): + file.write(f"{key}={value}\n") From 67f55bae2c68bdc2f904349bf67ef3c7128f7405 Mon Sep 17 00:00:00 2001 From: Rok Benko <115651717+rokbenko@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:18:31 +0200 Subject: [PATCH 02/19] Fix incorrect parameter name in Vision tool docs page (#1461) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: João Moura --- docs/tools/visiontool.mdx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/tools/visiontool.mdx b/docs/tools/visiontool.mdx index 83856e34b..f4eab0f1c 100644 --- a/docs/tools/visiontool.mdx +++ b/docs/tools/visiontool.mdx @@ -8,13 +8,13 @@ icon: eye ## Description -This tool is used to extract text from images. When passed to the agent it will extract the text from the image and then use it to generate a response, report or any other output. +This tool is used to extract text from images. When passed to the agent it will extract the text from the image and then use it to generate a response, report or any other output. The URL or the PATH of the image should be passed to the Agent. - ## Installation Install the crewai_tools package + ```shell pip install 'crewai[tools]' ``` @@ -44,7 +44,6 @@ def researcher(self) -> Agent: The VisionTool requires the following arguments: -| Argument | Type | Description | -|:---------------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------| -| **image_path** | `string` | **Mandatory**. The path to the image file from which text needs to be extracted. | - +| Argument | Type | Description | +| :----------------- | :------- | :------------------------------------------------------------------------------- | +| **image_path_url** | `string` | **Mandatory**. The path to the image file from which text needs to be extracted. | From 6d20ba70a170537188e3ae5cbcf35effa52cb14d Mon Sep 17 00:00:00 2001 From: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:19:33 -0700 Subject: [PATCH 03/19] Feat/memory base (#1444) * byom - short/entity memory * better * rm uneeded * fix text * use context * rm dep and sync * type check fix * fixed test using new cassete * fixing types * fixed types * fix types * fixed types * fixing types * fix type * cassette update * just mock the return of short term mem * remove print * try catch block * added docs * dding error handling here --- docs/concepts/memory.mdx | 77 ++---- pyproject.toml | 3 +- .../base_agent_executor_mixin.py | 18 +- src/crewai/agents/crew_agent_executor.py | 14 +- src/crewai/crew.py | 16 +- .../memory/contextual/contextual_memory.py | 4 +- .../memory/long_term/long_term_memory.py | 4 +- src/crewai/memory/memory.py | 8 +- src/crewai/memory/storage/base_rag_storage.py | 76 ++++++ src/crewai/memory/storage/interface.py | 4 +- src/crewai/memory/storage/rag_storage.py | 124 +++++----- .../cassettes/test_save_and_search.yaml | 189 --------------- tests/memory/short_term_memory_test.py | 35 ++- uv.lock | 227 +----------------- 14 files changed, 241 insertions(+), 558 deletions(-) create mode 100644 src/crewai/memory/storage/base_rag_storage.py delete mode 100644 tests/memory/cassettes/test_save_and_search.yaml diff --git a/docs/concepts/memory.mdx b/docs/concepts/memory.mdx index d3f9b955a..b07096442 100644 --- a/docs/concepts/memory.mdx +++ b/docs/concepts/memory.mdx @@ -34,7 +34,7 @@ By default, the memory system is disabled, and you can ensure it is active by se The memory will use OpenAI embeddings by default, but you can change it by setting `embedder` to a different model. It's also possible to initialize the memory instance with your own instance. -The 'embedder' only applies to **Short-Term Memory** which uses Chroma for RAG using the EmbedChain package. +The 'embedder' only applies to **Short-Term Memory** which uses Chroma for RAG. The **Long-Term Memory** uses SQLite3 to store task results. Currently, there is no way to override these storage implementations. The data storage files are saved into a platform-specific location found using the appdirs package, and the name of the project can be overridden using the **CREWAI_STORAGE_DIR** environment variable. @@ -105,12 +105,9 @@ my_crew = Crew( process=Process.sequential, memory=True, verbose=True, - embedder={ - "provider": "openai", - "config": { - "model": 'text-embedding-3-small' - } - } + embedder=embedding_functions.OpenAIEmbeddingFunction( + api_key=os.getenv("OPENAI_API_KEY"), model_name="text-embedding-3-small" + ) ) ``` @@ -125,14 +122,10 @@ my_crew = Crew( process=Process.sequential, memory=True, verbose=True, - embedder={ - "provider": "google", - "config": { - "model": 'models/embedding-001', - "task_type": "retrieval_document", - "title": "Embeddings for Embedchain" - } - } + embedder=embedding_functions.OpenAIEmbeddingFunction( + api_key=os.getenv("OPENAI_API_KEY"), + model_name="text-embedding-ada-002" + ) ) ``` @@ -147,30 +140,13 @@ my_crew = Crew( process=Process.sequential, memory=True, verbose=True, - embedder={ - "provider": "azure_openai", - "config": { - "model": 'text-embedding-ada-002', - "deployment_name": "your_embedding_model_deployment_name" - } - } -) -``` - -### Using GPT4ALL embeddings - -```python Code -from crewai import Crew, Agent, Task, Process - -my_crew = Crew( - agents=[...], - tasks=[...], - process=Process.sequential, - memory=True, - verbose=True, - embedder={ - "provider": "gpt4all" - } + embedder=embedding_functions.OpenAIEmbeddingFunction( + api_key="YOUR_API_KEY", + api_base="YOUR_API_BASE_PATH", + api_type="azure", + api_version="YOUR_API_VERSION", + model_name="text-embedding-3-small" + ) ) ``` @@ -185,12 +161,12 @@ my_crew = Crew( process=Process.sequential, memory=True, verbose=True, - embedder={ - "provider": "vertexai", - "config": { - "model": 'textembedding-gecko' - } - } + embedder=embedding_functions.GoogleVertexEmbeddingFunction( + project_id="YOUR_PROJECT_ID", + region="YOUR_REGION", + api_key="YOUR_API_KEY", + model_name="textembedding-gecko" + ) ) ``` @@ -205,13 +181,10 @@ my_crew = Crew( process=Process.sequential, memory=True, verbose=True, - embedder={ - "provider": "cohere", - "config": { - "model": "embed-english-v3.0", - "vector_dimension": 1024 - } - } + embedder=embedding_functions.CohereEmbeddingFunction( + api_key=YOUR_API_KEY, + model_name="" + ) ) ``` diff --git a/pyproject.toml b/pyproject.toml index 2dbcdedc9..c547249a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,14 +21,13 @@ dependencies = [ "python-dotenv>=1.0.0", "appdirs>=1.4.4", "jsonref>=1.1.0", - "agentops>=0.3.0", - "embedchain>=0.1.114", "json-repair>=0.25.2", "auth0-python>=4.7.1", "litellm>=1.44.22", "pyvis>=0.3.2", "uv>=0.4.18", "tomli-w>=1.1.0", + "chromadb>=0.4.24", ] [project.urls] diff --git a/src/crewai/agents/agent_builder/base_agent_executor_mixin.py b/src/crewai/agents/agent_builder/base_agent_executor_mixin.py index bf2e2841b..c452848e8 100644 --- a/src/crewai/agents/agent_builder/base_agent_executor_mixin.py +++ b/src/crewai/agents/agent_builder/base_agent_executor_mixin.py @@ -17,7 +17,7 @@ if TYPE_CHECKING: class CrewAgentExecutorMixin: crew: Optional["Crew"] - crew_agent: Optional["BaseAgent"] + agent: Optional["BaseAgent"] task: Optional["Task"] iterations: int have_forced_answer: bool @@ -33,9 +33,9 @@ class CrewAgentExecutorMixin: """Create and save a short-term memory item if conditions are met.""" if ( self.crew - and self.crew_agent + and self.agent and self.task - and "Action: Delegate work to coworker" not in output.log + and "Action: Delegate work to coworker" not in output.text ): try: if ( @@ -43,11 +43,11 @@ class CrewAgentExecutorMixin: and self.crew._short_term_memory ): self.crew._short_term_memory.save( - value=output.log, + value=output.text, metadata={ "observation": self.task.description, }, - agent=self.crew_agent.role, + agent=self.agent.role, ) except Exception as e: print(f"Failed to add to short term memory: {e}") @@ -61,18 +61,18 @@ class CrewAgentExecutorMixin: and self.crew._long_term_memory and self.crew._entity_memory and self.task - and self.crew_agent + and self.agent ): try: - ltm_agent = TaskEvaluator(self.crew_agent) - evaluation = ltm_agent.evaluate(self.task, output.log) + ltm_agent = TaskEvaluator(self.agent) + evaluation = ltm_agent.evaluate(self.task, output.text) if isinstance(evaluation, ConverterError): return long_term_memory = LongTermMemoryItem( task=self.task.description, - agent=self.crew_agent.role, + agent=self.agent.role, quality=evaluation.quality, datetime=str(time.time()), expected_output=self.task.expected_output, diff --git a/src/crewai/agents/crew_agent_executor.py b/src/crewai/agents/crew_agent_executor.py index 0c510ef71..b901fe132 100644 --- a/src/crewai/agents/crew_agent_executor.py +++ b/src/crewai/agents/crew_agent_executor.py @@ -19,6 +19,7 @@ from crewai.utilities.exceptions.context_window_exceeding_exception import ( ) from crewai.utilities.logger import Logger from crewai.utilities.training_handler import CrewTrainingHandler +from crewai.agents.agent_builder.base_agent import BaseAgent class CrewAgentExecutor(CrewAgentExecutorMixin): @@ -29,7 +30,7 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): llm: Any, task: Any, crew: Any, - agent: Any, + agent: BaseAgent, prompt: dict[str, str], max_iter: int, tools: List[Any], @@ -103,7 +104,8 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): if self.crew and self.crew._train: self._handle_crew_training_output(formatted_answer) - + self._create_short_term_memory(formatted_answer) + self._create_long_term_memory(formatted_answer) return {"output": formatted_answer.output} def _invoke_loop(self, formatted_answer=None): @@ -176,6 +178,8 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): return formatted_answer def _show_start_logs(self): + if self.agent is None: + raise ValueError("Agent cannot be None") if self.agent.verbose or ( hasattr(self, "crew") and getattr(self.crew, "verbose", False) ): @@ -188,6 +192,8 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): ) def _show_logs(self, formatted_answer: Union[AgentAction, AgentFinish]): + if self.agent is None: + raise ValueError("Agent cannot be None") if self.agent.verbose or ( hasattr(self, "crew") and getattr(self.crew, "verbose", False) ): @@ -306,7 +312,7 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): self, result: AgentFinish, human_feedback: str | None = None ) -> None: """Function to handle the process of the training data.""" - agent_id = str(self.agent.id) + agent_id = str(self.agent.id) # type: ignore # Load training data training_handler = CrewTrainingHandler(TRAINING_DATA_FILE) @@ -339,7 +345,7 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): "initial_output": result.output, "human_feedback": human_feedback, "agent": agent_id, - "agent_role": self.agent.role, + "agent_role": self.agent.role, # type: ignore } if self.crew is not None and hasattr(self.crew, "_train_iteration"): train_iteration = self.crew._train_iteration diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 29baa4499..5450e6e67 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -126,8 +126,8 @@ class Crew(BaseModel): default=None, description="An Instance of the EntityMemory to be used by the Crew", ) - embedder: Optional[dict] = Field( - default={"provider": "openai"}, + embedder: Optional[Any] = Field( + default=None, description="Configuration for the embedder to be used for the crew.", ) usage_metrics: Optional[UsageMetrics] = Field( @@ -774,7 +774,9 @@ class Crew(BaseModel): def _log_task_start(self, task: Task, role: str = "None"): if self.output_log_file: - self._file_handler.log(task_name=task.name, task=task.description, agent=role, status="started") + self._file_handler.log( + task_name=task.name, task=task.description, agent=role, status="started" + ) def _update_manager_tools(self, task: Task): if self.manager_agent: @@ -796,7 +798,13 @@ class Crew(BaseModel): def _process_task_result(self, task: Task, output: TaskOutput) -> None: role = task.agent.role if task.agent is not None else "None" if self.output_log_file: - self._file_handler.log(task_name=task.name, task=task.description, agent=role, status="completed", output=output.raw) + self._file_handler.log( + task_name=task.name, + task=task.description, + agent=role, + status="completed", + output=output.raw, + ) def _create_crew_output(self, task_outputs: List[TaskOutput]) -> CrewOutput: if len(task_outputs) != 1: diff --git a/src/crewai/memory/contextual/contextual_memory.py b/src/crewai/memory/contextual/contextual_memory.py index 23435c04c..5d91cf47d 100644 --- a/src/crewai/memory/contextual/contextual_memory.py +++ b/src/crewai/memory/contextual/contextual_memory.py @@ -31,7 +31,9 @@ class ContextualMemory: formatted as bullet points. """ stm_results = self.stm.search(query) - formatted_results = "\n".join([f"- {result}" for result in stm_results]) + formatted_results = "\n".join( + [f"- {result['context']}" for result in stm_results] + ) return f"Recent Insights:\n{formatted_results}" if stm_results else "" def _fetch_ltm_context(self, task) -> Optional[str]: diff --git a/src/crewai/memory/long_term/long_term_memory.py b/src/crewai/memory/long_term/long_term_memory.py index ab225e406..b9c36bdc9 100644 --- a/src/crewai/memory/long_term/long_term_memory.py +++ b/src/crewai/memory/long_term/long_term_memory.py @@ -1,4 +1,4 @@ -from typing import Any, Dict +from typing import Any, Dict, List from crewai.memory.long_term.long_term_memory_item import LongTermMemoryItem from crewai.memory.memory import Memory @@ -28,7 +28,7 @@ class LongTermMemory(Memory): datetime=item.datetime, ) - def search(self, task: str, latest_n: int = 3) -> Dict[str, Any]: + def search(self, task: str, latest_n: int = 3) -> List[Dict[str, Any]]: # type: ignore # signature of "search" incompatible with supertype "Memory" return self.storage.load(task, latest_n) # type: ignore # BUG?: "Storage" has no attribute "load" def reset(self) -> None: diff --git a/src/crewai/memory/memory.py b/src/crewai/memory/memory.py index 9df09d3c7..d0bcd614f 100644 --- a/src/crewai/memory/memory.py +++ b/src/crewai/memory/memory.py @@ -1,6 +1,6 @@ -from typing import Any, Dict, Optional +from typing import Any, Dict, Optional, List -from crewai.memory.storage.interface import Storage +from crewai.memory.storage.rag_storage import RAGStorage class Memory: @@ -8,7 +8,7 @@ class Memory: Base class for memory, now supporting agent tags and generic metadata. """ - def __init__(self, storage: Storage): + def __init__(self, storage: RAGStorage): self.storage = storage def save( @@ -23,5 +23,5 @@ class Memory: self.storage.save(value, metadata) - def search(self, query: str) -> Dict[str, Any]: + def search(self, query: str) -> List[Dict[str, Any]]: return self.storage.search(query) diff --git a/src/crewai/memory/storage/base_rag_storage.py b/src/crewai/memory/storage/base_rag_storage.py new file mode 100644 index 000000000..10b82ebff --- /dev/null +++ b/src/crewai/memory/storage/base_rag_storage.py @@ -0,0 +1,76 @@ +from abc import ABC, abstractmethod +from typing import Any, Dict, List, Optional + + +class BaseRAGStorage(ABC): + """ + Base class for RAG-based Storage implementations. + """ + + app: Any | None = None + + def __init__( + self, + type: str, + allow_reset: bool = True, + embedder_config: Optional[Any] = None, + crew: Any = None, + ): + self.type = type + self.allow_reset = allow_reset + self.embedder_config = embedder_config + self.crew = crew + self.agents = self._initialize_agents() + + def _initialize_agents(self) -> str: + if self.crew: + return "_".join( + [self._sanitize_role(agent.role) for agent in self.crew.agents] + ) + return "" + + @abstractmethod + def _sanitize_role(self, role: str) -> str: + """Sanitizes agent roles to ensure valid directory names.""" + pass + + @abstractmethod + def save(self, value: Any, metadata: Dict[str, Any]) -> None: + """Save a value with metadata to the storage.""" + pass + + @abstractmethod + def search( + self, + query: str, + limit: int = 3, + filter: Optional[dict] = None, + score_threshold: float = 0.35, + ) -> List[Any]: + """Search for entries in the storage.""" + pass + + @abstractmethod + def reset(self) -> None: + """Reset the storage.""" + pass + + @abstractmethod + def _generate_embedding( + self, text: str, metadata: Optional[Dict[str, Any]] = None + ) -> Any: + """Generate an embedding for the given text and metadata.""" + pass + + @abstractmethod + def _initialize_app(self): + """Initialize the vector db.""" + pass + + def setup_config(self, config: Dict[str, Any]): + """Setup the config of the storage.""" + pass + + def initialize_client(self): + """Initialize the client of the storage. This should setup the app and the db collection""" + pass diff --git a/src/crewai/memory/storage/interface.py b/src/crewai/memory/storage/interface.py index 0ffc1de16..8fbe10b03 100644 --- a/src/crewai/memory/storage/interface.py +++ b/src/crewai/memory/storage/interface.py @@ -1,4 +1,4 @@ -from typing import Any, Dict +from typing import Any, Dict, List class Storage: @@ -7,7 +7,7 @@ class Storage: def save(self, value: Any, metadata: Dict[str, Any]) -> None: pass - def search(self, key: str) -> Dict[str, Any]: # type: ignore + def search(self, key: str) -> List[Dict[str, Any]]: # type: ignore pass def reset(self) -> None: diff --git a/src/crewai/memory/storage/rag_storage.py b/src/crewai/memory/storage/rag_storage.py index ef051bed4..8d45d9f5a 100644 --- a/src/crewai/memory/storage/rag_storage.py +++ b/src/crewai/memory/storage/rag_storage.py @@ -3,10 +3,11 @@ import io import logging import os import shutil +import uuid from typing import Any, Dict, List, Optional - -from crewai.memory.storage.interface import Storage +from crewai.memory.storage.base_rag_storage import BaseRAGStorage from crewai.utilities.paths import db_storage_path +from chromadb.api import ClientAPI @contextlib.contextmanager @@ -24,61 +25,42 @@ def suppress_logging( logger.setLevel(original_level) -class RAGStorage(Storage): +class RAGStorage(BaseRAGStorage): """ Extends Storage to handle embeddings for memory entries, improving search efficiency. """ - def __init__(self, type, allow_reset=True, embedder_config=None, crew=None): - super().__init__() - if ( - not os.getenv("OPENAI_API_KEY") - and not os.getenv("OPENAI_BASE_URL") == "https://api.openai.com/v1" - ): - os.environ["OPENAI_API_KEY"] = "fake" + app: ClientAPI | None = None + def __init__(self, type, allow_reset=True, embedder_config=None, crew=None): + super().__init__(type, allow_reset, embedder_config, crew) agents = crew.agents if crew else [] agents = [self._sanitize_role(agent.role) for agent in agents] agents = "_".join(agents) + self.agents = agents - config = { - "app": { - "config": {"name": type, "collect_metrics": False, "log_level": "ERROR"} - }, - "chunker": { - "chunk_size": 5000, - "chunk_overlap": 100, - "length_function": "len", - "min_chunk_size": 150, - }, - "vectordb": { - "provider": "chroma", - "config": { - "collection_name": type, - "dir": f"{db_storage_path()}/{type}/{agents}", - "allow_reset": allow_reset, - }, - }, - } - - if embedder_config: - config["embedder"] = embedder_config self.type = type - self.config = config + self.embedder_config = embedder_config or self._create_embedding_function() self.allow_reset = allow_reset + self._initialize_app() def _initialize_app(self): - from embedchain import App - from embedchain.llm.base import BaseLlm + import chromadb - class FakeLLM(BaseLlm): - pass + chroma_client = chromadb.PersistentClient( + path=f"{db_storage_path()}/{self.type}/{self.agents}" + ) + self.app = chroma_client - self.app = App.from_config(config=self.config) - self.app.llm = FakeLLM() - if self.allow_reset: - self.app.reset() + try: + self.collection = self.app.get_collection( + name=self.type, embedding_function=self.embedder_config + ) + except Exception: + self.collection = self.app.create_collection( + name=self.type, embedding_function=self.embedder_config + ) def _sanitize_role(self, role: str) -> str: """ @@ -87,11 +69,14 @@ class RAGStorage(Storage): return role.replace("\n", "").replace(" ", "_").replace("/", "_") def save(self, value: Any, metadata: Dict[str, Any]) -> None: - if not hasattr(self, "app"): + if not hasattr(self, "app") or not hasattr(self, "collection"): self._initialize_app() - self._generate_embedding(value, metadata) + try: + self._generate_embedding(value, metadata) + except Exception as e: + logging.error(f"Error during {self.type} save: {str(e)}") - def search( # type: ignore # BUG?: Signature of "search" incompatible with supertype "Storage" + def search( self, query: str, limit: int = 3, @@ -100,31 +85,50 @@ class RAGStorage(Storage): ) -> List[Any]: if not hasattr(self, "app"): self._initialize_app() - from embedchain.vectordb.chroma import InvalidDimensionException - with suppress_logging(): - try: - results = ( - self.app.search(query, limit, where=filter) - if filter - else self.app.search(query, limit) - ) - except InvalidDimensionException: - self.app.reset() - return [] - return [r for r in results if r["metadata"]["score"] >= score_threshold] + try: + with suppress_logging(): + response = self.collection.query(query_texts=query, n_results=limit) - def _generate_embedding(self, text: str, metadata: Dict[str, Any]) -> Any: - if not hasattr(self, "app"): + results = [] + for i in range(len(response["ids"][0])): + result = { + "id": response["ids"][0][i], + "metadata": response["metadatas"][0][i], + "context": response["documents"][0][i], + "score": response["distances"][0][i], + } + if result["score"] >= score_threshold: + results.append(result) + + return results + except Exception as e: + logging.error(f"Error during {self.type} search: {str(e)}") + return [] + + def _generate_embedding(self, text: str, metadata: Dict[str, Any]) -> None: # type: ignore + if not hasattr(self, "app") or not hasattr(self, "collection"): self._initialize_app() - from embedchain.models.data_type import DataType - self.app.add(text, data_type=DataType.TEXT, metadata=metadata) + self.collection.add( + documents=[text], + metadatas=[metadata or {}], + ids=[str(uuid.uuid4())], + ) def reset(self) -> None: try: shutil.rmtree(f"{db_storage_path()}/{self.type}") + if self.app: + self.app.reset() except Exception as e: raise Exception( f"An error occurred while resetting the {self.type} memory: {e}" ) + + def _create_embedding_function(self): + import chromadb.utils.embedding_functions as embedding_functions + + return embedding_functions.OpenAIEmbeddingFunction( + api_key=os.getenv("OPENAI_API_KEY"), model_name="text-embedding-3-small" + ) diff --git a/tests/memory/cassettes/test_save_and_search.yaml b/tests/memory/cassettes/test_save_and_search.yaml deleted file mode 100644 index 473fe50d3..000000000 --- a/tests/memory/cassettes/test_save_and_search.yaml +++ /dev/null @@ -1,189 +0,0 @@ -interactions: -- request: - body: '{"input": ["test value test value test value test value test value test - value test value test value test value test value test value test value test - value test value test value test value test value test value"], "model": "text-embedding-ada-002", - "encoding_format": "base64"}' - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - connection: - - keep-alive - content-length: - - '292' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.47.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.47.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.11.7 - method: POST - uri: https://api.openai.com/v1/embeddings - response: - content: "{\n \"object\": \"list\",\n \"data\": [\n {\n \"object\": - \"embedding\",\n \"index\": 0,\n \"embedding\": \"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\"\n - \ }\n ],\n \"model\": \"text-embedding-ada-002\",\n \"usage\": {\n \"prompt_tokens\": - 38,\n \"total_tokens\": 38\n }\n}\n" - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8c7d0d952df8a533-MIA - Connection: - - keep-alive - Content-Encoding: - - gzip - Content-Type: - - application/json - Date: - - Mon, 23 Sep 2024 19:48:35 GMT - Server: - - cloudflare - Set-Cookie: - - __cf_bm=fCNrGtPzpUFtfoUMG2M7ss3WN9l7UWSHySlztYzxTug-1727120915-1.0.1.1-qw_aPQTh6.36xWyc5KuutqbYcTnlLJNPLVPbhmpVJi3BlkOJSv2ZFFB8ZaTHzSU5OUeNvdkT8Zf52isf39ig_g; - path=/; expires=Mon, 23-Sep-24 20:18:35 GMT; domain=.api.openai.com; HttpOnly; - Secure; SameSite=None - - _cfuvid=iDcOeEoxyAXVk7Sd7cdqMnYCstioELtzVAcYdG7ahuA-1727120915182-0.0.1.1-604800000; - path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-allow-origin: - - '*' - access-control-expose-headers: - - X-Request-ID - openai-model: - - text-embedding-ada-002 - openai-organization: - - crewai-iuxna1 - openai-processing-ms: - - '19' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=15552000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '10000000' - x-ratelimit-remaining-requests: - - '9999' - x-ratelimit-remaining-tokens: - - '9999947' - x-ratelimit-reset-requests: - - 6ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_8ec4409ad3f853ceb951750c74bc1516 - http_version: HTTP/1.1 - status_code: 200 -- request: - body: '{"input": ["test value"], "model": "text-embedding-ada-002", "encoding_format": - "base64"}' - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - connection: - - keep-alive - content-length: - - '89' - content-type: - - application/json - cookie: - - __cf_bm=fCNrGtPzpUFtfoUMG2M7ss3WN9l7UWSHySlztYzxTug-1727120915-1.0.1.1-qw_aPQTh6.36xWyc5KuutqbYcTnlLJNPLVPbhmpVJi3BlkOJSv2ZFFB8ZaTHzSU5OUeNvdkT8Zf52isf39ig_g; - _cfuvid=iDcOeEoxyAXVk7Sd7cdqMnYCstioELtzVAcYdG7ahuA-1727120915182-0.0.1.1-604800000 - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.47.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.47.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.11.7 - method: POST - uri: https://api.openai.com/v1/embeddings - response: - content: "{\n \"object\": \"list\",\n \"data\": [\n {\n \"object\": - \"embedding\",\n \"index\": 0,\n \"embedding\": \"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\"\n - \ }\n ],\n \"model\": \"text-embedding-ada-002\",\n \"usage\": {\n \"prompt_tokens\": - 2,\n \"total_tokens\": 2\n }\n}\n" - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8c7d0d9a1df7a533-MIA - Connection: - - keep-alive - Content-Encoding: - - gzip - Content-Type: - - application/json - Date: - - Mon, 23 Sep 2024 19:48:35 GMT - Server: - - cloudflare - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-allow-origin: - - '*' - access-control-expose-headers: - - X-Request-ID - openai-model: - - text-embedding-ada-002 - openai-organization: - - crewai-iuxna1 - openai-processing-ms: - - '19' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=15552000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '10000000' - x-ratelimit-remaining-requests: - - '9999' - x-ratelimit-remaining-tokens: - - '9999998' - x-ratelimit-reset-requests: - - 6ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_5916e70901482ad417bdb6d701dee598 - http_version: HTTP/1.1 - status_code: 200 -version: 1 diff --git a/tests/memory/short_term_memory_test.py b/tests/memory/short_term_memory_test.py index 8ae4e714c..c09b22691 100644 --- a/tests/memory/short_term_memory_test.py +++ b/tests/memory/short_term_memory_test.py @@ -1,5 +1,5 @@ import pytest - +from unittest.mock import patch from crewai.agent import Agent from crewai.crew import Crew from crewai.memory.short_term.short_term_memory import ShortTermMemory @@ -26,7 +26,6 @@ def short_term_memory(): return ShortTermMemory(crew=Crew(agents=[agent], tasks=[task])) -@pytest.mark.vcr(filter_headers=["authorization"]) def test_save_and_search(short_term_memory): memory = ShortTermMemoryItem( data="""test value test value test value test value test value test value @@ -35,12 +34,28 @@ def test_save_and_search(short_term_memory): agent="test_agent", metadata={"task": "test_task"}, ) - short_term_memory.save( - value=memory.data, - metadata=memory.metadata, - agent=memory.agent, - ) - find = short_term_memory.search("test value", score_threshold=0.01)[0] - assert find["context"] == memory.data, "Data value mismatch." - assert find["metadata"]["agent"] == "test_agent", "Agent value mismatch." + with patch.object(ShortTermMemory, "save") as mock_save: + short_term_memory.save( + value=memory.data, + metadata=memory.metadata, + agent=memory.agent, + ) + + mock_save.assert_called_once_with( + value=memory.data, + metadata=memory.metadata, + agent=memory.agent, + ) + + expected_result = [ + { + "context": memory.data, + "metadata": {"agent": "test_agent"}, + "score": 0.95, + } + ] + with patch.object(ShortTermMemory, "search", return_value=expected_result): + find = short_term_memory.search("test value", score_threshold=0.01)[0] + assert find["context"] == memory.data, "Data value mismatch." + assert find["metadata"]["agent"] == "test_agent", "Agent value mismatch." diff --git a/uv.lock b/uv.lock index 6abd2b4a8..da2f684ed 100644 --- a/uv.lock +++ b/uv.lock @@ -94,21 +94,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cf/b7/50cc827dd54df087d7c30293b29fbc13a7ea45a3ac54a4a12127b271265c/aiohttp-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c6769d71bfb1ed60321363a9bc05e94dcf05e38295ef41d46ac08919e5b00d19", size = 1306007 }, { url = "https://files.pythonhosted.org/packages/1e/c0/a4cb21ad677757368743d73aff27047dfc0d7248cb39dec06c059b773c24/aiohttp-3.10.8-cp312-cp312-win32.whl", hash = "sha256:a3081246bab4d419697ee45e555cef5cd1def7ac193dff6f50be761d2e44f194", size = 359125 }, { url = "https://files.pythonhosted.org/packages/d2/0f/1ecbc18eed29952393d5a9c4636bfe789dde3c98fe0a0a4759d323478e72/aiohttp-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:ab1546fc8e00676febc81c548a876c7bde32f881b8334b77f84719ab2c7d28dc", size = 379143 }, - { url = "https://files.pythonhosted.org/packages/9f/dd/3d944769ed65d3d245f8f976040654b3eae2e21d05c81f91fb450365bddf/aiohttp-3.10.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:b1a012677b8e0a39e181e218de47d6741c5922202e3b0b65e412e2ce47c39337", size = 575934 }, - { url = "https://files.pythonhosted.org/packages/2a/bf/a6a1d14b0e5f90d53b1f0850204f9fafdfec7c1d99dda8aaea1dd93ba181/aiohttp-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2df786c96c57cd6b87156ba4c5f166af7b88f3fc05f9d592252fdc83d8615a3c", size = 391728 }, - { url = "https://files.pythonhosted.org/packages/0e/1b/27cc6efa6ca3e563973c7e03e8b7e26b75b4046aefea991bad42c028a906/aiohttp-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8885ca09d3a9317219c0831276bfe26984b17b2c37b7bf70dd478d17092a4772", size = 387247 }, - { url = "https://files.pythonhosted.org/packages/ae/fd/235401bd4a98ea31cdda7b3822921e2a9cbc3ca0af1958a12a2709261735/aiohttp-3.10.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dbf252ac19860e0ab56cd480d2805498f47c5a2d04f5995d8d8a6effd04b48c", size = 1286909 }, - { url = "https://files.pythonhosted.org/packages/ab/1c/8ae6b12be2ae88e94be34d96765d6cc820d61d320f33c0423de8af0cfa47/aiohttp-3.10.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2036479b6b94afaaca7d07b8a68dc0e67b0caf5f6293bb6a5a1825f5923000", size = 1323446 }, - { url = "https://files.pythonhosted.org/packages/23/09/5ebe3a2dbdd008711b659dc2f2a6135bbc055b6c8869688083f4bec6b50a/aiohttp-3.10.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:365783e1b7c40b59ed4ce2b5a7491bae48f41cd2c30d52647a5b1ee8604c68ad", size = 1368237 }, - { url = "https://files.pythonhosted.org/packages/47/22/f184c27d03d34ce71e6d4b9976a4ff845d091b725f174b09f641e4a28f63/aiohttp-3.10.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:270e653b5a4b557476a1ed40e6b6ce82f331aab669620d7c95c658ef976c9c5e", size = 1282598 }, - { url = "https://files.pythonhosted.org/packages/82/f6/bae1703bfacb19bb35e3522632fc5279793070625a0b5e567b109c0f0e8d/aiohttp-3.10.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8960fabc20bfe4fafb941067cda8e23c8c17c98c121aa31c7bf0cdab11b07842", size = 1236350 }, - { url = "https://files.pythonhosted.org/packages/a4/bc/ad73aced93836b8749c70e617c5d389d17a36da9ee220cdb0804f803bd9b/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f21e8f2abed9a44afc3d15bba22e0dfc71e5fa859bea916e42354c16102b036f", size = 1250172 }, - { url = "https://files.pythonhosted.org/packages/3b/18/027a8497caf3a9c247477831d67ede58e1e42a92fd635ecdb74cf5d45c8b/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fecd55e7418fabd297fd836e65cbd6371aa4035a264998a091bbf13f94d9c44d", size = 1248783 }, - { url = "https://files.pythonhosted.org/packages/6f/d2/5080c27b656e6d478e820752d633d7a4dab4a2c4fd23a6f645b553fb9da5/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:badb51d851358cd7535b647bb67af4854b64f3c85f0d089c737f75504d5910ec", size = 1293209 }, - { url = "https://files.pythonhosted.org/packages/ae/ec/c38c8690e804cb9bf3e8c473a4a7bb339ed549cd63c469f19995269ca9ec/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e860985f30f3a015979e63e7ba1a391526cdac1b22b7b332579df7867848e255", size = 1319943 }, - { url = "https://files.pythonhosted.org/packages/df/55/d6e3a13c3f37ad7a3e60a377c96541261c1943837d240f1ab2151a96da6b/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:71462f8eeca477cbc0c9700a9464e3f75f59068aed5e9d4a521a103692da72dc", size = 1281380 }, - { url = "https://files.pythonhosted.org/packages/c3/31/0b84027487fa58a124251b47f9dca781e4777a50d1c4eea4d3fc8950bd10/aiohttp-3.10.8-cp313-cp313-win32.whl", hash = "sha256:177126e971782769b34933e94fddd1089cef0fe6b82fee8a885e539f5b0f0c6a", size = 357352 }, - { url = "https://files.pythonhosted.org/packages/cb/8a/b4f3a8d0fb7f4fdb3869db6c3334e23e11878123605579e067be85f7e01f/aiohttp-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:98a4eb60e27033dee9593814ca320ee8c199489fbc6b2699d0f710584db7feb7", size = 376618 }, ] [[package]] @@ -424,17 +409,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, ] [[package]] @@ -627,15 +601,14 @@ wheels = [ [[package]] name = "crewai" -version = "0.67.1" +version = "0.70.1" source = { editable = "." } dependencies = [ - { name = "agentops" }, { name = "appdirs" }, { name = "auth0-python" }, + { name = "chromadb" }, { name = "click" }, { name = "crewai-tools" }, - { name = "embedchain" }, { name = "instructor" }, { name = "json-repair" }, { name = "jsonref" }, @@ -683,14 +656,13 @@ dev = [ [package.metadata] requires-dist = [ - { name = "agentops", specifier = ">=0.3.0" }, { name = "agentops", marker = "extra == 'agentops'", specifier = ">=0.3.0" }, { name = "appdirs", specifier = ">=1.4.4" }, { name = "auth0-python", specifier = ">=4.7.1" }, + { name = "chromadb", specifier = ">=0.4.24" }, { name = "click", specifier = ">=8.1.7" }, { name = "crewai-tools", specifier = ">=0.12.1" }, { name = "crewai-tools", marker = "extra == 'tools'", specifier = ">=0.12.1" }, - { name = "embedchain", specifier = ">=0.1.114" }, { name = "instructor", specifier = ">=1.3.3" }, { name = "json-repair", specifier = ">=0.25.2" }, { name = "jsonref", specifier = ">=1.1.0" }, @@ -1337,22 +1309,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975 }, { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955 }, { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655 }, - { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 }, - { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 }, - { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 }, - { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 }, - { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 }, - { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 }, - { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 }, - { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 }, - { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 }, - { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 }, - { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 }, - { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 }, - { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 }, - { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 }, - { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 }, - { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, ] [[package]] @@ -1414,15 +1370,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ff/5f/142e19db367a34ea0ee8a8451e43215d0a1a5dbffcfdcae8801f22903301/grpcio-1.66.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49f0ca7ae850f59f828a723a9064cadbed90f1ece179d375966546499b8a2c9c", size = 6040273 }, { url = "https://files.pythonhosted.org/packages/5c/3b/12fcd752c55002e4b0e0a7bd5faec101bc0a4e3890be3f95a43353142481/grpcio-1.66.2-cp312-cp312-win32.whl", hash = "sha256:31fd163105464797a72d901a06472860845ac157389e10f12631025b3e4d0453", size = 3537988 }, { url = "https://files.pythonhosted.org/packages/f1/70/76bfea3faa862bfceccba255792e780691ff25b8227180759c9d38769379/grpcio-1.66.2-cp312-cp312-win_amd64.whl", hash = "sha256:ff1f7882e56c40b0d33c4922c15dfa30612f05fb785074a012f7cda74d1c3679", size = 4275553 }, - { url = "https://files.pythonhosted.org/packages/72/31/8708a8dfb3f1ac89926c27c5dd17412764157a2959dbc5a606eaf8ac71f6/grpcio-1.66.2-cp313-cp313-linux_armv7l.whl", hash = "sha256:3b00efc473b20d8bf83e0e1ae661b98951ca56111feb9b9611df8efc4fe5d55d", size = 5004245 }, - { url = "https://files.pythonhosted.org/packages/8b/37/0b57c3769efb3cc9ec97fcaa9f7243046660e7ed58c0faebc4ef315df92c/grpcio-1.66.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1caa38fb22a8578ab8393da99d4b8641e3a80abc8fd52646f1ecc92bcb8dee34", size = 10756749 }, - { url = "https://files.pythonhosted.org/packages/bf/5a/425e995724a19a1b110340ed653bc7c5de8019d9fc84b3798a0f79c3eb31/grpcio-1.66.2-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c408f5ef75cfffa113cacd8b0c0e3611cbfd47701ca3cdc090594109b9fcbaed", size = 5499666 }, - { url = "https://files.pythonhosted.org/packages/2e/e4/86a5c5ec40a6b683671a1d044ebca433812d99da8fcfc2889e9c43cecbd4/grpcio-1.66.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c806852deaedee9ce8280fe98955c9103f62912a5b2d5ee7e3eaa284a6d8d8e7", size = 6109578 }, - { url = "https://files.pythonhosted.org/packages/2f/86/a86742f3deaa22385c3bff984c5947fc62d47d3fab26c508730037d027e5/grpcio-1.66.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f145cc21836c332c67baa6fc81099d1d27e266401565bf481948010d6ea32d46", size = 5763274 }, - { url = "https://files.pythonhosted.org/packages/c3/61/b9a2a4345dea0a354c4ed8ac7aacbdd0ff986acbc8f92680213cf3d2faa3/grpcio-1.66.2-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:73e3b425c1e155730273f73e419de3074aa5c5e936771ee0e4af0814631fb30a", size = 6450416 }, - { url = "https://files.pythonhosted.org/packages/50/b9/ad303ce75d8cd71d855a661519aa160ce42f27498f589f1ae6d9f8c5e8ac/grpcio-1.66.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c509a4f78114cbc5f0740eb3d7a74985fd2eff022971bc9bc31f8bc93e66a3b", size = 6040045 }, - { url = "https://files.pythonhosted.org/packages/ac/b3/8db1873e3240ef1672ba87b89e949ece367089e29e4d221377bfdd288bd3/grpcio-1.66.2-cp313-cp313-win32.whl", hash = "sha256:20657d6b8cfed7db5e11b62ff7dfe2e12064ea78e93f1434d61888834bc86d75", size = 3537126 }, - { url = "https://files.pythonhosted.org/packages/a2/df/133216989fe7e17caeafd7ff5b17cc82c4e722025d0b8d5d2290c11fe2e6/grpcio-1.66.2-cp313-cp313-win_amd64.whl", hash = "sha256:fb70487c95786e345af5e854ffec8cb8cc781bcc5df7930c4fbb7feaa72e1cdf", size = 4278018 }, ] [[package]] @@ -1551,7 +1498,7 @@ wheels = [ [[package]] name = "httpx" -version = "0.27.2" +version = "0.27.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1560,9 +1507,9 @@ dependencies = [ { name = "idna" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 } +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5", size = 126413 } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, + { url = "https://files.pythonhosted.org/packages/41/7b/ddacf6dcebb42466abd03f368782142baa82e08fc0c1f8eaa05b4bae87d5/httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", size = 75590 }, ] [package.optional-dependencies] @@ -2363,22 +2310,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9b/fd/eb1a3573cda74d4c2381d10ded62c128e869954ced1881c15e2bcd97a48f/mmh3-5.0.1-cp312-cp312-win32.whl", hash = "sha256:842516acf04da546f94fad52db125ee619ccbdcada179da51c326a22c4578cb9", size = 39206 }, { url = "https://files.pythonhosted.org/packages/66/e8/542ed252924002b84c43a68a080cfd4facbea0d5df361e4f59637638d3c7/mmh3-5.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:d963be0dbfd9fca209c17172f6110787ebf78934af25e3694fe2ba40e55c1e2b", size = 39799 }, { url = "https://files.pythonhosted.org/packages/bd/25/ff2cd36c82a23afa57a05cdb52ab467a911fb12c055c8a8238c0d426cbf0/mmh3-5.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:a5da292ceeed8ce8e32b68847261a462d30fd7b478c3f55daae841404f433c15", size = 36537 }, - { url = "https://files.pythonhosted.org/packages/09/e0/fb19c46265c18311b422ba5ce3e18046ad45c48cfb213fd6dbec23ae6b51/mmh3-5.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:673e3f1c8d4231d6fb0271484ee34cb7146a6499fc0df80788adb56fd76842da", size = 52909 }, - { url = "https://files.pythonhosted.org/packages/c3/94/54fc591e7a24c7ce2c531ecfc5715cff932f9d320c2936550cc33d67304d/mmh3-5.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f795a306bd16a52ad578b663462cc8e95500b3925d64118ae63453485d67282b", size = 38396 }, - { url = "https://files.pythonhosted.org/packages/1f/9a/142bcc9d0d28fc8ae45bbfb83926adc069f984cdf3495a71534cc22b8e27/mmh3-5.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5ed57a5e28e502a1d60436cc25c76c3a5ba57545f250f2969af231dc1221e0a5", size = 38207 }, - { url = "https://files.pythonhosted.org/packages/f8/5b/f1c9110aa70321bb1ee713f17851b9534586c63bc25e0110e4fc03ae2450/mmh3-5.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:632c28e7612e909dbb6cbe2fe496201ada4695b7715584005689c5dc038e59ad", size = 94988 }, - { url = "https://files.pythonhosted.org/packages/87/e5/4dc67e7e0e716c641ab0a5875a659e37258417439590feff5c3bd3ff4538/mmh3-5.0.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53fd6bd525a5985e391c43384672d9d6b317fcb36726447347c7fc75bfed34ec", size = 99969 }, - { url = "https://files.pythonhosted.org/packages/ac/68/d148327337687c53f04ad9ceaedfa9ad155ee0111d0cb06220f044d66720/mmh3-5.0.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dceacf6b0b961a0e499836af3aa62d60633265607aef551b2a3e3c48cdaa5edd", size = 99662 }, - { url = "https://files.pythonhosted.org/packages/13/79/782adb6df6397947c1097b1e94b7f8d95629a4a73df05cf7207bd5148c1f/mmh3-5.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f0738d478fdfb5d920f6aff5452c78f2c35b0eff72caa2a97dfe38e82f93da2", size = 87606 }, - { url = "https://files.pythonhosted.org/packages/f2/c2/0404383281df049d0e4ccf07fabd659fc1f3da834df6708d934116cbf45d/mmh3-5.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e70285e7391ab88b872e5bef632bad16b9d99a6d3ca0590656a4753d55988af", size = 94836 }, - { url = "https://files.pythonhosted.org/packages/c8/33/fda67c5f28e4c2131891cf8cbc3513cfc55881e3cfe26e49328e38ffacb3/mmh3-5.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:27e5fc6360aa6b828546a4318da1a7da6bf6e5474ccb053c3a6aa8ef19ff97bd", size = 90492 }, - { url = "https://files.pythonhosted.org/packages/64/2f/0ed38aefe2a87f30bb1b12e5b75dc69fcffdc16def40d1752d6fc7cbbf96/mmh3-5.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7989530c3c1e2c17bf5a0ec2bba09fd19819078ba90beedabb1c3885f5040b0d", size = 89594 }, - { url = "https://files.pythonhosted.org/packages/95/ab/6e7a5e765fc78e3dbd0a04a04cfdf72e91eb8e31976228e69d82c741a5b4/mmh3-5.0.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cdad7bee649950da7ecd3cbbbd12fb81f1161072ecbdb5acfa0018338c5cb9cf", size = 94929 }, - { url = "https://files.pythonhosted.org/packages/74/51/f748f00c072006f4a093d9b08853a0e2e3cd5aeaa91343d4e2d942851978/mmh3-5.0.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e143b8f184c1bb58cecd85ab4a4fd6dc65a2d71aee74157392c3fddac2a4a331", size = 91317 }, - { url = "https://files.pythonhosted.org/packages/df/a1/21ee8017a7feb0270c49f756ff56da9f99bd150dcfe3b3f6f0d4b243423d/mmh3-5.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5eb12e886f3646dd636f16b76eb23fc0c27e8ff3c1ae73d4391e50ef60b40f6", size = 89861 }, - { url = "https://files.pythonhosted.org/packages/c2/d2/46a6d070de4659bdf91cd6a62d659f8cc547dadee52b6d02bcbacb3262ed/mmh3-5.0.1-cp313-cp313-win32.whl", hash = "sha256:16e6dddfa98e1c2d021268e72c78951234186deb4df6630e984ac82df63d0a5d", size = 39201 }, - { url = "https://files.pythonhosted.org/packages/ed/07/316c062f09019b99b248a4183c5333f8eeebe638345484774908a8f2c9c0/mmh3-5.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:d3ffb792d70b8c4a2382af3598dad6ae0c5bd9cee5b7ffcc99aa2f5fd2c1bf70", size = 39807 }, - { url = "https://files.pythonhosted.org/packages/9d/d3/f7e6d7d062b8d7072c3989a528d9d47486ee5d5ae75250f6e26b4976d098/mmh3-5.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:122fa9ec148383f9124292962bda745f192b47bfd470b2af5fe7bb3982b17896", size = 36539 }, ] [[package]] @@ -2462,21 +2393,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/77/00/8538f11e3356b5d95fa4b024aa566cde7a38aa7a5f08f4912b32a037c5dc/multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3", size = 125360 }, { url = "https://files.pythonhosted.org/packages/be/05/5d334c1f2462d43fec2363cd00b1c44c93a78c3925d952e9a71caf662e96/multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133", size = 26382 }, { url = "https://files.pythonhosted.org/packages/a3/bf/f332a13486b1ed0496d624bcc7e8357bb8053823e8cd4b9a18edc1d97e73/multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1", size = 28529 }, - { url = "https://files.pythonhosted.org/packages/22/67/1c7c0f39fe069aa4e5d794f323be24bf4d33d62d2a348acdb7991f8f30db/multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008", size = 48771 }, - { url = "https://files.pythonhosted.org/packages/3c/25/c186ee7b212bdf0df2519eacfb1981a017bda34392c67542c274651daf23/multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f", size = 29533 }, - { url = "https://files.pythonhosted.org/packages/67/5e/04575fd837e0958e324ca035b339cea174554f6f641d3fb2b4f2e7ff44a2/multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28", size = 29595 }, - { url = "https://files.pythonhosted.org/packages/d3/b2/e56388f86663810c07cfe4a3c3d87227f3811eeb2d08450b9e5d19d78876/multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b", size = 130094 }, - { url = "https://files.pythonhosted.org/packages/6c/ee/30ae9b4186a644d284543d55d491fbd4239b015d36b23fea43b4c94f7052/multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c", size = 134876 }, - { url = "https://files.pythonhosted.org/packages/84/c7/70461c13ba8ce3c779503c70ec9d0345ae84de04521c1f45a04d5f48943d/multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3", size = 133500 }, - { url = "https://files.pythonhosted.org/packages/4a/9f/002af221253f10f99959561123fae676148dd730e2daa2cd053846a58507/multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44", size = 131099 }, - { url = "https://files.pythonhosted.org/packages/82/42/d1c7a7301d52af79d88548a97e297f9d99c961ad76bbe6f67442bb77f097/multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2", size = 120403 }, - { url = "https://files.pythonhosted.org/packages/68/f3/471985c2c7ac707547553e8f37cff5158030d36bdec4414cb825fbaa5327/multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3", size = 125348 }, - { url = "https://files.pythonhosted.org/packages/67/2c/e6df05c77e0e433c214ec1d21ddd203d9a4770a1f2866a8ca40a545869a0/multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa", size = 119673 }, - { url = "https://files.pythonhosted.org/packages/c5/cd/bc8608fff06239c9fb333f9db7743a1b2eafe98c2666c9a196e867a3a0a4/multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa", size = 129927 }, - { url = "https://files.pythonhosted.org/packages/44/8e/281b69b7bc84fc963a44dc6e0bbcc7150e517b91df368a27834299a526ac/multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4", size = 128711 }, - { url = "https://files.pythonhosted.org/packages/12/a4/63e7cd38ed29dd9f1881d5119f272c898ca92536cdb53ffe0843197f6c85/multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6", size = 125519 }, - { url = "https://files.pythonhosted.org/packages/38/e0/4f5855037a72cd8a7a2f60a3952d9aa45feedb37ae7831642102604e8a37/multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81", size = 26426 }, - { url = "https://files.pythonhosted.org/packages/7e/a5/17ee3a4db1e310b7405f5d25834460073a8ccd86198ce044dfaf69eac073/multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774", size = 28531 }, { url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051 }, ] @@ -2495,7 +2411,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/a9/39cf856d03690af6fd570cf40331f1f79acdbb3132a9c35d2c5002f7f30b/multiprocess-0.70.17-py310-none-any.whl", hash = "sha256:38357ca266b51a2e22841b755d9a91e4bb7b937979a54d411677111716c32744", size = 134830 }, { url = "https://files.pythonhosted.org/packages/b2/07/8cbb75d6cfbe8712d8f7f6a5615f083c6e710ab916b748fbb20373ddb142/multiprocess-0.70.17-py311-none-any.whl", hash = "sha256:2884701445d0177aec5bd5f6ee0df296773e4fb65b11903b94c613fb46cfb7d1", size = 144346 }, { url = "https://files.pythonhosted.org/packages/a4/69/d3f343a61a2f86ef10ed7865a26beda7c71554136ce187b0384b1c2c9ca3/multiprocess-0.70.17-py312-none-any.whl", hash = "sha256:2818af14c52446b9617d1b0755fa70ca2f77c28b25ed97bdaa2c69a22c47b46c", size = 147990 }, - { url = "https://files.pythonhosted.org/packages/c8/b7/2e9a4fcd871b81e1f2a812cd5c6fb52ad1e8da7bf0d7646c55eaae220484/multiprocess-0.70.17-py313-none-any.whl", hash = "sha256:20c28ca19079a6c879258103a6d60b94d4ffe2d9da07dda93fb1c8bc6243f522", size = 149843 }, + { url = "https://files.pythonhosted.org/packages/ae/d7/fd7a092fc0ab1845a1a97ca88e61b9b7cc2e9d6fcf0ed24e9480590c2336/multiprocess-0.70.17-py38-none-any.whl", hash = "sha256:1d52f068357acd1e5bbc670b273ef8f81d57863235d9fbf9314751886e141968", size = 132635 }, + { url = "https://files.pythonhosted.org/packages/f9/41/0618ac724b8a56254962c143759e04fa01c73b37aa69dd433f16643bd38b/multiprocess-0.70.17-py39-none-any.whl", hash = "sha256:c3feb874ba574fbccfb335980020c1ac631fbf2a3f7bee4e2042ede62558a021", size = 133359 }, ] [[package]] @@ -2847,12 +2764,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/1a/d11805670c29d3a1b29fc4bd048dc90b094784779690592efe8c9f71249a/orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b", size = 167994 }, { url = "https://files.pythonhosted.org/packages/20/5f/03d89b007f9d6733dc11bc35d64812101c85d6c4e9c53af9fa7e7689cb11/orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb", size = 143130 }, { url = "https://files.pythonhosted.org/packages/c6/9d/9b9fb6c60b8a0e04031ba85414915e19ecea484ebb625402d968ea45b8d5/orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1", size = 137326 }, - { url = "https://files.pythonhosted.org/packages/15/05/121af8a87513c56745d01ad7cf215c30d08356da9ad882ebe2ba890824cd/orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149", size = 251331 }, - { url = "https://files.pythonhosted.org/packages/73/7f/8d6ccd64a6f8bdbfe6c9be7c58aeb8094aa52a01fbbb2cda42ff7e312bd7/orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe", size = 142012 }, - { url = "https://files.pythonhosted.org/packages/04/65/f2a03fd1d4f0308f01d372e004c049f7eb9bc5676763a15f20f383fa9c01/orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c", size = 169920 }, - { url = "https://files.pythonhosted.org/packages/e2/1c/3ef8d83d7c6a619ad3d69a4d5318591b4ce5862e6eda7c26bbe8208652ca/orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad", size = 167916 }, - { url = "https://files.pythonhosted.org/packages/f2/0d/820a640e5a7dfbe525e789c70871ebb82aff73b0c7bf80082653f86b9431/orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2", size = 143089 }, - { url = "https://files.pythonhosted.org/packages/1a/72/a424db9116c7cad2950a8f9e4aeb655a7b57de988eb015acd0fcd1b4609b/orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024", size = 137081 }, ] [[package]] @@ -2927,19 +2838,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/e8/45a05d9c39d2cea61ab175dbe6a2de1d05b679e8de2011da4ee190d7e748/pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", size = 16359235 }, { url = "https://files.pythonhosted.org/packages/1d/99/617d07a6a5e429ff90c90da64d428516605a1ec7d7bea494235e1c3882de/pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", size = 14056756 }, { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, - { url = "https://files.pythonhosted.org/packages/64/22/3b8f4e0ed70644e85cfdcd57454686b9057c6c38d2f74fe4b8bc2527214a/pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015", size = 12477643 }, - { url = "https://files.pythonhosted.org/packages/e4/93/b3f5d1838500e22c8d793625da672f3eec046b1a99257666c94446969282/pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28", size = 11281573 }, - { url = "https://files.pythonhosted.org/packages/f5/94/6c79b07f0e5aab1dcfa35a75f4817f5c4f677931d4234afcd75f0e6a66ca/pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0", size = 15196085 }, - { url = "https://files.pythonhosted.org/packages/e8/31/aa8da88ca0eadbabd0a639788a6da13bb2ff6edbbb9f29aa786450a30a91/pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24", size = 12711809 }, - { url = "https://files.pythonhosted.org/packages/ee/7c/c6dbdb0cb2a4344cacfb8de1c5808ca885b2e4dcfde8008266608f9372af/pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659", size = 16356316 }, - { url = "https://files.pythonhosted.org/packages/57/b7/8b757e7d92023b832869fa8881a992696a0bfe2e26f72c9ae9f255988d42/pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb", size = 14022055 }, - { url = "https://files.pythonhosted.org/packages/3b/bc/4b18e2b8c002572c5a441a64826252ce5da2aa738855747247a971988043/pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d", size = 11481175 }, - { url = "https://files.pythonhosted.org/packages/76/a3/a5d88146815e972d40d19247b2c162e88213ef51c7c25993942c39dbf41d/pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468", size = 12615650 }, - { url = "https://files.pythonhosted.org/packages/9c/8c/f0fd18f6140ddafc0c24122c8a964e48294acc579d47def376fef12bcb4a/pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18", size = 11290177 }, - { url = "https://files.pythonhosted.org/packages/ed/f9/e995754eab9c0f14c6777401f7eece0943840b7a9fc932221c19d1abee9f/pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2", size = 14651526 }, - { url = "https://files.pythonhosted.org/packages/25/b0/98d6ae2e1abac4f35230aa756005e8654649d305df9a28b16b9ae4353bff/pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4", size = 11871013 }, - { url = "https://files.pythonhosted.org/packages/cc/57/0f72a10f9db6a4628744c8e8f0df4e6e21de01212c7c981d31e50ffc8328/pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d", size = 15711620 }, - { url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436 }, ] [[package]] @@ -3035,17 +2933,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/55/04/5e6de6e6120451ec0c24516c41dbaf80cce1b6451f96561235ef2429da2e/pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42", size = 2235690 }, { url = "https://files.pythonhosted.org/packages/74/0a/d4ce3c44bca8635bd29a2eab5aa181b654a734a29b263ca8efe013beea98/pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a", size = 2554951 }, { url = "https://files.pythonhosted.org/packages/b5/ca/184349ee40f2e92439be9b3502ae6cfc43ac4b50bc4fc6b3de7957563894/pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9", size = 2243427 }, - { url = "https://files.pythonhosted.org/packages/c3/00/706cebe7c2c12a6318aabe5d354836f54adff7156fd9e1bd6c89f4ba0e98/pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3", size = 3525685 }, - { url = "https://files.pythonhosted.org/packages/cf/76/f658cbfa49405e5ecbfb9ba42d07074ad9792031267e782d409fd8fe7c69/pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb", size = 3374883 }, - { url = "https://files.pythonhosted.org/packages/46/2b/99c28c4379a85e65378211971c0b430d9c7234b1ec4d59b2668f6299e011/pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70", size = 4339837 }, - { url = "https://files.pythonhosted.org/packages/f1/74/b1ec314f624c0c43711fdf0d8076f82d9d802afd58f1d62c2a86878e8615/pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be", size = 4455562 }, - { url = "https://files.pythonhosted.org/packages/4a/2a/4b04157cb7b9c74372fa867096a1607e6fedad93a44deeff553ccd307868/pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0", size = 4366761 }, - { url = "https://files.pythonhosted.org/packages/ac/7b/8f1d815c1a6a268fe90481232c98dd0e5fa8c75e341a75f060037bd5ceae/pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc", size = 4536767 }, - { url = "https://files.pythonhosted.org/packages/e5/77/05fa64d1f45d12c22c314e7b97398ffb28ef2813a485465017b7978b3ce7/pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a", size = 4477989 }, - { url = "https://files.pythonhosted.org/packages/12/63/b0397cfc2caae05c3fb2f4ed1b4fc4fc878f0243510a7a6034ca59726494/pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309", size = 4610255 }, - { url = "https://files.pythonhosted.org/packages/7b/f9/cfaa5082ca9bc4a6de66ffe1c12c2d90bf09c309a5f52b27759a596900e7/pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060", size = 2235603 }, - { url = "https://files.pythonhosted.org/packages/01/6a/30ff0eef6e0c0e71e55ded56a38d4859bf9d3634a94a88743897b5f96936/pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea", size = 2554972 }, - { url = "https://files.pythonhosted.org/packages/48/2c/2e0a52890f269435eee38b21c8218e102c621fe8d8df8b9dd06fabf879ba/pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d", size = 2243375 }, { url = "https://files.pythonhosted.org/packages/38/30/095d4f55f3a053392f75e2eae45eba3228452783bab3d9a920b951ac495c/pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4", size = 3493889 }, { url = "https://files.pythonhosted.org/packages/f3/e8/4ff79788803a5fcd5dc35efdc9386af153569853767bff74540725b45863/pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da", size = 3346160 }, { url = "https://files.pythonhosted.org/packages/d7/ac/4184edd511b14f760c73f5bb8a5d6fd85c591c8aff7c2229677a355c4179/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026", size = 3435020 }, @@ -3179,8 +3066,6 @@ version = "5.9.8" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/90/c7/6dc0a455d111f68ee43f27793971cf03fe29b6ef972042549db29eec39a2/psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c", size = 503247 } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/5f/c26deb822fd3daf8fde4bdb658bf87d9ab1ffd3fca483816e89a9a9a9084/psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e", size = 248660 }, - { url = "https://files.pythonhosted.org/packages/32/1d/cf66073d74d6146187e2d0081a7616df4437214afa294ee4f16f80a2f96a/psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631", size = 251966 }, { url = "https://files.pythonhosted.org/packages/e7/e3/07ae864a636d70a8a6f58da27cb1179192f1140d5d1da10886ade9405797/psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81", size = 248702 }, { url = "https://files.pythonhosted.org/packages/b3/bd/28c5f553667116b2598b9cc55908ec435cb7f77a34f2bff3e3ca765b0f78/psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421", size = 285242 }, { url = "https://files.pythonhosted.org/packages/c5/4f/0e22aaa246f96d6ac87fe5ebb9c5a693fbe8877f537a1022527c47ca43c5/psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4", size = 288191 }, @@ -3365,18 +3250,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, - { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, - { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, - { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, - { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, - { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, - { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, - { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, - { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, - { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, - { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, - { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, - { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, @@ -3656,15 +3529,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, ] [[package]] @@ -3783,21 +3647,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ea/75/9753e9dcebfa7c3645563ef5c8a58f3a47e799c872165f37c55737dadd3e/regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", size = 787333 }, { url = "https://files.pythonhosted.org/packages/bc/4e/ba1cbca93141f7416624b3ae63573e785d4bc1834c8be44a8f0747919eca/regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", size = 262058 }, { url = "https://files.pythonhosted.org/packages/6e/16/efc5f194778bf43e5888209e5cec4b258005d37c613b67ae137df3b89c53/regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", size = 273526 }, - { url = "https://files.pythonhosted.org/packages/93/0a/d1c6b9af1ff1e36832fe38d74d5c5bab913f2bdcbbd6bc0e7f3ce8b2f577/regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", size = 483376 }, - { url = "https://files.pythonhosted.org/packages/a4/42/5910a050c105d7f750a72dcb49c30220c3ae4e2654e54aaaa0e9bc0584cb/regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", size = 288112 }, - { url = "https://files.pythonhosted.org/packages/8d/56/0c262aff0e9224fa7ffce47b5458d373f4d3e3ff84e99b5ff0cb15e0b5b2/regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", size = 284608 }, - { url = "https://files.pythonhosted.org/packages/b9/54/9fe8f9aec5007bbbbce28ba3d2e3eaca425f95387b7d1e84f0d137d25237/regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", size = 795337 }, - { url = "https://files.pythonhosted.org/packages/b2/e7/6b2f642c3cded271c4f16cc4daa7231be544d30fe2b168e0223724b49a61/regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", size = 835848 }, - { url = "https://files.pythonhosted.org/packages/cd/9e/187363bdf5d8c0e4662117b92aa32bf52f8f09620ae93abc7537d96d3311/regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", size = 823503 }, - { url = "https://files.pythonhosted.org/packages/f8/10/601303b8ee93589f879664b0cfd3127949ff32b17f9b6c490fb201106c4d/regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", size = 797049 }, - { url = "https://files.pythonhosted.org/packages/ef/1c/ea200f61ce9f341763f2717ab4daebe4422d83e9fd4ac5e33435fd3a148d/regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", size = 784144 }, - { url = "https://files.pythonhosted.org/packages/d8/5c/d2429be49ef3292def7688401d3deb11702c13dcaecdc71d2b407421275b/regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", size = 782483 }, - { url = "https://files.pythonhosted.org/packages/12/d9/cbc30f2ff7164f3b26a7760f87c54bf8b2faed286f60efd80350a51c5b99/regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", size = 790320 }, - { url = "https://files.pythonhosted.org/packages/19/1d/43ed03a236313639da5a45e61bc553c8d41e925bcf29b0f8ecff0c2c3f25/regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", size = 860435 }, - { url = "https://files.pythonhosted.org/packages/34/4f/5d04da61c7c56e785058a46349f7285ae3ebc0726c6ea7c5c70600a52233/regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", size = 859571 }, - { url = "https://files.pythonhosted.org/packages/12/7f/8398c8155a3c70703a8e91c29532558186558e1aea44144b382faa2a6f7a/regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", size = 787398 }, - { url = "https://files.pythonhosted.org/packages/58/3a/f5903977647a9a7e46d5535e9e96c194304aeeca7501240509bde2f9e17f/regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", size = 262035 }, - { url = "https://files.pythonhosted.org/packages/ff/80/51ba3a4b7482f6011095b3a036e07374f64de180b7d870b704ed22509002/regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", size = 273510 }, ] [[package]] @@ -3912,19 +3761,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/2d/5536d28c507a4679179ab15aa0049440e4d3dd6752050fa0843ed11e9354/rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", size = 528807 }, { url = "https://files.pythonhosted.org/packages/e3/62/7ebe6ec0d3dd6130921f8cffb7e34afb7f71b3819aa0446a24c5e81245ec/rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", size = 200993 }, { url = "https://files.pythonhosted.org/packages/ec/2f/b938864d66b86a6e4acadefdc56de75ef56f7cafdfd568a6464605457bd5/rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", size = 214458 }, - { url = "https://files.pythonhosted.org/packages/99/32/43b919a0a423c270a838ac2726b1c7168b946f2563fd99a51aaa9692d00f/rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", size = 321465 }, - { url = "https://files.pythonhosted.org/packages/58/a9/c4d899cb28e9e47b0ff12462e8f827381f243176036f17bef9c1604667f2/rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", size = 312900 }, - { url = "https://files.pythonhosted.org/packages/8f/90/9e51670575b5dfaa8c823369ef7d943087bfb73d4f124a99ad6ef19a2b26/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", size = 370973 }, - { url = "https://files.pythonhosted.org/packages/fc/c1/523f2a03f853fc0d4c1acbef161747e9ab7df0a8abf6236106e333540921/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", size = 370890 }, - { url = "https://files.pythonhosted.org/packages/51/ca/2458a771f16b0931de4d384decbe43016710bc948036c8f4562d6e063437/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", size = 397174 }, - { url = "https://files.pythonhosted.org/packages/00/7d/6e06807f6305ea2408b364efb0eef83a6e21b5e7b5267ad6b473b9a7e416/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", size = 426449 }, - { url = "https://files.pythonhosted.org/packages/8c/d1/6c9e65260a819a1714510a7d69ac1d68aa23ee9ce8a2d9da12187263c8fc/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", size = 357698 }, - { url = "https://files.pythonhosted.org/packages/5d/fb/ecea8b5286d2f03eec922be7173a03ed17278944f7c124348f535116db15/rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", size = 378530 }, - { url = "https://files.pythonhosted.org/packages/e3/e3/ac72f858957f52a109c588589b73bd2fad4a0fc82387fb55fb34aeb0f9cd/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", size = 545753 }, - { url = "https://files.pythonhosted.org/packages/b2/a4/a27683b519d5fc98e4390a3b130117d80fd475c67aeda8aac83c0e8e326a/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", size = 552443 }, - { url = "https://files.pythonhosted.org/packages/a1/ed/c074d248409b4432b1ccb2056974175fa0af2d1bc1f9c21121f80a358fa3/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", size = 528380 }, - { url = "https://files.pythonhosted.org/packages/d5/bd/04caf938895d2d78201e89c0c8a94dfd9990c34a19ff52fb01d0912343e3/rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", size = 200540 }, - { url = "https://files.pythonhosted.org/packages/95/cc/109eb8b9863680411ae703664abacaa035820c7755acc9686d5dd02cdd2e/rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", size = 214111 }, { url = "https://files.pythonhosted.org/packages/06/39/bf1f664c347c946ef56cecaa896e3693d91acc741afa78ebb3fdb7aba08b/rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", size = 319444 }, { url = "https://files.pythonhosted.org/packages/c1/71/876135d3cb90d62468540b84e8e83ff4dc92052ab309bfdea7ea0b9221ad/rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", size = 311699 }, { url = "https://files.pythonhosted.org/packages/f7/da/8ccaeba6a3dda7467aebaf893de9eafd56275e2c90773c83bf15fb0b8374/rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", size = 367825 }, @@ -4111,12 +3947,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/7d/9a57e187cbf2fbbbdfd4044a4f9ce141c8d221f9963750d3b001f0ec080d/shapely-2.0.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98fea108334be345c283ce74bf064fa00cfdd718048a8af7343c59eb40f59726", size = 2524835 }, { url = "https://files.pythonhosted.org/packages/6d/0a/f407509ab56825f39bf8cfce1fb410238da96cf096809c3e404e5bc71ea1/shapely-2.0.6-cp312-cp312-win32.whl", hash = "sha256:42fd4cd4834747e4990227e4cbafb02242c0cffe9ce7ef9971f53ac52d80d55f", size = 1295613 }, { url = "https://files.pythonhosted.org/packages/7b/b3/857afd9dfbfc554f10d683ac412eac6fa260d1f4cd2967ecb655c57e831a/shapely-2.0.6-cp312-cp312-win_amd64.whl", hash = "sha256:665990c84aece05efb68a21b3523a6b2057e84a1afbef426ad287f0796ef8a48", size = 1442539 }, - { url = "https://files.pythonhosted.org/packages/34/e8/d164ef5b0eab86088cde06dee8415519ffd5bb0dd1bd9d021e640e64237c/shapely-2.0.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:42805ef90783ce689a4dde2b6b2f261e2c52609226a0438d882e3ced40bb3013", size = 1445344 }, - { url = "https://files.pythonhosted.org/packages/ce/e2/9fba7ac142f7831757a10852bfa465683724eadbc93d2d46f74a16f9af04/shapely-2.0.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6d2cb146191a47bd0cee8ff5f90b47547b82b6345c0d02dd8b25b88b68af62d7", size = 1296182 }, - { url = "https://files.pythonhosted.org/packages/cf/dc/790d4bda27d196cd56ec66975eaae3351c65614cafd0e16ddde39ec9fb92/shapely-2.0.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3fdef0a1794a8fe70dc1f514440aa34426cc0ae98d9a1027fb299d45741c381", size = 2423426 }, - { url = "https://files.pythonhosted.org/packages/af/b0/f8169f77eac7392d41e231911e0095eb1148b4d40c50ea9e34d999c89a7e/shapely-2.0.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c665a0301c645615a107ff7f52adafa2153beab51daf34587170d85e8ba6805", size = 2513249 }, - { url = "https://files.pythonhosted.org/packages/f6/1d/a8c0e9ab49ff2f8e4dedd71b0122eafb22a18ad7e9d256025e1f10c84704/shapely-2.0.6-cp313-cp313-win32.whl", hash = "sha256:0334bd51828f68cd54b87d80b3e7cee93f249d82ae55a0faf3ea21c9be7b323a", size = 1294848 }, - { url = "https://files.pythonhosted.org/packages/23/38/2bc32dd1e7e67a471d4c60971e66df0bdace88656c47a9a728ace0091075/shapely-2.0.6-cp313-cp313-win_amd64.whl", hash = "sha256:d37d070da9e0e0f0a530a621e17c0b8c3c9d04105655132a87cfff8bd77cc4c2", size = 1441371 }, ] [[package]] @@ -4670,9 +4500,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/9b/8b206a928c188fdeb7b12e1c795199534cd44bdef223b8470129016009dd/watchdog-5.0.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d11b07c64f63f49876e0ab8042ae034674c8653bfcdaa8c4b32e71cfff87e8", size = 96739 }, { url = "https://files.pythonhosted.org/packages/e1/26/129ca9cd0f8016672f37000010c2fedc0b86816e894ebdc0af9bb04a6439/watchdog-5.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:349c9488e1d85d0a58e8cb14222d2c51cbc801ce11ac3936ab4c3af986536926", size = 88708 }, { url = "https://files.pythonhosted.org/packages/8f/b3/5e10ec32f0c429cdb55b1369066d6e83faf9985b3a53a4e37bb5c5e29aa0/watchdog-5.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:53a3f10b62c2d569e260f96e8d966463dec1a50fa4f1b22aec69e3f91025060e", size = 89309 }, - { url = "https://files.pythonhosted.org/packages/54/c4/49af4ab00bcfb688e9962eace2edda07a2cf89b9699ea536da48e8585cff/watchdog-5.0.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:950f531ec6e03696a2414b6308f5c6ff9dab7821a768c9d5788b1314e9a46ca7", size = 96740 }, - { url = "https://files.pythonhosted.org/packages/96/a4/b24de77cc9ae424c1687c9d4fb15aa560d7d7b28ba559aca72f781d0202b/watchdog-5.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6deb336cba5d71476caa029ceb6e88047fc1dc74b62b7c4012639c0b563906", size = 88711 }, - { url = "https://files.pythonhosted.org/packages/a4/71/3f2e9fe8403386b99d788868955b3a790f7a09721501a7e1eb58f514ffaa/watchdog-5.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1021223c08ba8d2d38d71ec1704496471ffd7be42cfb26b87cd5059323a389a1", size = 89319 }, { url = "https://files.pythonhosted.org/packages/a2/d6/1d1ca81c75d903eca3fdb7061d93845485b58a5ba182d146843b88fc51c2/watchdog-5.0.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:90a67d7857adb1d985aca232cc9905dd5bc4803ed85cfcdcfcf707e52049eda7", size = 88172 }, { url = "https://files.pythonhosted.org/packages/47/bb/d5e0abcfd6d729029a24766682e062526db8b59e9ae0c94aff509e0fd2b9/watchdog-5.0.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:720ef9d3a4f9ca575a780af283c8fd3a0674b307651c1976714745090da5a9e8", size = 88644 }, { url = "https://files.pythonhosted.org/packages/60/33/7cb71c9df9a77b6927ee5f48d25e1de5562ce0fa7e0c56dcf2b0472e64a2/watchdog-5.0.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dd021efa85970bd4824acacbb922066159d0f9e546389a4743d56919b6758b91", size = 79335 }, @@ -4734,18 +4561,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/44/81/1f701323a9f70805bc81c74c990137123344a80ea23ab9504a99492907f8/watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444", size = 264109 }, { url = "https://files.pythonhosted.org/packages/b4/0b/32cde5bc2ebd9f351be326837c61bdeb05ad652b793f25c91cac0b48a60b/watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", size = 277055 }, { url = "https://files.pythonhosted.org/packages/4b/81/daade76ce33d21dbec7a15afd7479de8db786e5f7b7d249263b4ea174e08/watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", size = 266169 }, - { url = "https://files.pythonhosted.org/packages/30/dc/6e9f5447ae14f645532468a84323a942996d74d5e817837a5c8ce9d16c69/watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", size = 373764 }, - { url = "https://files.pythonhosted.org/packages/79/c0/c3a9929c372816c7fc87d8149bd722608ea58dc0986d3ef7564c79ad7112/watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", size = 367873 }, - { url = "https://files.pythonhosted.org/packages/2e/11/ff9a4445a7cfc1c98caf99042df38964af12eed47d496dd5d0d90417349f/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", size = 438381 }, - { url = "https://files.pythonhosted.org/packages/48/a3/763ba18c98211d7bb6c0f417b2d7946d346cdc359d585cc28a17b48e964b/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", size = 432809 }, - { url = "https://files.pythonhosted.org/packages/30/4c/616c111b9d40eea2547489abaf4ffc84511e86888a166d3a4522c2ba44b5/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", size = 451801 }, - { url = "https://files.pythonhosted.org/packages/b6/be/d7da83307863a422abbfeb12903a76e43200c90ebe5d6afd6a59d158edea/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", size = 468886 }, - { url = "https://files.pythonhosted.org/packages/1d/d3/3dfe131ee59d5e90b932cf56aba5c996309d94dafe3d02d204364c23461c/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", size = 472973 }, - { url = "https://files.pythonhosted.org/packages/42/6c/279288cc5653a289290d183b60a6d80e05f439d5bfdfaf2d113738d0f932/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", size = 425282 }, - { url = "https://files.pythonhosted.org/packages/d6/d7/58afe5e85217e845edf26d8780c2d2d2ae77675eeb8d1b8b8121d799ce52/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", size = 612540 }, - { url = "https://files.pythonhosted.org/packages/6d/d5/b96eeb9fe3fda137200dd2f31553670cbc731b1e13164fd69b49870b76ec/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18", size = 593625 }, - { url = "https://files.pythonhosted.org/packages/c1/e5/c326fe52ee0054107267608d8cea275e80be4455b6079491dfd9da29f46f/watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07", size = 263899 }, - { url = "https://files.pythonhosted.org/packages/a6/8b/8a7755c5e7221bb35fe4af2dc44db9174f90ebf0344fd5e9b1e8b42d381e/watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", size = 276622 }, { url = "https://files.pythonhosted.org/packages/df/94/1ad200e937ec91b2a9d6b39ae1cf9c2b1a9cc88d5ceb43aa5c6962eb3c11/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", size = 376986 }, { url = "https://files.pythonhosted.org/packages/ee/fd/d9e020d687ccf90fe95efc513fbb39a8049cf5a3ff51f53c59fcf4c47a5d/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", size = 369445 }, { url = "https://files.pythonhosted.org/packages/43/cb/c0279b35053555d10ef03559c5aebfcb0c703d9c70a7b4e532df74b9b0e8/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", size = 439383 }, @@ -4818,17 +4633,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5c/f1/a29dd6046d3a722d26f182b783a7997d25298873a14028c4760347974ea3/websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", size = 164686 }, { url = "https://files.pythonhosted.org/packages/0f/99/ab1cdb282f7e595391226f03f9b498f52109d25a2ba03832e21614967dfa/websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", size = 158712 }, { url = "https://files.pythonhosted.org/packages/46/93/e19160db48b5581feac8468330aa11b7292880a94a37d7030478596cc14e/websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", size = 159145 }, - { url = "https://files.pythonhosted.org/packages/51/20/2b99ca918e1cbd33c53db2cace5f0c0cd8296fc77558e1908799c712e1cd/websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", size = 157828 }, - { url = "https://files.pythonhosted.org/packages/b8/47/0932a71d3d9c0e9483174f60713c84cee58d62839a143f21a2bcdbd2d205/websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", size = 155487 }, - { url = "https://files.pythonhosted.org/packages/a9/60/f1711eb59ac7a6c5e98e5637fef5302f45b6f76a2c9d64fd83bbb341377a/websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", size = 155721 }, - { url = "https://files.pythonhosted.org/packages/6a/e6/ba9a8db7f9d9b0e5f829cf626ff32677f39824968317223605a6b419d445/websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", size = 165609 }, - { url = "https://files.pythonhosted.org/packages/c1/22/4ec80f1b9c27a0aebd84ccd857252eda8418ab9681eb571b37ca4c5e1305/websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", size = 164556 }, - { url = "https://files.pythonhosted.org/packages/27/ac/35f423cb6bb15600438db80755609d27eda36d4c0b3c9d745ea12766c45e/websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", size = 164993 }, - { url = "https://files.pythonhosted.org/packages/31/4e/98db4fd267f8be9e52e86b6ee4e9aa7c42b83452ea0ea0672f176224b977/websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", size = 165360 }, - { url = "https://files.pythonhosted.org/packages/3f/15/3f0de7cda70ffc94b7e7024544072bc5b26e2c1eb36545291abb755d8cdb/websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", size = 164745 }, - { url = "https://files.pythonhosted.org/packages/a1/6e/66b6b756aebbd680b934c8bdbb6dcb9ce45aad72cde5f8a7208dbb00dd36/websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", size = 164732 }, - { url = "https://files.pythonhosted.org/packages/35/c6/12e3aab52c11aeb289e3dbbc05929e7a9d90d7a9173958477d3ef4f8ce2d/websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", size = 158709 }, - { url = "https://files.pythonhosted.org/packages/41/d8/63d6194aae711d7263df4498200c690a9c39fb437ede10f3e157a6343e0d/websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", size = 159144 }, { url = "https://files.pythonhosted.org/packages/2d/75/6da22cb3ad5b8c606963f9a5f9f88656256fecc29d420b4b2bf9e0c7d56f/websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", size = 155499 }, { url = "https://files.pythonhosted.org/packages/c0/ba/22833d58629088fcb2ccccedfae725ac0bbcd713319629e97125b52ac681/websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", size = 155737 }, { url = "https://files.pythonhosted.org/packages/95/54/61684fe22bdb831e9e1843d972adadf359cf04ab8613285282baea6a24bb/websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", size = 157095 }, @@ -4944,21 +4748,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/17/48637d4ddcb606f5591afee78d060eab70e172e14766e1fd23453bfed846/yarl-1.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4feaaa4742517eaceafcbe74595ed335a494c84634d33961214b278126ec1485", size = 502397 }, { url = "https://files.pythonhosted.org/packages/83/2c/7392645dc1c9eeb8a5485696302a33e3d59bea8a448c8e2f36f98a728e0a/yarl-1.13.1-cp312-cp312-win32.whl", hash = "sha256:bbf9c2a589be7414ac4a534d54e4517d03f1cbb142c0041191b729c2fa23f320", size = 102343 }, { url = "https://files.pythonhosted.org/packages/9c/c0/7329799080d7e0bf7b10db417900701ba6810e78a249aef1f4bf3fc2cccb/yarl-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:d07b52c8c450f9366c34aa205754355e933922c79135125541daae6cbf31c799", size = 111719 }, - { url = "https://files.pythonhosted.org/packages/d3/d2/9542e6207a6e64c32b14b2d9ca4fad6ff80310fc75e70cdbe31680a758c2/yarl-1.13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:95c6737f28069153c399d875317f226bbdea939fd48a6349a3b03da6829fb550", size = 186266 }, - { url = "https://files.pythonhosted.org/packages/8b/68/4c6d1aacbc23a05e84c3fab7aaa68c5a7d4531290021c2370fa1e5524fb1/yarl-1.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cd66152561632ed4b2a9192e7f8e5a1d41e28f58120b4761622e0355f0fe034c", size = 114268 }, - { url = "https://files.pythonhosted.org/packages/ed/87/6ad8e22c918d745092329ec427c0778b5c85ffd5b805e38750024b7464f2/yarl-1.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6a2acde25be0cf9be23a8f6cbd31734536a264723fca860af3ae5e89d771cd71", size = 112164 }, - { url = "https://files.pythonhosted.org/packages/ca/5b/c6c4ac4be1edea6759f05ad74d87a1c61329737bdb90da5f66e188310461/yarl-1.13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a18595e6a2ee0826bf7dfdee823b6ab55c9b70e8f80f8b77c37e694288f5de1", size = 471437 }, - { url = "https://files.pythonhosted.org/packages/c1/5c/ec7f0121a5fa67ee76325e1aaa27470d5521d80a25aa1bad5dde773edbe1/yarl-1.13.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a31d21089894942f7d9a8df166b495101b7258ff11ae0abec58e32daf8088813", size = 485894 }, - { url = "https://files.pythonhosted.org/packages/d7/e8/624fc8082cbff62c537798ce837a6044f70e2e00472ab719deb376ff6e39/yarl-1.13.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45f209fb4bbfe8630e3d2e2052535ca5b53d4ce2d2026bed4d0637b0416830da", size = 486702 }, - { url = "https://files.pythonhosted.org/packages/dc/18/013f7d2e3f0ff28b85299ed19164f899ea4f02da8812621a40937428bf48/yarl-1.13.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f722f30366474a99745533cc4015b1781ee54b08de73260b2bbe13316079851", size = 478911 }, - { url = "https://files.pythonhosted.org/packages/d7/3c/5b628939e3a22fb9375df453188e97190d21f6244c49637e19799896cd41/yarl-1.13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3bf60444269345d712838bb11cc4eadaf51ff1a364ae39ce87a5ca8ad3bb2c8", size = 456488 }, - { url = "https://files.pythonhosted.org/packages/8b/2b/a3548db86510c1d95bff344c1c588b84582eeb3a55ea15a149a24d7069f0/yarl-1.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:942c80a832a79c3707cca46bd12ab8aa58fddb34b1626d42b05aa8f0bcefc206", size = 475016 }, - { url = "https://files.pythonhosted.org/packages/d8/e2/e2a540f18f849909e3ee594766bf7b0a7fde176ff0cfb2f95121033752e2/yarl-1.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:44b07e1690f010c3c01d353b5790ec73b2f59b4eae5b0000593199766b3f7a5c", size = 477521 }, - { url = "https://files.pythonhosted.org/packages/3a/df/4cda4052da48a57ce4f20a0849b7344902aa3e149a0b409525509fc43985/yarl-1.13.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:396e59b8de7e4d59ff5507fb4322d2329865b909f29a7ed7ca37e63ade7f835c", size = 492000 }, - { url = "https://files.pythonhosted.org/packages/bf/b6/180dbb0aa846cafb9ce89bd33c477e200dd00072c7775372f34651c20b9a/yarl-1.13.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3bb83a0f12701c0b91112a11148b5217617982e1e466069d0555be9b372f2734", size = 502195 }, - { url = "https://files.pythonhosted.org/packages/ff/37/e97c280344342e326a1860a70054a0488c379e8937325f97f9a9fe6b453d/yarl-1.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c92b89bffc660f1274779cb6fbb290ec1f90d6dfe14492523a0667f10170de26", size = 492892 }, - { url = "https://files.pythonhosted.org/packages/ed/97/cd35f39ba8183ef193a6709aa0b2fcaabebd6915202d6999b01fa630b2bb/yarl-1.13.1-cp313-cp313-win32.whl", hash = "sha256:269c201bbc01d2cbba5b86997a1e0f73ba5e2f471cfa6e226bcaa7fd664b598d", size = 486463 }, - { url = "https://files.pythonhosted.org/packages/05/33/bd9d33503a0f73d095b01ed438423b924e6786e90102ca4912e573cc5aa3/yarl-1.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:1d0828e17fa701b557c6eaed5edbd9098eb62d8838344486248489ff233998b8", size = 493804 }, { url = "https://files.pythonhosted.org/packages/74/81/419c24f7c94f56b96d04955482efb5b381635ad265b5b7fbab333a9dfde3/yarl-1.13.1-py3-none-any.whl", hash = "sha256:6a5185ad722ab4dd52d5fb1f30dcc73282eb1ed494906a92d1a228d3f89607b0", size = 39862 }, ] From 81ae07abdb8a137a4f79be22380110f508cda23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moura?= Date: Fri, 18 Oct 2024 07:13:17 -0300 Subject: [PATCH 04/19] preparing new version --- pyproject.toml | 4 +- src/crewai/__init__.py | 2 +- src/crewai/cli/create_crew.py | 24 +- src/crewai/cli/templates/crew/pyproject.toml | 2 +- src/crewai/cli/templates/flow/pyproject.toml | 2 +- .../cli/templates/pipeline/pyproject.toml | 2 +- .../templates/pipeline_router/pyproject.toml | 2 +- src/crewai/cli/templates/tool/pyproject.toml | 2 +- uv.lock | 295 +++++++++++++++--- 9 files changed, 281 insertions(+), 54 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c547249a5..e47748e28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "crewai" -version = "0.70.1" +version = "0.74.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.13" @@ -16,7 +16,7 @@ dependencies = [ "opentelemetry-exporter-otlp-proto-http>=1.22.0", "instructor>=1.3.3", "regex>=2024.9.11", - "crewai-tools>=0.12.1", + "crewai-tools>=0.13.1", "click>=8.1.7", "python-dotenv>=1.0.0", "appdirs>=1.4.4", diff --git a/src/crewai/__init__.py b/src/crewai/__init__.py index d237ad2a4..a72d6e805 100644 --- a/src/crewai/__init__.py +++ b/src/crewai/__init__.py @@ -14,5 +14,5 @@ warnings.filterwarnings( category=UserWarning, module="pydantic.main", ) -__version__ = "0.70.1" +__version__ = "0.74.0" __all__ = ["Agent", "Crew", "Process", "Task", "Pipeline", "Router", "LLM", "Flow"] diff --git a/src/crewai/cli/create_crew.py b/src/crewai/cli/create_crew.py index 23088cb58..f74331a23 100644 --- a/src/crewai/cli/create_crew.py +++ b/src/crewai/cli/create_crew.py @@ -1,9 +1,10 @@ from pathlib import Path import click -from crewai.cli.utils import copy_template,load_env_vars, write_env_file -from crewai.cli.provider import get_provider_data, select_provider, select_model, PROVIDERS +from crewai.cli.utils import copy_template, load_env_vars, write_env_file +from crewai.cli.provider import get_provider_data, select_provider, PROVIDERS from crewai.cli.constants import ENV_VARS + def create_folder_structure(name, parent_folder=None): folder_name = name.replace(" ", "_").replace("-", "_").lower() class_name = name.replace("_", " ").replace("-", " ").title().replace(" ", "") @@ -35,7 +36,6 @@ def create_folder_structure(name, parent_folder=None): return folder_path, folder_name, class_name - def copy_template_files(folder_path, name, class_name, parent_folder): package_dir = Path(__file__).parent templates_dir = package_dir / "templates" / "crew" @@ -54,7 +54,9 @@ def copy_template_files(folder_path, name, class_name, parent_folder): dst_file = folder_path / file_name copy_template(src_file, dst_file, name, class_name, folder_path.name) - src_folder = folder_path / "src" / folder_path.name if not parent_folder else folder_path + src_folder = ( + folder_path / "src" / folder_path.name if not parent_folder else folder_path + ) for file_name in src_template_files: src_file = templates_dir / file_name @@ -81,24 +83,24 @@ def create_crew(name, parent_folder=None): return provider = selected_provider - selected_model = select_model(provider, provider_models) - if not selected_model: - return - model = selected_model + # selected_model = select_model(provider, provider_models) + # if not selected_model: + # return + # model = selected_model if provider in PROVIDERS: api_key_var = ENV_VARS[provider][0] else: api_key_var = click.prompt( f"Enter the environment variable name for your {provider.capitalize()} API key", - type=str + type=str, ) env_vars = {api_key_var: "YOUR_API_KEY_HERE"} write_env_file(folder_path, env_vars) - env_vars['MODEL'] = model - click.secho(f"Selected model: {model}", fg="green") + # env_vars['MODEL'] = model + # click.secho(f"Selected model: {model}", fg="green") package_dir = Path(__file__).parent templates_dir = package_dir / "templates" / "crew" diff --git a/src/crewai/cli/templates/crew/pyproject.toml b/src/crewai/cli/templates/crew/pyproject.toml index 54bb2ad34..d387443a1 100644 --- a/src/crewai/cli/templates/crew/pyproject.toml +++ b/src/crewai/cli/templates/crew/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.67.1,<1.0.0" + "crewai[tools]>=0.74.0,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/flow/pyproject.toml b/src/crewai/cli/templates/flow/pyproject.toml index 476d24f44..9db16e2a2 100644 --- a/src/crewai/cli/templates/flow/pyproject.toml +++ b/src/crewai/cli/templates/flow/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.67.1,<1.0.0", + "crewai[tools]>=0.74.0,<1.0.0", "asyncio" ] diff --git a/src/crewai/cli/templates/pipeline/pyproject.toml b/src/crewai/cli/templates/pipeline/pyproject.toml index 933f62d89..3eb9b73d1 100644 --- a/src/crewai/cli/templates/pipeline/pyproject.toml +++ b/src/crewai/cli/templates/pipeline/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Your Name "] [tool.poetry.dependencies] python = ">=3.10,<=3.13" -crewai = { extras = ["tools"], version = ">=0.70.1,<1.0.0" } +crewai = { extras = ["tools"], version = ">=0.74.0,<1.0.0" } asyncio = "*" [tool.poetry.scripts] diff --git a/src/crewai/cli/templates/pipeline_router/pyproject.toml b/src/crewai/cli/templates/pipeline_router/pyproject.toml index 3bc64ee00..dabc8d281 100644 --- a/src/crewai/cli/templates/pipeline_router/pyproject.toml +++ b/src/crewai/cli/templates/pipeline_router/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = ["Your Name "] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.67.1,<1.0.0" + "crewai[tools]>=0.74.0,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/tool/pyproject.toml b/src/crewai/cli/templates/tool/pyproject.toml index a5b2ece4f..0fef250f5 100644 --- a/src/crewai/cli/templates/tool/pyproject.toml +++ b/src/crewai/cli/templates/tool/pyproject.toml @@ -5,6 +5,6 @@ description = "Power up your crews with {{folder_name}}" readme = "README.md" requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.70.1" + "crewai[tools]>=0.74.0" ] diff --git a/uv.lock b/uv.lock index da2f684ed..b0416fa72 100644 --- a/uv.lock +++ b/uv.lock @@ -94,6 +94,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cf/b7/50cc827dd54df087d7c30293b29fbc13a7ea45a3ac54a4a12127b271265c/aiohttp-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c6769d71bfb1ed60321363a9bc05e94dcf05e38295ef41d46ac08919e5b00d19", size = 1306007 }, { url = "https://files.pythonhosted.org/packages/1e/c0/a4cb21ad677757368743d73aff27047dfc0d7248cb39dec06c059b773c24/aiohttp-3.10.8-cp312-cp312-win32.whl", hash = "sha256:a3081246bab4d419697ee45e555cef5cd1def7ac193dff6f50be761d2e44f194", size = 359125 }, { url = "https://files.pythonhosted.org/packages/d2/0f/1ecbc18eed29952393d5a9c4636bfe789dde3c98fe0a0a4759d323478e72/aiohttp-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:ab1546fc8e00676febc81c548a876c7bde32f881b8334b77f84719ab2c7d28dc", size = 379143 }, + { url = "https://files.pythonhosted.org/packages/9f/dd/3d944769ed65d3d245f8f976040654b3eae2e21d05c81f91fb450365bddf/aiohttp-3.10.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:b1a012677b8e0a39e181e218de47d6741c5922202e3b0b65e412e2ce47c39337", size = 575934 }, + { url = "https://files.pythonhosted.org/packages/2a/bf/a6a1d14b0e5f90d53b1f0850204f9fafdfec7c1d99dda8aaea1dd93ba181/aiohttp-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2df786c96c57cd6b87156ba4c5f166af7b88f3fc05f9d592252fdc83d8615a3c", size = 391728 }, + { url = "https://files.pythonhosted.org/packages/0e/1b/27cc6efa6ca3e563973c7e03e8b7e26b75b4046aefea991bad42c028a906/aiohttp-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8885ca09d3a9317219c0831276bfe26984b17b2c37b7bf70dd478d17092a4772", size = 387247 }, + { url = "https://files.pythonhosted.org/packages/ae/fd/235401bd4a98ea31cdda7b3822921e2a9cbc3ca0af1958a12a2709261735/aiohttp-3.10.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dbf252ac19860e0ab56cd480d2805498f47c5a2d04f5995d8d8a6effd04b48c", size = 1286909 }, + { url = "https://files.pythonhosted.org/packages/ab/1c/8ae6b12be2ae88e94be34d96765d6cc820d61d320f33c0423de8af0cfa47/aiohttp-3.10.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2036479b6b94afaaca7d07b8a68dc0e67b0caf5f6293bb6a5a1825f5923000", size = 1323446 }, + { url = "https://files.pythonhosted.org/packages/23/09/5ebe3a2dbdd008711b659dc2f2a6135bbc055b6c8869688083f4bec6b50a/aiohttp-3.10.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:365783e1b7c40b59ed4ce2b5a7491bae48f41cd2c30d52647a5b1ee8604c68ad", size = 1368237 }, + { url = "https://files.pythonhosted.org/packages/47/22/f184c27d03d34ce71e6d4b9976a4ff845d091b725f174b09f641e4a28f63/aiohttp-3.10.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:270e653b5a4b557476a1ed40e6b6ce82f331aab669620d7c95c658ef976c9c5e", size = 1282598 }, + { url = "https://files.pythonhosted.org/packages/82/f6/bae1703bfacb19bb35e3522632fc5279793070625a0b5e567b109c0f0e8d/aiohttp-3.10.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8960fabc20bfe4fafb941067cda8e23c8c17c98c121aa31c7bf0cdab11b07842", size = 1236350 }, + { url = "https://files.pythonhosted.org/packages/a4/bc/ad73aced93836b8749c70e617c5d389d17a36da9ee220cdb0804f803bd9b/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f21e8f2abed9a44afc3d15bba22e0dfc71e5fa859bea916e42354c16102b036f", size = 1250172 }, + { url = "https://files.pythonhosted.org/packages/3b/18/027a8497caf3a9c247477831d67ede58e1e42a92fd635ecdb74cf5d45c8b/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fecd55e7418fabd297fd836e65cbd6371aa4035a264998a091bbf13f94d9c44d", size = 1248783 }, + { url = "https://files.pythonhosted.org/packages/6f/d2/5080c27b656e6d478e820752d633d7a4dab4a2c4fd23a6f645b553fb9da5/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:badb51d851358cd7535b647bb67af4854b64f3c85f0d089c737f75504d5910ec", size = 1293209 }, + { url = "https://files.pythonhosted.org/packages/ae/ec/c38c8690e804cb9bf3e8c473a4a7bb339ed549cd63c469f19995269ca9ec/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e860985f30f3a015979e63e7ba1a391526cdac1b22b7b332579df7867848e255", size = 1319943 }, + { url = "https://files.pythonhosted.org/packages/df/55/d6e3a13c3f37ad7a3e60a377c96541261c1943837d240f1ab2151a96da6b/aiohttp-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:71462f8eeca477cbc0c9700a9464e3f75f59068aed5e9d4a521a103692da72dc", size = 1281380 }, + { url = "https://files.pythonhosted.org/packages/c3/31/0b84027487fa58a124251b47f9dca781e4777a50d1c4eea4d3fc8950bd10/aiohttp-3.10.8-cp313-cp313-win32.whl", hash = "sha256:177126e971782769b34933e94fddd1089cef0fe6b82fee8a885e539f5b0f0c6a", size = 357352 }, + { url = "https://files.pythonhosted.org/packages/cb/8a/b4f3a8d0fb7f4fdb3869db6c3334e23e11878123605579e067be85f7e01f/aiohttp-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:98a4eb60e27033dee9593814ca320ee8c199489fbc6b2699d0f710584db7feb7", size = 376618 }, ] [[package]] @@ -409,6 +424,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, ] [[package]] @@ -601,7 +627,7 @@ wheels = [ [[package]] name = "crewai" -version = "0.70.1" +version = "0.74.0" source = { editable = "." } dependencies = [ { name = "appdirs" }, @@ -661,7 +687,7 @@ requires-dist = [ { name = "auth0-python", specifier = ">=4.7.1" }, { name = "chromadb", specifier = ">=0.4.24" }, { name = "click", specifier = ">=8.1.7" }, - { name = "crewai-tools", specifier = ">=0.12.1" }, + { name = "crewai-tools", specifier = ">=0.13.1" }, { name = "crewai-tools", marker = "extra == 'tools'", specifier = ">=0.12.1" }, { name = "instructor", specifier = ">=1.3.3" }, { name = "json-repair", specifier = ">=0.25.2" }, @@ -702,7 +728,7 @@ dev = [ [[package]] name = "crewai-tools" -version = "0.12.1" +version = "0.13.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "beautifulsoup4" }, @@ -720,9 +746,9 @@ dependencies = [ { name = "requests" }, { name = "selenium" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/11/60/1860127d927939f9143cab9af059cfbe6f160839b6ba1d652a9ed4e04fa6/crewai_tools-0.12.1.tar.gz", hash = "sha256:22fa3ea57936913faed77a2a64c131371f78b2ced207e63dcc71220eac445698", size = 420190 } +sdist = { url = "https://files.pythonhosted.org/packages/d5/81/b8a0bb984aea2af49b0072e074c87c75a6c4581902b81f3a3d46f95f01c7/crewai_tools-0.13.1.tar.gz", hash = "sha256:363c7ec717f4c6f9b61cec9314a5ec2fbd026d75e8e6278f49f715ed5915cd4d", size = 816254 } wheels = [ - { url = "https://files.pythonhosted.org/packages/23/e6/cc9acbc6ee828898956b18036643fc2150b6c1b976ab34f29b9cadc085b5/crewai_tools-0.12.1-py3-none-any.whl", hash = "sha256:e87d393dd1900834a224686644e025eb44e74171f317c4ff2df778aff6ade4b8", size = 463435 }, + { url = "https://files.pythonhosted.org/packages/09/8a/04c885da3e01d1f11478dd866d3506906bfb60d7587627dd4b132ff10f64/crewai_tools-0.13.1-py3-none-any.whl", hash = "sha256:62067e2502bf66c0ae2e3a833c60b900bd1f793a9a80895a1f10a9cfa1b5dc3c", size = 463444 }, ] [[package]] @@ -893,7 +919,7 @@ wheels = [ [[package]] name = "embedchain" -version = "0.1.122" +version = "0.1.123" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "alembic" }, @@ -906,6 +932,7 @@ dependencies = [ { name = "langchain-cohere" }, { name = "langchain-community" }, { name = "langchain-openai" }, + { name = "langsmith" }, { name = "mem0ai" }, { name = "openai" }, { name = "posthog" }, @@ -917,9 +944,9 @@ dependencies = [ { name = "sqlalchemy" }, { name = "tiktoken" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/25/9b/fa14dc95f8736c672bcebd677f48990670f1a9fac8ea1631222b8b820d69/embedchain-0.1.122.tar.gz", hash = "sha256:ea0a4d00a4a1909e0d662dc499fa6a0da119783ec4773df1271da74da3e8296b", size = 124799 } +sdist = { url = "https://files.pythonhosted.org/packages/5d/6a/955b5a72fa6727db203c4d46ae0e30ac47f4f50389f663cd5ea157b0d819/embedchain-0.1.123.tar.gz", hash = "sha256:aecaf81c21de05b5cdb649b6cde95ef68ffa759c69c54f6ff2eaa667f2ad0580", size = 124797 } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/3f/42c97c1d3c9483076843987982a018115b6a28be02091fb475e6dbc743f2/embedchain-0.1.122-py3-none-any.whl", hash = "sha256:c137be81d0949b5ee16c689837d659837980cfabbb38643c2720cd1a794d8d27", size = 210911 }, + { url = "https://files.pythonhosted.org/packages/a7/51/0c78d26da4afbe68370306669556b274f1021cac02f3155d8da2be407763/embedchain-0.1.123-py3-none-any.whl", hash = "sha256:1210e993b6364d7c702b6bd44b053fc244dd77f2a65ea4b90b62709114ea6c25", size = 210909 }, ] [[package]] @@ -1309,6 +1336,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975 }, { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955 }, { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655 }, + { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 }, + { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 }, + { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 }, + { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 }, + { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 }, + { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 }, + { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 }, + { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 }, + { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 }, + { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 }, + { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 }, + { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 }, + { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 }, + { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 }, + { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 }, + { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, ] [[package]] @@ -1370,6 +1413,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ff/5f/142e19db367a34ea0ee8a8451e43215d0a1a5dbffcfdcae8801f22903301/grpcio-1.66.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49f0ca7ae850f59f828a723a9064cadbed90f1ece179d375966546499b8a2c9c", size = 6040273 }, { url = "https://files.pythonhosted.org/packages/5c/3b/12fcd752c55002e4b0e0a7bd5faec101bc0a4e3890be3f95a43353142481/grpcio-1.66.2-cp312-cp312-win32.whl", hash = "sha256:31fd163105464797a72d901a06472860845ac157389e10f12631025b3e4d0453", size = 3537988 }, { url = "https://files.pythonhosted.org/packages/f1/70/76bfea3faa862bfceccba255792e780691ff25b8227180759c9d38769379/grpcio-1.66.2-cp312-cp312-win_amd64.whl", hash = "sha256:ff1f7882e56c40b0d33c4922c15dfa30612f05fb785074a012f7cda74d1c3679", size = 4275553 }, + { url = "https://files.pythonhosted.org/packages/72/31/8708a8dfb3f1ac89926c27c5dd17412764157a2959dbc5a606eaf8ac71f6/grpcio-1.66.2-cp313-cp313-linux_armv7l.whl", hash = "sha256:3b00efc473b20d8bf83e0e1ae661b98951ca56111feb9b9611df8efc4fe5d55d", size = 5004245 }, + { url = "https://files.pythonhosted.org/packages/8b/37/0b57c3769efb3cc9ec97fcaa9f7243046660e7ed58c0faebc4ef315df92c/grpcio-1.66.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1caa38fb22a8578ab8393da99d4b8641e3a80abc8fd52646f1ecc92bcb8dee34", size = 10756749 }, + { url = "https://files.pythonhosted.org/packages/bf/5a/425e995724a19a1b110340ed653bc7c5de8019d9fc84b3798a0f79c3eb31/grpcio-1.66.2-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c408f5ef75cfffa113cacd8b0c0e3611cbfd47701ca3cdc090594109b9fcbaed", size = 5499666 }, + { url = "https://files.pythonhosted.org/packages/2e/e4/86a5c5ec40a6b683671a1d044ebca433812d99da8fcfc2889e9c43cecbd4/grpcio-1.66.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c806852deaedee9ce8280fe98955c9103f62912a5b2d5ee7e3eaa284a6d8d8e7", size = 6109578 }, + { url = "https://files.pythonhosted.org/packages/2f/86/a86742f3deaa22385c3bff984c5947fc62d47d3fab26c508730037d027e5/grpcio-1.66.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f145cc21836c332c67baa6fc81099d1d27e266401565bf481948010d6ea32d46", size = 5763274 }, + { url = "https://files.pythonhosted.org/packages/c3/61/b9a2a4345dea0a354c4ed8ac7aacbdd0ff986acbc8f92680213cf3d2faa3/grpcio-1.66.2-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:73e3b425c1e155730273f73e419de3074aa5c5e936771ee0e4af0814631fb30a", size = 6450416 }, + { url = "https://files.pythonhosted.org/packages/50/b9/ad303ce75d8cd71d855a661519aa160ce42f27498f589f1ae6d9f8c5e8ac/grpcio-1.66.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c509a4f78114cbc5f0740eb3d7a74985fd2eff022971bc9bc31f8bc93e66a3b", size = 6040045 }, + { url = "https://files.pythonhosted.org/packages/ac/b3/8db1873e3240ef1672ba87b89e949ece367089e29e4d221377bfdd288bd3/grpcio-1.66.2-cp313-cp313-win32.whl", hash = "sha256:20657d6b8cfed7db5e11b62ff7dfe2e12064ea78e93f1434d61888834bc86d75", size = 3537126 }, + { url = "https://files.pythonhosted.org/packages/a2/df/133216989fe7e17caeafd7ff5b17cc82c4e722025d0b8d5d2290c11fe2e6/grpcio-1.66.2-cp313-cp313-win_amd64.whl", hash = "sha256:fb70487c95786e345af5e854ffec8cb8cc781bcc5df7930c4fbb7feaa72e1cdf", size = 4278018 }, ] [[package]] @@ -1855,7 +1907,7 @@ wheels = [ [[package]] name = "langchain" -version = "0.2.16" +version = "0.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -1870,30 +1922,31 @@ dependencies = [ { name = "sqlalchemy" }, { name = "tenacity" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fd/53/8ebf21de8d17e7e0f0998f28d689f60d7ed420acb7ab2fba59ca04e80e54/langchain-0.2.16.tar.gz", hash = "sha256:ffb426a76a703b73ac69abad77cd16eaf03dda76b42cff55572f592d74944166", size = 414668 } +sdist = { url = "https://files.pythonhosted.org/packages/70/b2/258c6a33b5e5f817a57ecd22b1e74756f7246ac66f39d0cf6d2ef515fcb7/langchain-0.3.3.tar.gz", hash = "sha256:6435882996a029a60c61c356bbe51bab4a8f43a54210f5f03e3c4474d19d1842", size = 416891 } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/29/635343c0d155997569b544d26da5a2a9ebade2423baffc9cd6066b01a386/langchain-0.2.16-py3-none-any.whl", hash = "sha256:8f59ee8b45f268df4b924ea3b9c63e49286efa756d16b3f6a9de5c6e502c36e1", size = 1001195 }, + { url = "https://files.pythonhosted.org/packages/92/82/c17abaa44074ec716409305da4783f633b0eb9b09bb28ed5005220269bdb/langchain-0.3.3-py3-none-any.whl", hash = "sha256:05ac98c674853c2386d043172820e37ceac9b913aaaf1e51217f0fc424112c72", size = 1005176 }, ] [[package]] name = "langchain-cohere" -version = "0.1.9" +version = "0.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cohere" }, { name = "langchain-core" }, { name = "langchain-experimental" }, { name = "pandas" }, + { name = "pydantic" }, { name = "tabulate" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a4/a9/30462b68f8c15da886078fe5c96fab3085241168ea03d968eee1182e00a9/langchain_cohere-0.1.9.tar.gz", hash = "sha256:549620d23bc3d77f62d1045787095fe2c1cfa233dba69455139f9a2f65f952fa", size = 29987 } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ea/53fd2515e353cac4ddd6d7a41dbb0651dfc9ffb0924acb7a1aa7a722f29b/langchain_cohere-0.3.1.tar.gz", hash = "sha256:990bd4db68e229371c90eee98a1a78b4f4d33a32c22c8da6c2cd30b5044de9eb", size = 36739 } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/b1/ee8d44898cfe43703f05a0ffd95294d3ebe4c61879f19c6357c860131312/langchain_cohere-0.1.9-py3-none-any.whl", hash = "sha256:96d6a15125797319474ac84b54024e5024f3f5fc45032ebf228d95d6998c9b13", size = 35218 }, + { url = "https://files.pythonhosted.org/packages/64/5e/bbfb1b33703a973e7eef6582b523ae932e7e64c9b84ac7eecaa8af71475e/langchain_cohere-0.3.1-py3-none-any.whl", hash = "sha256:adf37542feb293562791b8dd1691580b0dcb2117fb987f2684f694912465f554", size = 43992 }, ] [[package]] name = "langchain-community" -version = "0.2.17" +version = "0.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -1902,19 +1955,20 @@ dependencies = [ { name = "langchain-core" }, { name = "langsmith" }, { name = "numpy" }, + { name = "pydantic-settings" }, { name = "pyyaml" }, { name = "requests" }, { name = "sqlalchemy" }, { name = "tenacity" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1f/54/be928e3962d24b40c31899f5c5ed99b0c7ef7c3bb7601eb2fe7a6ce75dc4/langchain_community-0.2.17.tar.gz", hash = "sha256:b0745c1fcf1bd532ed4388f90b47139d6a6c6ba48a87aa68aa32d4d6bb97259d", size = 1589425 } +sdist = { url = "https://files.pythonhosted.org/packages/86/6e/119bbbd4d55ab14dc6fc4a82a2466b88f7ddb989bdbdfcf96327c5daba4e/langchain_community-0.3.2.tar.gz", hash = "sha256:469bf5357a08c915cebc4c506dca4617eec737d82a9b6e340df5f3b814dc89bc", size = 1608524 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/33/c6ee472412f751062311075bb391a7870ab57cdb8da5d47f359895b2d3c2/langchain_community-0.2.17-py3-none-any.whl", hash = "sha256:d07c31b641e425fb8c3e7148ad6a62e1b54a9adac6e1173021a7dd3148266063", size = 2339964 }, + { url = "https://files.pythonhosted.org/packages/cc/57/a8b4826eaa29d3663c957251ab32275a0c178bdb0e262a1204ed820f430c/langchain_community-0.3.2-py3-none-any.whl", hash = "sha256:fffcd484c7674e81ceaa72a809962338bfb17ec8f9e0377ce4e9d884e6fe8ca5", size = 2367818 }, ] [[package]] name = "langchain-core" -version = "0.2.41" +version = "0.3.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -1925,48 +1979,48 @@ dependencies = [ { name = "tenacity" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/92/2ad97f0c23b5ee5043df1a93d97edd4404136003e7d22b641de081738408/langchain_core-0.2.41.tar.gz", hash = "sha256:bc12032c5a298d85be754ccb129bc13ea21ccb1d6e22f8d7ba18b8da64315bb5", size = 316952 } +sdist = { url = "https://files.pythonhosted.org/packages/7b/15/76ec101e550e7e16de85e64fcb4ff2d281cb70cfe65c95ee6e56182a5f51/langchain_core-0.3.12.tar.gz", hash = "sha256:98a3c078e375786aa84939bfd1111263af2f3bc402bbe2cac9fa18a387459cf2", size = 327019 } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/02/2b2cf9550cee1a7ffa42fe60c55e2d0e7d397535609b42562611fb40e78d/langchain_core-0.2.41-py3-none-any.whl", hash = "sha256:3278fda5ba9a05defae8bb19f1226032add6aab21917db7b3bc74e750e263e84", size = 397013 }, + { url = "https://files.pythonhosted.org/packages/ce/4a/a6499d93805c3e6316e641b6934e23c98c011d00b9a2138835d567e976e5/langchain_core-0.3.12-py3-none-any.whl", hash = "sha256:46050d34f5fa36dc57dca971c6a26f505643dd05ee0492c7ac286d0a78a82037", size = 407737 }, ] [[package]] name = "langchain-experimental" -version = "0.0.65" +version = "0.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-community" }, { name = "langchain-core" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/e0/d92210398a006f6e43ddd25166537f79cb3e9ccc32e316e70d349353842b/langchain_experimental-0.0.65.tar.gz", hash = "sha256:83706df07d8a7e6ec1bda74174add7e4431b5f4a8818e19b65986b94c9c99b25", size = 138516 } +sdist = { url = "https://files.pythonhosted.org/packages/bf/41/84d3eac564261aaab45bc02bdc43b5e49242439c6f2844a24b81404a17cd/langchain_experimental-0.3.2.tar.gz", hash = "sha256:d41cc28c46f58616d18a1230595929f80a58d1982c4053dc3afe7f1c03f22426", size = 139583 } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/ca/93913b7530b36869946ca8f93b161bea294ea46a367e748943a78bc3553c/langchain_experimental-0.0.65-py3-none-any.whl", hash = "sha256:2a0f268cfb8c79d43cedf9c4840f70bd8b25934e595311e6690804d0355dd7ee", size = 207160 }, + { url = "https://files.pythonhosted.org/packages/63/f6/d80592aa8d335af734054f5cfe130ecd38fdfb9c4f90ba0007f0419f2fce/langchain_experimental-0.3.2-py3-none-any.whl", hash = "sha256:b6a26f2a05e056a27ad30535ed306a6b9d8cc2e3c0326d15030d11b6e7505dbb", size = 208126 }, ] [[package]] name = "langchain-openai" -version = "0.1.25" +version = "0.2.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, { name = "openai" }, { name = "tiktoken" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/cb/98fe365f2e5eee39d0130279959a84182ab414879b666ffc2b9d69b95633/langchain_openai-0.1.25.tar.gz", hash = "sha256:eb116f744f820247a72f54313fb7c01524fba0927120d4e899e5e4ab41ad3928", size = 45224 } +sdist = { url = "https://files.pythonhosted.org/packages/55/4c/0a88c51192b0aeef5212019060da7112191750ab7a185195d8b45835578c/langchain_openai-0.2.2.tar.gz", hash = "sha256:9ae8e2ec7d1ca84fd3bfa82186724528d68e1510a1dc9cdf617a7c669b7a7768", size = 42364 } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/2e/a4430cad7a98e29e9612648f8b12d7449ab635a742c19bf1d62f8713ecaa/langchain_openai-0.1.25-py3-none-any.whl", hash = "sha256:f0b34a233d0d9cb8fce6006c903e57085c493c4f0e32862b99063b96eaedb109", size = 51550 }, + { url = "https://files.pythonhosted.org/packages/b0/4e/c62ce98a5412f031f7f03dda5c35b6ed474e0083986261073ca9da5554d5/langchain_openai-0.2.2-py3-none-any.whl", hash = "sha256:3a203228cb38e4711ebd8c0a3bd51854e447f1d017e8475b6467b07ce7dd3e88", size = 49687 }, ] [[package]] name = "langchain-text-splitters" -version = "0.2.4" +version = "0.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/83/b3/b1ccde47c86c5fe2585dc012555cff7949c556bd6993dd9c09e49a356190/langchain_text_splitters-0.2.4.tar.gz", hash = "sha256:f7daa7a3b0aa8309ce248e2e2b6fc8115be01118d336c7f7f7dfacda0e89bf29", size = 20236 } +sdist = { url = "https://files.pythonhosted.org/packages/57/35/08ac1ca01c58da825f070bd1fdc9192a9ff52c0a048f74c93b05df70c127/langchain_text_splitters-0.3.0.tar.gz", hash = "sha256:f9fe0b4d244db1d6de211e7343d4abc4aa90295aa22e1f0c89e51f33c55cd7ce", size = 20234 } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/f3/d01591229e9d0eec1e8106ed6f9b670f299beb1c94fed4aa335afa78acb0/langchain_text_splitters-0.2.4-py3-none-any.whl", hash = "sha256:2702dee5b7cbdd595ccbe43b8d38d01a34aa8583f4d6a5a68ad2305ae3e7b645", size = 25552 }, + { url = "https://files.pythonhosted.org/packages/da/6a/d1303b722a3fa7a0a8c2f8f5307e42f0bdbded46d99cca436f3db0df5294/langchain_text_splitters-0.3.0-py3-none-any.whl", hash = "sha256:e84243e45eaff16e5b776cd9c81b6d07c55c010ebcb1965deb3d1792b7358e83", size = 25543 }, ] [[package]] @@ -2113,7 +2167,7 @@ wheels = [ [[package]] name = "mem0ai" -version = "0.1.17" +version = "0.1.19" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-community" }, @@ -2126,9 +2180,9 @@ dependencies = [ { name = "rank-bm25" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/23/fc537f7125c88efeb81190b661b4e17786d039d4e00da2975ea253b45c8f/mem0ai-0.1.17.tar.gz", hash = "sha256:3b24c5904c96717c2285847f7ad98be0167421fd67b23c19771e81bef00ec2f1", size = 51167 } +sdist = { url = "https://files.pythonhosted.org/packages/6e/12/23f8f250a2ce798a51841417acbbfc9c12c294d3ae427e81a0a0dbab54f6/mem0ai-0.1.19.tar.gz", hash = "sha256:faf7c198a85df2f502ac41fe2bc1593ca0383f993b431a4e4a36e0aed3fa533c", size = 51167 } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/49/4fa5e5f759004e90fa9b4adbc9f224f09f09e182bf3d4dfebed69b10fe8a/mem0ai-0.1.17-py3-none-any.whl", hash = "sha256:6505bc45880c26b25edf0a17242d71939ebaab27be0ae09b77f25fd400f61b76", size = 73252 }, + { url = "https://files.pythonhosted.org/packages/7e/43/04d22bc9cac6fa19b10a405c59c21e94b8ae2a180b40307ec4a577f6ee39/mem0ai-0.1.19-py3-none-any.whl", hash = "sha256:dfff9cfe191072abd34ed8bb4fcbee2819603eed430d89611ef3181b1a46fff9", size = 73240 }, ] [[package]] @@ -2310,6 +2364,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9b/fd/eb1a3573cda74d4c2381d10ded62c128e869954ced1881c15e2bcd97a48f/mmh3-5.0.1-cp312-cp312-win32.whl", hash = "sha256:842516acf04da546f94fad52db125ee619ccbdcada179da51c326a22c4578cb9", size = 39206 }, { url = "https://files.pythonhosted.org/packages/66/e8/542ed252924002b84c43a68a080cfd4facbea0d5df361e4f59637638d3c7/mmh3-5.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:d963be0dbfd9fca209c17172f6110787ebf78934af25e3694fe2ba40e55c1e2b", size = 39799 }, { url = "https://files.pythonhosted.org/packages/bd/25/ff2cd36c82a23afa57a05cdb52ab467a911fb12c055c8a8238c0d426cbf0/mmh3-5.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:a5da292ceeed8ce8e32b68847261a462d30fd7b478c3f55daae841404f433c15", size = 36537 }, + { url = "https://files.pythonhosted.org/packages/09/e0/fb19c46265c18311b422ba5ce3e18046ad45c48cfb213fd6dbec23ae6b51/mmh3-5.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:673e3f1c8d4231d6fb0271484ee34cb7146a6499fc0df80788adb56fd76842da", size = 52909 }, + { url = "https://files.pythonhosted.org/packages/c3/94/54fc591e7a24c7ce2c531ecfc5715cff932f9d320c2936550cc33d67304d/mmh3-5.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f795a306bd16a52ad578b663462cc8e95500b3925d64118ae63453485d67282b", size = 38396 }, + { url = "https://files.pythonhosted.org/packages/1f/9a/142bcc9d0d28fc8ae45bbfb83926adc069f984cdf3495a71534cc22b8e27/mmh3-5.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5ed57a5e28e502a1d60436cc25c76c3a5ba57545f250f2969af231dc1221e0a5", size = 38207 }, + { url = "https://files.pythonhosted.org/packages/f8/5b/f1c9110aa70321bb1ee713f17851b9534586c63bc25e0110e4fc03ae2450/mmh3-5.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:632c28e7612e909dbb6cbe2fe496201ada4695b7715584005689c5dc038e59ad", size = 94988 }, + { url = "https://files.pythonhosted.org/packages/87/e5/4dc67e7e0e716c641ab0a5875a659e37258417439590feff5c3bd3ff4538/mmh3-5.0.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53fd6bd525a5985e391c43384672d9d6b317fcb36726447347c7fc75bfed34ec", size = 99969 }, + { url = "https://files.pythonhosted.org/packages/ac/68/d148327337687c53f04ad9ceaedfa9ad155ee0111d0cb06220f044d66720/mmh3-5.0.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dceacf6b0b961a0e499836af3aa62d60633265607aef551b2a3e3c48cdaa5edd", size = 99662 }, + { url = "https://files.pythonhosted.org/packages/13/79/782adb6df6397947c1097b1e94b7f8d95629a4a73df05cf7207bd5148c1f/mmh3-5.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f0738d478fdfb5d920f6aff5452c78f2c35b0eff72caa2a97dfe38e82f93da2", size = 87606 }, + { url = "https://files.pythonhosted.org/packages/f2/c2/0404383281df049d0e4ccf07fabd659fc1f3da834df6708d934116cbf45d/mmh3-5.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e70285e7391ab88b872e5bef632bad16b9d99a6d3ca0590656a4753d55988af", size = 94836 }, + { url = "https://files.pythonhosted.org/packages/c8/33/fda67c5f28e4c2131891cf8cbc3513cfc55881e3cfe26e49328e38ffacb3/mmh3-5.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:27e5fc6360aa6b828546a4318da1a7da6bf6e5474ccb053c3a6aa8ef19ff97bd", size = 90492 }, + { url = "https://files.pythonhosted.org/packages/64/2f/0ed38aefe2a87f30bb1b12e5b75dc69fcffdc16def40d1752d6fc7cbbf96/mmh3-5.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7989530c3c1e2c17bf5a0ec2bba09fd19819078ba90beedabb1c3885f5040b0d", size = 89594 }, + { url = "https://files.pythonhosted.org/packages/95/ab/6e7a5e765fc78e3dbd0a04a04cfdf72e91eb8e31976228e69d82c741a5b4/mmh3-5.0.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cdad7bee649950da7ecd3cbbbd12fb81f1161072ecbdb5acfa0018338c5cb9cf", size = 94929 }, + { url = "https://files.pythonhosted.org/packages/74/51/f748f00c072006f4a093d9b08853a0e2e3cd5aeaa91343d4e2d942851978/mmh3-5.0.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e143b8f184c1bb58cecd85ab4a4fd6dc65a2d71aee74157392c3fddac2a4a331", size = 91317 }, + { url = "https://files.pythonhosted.org/packages/df/a1/21ee8017a7feb0270c49f756ff56da9f99bd150dcfe3b3f6f0d4b243423d/mmh3-5.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5eb12e886f3646dd636f16b76eb23fc0c27e8ff3c1ae73d4391e50ef60b40f6", size = 89861 }, + { url = "https://files.pythonhosted.org/packages/c2/d2/46a6d070de4659bdf91cd6a62d659f8cc547dadee52b6d02bcbacb3262ed/mmh3-5.0.1-cp313-cp313-win32.whl", hash = "sha256:16e6dddfa98e1c2d021268e72c78951234186deb4df6630e984ac82df63d0a5d", size = 39201 }, + { url = "https://files.pythonhosted.org/packages/ed/07/316c062f09019b99b248a4183c5333f8eeebe638345484774908a8f2c9c0/mmh3-5.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:d3ffb792d70b8c4a2382af3598dad6ae0c5bd9cee5b7ffcc99aa2f5fd2c1bf70", size = 39807 }, + { url = "https://files.pythonhosted.org/packages/9d/d3/f7e6d7d062b8d7072c3989a528d9d47486ee5d5ae75250f6e26b4976d098/mmh3-5.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:122fa9ec148383f9124292962bda745f192b47bfd470b2af5fe7bb3982b17896", size = 36539 }, ] [[package]] @@ -2393,6 +2463,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/77/00/8538f11e3356b5d95fa4b024aa566cde7a38aa7a5f08f4912b32a037c5dc/multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3", size = 125360 }, { url = "https://files.pythonhosted.org/packages/be/05/5d334c1f2462d43fec2363cd00b1c44c93a78c3925d952e9a71caf662e96/multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133", size = 26382 }, { url = "https://files.pythonhosted.org/packages/a3/bf/f332a13486b1ed0496d624bcc7e8357bb8053823e8cd4b9a18edc1d97e73/multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1", size = 28529 }, + { url = "https://files.pythonhosted.org/packages/22/67/1c7c0f39fe069aa4e5d794f323be24bf4d33d62d2a348acdb7991f8f30db/multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008", size = 48771 }, + { url = "https://files.pythonhosted.org/packages/3c/25/c186ee7b212bdf0df2519eacfb1981a017bda34392c67542c274651daf23/multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f", size = 29533 }, + { url = "https://files.pythonhosted.org/packages/67/5e/04575fd837e0958e324ca035b339cea174554f6f641d3fb2b4f2e7ff44a2/multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28", size = 29595 }, + { url = "https://files.pythonhosted.org/packages/d3/b2/e56388f86663810c07cfe4a3c3d87227f3811eeb2d08450b9e5d19d78876/multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b", size = 130094 }, + { url = "https://files.pythonhosted.org/packages/6c/ee/30ae9b4186a644d284543d55d491fbd4239b015d36b23fea43b4c94f7052/multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c", size = 134876 }, + { url = "https://files.pythonhosted.org/packages/84/c7/70461c13ba8ce3c779503c70ec9d0345ae84de04521c1f45a04d5f48943d/multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3", size = 133500 }, + { url = "https://files.pythonhosted.org/packages/4a/9f/002af221253f10f99959561123fae676148dd730e2daa2cd053846a58507/multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44", size = 131099 }, + { url = "https://files.pythonhosted.org/packages/82/42/d1c7a7301d52af79d88548a97e297f9d99c961ad76bbe6f67442bb77f097/multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2", size = 120403 }, + { url = "https://files.pythonhosted.org/packages/68/f3/471985c2c7ac707547553e8f37cff5158030d36bdec4414cb825fbaa5327/multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3", size = 125348 }, + { url = "https://files.pythonhosted.org/packages/67/2c/e6df05c77e0e433c214ec1d21ddd203d9a4770a1f2866a8ca40a545869a0/multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa", size = 119673 }, + { url = "https://files.pythonhosted.org/packages/c5/cd/bc8608fff06239c9fb333f9db7743a1b2eafe98c2666c9a196e867a3a0a4/multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa", size = 129927 }, + { url = "https://files.pythonhosted.org/packages/44/8e/281b69b7bc84fc963a44dc6e0bbcc7150e517b91df368a27834299a526ac/multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4", size = 128711 }, + { url = "https://files.pythonhosted.org/packages/12/a4/63e7cd38ed29dd9f1881d5119f272c898ca92536cdb53ffe0843197f6c85/multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6", size = 125519 }, + { url = "https://files.pythonhosted.org/packages/38/e0/4f5855037a72cd8a7a2f60a3952d9aa45feedb37ae7831642102604e8a37/multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81", size = 26426 }, + { url = "https://files.pythonhosted.org/packages/7e/a5/17ee3a4db1e310b7405f5d25834460073a8ccd86198ce044dfaf69eac073/multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774", size = 28531 }, { url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051 }, ] @@ -2411,6 +2496,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/a9/39cf856d03690af6fd570cf40331f1f79acdbb3132a9c35d2c5002f7f30b/multiprocess-0.70.17-py310-none-any.whl", hash = "sha256:38357ca266b51a2e22841b755d9a91e4bb7b937979a54d411677111716c32744", size = 134830 }, { url = "https://files.pythonhosted.org/packages/b2/07/8cbb75d6cfbe8712d8f7f6a5615f083c6e710ab916b748fbb20373ddb142/multiprocess-0.70.17-py311-none-any.whl", hash = "sha256:2884701445d0177aec5bd5f6ee0df296773e4fb65b11903b94c613fb46cfb7d1", size = 144346 }, { url = "https://files.pythonhosted.org/packages/a4/69/d3f343a61a2f86ef10ed7865a26beda7c71554136ce187b0384b1c2c9ca3/multiprocess-0.70.17-py312-none-any.whl", hash = "sha256:2818af14c52446b9617d1b0755fa70ca2f77c28b25ed97bdaa2c69a22c47b46c", size = 147990 }, + { url = "https://files.pythonhosted.org/packages/c8/b7/2e9a4fcd871b81e1f2a812cd5c6fb52ad1e8da7bf0d7646c55eaae220484/multiprocess-0.70.17-py313-none-any.whl", hash = "sha256:20c28ca19079a6c879258103a6d60b94d4ffe2d9da07dda93fb1c8bc6243f522", size = 149843 }, { url = "https://files.pythonhosted.org/packages/ae/d7/fd7a092fc0ab1845a1a97ca88e61b9b7cc2e9d6fcf0ed24e9480590c2336/multiprocess-0.70.17-py38-none-any.whl", hash = "sha256:1d52f068357acd1e5bbc670b273ef8f81d57863235d9fbf9314751886e141968", size = 132635 }, { url = "https://files.pythonhosted.org/packages/f9/41/0618ac724b8a56254962c143759e04fa01c73b37aa69dd433f16643bd38b/multiprocess-0.70.17-py39-none-any.whl", hash = "sha256:c3feb874ba574fbccfb335980020c1ac631fbf2a3f7bee4e2042ede62558a021", size = 133359 }, ] @@ -2764,6 +2850,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/1a/d11805670c29d3a1b29fc4bd048dc90b094784779690592efe8c9f71249a/orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b", size = 167994 }, { url = "https://files.pythonhosted.org/packages/20/5f/03d89b007f9d6733dc11bc35d64812101c85d6c4e9c53af9fa7e7689cb11/orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb", size = 143130 }, { url = "https://files.pythonhosted.org/packages/c6/9d/9b9fb6c60b8a0e04031ba85414915e19ecea484ebb625402d968ea45b8d5/orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1", size = 137326 }, + { url = "https://files.pythonhosted.org/packages/15/05/121af8a87513c56745d01ad7cf215c30d08356da9ad882ebe2ba890824cd/orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149", size = 251331 }, + { url = "https://files.pythonhosted.org/packages/73/7f/8d6ccd64a6f8bdbfe6c9be7c58aeb8094aa52a01fbbb2cda42ff7e312bd7/orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe", size = 142012 }, + { url = "https://files.pythonhosted.org/packages/04/65/f2a03fd1d4f0308f01d372e004c049f7eb9bc5676763a15f20f383fa9c01/orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c", size = 169920 }, + { url = "https://files.pythonhosted.org/packages/e2/1c/3ef8d83d7c6a619ad3d69a4d5318591b4ce5862e6eda7c26bbe8208652ca/orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad", size = 167916 }, + { url = "https://files.pythonhosted.org/packages/f2/0d/820a640e5a7dfbe525e789c70871ebb82aff73b0c7bf80082653f86b9431/orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2", size = 143089 }, + { url = "https://files.pythonhosted.org/packages/1a/72/a424db9116c7cad2950a8f9e4aeb655a7b57de988eb015acd0fcd1b4609b/orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024", size = 137081 }, ] [[package]] @@ -2838,6 +2930,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/e8/45a05d9c39d2cea61ab175dbe6a2de1d05b679e8de2011da4ee190d7e748/pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", size = 16359235 }, { url = "https://files.pythonhosted.org/packages/1d/99/617d07a6a5e429ff90c90da64d428516605a1ec7d7bea494235e1c3882de/pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", size = 14056756 }, { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, + { url = "https://files.pythonhosted.org/packages/64/22/3b8f4e0ed70644e85cfdcd57454686b9057c6c38d2f74fe4b8bc2527214a/pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015", size = 12477643 }, + { url = "https://files.pythonhosted.org/packages/e4/93/b3f5d1838500e22c8d793625da672f3eec046b1a99257666c94446969282/pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28", size = 11281573 }, + { url = "https://files.pythonhosted.org/packages/f5/94/6c79b07f0e5aab1dcfa35a75f4817f5c4f677931d4234afcd75f0e6a66ca/pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0", size = 15196085 }, + { url = "https://files.pythonhosted.org/packages/e8/31/aa8da88ca0eadbabd0a639788a6da13bb2ff6edbbb9f29aa786450a30a91/pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24", size = 12711809 }, + { url = "https://files.pythonhosted.org/packages/ee/7c/c6dbdb0cb2a4344cacfb8de1c5808ca885b2e4dcfde8008266608f9372af/pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659", size = 16356316 }, + { url = "https://files.pythonhosted.org/packages/57/b7/8b757e7d92023b832869fa8881a992696a0bfe2e26f72c9ae9f255988d42/pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb", size = 14022055 }, + { url = "https://files.pythonhosted.org/packages/3b/bc/4b18e2b8c002572c5a441a64826252ce5da2aa738855747247a971988043/pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d", size = 11481175 }, + { url = "https://files.pythonhosted.org/packages/76/a3/a5d88146815e972d40d19247b2c162e88213ef51c7c25993942c39dbf41d/pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468", size = 12615650 }, + { url = "https://files.pythonhosted.org/packages/9c/8c/f0fd18f6140ddafc0c24122c8a964e48294acc579d47def376fef12bcb4a/pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18", size = 11290177 }, + { url = "https://files.pythonhosted.org/packages/ed/f9/e995754eab9c0f14c6777401f7eece0943840b7a9fc932221c19d1abee9f/pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2", size = 14651526 }, + { url = "https://files.pythonhosted.org/packages/25/b0/98d6ae2e1abac4f35230aa756005e8654649d305df9a28b16b9ae4353bff/pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4", size = 11871013 }, + { url = "https://files.pythonhosted.org/packages/cc/57/0f72a10f9db6a4628744c8e8f0df4e6e21de01212c7c981d31e50ffc8328/pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d", size = 15711620 }, + { url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436 }, ] [[package]] @@ -2933,6 +3038,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/55/04/5e6de6e6120451ec0c24516c41dbaf80cce1b6451f96561235ef2429da2e/pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42", size = 2235690 }, { url = "https://files.pythonhosted.org/packages/74/0a/d4ce3c44bca8635bd29a2eab5aa181b654a734a29b263ca8efe013beea98/pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a", size = 2554951 }, { url = "https://files.pythonhosted.org/packages/b5/ca/184349ee40f2e92439be9b3502ae6cfc43ac4b50bc4fc6b3de7957563894/pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9", size = 2243427 }, + { url = "https://files.pythonhosted.org/packages/c3/00/706cebe7c2c12a6318aabe5d354836f54adff7156fd9e1bd6c89f4ba0e98/pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3", size = 3525685 }, + { url = "https://files.pythonhosted.org/packages/cf/76/f658cbfa49405e5ecbfb9ba42d07074ad9792031267e782d409fd8fe7c69/pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb", size = 3374883 }, + { url = "https://files.pythonhosted.org/packages/46/2b/99c28c4379a85e65378211971c0b430d9c7234b1ec4d59b2668f6299e011/pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70", size = 4339837 }, + { url = "https://files.pythonhosted.org/packages/f1/74/b1ec314f624c0c43711fdf0d8076f82d9d802afd58f1d62c2a86878e8615/pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be", size = 4455562 }, + { url = "https://files.pythonhosted.org/packages/4a/2a/4b04157cb7b9c74372fa867096a1607e6fedad93a44deeff553ccd307868/pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0", size = 4366761 }, + { url = "https://files.pythonhosted.org/packages/ac/7b/8f1d815c1a6a268fe90481232c98dd0e5fa8c75e341a75f060037bd5ceae/pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc", size = 4536767 }, + { url = "https://files.pythonhosted.org/packages/e5/77/05fa64d1f45d12c22c314e7b97398ffb28ef2813a485465017b7978b3ce7/pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a", size = 4477989 }, + { url = "https://files.pythonhosted.org/packages/12/63/b0397cfc2caae05c3fb2f4ed1b4fc4fc878f0243510a7a6034ca59726494/pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309", size = 4610255 }, + { url = "https://files.pythonhosted.org/packages/7b/f9/cfaa5082ca9bc4a6de66ffe1c12c2d90bf09c309a5f52b27759a596900e7/pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060", size = 2235603 }, + { url = "https://files.pythonhosted.org/packages/01/6a/30ff0eef6e0c0e71e55ded56a38d4859bf9d3634a94a88743897b5f96936/pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea", size = 2554972 }, + { url = "https://files.pythonhosted.org/packages/48/2c/2e0a52890f269435eee38b21c8218e102c621fe8d8df8b9dd06fabf879ba/pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d", size = 2243375 }, { url = "https://files.pythonhosted.org/packages/38/30/095d4f55f3a053392f75e2eae45eba3228452783bab3d9a920b951ac495c/pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4", size = 3493889 }, { url = "https://files.pythonhosted.org/packages/f3/e8/4ff79788803a5fcd5dc35efdc9386af153569853767bff74540725b45863/pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da", size = 3346160 }, { url = "https://files.pythonhosted.org/packages/d7/ac/4184edd511b14f760c73f5bb8a5d6fd85c591c8aff7c2229677a355c4179/pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026", size = 3435020 }, @@ -3250,6 +3366,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, + { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, + { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, + { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, + { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, + { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, + { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, + { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, + { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, + { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, + { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, + { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, + { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, @@ -3260,6 +3388,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, ] +[[package]] +name = "pydantic-settings" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/66/5f1a9da10675bfb3b9da52f5b689c77e0a5612263fcce510cfac3e99a168/pydantic_settings-2.6.0.tar.gz", hash = "sha256:44a1804abffac9e6a30372bb45f6cafab945ef5af25e66b1c634c01dd39e0188", size = 75232 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/19/26bb6bdb9fdad5f0dfce538780814084fb667b4bc37fcb28459c14b8d3b5/pydantic_settings-2.6.0-py3-none-any.whl", hash = "sha256:4a819166f119b74d7f8c765196b165f95cc7487ce58ea27dec8a5a26be0970e0", size = 28578 }, +] + [[package]] name = "pygments" version = "2.18.0" @@ -3309,14 +3450,14 @@ wheels = [ [[package]] name = "pypdf" -version = "4.3.1" +version = "5.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/65/2ed7c9e1d31d860f096061b3dd2d665f501e09faaa0409a3f0d719d2a16d/pypdf-4.3.1.tar.gz", hash = "sha256:b2f37fe9a3030aa97ca86067a56ba3f9d3565f9a791b305c7355d8392c30d91b", size = 293266 } +sdist = { url = "https://files.pythonhosted.org/packages/9d/28/6bc2ca8a521512f2904e6aa3028af43a864fe2b66c77ea01bbbc97f52b98/pypdf-5.0.1.tar.gz", hash = "sha256:a361c3c372b4a659f9c8dd438d5ce29a753c79c620dc6e1fd66977651f5547ea", size = 4999113 } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/60/eccdd92dd4af3e4bea6d6a342f7588c618a15b9bec4b968af581e498bcc4/pypdf-4.3.1-py3-none-any.whl", hash = "sha256:64b31da97eda0771ef22edb1bfecd5deee4b72c3d1736b7df2689805076d6418", size = 295825 }, + { url = "https://files.pythonhosted.org/packages/48/8f/9bbf22ba6a00001a45dbc54337e5bbbd43e7d8f34c8158c92cddc45736af/pypdf-5.0.1-py3-none-any.whl", hash = "sha256:ff8a32da6c7a63fea9c32fa4dd837cdd0db7966adf6c14f043e3f12592e992db", size = 294470 }, ] [[package]] @@ -3529,6 +3670,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, ] [[package]] @@ -3647,6 +3797,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ea/75/9753e9dcebfa7c3645563ef5c8a58f3a47e799c872165f37c55737dadd3e/regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", size = 787333 }, { url = "https://files.pythonhosted.org/packages/bc/4e/ba1cbca93141f7416624b3ae63573e785d4bc1834c8be44a8f0747919eca/regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", size = 262058 }, { url = "https://files.pythonhosted.org/packages/6e/16/efc5f194778bf43e5888209e5cec4b258005d37c613b67ae137df3b89c53/regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", size = 273526 }, + { url = "https://files.pythonhosted.org/packages/93/0a/d1c6b9af1ff1e36832fe38d74d5c5bab913f2bdcbbd6bc0e7f3ce8b2f577/regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", size = 483376 }, + { url = "https://files.pythonhosted.org/packages/a4/42/5910a050c105d7f750a72dcb49c30220c3ae4e2654e54aaaa0e9bc0584cb/regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", size = 288112 }, + { url = "https://files.pythonhosted.org/packages/8d/56/0c262aff0e9224fa7ffce47b5458d373f4d3e3ff84e99b5ff0cb15e0b5b2/regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", size = 284608 }, + { url = "https://files.pythonhosted.org/packages/b9/54/9fe8f9aec5007bbbbce28ba3d2e3eaca425f95387b7d1e84f0d137d25237/regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", size = 795337 }, + { url = "https://files.pythonhosted.org/packages/b2/e7/6b2f642c3cded271c4f16cc4daa7231be544d30fe2b168e0223724b49a61/regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", size = 835848 }, + { url = "https://files.pythonhosted.org/packages/cd/9e/187363bdf5d8c0e4662117b92aa32bf52f8f09620ae93abc7537d96d3311/regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", size = 823503 }, + { url = "https://files.pythonhosted.org/packages/f8/10/601303b8ee93589f879664b0cfd3127949ff32b17f9b6c490fb201106c4d/regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", size = 797049 }, + { url = "https://files.pythonhosted.org/packages/ef/1c/ea200f61ce9f341763f2717ab4daebe4422d83e9fd4ac5e33435fd3a148d/regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", size = 784144 }, + { url = "https://files.pythonhosted.org/packages/d8/5c/d2429be49ef3292def7688401d3deb11702c13dcaecdc71d2b407421275b/regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", size = 782483 }, + { url = "https://files.pythonhosted.org/packages/12/d9/cbc30f2ff7164f3b26a7760f87c54bf8b2faed286f60efd80350a51c5b99/regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", size = 790320 }, + { url = "https://files.pythonhosted.org/packages/19/1d/43ed03a236313639da5a45e61bc553c8d41e925bcf29b0f8ecff0c2c3f25/regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", size = 860435 }, + { url = "https://files.pythonhosted.org/packages/34/4f/5d04da61c7c56e785058a46349f7285ae3ebc0726c6ea7c5c70600a52233/regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", size = 859571 }, + { url = "https://files.pythonhosted.org/packages/12/7f/8398c8155a3c70703a8e91c29532558186558e1aea44144b382faa2a6f7a/regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", size = 787398 }, + { url = "https://files.pythonhosted.org/packages/58/3a/f5903977647a9a7e46d5535e9e96c194304aeeca7501240509bde2f9e17f/regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", size = 262035 }, + { url = "https://files.pythonhosted.org/packages/ff/80/51ba3a4b7482f6011095b3a036e07374f64de180b7d870b704ed22509002/regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", size = 273510 }, ] [[package]] @@ -3761,6 +3926,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/2d/5536d28c507a4679179ab15aa0049440e4d3dd6752050fa0843ed11e9354/rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", size = 528807 }, { url = "https://files.pythonhosted.org/packages/e3/62/7ebe6ec0d3dd6130921f8cffb7e34afb7f71b3819aa0446a24c5e81245ec/rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", size = 200993 }, { url = "https://files.pythonhosted.org/packages/ec/2f/b938864d66b86a6e4acadefdc56de75ef56f7cafdfd568a6464605457bd5/rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", size = 214458 }, + { url = "https://files.pythonhosted.org/packages/99/32/43b919a0a423c270a838ac2726b1c7168b946f2563fd99a51aaa9692d00f/rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", size = 321465 }, + { url = "https://files.pythonhosted.org/packages/58/a9/c4d899cb28e9e47b0ff12462e8f827381f243176036f17bef9c1604667f2/rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", size = 312900 }, + { url = "https://files.pythonhosted.org/packages/8f/90/9e51670575b5dfaa8c823369ef7d943087bfb73d4f124a99ad6ef19a2b26/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", size = 370973 }, + { url = "https://files.pythonhosted.org/packages/fc/c1/523f2a03f853fc0d4c1acbef161747e9ab7df0a8abf6236106e333540921/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", size = 370890 }, + { url = "https://files.pythonhosted.org/packages/51/ca/2458a771f16b0931de4d384decbe43016710bc948036c8f4562d6e063437/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", size = 397174 }, + { url = "https://files.pythonhosted.org/packages/00/7d/6e06807f6305ea2408b364efb0eef83a6e21b5e7b5267ad6b473b9a7e416/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", size = 426449 }, + { url = "https://files.pythonhosted.org/packages/8c/d1/6c9e65260a819a1714510a7d69ac1d68aa23ee9ce8a2d9da12187263c8fc/rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", size = 357698 }, + { url = "https://files.pythonhosted.org/packages/5d/fb/ecea8b5286d2f03eec922be7173a03ed17278944f7c124348f535116db15/rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", size = 378530 }, + { url = "https://files.pythonhosted.org/packages/e3/e3/ac72f858957f52a109c588589b73bd2fad4a0fc82387fb55fb34aeb0f9cd/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", size = 545753 }, + { url = "https://files.pythonhosted.org/packages/b2/a4/a27683b519d5fc98e4390a3b130117d80fd475c67aeda8aac83c0e8e326a/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", size = 552443 }, + { url = "https://files.pythonhosted.org/packages/a1/ed/c074d248409b4432b1ccb2056974175fa0af2d1bc1f9c21121f80a358fa3/rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", size = 528380 }, + { url = "https://files.pythonhosted.org/packages/d5/bd/04caf938895d2d78201e89c0c8a94dfd9990c34a19ff52fb01d0912343e3/rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", size = 200540 }, + { url = "https://files.pythonhosted.org/packages/95/cc/109eb8b9863680411ae703664abacaa035820c7755acc9686d5dd02cdd2e/rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", size = 214111 }, { url = "https://files.pythonhosted.org/packages/06/39/bf1f664c347c946ef56cecaa896e3693d91acc741afa78ebb3fdb7aba08b/rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", size = 319444 }, { url = "https://files.pythonhosted.org/packages/c1/71/876135d3cb90d62468540b84e8e83ff4dc92052ab309bfdea7ea0b9221ad/rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", size = 311699 }, { url = "https://files.pythonhosted.org/packages/f7/da/8ccaeba6a3dda7467aebaf893de9eafd56275e2c90773c83bf15fb0b8374/rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", size = 367825 }, @@ -3947,6 +4125,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/7d/9a57e187cbf2fbbbdfd4044a4f9ce141c8d221f9963750d3b001f0ec080d/shapely-2.0.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98fea108334be345c283ce74bf064fa00cfdd718048a8af7343c59eb40f59726", size = 2524835 }, { url = "https://files.pythonhosted.org/packages/6d/0a/f407509ab56825f39bf8cfce1fb410238da96cf096809c3e404e5bc71ea1/shapely-2.0.6-cp312-cp312-win32.whl", hash = "sha256:42fd4cd4834747e4990227e4cbafb02242c0cffe9ce7ef9971f53ac52d80d55f", size = 1295613 }, { url = "https://files.pythonhosted.org/packages/7b/b3/857afd9dfbfc554f10d683ac412eac6fa260d1f4cd2967ecb655c57e831a/shapely-2.0.6-cp312-cp312-win_amd64.whl", hash = "sha256:665990c84aece05efb68a21b3523a6b2057e84a1afbef426ad287f0796ef8a48", size = 1442539 }, + { url = "https://files.pythonhosted.org/packages/34/e8/d164ef5b0eab86088cde06dee8415519ffd5bb0dd1bd9d021e640e64237c/shapely-2.0.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:42805ef90783ce689a4dde2b6b2f261e2c52609226a0438d882e3ced40bb3013", size = 1445344 }, + { url = "https://files.pythonhosted.org/packages/ce/e2/9fba7ac142f7831757a10852bfa465683724eadbc93d2d46f74a16f9af04/shapely-2.0.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6d2cb146191a47bd0cee8ff5f90b47547b82b6345c0d02dd8b25b88b68af62d7", size = 1296182 }, + { url = "https://files.pythonhosted.org/packages/cf/dc/790d4bda27d196cd56ec66975eaae3351c65614cafd0e16ddde39ec9fb92/shapely-2.0.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3fdef0a1794a8fe70dc1f514440aa34426cc0ae98d9a1027fb299d45741c381", size = 2423426 }, + { url = "https://files.pythonhosted.org/packages/af/b0/f8169f77eac7392d41e231911e0095eb1148b4d40c50ea9e34d999c89a7e/shapely-2.0.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c665a0301c645615a107ff7f52adafa2153beab51daf34587170d85e8ba6805", size = 2513249 }, + { url = "https://files.pythonhosted.org/packages/f6/1d/a8c0e9ab49ff2f8e4dedd71b0122eafb22a18ad7e9d256025e1f10c84704/shapely-2.0.6-cp313-cp313-win32.whl", hash = "sha256:0334bd51828f68cd54b87d80b3e7cee93f249d82ae55a0faf3ea21c9be7b323a", size = 1294848 }, + { url = "https://files.pythonhosted.org/packages/23/38/2bc32dd1e7e67a471d4c60971e66df0bdace88656c47a9a728ace0091075/shapely-2.0.6-cp313-cp313-win_amd64.whl", hash = "sha256:d37d070da9e0e0f0a530a621e17c0b8c3c9d04105655132a87cfff8bd77cc4c2", size = 1441371 }, ] [[package]] @@ -4500,6 +4684,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/9b/8b206a928c188fdeb7b12e1c795199534cd44bdef223b8470129016009dd/watchdog-5.0.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d11b07c64f63f49876e0ab8042ae034674c8653bfcdaa8c4b32e71cfff87e8", size = 96739 }, { url = "https://files.pythonhosted.org/packages/e1/26/129ca9cd0f8016672f37000010c2fedc0b86816e894ebdc0af9bb04a6439/watchdog-5.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:349c9488e1d85d0a58e8cb14222d2c51cbc801ce11ac3936ab4c3af986536926", size = 88708 }, { url = "https://files.pythonhosted.org/packages/8f/b3/5e10ec32f0c429cdb55b1369066d6e83faf9985b3a53a4e37bb5c5e29aa0/watchdog-5.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:53a3f10b62c2d569e260f96e8d966463dec1a50fa4f1b22aec69e3f91025060e", size = 89309 }, + { url = "https://files.pythonhosted.org/packages/54/c4/49af4ab00bcfb688e9962eace2edda07a2cf89b9699ea536da48e8585cff/watchdog-5.0.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:950f531ec6e03696a2414b6308f5c6ff9dab7821a768c9d5788b1314e9a46ca7", size = 96740 }, + { url = "https://files.pythonhosted.org/packages/96/a4/b24de77cc9ae424c1687c9d4fb15aa560d7d7b28ba559aca72f781d0202b/watchdog-5.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae6deb336cba5d71476caa029ceb6e88047fc1dc74b62b7c4012639c0b563906", size = 88711 }, + { url = "https://files.pythonhosted.org/packages/a4/71/3f2e9fe8403386b99d788868955b3a790f7a09721501a7e1eb58f514ffaa/watchdog-5.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1021223c08ba8d2d38d71ec1704496471ffd7be42cfb26b87cd5059323a389a1", size = 89319 }, { url = "https://files.pythonhosted.org/packages/a2/d6/1d1ca81c75d903eca3fdb7061d93845485b58a5ba182d146843b88fc51c2/watchdog-5.0.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:90a67d7857adb1d985aca232cc9905dd5bc4803ed85cfcdcfcf707e52049eda7", size = 88172 }, { url = "https://files.pythonhosted.org/packages/47/bb/d5e0abcfd6d729029a24766682e062526db8b59e9ae0c94aff509e0fd2b9/watchdog-5.0.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:720ef9d3a4f9ca575a780af283c8fd3a0674b307651c1976714745090da5a9e8", size = 88644 }, { url = "https://files.pythonhosted.org/packages/60/33/7cb71c9df9a77b6927ee5f48d25e1de5562ce0fa7e0c56dcf2b0472e64a2/watchdog-5.0.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dd021efa85970bd4824acacbb922066159d0f9e546389a4743d56919b6758b91", size = 79335 }, @@ -4561,6 +4748,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/44/81/1f701323a9f70805bc81c74c990137123344a80ea23ab9504a99492907f8/watchfiles-0.24.0-cp312-none-win32.whl", hash = "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444", size = 264109 }, { url = "https://files.pythonhosted.org/packages/b4/0b/32cde5bc2ebd9f351be326837c61bdeb05ad652b793f25c91cac0b48a60b/watchfiles-0.24.0-cp312-none-win_amd64.whl", hash = "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", size = 277055 }, { url = "https://files.pythonhosted.org/packages/4b/81/daade76ce33d21dbec7a15afd7479de8db786e5f7b7d249263b4ea174e08/watchfiles-0.24.0-cp312-none-win_arm64.whl", hash = "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", size = 266169 }, + { url = "https://files.pythonhosted.org/packages/30/dc/6e9f5447ae14f645532468a84323a942996d74d5e817837a5c8ce9d16c69/watchfiles-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", size = 373764 }, + { url = "https://files.pythonhosted.org/packages/79/c0/c3a9929c372816c7fc87d8149bd722608ea58dc0986d3ef7564c79ad7112/watchfiles-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", size = 367873 }, + { url = "https://files.pythonhosted.org/packages/2e/11/ff9a4445a7cfc1c98caf99042df38964af12eed47d496dd5d0d90417349f/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", size = 438381 }, + { url = "https://files.pythonhosted.org/packages/48/a3/763ba18c98211d7bb6c0f417b2d7946d346cdc359d585cc28a17b48e964b/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", size = 432809 }, + { url = "https://files.pythonhosted.org/packages/30/4c/616c111b9d40eea2547489abaf4ffc84511e86888a166d3a4522c2ba44b5/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", size = 451801 }, + { url = "https://files.pythonhosted.org/packages/b6/be/d7da83307863a422abbfeb12903a76e43200c90ebe5d6afd6a59d158edea/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", size = 468886 }, + { url = "https://files.pythonhosted.org/packages/1d/d3/3dfe131ee59d5e90b932cf56aba5c996309d94dafe3d02d204364c23461c/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", size = 472973 }, + { url = "https://files.pythonhosted.org/packages/42/6c/279288cc5653a289290d183b60a6d80e05f439d5bfdfaf2d113738d0f932/watchfiles-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", size = 425282 }, + { url = "https://files.pythonhosted.org/packages/d6/d7/58afe5e85217e845edf26d8780c2d2d2ae77675eeb8d1b8b8121d799ce52/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", size = 612540 }, + { url = "https://files.pythonhosted.org/packages/6d/d5/b96eeb9fe3fda137200dd2f31553670cbc731b1e13164fd69b49870b76ec/watchfiles-0.24.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18", size = 593625 }, + { url = "https://files.pythonhosted.org/packages/c1/e5/c326fe52ee0054107267608d8cea275e80be4455b6079491dfd9da29f46f/watchfiles-0.24.0-cp313-none-win32.whl", hash = "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07", size = 263899 }, + { url = "https://files.pythonhosted.org/packages/a6/8b/8a7755c5e7221bb35fe4af2dc44db9174f90ebf0344fd5e9b1e8b42d381e/watchfiles-0.24.0-cp313-none-win_amd64.whl", hash = "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", size = 276622 }, { url = "https://files.pythonhosted.org/packages/df/94/1ad200e937ec91b2a9d6b39ae1cf9c2b1a9cc88d5ceb43aa5c6962eb3c11/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", size = 376986 }, { url = "https://files.pythonhosted.org/packages/ee/fd/d9e020d687ccf90fe95efc513fbb39a8049cf5a3ff51f53c59fcf4c47a5d/watchfiles-0.24.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", size = 369445 }, { url = "https://files.pythonhosted.org/packages/43/cb/c0279b35053555d10ef03559c5aebfcb0c703d9c70a7b4e532df74b9b0e8/watchfiles-0.24.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", size = 439383 }, @@ -4633,6 +4832,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5c/f1/a29dd6046d3a722d26f182b783a7997d25298873a14028c4760347974ea3/websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", size = 164686 }, { url = "https://files.pythonhosted.org/packages/0f/99/ab1cdb282f7e595391226f03f9b498f52109d25a2ba03832e21614967dfa/websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", size = 158712 }, { url = "https://files.pythonhosted.org/packages/46/93/e19160db48b5581feac8468330aa11b7292880a94a37d7030478596cc14e/websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", size = 159145 }, + { url = "https://files.pythonhosted.org/packages/51/20/2b99ca918e1cbd33c53db2cace5f0c0cd8296fc77558e1908799c712e1cd/websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", size = 157828 }, + { url = "https://files.pythonhosted.org/packages/b8/47/0932a71d3d9c0e9483174f60713c84cee58d62839a143f21a2bcdbd2d205/websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", size = 155487 }, + { url = "https://files.pythonhosted.org/packages/a9/60/f1711eb59ac7a6c5e98e5637fef5302f45b6f76a2c9d64fd83bbb341377a/websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", size = 155721 }, + { url = "https://files.pythonhosted.org/packages/6a/e6/ba9a8db7f9d9b0e5f829cf626ff32677f39824968317223605a6b419d445/websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", size = 165609 }, + { url = "https://files.pythonhosted.org/packages/c1/22/4ec80f1b9c27a0aebd84ccd857252eda8418ab9681eb571b37ca4c5e1305/websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", size = 164556 }, + { url = "https://files.pythonhosted.org/packages/27/ac/35f423cb6bb15600438db80755609d27eda36d4c0b3c9d745ea12766c45e/websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", size = 164993 }, + { url = "https://files.pythonhosted.org/packages/31/4e/98db4fd267f8be9e52e86b6ee4e9aa7c42b83452ea0ea0672f176224b977/websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", size = 165360 }, + { url = "https://files.pythonhosted.org/packages/3f/15/3f0de7cda70ffc94b7e7024544072bc5b26e2c1eb36545291abb755d8cdb/websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", size = 164745 }, + { url = "https://files.pythonhosted.org/packages/a1/6e/66b6b756aebbd680b934c8bdbb6dcb9ce45aad72cde5f8a7208dbb00dd36/websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", size = 164732 }, + { url = "https://files.pythonhosted.org/packages/35/c6/12e3aab52c11aeb289e3dbbc05929e7a9d90d7a9173958477d3ef4f8ce2d/websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", size = 158709 }, + { url = "https://files.pythonhosted.org/packages/41/d8/63d6194aae711d7263df4498200c690a9c39fb437ede10f3e157a6343e0d/websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", size = 159144 }, { url = "https://files.pythonhosted.org/packages/2d/75/6da22cb3ad5b8c606963f9a5f9f88656256fecc29d420b4b2bf9e0c7d56f/websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", size = 155499 }, { url = "https://files.pythonhosted.org/packages/c0/ba/22833d58629088fcb2ccccedfae725ac0bbcd713319629e97125b52ac681/websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", size = 155737 }, { url = "https://files.pythonhosted.org/packages/95/54/61684fe22bdb831e9e1843d972adadf359cf04ab8613285282baea6a24bb/websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", size = 157095 }, @@ -4748,6 +4958,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/17/48637d4ddcb606f5591afee78d060eab70e172e14766e1fd23453bfed846/yarl-1.13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4feaaa4742517eaceafcbe74595ed335a494c84634d33961214b278126ec1485", size = 502397 }, { url = "https://files.pythonhosted.org/packages/83/2c/7392645dc1c9eeb8a5485696302a33e3d59bea8a448c8e2f36f98a728e0a/yarl-1.13.1-cp312-cp312-win32.whl", hash = "sha256:bbf9c2a589be7414ac4a534d54e4517d03f1cbb142c0041191b729c2fa23f320", size = 102343 }, { url = "https://files.pythonhosted.org/packages/9c/c0/7329799080d7e0bf7b10db417900701ba6810e78a249aef1f4bf3fc2cccb/yarl-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:d07b52c8c450f9366c34aa205754355e933922c79135125541daae6cbf31c799", size = 111719 }, + { url = "https://files.pythonhosted.org/packages/d3/d2/9542e6207a6e64c32b14b2d9ca4fad6ff80310fc75e70cdbe31680a758c2/yarl-1.13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:95c6737f28069153c399d875317f226bbdea939fd48a6349a3b03da6829fb550", size = 186266 }, + { url = "https://files.pythonhosted.org/packages/8b/68/4c6d1aacbc23a05e84c3fab7aaa68c5a7d4531290021c2370fa1e5524fb1/yarl-1.13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cd66152561632ed4b2a9192e7f8e5a1d41e28f58120b4761622e0355f0fe034c", size = 114268 }, + { url = "https://files.pythonhosted.org/packages/ed/87/6ad8e22c918d745092329ec427c0778b5c85ffd5b805e38750024b7464f2/yarl-1.13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6a2acde25be0cf9be23a8f6cbd31734536a264723fca860af3ae5e89d771cd71", size = 112164 }, + { url = "https://files.pythonhosted.org/packages/ca/5b/c6c4ac4be1edea6759f05ad74d87a1c61329737bdb90da5f66e188310461/yarl-1.13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a18595e6a2ee0826bf7dfdee823b6ab55c9b70e8f80f8b77c37e694288f5de1", size = 471437 }, + { url = "https://files.pythonhosted.org/packages/c1/5c/ec7f0121a5fa67ee76325e1aaa27470d5521d80a25aa1bad5dde773edbe1/yarl-1.13.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a31d21089894942f7d9a8df166b495101b7258ff11ae0abec58e32daf8088813", size = 485894 }, + { url = "https://files.pythonhosted.org/packages/d7/e8/624fc8082cbff62c537798ce837a6044f70e2e00472ab719deb376ff6e39/yarl-1.13.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45f209fb4bbfe8630e3d2e2052535ca5b53d4ce2d2026bed4d0637b0416830da", size = 486702 }, + { url = "https://files.pythonhosted.org/packages/dc/18/013f7d2e3f0ff28b85299ed19164f899ea4f02da8812621a40937428bf48/yarl-1.13.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f722f30366474a99745533cc4015b1781ee54b08de73260b2bbe13316079851", size = 478911 }, + { url = "https://files.pythonhosted.org/packages/d7/3c/5b628939e3a22fb9375df453188e97190d21f6244c49637e19799896cd41/yarl-1.13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3bf60444269345d712838bb11cc4eadaf51ff1a364ae39ce87a5ca8ad3bb2c8", size = 456488 }, + { url = "https://files.pythonhosted.org/packages/8b/2b/a3548db86510c1d95bff344c1c588b84582eeb3a55ea15a149a24d7069f0/yarl-1.13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:942c80a832a79c3707cca46bd12ab8aa58fddb34b1626d42b05aa8f0bcefc206", size = 475016 }, + { url = "https://files.pythonhosted.org/packages/d8/e2/e2a540f18f849909e3ee594766bf7b0a7fde176ff0cfb2f95121033752e2/yarl-1.13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:44b07e1690f010c3c01d353b5790ec73b2f59b4eae5b0000593199766b3f7a5c", size = 477521 }, + { url = "https://files.pythonhosted.org/packages/3a/df/4cda4052da48a57ce4f20a0849b7344902aa3e149a0b409525509fc43985/yarl-1.13.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:396e59b8de7e4d59ff5507fb4322d2329865b909f29a7ed7ca37e63ade7f835c", size = 492000 }, + { url = "https://files.pythonhosted.org/packages/bf/b6/180dbb0aa846cafb9ce89bd33c477e200dd00072c7775372f34651c20b9a/yarl-1.13.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3bb83a0f12701c0b91112a11148b5217617982e1e466069d0555be9b372f2734", size = 502195 }, + { url = "https://files.pythonhosted.org/packages/ff/37/e97c280344342e326a1860a70054a0488c379e8937325f97f9a9fe6b453d/yarl-1.13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c92b89bffc660f1274779cb6fbb290ec1f90d6dfe14492523a0667f10170de26", size = 492892 }, + { url = "https://files.pythonhosted.org/packages/ed/97/cd35f39ba8183ef193a6709aa0b2fcaabebd6915202d6999b01fa630b2bb/yarl-1.13.1-cp313-cp313-win32.whl", hash = "sha256:269c201bbc01d2cbba5b86997a1e0f73ba5e2f471cfa6e226bcaa7fd664b598d", size = 486463 }, + { url = "https://files.pythonhosted.org/packages/05/33/bd9d33503a0f73d095b01ed438423b924e6786e90102ca4912e573cc5aa3/yarl-1.13.1-cp313-cp313-win_amd64.whl", hash = "sha256:1d0828e17fa701b557c6eaed5edbd9098eb62d8838344486248489ff233998b8", size = 493804 }, { url = "https://files.pythonhosted.org/packages/74/81/419c24f7c94f56b96d04955482efb5b381635ad265b5b7fbab333a9dfde3/yarl-1.13.1-py3-none-any.whl", hash = "sha256:6a5185ad722ab4dd52d5fb1f30dcc73282eb1ed494906a92d1a228d3f89607b0", size = 39862 }, ] From d72ebb9bb8f4e5c976866e268247b905548a0e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moura?= Date: Fri, 18 Oct 2024 07:46:30 -0300 Subject: [PATCH 05/19] fixing annotations --- src/crewai/project/annotations.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/crewai/project/annotations.py b/src/crewai/project/annotations.py index 5bbf8dd1c..a2a054923 100644 --- a/src/crewai/project/annotations.py +++ b/src/crewai/project/annotations.py @@ -76,22 +76,24 @@ def crew(func) -> Callable[..., Crew]: instantiated_agents = [] agent_roles = set() - # Collect methods from crew in order + # Collect methods from crew instance (not class) all_functions = [ (name, getattr(self, name)) - for name, attr in self.__class__.__dict__.items() - if callable(attr) + for name in dir(self) + if callable(getattr(self, name)) and not name.startswith("__") ] + + # Filter tasks and agents tasks = [ (name, method) for name, method in all_functions - if hasattr(method, "is_task") + if hasattr(method, "is_task") and method.is_task ] agents = [ (name, method) for name, method in all_functions - if hasattr(method, "is_agent") + if hasattr(method, "is_agent") and method.is_agent ] # Instantiate tasks in order From 6fa2b89831418273a9aa7d1567c03a4f9ee8d774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moura?= Date: Fri, 18 Oct 2024 08:06:38 -0300 Subject: [PATCH 06/19] fix tasks and agents ordering --- src/crewai/project/annotations.py | 26 +++++--------------------- src/crewai/project/crew_base.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/crewai/project/annotations.py b/src/crewai/project/annotations.py index a2a054923..6c0b9942a 100644 --- a/src/crewai/project/annotations.py +++ b/src/crewai/project/annotations.py @@ -76,29 +76,13 @@ def crew(func) -> Callable[..., Crew]: instantiated_agents = [] agent_roles = set() - # Collect methods from crew instance (not class) - all_functions = [ - (name, getattr(self, name)) - for name in dir(self) - if callable(getattr(self, name)) and not name.startswith("__") - ] - - # Filter tasks and agents - tasks = [ - (name, method) - for name, method in all_functions - if hasattr(method, "is_task") and method.is_task - ] - - agents = [ - (name, method) - for name, method in all_functions - if hasattr(method, "is_agent") and method.is_agent - ] + # Use the preserved task and agent information + tasks = self._original_tasks.items() + agents = self._original_agents.items() # Instantiate tasks in order for task_name, task_method in tasks: - task_instance = task_method() + task_instance = task_method(self) instantiated_tasks.append(task_instance) agent_instance = getattr(task_instance, "agent", None) if agent_instance and agent_instance.role not in agent_roles: @@ -107,7 +91,7 @@ def crew(func) -> Callable[..., Crew]: # Instantiate agents not included by tasks for agent_name, agent_method in agents: - agent_instance = agent_method() + agent_instance = agent_method(self) if agent_instance.role not in agent_roles: instantiated_agents.append(agent_instance) agent_roles.add(agent_instance.role) diff --git a/src/crewai/project/crew_base.py b/src/crewai/project/crew_base.py index 6ad8a8c3c..a420c4dd2 100644 --- a/src/crewai/project/crew_base.py +++ b/src/crewai/project/crew_base.py @@ -34,6 +34,18 @@ def CrewBase(cls: T) -> T: self.map_all_agent_variables() self.map_all_task_variables() + # Preserve task and agent information + self._original_tasks = { + name: method + for name, method in cls.__dict__.items() + if hasattr(method, "is_task") and method.is_task + } + self._original_agents = { + name: method + for name, method in cls.__dict__.items() + if hasattr(method, "is_agent") and method.is_agent + } + @staticmethod def load_yaml(config_path: Path): try: From 53a9f107cae5f7eeb703d0f21fc2734584fc5ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moura?= Date: Fri, 18 Oct 2024 08:32:06 -0300 Subject: [PATCH 07/19] Avoiding exceptions --- src/crewai/telemetry/telemetry.py | 894 +++++++++++++++--------------- 1 file changed, 444 insertions(+), 450 deletions(-) diff --git a/src/crewai/telemetry/telemetry.py b/src/crewai/telemetry/telemetry.py index f6a018f27..a08ccd96f 100644 --- a/src/crewai/telemetry/telemetry.py +++ b/src/crewai/telemetry/telemetry.py @@ -65,7 +65,7 @@ class Telemetry: self.provider.add_span_processor(processor) self.ready = True - except BaseException as e: + except Exception as e: if isinstance( e, (SystemExit, KeyboardInterrupt, GeneratorExit, asyncio.CancelledError), @@ -83,404 +83,33 @@ class Telemetry: self.ready = False self.trace_set = False + def _safe_telemetry_operation(self, operation): + if not self.ready: + return + try: + operation() + except Exception: + pass + def crew_creation(self, crew: Crew, inputs: dict[str, Any] | None): """Records the creation of a crew.""" - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Crew Created") - self._add_attribute( - span, - "crewai_version", - pkg_resources.get_distribution("crewai").version, - ) - self._add_attribute(span, "python_version", platform.python_version()) - self._add_attribute(span, "crew_key", crew.key) - self._add_attribute(span, "crew_id", str(crew.id)) - self._add_attribute(span, "crew_process", crew.process) - self._add_attribute(span, "crew_memory", crew.memory) - self._add_attribute(span, "crew_number_of_tasks", len(crew.tasks)) - self._add_attribute(span, "crew_number_of_agents", len(crew.agents)) - if crew.share_crew: - self._add_attribute( - span, - "crew_agents", - json.dumps( - [ - { - "key": agent.key, - "id": str(agent.id), - "role": agent.role, - "goal": agent.goal, - "backstory": agent.backstory, - "verbose?": agent.verbose, - "max_iter": agent.max_iter, - "max_rpm": agent.max_rpm, - "i18n": agent.i18n.prompt_file, - "function_calling_llm": ( - agent.function_calling_llm.model - if agent.function_calling_llm - else "" - ), - "llm": agent.llm.model, - "delegation_enabled?": agent.allow_delegation, - "allow_code_execution?": agent.allow_code_execution, - "max_retry_limit": agent.max_retry_limit, - "tools_names": [ - tool.name.casefold() - for tool in agent.tools or [] - ], - } - for agent in crew.agents - ] - ), - ) - self._add_attribute( - span, - "crew_tasks", - json.dumps( - [ - { - "key": task.key, - "id": str(task.id), - "description": task.description, - "expected_output": task.expected_output, - "async_execution?": task.async_execution, - "human_input?": task.human_input, - "agent_role": ( - task.agent.role if task.agent else "None" - ), - "agent_key": task.agent.key if task.agent else None, - "context": ( - [task.description for task in task.context] - if task.context - else None - ), - "tools_names": [ - tool.name.casefold() - for tool in task.tools or [] - ], - } - for task in crew.tasks - ] - ), - ) - self._add_attribute(span, "platform", platform.platform()) - self._add_attribute(span, "platform_release", platform.release()) - self._add_attribute(span, "platform_system", platform.system()) - self._add_attribute(span, "platform_version", platform.version()) - self._add_attribute(span, "cpus", os.cpu_count()) - self._add_attribute( - span, "crew_inputs", json.dumps(inputs) if inputs else None - ) - else: - self._add_attribute( - span, - "crew_agents", - json.dumps( - [ - { - "key": agent.key, - "id": str(agent.id), - "role": agent.role, - "verbose?": agent.verbose, - "max_iter": agent.max_iter, - "max_rpm": agent.max_rpm, - "function_calling_llm": ( - agent.function_calling_llm.model - if agent.function_calling_llm - else "" - ), - "llm": agent.llm.model, - "delegation_enabled?": agent.allow_delegation, - "allow_code_execution?": agent.allow_code_execution, - "max_retry_limit": agent.max_retry_limit, - "tools_names": [ - tool.name.casefold() - for tool in agent.tools or [] - ], - } - for agent in crew.agents - ] - ), - ) - self._add_attribute( - span, - "crew_tasks", - json.dumps( - [ - { - "key": task.key, - "id": str(task.id), - "async_execution?": task.async_execution, - "human_input?": task.human_input, - "agent_role": ( - task.agent.role if task.agent else "None" - ), - "agent_key": task.agent.key if task.agent else None, - "tools_names": [ - tool.name.casefold() - for tool in task.tools or [] - ], - } - for task in crew.tasks - ] - ), - ) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - def task_started(self, crew: Crew, task: Task) -> Span | None: - """Records task started in a crew.""" - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - - created_span = tracer.start_span("Task Created") - - self._add_attribute(created_span, "crew_key", crew.key) - self._add_attribute(created_span, "crew_id", str(crew.id)) - self._add_attribute(created_span, "task_key", task.key) - self._add_attribute(created_span, "task_id", str(task.id)) - - if crew.share_crew: - self._add_attribute( - created_span, "formatted_description", task.description - ) - self._add_attribute( - created_span, "formatted_expected_output", task.expected_output - ) - - created_span.set_status(Status(StatusCode.OK)) - created_span.end() - - span = tracer.start_span("Task Execution") - - self._add_attribute(span, "crew_key", crew.key) - self._add_attribute(span, "crew_id", str(crew.id)) - self._add_attribute(span, "task_key", task.key) - self._add_attribute(span, "task_id", str(task.id)) - - if crew.share_crew: - self._add_attribute(span, "formatted_description", task.description) - self._add_attribute( - span, "formatted_expected_output", task.expected_output - ) - - return span - except Exception: - pass - - return None - - def task_ended(self, span: Span, task: Task, crew: Crew): - """Records task execution in a crew.""" - if self.ready: - try: - if crew.share_crew: - self._add_attribute( - span, - "task_output", - task.output.raw if task.output else "", - ) - - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def tool_repeated_usage(self, llm: Any, tool_name: str, attempts: int): - """Records the repeated usage 'error' of a tool by an agent.""" - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Tool Repeated Usage") - self._add_attribute( - span, - "crewai_version", - pkg_resources.get_distribution("crewai").version, - ) - self._add_attribute(span, "tool_name", tool_name) - self._add_attribute(span, "attempts", attempts) - if llm: - self._add_attribute(span, "llm", llm.model) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def tool_usage(self, llm: Any, tool_name: str, attempts: int): - """Records the usage of a tool by an agent.""" - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Tool Usage") - self._add_attribute( - span, - "crewai_version", - pkg_resources.get_distribution("crewai").version, - ) - self._add_attribute(span, "tool_name", tool_name) - self._add_attribute(span, "attempts", attempts) - if llm: - self._add_attribute(span, "llm", llm.model) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def tool_usage_error(self, llm: Any): - """Records the usage of a tool by an agent.""" - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Tool Usage Error") - self._add_attribute( - span, - "crewai_version", - pkg_resources.get_distribution("crewai").version, - ) - if llm: - self._add_attribute(span, "llm", llm.model) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def individual_test_result_span( - self, crew: Crew, quality: float, exec_time: int, model_name: str - ): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Crew Individual Test Result") - - self._add_attribute( - span, - "crewai_version", - pkg_resources.get_distribution("crewai").version, - ) - self._add_attribute(span, "crew_key", crew.key) - self._add_attribute(span, "crew_id", str(crew.id)) - self._add_attribute(span, "quality", str(quality)) - self._add_attribute(span, "exec_time", str(exec_time)) - self._add_attribute(span, "model_name", model_name) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def test_execution_span( - self, - crew: Crew, - iterations: int, - inputs: dict[str, Any] | None, - model_name: str, - ): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Crew Test Execution") - - self._add_attribute( - span, - "crewai_version", - pkg_resources.get_distribution("crewai").version, - ) - self._add_attribute(span, "crew_key", crew.key) - self._add_attribute(span, "crew_id", str(crew.id)) - self._add_attribute(span, "iterations", str(iterations)) - self._add_attribute(span, "model_name", model_name) - - if crew.share_crew: - self._add_attribute( - span, "inputs", json.dumps(inputs) if inputs else None - ) - - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def deploy_signup_error_span(self): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Deploy Signup Error") - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def start_deployment_span(self, uuid: Optional[str] = None): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Start Deployment") - if uuid: - self._add_attribute(span, "uuid", uuid) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def create_crew_deployment_span(self): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Create Crew Deployment") - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def get_crew_logs_span(self, uuid: Optional[str], log_type: str = "deployment"): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Get Crew Logs") - self._add_attribute(span, "log_type", log_type) - if uuid: - self._add_attribute(span, "uuid", uuid) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def remove_crew_span(self, uuid: Optional[str] = None): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Remove Crew") - if uuid: - self._add_attribute(span, "uuid", uuid) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass - - def crew_execution_span(self, crew: Crew, inputs: dict[str, Any] | None): - """Records the complete execution of a crew. - This is only collected if the user has opted-in to share the crew. - """ - self.crew_creation(crew, inputs) - - if (self.ready) and (crew.share_crew): - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Crew Execution") - self._add_attribute( - span, - "crewai_version", - pkg_resources.get_distribution("crewai").version, - ) - self._add_attribute(span, "crew_key", crew.key) - self._add_attribute(span, "crew_id", str(crew.id)) - self._add_attribute( - span, "crew_inputs", json.dumps(inputs) if inputs else None - ) + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Crew Created") + self._add_attribute( + span, + "crewai_version", + pkg_resources.get_distribution("crewai").version, + ) + self._add_attribute(span, "python_version", platform.python_version()) + self._add_attribute(span, "crew_key", crew.key) + self._add_attribute(span, "crew_id", str(crew.id)) + self._add_attribute(span, "crew_process", crew.process) + self._add_attribute(span, "crew_memory", crew.memory) + self._add_attribute(span, "crew_number_of_tasks", len(crew.tasks)) + self._add_attribute(span, "crew_number_of_agents", len(crew.agents)) + if crew.share_crew: self._add_attribute( span, "crew_agents", @@ -496,8 +125,15 @@ class Telemetry: "max_iter": agent.max_iter, "max_rpm": agent.max_rpm, "i18n": agent.i18n.prompt_file, + "function_calling_llm": ( + agent.function_calling_llm.model + if agent.function_calling_llm + else "" + ), "llm": agent.llm.model, "delegation_enabled?": agent.allow_delegation, + "allow_code_execution?": agent.allow_code_execution, + "max_retry_limit": agent.max_retry_limit, "tools_names": [ tool.name.casefold() for tool in agent.tools or [] ], @@ -512,12 +148,15 @@ class Telemetry: json.dumps( [ { + "key": task.key, "id": str(task.id), "description": task.description, "expected_output": task.expected_output, "async_execution?": task.async_execution, "human_input?": task.human_input, - "agent_role": task.agent.role if task.agent else "None", + "agent_role": ( + task.agent.role if task.agent else "None" + ), "agent_key": task.agent.key if task.agent else None, "context": ( [task.description for task in task.context] @@ -532,78 +171,433 @@ class Telemetry: ] ), ) - return span - except Exception: - pass - - def end_crew(self, crew, final_string_output): - if (self.ready) and (crew.share_crew): - try: + self._add_attribute(span, "platform", platform.platform()) + self._add_attribute(span, "platform_release", platform.release()) + self._add_attribute(span, "platform_system", platform.system()) + self._add_attribute(span, "platform_version", platform.version()) + self._add_attribute(span, "cpus", os.cpu_count()) self._add_attribute( - crew._execution_span, - "crewai_version", - pkg_resources.get_distribution("crewai").version, + span, "crew_inputs", json.dumps(inputs) if inputs else None ) + else: self._add_attribute( - crew._execution_span, "crew_output", final_string_output - ) - self._add_attribute( - crew._execution_span, - "crew_tasks_output", + span, + "crew_agents", json.dumps( [ { + "key": agent.key, + "id": str(agent.id), + "role": agent.role, + "verbose?": agent.verbose, + "max_iter": agent.max_iter, + "max_rpm": agent.max_rpm, + "function_calling_llm": ( + agent.function_calling_llm.model + if agent.function_calling_llm + else "" + ), + "llm": agent.llm.model, + "delegation_enabled?": agent.allow_delegation, + "allow_code_execution?": agent.allow_code_execution, + "max_retry_limit": agent.max_retry_limit, + "tools_names": [ + tool.name.casefold() for tool in agent.tools or [] + ], + } + for agent in crew.agents + ] + ), + ) + self._add_attribute( + span, + "crew_tasks", + json.dumps( + [ + { + "key": task.key, "id": str(task.id), - "description": task.description, - "output": task.output.raw_output, + "async_execution?": task.async_execution, + "human_input?": task.human_input, + "agent_role": ( + task.agent.role if task.agent else "None" + ), + "agent_key": task.agent.key if task.agent else None, + "tools_names": [ + tool.name.casefold() for tool in task.tools or [] + ], } for task in crew.tasks ] ), ) - crew._execution_span.set_status(Status(StatusCode.OK)) - crew._execution_span.end() - except Exception: - pass + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def task_started(self, crew: Crew, task: Task) -> Span | None: + """Records task started in a crew.""" + + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + + created_span = tracer.start_span("Task Created") + + self._add_attribute(created_span, "crew_key", crew.key) + self._add_attribute(created_span, "crew_id", str(crew.id)) + self._add_attribute(created_span, "task_key", task.key) + self._add_attribute(created_span, "task_id", str(task.id)) + + if crew.share_crew: + self._add_attribute( + created_span, "formatted_description", task.description + ) + self._add_attribute( + created_span, "formatted_expected_output", task.expected_output + ) + + created_span.set_status(Status(StatusCode.OK)) + created_span.end() + + span = tracer.start_span("Task Execution") + + self._add_attribute(span, "crew_key", crew.key) + self._add_attribute(span, "crew_id", str(crew.id)) + self._add_attribute(span, "task_key", task.key) + self._add_attribute(span, "task_id", str(task.id)) + + if crew.share_crew: + self._add_attribute(span, "formatted_description", task.description) + self._add_attribute( + span, "formatted_expected_output", task.expected_output + ) + + return span + + return self._safe_telemetry_operation(operation) + + def task_ended(self, span: Span, task: Task, crew: Crew): + """Records task execution in a crew.""" + + def operation(): + if crew.share_crew: + self._add_attribute( + span, + "task_output", + task.output.raw if task.output else "", + ) + + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def tool_repeated_usage(self, llm: Any, tool_name: str, attempts: int): + """Records the repeated usage 'error' of a tool by an agent.""" + + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Tool Repeated Usage") + self._add_attribute( + span, + "crewai_version", + pkg_resources.get_distribution("crewai").version, + ) + self._add_attribute(span, "tool_name", tool_name) + self._add_attribute(span, "attempts", attempts) + if llm: + self._add_attribute(span, "llm", llm.model) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def tool_usage(self, llm: Any, tool_name: str, attempts: int): + """Records the usage of a tool by an agent.""" + + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Tool Usage") + self._add_attribute( + span, + "crewai_version", + pkg_resources.get_distribution("crewai").version, + ) + self._add_attribute(span, "tool_name", tool_name) + self._add_attribute(span, "attempts", attempts) + if llm: + self._add_attribute(span, "llm", llm.model) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def tool_usage_error(self, llm: Any): + """Records the usage of a tool by an agent.""" + + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Tool Usage Error") + self._add_attribute( + span, + "crewai_version", + pkg_resources.get_distribution("crewai").version, + ) + if llm: + self._add_attribute(span, "llm", llm.model) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def individual_test_result_span( + self, crew: Crew, quality: float, exec_time: int, model_name: str + ): + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Crew Individual Test Result") + + self._add_attribute( + span, + "crewai_version", + pkg_resources.get_distribution("crewai").version, + ) + self._add_attribute(span, "crew_key", crew.key) + self._add_attribute(span, "crew_id", str(crew.id)) + self._add_attribute(span, "quality", str(quality)) + self._add_attribute(span, "exec_time", str(exec_time)) + self._add_attribute(span, "model_name", model_name) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def test_execution_span( + self, + crew: Crew, + iterations: int, + inputs: dict[str, Any] | None, + model_name: str, + ): + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Crew Test Execution") + + self._add_attribute( + span, + "crewai_version", + pkg_resources.get_distribution("crewai").version, + ) + self._add_attribute(span, "crew_key", crew.key) + self._add_attribute(span, "crew_id", str(crew.id)) + self._add_attribute(span, "iterations", str(iterations)) + self._add_attribute(span, "model_name", model_name) + + if crew.share_crew: + self._add_attribute( + span, "inputs", json.dumps(inputs) if inputs else None + ) + + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def deploy_signup_error_span(self): + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Deploy Signup Error") + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def start_deployment_span(self, uuid: Optional[str] = None): + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Start Deployment") + if uuid: + self._add_attribute(span, "uuid", uuid) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def create_crew_deployment_span(self): + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Create Crew Deployment") + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def get_crew_logs_span(self, uuid: Optional[str], log_type: str = "deployment"): + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Get Crew Logs") + self._add_attribute(span, "log_type", log_type) + if uuid: + self._add_attribute(span, "uuid", uuid) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def remove_crew_span(self, uuid: Optional[str] = None): + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Remove Crew") + if uuid: + self._add_attribute(span, "uuid", uuid) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) + + def crew_execution_span(self, crew: Crew, inputs: dict[str, Any] | None): + """Records the complete execution of a crew. + This is only collected if the user has opted-in to share the crew. + """ + self.crew_creation(crew, inputs) + + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Crew Execution") + self._add_attribute( + span, + "crewai_version", + pkg_resources.get_distribution("crewai").version, + ) + self._add_attribute(span, "crew_key", crew.key) + self._add_attribute(span, "crew_id", str(crew.id)) + self._add_attribute( + span, "crew_inputs", json.dumps(inputs) if inputs else None + ) + self._add_attribute( + span, + "crew_agents", + json.dumps( + [ + { + "key": agent.key, + "id": str(agent.id), + "role": agent.role, + "goal": agent.goal, + "backstory": agent.backstory, + "verbose?": agent.verbose, + "max_iter": agent.max_iter, + "max_rpm": agent.max_rpm, + "i18n": agent.i18n.prompt_file, + "llm": agent.llm.model, + "delegation_enabled?": agent.allow_delegation, + "tools_names": [ + tool.name.casefold() for tool in agent.tools or [] + ], + } + for agent in crew.agents + ] + ), + ) + self._add_attribute( + span, + "crew_tasks", + json.dumps( + [ + { + "id": str(task.id), + "description": task.description, + "expected_output": task.expected_output, + "async_execution?": task.async_execution, + "human_input?": task.human_input, + "agent_role": task.agent.role if task.agent else "None", + "agent_key": task.agent.key if task.agent else None, + "context": ( + [task.description for task in task.context] + if task.context + else None + ), + "tools_names": [ + tool.name.casefold() for tool in task.tools or [] + ], + } + for task in crew.tasks + ] + ), + ) + return span + + if crew.share_crew: + return self._safe_telemetry_operation(operation) + return None + + def end_crew(self, crew, final_string_output): + def operation(): + self._add_attribute( + crew._execution_span, + "crewai_version", + pkg_resources.get_distribution("crewai").version, + ) + self._add_attribute( + crew._execution_span, "crew_output", final_string_output + ) + self._add_attribute( + crew._execution_span, + "crew_tasks_output", + json.dumps( + [ + { + "id": str(task.id), + "description": task.description, + "output": task.output.raw_output, + } + for task in crew.tasks + ] + ), + ) + crew._execution_span.set_status(Status(StatusCode.OK)) + crew._execution_span.end() + + if crew.share_crew: + self._safe_telemetry_operation(operation) def _add_attribute(self, span, key, value): """Add an attribute to a span.""" - try: + + def operation(): return span.set_attribute(key, value) - except Exception: - pass + + self._safe_telemetry_operation(operation) def flow_creation_span(self, flow_name: str): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Flow Creation") - self._add_attribute(span, "flow_name", flow_name) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Flow Creation") + self._add_attribute(span, "flow_name", flow_name) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) def flow_plotting_span(self, flow_name: str, node_names: list[str]): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Flow Plotting") - self._add_attribute(span, "flow_name", flow_name) - self._add_attribute(span, "node_names", json.dumps(node_names)) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Flow Plotting") + self._add_attribute(span, "flow_name", flow_name) + self._add_attribute(span, "node_names", json.dumps(node_names)) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) def flow_execution_span(self, flow_name: str, node_names: list[str]): - if self.ready: - try: - tracer = trace.get_tracer("crewai.telemetry") - span = tracer.start_span("Flow Execution") - self._add_attribute(span, "flow_name", flow_name) - self._add_attribute(span, "node_names", json.dumps(node_names)) - span.set_status(Status(StatusCode.OK)) - span.end() - except Exception: - pass + def operation(): + tracer = trace.get_tracer("crewai.telemetry") + span = tracer.start_span("Flow Execution") + self._add_attribute(span, "flow_name", flow_name) + self._add_attribute(span, "node_names", json.dumps(node_names)) + span.set_status(Status(StatusCode.OK)) + span.end() + + self._safe_telemetry_operation(operation) From 60efcad481f68c3d650c810df7ba5e45d2826574 Mon Sep 17 00:00:00 2001 From: Eduardo Chiarotti Date: Fri, 18 Oct 2024 15:45:01 -0300 Subject: [PATCH 08/19] feat: add poetry.lock to uv migration (#1468) --- src/crewai/cli/update_crew.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/crewai/cli/update_crew.py b/src/crewai/cli/update_crew.py index e2d39590d..d38e11a25 100644 --- a/src/crewai/cli/update_crew.py +++ b/src/crewai/cli/update_crew.py @@ -1,3 +1,4 @@ +import os import shutil import tomli_w @@ -94,6 +95,15 @@ def migrate_pyproject(input_file, output_file): shutil.copy2(input_file, backup_file) print(f"Original pyproject.toml backed up as {backup_file}") + # Rename the poetry.lock file + lock_file = "poetry.lock" + lock_backup = "poetry-old.lock" + if os.path.exists(lock_file): + os.rename(lock_file, lock_backup) + print(f"Original poetry.lock renamed to {lock_backup}") + else: + print("No poetry.lock file found to rename.") + # Write the new pyproject.toml with open(output_file, "wb") as f: tomli_w.dump(new_pyproject, f) From 84f48c465d602a2b121a82d464fe701f84160e9f Mon Sep 17 00:00:00 2001 From: "Brandon Hancock (bhancock_ai)" <109994880+bhancockio@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:56:56 -0400 Subject: [PATCH 09/19] fix tool calling issue (#1467) * fix tool calling issue * Update tool type check * Drop print --- src/crewai/agent.py | 2 +- src/crewai/agents/crew_agent_executor.py | 8 +- src/crewai/tools/tool_usage.py | 10 +- tests/tools/test_tool_usage.py | 143 +++++++++++++++++++++++ 4 files changed, 154 insertions(+), 9 deletions(-) create mode 100644 tests/tools/test_tool_usage.py diff --git a/src/crewai/agent.py b/src/crewai/agent.py index 3f81ece21..165a40656 100644 --- a/src/crewai/agent.py +++ b/src/crewai/agent.py @@ -394,7 +394,7 @@ class Agent(BaseAgent): """ tool_strings = [] for tool in tools: - args_schema = str(tool.args) + args_schema = str(tool.model_fields) if hasattr(tool, "func") and tool.func: sig = signature(tool.func) description = ( diff --git a/src/crewai/agents/crew_agent_executor.py b/src/crewai/agents/crew_agent_executor.py index b901fe132..b11782ca1 100644 --- a/src/crewai/agents/crew_agent_executor.py +++ b/src/crewai/agents/crew_agent_executor.py @@ -2,6 +2,7 @@ import json import re from typing import Any, Dict, List, Union +from crewai.agents.agent_builder.base_agent import BaseAgent from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin from crewai.agents.parser import ( FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE, @@ -19,7 +20,6 @@ from crewai.utilities.exceptions.context_window_exceeding_exception import ( ) from crewai.utilities.logger import Logger from crewai.utilities.training_handler import CrewTrainingHandler -from crewai.agents.agent_builder.base_agent import BaseAgent class CrewAgentExecutor(CrewAgentExecutorMixin): @@ -323,9 +323,9 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): if self.crew is not None and hasattr(self.crew, "_train_iteration"): train_iteration = self.crew._train_iteration if agent_id in training_data and isinstance(train_iteration, int): - training_data[agent_id][train_iteration]["improved_output"] = ( - result.output - ) + training_data[agent_id][train_iteration][ + "improved_output" + ] = result.output training_handler.save(training_data) else: self._logger.log( diff --git a/src/crewai/tools/tool_usage.py b/src/crewai/tools/tool_usage.py index f75a9443a..71c02fc3c 100644 --- a/src/crewai/tools/tool_usage.py +++ b/src/crewai/tools/tool_usage.py @@ -6,14 +6,13 @@ from difflib import SequenceMatcher from textwrap import dedent from typing import Any, List, Union +import crewai.utilities.events as events from crewai.agents.tools_handler import ToolsHandler from crewai.task import Task from crewai.telemetry import Telemetry 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 -import crewai.utilities.events as events - agentops = None if os.environ.get("AGENTOPS_API_KEY"): @@ -300,8 +299,11 @@ class ToolUsage: descriptions = [] for tool in self.tools: args = { - k: {k2: v2 for k2, v2 in v.items() if k2 in ["description", "type"]} - for k, v in tool.args.items() + name: { + "description": field.description, + "type": field.annotation.__name__, + } + for name, field in tool.args_schema.model_fields.items() } descriptions.append( "\n".join( diff --git a/tests/tools/test_tool_usage.py b/tests/tools/test_tool_usage.py new file mode 100644 index 000000000..d0a6ec0b0 --- /dev/null +++ b/tests/tools/test_tool_usage.py @@ -0,0 +1,143 @@ +import json +import random +from unittest.mock import MagicMock, patch + +import pytest +from crewai_tools import BaseTool +from pydantic import BaseModel, Field + +from crewai import Agent, Crew, Task +from crewai.tools.tool_usage import ToolUsage + + +class RandomNumberToolInput(BaseModel): + min_value: int = Field( + ..., description="The minimum value of the range (inclusive)" + ) + max_value: int = Field( + ..., description="The maximum value of the range (inclusive)" + ) + + +class RandomNumberTool(BaseTool): + name: str = "Random Number Generator" + description: str = "Generates a random number within a specified range" + args_schema: type[BaseModel] = RandomNumberToolInput + + def _run(self, min_value: int, max_value: int) -> int: + return random.randint(min_value, max_value) + + +# Example agent and task +example_agent = Agent( + role="Number Generator", + goal="Generate random numbers for various purposes", + backstory="You are an AI agent specialized in generating random numbers within specified ranges.", + tools=[RandomNumberTool()], + verbose=True, +) + +example_task = Task( + description="Generate a random number between 1 and 100", + expected_output="A random number between 1 and 100", + agent=example_agent, +) + + +def test_random_number_tool_usage(): + crew = Crew( + agents=[example_agent], + tasks=[example_task], + ) + + with patch.object(random, "randint", return_value=42): + result = crew.kickoff() + + assert "42" in result.raw + + +def test_random_number_tool_range(): + tool = RandomNumberTool() + result = tool._run(1, 10) + assert 1 <= result <= 10 + + +def test_random_number_tool_with_crew(): + crew = Crew( + agents=[example_agent], + tasks=[example_task], + ) + + result = crew.kickoff() + + # Check if the result contains a number between 1 and 100 + assert any(str(num) in result.raw for num in range(1, 101)) + + +def test_random_number_tool_invalid_range(): + tool = RandomNumberTool() + with pytest.raises(ValueError): + tool._run(10, 1) # min_value > max_value + + +def test_random_number_tool_schema(): + tool = RandomNumberTool() + + # Get the schema using model_json_schema() + schema = tool.args_schema.model_json_schema() + + # Convert the schema to a string + schema_str = json.dumps(schema) + + # Check if the schema string contains the expected fields + assert "min_value" in schema_str + assert "max_value" in schema_str + + # Parse the schema string back to a dictionary + schema_dict = json.loads(schema_str) + + # Check if the schema contains the correct field types + assert schema_dict["properties"]["min_value"]["type"] == "integer" + assert schema_dict["properties"]["max_value"]["type"] == "integer" + + # Check if the schema contains the field descriptions + assert ( + "minimum value" in schema_dict["properties"]["min_value"]["description"].lower() + ) + assert ( + "maximum value" in schema_dict["properties"]["max_value"]["description"].lower() + ) + + +def test_tool_usage_render(): + tool = RandomNumberTool() + + tool_usage = ToolUsage( + tools_handler=MagicMock(), + tools=[tool], + original_tools=[tool], + tools_description="Sample tool for testing", + tools_names="random_number_generator", + task=MagicMock(), + function_calling_llm=MagicMock(), + agent=MagicMock(), + action=MagicMock(), + ) + + rendered = tool_usage._render() + + # Updated checks to match the actual output + assert "Tool Name: random number generator" in rendered + assert ( + "Random Number Generator(min_value: 'integer', max_value: 'integer') - Generates a random number within a specified range min_value: 'The minimum value of the range (inclusive)', max_value: 'The maximum value of the range (inclusive)'" + in rendered + ) + assert "Tool Arguments:" in rendered + assert ( + "'min_value': {'description': 'The minimum value of the range (inclusive)', 'type': 'int'}" + in rendered + ) + assert ( + "'max_value': {'description': 'The maximum value of the range (inclusive)', 'type': 'int'}" + in rendered + ) From d1737a96fb732d172eb91b503ebd0c1b383af144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moura?= Date: Fri, 18 Oct 2024 17:56:28 -0300 Subject: [PATCH 10/19] cutting new version --- pyproject.toml | 8 ++++---- src/crewai/__init__.py | 2 +- src/crewai/cli/templates/crew/pyproject.toml | 2 +- src/crewai/cli/templates/flow/pyproject.toml | 2 +- src/crewai/cli/templates/pipeline/pyproject.toml | 2 +- .../cli/templates/pipeline_router/pyproject.toml | 2 +- src/crewai/cli/templates/tool/pyproject.toml | 2 +- uv.lock | 14 +++++++------- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e47748e28..436a01170 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "crewai" -version = "0.74.0" +version = "0.74.1" 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.13" @@ -16,7 +16,7 @@ dependencies = [ "opentelemetry-exporter-otlp-proto-http>=1.22.0", "instructor>=1.3.3", "regex>=2024.9.11", - "crewai-tools>=0.13.1", + "crewai-tools>=0.13.2", "click>=8.1.7", "python-dotenv>=1.0.0", "appdirs>=1.4.4", @@ -36,7 +36,7 @@ Documentation = "https://docs.crewai.com" Repository = "https://github.com/crewAIInc/crewAI" [project.optional-dependencies] -tools = ["crewai-tools>=0.12.1"] +tools = ["crewai-tools>=0.13.2"] agentops = ["agentops>=0.3.0"] [tool.uv] @@ -51,7 +51,7 @@ dev-dependencies = [ "mkdocs-material-extensions>=1.3.1", "pillow>=10.2.0", "cairosvg>=2.7.1", - "crewai-tools>=0.12.1", + "crewai-tools>=0.13.2", "pytest>=8.0.0", "pytest-vcr>=1.0.2", "python-dotenv>=1.0.0", diff --git a/src/crewai/__init__.py b/src/crewai/__init__.py index a72d6e805..41da7aa21 100644 --- a/src/crewai/__init__.py +++ b/src/crewai/__init__.py @@ -14,5 +14,5 @@ warnings.filterwarnings( category=UserWarning, module="pydantic.main", ) -__version__ = "0.74.0" +__version__ = "0.74.1" __all__ = ["Agent", "Crew", "Process", "Task", "Pipeline", "Router", "LLM", "Flow"] diff --git a/src/crewai/cli/templates/crew/pyproject.toml b/src/crewai/cli/templates/crew/pyproject.toml index d387443a1..35931e8e0 100644 --- a/src/crewai/cli/templates/crew/pyproject.toml +++ b/src/crewai/cli/templates/crew/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.0,<1.0.0" + "crewai[tools]>=0.74.1,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/flow/pyproject.toml b/src/crewai/cli/templates/flow/pyproject.toml index 9db16e2a2..0e81b72b9 100644 --- a/src/crewai/cli/templates/flow/pyproject.toml +++ b/src/crewai/cli/templates/flow/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.0,<1.0.0", + "crewai[tools]>=0.74.1,<1.0.0", "asyncio" ] diff --git a/src/crewai/cli/templates/pipeline/pyproject.toml b/src/crewai/cli/templates/pipeline/pyproject.toml index 3eb9b73d1..d8c2c64b3 100644 --- a/src/crewai/cli/templates/pipeline/pyproject.toml +++ b/src/crewai/cli/templates/pipeline/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Your Name "] [tool.poetry.dependencies] python = ">=3.10,<=3.13" -crewai = { extras = ["tools"], version = ">=0.74.0,<1.0.0" } +crewai = { extras = ["tools"], version = ">=0.74.1,<1.0.0" } asyncio = "*" [tool.poetry.scripts] diff --git a/src/crewai/cli/templates/pipeline_router/pyproject.toml b/src/crewai/cli/templates/pipeline_router/pyproject.toml index dabc8d281..a672ba2b7 100644 --- a/src/crewai/cli/templates/pipeline_router/pyproject.toml +++ b/src/crewai/cli/templates/pipeline_router/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = ["Your Name "] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.0,<1.0.0" + "crewai[tools]>=0.74.1,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/tool/pyproject.toml b/src/crewai/cli/templates/tool/pyproject.toml index 0fef250f5..21e520146 100644 --- a/src/crewai/cli/templates/tool/pyproject.toml +++ b/src/crewai/cli/templates/tool/pyproject.toml @@ -5,6 +5,6 @@ description = "Power up your crews with {{folder_name}}" readme = "README.md" requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.0" + "crewai[tools]>=0.74.1" ] diff --git a/uv.lock b/uv.lock index b0416fa72..1d2f9cb39 100644 --- a/uv.lock +++ b/uv.lock @@ -627,7 +627,7 @@ wheels = [ [[package]] name = "crewai" -version = "0.74.0" +version = "0.74.1" source = { editable = "." } dependencies = [ { name = "appdirs" }, @@ -687,8 +687,8 @@ requires-dist = [ { name = "auth0-python", specifier = ">=4.7.1" }, { name = "chromadb", specifier = ">=0.4.24" }, { name = "click", specifier = ">=8.1.7" }, - { name = "crewai-tools", specifier = ">=0.13.1" }, - { name = "crewai-tools", marker = "extra == 'tools'", specifier = ">=0.12.1" }, + { name = "crewai-tools", specifier = ">=0.13.2" }, + { name = "crewai-tools", marker = "extra == 'tools'", specifier = ">=0.13.2" }, { name = "instructor", specifier = ">=1.3.3" }, { name = "json-repair", specifier = ">=0.25.2" }, { name = "jsonref", specifier = ">=1.1.0" }, @@ -709,7 +709,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "cairosvg", specifier = ">=2.7.1" }, - { name = "crewai-tools", specifier = ">=0.12.1" }, + { name = "crewai-tools", specifier = ">=0.13.2" }, { name = "mkdocs", specifier = ">=1.4.3" }, { name = "mkdocs-material", specifier = ">=9.5.7" }, { name = "mkdocs-material-extensions", specifier = ">=1.3.1" }, @@ -728,7 +728,7 @@ dev = [ [[package]] name = "crewai-tools" -version = "0.13.1" +version = "0.13.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "beautifulsoup4" }, @@ -746,9 +746,9 @@ dependencies = [ { name = "requests" }, { name = "selenium" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d5/81/b8a0bb984aea2af49b0072e074c87c75a6c4581902b81f3a3d46f95f01c7/crewai_tools-0.13.1.tar.gz", hash = "sha256:363c7ec717f4c6f9b61cec9314a5ec2fbd026d75e8e6278f49f715ed5915cd4d", size = 816254 } +sdist = { url = "https://files.pythonhosted.org/packages/96/02/136f42ed8a7bd706a85663714c615bdcb684e43e95e4719c892aa0ce3d53/crewai_tools-0.13.2.tar.gz", hash = "sha256:c6782f2e868c0e96b25891f1b40fb8c90c01e920bab2fd1388f89ef1d7a4b99b", size = 816250 } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/8a/04c885da3e01d1f11478dd866d3506906bfb60d7587627dd4b132ff10f64/crewai_tools-0.13.1-py3-none-any.whl", hash = "sha256:62067e2502bf66c0ae2e3a833c60b900bd1f793a9a80895a1f10a9cfa1b5dc3c", size = 463444 }, + { url = "https://files.pythonhosted.org/packages/28/30/df215173b6193b2cfb1902a339443be73056eae89579805b853c6f359761/crewai_tools-0.13.2-py3-none-any.whl", hash = "sha256:8c7583c9559fb625f594349c6553a5251ebd7b21918735ad6fbe8bab7ec3db50", size = 463444 }, ] [[package]] From 40f81aecf5a84dbb5361dfa86044d72990390084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moura?= Date: Fri, 18 Oct 2024 17:57:37 -0300 Subject: [PATCH 11/19] new verison --- pyproject.toml | 2 +- src/crewai/__init__.py | 2 +- src/crewai/cli/templates/crew/pyproject.toml | 2 +- src/crewai/cli/templates/flow/pyproject.toml | 2 +- src/crewai/cli/templates/pipeline/pyproject.toml | 2 +- src/crewai/cli/templates/pipeline_router/pyproject.toml | 2 +- src/crewai/cli/templates/tool/pyproject.toml | 2 +- uv.lock | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 436a01170..772d41b36 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "crewai" -version = "0.74.1" +version = "0.74.2" 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.13" diff --git a/src/crewai/__init__.py b/src/crewai/__init__.py index 41da7aa21..a41e3827f 100644 --- a/src/crewai/__init__.py +++ b/src/crewai/__init__.py @@ -14,5 +14,5 @@ warnings.filterwarnings( category=UserWarning, module="pydantic.main", ) -__version__ = "0.74.1" +__version__ = "0.74.2" __all__ = ["Agent", "Crew", "Process", "Task", "Pipeline", "Router", "LLM", "Flow"] diff --git a/src/crewai/cli/templates/crew/pyproject.toml b/src/crewai/cli/templates/crew/pyproject.toml index 35931e8e0..36ba1548c 100644 --- a/src/crewai/cli/templates/crew/pyproject.toml +++ b/src/crewai/cli/templates/crew/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.1,<1.0.0" + "crewai[tools]>=0.74.2,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/flow/pyproject.toml b/src/crewai/cli/templates/flow/pyproject.toml index 0e81b72b9..490d66346 100644 --- a/src/crewai/cli/templates/flow/pyproject.toml +++ b/src/crewai/cli/templates/flow/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.1,<1.0.0", + "crewai[tools]>=0.74.2,<1.0.0", "asyncio" ] diff --git a/src/crewai/cli/templates/pipeline/pyproject.toml b/src/crewai/cli/templates/pipeline/pyproject.toml index d8c2c64b3..517c2a4d1 100644 --- a/src/crewai/cli/templates/pipeline/pyproject.toml +++ b/src/crewai/cli/templates/pipeline/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Your Name "] [tool.poetry.dependencies] python = ">=3.10,<=3.13" -crewai = { extras = ["tools"], version = ">=0.74.1,<1.0.0" } +crewai = { extras = ["tools"], version = ">=0.74.2,<1.0.0" } asyncio = "*" [tool.poetry.scripts] diff --git a/src/crewai/cli/templates/pipeline_router/pyproject.toml b/src/crewai/cli/templates/pipeline_router/pyproject.toml index a672ba2b7..b349e4dda 100644 --- a/src/crewai/cli/templates/pipeline_router/pyproject.toml +++ b/src/crewai/cli/templates/pipeline_router/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = ["Your Name "] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.1,<1.0.0" + "crewai[tools]>=0.74.2,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/tool/pyproject.toml b/src/crewai/cli/templates/tool/pyproject.toml index 21e520146..bd1df942f 100644 --- a/src/crewai/cli/templates/tool/pyproject.toml +++ b/src/crewai/cli/templates/tool/pyproject.toml @@ -5,6 +5,6 @@ description = "Power up your crews with {{folder_name}}" readme = "README.md" requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.1" + "crewai[tools]>=0.74.2" ] diff --git a/uv.lock b/uv.lock index 1d2f9cb39..729338bcd 100644 --- a/uv.lock +++ b/uv.lock @@ -627,7 +627,7 @@ wheels = [ [[package]] name = "crewai" -version = "0.74.1" +version = "0.74.2" source = { editable = "." } dependencies = [ { name = "appdirs" }, From b98256e43435817395a288b1752cfc4a3de34640 Mon Sep 17 00:00:00 2001 From: Vini Brasil Date: Mon, 21 Oct 2024 09:24:03 -0300 Subject: [PATCH 12/19] Adapt `crewai tool install ` to uv (#1481) This commit updates the tool install comamnd to uv's new custom index feature. Related: https://github.com/astral-sh/uv/pull/7746/ --- pyproject.toml | 2 +- src/crewai/cli/tools/main.py | 8 ++++---- tests/cli/tools/test_main.py | 4 ++-- uv.lock | 40 ++++++++++++++++++------------------ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 772d41b36..d7920c7b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "auth0-python>=4.7.1", "litellm>=1.44.22", "pyvis>=0.3.2", - "uv>=0.4.18", + "uv>=0.4.25", "tomli-w>=1.1.0", "chromadb>=0.4.24", ] diff --git a/src/crewai/cli/tools/main.py b/src/crewai/cli/tools/main.py index b6237c61d..c875229c3 100644 --- a/src/crewai/cli/tools/main.py +++ b/src/crewai/cli/tools/main.py @@ -28,8 +28,6 @@ class ToolCommand(BaseCommand, PlusAPIMixin): A class to handle tool repository related operations for CrewAI projects. """ - BASE_URL = "https://app.crewai.com/pypi/" - def __init__(self): BaseCommand.__init__(self) PlusAPIMixin.__init__(self, telemetry=self._telemetry) @@ -178,12 +176,14 @@ class ToolCommand(BaseCommand, PlusAPIMixin): def _add_package(self, tool_details): tool_handle = tool_details["handle"] repository_handle = tool_details["repository"]["handle"] + repository_url = tool_details["repository"]["url"] + index = f"{repository_handle}={repository_url}" add_package_command = [ "uv", "add", - "--extra-index-url", - self.BASE_URL + repository_handle, + "--index", + index, tool_handle, ] add_package_result = subprocess.run( diff --git a/tests/cli/tools/test_main.py b/tests/cli/tools/test_main.py index fda833a85..e4fc19be3 100644 --- a/tests/cli/tools/test_main.py +++ b/tests/cli/tools/test_main.py @@ -75,8 +75,8 @@ def test_install_success(mock_get, mock_subprocess_run): [ "uv", "add", - "--extra-index-url", - "https://app.crewai.com/pypi/sample-repo", + "--index", + "sample-repo=https://example.com/repo", "sample-tool", ], capture_output=False, diff --git a/uv.lock b/uv.lock index 729338bcd..5d4d5b0b7 100644 --- a/uv.lock +++ b/uv.lock @@ -703,7 +703,7 @@ requires-dist = [ { name = "pyvis", specifier = ">=0.3.2" }, { name = "regex", specifier = ">=2024.9.11" }, { name = "tomli-w", specifier = ">=1.1.0" }, - { name = "uv", specifier = ">=0.4.18" }, + { name = "uv", specifier = ">=0.4.25" }, ] [package.metadata.requires-dev] @@ -4542,27 +4542,27 @@ socks = [ [[package]] name = "uv" -version = "0.4.18" +version = "0.4.25" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/60/bf5ad6895740e7269ee2f5cf7515cf2756cc8eb06c07c9783abcf1d7860f/uv-0.4.18.tar.gz", hash = "sha256:954964eff8c7e2bc63dd4beeb8d45bcaddb5149a7ef29a36abd77ec76c8b837e", size = 2008833 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/bc/1a013408b7f9f437385705652f404b6b15127ecf108327d13be493bdfb81/uv-0.4.25.tar.gz", hash = "sha256:d39077cdfe3246885fcdf32e7066ae731a166101d063629f9cea08738f79e6a3", size = 2064863 } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/f9/b3f093abb8f91e2374461b903a4f5e37e96dd04dbf584e34b79bf9a6bbdf/uv-0.4.18-py3-none-linux_armv6l.whl", hash = "sha256:1944c0ee567ca7db60705c5d213a75b25601094b026cc17af3e704651c1e3753", size = 12264752 }, - { url = "https://files.pythonhosted.org/packages/b6/98/3623ca28954953a5abdc988eb68d0460e1decf37b245c84db2d1323b17f8/uv-0.4.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5234d47abe339c15c318e8b1bbd136ea61c4574503eda6944a5aaea91b7f6775", size = 12488345 }, - { url = "https://files.pythonhosted.org/packages/29/2b/ff62b32b4a7cbfb445156b1d8757f29190f854aa702baa045e8645a19144/uv-0.4.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0c4cb31594cb2ed21bd3b603a207e99dfb9610c3db44da9dbbff0f237270f582", size = 11568639 }, - { url = "https://files.pythonhosted.org/packages/bb/7f/49a724b0c8e09fca03c166e7f18ad48c8962c9be543899a27eecc13b8b86/uv-0.4.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:8af0b60adcfa2e87c77a3008d3ed6e0b577c0535468dc58e06f905ccbd27124f", size = 11812252 }, - { url = "https://files.pythonhosted.org/packages/e5/88/0b20af8d76e7b8e6ae19af6d14180a0a9e3c23ef6f3cd38370a2ba663364/uv-0.4.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f043c3c4514c149a00a86c3bf44df43062416d41002114e60df33895e8511c41", size = 12084699 }, - { url = "https://files.pythonhosted.org/packages/a1/fe/afd83b6ed495fe40a4a738cce0de77465af452f8bd58b254a6cf7544a581/uv-0.4.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b59d742b81c7acf75a3aac71d9b24e07407e044bebcf39d3fc3c87094014e20", size = 12793964 }, - { url = "https://files.pythonhosted.org/packages/a6/54/623029d342f68518c25ed8a3863bc43ced0ad39da4dc83b310db3fe0a727/uv-0.4.18-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:fcc606da545d9a5ec5c2209e7eb2a4eb76627ad75df5eb5616c0b40789fe3933", size = 13386984 }, - { url = "https://files.pythonhosted.org/packages/e9/50/eace0e9326318bf278491aafc3d63e8675a3d03472d2bc58ef601564cbb4/uv-0.4.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c3ccee0fd8cf0a9d679407e157b76db1a854638a4ba4fa14f4d116b4e39b03", size = 13137886 }, - { url = "https://files.pythonhosted.org/packages/f7/f5/f21bec94affe10e677ecbc0cc1b89d766c950dbc8e23df87451c71848c3f/uv-0.4.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df225a568da01f3d7e126d886c3694c5a4a7d8b85162a4d6e97822716ca0e7c4", size = 17098535 }, - { url = "https://files.pythonhosted.org/packages/4e/89/77ad3d48f2ea11fd4e416b8cc1be18b26f189a4f0bf7918ac6fdb4255fa6/uv-0.4.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b08564c8c7e8b3665ad1d6c8924d4654451f96c956eb5f3b8ec995c77734163d", size = 12909876 }, - { url = "https://files.pythonhosted.org/packages/ca/29/1f451ef9b2138fdc777e24654da24fa60e42435936d29bcba0fb5bae3c44/uv-0.4.18-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:4be600474db6733078503012f2811c4383f490f77366e66b5f686316db52c870", size = 11976385 }, - { url = "https://files.pythonhosted.org/packages/f3/ea/4ac40da05e070f411edb4e99f01846aa8694071ce85f4eb83313f2cce423/uv-0.4.18-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:3e3ade81af961f48517fcd99318192c9c635ef9a38a7ca65026af0c803c71906", size = 12067581 }, - { url = "https://files.pythonhosted.org/packages/cd/49/f6113c4cea8f7ba9e0a70723e8cb3b042c8cb1288f5671594a6b8de491bd/uv-0.4.18-py3-none-musllinux_1_1_i686.whl", hash = "sha256:4ec60141f92c9667548ebad8daf4c13aabdb58b22c21dcd834641e791e55f289", size = 12559831 }, - { url = "https://files.pythonhosted.org/packages/d2/e7/968414391249660bf4375123dd244eef36fc1c1676dcdc719aea1f319bd7/uv-0.4.18-py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:6566448278b6849846b6c586fc86748c66aa53ed70f5568e713122543cc86a50", size = 14181171 }, - { url = "https://files.pythonhosted.org/packages/bb/ec/1fa1cffaa837df4bfd545818779dc608d0465be5c0e57b4328b5ed91b97f/uv-0.4.18-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:ade18dbbeb05c8cba4f842cc15b20e59467069183f348844750901227df5008d", size = 13042177 }, - { url = "https://files.pythonhosted.org/packages/31/32/fcd60657f45c072fce9f14916b2fcb876b40d8e3ee0ad1f9f212aecd9bfa/uv-0.4.18-py3-none-win32.whl", hash = "sha256:157e4a2c063b270de348862dd31abfe600d5601183fd2a6efe552840ac179626", size = 12184460 }, - { url = "https://files.pythonhosted.org/packages/36/bd/35de80c6ac6d28383d5e7c91e8cea54b4aae8ae144c3411a16e9d28643c8/uv-0.4.18-py3-none-win_amd64.whl", hash = "sha256:8250148484e1b0f89ec19467946e86ee303619985c23228b5a2f2d94d15c6d8b", size = 13893818 }, + { url = "https://files.pythonhosted.org/packages/84/18/9c9056d373620b1cf5182ce9b2d258e86d117d667cf8883e12870f2a5edf/uv-0.4.25-py3-none-linux_armv6l.whl", hash = "sha256:94fb2b454afa6bdfeeea4b4581c878944ca9cf3a13712e6762f245f5fbaaf952", size = 13028246 }, + { url = "https://files.pythonhosted.org/packages/a1/19/8a3f09aba30ac5433dfecde55d5241a07c96bb12340c3b810bc58188a12e/uv-0.4.25-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a7c3a18c20ddb527d296d1222bddf42b78031c50b5b4609d426569b5fb61f5b0", size = 13175265 }, + { url = "https://files.pythonhosted.org/packages/e8/c9/2f924bb29bd53c51b839c1c6126bd2cf4c451d4a7d8f34be078f9e31c57e/uv-0.4.25-py3-none-macosx_11_0_arm64.whl", hash = "sha256:18100f0f36419a154306ed6211e3490bf18384cdf3f1a0950848bf64b62fa251", size = 12255610 }, + { url = "https://files.pythonhosted.org/packages/b2/5a/d8f8971aeb3389679505cf633a786cd72a96ce232f80f14cfe5a693b4c64/uv-0.4.25-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:6e981b1465e30102e41946adede9cb08051a5d70c6daf09f91a7ea84f0b75c08", size = 12506511 }, + { url = "https://files.pythonhosted.org/packages/e3/96/8c73520daeba5022cec8749e44afd4ca9ef774bf728af9c258bddec3577f/uv-0.4.25-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:578ae385fad6bd6f3868828e33d54994c716b315b1bc49106ec1f54c640837e4", size = 12836250 }, + { url = "https://files.pythonhosted.org/packages/67/3d/b0e810d365fb154fe1d380a0f43ee35a683cf9162f2501396d711bec2621/uv-0.4.25-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d29a78f011ecc2f31c13605acb6574c2894c06d258b0f8d0dbb899986800450", size = 13521303 }, + { url = "https://files.pythonhosted.org/packages/2d/f4/dd3830ec7fc6e7e5237c184f30f2dbfed4f93605e472147eca1373bcc72b/uv-0.4.25-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec181be2bda10651a3558156409ac481549983e0276d0e3645e3b1464e7f8715", size = 14105308 }, + { url = "https://files.pythonhosted.org/packages/f4/4e/0fca02f8681e4870beda172552e747e0424f6e9186546b00a5e92525fea9/uv-0.4.25-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50c7d0d9e7f392f81b13bf3b7e37768d1486f2fc9d533a54982aa0ed11e4db23", size = 13859475 }, + { url = "https://files.pythonhosted.org/packages/33/07/1100e9bc652f2850930f466869515d16ffe9582aaaaa99bac332ebdfe3ea/uv-0.4.25-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2fc35b5273f1e018aecd66b70e0fd7d2eb6698853dde3e2fc644e7ebf9f825b1", size = 18100840 }, + { url = "https://files.pythonhosted.org/packages/fa/98/ba1cb7dd2aa639a064a9e49721e08f12a3424456d60dde1327e7c6437930/uv-0.4.25-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7022a71ff63a3838796f40e954b76bf7820fc27e96fe002c537e75ff8e34f1d", size = 13645464 }, + { url = "https://files.pythonhosted.org/packages/0d/05/b97fb8c828a070e8291826922b2712d1146b11563b4860bc9ba80f5635d1/uv-0.4.25-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:e02afb0f6d4b58718347f7d7cfa5a801e985ce42181ba971ed85ef149f6658ca", size = 12694995 }, + { url = "https://files.pythonhosted.org/packages/b3/97/63df050811379130202898f60e735a1a331ba3a93b8aa1e9bb466f533913/uv-0.4.25-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:3d7680795ea78cdbabbcce73d039b2651cf1fa635ddc1aa3082660f6d6255c50", size = 12831737 }, + { url = "https://files.pythonhosted.org/packages/dc/e0/08352dcffa6e8435328861ea60b2c05e8bd030f1e93998443ba66209db7b/uv-0.4.25-py3-none-musllinux_1_1_i686.whl", hash = "sha256:aae9dcafd20d5ba978c8a4939ab942e8e2e155c109e9945207fbbd81d2892c9e", size = 13273529 }, + { url = "https://files.pythonhosted.org/packages/25/f4/eaf95e5eee4e2e69884df0953d094deae07216f72068ef1df08c0f49841d/uv-0.4.25-py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:4c55040e67470f2b73e95e432aba06f103a0b348ea0b9c6689b1029c8d9e89fd", size = 15039860 }, + { url = "https://files.pythonhosted.org/packages/69/04/482b1cc9e8d599c7d766c4ba2d7a512ed3989921443792f92f26b8d44fe6/uv-0.4.25-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:bdbfd0c476b9e80a3f89af96aed6dd7d2782646311317a9c72614ccce99bb2ad", size = 13776302 }, + { url = "https://files.pythonhosted.org/packages/cd/7e/3d1cb735cc3df6341ac884b73eeec1f51a29192721be40be8e9b1d82666d/uv-0.4.25-py3-none-win32.whl", hash = "sha256:7d266e02fefef930609328c31c075084295c3cb472bab3f69549fad4fd9d82b3", size = 12970553 }, + { url = "https://files.pythonhosted.org/packages/04/e9/c00d2bb4a286b13fad0f06488ea9cbe9e76d0efcd81e7a907f72195d5b83/uv-0.4.25-py3-none-win_amd64.whl", hash = "sha256:be2a4fc4fcade9ea5e67e51738c95644360d6e59b6394b74fc579fb617f902f7", size = 14702875 }, ] [[package]] From 71a217b210019cacaeda17b444baa9346c77ce2a Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 22 Oct 2024 02:49:33 +1100 Subject: [PATCH 13/19] fix(docs): typo (#1470) --- src/crewai/cli/templates/crew/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crewai/cli/templates/crew/main.py b/src/crewai/cli/templates/crew/main.py index a20125637..88edfcbff 100644 --- a/src/crewai/cli/templates/crew/main.py +++ b/src/crewai/cli/templates/crew/main.py @@ -3,7 +3,7 @@ import sys from {{folder_name}}.crew import {{crew_name}}Crew # This main file is intended to be a way for you to run your -# crew locally, so refrain from adding necessary logic into this file. +# crew locally, so refrain from adding unnecessary logic into this file. # Replace with inputs you want to test with, it will automatically # interpolate any tasks and agents information From 6bcb3d108050b9cf8a710886a336a81d4dedb6c3 Mon Sep 17 00:00:00 2001 From: "Brandon Hancock (bhancock_ai)" <109994880+bhancockio@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:26:30 -0400 Subject: [PATCH 14/19] drop unneccesary tests (#1484) * drop uneccesary tests * fix linting --- tests/tools/test_tool_usage.py | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/tests/tools/test_tool_usage.py b/tests/tools/test_tool_usage.py index d0a6ec0b0..8af9b8abb 100644 --- a/tests/tools/test_tool_usage.py +++ b/tests/tools/test_tool_usage.py @@ -1,12 +1,12 @@ import json import random -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock import pytest from crewai_tools import BaseTool from pydantic import BaseModel, Field -from crewai import Agent, Crew, Task +from crewai import Agent, Task from crewai.tools.tool_usage import ToolUsage @@ -44,36 +44,12 @@ example_task = Task( ) -def test_random_number_tool_usage(): - crew = Crew( - agents=[example_agent], - tasks=[example_task], - ) - - with patch.object(random, "randint", return_value=42): - result = crew.kickoff() - - assert "42" in result.raw - - def test_random_number_tool_range(): tool = RandomNumberTool() result = tool._run(1, 10) assert 1 <= result <= 10 -def test_random_number_tool_with_crew(): - crew = Crew( - agents=[example_agent], - tasks=[example_task], - ) - - result = crew.kickoff() - - # Check if the result contains a number between 1 and 100 - assert any(str(num) in result.raw for num in range(1, 101)) - - def test_random_number_tool_invalid_range(): tool = RandomNumberTool() with pytest.raises(ValueError): From 093259389e2a3afaa45365ec275fc941c68dc028 Mon Sep 17 00:00:00 2001 From: "Brandon Hancock (bhancock_ai)" <109994880+bhancockio@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:32:55 -0400 Subject: [PATCH 15/19] simplify flow (#1482) * simplify flow * propogate changes * Update docs and scripts * Template fix * make flow kickoff sync * Clean up docs --- docs/concepts/flows.mdx | 200 +++++++----------- src/crewai/cli/cli.py | 8 +- .../cli/{run_flow.py => kickoff_flow.py} | 6 +- src/crewai/cli/templates/flow/main.py | 46 ++-- src/crewai/cli/templates/flow/pyproject.toml | 6 +- src/crewai/flow/flow.py | 5 +- 6 files changed, 111 insertions(+), 160 deletions(-) rename src/crewai/cli/{run_flow.py => kickoff_flow.py} (78%) diff --git a/docs/concepts/flows.mdx b/docs/concepts/flows.mdx index 65cbb95c2..dee6fd4fa 100644 --- a/docs/concepts/flows.mdx +++ b/docs/concepts/flows.mdx @@ -23,9 +23,9 @@ Flows allow you to create structured, event-driven workflows. They provide a sea Let's create a simple Flow where you will use OpenAI to generate a random city in one task and then use that city to generate a fun fact in another task. ```python Code -import asyncio from crewai.flow.flow import Flow, listen, start +from dotenv import load_dotenv from litellm import completion @@ -67,19 +67,19 @@ class ExampleFlow(Flow): return fun_fact -async def main(): - flow = ExampleFlow() - result = await flow.kickoff() - print(f"Generated fun fact: {result}") +flow = ExampleFlow() +result = flow.kickoff() -asyncio.run(main()) +print(f"Generated fun fact: {result}") ``` In the above example, we have created a simple Flow that generates a random city using OpenAI and then generates a fun fact about that city. The Flow consists of two tasks: `generate_city` and `generate_fun_fact`. The `generate_city` task is the starting point of the Flow, and the `generate_fun_fact` task listens for the output of the `generate_city` task. When you run the Flow, it will generate a random city and then generate a fun fact about that city. The output will be printed to the console. +**Note:** Ensure you have set up your `.env` file to store your `OPENAI_API_KEY`. This key is necessary for authenticating requests to the OpenAI API. + ### @start() The `@start()` decorator is used to mark a method as the starting point of a Flow. When a Flow is started, all the methods decorated with `@start()` are executed in parallel. You can have multiple start methods in a Flow, and they will all be executed when the Flow is started. @@ -119,7 +119,6 @@ Here's how you can access the final output: ```python Code -import asyncio from crewai.flow.flow import Flow, listen, start class OutputExampleFlow(Flow): @@ -131,26 +130,24 @@ class OutputExampleFlow(Flow): def second_method(self, first_output): return f"Second method received: {first_output}" -async def main(): - flow = OutputExampleFlow() - final_output = await flow.kickoff() - print("---- Final Output ----") - print(final_output) -asyncio.run(main()) -``` +flow = OutputExampleFlow() +final_output = flow.kickoff() + +print("---- Final Output ----") +print(final_output) +```` ``` text Output ---- Final Output ---- Second method received: Output from first_method -``` +```` -In this example, the `second_method` is the last method to complete, so its output will be the final output of the Flow. +In this example, the `second_method` is the last method to complete, so its output will be the final output of the Flow. The `kickoff()` method will return the final output, which is then printed to the console. - #### Accessing and Updating State In addition to retrieving the final output, you can also access and update the state within your Flow. The state can be used to store and share data between different methods in the Flow. After the Flow has run, you can access the state to retrieve any information that was added or updated during the execution. @@ -160,7 +157,6 @@ Here's an example of how to update and access the state: ```python Code -import asyncio from crewai.flow.flow import Flow, listen, start from pydantic import BaseModel @@ -181,42 +177,38 @@ class StateExampleFlow(Flow[ExampleState]): self.state.counter += 1 return self.state.message -async def main(): - flow = StateExampleFlow() - final_output = await flow.kickoff() - print(f"Final Output: {final_output}") - print("Final State:") - print(flow.state) - -asyncio.run(main()) +flow = StateExampleFlow() +final_output = flow.kickoff() +print(f"Final Output: {final_output}") +print("Final State:") +print(flow.state) ``` -``` text Output +```text Output Final Output: Hello from first_method - updated by second_method Final State: counter=2 message='Hello from first_method - updated by second_method' ``` + -In this example, the state is updated by both `first_method` and `second_method`. +In this example, the state is updated by both `first_method` and `second_method`. After the Flow has run, you can access the final state to see the updates made by these methods. -By ensuring that the final method's output is returned and providing access to the state, CrewAI Flows make it easy to integrate the results of your AI workflows into larger applications or systems, +By ensuring that the final method's output is returned and providing access to the state, CrewAI Flows make it easy to integrate the results of your AI workflows into larger applications or systems, while also maintaining and accessing the state throughout the Flow's execution. ## Flow State Management -Managing state effectively is crucial for building reliable and maintainable AI workflows. CrewAI Flows provides robust mechanisms for both unstructured and structured state management, +Managing state effectively is crucial for building reliable and maintainable AI workflows. CrewAI Flows provides robust mechanisms for both unstructured and structured state management, allowing developers to choose the approach that best fits their application's needs. ### Unstructured State Management -In unstructured state management, all state is stored in the `state` attribute of the `Flow` class. +In unstructured state management, all state is stored in the `state` attribute of the `Flow` class. This approach offers flexibility, enabling developers to add or modify state attributes on the fly without defining a strict schema. ```python Code -import asyncio - from crewai.flow.flow import Flow, listen, start class UntructuredExampleFlow(Flow): @@ -239,12 +231,8 @@ class UntructuredExampleFlow(Flow): print(f"State after third_method: {self.state}") -async def main(): - flow = UntructuredExampleFlow() - await flow.kickoff() - - -asyncio.run(main()) +flow = UntructuredExampleFlow() +flow.kickoff() ``` **Key Points:** @@ -254,12 +242,10 @@ asyncio.run(main()) ### Structured State Management -Structured state management leverages predefined schemas to ensure consistency and type safety across the workflow. +Structured state management leverages predefined schemas to ensure consistency and type safety across the workflow. By using models like Pydantic's `BaseModel`, developers can define the exact shape of the state, enabling better validation and auto-completion in development environments. ```python Code -import asyncio - from crewai.flow.flow import Flow, listen, start from pydantic import BaseModel @@ -288,12 +274,8 @@ class StructuredExampleFlow(Flow[ExampleState]): print(f"State after third_method: {self.state}") -async def main(): - flow = StructuredExampleFlow() - await flow.kickoff() - - -asyncio.run(main()) +flow = StructuredExampleFlow() +flow.kickoff() ``` **Key Points:** @@ -326,7 +308,6 @@ The `or_` function in Flows allows you to listen to multiple methods and trigger ```python Code -import asyncio from crewai.flow.flow import Flow, listen, or_, start class OrExampleFlow(Flow): @@ -344,22 +325,19 @@ class OrExampleFlow(Flow): print(f"Logger: {result}") -async def main(): - flow = OrExampleFlow() - await flow.kickoff() - -asyncio.run(main()) +flow = OrExampleFlow() +flow.kickoff() ``` -``` text Output +```text Output Logger: Hello from the start method Logger: Hello from the second method ``` -When you run this Flow, the `logger` method will be triggered by the output of either the `start_method` or the `second_method`. +When you run this Flow, the `logger` method will be triggered by the output of either the `start_method` or the `second_method`. The `or_` function is used to listen to multiple methods and trigger the listener method when any of the specified methods emit an output. ### Conditional Logic: `and` @@ -369,7 +347,6 @@ The `and_` function in Flows allows you to listen to multiple methods and trigge ```python Code -import asyncio from crewai.flow.flow import Flow, and_, listen, start class AndExampleFlow(Flow): @@ -387,34 +364,28 @@ class AndExampleFlow(Flow): print("---- Logger ----") print(self.state) - -async def main(): - flow = AndExampleFlow() - await flow.kickoff() - - -asyncio.run(main()) +flow = AndExampleFlow() +flow.kickoff() ``` -``` text Output +```text Output ---- Logger ---- {'greeting': 'Hello from the start method', 'joke': 'What do computers eat? Microchips.'} ``` -When you run this Flow, the `logger` method will be triggered only when both the `start_method` and the `second_method` emit an output. +When you run this Flow, the `logger` method will be triggered only when both the `start_method` and the `second_method` emit an output. The `and_` function is used to listen to multiple methods and trigger the listener method only when all the specified methods emit an output. ### Router -The `@router()` decorator in Flows allows you to define conditional routing logic based on the output of a method. +The `@router()` decorator in Flows allows you to define conditional routing logic based on the output of a method. You can specify different routes based on the output of the method, allowing you to control the flow of execution dynamically. ```python Code -import asyncio import random from crewai.flow.flow import Flow, listen, router, start from pydantic import BaseModel @@ -446,15 +417,11 @@ class RouterFlow(Flow[ExampleState]): print("Fourth method running") -async def main(): - flow = RouterFlow() - await flow.kickoff() - - -asyncio.run(main()) +flow = RouterFlow() +flow.kickoff() ``` -``` text Output +```text Output Starting the structured flow Third method running Fourth method running @@ -462,16 +429,16 @@ Fourth method running -In the above example, the `start_method` generates a random boolean value and sets it in the state. -The `second_method` uses the `@router()` decorator to define conditional routing logic based on the value of the boolean. -If the boolean is `True`, the method returns `"success"`, and if it is `False`, the method returns `"failed"`. +In the above example, the `start_method` generates a random boolean value and sets it in the state. +The `second_method` uses the `@router()` decorator to define conditional routing logic based on the value of the boolean. +If the boolean is `True`, the method returns `"success"`, and if it is `False`, the method returns `"failed"`. The `third_method` and `fourth_method` listen to the output of the `second_method` and execute based on the returned value. When you run this Flow, the output will change based on the random boolean value generated by the `start_method`. ## Adding Crews to Flows -Creating a flow with multiple crews in CrewAI is straightforward. +Creating a flow with multiple crews in CrewAI is straightforward. You can generate a new CrewAI project that includes all the scaffolding needed to create a flow with multiple crews by running the following command: @@ -485,22 +452,21 @@ This command will generate a new CrewAI project with the necessary folder struct After running the `crewai create flow name_of_flow` command, you will see a folder structure similar to the following: -| Directory/File | Description | -|:---------------------------------|:------------------------------------------------------------------| -| `name_of_flow/` | Root directory for the flow. | -| ├── `crews/` | Contains directories for specific crews. | -| │ └── `poem_crew/` | Directory for the "poem_crew" with its configurations and scripts.| -| │ ├── `config/` | Configuration files directory for the "poem_crew". | -| │ │ ├── `agents.yaml` | YAML file defining the agents for "poem_crew". | -| │ │ └── `tasks.yaml` | YAML file defining the tasks for "poem_crew". | -| │ ├── `poem_crew.py` | Script for "poem_crew" functionality. | -| ├── `tools/` | Directory for additional tools used in the flow. | -| │ └── `custom_tool.py` | Custom tool implementation. | -| ├── `main.py` | Main script for running the flow. | -| ├── `README.md` | Project description and instructions. | -| ├── `pyproject.toml` | Configuration file for project dependencies and settings. | -| └── `.gitignore` | Specifies files and directories to ignore in version control. | - +| Directory/File | Description | +| :--------------------- | :----------------------------------------------------------------- | +| `name_of_flow/` | Root directory for the flow. | +| ├── `crews/` | Contains directories for specific crews. | +| │ └── `poem_crew/` | Directory for the "poem_crew" with its configurations and scripts. | +| │ ├── `config/` | Configuration files directory for the "poem_crew". | +| │ │ ├── `agents.yaml` | YAML file defining the agents for "poem_crew". | +| │ │ └── `tasks.yaml` | YAML file defining the tasks for "poem_crew". | +| │ ├── `poem_crew.py` | Script for "poem_crew" functionality. | +| ├── `tools/` | Directory for additional tools used in the flow. | +| │ └── `custom_tool.py` | Custom tool implementation. | +| ├── `main.py` | Main script for running the flow. | +| ├── `README.md` | Project description and instructions. | +| ├── `pyproject.toml` | Configuration file for project dependencies and settings. | +| └── `.gitignore` | Specifies files and directories to ignore in version control. | ### Building Your Crews @@ -520,7 +486,6 @@ Here's an example of how you can connect the `poem_crew` in the `main.py` file: ```python Code #!/usr/bin/env python -import asyncio from random import randint from pydantic import BaseModel @@ -536,14 +501,12 @@ class PoemFlow(Flow[PoemState]): @start() def generate_sentence_count(self): print("Generating sentence count") - # Generate a number between 1 and 5 self.state.sentence_count = randint(1, 5) @listen(generate_sentence_count) def generate_poem(self): print("Generating poem") - poem_crew = PoemCrew().crew() - result = poem_crew.kickoff(inputs={"sentence_count": self.state.sentence_count}) + result = PoemCrew().crew().kickoff(inputs={"sentence_count": self.state.sentence_count}) print("Poem generated", result.raw) self.state.poem = result.raw @@ -554,18 +517,17 @@ class PoemFlow(Flow[PoemState]): with open("poem.txt", "w") as f: f.write(self.state.poem) -async def run(): - """ - Run the flow. - """ +def kickoff(): poem_flow = PoemFlow() - await poem_flow.kickoff() + poem_flow.kickoff() -def main(): - asyncio.run(run()) + +def plot(): + poem_flow = PoemFlow() + poem_flow.plot() if __name__ == "__main__": - main() + kickoff() ``` In this example, the `PoemFlow` class defines a flow that generates a sentence count, uses the `PoemCrew` to generate a poem, and then saves the poem to a file. The flow is kicked off by calling the `kickoff()` method. @@ -587,13 +549,13 @@ source .venv/bin/activate After activating the virtual environment, you can run the flow by executing one of the following commands: ```bash -crewai flow run +crewai flow kickoff ``` or ```bash -uv run run_flow +uv run kickoff ``` The flow will execute, and you should see the output in the console. @@ -657,13 +619,13 @@ By exploring these examples, you can gain insights into how to leverage CrewAI F Also, check out our YouTube video on how to use flows in CrewAI below! - \ No newline at end of file + diff --git a/src/crewai/cli/cli.py b/src/crewai/cli/cli.py index 55c8e5b43..6c5263345 100644 --- a/src/crewai/cli/cli.py +++ b/src/crewai/cli/cli.py @@ -14,11 +14,11 @@ from .authentication.main import AuthenticationCommand from .deploy.main import DeployCommand from .evaluate_crew import evaluate_crew from .install_crew import install_crew +from .kickoff_flow import kickoff_flow from .plot_flow import plot_flow from .replay_from_task import replay_task_command from .reset_memories_command import reset_memories_command from .run_crew import run_crew -from .run_flow import run_flow from .tools.main import ToolCommand from .train_crew import train_crew from .update_crew import update_crew @@ -304,11 +304,11 @@ def flow(): pass -@flow.command(name="run") +@flow.command(name="kickoff") def flow_run(): - """Run the Flow.""" + """Kickoff the Flow.""" click.echo("Running the Flow") - run_flow() + kickoff_flow() @flow.command(name="plot") diff --git a/src/crewai/cli/run_flow.py b/src/crewai/cli/kickoff_flow.py similarity index 78% rename from src/crewai/cli/run_flow.py rename to src/crewai/cli/kickoff_flow.py index 2900e59b3..2123a6c15 100644 --- a/src/crewai/cli/run_flow.py +++ b/src/crewai/cli/kickoff_flow.py @@ -3,11 +3,11 @@ import subprocess import click -def run_flow() -> None: +def kickoff_flow() -> None: """ - Run the flow by running a command in the UV environment. + Kickoff the flow by running a command in the UV environment. """ - command = ["uv", "run", "run_flow"] + command = ["uv", "run", "kickoff"] try: result = subprocess.run(command, capture_output=False, text=True, check=True) diff --git a/src/crewai/cli/templates/flow/main.py b/src/crewai/cli/templates/flow/main.py index 38d2d8736..73684051a 100644 --- a/src/crewai/cli/templates/flow/main.py +++ b/src/crewai/cli/templates/flow/main.py @@ -1,65 +1,53 @@ #!/usr/bin/env python -import asyncio from random import randint from pydantic import BaseModel + from crewai.flow.flow import Flow, listen, start + from .crews.poem_crew.poem_crew import PoemCrew + class PoemState(BaseModel): sentence_count: int = 1 poem: str = "" + class PoemFlow(Flow[PoemState]): @start() def generate_sentence_count(self): print("Generating sentence count") - # Generate a number between 1 and 5 - self.state.sentence_count = randint(1, 5) + self.state.sentence_count = randint(1, 5) @listen(generate_sentence_count) def generate_poem(self): print("Generating poem") - print(f"State before poem: {self.state}") - result = PoemCrew().crew().kickoff(inputs={"sentence_count": self.state.sentence_count}) - + result = ( + PoemCrew() + .crew() + .kickoff(inputs={"sentence_count": self.state.sentence_count}) + ) + print("Poem generated", result.raw) self.state.poem = result.raw - - print(f"State after generate_poem: {self.state}") @listen(generate_poem) def save_poem(self): print("Saving poem") - print(f"State before save_poem: {self.state}") with open("poem.txt", "w") as f: f.write(self.state.poem) - print(f"State after save_poem: {self.state}") -async def run_flow(): - """ - Run the flow. - """ + +def kickoff(): poem_flow = PoemFlow() - await poem_flow.kickoff() + poem_flow.kickoff() -async def plot_flow(): - """ - Plot the flow. - """ + +def plot(): poem_flow = PoemFlow() poem_flow.plot() -def main(): - asyncio.run(run_flow()) - - -def plot(): - asyncio.run(plot_flow()) - - - if __name__ == "__main__": - main() + kickoff() diff --git a/src/crewai/cli/templates/flow/pyproject.toml b/src/crewai/cli/templates/flow/pyproject.toml index 490d66346..f93390741 100644 --- a/src/crewai/cli/templates/flow/pyproject.toml +++ b/src/crewai/cli/templates/flow/pyproject.toml @@ -6,13 +6,11 @@ authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ "crewai[tools]>=0.74.2,<1.0.0", - "asyncio" ] [project.scripts] -{{folder_name}} = "{{folder_name}}.main:main" -run_flow = "{{folder_name}}.main:main" -plot_flow = "{{folder_name}}.main:plot" +kickoff = "{{folder_name}}.main:kickoff" +plot = "{{folder_name}}.main:plot" [build-system] requires = ["hatchling"] diff --git a/src/crewai/flow/flow.py b/src/crewai/flow/flow.py index 66fa49659..de9b2eeb2 100644 --- a/src/crewai/flow/flow.py +++ b/src/crewai/flow/flow.py @@ -190,7 +190,10 @@ class Flow(Generic[T], metaclass=FlowMeta): """Returns the list of all outputs from executed methods.""" return self._method_outputs - async def kickoff(self) -> Any: + def kickoff(self) -> Any: + return asyncio.run(self.kickoff_async()) + + async def kickoff_async(self) -> Any: if not self._start_methods: raise ValueError("No start method defined") From 873191533097bbe0718e1b4b353ec65bb8b7bd68 Mon Sep 17 00:00:00 2001 From: Tony Kipkemboi Date: Tue, 22 Oct 2024 13:41:29 -0400 Subject: [PATCH 16/19] Add Cerebras LLM example configuration to LLM docs (#1488) --- docs/concepts/llms.mdx | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/concepts/llms.mdx b/docs/concepts/llms.mdx index 728c88c36..90e86adaf 100644 --- a/docs/concepts/llms.mdx +++ b/docs/concepts/llms.mdx @@ -62,6 +62,8 @@ os.environ["OPENAI_API_BASE"] = "https://api.your-provider.com/v1" 2. Using LLM class attributes: ```python Code +from crewai import LLM + llm = LLM( model="custom-model-name", api_key="your-api-key", @@ -95,9 +97,11 @@ When configuring an LLM for your agent, you have access to a wide range of param | **api_key** | `str` | Your API key for authentication. | -Example: +## OpenAI Example Configuration ```python Code +from crewai import LLM + llm = LLM( model="gpt-4", temperature=0.8, @@ -112,15 +116,31 @@ llm = LLM( ) agent = Agent(llm=llm, ...) ``` + +## Cerebras Example Configuration + +```python Code +from crewai import LLM + +llm = LLM( + model="cerebras/llama-3.1-70b", + base_url="https://api.cerebras.ai/v1", + api_key="your-api-key-here" +) +agent = Agent(llm=llm, ...) +``` + ## Using Ollama (Local LLMs) -crewAI supports using Ollama for running open-source models locally: +CrewAI supports using Ollama for running open-source models locally: 1. Install Ollama: [ollama.ai](https://ollama.ai/) 2. Run a model: `ollama run llama2` 3. Configure agent: ```python Code +from crewai import LLM + agent = Agent( llm=LLM(model="ollama/llama3.1", base_url="http://localhost:11434"), ... @@ -132,6 +152,8 @@ agent = Agent( You can change the base API URL for any LLM provider by setting the `base_url` parameter: ```python Code +from crewai import LLM + llm = LLM( model="custom-model-name", base_url="https://api.your-provider.com/v1", From 4687779702e93f5b4163ea858557e6a4ae064b66 Mon Sep 17 00:00:00 2001 From: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:30:30 -0700 Subject: [PATCH 17/19] ensure original embedding config works (#1476) * ensure original embedding config works * some fixes * raise error on unsupported provider * WIP: brandons notes * fixes * rm prints * fixed docs * fixed run types * updates to add more docs and correct imports with huggingface embedding server enabled --------- Co-authored-by: Brandon Hancock --- docs/concepts/memory.mdx | 86 +++++++++++++++++--- src/crewai/memory/entity/entity_memory.py | 2 +- src/crewai/memory/storage/rag_storage.py | 96 +++++++++++++++++++++-- 3 files changed, 166 insertions(+), 18 deletions(-) diff --git a/docs/concepts/memory.mdx b/docs/concepts/memory.mdx index b07096442..de1fb3510 100644 --- a/docs/concepts/memory.mdx +++ b/docs/concepts/memory.mdx @@ -105,9 +105,48 @@ my_crew = Crew( process=Process.sequential, memory=True, verbose=True, - embedder=embedding_functions.OpenAIEmbeddingFunction( - api_key=os.getenv("OPENAI_API_KEY"), model_name="text-embedding-3-small" - ) + embedder={ + "provider": "openai", + "config": { + "model": 'text-embedding-3-small' + } + } +) +``` +Alternatively, you can directly pass the OpenAIEmbeddingFunction to the embedder parameter. + +Example: +```python Code +from crewai import Crew, Agent, Task, Process +from chromadb.utils.embedding_functions.openai_embedding_function import OpenAIEmbeddingFunction + +my_crew = Crew( + agents=[...], + tasks=[...], + process=Process.sequential, + memory=True, + verbose=True, + embedder=OpenAIEmbeddingFunction(api_key=os.getenv("OPENAI_API_KEY"), model_name="text-embedding-3-small"), +) +``` + +### Using Ollama embeddings + +```python Code +from crewai import Crew, Agent, Task, Process + +my_crew = Crew( + agents=[...], + tasks=[...], + process=Process.sequential, + memory=True, + verbose=True, + embedder={ + "provider": "ollama", + "config": { + "model": "mxbai-embed-large" + } + } ) ``` @@ -122,10 +161,13 @@ my_crew = Crew( process=Process.sequential, memory=True, verbose=True, - embedder=embedding_functions.OpenAIEmbeddingFunction( - api_key=os.getenv("OPENAI_API_KEY"), - model_name="text-embedding-ada-002" - ) + embedder={ + "provider": "google", + "config": { + "api_key": "", + "model_name": "" + } + } ) ``` @@ -181,10 +223,32 @@ my_crew = Crew( process=Process.sequential, memory=True, verbose=True, - embedder=embedding_functions.CohereEmbeddingFunction( - api_key=YOUR_API_KEY, - model_name="" - ) + embedder={ + "provider": "cohere", + "config": { + "api_key": "YOUR_API_KEY", + "model_name": "" + } + } +) +``` +### Using HuggingFace embeddings + +```python Code +from crewai import Crew, Agent, Task, Process + +my_crew = Crew( + agents=[...], + tasks=[...], + process=Process.sequential, + memory=True, + verbose=True, + embedder={ + "provider": "huggingface", + "config": { + "api_url": "", + } + } ) ``` diff --git a/src/crewai/memory/entity/entity_memory.py b/src/crewai/memory/entity/entity_memory.py index d4f8d9aae..4de0594c7 100644 --- a/src/crewai/memory/entity/entity_memory.py +++ b/src/crewai/memory/entity/entity_memory.py @@ -16,7 +16,7 @@ class EntityMemory(Memory): if storage else RAGStorage( type="entities", - allow_reset=False, + allow_reset=True, embedder_config=embedder_config, crew=crew, ) diff --git a/src/crewai/memory/storage/rag_storage.py b/src/crewai/memory/storage/rag_storage.py index 8d45d9f5a..db98c0036 100644 --- a/src/crewai/memory/storage/rag_storage.py +++ b/src/crewai/memory/storage/rag_storage.py @@ -8,6 +8,9 @@ from typing import Any, Dict, List, Optional from crewai.memory.storage.base_rag_storage import BaseRAGStorage from crewai.utilities.paths import db_storage_path from chromadb.api import ClientAPI +from chromadb.api.types import validate_embedding_function +from chromadb import Documents, EmbeddingFunction, Embeddings +from typing import cast @contextlib.contextmanager @@ -41,16 +44,93 @@ class RAGStorage(BaseRAGStorage): self.agents = agents self.type = type - self.embedder_config = embedder_config or self._create_embedding_function() + self.allow_reset = allow_reset self._initialize_app() + def _set_embedder_config(self): + import chromadb.utils.embedding_functions as embedding_functions + + if self.embedder_config is None: + self.embedder_config = self._create_default_embedding_function() + + if isinstance(self.embedder_config, dict): + provider = self.embedder_config.get("provider") + config = self.embedder_config.get("config", {}) + model_name = config.get("model") + if provider == "openai": + self.embedder_config = embedding_functions.OpenAIEmbeddingFunction( + api_key=config.get("api_key") or os.getenv("OPENAI_API_KEY"), + model_name=model_name, + ) + elif provider == "azure": + self.embedder_config = embedding_functions.OpenAIEmbeddingFunction( + api_key=config.get("api_key"), + api_base=config.get("api_base"), + api_type=config.get("api_type", "azure"), + api_version=config.get("api_version"), + model_name=model_name, + ) + elif provider == "ollama": + from openai import OpenAI + + class OllamaEmbeddingFunction(EmbeddingFunction): + def __call__(self, input: Documents) -> Embeddings: + client = OpenAI( + base_url="http://localhost:11434/v1", + api_key=config.get("api_key", "ollama"), + ) + try: + response = client.embeddings.create( + input=input, model=model_name + ) + embeddings = [item.embedding for item in response.data] + return cast(Embeddings, embeddings) + except Exception as e: + raise e + + self.embedder_config = OllamaEmbeddingFunction() + elif provider == "vertexai": + self.embedder_config = ( + embedding_functions.GoogleVertexEmbeddingFunction( + model_name=model_name, + api_key=config.get("api_key"), + ) + ) + elif provider == "google": + self.embedder_config = ( + embedding_functions.GoogleGenerativeAiEmbeddingFunction( + model_name=model_name, + api_key=config.get("api_key"), + ) + ) + elif provider == "cohere": + self.embedder_config = embedding_functions.CohereEmbeddingFunction( + model_name=model_name, + api_key=config.get("api_key"), + ) + elif provider == "huggingface": + self.embedder_config = embedding_functions.HuggingFaceEmbeddingServer( + url=config.get("api_url"), + ) + else: + raise Exception( + f"Unsupported embedding provider: {provider}, supported providers: [openai, azure, ollama, vertexai, google, cohere, huggingface]" + ) + else: + validate_embedding_function(self.embedder_config) # type: ignore # used for validating embedder_config if defined a embedding function/class + self.embedder_config = self.embedder_config + def _initialize_app(self): import chromadb + from chromadb.config import Settings + self._set_embedder_config() chroma_client = chromadb.PersistentClient( - path=f"{db_storage_path()}/{self.type}/{self.agents}" + path=f"{db_storage_path()}/{self.type}/{self.agents}", + settings=Settings(allow_reset=self.allow_reset), ) + self.app = chroma_client try: @@ -122,11 +202,15 @@ class RAGStorage(BaseRAGStorage): if self.app: self.app.reset() except Exception as e: - raise Exception( - f"An error occurred while resetting the {self.type} memory: {e}" - ) + if "attempt to write a readonly database" in str(e): + # Ignore this specific error + pass + else: + raise Exception( + f"An error occurred while resetting the {self.type} memory: {e}" + ) - def _create_embedding_function(self): + def _create_default_embedding_function(self): import chromadb.utils.embedding_functions as embedding_functions return embedding_functions.OpenAIEmbeddingFunction( From 9cd4ff05c997fc77c0418c50e6a607419cd42ac2 Mon Sep 17 00:00:00 2001 From: "Brandon Hancock (bhancock_ai)" <109994880+bhancockio@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:31:44 -0400 Subject: [PATCH 18/19] use copy to split testing and training on crews (#1491) * use copy to split testing and training on crews * make tests handle new copy functionality on train and test * fix last test * fix test --- src/crewai/crew.py | 19 ++++++---- tests/crew_test.py | 94 +++++++++++++++++----------------------------- 2 files changed, 45 insertions(+), 68 deletions(-) diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 5450e6e67..377b6fec9 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -435,15 +435,16 @@ class Crew(BaseModel): self, n_iterations: int, filename: str, inputs: Optional[Dict[str, Any]] = {} ) -> None: """Trains the crew for a given number of iterations.""" - self._setup_for_training(filename) + train_crew = self.copy() + train_crew._setup_for_training(filename) for n_iteration in range(n_iterations): - self._train_iteration = n_iteration - self.kickoff(inputs=inputs) + train_crew._train_iteration = n_iteration + train_crew.kickoff(inputs=inputs) training_data = CrewTrainingHandler(TRAINING_DATA_FILE).load() - for agent in self.agents: + for agent in train_crew.agents: result = TaskEvaluator(agent).evaluate_training_data( training_data=training_data, agent_id=str(agent.id) ) @@ -987,17 +988,19 @@ class Crew(BaseModel): inputs: Optional[Dict[str, Any]] = None, ) -> None: """Test and evaluate the Crew with the given inputs for n iterations concurrently using concurrent.futures.""" - self._test_execution_span = self._telemetry.test_execution_span( - self, + test_crew = self.copy() + + self._test_execution_span = test_crew._telemetry.test_execution_span( + test_crew, n_iterations, inputs, openai_model_name, # type: ignore[arg-type] ) # type: ignore[arg-type] - evaluator = CrewEvaluator(self, openai_model_name) # type: ignore[arg-type] + evaluator = CrewEvaluator(test_crew, openai_model_name) # type: ignore[arg-type] for i in range(1, n_iterations + 1): evaluator.set_iteration(i) - self.kickoff(inputs=inputs) + test_crew.kickoff(inputs=inputs) evaluator.print_crew_evaluation_result() diff --git a/tests/crew_test.py b/tests/crew_test.py index c01e84f80..6444b781c 100644 --- a/tests/crew_test.py +++ b/tests/crew_test.py @@ -9,6 +9,7 @@ from unittest.mock import MagicMock, patch import instructor import pydantic_core import pytest + from crewai.agent import Agent from crewai.agents.cache import CacheHandler from crewai.crew import Crew @@ -497,6 +498,7 @@ def test_cache_hitting_between_agents(): @pytest.mark.vcr(filter_headers=["authorization"]) def test_api_calls_throttling(capsys): from unittest.mock import patch + from crewai_tools import tool @tool @@ -779,11 +781,14 @@ def test_async_task_execution_call_count(): list_important_history.output = mock_task_output write_article.output = mock_task_output - with patch.object( - Task, "execute_sync", return_value=mock_task_output - ) as mock_execute_sync, patch.object( - Task, "execute_async", return_value=mock_future - ) as mock_execute_async: + with ( + patch.object( + Task, "execute_sync", return_value=mock_task_output + ) as mock_execute_sync, + patch.object( + Task, "execute_async", return_value=mock_future + ) as mock_execute_async, + ): crew.kickoff() assert mock_execute_async.call_count == 2 @@ -1105,6 +1110,7 @@ def test_dont_set_agents_step_callback_if_already_set(): @pytest.mark.vcr(filter_headers=["authorization"]) def test_crew_function_calling_llm(): from unittest.mock import patch + from crewai_tools import tool llm = "gpt-4o" @@ -1448,52 +1454,6 @@ def test_crew_does_not_interpolate_without_inputs(): interpolate_task_inputs.assert_not_called() -# def test_crew_partial_inputs(): -# agent = Agent( -# role="{topic} Researcher", -# goal="Express hot takes on {topic}.", -# backstory="You have a lot of experience with {topic}.", -# ) - -# task = Task( -# description="Give me an analysis around {topic}.", -# expected_output="{points} bullet points about {topic}.", -# ) - -# crew = Crew(agents=[agent], tasks=[task], inputs={"topic": "AI"}) -# inputs = {"topic": "AI"} -# crew._interpolate_inputs(inputs=inputs) # Manual call for now - -# assert crew.tasks[0].description == "Give me an analysis around AI." -# assert crew.tasks[0].expected_output == "{points} bullet points about AI." -# assert crew.agents[0].role == "AI Researcher" -# assert crew.agents[0].goal == "Express hot takes on AI." -# assert crew.agents[0].backstory == "You have a lot of experience with AI." - - -# def test_crew_invalid_inputs(): -# agent = Agent( -# role="{topic} Researcher", -# goal="Express hot takes on {topic}.", -# backstory="You have a lot of experience with {topic}.", -# ) - -# task = Task( -# description="Give me an analysis around {topic}.", -# expected_output="{points} bullet points about {topic}.", -# ) - -# crew = Crew(agents=[agent], tasks=[task], inputs={"subject": "AI"}) -# inputs = {"subject": "AI"} -# crew._interpolate_inputs(inputs=inputs) # Manual call for now - -# assert crew.tasks[0].description == "Give me an analysis around {topic}." -# assert crew.tasks[0].expected_output == "{points} bullet points about {topic}." -# assert crew.agents[0].role == "{topic} Researcher" -# assert crew.agents[0].goal == "Express hot takes on {topic}." -# assert crew.agents[0].backstory == "You have a lot of experience with {topic}." - - def test_task_callback_on_crew(): from unittest.mock import MagicMock, patch @@ -1770,7 +1730,10 @@ def test_manager_agent_with_tools_raises_exception(): @patch("crewai.crew.Crew.kickoff") @patch("crewai.crew.CrewTrainingHandler") @patch("crewai.crew.TaskEvaluator") -def test_crew_train_success(task_evaluator, crew_training_handler, kickoff): +@patch("crewai.crew.Crew.copy") +def test_crew_train_success( + copy_mock, task_evaluator, crew_training_handler, kickoff_mock +): task = Task( description="Come up with a list of 5 interesting ideas to explore for an article, then write one amazing paragraph highlight for each idea that showcases how good an article about this topic could be. Return the list of ideas with their paragraph and your notes.", expected_output="5 bullet points with a paragraph for each idea.", @@ -1781,9 +1744,19 @@ def test_crew_train_success(task_evaluator, crew_training_handler, kickoff): agents=[researcher, writer], tasks=[task], ) + + # Create a mock for the copied crew + copy_mock.return_value = crew + crew.train( n_iterations=2, inputs={"topic": "AI"}, filename="trained_agents_data.pkl" ) + + # Ensure kickoff is called on the copied crew + kickoff_mock.assert_has_calls( + [mock.call(inputs={"topic": "AI"}), mock.call(inputs={"topic": "AI"})] + ) + task_evaluator.assert_has_calls( [ mock.call(researcher), @@ -1822,10 +1795,6 @@ def test_crew_train_success(task_evaluator, crew_training_handler, kickoff): ] ) - kickoff.assert_has_calls( - [mock.call(inputs={"topic": "AI"}), mock.call(inputs={"topic": "AI"})] - ) - def test_crew_train_error(): task = Task( @@ -1840,7 +1809,7 @@ def test_crew_train_error(): ) with pytest.raises(TypeError) as e: - crew.train() + crew.train() # type: ignore purposefully throwing err assert "train() missing 1 required positional argument: 'n_iterations'" in str( e ) @@ -2536,8 +2505,9 @@ def test_conditional_should_execute(): @mock.patch("crewai.crew.CrewEvaluator") +@mock.patch("crewai.crew.Crew.copy") @mock.patch("crewai.crew.Crew.kickoff") -def test_crew_testing_function(mock_kickoff, crew_evaluator): +def test_crew_testing_function(kickoff_mock, copy_mock, crew_evaluator): task = Task( description="Come up with a list of 5 interesting ideas to explore for an article, then write one amazing paragraph highlight for each idea that showcases how good an article about this topic could be. Return the list of ideas with their paragraph and your notes.", expected_output="5 bullet points with a paragraph for each idea.", @@ -2548,11 +2518,15 @@ def test_crew_testing_function(mock_kickoff, crew_evaluator): agents=[researcher], tasks=[task], ) + + # Create a mock for the copied crew + copy_mock.return_value = crew + n_iterations = 2 crew.test(n_iterations, openai_model_name="gpt-4o-mini", inputs={"topic": "AI"}) - assert len(mock_kickoff.mock_calls) == n_iterations - mock_kickoff.assert_has_calls( + # Ensure kickoff is called on the copied crew + kickoff_mock.assert_has_calls( [mock.call(inputs={"topic": "AI"}), mock.call(inputs={"topic": "AI"})] ) From b8a3c2974508a04d250acda40cd44eb4c87d1286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moura?= Date: Wed, 23 Oct 2024 05:34:34 -0300 Subject: [PATCH 19/19] preparing new verison --- pyproject.toml | 2 +- src/crewai/__init__.py | 2 +- src/crewai/cli/cli.py | 5 +++-- src/crewai/cli/create_crew.py | 17 +++++++++-------- src/crewai/cli/templates/crew/pyproject.toml | 2 +- src/crewai/cli/templates/flow/pyproject.toml | 2 +- .../cli/templates/pipeline/pyproject.toml | 2 +- .../templates/pipeline_router/pyproject.toml | 2 +- src/crewai/cli/templates/tool/pyproject.toml | 2 +- uv.lock | 2 +- 10 files changed, 20 insertions(+), 18 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d7920c7b0..56fdee20d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "crewai" -version = "0.74.2" +version = "0.75.1" 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.13" diff --git a/src/crewai/__init__.py b/src/crewai/__init__.py index a41e3827f..1a1439d57 100644 --- a/src/crewai/__init__.py +++ b/src/crewai/__init__.py @@ -14,5 +14,5 @@ warnings.filterwarnings( category=UserWarning, module="pydantic.main", ) -__version__ = "0.74.2" +__version__ = "0.75.1" __all__ = ["Agent", "Crew", "Process", "Task", "Pipeline", "Router", "LLM", "Flow"] diff --git a/src/crewai/cli/cli.py b/src/crewai/cli/cli.py index 6c5263345..ae2cac143 100644 --- a/src/crewai/cli/cli.py +++ b/src/crewai/cli/cli.py @@ -32,10 +32,11 @@ def crewai(): @crewai.command() @click.argument("type", type=click.Choice(["crew", "pipeline", "flow"])) @click.argument("name") -def create(type, name): +@click.option("--provider", type=str, help="The provider to use for the crew") +def create(type, name, provider): """Create a new crew, pipeline, or flow.""" if type == "crew": - create_crew(name) + create_crew(name, provider) elif type == "pipeline": create_pipeline(name) elif type == "flow": diff --git a/src/crewai/cli/create_crew.py b/src/crewai/cli/create_crew.py index f74331a23..f3a50f5f4 100644 --- a/src/crewai/cli/create_crew.py +++ b/src/crewai/cli/create_crew.py @@ -70,18 +70,19 @@ def copy_template_files(folder_path, name, class_name, parent_folder): copy_template(src_file, dst_file, name, class_name, folder_path.name) -def create_crew(name, parent_folder=None): +def create_crew(name, provider=None, parent_folder=None): folder_path, folder_name, class_name = create_folder_structure(name, parent_folder) env_vars = load_env_vars(folder_path) - provider_models = get_provider_data() - if not provider_models: - return + if not provider: + provider_models = get_provider_data() + if not provider_models: + return - selected_provider = select_provider(provider_models) - if not selected_provider: - return - provider = selected_provider + selected_provider = select_provider(provider_models) + if not selected_provider: + return + provider = selected_provider # selected_model = select_model(provider, provider_models) # if not selected_model: diff --git a/src/crewai/cli/templates/crew/pyproject.toml b/src/crewai/cli/templates/crew/pyproject.toml index 36ba1548c..a33e4bfce 100644 --- a/src/crewai/cli/templates/crew/pyproject.toml +++ b/src/crewai/cli/templates/crew/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.2,<1.0.0" + "crewai[tools]>=0.75.1,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/flow/pyproject.toml b/src/crewai/cli/templates/flow/pyproject.toml index f93390741..d0ef63377 100644 --- a/src/crewai/cli/templates/flow/pyproject.toml +++ b/src/crewai/cli/templates/flow/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = [{ name = "Your Name", email = "you@example.com" }] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.2,<1.0.0", + "crewai[tools]>=0.75.1,<1.0.0", ] [project.scripts] diff --git a/src/crewai/cli/templates/pipeline/pyproject.toml b/src/crewai/cli/templates/pipeline/pyproject.toml index 517c2a4d1..62a69f3a7 100644 --- a/src/crewai/cli/templates/pipeline/pyproject.toml +++ b/src/crewai/cli/templates/pipeline/pyproject.toml @@ -6,7 +6,7 @@ authors = ["Your Name "] [tool.poetry.dependencies] python = ">=3.10,<=3.13" -crewai = { extras = ["tools"], version = ">=0.74.2,<1.0.0" } +crewai = { extras = ["tools"], version = ">=0.75.1,<1.0.0" } asyncio = "*" [tool.poetry.scripts] diff --git a/src/crewai/cli/templates/pipeline_router/pyproject.toml b/src/crewai/cli/templates/pipeline_router/pyproject.toml index b349e4dda..20b3a7c07 100644 --- a/src/crewai/cli/templates/pipeline_router/pyproject.toml +++ b/src/crewai/cli/templates/pipeline_router/pyproject.toml @@ -5,7 +5,7 @@ description = "{{name}} using crewAI" authors = ["Your Name "] requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.2,<1.0.0" + "crewai[tools]>=0.75.1,<1.0.0" ] [project.scripts] diff --git a/src/crewai/cli/templates/tool/pyproject.toml b/src/crewai/cli/templates/tool/pyproject.toml index bd1df942f..c5d6a47e7 100644 --- a/src/crewai/cli/templates/tool/pyproject.toml +++ b/src/crewai/cli/templates/tool/pyproject.toml @@ -5,6 +5,6 @@ description = "Power up your crews with {{folder_name}}" readme = "README.md" requires-python = ">=3.10,<=3.13" dependencies = [ - "crewai[tools]>=0.74.2" + "crewai[tools]>=0.75.1" ] diff --git a/uv.lock b/uv.lock index 5d4d5b0b7..ddd57b313 100644 --- a/uv.lock +++ b/uv.lock @@ -627,7 +627,7 @@ wheels = [ [[package]] name = "crewai" -version = "0.74.2" +version = "0.75.1" source = { editable = "." } dependencies = [ { name = "appdirs" },