Skip to main content

synaptic_deep/backend/
mod.rs

1use async_trait::async_trait;
2use serde::{Deserialize, Serialize};
3use std::time::Duration;
4use synaptic_core::SynapticError;
5
6pub mod state;
7pub mod store;
8
9#[cfg(feature = "filesystem")]
10pub mod filesystem;
11
12pub use state::StateBackend;
13pub use store::StoreBackend;
14
15#[cfg(feature = "filesystem")]
16pub use filesystem::FilesystemBackend;
17
18/// A directory entry returned by [`Backend::ls`].
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct DirEntry {
21    pub name: String,
22    pub is_dir: bool,
23    pub size: Option<u64>,
24}
25
26/// Result of a shell command execution.
27#[derive(Debug, Clone)]
28pub struct ExecResult {
29    pub stdout: String,
30    pub stderr: String,
31    pub exit_code: i32,
32}
33
34/// A single grep match.
35#[derive(Debug, Clone)]
36pub struct GrepMatch {
37    pub file: String,
38    pub line_number: usize,
39    pub line: String,
40}
41
42/// Output mode for grep operations.
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum GrepOutputMode {
45    FilesWithMatches,
46    Content,
47    Count,
48}
49
50/// Pluggable filesystem backend for deep agents.
51///
52/// Implementations provide file I/O, glob, and grep operations.
53/// The default `execute` method returns an error; override it to support shell commands.
54#[async_trait]
55pub trait Backend: Send + Sync {
56    /// List entries in a directory.
57    async fn ls(&self, path: &str) -> Result<Vec<DirEntry>, SynapticError>;
58
59    /// Read file contents with line-based pagination.
60    async fn read_file(
61        &self,
62        path: &str,
63        offset: usize,
64        limit: usize,
65    ) -> Result<String, SynapticError>;
66
67    /// Create or overwrite a file.
68    async fn write_file(&self, path: &str, content: &str) -> Result<(), SynapticError>;
69
70    /// Find-and-replace text in a file.
71    async fn edit_file(
72        &self,
73        path: &str,
74        old_text: &str,
75        new_text: &str,
76        replace_all: bool,
77    ) -> Result<(), SynapticError>;
78
79    /// Match file paths against a glob pattern within a base directory.
80    async fn glob(&self, pattern: &str, base: &str) -> Result<Vec<String>, SynapticError>;
81
82    /// Search file contents by regex pattern.
83    async fn grep(
84        &self,
85        pattern: &str,
86        path: Option<&str>,
87        file_glob: Option<&str>,
88        output_mode: GrepOutputMode,
89    ) -> Result<String, SynapticError>;
90
91    /// Execute a shell command. Returns error by default.
92    async fn execute(
93        &self,
94        _command: &str,
95        _timeout: Option<Duration>,
96    ) -> Result<ExecResult, SynapticError> {
97        Err(SynapticError::Tool(
98            "execution not supported by this backend".into(),
99        ))
100    }
101
102    /// Whether this backend supports shell command execution.
103    fn supports_execution(&self) -> bool {
104        false
105    }
106}