fix(server): update security modules and TODOs

This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-01-25 08:42:36 -03:00
parent 0a24cd4b50
commit fdf74903ad
6 changed files with 665 additions and 779 deletions

View file

@ -23,8 +23,8 @@ directory = []
# Communication # Communication
chat = ["automation", "drive", "cache"] chat = ["automation", "drive", "cache"]
people = ["automation", "drive", "cache"] people = ["automation", "drive", "cache"]
mail = ["automation", "drive", "cache", "dep:lettre", "dep:mailparse", "dep:imap", "dep:native-tls"] mail = ["automation", "drive", "cache", "dep:lettre", "dep:mailparse", "dep:imap"]
meet = ["automation", "drive", "cache", "dep:livekit"] meet = ["automation", "drive", "cache"]
social = ["automation", "drive", "cache"] social = ["automation", "drive", "cache"]
# Productivity # Productivity
@ -38,7 +38,7 @@ billing = ["automation", "drive", "cache"]
# Documents # Documents
docs = ["automation", "drive", "cache", "docx-rs", "ooxmlsdk"] 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"] slides = ["automation", "drive", "cache", "ooxmlsdk"]
paper = ["automation", "drive", "cache"] paper = ["automation", "drive", "cache"]
@ -95,26 +95,19 @@ bigdecimal = { workspace = true }
aes-gcm = { workspace = true } aes-gcm = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
argon2 = { workspace = true } argon2 = { workspace = true }
async-lock = { workspace = true }
async-stream = { workspace = true }
async-trait = { workspace = true } async-trait = { workspace = true }
axum = { workspace = true } axum = { workspace = true }
axum-server = { workspace = true } axum-server = { workspace = true }
base64 = { workspace = true } base64 = { workspace = true }
bytes = { workspace = true }
chrono = { workspace = true, features = ["clock", "std"] } chrono = { workspace = true, features = ["clock", "std"] }
color-eyre = { workspace = true } color-eyre = { workspace = true }
diesel = { workspace = true, features = ["postgres", "uuid", "chrono", "serde_json", "r2d2", "numeric", "32-column-tables"] } diesel = { workspace = true, features = ["postgres", "uuid", "chrono", "serde_json", "r2d2", "numeric", "32-column-tables"] }
dirs = { workspace = true } dirs = { workspace = true }
dotenvy = { workspace = true } dotenvy = { workspace = true }
env_logger = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
futures-util = { workspace = true } futures-util = { workspace = true }
tokio-util = { workspace = true, features = ["codec"] }
hex = { workspace = true } hex = { workspace = true }
hmac = { workspace = true } hmac = { workspace = true }
hyper = { workspace = true, features = ["client", "server", "http1", "http2"] }
hyper-rustls = { workspace = true, features = ["http2"] }
log = { workspace = true } log = { workspace = true }
num-format = { workspace = true } num-format = { workspace = true }
once_cell = { workspace = true } once_cell = { workspace = true }
@ -127,11 +120,8 @@ toml = { workspace = true }
sha2 = { workspace = true } sha2 = { workspace = true }
sha1 = { workspace = true } sha1 = { workspace = true }
tokio = { workspace = true, features = ["full", "process"] } tokio = { workspace = true, features = ["full", "process"] }
tokio-stream = { workspace = true }
tower = { workspace = true }
tower-http = { workspace = true, features = ["cors", "fs", "trace"] } tower-http = { workspace = true, features = ["cors", "fs", "trace"] }
tracing = { workspace = true } tracing = { workspace = true }
tracing-subscriber = { workspace = true }
urlencoding = { workspace = true } urlencoding = { workspace = true }
uuid = { workspace = true, features = ["v4", "v5"] } uuid = { workspace = true, features = ["v4", "v5"] }
@ -140,13 +130,10 @@ rustls = { workspace = true, features = ["ring", "std", "tls12"] }
tokio-rustls = { workspace = true } tokio-rustls = { workspace = true }
rcgen = { workspace = true, features = ["crypto", "ring", "pem"] } rcgen = { workspace = true, features = ["crypto", "ring", "pem"] }
x509-parser = { workspace = true } x509-parser = { workspace = true }
rustls-native-certs = { workspace = true }
webpki-roots = { workspace = true }
ring = { workspace = true } ring = { workspace = true }
ciborium = { workspace = true } ciborium = { workspace = true }
time = { workspace = true, features = ["formatting"] } time = { workspace = true, features = ["formatting"] }
jsonwebtoken = { workspace = true } jsonwebtoken = { workspace = true }
tower-cookies = { workspace = true }
# === APP-SPECIFIC DEPENDENCIES === # === APP-SPECIFIC DEPENDENCIES ===
@ -154,10 +141,6 @@ tower-cookies = { workspace = true }
imap = { workspace = true, optional = true } imap = { workspace = true, optional = true }
lettre = { workspace = true, optional = true } lettre = { workspace = true, optional = true }
mailparse = { 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) # Vector Database (vectordb feature)
qdrant-client = { workspace = true, optional = true } qdrant-client = { workspace = true, optional = true }
@ -166,7 +149,6 @@ qdrant-client = { workspace = true, optional = true }
docx-rs = { workspace = true, optional = true } docx-rs = { workspace = true, optional = true }
ooxmlsdk = { workspace = true, optional = true, features = ["parts"] } ooxmlsdk = { workspace = true, optional = true, features = ["parts"] }
calamine = { workspace = true, optional = true } calamine = { workspace = true, optional = true }
spreadsheet-ods = { workspace = true, optional = true }
rust_xlsxwriter = { workspace = true, optional = true } rust_xlsxwriter = { workspace = true, optional = true }
umya-spreadsheet = { 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) # System Monitoring (monitoring feature)
sysinfo = { workspace = true, optional = true } sysinfo = { workspace = true, optional = true }
# Networking/gRPC (grpc feature)
tonic = { workspace = true, features = ["transport"], optional = true }
# UI Enhancement (progress-bars feature) # UI Enhancement (progress-bars feature)
indicatif = { workspace = true, optional = true } indicatif = { workspace = true, optional = true }
smartstring = { workspace = true } smartstring = { workspace = true }
@ -224,9 +203,6 @@ vaultrs = { workspace = true }
# Calendar standards (RFC 5545) # Calendar standards (RFC 5545)
icalendar = { workspace = true } icalendar = { workspace = true }
# Layered configuration
figment = { workspace = true, features = ["toml"] }
# Rate limiting # Rate limiting
governor = { workspace = true } governor = { workspace = true }
@ -239,9 +215,6 @@ walkdir = { workspace = true }
# Embedded static files # Embedded static files
rust-embed = { workspace = true } rust-embed = { workspace = true }
mime_guess = { workspace = true }
hyper-util = { workspace = true, features = ["client-legacy"] }
http-body-util = { workspace = true }
[dev-dependencies] [dev-dependencies]
mockito = { workspace = true } mockito = { workspace = true }

358
TODO.md
View file

@ -1,79 +1,309 @@
# Plano de Compilação Individual de Features # General Bots 7.0 - Enhanced Multi-Agent Orchestration
## Objetivo **Target Release:** Q3 2026
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. **Current Version:** 6.1.0
**Priority:** Critical for enterprise adoption
## Features a Testar ---
### Grupo 1: Comunicação ## Phase 1: Enhanced Orchestration (Months 1-2) 🚀
- [x] `chat`
- [x] `people`
- [x] `mail`
- [ ] `meet` (Failed: webrtc-sys C++ build error: missing absl/container/inlined_vector.h)
- [x] `social`
### Grupo 2: Produtividade ### 1.1 ORCHESTRATE WORKFLOW Keyword
- [x] `calendar` - [ ] **File:** `src/basic/keywords/orchestration.rs`
- [x] `tasks` - [ ] Add `ORCHESTRATE WORKFLOW` keyword to BASIC interpreter
- [x] `project` - [ ] Support STEP definitions with BOT calls
- [x] `goals` - [ ] Support PARALLEL branches execution
- [x] `workspaces` - [ ] Support conditional IF/THEN logic in workflows
- [x] `tickets` - [ ] Variable passing between steps
- [x] `billing` - [ ] **Database:** Add `workflow_executions` table
- crm - [ ] **Test:** Create workflow execution tests
### Grupo 3: Documentos
- [x] `docs`
- [x] `sheet`
- [x] `slides`
- [x] `paper`
### Grupo 4: Mídia ### 1.2 Event Bus System
- [x] `video` - [ ] **File:** `src/basic/keywords/events.rs`
- [x] `player` - [ ] Add `ON EVENT` keyword for event handlers
- [x] `canvas` - [ ] 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 ### 1.3 Bot Learning Enhancement
- [x] `learn` - [ ] **File:** `src/basic/keywords/bot_learning.rs`
- [x] `research` (Fixed: gated email dependencies, added missing imports) - [ ] Add `BOT LEARN` keyword for pattern storage (extends existing `SET BOT MEMORY`)
- [x] `sources` - [ ] 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 **Note:** Difference between `SET BOT MEMORY` vs `BOT LEARN`:
- [x] `analytics` - `SET BOT MEMORY`: Manual key-value storage (existing)
- [x] `dashboards` - `BOT LEARN`: Automatic pattern recognition from conversations
- [x] `monitoring` (Fixed: E0308 type mismatch in SVG generation)
### Grupo 7: Desenvolvimento ### 1.4 Database Schema
- [x] `designer` ```sql
- [x] `editor` -- 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 CREATE TABLE workflow_events (
- [x] `attendant` id UUID PRIMARY KEY,
- [x] `security` workflow_id UUID REFERENCES workflow_executions(id),
- [x] `settings` 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) ## Phase 2: Visual Workflow Designer (Months 3-4) 🎨
- [x] Fixed all shared warnings (unused variables/mut/imports in compiler, state, drive_monitor).
### Avisos Específicos de Feature ### 2.1 Drag-and-Drop Canvas
- [x] **mail**: Fixed unused imports. - [ ] **File:** `src/designer/workflow_canvas.rs`
- [x] **tasks**: Fixed unused imports. - [ ] Extend existing designer with workflow nodes
- [x] **project**: Fixed unused imports. - [ ] Add node types: BotAgent, HumanApproval, Condition, Loop, Parallel
- [x] **tickets**: Fixed unused imports. - [ ] Drag-and-drop interface using existing HTMX
- [x] **learn**: Fixed unused imports. - [ ] **Frontend:** Add workflow canvas to existing designer UI
- [x] **analytics**: Fixed unused imports. - [ ] **Output:** Generate BASIC code from visual design
- [x] **designer**: Fixed unused variable `messages`.
### 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) ### 2.3 Visual Designer Enhancement
1. **Automated Fixes**: Run `cargo clippy --fix --workspace` to resolve simple warnings (unused imports/variables/mut). - [ ] **File:** `src/designer/mod.rs`
- [ ] Execution in progress. - [ ] Add workflow mode to existing designer
2. **Manual Fixes**: Address warnings not resolvable by auto-fix. - [ ] Real-time BASIC code preview
- [ ] Complex logic changes. - [ ] Workflow validation and error checking
- [ ] Feature gating adjustments. - [ ] **Test:** Visual designer workflow tests
3. **Verification**: Run `cargo check --workspace` to ensure zero warnings.
---
## 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
View file

@ -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

View 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)

View file

@ -49,7 +49,7 @@ impl LocalJwtAuthProvider {
let roles: Vec<Role> = claims let roles: Vec<Role> = claims
.roles .roles
.as_ref() .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]); .unwrap_or_else(|| vec![Role::User]);
let mut user = AuthenticatedUser::new(user_id, username).with_roles(roles); let mut user = AuthenticatedUser::new(user_id, username).with_roles(roles);

View file

@ -6,8 +6,8 @@ use axum::{
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::str::FromStr; use std::str::FromStr;
use std::sync::OnceLock;
use std::sync::Arc; use std::sync::Arc;
use std::sync::OnceLock;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use tracing::warn; use tracing::warn;
@ -18,7 +18,9 @@ static PROTECTION_MANAGER: OnceLock<Arc<RwLock<ProtectionManager>>> = OnceLock::
fn get_manager() -> &'static Arc<RwLock<ProtectionManager>> { fn get_manager() -> &'static Arc<RwLock<ProtectionManager>> {
PROTECTION_MANAGER.get_or_init(|| { 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", "/api/security/protection/:tool/status",
get(get_tool_status), get(get_tool_status),
) )
.route( .route("/api/security/protection/:tool/install", post(install_tool))
"/api/security/protection/:tool/install",
post(install_tool),
)
.route( .route(
"/api/security/protection/:tool/uninstall", "/api/security/protection/:tool/uninstall",
post(uninstall_tool), 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<()>>)> { 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, StatusCode::BAD_REQUEST,
Json(ApiResponse::error(format!("Unknown tool: {tool_name}"))), 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 manager = get_manager().read().await;
let status_map = manager.get_all_status().await; let status_map = manager.get_all_status().await;
let tools: Vec<ToolStatus> = status_map.into_values().collect(); 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))), Ok(status) => Ok(Json(ApiResponse::success(status))),
Err(e) => { Err(e) => {
warn!(error = %e, "Failed to get tool status"); 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) => { Err(e) => {
warn!(error = %e, "Failed to install tool"); 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) => { Err(e) => {
warn!(error = %e, "Failed to start service"); 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) => { Err(e) => {
warn!(error = %e, "Failed to stop service"); 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) => { Err(e) => {
warn!(error = %e, "Failed to enable service"); 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) => { Err(e) => {
warn!(error = %e, "Failed to disable service"); 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))), Ok(result) => Ok(Json(ApiResponse::success(result))),
Err(e) => { Err(e) => {
warn!(error = %e, "Failed to run scan"); 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))), Ok(report) => Ok(Json(ApiResponse::success(report))),
Err(e) => { Err(e) => {
warn!(error = %e, "Failed to get report"); 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) => { Err(e) => {
warn!(error = %e, "Failed to update definitions"); 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) => { Err(e) => {
warn!(error = %e, "Failed to toggle auto setting"); 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 { match super::lmd::list_quarantined().await {
Ok(files) => Ok(Json(ApiResponse::success(files))), Ok(files) => Ok(Json(ApiResponse::success(files))),
Err(e) => { Err(e) => {
warn!(error = %e, "Failed to get quarantine list"); 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) => { Err(e) => {
warn!(error = %e, "Failed to restore file from quarantine"); 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")),
))
} }
} }
} }