Skip to main content

zeph_tools/
lib.rs

1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Tool execution abstraction, shell backend, web scraping, and audit logging for Zeph.
5//!
6//! This crate provides the [`ToolExecutor`] trait and its concrete implementations:
7//!
8//! - [`ShellExecutor`] — executes bash blocks from LLM responses with sandboxing, blocklists,
9//!   output filtering, transactional rollback, and audit logging.
10//! - [`WebScrapeExecutor`] — fetches and scrapes web pages via CSS selectors, with SSRF
11//!   protection and domain policies.
12//! - [`CompositeExecutor`] — chains two executors with first-match-wins dispatch.
13//! - [`FileExecutor`] — reads and writes local files within a sandbox.
14//! - [`DiagnosticsExecutor`] — exposes agent self-diagnostics as a tool.
15//!
16//! # Architecture
17//!
18//! The primary abstraction is [`ToolExecutor`], an async trait implemented by every backend.
19//! When dynamic dispatch is needed (e.g., storing heterogeneous executors in a `Vec`), use
20//! [`ErasedToolExecutor`] or wrap with [`DynExecutor`].
21//!
22//! Tool calls originate from two paths:
23//!
24//! 1. **Fenced code blocks** — legacy LLM responses containing ` ```bash ` or ` ```scrape `
25//!    blocks dispatched via [`ToolExecutor::execute`].
26//! 2. **Structured tool calls** — modern JSON tool calls dispatched via
27//!    [`ToolExecutor::execute_tool_call`].
28//!
29//! # Security
30//!
31//! Every executor enforces security controls before execution:
32//!
33//! - [`ShellExecutor`] checks the command against a blocklist, validates paths against an
34//!   allowlist sandbox, and optionally requires user confirmation for destructive patterns.
35//! - [`WebScrapeExecutor`] validates the URL scheme (HTTPS only), resolves DNS, and rejects
36//!   private-network addresses (SSRF protection).
37//! - [`AuditLogger`] writes a structured JSONL entry for every tool invocation.
38//!
39//! # Example
40//!
41//! ```rust,no_run
42//! use zeph_tools::{ShellExecutor, ToolExecutor, ShellConfig};
43//!
44//! # async fn example() {
45//! let config = ShellConfig::default();
46//! let executor = ShellExecutor::new(&config);
47//!
48//! // Execute a fenced bash block from an LLM response.
49//! let response = "```bash\necho hello\n```";
50//! if let Ok(Some(output)) = executor.execute(response).await {
51//!     println!("{}", output.summary);
52//! }
53//! # }
54//! ```
55
56// TODO(critic): post-v1.0 — re-evaluate splitting executor / web / shell into sub-crates if compile times degrade.
57
58pub mod adversarial_gate;
59pub mod adversarial_policy;
60pub mod anomaly;
61pub mod audit;
62pub mod cache;
63pub mod composite;
64pub mod compression;
65pub mod config;
66pub mod cwd;
67pub mod diagnostics;
68pub mod domain_match;
69pub mod error_taxonomy;
70pub mod execution_context;
71pub mod executor;
72pub mod executor_delegate;
73pub mod file;
74pub mod filter;
75pub mod moderation;
76pub mod net;
77pub mod permissions;
78pub mod policy;
79pub mod policy_gate;
80pub mod registry;
81pub mod risk_chain;
82pub mod sandbox;
83pub mod schema_filter;
84pub mod scope;
85pub mod scrape;
86pub mod search_code;
87pub mod shadow_probe;
88pub mod shell;
89pub mod tool_filter;
90pub mod trust_gate;
91pub mod trust_level;
92pub mod utility;
93pub mod verifier;
94pub use adversarial_gate::AdversarialPolicyGateExecutor;
95pub use adversarial_policy::{
96    PolicyDecision as AdversarialPolicyDecision, PolicyLlmClient, PolicyMessage, PolicyRole,
97    PolicyValidator, parse_policy_lines,
98};
99pub use anomaly::{AnomalyDetector, AnomalySeverity, is_reasoning_model};
100pub use audit::{
101    AuditEntry, AuditLogger, AuditResult, EgressEvent, VigilRiskLevel, chrono_now,
102    log_tool_risk_summary,
103};
104pub use cache::{CacheKey, ToolResultCache, is_cacheable};
105pub use composite::CompositeExecutor;
106pub use compression::{
107    CompressedExecutor, CompressionError, CompressionRule, CompressionRuleStore,
108    IdentityCompressor, OutputCompressor, RuleBasedCompressor, safe_compile,
109};
110pub use config::{build_permission_policy, validate_sandbox_denied_domains};
111pub use cwd::{SetCwdExecutor, resolve_and_set_cwd};
112pub use diagnostics::DiagnosticsExecutor;
113pub use error_taxonomy::{
114    ErrorDomain, ToolErrorCategory, ToolErrorFeedback, ToolInvocationPhase, classify_http_status,
115    classify_io_error,
116};
117pub use execution_context::ExecutionContext;
118pub use executor::{
119    CheckpointActionResult, CheckpointEntryView, CheckpointListResult, ClaimSource, DiffData,
120    DynExecutor, ErasedToolExecutor, ErrorKind, FilterStats, MAX_TOOL_OUTPUT_CHARS,
121    TOOL_EVENT_CHANNEL_CAP, ToolCall, ToolError, ToolEvent, ToolEventRx, ToolEventTx, ToolExecutor,
122    ToolOutput, truncate_tool_output, truncate_tool_output_at,
123};
124pub use file::FileExecutor;
125pub use filter::{
126    CommandMatcher, FilterConfidence, FilterMetrics, FilterResult, OutputFilter,
127    OutputFilterRegistry, sanitize_output, strip_ansi,
128};
129pub use moderation::{
130    DeleteAllReactionsParams, DeleteReactionParams, ModerationError, ModerationExecutor,
131    ReactionModerationBackend,
132};
133pub use net::is_private_ip;
134pub use permissions::PermissionPolicy;
135pub use policy::{PolicyCompileError, PolicyContext, PolicyDecision, PolicyEnforcer};
136pub use policy_gate::{PolicyGateExecutor, RiskSignalQueue, TrajectoryRiskSlot};
137pub use registry::ToolRegistry;
138pub use risk_chain::{RiskChainAccumulator, RiskChainVerdict, RiskTag};
139#[cfg(target_os = "macos")]
140pub use sandbox::MacosSandbox;
141pub use sandbox::{
142    NoopSandbox, Sandbox, SandboxError, SandboxPolicy, build_sandbox, build_sandbox_with_policy,
143};
144pub use schema_filter::{
145    DependencyExclusion, InclusionReason, ToolDependencyGraph, ToolEmbedding, ToolFilterResult,
146    ToolSchemaFilter,
147};
148pub use scope::{ScopeError, ScopeWarning, ScopedToolExecutor, ToolScope, build_scoped_executor};
149pub use scrape::WebScrapeExecutor;
150pub use search_code::{
151    LspSearchBackend, SearchCodeExecutor, SearchCodeHit, SearchCodeSource, SemanticSearchBackend,
152};
153pub use shadow_probe::{ProbeGate, ProbeOutcome, ShadowProbeExecutor};
154pub use shell::background::{BackgroundCompletion, BackgroundRunSnapshot, RunId};
155pub use shell::{
156    DEFAULT_BLOCKED_COMMANDS, NETWORK_COMMANDS, SHELL_INTERPRETERS, SafeFixSuggestion,
157    ShellExecutor, ShellOutputEnvelope, ShellPolicyHandle, check_blocklist, deobfuscate_command,
158    effective_shell_command, is_blocked_rm_worktrees,
159};
160pub use tool_filter::ToolFilter;
161pub use trust_gate::TrustGateExecutor;
162pub use trust_level::SkillTrustLevel;
163pub use utility::{
164    UtilityAction, UtilityContext, UtilityScore, UtilityScorer, has_explicit_tool_request,
165};
166pub use verifier::{
167    DestructiveCommandVerifier, FirewallVerifier, InjectionPatternVerifier, PreExecutionVerifier,
168    UrlGroundingVerifier, VerificationResult,
169};
170pub use zeph_common::ToolName;
171pub use zeph_config::tools::{
172    AdversarialPolicyConfig, AnomalyConfig, AuditConfig, AuditDestination, AuthorizationConfig,
173    DefaultEffect, DependencyConfig, EgressConfig, FileConfig, FilterConfig, OverflowConfig,
174    PolicyConfig, PolicyEffect, PolicyRuleConfig, ResultCacheConfig, RetryConfig, SandboxConfig,
175    SandboxProfile, ScrapeConfig, SecurityFilterConfig, ShellConfig, TafcConfig, ToolDependency,
176    ToolsConfig, UtilityScoringConfig,
177};
178pub use zeph_config::tools::{
179    AutonomyLevel, PermissionAction, PermissionRule, PermissionsConfig, SpeculationMode,
180    SpeculativeAllowlistConfig, SpeculativeConfig, SpeculativePatternConfig,
181};
182pub use zeph_config::tools::{
183    DestructiveVerifierConfig, FirewallVerifierConfig, InjectionVerifierConfig,
184    PreExecutionVerifierConfig, UrlGroundingVerifierConfig,
185};