Skip to content

Improve Dev experience with object style access for response models - #48363

Draft
Shivakishore14 wants to merge 3 commits into
Azure:mainfrom
Shivakishore14:sshiva/responses-option1-object-models
Draft

Improve Dev experience with object style access for response models#48363
Shivakishore14 wants to merge 3 commits into
Azure:mainfrom
Shivakishore14:sshiva/responses-option1-object-models

Conversation

@Shivakishore14

@Shivakishore14 Shivakishore14 commented Jul 30, 2026

Copy link
Copy Markdown
Member

Summary

This PR restores object-style ergonomics for public Responses protocol response models while keeping the TypedDict/wire-native direction for request payloads and internal processing.

The TypedDict migration changes both request and response construction compared with the pre-TypedDict generated model stack:

  • Before TypedDict: CreateResponse(...), ItemMessage(...), and ResponseObject(...) all returned generated model objects with attribute access.
  • With pure TypedDict: all of those constructors return plain dictionaries.
  • With this PR: request payloads such as CreateResponse(...) remain plain dictionaries, while response protocol payloads such as ItemMessage(...) and ResponseObject(...) regain dict-backed object access.

This keeps the useful part of the TypedDict approach and adds a thin compatibility layer for response payloads:

  • request payloads such as CreateResponse remain dict-native
  • response protocol model exports are backed by lightweight ResponseModel objects
  • response models support attribute access, e.g. item.content[0].text
  • response models remain dict-compatible and can be converted with to_dict() / as_dict()
  • wire serialization still normalizes models back to JSON-compatible dictionaries via to_wire_dict()

Before and after

Request construction

Request construction is intentionally changed from generated model object to dict-native payload:

# Before TypedDict emitter changes
request = CreateResponse(model="test-model", input="hello")
model = request.model

# After TypedDict emitter changes (current state: unchanged)
request = CreateResponse(model="test-model", input="hello")
model = request["model"]

This aligns with the OpenAI Python SDK pattern where request parameters are TypedDict-like.

Response model construction

Response model construction keeps the pre-TypedDict object-style ergonomics while remaining wire-serializable:

response = ResponseObject(
    id="resp_123",
    status="completed",
    output=[
        ItemMessage(
            type="message",
            role="assistant",
            content=[MessageContentInputTextContent(type="input_text", text="hello")],
        )
    ],
)

text = response.output[0].content[0].text
wire_payload = response.to_dict()

Why

The Responses package is a protocol/server framework, so JSON-shaped internal payloads are valuable for validation, persistence, streaming, replay, SSE, and storage serialization. However, requiring users to inspect response payloads through deeply nested dictionary access is a reduced SDK experience:

text = item["content"][0]["text"]

With this PR, public response payloads can keep the more familiar object-style access:

text = item.content[0].text

This better matches the OpenAI Python SDK split where request parameters are TypedDict-like, but response objects provide runtime model ergonomics.

Changes

  • Added ResponseModel, a dictionary-backed object model with:
    • attribute access
    • recursive wrapping for nested mappings/lists
    • to_dict() and as_dict() helpers
  • Updated azure.ai.agentserver.responses.models exports so generated response-shape classes are replaced by named ResponseModel subclasses.
  • Preserved request payload classes such as CreateResponse as plain dict-native TypedDict constructors.
  • Updated wire helpers to read attribute-backed values and serialize model helpers back to plain wire dictionaries.
  • Updated the changelog migration guide to describe both request construction and response model construction.
  • Added focused unit tests for request dict behavior, response attribute access, and wire serialization.

Validation

Ran targeted tests from sdk/agentserver/azure-ai-agentserver-responses:

PYTHONPATH=.:../azure-ai-agentserver-core:../../core/azure-core \
  python -m pytest tests/unit/test_object_model_ergonomics.py tests/unit/test_string_content_expansion.py -q

Result:

16 passed

Keep request payloads dict-native while exposing response protocol models as dict-backed objects with attribute access and dictionary conversion helpers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added the Hosted Agents sdk/agentserver/* label Jul 30, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Clarify that CreateResponse construction now returns a dict-native request payload while response models retain object-style access.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Shivakishore14 Shivakishore14 changed the title Restore Responses SDK response model ergonomics Improve Dev experience with object style access for response models Jul 30, 2026
Cover multi-turn scenarios where response model output is passed into a later CreateResponse payload and normalized back to wire dictionaries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Hosted Agents sdk/agentserver/*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant