async_tool_messages

Helpers for the async-tool message protocol used in LLM contexts.

When a function is registered with cancel_on_interruption=False, the LLMUserContextAggregator / LLMAssistantContextAggregator pair appends async-tool messages to the conversation context as the underlying task progresses:

  • A started message (role="tool") is appended immediately when the tool starts running.

  • An intermediate message (role="developer") is appended each time an intermediate result is reported via result_callback(..., FunctionCallResultProperties(is_final=False)).

  • A final message (role="developer") is appended when the task finishes.

This module is the single source of truth for the on-the-wire payload shape:

  • The aggregator uses the build_*_message functions when injecting messages.

  • Realtime LLM services use parse_message to detect async-tool messages while iterating the context, then read payload.result and deliver it via their formal tool-result channel.

Internally, AsyncToolMessagePayload is the canonical structured form; the on-the-wire JSON string is always derived from it (never stored) so the two representations can’t drift.

Consumers are expected to import the module rather than its individual functions, e.g.:

from pipecat.processors.aggregators import async_tool_messages
...
async_tool_messages.build_started_message(tool_call_id)
async_tool_messages.parse_message(msg)
class pipecat.processors.aggregators.async_tool_messages.AsyncToolMessagePayload(kind: Literal['started', 'intermediate', 'final'], tool_call_id: str, status: Literal['running', 'finished'], description: str, result: str | None)[source]

Bases: object

The structured contents of an async-tool message in an LLM context.

Parameters:
  • kind – Which of the three async-tool message stages this is.

  • tool_call_id – The id of the tool invocation this payload relates to.

  • status"running" for started/intermediate, "finished" for the final message.

  • description – Human-readable description from the payload. May be empty.

  • result – For intermediate and final messages, the JSON-encoded result string (or the literal "COMPLETED" if the function returned no value). None for started messages.

kind: Literal['started', 'intermediate', 'final']
tool_call_id: str
status: Literal['running', 'finished']
description: str
result: str | None
pipecat.processors.aggregators.async_tool_messages.build_started_message(tool_call_id: str) ChatCompletionDeveloperMessageParam | ChatCompletionSystemMessageParam | ChatCompletionUserMessageParam | ChatCompletionAssistantMessageParam | ChatCompletionToolMessageParam | ChatCompletionFunctionMessageParam[source]

Build a started async-tool message for an LLM context.

Append the returned message to the LLM context immediately when an async function call (registered with cancel_on_interruption=False) starts running. The message lets the model know a task is in flight and that its results will arrive later in subsequent developer-role messages.

Parameters:

tool_call_id – The id of the tool invocation this message is for.

Returns:

A message ready to pass to LLMContext.add_message.

pipecat.processors.aggregators.async_tool_messages.build_intermediate_result_message(tool_call_id: str, result: str) ChatCompletionDeveloperMessageParam | ChatCompletionSystemMessageParam | ChatCompletionUserMessageParam | ChatCompletionAssistantMessageParam | ChatCompletionToolMessageParam | ChatCompletionFunctionMessageParam[source]

Build an intermediate-result async-tool message for an LLM context.

Append the returned message to the LLM context each time the running async function reports a non-final result via result_callback(..., FunctionCallResultProperties(is_final=False)).

Parameters:
  • tool_call_id – The id of the tool invocation the result is for.

  • result – The JSON-encoded result string (caller is responsible for encoding the function’s actual return value, typically via json.dumps).

Returns:

A message ready to pass to LLMContext.add_message.

pipecat.processors.aggregators.async_tool_messages.build_final_result_message(tool_call_id: str, result: str) ChatCompletionDeveloperMessageParam | ChatCompletionSystemMessageParam | ChatCompletionUserMessageParam | ChatCompletionAssistantMessageParam | ChatCompletionToolMessageParam | ChatCompletionFunctionMessageParam[source]

Build a final-result async-tool message for an LLM context.

Append the returned message to the LLM context when the async function finishes. After this message no further async-tool messages will arrive for this tool_call_id.

Parameters:
  • tool_call_id – The id of the tool invocation the result is for.

  • result – The JSON-encoded result string, or the literal "COMPLETED" sentinel when the function returned None (matching the same convention used for synchronous tool calls).

Returns:

A message ready to pass to LLMContext.add_message.

pipecat.processors.aggregators.async_tool_messages.parse_message(message: ChatCompletionDeveloperMessageParam | ChatCompletionSystemMessageParam | ChatCompletionUserMessageParam | ChatCompletionAssistantMessageParam | ChatCompletionToolMessageParam | ChatCompletionFunctionMessageParam) AsyncToolMessagePayload | None[source]

Decode an async-tool message payload, or return None if not async-tool.

Parameters:

message – A standard message from the LLM context. Callers iterating over LLMContext.get_messages() should filter out LLMSpecificMessage entries first; only LLMStandardMessage values can carry async-tool payloads.

Returns:

An AsyncToolMessagePayload if the message is a recognized async-tool payload, otherwise None.