@@ -23,6 +23,7 @@ import { WriteTool } from "../tool/write"
2323import { TodoReadTool , TodoWriteTool } from "../tool/todo"
2424import { AuthAnthropic } from "../auth/anthropic"
2525import { ModelsDev } from "./models"
26+ import { NamedError } from "../util/error"
2627
2728export namespace Provider {
2829 const log = Log . create ( { service : "provider" } )
@@ -75,26 +76,34 @@ export namespace Provider {
7576 string ,
7677 ( provider : Info ) => Promise < Record < string , any > | false >
7778 > = {
78- anthropic : async ( ) => {
79+ async anthropic ( provider ) {
7980 const access = await AuthAnthropic . access ( )
80- if ( access )
81+ if ( access ) {
82+ // claude sub doesn't have usage cost
83+ for ( const model of Object . values ( provider . models ) ) {
84+ model . cost = {
85+ input : 0 ,
86+ inputCached : 0 ,
87+ output : 0 ,
88+ outputCached : 0 ,
89+ }
90+ }
8191 return {
8292 apiKey : "" ,
8393 headers : {
8494 authorization : `Bearer ${ access } ` ,
8595 "anthropic-beta" : "oauth-2025-04-20" ,
8696 } ,
8797 }
88- return env ( "ANTHROPIC_API_KEY" )
98+ }
99+ return env ( "ANTHROPIC_API_KEY" ) ( provider )
89100 } ,
90101 google : env ( "GOOGLE_GENERATIVE_AI_API_KEY" ) ,
91102 openai : env ( "OPENAI_API_KEY" ) ,
92103 }
93104
94105 const state = App . state ( "provider" , async ( ) => {
95- log . info ( "loading config" )
96106 const config = await Config . get ( )
97- log . info ( "loading providers" )
98107 const database : Record < string , Provider . Info > = await ModelsDev . get ( )
99108
100109 const providers : {
@@ -134,6 +143,10 @@ export namespace Provider {
134143 }
135144 }
136145
146+ for ( const providerID of Object . keys ( providers ) ) {
147+ log . info ( "loaded" , { providerID } )
148+ }
149+
137150 return {
138151 models,
139152 providers,
@@ -148,28 +161,32 @@ export namespace Provider {
148161 }
149162
150163 async function getSDK ( providerID : string ) {
151- const s = await state ( )
152- if ( s . sdk . has ( providerID ) ) return s . sdk . get ( providerID ) !
153-
154- const dir = path . join (
155- Global . Path . cache ,
156- `node_modules` ,
157- `@ai-sdk` ,
158- providerID ,
159- )
160- if ( ! ( await Bun . file ( path . join ( dir , "package.json" ) ) . exists ( ) ) ) {
161- log . info ( "installing" , {
164+ return ( async ( ) => {
165+ const s = await state ( )
166+ const existing = s . sdk . get ( providerID )
167+ if ( existing ) return existing
168+ const dir = path . join (
169+ Global . Path . cache ,
170+ `node_modules` ,
171+ `@ai-sdk` ,
162172 providerID ,
163- } )
164- await BunProc . run ( [ "add" , `@ai-sdk/${ providerID } @alpha` ] , {
165- cwd : Global . Path . cache ,
166- } )
167- }
168- const mod = await import ( path . join ( dir ) )
169- const fn = mod [ Object . keys ( mod ) . find ( ( key ) => key . startsWith ( "create" ) ) ! ]
170- const loaded = fn ( s . providers [ providerID ] ?. options )
171- s . sdk . set ( providerID , loaded )
172- return loaded as SDK
173+ )
174+ if ( ! ( await Bun . file ( path . join ( dir , "package.json" ) ) . exists ( ) ) ) {
175+ log . info ( "installing" , {
176+ providerID,
177+ } )
178+ await BunProc . run ( [ "add" , `@ai-sdk/${ providerID } @alpha` ] , {
179+ cwd : Global . Path . cache ,
180+ } )
181+ }
182+ const mod = await import ( path . join ( dir ) )
183+ const fn = mod [ Object . keys ( mod ) . find ( ( key ) => key . startsWith ( "create" ) ) ! ]
184+ const loaded = fn ( s . providers [ providerID ] ?. options )
185+ s . sdk . set ( providerID , loaded )
186+ return loaded as SDK
187+ } ) ( ) . catch ( ( e ) => {
188+ throw new InitError ( { providerID : providerID } , { cause : e } )
189+ } )
173190 }
174191
175192 export async function getModel ( providerID : string , modelID : string ) {
@@ -183,12 +200,11 @@ export namespace Provider {
183200 } )
184201
185202 const provider = s . providers [ providerID ]
186- if ( ! provider ) throw new ModelNotFoundError ( modelID )
203+ if ( ! provider ) throw new ModelNotFoundError ( { providerID , modelID } )
187204 const info = provider . info . models [ modelID ]
188- if ( ! info ) throw new ModelNotFoundError ( modelID )
205+ if ( ! info ) throw new ModelNotFoundError ( { providerID , modelID } )
189206
190207 const sdk = await getSDK ( providerID )
191- if ( ! sdk ) throw new ModelNotFoundError ( modelID )
192208
193209 try {
194210 const language = sdk . languageModel ( modelID )
@@ -202,7 +218,14 @@ export namespace Provider {
202218 language,
203219 }
204220 } catch ( e ) {
205- if ( e instanceof NoSuchModelError ) throw new ModelNotFoundError ( modelID )
221+ if ( e instanceof NoSuchModelError )
222+ throw new ModelNotFoundError (
223+ {
224+ modelID : modelID ,
225+ providerID,
226+ } ,
227+ { cause : e } ,
228+ )
206229 throw e
207230 }
208231 }
@@ -259,9 +282,26 @@ export namespace Provider {
259282 return TOOL_MAPPING [ providerID ] ?? TOOLS
260283 }
261284
262- class ModelNotFoundError extends Error {
263- constructor ( public readonly model : string ) {
264- super ( )
265- }
266- }
285+ export const ModelNotFoundError = NamedError . create (
286+ "ProviderModelNotFoundError" ,
287+ z . object ( {
288+ providerID : z . string ( ) ,
289+ modelID : z . string ( ) ,
290+ } ) ,
291+ )
292+
293+ export const InitError = NamedError . create (
294+ "ProviderInitError" ,
295+ z . object ( {
296+ providerID : z . string ( ) ,
297+ } ) ,
298+ )
299+
300+ export const AuthError = NamedError . create (
301+ "ProviderAuthError" ,
302+ z . object ( {
303+ providerID : z . string ( ) ,
304+ message : z . string ( ) ,
305+ } ) ,
306+ )
267307}
0 commit comments