Skip to content

Scope Response.Update AdditionalProperties by MessageID - #1133

Open
PratikDhanave (PratikDhanave) wants to merge 1 commit into
microsoft:mainfrom
PratikDhanaveFork:fix/response-update-additionalprops-scope
Open

PratikDhanave (PratikDhanave) wants to merge 1 commit into
microsoft:mainfrom
PratikDhanaveFork:fix/response-update-additionalprops-scope

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

Response.Update copied update.AdditionalProperties into both the target message's AdditionalProperties and the response-level AdditionalProperties. So message-scoped provider metadata (an update carrying a MessageID) leaked up to the response, and response-scoped metadata (an update with no MessageID) leaked onto whichever message was current — duplicated and mis-attributed versus .NET.

Response.Update is a direct port of M.E.AI ChatResponseExtensions.ProcessUpdate, which scopes these either/or:

AdditionalProperties are scoped to the message if the update has a MessageId, otherwise theyre scoped to the response.

Change

  • Copy to the message only when update.MessageID != "", and to the response only when it is empty.

Test

  • TestResponse_Update_AdditionalPropertiesScopedByMessageID: with a MessageID the props land on the message and the response stays empty; without one they land on the response and the message stays empty. Both halves fail before the change (props on both), pass after. The existing TestResponse_Update_AdditionalProperties (always uses a MessageID, asserts the message side) still passes.

Response.Update copied an update's AdditionalProperties into BOTH the target
message and the response, so message-scoped provider metadata leaked to the
response level and response-scoped metadata leaked onto the current message.

Scope them to the message when the update carries a MessageID and to the
response otherwise, matching .NET's ChatResponseExtensions.ProcessUpdate
(which Response.Update ports).
Copilot AI lite review requested due to automatic review settings September 21, 2026 06:15
@github-actions github-actions Bot added area:agent Changes files in the agent area size:medium At most 100 changed lines across at most 5 files labels Sep 21, 2026

Copilot AI left a comment

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.

Copilot review overview

🔵 Needs a closer look

Empty-message-ID round trips can misplace message-scoped properties on the response.

Review effort: Lite
Findings: None

What changed in this PR

Updates Response.Update to scope AdditionalProperties by MessageID, with regression tests for message- and response-level metadata.

Changes:

  • Applies metadata to only the appropriate scope.
  • Adds coverage for both scoping cases.
File Description
agent/​response.go Implements MessageID-based metadata scoping.
agent/​response_test.go Tests message- and response-level property behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions github-actions Bot added kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure labels Sep 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Scope: user-visible behavior (bug fix; no exported API surface change)

Changed Go contract: agent.Response.Update(update *ResponseUpdate) — internal scoping logic for copying update.AdditionalProperties into msg.AdditionalProperties vs. resp.AdditionalProperties. No exported types, methods, fields, or signatures were added/removed/changed.

Upstream evidence reviewed: Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatResponseExtensions.cs (private ProcessUpdate(ChatResponseUpdate update, ChatResponse response), lines ~592-616) in dotnet/extensions, which Microsoft.Agents.AI.ChatClient.ChatClientAgent builds on for ChatResponse construction. The upstream comment states verbatim: "AdditionalProperties are scoped to the message if the update has a MessageId, otherwise they're scoped to the response," implemented as an either/or if (update.MessageId is { Length: > 0 }) { message... } else { response... } — never both.

Result: aligned. The Go change makes Response.Update an exact behavioral port of the upstream either/or scoping (message-only when MessageID != "", response-only when empty), fixing a prior divergence where Go copied to both targets unconditionally. This is a pure bugfix restoring parity with .NET; no public Go API was added, removed, or changed, and the fix does not require any corresponding gate/option since upstream has none either — this is unconditional behavior in both implementations. Test coverage (TestResponse_Update_AdditionalPropertiesScopedByMessageID) matches the upstream either/or semantics.

No public-api-change label needed (no exported API changed). Recommending parity-approved.

Generated by Go API Consistency Review Agent · copilot · auto · 27.5 AIC · ⌖ 13.3 AIC · ⊞ 9.2K ·

@github-actions github-actions Bot added the parity-approved Go API consistency review found no parity issues label Sep 21, 2026
@qmuntal
Quim Muntal (qmuntal) added this pull request to the merge queue Sep 21, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:agent Changes files in the agent area kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure parity-approved Go API consistency review found no parity issues size:medium At most 100 changed lines across at most 5 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants