@@ -2057,3 +2057,91 @@ it.effect("opencode loader keeps paid models when auth exists", () =>
20572057 expect ( keyedCount ) . toBeGreaterThan ( 0 )
20582058 } ) . pipe ( provideMultiInstance ) ,
20592059)
2060+
2061+ it . instance (
2062+ "configuration-only OpenAI gateway wraps the selected Responses model" ,
2063+ Effect . gen ( function * ( ) {
2064+ yield * remove ( "OPENAI_API_KEY" )
2065+ const receipt = { uploads : 0 , deletes : 0 , bodies : [ ] as Array < Record < string , unknown > > }
2066+ const server = yield * Effect . acquireRelease (
2067+ Effect . sync ( ( ) =>
2068+ Bun . serve ( {
2069+ port : 0 ,
2070+ async fetch ( request ) {
2071+ const url = new URL ( request . url )
2072+ if ( request . method === "DELETE" ) {
2073+ receipt . deletes ++
2074+ return Response . json ( { deleted : true } )
2075+ }
2076+ if ( url . pathname . endsWith ( "/capability" ) )
2077+ return Response . json ( { supported : true , scope : "owned-default-selector" } )
2078+ if ( url . pathname . endsWith ( "/image-files" ) ) {
2079+ receipt . uploads ++
2080+ return Response . json ( { file_id : "file-owned" , signature : "proof" , expires_at : Date . now ( ) / 1000 + 3600 } )
2081+ }
2082+ receipt . bodies . push ( await request . json ( ) )
2083+ return Response . json ( {
2084+ id : "resp_owned" ,
2085+ object : "response" ,
2086+ created_at : 1 ,
2087+ model : "gateway-fixture" ,
2088+ output : [ ] ,
2089+ usage : { input_tokens : 1 , output_tokens : 1 , total_tokens : 2 } ,
2090+ status : "completed" ,
2091+ } )
2092+ } ,
2093+ } ) ,
2094+ ) ,
2095+ ( server ) => Effect . sync ( ( ) => server . stop ( true ) ) ,
2096+ )
2097+ const instance = yield * TestInstance
2098+ yield * Effect . promise ( ( ) =>
2099+ Bun . write (
2100+ path . join ( instance . directory , "bcode.json" ) ,
2101+ JSON . stringify ( {
2102+ provider : {
2103+ openai : {
2104+ npm : "@ai-sdk/openai" ,
2105+ options : { apiKey : "v4rt_owned" , baseURL : `${ server . url } api/v4/llm/openai/v1` } ,
2106+ models : { "gateway-fixture" : { name : "Gateway Fixture" , limit : { context : 128000 , output : 4096 } } } ,
2107+ } ,
2108+ } ,
2109+ } ) ,
2110+ ) ,
2111+ )
2112+ const provider = yield * Provider . Service
2113+ const model = yield * provider . getModel ( ProviderV2 . ID . openai , ModelV2 . ID . make ( "gateway-fixture" ) )
2114+ const language = yield * provider . getLanguage ( model )
2115+ expect ( typeof ( language as unknown as { closeImageFiles ?: unknown } ) . closeImageFiles ) . toBe ( "function" )
2116+ const screenshot = Buffer . from ( "owned screenshot fixture" ) . toString ( "base64" )
2117+ for ( const turn of [ 1 , 2 , 3 ] )
2118+ yield * Effect . promise ( ( ) =>
2119+ language . doGenerate ( {
2120+ prompt : [
2121+ {
2122+ role : "user" ,
2123+ content : [
2124+ { type : "text" , text : `turn ${ turn } ` } ,
2125+ {
2126+ type : "file" ,
2127+ mediaType : "image/png" ,
2128+ data : screenshot ,
2129+ providerOptions : { openai : { imageDetail : "high" } } ,
2130+ } ,
2131+ ] ,
2132+ } ,
2133+ ] ,
2134+ } ) ,
2135+ )
2136+ expect ( receipt . uploads ) . toBe ( 1 )
2137+ expect ( receipt . bodies ) . toHaveLength ( 3 )
2138+ for ( const body of receipt . bodies ) {
2139+ const serialized = JSON . stringify ( body )
2140+ expect ( serialized ) . toContain ( "file-owned" )
2141+ expect ( serialized ) . not . toContain ( screenshot )
2142+ expect ( serialized ) . toContain ( "high" )
2143+ }
2144+ yield * Effect . promise ( ( ) => ( language as unknown as { closeImageFiles ( ) : Promise < void > } ) . closeImageFiles ( ) )
2145+ expect ( receipt . deletes ) . toBe ( 1 )
2146+ } ) ,
2147+ )
0 commit comments