* Generate structured output using the provider's native JSON Schema response format. * Uses stream: false to get the complete response in one call. * * OpenAI-compatible Responses APIs have strict requirements for structured output: * - All properties must be in the `required` array
(
options: StructuredOutputOptions<TProviderOptions>,
)
| 178 | * We apply provider-specific transformations for structured output compatibility. |
| 179 | */ |
| 180 | async structuredOutput( |
| 181 | options: StructuredOutputOptions<TProviderOptions>, |
| 182 | ): Promise<StructuredOutputResult<unknown>> { |
| 183 | const { chatOptions, outputSchema } = options |
| 184 | const requestParams = this.mapOptionsToRequest(chatOptions) |
| 185 | |
| 186 | // Apply provider-specific transformations for structured output compatibility |
| 187 | const jsonSchema = this.makeStructuredOutputCompatible( |
| 188 | outputSchema, |
| 189 | outputSchema.required, |
| 190 | ) |
| 191 | |
| 192 | try { |
| 193 | // Strip streaming-only fields a subclass override of mapOptionsToRequest |
| 194 | // might have returned (parallel to chat-completions's structuredOutput |
| 195 | // cleanup) — sending stream_options to a non-streaming call is a 4xx. |
| 196 | const { |
| 197 | stream: _stream, |
| 198 | stream_options: _streamOptions, |
| 199 | ...cleanParams |
| 200 | } = requestParams as Record<string, unknown> |
| 201 | void _stream |
| 202 | void _streamOptions |
| 203 | chatOptions.logger.request( |
| 204 | `activity=structuredOutput provider=${this.name} model=${this.model} messages=${chatOptions.messages.length}`, |
| 205 | { provider: this.name, model: this.model }, |
| 206 | ) |
| 207 | const response = await this.client.responses.create( |
| 208 | { |
| 209 | ...(cleanParams as Omit<ResponseCreateParams, 'stream'>), |
| 210 | stream: false, |
| 211 | // Configure structured output via text.format |
| 212 | text: { |
| 213 | format: { |
| 214 | type: 'json_schema', |
| 215 | name: 'structured_output', |
| 216 | schema: jsonSchema, |
| 217 | strict: true, |
| 218 | }, |
| 219 | }, |
| 220 | }, |
| 221 | extractRequestOptions(chatOptions.request), |
| 222 | ) |
| 223 | |
| 224 | // Extract text content from the response. `stream: false` narrows the |
| 225 | // SDK return type to `Response`, but the explicit annotation makes |
| 226 | // that contract local rather than relying on inference through the |
| 227 | // overloaded `client.responses.create` signature. |
| 228 | const rawText = this.extractTextFromResponse(response satisfies Response) |
| 229 | |
| 230 | // Fail loud on empty content rather than letting it cascade into a |
| 231 | // confusing "Failed to parse JSON. Content: " error — the root cause |
| 232 | // (the model returned no text content for the structured request) is |
| 233 | // then visible in logs. Mirrors the chat-completions sibling. |
| 234 | if (rawText.length === 0) { |
| 235 | throw new Error( |
| 236 | `${this.name}.structuredOutput: response contained no content`, |
| 237 | ) |
nothing calls this directly
no test coverage detected