Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle multiple function calls in openai #346

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
36 changes: 28 additions & 8 deletions src/pipecat/services/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ async def _stream_chat_completions(
return chunks

async def _process_context(self, context: OpenAILLMContext):
functions_list = []
arguments_list = []
tool_id_list = []
func_idx = 0
function_name = ""
arguments = ""
tool_call_id = ""
Expand Down Expand Up @@ -150,6 +154,14 @@ async def _process_context(self, context: OpenAILLMContext):
# yield a frame containing the function name and the arguments.

tool_call = chunk.choices[0].delta.tool_calls[0]
if tool_call.index != func_idx:
functions_list.append(function_name)
arguments_list.append(arguments)
tool_id_list.append(tool_call_id)
function_name = ""
arguments = ""
tool_call_id = ""
func_idx += 1
if tool_call.function and tool_call.function.name:
function_name += tool_call.function.name
tool_call_id = tool_call.id
Expand All @@ -165,11 +177,20 @@ async def _process_context(self, context: OpenAILLMContext):
# the context, and re-prompt to get a chat answer. If we don't have a registered
# handler, raise an exception.
if function_name and arguments:
if self.has_function(function_name):
await self._handle_function_call(context, tool_call_id, function_name, arguments)
else:
raise OpenAIUnhandledFunctionException(
f"The LLM tried to call a function named '{function_name}', but there isn't a callback registered for that function.")
# added to the list as last function name and arguments not added to the list
functions_list.append(function_name)
arguments_list.append(arguments)
tool_id_list.append(tool_call_id)
for function_name,arguments,tool_id in zip(functions_list,arguments_list,tool_id_list):
if self.has_function(function_name):
await self._handle_function_call(context, tool_id, function_name, arguments)
else:
raise OpenAIUnhandledFunctionException(
f"The LLM tried to call a function named '{function_name}', but there isn't a callback registered for that function.")
# re-prompt to get a human answer after all the functions are called
await self._process_context(context)



async def _handle_function_call(
self,
Expand Down Expand Up @@ -206,13 +227,12 @@ async def _handle_function_call(
"content": result
})
context.add_message(tool_result)
# re-prompt to get a human answer
await self._process_context(context)

elif isinstance(result, list):
# reduced magic
for msg in result:
context.add_message(msg)
await self._process_context(context)

elif isinstance(result, type(None)):
pass
else:
Expand Down