From 48ad3eb7af49db083de6bcac7b547c7755ee49e4 Mon Sep 17 00:00:00 2001 From: HamadaSalhab Date: Thu, 3 Oct 2024 00:41:16 +0300 Subject: [PATCH 01/17] Add optional description field to agent tools --- agents-api/agents_api/autogen/Tools.py | 16 ++++++++++++++++ .../models/chat/prepare_chat_context.py | 3 ++- .../models/execution/prepare_execution_input.py | 1 + .../agents_api/models/tools/create_tools.py | 8 +++++--- agents-api/agents_api/models/tools/list_tools.py | 8 +++++++- typespec/tools/models.tsp | 3 +++ 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/agents-api/agents_api/autogen/Tools.py b/agents-api/agents_api/autogen/Tools.py index c2d4199a2..c424b899c 100644 --- a/agents-api/agents_api/autogen/Tools.py +++ b/agents-api/agents_api/autogen/Tools.py @@ -41,6 +41,10 @@ class CreateToolRequest(BaseModel): """ Name of the tool (must be unique for this agent and a valid python identifier string ) """ + description: str | None = None + """ + Description of the tool + """ function: FunctionDef | None = None """ The function to call @@ -191,6 +195,10 @@ class PatchToolRequest(BaseModel): """ Name of the tool (must be unique for this agent and a valid python identifier string ) """ + description: str | None = None + """ + Description of the tool + """ function: FunctionDef | None = None """ The function to call @@ -255,6 +263,10 @@ class Tool(BaseModel): """ Name of the tool (must be unique for this agent and a valid python identifier string ) """ + description: str | None = None + """ + Description of the tool + """ function: FunctionDef | None = None """ The function to call @@ -299,6 +311,10 @@ class UpdateToolRequest(BaseModel): """ Name of the tool (must be unique for this agent and a valid python identifier string ) """ + description: str | None = None + """ + Description of the tool + """ function: FunctionDef | None = None """ The function to call diff --git a/agents-api/agents_api/models/chat/prepare_chat_context.py b/agents-api/agents_api/models/chat/prepare_chat_context.py index 4d521acb0..362cde769 100644 --- a/agents-api/agents_api/models/chat/prepare_chat_context.py +++ b/agents-api/agents_api/models/chat/prepare_chat_context.py @@ -90,12 +90,13 @@ def prepare_chat_context( participant_type: "agent", }, - *tools { agent_id, tool_id, name, type, spec, updated_at, created_at }, + *tools { agent_id, tool_id, name, type, spec, description, updated_at, created_at }, tool = { "id": tool_id, "name": name, "type": type, "spec": spec, + "description": description, "updated_at": updated_at, "created_at": created_at, } diff --git a/agents-api/agents_api/models/execution/prepare_execution_input.py b/agents-api/agents_api/models/execution/prepare_execution_input.py index b763a7508..9aa0774c9 100644 --- a/agents-api/agents_api/models/execution/prepare_execution_input.py +++ b/agents-api/agents_api/models/execution/prepare_execution_input.py @@ -149,6 +149,7 @@ def prepare_execution_input( "name", "type", "spec", + "description", "created_at", "updated_at", ) diff --git a/agents-api/agents_api/models/tools/create_tools.py b/agents-api/agents_api/models/tools/create_tools.py index dd8397797..4119dda93 100644 --- a/agents-api/agents_api/models/tools/create_tools.py +++ b/agents-api/agents_api/models/tools/create_tools.py @@ -64,6 +64,7 @@ def create_tools( str(uuid4()), tool.type, tool.name, + tool.description, getattr(tool, tool.type).dict(), ] for tool in data @@ -85,11 +86,11 @@ def create_tools( # Datalog query for inserting new tool records into the 'agent_functions' relation create_query = """ - input[agent_id, tool_id, type, name, spec] <- $records + input[agent_id, tool_id, type, name, spec, description] <- $records # Do not add duplicate - ?[agent_id, tool_id, type, name, spec] := - input[agent_id, tool_id, type, name, spec], + ?[agent_id, tool_id, type, name, spec, description] := + input[agent_id, tool_id, type, name, spec, description], not *tools{ agent_id: to_uuid(agent_id), type, @@ -102,6 +103,7 @@ def create_tools( type, name, spec, + description, } :returning """ diff --git a/agents-api/agents_api/models/tools/list_tools.py b/agents-api/agents_api/models/tools/list_tools.py index 931ca3ca9..bf94e21de 100644 --- a/agents-api/agents_api/models/tools/list_tools.py +++ b/agents-api/agents_api/models/tools/list_tools.py @@ -30,7 +30,11 @@ @wrap_in_class( Tool, transform=lambda d: { - d["type"]: {**d.pop("spec"), "name": d["name"]}, + d["type"]: { + **d.pop("spec"), + "name": d["name"], + "description": d("description"), + }, **d, }, ) @@ -58,6 +62,7 @@ def list_tools( name, type, spec, + description, updated_at, created_at, ] := input[agent_id], @@ -67,6 +72,7 @@ def list_tools( name, type, spec, + description, updated_at, created_at, }} diff --git a/typespec/tools/models.tsp b/typespec/tools/models.tsp index be0fb4f68..196d36a6a 100644 --- a/typespec/tools/models.tsp +++ b/typespec/tools/models.tsp @@ -80,6 +80,9 @@ model Tool { /** Name of the tool (must be unique for this agent and a valid python identifier string )*/ name: validPythonIdentifier; + /** Description of the tool */ + description?: string; + /** The function to call */ function?: FunctionDef; integration?: IntegrationDef; From 5339101344ca186a1c3b234a04e02c260a100d32 Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Wed, 2 Oct 2024 19:09:55 -0400 Subject: [PATCH 02/17] feat(typespec): Add API call tool definition type Signed-off-by: Diwank Singh Tomer --- agents-api/agents_api/autogen/Tools.py | 151 ++++++++++++++++++++++++- typespec/common/scalars.tsp | 3 + typespec/tools/models.tsp | 54 +++++++-- 3 files changed, 197 insertions(+), 11 deletions(-) diff --git a/agents-api/agents_api/autogen/Tools.py b/agents-api/agents_api/autogen/Tools.py index c424b899c..cc2b6eddd 100644 --- a/agents-api/agents_api/autogen/Tools.py +++ b/agents-api/agents_api/autogen/Tools.py @@ -6,7 +6,114 @@ from typing import Annotated, Any, Literal from uuid import UUID -from pydantic import AwareDatetime, BaseModel, ConfigDict, Field +from pydantic import AnyUrl, AwareDatetime, BaseModel, ConfigDict, Field, StrictBool + + +class ApiCallDef(BaseModel): + """ + API call definition + """ + + model_config = ConfigDict( + populate_by_name=True, + ) + method: Literal[ + "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "CONNECT", "TRACE" + ] + """ + The HTTP method to use + """ + url: AnyUrl + """ + The URL to call + """ + headers: dict[str, str] | None = None + """ + The headers to send with the request + """ + content: str | None = None + """ + The content as base64 to send with the request + """ + data: dict[str, str] | None = None + """ + The data to send as form data + """ + json_: Annotated[dict[str, Any] | None, Field(None, alias="json")] + """ + JSON body to send with the request + """ + cookies: dict[str, str] | None = None + """ + Cookies + """ + params: str | dict[str, Any] | None = None + """ + The parameters to send with the request + """ + follow_redirects: StrictBool | None = None + """ + Follow redirects + """ + + +class ApiCallDefUpdate(BaseModel): + """ + API call definition + """ + + model_config = ConfigDict( + populate_by_name=True, + ) + method: ( + Literal[ + "GET", + "POST", + "PUT", + "DELETE", + "PATCH", + "HEAD", + "OPTIONS", + "CONNECT", + "TRACE", + ] + | None + ) = None + """ + The HTTP method to use + """ + url: AnyUrl | None = None + """ + The URL to call + """ + headers: dict[str, str] | None = None + """ + The headers to send with the request + """ + content: str | None = None + """ + The content as base64 to send with the request + """ + data: dict[str, str] | None = None + """ + The data to send as form data + """ + json_: Annotated[dict[str, Any] | None, Field(None, alias="json")] + """ + JSON body to send with the request + """ + cookies: dict[str, str] | None = None + """ + Cookies + """ + params: str | dict[str, Any] | None = None + """ + The parameters to send with the request + """ + follow_redirects: StrictBool | None = None + """ + Follow redirects + """ class ChosenToolCall(BaseModel): @@ -50,7 +157,17 @@ class CreateToolRequest(BaseModel): The function to call """ integration: IntegrationDef | None = None + """ + The integration to call + """ system: SystemDef | None = None + """ + The system to call + """ + api_call: ApiCallDef | None = None + """ + The API call to make + """ class FunctionCallOption(BaseModel): @@ -174,7 +291,7 @@ class NamedToolChoice(BaseModel): ) type: Literal["function", "integration", "system", "api_call"] """ - Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) + Whether this tool is a `function` """ function: FunctionCallOption | None = None @@ -204,7 +321,17 @@ class PatchToolRequest(BaseModel): The function to call """ integration: IntegrationDefUpdate | None = None + """ + The integration to call + """ system: SystemDefUpdate | None = None + """ + The system to call + """ + api_call: ApiCallDefUpdate | None = None + """ + The API call to make + """ class SystemDef(BaseModel): @@ -272,7 +399,17 @@ class Tool(BaseModel): The function to call """ integration: IntegrationDef | None = None + """ + The integration to call + """ system: SystemDef | None = None + """ + The system to call + """ + api_call: ApiCallDef | None = None + """ + The API call to make + """ created_at: Annotated[AwareDatetime, Field(json_schema_extra={"readOnly": True})] """ When this resource was created as UTC date-time @@ -320,7 +457,17 @@ class UpdateToolRequest(BaseModel): The function to call """ integration: IntegrationDef | None = None + """ + The integration to call + """ system: SystemDef | None = None + """ + The system to call + """ + api_call: ApiCallDef | None = None + """ + The API call to make + """ class ChosenFunctionCall(ChosenToolCall): diff --git a/typespec/common/scalars.tsp b/typespec/common/scalars.tsp index 76ccef2d3..8dc07cbbc 100644 --- a/typespec/common/scalars.tsp +++ b/typespec/common/scalars.tsp @@ -69,3 +69,6 @@ alias integrationProvider = ( // | "webpage" // | "requests" ); + +/** A valid HTTP method */ +alias httpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | "CONNECT" | "TRACE"; diff --git a/typespec/tools/models.tsp b/typespec/tools/models.tsp index 196d36a6a..75838e6b4 100644 --- a/typespec/tools/models.tsp +++ b/typespec/tools/models.tsp @@ -72,7 +72,37 @@ model SystemDef { arguments?: FunctionParameters; } -// TODO: We should use this model for all tools, not just functions and discriminate on the type +/** API call definition */ +model ApiCallDef { + /** The HTTP method to use */ + method: httpMethod; + + /** The URL to call */ + url: url; + + /** The headers to send with the request */ + headers?: Record; + + /** The content as base64 to send with the request */ + content?: string; + + /** The data to send as form data */ + data?: Record; + + /** JSON body to send with the request */ + json?: Record; + + /** Cookies */ + cookies?: Record; + + /** The parameters to send with the request */ + params?: string | Record; + + /** Follow redirects */ + follow_redirects?: boolean; +} + + model Tool { /** Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) */ type: ToolType = ToolType.function; @@ -85,9 +115,15 @@ model Tool { /** The function to call */ function?: FunctionDef; + + /** The integration to call */ integration?: IntegrationDef; + + /** The system to call */ system?: SystemDef; - api_call?: never; // TODO: Implement + + /** The API call to make */ + api_call?: ApiCallDef; ...HasTimestamps; ...HasId; @@ -100,13 +136,13 @@ model FunctionCallOption { @discriminator("type") model NamedToolChoice { - /** Whether this tool is a `function`, `api_call`, `system` etc. (Only `function` tool supported right now) */ + /** Whether this tool is a `function` */ type: ToolType; function?: FunctionCallOption; - integration?: never; // TODO: Implement - system?: never; // TODO: Implement - api_call?: never; // TODO: Implement + integration?: never; + system?: never; + api_call?: never; } model NamedFunctionChoice extends NamedToolChoice { @@ -145,9 +181,9 @@ model ChosenToolCall { type: ToolType; function?: FunctionCallOption; - integration?: never; // TODO: Implement - system?: never; // TODO: Implement - api_call?: never; // TODO: Implement + integration?: never; + system?: never; + api_call?: never; ...HasId; } From e2be3a67cf77e7248890223112643967e5276ecb Mon Sep 17 00:00:00 2001 From: HamadaSalhab Date: Thu, 3 Oct 2024 02:16:52 +0300 Subject: [PATCH 03/17] bug fix --- agents-api/agents_api/models/tools/list_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents-api/agents_api/models/tools/list_tools.py b/agents-api/agents_api/models/tools/list_tools.py index bf94e21de..727bf8028 100644 --- a/agents-api/agents_api/models/tools/list_tools.py +++ b/agents-api/agents_api/models/tools/list_tools.py @@ -33,7 +33,7 @@ d["type"]: { **d.pop("spec"), "name": d["name"], - "description": d("description"), + "description": d["description"], }, **d, }, From 1c1cdf910688dc4179f392f2ae43346ad4bf4048 Mon Sep 17 00:00:00 2001 From: HamadaSalhab Date: Thu, 3 Oct 2024 02:53:25 +0300 Subject: [PATCH 04/17] Remove description field from SystemDef & IntegrationDef --- agents-api/agents_api/autogen/Tools.py | 16 ---------------- typespec/tools/models.tsp | 6 ------ 2 files changed, 22 deletions(-) diff --git a/agents-api/agents_api/autogen/Tools.py b/agents-api/agents_api/autogen/Tools.py index cc2b6eddd..58322c0b1 100644 --- a/agents-api/agents_api/autogen/Tools.py +++ b/agents-api/agents_api/autogen/Tools.py @@ -229,10 +229,6 @@ class IntegrationDef(BaseModel): """ The specific method of the integration to call """ - description: str | None = None - """ - Optional description of the integration - """ setup: dict[str, Any] | None = None """ The setup parameters the integration accepts @@ -271,10 +267,6 @@ class IntegrationDefUpdate(BaseModel): """ The specific method of the integration to call """ - description: str | None = None - """ - Optional description of the integration - """ setup: dict[str, Any] | None = None """ The setup parameters the integration accepts @@ -346,10 +338,6 @@ class SystemDef(BaseModel): """ The name of the system call """ - description: str | None = None - """ - Optional description of the system call - """ arguments: dict[str, Any] | None = None """ The arguments to pre-apply to the system call @@ -368,10 +356,6 @@ class SystemDefUpdate(BaseModel): """ The name of the system call """ - description: str | None = None - """ - Optional description of the system call - """ arguments: dict[str, Any] | None = None """ The arguments to pre-apply to the system call diff --git a/typespec/tools/models.tsp b/typespec/tools/models.tsp index 75838e6b4..7b3b79593 100644 --- a/typespec/tools/models.tsp +++ b/typespec/tools/models.tsp @@ -50,9 +50,6 @@ model IntegrationDef { /** The specific method of the integration to call */ method?: string; - /** Optional description of the integration */ - description?: string; - /** The setup parameters the integration accepts */ setup?: FunctionParameters; @@ -65,9 +62,6 @@ model SystemDef { /** The name of the system call */ call: string; - /** Optional description of the system call */ - description?: string; - /** The arguments to pre-apply to the system call */ arguments?: FunctionParameters; } From 9df45afdb161fe7d409506ba9c235e0dad88a1fd Mon Sep 17 00:00:00 2001 From: HamadaSalhab Date: Thu, 3 Oct 2024 02:54:57 +0300 Subject: [PATCH 05/17] bug fix wip --- agents-api/agents_api/models/tools/create_tools.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/agents-api/agents_api/models/tools/create_tools.py b/agents-api/agents_api/models/tools/create_tools.py index 4119dda93..e5b92a045 100644 --- a/agents-api/agents_api/models/tools/create_tools.py +++ b/agents-api/agents_api/models/tools/create_tools.py @@ -64,27 +64,29 @@ def create_tools( str(uuid4()), tool.type, tool.name, - tool.description, + tool.description if hasattr(tool, "description") else None, getattr(tool, tool.type).dict(), ] for tool in data ] ensure_tool_name_unique_query = """ - input[agent_id, tool_id, type, name, spec] <- $records + input[agent_id, tool_id, type, name, spec, description] <- $records ?[tool_id] := - input[agent_id, _, type, name, _], + input[agent_id, _, type, name, _, _], *tools{ agent_id: to_uuid(agent_id), tool_id, type, name, + spec, + description, } :assert none """ - # Datalog query for inserting new tool records into the 'agent_functions' relation + # Datalog query for inserting new tool records into the 'tools' relation create_query = """ input[agent_id, tool_id, type, name, spec, description] <- $records From a7e37491926838f2db55ed67d510e462b3a74087 Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Wed, 2 Oct 2024 22:34:25 -0400 Subject: [PATCH 06/17] feat(agents-api): Add migration for adding description to the tools relation Signed-off-by: Diwank Singh Tomer --- ...ate_1727922523_add_description_to_tools.py | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 agents-api/migrations/migrate_1727922523_add_description_to_tools.py diff --git a/agents-api/migrations/migrate_1727922523_add_description_to_tools.py b/agents-api/migrations/migrate_1727922523_add_description_to_tools.py new file mode 100644 index 000000000..ce15b9e15 --- /dev/null +++ b/agents-api/migrations/migrate_1727922523_add_description_to_tools.py @@ -0,0 +1,64 @@ +#/usr/bin/env python3 + +MIGRATION_ID = "add_description_to_tools" +CREATED_AT = 1727922523.283493 + + +add_description_to_tools = dict( + up=""" + ?[agent_id, tool_id, type, name, description, spec, updated_at, created_at] := *tools { + agent_id, tool_id, type, name, spec, updated_at, created_at + }, description = null + + :replace tools { + agent_id: Uuid, + tool_id: Uuid, + => + type: String, + name: String, + description: String?, + spec: Json, + + updated_at: Float default now(), + created_at: Float default now(), + } + """, + down=""" + ?[agent_id, tool_id, type, name, spec, updated_at, created_at] := *tools { + agent_id, tool_id, type, name, spec, updated_at, created_at + } + + :replace tools { + agent_id: Uuid, + tool_id: Uuid, + => + type: String, + name: String, + spec: Json, + + updated_at: Float default now(), + created_at: Float default now(), + } + """, +) + + +queries_to_run = [ + add_description_to_tools, +] + + +def run(client, *queries): + joiner = "}\n\n{" + + query = joiner.join(queries) + query = f"{{\n{query}\n}}" + client.run(query) + + +def up(client): + run(client, *[q["up"] for q in queries_to_run]) + + +def down(client): + run(client, *[q["down"] for q in reversed(queries_to_run)]) From b52a0b77cf8048275d3be4c89eec6efcd1f46cd7 Mon Sep 17 00:00:00 2001 From: HamadaSalhab Date: Thu, 3 Oct 2024 12:33:48 +0300 Subject: [PATCH 07/17] fix(agents-api): Fix create tool bug --- .../agents_api/models/tools/create_tools.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/agents-api/agents_api/models/tools/create_tools.py b/agents-api/agents_api/models/tools/create_tools.py index e5b92a045..1ca501bc6 100644 --- a/agents-api/agents_api/models/tools/create_tools.py +++ b/agents-api/agents_api/models/tools/create_tools.py @@ -22,13 +22,13 @@ T = TypeVar("T") -@rewrap_exceptions( - { - QueryException: partialclass(HTTPException, status_code=400), - ValidationError: partialclass(HTTPException, status_code=400), - TypeError: partialclass(HTTPException, status_code=400), - } -) +# @rewrap_exceptions( +# { +# QueryException: partialclass(HTTPException, status_code=400), +# ValidationError: partialclass(HTTPException, status_code=400), +# TypeError: partialclass(HTTPException, status_code=400), +# } +# ) @wrap_in_class( Tool, transform=lambda d: { @@ -38,7 +38,7 @@ }, _kind="inserted", ) -@cozo_query +@cozo_query(debug=True) @beartype def create_tools( *, @@ -64,8 +64,8 @@ def create_tools( str(uuid4()), tool.type, tool.name, - tool.description if hasattr(tool, "description") else None, getattr(tool, tool.type).dict(), + tool.description if hasattr(tool, "description") else None, ] for tool in data ] From fa3acf344abc3766b52a8599f1af3daae68b3a43 Mon Sep 17 00:00:00 2001 From: HamadaSalhab Date: Thu, 3 Oct 2024 21:11:01 +0300 Subject: [PATCH 08/17] Remove debug changes --- .../agents_api/models/tools/create_tools.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/agents-api/agents_api/models/tools/create_tools.py b/agents-api/agents_api/models/tools/create_tools.py index 1ca501bc6..9ce7d4d8b 100644 --- a/agents-api/agents_api/models/tools/create_tools.py +++ b/agents-api/agents_api/models/tools/create_tools.py @@ -22,13 +22,13 @@ T = TypeVar("T") -# @rewrap_exceptions( -# { -# QueryException: partialclass(HTTPException, status_code=400), -# ValidationError: partialclass(HTTPException, status_code=400), -# TypeError: partialclass(HTTPException, status_code=400), -# } -# ) +@rewrap_exceptions( + { + QueryException: partialclass(HTTPException, status_code=400), + ValidationError: partialclass(HTTPException, status_code=400), + TypeError: partialclass(HTTPException, status_code=400), + } +) @wrap_in_class( Tool, transform=lambda d: { @@ -38,7 +38,7 @@ }, _kind="inserted", ) -@cozo_query(debug=True) +@cozo_query @beartype def create_tools( *, From 3b33038e5f9a64d37fb2296d1c4de7bcd3fff4a7 Mon Sep 17 00:00:00 2001 From: vedantsahai18 Date: Thu, 3 Oct 2024 16:19:57 -0400 Subject: [PATCH 09/17] feat: added execute_api_call activity and support for api tool type --- .../activities/excecute_api_call.py | 63 +++++++++++++++++++ .../workflows/task_execution/__init__.py | 39 ++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 agents-api/agents_api/activities/excecute_api_call.py diff --git a/agents-api/agents_api/activities/excecute_api_call.py b/agents-api/agents_api/activities/excecute_api_call.py new file mode 100644 index 000000000..f0b6f5250 --- /dev/null +++ b/agents-api/agents_api/activities/excecute_api_call.py @@ -0,0 +1,63 @@ +from typing import Any, Annotated, Field, Optional, Union +import httpx +from beartype import beartype +from temporalio import activity + +from ..autogen.openapi_model import ApiCallDef +# from ..clients import integrations +from ..common.protocol.tasks import StepContext +from ..env import testing +# from ..models.tools import get_tool_args_from_metadata +from pydantic import Field + + +@beartype +async def execute_api_call( + context: StepContext, + tool_name: str, + api_call: ApiCallDef, + content: Optional[str] = None, + data: Optional[dict[str, Any]] = None, + json_: Annotated[Optional[dict[str, Any]], Field(None, alias="json")] = None, + cookies: Optional[dict[str, str]] = None, + params: Optional[Union[str, dict[str, Any]]] = None, +) -> Any: + developer_id = context.execution_input.developer_id + agent_id = context.execution_input.agent.id + task_id = context.execution_input.task.id + + # TODO: Implement get_tool_args_from_metadata to get the arguments and setup for the api call + # merged_tool_setup = get_tool_args_from_metadata( + # developer_id=developer_id, agent_id=agent_id, task_id=task_id, arg_type="setup" + # ) + + # arguments = ( + # merged_tool_args.get(tool_name, {}) | (integration.arguments or {}) | arguments + # ) + + + try: + return await httpx.request( + method=api_call.method, + url=api_call.url, + headers=api_call.headers, + content=content, + data=data, + json=json_, + cookies=cookies, + params=params, + follow_redirects=api_call.follow_redirects, + ) + + except BaseException as e: + if activity.in_activity(): + activity.logger.error(f"Error in execute_api_call: {e}") + + raise + + +mock_execute_api_call = execute_api_call + +execute_api_call = activity.defn(name="execute_api_call")( + execute_api_call if not testing else mock_execute_api_call +) diff --git a/agents-api/agents_api/workflows/task_execution/__init__.py b/agents-api/agents_api/workflows/task_execution/__init__.py index 2ca7e6ade..e8ba3a2bc 100644 --- a/agents-api/agents_api/workflows/task_execution/__init__.py +++ b/agents-api/agents_api/workflows/task_execution/__init__.py @@ -12,6 +12,7 @@ with workflow.unsafe.imports_passed_through(): from ...activities import task_steps from ...activities.execute_integration import execute_integration + from ...activities.excecute_api_call import execute_api_call from ...autogen.openapi_model import ( EmbedStep, ErrorWorkflowStep, @@ -21,6 +22,7 @@ GetStep, IfElseWorkflowStep, IntegrationDef, + ApiCallDef, LogStep, MapReduceStep, ParallelStep, @@ -505,6 +507,43 @@ async def run( state = PartialTransition(output=tool_call_response) + case ToolCallStep(), StepOutcome(output=tool_call) if tool_call[ + "type" + ] == "api_call": + call = tool_call["api_call"] + tool_name = call["name"] + # arguments = call["arguments"] + apicall_spec = next( + (t for t in context.tools if t.name == tool_name), None + ) + + if apicall_spec is None: + raise ApplicationError(f"Integration {tool_name} not found") + + api_call = ApiCallDef( + method=apicall_spec.spec["method"], + url=apicall_spec.spec["url"], + headers=apicall_spec.spec["headers"], + follow_redirects=apicall_spec.spec["follow_redirects"], + ) + + # Extract the optional arguments for `content`, `data`, `json`, `cookies`, and `params` + content = call["content"] + data = call["data"] + json_ = call["json"] + cookies = call["cookies"] + params = call["params"] + + # Execute the API call using the `execute_api_call` function + tool_call_response = await workflow.execute_activity( + execute_api_call, + args=[context, tool_name, api_call, content, data, json_, cookies, params], + schedule_to_close_timeout=timedelta(seconds=30 if debug or testing else 600), + ) + + state = PartialTransition(output=tool_call_response) + + case ToolCallStep(), StepOutcome(output=_): # FIXME: Handle system/api_call tool_calls raise ApplicationError("Not implemented") From 3f2c06fb47066860aedcd4850ace5338ba2aee2f Mon Sep 17 00:00:00 2001 From: vedantsahai18 Date: Thu, 3 Oct 2024 16:54:03 -0400 Subject: [PATCH 10/17] fix: fixed dep errors --- .../activities/excecute_api_call.py | 8 +++++--- .../workflows/task_execution/__init__.py | 20 ++++++++++++++----- ...ate_1727922523_add_description_to_tools.py | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/agents-api/agents_api/activities/excecute_api_call.py b/agents-api/agents_api/activities/excecute_api_call.py index f0b6f5250..7259ac021 100644 --- a/agents-api/agents_api/activities/excecute_api_call.py +++ b/agents-api/agents_api/activities/excecute_api_call.py @@ -1,14 +1,17 @@ -from typing import Any, Annotated, Field, Optional, Union +from typing import Annotated, Any, Optional, Union + import httpx from beartype import beartype +from pydantic import Field from temporalio import activity from ..autogen.openapi_model import ApiCallDef + # from ..clients import integrations from ..common.protocol.tasks import StepContext from ..env import testing + # from ..models.tools import get_tool_args_from_metadata -from pydantic import Field @beartype @@ -35,7 +38,6 @@ async def execute_api_call( # merged_tool_args.get(tool_name, {}) | (integration.arguments or {}) | arguments # ) - try: return await httpx.request( method=api_call.method, diff --git a/agents-api/agents_api/workflows/task_execution/__init__.py b/agents-api/agents_api/workflows/task_execution/__init__.py index e8ba3a2bc..fce61cbd7 100644 --- a/agents-api/agents_api/workflows/task_execution/__init__.py +++ b/agents-api/agents_api/workflows/task_execution/__init__.py @@ -11,9 +11,10 @@ # Import necessary modules and types with workflow.unsafe.imports_passed_through(): from ...activities import task_steps - from ...activities.execute_integration import execute_integration from ...activities.excecute_api_call import execute_api_call + from ...activities.execute_integration import execute_integration from ...autogen.openapi_model import ( + ApiCallDef, EmbedStep, ErrorWorkflowStep, EvaluateStep, @@ -22,7 +23,6 @@ GetStep, IfElseWorkflowStep, IntegrationDef, - ApiCallDef, LogStep, MapReduceStep, ParallelStep, @@ -537,13 +537,23 @@ async def run( # Execute the API call using the `execute_api_call` function tool_call_response = await workflow.execute_activity( execute_api_call, - args=[context, tool_name, api_call, content, data, json_, cookies, params], - schedule_to_close_timeout=timedelta(seconds=30 if debug or testing else 600), + args=[ + context, + tool_name, + api_call, + content, + data, + json_, + cookies, + params, + ], + schedule_to_close_timeout=timedelta( + seconds=30 if debug or testing else 600 + ), ) state = PartialTransition(output=tool_call_response) - case ToolCallStep(), StepOutcome(output=_): # FIXME: Handle system/api_call tool_calls raise ApplicationError("Not implemented") diff --git a/agents-api/migrations/migrate_1727922523_add_description_to_tools.py b/agents-api/migrations/migrate_1727922523_add_description_to_tools.py index ce15b9e15..1d6724090 100644 --- a/agents-api/migrations/migrate_1727922523_add_description_to_tools.py +++ b/agents-api/migrations/migrate_1727922523_add_description_to_tools.py @@ -1,4 +1,4 @@ -#/usr/bin/env python3 +# /usr/bin/env python3 MIGRATION_ID = "add_description_to_tools" CREATED_AT = 1727922523.283493 From e4a654a904fab1e950cb8fae54ef5216dc66b394 Mon Sep 17 00:00:00 2001 From: vedantsahai18 Date: Thu, 3 Oct 2024 17:17:14 -0400 Subject: [PATCH 11/17] fix: create agent router bug fixed --- agents-api/agents_api/routers/agents/create_agent.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agents-api/agents_api/routers/agents/create_agent.py b/agents-api/agents_api/routers/agents/create_agent.py index a662bef15..06e8f17cd 100644 --- a/agents-api/agents_api/routers/agents/create_agent.py +++ b/agents-api/agents_api/routers/agents/create_agent.py @@ -4,7 +4,7 @@ from fastapi import Depends from starlette.status import HTTP_201_CREATED -import agents_api.models as models +from ...models.agent.create_agent import create_agent as create_agent_query from ...autogen.openapi_model import ( CreateAgentRequest, @@ -20,7 +20,7 @@ async def create_agent( data: CreateAgentRequest, ) -> ResourceCreatedResponse: # TODO: Validate model name - agent = models.agent.create_agent( + agent = create_agent_query( developer_id=x_developer_id, data=data, ) From a6cb382fad437a029ad3ed53feb2612d057e25f9 Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Thu, 3 Oct 2024 17:38:50 -0400 Subject: [PATCH 12/17] feat(agents-api): Add tests for the new api call tool type Signed-off-by: Diwank Singh Tomer --- .../models/task/create_or_update_task.py | 2 +- .../agents_api/models/task/create_task.py | 2 +- .../agents_api/routers/agents/create_agent.py | 3 +- agents-api/tests/test_execution_workflow.py | 57 +++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/agents-api/agents_api/models/task/create_or_update_task.py b/agents-api/agents_api/models/task/create_or_update_task.py index af7e258d9..702e505ad 100644 --- a/agents-api/agents_api/models/task/create_or_update_task.py +++ b/agents-api/agents_api/models/task/create_or_update_task.py @@ -64,7 +64,7 @@ def create_or_update_task( data.metadata = data.metadata or {} data.input_schema = data.input_schema or {} - task_data = task_to_spec(data).model_dump(exclude_none=True, exclude_unset=True) + task_data = task_to_spec(data).model_dump(exclude_none=True, exclude_unset=True, mode="json") task_data.pop("task_id", None) task_data["created_at"] = utcnow().timestamp() diff --git a/agents-api/agents_api/models/task/create_task.py b/agents-api/agents_api/models/task/create_task.py index a44146c34..9affe0ead 100644 --- a/agents-api/agents_api/models/task/create_task.py +++ b/agents-api/agents_api/models/task/create_task.py @@ -55,7 +55,7 @@ def create_task( # Prepares the update data by filtering out None values and adding user_id and developer_id. columns, values = cozo_process_mutate_data( { - **task_spec.model_dump(exclude_none=True, exclude_unset=True), + **task_spec.model_dump(exclude_none=True, exclude_unset=True, mode="json"), "task_id": str(task_id), "agent_id": str(agent_id), } diff --git a/agents-api/agents_api/routers/agents/create_agent.py b/agents-api/agents_api/routers/agents/create_agent.py index 06e8f17cd..2e1c4df0a 100644 --- a/agents-api/agents_api/routers/agents/create_agent.py +++ b/agents-api/agents_api/routers/agents/create_agent.py @@ -4,13 +4,12 @@ from fastapi import Depends from starlette.status import HTTP_201_CREATED -from ...models.agent.create_agent import create_agent as create_agent_query - from ...autogen.openapi_model import ( CreateAgentRequest, ResourceCreatedResponse, ) from ...dependencies.developer_id import get_developer_id +from ...models.agent.create_agent import create_agent as create_agent_query from .router import router diff --git a/agents-api/tests/test_execution_workflow.py b/agents-api/tests/test_execution_workflow.py index b6394f1bc..42ca4cd78 100644 --- a/agents-api/tests/test_execution_workflow.py +++ b/agents-api/tests/test_execution_workflow.py @@ -441,6 +441,63 @@ async def _( assert result["hello"] == data.input["test"] +@test("workflow: tool call api_call") +async def _( + client=cozo_client, + developer_id=test_developer_id, + agent=test_agent, +): + data = CreateExecutionRequest(input={"test": "input"}) + + task = create_task( + developer_id=developer_id, + agent_id=agent.id, + data=CreateTaskRequest( + **{ + "name": "test task", + "description": "test task about", + "input_schema": {"type": "object", "additionalProperties": True}, + "tools": [ + { + "type": "api_call", + "name": "hello", + "api_call": { + "method": "GET", + "url": "https://httpbin.org/get", + }, + } + ], + "main": [ + { + "tool": "hello", + "params": {"test": "_.test"}, + }, + { + "evaluate": {"hello": "_.json()['args']['test']"}, + } + ], + } + ), + client=client, + ) + + async with patch_testing_temporal() as (_, mock_run_task_execution_workflow): + execution, handle = await start_execution( + developer_id=developer_id, + task_id=task.id, + data=data, + client=client, + ) + + assert handle is not None + assert execution.task_id == task.id + assert execution.input == data.input + mock_run_task_execution_workflow.assert_called_once() + + result = await handle.result() + assert result["hello"] == data.input["test"] + + @test("workflow: tool call integration dummy") async def _( client=cozo_client, From 040d7742e8bf4d6d62591b5e684c24d9817729b9 Mon Sep 17 00:00:00 2001 From: vedantsahai18 Date: Thu, 3 Oct 2024 18:32:33 -0400 Subject: [PATCH 13/17] fix(agent-api): bug in the api_call tool --- .../agents_api/activities/excecute_api_call.py | 13 +++++++++++-- agents-api/agents_api/worker/worker.py | 2 ++ .../agents_api/workflows/task_execution/__init__.py | 10 +++++----- agents-api/tests/test_execution_workflow.py | 2 +- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/agents-api/agents_api/activities/excecute_api_call.py b/agents-api/agents_api/activities/excecute_api_call.py index 7259ac021..fbc09316e 100644 --- a/agents-api/agents_api/activities/excecute_api_call.py +++ b/agents-api/agents_api/activities/excecute_api_call.py @@ -39,9 +39,9 @@ async def execute_api_call( # ) try: - return await httpx.request( + response = httpx.request( method=api_call.method, - url=api_call.url, + url=str(api_call.url), headers=api_call.headers, content=content, data=data, @@ -51,6 +51,15 @@ async def execute_api_call( follow_redirects=api_call.follow_redirects, ) + response_dict = { + "status_code": response.status_code, + # "headers": response.headers, + # "content": response.content, + "json": response.json(), + } + + return response_dict + except BaseException as e: if activity.in_activity(): activity.logger.error(f"Error in execute_api_call: {e}") diff --git a/agents-api/agents_api/worker/worker.py b/agents-api/agents_api/worker/worker.py index 77698364d..eb0a69154 100644 --- a/agents-api/agents_api/worker/worker.py +++ b/agents-api/agents_api/worker/worker.py @@ -16,6 +16,7 @@ def create_worker(client: Client) -> Any: from ..activities.demo import demo_activity from ..activities.embed_docs import embed_docs from ..activities.execute_integration import execute_integration + from ..activities. excecute_api_call import execute_api_call from ..activities.mem_mgmt import mem_mgmt from ..activities.mem_rating import mem_rating from ..activities.summarization import summarization @@ -52,6 +53,7 @@ def create_worker(client: Client) -> Any: demo_activity, embed_docs, execute_integration, + execute_api_call, mem_mgmt, mem_rating, summarization, diff --git a/agents-api/agents_api/workflows/task_execution/__init__.py b/agents-api/agents_api/workflows/task_execution/__init__.py index fce61cbd7..2b20af26a 100644 --- a/agents-api/agents_api/workflows/task_execution/__init__.py +++ b/agents-api/agents_api/workflows/task_execution/__init__.py @@ -528,11 +528,11 @@ async def run( ) # Extract the optional arguments for `content`, `data`, `json`, `cookies`, and `params` - content = call["content"] - data = call["data"] - json_ = call["json"] - cookies = call["cookies"] - params = call["params"] + content = call.get("content", None) + data = call.get("data", None) + json_ = call.get("json", None) + cookies = call.get("cookies", None) + params = call.get("params", None) # Execute the API call using the `execute_api_call` function tool_call_response = await workflow.execute_activity( diff --git a/agents-api/tests/test_execution_workflow.py b/agents-api/tests/test_execution_workflow.py index 42ca4cd78..8ed886254 100644 --- a/agents-api/tests/test_execution_workflow.py +++ b/agents-api/tests/test_execution_workflow.py @@ -473,7 +473,7 @@ async def _( "params": {"test": "_.test"}, }, { - "evaluate": {"hello": "_.json()['args']['test']"}, + "evaluate": {"hello": "_.json.args"}, } ], } From c24e57a1a5e9ff6d204c0aca40a9e3b1dd90df48 Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Thu, 3 Oct 2024 19:06:04 -0400 Subject: [PATCH 14/17] fix(agents-api): Fix api-call tool implementation and test Signed-off-by: Diwank Singh Tomer --- .../activities/excecute_api_call.py | 42 +++++++------------ .../activities/task_steps/base_evaluate.py | 11 ++++- agents-api/agents_api/autogen/Tasks.py | 2 +- .../models/task/create_or_update_task.py | 4 +- agents-api/agents_api/worker/worker.py | 2 +- .../workflows/task_execution/__init__.py | 19 +++------ agents-api/tests/test_execution_workflow.py | 8 ++-- typespec/tasks/steps.tsp | 2 +- 8 files changed, 40 insertions(+), 50 deletions(-) diff --git a/agents-api/agents_api/activities/excecute_api_call.py b/agents-api/agents_api/activities/excecute_api_call.py index fbc09316e..92a705b4c 100644 --- a/agents-api/agents_api/activities/excecute_api_call.py +++ b/agents-api/agents_api/activities/excecute_api_call.py @@ -1,4 +1,4 @@ -from typing import Annotated, Any, Optional, Union +from typing import Annotated, Any, Optional, TypedDict, Union import httpx from beartype import beartype @@ -14,47 +14,33 @@ # from ..models.tools import get_tool_args_from_metadata +class RequestArgs(TypedDict): + content: Optional[str] + data: Optional[dict[str, Any]] + json_: Optional[dict[str, Any]] + cookies: Optional[dict[str, str]] + params: Optional[Union[str, dict[str, Any]]] + + @beartype async def execute_api_call( - context: StepContext, - tool_name: str, api_call: ApiCallDef, - content: Optional[str] = None, - data: Optional[dict[str, Any]] = None, - json_: Annotated[Optional[dict[str, Any]], Field(None, alias="json")] = None, - cookies: Optional[dict[str, str]] = None, - params: Optional[Union[str, dict[str, Any]]] = None, + request_args: RequestArgs, ) -> Any: - developer_id = context.execution_input.developer_id - agent_id = context.execution_input.agent.id - task_id = context.execution_input.task.id - - # TODO: Implement get_tool_args_from_metadata to get the arguments and setup for the api call - # merged_tool_setup = get_tool_args_from_metadata( - # developer_id=developer_id, agent_id=agent_id, task_id=task_id, arg_type="setup" - # ) - - # arguments = ( - # merged_tool_args.get(tool_name, {}) | (integration.arguments or {}) | arguments - # ) - try: - response = httpx.request( + response = httpx.request( method=api_call.method, url=str(api_call.url), headers=api_call.headers, - content=content, - data=data, - json=json_, - cookies=cookies, - params=params, follow_redirects=api_call.follow_redirects, + **request_args, ) response_dict = { "status_code": response.status_code, + # FIXME: We need to handle the headers properly and convert them to a plain dict # "headers": response.headers, - # "content": response.content, + "content": response.content, "json": response.json(), } diff --git a/agents-api/agents_api/activities/task_steps/base_evaluate.py b/agents-api/agents_api/activities/task_steps/base_evaluate.py index 0263345ec..3fcbf2f73 100644 --- a/agents-api/agents_api/activities/task_steps/base_evaluate.py +++ b/agents-api/agents_api/activities/task_steps/base_evaluate.py @@ -12,7 +12,7 @@ @beartype async def base_evaluate( - exprs: str | list[str] | dict[str, str], + exprs: str | list[str] | dict[str, str] | dict[str, dict[str, str]], values: dict[str, Any] = {}, extra_lambda_strs: dict[str, str] | None = None, ) -> Any | list[Any] | dict[str, Any]: @@ -53,9 +53,18 @@ async def base_evaluate( case list(): return [evaluator.eval(expr) for expr in exprs] + case dict() as d if all(isinstance(v, dict) for v in d.values()): + return { + k: {ik: evaluator.eval(iv) for ik, iv in v.items()} + for k, v in d.items() + } + case dict(): return {k: evaluator.eval(v) for k, v in exprs.items()} + case _: + raise ValueError(f"Invalid expression: {exprs}") + except BaseException as e: if activity.in_activity(): activity.logger.error(f"Error in base_evaluate: {e}") diff --git a/agents-api/agents_api/autogen/Tasks.py b/agents-api/agents_api/autogen/Tasks.py index 9dd531c47..83fde00da 100644 --- a/agents-api/agents_api/autogen/Tasks.py +++ b/agents-api/agents_api/autogen/Tasks.py @@ -944,7 +944,7 @@ class ToolCallStep(BaseModel): """ The tool to run """ - arguments: dict[str, str] | Literal["_"] = "_" + arguments: dict[str, dict[str, str] | str] | Literal["_"] = "_" """ The input parameters for the tool (defaults to last step output) """ diff --git a/agents-api/agents_api/models/task/create_or_update_task.py b/agents-api/agents_api/models/task/create_or_update_task.py index 702e505ad..d787d78b5 100644 --- a/agents-api/agents_api/models/task/create_or_update_task.py +++ b/agents-api/agents_api/models/task/create_or_update_task.py @@ -64,7 +64,9 @@ def create_or_update_task( data.metadata = data.metadata or {} data.input_schema = data.input_schema or {} - task_data = task_to_spec(data).model_dump(exclude_none=True, exclude_unset=True, mode="json") + task_data = task_to_spec(data).model_dump( + exclude_none=True, exclude_unset=True, mode="json" + ) task_data.pop("task_id", None) task_data["created_at"] = utcnow().timestamp() diff --git a/agents-api/agents_api/worker/worker.py b/agents-api/agents_api/worker/worker.py index eb0a69154..08322772f 100644 --- a/agents-api/agents_api/worker/worker.py +++ b/agents-api/agents_api/worker/worker.py @@ -15,8 +15,8 @@ def create_worker(client: Client) -> Any: from ..activities import task_steps from ..activities.demo import demo_activity from ..activities.embed_docs import embed_docs + from ..activities.excecute_api_call import execute_api_call from ..activities.execute_integration import execute_integration - from ..activities. excecute_api_call import execute_api_call from ..activities.mem_mgmt import mem_mgmt from ..activities.mem_rating import mem_rating from ..activities.summarization import summarization diff --git a/agents-api/agents_api/workflows/task_execution/__init__.py b/agents-api/agents_api/workflows/task_execution/__init__.py index 2b20af26a..6023f6f25 100644 --- a/agents-api/agents_api/workflows/task_execution/__init__.py +++ b/agents-api/agents_api/workflows/task_execution/__init__.py @@ -512,7 +512,7 @@ async def run( ] == "api_call": call = tool_call["api_call"] tool_name = call["name"] - # arguments = call["arguments"] + arguments = call["arguments"] apicall_spec = next( (t for t in context.tools if t.name == tool_name), None ) @@ -527,25 +527,16 @@ async def run( follow_redirects=apicall_spec.spec["follow_redirects"], ) - # Extract the optional arguments for `content`, `data`, `json`, `cookies`, and `params` - content = call.get("content", None) - data = call.get("data", None) - json_ = call.get("json", None) - cookies = call.get("cookies", None) - params = call.get("params", None) + if "json_" in arguments: + arguments["json"] = arguments["json_"] + del arguments["json_"] # Execute the API call using the `execute_api_call` function tool_call_response = await workflow.execute_activity( execute_api_call, args=[ - context, - tool_name, api_call, - content, - data, - json_, - cookies, - params, + arguments, ], schedule_to_close_timeout=timedelta( seconds=30 if debug or testing else 600 diff --git a/agents-api/tests/test_execution_workflow.py b/agents-api/tests/test_execution_workflow.py index 8ed886254..4bd32e66b 100644 --- a/agents-api/tests/test_execution_workflow.py +++ b/agents-api/tests/test_execution_workflow.py @@ -470,11 +470,13 @@ async def _( "main": [ { "tool": "hello", - "params": {"test": "_.test"}, + "arguments": { + "params": {"test": "_.test"}, + }, }, { - "evaluate": {"hello": "_.json.args"}, - } + "evaluate": {"hello": "_.json.args.test"}, + }, ], } ), diff --git a/typespec/tasks/steps.tsp b/typespec/tasks/steps.tsp index 2267ae320..7a5f6d5b9 100644 --- a/typespec/tasks/steps.tsp +++ b/typespec/tasks/steps.tsp @@ -82,7 +82,7 @@ model ToolCallStepDef { tool: validPythonIdentifier; /** The input parameters for the tool (defaults to last step output) */ - arguments: ExpressionObject | "_" = "_"; + arguments: NestedExpressionObject | "_" = "_"; } model PromptStep extends BaseWorkflowStep<"prompt"> { From 3fe372e9635dada516ed23eea05f3f088c2df328 Mon Sep 17 00:00:00 2001 From: HamadaSalhab Date: Fri, 4 Oct 2024 02:15:38 +0300 Subject: [PATCH 15/17] Add todo for fixing docs tests --- agents-api/tests/test_docs_queries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents-api/tests/test_docs_queries.py b/agents-api/tests/test_docs_queries.py index fcf7f9bd6..dda200b6e 100644 --- a/agents-api/tests/test_docs_queries.py +++ b/agents-api/tests/test_docs_queries.py @@ -40,7 +40,7 @@ def _( client=client, ) - +# TODO: Execute embedding workflow to fix this test and other docs tests @test("model: get docs") def _(client=cozo_client, doc=test_doc, developer_id=test_developer_id): get_doc( From 3154d85a5ea425944a2692e183ac727b75ec8547 Mon Sep 17 00:00:00 2001 From: creatorrr Date: Fri, 4 Oct 2024 00:45:14 +0000 Subject: [PATCH 16/17] refactor: Lint agents-api (CI) --- agents-api/tests/test_docs_queries.py | 1 + 1 file changed, 1 insertion(+) diff --git a/agents-api/tests/test_docs_queries.py b/agents-api/tests/test_docs_queries.py index dda200b6e..b0f886c4f 100644 --- a/agents-api/tests/test_docs_queries.py +++ b/agents-api/tests/test_docs_queries.py @@ -40,6 +40,7 @@ def _( client=client, ) + # TODO: Execute embedding workflow to fix this test and other docs tests @test("model: get docs") def _(client=cozo_client, doc=test_doc, developer_id=test_developer_id): From 326067adba2a9903e818a19e401ac2e74ca8e81d Mon Sep 17 00:00:00 2001 From: Diwank Singh Tomer Date: Thu, 3 Oct 2024 20:50:44 -0400 Subject: [PATCH 17/17] fix(agents-api): Fix execute_api_call to use async httpx and pass headers back Signed-off-by: Diwank Singh Tomer --- .../agents_api/activities/excecute_api_call.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/agents-api/agents_api/activities/excecute_api_call.py b/agents-api/agents_api/activities/excecute_api_call.py index 92a705b4c..88fabce89 100644 --- a/agents-api/agents_api/activities/excecute_api_call.py +++ b/agents-api/agents_api/activities/excecute_api_call.py @@ -28,18 +28,18 @@ async def execute_api_call( request_args: RequestArgs, ) -> Any: try: - response = httpx.request( - method=api_call.method, - url=str(api_call.url), - headers=api_call.headers, - follow_redirects=api_call.follow_redirects, - **request_args, - ) + async with httpx.AsyncClient() as client: + response = await client.request( + method=api_call.method, + url=str(api_call.url), + headers=api_call.headers, + follow_redirects=api_call.follow_redirects, + **request_args, + ) response_dict = { "status_code": response.status_code, - # FIXME: We need to handle the headers properly and convert them to a plain dict - # "headers": response.headers, + "headers": dict(response.headers), "content": response.content, "json": response.json(), }