Skip to content

[dotnet-port-api] Add Response.ModelID - #1156

Open
PratikDhanave (PratikDhanave) wants to merge 1 commit into
microsoft:mainfrom
PratikDhanaveFork:feat/response-modelid
Open

PratikDhanave (PratikDhanave) wants to merge 1 commit into
microsoft:mainfrom
PratikDhanaveFork:feat/response-modelid

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

Implements #1140.

M.E.AI ChatResponse/ChatResponseUpdate carry a ModelId that ProcessUpdate folds onto the response. Go had no canonical, provider-agnostic way to read which model produced a response — it was only surfaced ad hoc via provider AdditionalProperties.

Change

  • Add ModelID to agent.Response and agent.ResponseUpdate.
  • Fold it in Response.Update (like ResponseID/FinishReason) and propagate it in ToUpdates.
  • Populate it from the model on the response in the OpenAI (chat + responses), Anthropic, and Gemini providers.

ConversationID from the issue is intentionally omitted: Go conversation identity lives on Session.ServiceID, so a separate field would be redundant.

Tests

  • TestResponse_Update_ModelID: ModelID folds from a later update and round-trips through ToUpdates.
  • TestChatModelIDSurfaced: the OpenAI chat provider surfaces the response model on Response.ModelID.

Response and ResponseUpdate now carry ModelID, the identifier of the model
that produced the response, matching M.E.AI ChatResponse/ChatResponseUpdate
(ProcessUpdate folds ModelId). Response.Update folds it like ResponseID, and
ToUpdates round-trips it. The OpenAI (chat + responses), Anthropic, and Gemini
providers populate it from the model on the response.

ConversationID is intentionally not added: in Go the conversation identity
lives on Session.ServiceID, so a separate field would be redundant.

Implements microsoft#1140.
Copilot AI lite review requested due to automatic review settings September 22, 2026 05:22
@github-actions github-actions Bot added area:agent Changes files in the agent area area:provider Changes files in the provider area area:provider/anthropic Changes files in the provider / anthropic area area:provider/gemini Changes files in the provider / gemini area area:provider/openai Changes files in the provider / openai area size:large At most 300 changed lines across at most 10 files labels Sep 22, 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

🟡 Changes recommended

Streaming model IDs and metadata-only round-tripping remain incomplete.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 4 Medium severity

Open (4)
What changed in this PR

Adds provider-agnostic ModelID fields to agent responses and response updates, with provider mappings and folding support.

Changes:

  • Adds and propagates ModelID.
  • Surfaces model IDs across OpenAI, Anthropic, and Gemini providers.
  • Adds response and OpenAI chat tests.
File Reviewed changes
provider/​openaiprovider/​responses.go Non-streaming model ID is populated; streaming updates still omit it.
provider/​openaiprovider/​chat.go Surfaces the model ID for chat responses.
provider/​openaiprovider/​chat_test.go Tests OpenAI chat model ID exposure.
provider/​geminiprovider/​agent.go Non-streaming model ID is populated; streaming updates still omit it.
provider/​anthropicprovider/​agent.go Non-streaming model ID is populated; streaming updates still omit it.
agent/​response.go Adds and folds ModelID; metadata-only updates omit it during round-tripping.
agent/​response_test.go Tests model ID folding and round-tripping.

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

Comment thread agent/response.go
AgentID: resp.AgentID,
MessageID: msg.ID,
ResponseID: resp.ID,
ModelID: resp.ModelID,
Role: message.RoleAssistant,
MessageID: resp.ID,
ResponseID: resp.ID,
ModelID: string(resp.Model),
yield(&agent.ResponseUpdate{
Contents: responseContents,
Role: message.RoleAssistant,
ModelID: resp.ModelVersion,

currentUpdate := &agent.ResponseUpdate{
ResponseID: resp.ID,
ModelID: resp.Model,
@github-actions github-actions Bot added kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure labels Sep 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Scope: public API

Changed Go contract: ModelID added to exported agent.Response and agent.ResponseUpdate struct fields; folded in Response.Update/ToUpdates; populated by the OpenAI (chat + responses), Anthropic, and Gemini providers.

Upstream evidence reviewed:

  • .NET: dotnet/src/Microsoft.Agents.AI.Abstractions/AgentResponse.cs and AgentResponseUpdate.cs (no ModelId property); dotnet/src/Microsoft.Agents.AI/ChatClient/AIAgentChatClient.cs:368 (ModelId folded only on ChatResponse via CloneWithConversationId); dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentResponseUpdateTests.cs:42 (ModelId present on ChatResponseUpdate fixture, not asserted on AgentResponseUpdate).
  • Python: python/packages/core/agent_framework/_types.py — AgentResponse.__init__ (~line 2848) and AgentResponseUpdate.__init__ (~line 3134) have no model/model_id parameter, while sibling ChatResponse.__init__ (~line 2449) and ChatResponseUpdate.__init__ (~line 2735) do.

Result: findings reported. Both upstream .NET and Python implementations intentionally keep model identity on the lower-level ChatResponse/ChatResponseUpdate types and omit it from the agent-level AgentResponse/AgentResponseUpdate contract that Go's agent.Response/ResponseUpdate mirror. This PR adds ModelID directly to the agent-level Go types, which is a parity divergence rather than an idiomatic naming difference — see inline comment on agent/response.go for detail and suggested resolution (confirm as an intentional Go-specific enhancement and document it, or rescope to a future chat-level type). public-api-change label added since this PR adds new exported struct fields.

Generated by Go API Consistency Review Agent · copilot · auto · 98.2 AIC · ⌖ 5.96 AIC · ⊞ 9.2K · ◷

@github-actions github-actions Bot added the public-api-change Pull Request changes public APIs label Sep 22, 2026

@github-actions github-actions Bot 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.

Generated by Go API Consistency Review Agent · copilot · auto · 98.2 AIC · ⌖ 5.96 AIC · ⊞ 9.2K

Comment thread agent/response.go

// ModelID is the identifier of the model that produced this response, when
// the provider supplies it. It is empty otherwise.
ModelID string `json:",omitzero"`

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.

This PR adds ModelID to agent.Response/agent.ResponseUpdate (the Go equivalent of upstream AgentResponse/AgentResponseUpdate, not ChatResponse/ChatResponseUpdate). Upstream, ModelId/model exists only on the lower-level ChatResponse/ChatResponseUpdate types:

  • .NET: Microsoft.Agents.AI.Abstractions/AgentResponse.cs and AgentResponseUpdate.cs have no ModelId property (properties are AgentId, ResponseId, ContinuationToken, CreatedAt, FinishReason, Usage, RawRepresentation, AdditionalProperties). ModelId is folded only in AIAgentChatClient.CloneWithConversationId on ChatResponse (dotnet/src/Microsoft.Agents.AI/ChatClient/AIAgentChatClient.cs:368), and referenced in AgentResponseUpdateTests.ConstructorWithChatResponseUpdateRoundtrips (dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AgentResponseUpdateTests.cs:42) as a ChatResponseUpdate field that is not asserted to roundtrip onto AgentResponseUpdate.
  • Python: AgentResponse.__init__/AgentResponseUpdate.__init__ (python/packages/core/agent_framework/_types.py:2848 and :3134) take no model/model_id parameter, while the sibling ChatResponse.__init__/ChatResponseUpdate.__init__ (same file, :2449 and :2735) do.

So both upstream implementations deliberately keep model identity at the chat-client layer and omit it from the agent-level response contract. Adding ModelID unconditionally to Go's agent.Response/ResponseUpdate (the AgentResponse analog) is a divergence from that design, not merely an idiomatic Go difference — it's a new agent-level field neither upstream implementation exposes.

Suggested resolution: either (a) confirm with maintainers this is an intentional Go-specific enhancement over the agent-level contract (and document that divergence), or (b) if a ModelID surface is wanted, scope it to a chat-level type analogous to ChatResponse/ChatResponseUpdate if/when Go introduces one, rather than agent.Response.

@qmuntal Quim Muntal (qmuntal) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Fix review comments.

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 area:provider/anthropic Changes files in the provider / anthropic area area:provider/gemini Changes files in the provider / gemini area area:provider/openai Changes files in the provider / openai area area:provider Changes files in the provider area kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure public-api-change Pull Request changes public APIs size:large At most 300 changed lines across at most 10 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants