@hebo-ai/gateway 0.4.0-alpha.2 → 0.4.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -209,7 +209,7 @@ Out-of-the-box model presets:
209
209
  Nova: `nova` (`v1`, `v2`, `v1.x`, `v2.x`, `latest`, `embeddings`, `all`)
210
210
 
211
211
  - **Anthropic** — `@hebo-ai/gateway/models/anthropic`
212
- Claude: `claude` (`v4.5`, `v4.1`, `v4`, `v3.7`, `v3.5`, `v3`, `v4.x`, `v3.x`, `haiku`, `sonnet`, `opus`, `latest`, `all`)
212
+ Claude: `claude` (`v4.6`, `v4.5`, `v4.1`, `v4`, `v3.7`, `v3.5`, `v3`, `v4.x`, `v3.x`, `haiku`, `sonnet`, `opus`, `latest`, `all`)
213
213
 
214
214
  - **Cohere** — `@hebo-ai/gateway/models/cohere`
215
215
  Command: `command` (`A`, `R`, `latest`, `all`)
@@ -222,7 +222,7 @@ Out-of-the-box model presets:
222
222
  Llama: `llama` (`v3.1`, `v3.2`, `v3.3`, `v4`, `v3.x`, `v4.x`, `latest`, `all`)
223
223
 
224
224
  - **OpenAI** — `@hebo-ai/gateway/models/openai`
225
- GPT: `gpt` (`v5`, `v5.1`, `v5.2`, `v5.x`, `chat`, `codex`, `pro`, `latest`, `all`)
225
+ GPT: `gpt` (`v5`, `v5.1`, `v5.2`, `v5.3`, `v5.x`, `chat`, `codex`, `pro`, `latest`, `all`)
226
226
  GPT-OSS: `gptOss` (`v1`, `v1.x`, `latest`, `all`)
227
227
  Embeddings: `textEmbeddings` (`v3`, `v3.x`, `latest`, `all`)
228
228
 
@@ -349,8 +349,8 @@ const gw = gateway({
349
349
  * @returns Modified result, or undefined to keep original.
350
350
  */
351
351
  after: async (ctx: {
352
- result: ChatCompletions | ReadableStream<ChatCompletionsChunk | OpenAIError> | Embeddings | object
353
- }): Promise<ChatCompletions | ReadableStream<ChatCompletionsChunk | OpenAIError> | Embeddings | object | void> => {
352
+ result: ChatCompletions | ReadableStream<ChatCompletionsChunk | OpenAIError> | Embeddings
353
+ }): Promise<ChatCompletions | ReadableStream<ChatCompletionsChunk | OpenAIError> | Embeddings | void> => {
354
354
  // Example Use Cases:
355
355
  // - Transform result
356
356
  // - Result logging
@@ -555,6 +555,15 @@ Reasoning output is surfaced as extension to the `completion` object.
555
555
 
556
556
  Most SDKs handle these fields out-of-the-box.
557
557
 
558
+ #### Thinking Blocks & Context Preservation
559
+
560
+ Advanced models (like Anthropic Claude 3.7 or Gemini 3) surface structured reasoning steps and signatures that act as a "save state" for the model's internal reasoning process. To maintain this context across multi-turn conversations and tool-calling workflows, you should pass back the following extensions in subsequent messages:
561
+
562
+ - **reasoning_details**: Standardized array of reasoning steps and generic signatures.
563
+ - **extra_content**: Provider-specific extensions, such as **Google's thought signatures** on Vertex AI.
564
+
565
+ For **Gemini 3** models, returning the thought signature via `extra_content` is mandatory to resume the chain-of-thought; failing to do so may result in errors or degraded performance.
566
+
558
567
  ## 🧪 Advanced Usage
559
568
 
560
569
  ### Logger Settings
@@ -573,7 +582,6 @@ const gw = gateway({
573
582
  ```
574
583
 
575
584
  If you provide a custom logger, it must implement `trace`, `debug`, `info`, `warn`, and `error` methods.
576
- For production workloads, we recommend `pino` for better logging performance and lower overhead.
577
585
 
578
586
  Example with **pino**:
579
587
 
@@ -591,6 +599,9 @@ const gw = gateway({
591
599
  });
592
600
  ```
593
601
 
602
+ > [!TIP]
603
+ > For production workloads, we recommend `pino` for better logging performance and lower overhead.
604
+
594
605
  ### Telemetry Settings
595
606
 
596
607
  Hebo Gateway can forward telemetry settings via the `telemetry` config field.
@@ -610,6 +621,9 @@ const gw = gateway({
610
621
  });
611
622
  ```
612
623
 
624
+ > [!TIP]
625
+ > For observability integration that is not otel compliant (for example, Langfuse), you can disable built-in telemetry and manually instrument requests during `before` / `after` hooks.
626
+
613
627
  ### Passing Framework State to Hooks
614
628
 
615
629
  You can pass per-request info from your framework into the gateway via the second `state` argument on the handler, then read it in hooks through `ctx.state`.
@@ -1,6 +1,6 @@
1
1
  import type { SharedV3ProviderOptions, SharedV3ProviderMetadata } from "@ai-sdk/provider";
2
- import type { GenerateTextResult, StreamTextResult, FinishReason, ToolChoice, ToolSet, ModelMessage, UserContent, LanguageModelUsage, Output, TextStreamPart, AssistantModelMessage, ToolModelMessage, UserModelMessage } from "ai";
3
- import type { ChatCompletionsToolCall, ChatCompletionsTool, ChatCompletionsToolChoice, ChatCompletionsContentPart, ChatCompletionsMessage, ChatCompletionsUserMessage, ChatCompletionsAssistantMessage, ChatCompletionsToolMessage, ChatCompletionsFinishReason, ChatCompletionsUsage, ChatCompletionsInputs, ChatCompletions, ChatCompletionsChunk } from "./schema";
2
+ import type { GenerateTextResult, StreamTextResult, FinishReason, ToolChoice, ToolSet, ModelMessage, UserContent, LanguageModelUsage, Output, TextStreamPart, ReasoningOutput, AssistantModelMessage, ToolModelMessage, UserModelMessage } from "ai";
3
+ import type { ChatCompletionsToolCall, ChatCompletionsTool, ChatCompletionsToolChoice, ChatCompletionsContentPart, ChatCompletionsMessage, ChatCompletionsUserMessage, ChatCompletionsAssistantMessage, ChatCompletionsToolMessage, ChatCompletionsFinishReason, ChatCompletionsUsage, ChatCompletionsInputs, ChatCompletions, ChatCompletionsChunk, ChatCompletionsReasoningDetail } from "./schema";
4
4
  import { OpenAIError } from "../../errors/openai";
5
5
  export type TextCallOptions = {
6
6
  messages: ModelMessage[];
@@ -31,6 +31,7 @@ export declare class ChatCompletionsStream extends TransformStream<TextStreamPar
31
31
  constructor(model: string);
32
32
  }
33
33
  export declare const toChatCompletionsAssistantMessage: (result: GenerateTextResult<ToolSet, Output.Output>) => ChatCompletionsAssistantMessage;
34
+ export declare function toReasoningDetail(reasoning: ReasoningOutput, id: string, index: number): ChatCompletionsReasoningDetail;
34
35
  export declare function toChatCompletionsUsage(usage: LanguageModelUsage): ChatCompletionsUsage;
35
36
  export declare function toChatCompletionsToolCall(id: string, name: string, args: unknown, providerMetadata?: SharedV3ProviderMetadata): ChatCompletionsToolCall;
36
37
  export declare const toChatCompletionsFinishReason: (finishReason: FinishReason) => ChatCompletionsFinishReason;
@@ -61,33 +61,67 @@ export function fromChatCompletionsUserMessage(message) {
61
61
  };
62
62
  }
63
63
  export function fromChatCompletionsAssistantMessage(message) {
64
- const { tool_calls, role, content, extra_content } = message;
65
- if (!tool_calls?.length) {
66
- const out = {
67
- role: role,
68
- content: content ?? "",
69
- };
70
- if (extra_content) {
71
- out.providerOptions = extra_content;
64
+ const { tool_calls, role, content, extra_content, reasoning_details } = message;
65
+ const parts = [];
66
+ if (Array.isArray(parts)) {
67
+ if (reasoning_details?.length) {
68
+ for (const detail of reasoning_details) {
69
+ if (detail.text && detail.type === "reasoning.text") {
70
+ parts.push({
71
+ type: "reasoning",
72
+ text: detail.text,
73
+ providerOptions: detail.signature
74
+ ? {
75
+ unknown: {
76
+ signature: detail.signature,
77
+ },
78
+ }
79
+ : undefined,
80
+ });
81
+ }
82
+ else if (detail.type === "reasoning.encrypted" && detail.data) {
83
+ parts.push({
84
+ type: "reasoning",
85
+ text: "",
86
+ providerOptions: {
87
+ unknown: {
88
+ redactedData: detail.data,
89
+ },
90
+ },
91
+ });
92
+ }
93
+ }
94
+ }
95
+ if (tool_calls?.length) {
96
+ for (const tc of tool_calls) {
97
+ const { id, function: fn, extra_content } = tc;
98
+ const out = {
99
+ type: "tool-call",
100
+ toolCallId: id,
101
+ toolName: fn.name,
102
+ input: parseToolOutput(fn.arguments).value,
103
+ };
104
+ if (extra_content) {
105
+ out.providerOptions = extra_content;
106
+ }
107
+ parts.push(out);
108
+ }
109
+ }
110
+ else if (content !== undefined && content !== null) {
111
+ parts.push({
112
+ type: "text",
113
+ text: content,
114
+ });
72
115
  }
73
- return out;
74
116
  }
75
- return {
117
+ const out = {
76
118
  role: role,
77
- content: tool_calls.map((tc) => {
78
- const { id, function: fn, extra_content } = tc;
79
- const out = {
80
- type: "tool-call",
81
- toolCallId: id,
82
- toolName: fn.name,
83
- input: parseToolOutput(fn.arguments).value,
84
- };
85
- if (extra_content) {
86
- out.providerOptions = extra_content;
87
- }
88
- return out;
89
- }),
119
+ content: Array.isArray(parts) && parts.length > 0 ? parts : (content ?? ""),
90
120
  };
121
+ if (extra_content) {
122
+ out.providerOptions = extra_content;
123
+ }
124
+ return out;
91
125
  }
92
126
  export function fromChatCompletionsToolResultMessage(message, toolById) {
93
127
  const toolCalls = message.tool_calls ?? [];
@@ -251,6 +285,7 @@ export class ChatCompletionsStream extends TransformStream {
251
285
  const streamId = `chatcmpl-${crypto.randomUUID()}`;
252
286
  const creationTime = Math.floor(Date.now() / 1000);
253
287
  let toolCallIndexCounter = 0;
288
+ const reasoningIdToIndex = new Map();
254
289
  const createChunk = (delta, provider_metadata, finish_reason, usage) => {
255
290
  if (provider_metadata) {
256
291
  delta.extra_content = provider_metadata;
@@ -278,7 +313,21 @@ export class ChatCompletionsStream extends TransformStream {
278
313
  break;
279
314
  }
280
315
  case "reasoning-delta": {
281
- controller.enqueue(createChunk({ reasoning_content: part.text }, part.providerMetadata));
316
+ let index = reasoningIdToIndex.get(part.id);
317
+ if (index === undefined) {
318
+ index = reasoningIdToIndex.size;
319
+ reasoningIdToIndex.set(part.id, index);
320
+ }
321
+ controller.enqueue(createChunk({
322
+ reasoning_content: part.text,
323
+ reasoning_details: [
324
+ toReasoningDetail({
325
+ type: "reasoning",
326
+ text: part.text,
327
+ providerMetadata: part.providerMetadata,
328
+ }, part.id, index),
329
+ ],
330
+ }, part.providerMetadata));
282
331
  break;
283
332
  }
284
333
  case "tool-call": {
@@ -316,20 +365,63 @@ export const toChatCompletionsAssistantMessage = (result) => {
316
365
  if (result.toolCalls && result.toolCalls.length > 0) {
317
366
  message.tool_calls = result.toolCalls.map((toolCall) => toChatCompletionsToolCall(toolCall.toolCallId, toolCall.toolName, toolCall.input, toolCall.providerMetadata));
318
367
  }
368
+ const reasoningDetails = [];
319
369
  for (const part of result.content) {
320
370
  if (part.type === "text") {
321
- message.content = part.text;
322
- if (part.providerMetadata) {
323
- message.extra_content = part.providerMetadata;
371
+ if (message.content === null) {
372
+ message.content = part.text;
373
+ if (part.providerMetadata) {
374
+ message.extra_content = part.providerMetadata;
375
+ }
324
376
  }
325
- break;
377
+ }
378
+ else if (part.type === "reasoning") {
379
+ reasoningDetails.push(toReasoningDetail(part, `reasoning-${crypto.randomUUID()}`, reasoningDetails.length));
326
380
  }
327
381
  }
328
382
  if (result.reasoningText) {
329
383
  message.reasoning_content = result.reasoningText;
384
+ if (reasoningDetails.length === 0) {
385
+ reasoningDetails.push(toReasoningDetail({ type: "reasoning", text: result.reasoningText }, `reasoning-${crypto.randomUUID()}`, 0));
386
+ }
387
+ }
388
+ if (reasoningDetails.length > 0) {
389
+ message.reasoning_details = reasoningDetails;
330
390
  }
331
391
  return message;
332
392
  };
393
+ export function toReasoningDetail(reasoning, id, index) {
394
+ const providerMetadata = reasoning.providerMetadata ?? {};
395
+ let redactedData;
396
+ let signature;
397
+ for (const metadata of Object.values(providerMetadata)) {
398
+ if (metadata && typeof metadata === "object") {
399
+ if ("redactedData" in metadata && typeof metadata["redactedData"] === "string") {
400
+ redactedData = metadata["redactedData"];
401
+ }
402
+ if ("signature" in metadata && typeof metadata["signature"] === "string") {
403
+ signature = metadata["signature"];
404
+ }
405
+ }
406
+ }
407
+ if (redactedData) {
408
+ return {
409
+ id,
410
+ index,
411
+ type: "reasoning.encrypted",
412
+ data: redactedData,
413
+ format: "unknown",
414
+ };
415
+ }
416
+ return {
417
+ id,
418
+ index,
419
+ type: "reasoning.text",
420
+ text: reasoning.text,
421
+ signature,
422
+ format: "unknown",
423
+ };
424
+ }
333
425
  export function toChatCompletionsUsage(usage) {
334
426
  const out = {};
335
427
  const prompt = usage.inputTokens;
@@ -57,6 +57,17 @@ export declare const ChatCompletionsUserMessageSchema: z.ZodObject<{
57
57
  name: z.ZodOptional<z.ZodString>;
58
58
  }, z.core.$strip>;
59
59
  export type ChatCompletionsUserMessage = z.infer<typeof ChatCompletionsUserMessageSchema>;
60
+ export declare const ChatCompletionsReasoningDetailSchema: z.ZodObject<{
61
+ id: z.ZodOptional<z.ZodString>;
62
+ index: z.ZodInt;
63
+ type: z.ZodString;
64
+ text: z.ZodOptional<z.ZodString>;
65
+ signature: z.ZodOptional<z.ZodString>;
66
+ data: z.ZodOptional<z.ZodString>;
67
+ summary: z.ZodOptional<z.ZodString>;
68
+ format: z.ZodOptional<z.ZodString>;
69
+ }, z.core.$strip>;
70
+ export type ChatCompletionsReasoningDetail = z.infer<typeof ChatCompletionsReasoningDetailSchema>;
60
71
  export declare const ChatCompletionsAssistantMessageSchema: z.ZodObject<{
61
72
  role: z.ZodLiteral<"assistant">;
62
73
  content: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
@@ -71,6 +82,16 @@ export declare const ChatCompletionsAssistantMessageSchema: z.ZodObject<{
71
82
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
72
83
  }, z.core.$strip>>>;
73
84
  reasoning_content: z.ZodOptional<z.ZodString>;
85
+ reasoning_details: z.ZodOptional<z.ZodArray<z.ZodObject<{
86
+ id: z.ZodOptional<z.ZodString>;
87
+ index: z.ZodInt;
88
+ type: z.ZodString;
89
+ text: z.ZodOptional<z.ZodString>;
90
+ signature: z.ZodOptional<z.ZodString>;
91
+ data: z.ZodOptional<z.ZodString>;
92
+ summary: z.ZodOptional<z.ZodString>;
93
+ format: z.ZodOptional<z.ZodString>;
94
+ }, z.core.$strip>>>;
74
95
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
75
96
  }, z.core.$strip>;
76
97
  export type ChatCompletionsAssistantMessage = z.infer<typeof ChatCompletionsAssistantMessageSchema>;
@@ -118,6 +139,16 @@ export declare const ChatCompletionsMessageSchema: z.ZodUnion<readonly [z.ZodObj
118
139
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
119
140
  }, z.core.$strip>>>;
120
141
  reasoning_content: z.ZodOptional<z.ZodString>;
142
+ reasoning_details: z.ZodOptional<z.ZodArray<z.ZodObject<{
143
+ id: z.ZodOptional<z.ZodString>;
144
+ index: z.ZodInt;
145
+ type: z.ZodString;
146
+ text: z.ZodOptional<z.ZodString>;
147
+ signature: z.ZodOptional<z.ZodString>;
148
+ data: z.ZodOptional<z.ZodString>;
149
+ summary: z.ZodOptional<z.ZodString>;
150
+ format: z.ZodOptional<z.ZodString>;
151
+ }, z.core.$strip>>>;
121
152
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
122
153
  }, z.core.$strip>, z.ZodObject<{
123
154
  role: z.ZodLiteral<"tool">;
@@ -189,6 +220,16 @@ declare const ChatCompletionsInputsSchema: z.ZodObject<{
189
220
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
190
221
  }, z.core.$strip>>>;
191
222
  reasoning_content: z.ZodOptional<z.ZodString>;
223
+ reasoning_details: z.ZodOptional<z.ZodArray<z.ZodObject<{
224
+ id: z.ZodOptional<z.ZodString>;
225
+ index: z.ZodInt;
226
+ type: z.ZodString;
227
+ text: z.ZodOptional<z.ZodString>;
228
+ signature: z.ZodOptional<z.ZodString>;
229
+ data: z.ZodOptional<z.ZodString>;
230
+ summary: z.ZodOptional<z.ZodString>;
231
+ format: z.ZodOptional<z.ZodString>;
232
+ }, z.core.$strip>>>;
192
233
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
193
234
  }, z.core.$strip>, z.ZodObject<{
194
235
  role: z.ZodLiteral<"tool">;
@@ -265,6 +306,16 @@ export declare const ChatCompletionsBodySchema: z.ZodObject<{
265
306
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
266
307
  }, z.core.$strip>>>;
267
308
  reasoning_content: z.ZodOptional<z.ZodString>;
309
+ reasoning_details: z.ZodOptional<z.ZodArray<z.ZodObject<{
310
+ id: z.ZodOptional<z.ZodString>;
311
+ index: z.ZodInt;
312
+ type: z.ZodString;
313
+ text: z.ZodOptional<z.ZodString>;
314
+ signature: z.ZodOptional<z.ZodString>;
315
+ data: z.ZodOptional<z.ZodString>;
316
+ summary: z.ZodOptional<z.ZodString>;
317
+ format: z.ZodOptional<z.ZodString>;
318
+ }, z.core.$strip>>>;
268
319
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
269
320
  }, z.core.$strip>, z.ZodObject<{
270
321
  role: z.ZodLiteral<"tool">;
@@ -322,6 +373,16 @@ export declare const ChatCompletionsChoiceSchema: z.ZodObject<{
322
373
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
323
374
  }, z.core.$strip>>>;
324
375
  reasoning_content: z.ZodOptional<z.ZodString>;
376
+ reasoning_details: z.ZodOptional<z.ZodArray<z.ZodObject<{
377
+ id: z.ZodOptional<z.ZodString>;
378
+ index: z.ZodInt;
379
+ type: z.ZodString;
380
+ text: z.ZodOptional<z.ZodString>;
381
+ signature: z.ZodOptional<z.ZodString>;
382
+ data: z.ZodOptional<z.ZodString>;
383
+ summary: z.ZodOptional<z.ZodString>;
384
+ format: z.ZodOptional<z.ZodString>;
385
+ }, z.core.$strip>>>;
325
386
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
326
387
  }, z.core.$strip>;
327
388
  finish_reason: z.ZodUnion<readonly [z.ZodLiteral<"stop">, z.ZodLiteral<"length">, z.ZodLiteral<"content_filter">, z.ZodLiteral<"tool_calls">]>;
@@ -361,6 +422,16 @@ export declare const ChatCompletionsSchema: z.ZodObject<{
361
422
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
362
423
  }, z.core.$strip>>>;
363
424
  reasoning_content: z.ZodOptional<z.ZodString>;
425
+ reasoning_details: z.ZodOptional<z.ZodArray<z.ZodObject<{
426
+ id: z.ZodOptional<z.ZodString>;
427
+ index: z.ZodInt;
428
+ type: z.ZodString;
429
+ text: z.ZodOptional<z.ZodString>;
430
+ signature: z.ZodOptional<z.ZodString>;
431
+ data: z.ZodOptional<z.ZodString>;
432
+ summary: z.ZodOptional<z.ZodString>;
433
+ format: z.ZodOptional<z.ZodString>;
434
+ }, z.core.$strip>>>;
364
435
  extra_content: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
365
436
  }, z.core.$strip>;
366
437
  finish_reason: z.ZodUnion<readonly [z.ZodLiteral<"stop">, z.ZodLiteral<"length">, z.ZodLiteral<"content_filter">, z.ZodLiteral<"tool_calls">]>;
@@ -396,6 +467,16 @@ export declare const ChatCompletionsAssistantMessageDeltaSchema: z.ZodObject<{
396
467
  content: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>>;
397
468
  name: z.ZodOptional<z.ZodOptional<z.ZodString>>;
398
469
  reasoning_content: z.ZodOptional<z.ZodOptional<z.ZodString>>;
470
+ reasoning_details: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodObject<{
471
+ id: z.ZodOptional<z.ZodString>;
472
+ index: z.ZodInt;
473
+ type: z.ZodString;
474
+ text: z.ZodOptional<z.ZodString>;
475
+ signature: z.ZodOptional<z.ZodString>;
476
+ data: z.ZodOptional<z.ZodString>;
477
+ summary: z.ZodOptional<z.ZodString>;
478
+ format: z.ZodOptional<z.ZodString>;
479
+ }, z.core.$strip>>>>;
399
480
  extra_content: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
400
481
  tool_calls: z.ZodOptional<z.ZodArray<z.ZodObject<{
401
482
  type: z.ZodOptional<z.ZodLiteral<"function">>;
@@ -416,6 +497,16 @@ export declare const ChatCompletionsChoiceDeltaSchema: z.ZodObject<{
416
497
  content: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>>;
417
498
  name: z.ZodOptional<z.ZodOptional<z.ZodString>>;
418
499
  reasoning_content: z.ZodOptional<z.ZodOptional<z.ZodString>>;
500
+ reasoning_details: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodObject<{
501
+ id: z.ZodOptional<z.ZodString>;
502
+ index: z.ZodInt;
503
+ type: z.ZodString;
504
+ text: z.ZodOptional<z.ZodString>;
505
+ signature: z.ZodOptional<z.ZodString>;
506
+ data: z.ZodOptional<z.ZodString>;
507
+ summary: z.ZodOptional<z.ZodString>;
508
+ format: z.ZodOptional<z.ZodString>;
509
+ }, z.core.$strip>>>>;
419
510
  extra_content: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
420
511
  tool_calls: z.ZodOptional<z.ZodArray<z.ZodObject<{
421
512
  type: z.ZodOptional<z.ZodLiteral<"function">>;
@@ -444,6 +535,16 @@ export declare const ChatCompletionsChunkSchema: z.ZodObject<{
444
535
  content: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>>;
445
536
  name: z.ZodOptional<z.ZodOptional<z.ZodString>>;
446
537
  reasoning_content: z.ZodOptional<z.ZodOptional<z.ZodString>>;
538
+ reasoning_details: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodObject<{
539
+ id: z.ZodOptional<z.ZodString>;
540
+ index: z.ZodInt;
541
+ type: z.ZodString;
542
+ text: z.ZodOptional<z.ZodString>;
543
+ signature: z.ZodOptional<z.ZodString>;
544
+ data: z.ZodOptional<z.ZodString>;
545
+ summary: z.ZodOptional<z.ZodString>;
546
+ format: z.ZodOptional<z.ZodString>;
547
+ }, z.core.$strip>>>>;
447
548
  extra_content: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>>;
448
549
  tool_calls: z.ZodOptional<z.ZodArray<z.ZodObject<{
449
550
  type: z.ZodOptional<z.ZodLiteral<"function">>;
@@ -44,6 +44,16 @@ export const ChatCompletionsUserMessageSchema = z.object({
44
44
  ]),
45
45
  name: z.string().optional(),
46
46
  });
47
+ export const ChatCompletionsReasoningDetailSchema = z.object({
48
+ id: z.string().optional(),
49
+ index: z.int().nonnegative(),
50
+ type: z.string(),
51
+ text: z.string().optional(),
52
+ signature: z.string().optional(),
53
+ data: z.string().optional(),
54
+ summary: z.string().optional(),
55
+ format: z.string().optional(),
56
+ });
47
57
  export const ChatCompletionsAssistantMessageSchema = z.object({
48
58
  role: z.literal("assistant"),
49
59
  // FUTURE: this should support arrays of TextContentPart and RefusalContentPart
@@ -53,6 +63,10 @@ export const ChatCompletionsAssistantMessageSchema = z.object({
53
63
  tool_calls: z.array(ChatCompletionsToolCallSchema).optional(),
54
64
  // Extensions
55
65
  reasoning_content: z.string().optional().meta({ extension: true }),
66
+ reasoning_details: z
67
+ .array(ChatCompletionsReasoningDetailSchema)
68
+ .optional()
69
+ .meta({ extension: true }),
56
70
  extra_content: z.record(z.string(), z.any()).optional().meta({ extension: true }),
57
71
  });
58
72
  export const ChatCompletionsToolMessageSchema = z.object({