From fdf74903ada13d5f884dd75cb45a6b87a362ff74 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Sun, 25 Jan 2026 08:42:36 -0300 Subject: [PATCH] fix(server): update security modules and TODOs --- Cargo.toml | 33 +- TODO.md | 358 ++++++++++++++---- TODO.tmp | 663 --------------------------------- docs/guides/tools-vs-bots.md | 308 +++++++++++++++ src/security/auth_provider.rs | 2 +- src/security/protection/api.rs | 80 ++-- 6 files changed, 665 insertions(+), 779 deletions(-) delete mode 100644 TODO.tmp create mode 100644 docs/guides/tools-vs-bots.md diff --git a/Cargo.toml b/Cargo.toml index 5edb2fe3b..bcc5b4d76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,8 @@ directory = [] # Communication chat = ["automation", "drive", "cache"] people = ["automation", "drive", "cache"] -mail = ["automation", "drive", "cache", "dep:lettre", "dep:mailparse", "dep:imap", "dep:native-tls"] -meet = ["automation", "drive", "cache", "dep:livekit"] +mail = ["automation", "drive", "cache", "dep:lettre", "dep:mailparse", "dep:imap"] +meet = ["automation", "drive", "cache"] social = ["automation", "drive", "cache"] # Productivity @@ -38,7 +38,7 @@ billing = ["automation", "drive", "cache"] # Documents docs = ["automation", "drive", "cache", "docx-rs", "ooxmlsdk"] -sheet = ["automation", "drive", "cache", "calamine", "spreadsheet-ods", "dep:rust_xlsxwriter", "dep:umya-spreadsheet"] +sheet = ["automation", "drive", "cache", "calamine", "dep:rust_xlsxwriter", "dep:umya-spreadsheet"] slides = ["automation", "drive", "cache", "ooxmlsdk"] paper = ["automation", "drive", "cache"] @@ -95,26 +95,19 @@ bigdecimal = { workspace = true } aes-gcm = { workspace = true } anyhow = { workspace = true } argon2 = { workspace = true } -async-lock = { workspace = true } -async-stream = { workspace = true } async-trait = { workspace = true } axum = { workspace = true } axum-server = { workspace = true } base64 = { workspace = true } -bytes = { workspace = true } chrono = { workspace = true, features = ["clock", "std"] } color-eyre = { workspace = true } diesel = { workspace = true, features = ["postgres", "uuid", "chrono", "serde_json", "r2d2", "numeric", "32-column-tables"] } dirs = { workspace = true } dotenvy = { workspace = true } -env_logger = { workspace = true } futures = { workspace = true } futures-util = { workspace = true } -tokio-util = { workspace = true, features = ["codec"] } hex = { workspace = true } hmac = { workspace = true } -hyper = { workspace = true, features = ["client", "server", "http1", "http2"] } -hyper-rustls = { workspace = true, features = ["http2"] } log = { workspace = true } num-format = { workspace = true } once_cell = { workspace = true } @@ -127,11 +120,8 @@ toml = { workspace = true } sha2 = { workspace = true } sha1 = { workspace = true } tokio = { workspace = true, features = ["full", "process"] } -tokio-stream = { workspace = true } -tower = { workspace = true } tower-http = { workspace = true, features = ["cors", "fs", "trace"] } tracing = { workspace = true } -tracing-subscriber = { workspace = true } urlencoding = { workspace = true } uuid = { workspace = true, features = ["v4", "v5"] } @@ -140,13 +130,10 @@ rustls = { workspace = true, features = ["ring", "std", "tls12"] } tokio-rustls = { workspace = true } rcgen = { workspace = true, features = ["crypto", "ring", "pem"] } x509-parser = { workspace = true } -rustls-native-certs = { workspace = true } -webpki-roots = { workspace = true } ring = { workspace = true } ciborium = { workspace = true } time = { workspace = true, features = ["formatting"] } jsonwebtoken = { workspace = true } -tower-cookies = { workspace = true } # === APP-SPECIFIC DEPENDENCIES === @@ -154,10 +141,6 @@ tower-cookies = { workspace = true } imap = { workspace = true, optional = true } lettre = { workspace = true, optional = true } mailparse = { workspace = true, optional = true } -native-tls = { workspace = true, optional = true } - -# Video Meetings (meet feature) -livekit = { workspace = true, optional = true } # Vector Database (vectordb feature) qdrant-client = { workspace = true, optional = true } @@ -166,7 +149,6 @@ qdrant-client = { workspace = true, optional = true } docx-rs = { workspace = true, optional = true } ooxmlsdk = { workspace = true, optional = true, features = ["parts"] } calamine = { workspace = true, optional = true } -spreadsheet-ods = { workspace = true, optional = true } rust_xlsxwriter = { workspace = true, optional = true } umya-spreadsheet = { workspace = true, optional = true } @@ -206,9 +188,6 @@ redis = { workspace = true, features = ["tokio-comp"], optional = true } # System Monitoring (monitoring feature) sysinfo = { workspace = true, optional = true } -# Networking/gRPC (grpc feature) -tonic = { workspace = true, features = ["transport"], optional = true } - # UI Enhancement (progress-bars feature) indicatif = { workspace = true, optional = true } smartstring = { workspace = true } @@ -224,9 +203,6 @@ vaultrs = { workspace = true } # Calendar standards (RFC 5545) icalendar = { workspace = true } -# Layered configuration -figment = { workspace = true, features = ["toml"] } - # Rate limiting governor = { workspace = true } @@ -239,9 +215,6 @@ walkdir = { workspace = true } # Embedded static files rust-embed = { workspace = true } -mime_guess = { workspace = true } -hyper-util = { workspace = true, features = ["client-legacy"] } -http-body-util = { workspace = true } [dev-dependencies] mockito = { workspace = true } diff --git a/TODO.md b/TODO.md index 1052f48e6..6c20e89b5 100644 --- a/TODO.md +++ b/TODO.md @@ -1,79 +1,309 @@ -# Plano de Compilação Individual de Features +# General Bots 7.0 - Enhanced Multi-Agent Orchestration -## Objetivo -Compilar cada feature individualmente do botserver com `cargo check --no-default-features --features ` para identificar todos os erros de dependência e compilação, consolidando os logs para análise sistemática. +**Target Release:** Q3 2026 +**Current Version:** 6.1.0 +**Priority:** Critical for enterprise adoption -## Features a Testar +--- -### Grupo 1: Comunicação -- [x] `chat` -- [x] `people` -- [x] `mail` -- [ ] `meet` (Failed: webrtc-sys C++ build error: missing absl/container/inlined_vector.h) -- [x] `social` +## Phase 1: Enhanced Orchestration (Months 1-2) 🚀 -### Grupo 2: Produtividade -- [x] `calendar` -- [x] `tasks` -- [x] `project` -- [x] `goals` -- [x] `workspaces` -- [x] `tickets` -- [x] `billing` -- crm -### Grupo 3: Documentos -- [x] `docs` -- [x] `sheet` -- [x] `slides` -- [x] `paper` +### 1.1 ORCHESTRATE WORKFLOW Keyword +- [ ] **File:** `src/basic/keywords/orchestration.rs` +- [ ] Add `ORCHESTRATE WORKFLOW` keyword to BASIC interpreter +- [ ] Support STEP definitions with BOT calls +- [ ] Support PARALLEL branches execution +- [ ] Support conditional IF/THEN logic in workflows +- [ ] Variable passing between steps +- [ ] **Database:** Add `workflow_executions` table +- [ ] **Test:** Create workflow execution tests -### Grupo 4: Mídia -- [x] `video` -- [x] `player` -- [x] `canvas` +### 1.2 Event Bus System +- [ ] **File:** `src/basic/keywords/events.rs` +- [ ] Add `ON EVENT` keyword for event handlers +- [ ] Add `PUBLISH EVENT` keyword for event emission +- [ ] Add `WAIT FOR EVENT` with timeout support +- [ ] **Integration:** Use existing Redis pub/sub +- [ ] **Database:** Add `workflow_events` table +- [ ] **Test:** Event-driven workflow tests -### Grupo 5: Aprendizado -- [x] `learn` -- [x] `research` (Fixed: gated email dependencies, added missing imports) -- [x] `sources` +### 1.3 Bot Learning Enhancement +- [ ] **File:** `src/basic/keywords/bot_learning.rs` +- [ ] Add `BOT LEARN` keyword for pattern storage (extends existing `SET BOT MEMORY`) +- [ ] Add `BOT RECALL` keyword for pattern retrieval (extends existing bot memory) +- [ ] Add `BOT SHARE KNOWLEDGE` for cross-bot learning +- [ ] **Integration:** Use existing VectorDB (Qdrant) + existing bot_memories table +- [ ] **Write-back:** Store learned patterns in `.gbkb` folders for persistence +- [ ] **Test:** Bot learning and recall tests -### Grupo 6: Analytics -- [x] `analytics` -- [x] `dashboards` -- [x] `monitoring` (Fixed: E0308 type mismatch in SVG generation) +**Note:** Difference between `SET BOT MEMORY` vs `BOT LEARN`: +- `SET BOT MEMORY`: Manual key-value storage (existing) +- `BOT LEARN`: Automatic pattern recognition from conversations -### Grupo 7: Desenvolvimento -- [x] `designer` -- [x] `editor` +### 1.4 Database Schema +```sql +-- Add to migrations/ +CREATE TABLE workflow_executions ( + id UUID PRIMARY KEY, + bot_id UUID REFERENCES bots(id), + workflow_name TEXT, + current_step INTEGER, + state JSONB, + status TEXT DEFAULT 'running', + created_at TIMESTAMPTZ DEFAULT NOW() +); -### Grupo 8: Admin -- [x] `attendant` -- [x] `security` -- [x] `settings` +CREATE TABLE workflow_events ( + id UUID PRIMARY KEY, + workflow_id UUID REFERENCES workflow_executions(id), + event_name TEXT, + event_data JSONB, + created_at TIMESTAMPTZ DEFAULT NOW() +); -## Erros e Avisos Identificados +CREATE TABLE bot_knowledge ( + id UUID PRIMARY KEY, + bot_id UUID REFERENCES bots(id), + pattern TEXT, + confidence FLOAT, + learned_from UUID REFERENCES conversations(id), + kb_file_path TEXT, -- Path to .gbkb file for persistence + created_at TIMESTAMPTZ DEFAULT NOW() +); +``` -### Erros de Compilação (Bloqueios) -- [ ] **meet**: Falha no build C++ da dependência `webrtc-sys` (header `absl/container/inlined_vector.h` não encontrado). - - Requer instalação de dependências de sistema (não resolvido neste ambiente). +--- -### Avisos Comuns (Shared) -- [x] Fixed all shared warnings (unused variables/mut/imports in compiler, state, drive_monitor). +## Phase 2: Visual Workflow Designer (Months 3-4) 🎨 -### Avisos Específicos de Feature -- [x] **mail**: Fixed unused imports. -- [x] **tasks**: Fixed unused imports. -- [x] **project**: Fixed unused imports. -- [x] **tickets**: Fixed unused imports. -- [x] **learn**: Fixed unused imports. -- [x] **analytics**: Fixed unused imports. -- [x] **designer**: Fixed unused variable `messages`. +### 2.1 Drag-and-Drop Canvas +- [ ] **File:** `src/designer/workflow_canvas.rs` +- [ ] Extend existing designer with workflow nodes +- [ ] Add node types: BotAgent, HumanApproval, Condition, Loop, Parallel +- [ ] Drag-and-drop interface using existing HTMX +- [ ] **Frontend:** Add workflow canvas to existing designer UI +- [ ] **Output:** Generate BASIC code from visual design +### 2.2 Bot Templates +- [ ] **Directory:** `bottemplates/` (not templates/) +- [ ] Create pre-built workflow `.gbai` packages +- [ ] Customer support escalation template +- [ ] E-commerce order processing template +- [ ] Content moderation template +- [ ] **Integration:** Auto-discovery via existing package system -## Remaining Warnings Plan (From TODO.tmp) -1. **Automated Fixes**: Run `cargo clippy --fix --workspace` to resolve simple warnings (unused imports/variables/mut). - - [ ] Execution in progress. -2. **Manual Fixes**: Address warnings not resolvable by auto-fix. - - [ ] Complex logic changes. - - [ ] Feature gating adjustments. -3. **Verification**: Run `cargo check --workspace` to ensure zero warnings. +### 2.3 Visual Designer Enhancement +- [ ] **File:** `src/designer/mod.rs` +- [ ] Add workflow mode to existing designer +- [ ] Real-time BASIC code preview +- [ ] Workflow validation and error checking +- [ ] **Test:** Visual designer workflow tests + +--- + +## Phase 3: Intelligence & Learning (Months 5-6) 🧠 + +### 3.1 Smart LLM Routing +- [ ] **File:** `src/llm/smart_router.rs` +- [ ] Extend existing `llm/observability.rs` +- [ ] Add cost/latency tracking per model +- [ ] Automatic model selection based on task type +- [ ] **BASIC:** Enhance LLM keyword with OPTIMIZE FOR parameter +- [ ] **Database:** Add `model_performance` table +- [ ] **Test:** LLM routing optimization tests + +### 3.2 Bot Learning System +- [ ] **File:** `src/bots/learning.rs` +- [ ] Pattern recognition from conversation history +- [ ] Cross-bot knowledge sharing mechanisms +- [ ] Confidence scoring for learned patterns +- [ ] **Write-back to .gbkb:** Store learned patterns as knowledge base files +- [ ] **Integration:** Use existing conversation storage + VectorDB +- [ ] **Test:** Bot learning behavior tests + +### 3.3 Enhanced BASIC Keywords +```basic +' New keywords to implement +result = LLM "Analyze data" WITH OPTIMIZE FOR "speed" +BOT LEARN PATTERN "customer prefers email" WITH CONFIDENCE 0.8 +preferences = BOT RECALL "customer communication patterns" +BOT SHARE KNOWLEDGE WITH "support-bot-2" +``` + +--- + +## Phase 4: Plugin Ecosystem (Months 7-8) 🔌 + +### 4.1 Plugin Registry +- [ ] **File:** `src/plugins/registry.rs` +- [ ] **Database:** Add `plugins` table with metadata +- [ ] Plugin security scanning system +- [ ] Version management and updates +- [ ] **Integration:** Extend existing MCP support + +### 4.2 Plugin Discovery Keywords +- [ ] **File:** `src/basic/keywords/plugins.rs` +- [ ] Add `SEARCH PLUGINS` keyword +- [ ] Add `INSTALL PLUGIN` keyword +- [ ] Add `LIST PLUGINS` keyword +- [ ] **Integration:** Auto-update `mcp.csv` on install +- [ ] **Test:** Plugin installation and discovery tests + +### 4.3 Plugin Marketplace +- [ ] **Database Schema:** +```sql +CREATE TABLE plugins ( + id UUID PRIMARY KEY, + name TEXT UNIQUE, + description TEXT, + mcp_server_url TEXT, + permissions TEXT[], + security_scan_result JSONB, + downloads INTEGER DEFAULT 0, + rating FLOAT, + created_at TIMESTAMPTZ DEFAULT NOW() +); +``` + +--- + +## Implementation Guidelines + +### Code Standards +- [ ] **No breaking changes** - all existing `.gbai` packages must work +- [ ] **Extend existing systems** - don't rebuild what works +- [ ] **BASIC-first design** - everything accessible via BASIC keywords +- [ ] **Use existing infrastructure** - PostgreSQL, Redis, Qdrant, LXC +- [ ] **Proper error handling** - no unwrap(), use SafeCommand wrapper + +### Testing Requirements +- [ ] **Unit tests** for all new BASIC keywords +- [ ] **Integration tests** for workflow execution +- [ ] **Performance tests** for multi-agent coordination +- [ ] **Backward compatibility tests** for existing `.gbai` packages + +### Documentation Updates +- [ ] **File:** `docs/reference/basic-language.md` - Add new keywords +- [ ] **File:** `docs/guides/workflows.md` - Workflow creation guide +- [ ] **File:** `docs/guides/multi-agent.md` - Multi-agent patterns +- [ ] **File:** `docs/api/workflow-api.md` - Workflow REST endpoints + +--- + +## File Structure Changes + +``` +src/ +├── basic/keywords/ +│ ├── orchestration.rs # NEW: ORCHESTRATE WORKFLOW +│ ├── events.rs # NEW: ON EVENT, PUBLISH EVENT +│ ├── agent_learning.rs # NEW: AGENT LEARN/RECALL +│ └── plugins.rs # NEW: SEARCH/INSTALL PLUGINS +├── designer/ +│ ├── workflow_canvas.rs # NEW: Visual workflow editor +│ └── mod.rs # EXTEND: Add workflow mode +├── llm/ +│ └── smart_router.rs # NEW: Intelligent model routing +├── agents/ +│ └── learning.rs # NEW: Agent learning system +└── plugins/ + └── registry.rs # NEW: Plugin management + +templates/ +└── workflow-templates/ # NEW: Pre-built workflows + ├── customer-support.gbai/ + ├── order-processing.gbai/ + └── content-moderation.gbai/ + +docs/ +├── guides/ +│ ├── tools-vs-bots.md # DONE: Tool vs Bot explanation +│ ├── workflows.md # NEW: Workflow creation +│ └── multi-agent.md # NEW: Multi-agent patterns +└── reference/ + └── basic-language.md # UPDATE: New keywords +``` + +--- + +## Success Metrics + +### Technical Metrics +- [ ] **Backward compatibility:** 100% existing `.gbai` packages work +- [ ] **Performance:** Workflow execution <2s overhead +- [ ] **Reliability:** 99.9% workflow completion rate +- [ ] **Memory usage:** <10% increase from current baseline + +### Business Metrics +- [ ] **Workflow creation time:** 50% reduction vs manual coordination +- [ ] **Training time:** 80% reduction for non-programmers +- [ ] **Enterprise adoption:** 10x faster implementation +- [ ] **Community plugins:** 100+ plugins in first 6 months + +--- + +## Risk Mitigation + +### Technical Risks +- [ ] **Context overflow:** Implement workflow state persistence +- [ ] **Bot coordination failures:** Add timeout and retry mechanisms +- [ ] **Performance degradation:** Implement workflow step caching +- [ ] **Memory leaks:** Proper cleanup of workflow sessions + +### Business Risks +- [ ] **Breaking changes:** Comprehensive backward compatibility testing +- [ ] **Complexity creep:** Keep BASIC-first design principle +- [ ] **Performance impact:** Benchmark all new features +- [ ] **Security vulnerabilities:** Security review for all plugin systems + +--- + +## Dependencies + +### External Dependencies (No New Ones) +- ✅ **Rust 1.75+** - Already required +- ✅ **PostgreSQL** - Already in LXC container +- ✅ **Redis** - Already in LXC container +- ✅ **Qdrant** - Already in LXC container +- ✅ **Rhai** - Already used for BASIC interpreter + +### Internal Dependencies +- ✅ **Existing BASIC interpreter** - Extend with new keywords +- ✅ **Existing bot management** - Use for multi-agent coordination +- ✅ **Existing session system** - Store workflow state +- ✅ **Existing MCP support** - Extend for plugin system + +--- + +## Delivery Timeline + +| Phase | Duration | Deliverable | Dependencies | +|-------|----------|-------------|--------------| +| **Phase 1** | 2 months | Enhanced orchestration | None | +| **Phase 2** | 2 months | Visual designer | Phase 1 | +| **Phase 3** | 2 months | Intelligence & learning | Phase 1 | +| **Phase 4** | 2 months | Plugin ecosystem | Phase 1 | + +**Total Duration:** 8 months +**Target Release:** General Bots 7.0 - Q3 2026 + +--- + +## Getting Started + +### Immediate Next Steps +1. [ ] **Create feature branch:** `git checkout -b feature/orchestration-7.0` +2. [ ] **Set up development environment:** Ensure Rust 1.75+, PostgreSQL, Redis +3. [ ] **Start with Phase 1.1:** Implement `ORCHESTRATE WORKFLOW` keyword +4. [ ] **Create basic test:** Simple 2-step workflow execution +5. [ ] **Document progress:** Update this TODO.md as tasks complete + +### Development Order +1. **Start with BASIC keywords** - Core functionality first +2. **Add database schema** - Persistence layer +3. **Implement workflow engine** - Execution logic +4. **Add visual designer** - User interface +5. **Enhance with intelligence** - AI improvements +6. **Build plugin system** - Extensibility + +**Remember:** Build on existing systems, don't rebuild. Every new feature should extend what already works in General Bots. diff --git a/TODO.tmp b/TODO.tmp deleted file mode 100644 index f9a458821..000000000 --- a/TODO.tmp +++ /dev/null @@ -1,663 +0,0 @@ - Checking bottest v6.1.0 (/home/rodriguez/src/gb/bottest) - Compiling botapp v6.1.0 (/home/rodriguez/src/gb/botapp) - Checking botserver v6.1.0 (/home/rodriguez/src/gb/botserver) -warning: this function has too many arguments (8/7) - --> botserver/src/auto_task/app_logs.rs:117:5 - | -117 | / pub fn log( -118 | | &self, -119 | | app_name: &str, -120 | | level: LogLevel, -... | -125 | | user_id: Option, -126 | | ) { - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments - = note: `#[warn(clippy::too_many_arguments)]` on by default - -warning: this function has too many arguments (8/7) - --> botserver/src/auto_task/app_logs.rs:154:5 - | -154 | / pub fn log_error( -155 | | &self, -156 | | app_name: &str, -157 | | source: LogSource, -... | -162 | | stack_trace: Option<&str>, -163 | | ) { - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments - -warning: this function has too many arguments (8/7) - --> botserver/src/auto_task/task_manifest.rs:938:1 - | -938 | / pub fn create_manifest_from_llm_response( -939 | | app_name: &str, -940 | | description: &str, -941 | | tables: Vec, -... | -946 | | monitors: Vec, -947 | | ) -> TaskManifest { - | |_________________^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments - -warning: this function has too many arguments (11/7) - --> botserver/src/basic/keywords/human_approval.rs:256:5 - | -256 | / pub fn create_request( -257 | | &self, -258 | | bot_id: Uuid, -259 | | session_id: Uuid, -... | -267 | | default_action: Option, -268 | | ) -> ApprovalRequest { - | |________________________^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments - -warning: this function has too many arguments (8/7) - --> botserver/src/basic/keywords/create_site.rs:111:1 - | -111 | / async fn create_site( -112 | | config: crate::core::config::AppConfig, -113 | | s3: Option>, -114 | | bucket: String, -... | -119 | | prompt: Dynamic, -120 | | ) -> Result> { - | |_________________________________________________^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments - -warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str` - --> botserver/src/channels/media_upload.rs:44:5 - | -44 | / pub fn from_str(s: &str) -> Option { -45 | | match s.to_lowercase().as_str() { -46 | | "twitter" | "x" => Some(Self::Twitter), -47 | | "facebook" | "fb" => Some(Self::Facebook), -... | -61 | | } - | |_____^ - | - = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#should_implement_trait - = note: `#[warn(clippy::should_implement_trait)]` on by default - -warning: match expression looks like `matches!` macro - --> botserver/src/channels/oauth.rs:52:9 - | -52 | / match self { -53 | | Self::Bluesky | Self::Telegram | Self::Twilio => false, -54 | | _ => true, -55 | | } - | |_________^ help: try: `!matches!(self, Self::Bluesky | Self::Telegram | Self::Twilio)` - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#match_like_matches_macro - = note: `#[warn(clippy::match_like_matches_macro)]` on by default - -warning: very complex type used. Consider factoring parts into `type` definitions - --> botserver/src/core/middleware.rs:501:6 - | -501 | ) -> impl Fn(Request, Next) -> std::pin::Pin> + Send>> - | ______^ -502 | | + Clone -503 | | + Send { - | |_____________^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#type_complexity - = note: `#[warn(clippy::type_complexity)]` on by default - -warning: stripping a prefix manually - --> botserver/src/core/middleware.rs:691:9 - | -691 | &auth_header[7..] - | ^^^^^^^^^^^^^^^^^ - | -note: the prefix was tested here - --> botserver/src/core/middleware.rs:690:17 - | -690 | let token = if auth_header.starts_with("Bearer ") { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#manual_strip - = note: `#[warn(clippy::manual_strip)]` on by default -help: try using the `strip_prefix` method - | -690 ~ let token = if let Some() = auth_header.strip_prefix("Bearer ") { -691 ~ - | - -warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str` - --> botserver/src/core/organization_invitations.rs:37:5 - | -37 | / pub fn from_str(s: &str) -> Option { -38 | | match s.to_lowercase().as_str() { -39 | | "owner" => Some(Self::Owner), -40 | | "admin" => Some(Self::Admin), -... | -47 | | } - | |_____^ - | - = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#should_implement_trait - -warning: this function has too many arguments (10/7) - --> botserver/src/core/organization_invitations.rs:184:5 - | -184 | / pub async fn create_invitation( -185 | | &self, -186 | | organization_id: Uuid, -187 | | organization_name: &str, -... | -194 | | expires_in_days: i64, -195 | | ) -> Result { - | |_______________________________________________^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments - -warning: this function has too many arguments (9/7) - --> botserver/src/core/organization_invitations.rs:249:5 - | -249 | / pub async fn bulk_invite( -250 | | &self, -251 | | organization_id: Uuid, -252 | | organization_name: &str, -... | -258 | | message: Option, -259 | | ) -> BulkInviteResponse { - | |___________________________^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments - -warning: clamp-like pattern without using clamp function - --> botserver/src/core/organization_invitations.rs:651:27 - | -651 | let expires_in_days = req.expires_in_days.unwrap_or(7).max(1).min(30); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `req.expires_in_days.unwrap_or(7).clamp(1, 30)` - | - = note: clamp will panic if max < min - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#manual_clamp - = note: `#[warn(clippy::manual_clamp)]` on by default - -warning: very complex type used. Consider factoring parts into `type` definitions - --> botserver/src/core/organization_rbac.rs:246:17 - | -246 | user_roles: Arc>>>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#type_complexity - -warning: this function has too many arguments (8/7) - --> botserver/src/core/package_manager/setup/directory_setup.rs:221:5 - | -221 | / pub async fn create_user( -222 | | &mut self, -223 | | org_id: &str, -224 | | username: &str, -... | -229 | | is_admin: bool, -230 | | ) -> Result { - | |____________________________^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments - -warning: very complex type used. Consider factoring parts into `type` definitions - --> botserver/src/core/performance.rs:740:16 - | -740 | processor: Arc) -> std::pin::Pin + Send>> + Send + Sync>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#type_complexity - -warning: very complex type used. Consider factoring parts into `type` definitions - --> botserver/src/core/performance.rs:749:28 - | -749 | let processor_arc: Arc) -> std::pin::Pin + Send>> + Send + Sync> = - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#type_complexity - -warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str` - --> botserver/src/security/api_keys.rs:65:5 - | -65 | / pub fn from_str(s: &str) -> Option { -66 | | match s { -67 | | "read" => Some(Self::Read), -68 | | "write" => Some(Self::Write), -... | -85 | | } - | |_____^ - | - = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#should_implement_trait - -warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str` - --> botserver/src/security/auth.rs:150:5 - | -150 | / pub fn from_str(s: &str) -> Self { -151 | | match s.to_lowercase().as_str() { -152 | | "anonymous" => Self::Anonymous, -153 | | "user" => Self::User, -... | -164 | | } - | |_____^ - | - = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#should_implement_trait - -warning: very complex type used. Consider factoring parts into `type` definitions - --> botserver/src/security/passkey.rs:898:10 - | -898 | ) -> Result<(Vec, Vec, Option>), PasskeyError> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#type_complexity - -warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str` - --> botserver/src/security/protection/manager.rs:36:5 - | -36 | / pub fn from_str(s: &str) -> Option { -37 | | match s.to_lowercase().as_str() { -38 | | "lynis" => Some(Self::Lynis), -39 | | "rkhunter" => Some(Self::RKHunter), -... | -46 | | } - | |_____^ - | - = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#should_implement_trait - -warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str` - --> botserver/src/security/secrets.rs:13:5 - | -13 | / pub fn from_str(secret: &str) -> Self { -14 | | Self { -15 | | inner: secret.to_string(), -16 | | } -17 | | } - | |_____^ - | - = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#should_implement_trait - -warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str` - --> botserver/src/botmodels/python_bridge.rs:124:5 - | -124 | / pub fn from_str(s: &str) -> Option { -125 | | match s.to_lowercase().as_str() { -126 | | "mediapipe" => Some(Self::MediaPipe), -127 | | "deepface" => Some(Self::DeepFace), -... | -134 | | } - | |_____^ - | - = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#should_implement_trait - -warning: `botserver` (bin "botserver") generated 23 warnings -warning: variable does not need to be mutable - --> botserver/src/botmodels/opencv.rs:613:13 - | -613 | let mut detector = OpenCvFaceDetector::new(config); - | ----^^^^^^^^ - | | - | help: remove this `mut` - | - = note: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default - -warning: this `impl` can be derived - --> botserver/src/core/session/mod.rs:551:5 - | -551 | / impl Default for Role { -552 | | fn default() -> Self { -553 | | Self::User -554 | | } -555 | | } - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#derivable_impls - = note: `#[warn(clippy::derivable_impls)]` on by default -help: replace the manual implementation with a derive attribute and mark the default variant - | -544 ~ #[derive(Default)] -545 ~ pub enum Role { -546 | Admin, -547 | Attendant, -548 ~ #[default] -549 ~ User, -550 | Guest, -551 | } -552 | -553 ~ - | - -warning: this `impl` can be derived - --> botserver/src/core/session/mod.rs:593:5 - | -593 | / impl Default for Channel { -594 | | fn default() -> Self { -595 | | Self::WhatsApp -596 | | } -597 | | } - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#derivable_impls -help: replace the manual implementation with a derive attribute and mark the default variant - | -584 ~ #[derive(Default)] -585 ~ pub enum Channel { -586 ~ #[default] -587 ~ WhatsApp, -588 | Teams, -... -594 | -595 ~ - | - -warning: this `impl` can be derived - --> botserver/src/core/session/mod.rs:668:5 - | -668 | / impl Default for SessionState { -669 | | fn default() -> Self { -670 | | Self::Active -671 | | } -672 | | } - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#derivable_impls -help: replace the manual implementation with a derive attribute and mark the default variant - | -661 ~ #[derive(Default)] -662 ~ pub enum SessionState { -663 ~ #[default] -664 ~ Active, -665 | Waiting, -... -669 | -670 ~ - | - -warning: this `impl` can be derived - --> botserver/src/core/session/mod.rs:723:5 - | -723 | / impl Default for ContentType { -724 | | fn default() -> Self { -725 | | Self::Text -726 | | } -727 | | } - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#derivable_impls -help: replace the manual implementation with a derive attribute and mark the default variant - | -712 ~ #[derive(Default)] -713 ~ pub enum ContentType { -714 ~ #[default] -715 ~ Text, -716 | Image, -... -724 | -725 ~ - | - -warning: this `impl` can be derived - --> botserver/src/core/session/mod.rs:763:5 - | -763 | / impl Default for Priority { -764 | | fn default() -> Self { -765 | | Self::Normal -766 | | } -767 | | } - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#derivable_impls -help: replace the manual implementation with a derive attribute and mark the default variant - | -756 ~ #[derive(Default)] -757 ~ pub enum Priority { -758 | Low = 0, -759 ~ #[default] -760 ~ Normal = 1, -761 | High = 2, -... -764 | -765 ~ - | - -warning: this `impl` can be derived - --> botserver/src/core/session/mod.rs:779:5 - | -779 | / impl Default for QueueStatus { -780 | | fn default() -> Self { -781 | | Self::Waiting -782 | | } -783 | | } - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#derivable_impls -help: replace the manual implementation with a derive attribute and mark the default variant - | -771 ~ #[derive(Default)] -772 ~ pub enum QueueStatus { -773 ~ #[default] -774 ~ Waiting, -775 | Assigned, -... -780 | -781 ~ - | - -warning: this `impl` can be derived - --> botserver/src/core/session/mod.rs:824:5 - | -824 | / impl Default for ConversationState { -825 | | fn default() -> Self { -826 | | Self::Initial -827 | | } -828 | | } - | |_____^ - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#derivable_impls -help: replace the manual implementation with a derive attribute and mark the default variant - | -815 ~ #[derive(Default)] -816 ~ pub enum ConversationState { -817 ~ #[default] -818 ~ Initial, -819 | WaitingForUser, -... -825 | -826 ~ - | - -error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> botserver/src/core/shared/memory_monitor.rs:500:36 - | -500 | assert!(stats.rss_bytes > 0 || stats.virtual_bytes >= 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: because `0` is the minimum value for this type, this comparison is always true - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#absurd_extreme_comparisons - = note: `#[deny(clippy::absurd_extreme_comparisons)]` on by default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/csrf.rs:606:9 - | -606 | config.token_expiry_minutes = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::csrf::CsrfConfig { token_expiry_minutes: 0, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/csrf.rs:605:9 - | -605 | let mut config = CsrfConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - = note: `#[warn(clippy::field_reassign_with_default)]` on by default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/dlp.rs:1079:9 - | -1079 | config.scan_inbound = false; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::dlp::DlpConfig { scan_inbound: false, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/dlp.rs:1078:9 - | -1078 | let mut config = DlpConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/encryption.rs:622:9 - | -622 | config.envelope_encryption = true; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::encryption::EncryptionConfig { envelope_encryption: true, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/encryption.rs:621:9 - | -621 | let mut config = EncryptionConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false - --> botserver/src/security/password.rs:720:17 - | -720 | assert!(result.strength.score() >= 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: because `0` is the minimum value for this type, this comparison is always true - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#absurd_extreme_comparisons - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/security_monitoring.rs:1011:9 - | -1011 | config.brute_force_threshold = 3; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::security_monitoring::SecurityMonitoringConfig { brute_force_threshold: 3, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/security_monitoring.rs:1010:9 - | -1010 | let mut config = SecurityMonitoringConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/security_monitoring.rs:1033:9 - | -1033 | config.brute_force_threshold = 2; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::security_monitoring::SecurityMonitoringConfig { brute_force_threshold: 2, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/security_monitoring.rs:1032:9 - | -1032 | let mut config = SecurityMonitoringConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/security_monitoring.rs:1183:9 - | -1183 | config.retention_hours = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::security_monitoring::SecurityMonitoringConfig { retention_hours: 0, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/security_monitoring.rs:1182:9 - | -1182 | let mut config = SecurityMonitoringConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/session.rs:715:9 - | -715 | config.max_concurrent_sessions = 2; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::session::SessionConfig { max_concurrent_sessions: 2, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/session.rs:714:9 - | -714 | let mut config = SessionConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/webhook.rs:701:9 - | -701 | config.timestamp_tolerance_seconds = 60; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::webhook::WebhookConfig { timestamp_tolerance_seconds: 60, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/webhook.rs:700:9 - | -700 | let mut config = WebhookConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/webhook.rs:732:9 - | -732 | config.require_https = false; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::webhook::WebhookConfig { require_https: false, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/webhook.rs:731:9 - | -731 | let mut config = WebhookConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/webhook.rs:742:9 - | -742 | config.max_payload_size = 100; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::webhook::WebhookConfig { max_payload_size: 100, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/webhook.rs:741:9 - | -741 | let mut config = WebhookConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: field assignment outside of initializer for an instance created with Default::default() - --> botserver/src/security/webhook.rs:871:9 - | -871 | config.replay_window_seconds = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: consider initializing the variable with `security::webhook::WebhookConfig { replay_window_seconds: 0, ..Default::default() }` and removing relevant reassignments - --> botserver/src/security/webhook.rs:870:9 - | -870 | let mut config = WebhookConfig::default(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default - -warning: useless use of `vec!` - --> botserver/src/security/command_guard.rs:597:24 - | -597 | let _allowed = vec![PathBuf::from("/tmp")]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[PathBuf::from("/tmp")]` - | - = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#useless_vec - = note: `#[warn(clippy::useless_vec)]` on by default - -warning: comparison is useless due to type limits - --> botserver/src/core/shared/memory_monitor.rs:500:36 - | -500 | assert!(stats.rss_bytes > 0 || stats.virtual_bytes >= 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_comparisons)]` on by default - -warning: comparison is useless due to type limits - --> botserver/src/security/password.rs:720:17 - | -720 | assert!(result.strength.score() >= 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: `botserver` (bin "botserver" test) generated 45 warnings (23 duplicates) -error: could not compile `botserver` (bin "botserver" test) due to 2 previous errors; 45 warnings emitted diff --git a/docs/guides/tools-vs-bots.md b/docs/guides/tools-vs-bots.md new file mode 100644 index 000000000..28be1bb42 --- /dev/null +++ b/docs/guides/tools-vs-bots.md @@ -0,0 +1,308 @@ +# Tools vs Bots: When to Use Each + +**Chapter 4: Understanding the Difference Between Function Calls and AI Agents** + +--- + +## Overview + +General Bots provides two ways to extend your bot's capabilities: +- **TOOLs** - Simple functions with input/output +- **BOTs** - Intelligent AI agents that can reason and remember + +Understanding when to use each is crucial for building efficient, cost-effective automation. + +## Quick Comparison + +| Feature | TOOL | BOT | +|---------|------|-----| +| **Purpose** | Data operations | Decision making | +| **Intelligence** | None (function) | Full LLM reasoning | +| **Speed** | Fast (10-100ms) | Slower (1-5 seconds) | +| **Cost** | Free | LLM tokens ($0.001-0.01) | +| **Input** | Structured data | Natural language | +| **Output** | Structured data | Conversational response | +| **Memory** | Stateless | Remembers context | + +## Tools: The Function Approach + +### What Are Tools? + +Tools are **stateless functions** that perform specific operations: + +```basic +' Tool usage - direct function call +USE TOOL "check-order" +result = CALL TOOL "check-order" WITH order_id="12345" +' Returns: {"status": "delivered", "amount": 899} +``` + +### When to Use Tools + +✅ **Perfect for:** +- Database queries +- API calls +- Calculations +- Data transformations +- Real-time operations + +```basic +' Examples of good tool usage +USE TOOL "get-weather" +weather = CALL TOOL "get-weather" WITH city="São Paulo" + +USE TOOL "calculate-tax" +tax = CALL TOOL "calculate-tax" WITH amount=100, region="BR" + +USE TOOL "send-email" +CALL TOOL "send-email" WITH to="user@example.com", subject="Order Confirmed" +``` + +### Tool Limitations + +❌ **Cannot:** +- Make decisions +- Understand context +- Remember previous calls +- Handle ambiguous input +- Provide explanations + +## Bots: The AI Agent Approach + +### What Are Bots? + +Bots are **intelligent agents** that can reason, remember, and make decisions: + +```basic +' Bot usage - conversational interaction +ADD BOT "order-specialist" +response = ASK BOT "order-specialist" ABOUT "Customer says order 12345 arrived damaged. What should we do?" +' Returns: Detailed analysis with reasoning and recommendation +``` + +### When to Use Bots + +✅ **Perfect for:** +- Complex decision making +- Natural language understanding +- Multi-step reasoning +- Context-aware responses +- Customer service scenarios + +```basic +' Examples of good bot usage +ADD BOT "financial-advisor" +advice = ASK BOT "financial-advisor" ABOUT "Customer wants refund after 60 days but threatens legal action" + +ADD BOT "technical-support" +solution = ASK BOT "technical-support" ABOUT "User can't login, tried password reset twice" + +ADD BOT "content-moderator" +decision = ASK BOT "content-moderator" ABOUT "Review this user comment for policy violations" +``` + +### Bot Capabilities + +✅ **Can:** +- Analyze complex situations +- Remember conversation history +- Use multiple tools internally +- Provide detailed explanations +- Handle edge cases + +## Real-World Example: Order Processing + +### Scenario +Customer contacts support: *"My laptop order #12345 arrived broken. I need this fixed immediately as I have a presentation tomorrow."* + +### Tool-Only Approach (Limited) + +```basic +' Simple but inflexible +USE TOOL "check-order" +order = CALL TOOL "check-order" WITH order_id="12345" + +USE TOOL "check-warranty" +warranty = CALL TOOL "check-warranty" WITH order_id="12345" + +IF order.status = "delivered" AND warranty.valid = true THEN + TALK "You're eligible for replacement" +ELSE + TALK "Please contact manager" +END IF +``` + +**Problems:** +- No understanding of urgency ("presentation tomorrow") +- No consideration of customer history +- Rigid, rule-based responses +- Cannot handle edge cases + +### Bot Approach (Intelligent) + +```basic +' Intelligent and flexible +ADD BOT "support-specialist" +response = ASK BOT "support-specialist" ABOUT "Customer says laptop order #12345 arrived broken. They have presentation tomorrow and need immediate help." +``` + +**Bot's internal reasoning:** +1. Uses `check-order` tool → Order delivered 2 days ago, $1,299 laptop +2. Uses `check-warranty` tool → Premium warranty valid +3. Uses `customer-history` tool → VIP customer, 8 previous orders +4. **Analyzes urgency** → Presentation tomorrow = time-sensitive +5. **Considers options** → Replacement (2-day shipping) vs immediate refund for local purchase +6. **Makes recommendation** → "Given urgency and VIP status, authorize immediate refund so customer can buy locally, plus expedited replacement as backup" + +## Hybrid Approach: Best of Both Worlds + +**Recommended pattern: Bots use Tools internally** + +```basic +' support-specialist.bas - Bot implementation +USE TOOL "check-order" +USE TOOL "check-warranty" +USE TOOL "customer-history" +USE TOOL "inventory-check" +USE KB "support-policies" + +WHEN ASKED ABOUT order_issue DO + ' Gather data using tools (fast, cheap) + order = CALL TOOL "check-order" WITH order_id + warranty = CALL TOOL "check-warranty" WITH order_id + customer = CALL TOOL "customer-history" WITH customer_id + + ' Apply AI reasoning (intelligent, contextual) + urgency = ANALYZE urgency FROM user_message + customer_value = CALCULATE value FROM customer.total_orders + + IF urgency = "high" AND customer_value = "vip" THEN + recommendation = "Expedited resolution with manager approval" + ELSE IF warranty.type = "premium" THEN + recommendation = "Standard replacement process" + ELSE + recommendation = "Store credit or repair option" + END IF + + RETURN detailed_response WITH reasoning AND next_steps +END WHEN +``` + +## Performance Guidelines + +### Tool Performance +- **Latency:** 10-100ms +- **Cost:** $0 (no LLM calls) +- **Throughput:** 1000+ operations/second +- **Use for:** High-frequency, simple operations + +### Bot Performance +- **Latency:** 1-5 seconds +- **Cost:** $0.001-0.01 per interaction +- **Throughput:** 10-100 interactions/second +- **Use for:** Complex, high-value decisions + +## Decision Framework + +### Use TOOL when: +1. **Operation is deterministic** - Same input always produces same output +2. **Speed is critical** - Real-time responses needed +3. **Cost matters** - High-frequency operations +4. **Data is structured** - Clear input/output format + +### Use BOT when: +1. **Context matters** - Previous conversation affects response +2. **Reasoning required** - Multiple factors to consider +3. **Natural language input** - Ambiguous or conversational requests +4. **Edge cases exist** - Situations requiring judgment + +### Use HYBRID when: +1. **Complex workflows** - Multiple steps with decision points +2. **Data + Intelligence** - Need both fast data access and smart reasoning +3. **Scalability important** - Balance cost and capability + +## Common Patterns + +### Pattern 1: Data Retrieval +```basic +' TOOL: Simple lookup +price = CALL TOOL "get-price" WITH product_id="laptop-123" + +' BOT: Contextual pricing +ADD BOT "pricing-advisor" +quote = ASK BOT "pricing-advisor" ABOUT "Customer wants bulk discount for 50 laptops, they're a returning enterprise client" +``` + +### Pattern 2: Validation +```basic +' TOOL: Rule-based validation +valid = CALL TOOL "validate-email" WITH email="user@domain.com" + +' BOT: Contextual validation +ADD BOT "content-reviewer" +assessment = ASK BOT "content-reviewer" ABOUT "Is this product review appropriate for our family-friendly site?" +``` + +### Pattern 3: Workflow Orchestration +```basic +' Hybrid: Bot coordinates, tools execute +ORCHESTRATE WORKFLOW "order-processing" + STEP 1: CALL TOOL "validate-payment" WITH payment_info + STEP 2: BOT "fraud-detector" ANALYZES transaction_pattern + STEP 3: CALL TOOL "reserve-inventory" WITH product_id + STEP 4: BOT "shipping-optimizer" SELECTS best_carrier + STEP 5: CALL TOOL "send-confirmation" WITH order_details +END WORKFLOW +``` + +## Best Practices + +### 1. Start Simple, Add Intelligence +```basic +' Phase 1: Tool-based (fast to implement) +result = CALL TOOL "process-refund" WITH order_id, amount + +' Phase 2: Add bot intelligence (when complexity grows) +ADD BOT "refund-specialist" +decision = ASK BOT "refund-specialist" ABOUT "Customer wants refund but policy expired, they're threatening bad review" +``` + +### 2. Cache Bot Responses +```basic +' Expensive bot call +ADD BOT "product-recommender" +recommendations = ASK BOT "product-recommender" ABOUT "Best laptop for gaming under $1000" + +' Cache result for similar queries +REMEMBER "gaming-laptop-under-1000" AS recommendations +``` + +### 3. Fallback Patterns +```basic +' Try bot first, fallback to tool +TRY + response = ASK BOT "smart-assistant" ABOUT user_query +CATCH bot_error + ' Fallback to simple tool + response = CALL TOOL "keyword-search" WITH query=user_query +END TRY +``` + +## Summary + +**Tools** are your **workhorses** - fast, reliable, cost-effective for data operations. + +**Bots** are your **brain trust** - intelligent, contextual, perfect for complex decisions. + +**Hybrid approach** gives you the best of both: use tools for speed and bots for intelligence. + +Choose based on your specific needs: +- Need speed? → Tool +- Need intelligence? → Bot +- Need both? → Bot that uses tools + +The key is understanding that **tools and bots complement each other** - they're not competing solutions, but different tools for different jobs in your AI automation toolkit. + +--- + +**Next:** [Chapter 5: Building Multi-Agent Workflows](workflows.md) diff --git a/src/security/auth_provider.rs b/src/security/auth_provider.rs index f54b88fae..55e0226e5 100644 --- a/src/security/auth_provider.rs +++ b/src/security/auth_provider.rs @@ -49,7 +49,7 @@ impl LocalJwtAuthProvider { let roles: Vec = claims .roles .as_ref() - .map(|r| r.iter().map(|s| Role::from_str(s)).collect()) + .map(|r| r.iter().filter_map(|s| Role::from_str(s).ok()).collect()) .unwrap_or_else(|| vec![Role::User]); let mut user = AuthenticatedUser::new(user_id, username).with_roles(roles); diff --git a/src/security/protection/api.rs b/src/security/protection/api.rs index 9406b6ad3..63e51e27a 100644 --- a/src/security/protection/api.rs +++ b/src/security/protection/api.rs @@ -6,8 +6,8 @@ use axum::{ }; use serde::{Deserialize, Serialize}; use std::str::FromStr; -use std::sync::OnceLock; use std::sync::Arc; +use std::sync::OnceLock; use tokio::sync::RwLock; use tracing::warn; @@ -18,7 +18,9 @@ static PROTECTION_MANAGER: OnceLock>> = OnceLock:: fn get_manager() -> &'static Arc> { PROTECTION_MANAGER.get_or_init(|| { - Arc::new(RwLock::new(ProtectionManager::new(ProtectionConfig::default()))) + Arc::new(RwLock::new(ProtectionManager::new( + ProtectionConfig::default(), + ))) }) } @@ -73,10 +75,7 @@ pub fn configure_protection_routes() -> Router> { "/api/security/protection/:tool/status", get(get_tool_status), ) - .route( - "/api/security/protection/:tool/install", - post(install_tool), - ) + .route("/api/security/protection/:tool/install", post(install_tool)) .route( "/api/security/protection/:tool/uninstall", post(uninstall_tool), @@ -109,7 +108,7 @@ pub fn configure_protection_routes() -> Router> { } fn parse_tool(tool_name: &str) -> Result>)> { - ProtectionTool::from_str(tool_name).ok_or_else(|| { + ProtectionTool::from_str(tool_name).map_err(|_| { ( StatusCode::BAD_REQUEST, Json(ApiResponse::error(format!("Unknown tool: {tool_name}"))), @@ -117,7 +116,8 @@ fn parse_tool(tool_name: &str) -> Result Result>, (StatusCode, Json>)> { +async fn get_all_status( +) -> Result>, (StatusCode, Json>)> { let manager = get_manager().read().await; let status_map = manager.get_all_status().await; let tools: Vec = status_map.into_values().collect(); @@ -135,7 +135,10 @@ async fn get_tool_status( Ok(status) => Ok(Json(ApiResponse::success(status))), Err(e) => { warn!(error = %e, "Failed to get tool status"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to get tool status")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to get tool status")), + )) } } } @@ -153,7 +156,10 @@ async fn install_tool( }))), Err(e) => { warn!(error = %e, "Failed to install tool"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to install tool")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to install tool")), + )) } } } @@ -184,7 +190,10 @@ async fn start_service( }))), Err(e) => { warn!(error = %e, "Failed to start service"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to start service")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to start service")), + )) } } } @@ -202,7 +211,10 @@ async fn stop_service( }))), Err(e) => { warn!(error = %e, "Failed to stop service"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to stop service")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to stop service")), + )) } } } @@ -220,7 +232,10 @@ async fn enable_service( }))), Err(e) => { warn!(error = %e, "Failed to enable service"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to enable service")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to enable service")), + )) } } } @@ -238,7 +253,10 @@ async fn disable_service( }))), Err(e) => { warn!(error = %e, "Failed to disable service"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to disable service")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to disable service")), + )) } } } @@ -253,7 +271,10 @@ async fn run_scan( Ok(result) => Ok(Json(ApiResponse::success(result))), Err(e) => { warn!(error = %e, "Failed to run scan"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to run scan")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to run scan")), + )) } } } @@ -268,7 +289,10 @@ async fn get_report( Ok(report) => Ok(Json(ApiResponse::success(report))), Err(e) => { warn!(error = %e, "Failed to get report"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to get report")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to get report")), + )) } } } @@ -286,7 +310,10 @@ async fn update_definitions( }))), Err(e) => { warn!(error = %e, "Failed to update definitions"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to update definitions")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to update definitions")), + )) } } } @@ -313,17 +340,25 @@ async fn toggle_auto( }))), Err(e) => { warn!(error = %e, "Failed to toggle auto setting"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to toggle auto setting")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to toggle auto setting")), + )) } } } -async fn get_quarantine() -> Result>>, (StatusCode, Json>)> { +async fn get_quarantine( +) -> Result>>, (StatusCode, Json>)> +{ match super::lmd::list_quarantined().await { Ok(files) => Ok(Json(ApiResponse::success(files))), Err(e) => { warn!(error = %e, "Failed to get quarantine list"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to get quarantine list")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to get quarantine list")), + )) } } } @@ -338,7 +373,10 @@ async fn remove_from_quarantine( }))), Err(e) => { warn!(error = %e, "Failed to restore file from quarantine"); - Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ApiResponse::error("Failed to restore file from quarantine")))) + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + Json(ApiResponse::error("Failed to restore file from quarantine")), + )) } } }