fix(responses): fix regression in support for mcp tool require_approval argument (#3731)

# What does this PR do?

It prevents a tool call message being added to the chat completions
message without a corresponding tool call result, which is needed in the
case that an approval is required first or if the approval request is
denied. In both these cases the tool call messages is popped of the next
turn messages.

Closes #3728

## Test Plan
Ran the integration tests
Manual check of both approval and denial against gpt-4o

Signed-off-by: Gordon Sim <gsim@redhat.com>
This commit is contained in:
grs 2025-10-08 15:47:17 +01:00 committed by GitHub
parent 5d711d4bcb
commit 96886afaca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 6 additions and 4 deletions

View file

@ -269,7 +269,7 @@ class OpenAIResponsesImpl:
response_tools=tools, response_tools=tools,
temperature=temperature, temperature=temperature,
response_format=response_format, response_format=response_format,
inputs=input, inputs=all_input,
) )
# Create orchestrator and delegate streaming logic # Create orchestrator and delegate streaming logic

View file

@ -175,6 +175,8 @@ class StreamingResponseOrchestrator:
): ):
yield stream_event yield stream_event
messages = next_turn_messages
if not function_tool_calls and not non_function_tool_calls: if not function_tool_calls and not non_function_tool_calls:
break break
@ -187,9 +189,7 @@ class StreamingResponseOrchestrator:
logger.info(f"Exiting inference loop since iteration count({n_iter}) exceeds {self.max_infer_iters=}") logger.info(f"Exiting inference loop since iteration count({n_iter}) exceeds {self.max_infer_iters=}")
break break
messages = next_turn_messages self.final_messages = messages.copy()
self.final_messages = messages.copy() + [current_response.choices[0].message]
# Create final response # Create final response
final_response = OpenAIResponseObject( final_response = OpenAIResponseObject(
@ -232,9 +232,11 @@ class StreamingResponseOrchestrator:
non_function_tool_calls.append(tool_call) non_function_tool_calls.append(tool_call)
else: else:
logger.info(f"Approval denied for {tool_call.id} on {tool_call.function.name}") logger.info(f"Approval denied for {tool_call.id} on {tool_call.function.name}")
next_turn_messages.pop()
else: else:
logger.info(f"Requesting approval for {tool_call.id} on {tool_call.function.name}") logger.info(f"Requesting approval for {tool_call.id} on {tool_call.function.name}")
approvals.append(tool_call) approvals.append(tool_call)
next_turn_messages.pop()
else: else:
non_function_tool_calls.append(tool_call) non_function_tool_calls.append(tool_call)