11import type { Logger } from '@sim/logger'
2+ import type OpenAI from 'openai'
23import type { StreamingExecution } from '@/executor/types'
34import { MAX_TOOL_ITERATIONS } from '@/providers'
45import type { Message , ProviderRequest , ProviderResponse , TimeSegment } from '@/providers/types'
@@ -30,7 +31,7 @@ type ToolChoice = PreparedTools['toolChoice']
3031 * - Sets additionalProperties: false on all object types.
3132 * - Ensures required includes ALL property keys.
3233 */
33- function enforceStrictSchema ( schema : any ) : any {
34+ function enforceStrictSchema ( schema : Record < string , unknown > ) : Record < string , unknown > {
3435 if ( ! schema || typeof schema !== 'object' ) return schema
3536
3637 const result = { ...schema }
@@ -41,31 +42,37 @@ function enforceStrictSchema(schema: any): any {
4142
4243 // Recursively process properties and ensure required includes all keys
4344 if ( result . properties && typeof result . properties === 'object' ) {
44- const propKeys = Object . keys ( result . properties )
45+ const propKeys = Object . keys ( result . properties as Record < string , unknown > )
4546 result . required = propKeys // Strict mode requires ALL properties
4647 result . properties = Object . fromEntries (
47- Object . entries ( result . properties ) . map ( ( [ key , value ] ) => [ key , enforceStrictSchema ( value ) ] )
48+ Object . entries ( result . properties as Record < string , unknown > ) . map ( ( [ key , value ] ) => [
49+ key ,
50+ enforceStrictSchema ( value as Record < string , unknown > ) ,
51+ ] )
4852 )
4953 }
5054 }
5155
5256 // Handle array items
5357 if ( result . type === 'array' && result . items ) {
54- result . items = enforceStrictSchema ( result . items )
58+ result . items = enforceStrictSchema ( result . items as Record < string , unknown > )
5559 }
5660
5761 // Handle anyOf, oneOf, allOf
5862 for ( const keyword of [ 'anyOf' , 'oneOf' , 'allOf' ] ) {
5963 if ( Array . isArray ( result [ keyword ] ) ) {
60- result [ keyword ] = result [ keyword ] . map ( enforceStrictSchema )
64+ result [ keyword ] = ( result [ keyword ] as Record < string , unknown > [ ] ) . map ( enforceStrictSchema )
6165 }
6266 }
6367
6468 // Handle $defs / definitions
6569 for ( const defKey of [ '$defs' , 'definitions' ] ) {
6670 if ( result [ defKey ] && typeof result [ defKey ] === 'object' ) {
6771 result [ defKey ] = Object . fromEntries (
68- Object . entries ( result [ defKey ] ) . map ( ( [ key , value ] ) => [ key , enforceStrictSchema ( value ) ] )
72+ Object . entries ( result [ defKey ] as Record < string , unknown > ) . map ( ( [ key , value ] ) => [
73+ key ,
74+ enforceStrictSchema ( value as Record < string , unknown > ) ,
75+ ] )
6976 )
7077 }
7178 }
@@ -123,7 +130,7 @@ export async function executeResponsesProviderRequest(
123130
124131 const initialInput = buildResponsesInputFromMessages ( allMessages )
125132
126- const basePayload : Record < string , any > = {
133+ const basePayload : Record < string , unknown > = {
127134 model : config . modelName ,
128135 }
129136
@@ -139,13 +146,13 @@ export async function executeResponsesProviderRequest(
139146
140147 if ( request . verbosity !== undefined && request . verbosity !== 'auto' ) {
141148 basePayload . text = {
142- ...( basePayload . text ?? { } ) ,
149+ ...( ( basePayload . text as Record < string , unknown > ) ?? { } ) ,
143150 verbosity : request . verbosity ,
144151 }
145152 }
146153
147154 // Store response format config - for Azure with tools, we defer applying it until after tool calls complete
148- let deferredTextFormat : { type : string ; name : string ; schema : any ; strict : boolean } | undefined
155+ let deferredTextFormat : OpenAI . Responses . ResponseFormatTextJSONSchemaConfig | undefined
149156 const hasTools = ! ! request . tools ?. length
150157 const isAzure = config . providerId === 'azure-openai'
151158
@@ -171,7 +178,7 @@ export async function executeResponsesProviderRequest(
171178 )
172179 } else {
173180 basePayload . text = {
174- ...( basePayload . text ?? { } ) ,
181+ ...( ( basePayload . text as Record < string , unknown > ) ?? { } ) ,
175182 format : textFormat ,
176183 }
177184 logger . info ( `Added JSON schema response format to ${ config . providerLabel } request` )
@@ -231,7 +238,10 @@ export async function executeResponsesProviderRequest(
231238 }
232239 }
233240
234- const createRequestBody = ( input : ResponsesInputItem [ ] , overrides : Record < string , any > = { } ) => ( {
241+ const createRequestBody = (
242+ input : ResponsesInputItem [ ] ,
243+ overrides : Record < string , unknown > = { }
244+ ) => ( {
235245 ...basePayload ,
236246 input,
237247 ...overrides ,
@@ -247,7 +257,9 @@ export async function executeResponsesProviderRequest(
247257 }
248258 }
249259
250- const postResponses = async ( body : Record < string , any > ) => {
260+ const postResponses = async (
261+ body : Record < string , unknown >
262+ ) : Promise < OpenAI . Responses . Response > => {
251263 const response = await fetch ( config . endpoint , {
252264 method : 'POST' ,
253265 headers : config . headers ,
@@ -496,10 +508,10 @@ export async function executeResponsesProviderRequest(
496508 duration : duration ,
497509 } )
498510
499- let resultContent : any
511+ let resultContent : Record < string , unknown >
500512 if ( result . success ) {
501513 toolResults . push ( result . output )
502- resultContent = result . output
514+ resultContent = result . output as Record < string , unknown >
503515 } else {
504516 resultContent = {
505517 error : true ,
@@ -615,11 +627,11 @@ export async function executeResponsesProviderRequest(
615627 }
616628
617629 // Make final call with the response format - build payload without tools
618- const finalPayload : Record < string , any > = {
630+ const finalPayload : Record < string , unknown > = {
619631 model : config . modelName ,
620632 input : formattedInput ,
621633 text : {
622- ...( basePayload . text ?? { } ) ,
634+ ...( ( basePayload . text as Record < string , unknown > ) ?? { } ) ,
623635 format : deferredTextFormat ,
624636 } ,
625637 }
@@ -635,7 +647,7 @@ export async function executeResponsesProviderRequest(
635647 }
636648 if ( request . verbosity !== undefined && request . verbosity !== 'auto' ) {
637649 finalPayload . text = {
638- ...finalPayload . text ,
650+ ...( ( finalPayload . text as Record < string , unknown > ) ?? { } ) ,
639651 verbosity : request . verbosity ,
640652 }
641653 }
@@ -679,10 +691,10 @@ export async function executeResponsesProviderRequest(
679691 const accumulatedCost = calculateCost ( request . model , tokens . input , tokens . output )
680692
681693 // For Azure with deferred format in streaming mode, include the format in the streaming call
682- const streamOverrides : Record < string , any > = { stream : true , tool_choice : 'auto' }
694+ const streamOverrides : Record < string , unknown > = { stream : true , tool_choice : 'auto' }
683695 if ( deferredTextFormat ) {
684696 streamOverrides . text = {
685- ...( basePayload . text ?? { } ) ,
697+ ...( ( basePayload . text as Record < string , unknown > ) ?? { } ) ,
686698 format : deferredTextFormat ,
687699 }
688700 }
0 commit comments