Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/gradient_labs/_conversation_return_async_tool_result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from typing import Optional, Any, Dict
from datetime import datetime

from dataclasses import dataclass
from dataclasses_json import dataclass_json

from ._http_client import HttpClient


@dataclass_json
@dataclass(frozen=True)
class ReturnAsyncToolResultParams:
"""Parameters for returning an async tool execution result.

When a tool is configured for asynchronous execution, the agent will request
the tool execution via an action.execute webhook event, and your system should
return the result using this method.
"""

# async_tool_execution_id is the unique identifier for the async tool execution.
# This ID is provided in the action.execute webhook event when the agent
# requests the tool execution.
async_tool_execution_id: str

# payload is the result data from the tool execution as a JSON object.
# The structure of this object depends on your tool's implementation.
# The agent will use AI to extract relevant information from any well-formed
# JSON object.
payload: Dict[str, Any]

# timestamp optionally defines the time when the result was generated.
# If not given, this will default to the current time.
timestamp: Optional[datetime] = None


def return_async_tool_result(
*, client: HttpClient, conversation_id: str, params: ReturnAsyncToolResultParams
) -> None:
"""Returns the result of an async tool execution.

When a tool is configured for asynchronous execution, the agent will request
the tool execution via an action.execute webhook event, and your system should
return the result by calling this function.

This allows your system to perform long-running operations without blocking the
conversation, and return results when they're ready.

Important Notes:
- The conversation must be in an ongoing state. You cannot return async tool
results to conversations that are finished, failed, or cancelled.
- Make sure to use the correct async_tool_execution_id from the action.execute
webhook event.
- The result payload should be a valid JSON object containing the data the
agent needs to continue the conversation.
"""
body = {
"async_tool_execution_id": params.async_tool_execution_id,
"payload": params.payload,
}
if params.timestamp:
body["timestamp"] = client.localize(params.timestamp)

_ = client.put(
f"conversations/{conversation_id}/return-async-tool-result",
body=body,
)
24 changes: 24 additions & 0 deletions src/gradient_labs/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
from ._conversation_resume import resume_conversation, ResumeParams
from ._conversation_read import read_conversation, ReadParams
from ._conversation_start import start_conversation, StartConversationParams
from ._conversation_return_async_tool_result import (
return_async_tool_result,
ReturnAsyncToolResultParams,
)

from ._handoff_target_upsert import upsert_hand_off_target, UpsertHandOffTargetParams
from ._handoff_targets import list_handoff_targets, HandOffTargets
Expand Down Expand Up @@ -208,6 +212,26 @@ def add_message(
params=params,
)

def return_async_tool_result(
self,
*,
conversation_id: str,
params: ReturnAsyncToolResultParams,
) -> None:
"""Returns the result of an async tool execution.

When a tool is configured for asynchronous execution, the agent will request
the tool execution via an action.execute webhook event, and your system should
return the result by calling this method.

This allows your system to perform long-running operations without blocking the
conversation, and return results when they're ready."""
return_async_tool_result(
client=self.http_client,
conversation_id=conversation_id,
params=params,
)

def upsert_hand_off_target(self, *, params: UpsertHandOffTargetParams) -> None:
"""upsert_hand_off_target inserts or updates a hand-off target.

Expand Down