@@ -209,6 +209,45 @@ describe('Tool Parameters Utils', () => {
209209 expect ( selfHostedSchema . properties . apiKey . description ) . not . toContain ( 'hosted key' )
210210 } )
211211
212+ it . concurrent ( 'keeps the key required for conditionally hosted tools' , ( ) => {
213+ const enabled = Object . assign (
214+ ( params : Record < string , unknown > ) => params . provider === 'falai' ,
215+ {
216+ condition : { field : 'provider' , operator : 'equals' as const , value : 'falai' } ,
217+ }
218+ )
219+ const conditionalTool = {
220+ ...mockToolConfig ,
221+ id : 'conditional_hosted_tool' ,
222+ params : {
223+ apiKey : {
224+ type : 'string' ,
225+ required : true ,
226+ visibility : 'user-only' as ParameterVisibility ,
227+ description : 'Provider API Key' ,
228+ } ,
229+ } ,
230+ hosting : {
231+ enabled,
232+ envKeyPrefix : 'FALAI_API_KEY' ,
233+ apiKeyParam : 'apiKey' ,
234+ byokProviderId : 'falai' ,
235+ pricing : { type : 'per_request' as const , cost : 0.01 } ,
236+ rateLimit : { mode : 'per_request' as const , requestsPerMinute : 100 } ,
237+ } ,
238+ }
239+
240+ const schema = createUserToolSchema ( conditionalTool , {
241+ surface : 'copilot' ,
242+ hostedKeySupport : true ,
243+ } )
244+
245+ // Injection only happens when the predicate passes at runtime, so the
246+ // schema must not promise a hosted key for every configuration.
247+ expect ( schema . required ) . toContain ( 'apiKey' )
248+ expect ( schema . properties . apiKey . description ) . not . toContain ( 'hosted key' )
249+ } )
250+
212251 it . concurrent ( 'does not relax required keys on tools without hosting' , ( ) => {
213252 const plainTool = {
214253 ...mockToolConfig ,
0 commit comments