Add GCSWorkspace Implementation to Forge (#6510)

* Added gcs workspace implementation

* Renamed abilites to actions (#6511)

* Renamed abilites to actions

* formatting

* schema to model
This commit is contained in:
Swifty
2023-12-06 15:30:21 +01:00
committed by GitHub
parent 4c495ce1b0
commit 78f5ff17e6
19 changed files with 398 additions and 140 deletions

View File

@@ -0,0 +1 @@
from .registry import ActionRegister, Action, action, ActionParameter

View File

@@ -1,8 +1,9 @@
from typing import List
from ..registry import ability
from ..registry import action
@ability(
@action(
name="list_files",
description="List files in a directory",
parameters=[
@@ -22,7 +23,7 @@ async def list_files(agent, task_id: str, path: str) -> List[str]:
return agent.workspace.list(task_id=task_id, path=str(path))
@ability(
@action(
name="write_file",
description="Write data to a file",
parameters=[
@@ -57,7 +58,7 @@ async def write_file(agent, task_id: str, file_path: str, data: bytes):
)
@ability(
@action(
name="read_file",
description="Read data from a file",
parameters=[

View File

@@ -1,10 +1,10 @@
from ..forge_log import ForgeLogger
from .registry import ability
from sdk.forge_log import ForgeLogger
from .registry import action
logger = ForgeLogger(__name__)
@ability(
@action(
name="finish",
description="Use this to shut down once you have accomplished all of your goals,"
" or when there are insurmountable problems that make it impossible"

View File

@@ -7,9 +7,9 @@ from typing import Any, Callable, List
import pydantic
class AbilityParameter(pydantic.BaseModel):
class ActionParameter(pydantic.BaseModel):
"""
This class represents a parameter for an ability.
This class represents a parameter for an action.
Attributes:
name (str): The name of the parameter.
@@ -24,22 +24,22 @@ class AbilityParameter(pydantic.BaseModel):
required: bool
class Ability(pydantic.BaseModel):
class Action(pydantic.BaseModel):
"""
This class represents an ability in the system.
This class represents an action in the system.
Attributes:
name (str): The name of the ability.
description (str): A brief description of what the ability does.
method (Callable): The method that implements the ability.
parameters (List[AbilityParameter]): A list of parameters that the ability requires.
output_type (str): The type of the output that the ability returns.
name (str): The name of the action.
description (str): A brief description of what the action does.
method (Callable): The method that implements the action.
parameters (List[ActionParameter]): A list of parameters that the action requires.
output_type (str): The type of the output that the action returns.
"""
name: str
description: str
method: Callable
parameters: List[AbilityParameter]
parameters: List[ActionParameter]
output_type: str
category: str | None = None
@@ -71,22 +71,22 @@ class Ability(pydantic.BaseModel):
return func_summary
def ability(
name: str, description: str, parameters: List[AbilityParameter], output_type: str
def action(
name: str, description: str, parameters: List[ActionParameter], output_type: str
):
def decorator(func):
func_params = inspect.signature(func).parameters
param_names = set(
[AbilityParameter.parse_obj(param).name for param in parameters]
[ActionParameter.parse_obj(param).name for param in parameters]
)
param_names.add("agent")
param_names.add("task_id")
func_param_names = set(func_params.keys())
if param_names != func_param_names:
raise ValueError(
f"Mismatch in parameter names. Ability Annotation includes {param_names}, but function actually takes {func_param_names} in function {func.__name__} signature"
f"Mismatch in parameter names. Action Annotation includes {param_names}, but function actually takes {func_param_names} in function {func.__name__} signature"
)
func.ability = Ability(
func.action = Action(
name=name,
description=description,
parameters=parameters,
@@ -98,88 +98,88 @@ def ability(
return decorator
class AbilityRegister:
class ActionRegister:
def __init__(self, agent) -> None:
self.abilities = {}
self.register_abilities()
self.agent = agent
def register_abilities(self) -> None:
for ability_path in glob.glob(
for action_path in glob.glob(
os.path.join(os.path.dirname(__file__), "**/*.py"), recursive=True
):
if not os.path.basename(ability_path) in [
if not os.path.basename(action_path) in [
"__init__.py",
"registry.py",
]:
ability = os.path.relpath(
ability_path, os.path.dirname(__file__)
action = os.path.relpath(
action_path, os.path.dirname(__file__)
).replace("/", ".")
try:
module = importlib.import_module(
f".{ability[:-3]}", package="forge.sdk.abilities"
f".{action[:-3]}", package="forge.sdk.abilities"
)
for attr in dir(module):
func = getattr(module, attr)
if hasattr(func, "ability"):
ab = func.ability
if hasattr(func, "action"):
ab = func.action
ab.category = (
ability.split(".")[0].lower().replace("_", " ")
if len(ability.split(".")) > 1
action.split(".")[0].lower().replace("_", " ")
if len(action.split(".")) > 1
else "general"
)
self.abilities[func.ability.name] = func.ability
self.abilities[func.action.name] = func.action
except Exception as e:
print(f"Error occurred while registering abilities: {str(e)}")
def list_abilities(self) -> List[Ability]:
def list_abilities(self) -> List[Action]:
return self.abilities
def list_abilities_for_prompt(self) -> List[str]:
return [str(ability) for ability in self.abilities.values()]
return [str(action) for action in self.abilities.values()]
def abilities_description(self) -> str:
abilities_by_category = {}
for ability in self.abilities.values():
if ability.category not in abilities_by_category:
abilities_by_category[ability.category] = []
abilities_by_category[ability.category].append(str(ability))
for action in self.abilities.values():
if action.category not in abilities_by_category:
abilities_by_category[action.category] = []
abilities_by_category[action.category].append(str(action))
abilities_description = ""
for category, abilities in abilities_by_category.items():
if abilities_description != "":
abilities_description += "\n"
abilities_description += f"{category}:"
for ability in abilities:
abilities_description += f" {ability}"
for action in abilities:
abilities_description += f" {action}"
return abilities_description
async def run_ability(
self, task_id: str, ability_name: str, *args: Any, **kwds: Any
async def run_action(
self, task_id: str, action_name: str, *args: Any, **kwds: Any
) -> Any:
"""
This method runs a specified ability with the provided arguments and keyword arguments.
This method runs a specified action with the provided arguments and keyword arguments.
The agent is passed as the first argument to the ability. This allows the ability to access and manipulate
The agent is passed as the first argument to the action. This allows the action to access and manipulate
the agent's state as needed.
Args:
task_id (str): The ID of the task that the ability is being run for.
ability_name (str): The name of the ability to run.
task_id (str): The ID of the task that the action is being run for.
action_name (str): The name of the action to run.
*args: Variable length argument list.
**kwds: Arbitrary keyword arguments.
Returns:
Any: The result of the ability execution.
Any: The result of the action execution.
Raises:
Exception: If there is an error in running the ability.
Exception: If there is an error in running the action.
"""
try:
ability = self.abilities[ability_name]
return await ability(self.agent, task_id, *args, **kwds)
action = self.abilities[action_name]
return await action(self.agent, task_id, *args, **kwds)
except Exception:
raise
@@ -188,6 +188,6 @@ if __name__ == "__main__":
import sys
sys.path.append("/Users/swifty/dev/forge/forge")
register = AbilityRegister(agent=None)
register = ActionRegister(agent=None)
print(register.abilities_description())
print(register.run_ability("abc", "list_files", "/Users/swifty/dev/forge/forge"))
print(register.run_action("abc", "list_files", "/Users/swifty/dev/forge/forge"))

View File

@@ -1,4 +1,3 @@
from __future__ import annotations
import json
@@ -7,12 +6,12 @@ from itertools import islice
from duckduckgo_search import DDGS
from ..registry import ability
from ..registry import action
DUCKDUCKGO_MAX_ATTEMPTS = 3
@ability(
@action(
name="web_search",
description="Searches the web",
parameters=[

View File

@@ -34,7 +34,7 @@ from webdriver_manager.firefox import GeckoDriverManager
from webdriver_manager.microsoft import EdgeChromiumDriverManager as EdgeDriverManager
from ..registry import ability
from ..registry import action
from forge.sdk.errors import *
import functools
import re
@@ -76,7 +76,6 @@ def format_hyperlinks(hyperlinks: list[tuple[str, str]]) -> list[str]:
return [f"{link_text} ({link_url})" for link_text, link_url in hyperlinks]
def validate_url(func: Callable[..., Any]) -> Any:
"""The method decorator validate_url is used to validate urls for any command that requires
a url as an argument"""
@@ -178,8 +177,6 @@ def check_local_file_access(url: str) -> bool:
return any(url.startswith(prefix) for prefix in local_prefixes)
logger = logging.getLogger(__name__)
FILE_DIR = Path(__file__).parent.parent
@@ -191,7 +188,7 @@ class BrowsingError(CommandExecutionError):
"""An error occurred while trying to browse the page"""
@ability(
@action(
name="read_webpage",
description="Read a webpage, and extract specific information from it if a question is specified. If you are looking to extract specific information from the webpage, you should specify a question.",
parameters=[
@@ -201,17 +198,19 @@ class BrowsingError(CommandExecutionError):
"type": "string",
"required": True,
},
{
{
"name": "question",
"description": "A question that you want to answer using the content of the webpage.",
"type": "string",
"required": False,
}
},
],
output_type="string",
)
@validate_url
async def read_webpage(agent, task_id: str, url: str, question: str = "") -> Tuple(str, List[str]):
async def read_webpage(
agent, task_id: str, url: str, question: str = ""
) -> Tuple(str, List[str]):
"""Browse a website and return the answer and links to the user
Args:
@@ -372,4 +371,3 @@ def close_browser(driver: WebDriver) -> None:
None
"""
driver.quit()

View File

@@ -6,12 +6,13 @@ from forge.sdk import (
StepRequestBody,
Task,
TaskRequestBody,
Workspace,
PromptEngine,
chat_completion_request,
ChromaMemStore
Workspace,
PromptEngine,
chat_completion_request,
ChromaMemStore,
)
import json
from forge.actions import ActionRegister
import json
import pprint
LOG = ForgeLogger(__name__)
@@ -78,6 +79,7 @@ class ForgeAgent(Agent):
Feel free to create subclasses of the database and workspace to implement your own storage
"""
super().__init__(database, workspace)
self.abilities = ActionRegister(self)
async def create_task(self, task_request: TaskRequestBody) -> Task:
"""
@@ -139,9 +141,11 @@ class ForgeAgent(Agent):
step.output = "Washington D.C"
LOG.info(f"\t✅ Final Step completed: {step.step_id}. \n" +
f"Output should be placeholder text Washington D.C. You'll need to \n" +
f"modify execute_step to include LLM behavior. Follow the tutorial " +
f"if confused. ")
LOG.info(
f"\t✅ Final Step completed: {step.step_id}. \n"
+ f"Output should be placeholder text Washington D.C. You'll need to \n"
+ f"modify execute_step to include LLM behavior. Follow the tutorial "
+ f"if confused. "
)
return step

View File

@@ -11,6 +11,7 @@ import uuid
LOG = ForgeLogger(__name__)
class ChatModel(Base):
__tablename__ = "chat"
msg_id = Column(String, primary_key=True, index=True)
@@ -22,6 +23,7 @@ class ChatModel(Base):
DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow
)
class ActionModel(Base):
__tablename__ = "action"
action_id = Column(String, primary_key=True, index=True)
@@ -35,10 +37,9 @@ class ActionModel(Base):
class ForgeDatabase(AgentDB):
async def add_chat_history(self, task_id, messages):
for message in messages:
await self.add_chat_message(task_id, message['role'], message['content'])
await self.add_chat_message(task_id, message["role"], message["content"])
async def add_chat_message(self, task_id, role, content):
if self.debug_enabled:
@@ -55,7 +56,9 @@ class ForgeDatabase(AgentDB):
session.commit()
session.refresh(mew_msg)
if self.debug_enabled:
LOG.debug(f"Created new Chat message with task_id: {mew_msg.msg_id}")
LOG.debug(
f"Created new Chat message with task_id: {mew_msg.msg_id}"
)
return mew_msg
except SQLAlchemyError as e:
LOG.error(f"SQLAlchemy error while creating task: {e}")
@@ -65,7 +68,7 @@ class ForgeDatabase(AgentDB):
except Exception as e:
LOG.error(f"Unexpected error while creating task: {e}")
raise
async def get_chat_history(self, task_id):
if self.debug_enabled:
LOG.debug(f"Getting chat history with task_id: {task_id}")
@@ -80,9 +83,7 @@ class ForgeDatabase(AgentDB):
return [{"role": m.role, "content": m.content} for m in messages]
else:
LOG.error(
f"Chat history not found with task_id: {task_id}"
)
LOG.error(f"Chat history not found with task_id: {task_id}")
raise NotFoundError("Chat history not found")
except SQLAlchemyError as e:
LOG.error(f"SQLAlchemy error while getting chat history: {e}")
@@ -92,7 +93,7 @@ class ForgeDatabase(AgentDB):
except Exception as e:
LOG.error(f"Unexpected error while getting chat history: {e}")
raise
async def create_action(self, task_id, name, args):
try:
with self.Session() as session:
@@ -106,7 +107,9 @@ class ForgeDatabase(AgentDB):
session.commit()
session.refresh(new_action)
if self.debug_enabled:
LOG.debug(f"Created new Action with task_id: {new_action.action_id}")
LOG.debug(
f"Created new Action with task_id: {new_action.action_id}"
)
return new_action
except SQLAlchemyError as e:
LOG.error(f"SQLAlchemy error while creating action: {e}")
@@ -131,9 +134,7 @@ class ForgeDatabase(AgentDB):
return [{"name": a.name, "args": a.args} for a in actions]
else:
LOG.error(
f"Action history not found with task_id: {task_id}"
)
LOG.error(f"Action history not found with task_id: {task_id}")
raise NotFoundError("Action history not found")
except SQLAlchemyError as e:
LOG.error(f"SQLAlchemy error while getting action history: {e}")

View File

@@ -7,7 +7,7 @@ from .db import AgentDB, Base
from .forge_log import ForgeLogger
from .llm import chat_completion_request, create_embedding_request, transcribe_audio
from .prompting import PromptEngine
from .schema import (
from .model import (
Artifact,
ArtifactUpload,
Pagination,
@@ -24,4 +24,4 @@ from .schema import (
from .workspace import LocalWorkspace, Workspace
from .errors import *
from .memory.chroma_memstore import ChromaMemStore
from .memory.memstore import MemStore
from .memory.memstore import MemStore

View File

@@ -9,13 +9,12 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles
from .abilities.registry import AbilityRegister
from .db import AgentDB
from .errors import NotFoundError
from .forge_log import ForgeLogger
from .middlewares import AgentMiddleware
from .routes.agent_protocol import base_router
from .schema import *
from .model import *
from .workspace import Workspace
LOG = ForgeLogger(__name__)
@@ -25,7 +24,6 @@ class Agent:
def __init__(self, database: AgentDB, workspace: Workspace):
self.db = database
self.workspace = workspace
self.abilities = AbilityRegister(self)
def get_agent_app(self, router: APIRouter = base_router):
"""

View File

@@ -2,7 +2,7 @@ import pytest
from .agent import Agent
from .db import AgentDB
from .schema import StepRequestBody, Task, TaskListResponse, TaskRequestBody
from .model import StepRequestBody, Task, TaskListResponse, TaskRequestBody
from .workspace import LocalWorkspace

View File

@@ -23,7 +23,7 @@ from sqlalchemy.orm import DeclarativeBase, joinedload, relationship, sessionmak
from .errors import NotFoundError
from .forge_log import ForgeLogger
from .schema import Artifact, Pagination, Status, Step, StepRequestBody, Task
from .model import Artifact, Pagination, Status, Step, StepRequestBody, Task
LOG = ForgeLogger(__name__)

View File

@@ -14,7 +14,7 @@ from forge.sdk.db import (
convert_to_task,
)
from forge.sdk.errors import NotFoundError as DataNotFoundError
from forge.sdk.schema import *
from autogpts.forge.forge.sdk.model import *
@pytest.mark.asyncio

View File

@@ -30,7 +30,7 @@ from fastapi.responses import FileResponse
from forge.sdk.errors import *
from forge.sdk.forge_log import ForgeLogger
from forge.sdk.schema import *
from autogpts.forge.forge.sdk.model import *
base_router = APIRouter()

View File

@@ -2,6 +2,7 @@ import abc
import os
import typing
from pathlib import Path
from google.cloud import storage
class Workspace(abc.ABC):
@@ -81,3 +82,51 @@ class LocalWorkspace(Workspace):
if not base.exists() or not base.is_dir():
return []
return [str(p.relative_to(self.base_path / task_id)) for p in base.iterdir()]
class GCSWorkspace(Workspace):
def __init__(self, bucket_name: str, base_path: str = ""):
self.bucket_name = bucket_name
self.base_path = Path(base_path).resolve() if base_path else ""
self.storage_client = storage.Client()
self.bucket = self.storage_client.get_bucket(self.bucket_name)
def _resolve_path(self, task_id: str, path: str) -> Path:
path = str(path)
path = path if not path.startswith("/") else path[1:]
abs_path = (self.base_path / task_id / path).resolve()
if not str(abs_path).startswith(str(self.base_path)):
print("Error")
raise ValueError(f"Directory traversal is not allowed! - {abs_path}")
return abs_path
def read(self, task_id: str, path: str) -> bytes:
blob = self.bucket.blob(self._resolve_path(task_id, path))
if not blob.exists():
raise FileNotFoundError()
return blob.download_as_bytes()
def write(self, task_id: str, path: str, data: bytes) -> None:
blob = self.bucket.blob(self._resolve_path(task_id, path))
blob.upload_from_string(data)
def delete(self, task_id: str, path: str, directory=False, recursive=False):
if directory and not recursive:
raise ValueError("recursive must be True when deleting a directory")
blob = self.bucket.blob(self._resolve_path(task_id, path))
if not blob.exists():
return
if directory:
for b in list(self.bucket.list_blobs(prefix=blob.name)):
b.delete()
else:
blob.delete()
def exists(self, task_id: str, path: str) -> bool:
blob = self.bucket.blob(self._resolve_path(task_id, path))
return blob.exists()
def list(self, task_id: str, path: str) -> typing.List[str]:
prefix = os.path.join(task_id, self.base_path, path).replace("\\", "/") + "/"
blobs = list(self.bucket.list_blobs(prefix=prefix))
return [str(Path(b.name).relative_to(prefix[:-1])) for b in blobs]

View File

@@ -538,6 +538,17 @@ files = [
[package.dependencies]
beautifulsoup4 = "*"
[[package]]
name = "cachetools"
version = "5.3.2"
description = "Extensible memoizing collections and decorators"
optional = false
python-versions = ">=3.7"
files = [
{file = "cachetools-5.3.2-py3-none-any.whl", hash = "sha256:861f35a13a451f94e301ce2bec7cac63e881232ccce7ed67fab9b5df4d3beaa1"},
{file = "cachetools-5.3.2.tar.gz", hash = "sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2"},
]
[[package]]
name = "certifi"
version = "2023.7.22"
@@ -1269,6 +1280,206 @@ gitdb = ">=4.0.1,<5"
[package.extras]
test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-sugar"]
[[package]]
name = "google-api-core"
version = "2.14.0"
description = "Google API client core library"
optional = false
python-versions = ">=3.7"
files = [
{file = "google-api-core-2.14.0.tar.gz", hash = "sha256:5368a4502b793d9bbf812a5912e13e4e69f9bd87f6efb508460c43f5bbd1ce41"},
{file = "google_api_core-2.14.0-py3-none-any.whl", hash = "sha256:de2fb50ed34d47ddbb2bd2dcf680ee8fead46279f4ed6b16de362aca23a18952"},
]
[package.dependencies]
google-auth = ">=2.14.1,<3.0.dev0"
googleapis-common-protos = ">=1.56.2,<2.0.dev0"
protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0"
requests = ">=2.18.0,<3.0.0.dev0"
[package.extras]
grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0)"]
grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]]
name = "google-auth"
version = "2.25.1"
description = "Google Authentication Library"
optional = false
python-versions = ">=3.7"
files = [
{file = "google-auth-2.25.1.tar.gz", hash = "sha256:d5d66b8f4f6e3273740d7bb73ddefa6c2d1ff691704bd407d51c6b5800e7c97b"},
{file = "google_auth-2.25.1-py2.py3-none-any.whl", hash = "sha256:dfd7b44935d498e106c08883b2dac0ad36d8aa10402a6412e9a1c9d74b4773f1"},
]
[package.dependencies]
cachetools = ">=2.0.0,<6.0"
pyasn1-modules = ">=0.2.1"
rsa = ">=3.1.4,<5"
[package.extras]
aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"]
enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"]
pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"]
reauth = ["pyu2f (>=0.1.5)"]
requests = ["requests (>=2.20.0,<3.0.0.dev0)"]
[[package]]
name = "google-cloud-core"
version = "2.3.3"
description = "Google Cloud API client core library"
optional = false
python-versions = ">=3.7"
files = [
{file = "google-cloud-core-2.3.3.tar.gz", hash = "sha256:37b80273c8d7eee1ae816b3a20ae43585ea50506cb0e60f3cf5be5f87f1373cb"},
{file = "google_cloud_core-2.3.3-py2.py3-none-any.whl", hash = "sha256:fbd11cad3e98a7e5b0343dc07cb1039a5ffd7a5bb96e1f1e27cee4bda4a90863"},
]
[package.dependencies]
google-api-core = ">=1.31.6,<2.0.dev0 || >2.3.0,<3.0.0dev"
google-auth = ">=1.25.0,<3.0dev"
[package.extras]
grpc = ["grpcio (>=1.38.0,<2.0dev)"]
[[package]]
name = "google-cloud-storage"
version = "2.13.0"
description = "Google Cloud Storage API client library"
optional = false
python-versions = ">=3.7"
files = [
{file = "google-cloud-storage-2.13.0.tar.gz", hash = "sha256:f62dc4c7b6cd4360d072e3deb28035fbdad491ac3d9b0b1815a12daea10f37c7"},
{file = "google_cloud_storage-2.13.0-py2.py3-none-any.whl", hash = "sha256:ab0bf2e1780a1b74cf17fccb13788070b729f50c252f0c94ada2aae0ca95437d"},
]
[package.dependencies]
google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0dev"
google-auth = ">=2.23.3,<3.0dev"
google-cloud-core = ">=2.3.0,<3.0dev"
google-crc32c = ">=1.0,<2.0dev"
google-resumable-media = ">=2.6.0"
requests = ">=2.18.0,<3.0.0dev"
[package.extras]
protobuf = ["protobuf (<5.0.0dev)"]
[[package]]
name = "google-crc32c"
version = "1.5.0"
description = "A python wrapper of the C library 'Google CRC32C'"
optional = false
python-versions = ">=3.7"
files = [
{file = "google-crc32c-1.5.0.tar.gz", hash = "sha256:89284716bc6a5a415d4eaa11b1726d2d60a0cd12aadf5439828353662ede9dd7"},
{file = "google_crc32c-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:596d1f98fc70232fcb6590c439f43b350cb762fb5d61ce7b0e9db4539654cc13"},
{file = "google_crc32c-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:be82c3c8cfb15b30f36768797a640e800513793d6ae1724aaaafe5bf86f8f346"},
{file = "google_crc32c-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:461665ff58895f508e2866824a47bdee72497b091c730071f2b7575d5762ab65"},
{file = "google_crc32c-1.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2096eddb4e7c7bdae4bd69ad364e55e07b8316653234a56552d9c988bd2d61b"},
{file = "google_crc32c-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:116a7c3c616dd14a3de8c64a965828b197e5f2d121fedd2f8c5585c547e87b02"},
{file = "google_crc32c-1.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5829b792bf5822fd0a6f6eb34c5f81dd074f01d570ed7f36aa101d6fc7a0a6e4"},
{file = "google_crc32c-1.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:64e52e2b3970bd891309c113b54cf0e4384762c934d5ae56e283f9a0afcd953e"},
{file = "google_crc32c-1.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:02ebb8bf46c13e36998aeaad1de9b48f4caf545e91d14041270d9dca767b780c"},
{file = "google_crc32c-1.5.0-cp310-cp310-win32.whl", hash = "sha256:2e920d506ec85eb4ba50cd4228c2bec05642894d4c73c59b3a2fe20346bd00ee"},
{file = "google_crc32c-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:07eb3c611ce363c51a933bf6bd7f8e3878a51d124acfc89452a75120bc436289"},
{file = "google_crc32c-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cae0274952c079886567f3f4f685bcaf5708f0a23a5f5216fdab71f81a6c0273"},
{file = "google_crc32c-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1034d91442ead5a95b5aaef90dbfaca8633b0247d1e41621d1e9f9db88c36298"},
{file = "google_crc32c-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c42c70cd1d362284289c6273adda4c6af8039a8ae12dc451dcd61cdabb8ab57"},
{file = "google_crc32c-1.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8485b340a6a9e76c62a7dce3c98e5f102c9219f4cfbf896a00cf48caf078d438"},
{file = "google_crc32c-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77e2fd3057c9d78e225fa0a2160f96b64a824de17840351b26825b0848022906"},
{file = "google_crc32c-1.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f583edb943cf2e09c60441b910d6a20b4d9d626c75a36c8fcac01a6c96c01183"},
{file = "google_crc32c-1.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a1fd716e7a01f8e717490fbe2e431d2905ab8aa598b9b12f8d10abebb36b04dd"},
{file = "google_crc32c-1.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:72218785ce41b9cfd2fc1d6a017dc1ff7acfc4c17d01053265c41a2c0cc39b8c"},
{file = "google_crc32c-1.5.0-cp311-cp311-win32.whl", hash = "sha256:66741ef4ee08ea0b2cc3c86916ab66b6aef03768525627fd6a1b34968b4e3709"},
{file = "google_crc32c-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:ba1eb1843304b1e5537e1fca632fa894d6f6deca8d6389636ee5b4797affb968"},
{file = "google_crc32c-1.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:98cb4d057f285bd80d8778ebc4fde6b4d509ac3f331758fb1528b733215443ae"},
{file = "google_crc32c-1.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd8536e902db7e365f49e7d9029283403974ccf29b13fc7028b97e2295b33556"},
{file = "google_crc32c-1.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19e0a019d2c4dcc5e598cd4a4bc7b008546b0358bd322537c74ad47a5386884f"},
{file = "google_crc32c-1.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c65b9817512edc6a4ae7c7e987fea799d2e0ee40c53ec573a692bee24de876"},
{file = "google_crc32c-1.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ac08d24c1f16bd2bf5eca8eaf8304812f44af5cfe5062006ec676e7e1d50afc"},
{file = "google_crc32c-1.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3359fc442a743e870f4588fcf5dcbc1bf929df1fad8fb9905cd94e5edb02e84c"},
{file = "google_crc32c-1.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e986b206dae4476f41bcec1faa057851f3889503a70e1bdb2378d406223994a"},
{file = "google_crc32c-1.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:de06adc872bcd8c2a4e0dc51250e9e65ef2ca91be023b9d13ebd67c2ba552e1e"},
{file = "google_crc32c-1.5.0-cp37-cp37m-win32.whl", hash = "sha256:d3515f198eaa2f0ed49f8819d5732d70698c3fa37384146079b3799b97667a94"},
{file = "google_crc32c-1.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:67b741654b851abafb7bc625b6d1cdd520a379074e64b6a128e3b688c3c04740"},
{file = "google_crc32c-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c02ec1c5856179f171e032a31d6f8bf84e5a75c45c33b2e20a3de353b266ebd8"},
{file = "google_crc32c-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edfedb64740750e1a3b16152620220f51d58ff1b4abceb339ca92e934775c27a"},
{file = "google_crc32c-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84e6e8cd997930fc66d5bb4fde61e2b62ba19d62b7abd7a69920406f9ecca946"},
{file = "google_crc32c-1.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:024894d9d3cfbc5943f8f230e23950cd4906b2fe004c72e29b209420a1e6b05a"},
{file = "google_crc32c-1.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:998679bf62b7fb599d2878aa3ed06b9ce688b8974893e7223c60db155f26bd8d"},
{file = "google_crc32c-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:83c681c526a3439b5cf94f7420471705bbf96262f49a6fe546a6db5f687a3d4a"},
{file = "google_crc32c-1.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4c6fdd4fccbec90cc8a01fc00773fcd5fa28db683c116ee3cb35cd5da9ef6c37"},
{file = "google_crc32c-1.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5ae44e10a8e3407dbe138984f21e536583f2bba1be9491239f942c2464ac0894"},
{file = "google_crc32c-1.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37933ec6e693e51a5b07505bd05de57eee12f3e8c32b07da7e73669398e6630a"},
{file = "google_crc32c-1.5.0-cp38-cp38-win32.whl", hash = "sha256:fe70e325aa68fa4b5edf7d1a4b6f691eb04bbccac0ace68e34820d283b5f80d4"},
{file = "google_crc32c-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:74dea7751d98034887dbd821b7aae3e1d36eda111d6ca36c206c44478035709c"},
{file = "google_crc32c-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c6c777a480337ac14f38564ac88ae82d4cd238bf293f0a22295b66eb89ffced7"},
{file = "google_crc32c-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:759ce4851a4bb15ecabae28f4d2e18983c244eddd767f560165563bf9aefbc8d"},
{file = "google_crc32c-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f13cae8cc389a440def0c8c52057f37359014ccbc9dc1f0827936bcd367c6100"},
{file = "google_crc32c-1.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e560628513ed34759456a416bf86b54b2476c59144a9138165c9a1575801d0d9"},
{file = "google_crc32c-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1674e4307fa3024fc897ca774e9c7562c957af85df55efe2988ed9056dc4e57"},
{file = "google_crc32c-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:278d2ed7c16cfc075c91378c4f47924c0625f5fc84b2d50d921b18b7975bd210"},
{file = "google_crc32c-1.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d5280312b9af0976231f9e317c20e4a61cd2f9629b7bfea6a693d1878a264ebd"},
{file = "google_crc32c-1.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8b87e1a59c38f275c0e3676fc2ab6d59eccecfd460be267ac360cc31f7bcde96"},
{file = "google_crc32c-1.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7c074fece789b5034b9b1404a1f8208fc2d4c6ce9decdd16e8220c5a793e6f61"},
{file = "google_crc32c-1.5.0-cp39-cp39-win32.whl", hash = "sha256:7f57f14606cd1dd0f0de396e1e53824c371e9544a822648cd76c034d209b559c"},
{file = "google_crc32c-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:a2355cba1f4ad8b6988a4ca3feed5bff33f6af2d7f134852cf279c2aebfde541"},
{file = "google_crc32c-1.5.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f314013e7dcd5cf45ab1945d92e713eec788166262ae8deb2cfacd53def27325"},
{file = "google_crc32c-1.5.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b747a674c20a67343cb61d43fdd9207ce5da6a99f629c6e2541aa0e89215bcd"},
{file = "google_crc32c-1.5.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f24ed114432de109aa9fd317278518a5af2d31ac2ea6b952b2f7782b43da091"},
{file = "google_crc32c-1.5.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8667b48e7a7ef66afba2c81e1094ef526388d35b873966d8a9a447974ed9178"},
{file = "google_crc32c-1.5.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:1c7abdac90433b09bad6c43a43af253e688c9cfc1c86d332aed13f9a7c7f65e2"},
{file = "google_crc32c-1.5.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6f998db4e71b645350b9ac28a2167e6632c239963ca9da411523bb439c5c514d"},
{file = "google_crc32c-1.5.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c99616c853bb585301df6de07ca2cadad344fd1ada6d62bb30aec05219c45d2"},
{file = "google_crc32c-1.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ad40e31093a4af319dadf503b2467ccdc8f67c72e4bcba97f8c10cb078207b5"},
{file = "google_crc32c-1.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd67cf24a553339d5062eff51013780a00d6f97a39ca062781d06b3a73b15462"},
{file = "google_crc32c-1.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:398af5e3ba9cf768787eef45c803ff9614cc3e22a5b2f7d7ae116df8b11e3314"},
{file = "google_crc32c-1.5.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b1f8133c9a275df5613a451e73f36c2aea4fe13c5c8997e22cf355ebd7bd0728"},
{file = "google_crc32c-1.5.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ba053c5f50430a3fcfd36f75aff9caeba0440b2d076afdb79a318d6ca245f88"},
{file = "google_crc32c-1.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:272d3892a1e1a2dbc39cc5cde96834c236d5327e2122d3aaa19f6614531bb6eb"},
{file = "google_crc32c-1.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:635f5d4dd18758a1fbd1049a8e8d2fee4ffed124462d837d1a02a0e009c3ab31"},
{file = "google_crc32c-1.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c672d99a345849301784604bfeaeba4db0c7aae50b95be04dd651fd2a7310b93"},
]
[package.extras]
testing = ["pytest"]
[[package]]
name = "google-resumable-media"
version = "2.6.0"
description = "Utilities for Google Media Downloads and Resumable Uploads"
optional = false
python-versions = ">= 3.7"
files = [
{file = "google-resumable-media-2.6.0.tar.gz", hash = "sha256:972852f6c65f933e15a4a210c2b96930763b47197cdf4aa5f5bea435efb626e7"},
{file = "google_resumable_media-2.6.0-py2.py3-none-any.whl", hash = "sha256:fc03d344381970f79eebb632a3c18bb1828593a2dc5572b5f90115ef7d11e81b"},
]
[package.dependencies]
google-crc32c = ">=1.0,<2.0dev"
[package.extras]
aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "google-auth (>=1.22.0,<2.0dev)"]
requests = ["requests (>=2.18.0,<3.0.0dev)"]
[[package]]
name = "googleapis-common-protos"
version = "1.61.0"
description = "Common protobufs used in Google APIs"
optional = false
python-versions = ">=3.7"
files = [
{file = "googleapis-common-protos-1.61.0.tar.gz", hash = "sha256:8a64866a97f6304a7179873a465d6eee97b7a24ec6cfd78e0f575e96b821240b"},
{file = "googleapis_common_protos-1.61.0-py2.py3-none-any.whl", hash = "sha256:22f1915393bb3245343f6efe87f6fe868532efc12aa26b391b15132e1279f1c0"},
]
[package.dependencies]
protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0"
[package.extras]
grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"]
[[package]]
name = "greenlet"
version = "3.0.0"
@@ -2074,16 +2285,6 @@ files = [
{file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
{file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
{file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
{file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
{file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
{file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
{file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
@@ -2406,40 +2607,6 @@ files = [
[package.dependencies]
setuptools = "*"
[[package]]
name = "numpy"
version = "1.25.2"
description = "Fundamental package for array computing in Python"
optional = false
python-versions = ">=3.9"
files = [
{file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3"},
{file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f"},
{file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187"},
{file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357"},
{file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9"},
{file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044"},
{file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545"},
{file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418"},
{file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f"},
{file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2"},
{file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf"},
{file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364"},
{file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d"},
{file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4"},
{file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3"},
{file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926"},
{file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca"},
{file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295"},
{file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f"},
{file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01"},
{file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380"},
{file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55"},
{file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901"},
{file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf"},
{file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"},
]
[[package]]
name = "numpy"
version = "1.26.2"
@@ -2977,6 +3144,31 @@ files = [
[package.extras]
tests = ["pytest"]
[[package]]
name = "pyasn1"
version = "0.5.1"
description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
files = [
{file = "pyasn1-0.5.1-py2.py3-none-any.whl", hash = "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58"},
{file = "pyasn1-0.5.1.tar.gz", hash = "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c"},
]
[[package]]
name = "pyasn1-modules"
version = "0.3.0"
description = "A collection of ASN.1-based protocols modules"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
files = [
{file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"},
{file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"},
]
[package.dependencies]
pyasn1 = ">=0.4.6,<0.6.0"
[[package]]
name = "pycodestyle"
version = "2.11.1"
@@ -3430,6 +3622,20 @@ urllib3 = ">=1.21.1,<3"
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "rsa"
version = "4.9"
description = "Pure-Python RSA implementation"
optional = false
python-versions = ">=3.6,<4"
files = [
{file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"},
{file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"},
]
[package.dependencies]
pyasn1 = ">=0.1.3"
[[package]]
name = "selenium"
version = "4.14.0"
@@ -4480,4 +4686,4 @@ benchmark = ["agbenchmark"]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "4a5e66484e910fb0d4081a8f841a8a39f6c567f54c5f1034627acb9d63f5fd0f"
content-hash = "37e90f0834456bed59baa859d5d7f01b2892e67ee30cf00b3195a64a25a41083"

View File

@@ -27,6 +27,7 @@ bs4 = "^0.0.1"
# agbenchmark = { path = "../../benchmark", optional = true }
agbenchmark = {git = "https://github.com/Significant-Gravitas/AutoGPT.git", subdirectory = "benchmark", optional = true}
webdriver-manager = "^4.0.1"
google-cloud-storage = "^2.13.0"
[tool.poetry.extras]
benchmark = ["agbenchmark"]