@@ -5,6 +5,7 @@ import path from "node:path";
55
66import { formatToml , preserveReasoningOptions , syncProvider , type SyncProvider } from "../src/sync/index.js" ;
77import {
8+ anthropic ,
89 buildAnthropicModel ,
910 parseAnthropicPricing ,
1011 type AnthropicModel ,
@@ -131,6 +132,42 @@ test("labels Anthropic aliases as latest", () => {
131132 expect ( model . name ) . toBe ( "Claude Sonnet 5 (latest)" ) ;
132133} ) ;
133134
135+ test ( "Anthropic sync preserves base model inheritance" , ( ) => {
136+ const resolved = {
137+ base_model : "anthropic/claude-opus-4-5" ,
138+ name : "Claude Opus 4.5 (latest)" ,
139+ description : "Flagship Claude model" ,
140+ release_date : "2025-11-24" ,
141+ last_updated : "2025-11-24" ,
142+ attachment : true ,
143+ reasoning : true ,
144+ tool_call : true ,
145+ knowledge : "2025-05" ,
146+ open_weights : false ,
147+ cost : { input : 5 , output : 25 } ,
148+ limit : { context : 200_000 , output : 64_000 } ,
149+ modalities : { input : [ "text" as const , "image" as const ] , output : [ "text" as const ] } ,
150+ } ;
151+ const translated = anthropic . translateModel ( anthropicModel ( {
152+ id : "claude-opus-4-5" ,
153+ canonical_id : "claude-opus-4-5-20251101" ,
154+ display_name : "Claude Opus 4.5" ,
155+ created_at : "2025-11-24T00:00:00Z" ,
156+ max_input_tokens : 200_000 ,
157+ max_tokens : 64_000 ,
158+ } ) , {
159+ existing : ( ) => resolved ,
160+ authored : ( ) => ( { base_model : "anthropic/claude-opus-4-5" } ) ,
161+ } ) ;
162+
163+ expect ( translated ?. model ) . toMatchObject ( {
164+ base_model : "anthropic/claude-opus-4-5" ,
165+ name : "Claude Opus 4.5 (latest)" ,
166+ } ) ;
167+ expect ( translated ?. model ) . not . toHaveProperty ( "knowledge" ) ;
168+ expect ( translated ?. model ) . not . toHaveProperty ( "release_date" ) ;
169+ } ) ;
170+
134171test ( "filters customer-owned OpenAI models from availability tracking" , ( ) => {
135172 expect ( parseOpenAIModels ( {
136173 object : "list" ,
0 commit comments