spec: type chat completion choices, so reading the reply needs no cast

`ChatCompletionResponse.choices` was `items: { type: object }`. Every generator
projects that as the language's untyped bag — `Array<object>` in TypeScript,
`List[object]` in Python — so the one line every SDK user writes first,

    choices[0].message.content

did not compile without a cast, on the most-called route in the API. The gate
that caught it is the new TypeScript chat example:

    examples/chat/index.ts(25,36): error TS2339:
      Property 'message' does not exist on type 'object'.

`ChatChoice` is not a guess about the wire. The route's own tag is "OpenAI
Compatible", `index`/`message`/`finish_reason` is that contract, and `message`
is the ChatMessage this file already defines and already accepts on the REQUEST
side — the response was simply never pointed at it.

merge.py: 1132 paths, 1519 operations, 779 schemas (+1), 0 missing responses.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-07-30 22:58:03 -07:00
co-authored by Hanzo Dev
parent 89e781199b
commit 751c7280aa
2 changed files with 32 additions and 2 deletions
+17 -1
View File
@@ -5898,6 +5898,22 @@ components:
tool_calls:
type: array
items: { type: object }
ChatChoice:
title: ChatChoice
# The one field of the one route every SDK user calls first. As a bare
# `type: object` it generated `Array<object>` / `List[object]`, so reading
# the reply — choices[0].message.content, the whole point of the call —
# needed a cast in every language, on the endpoint we most want to feel
# typed. This is not a guess about the wire: the route is
# OpenAI-compatible (that is its tag), and `message` is the ChatMessage
# already defined above and already accepted on the request.
type: object
properties:
index: { type: integer }
message: { $ref: '#/components/schemas/ChatMessage' }
finish_reason:
type: string
examples: [stop, length, tool_calls, content_filter]
ChatCompletionResponse:
title: ChatCompletionResponse
type: object
@@ -5908,7 +5924,7 @@ components:
model: { type: string }
choices:
type: array
items: { type: object }
items: { $ref: '#/components/schemas/ChatChoice' }
usage: { $ref: '#/components/schemas/Usage' }
CompletionRequest:
title: CompletionRequest
+15 -1
View File
@@ -40292,6 +40292,20 @@ components:
type: string
serviceAccountId:
type: string
ai_ChatChoice:
type: object
properties:
index:
type: integer
message:
$ref: '#/components/schemas/ai_ChatMessage'
finish_reason:
type: string
examples:
- stop
- length
- tool_calls
- content_filter
ai_ChatCompletionRequest:
type: object
required:
@@ -40334,7 +40348,7 @@ components:
choices:
type: array
items:
type: object
$ref: '#/components/schemas/ai_ChatChoice'
usage:
$ref: '#/components/schemas/ai_Usage'
ai_ChatMessage: