@@ -126,9 +126,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
126126 {
127127 type : "text" ,
128128 text : systemPrompt ,
129- // @ts -ignore-next-line
130129 cache_control : { type : "ephemeral" } ,
131- } ,
130+ } as OpenAI . Chat . ChatCompletionContentPartText & { cache_control ?: { type : string } } ,
132131 ] ,
133132 }
134133 }
@@ -155,8 +154,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
155154 msg . content . push ( lastTextPart )
156155 }
157156
158- // @ts -ignore-next-line
159- lastTextPart [ " cache_control" ] = { type : "ephemeral" }
157+ // Type assertion to add cache_control property
158+ ; ( lastTextPart as any ) . cache_control = { type : "ephemeral" }
160159 }
161160 } )
162161 }
@@ -254,17 +253,21 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
254253 } catch ( error : any ) {
255254 // Handle Azure-specific errors
256255 if ( error ?. status === 400 && error ?. message ?. includes ( "does not support 'system'" ) ) {
256+ const sanitizedModelId = String ( this . options . openAiModelId || "unknown" ) . substring ( 0 , 100 )
257257 throw new Error (
258258 `Azure OpenAI error: This model does not support system messages. ` +
259259 `For reasoning models (o1, o3, o4), please ensure the model ID is correctly set. ` +
260- `Current model: ${ this . options . openAiModelId } ` ,
260+ `Current model: ${ sanitizedModelId } ` ,
261261 )
262262 } else if ( error ?. status === 404 ) {
263+ const sanitizedApiVersion = String (
264+ this . options . azureApiVersion || azureOpenAiDefaultApiVersion ,
265+ ) . substring ( 0 , 50 )
263266 throw new Error (
264267 `Azure OpenAI error: Resource not found. Please check: ` +
265268 `1) Your deployment name is correct, ` +
266269 `2) The base URL format is correct (e.g., https://YOUR-RESOURCE.openai.azure.com), ` +
267- `3) The API version is supported (current: ${ this . options . azureApiVersion || azureOpenAiDefaultApiVersion } )` ,
270+ `3) The API version is supported (current: ${ sanitizedApiVersion } )` ,
268271 )
269272 } else if ( error ?. message ?. includes ( "api-key" ) ) {
270273 throw new Error (
@@ -469,23 +472,29 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
469472 */
470473 private _extractBaseUrl ( url : string ) : string {
471474 try {
475+ // Validate URL before parsing
476+ if ( ! url || typeof url !== "string" ) {
477+ return ""
478+ }
479+
472480 const urlObj = new URL ( url )
473481 // For Azure OpenAI, we need to preserve the path up to /openai/deployments/{deployment-name}
474482 // but remove /chat/completions and query parameters
475- const pathParts = urlObj . pathname . split ( "/" )
483+ const pathParts = urlObj . pathname . split ( "/" ) . filter ( ( part ) => part . length > 0 )
476484 const deploymentIndex = pathParts . indexOf ( "deployments" )
477485
478486 if ( deploymentIndex !== - 1 && deploymentIndex + 1 < pathParts . length ) {
479487 // Keep path up to and including the deployment name
480- const basePath = pathParts . slice ( 0 , deploymentIndex + 2 ) . join ( "/" )
488+ const basePath = "/" + pathParts . slice ( 0 , deploymentIndex + 2 ) . join ( "/" )
481489 return `${ urlObj . protocol } //${ urlObj . host } ${ basePath } `
482490 }
483491
484492 // If not a deployment URL, just return origin + pathname without query
485493 return `${ urlObj . protocol } //${ urlObj . host } ${ urlObj . pathname } `
486494 } catch ( error ) {
487- // If URL parsing fails, return as-is
488- return url
495+ // If URL parsing fails, return empty string to avoid potential security issues
496+ console . error ( "Failed to parse URL:" , error )
497+ return ""
489498 }
490499 }
491500
0 commit comments