ToolResponse object serialized to a dict via .to_dict(). This ensures the WebSocket handler, client renderer, and chat storage all work with a consistent data shape.
The ToolResponse class
Defined in connectors/utils/responses.py:
Fields
An agent-specific string that identifies the kind of data in
response. The client uses this value to choose the correct renderer (e.g., an email list, a business card grid, a financial table). See the response type reference below.The internal name of the agent that produced this response. Matches the
Agent(name=...) value. Examples: "GMail", "Plaid", "Yelp", "Google".A human-readable label shown in the UI alongside the tool output. Describes the specific action taken, for example
"GMAIL Inbox" or "Searching Yelp for sushi in Boston, MA".Controls whether the WebSocket handler forwards the tool output to the client. Set to
false for intermediate results that the LLM should process internally without surfacing to the user. The handler checks this flag before emitting a tool_output event.The data payload. Shape varies by
response_type. Can be a list (email messages, search results, businesses), a dict (account details, transaction maps), or a string (error or status messages).The .to_dict() pattern
All tool functions return ToolResponse(...).to_dict() rather than the ToolResponse object itself. This ensures the value is JSON-serializable and compatible with the OpenAI Agents SDK’s tool output format.
Real examples
Gmail — inbox fetch
connectors/gmail.py — fetch_google_email_inbox
response contains:
Gmail — send email
connectors/gmail.py — send_google_email
Plaid — account balances
connectors/plaid_agent.py — get_accounts_at_plaid
Plaid — transactions
connectors/plaid_agent.py — get_transactions_at_plaid
account_transactions structure:
Yelp — business search
connectors/yelp.py — search_businesses_at_yelp
Yelp — reviews
connectors/yelp.py — get_business_reviews_at_yelp
display_response and client rendering
When the WebSocket handler receives a tool_call_output_item event from the agent runner, it checks output.get("display_response", True) before forwarding the data to the client:
display_response=False for tools that fetch data as intermediate context for the LLM (for example, a location lookup that feeds into a subsequent search) without needing to render the raw data in the chat UI.
Response type reference
response_type | Agent | Description |
|---|---|---|
google_email_inbox | GMail | Inbox email list |
google_email_search | GMail | Email search results |
google_email_search_from_email | GMail | Emails from a specific sender |
send_google_email | GMail | Sent email confirmation |
reply_to_google_email | GMail | Sent reply confirmation |
plaid_accounts_response | Plaid | Bank account balances |
plaid_transactions_response | Plaid | Transaction history by account |
yelp_search_results | Yelp | Business search results |
yelp_reviews | Yelp | Business reviews |
google_search_results | Google Search | Web search results |
error | Any | Error message from a failed tool call |
account_needed | Any | Signals that the user must connect an account |
google_account_needed | Any | Signals that a Google account connection is required |
connect_google_account | Any | Prompts the user to connect their Google account |
connect_plaid_account | Any | Prompts the user to connect a Plaid account |
open_window | Open URL | Instructs the client to open a URL in the current window |
open_tab | Open URL | Instructs the client to open a URL in a new tab |
Built-in ToolResponse subclasses
For common scenarios, connectors/utils/responses.py provides ready-made subclasses:
How the orchestrator synthesizes multiple tool responses
When the orchestrator calls multiple agents in a single turn, each agent returns its ownToolResponse. The WebSocket handler emits a tool_output event for each one that has display_response=True. The LLM then receives all tool outputs as context and generates a single synthesized llm_response that references the combined results.
The full sequence for a multi-agent turn looks like this:
tool_output inline as a structured card while streaming the final llm_response text alongside it.