Skip to content

revert - #1424

Merged
iceljc merged 1 commit into
SciSharp:masterfrom
iceljc:master
Sep 4, 2026
Merged

revert#1424
iceljc merged 1 commit into
SciSharp:masterfrom
iceljc:master

Conversation

@iceljc

@iceljc iceljc commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@iceljc
iceljc merged commit bc5b2dd into SciSharp:master Sep 4, 2026
0 of 4 checks passed
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Preserve parallel tool calls in OpenAI Responses API

🐞 Bug fix ✨ Enhancement 🕐 10-20 Minutes

Grey Divider

AI Description

• Preserve every OpenAI Responses API tool call across synchronous and streaming flows.
• Retain first-call fields for compatibility while exposing the complete ordered call list.
• Omit temperature from Responses API requests for models that reject the parameter.
Diagram

graph TD
  A["Agent Request"] --> B["Response Options"] --> C["Responses API"] --> D["Response Modes"] --> E["Call Collector"] --> F["Role Dialog"] --> G["Tool Execution"]
Loading
High-Level Assessment

The approach is appropriate because it reuses the existing RoleDialogModel.ToolCalls contract across all Responses API modes while retaining legacy first-call fields for compatibility. Collecting only one call would preserve the original defect, while introducing a separate response model would duplicate an established abstraction.

Files changed (1) +26 / -14

Bug fix (1) +26 / -14
ChatCompletionProvider.Response.csCapture all Responses API tool calls and remove temperature +26/-14

Capture all Responses API tool calls and remove temperature

• Collects every function call from synchronous, callback-based, and streaming responses, converts them to LlmToolCall entries, and records all function names in logs. It preserves the first call in legacy fields and stops including temperature in Responses API options.

src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Additional tool calls are dropped 🐞 Bug ≡ Correctness
Description
The provider now returns every requested call in ToolCalls, but RoutingService.InvokeAgent
copies and executes only the legacy singular fields. Any second or later tool call is discarded and
omitted from subsequent Responses API history, so the model can re-request it on the next turn.
Code

src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[49]

+                ToolCalls = toolCalls,
Evidence
The changed provider collects all output calls but stores only the first in the singular fields. The
main routing path ignores ToolCalls, invokes one function, and the Responses history serializer
can reconstruct only that singular call and output.

src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[28-49]
src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs[39-65]
src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs[89-102]
src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[519-531]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
OpenAI Responses now returns all model-requested calls through `RoleDialogModel.ToolCalls`, but the main routing path executes only the first call. Update orchestration to execute every call, retain each call ID and result, and send all call/result pairs back before requesting the next completion.

## Issue Context
The provider keeps the first call in legacy singular fields for compatibility. Multi-call orchestration must avoid recursively requesting another completion after each individual call; all calls from one model response need corresponding outputs in the next request.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[28-49]
- src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs[39-65]
- src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs[89-130]
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[519-531]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Responses temperature is ignored 🐞 Bug ≡ Correctness
Description
Removing CreateResponseOptions.Temperature causes every Responses API request to ignore the
conversation's temperature state and use the SDK/API default instead. Configured deterministic or
creative behavior therefore changes whenever UseResponseApi is enabled, while the Chat Completions
path still honors the same state.
Code

src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[434]

-            Temperature = temperature,
Evidence
The current Responses option builder reads max tokens and reasoning effort but never reads or
assigns temperature. In contrast, the sibling Chat Completions option builder reads the
temperature state and assigns it to the outgoing options, proving this setting is part of provider
request configuration.

src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[433-459]
src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs[607-618]
src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs[629-639]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Restore propagation of the configured conversation temperature into `CreateResponseOptions`. Continue suppressing temperature only for Responses configurations that cannot accept it, such as the reasoning modes previously covered by the conditional.

## Issue Context
`PrepareResponseOptions` is shared by synchronous, callback-based, and streaming Responses API operations. The sibling Chat Completions initializer demonstrates that `temperature` is conversation state intended to affect provider requests.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[433-459]
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs[607-639]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced: This changes OpenAI response and streaming tool-call handling across multiple execution paths, with behavioral and configuration effects that warrant a careful single-pass review.

Grey Divider

Tip of the day
💡 Did you know, you can route each action level your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

ToolCallId = functionCall.CallId,
FunctionName = functionCall.FunctionName.NormalizeFunctionName(),
FunctionArgs = functionCall.FunctionArguments?.ToString(),
ToolCalls = toolCalls,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Additional tool calls are dropped 🐞 Bug ≡ Correctness

The provider now returns every requested call in ToolCalls, but RoutingService.InvokeAgent
copies and executes only the legacy singular fields. Any second or later tool call is discarded and
omitted from subsequent Responses API history, so the model can re-request it on the next turn.
Agent Prompt
## Issue description
OpenAI Responses now returns all model-requested calls through `RoleDialogModel.ToolCalls`, but the main routing path executes only the first call. Update orchestration to execute every call, retain each call ID and result, and send all call/result pairs back before requesting the next completion.

## Issue Context
The provider keeps the first call in legacy singular fields for compatibility. Multi-call orchestration must avoid recursively requesting another completion after each individual call; all calls from one model response need corresponding outputs in the next request.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[28-49]
- src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs[39-65]
- src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs[89-130]
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[519-531]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


var options = new CreateResponseOptions(_model, [])
{
Temperature = temperature,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Responses temperature is ignored 🐞 Bug ≡ Correctness

Removing CreateResponseOptions.Temperature causes every Responses API request to ignore the
conversation's temperature state and use the SDK/API default instead. Configured deterministic or
creative behavior therefore changes whenever UseResponseApi is enabled, while the Chat Completions
path still honors the same state.
Agent Prompt
## Issue description
Restore propagation of the configured conversation temperature into `CreateResponseOptions`. Continue suppressing temperature only for Responses configurations that cannot accept it, such as the reasoning modes previously covered by the conditional.

## Issue Context
`PrepareResponseOptions` is shared by synchronous, callback-based, and streaming Responses API operations. The sibling Chat Completions initializer demonstrates that `temperature` is conversation state intended to affect provider requests.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs[433-459]
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs[607-639]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant