steer_core/tools/static_tools/
grep.rs1use async_trait::async_trait;
2use std::time::Duration;
3use tokio::time::timeout;
4
5use super::workspace_op_error;
6use crate::tools::capability::Capabilities;
7use crate::tools::static_tool::{StaticTool, StaticToolContext, StaticToolError};
8use steer_tools::result::GrepResult;
9use steer_tools::tools::grep::{GrepError, GrepParams, GrepToolSpec};
10use steer_workspace::{GrepRequest, WorkspaceOpContext};
11
12pub struct GrepTool;
13
14#[async_trait]
15impl StaticTool for GrepTool {
16 type Params = GrepParams;
17 type Output = GrepResult;
18 type Spec = GrepToolSpec;
19
20 const DESCRIPTION: &'static str = r#"Fast content search built on ripgrep for blazing performance at any scale.
21- Searches using regular expressions or literal strings
22- Supports regex syntax like "log.*Error", "function\\s+\\w+", etc.
23- If the pattern isn't valid regex, it automatically searches for the literal text
24- Filter files by name pattern with include parameter (e.g., "*.js", "*.{ts,tsx}")
25- Automatically respects .gitignore files
26- Returns matches as "filepath:line_number: line_content""#;
27 const REQUIRES_APPROVAL: bool = false;
28 const REQUIRED_CAPABILITIES: Capabilities = Capabilities::WORKSPACE;
29
30 async fn execute(
31 &self,
32 params: Self::Params,
33 ctx: &StaticToolContext,
34 ) -> Result<Self::Output, StaticToolError<GrepError>> {
35 const GREP_TIMEOUT: Duration = Duration::from_secs(30);
36
37 let request = GrepRequest {
38 pattern: params.pattern,
39 include: params.include,
40 path: params.path,
41 };
42 let op_ctx =
43 WorkspaceOpContext::new(ctx.tool_call_id.0.clone(), ctx.cancellation_token.clone());
44
45 tokio::select! {
46 () = ctx.cancellation_token.cancelled() => Err(StaticToolError::Cancelled),
47 result = timeout(GREP_TIMEOUT, ctx.services.workspace.grep(request, &op_ctx)) => {
48 match result {
49 Ok(Ok(search_result)) => Ok(GrepResult(search_result)),
50 Ok(Err(error)) => Err(StaticToolError::execution(GrepError::Workspace(workspace_op_error(error)))),
51 Err(_) => Err(StaticToolError::Timeout),
52 }
53 }
54 }
55 }
56}