rust_genai/
deep_research.rs

1//! Deep Research convenience wrapper (Preview).
2
3use std::pin::Pin;
4use std::sync::Arc;
5
6use futures_util::Stream;
7use rust_genai_types::interactions::{
8    CreateInteractionConfig, Interaction, InteractionEvent, InteractionInput,
9    InteractionThinkingSummaries,
10};
11use rust_genai_types::tool::{GoogleSearch, Tool};
12
13use crate::client::ClientInner;
14use crate::error::Result;
15use crate::interactions::Interactions;
16
17#[derive(Clone)]
18pub struct DeepResearch {
19    inner: Arc<ClientInner>,
20}
21
22impl DeepResearch {
23    pub(crate) fn new(inner: Arc<ClientInner>) -> Self {
24        Self { inner }
25    }
26
27    /// 启动 Deep Research(默认配置)。
28    pub async fn start(
29        &self,
30        model: impl Into<String>,
31        input: impl Into<InteractionInput>,
32    ) -> Result<Interaction> {
33        let mut config = CreateInteractionConfig::new(model, input);
34        apply_deep_research_defaults(&mut config);
35        Interactions::new(self.inner.clone()).create(config).await
36    }
37
38    /// 启动 Deep Research(自定义配置)。
39    pub async fn start_with_config(
40        &self,
41        mut config: CreateInteractionConfig,
42    ) -> Result<Interaction> {
43        apply_deep_research_defaults(&mut config);
44        Interactions::new(self.inner.clone()).create(config).await
45    }
46
47    /// 流式启动 Deep Research(自定义配置)。
48    pub async fn stream_with_config(
49        &self,
50        mut config: CreateInteractionConfig,
51    ) -> Result<Pin<Box<dyn Stream<Item = Result<InteractionEvent>> + Send>>> {
52        apply_deep_research_defaults(&mut config);
53        Interactions::new(self.inner.clone())
54            .create_stream(config)
55            .await
56    }
57}
58
59fn apply_deep_research_defaults(config: &mut CreateInteractionConfig) {
60    if config.background.is_none() {
61        config.background = Some(true);
62    }
63    if config.store.is_none() {
64        config.store = Some(true);
65    }
66    if config.thinking_summaries.is_none() {
67        config.thinking_summaries = Some(InteractionThinkingSummaries::Auto);
68    }
69    if config.tools.is_none() {
70        config.tools = Some(vec![Tool {
71            google_search: Some(GoogleSearch::default()),
72            ..Default::default()
73        }]);
74    }
75}