ai-cortex-sdk 0.1.1

Rust client SDK for AI Cortex server: PAT auth, device binding, software store, offline license (Ed25519), and auto-update (check-update pull + SSE push).
Documentation
use serde::Deserialize;

/// SDK 配置。
///
/// 鉴权改为用户 PAT(`Authorization: Bearer actx_pat_...`),不再使用 app_key/app_secret HMAC。
/// PAT 由用户在 web 端创建后填入配置。
#[derive(Debug, Clone, Deserialize)]
pub struct CortexConfig {
    pub server_url: String,
    /// 用户个人访问令牌(PAT),形如 `actx_pat_...`。
    pub pat: String,
    /// SDK 以哪个软件身份心跳/下载(设备按该软件的许可证 max_devices 校验上限)。
    pub software_id: String,
    #[serde(default = "default_timeout")]
    pub timeout: u64,
    /// 心跳上报间隔(秒)。0 = 关闭心跳;默认 60s。
    #[serde(default = "default_heartbeat_interval")]
    pub heartbeat_interval: u64,
    /// 可选:钉扎的软件公钥(hex)。设置后,拉取到的离线许可证 public_key 必须与之匹配才信任。
    /// 不设置则信任服务端在 issue 响应中下发的 public_key(依赖 TLS)。
    #[serde(default)]
    pub software_public_key: Option<String>,
}

fn default_timeout() -> u64 {
    30
}

fn default_heartbeat_interval() -> u64 {
    60
}

impl CortexConfig {
    pub fn new(
        server_url: impl Into<String>,
        pat: impl Into<String>,
        software_id: impl Into<String>,
    ) -> Self {
        Self {
            server_url: server_url.into(),
            pat: pat.into(),
            software_id: software_id.into(),
            timeout: 30,
            heartbeat_interval: 60,
            software_public_key: None,
        }
    }

    pub fn with_timeout(mut self, timeout: u64) -> Self {
        self.timeout = timeout;
        self
    }

    /// 钉扎软件公钥(hex)。设置后离线许可证验签时要求下发公钥与之严格匹配。
    pub fn with_software_public_key(mut self, pk: impl Into<String>) -> Self {
        self.software_public_key = Some(pk.into());
        self
    }

    /// 设置 SDK 心跳/下载所代表的软件 id。
    pub fn with_software_id(mut self, software_id: impl Into<String>) -> Self {
        self.software_id = software_id.into();
        self
    }

    /// 设置心跳上报间隔(秒)。设为 0 可关闭心跳。
    pub fn with_heartbeat_interval(mut self, secs: u64) -> Self {
        self.heartbeat_interval = secs;
        self
    }

    /// 关闭心跳上报。
    pub fn without_heartbeat(mut self) -> Self {
        self.heartbeat_interval = 0;
        self
    }
}