diff --git a/api-reference/pipecat-flows/flow-manager.mdx b/api-reference/pipecat-flows/flow-manager.mdx index 3e9b5827..e32ed13e 100644 --- a/api-reference/pipecat-flows/flow-manager.mdx +++ b/api-reference/pipecat-flows/flow-manager.mdx @@ -187,7 +187,7 @@ messages = flow_manager.get_current_context() flow_manager.register_action(action_type: str, handler: Callable) -> None ``` -Register a handler for a custom action type. The handler can be either a legacy handler `(action)` or a modern handler `(action, flow_manager)`. +Register a handler for a custom action type. The handler can be either a modern handler `(action, flow_manager)` or a legacy handler `(action)`. Legacy single-argument handlers are deprecated and will be removed in 2.0.0. | Parameter | Type | Description | | ------------- | ---------- | ---------------------------------------------------------- | diff --git a/api-reference/pipecat-flows/types.mdx b/api-reference/pipecat-flows/types.mdx index 0e933cc2..045ad3d3 100644 --- a/api-reference/pipecat-flows/types.mdx +++ b/api-reference/pipecat-flows/types.mdx @@ -119,10 +119,12 @@ Dataclass for defining function call schemas with Flows-specific properties. Pro - Function handler to process the function call. Can be a legacy handler - `(args)` or modern handler `(args, flow_manager)`. The handler should return a - [`FlowResult`](#flowresult) or a - [`ConsolidatedFunctionResult`](#consolidatedfunctionresult) tuple. + Function handler to process the function call. Can be a modern handler + `(args, flow_manager)`, legacy handler `(args)`, or zero-arg handler `()`. + Legacy and zero-arg handlers are deprecated. The handler returns any + JSON-serializable value, or a + [`ConsolidatedFunctionResult`](#consolidatedfunctionresult) tuple to also + specify the next node. @@ -317,26 +319,31 @@ node_config: NodeConfig = { ## FlowsDirectFunction -Protocol defining the interface for direct functions. Any async callable matching this signature can be used as a direct function in node configurations. +Type alias for direct functions with automatic metadata extraction. Any async callable matching this signature can be used as a direct function in node configurations. ```python -class FlowsDirectFunction(Protocol): - def __call__( - self, flow_manager: FlowManager, **kwargs: Any - ) -> Awaitable[ConsolidatedFunctionResult]: ... +FlowsDirectFunction = Callable[..., Awaitable[ConsolidatedFunctionResult]] ``` +Direct functions must accept `flow_manager: FlowManager` as the first parameter, followed by any named parameters described in the function's docstring. Python's `Protocol` system cannot express "any concrete named-parameter list", so this is defined as a generic `Callable`. Runtime validation is handled by `FlowsDirectFunctionWrapper.validate_function`. + ## Type Aliases ### FlowResult + + **Deprecated.** `FlowResult` is no longer required by any handler type and + will be removed in 2.0.0. Function handlers can return any JSON-serializable + value. Define your own `TypedDict` if you want a structured result. + + ```python class FlowResult(TypedDict, total=False): status: str error: str ``` -Base return type for function results. The `status` field indicates the outcome. The optional `error` field contains an error message if execution failed. Additional fields are allowed and passed through to the LLM. +Optional convention TypedDict for `status`/`error` results. The `status` field indicates the outcome. The optional `error` field contains an error message if execution failed. Additional fields are allowed and passed through to the LLM. ### FlowArgs @@ -344,35 +351,69 @@ Base return type for function results. The `status` field indicates the outcome. FlowArgs = dict[str, Any] ``` -Type alias for function handler arguments. Contains the parameters extracted from the LLM's function call. +Type alias for function handler arguments. Contains the parameters extracted from the LLM's function call. Each invocation gets its own dict, so handlers may mutate it freely. + + + In 2.0.0, this alias is planned to widen to `Mapping[str, Any]` to align with + Pipecat's typing. Handlers that only read args will be unaffected; handlers + that mutate args will need to keep the annotation as `dict[str, Any]` + explicitly. + ### ConsolidatedFunctionResult ```python -ConsolidatedFunctionResult = tuple[FlowResult | None, NodeConfig | None] +ConsolidatedFunctionResult = tuple[Any, NodeConfig | None] ``` Return type for consolidated function handlers that both do work and specify the next node: -- First element: The function result (or `None` for transition-only functions) +- First element: Any JSON-serializable value (or `None` for transition-only functions) - Second element: The next node as a `NodeConfig`, or `None` for node functions ### FlowFunctionHandler ```python -FlowFunctionHandler = Callable[ - [FlowArgs, FlowManager], Awaitable[FlowResult | ConsolidatedFunctionResult] -] +FlowFunctionHandler = Callable[[FlowArgs, FlowManager], Awaitable[Any]] ``` Type for modern function handlers that receive both arguments and the `FlowManager` instance. +**Args:** +- `args` (`FlowArgs`): Dictionary of arguments from the function call. +- `flow_manager` (`FlowManager`): Reference to the FlowManager instance. + +**Returns:** Any JSON-serializable value, or a `ConsolidatedFunctionResult` tuple to also specify the next node. + +### ZeroArgFunctionHandler + + + **Deprecated.** Zero-argument function handlers are deprecated and will be + removed in 2.0.0. Update handlers to accept `(args, flow_manager)` instead. + + +```python +ZeroArgFunctionHandler = Callable[[], Awaitable[Any]] +``` + +Type for function handlers that take no arguments. The flow manager detects the signature automatically and emits a `DeprecationWarning`. + +**Returns:** Any JSON-serializable value, or a `ConsolidatedFunctionResult` tuple to also specify the next node. + ### LegacyFunctionHandler + + **Deprecated.** Single-argument function handlers are deprecated and will be + removed in 2.0.0. Update handlers to accept `(args, flow_manager)` instead. + + ```python -LegacyFunctionHandler = Callable[ - [FlowArgs], Awaitable[FlowResult | ConsolidatedFunctionResult] -] +LegacyFunctionHandler = Callable[[FlowArgs], Awaitable[Any]] ``` -Type for legacy function handlers that only receive arguments. Both legacy and modern handlers are supported; the flow manager detects the signature automatically. +Type for legacy function handlers that only receive arguments. Both legacy and modern handlers are supported; the flow manager detects the signature automatically and emits a `DeprecationWarning`. + +**Args:** +- `args` (`FlowArgs`): Dictionary of arguments from the function call. + +**Returns:** Any JSON-serializable value, or a `ConsolidatedFunctionResult` tuple to also specify the next node. diff --git a/pipecat-flows/guides/actions.mdx b/pipecat-flows/guides/actions.mdx index de86ada8..789d5a60 100644 --- a/pipecat-flows/guides/actions.mdx +++ b/pipecat-flows/guides/actions.mdx @@ -67,7 +67,12 @@ async def notify_slack(action: dict, flow_manager: FlowManager): flow_manager.register_action("notify_slack", notify_slack) ``` -Then use it in your node configuration: + + Action handlers should accept `(action, flow_manager)`. Single-argument + handlers `(action)` are deprecated and will be removed in 2.0.0. + + +Once registered, use it in your node configuration: ```python "pre_actions": [ diff --git a/pipecat-flows/guides/functions.mdx b/pipecat-flows/guides/functions.mdx index 7e82c1d1..37fb4710 100644 --- a/pipecat-flows/guides/functions.mdx +++ b/pipecat-flows/guides/functions.mdx @@ -54,9 +54,9 @@ async def record_favorite_color_and_set_next_node( ## Handler Return Values -Function handlers return a tuple containing: +Function handlers can return any JSON-serializable value (string, dict, list, etc.) that gets passed to the LLM. To also specify the next node, return a tuple: -- **Result**: Data provided to the LLM for context in subsequent completions, or `None`. This can be any serializable value — a string, dict, etc. +- **Result**: Data provided to the LLM for context in subsequent completions, or `None`. Any JSON-serializable value is accepted. - **Next Node**: The `NodeConfig` for Flows to transition to next, or `None` Some handlers may not want to transition conversational state, in which case you can return `None` for the next node. Other handlers may _only_ want to transition conversational state without doing other work, in which case you can return `None` for the result. @@ -69,7 +69,7 @@ For more concise code, you can optionally use Direct Functions where the functio async def record_favorite_color( flow_manager: FlowManager, color: str -) -> tuple[FlowResult, NodeConfig]: +) -> tuple[str, NodeConfig]: """Record the color the user said is their favorite. Args: @@ -95,12 +95,12 @@ from pipecat_flows import flows_direct_function async def long_running_lookup( flow_manager: FlowManager, order_id: str -) -> tuple[FlowResult, NodeConfig]: +) -> tuple[dict, NodeConfig]: """Look up an order that should not be cancelled if the user speaks. Args: order_id: The order ID to look up. """ order = await db.get_order(order_id) - return {"status": "success"}, create_order_node(order) + return {"status": "success", "order": order}, create_order_node(order) ```