Skip to main content

rainy_sdk/endpoints/
search.rs

1//! Web Research endpoint
2//!
3//! This endpoint provides deep web research capabilities via Exa/Tavily.
4//! Requires a Cowork plan with web_research feature enabled.
5
6use crate::{
7    error::{RainyError, Result},
8    search::{DeepResearchResponse, ResearchConfig, ResearchRequest},
9    RainyClient,
10};
11
12impl RainyClient {
13    /// Perform deep web research on a topic.
14    ///
15    /// This method leverages the Rainy Agent Network to perform comprehensive
16    /// web research using providers like Exa or Tavily.
17    ///
18    /// # Arguments
19    ///
20    /// * `topic` - The research topic or question.
21    /// * `config` - Research configuration (provider, depth, etc.)
22    ///
23    /// # Returns
24    ///
25    /// A `Result` containing `DeepResearchResponse` on success.
26    ///
27    /// # Example
28    ///
29    /// ```rust,no_run
30    /// # use rainy_sdk::{RainyClient, search::ResearchConfig, models::{ResearchProvider, ResearchDepth}};
31    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
32    /// let client = RainyClient::with_api_key("your-api-key")?;
33    ///
34    /// // Basic research
35    /// let response = client.research("Latest Rust features", None).await?;
36    /// if let Some(content) = response.result {
37    ///     println!("Report: {}", content);
38    /// }
39    ///
40    /// // Advanced deep research with Exa
41    /// let config = ResearchConfig::new()
42    ///     .with_provider(ResearchProvider::Exa)
43    ///     .with_depth(ResearchDepth::Advanced);
44    ///
45    /// let response = client.research("Quantum Computing advances", Some(config)).await?;
46    /// # Ok(())
47    /// # }
48    /// ```
49    pub async fn research(
50        &self,
51        topic: impl Into<String>,
52        config: Option<ResearchConfig>,
53    ) -> Result<DeepResearchResponse> {
54        let cfg = config.unwrap_or_default();
55        let request = ResearchRequest::new(topic.into(), &cfg);
56
57        // Note: The endpoint is /agents/research based on previous analysis
58        let url = format!("{}/agents/research", self.auth_config().base_url);
59
60        let response = self
61            .http_client()
62            .post(&url)
63            .json(&request)
64            .send()
65            .await
66            .map_err(|e| RainyError::Network {
67                message: e.to_string(),
68                retryable: true,
69                source_error: Some(e.to_string()),
70            })?;
71
72        if response.status().as_u16() == 403 {
73            return Err(RainyError::Authentication {
74                code: "FEATURE_NOT_AVAILABLE".to_string(),
75                message: "Research feature requires a valid subscription".to_string(),
76                retryable: false,
77            });
78        }
79
80        self.handle_response(response).await
81    }
82}