Skip to main content

rightkit_agent_tools/
lib.rs

1//! rightkit-agent-tools: one typed tool interface for agents over the Right Suite.
2//!
3//! * [`Tool`] / [`ToolSpec`]: a name, a JSON schema and an effect class.
4//! * [`Toolbox`]: registry plus the one gate every call passes (hard exposure
5//!   rules, per-caller allowlist, argument schema, the caller's admission hook,
6//!   journal).
7//! * Backends: `<app>.*` over each app's in-app control service
8//!   (`rightkit-qa-driver` on `rightkit-daemon`, including the app's own typed
9//!   commands), `desktop.*` over `rightkit-automation`, `browser.*` over
10//!   `rightkit-browser`, `speech.*` over the shared speech service
11//!   (`rightkit-speech-client`, the first client).
12//! * `right-ctl <app> <command>`: the CLI over the same toolbox.
13//!
14//! HeardRight's rules are built in and not configurable: no dictation, text
15//! delivery, pasteboard or history tool can be registered or called ([`exposure`]).
16
17pub mod backends;
18pub mod exposure;
19mod journal;
20mod spec;
21mod toolbox;
22
23pub use backends::control::{
24    control_tools, AppProfile, CommandPolicy, CLIENT_APP, CONTROL_METHODS,
25};
26pub use journal::JsonlJournal;
27pub use spec::*;
28pub use toolbox::{
29    DeniedBy, Journal, MemoryJournal, Metrics, ToolAdmission, ToolEvent, ToolRequest, Toolbox,
30    Verdict,
31};
32
33use rightkit_daemon::Suite;
34use std::sync::Arc;
35
36/// The caller identity `right-ctl` uses (and the service-side allowlist key).
37pub const CTL_CALLER: &str = CLIENT_APP;
38
39/// A toolbox for the CLI caller: `<app>.*` tools for each named app (built-in
40/// [`AppProfile::for_app`] profile), `speech.*` when HeardRight is among them,
41/// and allowlist patterns granting `right-ctl` exactly what each profile allows.
42pub fn control_toolbox(suite: &Suite, apps: &[&str]) -> Result<Toolbox, ToolError> {
43    let mut tb = Toolbox::new();
44    for app in apps {
45        add_app(&mut tb, suite, AppProfile::for_app(app))?;
46    }
47    Ok(tb)
48}
49
50/// Register one app profile and grant [`CTL_CALLER`] its patterns.
51pub fn add_app(tb: &mut Toolbox, suite: &Suite, profile: AppProfile) -> Result<(), ToolError> {
52    tb.register_all(control_tools(suite, &profile))?;
53    tb.allow(CTL_CALLER, profile.allow_patterns());
54    #[cfg(feature = "speech")]
55    if profile.app == "heardright" {
56        tb.register_all(backends::speech::speech_tools(suite))?;
57        tb.allow(CTL_CALLER, ["speech.transcribe", "speech.capabilities"]);
58    }
59    Ok(())
60}
61
62/// Convenience: share a toolbox.
63pub fn shared(tb: Toolbox) -> Arc<Toolbox> {
64    Arc::new(tb)
65}