@@ -310,6 +310,86 @@ describe("getModelMaxOutputTokens", () => {
310310
311311 expect ( getModelMaxOutputTokens ( { modelId : "test" , model, settings } ) ) . toBe ( 16_384 )
312312 } )
313+
314+ it ( "should return full maxTokens for OpenAI Compatible providers without clamping" , ( ) => {
315+ const model : ModelInfo = {
316+ supportsPromptCache : false ,
317+ maxTokens : 128_000 , // 64% of context window
318+ contextWindow : 200_000 ,
319+ supportsImages : false ,
320+ }
321+
322+ // Test with custom OpenAI baseUrl (OpenAI Compatible)
323+ const settings : ProviderSettings = {
324+ apiProvider : "openai" ,
325+ openAiBaseUrl : "https://custom-api.example.com/v1" ,
326+ }
327+
328+ // Should return full 128_000 without clamping to 20%
329+ expect ( getModelMaxOutputTokens ( { modelId : "glm-4.6" , model, settings } ) ) . toBe ( 128_000 )
330+ } )
331+
332+ it ( "should apply 20% clamping for regular OpenAI provider" , ( ) => {
333+ const model : ModelInfo = {
334+ supportsPromptCache : false ,
335+ maxTokens : 128_000 , // 64% of context window
336+ contextWindow : 200_000 ,
337+ supportsImages : false ,
338+ }
339+
340+ // Test with default OpenAI baseUrl (regular OpenAI)
341+ const settings : ProviderSettings = {
342+ apiProvider : "openai" ,
343+ openAiBaseUrl : "https://api.openai.com/v1" ,
344+ }
345+
346+ // Should clamp to 20% of context window: 200_000 * 0.2 = 40_000
347+ expect ( getModelMaxOutputTokens ( { modelId : "some-model" , model, settings } ) ) . toBe ( 40_000 )
348+ } )
349+
350+ it ( "should apply 20% clamping when openAiBaseUrl is not set" , ( ) => {
351+ const model : ModelInfo = {
352+ supportsPromptCache : false ,
353+ maxTokens : 128_000 , // 64% of context window
354+ contextWindow : 200_000 ,
355+ supportsImages : false ,
356+ }
357+
358+ // Test without openAiBaseUrl (defaults to regular OpenAI)
359+ const settings : ProviderSettings = {
360+ apiProvider : "openai" ,
361+ }
362+
363+ // Should clamp to 20% of context window: 200_000 * 0.2 = 40_000
364+ expect ( getModelMaxOutputTokens ( { modelId : "some-model" , model, settings } ) ) . toBe ( 40_000 )
365+ } )
366+
367+ it ( "should handle OpenAI Compatible with various base URLs" , ( ) => {
368+ const model : ModelInfo = {
369+ supportsPromptCache : false ,
370+ maxTokens : 100_000 ,
371+ contextWindow : 128_000 ,
372+ supportsImages : false ,
373+ }
374+
375+ // Test with various custom URLs that indicate OpenAI Compatible
376+ const customUrls = [
377+ "http://localhost:11434/v1" ,
378+ "https://api.groq.com/openai/v1" ,
379+ "https://api.together.xyz/v1" ,
380+ "https://api.deepinfra.com/v1/openai" ,
381+ ]
382+
383+ customUrls . forEach ( ( url ) => {
384+ const settings : ProviderSettings = {
385+ apiProvider : "openai" ,
386+ openAiBaseUrl : url ,
387+ }
388+
389+ // Should return full maxTokens without clamping
390+ expect ( getModelMaxOutputTokens ( { modelId : "test-model" , model, settings } ) ) . toBe ( 100_000 )
391+ } )
392+ } )
313393} )
314394
315395describe ( "shouldUseReasoningBudget" , ( ) => {
0 commit comments