fix: restore chat completion multi-choice support#672
Conversation
Greptile SummaryThis PR restores multi-choice support for chat completions by introducing
|
| Filename | Overview |
|---|---|
| packages/data-designer-engine/src/data_designer/engine/models/clients/types.py | Adds ChatCompletionChoice, n field on ChatCompletionRequest, choices list + messages property + __post_init__ on ChatCompletionResponse; backward-compat preserved via __post_init__ seeding choices from message when none are supplied. |
| packages/data-designer-engine/src/data_designer/engine/models/clients/parsing.py | Refactors both sync and async parsers to iterate over all choices; introduces clean symmetric helpers for normalizing, parsing, and extracting choice fields. |
| packages/data-designer-engine/src/data_designer/engine/models/facade.py | Adds n to _COMPLETION_REQUEST_FIELDS so completion() forwards it; strips n in generate() and agenerate() since those methods only consume a single parsed result. |
| packages/data-designer-engine/src/data_designer/engine/models/clients/adapters/anthropic.py | Adds n to the Anthropic exclusion list so it is never forwarded to Anthropic's API. |
| packages/data-designer-engine/src/data_designer/engine/models/clients/init.py | Exports the new ChatCompletionChoice type from the package's public surface. |
Sequence Diagram
sequenceDiagram
participant Caller
participant ModelFacade
participant ModelClient
participant Parser as parse_chat_completion_response
Note over Caller,Parser: completion() path — n is forwarded
Caller->>ModelFacade: "completion(messages, n=4)"
ModelFacade->>ModelFacade: consolidate_kwargs → n kept
ModelFacade->>ModelFacade: "_build_chat_completion_request → ChatCompletionRequest(n=4)"
ModelFacade->>ModelClient: client.completion(request)
ModelClient->>Parser: parse_chat_completion_response(raw)
Parser->>Parser: normalize_choice_list → [c0, c1, c2, c3]
Parser->>Parser: parse_chat_completion_choice × 4
Parser-->>ModelClient: "ChatCompletionResponse(message=c0.message, choices=[c0..c3])"
ModelClient-->>ModelFacade: response
ModelFacade-->>Caller: response.message (first) or response.choices[i]
Note over Caller,Parser: generate() path — n is stripped
Caller->>ModelFacade: "generate(prompt, n=4)"
ModelFacade->>ModelFacade: completion_kwargs.pop(n) → n removed
ModelFacade->>ModelFacade: completion(messages) [no n]
ModelFacade-->>Caller: (parsed_output, messages)
Note over Caller,Parser: Anthropic path — n excluded from body
Caller->>ModelFacade: "completion(messages, n=4)"
ModelFacade->>ModelClient: "AnthropicClient.completion(request with n=4)"
ModelClient->>ModelClient: "TransportKwargs.from_request(request, exclude={n})"
ModelClient-->>ModelFacade: response (n never sent to Anthropic API)
Reviews (3): Last reviewed commit: "strip n from generate requests" | Re-trigger Greptile
Review: PR #672 — fix: restore chat completion multi-choice supportSummaryThe PR restores chat-completion multi-choice support (issue #620) by:
The change is well-scoped and backward-compatible. Existing single-choice callers continue to work via FindingsCorrectness
API design
Tests
Style / conventions
Performance / security
Structural ImpactNo pre-computed structural impact analysis was available ( VerdictApprove with minor follow-ups. The core change is clean, backward-compatible, and well-tested for the sync OpenAI-compatible path. The two items I'd most like to see addressed before merge:
Nice-to-have: async multi-choice parsing test, soft validation of |
|
Addressed the feedback in
Validation:
|
Restore the chat completion n request field and preserve all returned choices in the canonical response while keeping response.message as the first choice. Add coverage for request forwarding, compatibility access, multi-choice parsing, and generate forwarding. Fixes #620 Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Prevent generate and agenerate from forwarding multi-choice requests that they cannot expose, while keeping completion() multi-choice support intact. Add coverage for async parsing and Anthropic n exclusion. Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
b2e22f7 to
a0e0fc0
Compare
📋 Summary
Restores chat completion multi-choice compatibility by reintroducing the
nrequest field and preserving all returned choices in the canonical response. Existing single-choice callers can continue usingresponse.message, while callers that request multiple completions can useresponse.choices.🔗 Related Issue
Fixes #620
🔄 Changes
ChatCompletionRequest.nand export a newChatCompletionChoiceresponse type.ChatCompletionResponse.choices, while keepingresponse.messageas the first choice for existing callers.nthroughModelFacade.completion()and OpenAI-compatible transport bodies, while excluding it from Anthropic request forwarding.nfromgenerate()andagenerate()before delegating to completion because those APIs return one parsed result.nexclusion, andgenerate(..., n=...)stripping.🔍 Attention Areas
types.py— updates the canonical chat completion response contract while preservingresponse.message.facade.py—completion(..., n=...)exposes multiple choices, whilegenerate(..., n=...)stripsnbecause it returns a single parsed result.🧪 Testing
make testpasses (not run; focused model suite was run instead)PYTHONPATH=packages/data-designer-config/src:packages/data-designer-engine/src:packages/data-designer/src uv run --group dev pytest packages/data-designer-engine/tests/engine/models -qpasses (532 passed)uv run --group dev ruff check ...passes for touched files✅ Checklist