1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Data structures for Retrieval-Augmented Generation (RAG).
//!
//! This module provides core data structures for RAG integration.
//! Retrieval and ingestion logic should be implemented as `Agent`s,
//! not as separate traits, allowing for better composability and
//! integration with the agent ecosystem.
//!
//! # Design Philosophy
//!
//! Instead of defining `Retriever` and `Ingestor` traits, implement
//! retrieval and ingestion as regular agents:
//!
//! ## Retrieval Pattern
//!
//! Retrievers return `Vec<Document>` and can be composed with `RetrievalAwareAgent`:
//!
//! ```ignore
//! // Retriever as Agent
//! impl Agent for MyVectorStore {
//! type Output = Vec<Document>;
//! async fn execute(&self, payload: Payload) -> Result<Vec<Document>, AgentError> {
//! let query = payload.to_text();
//! // Perform semantic search...
//! Ok(documents)
//! }
//! }
//!
//! // Compose with RetrievalAwareAgent
//! let retriever = MyVectorStore::new();
//! let base_agent = MyLLMAgent::new();
//! let rag_agent = RetrievalAwareAgent::new(retriever, base_agent);
//! ```
//!
//! ## Ingestion Pattern
//!
//! Ingest agent accept `Attachment`s from payload and handle all implementation details
//! (upload, store creation, metadata management) internally:
//!
//! ```ignore
//! use llm_toolkit::attachment::Attachment;
//!
//! // Gemini Files API style
//! struct GeminiIngestAgent {
//! client: GeminiClient,
//! store_name: String, // Internal state
//! }
//!
//! impl Agent for GeminiIngestAgent {
//! type Output = IngestResult; // Can be any type
//!
//! async fn execute(&self, payload: Payload) -> Result<IngestResult, AgentError> {
//! let attachments = payload.attachments();
//! let mut file_names = Vec::new();
//!
//! for attachment in attachments {
//! // 1. Upload file
//! let file = self.client.files.upload(attachment).await?;
//!
//! // 2. Import into store (internal detail)
//! self.client.stores.import_file(&self.store_name, &file.name).await?;
//!
//! file_names.push(file.name);
//! }
//!
//! Ok(IngestResult { file_names })
//! }
//! }
//!
//! // Usage - just pass files
//! let geminiIngestAgent = GeminiIngestAgent::new(client, "my-store");
//! let payload = Payload::attachment(Attachment::local("document.pdf"));
//! let result = geminiIngestAgent.execute(payload).await?;
//! ```
use ;
/// Represents a piece of retrieved content from a knowledge source.
///
/// This is typically returned by retriever agents (agents with `Output = Vec<Document>`).
/// Documents can be attached to payloads and will be formatted by `PersonaAgent`
/// into a "Retrieved Context" section in the prompt.
///
/// # Examples
///
/// ```rust
/// use llm_toolkit::retrieval::Document;
///
/// let doc = Document {
/// content: "Rust is a systems programming language.".to_string(),
/// source: Some("rust_intro.md".to_string()),
/// score: Some(0.92),
/// };
/// ```