22
33import type { RequestInit , RequestInfo , BodyInit } from './internal/builtin-types' ;
44import type { HTTPMethod , PromiseOrValue } from './internal/types' ;
5- import { debug } from './internal/utils/log' ;
65import { uuid4 } from './internal/utils/uuid' ;
76import { validatePositiveInteger , isAbsoluteURL } from './internal/utils/values' ;
87import { sleep } from './internal/utils/sleep' ;
@@ -81,6 +80,7 @@ import {
8180 Moderations ,
8281} from './resources/moderations' ;
8382import { readEnv } from './internal/utils/env' ;
83+ import { logger } from './internal/utils/log' ;
8484import { isEmptyObj } from './internal/utils/values' ;
8585import { Audio , AudioModel , AudioResponseFormat } from './resources/audio/audio' ;
8686import { Beta } from './resources/beta/beta' ;
@@ -134,6 +134,25 @@ const safeJSON = (text: string) => {
134134 }
135135} ;
136136
137+ type LogFn = ( message : string , ...rest : unknown [ ] ) => void ;
138+ export type Logger = {
139+ error : LogFn ;
140+ warn : LogFn ;
141+ info : LogFn ;
142+ debug : LogFn ;
143+ } ;
144+ export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug' ;
145+ const isLogLevel = ( key : string | undefined ) : key is LogLevel => {
146+ const levels : Record < LogLevel , true > = {
147+ off : true ,
148+ error : true ,
149+ warn : true ,
150+ info : true ,
151+ debug : true ,
152+ } ;
153+ return key ! in levels ;
154+ } ;
155+
137156export interface ClientOptions {
138157 /**
139158 * Defaults to process.env['OPENAI_API_KEY'].
@@ -210,6 +229,20 @@ export interface ClientOptions {
210229 * Only set this option to `true` if you understand the risks and have appropriate mitigations in place.
211230 */
212231 dangerouslyAllowBrowser ?: boolean ;
232+
233+ /**
234+ * Set the log level.
235+ *
236+ * Defaults to process.env['OPENAI_LOG'].
237+ */
238+ logLevel ?: LogLevel | undefined | null ;
239+
240+ /**
241+ * Set the logger.
242+ *
243+ * Defaults to globalThis.console.
244+ */
245+ logger ?: Logger | undefined | null ;
213246}
214247
215248type FinalizedRequestInit = RequestInit & { headers : Headers } ;
@@ -225,6 +258,8 @@ export class OpenAI {
225258 baseURL : string ;
226259 maxRetries : number ;
227260 timeout : number ;
261+ logger : Logger | undefined ;
262+ logLevel : LogLevel | undefined ;
228263 httpAgent : Shims . Agent | undefined ;
229264
230265 private fetch : Fetch ;
@@ -276,6 +311,15 @@ export class OpenAI {
276311
277312 this . baseURL = options . baseURL ! ;
278313 this . timeout = options . timeout ?? OpenAI . DEFAULT_TIMEOUT /* 10 minutes */ ;
314+ this . logger = options . logger ?? console ;
315+ if ( options . logLevel != null ) {
316+ this . logLevel = options . logLevel ;
317+ } else {
318+ const envLevel = readEnv ( 'OPENAI_LOG' ) ;
319+ if ( isLogLevel ( envLevel ) ) {
320+ this . logLevel = envLevel ;
321+ }
322+ }
279323 this . httpAgent = options . httpAgent ;
280324 this . maxRetries = options . maxRetries ?? 2 ;
281325 this . fetch = options . fetch ?? Shims . getDefaultFetch ( ) ;
@@ -415,7 +459,7 @@ export class OpenAI {
415459 options : PromiseOrValue < FinalRequestOptions > ,
416460 remainingRetries : number | null = null ,
417461 ) : APIPromise < Rsp > {
418- return new APIPromise ( this . makeRequest ( options , remainingRetries ) ) ;
462+ return new APIPromise ( this , this . makeRequest ( options , remainingRetries ) ) ;
419463 }
420464
421465 private async makeRequest (
@@ -434,7 +478,7 @@ export class OpenAI {
434478
435479 await this . prepareRequest ( req , { url, options } ) ;
436480
437- debug ( 'request' , url , options , req . headers ) ;
481+ logger ( this ) . debug ( 'request' , url , options , req . headers ) ;
438482
439483 if ( options . signal ?. aborted ) {
440484 throw new Errors . APIUserAbortError ( ) ;
@@ -459,7 +503,7 @@ export class OpenAI {
459503 if ( ! response . ok ) {
460504 if ( retriesRemaining && this . shouldRetry ( response ) ) {
461505 const retryMessage = `retrying, ${ retriesRemaining } attempts remaining` ;
462- debug ( `response (error; ${ retryMessage } )` , response . status , url , response . headers ) ;
506+ logger ( this ) . debug ( `response (error; ${ retryMessage } )` , response . status , url , response . headers ) ;
463507 return this . retryRequest ( options , retriesRemaining , response . headers ) ;
464508 }
465509
@@ -468,7 +512,13 @@ export class OpenAI {
468512 const errMessage = errJSON ? undefined : errText ;
469513 const retryMessage = retriesRemaining ? `(error; no more retries left)` : `(error; not retryable)` ;
470514
471- debug ( `response (error; ${ retryMessage } )` , response . status , url , response . headers , errMessage ) ;
515+ logger ( this ) . debug (
516+ `response (error; ${ retryMessage } )` ,
517+ response . status ,
518+ url ,
519+ response . headers ,
520+ errMessage ,
521+ ) ;
472522
473523 const err = this . makeStatusError ( response . status , errJSON , errMessage , response . headers ) ;
474524 throw err ;
0 commit comments