Skip to main content

rainy_sdk/endpoints/
cowork.rs

1//! Cowork endpoint for retrieving subscription capabilities
2//!
3//! This endpoint validates the API key and returns the user's
4//! Cowork plan, available models, and feature access.
5#![allow(deprecated)]
6
7use crate::{
8    cowork::{
9        CoworkCapabilities, CoworkFeatures, CoworkModelsResponse, CoworkPlan, CoworkProfile,
10        CoworkUsage,
11    },
12    error::Result,
13    RainyClient,
14};
15
16impl RainyClient {
17    /// Retrieve available models for the current Cowork plan directly from the API.
18    ///
19    /// This is more efficient than fetching full capabilities if only models are needed.
20    #[deprecated(note = "Legacy Cowork endpoint removed in Rainy API v3.")]
21    pub async fn get_cowork_models(&self) -> Result<CoworkModelsResponse> {
22        self.make_request(reqwest::Method::GET, "/cowork/models", None)
23            .await
24    }
25
26    /// Retrieve Cowork capabilities for the current API key.
27    ///
28    /// This method validates the API key and returns information about:
29    /// - Subscription plan (Free, GoPlus, Plus, Pro, ProPlus)
30    /// - Available AI models
31    /// - Feature access (web research, document export, etc.)
32    /// - Usage tracking
33    ///
34    /// # Returns
35    ///
36    /// A `Result` containing `CoworkCapabilities` on success, or a `RainyError` on failure.
37    #[deprecated(note = "Legacy Cowork endpoint removed in Rainy API v3.")]
38    pub async fn get_cowork_capabilities(&self) -> Result<CoworkCapabilities> {
39        match self.get_cowork_profile().await {
40            Ok(profile) => {
41                // In a real app, features/models might come from the API too,
42                // or be derived from the plan ID.
43                // For now, we simulate them based on plan ID or use defaults.
44                // Assuming the API returns features/models in the profile response is better,
45                // but if not, logic goes here.
46                // The new CoworkProfile struct does NOT have models/features, so we map them here.
47
48                let models = match profile.plan.id.as_str() {
49                    "free" => vec!["gemini-2.0-flash".to_string()],
50                    "go" | "go_plus" => {
51                        vec![
52                            "gemini-2.0-flash".to_string(),
53                            "gemini-2.5-flash".to_string(),
54                        ]
55                    }
56                    "plus" => vec![
57                        "gemini-2.0-flash".to_string(),
58                        "gemini-2.5-flash".to_string(),
59                        "gemini-2.5-pro".to_string(),
60                    ],
61                    "pro" | "pro_plus" => vec![
62                        "gemini-2.0-flash".to_string(),
63                        "gemini-2.5-flash".to_string(),
64                        "gemini-2.5-pro".to_string(),
65                        "claude-sonnet-4".to_string(),
66                    ],
67                    _ => vec![],
68                };
69
70                let features = CoworkFeatures {
71                    web_research: profile.plan.id != "free",
72                    document_export: profile.plan.id != "free",
73                    image_analysis: true,
74                    priority_support: profile.plan.id.contains("pro"),
75                };
76
77                Ok(CoworkCapabilities {
78                    profile,
79                    features,
80                    is_valid: true,
81                    models,
82                    upgrade_message: None,
83                })
84            }
85            Err(_) => Ok(CoworkCapabilities::free()),
86        }
87    }
88
89    /// Check if the current API key grants paid access.
90    #[deprecated(note = "Legacy Cowork capability helper removed in Rainy API v3.")]
91    pub async fn has_paid_plan(&self) -> bool {
92        match self.get_cowork_capabilities().await {
93            Ok(caps) => caps.profile.plan.is_paid(),
94            Err(_) => false,
95        }
96    }
97
98    /// Check if a specific feature is available.
99    #[deprecated(note = "Legacy Cowork capability helper removed in Rainy API v3.")]
100    pub async fn can_use_feature(&self, feature: &str) -> bool {
101        match self.get_cowork_capabilities().await {
102            Ok(caps) => caps.can_use_feature(feature),
103            Err(_) => false,
104        }
105    }
106
107    /// Check if a specific model is available for the current plan.
108    #[deprecated(note = "Legacy Cowork capability helper removed in Rainy API v3.")]
109    pub async fn can_use_model(&self, model: &str) -> bool {
110        match self.get_cowork_capabilities().await {
111            Ok(caps) => caps.can_use_model(model),
112            Err(_) => false,
113        }
114    }
115
116    /// Check if user can make another request based on usage limits.
117    #[deprecated(note = "Legacy Cowork capability helper removed in Rainy API v3.")]
118    pub async fn can_make_request(&self) -> bool {
119        match self.get_cowork_capabilities().await {
120            Ok(caps) => caps.can_make_request(),
121            Err(_) => false,
122        }
123    }
124}
125
126/// Offline capabilities based on cached plan data.
127pub fn get_offline_capabilities(cached_plan: Option<CoworkPlan>) -> CoworkCapabilities {
128    match cached_plan {
129        Some(plan) if plan.is_paid() => {
130            // Reconstruct minimal capabilities
131            CoworkCapabilities {
132                profile: CoworkProfile {
133                    name: "Offline User".to_string(),
134                    email: "".to_string(),
135                    plan,
136                    usage: CoworkUsage::default(),
137                },
138                features: CoworkFeatures::default(), // Pessimistic offline features
139                is_valid: true,
140                models: vec!["gemini-2.5-flash".to_string()],
141                upgrade_message: None,
142            }
143        }
144        _ => CoworkCapabilities::free(),
145    }
146}