agent_workspace_contract/
ports.rs1use super::*;
2
3#[async_trait]
5pub trait WorkspaceFiles: Send + Sync + Debug {
6 async fn file_read(&self, path: &str) -> Result<String>;
7 async fn file_write(&self, path: &str, content: &str) -> Result<()>;
8 async fn directory_create_all(&self, path: &str) -> Result<()>;
9 async fn file_remove(&self, path: &str) -> Result<()>;
10 async fn path_exists(&self, path: &str) -> Result<bool>;
11 async fn directory_list(&self, path: &str) -> Result<Vec<DirEntry>>;
12}
13
14#[async_trait]
16pub trait WorkspaceSearch: Send + Sync + Debug {
17 async fn search_walk_tree(&self, path: &str, max_depth: usize) -> Result<Vec<String>>;
18 async fn search_find_files(&self, pattern: &str, path: &str) -> Result<Vec<String>>;
19 async fn search_grep(
20 &self,
21 pattern: &str,
22 path: &str,
23 include: Option<&str>,
24 ) -> Result<Vec<GrepMatch>>;
25}
26
27#[async_trait]
29pub trait WorkspaceCommands: Send + Sync + Debug {
30 async fn command_exec(&self, command: &str, cwd: Option<&str>) -> Result<CmdOutput>;
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct ProviderRequestFailure {
40 pub status_code: Option<u16>,
41 pub transport_failure: bool,
42 pub retry_after_ms: Option<u64>,
43}
44
45pub trait ProviderResiliencePolicy: Send + Sync + Debug {
47 fn retry_delay_ms(
50 &self,
51 failure: ProviderRequestFailure,
52 completed_attempts: u32,
53 idempotent: bool,
54 ) -> Option<u64>;
55
56 fn circuit_open_ms(&self, consecutive_failures: u32) -> Option<u64>;
59}
60
61#[async_trait]
62impl<T: Workspace + ?Sized> WorkspaceFiles for T {
63 async fn file_read(&self, path: &str) -> Result<String> {
64 Workspace::read_file(self, path).await
65 }
66 async fn file_write(&self, path: &str, content: &str) -> Result<()> {
67 Workspace::write_file(self, path, content).await
68 }
69 async fn directory_create_all(&self, path: &str) -> Result<()> {
70 Workspace::create_dir_all(self, path).await
71 }
72 async fn file_remove(&self, path: &str) -> Result<()> {
73 Workspace::remove_file(self, path).await
74 }
75 async fn path_exists(&self, path: &str) -> Result<bool> {
76 Workspace::exists(self, path).await
77 }
78 async fn directory_list(&self, path: &str) -> Result<Vec<DirEntry>> {
79 Workspace::list_dir(self, path).await
80 }
81}
82
83#[async_trait]
84impl<T: Workspace + ?Sized> WorkspaceSearch for T {
85 async fn search_walk_tree(&self, path: &str, max_depth: usize) -> Result<Vec<String>> {
86 Workspace::walk_tree(self, path, max_depth).await
87 }
88 async fn search_find_files(&self, pattern: &str, path: &str) -> Result<Vec<String>> {
89 Workspace::find_files(self, pattern, path).await
90 }
91 async fn search_grep(
92 &self,
93 pattern: &str,
94 path: &str,
95 include: Option<&str>,
96 ) -> Result<Vec<GrepMatch>> {
97 Workspace::grep(self, pattern, path, include).await
98 }
99}
100
101#[async_trait]
102impl<T: Workspace + ?Sized> WorkspaceCommands for T {
103 async fn command_exec(&self, command: &str, cwd: Option<&str>) -> Result<CmdOutput> {
104 Workspace::exec(self, command, cwd).await
105 }
106}