@@ -256,12 +256,6 @@ struct HttpRequest {
256256
257257#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
258258enum ProviderAdapter {
259- DeepSeek ,
260- StepFun ,
261- SiliconFlowCn ,
262- SiliconFlowEn ,
263- OpenRouter ,
264- Novita ,
265259 Kimi ,
266260 Zhipu ,
267261 MiniMax ,
@@ -336,7 +330,6 @@ fn prepare_query(provider: &StoredProvider) -> Result<PreparedQuery, String> {
336330 }
337331
338332 match provider. usage_query . mode . as_str ( ) {
339- "balance" => prepare_balance_query ( provider) ,
340333 "coding-plan" => prepare_coding_plan_query ( provider) ,
341334 "general" => prepare_script_query ( provider, GENERAL_SCRIPT , true ) ,
342335 "newapi" => prepare_script_query ( provider, NEWAPI_SCRIPT , true ) ,
@@ -383,46 +376,6 @@ fn prepare_script_query(
383376 } )
384377}
385378
386- fn prepare_balance_query ( provider : & StoredProvider ) -> Result < PreparedQuery , String > {
387- if provider. api_key . trim ( ) . is_empty ( ) {
388- return Err ( "Provider API key is not configured" . to_string ( ) ) ;
389- }
390- let base = validate_destination ( & provider. base_url ) ?;
391- if base. scheme ( ) != "https" {
392- return Err ( "Built-in usage adapters require HTTPS" . to_string ( ) ) ;
393- }
394- let host = base. host_str ( ) . unwrap_or_default ( ) . to_ascii_lowercase ( ) ;
395- let ( adapter, endpoint) = match host. as_str ( ) {
396- "api.deepseek.com" => (
397- ProviderAdapter :: DeepSeek ,
398- "https://api.deepseek.com/user/balance" ,
399- ) ,
400- "api.stepfun.ai" | "api.stepfun.com" => (
401- ProviderAdapter :: StepFun ,
402- "https://api.stepfun.com/v1/accounts" ,
403- ) ,
404- "api.siliconflow.cn" => (
405- ProviderAdapter :: SiliconFlowCn ,
406- "https://api.siliconflow.cn/v1/user/info" ,
407- ) ,
408- "api.siliconflow.com" => (
409- ProviderAdapter :: SiliconFlowEn ,
410- "https://api.siliconflow.com/v1/user/info" ,
411- ) ,
412- "openrouter.ai" => (
413- ProviderAdapter :: OpenRouter ,
414- "https://openrouter.ai/api/v1/credits" ,
415- ) ,
416- "api.novita.ai" => (
417- ProviderAdapter :: Novita ,
418- "https://api.novita.ai/v3/user/balance" ,
419- ) ,
420- _ => return Err ( "No balance adapter matches this provider" . to_string ( ) ) ,
421- } ;
422- let request = bearer_request ( endpoint, & provider. api_key ) ?;
423- Ok ( single_request_query ( request, adapter) )
424- }
425-
426379fn prepare_coding_plan_query ( provider : & StoredProvider ) -> Result < PreparedQuery , String > {
427380 let base = validate_destination ( & provider. base_url ) ?;
428381 if base. scheme ( ) != "https" {
@@ -723,37 +676,6 @@ fn parse_adapter_response(
723676 body : & Value ,
724677) -> Result < Vec < ProviderUsageEntry > , String > {
725678 let entries = match adapter {
726- ProviderAdapter :: DeepSeek => parse_deepseek ( body) ?,
727- ProviderAdapter :: StepFun => vec ! [ balance_entry(
728- "StepFun balance" ,
729- required_number( body, "balance" ) ?,
730- "CNY" ,
731- ) ] ,
732- ProviderAdapter :: SiliconFlowCn | ProviderAdapter :: SiliconFlowEn => {
733- let data = body
734- . get ( "data" )
735- . ok_or_else ( || "SiliconFlow response is missing data" . to_string ( ) ) ?;
736- vec ! [ balance_entry(
737- "SiliconFlow balance" ,
738- required_number( data, "totalBalance" ) ?,
739- if adapter == ProviderAdapter :: SiliconFlowCn {
740- "CNY"
741- } else {
742- "USD"
743- } ,
744- ) ]
745- }
746- ProviderAdapter :: OpenRouter => {
747- let data = body. get ( "data" ) . unwrap_or ( body) ;
748- let total = required_number ( data, "total_credits" ) ?;
749- let used = required_number ( data, "total_usage" ) ?;
750- vec ! [ balance_entry( "OpenRouter balance" , total - used, "USD" ) ]
751- }
752- ProviderAdapter :: Novita => vec ! [ balance_entry(
753- "Novita balance" ,
754- required_number( body, "availableBalance" ) ? / 10_000.0 ,
755- "USD" ,
756- ) ] ,
757679 ProviderAdapter :: Kimi => parse_kimi ( body) ,
758680 ProviderAdapter :: Zhipu => parse_zhipu ( body) ,
759681 ProviderAdapter :: MiniMax => parse_minimax ( body) ,
@@ -768,28 +690,6 @@ fn parse_adapter_response(
768690 Ok ( entries)
769691}
770692
771- fn parse_deepseek ( body : & Value ) -> Result < Vec < ProviderUsageEntry > , String > {
772- let infos = body
773- . get ( "balance_infos" )
774- . and_then ( Value :: as_array)
775- . ok_or_else ( || "DeepSeek response is missing balance information" . to_string ( ) ) ?;
776- infos
777- . iter ( )
778- . map ( |info| {
779- let unit = info
780- . get ( "currency" )
781- . and_then ( Value :: as_str)
782- . filter ( |unit| !unit. is_empty ( ) )
783- . ok_or_else ( || "DeepSeek response has an invalid currency" . to_string ( ) ) ?;
784- Ok ( balance_entry (
785- "DeepSeek balance" ,
786- required_number ( info, "total_balance" ) ?,
787- unit,
788- ) )
789- } )
790- . collect ( )
791- }
792-
793693fn parse_kimi ( body : & Value ) -> Vec < ProviderUsageEntry > {
794694 let mut entries = Vec :: new ( ) ;
795695 if let Some ( limits) = body. get ( "limits" ) . and_then ( Value :: as_array) {
@@ -938,10 +838,6 @@ fn parse_volcengine_coding(body: &Value) -> Vec<ProviderUsageEntry> {
938838 . collect ( )
939839}
940840
941- fn balance_entry ( label : & str , value : f64 , unit : & str ) -> ProviderUsageEntry {
942- quota_entry ( label, value, Some ( unit) )
943- }
944-
945841fn quota_entry ( label : & str , value : f64 , unit : Option < & str > ) -> ProviderUsageEntry {
946842 ProviderUsageEntry {
947843 label : label. to_string ( ) ,
@@ -950,11 +846,6 @@ fn quota_entry(label: &str, value: f64, unit: Option<&str>) -> ProviderUsageEntr
950846 }
951847}
952848
953- fn required_number ( value : & Value , field : & str ) -> Result < f64 , String > {
954- optional_number ( value, field)
955- . ok_or_else ( || "Usage query response is missing a number" . to_string ( ) )
956- }
957-
958849fn optional_number ( value : & Value , field : & str ) -> Option < f64 > {
959850 let value = value. get ( field) ?;
960851 let number = value
@@ -1463,7 +1354,7 @@ mod tests {
14631354 #[ test]
14641355 fn cache_requires_current_provider_identity_and_supports_invalidation ( ) {
14651356 let mut cache = UsageCache :: default ( ) ;
1466- let original = test_provider ( "balance " , "https://api.deepseek .com/v1" ) ;
1357+ let original = test_provider ( "coding-plan " , "https://api.kimi .com/coding /v1" ) ;
14671358 let original_identity = provider_query_identity ( & original) ;
14681359 cache. record_success (
14691360 "provider-a" ,
@@ -1501,7 +1392,7 @@ mod tests {
15011392 #[ test]
15021393 fn failure_only_results_are_not_reusable_cache_entries ( ) {
15031394 let mut cache = UsageCache :: default ( ) ;
1504- let provider = test_provider ( "balance " , "https://api.deepseek .com/v1" ) ;
1395+ let provider = test_provider ( "coding-plan " , "https://api.kimi .com/coding /v1" ) ;
15051396 let identity = provider_query_identity ( & provider) ;
15061397
15071398 let result = cache. record_failure ( "provider-a" , identity, "request failed" ) ;
@@ -1511,49 +1402,6 @@ mod tests {
15111402 assert ! ( cache. get( "provider-a" , & identity) . is_none( ) ) ;
15121403 }
15131404
1514- #[ test]
1515- fn balance_adapters_build_expected_endpoints ( ) {
1516- let cases = [
1517- (
1518- "https://api.deepseek.com/v1" ,
1519- ProviderAdapter :: DeepSeek ,
1520- "/user/balance" ,
1521- ) ,
1522- (
1523- "https://api.stepfun.com/v1" ,
1524- ProviderAdapter :: StepFun ,
1525- "/v1/accounts" ,
1526- ) ,
1527- (
1528- "https://api.siliconflow.cn/v1" ,
1529- ProviderAdapter :: SiliconFlowCn ,
1530- "/v1/user/info" ,
1531- ) ,
1532- (
1533- "https://api.siliconflow.com/v1" ,
1534- ProviderAdapter :: SiliconFlowEn ,
1535- "/v1/user/info" ,
1536- ) ,
1537- (
1538- "https://openrouter.ai/api/v1" ,
1539- ProviderAdapter :: OpenRouter ,
1540- "/api/v1/credits" ,
1541- ) ,
1542- (
1543- "https://api.novita.ai/v3/openai" ,
1544- ProviderAdapter :: Novita ,
1545- "/v3/user/balance" ,
1546- ) ,
1547- ] ;
1548-
1549- for ( base_url, expected_adapter, expected_path) in cases {
1550- let query = test_provider ( "balance" , base_url) ;
1551- let prepared = prepare_query ( & query) . expect ( "prepare balance query" ) ;
1552- assert_eq ! ( prepared. primary. adapter, expected_adapter) ;
1553- assert_eq ! ( prepared. primary. request. url. path( ) , expected_path) ;
1554- }
1555- }
1556-
15571405 #[ test]
15581406 fn coding_plan_adapters_build_expected_endpoints ( ) {
15591407 let cases = [
@@ -1613,48 +1461,6 @@ mod tests {
16131461 . is_ok( ) ) ;
16141462 }
16151463
1616- #[ test]
1617- fn balance_adapter_responses_are_normalized ( ) {
1618- let cases = [
1619- (
1620- ProviderAdapter :: DeepSeek ,
1621- json ! ( { "balance_infos" : [ { "currency" : "CNY" , "total_balance" : "12.50" } ] } ) ,
1622- "12.5" ,
1623- "CNY" ,
1624- ) ,
1625- (
1626- ProviderAdapter :: StepFun ,
1627- json ! ( { "balance" : 9.25 } ) ,
1628- "9.25" ,
1629- "CNY" ,
1630- ) ,
1631- (
1632- ProviderAdapter :: SiliconFlowEn ,
1633- json ! ( { "data" : { "totalBalance" : "8.75" } } ) ,
1634- "8.75" ,
1635- "USD" ,
1636- ) ,
1637- (
1638- ProviderAdapter :: OpenRouter ,
1639- json ! ( { "data" : { "total_credits" : 20 , "total_usage" : 3.5 } } ) ,
1640- "16.5" ,
1641- "USD" ,
1642- ) ,
1643- (
1644- ProviderAdapter :: Novita ,
1645- json ! ( { "availableBalance" : 42_000 } ) ,
1646- "4.2" ,
1647- "USD" ,
1648- ) ,
1649- ] ;
1650-
1651- for ( adapter, body, value, unit) in cases {
1652- let entries = parse_adapter_response ( adapter, & body) . expect ( "parse adapter response" ) ;
1653- assert_eq ! ( entries[ 0 ] . value, value) ;
1654- assert_eq ! ( entries[ 0 ] . unit. as_deref( ) , Some ( unit) ) ;
1655- }
1656- }
1657-
16581464 #[ test]
16591465 fn coding_plan_responses_are_normalized_as_remaining_quota ( ) {
16601466 let cases = [
0 commit comments