From 874b8bb136495843e960da3786d9b33f0fe105cd Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Sat, 11 Jan 2025 15:59:09 -0500 Subject: [PATCH] Allow for an override of running a completion after a function call completes, OpenAI --- src/pipecat/frames/frames.py | 1 + .../aggregators/openai_llm_context.py | 17 +++++++++++++---- src/pipecat/services/openai.py | 9 +++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/pipecat/frames/frames.py b/src/pipecat/frames/frames.py index 44b40504e..e60f23f96 100644 --- a/src/pipecat/frames/frames.py +++ b/src/pipecat/frames/frames.py @@ -330,6 +330,7 @@ class FunctionCallResultFrame(DataFrame): arguments: str result: Any run_llm: bool = True + override_run_llm: bool = False @dataclass diff --git a/src/pipecat/processors/aggregators/openai_llm_context.py b/src/pipecat/processors/aggregators/openai_llm_context.py index 039d0e6d5..35412f365 100644 --- a/src/pipecat/processors/aggregators/openai_llm_context.py +++ b/src/pipecat/processors/aggregators/openai_llm_context.py @@ -9,7 +9,7 @@ import copy import io import json from dataclasses import dataclass -from typing import Any, Awaitable, Callable, List +from typing import Any, Awaitable, Callable, List, Optional from loguru import logger from PIL import Image @@ -219,22 +219,31 @@ class OpenAILLMContext: # Define a callback function that pushes a FunctionCallResultFrame upstream & downstream. async def function_call_result_callback(result): + # Extract result and frame parameters if provided + if isinstance(result, dict) and "result" in result: + frame_run_llm = result.get("run_llm", run_llm) + frame_override = result.get("override_run_llm", False) + else: + frame_run_llm = run_llm + frame_override = False + result_frame_downstream = FunctionCallResultFrame( function_name=function_name, tool_call_id=tool_call_id, arguments=arguments, result=result, - run_llm=run_llm, + run_llm=frame_run_llm, + override_run_llm=frame_override, ) result_frame_upstream = FunctionCallResultFrame( function_name=function_name, tool_call_id=tool_call_id, arguments=arguments, result=result, - run_llm=run_llm, + run_llm=frame_run_llm, + override_run_llm=frame_override, ) - # Push frame both downstream and upstream await llm.push_frame(result_frame_downstream, FrameDirection.DOWNSTREAM) await llm.push_frame(result_frame_upstream, FrameDirection.UPSTREAM) diff --git a/src/pipecat/services/openai.py b/src/pipecat/services/openai.py index 84c4c0560..d57ea545b 100644 --- a/src/pipecat/services/openai.py +++ b/src/pipecat/services/openai.py @@ -580,8 +580,13 @@ class OpenAIAssistantContextAggregator(LLMAssistantContextAggregator): "tool_call_id": frame.tool_call_id, } ) - # Only run the LLM if there are no more function calls in progress. - run_llm = not bool(self._function_calls_in_progress) + + if frame.override_run_llm: + # Explicit override + run_llm = frame.run_llm + else: + # Default behavior + run_llm = not bool(self._function_calls_in_progress) else: self._context.add_message({"role": "assistant", "content": aggregation})