Skip to main content

tau_agent_plugin/
lib.rs

1//! Plugin SDK for the tau agent.
2//!
3//! This crate provides everything a plugin author needs in one place:
4//! - The `ToolExecutor` trait (the tool execution abstraction)
5//! - The `tunnel` module for plugin ↔ server communication
6//! - Re-exports of all plugin-relevant types from `tau-agent-base`
7
8pub mod executor;
9pub mod tunnel;
10
11// Re-export the ToolExecutor trait at crate root for convenience
12pub use executor::ToolExecutor;
13
14// Re-export plugin-relevant types from tau-agent-base
15pub use tau_agent_base::paths::data_dir;
16pub use tau_agent_base::plugin_protocol::*;
17pub use tau_agent_base::protocol::{Request, Response, SessionInfo};
18pub use tau_agent_base::tool_prompt::ToolPrompt;
19pub use tau_agent_base::types::*;
20pub use tau_agent_base::{Error, Result, read_json_line, write_json_line};
21
22/// Built-in tool prompts for the default tools (bash, read, edit, write).
23///
24/// This is the canonical single source for these prompts. Both the engine's
25/// `system_prompt::build_default` and the worker crate delegate here.
26pub fn default_tool_prompts() -> Vec<ToolPrompt> {
27    vec![
28        ToolPrompt {
29            name: "bash".into(),
30            snippet: "Execute bash commands (ls, grep, find, etc.)".into(),
31            guidelines: vec!["Use bash for file operations like ls, rg, find".into()],
32        },
33        ToolPrompt {
34            name: "read".into(),
35            snippet: "Read file contents".into(),
36            guidelines: vec![
37                "Use read to examine files instead of cat or sed.".into(),
38                "Each line in the output is prefixed with `<hash>§` (or `<hash>.<n>§` for duplicate lines) — these are stable per-line anchors you can pass to the edit tool's anchor shape.".into(),
39            ],
40        },
41        ToolPrompt {
42            name: "edit".into(),
43            snippet: "Make precise file edits with exact text replacement or by line-anchor, including multiple disjoint edits in one call across one or more files".into(),
44            guidelines: vec![
45                "Use edit for precise changes (old text must match exactly)".into(),
46                "When changing multiple separate locations in one file, use one edit call with edits[] instead of multiple edit calls".into(),
47                "For refactors that touch several files, batch them into one edit call using `files: [{path, edits: [...]}, ...]` instead of issuing one edit call per file.".into(),
48                "Each edits[].old_text is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.".into(),
49                "Keep edits[].old_text as small as possible while still being unique in the file. Do not pad with large unchanged regions.".into(),
50                "Anchor shape: `{edit_type: \"replace\"|\"insert_before\"|\"insert_after\", anchor, end_anchor?, text}`. `anchor` / `end_anchor` come from the read tool's `<hash>§` prefixes (the bare token or the full hashed line both work). `replace` is inclusive on both ends; omit `end_anchor` for a single-line replace.".into(),
51                "Prefer the anchor shape over `old_text` when whitespace is fiddly or the text appears more than once — anchors sidestep both problems.".into(),
52                "Anchors are validated against the file's current content. If you get an `anchor not found` error, re-read the file to get fresh anchors and try again.".into(),
53            ],
54        },
55        ToolPrompt {
56            name: "write".into(),
57            snippet: "Create or overwrite files".into(),
58            guidelines: vec!["Use write only for new files or complete rewrites.".into()],
59        },
60        ToolPrompt {
61            name: "get_file_skeleton".into(),
62            snippet: "Quickly outline source files (classes / functions / methods, no bodies) using tree-sitter".into(),
63            guidelines: vec![
64                "Prefer get_file_skeleton over reading whole files when surveying a codebase — pass several paths in one call to skim 10 files for ~5% the tokens of reading them, then use `read` for the parts you need to see in full.".into(),
65                "Supports Rust, Python, JavaScript, TypeScript, and TSX. Other extensions return a per-file error suggesting `read` instead — partial success is fine, only an all-fail call is flagged as an error.".into(),
66            ],
67        },
68        ToolPrompt {
69            name: "get_function".into(),
70            snippet: "Extract complete bodies of named functions/methods from one or more files (tree-sitter)".into(),
71            guidelines: vec![
72                "Use get_function to drill into 1-2 specific functions in a large file instead of `read`-ing the whole thing.".into(),
73                "Function names support dot-paths for methods (`Foo.bar`, `ClassName.methodName`); `::` is also accepted for Rust. Bare names (`bar`) match any definition whose qualified name ends in `.bar` — multiple matches are returned together.".into(),
74                "Pairs with get_file_skeleton: skim the skeleton first, then pull bodies you actually need.".into(),
75            ],
76        },
77        ToolPrompt {
78            name: "diagnostics_scan".into(),
79            snippet: "Run lint/syntax diagnostics on specific files and get structured per-file feedback (built-in: Rust via cargo check; configurable via .tau/diagnostics.toml)".into(),
80            guidelines: vec![
81                "Use diagnostics_scan after edits to verify the file compiles/lints cleanly, instead of running full-project `cargo check` via bash.".into(),
82                "Pass only the files you actually changed; the tool resolves project context automatically.".into(),
83                "Output is structured JSON ({summary, diagnostics[], skipped[]}). is_error is false even when diagnostics are present — read the JSON to count errors.".into(),
84            ],
85        },
86    ]
87}