1
1
import {
2
2
ChatCompletionCreateParamsWithModel ,
3
+ ClientTypeChatCompletionRequestOptions ,
3
4
GenericChatCompletion ,
4
5
GenericClient ,
5
6
InstructorConfig ,
8
9
ReturnTypeBasedOnParams
9
10
} from "@/types"
10
11
import OpenAI from "openai"
11
- import { z } from "zod"
12
+ import { z , ZodError } from "zod"
12
13
import ZodStream , { OAIResponseParser , OAIStream , withResponseModel , type Mode } from "zod-stream"
13
14
import { fromZodError } from "zod-validation-error"
14
15
@@ -102,11 +103,14 @@ class Instructor<C extends GenericClient | OpenAI> {
102
103
}
103
104
}
104
105
105
- private async chatCompletionStandard < T extends z . AnyZodObject > ( {
106
- max_retries = MAX_RETRIES_DEFAULT ,
107
- response_model,
108
- ...params
109
- } : ChatCompletionCreateParamsWithModel < T > ) : Promise < z . infer < T > > {
106
+ private async chatCompletionStandard < T extends z . AnyZodObject > (
107
+ {
108
+ max_retries = MAX_RETRIES_DEFAULT ,
109
+ response_model,
110
+ ...params
111
+ } : ChatCompletionCreateParamsWithModel < T > ,
112
+ requestOptions ?: ClientTypeChatCompletionRequestOptions < C >
113
+ ) : Promise < z . infer < T > > {
110
114
let attempts = 0
111
115
let validationIssues = ""
112
116
let lastMessage : OpenAI . ChatCompletionMessageParam | null = null
@@ -147,13 +151,17 @@ class Instructor<C extends GenericClient | OpenAI> {
147
151
148
152
try {
149
153
if ( this . client . chat ?. completions ?. create ) {
150
- const result = await this . client . chat . completions . create ( {
151
- ...resolvedParams ,
152
- stream : false
153
- } )
154
+ const result = await this . client . chat . completions . create (
155
+ {
156
+ ...resolvedParams ,
157
+ stream : false
158
+ } ,
159
+ requestOptions
160
+ )
161
+
154
162
completion = result as GenericChatCompletion < typeof result >
155
163
} else {
156
- throw new Error ( "Unsupported client type" )
164
+ throw new Error ( "Unsupported client type -- no completion method found. " )
157
165
}
158
166
this . log ( "debug" , "raw standard completion response: " , completion )
159
167
} catch ( error ) {
@@ -176,7 +184,17 @@ class Instructor<C extends GenericClient | OpenAI> {
176
184
const data = JSON . parse ( parsedCompletion ) as z . infer < T > & { _meta ?: CompletionMeta }
177
185
return { ...data , _meta : { usage : completion ?. usage ?? undefined } }
178
186
} catch ( error ) {
179
- this . log ( "error" , "failed to parse completion" , parsedCompletion , this . mode )
187
+ this . log (
188
+ "error" ,
189
+ "failed to parse completion" ,
190
+ parsedCompletion ,
191
+ this . mode ,
192
+ "attempt: " ,
193
+ attempts ,
194
+ "max attempts: " ,
195
+ max_retries
196
+ )
197
+
180
198
throw error
181
199
}
182
200
}
@@ -202,26 +220,38 @@ class Instructor<C extends GenericClient | OpenAI> {
202
220
throw new Error ( "Validation failed." )
203
221
}
204
222
}
223
+
205
224
return validation . data
206
225
} catch ( error ) {
226
+ if ( ! ( error instanceof ZodError ) ) {
227
+ throw error
228
+ }
229
+
207
230
if ( attempts < max_retries ) {
208
231
this . log (
209
232
"debug" ,
210
233
`response model: ${ response_model . name } - Retrying, attempt: ` ,
211
234
attempts
212
235
)
236
+
213
237
this . log (
214
238
"warn" ,
215
239
`response model: ${ response_model . name } - Validation issues: ` ,
216
- validationIssues
240
+ validationIssues ,
241
+ " - Attempt: " ,
242
+ attempts ,
243
+ " - Max attempts: " ,
244
+ max_retries
217
245
)
246
+
218
247
attempts ++
219
248
return await makeCompletionCallWithRetries ( )
220
249
} else {
221
250
this . log (
222
251
"debug" ,
223
252
`response model: ${ response_model . name } - Max attempts reached: ${ attempts } `
224
253
)
254
+
225
255
this . log (
226
256
"error" ,
227
257
`response model: ${ response_model . name } - Validation issues: ` ,
@@ -236,13 +266,10 @@ class Instructor<C extends GenericClient | OpenAI> {
236
266
return makeCompletionCallWithRetries ( )
237
267
}
238
268
239
- private async chatCompletionStream < T extends z . AnyZodObject > ( {
240
- max_retries,
241
- response_model,
242
- ...params
243
- } : ChatCompletionCreateParamsWithModel < T > ) : Promise <
244
- AsyncGenerator < Partial < T > & { _meta ?: CompletionMeta } , void , unknown >
245
- > {
269
+ private async chatCompletionStream < T extends z . AnyZodObject > (
270
+ { max_retries, response_model, ...params } : ChatCompletionCreateParamsWithModel < T > ,
271
+ requestOptions ?: ClientTypeChatCompletionRequestOptions < C >
272
+ ) : Promise < AsyncGenerator < Partial < T > & { _meta ?: CompletionMeta } , void , unknown > > {
246
273
if ( max_retries ) {
247
274
this . log ( "warn" , "max_retries is not supported for streaming completions" )
248
275
}
@@ -269,10 +296,13 @@ class Instructor<C extends GenericClient | OpenAI> {
269
296
return streamClient . create ( {
270
297
completionPromise : async ( ) => {
271
298
if ( this . client . chat ?. completions ?. create ) {
272
- const completion = await this . client . chat . completions . create ( {
273
- ...completionParams ,
274
- stream : true
275
- } )
299
+ const completion = await this . client . chat . completions . create (
300
+ {
301
+ ...completionParams ,
302
+ stream : true
303
+ } ,
304
+ requestOptions
305
+ )
276
306
277
307
this . log ( "debug" , "raw stream completion response: " , completion )
278
308
@@ -306,18 +336,19 @@ class Instructor<C extends GenericClient | OpenAI> {
306
336
P extends T extends z . AnyZodObject ? ChatCompletionCreateParamsWithModel < T >
307
337
: ClientTypeChatCompletionParams < OpenAILikeClient < C > > & { response_model : never }
308
338
> (
309
- params : P
339
+ params : P ,
340
+ requestOptions ?: ClientTypeChatCompletionRequestOptions < C >
310
341
) : Promise < ReturnTypeBasedOnParams < typeof this . client , P > > => {
311
342
this . validateModelModeSupport ( params )
312
343
313
344
if ( this . isChatCompletionCreateParamsWithModel ( params ) ) {
314
345
if ( params . stream ) {
315
- return this . chatCompletionStream ( params ) as ReturnTypeBasedOnParams <
346
+ return this . chatCompletionStream ( params , requestOptions ) as ReturnTypeBasedOnParams <
316
347
typeof this . client ,
317
348
P & { stream : true }
318
349
>
319
350
} else {
320
- return this . chatCompletionStandard ( params ) as ReturnTypeBasedOnParams <
351
+ return this . chatCompletionStandard ( params , requestOptions ) as ReturnTypeBasedOnParams <
321
352
typeof this . client ,
322
353
P
323
354
>
@@ -326,8 +357,8 @@ class Instructor<C extends GenericClient | OpenAI> {
326
357
if ( this . client . chat ?. completions ?. create ) {
327
358
const result =
328
359
this . isStandardStream ( params ) ?
329
- await this . client . chat . completions . create ( params )
330
- : await this . client . chat . completions . create ( params )
360
+ await this . client . chat . completions . create ( params , requestOptions )
361
+ : await this . client . chat . completions . create ( params , requestOptions )
331
362
332
363
return result as unknown as ReturnTypeBasedOnParams < OpenAILikeClient < C > , P >
333
364
} else {
0 commit comments