1use thiserror::Error;
2
3pub const LARGE_TOOL_RESULT_BYTES: usize = 16 * 1024;
4pub const TOOL_RESULT_PREVIEW_BYTES: usize = 4 * 1024;
5pub const TOOL_RESULT_DEFAULT_READ_BYTES: usize = 8 * 1024;
6pub const TOOL_RESULT_MAX_READ_BYTES: usize = 64 * 1024;
7
8#[derive(Clone, Debug, Eq, PartialEq)]
9pub struct StoredToolResult {
10 pub handle: String,
11 pub stored_bytes: usize,
12}
13
14#[derive(Clone, Debug, Eq, PartialEq)]
15pub struct ToolResultPage {
16 pub content: String,
17 pub start_byte: usize,
18 pub end_byte: usize,
19 pub total_bytes: usize,
20}
21
22#[derive(Clone, Debug, Eq, PartialEq)]
23pub struct ToolResultMatch {
24 pub line: usize,
25 pub content: String,
26}
27
28#[derive(Debug, Error, Eq, PartialEq)]
29pub enum ToolResultStoreError {
30 #[error("invalid tool-result handle")]
31 InvalidHandle,
32 #[error("tool-result query must not be empty")]
33 InvalidQuery,
34 #[error("tool-result handle was not found")]
35 NotFound,
36 #[error("tool result exceeds the storage limit")]
37 TooLarge,
38 #[error("tool-result store is unavailable: {0}")]
39 Unavailable(String),
40}
41
42pub trait ToolResultStore: Send + Sync {
48 fn store(
49 &self,
50 tool_call_id: &str,
51 tool_name: &str,
52 content: &str,
53 ) -> Result<StoredToolResult, ToolResultStoreError>;
54
55 fn read_range(
56 &self,
57 handle: &str,
58 start_byte: usize,
59 byte_count: usize,
60 ) -> Result<ToolResultPage, ToolResultStoreError>;
61
62 fn search(
63 &self,
64 handle: &str,
65 query: &str,
66 max_matches: usize,
67 ) -> Result<Vec<ToolResultMatch>, ToolResultStoreError>;
68}