aboutsummaryrefslogtreecommitdiffstats
path: root/crates/atuin-ai/src/tools/descriptor.rs
blob: 6ccb595fa8c7c86e04a0d21a6fb4fe7e448fd3a6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/// Centralized metadata for a tool type.
///
/// Covers both client-side tools (ones the CLI executes locally) and
/// server-side tools (ones the API executes remotely). This is the single
/// source of truth for display text and classification.
pub(crate) struct ToolDescriptor {
    /// Canonical wire names for this tool (the names the server sends).
    pub canonical_names: &'static [&'static str],
    /// The capability string the client must advertise for this tool to be
    /// accepted. `None` for server-side tools (always accepted).
    pub capability: Option<&'static str>,
    /// Imperative verb for permission prompts (e.g. "read", "run").
    pub display_verb: &'static str,
    /// Present-tense progressive verb for spinners (e.g. "Reading file...").
    pub progressive_verb: &'static str,
    /// Past-tense verb for summaries (e.g. "Read file").
    pub past_verb: &'static str,
    /// Whether this tool is executed client-side (by the CLI).
    #[expect(dead_code)]
    pub is_client: bool,
}

// ── Client-side tool descriptors ──

pub(crate) const READ: &ToolDescriptor = &ToolDescriptor {
    canonical_names: &["read_file"],
    capability: Some("client_v1_read_file"),
    display_verb: "read",
    progressive_verb: "Reading file...",
    past_verb: "Read file",
    is_client: true,
};

pub(crate) const EDIT: &ToolDescriptor = &ToolDescriptor {
    canonical_names: &["edit_file"],
    capability: Some("client_v1_edit_file"),
    display_verb: "edit",
    progressive_verb: "Editing file...",
    past_verb: "Edited file",
    is_client: true,
};

pub(crate) const WRITE: &ToolDescriptor = &ToolDescriptor {
    canonical_names: &["write_file"],
    capability: Some("client_v1_write_file"),
    display_verb: "write to",
    progressive_verb: "Writing file...",
    past_verb: "Wrote file",
    is_client: true,
};

pub(crate) const SHELL: &ToolDescriptor = &ToolDescriptor {
    canonical_names: &["execute_shell_command"],
    capability: Some("client_v1_execute_shell_command"),
    display_verb: "run",
    progressive_verb: "Running command...",
    past_verb: "Ran command",
    is_client: true,
};

pub(crate) const ATUIN_HISTORY: &ToolDescriptor = &ToolDescriptor {
    canonical_names: &["atuin_history"],
    capability: Some("client_v1_atuin_history"),
    display_verb: "search your Atuin history for",
    progressive_verb: "Searching...",
    past_verb: "Searched",
    is_client: true,
};

// ── Server-side tool descriptors ──
// These appear in tool summaries but aren't client-side tools.

pub(crate) const SERVER_SEARCH: &ToolDescriptor = &ToolDescriptor {
    canonical_names: &["web_search"],
    capability: None,
    display_verb: "search",
    progressive_verb: "Searching...",
    past_verb: "Searched",
    is_client: false,
};

pub(crate) const SERVER_SCRAPE: &ToolDescriptor = &ToolDescriptor {
    canonical_names: &["web_scrape"],
    capability: None,
    display_verb: "scrape",
    progressive_verb: "Scraping...",
    past_verb: "Scraped",
    is_client: false,
};

/// All known tool descriptors, for lookup by name.
const ALL_DESCRIPTORS: &[&ToolDescriptor] = &[
    READ,
    EDIT,
    WRITE,
    SHELL,
    ATUIN_HISTORY,
    SERVER_SEARCH,
    SERVER_SCRAPE,
];

/// Look up a tool descriptor by its canonical wire name.
/// Returns None for unknown tool names.
pub(crate) fn by_name(name: &str) -> Option<&'static ToolDescriptor> {
    ALL_DESCRIPTORS
        .iter()
        .find(|d| d.canonical_names.contains(&name))
        .copied()
}