@@ -48,8 +48,6 @@ export const azureOpenAIProvider: ProviderConfig = {
4848 stream : ! ! request . stream ,
4949 } )
5050
51- // Extract Azure-specific configuration from request or environment
52- // Priority: request parameters > environment variables
5351 const azureEndpoint = request . azureEndpoint || env . AZURE_OPENAI_ENDPOINT
5452 const azureApiVersion =
5553 request . azureApiVersion || env . AZURE_OPENAI_API_VERSION || '2024-07-01-preview'
@@ -60,38 +58,32 @@ export const azureOpenAIProvider: ProviderConfig = {
6058 )
6159 }
6260
63- // API key is now handled server-side before this function is called
6461 const azureOpenAI = new AzureOpenAI ( {
6562 apiKey : request . apiKey ,
6663 apiVersion : azureApiVersion ,
6764 endpoint : azureEndpoint ,
6865 } )
6966
70- // Start with an empty array for all messages
7167 const allMessages = [ ]
7268
73- // Add system prompt if present
7469 if ( request . systemPrompt ) {
7570 allMessages . push ( {
7671 role : 'system' ,
7772 content : request . systemPrompt ,
7873 } )
7974 }
8075
81- // Add context if present
8276 if ( request . context ) {
8377 allMessages . push ( {
8478 role : 'user' ,
8579 content : request . context ,
8680 } )
8781 }
8882
89- // Add remaining messages
9083 if ( request . messages ) {
9184 allMessages . push ( ...request . messages )
9285 }
9386
94- // Transform tools to Azure OpenAI format if provided
9587 const tools = request . tools ?. length
9688 ? request . tools . map ( ( tool ) => ( {
9789 type : 'function' ,
@@ -103,24 +95,19 @@ export const azureOpenAIProvider: ProviderConfig = {
10395 } ) )
10496 : undefined
10597
106- // Build the request payload - use deployment name instead of model name
10798 const deploymentName = ( request . model || 'azure/gpt-4o' ) . replace ( 'azure/' , '' )
10899 const payload : any = {
109- model : deploymentName , // Azure OpenAI uses deployment name
100+ model : deploymentName ,
110101 messages : allMessages ,
111102 }
112103
113- // Add optional parameters
114104 if ( request . temperature !== undefined ) payload . temperature = request . temperature
115105 if ( request . maxTokens !== undefined ) payload . max_tokens = request . maxTokens
116106
117- // Add GPT-5 specific parameters
118107 if ( request . reasoningEffort !== undefined ) payload . reasoning_effort = request . reasoningEffort
119108 if ( request . verbosity !== undefined ) payload . verbosity = request . verbosity
120109
121- // Add response format for structured output if specified
122110 if ( request . responseFormat ) {
123- // Use Azure OpenAI's JSON schema format
124111 payload . response_format = {
125112 type : 'json_schema' ,
126113 json_schema : {
@@ -133,7 +120,6 @@ export const azureOpenAIProvider: ProviderConfig = {
133120 logger . info ( 'Added JSON schema response format to Azure OpenAI request' )
134121 }
135122
136- // Handle tools and tool usage control
137123 let preparedTools : ReturnType < typeof prepareToolsWithUsageControl > | null = null
138124
139125 if ( tools ?. length ) {
@@ -161,12 +147,10 @@ export const azureOpenAIProvider: ProviderConfig = {
161147 }
162148 }
163149
164- // Start execution timer for the entire provider execution
165150 const providerStartTime = Date . now ( )
166151 const providerStartTimeISO = new Date ( providerStartTime ) . toISOString ( )
167152
168153 try {
169- // Check if we can stream directly (no tools required)
170154 if ( request . stream && ( ! tools || tools . length === 0 ) ) {
171155 logger . info ( 'Using streaming response for Azure OpenAI request' )
172156
@@ -245,17 +229,11 @@ export const azureOpenAIProvider: ProviderConfig = {
245229 } ,
246230 } as StreamingExecution
247231
248- // Return the streaming execution object with explicit casting
249232 return streamingResult as StreamingExecution
250233 }
251234
252- // Make the initial API request
253235 const initialCallTime = Date . now ( )
254-
255- // Track the original tool_choice for forced tool tracking
256236 const originalToolChoice = payload . tool_choice
257-
258- // Track forced tools and their usage
259237 const forcedTools = preparedTools ?. forcedTools || [ ]
260238 let usedForcedTools : string [ ] = [ ]
261239
@@ -272,15 +250,10 @@ export const azureOpenAIProvider: ProviderConfig = {
272250 const toolResults = [ ]
273251 const currentMessages = [ ...allMessages ]
274252 let iterationCount = 0
275-
276- // Track time spent in model vs tools
277253 let modelTime = firstResponseTime
278254 let toolsTime = 0
279-
280- // Track if a forced tool has been used
281255 let hasUsedForcedTool = false
282256
283- // Track each model and tool call segment with timestamps
284257 const timeSegments : TimeSegment [ ] = [
285258 {
286259 type : 'model' ,
@@ -291,7 +264,6 @@ export const azureOpenAIProvider: ProviderConfig = {
291264 } ,
292265 ]
293266
294- // Check if a forced tool was used in the first response
295267 const firstCheckResult = checkForForcedToolUsage (
296268 currentResponse ,
297269 originalToolChoice ,
@@ -303,12 +275,10 @@ export const azureOpenAIProvider: ProviderConfig = {
303275 usedForcedTools = firstCheckResult . usedForcedTools
304276
305277 while ( iterationCount < MAX_TOOL_ITERATIONS ) {
306- // Extract text content FIRST, before checking for tool calls
307278 if ( currentResponse . choices [ 0 ] ?. message ?. content ) {
308279 content = currentResponse . choices [ 0 ] . message . content
309280 }
310281
311- // Check for tool calls
312282 const toolCallsInResponse = currentResponse . choices [ 0 ] ?. message ?. tool_calls
313283 if ( ! toolCallsInResponse || toolCallsInResponse . length === 0 ) {
314284 break
@@ -318,10 +288,8 @@ export const azureOpenAIProvider: ProviderConfig = {
318288 `Processing ${ toolCallsInResponse . length } tool calls (iteration ${ iterationCount + 1 } /${ MAX_TOOL_ITERATIONS } )`
319289 )
320290
321- // Track time for tool calls in this batch
322291 const toolsStartTime = Date . now ( )
323292
324- // Execute all tool calls in parallel using Promise.allSettled for resilience
325293 const toolExecutionPromises = toolCallsInResponse . map ( async ( toolCall ) => {
326294 const toolCallStartTime = Date . now ( )
327295 const toolName = toolCall . function . name
@@ -367,7 +335,6 @@ export const azureOpenAIProvider: ProviderConfig = {
367335
368336 const executionResults = await Promise . allSettled ( toolExecutionPromises )
369337
370- // Add ONE assistant message with ALL tool calls BEFORE processing results
371338 currentMessages . push ( {
372339 role : 'assistant' ,
373340 content : null ,
@@ -381,14 +348,12 @@ export const azureOpenAIProvider: ProviderConfig = {
381348 } ) ) ,
382349 } )
383350
384- // Process results in order to maintain consistency
385351 for ( const settledResult of executionResults ) {
386352 if ( settledResult . status === 'rejected' || ! settledResult . value ) continue
387353
388354 const { toolCall, toolName, toolParams, result, startTime, endTime, duration } =
389355 settledResult . value
390356
391- // Add to time segments
392357 timeSegments . push ( {
393358 type : 'tool' ,
394359 name : toolName ,
@@ -397,7 +362,6 @@ export const azureOpenAIProvider: ProviderConfig = {
397362 duration : duration ,
398363 } )
399364
400- // Prepare result content for the LLM
401365 let resultContent : any
402366 if ( result . success ) {
403367 toolResults . push ( result . output )
@@ -420,50 +384,39 @@ export const azureOpenAIProvider: ProviderConfig = {
420384 success : result . success ,
421385 } )
422386
423- // Add tool result message
424387 currentMessages . push ( {
425388 role : 'tool' ,
426389 tool_call_id : toolCall . id ,
427390 content : JSON . stringify ( resultContent ) ,
428391 } )
429392 }
430393
431- // Calculate tool call time for this iteration
432394 const thisToolsTime = Date . now ( ) - toolsStartTime
433395 toolsTime += thisToolsTime
434396
435- // Make the next request with updated messages
436397 const nextPayload = {
437398 ...payload ,
438399 messages : currentMessages ,
439400 }
440401
441- // Update tool_choice based on which forced tools have been used
442402 if ( typeof originalToolChoice === 'object' && hasUsedForcedTool && forcedTools . length > 0 ) {
443- // If we have remaining forced tools, get the next one to force
444403 const remainingTools = forcedTools . filter ( ( tool ) => ! usedForcedTools . includes ( tool ) )
445404
446405 if ( remainingTools . length > 0 ) {
447- // Force the next tool
448406 nextPayload . tool_choice = {
449407 type : 'function' ,
450408 function : { name : remainingTools [ 0 ] } ,
451409 }
452410 logger . info ( `Forcing next tool: ${ remainingTools [ 0 ] } ` )
453411 } else {
454- // All forced tools have been used, switch to auto
455412 nextPayload . tool_choice = 'auto'
456413 logger . info ( 'All forced tools have been used, switching to auto tool_choice' )
457414 }
458415 }
459416
460- // Time the next model call
461417 const nextModelStartTime = Date . now ( )
462-
463- // Make the next request
464418 currentResponse = await azureOpenAI . chat . completions . create ( nextPayload )
465419
466- // Check if any forced tools were used in this response
467420 const nextCheckResult = checkForForcedToolUsage (
468421 currentResponse ,
469422 nextPayload . tool_choice ,
@@ -477,7 +430,6 @@ export const azureOpenAIProvider: ProviderConfig = {
477430 const nextModelEndTime = Date . now ( )
478431 const thisModelTime = nextModelEndTime - nextModelStartTime
479432
480- // Add to time segments
481433 timeSegments . push ( {
482434 type : 'model' ,
483435 name : `Model response (iteration ${ iterationCount + 1 } )` ,
@@ -486,15 +438,12 @@ export const azureOpenAIProvider: ProviderConfig = {
486438 duration : thisModelTime ,
487439 } )
488440
489- // Add to model time
490441 modelTime += thisModelTime
491442
492- // Update content if we have a text response
493443 if ( currentResponse . choices [ 0 ] ?. message ?. content ) {
494444 content = currentResponse . choices [ 0 ] . message . content
495445 }
496446
497- // Update token counts and cost
498447 if ( currentResponse . usage ) {
499448 tokens . prompt += currentResponse . usage . prompt_tokens || 0
500449 tokens . completion += currentResponse . usage . completion_tokens || 0
@@ -583,7 +532,6 @@ export const azureOpenAIProvider: ProviderConfig = {
583532 return streamingResult as StreamingExecution
584533 }
585534
586- // Calculate overall timing
587535 const providerEndTime = Date . now ( )
588536 const providerEndTimeISO = new Date ( providerEndTime ) . toISOString ( )
589537 const totalDuration = providerEndTime - providerStartTime
@@ -604,10 +552,8 @@ export const azureOpenAIProvider: ProviderConfig = {
604552 iterations : iterationCount + 1 ,
605553 timeSegments : timeSegments ,
606554 } ,
607- // We're not calculating cost here as it will be handled in logger.ts
608555 }
609556 } catch ( error ) {
610- // Include timing information even for errors
611557 const providerEndTime = Date . now ( )
612558 const providerEndTimeISO = new Date ( providerEndTime ) . toISOString ( )
613559 const totalDuration = providerEndTime - providerStartTime
@@ -617,9 +563,8 @@ export const azureOpenAIProvider: ProviderConfig = {
617563 duration : totalDuration ,
618564 } )
619565
620- // Create a new error with timing information
621566 const enhancedError = new Error ( error instanceof Error ? error . message : String ( error ) )
622- // @ts -ignore - Adding timing property to the error
567+ // @ts -ignore
623568 enhancedError . timing = {
624569 startTime : providerStartTimeISO ,
625570 endTime : providerEndTimeISO ,
0 commit comments