fix(server): update security modules and TODOs
This commit is contained in:
parent
0a24cd4b50
commit
fdf74903ad
6 changed files with 665 additions and 779 deletions
33
Cargo.toml
33
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 }
|
||||
|
|
|
|||
358
TODO.md
358
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 <feature>` 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.
|
||||
|
|
|
|||
663
TODO.tmp
663
TODO.tmp
|
|
@ -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<Uuid>,
|
||||
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<TableDefinition>,
|
||||
... |
|
||||
946 | | monitors: Vec<MonitorDefinition>,
|
||||
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<ApprovalDecision>,
|
||||
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<std::sync::Arc<aws_sdk_s3::Client>>,
|
||||
114 | | bucket: String,
|
||||
... |
|
||||
119 | | prompt: Dynamic,
|
||||
120 | | ) -> Result<String, Box<dyn Error + Send + Sync>> {
|
||||
| |_________________________________________________^
|
||||
|
|
||||
= 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<Self> {
|
||||
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<Body>, Next) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Response, Response>> + 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(<stripped>) = auth_header.strip_prefix("Bearer ") {
|
||||
691 ~ <stripped>
|
||||
|
|
||||
|
||||
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<Self> {
|
||||
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<OrganizationInvitation, String> {
|
||||
| |_______________________________________________^
|
||||
|
|
||||
= 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<String>,
|
||||
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<RwLock<HashMap<(Uuid, Uuid), Vec<Uuid>>>>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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<DefaultUser> {
|
||||
| |____________________________^
|
||||
|
|
||||
= 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<dyn Fn(Vec<T>) -> std::pin::Pin<Box<dyn std::future::Future<Output = ()> + 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<dyn Fn(Vec<T>) -> std::pin::Pin<Box<dyn std::future::Future<Output = ()> + 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<Self> {
|
||||
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<u8>, Vec<u8>, Option<Vec<u8>>), 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<Self> {
|
||||
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<Self> {
|
||||
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
|
||||
308
docs/guides/tools-vs-bots.md
Normal file
308
docs/guides/tools-vs-bots.md
Normal file
|
|
@ -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)
|
||||
|
|
@ -49,7 +49,7 @@ impl LocalJwtAuthProvider {
|
|||
let roles: Vec<Role> = 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);
|
||||
|
|
|
|||
|
|
@ -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<Arc<RwLock<ProtectionManager>>> = OnceLock::
|
|||
|
||||
fn get_manager() -> &'static Arc<RwLock<ProtectionManager>> {
|
||||
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<Arc<AppState>> {
|
|||
"/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<Arc<AppState>> {
|
|||
}
|
||||
|
||||
fn parse_tool(tool_name: &str) -> Result<ProtectionTool, (StatusCode, Json<ApiResponse<()>>)> {
|
||||
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<ProtectionTool, (StatusCode, Json<ApiRe
|
|||
})
|
||||
}
|
||||
|
||||
async fn get_all_status() -> Result<Json<ApiResponse<AllStatusResponse>>, (StatusCode, Json<ApiResponse<()>>)> {
|
||||
async fn get_all_status(
|
||||
) -> Result<Json<ApiResponse<AllStatusResponse>>, (StatusCode, Json<ApiResponse<()>>)> {
|
||||
let manager = get_manager().read().await;
|
||||
let status_map = manager.get_all_status().await;
|
||||
let tools: Vec<ToolStatus> = 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<Json<ApiResponse<Vec<super::lmd::QuarantinedFile>>>, (StatusCode, Json<ApiResponse<()>>)> {
|
||||
async fn get_quarantine(
|
||||
) -> Result<Json<ApiResponse<Vec<super::lmd::QuarantinedFile>>>, (StatusCode, Json<ApiResponse<()>>)>
|
||||
{
|
||||
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")),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue