diff --git a/.gitignore b/.gitignore index 372c78ca..9128de4f 100644 --- a/.gitignore +++ b/.gitignore @@ -163,6 +163,5 @@ CURRENT_BULLETIN.md # agbenchmark -agbenchmark/reports -agbenchmark/workspace +agbenchmark agent.db diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..efd301c6 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +.PHONY: update-protocol + +update-protocol: + @if [ -d "../agent-protocol/sdk/python/agent_protocol" ]; then \ + cp -r ../agent-protocol/sdk/python/agent_protocol autogpt; \ + rm -Rf autogpt/agent_protocol/utils; \ + rm -Rf autogpt/agent_protocol/cli.py; \ + echo "Protocol updated successfully!"; \ + else \ + echo "Error: Source directory ../agent-protocol/sdk/python/agent_protocol does not exist."; \ + exit 1; \ + fi + +change-protocol: + @if [ -d "autogpt/agent_protocol" ]; then \ + cp -r autogpt/agent_protocol ../agent-protocol/sdk/python; \ + rm ../agent-protocol/sdk/python/agent_protocol/README.md; \ + echo "Protocol reversed successfully!"; \ + else \ + echo "Error: Target directory autogpt/agent_protocol does not exist."; \ + exit 1; \ + fi diff --git a/autogpt/__main__.py b/autogpt/__main__.py index 28840572..657e7831 100644 --- a/autogpt/__main__.py +++ b/autogpt/__main__.py @@ -1,11 +1,11 @@ import os -from agent_protocol import Agent from dotenv import load_dotenv import autogpt.agent import autogpt.db from autogpt.benchmark_integration import add_benchmark_routes +from autogpt.workspace import LocalWorkspace if __name__ == "__main__": """Runs the agent server""" @@ -13,13 +13,11 @@ if __name__ == "__main__": router = add_benchmark_routes() database_name = os.getenv("DATABASE_STRING") + workspace = LocalWorkspace(os.getenv("AGENT_WORKSPACE")) print(database_name) port = os.getenv("PORT") - workspace = os.getenv("AGENT_WORKSPACE") - auto_gpt = autogpt.agent.AutoGPT() database = autogpt.db.AgentDB(database_name) - agent = Agent.setup_agent(auto_gpt.task_handler, auto_gpt.step_handler) - agent.db = database - agent.workspace = workspace + agent = autogpt.agent.AutoGPT(db=database, workspace=workspace) + agent.start(port=port, router=router) diff --git a/autogpt/agent.py b/autogpt/agent.py index 63a9cf57..33036a9b 100644 --- a/autogpt/agent.py +++ b/autogpt/agent.py @@ -1,32 +1,64 @@ -import time - -from agent_protocol import Agent, Step, Task +import os import autogpt.utils +from autogpt.agent_protocol import Agent, Artifact, Step, Task, TaskDB + +from .workspace import Workspace -class AutoGPT: - def __init__(self) -> None: - pass +class AutoGPT(Agent): + def __init__(self, db: TaskDB, workspace: Workspace) -> None: + super().__init__(db) + self.workspace = workspace - async def task_handler(self, task: Task) -> None: + async def create_task(self, task: Task) -> None: print(f"task: {task.input}") - await Agent.db.create_step(task.task_id, task.input, is_last=True) - time.sleep(2) - - # autogpt.utils.run(task.input) the task_handler only creates the task, it doesn't execute it - # print(f"Created Task id: {task.task_id}") return task - async def step_handler(self, step: Step) -> Step: - # print(f"step: {step}") - agent_step = await Agent.db.get_step(step.task_id, step.step_id) - updated_step: Step = await Agent.db.update_step( - agent_step.task_id, agent_step.step_id, status="completed" - ) - updated_step.output = agent_step.input - if step.is_last: - print(f"Task completed: {updated_step.task_id}") + async def run_step(self, step: Step) -> Step: + artifacts = autogpt.utils.run(step.input) + for artifact in artifacts: + art = await self.db.create_artifact( + task_id=step.task_id, + file_name=artifact["file_name"], + uri=artifact["uri"], + agent_created=True, + step_id=step.step_id, + ) + assert isinstance( + art, Artifact + ), f"Artifact not isntance of Artifact {type(art)}" + step.artifacts.append(art) + step.status = "completed" + return step + + async def retrieve_artifact(self, task_id: str, artifact: Artifact) -> bytes: + """ + Retrieve the artifact data from wherever it is stored and return it as bytes. + """ + if not artifact.uri.startswith("file://"): + raise NotImplementedError("Loading from uri not implemented") + file_path = artifact.uri.split("file://")[1] + if not self.workspace.exists(file_path): + raise FileNotFoundError(f"File {file_path} not found in workspace") + return self.workspace.read(file_path) + + async def save_artifact( + self, task_id: str, artifact: Artifact, data: bytes + ) -> Artifact: + """ + Save the artifact data to the agent's workspace, loading from uri if bytes are not available. + """ + assert ( + data is not None and artifact.uri is not None + ), "Data or Artifact uri must be set" + + if data is not None: + file_path = os.path.join(task_id / artifact.file_name) + self.write(file_path, data) + artifact.uri = f"file://{file_path}" + self.db.save_artifact(task_id, artifact) else: - print(f"Step completed: {updated_step}") - return updated_step + raise NotImplementedError("Loading from uri not implemented") + + return artifact diff --git a/autogpt/agent_protocol/README.md b/autogpt/agent_protocol/README.md new file mode 100644 index 00000000..ec0117fd --- /dev/null +++ b/autogpt/agent_protocol/README.md @@ -0,0 +1,21 @@ +# Autogpt Protocol Directory + +# DO NOT MODIFY ANY FILES IN THIS DIRECTORY + +This directory contains protocol definitions crucial for our project. The current setup is a temporary measure to allow for speedy updating of the protocol. + +## Background + +In an ideal scenario, we'd directly use a submodule pointing to the original repository. However, given our specific needs and to expedite our development process, we've chosen a slightly different approach. + +## Process + +1. **Fork and Clone**: We started by forking the original repository `e2b-dev/agent-protocol` (not `Swiftyos/agent-protocol` as previously mentioned) to have our own version. This allows us to have more control over updates and possibly any specific changes that our project might need in the future. + +2. **Manual Content Integration**: Instead of adding the entire forked repository as a submodule, we've manually copied over the contents of `sdk/python/agent_protocol` into this directory. This ensures we only have the parts we need, without any additional overhead. + +3. **Updates**: Any necessary updates to the protocol can be made directly in our fork, and subsequently, the required changes can be reflected in this directory. + +## Credits + +All credit for the original protocol definitions goes to [e2b-dev/agent-protocol](https://github.com/e2b-dev/agent-protocol). We deeply appreciate their efforts in building the protocol, and this temporary measure is in no way intended to diminish the significance of their work. It's purely a practical approach for our specific requirements at this point in our development phase. diff --git a/autogpt/agent_protocol/__init__.py b/autogpt/agent_protocol/__init__.py new file mode 100644 index 00000000..66eb909f --- /dev/null +++ b/autogpt/agent_protocol/__init__.py @@ -0,0 +1,16 @@ +from .agent import Agent +from .agent import base_router as router +from .db import Step, Task, TaskDB +from .models import Artifact, Status, StepRequestBody, TaskRequestBody + +__all__ = [ + "Agent", + "Artifact", + "Status", + "Step", + "StepRequestBody", + "Task", + "TaskDB", + "TaskRequestBody", + "router", +] diff --git a/autogpt/agent_protocol/agent.py b/autogpt/agent_protocol/agent.py new file mode 100644 index 00000000..0c2f8418 --- /dev/null +++ b/autogpt/agent_protocol/agent.py @@ -0,0 +1,233 @@ +import asyncio +from typing import List +from uuid import uuid4 + +from fastapi import APIRouter, Request, Response, UploadFile +from fastapi.responses import FileResponse, JSONResponse, Response +from hypercorn.asyncio import serve +from hypercorn.config import Config + +from .db import Step, Task, TaskDB +from .middlewares import AgentMiddleware +from .models import Artifact, Status, StepRequestBody, TaskRequestBody +from .server import app + +base_router = APIRouter() + + +@base_router.get("/heartbeat") +async def heartbeat() -> Response: + """ + Heartbeat endpoint to check if the server is running. + """ + return Response(status_code=200) + + +@base_router.post("/agent/tasks", response_model=Task, tags=["agent"]) +async def create_agent_task( + request: Request, body: TaskRequestBody | None = None +) -> Task: + """ + Creates a task for the agent. + """ + agent: Agent = request["agent"] + + task = await agent.db.create_task( + input=body.input if body else None, + additional_input=body.additional_input if body else None, + ) + print(task) + await agent.create_task(task) + + return task + + +@base_router.get("/agent/tasks", response_model=List[str], tags=["agent"]) +async def list_agent_tasks_ids(request: Request) -> List[str]: + """ + List all tasks that have been created for the agent. + """ + agent: Agent = request["agent"] + return [task.task_id for task in await agent.db.list_tasks()] + + +@base_router.get("/agent/tasks/{task_id}", response_model=Task, tags=["agent"]) +async def get_agent_task(request: Request, task_id: str) -> Task: + """ + Get details about a specified agent task. + """ + agent: Agent = request["agent"] + return await agent.db.get_task(task_id) + + +@base_router.get( + "/agent/tasks/{task_id}/steps", + response_model=List[str], + tags=["agent"], +) +async def list_agent_task_steps(request: Request, task_id: str) -> List[str]: + """ + List all steps for the specified task. + """ + agent: Agent = request["agent"] + task = await agent.db.get_task(task_id) + return [s.step_id for s in task.steps] + + +@base_router.post( + "/agent/tasks/{task_id}/steps", + response_model=Step, + tags=["agent"], +) +async def execute_agent_task_step( + request: Request, + task_id: str, + body: StepRequestBody | None = None, +) -> Step: + """ + Execute a step in the specified agent task. + """ + agent: Agent = request["agent"] + + if body.input != "y": + step = await agent.db.create_step( + task_id=task_id, + input=body.input if body else None, + additional_properties=body.additional_input if body else None, + ) + step = await agent.run_step(step) + step.output = "Task completed" + step.is_last = True + else: + steps = await agent.db.list_steps(task_id) + artifacts = await agent.db.list_artifacts(task_id) + step = steps[-1] + step.artifacts = artifacts + step.output = "No more steps to run." + step.is_last = True + if isinstance(step.status, Status): + step.status = step.status.value + return JSONResponse(content=step.dict(), status_code=200) + + +@base_router.get( + "/agent/tasks/{task_id}/steps/{step_id}", + response_model=Step, + tags=["agent"], +) +async def get_agent_task_step(request: Request, task_id: str, step_id: str) -> Step: + """ + Get details about a specified task step. + """ + agent: Agent = request["agent"] + return await agent.db.get_step(task_id, step_id) + + +@base_router.get( + "/agent/tasks/{task_id}/artifacts", + response_model=List[Artifact], + tags=["agent"], +) +async def list_agent_task_artifacts(request: Request, task_id: str) -> List[Artifact]: + """ + List all artifacts for the specified task. + """ + agent: Agent = request["agent"] + task = await agent.db.get_task(task_id) + return task.artifacts + + +@base_router.post( + "/agent/tasks/{task_id}/artifacts", + response_model=Artifact, + tags=["agent"], +) +async def upload_agent_task_artifacts( + request: Request, + task_id: str, + file: UploadFile | None = None, + uri: str | None = None, +) -> Artifact: + """ + Upload an artifact for the specified task. + """ + agent: Agent = request["agent"] + if not file and not uri: + return Response(status_code=400, content="No file or uri provided") + data = None + if not uri: + file_name = file.filename or str(uuid4()) + try: + data = b"" + while contents := file.file.read(1024 * 1024): + data += contents + except Exception as e: + return Response(status_code=500, content=str(e)) + + artifact = await agent.save_artifact(task_id, artifact, data) + agent.db.add_artifact(task_id, artifact) + + return artifact + + +@base_router.get( + "/agent/tasks/{task_id}/artifacts/{artifact_id}", + tags=["agent"], +) +async def download_agent_task_artifacts( + request: Request, task_id: str, artifact_id: str +) -> FileResponse: + """ + Download the specified artifact. + """ + agent: Agent = request["agent"] + artifact = await agent.db.get_artifact(task_id, artifact_id) + retrieved_artifact: Artifact = await agent.retrieve_artifact(task_id, artifact) + path = artifact.file_name + with open(path, "wb") as f: + f.write(retrieved_artifact) + return FileResponse( + # Note: mimetype is guessed in the FileResponse constructor + path=path, + filename=artifact.file_name, + ) + + +class Agent: + def __init__(self, db: TaskDB): + self.name = self.__class__.__name__ + self.db = db + + def start(self, port: int = 8000, router: APIRouter = base_router): + """ + Start the agent server. + """ + config = Config() + config.bind = [f"localhost:{port}"] # As an example configuration setting + app.title = f"{self.name} - Agent Communication Protocol" + app.include_router(router) + app.add_middleware(AgentMiddleware, agent=self) + asyncio.run(serve(app, config)) + + async def create_task(self, task: Task): + """ + Handles a new task + """ + return task + + async def run_step(self, step: Step) -> Step: + return step + + async def retrieve_artifact(self, task_id: str, artifact: Artifact) -> bytes: + """ + Retrieve the artifact data from wherever it is stored and return it as bytes. + """ + raise NotImplementedError("") + + async def save_artifact( + self, task_id: str, artifact: Artifact, data: bytes | None = None + ) -> Artifact: + """ + Save the artifact data to the agent's workspace, loading from uri if bytes are not available. + """ + raise NotImplementedError() diff --git a/autogpt/agent_protocol/db.py b/autogpt/agent_protocol/db.py new file mode 100644 index 00000000..590efe2b --- /dev/null +++ b/autogpt/agent_protocol/db.py @@ -0,0 +1,173 @@ +import uuid +from abc import ABC +from typing import Any, Dict, List, Optional + +from .models import Artifact, Status +from .models import Step as APIStep +from .models import Task as APITask + + +class Step(APIStep): + additional_properties: Optional[Dict[str, str]] = None + + +class Task(APITask): + steps: Optional[List[Step]] = [] + + +class NotFoundException(Exception): + """ + Exception raised when a resource is not found. + """ + + def __init__(self, item_name: str, item_id: str): + self.item_name = item_name + self.item_id = item_id + super().__init__(f"{item_name} with {item_id} not found.") + + +class TaskDB(ABC): + async def create_task( + self, input: Optional[str], additional_input: Any = None + ) -> Task: + raise NotImplementedError + + async def create_step( + self, + task_id: str, + name: Optional[str] = None, + input: Optional[str] = None, + is_last: bool = False, + additional_properties: Optional[Dict[str, str]] = None, + ) -> Step: + raise NotImplementedError + + async def create_artifact( + self, + task_id: str, + artifact: Artifact, + step_id: str | None = None, + ) -> Artifact: + raise NotImplementedError + + async def get_task(self, task_id: str) -> Task: + raise NotImplementedError + + async def get_step(self, task_id: str, step_id: str) -> Step: + raise NotImplementedError + + async def get_artifact(self, task_id: str, artifact_id: str) -> Artifact: + raise NotImplementedError + + async def list_tasks(self) -> List[Task]: + raise NotImplementedError + + async def list_steps( + self, task_id: str, status: Optional[Status] = None + ) -> List[Step]: + raise NotImplementedError + + async def update_step( + self, + task_id: str, + step_id: str, + status: str, + additional_properties: Optional[Dict[str, str]] = None, + ) -> Step: + raise NotImplementedError + + +class InMemoryTaskDB(TaskDB): + _tasks: Dict[str, Task] = {} + + async def create_task( + self, + input: Optional[str], + additional_input: Any = None, + ) -> Task: + task_id = str(uuid.uuid4()) + task = Task( + task_id=task_id, + input=input, + steps=[], + artifacts=[], + additional_input=additional_input, + ) + self._tasks[task_id] = task + return task + + async def create_step( + self, + task_id: str, + name: Optional[str] = None, + input: Optional[str] = None, + is_last=False, + additional_properties: Optional[Dict[str, Any]] = None, + ) -> Step: + step_id = str(uuid.uuid4()) + step = Step( + task_id=task_id, + step_id=step_id, + name=name, + input=input, + status=Status.created, + is_last=is_last, + additional_properties=additional_properties, + ) + task = await self.get_task(task_id) + task.steps.append(step) + return step + + async def get_task(self, task_id: str) -> Task: + task = self._tasks.get(task_id, None) + if not task: + raise NotFoundException("Task", task_id) + return task + + async def get_step(self, task_id: str, step_id: str) -> Step: + task = await self.get_task(task_id) + step = next(filter(lambda s: s.task_id == task_id, task.steps), None) + if not step: + raise NotFoundException("Step", step_id) + return step + + async def get_artifact(self, task_id: str, artifact_id: str) -> Artifact: + task = await self.get_task(task_id) + artifact = next( + filter(lambda a: a.artifact_id == artifact_id, task.artifacts), None + ) + if not artifact: + raise NotFoundException("Artifact", artifact_id) + return artifact + + async def create_artifact( + self, + task_id: str, + file_name: str, + relative_path: Optional[str] = None, + step_id: Optional[str] = None, + ) -> Artifact: + artifact_id = str(uuid.uuid4()) + artifact = Artifact( + artifact_id=artifact_id, file_name=file_name, relative_path=relative_path + ) + task = await self.get_task(task_id) + task.artifacts.append(artifact) + + if step_id: + step = await self.get_step(task_id, step_id) + step.artifacts.append(artifact) + + return artifact + + async def list_tasks(self) -> List[Task]: + return [task for task in self._tasks.values()] + + async def list_steps( + self, task_id: str, status: Optional[Status] = None + ) -> List[Step]: + task = await self.get_task(task_id) + steps = task.steps + if status: + steps = list(filter(lambda s: s.status == status, steps)) + return steps diff --git a/autogpt/agent_protocol/middlewares.py b/autogpt/agent_protocol/middlewares.py new file mode 100644 index 00000000..6a0d846a --- /dev/null +++ b/autogpt/agent_protocol/middlewares.py @@ -0,0 +1,46 @@ +from fastapi import FastAPI, Request +from fastapi.responses import PlainTextResponse + +from .db import NotFoundException + + +async def not_found_exception_handler( + request: Request, exc: NotFoundException +) -> PlainTextResponse: + return PlainTextResponse( + str(exc), + status_code=404, + ) + + +class AgentMiddleware: + """ + Middleware that injects the agent instance into the request scope. + """ + + def __init__(self, app: FastAPI, agent: "Agent"): + """ + + Args: + app: The FastAPI app - automatically injected by FastAPI. + agent: The agent instance to inject into the request scope. + + Examples: + >>> from fastapi import FastAPI, Request + >>> from agent_protocol.agent import Agent + >>> from agent_protocol.middlewares import AgentMiddleware + >>> app = FastAPI() + >>> @app.get("/") + >>> async def root(request: Request): + >>> agent = request["agent"] + >>> task = agent.db.create_task("Do something.") + >>> return {"task_id": a.task_id} + >>> agent = Agent() + >>> app.add_middleware(AgentMiddleware, agent=agent) + """ + self.app = app + self.agent = agent + + async def __call__(self, scope, receive, send): + scope["agent"] = self.agent + await self.app(scope, receive, send) diff --git a/autogpt/agent_protocol/models.py b/autogpt/agent_protocol/models.py new file mode 100644 index 00000000..5a42f1b9 --- /dev/null +++ b/autogpt/agent_protocol/models.py @@ -0,0 +1,131 @@ +# generated by fastapi-codegen: +# filename: ../../openapi.yml +# timestamp: 2023-08-17T11:26:07+00:00 + +from __future__ import annotations + +from enum import Enum +from typing import Any, List, Optional + +from pydantic import BaseModel, Field + + +class TaskInput(BaseModel): + __root__: Any = Field( + ..., + description="Input parameters for the task. Any value is allowed.", + example='{\n"debug": false,\n"mode": "benchmarks"\n}', + ) + + +class Artifact(BaseModel): + artifact_id: str = Field( + ..., + description="ID of the artifact.", + example="b225e278-8b4c-4f99-a696-8facf19f0e56", + ) + file_name: str = Field( + ..., description="Filename of the artifact.", example="main.py" + ) + agent_created: Optional[bool] = Field( + None, + description="Whether the artifact has been created by the agent.", + example=False, + ) + uri: Optional[str] = Field( + None, + description="URI of the artifact.", + example="file://home/bob/workspace/bucket/main.py", + ) + + +class ArtifactUpload(BaseModel): + file: bytes = Field(..., description="File to upload.") + relative_path: Optional[str] = Field( + None, + description="Relative path of the artifact in the agent's workspace.", + example="python/code", + ) + + +class StepInput(BaseModel): + __root__: Any = Field( + ..., + description="Input parameters for the task step. Any value is allowed.", + example='{\n"file_to_refactor": "models.py"\n}', + ) + + +class StepOutput(BaseModel): + __root__: Any = Field( + ..., + description="Output that the task step has produced. Any value is allowed.", + example='{\n"tokens": 7894,\n"estimated_cost": "0,24$"\n}', + ) + + +class TaskRequestBody(BaseModel): + input: Optional[str] = Field( + None, + description="Input prompt for the task.", + example="Write the words you receive to the file 'output.txt'.", + ) + additional_input: Optional[TaskInput] = None + + +class Task(TaskRequestBody): + task_id: str = Field( + ..., + description="The ID of the task.", + example="50da533e-3904-4401-8a07-c49adf88b5eb", + ) + artifacts: Optional[List[Artifact]] = Field( + [], + description="A list of artifacts that the task has produced.", + example=[ + "7a49f31c-f9c6-4346-a22c-e32bc5af4d8e", + "ab7b4091-2560-4692-a4fe-d831ea3ca7d6", + ], + ) + + +class StepRequestBody(BaseModel): + input: Optional[str] = Field( + None, description="Input prompt for the step.", example="Washington" + ) + additional_input: Optional[StepInput] = None + + +class Status(Enum): + created = "created" + running = "running" + completed = "completed" + + +class Step(StepRequestBody): + task_id: str = Field( + ..., + description="The ID of the task this step belongs to.", + example="50da533e-3904-4401-8a07-c49adf88b5eb", + ) + step_id: str = Field( + ..., + description="The ID of the task step.", + example="6bb1801a-fd80-45e8-899a-4dd723cc602e", + ) + name: Optional[str] = Field( + None, description="The name of the task step.", example="Write to file" + ) + status: Status = Field(..., description="The status of the task step.") + output: Optional[str] = Field( + None, + description="Output of the task step.", + example="I am going to use the write_to_file command and write Washington to a file called output.txt Task: + steps_list = [] + for step in task_obj.steps: + status = Status.completed if step.status == "completed" else Status.created + steps_list.append( + Step( + task_id=step.task_id, + step_id=step.step_id, + name=step.name, + status=status, + is_last=step.is_last == 1, + additional_properties=step.additional_properties, + ) + ) + return Task( + task_id=task_obj.task_id, + input=task_obj.input, + additional_input=task_obj.additional_input, + artifacts=[], + steps=steps_list, + ) + + +def convert_to_step(step_model: StepModel) -> Step: + print(step_model) + step_artifacts = [ + Artifact( + artifact_id=artifact.artifact_id, + file_name=artifact.file_name, + agent_created=artifact.agent_created, + uri=artifact.uri, + ) + for artifact in step_model.task.artifacts + if artifact.step_id == step_model.step_id + ] + status = Status.completed if step_model.status == "completed" else Status.created + return Step( + task_id=step_model.task_id, + step_id=step_model.step_id, + name=step_model.name, + input=step_model.input, + status=status, + artifacts=step_artifacts, + is_last=step_model.is_last == 1, + additional_properties=step_model.additional_properties, + ) + + # sqlite:///{database_name} class AgentDB(TaskDB): def __init__(self, database_string) -> None: @@ -75,26 +117,23 @@ class AgentDB(TaskDB): print("Databases Created") async def create_task( - self, - input: Optional[str], - additional_input: Optional[TaskInput] = None, - artifacts: List[Artifact] = None, - steps: List[Step] = None, + self, input: Optional[str], additional_input: Optional[TaskInput] = None ) -> Task: session = self.Session() new_task = TaskModel( input=input, - additional_input=additional_input.json() if additional_input else None, + additional_input=additional_input.__root__ if additional_input else None, ) session.add(new_task) session.commit() session.refresh(new_task) - return await self.get_task(new_task.task_id) + return convert_to_task(new_task) async def create_step( self, task_id: str, name: Optional[str] = None, + input: Optional[str] = None, is_last: bool = False, additional_properties: Optional[Dict[str, str]] = None, ) -> Step: @@ -102,6 +141,7 @@ class AgentDB(TaskDB): new_step = StepModel( task_id=task_id, name=name, + input=input, status="created", is_last=is_last, additional_properties=additional_properties, @@ -109,23 +149,28 @@ class AgentDB(TaskDB): session.add(new_step) session.commit() session.refresh(new_step) - return await self.get_step(task_id, new_step.step_id) + return convert_to_step(new_step) async def create_artifact( self, task_id: str, file_name: str, - relative_path: Optional[str] = None, - step_id: Optional[str] = None, - file_data: bytes | None = None, + uri: str, + agent_created: bool = False, + step_id: str | None = None, ) -> Artifact: session = self.Session() + + if existing_artifact := session.query(ArtifactModel).filter_by(uri=uri).first(): + session.close() + return existing_artifact + new_artifact = ArtifactModel( task_id=task_id, step_id=step_id, + agent_created=agent_created, file_name=file_name, - relative_path=relative_path, - file_data=file_data, + uri=uri, ) session.add(new_artifact) session.commit() @@ -135,50 +180,27 @@ class AgentDB(TaskDB): async def get_task(self, task_id: int) -> Task: """Get a task by its id""" session = self.Session() - task_obj = session.query(TaskModel).filter_by(task_id=task_id).first() + task_obj = ( + session.query(TaskModel) + .options(joinedload(TaskModel.steps)) + .filter_by(task_id=task_id) + .first() + ) if task_obj: - task = Task( - task_id=task_obj.task_id, - input=task_obj.input, - additional_input=task_obj.additional_input, - steps=[], - ) - steps_obj = session.query(StepModel).filter_by(task_id=task_id).all() - if steps_obj: - for step in steps_obj: - status = ( - Status.created if step.status == "created" else Status.completed - ) - task.steps.append( - Step( - task_id=step.task_id, - step_id=step.step_id, - name=step.name, - status=status, - is_last=step.is_last == 1, - additional_properties=step.additional_properties, - ) - ) - return task + return convert_to_task(task_obj) else: raise DataNotFoundError("Task not found") async def get_step(self, task_id: int, step_id: int) -> Step: session = self.Session() - if ( - step := session.query(StepModel) - .filter_by(task_id=task_id, step_id=step_id) + if step := ( + session.query(StepModel) + .options(joinedload(StepModel.task).joinedload(TaskModel.artifacts)) + .filter(StepModel.step_id == step_id) .first() ): - status = Status.completed if step.status == "completed" else Status.created - return Step( - task_id=task_id, - step_id=step_id, - name=step.name, - status=status, - is_last=step.is_last == 1, - additional_properties=step.additional_properties, - ) + return convert_to_step(step) + else: raise DataNotFoundError("Step not found") @@ -204,30 +226,20 @@ class AgentDB(TaskDB): async def get_artifact(self, task_id: str, artifact_id: str) -> Artifact: session = self.Session() - if ( - artifact := session.query(ArtifactModel) + if artifact_model := ( + session.query(ArtifactModel) .filter_by(task_id=task_id, artifact_id=artifact_id) .first() ): return Artifact( - artifact_id=artifact.artifact_id, - file_name=artifact.file_name, - relative_path=artifact.relative_path, + artifact_id=str(artifact_model.artifact_id), # Casting to string + file_name=artifact_model.file_name, + agent_created=artifact_model.agent_created, + uri=artifact_model.uri, ) else: raise DataNotFoundError("Artifact not found") - async def get_artifact_file(self, task_id: str, artifact_id: str) -> bytes: - session = self.Session() - if ( - artifact := session.query(ArtifactModel.file_data) - .filter_by(task_id=task_id, artifact_id=artifact_id) - .first() - ): - return artifact.file_data - else: - raise DataNotFoundError("Artifact not found") - async def list_tasks(self) -> List[Task]: session = self.Session() tasks = session.query(TaskModel).all() @@ -252,3 +264,16 @@ class AgentDB(TaskDB): ) for step in steps ] + + async def list_artifacts(self, task_id: str) -> List[Artifact]: + session = self.Session() + artifacts = session.query(ArtifactModel).filter_by(task_id=task_id).all() + return [ + Artifact( + artifact_id=str(artifact.artifact_id), + file_name=artifact.file_name, + agent_created=artifact.agent_created, + uri=artifact.uri, + ) + for artifact in artifacts + ] diff --git a/autogpt/db_test.py b/autogpt/db_test.py index 09350720..cd2568b4 100644 --- a/autogpt/db_test.py +++ b/autogpt/db_test.py @@ -52,6 +52,17 @@ async def test_create_and_get_task(): os.remove(db_name.split("///")[1]) +@pytest.mark.asyncio +async def test_create_and_get_task_with_steps(): + db_name = "sqlite:///test_db.sqlite3" + agent_db = AgentDB(db_name) + await agent_db.create_task("task_input") + task = await agent_db.get_task(1) + + assert task.input == "task_input" + os.remove(db_name.split("///")[1]) + + @pytest.mark.asyncio async def test_get_task_not_found(): db_name = "sqlite:///test_db.sqlite3" @@ -102,41 +113,23 @@ async def test_get_artifact(): # Given: A task and its corresponding artifact task = await db.create_task("test_input") step = await db.create_step(task.task_id, "step_name") + + # Create an artifact artifact = await db.create_artifact( - task.task_id, "sample_file.txt", "/path/to/sample_file.txt", step.step_id + task_id=task.task_id, + file_name="sample_file.txt", + uri="file:///path/to/sample_file.txt", + agent_created=True, + step_id=step.step_id, ) # When: The artifact is fetched by its ID - fetched_artifact = await db.get_artifact(task.task_id, artifact.artifact_id) + fetched_artifact = await db.get_artifact(int(task.task_id), artifact.artifact_id) # Then: The fetched artifact matches the original - assert fetched_artifact.artifact_id == artifact.artifact_id assert fetched_artifact.file_name == "sample_file.txt" - assert fetched_artifact.relative_path == "/path/to/sample_file.txt" - os.remove(db_name.split("///")[1]) + assert fetched_artifact.uri == "file:///path/to/sample_file.txt" - -@pytest.mark.asyncio -async def test_get_artifact_file(): - db_name = "sqlite:///test_db.sqlite3" - db = AgentDB(db_name) - sample_data = b"sample data" - # Given: A task and its corresponding artifact - task = await db.create_task("test_input") - step = await db.create_step(task.task_id, "step_name") - artifact = await db.create_artifact( - task.task_id, - "sample_file.txt", - "/path/to/sample_file.txt", - step.step_id, - sample_data, - ) - - # When: The artifact is fetched by its ID - fetched_artifact = await db.get_artifact_file(task.task_id, artifact.artifact_id) - - # Then: The fetched artifact matches the original - assert fetched_artifact == sample_data os.remove(db_name.split("///")[1]) @@ -174,6 +167,6 @@ async def test_list_steps(): # Then: The fetched steps list includes the created steps step_ids = [step.step_id for step in fetched_steps] - assert step1.step_id in step_ids - assert step2.step_id in step_ids + assert str(step1.step_id) in step_ids + assert str(step2.step_id) in step_ids os.remove(db_name.split("///")[1]) diff --git a/autogpt/llm.py b/autogpt/llm.py new file mode 100644 index 00000000..e69de29b diff --git a/autogpt/utils.py b/autogpt/utils.py index d2d98303..3b94272d 100644 --- a/autogpt/utils.py +++ b/autogpt/utils.py @@ -5,6 +5,7 @@ PLEASE IGNORE ------------------------------------------------------------- """ +import glob import os import typing from pathlib import Path @@ -41,11 +42,28 @@ def chat_completion_request( exit() -def run(task: str) -> None: +def run(task: str): """Runs the agent for benchmarking""" print("Running agent") steps = plan(task) execute_plan(steps) + # check for artifacts in workspace + items = glob.glob(os.path.join(workspace, "*")) + if items: + artifacts = [] + print(f"Found {len(items)} artifacts in workspace") + for item in items: + with open(item, "r") as f: + item_contents = f.read() + path_within_workspace = os.path.relpath(item, workspace) + artifacts.append( + { + "file_name": os.path.basename(item), + "uri": f"file://{path_within_workspace}", + "contents": item_contents, + } + ) + return artifacts def execute_plan(plan: typing.List[str]) -> None: diff --git a/autogpt/workspace.py b/autogpt/workspace.py new file mode 100644 index 00000000..54e0a0b1 --- /dev/null +++ b/autogpt/workspace.py @@ -0,0 +1,127 @@ +import abc +import os +import typing +from pathlib import Path + +from google.cloud import storage + + +class Workspace(abc.ABC): + @abc.abstractclassmethod + def __init__(self, base_path: str) -> None: + self.base_path = base_path + + @abc.abstractclassmethod + def read(self, path: str) -> bytes: + pass + + @abc.abstractclassmethod + def write(self, path: str, data: bytes) -> None: + pass + + @abc.abstractclassmethod + def delete( + self, path: str, directory: bool = False, recursive: bool = False + ) -> None: + pass + + @abc.abstractclassmethod + def exists(self, path: str) -> bool: + pass + + @abc.abstractclassmethod + def list(self, path: str) -> typing.List[str]: + pass + + +class LocalWorkspace(Workspace): + def __init__(self, base_path: str): + self.base_path = Path(base_path).resolve() + + def _resolve_path(self, path: str) -> Path: + abs_path = (self.base_path / path).resolve() + if not str(abs_path).startswith(str(self.base_path)): + raise ValueError("Directory traversal is not allowed!") + return abs_path + + def read(self, path: str) -> bytes: + path = self.base_path / path + with open(self._resolve_path(path), "rb") as f: + return f.read() + + def write(self, path: str, data: bytes) -> None: + path = self.base_path / path + with open(self._resolve_path(path), "wb") as f: + f.write(data) + + def delete( + self, path: str, directory: bool = False, recursive: bool = False + ) -> None: + path = self.base_path / path + resolved_path = self._resolve_path(path) + if directory: + if recursive: + os.rmdir(resolved_path) + else: + os.removedirs(resolved_path) + else: + os.remove(resolved_path) + + def exists(self, path: str) -> bool: + path = self.base_path / path + return self._resolve_path(path).exists() + + def list(self, path: str) -> typing.List[str]: + path = self.base_path / path + base = self._resolve_path(path) + return [str(p.relative_to(self.base_path)) for p in base.iterdir()] + + +class GCSWorkspace(Workspace): + def __init__(self, base_path: str, bucket_name: str): + self.client = storage.Client() + self.bucket_name = bucket_name + self.base_path = base_path.strip("/") # Ensure no trailing or leading slash + + def _resolve_path(self, path: str) -> str: + resolved = os.path.join(self.base_path, path).strip("/") + if not resolved.startswith(self.base_path): + raise ValueError("Directory traversal is not allowed!") + return resolved + + def read(self, path: str) -> bytes: + path = self.base_path / path + bucket = self.client.get_bucket(self.bucket_name) + blob = bucket.get_blob(self._resolve_path(path)) + return blob.download_as_bytes() + + def write(self, path: str, data: bytes) -> None: + path = self.base_path / path + bucket = self.client.get_bucket(self.bucket_name) + blob = bucket.blob(self._resolve_path(path)) + blob.upload_from_string(data) + + def delete( + self, path: str, directory: bool = False, recursive: bool = False + ) -> None: + path = self.base_path / path + bucket = self.client.get_bucket(self.bucket_name) + if directory and recursive: + # Note: GCS doesn't really have directories, so this will just delete all blobs with the given prefix + blobs = bucket.list_blobs(prefix=self._resolve_path(path)) + bucket.delete_blobs(blobs) + else: + blob = bucket.blob(self._resolve_path(path)) + blob.delete() + + def exists(self, path: str) -> bool: + path = self.base_path / path + bucket = self.client.get_bucket(self.bucket_name) + blob = bucket.blob(self._resolve_path(path)) + return blob.exists() + + def list(self, path: str) -> typing.List[str]: + path = self.base_path / path + bucket = self.client.get_bucket(self.bucket_name) + blobs = bucket.list_blobs(prefix=self._resolve_path(path)) + return [blob.name for blob in blobs] diff --git a/autogpt/workspace_test.py b/autogpt/workspace_test.py new file mode 100644 index 00000000..13e2ca7c --- /dev/null +++ b/autogpt/workspace_test.py @@ -0,0 +1,46 @@ +import os + +import pytest + +# Assuming the classes are defined in a file named workspace.py +from .workspace import LocalWorkspace + +# Constants +TEST_BASE_PATH = "/tmp/test_workspace" +TEST_FILE_CONTENT = b"Hello World" + + +# Setup and Teardown for LocalWorkspace + + +@pytest.fixture +def setup_local_workspace(): + os.makedirs(TEST_BASE_PATH, exist_ok=True) + yield + os.system(f"rm -rf {TEST_BASE_PATH}") # Cleanup after tests + + +def test_local_read_write_delete_exists(setup_local_workspace): + workspace = LocalWorkspace(TEST_BASE_PATH) + + # Write + workspace.write("test_file.txt", TEST_FILE_CONTENT) + + # Exists + assert workspace.exists("test_file.txt") + + # Read + assert workspace.read("test_file.txt") == TEST_FILE_CONTENT + + # Delete + workspace.delete("test_file.txt") + assert not workspace.exists("test_file.txt") + + +def test_local_list(setup_local_workspace): + workspace = LocalWorkspace(TEST_BASE_PATH) + workspace.write("test1.txt", TEST_FILE_CONTENT) + workspace.write("test2.txt", TEST_FILE_CONTENT) + + files = workspace.list(".") + assert set(files) == set(["test1.txt", "test2.txt"]) diff --git a/poetry.lock b/poetry.lock index 030fd480..3b461e9d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. [[package]] name = "aenum" version = "3.1.15" description = "Advanced Enumerations (compatible with Python's stdlib Enum), NamedTuples, and NamedConstants" +category = "dev" optional = false python-versions = "*" files = [ @@ -16,6 +17,7 @@ files = [ name = "agbenchmark" version = "0.0.9" description = "Benchmarking the performance of agents far and wide, regardless of how they are set up and how they work" +category = "dev" optional = false python-versions = ">=3.10,<4.0" files = [ @@ -49,6 +51,7 @@ types-requests = ">=2.31.0.1,<3.0.0.0" name = "agent-protocol" version = "0.2.4" description = "API for interacting with Agent" +category = "dev" optional = false python-versions = ">=3.7,<4.0.0" files = [ @@ -70,6 +73,7 @@ requests = ">=2.31.0,<3.0.0" name = "agent-protocol-client" version = "0.2.2" description = "Agent Communication Protocol Client" +category = "dev" optional = false python-versions = ">=3.10,<4.0" files = [ @@ -88,6 +92,7 @@ urllib3 = ">=1.25.3" name = "aiofiles" version = "23.2.1" description = "File support for asyncio." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -99,6 +104,7 @@ files = [ name = "aiohttp" version = "3.8.5" description = "Async http client/server framework (asyncio)" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -207,6 +213,7 @@ speedups = ["Brotli", "aiodns", "cchardet"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -221,6 +228,7 @@ frozenlist = ">=1.1.0" name = "altair" version = "5.0.1" description = "Vega-Altair: A declarative statistical visualization library for Python." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -244,6 +252,7 @@ doc = ["docutils", "geopandas", "jinja2", "myst-parser", "numpydoc", "pillow", " name = "ansi2html" version = "1.8.0" description = "" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -259,6 +268,7 @@ test = ["pytest", "pytest-cov"] name = "anyio" version = "3.7.1" description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -280,6 +290,7 @@ trio = ["trio (<0.22)"] name = "appnope" version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" +category = "dev" optional = false python-versions = "*" files = [ @@ -291,6 +302,7 @@ files = [ name = "asttokens" version = "2.2.1" description = "Annotate AST trees with source code positions" +category = "dev" optional = false python-versions = "*" files = [ @@ -308,6 +320,7 @@ test = ["astroid", "pytest"] name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -319,6 +332,7 @@ files = [ name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -337,6 +351,7 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" +category = "dev" optional = false python-versions = "*" files = [ @@ -348,6 +363,7 @@ files = [ name = "black" version = "23.7.0" description = "The uncompromising code formatter." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -389,10 +405,23 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "cachetools" +version = "5.3.1" +description = "Extensible memoizing collections and decorators" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.1-py3-none-any.whl", hash = "sha256:95ef631eeaea14ba2e36f06437f36463aac3a096799e876ee55e5cdccb102590"}, + {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, +] + [[package]] name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -404,6 +433,7 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." +category = "dev" optional = false python-versions = "*" files = [ @@ -480,6 +510,7 @@ pycparser = "*" name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -491,6 +522,7 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -575,6 +607,7 @@ files = [ name = "click" version = "8.1.6" description = "Composable command line interface toolkit" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -589,6 +622,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -600,6 +634,7 @@ files = [ name = "contourpy" version = "1.1.0" description = "Python library for calculating contours of 2D quadrilateral grids" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -658,6 +693,7 @@ test-no-images = ["pytest", "pytest-cov", "wurlitzer"] name = "cycler" version = "0.11.0" description = "Composable style cycles" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -669,6 +705,7 @@ files = [ name = "dash" version = "2.12.1" description = "A Python framework for building reactive web-apps. Developed by Plotly." +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -702,6 +739,7 @@ testing = ["beautifulsoup4 (>=4.8.2)", "cryptography (<3.4)", "dash-testing-stub name = "dash-bootstrap-components" version = "1.4.2" description = "Bootstrap themed components for use in Plotly Dash" +category = "dev" optional = false python-versions = ">=3.7, <4" files = [ @@ -719,6 +757,7 @@ pandas = ["numpy", "pandas"] name = "dash-core-components" version = "2.0.0" description = "Core component suite for Dash" +category = "dev" optional = false python-versions = "*" files = [ @@ -730,6 +769,7 @@ files = [ name = "dash-html-components" version = "2.0.0" description = "Vanilla HTML components for Dash" +category = "dev" optional = false python-versions = "*" files = [ @@ -741,6 +781,7 @@ files = [ name = "dash-table" version = "5.0.0" description = "Dash table" +category = "dev" optional = false python-versions = "*" files = [ @@ -752,6 +793,7 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -763,6 +805,7 @@ files = [ name = "distlib" version = "0.3.7" description = "Distribution utilities" +category = "dev" optional = false python-versions = "*" files = [ @@ -774,6 +817,7 @@ files = [ name = "exceptiongroup" version = "1.1.3" description = "Backport of PEP 654 (exception groups)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -788,6 +832,7 @@ test = ["pytest (>=6)"] name = "executing" version = "1.2.0" description = "Get the currently executing AST node of a frame, and other information" +category = "dev" optional = false python-versions = "*" files = [ @@ -802,6 +847,7 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] name = "fastapi" version = "0.100.1" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -821,6 +867,7 @@ all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)" name = "ffmpy" version = "0.3.1" description = "A simple Python wrapper for ffmpeg" +category = "dev" optional = false python-versions = "*" files = [ @@ -831,6 +878,7 @@ files = [ name = "filelock" version = "3.12.2" description = "A platform independent file lock." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -846,6 +894,7 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "flake8" version = "6.1.0" description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" optional = false python-versions = ">=3.8.1" files = [ @@ -862,6 +911,7 @@ pyflakes = ">=3.1.0,<3.2.0" name = "flask" version = "2.2.5" description = "A simple framework for building complex web applications." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -883,6 +933,7 @@ dotenv = ["python-dotenv"] name = "fonttools" version = "4.42.0" description = "Tools to manipulate font files" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -940,6 +991,7 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "frozenlist" version = "1.4.0" description = "A list-like structure which implements collections.abc.MutableSequence" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1010,6 +1062,7 @@ files = [ name = "fsspec" version = "2023.6.0" description = "File-system specification" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1045,6 +1098,7 @@ tqdm = ["tqdm"] name = "gitdb" version = "4.0.10" description = "Git Object Database" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1059,6 +1113,7 @@ smmap = ">=3.0.1,<6" name = "gitpython" version = "3.1.32" description = "GitPython is a Python library used to interact with Git repositories" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1069,10 +1124,218 @@ files = [ [package.dependencies] gitdb = ">=4.0.1,<5" +[[package]] +name = "google-api-core" +version = "2.11.1" +description = "Google API client core library" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-api-core-2.11.1.tar.gz", hash = "sha256:25d29e05a0058ed5f19c61c0a78b1b53adea4d9364b464d014fbda941f6d1c9a"}, + {file = "google_api_core-2.11.1-py3-none-any.whl", hash = "sha256:d92a5a92dc36dd4f4b9ee4e55528a90e432b059f93aee6ad857f9de8cc7ae94a"}, +] + +[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.17.3" +description = "Google Authentication Library" +category = "main" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +files = [ + {file = "google-auth-2.17.3.tar.gz", hash = "sha256:ce311e2bc58b130fddf316df57c9b3943c2a7b4f6ec31de9663a9333e4064efc"}, + {file = "google_auth-2.17.3-py2.py3-none-any.whl", hash = "sha256:f586b274d3eb7bd932ea424b1c702a30e0393a2e2bc4ca3eae8263ffd8be229f"}, +] + +[package.dependencies] +cachetools = ">=2.0.0,<6.0" +pyasn1-modules = ">=0.2.1" +rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""} +six = ">=1.9.0" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] +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.0dev)"] + +[[package]] +name = "google-cloud-core" +version = "2.3.3" +description = "Google Cloud API client core library" +category = "main" +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.0 || >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.10.0" +description = "Google Cloud Storage API client library" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-cloud-storage-2.10.0.tar.gz", hash = "sha256:934b31ead5f3994e5360f9ff5750982c5b6b11604dc072bc452c25965e076dc7"}, + {file = "google_cloud_storage-2.10.0-py2.py3-none-any.whl", hash = "sha256:9433cf28801671de1c80434238fb1e7e4a1ba3087470e90f70c928ea77c2b9d7"}, +] + +[package.dependencies] +google-api-core = ">=1.31.5,<2.0.0 || >2.3.0,<3.0.0dev" +google-auth = ">=1.25.0,<3.0dev" +google-cloud-core = ">=2.3.0,<3.0dev" +google-resumable-media = ">=2.3.2" +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'" +category = "main" +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.5.0" +description = "Utilities for Google Media Downloads and Resumable Uploads" +category = "main" +optional = false +python-versions = ">= 3.7" +files = [ + {file = "google-resumable-media-2.5.0.tar.gz", hash = "sha256:218931e8e2b2a73a58eb354a288e03a0fd5fb1c4583261ac6e4c078666468c93"}, + {file = "google_resumable_media-2.5.0-py2.py3-none-any.whl", hash = "sha256:da1bd943e2e114a56d85d6848497ebf9be6a14d3db23e9fc57581e7c3e8170ec"}, +] + +[package.dependencies] +google-crc32c = ">=1.0,<2.0dev" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)"] +requests = ["requests (>=2.18.0,<3.0.0dev)"] + +[[package]] +name = "googleapis-common-protos" +version = "1.60.0" +description = "Common protobufs used in Google APIs" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "googleapis-common-protos-1.60.0.tar.gz", hash = "sha256:e73ebb404098db405ba95d1e1ae0aa91c3e15a71da031a2eeb6b2e23e7bc3708"}, + {file = "googleapis_common_protos-1.60.0-py2.py3-none-any.whl", hash = "sha256:69f9bbcc6acde92cab2db95ce30a70bd2b81d20b12eff3f1aabaffcbe8a93918"}, +] + +[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 = "gradio" version = "3.40.1" description = "Python library for easily interacting with trained machine learning models" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1117,6 +1380,7 @@ oauth = ["authlib", "itsdangerous"] name = "gradio-client" version = "0.4.0" description = "Python library for easily interacting with trained machine learning models" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1137,6 +1401,7 @@ websockets = ">=10.0,<12.0" name = "greenlet" version = "2.0.2" description = "Lightweight in-process concurrent programming" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -1210,6 +1475,7 @@ test = ["objgraph", "psutil"] name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1221,6 +1487,7 @@ files = [ name = "h2" version = "4.1.0" description = "HTTP/2 State-Machine based protocol implementation" +category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -1234,13 +1501,14 @@ hyperframe = ">=6.0,<7" [[package]] name = "helicone" -version = "1.0.8" +version = "1.0.9" description = "A Python wrapper for the OpenAI API that logs all requests to Helicone." +category = "main" optional = false python-versions = ">=3.8.1" files = [ - {file = "helicone-1.0.8-py3-none-any.whl", hash = "sha256:8b63f7513b1d337a52ed5dfb2b8de4e0e893358d390532af2466cc663fcce778"}, - {file = "helicone-1.0.8.tar.gz", hash = "sha256:3e4508df0c76c646ba42f048d17e5fcf2ef7c9729a077eff0e100b697b671987"}, + {file = "helicone-1.0.9-py3-none-any.whl", hash = "sha256:440b4ff1ba65239f33b70aab3f53b7c69d7c6883a3552a76f8b13818dbef915c"}, + {file = "helicone-1.0.9.tar.gz", hash = "sha256:96122e95d40917a722f79ea71ff5099e248951623b5d0068275b08760e351b0b"}, ] [package.dependencies] @@ -1251,6 +1519,7 @@ openai = ">=0.27.0,<0.28.0" name = "hpack" version = "4.0.0" description = "Pure-Python HPACK header compression" +category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -1262,6 +1531,7 @@ files = [ name = "httpcore" version = "0.17.3" description = "A minimal low-level HTTP client." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1273,16 +1543,17 @@ files = [ anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" +sniffio = ">=1.0.0,<2.0.0" [package.extras] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "httpx" version = "0.24.1" description = "The next generation HTTP client." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1298,14 +1569,15 @@ sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "huggingface-hub" version = "0.16.4" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" +category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -1338,6 +1610,7 @@ typing = ["pydantic", "types-PyYAML", "types-requests", "types-simplejson", "typ name = "hypercorn" version = "0.14.4" description = "A ASGI Server based on Hyper libraries and inspired by Gunicorn" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1362,6 +1635,7 @@ uvloop = ["uvloop"] name = "hyperframe" version = "6.0.1" description = "HTTP/2 framing layer for Python" +category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -1373,6 +1647,7 @@ files = [ name = "identify" version = "2.5.26" description = "File identification library for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1387,6 +1662,7 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1398,6 +1674,7 @@ files = [ name = "importlib-resources" version = "6.0.1" description = "Read resources from Python packages" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1413,6 +1690,7 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1424,6 +1702,7 @@ files = [ name = "ipython" version = "8.14.0" description = "IPython: Productive Interactive Computing" +category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -1462,6 +1741,7 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." +category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -1479,6 +1759,7 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "itsdangerous" version = "2.1.2" description = "Safely pass data to untrusted environments and back." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1490,6 +1771,7 @@ files = [ name = "jedi" version = "0.19.0" description = "An autocompletion tool for Python that can be used for text editors." +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1509,6 +1791,7 @@ testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1526,6 +1809,7 @@ i18n = ["Babel (>=2.7)"] name = "jsonpickle" version = "3.0.2" description = "Python library for serializing any arbitrary object graph into JSON" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1542,6 +1826,7 @@ testing-libs = ["simplejson", "ujson"] name = "jsonschema" version = "4.19.0" description = "An implementation of JSON Schema validation for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1563,6 +1848,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2023.7.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1577,6 +1863,7 @@ referencing = ">=0.28.0" name = "kiwisolver" version = "1.4.4" description = "A fast implementation of the Cassowary constraint solver" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1654,6 +1941,7 @@ files = [ name = "linkify-it-py" version = "2.0.2" description = "Links recognition library with FULL unicode support." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1674,6 +1962,7 @@ test = ["coverage", "pytest", "pytest-cov"] name = "lockfile" version = "0.12.2" description = "Platform-independent file locking module" +category = "main" optional = false python-versions = "*" files = [ @@ -1685,6 +1974,7 @@ files = [ name = "markdown-it-py" version = "2.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1710,6 +2000,7 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1769,6 +2060,7 @@ files = [ name = "matplotlib" version = "3.7.2" description = "Python plotting package" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1830,6 +2122,7 @@ python-dateutil = ">=2.7" name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1844,6 +2137,7 @@ traitlets = "*" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1855,6 +2149,7 @@ files = [ name = "mdit-py-plugins" version = "0.3.3" description = "Collection of plugins for markdown-it-py" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1874,6 +2169,7 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1881,10 +2177,28 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "mock" +version = "5.1.0" +description = "Rolling backport of unittest.mock for all Pythons" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mock-5.1.0-py3-none-any.whl", hash = "sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744"}, + {file = "mock-5.1.0.tar.gz", hash = "sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d"}, +] + +[package.extras] +build = ["blurb", "twine", "wheel"] +docs = ["sphinx"] +test = ["pytest", "pytest-cov"] + [[package]] name = "multidict" version = "6.0.4" description = "multidict implementation" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1968,6 +2282,7 @@ files = [ name = "mypy" version = "1.5.1" description = "Optional static typing for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2014,6 +2329,7 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2025,6 +2341,7 @@ files = [ name = "nest-asyncio" version = "1.5.7" description = "Patch asyncio to allow nested event loops" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2036,6 +2353,7 @@ files = [ name = "networkx" version = "3.1" description = "Python package for creating and manipulating graphs and networks" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2054,6 +2372,7 @@ test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" +category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -2068,6 +2387,7 @@ setuptools = "*" name = "numpy" version = "1.25.2" description = "Fundamental package for array computing in Python" +category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -2102,6 +2422,7 @@ files = [ name = "openai" version = "0.27.8" description = "Python client library for the OpenAI API" +category = "main" optional = false python-versions = ">=3.7.1" files = [ @@ -2116,7 +2437,7 @@ tqdm = "*" [package.extras] datalib = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] -dev = ["black (>=21.6b0,<22.0)", "pytest (==6.*)", "pytest-asyncio", "pytest-mock"] +dev = ["black (>=21.6b0,<22.0)", "pytest (>=6.0.0,<7.0.0)", "pytest-asyncio", "pytest-mock"] embeddings = ["matplotlib", "numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "plotly", "scikit-learn (>=1.0.2)", "scipy", "tenacity (>=8.0.1)"] wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "wandb"] @@ -2124,6 +2445,7 @@ wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1 name = "orjson" version = "3.9.5" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2193,6 +2515,7 @@ files = [ name = "outcome" version = "1.2.0" description = "Capture the outcome of Python function calls." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2207,6 +2530,7 @@ attrs = ">=19.2.0" name = "packaging" version = "23.1" description = "Core utilities for Python packages" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2218,6 +2542,7 @@ files = [ name = "pandas" version = "2.0.3" description = "Powerful data structures for data analysis, time series, and statistics" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2284,6 +2609,7 @@ xml = ["lxml (>=4.6.3)"] name = "parso" version = "0.8.3" description = "A Python Parser" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2299,6 +2625,7 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2310,6 +2637,7 @@ files = [ name = "pexpect" version = "4.8.0" description = "Pexpect allows easy control of interactive console applications." +category = "dev" optional = false python-versions = "*" files = [ @@ -2324,6 +2652,7 @@ ptyprocess = ">=0.5" name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" +category = "dev" optional = false python-versions = "*" files = [ @@ -2335,6 +2664,7 @@ files = [ name = "pillow" version = "10.0.0" description = "Python Imaging Library (Fork)" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2356,7 +2686,6 @@ files = [ {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"}, {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"}, {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"}, - {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"}, {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"}, {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"}, {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"}, @@ -2366,7 +2695,6 @@ files = [ {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"}, {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"}, {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"}, - {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"}, {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"}, {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"}, {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"}, @@ -2404,6 +2732,7 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "platformdirs" version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2419,6 +2748,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "plotly" version = "5.16.1" description = "An open-source, interactive data visualization library for Python" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2434,6 +2764,7 @@ tenacity = ">=6.2.0" name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2449,6 +2780,7 @@ testing = ["pytest", "pytest-benchmark"] name = "pre-commit" version = "3.3.3" description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2467,6 +2799,7 @@ virtualenv = ">=20.10.0" name = "priority" version = "2.0.0" description = "A pure-Python implementation of the HTTP/2 priority tree" +category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -2478,6 +2811,7 @@ files = [ name = "prompt-toolkit" version = "3.0.39" description = "Library for building powerful interactive command lines in Python" +category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -2488,10 +2822,34 @@ files = [ [package.dependencies] wcwidth = "*" +[[package]] +name = "protobuf" +version = "4.24.0" +description = "" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "protobuf-4.24.0-cp310-abi3-win32.whl", hash = "sha256:81cb9c4621d2abfe181154354f63af1c41b00a4882fb230b4425cbaed65e8f52"}, + {file = "protobuf-4.24.0-cp310-abi3-win_amd64.whl", hash = "sha256:6c817cf4a26334625a1904b38523d1b343ff8b637d75d2c8790189a4064e51c3"}, + {file = "protobuf-4.24.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:ae97b5de10f25b7a443b40427033e545a32b0e9dda17bcd8330d70033379b3e5"}, + {file = "protobuf-4.24.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:567fe6b0647494845d0849e3d5b260bfdd75692bf452cdc9cb660d12457c055d"}, + {file = "protobuf-4.24.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:a6b1ca92ccabfd9903c0c7dde8876221dc7d8d87ad5c42e095cc11b15d3569c7"}, + {file = "protobuf-4.24.0-cp37-cp37m-win32.whl", hash = "sha256:a38400a692fd0c6944c3c58837d112f135eb1ed6cdad5ca6c5763336e74f1a04"}, + {file = "protobuf-4.24.0-cp37-cp37m-win_amd64.whl", hash = "sha256:5ab19ee50037d4b663c02218a811a5e1e7bb30940c79aac385b96e7a4f9daa61"}, + {file = "protobuf-4.24.0-cp38-cp38-win32.whl", hash = "sha256:e8834ef0b4c88666ebb7c7ec18045aa0f4325481d724daa624a4cf9f28134653"}, + {file = "protobuf-4.24.0-cp38-cp38-win_amd64.whl", hash = "sha256:8bb52a2be32db82ddc623aefcedfe1e0eb51da60e18fcc908fb8885c81d72109"}, + {file = "protobuf-4.24.0-cp39-cp39-win32.whl", hash = "sha256:ae7a1835721086013de193311df858bc12cd247abe4ef9710b715d930b95b33e"}, + {file = "protobuf-4.24.0-cp39-cp39-win_amd64.whl", hash = "sha256:44825e963008f8ea0d26c51911c30d3e82e122997c3c4568fd0385dd7bacaedf"}, + {file = "protobuf-4.24.0-py3-none-any.whl", hash = "sha256:82e6e9ebdd15b8200e8423676eab38b774624d6a1ad696a60d86a2ac93f18201"}, + {file = "protobuf-4.24.0.tar.gz", hash = "sha256:5d0ceb9de6e08311832169e601d1fc71bd8e8c779f3ee38a97a78554945ecb85"}, +] + [[package]] name = "psutil" version = "5.9.5" description = "Cross-platform lib for process and system monitoring in Python." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2518,6 +2876,7 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" +category = "dev" optional = false python-versions = "*" files = [ @@ -2529,6 +2888,7 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" +category = "dev" optional = false python-versions = "*" files = [ @@ -2539,10 +2899,38 @@ files = [ [package.extras] tests = ["pytest"] +[[package]] +name = "pyasn1" +version = "0.5.0" +description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"}, + {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, +] + +[[package]] +name = "pyasn1-modules" +version = "0.3.0" +description = "A collection of ASN.1-based protocols modules" +category = "main" +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.0" description = "Python style guide checker" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2554,6 +2942,7 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2565,6 +2954,7 @@ files = [ name = "pydantic" version = "1.10.12" description = "Data validation and settings management using python type hints" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2617,6 +3007,7 @@ email = ["email-validator (>=1.0.3)"] name = "pydub" version = "0.25.1" description = "Manipulate audio with an simple and easy high level interface" +category = "dev" optional = false python-versions = "*" files = [ @@ -2628,6 +3019,7 @@ files = [ name = "pyflakes" version = "3.1.0" description = "passive checker of Python programs" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2639,6 +3031,7 @@ files = [ name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2653,6 +3046,7 @@ plugins = ["importlib-metadata"] name = "pyparsing" version = "3.0.9" description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "dev" optional = false python-versions = ">=3.6.8" files = [ @@ -2667,6 +3061,7 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pysocks" version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2679,6 +3074,7 @@ files = [ name = "pytest" version = "7.4.0" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2701,6 +3097,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-asyncio" version = "0.21.1" description = "Pytest support for asyncio" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2719,6 +3116,7 @@ testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -2733,6 +3131,7 @@ six = ">=1.5" name = "python-dotenv" version = "1.0.0" description = "Read key-value pairs from a .env file and set them as environment variables" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2747,6 +3146,7 @@ cli = ["click (>=5.0)"] name = "python-multipart" version = "0.0.6" description = "A streaming multipart parser for Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2761,6 +3161,7 @@ dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatc name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" +category = "dev" optional = false python-versions = "*" files = [ @@ -2772,6 +3173,7 @@ files = [ name = "pyvis" version = "0.3.2" description = "A Python network graph visualization library" +category = "dev" optional = false python-versions = ">3.6" files = [ @@ -2788,6 +3190,7 @@ networkx = ">=1.11" name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2837,6 +3240,7 @@ files = [ name = "referencing" version = "0.30.2" description = "JSON Referencing + Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2852,6 +3256,7 @@ rpds-py = ">=0.7.0" name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2873,6 +3278,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "retrying" version = "1.3.4" description = "Retrying" +category = "dev" optional = false python-versions = "*" files = [ @@ -2887,6 +3293,7 @@ six = ">=1.7.0" name = "rpds-py" version = "0.9.2" description = "Python bindings to Rust's persistent data structures (rpds)" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2989,10 +3396,26 @@ files = [ {file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"}, ] +[[package]] +name = "rsa" +version = "4.9" +description = "Pure-Python RSA implementation" +category = "main" +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.11.2" description = "" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3010,6 +3433,7 @@ urllib3 = {version = ">=1.26,<3", extras = ["socks"]} name = "semantic-version" version = "2.10.0" description = "A library implementing the 'SemVer' scheme." +category = "dev" optional = false python-versions = ">=2.7" files = [ @@ -3025,6 +3449,7 @@ doc = ["Sphinx", "sphinx-rtd-theme"] name = "setuptools" version = "68.1.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3041,6 +3466,7 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -3052,6 +3478,7 @@ files = [ name = "smmap" version = "5.0.0" description = "A pure Python implementation of a sliding window memory map manager" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -3063,6 +3490,7 @@ files = [ name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3074,6 +3502,7 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +category = "dev" optional = false python-versions = "*" files = [ @@ -3085,6 +3514,7 @@ files = [ name = "sqlalchemy" version = "2.0.20" description = "Database Abstraction Library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3132,7 +3562,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""} +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} typing-extensions = ">=4.2.0" [package.extras] @@ -3163,6 +3593,7 @@ sqlcipher = ["sqlcipher3-binary"] name = "stack-data" version = "0.6.2" description = "Extract data from python stack frames and tracebacks for informative displays" +category = "dev" optional = false python-versions = "*" files = [ @@ -3182,6 +3613,7 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "starlette" version = "0.27.0" description = "The little ASGI library that shines." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3199,6 +3631,7 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyam name = "tenacity" version = "8.2.3" description = "Retry code until it succeeds" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3213,6 +3646,7 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3224,6 +3658,7 @@ files = [ name = "toolz" version = "0.12.0" description = "List processing tools and functional utilities" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -3235,6 +3670,7 @@ files = [ name = "tqdm" version = "4.66.1" description = "Fast, Extensible Progress Meter" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3255,6 +3691,7 @@ telegram = ["requests"] name = "traitlets" version = "5.9.0" description = "Traitlets Python configuration system" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3270,6 +3707,7 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] name = "trio" version = "0.22.2" description = "A friendly Python library for async concurrency and I/O" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3290,6 +3728,7 @@ sortedcontainers = "*" name = "trio-websocket" version = "0.10.3" description = "WebSocket library for Trio" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3306,6 +3745,7 @@ wsproto = ">=0.14" name = "types-requests" version = "2.31.0.2" description = "Typing stubs for requests" +category = "dev" optional = false python-versions = "*" files = [ @@ -3320,6 +3760,7 @@ types-urllib3 = "*" name = "types-urllib3" version = "1.26.25.14" description = "Typing stubs for urllib3" +category = "dev" optional = false python-versions = "*" files = [ @@ -3331,6 +3772,7 @@ files = [ name = "typing-extensions" version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3342,6 +3784,7 @@ files = [ name = "tzdata" version = "2023.3" description = "Provider of IANA time zone data" +category = "dev" optional = false python-versions = ">=2" files = [ @@ -3353,6 +3796,7 @@ files = [ name = "uc-micro-py" version = "1.0.2" description = "Micro subset of unicode data files for linkify-it-py projects." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3367,6 +3811,7 @@ test = ["coverage", "pytest", "pytest-cov"] name = "urllib3" version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3387,6 +3832,7 @@ zstd = ["zstandard (>=0.18.0)"] name = "uvicorn" version = "0.23.2" description = "The lightning-fast ASGI server." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -3406,6 +3852,7 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", name = "virtualenv" version = "20.24.3" description = "Virtual Python Environment builder" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3426,6 +3873,7 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "watchdog" version = "3.0.0" description = "Filesystem events monitoring" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3465,6 +3913,7 @@ watchmedo = ["PyYAML (>=3.10)"] name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" +category = "dev" optional = false python-versions = "*" files = [ @@ -3476,6 +3925,7 @@ files = [ name = "websockets" version = "11.0.3" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3555,6 +4005,7 @@ files = [ name = "werkzeug" version = "2.2.3" description = "The comprehensive WSGI web application library." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -3572,6 +4023,7 @@ watchdog = ["watchdog"] name = "wsproto" version = "1.2.0" description = "WebSockets state-machine based protocol implementation" +category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -3586,6 +4038,7 @@ h11 = ">=0.9.0,<1" name = "yarl" version = "1.9.2" description = "Yet another URL library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3672,4 +4125,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "8297a1f79243f2dcaa276ea1c847b1217b5f3f333ee51d664b19325b08128317" +content-hash = "74c858097e6642dd28b70bed5c198022f6efd16d930b722e15912986666a2f07" diff --git a/pyproject.toml b/pyproject.toml index dbe0583f..d3c263a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,10 +10,10 @@ readme = "README.md" python = "^3.10" python-dotenv = "^1.0.0" openai = "^0.27.8" -agent-protocol = "^0.2.2" helicone = "^1.0.6" tenacity = "^8.2.2" sqlalchemy = "^2.0.19" +google-cloud-storage = "^2.10.0" [tool.poetry.group.dev.dependencies] @@ -27,6 +27,7 @@ types-requests = "^2.31.0.2" pytest = "^7.4.0" pytest-asyncio = "^0.21.1" watchdog = "^3.0.0" +mock = "^5.1.0" [tool.poetry.group.ui.dependencies] diff --git a/run b/run index 45822d67..cda72f5c 100755 --- a/run +++ b/run @@ -1,8 +1,8 @@ #!/bin/bash -export PYTHONPATH=$PYTHONPATH:$PWD -poetry install -poetry shell -watchmedo auto-restart -p "*.py" -R python3 -- autogpt/__main__.py "$@" +# poetry install +# poetry shell + +export PYTHONPATH=$PYTHONPATH:$PWD; watchmedo auto-restart -p "*.py" -R python3 -- autogpt/__main__.py "$@" diff --git a/test.py b/test.py deleted file mode 100644 index 82072225..00000000 --- a/test.py +++ /dev/null @@ -1,16 +0,0 @@ -DATABASE_NAME = "agent.db" -import sqlite3 - -# Read all data from database - - -def read_all(): - conn = sqlite3.connect(DATABASE_NAME) - cur = conn.cursor() - cur.execute("SELECT * FROM tasks") - rows = cur.fetchall() - conn.close() - return rows - - -print(read_all())