1pub mod error;
12pub mod handler;
13#[allow(clippy::needless_for_each)]
14pub mod openapi;
15pub mod router;
16pub mod usage;
17
18pub use error::ApiError;
19pub use handler::amp_threads::AmpThreadIndex;
20pub use openapi::ApiDoc;
21pub use router::make_router;
22pub use usage::{UsageRecorder, UsageStats};
23
24use arc_swap::ArcSwap;
25use byokey_auth::AuthManager;
26use byokey_provider::DeviceProfileCache;
27use byokey_types::{AmpQuotaStore, RateLimitStore, UsageStore};
28use std::sync::Arc;
29
30pub struct AppState {
32 pub config: Arc<ArcSwap<byokey_config::Config>>,
35 pub auth: Arc<AuthManager>,
37 pub http: rquest::Client,
39 pub usage: Arc<UsageRecorder>,
41 pub ratelimits: Arc<RateLimitStore>,
43 pub device_profiles: Arc<DeviceProfileCache>,
45 pub amp_quota: Arc<AmpQuotaStore>,
47 pub amp_threads: Arc<AmpThreadIndex>,
49}
50
51impl AppState {
52 pub fn new(
57 config: Arc<ArcSwap<byokey_config::Config>>,
58 auth: Arc<AuthManager>,
59 usage_store: Option<Arc<dyn UsageStore>>,
60 ) -> Arc<Self> {
61 Self::with_thread_index(config, auth, usage_store, {
62 let idx = Arc::new(AmpThreadIndex::build());
63 idx.watch();
64 idx
65 })
66 }
67
68 pub fn with_thread_index(
70 config: Arc<ArcSwap<byokey_config::Config>>,
71 auth: Arc<AuthManager>,
72 usage_store: Option<Arc<dyn UsageStore>>,
73 amp_threads: Arc<AmpThreadIndex>,
74 ) -> Arc<Self> {
75 let snapshot = config.load();
76 let http = build_http_client(snapshot.proxy_url.as_deref());
77 Arc::new(Self {
78 config,
79 auth,
80 http,
81 usage: Arc::new(UsageRecorder::new(usage_store)),
82 ratelimits: Arc::new(RateLimitStore::new()),
83 device_profiles: Arc::new(DeviceProfileCache::new()),
84 amp_quota: Arc::new(AmpQuotaStore::new()),
85 amp_threads,
86 })
87 }
88}
89
90fn build_http_client(proxy_url: Option<&str>) -> rquest::Client {
92 if let Some(url) = proxy_url {
93 match rquest::Proxy::all(url) {
94 Ok(proxy) => {
95 return rquest::Client::builder()
96 .proxy(proxy)
97 .build()
98 .unwrap_or_else(|_| rquest::Client::new());
99 }
100 Err(e) => {
101 tracing::warn!(url = url, error = %e, "invalid proxy_url, using direct connection");
102 }
103 }
104 }
105 rquest::Client::new()
106}