gemini_adk_rs/tools/retrieval/
base.rs

1//! Base retrieval tool trait.
2
3use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5
6use crate::error::ToolError;
7
8/// A single retrieval result — a document chunk with metadata.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct RetrievalResult {
11    /// The retrieved text content.
12    pub content: String,
13    /// Source identifier (e.g., file path, URL, document ID).
14    pub source: String,
15    /// Relevance score (0.0–1.0, higher is more relevant).
16    pub score: f64,
17    /// Optional metadata about the retrieved chunk.
18    #[serde(default)]
19    pub metadata: serde_json::Value,
20}
21
22/// Trait for retrieval tools that fetch relevant context.
23///
24/// Implementations search over a corpus and return ranked results
25/// that can be injected into the LLM context.
26#[async_trait]
27pub trait BaseRetrievalTool: Send + Sync {
28    /// The name of this retrieval tool.
29    fn name(&self) -> &str;
30
31    /// Search the corpus with a query and return ranked results.
32    async fn retrieve(&self, query: &str, top_k: usize) -> Result<Vec<RetrievalResult>, ToolError>;
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    fn _assert_object_safe(_: &dyn BaseRetrievalTool) {}
40
41    #[test]
42    fn retrieval_result_serde() {
43        let result = RetrievalResult {
44            content: "Test content".into(),
45            source: "doc.txt".into(),
46            score: 0.95,
47            metadata: serde_json::json!({"page": 1}),
48        };
49        let json = serde_json::to_string(&result).unwrap();
50        let deserialized: RetrievalResult = serde_json::from_str(&json).unwrap();
51        assert!((deserialized.score - 0.95).abs() < f64::EPSILON);
52    }
53}