use saya_agent::ToolError;
use super::DatabaseTools;
use super::redaction_guard;
pub(crate) const WORKSPACE_WRITE_MAX_BYTES: usize = 64 * 1024;
impl DatabaseTools {
pub(super) async fn workspace_write(
&self,
arguments: &serde_json::Value,
) -> Result<serde_json::Value, ToolError> {
let rel = arguments
.get("path")
.and_then(serde_json::Value::as_str)
.ok_or(ToolError::PathNotString)?;
let content = arguments
.get("content")
.and_then(serde_json::Value::as_str)
.ok_or(ToolError::ContentNotString)?;
let Some(workspace) = &self.workspace else {
return Err(ToolError::WorkspaceUnavailable);
};
if content.len() > WORKSPACE_WRITE_MAX_BYTES {
return Err(ToolError::WorkspaceWriteTooLarge {
limit: WORKSPACE_WRITE_MAX_BYTES,
});
}
let existing_markers = redaction_guard::existing_marker_count(workspace, rel)
.map_err(|error| ToolError::WorkspaceWrite(error.to_string()))?;
redaction_guard::refuse_marker_growth(
rel,
existing_markers,
content.as_bytes(),
ToolError::WorkspaceWrite,
)?;
workspace
.write(rel, content.as_bytes())
.map_err(|error| ToolError::WorkspaceWrite(error.to_string()))?;
Ok(serde_json::json!({
"path": rel,
"bytes_written": content.len(),
}))
}
}