Skip to main content

harness_read/
schema.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[serde(deny_unknown_fields)]
6pub struct ReadParams {
7    pub path: String,
8    #[serde(default, skip_serializing_if = "Option::is_none")]
9    pub offset: Option<usize>,
10    #[serde(default, skip_serializing_if = "Option::is_none")]
11    pub limit: Option<usize>,
12}
13
14#[derive(Debug, Clone, thiserror::Error)]
15pub enum ReadParseError {
16    #[error("{0}")]
17    Message(String),
18}
19
20pub fn safe_parse_read_params(input: &Value) -> Result<ReadParams, ReadParseError> {
21    let parsed: ReadParams = serde_json::from_value(input.clone())
22        .map_err(|e| ReadParseError::Message(e.to_string()))?;
23    if parsed.path.is_empty() {
24        return Err(ReadParseError::Message("path must not be empty".to_string()));
25    }
26    if let Some(o) = parsed.offset {
27        if o < 1 {
28            return Err(ReadParseError::Message("offset must be >= 1".to_string()));
29        }
30    }
31    if let Some(l) = parsed.limit {
32        if l < 1 {
33            return Err(ReadParseError::Message("limit must be >= 1".to_string()));
34        }
35    }
36    Ok(parsed)
37}
38
39pub const READ_TOOL_NAME: &str = "read";
40pub const READ_TOOL_DESCRIPTION: &str = "Read a file or directory from the local filesystem.\n\nUsage:\n- The path parameter should be an absolute path. If relative, it resolves against the session working directory.\n- By default, returns up to 2000 lines from the start of the file.\n- The offset parameter is the 1-indexed line number to start from.\n- For later sections, call this tool again with a larger offset.\n- Use the grep tool for content search in large files; glob to locate files by pattern.\n- Contents are returned with each line prefixed by its line number as \"<line>: <content>\".\n- Any line longer than 2000 characters is truncated.\n- Call this tool in parallel when reading multiple files.\n- Avoid tiny repeated slices (under 30 lines). Read a larger window instead.\n- Images and PDFs are returned as file attachments.\n- Binary files are refused; use specialized tools.";