Team Ai
Apppublic

devin15/cursor2api-rust

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
model.rs339 linesDownload Raw Back to app
1use crate::{2    app::constant::{3        ERR_INVALID_PATH, ERR_RESET_CONFIG, ERR_UPDATE_CONFIG, ROUTE_ABOUT_PATH, ROUTE_CONFIG_PATH,4        ROUTE_LOGS_PATH, ROUTE_README_PATH, ROUTE_ROOT_PATH, ROUTE_SHARED_JS_PATH,5        ROUTE_SHARED_STYLES_PATH, ROUTE_TOKENINFO_PATH, ROUTE_API_PATH,6    },7    common::models::userinfo::TokenProfile,8};9use crate::chat::model::Message;10use std::sync::{LazyLock, RwLock};11use serde::{Deserialize, Serialize};12 13// 页面内容类型枚举14#[derive(Clone, Serialize, Deserialize)]15#[serde(tag = "type", content = "content")]16pub enum PageContent {17    #[serde(rename = "default")]18    Default, // 默认行为19    #[serde(rename = "text")]20    Text(String), // 纯文本21    #[serde(rename = "html")]22    Html(String), // HTML 内容23}24 25impl Default for PageContent {26    fn default() -> Self {27        Self::Default28    }29}30 31mod usage_check;32pub use usage_check::UsageCheck;33 34// 静态配置35#[derive(Clone)]36pub struct AppConfig {37    stream_check: bool,38    stop_stream: bool,39    vision_ability: VisionAbility,40    slow_pool: bool,41    allow_claude: bool,42    pages: Pages,43    usage_check: UsageCheck,44}45 46#[derive(Serialize, Deserialize, Clone)]47pub enum VisionAbility {48    #[serde(rename = "none", alias = "disabled")]49    None,50    #[serde(rename = "base64", alias = "base64-only")]51    Base64,52    #[serde(rename = "all", alias = "base64-http")]53    All,54}55 56impl VisionAbility {57    pub fn from_str(s: &str) -> Self {58        match s.to_lowercase().as_str() {59            "none" | "disabled" => Self::None,60            "base64" | "base64-only" => Self::Base64,61            "all" | "base64-http" => Self::All,62            _ => Self::default(),63        }64    }65}66 67impl Default for VisionAbility {68    fn default() -> Self {69        Self::Base6470    }71}72 73#[derive(Clone, Default)]74pub struct Pages {75    pub root_content: PageContent,76    pub logs_content: PageContent,77    pub config_content: PageContent,78    pub tokeninfo_content: PageContent,79    pub shared_styles_content: PageContent,80    pub shared_js_content: PageContent,81    pub about_content: PageContent,82    pub readme_content: PageContent,83    pub api_content: PageContent,84}85 86// 运行时状态87pub struct AppState {88    pub total_requests: u64,89    pub active_requests: u64,90    pub error_requests: u64,91    pub request_logs: Vec<RequestLog>,92    pub token_infos: Vec<TokenInfo>,93}94 95// 全局配置实例96pub static APP_CONFIG: LazyLock<RwLock<AppConfig>> = LazyLock::new(|| {97    RwLock::new(AppConfig::default())98});99 100impl Default for AppConfig {101    fn default() -> Self {102        Self {103            stream_check: true,104            stop_stream: true,105            vision_ability: VisionAbility::Base64,106            slow_pool: false,107            allow_claude: false,108            pages: Pages::default(),109            usage_check: UsageCheck::Default,110        }111    }112}113 114macro_rules! config_methods {115    ($($field:ident: $type:ty, $default:expr;)*) => {116        $(117            paste::paste! {118                pub fn [<get_ $field>]() -> $type {119                    APP_CONFIG120                        .read()121                        .map(|config| config.$field.clone())122                        .unwrap_or($default)123                }124 125                pub fn [<update_ $field>](value: $type) -> Result<(), &'static str> {126                    if let Ok(mut config) = APP_CONFIG.write() {127                        config.$field = value;128                        Ok(())129                    } else {130                        Err(ERR_UPDATE_CONFIG)131                    }132                }133 134                pub fn [<reset_ $field>]() -> Result<(), &'static str> {135                    if let Ok(mut config) = APP_CONFIG.write() {136                        config.$field = $default;137                        Ok(())138                    } else {139                        Err(ERR_RESET_CONFIG)140                    }141                }142            }143        )*144    };145}146 147impl AppConfig {148    pub fn init(149        stream_check: bool,150        stop_stream: bool,151        vision_ability: VisionAbility,152        slow_pool: bool,153        allow_claude: bool,154    ) {155        if let Ok(mut config) = APP_CONFIG.write() {156            config.stream_check = stream_check;157            config.stop_stream = stop_stream;158            config.vision_ability = vision_ability;159            config.slow_pool = slow_pool;160            config.allow_claude = allow_claude;161        }162    }163 164    config_methods! {165        stream_check: bool, true;166        stop_stream: bool, true;167        slow_pool: bool, false;168        allow_claude: bool, false;169    }170 171    pub fn get_vision_ability() -> VisionAbility {172        APP_CONFIG173            .read()174            .map(|config| config.vision_ability.clone())175            .unwrap_or_default()176    }177 178    pub fn get_page_content(path: &str) -> Option<PageContent> {179        APP_CONFIG.read().ok().map(|config| match path {180            ROUTE_ROOT_PATH => config.pages.root_content.clone(),181            ROUTE_LOGS_PATH => config.pages.logs_content.clone(),182            ROUTE_CONFIG_PATH => config.pages.config_content.clone(),183            ROUTE_TOKENINFO_PATH => config.pages.tokeninfo_content.clone(),184            ROUTE_SHARED_STYLES_PATH => config.pages.shared_styles_content.clone(),185            ROUTE_SHARED_JS_PATH => config.pages.shared_js_content.clone(),186            ROUTE_ABOUT_PATH => config.pages.about_content.clone(),187            ROUTE_README_PATH => config.pages.readme_content.clone(),188            ROUTE_API_PATH => config.pages.api_content.clone(),189            _ => PageContent::default(),190        })191    }192 193    pub fn get_usage_check() -> UsageCheck {194        APP_CONFIG195            .read()196            .map(|config| config.usage_check.clone())197            .unwrap_or_default()198    }199 200    pub fn update_vision_ability(new_ability: VisionAbility) -> Result<(), &'static str> {201        if let Ok(mut config) = APP_CONFIG.write() {202            config.vision_ability = new_ability;203            Ok(())204        } else {205            Err(ERR_UPDATE_CONFIG)206        }207    }208 209    pub fn update_page_content(path: &str, content: PageContent) -> Result<(), &'static str> {210        if let Ok(mut config) = APP_CONFIG.write() {211            match path {212                ROUTE_ROOT_PATH => config.pages.root_content = content,213                ROUTE_LOGS_PATH => config.pages.logs_content = content,214                ROUTE_CONFIG_PATH => config.pages.config_content = content,215                ROUTE_TOKENINFO_PATH => config.pages.tokeninfo_content = content,216                ROUTE_SHARED_STYLES_PATH => config.pages.shared_styles_content = content,217                ROUTE_SHARED_JS_PATH => config.pages.shared_js_content = content,218                ROUTE_ABOUT_PATH => config.pages.about_content = content,219                ROUTE_README_PATH => config.pages.readme_content = content,220                ROUTE_API_PATH => config.pages.api_content = content,221                _ => return Err(ERR_INVALID_PATH),222            }223            Ok(())224        } else {225            Err(ERR_UPDATE_CONFIG)226        }227    }228 229    pub fn update_usage_check(rule: UsageCheck) -> Result<(), &'static str> {230        if let Ok(mut config) = APP_CONFIG.write() {231            config.usage_check = rule;232            Ok(())233        } else {234            Err(ERR_UPDATE_CONFIG)235        }236    }237 238    pub fn reset_vision_ability() -> Result<(), &'static str> {239        if let Ok(mut config) = APP_CONFIG.write() {240            config.vision_ability = VisionAbility::Base64;241            Ok(())242        } else {243            Err(ERR_RESET_CONFIG)244        }245    }246 247    pub fn reset_page_content(path: &str) -> Result<(), &'static str> {248        if let Ok(mut config) = APP_CONFIG.write() {249            match path {250                ROUTE_ROOT_PATH => config.pages.root_content = PageContent::default(),251                ROUTE_LOGS_PATH => config.pages.logs_content = PageContent::default(),252                ROUTE_CONFIG_PATH => config.pages.config_content = PageContent::default(),253                ROUTE_TOKENINFO_PATH => config.pages.tokeninfo_content = PageContent::default(),254                ROUTE_SHARED_STYLES_PATH => {255                    config.pages.shared_styles_content = PageContent::default()256                }257                ROUTE_SHARED_JS_PATH => config.pages.shared_js_content = PageContent::default(),258                ROUTE_ABOUT_PATH => config.pages.about_content = PageContent::default(),259                ROUTE_README_PATH => config.pages.readme_content = PageContent::default(),260                ROUTE_API_PATH => config.pages.api_content = PageContent::default(),261                _ => return Err(ERR_INVALID_PATH),262            }263            Ok(())264        } else {265            Err(ERR_RESET_CONFIG)266        }267    }268 269    pub fn reset_usage_check() -> Result<(), &'static str> {270        if let Ok(mut config) = APP_CONFIG.write() {271            config.usage_check = UsageCheck::default();272            Ok(())273        } else {274            Err(ERR_RESET_CONFIG)275        }276    }277}278 279impl AppState {280    pub fn new(token_infos: Vec<TokenInfo>) -> Self {281        Self {282            total_requests: 0,283            active_requests: 0,284            error_requests: 0,285            request_logs: Vec::new(),286            token_infos,287        }288    }289}290 291// 请求日志292#[derive(Serialize, Clone)]293pub struct RequestLog {294    pub id: u64,295    pub timestamp: chrono::DateTime<chrono::Local>,296    pub model: String,297    pub token_info: TokenInfo,298    #[serde(skip_serializing_if = "Option::is_none")]299    pub prompt: Option<String>,300    pub timing: TimingInfo,301    pub stream: bool,302    pub status: &'static str,303    #[serde(skip_serializing_if = "Option::is_none")]304    pub error: Option<String>,305}306 307#[derive(Serialize, Clone)]308pub struct TimingInfo {309    pub total: f64,    // 总用时(秒)310    #[serde(skip_serializing_if = "Option::is_none")]311    pub first: Option<f64>,  // 首字时间(秒)312}313 314// 聊天请求315#[derive(Deserialize)]316pub struct ChatRequest {317    pub model: String,318    pub messages: Vec<Message>,319    #[serde(default)]320    pub stream: bool,321}322 323// 用于存储 token 信息324#[derive(Serialize, Clone)]325pub struct TokenInfo {326    pub token: String,327    pub checksum: String,328    #[serde(skip_serializing_if = "Option::is_none")]329    pub profile: Option<TokenProfile>,330}331 332// TokenUpdateRequest 结构体333#[derive(Deserialize)]334pub struct TokenUpdateRequest {335    pub tokens: String,336    #[serde(default)]337    pub token_list: Option<String>,338}339