@@ -4,6 +4,7 @@ import { tmpdir } from "node:os";
44import { join } from "node:path" ;
55import type { Context } from "hono" ;
66import { ComposedHandler } from "../handlers/composed-handler.js" ;
7+ import type { ReasoningModeCapabilities } from "../model-loader.js" ;
78import { type SlimModelEntry , writeAllModelsCache } from "../providers/all-models-cache.js" ;
89import type { ProviderTransport } from "../providers/transport/types.js" ;
910import { SessionEventRegistry } from "./index.js" ;
@@ -61,6 +62,22 @@ function variantEntry(
6162 } ;
6263}
6364
65+ function routeCapabilityEntry ( provider : string , mode : ReasoningModeCapabilities ) : SlimModelEntry {
66+ return {
67+ modelId : BASE_MODEL_ID ,
68+ aliases : [ `openai/${ BASE_MODEL_ID } ` ] ,
69+ sources : { } ,
70+ aggregators : [
71+ {
72+ provider,
73+ externalId : BASE_MODEL_ID ,
74+ confidence : provider === "openai" ? "api_official" : "gateway_official" ,
75+ reasoning : { mode } ,
76+ } ,
77+ ] ,
78+ } ;
79+ }
80+
6481function writeCatalog ( entries : SlimModelEntry [ ] = [ variantEntry ( ) ] ) : void {
6582 writeAllModelsCache ( { entries } , cachePath ) ;
6683}
@@ -99,12 +116,46 @@ describe("resolveVariantPreset", () => {
99116
100117 expect ( resolveVariantPreset ( BASE_MODEL_ID , PROVIDER , cachePath ) ) . toEqual ( {
101118 params : { reasoning : { mode : "pro" } } ,
102- variantModelId : VARIANT_MODEL_ID ,
103119 provider : PROVIDER ,
104120 preset : PRESET ,
121+ sourceLabel : `variant ${ VARIANT_MODEL_ID } @ ${ PROVIDER } ` ,
122+ } ) ;
123+ } ) ;
124+
125+ test ( "prefers supported typed route capability over the legacy variant fallback" , ( ) => {
126+ makeHome ( ) ;
127+ writeCatalog ( [
128+ routeCapabilityEntry ( "openai" , {
129+ status : "supported" ,
130+ values : [ "standard" , "pro" ] ,
131+ default : "standard" ,
132+ } ) ,
133+ variantEntry ( "openai" ) ,
134+ ] ) ;
135+
136+ expect ( resolveVariantPreset ( BASE_MODEL_ID , "openai" , cachePath ) ) . toEqual ( {
137+ params : { reasoning : { mode : "pro" } } ,
138+ provider : "openai" ,
139+ preset : PRESET ,
140+ sourceLabel : "route capability @ openai" ,
105141 } ) ;
106142 } ) ;
107143
144+ test ( "does not weaken explicit rejected or unknown route facts with a legacy variant" , ( ) => {
145+ makeHome ( ) ;
146+ for ( const status of [ "rejected" , "unknown" ] as const ) {
147+ writeCatalog ( [ routeCapabilityEntry ( "openai" , { status } ) , variantEntry ( "openai" ) ] ) ;
148+ expect ( resolveVariantPreset ( BASE_MODEL_ID , "openai" , cachePath ) ) . toBeUndefined ( ) ;
149+ }
150+ } ) ;
151+
152+ test ( "requires pro to be an exact supported native value" , ( ) => {
153+ makeHome ( ) ;
154+ writeCatalog ( [ routeCapabilityEntry ( "openai" , { status : "supported" , values : [ "standard" ] } ) ] ) ;
155+
156+ expect ( resolveVariantPreset ( BASE_MODEL_ID , "openai" , cachePath ) ) . toBeUndefined ( ) ;
157+ } ) ;
158+
108159 test ( "returns undefined when the variant belongs to a different provider" , ( ) => {
109160 makeHome ( ) ;
110161 writeCatalog ( [ variantEntry ( "openrouter" ) ] ) ;
@@ -248,10 +299,10 @@ describe("applyProInjection", () => {
248299// ─── ComposedHandler wiring (step 5a-pre) ────────────────────────────────────
249300
250301/** Fake transport; the stubbed global fetch captures the final wire payload. */
251- function makeTransport ( ) : ProviderTransport {
302+ function makeTransport ( provider = PROVIDER ) : ProviderTransport {
252303 return {
253- name : PROVIDER ,
254- displayName : "OpenRouter" ,
304+ name : provider ,
305+ displayName : provider ,
255306 streamFormat : "openai-sse" ,
256307 getEndpoint : ( ) => "http://localhost/v1/chat/completions" ,
257308 getHeaders : async ( ) => ( { } ) ,
@@ -295,12 +346,20 @@ function makeClaudePayload(): Record<string, unknown> {
295346function makeHandler ( options : {
296347 proOnUltracode ?: boolean ;
297348 modelParams ?: Record < string , unknown > ;
349+ provider ?: string ;
298350} ) : ComposedHandler {
299- return new ComposedHandler ( makeTransport ( ) , `${ PROVIDER } @${ BASE_MODEL_ID } ` , BASE_MODEL_ID , 8080 , {
300- ...options ,
301- sessionEventRegistry : registry ,
302- catalogCachePath : cachePath ,
303- } ) ;
351+ const { provider = PROVIDER , ...handlerOptions } = options ;
352+ return new ComposedHandler (
353+ makeTransport ( provider ) ,
354+ `${ provider } @${ BASE_MODEL_ID } ` ,
355+ BASE_MODEL_ID ,
356+ 8080 ,
357+ {
358+ ...handlerOptions ,
359+ sessionEventRegistry : registry ,
360+ catalogCachePath : cachePath ,
361+ }
362+ ) ;
304363}
305364
306365describe ( "ComposedHandler step 5a-pre wiring" , ( ) => {
@@ -314,6 +373,25 @@ describe("ComposedHandler step 5a-pre wiring", () => {
314373 expect ( wire . body ( ) . reasoning ?. mode ) . toBe ( "pro" ) ;
315374 } ) ;
316375
376+ test ( "typed OpenAI route support puts reasoning.mode=pro on the wire" , async ( ) => {
377+ makeHome ( FIXTURE_EFFORT_ULTRACODE_STDOUT , FIXTURE_ULTRA_EFFORT_ENTER ) ;
378+ writeCatalog ( [
379+ routeCapabilityEntry ( "openai" , {
380+ status : "supported" ,
381+ values : [ "standard" , "pro" ] ,
382+ default : "standard" ,
383+ } ) ,
384+ ] ) ;
385+ const wire = stubFetchCapture ( ) ;
386+
387+ await makeHandler ( { proOnUltracode : true , provider : "openai" } ) . handle (
388+ makeContext ( ) ,
389+ makeClaudePayload ( )
390+ ) ;
391+
392+ expect ( wire . body ( ) . reasoning ?. mode ) . toBe ( "pro" ) ;
393+ } ) ;
394+
317395 test ( "ORDERING INVARIANT: swapping 5a-pre after 5a would override explicit --model-params" , async ( ) => {
318396 makeHome ( FIXTURE_EFFORT_ULTRACODE_STDOUT , FIXTURE_ULTRA_EFFORT_ENTER ) ;
319397 writeCatalog ( ) ;
0 commit comments