|
44 | 44 | OpenAIResponseObjectStreamResponseRefusalDone, |
45 | 45 | OpenAIResponseOutput, |
46 | 46 | OpenAIResponseOutputMessageContentOutputText, |
| 47 | + OpenAIResponseOutputMessageFileSearchToolCall, |
47 | 48 | OpenAIResponseOutputMessageFunctionToolCall, |
| 49 | + OpenAIResponseOutputMessageMCPCall, |
48 | 50 | OpenAIResponseOutputMessageMCPListTools, |
| 51 | + OpenAIResponseOutputMessageWebSearchToolCall, |
49 | 52 | OpenAIResponseText, |
50 | 53 | OpenAIResponseUsage, |
51 | 54 | OpenAIResponseUsageInputTokensDetails, |
@@ -177,6 +180,7 @@ async def create_response(self) -> AsyncIterator[OpenAIResponseObjectStream]: |
177 | 180 | # (some providers don't support non-empty response_format when tools are present) |
178 | 181 | response_format = None if self.ctx.response_format.type == "text" else self.ctx.response_format |
179 | 182 | logger.debug(f"calling openai_chat_completion with tools: {self.ctx.chat_tools}") |
| 183 | + |
180 | 184 | params = OpenAIChatCompletionRequestWithExtraBody( |
181 | 185 | model=self.ctx.model, |
182 | 186 | messages=messages, |
@@ -613,19 +617,22 @@ async def _process_streaming_chunks( |
613 | 617 |
|
614 | 618 | # Emit output_item.added event for the new function call |
615 | 619 | self.sequence_number += 1 |
616 | | - function_call_item = OpenAIResponseOutputMessageFunctionToolCall( |
617 | | - arguments="", # Will be filled incrementally via delta events |
618 | | - call_id=tool_call.id or "", |
619 | | - name=tool_call.function.name if tool_call.function else "", |
620 | | - id=tool_call_item_id, |
621 | | - status="in_progress", |
622 | | - ) |
623 | | - yield OpenAIResponseObjectStreamResponseOutputItemAdded( |
624 | | - response_id=self.response_id, |
625 | | - item=function_call_item, |
626 | | - output_index=len(output_messages), |
627 | | - sequence_number=self.sequence_number, |
628 | | - ) |
| 620 | + is_mcp_tool = tool_call.function.name and tool_call.function.name in self.mcp_tool_to_server |
| 621 | + if not is_mcp_tool and tool_call.function.name not in ["web_search", "knowledge_search"]: |
| 622 | + # for MCP tools (and even other non-function tools) we emit an output message item later |
| 623 | + function_call_item = OpenAIResponseOutputMessageFunctionToolCall( |
| 624 | + arguments="", # Will be filled incrementally via delta events |
| 625 | + call_id=tool_call.id or "", |
| 626 | + name=tool_call.function.name if tool_call.function else "", |
| 627 | + id=tool_call_item_id, |
| 628 | + status="in_progress", |
| 629 | + ) |
| 630 | + yield OpenAIResponseObjectStreamResponseOutputItemAdded( |
| 631 | + response_id=self.response_id, |
| 632 | + item=function_call_item, |
| 633 | + output_index=len(output_messages), |
| 634 | + sequence_number=self.sequence_number, |
| 635 | + ) |
629 | 636 |
|
630 | 637 | # Stream tool call arguments as they arrive (differentiate between MCP and function calls) |
631 | 638 | if tool_call.function and tool_call.function.arguments: |
@@ -806,6 +813,35 @@ async def _coordinate_tool_execution( |
806 | 813 | if not matching_item_id: |
807 | 814 | matching_item_id = f"tc_{uuid.uuid4()}" |
808 | 815 |
|
| 816 | + self.sequence_number += 1 |
| 817 | + if tool_call.function.name and tool_call.function.name in self.mcp_tool_to_server: |
| 818 | + item = OpenAIResponseOutputMessageMCPCall( |
| 819 | + arguments="", |
| 820 | + name=tool_call.function.name, |
| 821 | + id=matching_item_id, |
| 822 | + server_label=self.mcp_tool_to_server[tool_call.function.name].server_label, |
| 823 | + status="in_progress", |
| 824 | + ) |
| 825 | + elif tool_call.function.name == "web_search": |
| 826 | + item = OpenAIResponseOutputMessageWebSearchToolCall( |
| 827 | + id=matching_item_id, |
| 828 | + status="in_progress", |
| 829 | + ) |
| 830 | + elif tool_call.function.name == "knowledge_search": |
| 831 | + item = OpenAIResponseOutputMessageFileSearchToolCall( |
| 832 | + id=matching_item_id, |
| 833 | + status="in_progress", |
| 834 | + ) |
| 835 | + else: |
| 836 | + raise ValueError(f"Unsupported tool call: {tool_call.function.name}") |
| 837 | + |
| 838 | + yield OpenAIResponseObjectStreamResponseOutputItemAdded( |
| 839 | + response_id=self.response_id, |
| 840 | + item=item, |
| 841 | + output_index=len(output_messages), |
| 842 | + sequence_number=self.sequence_number, |
| 843 | + ) |
| 844 | + |
809 | 845 | # Execute tool call with streaming |
810 | 846 | tool_call_log = None |
811 | 847 | tool_response_message = None |
@@ -1064,7 +1100,11 @@ async def _add_mcp_list_tools( |
1064 | 1100 | self.sequence_number += 1 |
1065 | 1101 | yield OpenAIResponseObjectStreamResponseOutputItemAdded( |
1066 | 1102 | response_id=self.response_id, |
1067 | | - item=mcp_list_message, |
| 1103 | + item=OpenAIResponseOutputMessageMCPListTools( |
| 1104 | + id=mcp_list_message.id, |
| 1105 | + server_label=mcp_list_message.server_label, |
| 1106 | + tools=[], |
| 1107 | + ), |
1068 | 1108 | output_index=len(output_messages) - 1, |
1069 | 1109 | sequence_number=self.sequence_number, |
1070 | 1110 | ) |
|
0 commit comments