distri_filesystem/
config.rs1use distri_types::configuration::ObjectStorageConfig;
2use distri_types::Part;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone)]
7pub struct FileSystemConfig {
8 pub object_store: ObjectStorageConfig,
10 pub root_prefix: Option<String>,
12}
13
14impl Default for FileSystemConfig {
15 fn default() -> Self {
16 Self {
17 object_store: ObjectStorageConfig::FileSystem {
18 base_path: ".distri/files".to_string(),
19 },
20 root_prefix: Some("runs/default".to_string()),
21 }
22 }
23}
24
25#[derive(Debug, Clone)]
27pub struct ArtifactStorageConfig {
28 pub data_token_threshold: usize,
30 pub text_token_threshold: usize,
32 pub always_store_images: bool,
34 pub always_store_for_testing: bool,
36}
37
38impl Default for ArtifactStorageConfig {
39 fn default() -> Self {
40 Self {
41 data_token_threshold: 1000,
42 text_token_threshold: 1000,
43 always_store_images: true,
44 always_store_for_testing: true,
45 }
46 }
47}
48
49impl ArtifactStorageConfig {
50 pub fn for_testing() -> Self {
52 Self {
53 data_token_threshold: 0,
54 text_token_threshold: 0,
55 always_store_images: true,
56 always_store_for_testing: true,
57 }
58 }
59
60 pub fn for_production() -> Self {
62 Self {
63 data_token_threshold: 10000,
64 text_token_threshold: 10000,
65 always_store_images: false,
66 always_store_for_testing: false,
67 }
68 }
69
70 pub fn should_store(&self, part: &Part) -> bool {
72 if self.always_store_for_testing {
73 return match part {
74 Part::ToolCall(_) => false,
75 Part::Artifact(_) => false,
76 _ => true,
77 };
78 }
79
80 match part {
81 Part::Data(value) => {
82 let estimated_tokens = estimate_json_tokens(value);
83 estimated_tokens > self.data_token_threshold
84 }
85 Part::Text(text) => {
86 let estimated_tokens = estimate_text_tokens(text);
87 estimated_tokens > self.text_token_threshold
88 }
89 Part::ToolCall(_) => false,
90 Part::ToolResult(response) => response.parts.iter().any(|p| self.should_store(p)),
91 Part::Image(_) => self.always_store_images,
92 Part::Artifact(_) => false,
93 }
94 }
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize, Default)]
99pub struct ReadParams {
100 pub start_line: Option<u64>,
101 pub end_line: Option<u64>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct FileReadResult {
107 pub content: String,
108 pub start_line: u64,
109 pub end_line: u64,
110 pub total_lines: u64,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct DirectoryListing {
116 pub path: String,
117 pub entries: Vec<DirectoryEntry>,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct DirectoryEntry {
123 pub name: String,
124 pub is_file: bool,
125 pub is_dir: bool,
126 pub size: Option<u64>,
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct SearchResult {
132 pub path: String,
133 pub matches: Vec<SearchMatch>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct SearchMatch {
139 pub file_path: String,
140 pub line_number: Option<u64>,
141 pub line_content: String,
142 pub match_text: String,
143}
144
145fn estimate_json_tokens(value: &serde_json::Value) -> usize {
147 let json_string = serde_json::to_string(value).unwrap_or_default();
148 json_string.len() / 4
149}
150
151fn estimate_text_tokens(text: &str) -> usize {
153 text.len() / 4
154}