From 091f76f59b297704df67060bc84c807f9236d6ab Mon Sep 17 00:00:00 2001 From: Patrick Barker Date: Tue, 4 Jun 2024 21:30:55 -0600 Subject: [PATCH] open types --- poetry.lock | 38 ++--- pyproject.toml | 6 +- surfkit/cli/main.py | 203 ++++++++++++++++++------- surfkit/cli/templates/agent.py | 199 +++++------------------- surfkit/cli/templates/agents/surf4v.py | 18 +-- 5 files changed, 214 insertions(+), 250 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2bd7561..83560e5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "agentdesk" -version = "0.2.83" +version = "0.2.84" description = "A desktop for AI agents" optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "agentdesk-0.2.83-py3-none-any.whl", hash = "sha256:b5cac242da1e672f35fc42b20cefa097114bc4d35119bb128823444de78bc2c0"}, - {file = "agentdesk-0.2.83.tar.gz", hash = "sha256:c01064c0f349af88addd3be156dd0b086d7516f4f0cb6e4dd0cf9fe7d6275baf"}, + {file = "agentdesk-0.2.84-py3-none-any.whl", hash = "sha256:86c1dd89b0c6760a4ce9615814f641d9d01c170ec03f0af3996585ad7e088346"}, + {file = "agentdesk-0.2.84.tar.gz", hash = "sha256:b498304e47658b4b36aae806449737088c0ed0b2e4258be864757683d878ddaf"}, ] [package.dependencies] @@ -340,17 +340,17 @@ six = "*" [[package]] name = "boto3" -version = "1.34.115" +version = "1.34.118" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.115-py3-none-any.whl", hash = "sha256:0a580de3d25364da5db26ecc7dde9438ee1be1e529a7c04cc96972b6e2258378"}, - {file = "boto3-1.34.115.tar.gz", hash = "sha256:67f5a6d6e6eff9c15711c265173b53eb4ad8d05b756b76ef33ac792cea7958f6"}, + {file = "boto3-1.34.118-py3-none-any.whl", hash = "sha256:e9edaf979fbe59737e158f2f0f3f0861ff1d61233f18f6be8ebb483905f24587"}, + {file = "boto3-1.34.118.tar.gz", hash = "sha256:4eb8019421cb664a6fcbbee6152aa95a28ce8bbc1c4ee263871c09cdd58bf8ee"}, ] [package.dependencies] -botocore = ">=1.34.115,<1.35.0" +botocore = ">=1.34.118,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -359,13 +359,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "boto3-stubs" -version = "1.34.115" -description = "Type annotations for boto3 1.34.115 generated with mypy-boto3-builder 7.24.0" +version = "1.34.118" +description = "Type annotations for boto3 1.34.118 generated with mypy-boto3-builder 7.24.0" optional = false python-versions = ">=3.8" files = [ - {file = "boto3_stubs-1.34.115-py3-none-any.whl", hash = "sha256:fd06dc6cfb2503fcd4314e63d52eae4889f84e06ff4f92dca4a1f6cae68bfb00"}, - {file = "boto3_stubs-1.34.115.tar.gz", hash = "sha256:1d58dde687903e9b8cd01b2680219ace3981aab72f82165b58bb0a56cff2ce3f"}, + {file = "boto3_stubs-1.34.118-py3-none-any.whl", hash = "sha256:4d1dca9593339791ae403eb5a09f6cf43110599fc147f4429eee4d6043ad2257"}, + {file = "boto3_stubs-1.34.118.tar.gz", hash = "sha256:e28837e42b157b5901818b4b49fe68bece26b17957a9ab10cafecc2373e8c8ba"}, ] [package.dependencies] @@ -417,7 +417,7 @@ bedrock-agent = ["mypy-boto3-bedrock-agent (>=1.34.0,<1.35.0)"] bedrock-agent-runtime = ["mypy-boto3-bedrock-agent-runtime (>=1.34.0,<1.35.0)"] bedrock-runtime = ["mypy-boto3-bedrock-runtime (>=1.34.0,<1.35.0)"] billingconductor = ["mypy-boto3-billingconductor (>=1.34.0,<1.35.0)"] -boto3 = ["boto3 (==1.34.115)", "botocore (==1.34.115)"] +boto3 = ["boto3 (==1.34.118)", "botocore (==1.34.118)"] braket = ["mypy-boto3-braket (>=1.34.0,<1.35.0)"] budgets = ["mypy-boto3-budgets (>=1.34.0,<1.35.0)"] ce = ["mypy-boto3-ce (>=1.34.0,<1.35.0)"] @@ -765,13 +765,13 @@ xray = ["mypy-boto3-xray (>=1.34.0,<1.35.0)"] [[package]] name = "botocore" -version = "1.34.115" +version = "1.34.118" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.115-py3-none-any.whl", hash = "sha256:15b8ad1ee0e9cd57884fb0bcaf3a9551d2552e44a02c2ffb55ec583eebdb888e"}, - {file = "botocore-1.34.115.tar.gz", hash = "sha256:a5d5e28b9c847b17a1ecb7660b46b83d9512b125f671e03e93d14bf6f0b274c2"}, + {file = "botocore-1.34.118-py3-none-any.whl", hash = "sha256:e3f6c5636a4394768e81e33a16f5c6ae7f364f512415d423f9b9dc67fc638df4"}, + {file = "botocore-1.34.118.tar.gz", hash = "sha256:0a3d1ec0186f8b516deb39474de3d226d531f77f92a0f56ad79b80219db3ae9e"}, ] [package.dependencies] @@ -4474,13 +4474,13 @@ widechars = ["wcwidth"] [[package]] name = "taskara" -version = "0.1.96" +version = "0.1.99" description = "Task management for AI agents" optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "taskara-0.1.96-py3-none-any.whl", hash = "sha256:8f66387fcbf79c9285b81937ea5ba8e4ad992e2e8e481b22ff33380e575ea29a"}, - {file = "taskara-0.1.96.tar.gz", hash = "sha256:b983400801b022a83ddf814f45d21c7f6779e9fcb45a79b9cb34c36f67c1a2c3"}, + {file = "taskara-0.1.99-py3-none-any.whl", hash = "sha256:46c827425eed3ef080a040c141d778cb8b0fdaa0f8248cd71d92de57f7dd1d2b"}, + {file = "taskara-0.1.99.tar.gz", hash = "sha256:142a843fed658b017924f3d251d4c6348bb66ebd66c380e407b8d863bd1678a4"}, ] [package.dependencies] @@ -5481,4 +5481,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "7e09a4789cbf292621a3f0b1f174953ccbf5cece36704be600ca8340ca511263" +content-hash = "c6800fc418ae150ddf5fe5226818fe8528dee316fc56b223448f44500c957452" diff --git a/pyproject.toml b/pyproject.toml index 6145fe4..b7e80a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "surfkit" -version = "0.1.195" +version = "0.1.196" description = "A toolkit for building AI agents that use devices" authors = ["Patrick Barker "] license = "MIT" @@ -20,8 +20,8 @@ devicebay = "^0.1.11" litellm = "^1.35.8" tiktoken = "^0.6.0" rich = "^13.7.1" -taskara = "^0.1.96" -agentdesk = "^0.2.83" +agentdesk = "^0.2.84" +taskara = "^0.1.99" [tool.poetry.group.dev.dependencies] diff --git a/surfkit/cli/main.py b/surfkit/cli/main.py index 571c2bf..22a4ed0 100644 --- a/surfkit/cli/main.py +++ b/surfkit/cli/main.py @@ -268,6 +268,89 @@ def create_benchmark( typer.echo(f"Benchmark '{v1_benchmark.name}' created using '{trck.name}' tracker") +@create_group.command("task") +def create_task( + description: str = typer.Option( + ..., "--description", "-d", help="A task description" + ), + assigned_to: Optional[str] = typer.Option( + None, "--assigned-to", "-o", help="Agent to assign the task to" + ), + assigned_type: Optional[str] = typer.Option( + None, "--assigned-type", "-t", help="Agent type to assign the task to" + ), + device: Optional[str] = typer.Option( + None, "--device", "-e", help="Device to give the agent" + ), + device_type: Optional[str] = typer.Option( + None, "--device-type", "-y", help="Device type to give the agen" + ), + max_steps: int = typer.Option( + 30, "--max-steps", "-m", help="Max steps the agent can take" + ), + tracker: Optional[str] = typer.Option( + None, "--tracker", help="Tracker to use. Defaults to the hub." + ), +): + from agentdesk import Desktop + from devicebay import V1DeviceType + from taskara.runtime.base import Tracker + from taskara.task import Task + + from surfkit.config import HUB_API_URL, GlobalConfig + + _device_type = None + if device_type: + _device_type = V1DeviceType(name=device_type) + + _device = None + if device: + desk_vms = Desktop.find(name=device) + if not desk_vms: + typer.echo(f"Desktop '{device}' not found") + raise typer.Exit() + _desk_vm = desk_vms[0] + + _desk = Desktop.from_vm(_desk_vm) + _device = _desk.to_v1() + + if tracker: + from surfkit.util import find_open_port + + trackers = Tracker.find(name=tracker) + if not trackers: + typer.echo(f"Tracker '{tracker}' not found") + raise typer.Exit() + trck = trackers[0] + + local_port = trck.port + if trck.runtime.requires_proxy(): + local_port = find_open_port(9070, 10070) + if not local_port: + raise SystemError("No available ports found") + trck.proxy(local_port=local_port) + _remote_tracker = f"http://localhost:{local_port}" + else: + config = GlobalConfig.read() + if not config.api_key: + raise ValueError( + "No API key found. Please run `surfkit login` first or provide a tracker" + ) + _remote_tracker = HUB_API_URL + + task = Task( + description=description, + assigned_to=assigned_to, + assigned_type=assigned_type, + device=_device, + device_type=_device_type, + max_steps=max_steps, + remote=_remote_tracker, + ) + + typer.echo(f"Task '{task.id}' created") + + @create_group.command("agent") def create_agent( runtime: str = typer.Option( @@ -344,13 +427,11 @@ def create_agent( all_types.extend(types) elif len(type_parts) == 2: try: - config = GlobalConfig.read() - if config.api_key: - types = AgentType.find( - remote=HUB_API_URL, namespace=type_parts[0], name=type_parts[1] - ) - if types: - all_types.extend(types) + types = AgentType.find( + remote=HUB_API_URL, namespace=type_parts[0], name=type_parts[1] + ) + if types: + all_types.extend(types) except Exception as e: logger.debug(f"Failed to load global config: {e}") @@ -692,16 +773,14 @@ def list_evals(): def list_types(): from typing import List - from surfkit.config import HUB_API_URL, GlobalConfig + from surfkit.config import HUB_API_URL from surfkit.types import AgentType all_types: List[AgentType] = [] try: - config = GlobalConfig.read() - if config.api_key: - types = AgentType.find(remote=HUB_API_URL) - all_types.extend(types) + types = AgentType.find(remote=HUB_API_URL) + all_types.extend(types) except Exception as e: pass @@ -1228,7 +1307,7 @@ def publish( headers = {"Authorization": f"Bearer {config.api_key}"} resp = requests.post(url, json=typ.to_v1().model_dump(), headers=headers) resp.raise_for_status() - typer.echo(f"Agent published!") + typer.echo(f"Agent '{typ.name}' published") @app.command(help="Create a new agent repo") @@ -1413,39 +1492,47 @@ def solve( _remote_task_svr = tracker_remote else: - trackers = Tracker.find() - if not trackers: - create = typer.confirm("No trackers found. Would you like to create one?") - if create: - from taskara.runtime.docker import DockerTrackerRuntime + from surfkit.config import HUB_API_URL, GlobalConfig - task_runt = DockerTrackerRuntime() + config = GlobalConfig.read() + if config.api_key: + _remote_task_svr = HUB_API_URL + else: + trackers = Tracker.find() + if not trackers: + create = typer.confirm( + "No trackers found. Would you like to create one?" + ) + if create: + from taskara.runtime.docker import DockerTrackerRuntime - name = get_random_name(sep="-") - if not name: - raise SystemError("Name is required for tracker") + task_runt = DockerTrackerRuntime() - task_svr = task_runt.run(name=name, auth_enabled=auth_enabled) - typer.echo( - f"Tracker '{name}' created using '{task_runt.name()}' runtime" - ) + name = get_random_name(sep="-") + if not name: + raise SystemError("Name is required for tracker") + + task_svr = task_runt.run(name=name, auth_enabled=auth_enabled) + typer.echo( + f"Tracker '{name}' created using '{task_runt.name()}' runtime" + ) + else: + raise ValueError( + "`tracker`, `tracker_runtime`, or `tracker_remote` flag must be provided. Or a tracker must be running" + ) else: - raise ValueError( - "`tracker`, `tracker_runtime`, or `tracker_remote` flag must be provided. Or a tracker must be running" + task_svr = trackers[0] + typer.echo( + f"Using tracker '{task_svr.name}' running on '{task_svr.runtime.name()}'" ) - else: - task_svr = trackers[0] - typer.echo( - f"Using tracker '{task_svr.name}' running on '{task_svr.runtime.name()}'" - ) - local_port = task_svr.port - if task_svr.runtime.requires_proxy(): - local_port = find_open_port(9070, 10070) - if not local_port: - raise SystemError("No available ports found") - task_svr.proxy(local_port=local_port) - _remote_task_svr = f"http://localhost:{local_port}" + local_port = task_svr.port + if task_svr.runtime.requires_proxy(): + local_port = find_open_port(9070, 10070) + if not local_port: + raise SystemError("No available ports found") + task_svr.proxy(local_port=local_port) + _remote_task_svr = f"http://localhost:{local_port}" if not agent_runtime: if agent_file: @@ -1541,28 +1628,27 @@ def solve( all_types: List[AgentType] = [] - types = AgentType.find() - all_types.extend(types) + type_parts = agent_type.split("/") - try: - config = GlobalConfig.read() - if config.api_key: - types = AgentType.find(remote=HUB_API_URL, name=type) - if types: - all_types.extend(types) - except Exception as e: - pass + if len(type_parts) == 1: + types = AgentType.find(name=agent_type) + if types: + all_types.extend(types) + elif len(type_parts) == 2: + try: + config = GlobalConfig.read() + if config.api_key: + types = AgentType.find( + remote=HUB_API_URL, namespace=type_parts[0], name=type_parts[1] + ) + if types: + all_types.extend(types) + except Exception as e: + logger.debug(f"Failed to load global config: {e}") if not all_types: - print("No types found") - return - - types = AgentType.find(name=type) - if types: - all_types.extend(types) + raise ValueError(f"Agent type '{agent_type}' not found") - if not all_types: - raise ValueError(f"Agent type '{type}' not found") typ = all_types[0] if not agent: agent = get_random_name("-") @@ -1636,7 +1722,6 @@ def solve( assigned_to=agent, assigned_type=agent_type, remote=_remote_task_svr, - owner_id="local", ) if _device and view: diff --git a/surfkit/cli/templates/agent.py b/surfkit/cli/templates/agent.py index da95392..9b83d53 100644 --- a/surfkit/cli/templates/agent.py +++ b/surfkit/cli/templates/agent.py @@ -25,25 +25,35 @@ def generate_dockerfile(agent_name: str) -> None: def generate_server(agent_name: str) -> None: out = f""" -import os -from typing import List, Final import logging - -from taskara import Task -from taskara.server.models import V1TaskUpdate, V1Tasks, V1Task -from surfkit.hub import Hub -from surfkit.server.models import V1SolveTask -from surfkit.env import HUB_SERVER_ENV, HUB_API_KEY_ENV -from fastapi import FastAPI, BackgroundTasks, HTTPException -from fastapi.middleware.cors import CORSMiddleware +import os +import sys from contextlib import asynccontextmanager -from tenacity import retry, stop_after_attempt, wait_fixed +from typing import Final + import uvicorn +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from surfkit.server.routes import task_router from .agent import Agent, router -logger: Final = logging.getLogger(__name__) +# Configure logging +logger: Final = logging.getLogger("{pkg_from_name(agent_name)}") logger.setLevel(int(os.getenv("LOG_LEVEL", str(logging.DEBUG)))) +handler = logging.StreamHandler(sys.stdout) +handler.setLevel(logging.INFO) +formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +handler.setFormatter(formatter) + +# Ensure logs are flushed immediately +handler.flush = sys.stdout.flush +logger.addHandler(handler) +logger.propagate = False + +ALLOW_ORIGINS = os.getenv("ALLOW_ORIGINS", "*").split(",") +ALLOW_METHODS = os.getenv("ALLOW_METHODS", "*").split(",") +ALLOW_HEADERS = os.getenv("ALLOW_HEADERS", "*").split(",") @asynccontextmanager @@ -57,163 +67,26 @@ async def lifespan(app: FastAPI): app.add_middleware( CORSMiddleware, - allow_origins=["*"], + allow_origins=ALLOW_ORIGINS, allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], + allow_methods=ALLOW_METHODS, + allow_headers=ALLOW_HEADERS, ) - -@app.get("/") -async def root(): - return {{"message": "Agent in the shell"}} - - -@app.get("/health") -async def health(): - return {{"status": "ok"}} - - -@app.post("/v1/tasks") -async def solve_task(background_tasks: BackgroundTasks, task_model: V1SolveTask): - logger.info(f"solving task: {{task_model.model_dump()}}") - try: - # TODO: we need to find a way to do this earlier but get status back - router.check_model() - except Exception as e: - logger.error( - f"Cannot connect to LLM providers: {{e}} -- did you provide a valid key?" - ) - raise HTTPException( - status_code=500, - detail=f"failed to conect to LLM providers: {{e}} -- did you provide a valid key?", - ) - - background_tasks.add_task(_solve_task, task_model) - logger.info("created background task...") - - -def _solve_task(task_model: V1SolveTask): - task = Task.from_v1(task_model.task, owner_id="local") - if task.remote: - logger.info("connecting to remote task...") - HUB_SERVER = os.environ.get(HUB_SERVER_ENV, "https://surf.agentlabs.xyz") - HUB_API_KEY = os.environ.get(HUB_API_KEY_ENV) - if not HUB_API_KEY: - raise Exception(f"${{HUB_API_KEY_ENV}} not set") - - hub = Hub(HUB_SERVER) - user_info = hub.get_user_info(HUB_API_KEY) - logger.debug(f"got user info: {{user_info.__dict__}}") - - task = get_remote_task( - id=task.id, - owner_id=user_info.email, # type: ignore - server=task.remote, - ) - logger.debug(f"got remote task: {{task.__dict__}}") - - logger.info("Saving remote tasks status to running...") - task.status = "in progress" - task.save() - - if task_model.task.device: - logger.info(f"connecting to device {{task_model.task.device.name}}...") - device = None - for Device in Agent.supported_devices(): - if Device.name() == task_model.task.device.name: - logger.debug(f"found device: {{task_model.task.device.model_dump()}}") - config = Device.connect_config_type()(**task_model.task.device.config) - device = Device.connect(config=config) - - if not device: - raise ValueError( - f"Device {{task_model.task.device.name}} provided in solve task, but not supported by agent" - ) - - logger.debug(f"connected to device: {{device.__dict__}}") - else: - raise ValueError("No device provided") - - logger.info("starting agent...") - if task_model.agent: - config = Agent.config_type().model_validate(task_model.agent.config) - agent = Agent.from_config(config=config) - else: - agent = Agent.default() - - try: - fin_task = agent.solve_task(task=task, device=device, max_steps=task.max_steps) - except Exception as e: - logger.error(f"error running agent: {{e}}") - task.status = "failed" - task.error = str(e) - task.save() - task.post_message("assistant", f"Failed to run task '{{task.description}}': {{e}}") - raise e - if fin_task: - fin_task.save() - - -@app.get("/v1/tasks", response_model=V1Tasks) -async def get_tasks(): - tasks = Task.find() - return V1Tasks(tasks=[task.to_v1() for task in tasks]) - - -@app.get("/v1/tasks/{{id}}", response_model=V1Task) -async def get_task(id: str): - tasks = Task.find(id=id) - if not tasks: - raise Exception(f"Task {{id}} not found") - return tasks[0].to_v1() - - -@app.put("/v1/tasks/{{id}}", response_model=V1Task) -async def put_task(id: str, data: V1TaskUpdate): - tasks = Task.find(id=id) - if not tasks: - raise Exception(f"Task {{id}} not found") - task = tasks[0] - if data.status: - task.status = data.status - task.save() - return task.to_v1() - - -@retry(stop=stop_after_attempt(10), wait=wait_fixed(10)) -def get_remote_task(id: str, owner_id: str, server: str) -> Task: - HUB_API_KEY = os.environ.get(HUB_API_KEY_ENV) - if not HUB_API_KEY: - raise Exception(f"${{HUB_API_KEY_ENV}} not set") - - logger.debug(f"connecting to remote task: {{id}} key: {{HUB_API_KEY}}") - try: - tasks = Task.find( - id=id, - remote=server, - owner_id=owner_id, - ) - if not tasks: - raise Exception(f"Task {{id}} not found") - logger.debug(f"got remote task: {{tasks[0].__dict__}}") - return tasks[0] - except Exception as e: - logger.error(f"error getting remote task: {{e}}") - raise e - +app.include_router(task_router(Agent, router)) if __name__ == "__main__": port = os.getenv("SERVER_PORT", "9090") reload = os.getenv("SERVER_RELOAD", "false") == "true" host = os.getenv("SERVER_HOST", "0.0.0.0") + uvicorn.run( "{pkg_from_name(agent_name)}.server:app", - host="0.0.0.0", + host=host, port=int(port), - reload=True, - # TODO: Figure out what needs to happen here after the ~/.agentsea swapover. - # reload_excludes=["./logs"], + reload=reload, + reload_excludes=[".data"], + log_config=None, ) """ with open(f"{pkg_from_name(agent_name)}/server.py", "w") as f: @@ -262,7 +135,7 @@ def generate_pyproject(agent_name: str, description, git_user_ref: str) -> None: pydantic = "^2.6.3" requests = "^2.31.0" fastapi = {{version = "^0.109", extras = ["all"]}} -surfkit = "^0.1.123" +surfkit = "^0.1.195" [tool.poetry.group.dev.dependencies] @@ -294,6 +167,10 @@ def generate_agentfile( description: "{description}" cmd: "poetry run python -m {pkg_from_name(name)}.server" img_repo: "{image_repo}" +tags: + - "gui" +supports: + - "desktop" versions: latest: "{image_repo}:latest" runtimes: @@ -304,9 +181,10 @@ def generate_agentfile( - "kube" llm_providers: preference: + - "gpt-4o" - "gpt-4-turbo" - "anthropic/claude-3-opus-20240229" -public: False +public: True icon: {icon_url} resource_requests: cpu: "1" @@ -487,6 +365,7 @@ def generate_gitignore() -> None: .data/ cidata.iso +.agentsea """ file_path = Path(".gitignore") diff --git a/surfkit/cli/templates/agents/surf4v.py b/surfkit/cli/templates/agents/surf4v.py index 83444cb..84b219d 100644 --- a/surfkit/cli/templates/agents/surf4v.py +++ b/surfkit/cli/templates/agents/surf4v.py @@ -14,11 +14,11 @@ def template(self, agent_name: str) -> str: import os from devicebay import Device -from agentdesk.device import Desktop +from agentdesk import Desktop from toolfuse.util import AgentUtils from pydantic import BaseModel from surfkit.agent import TaskAgent -from taskara import Task +from taskara import Task, TaskStatus from mllm import Router from skillpacks.server.models import V1ActionSelection from threadmem import RoleThread, RoleMessage @@ -121,7 +121,7 @@ def solve_task( thread, done = self.take_action(device, task, thread) except Exception as e: console.print(f"Error: {{e}}", style="red") - task.status = "failed" + task.status = TaskStatus.FAILED task.error = str(e) task.save() task.post_message("assistant", f"❗ Error taking action: {{e}}") @@ -135,7 +135,7 @@ def solve_task( time.sleep(2) - task.status = "failed" + task.status = TaskStatus.FAILED task.save() task.post_message("assistant", "❗ Max steps reached without solving task") console.print("Reached max steps without solving task", style="red") @@ -166,10 +166,10 @@ def take_action( # Check to see if the task has been cancelled if task.remote: task.refresh() - if task.status == "cancelling" or task.status == "cancelled": + if task.status == TaskStatus.CANCELING or task.status == TaskStatus.CANCELED: console.print(f"task is {{task.status}}", style="red") - if task.status == "cancelling": - task.status = "cancelled" + if task.status == TaskStatus.CANCELING: + task.status = TaskStatus.CANCELED task.save() return thread, True @@ -236,7 +236,7 @@ def take_action( "assistant", f"✅ I think the task is done, please review the result: {{selection.action.parameters['value']}}", ) - task.status = "review" + task.status = TaskStatus.REVIEW task.save() return _thread, True @@ -261,7 +261,7 @@ def take_action( # Record the action for feedback and tuning task.record_action( - prompt=response.prompt_id, + prompt=response.prompt, action=selection.action, tool=desktop.ref(), result=action_response,