Commit graph

305 commits

Author SHA1 Message Date
f1d0a985e4 fix: remove duplicate code block from secrets mod
Some checks failed
BotServer CI/CD / build (push) Failing after 5m52s
2026-04-05 00:48:13 -03:00
697210a37e fix: remove duplicate code block in secrets mod
Some checks failed
BotServer CI/CD / build (push) Failing after 12s
2026-04-05 00:44:20 -03:00
c90c5dc039 fix: use blocking HTTP for Vault email config to avoid runtime nesting
Some checks failed
BotServer CI/CD / build (push) Failing after 2s
2026-04-05 00:37:33 -03:00
eba075bb9d fix: use existing tokio Handle instead of spawning new runtime for email config
All checks were successful
BotServer CI/CD / build (push) Successful in 4m32s
2026-04-05 00:13:10 -03:00
597a962fbf fix: use multi-threaded runtime for email config lookup to avoid blocking
All checks were successful
BotServer CI/CD / build (push) Successful in 4m23s
2026-04-04 23:48:00 -03:00
30bb764876 fix: add 5s timeout to email config lookup to prevent hanging
All checks were successful
BotServer CI/CD / build (push) Successful in 4m26s
2026-04-04 23:35:20 -03:00
1dc11c9b4e refactor: unify email sending to use EmailService + Vault, remove Gmail hardcoded defaults
Some checks failed
BotServer CI/CD / build (push) Failing after 17s
- Replace gmail defaults with Vault-backed get_email_config_for_bot_sync
- send_campaign_email now delegates to EmailService::send_email
- Remove hardcoded smtp.gmail.com, imap.gmail.com, noreply@generalbots.com
- All SMTP config flows through Vault: bot → default bot → system
- Remove unused lettre imports from marketing/email.rs
2026-04-04 22:16:20 -03:00
dde6ac236e fix: check for non-empty smtp_from in email fallback chain
All checks were successful
BotServer CI/CD / build (push) Successful in 4m29s
2026-04-04 18:45:47 -03:00
01db253900 fix: add log::info import, fix ContentType parse, remove unused RedisClient import
All checks were successful
BotServer CI/CD / build (push) Successful in 4m38s
2026-04-04 17:49:40 -03:00
45eb8357cb feat: implement real email sending via lettre + Vault credentials
Some checks failed
BotServer CI/CD / build (push) Failing after 8m6s
- Replace EmailService::send_email stub with full lettre SMTP implementation
- Vault resolution chain: bot-specific → default bot → system fallback
- Seed Vault prod with default email config (contato@pragmatismo.com.br)
- Update all call sites to pass bot_id for Vault lookup
- Support attachments via lettre MultiPart/Attachment API
- Remove unused imports and dead code
2026-04-04 17:16:50 -03:00
0de4565e5a refactor: Generalize WhatsAppAdapter::new to accept &AppState
All checks were successful
BotServer CI/CD / build (push) Successful in 4m55s
- Simplify constructor from (pool, bot_id, cache) to (&state, bot_id)
- Adapter now extracts conn and cache from AppState internally
- Updates 15 call sites across 6 files
- Removes redundant parameter plumbing at every call site
2026-04-04 15:46:10 -03:00
44669c3825 fix: Fix resolve_export_path typo and remove unused PathBuf imports
All checks were successful
BotServer CI/CD / build (push) Successful in 4m28s
2026-04-04 10:23:42 -03:00
552d58376f fix: Fix compilation errors from path refactoring
Some checks failed
BotServer CI/CD / build (push) Failing after 1m27s
- bootstrap_utils.rs: Change Vec<(&'static str,...)> to Vec<(String,...)> to avoid dangling references
- bootstrap_manager.rs: Use name.as_str() for safe_pkill
- setup.rs: Use PathBuf instead of Path::new with format!
- directory/bootstrap.rs: Use PathBuf for pat_dir
- main.rs: Use PathBuf for vault_init_path_early
2026-04-04 10:04:00 -03:00
7d8f141fc2 refactor: Replace all hardcoded ./botserver-stack paths with get_stack_path()/get_work_path()
Some checks failed
BotServer CI/CD / build (push) Failing after 1m28s
- Adds get_stack_path() helper: returns /opt/gbo in production (.env without botserver-stack), ./botserver-stack in dev
- Adds get_work_path() helper: returns /opt/gbo/work in production, ./botserver-stack/data/system/work in dev
- Updated 35+ files to use dynamic path resolution
- Production system container no longer needs botserver-stack directory
- Work files go to /opt/gbo/work instead of /opt/gbo/bin/botserver-stack
2026-04-04 09:24:44 -03:00
4d7297243e Fix clippy warnings: reduce 17 warnings to 0
All checks were successful
BotServer CI/CD / build (push) Successful in 6m58s
- Fix double_ended_iterator_last: use next_back() instead of last()
- Fix manual_clamp: use .clamp() instead of min().max()
- Fix too_many_arguments: create KbInjectionContext struct
- Fix needless_borrow: remove unnecessary & reference
- Fix let_and_return: return value directly
- Fix await_holding_lock: drop guard before await
- Fix collapsible_else_if: collapse nested if-else

All changes verified with cargo clippy (0 warnings, 0 errors)
Note: Local botserver crashes with existing panic during LocalFileMonitor initialization
This panic exists in original code too, not caused by these changes
2026-04-03 22:34:43 -03:00
6f183c63d2 feat: dual-mode service configs - Vault first, fallback to DB/localhost
Some checks failed
BotServer CI/CD / build (push) Has been cancelled
All services now try Vault first (remote/distributed mode), then fall back
to database config, then localhost defaults (local/dev mode).

Services fixed:
- Qdrant/VectorDB: kb_indexer.rs, kb_statistics.rs, bootstrap_utils.rs, kb_context.rs
- LLM/Embedding: email/vectordb.rs (was hardcoded localhost:8082)
- All services: security/integration.rs (postgres, cache, drive, directory, qdrant, llm)

Pattern: SecretsManager::get_X_config_sync() → DB config → localhost default
2026-04-03 15:01:37 -03:00
61642343a8 fix: replace all block_in_place with std:🧵:spawn to fix nested runtime panic
Some checks are pending
BotServer CI/CD / build (push) Waiting to run
Root cause: block_in_place + new_current_thread().block_on() panics when
called from within tokio runtime (including spawn_blocking). Tokio doesn't
allow nested block_on() calls.

Fix: Replace ALL block_in_place patterns with std:🧵:spawn + mpsc channel.
This creates a completely separate OS thread with its own runtime, avoiding
any nesting issues. Works from any context: async, spawn_blocking, or sync.

Files: 14 files across secrets, utils, state, calendar, analytics, email,
and all keyword handlers (universal_messaging, search, book, create_draft,
create_site, hearing/syntax, use_tool, find, admin_email, goals)
2026-04-03 12:54:36 -03:00
4bdf46bdfc fix: use Result instead Option for runtime builder in get_work_path
Some checks are pending
BotServer CI/CD / build (push) Waiting to run
2026-04-03 12:16:08 -03:00
b2a9c8213d fix: use std:🧵:spawn for sync-to-async bridges to avoid nested block_on panic
Some checks are pending
BotServer CI/CD / build (push) Waiting to run
Root cause: new_current_thread().block_on() panics when called from within
an existing tokio runtime (including from spawn_blocking). Tokio doesn't
allow nested block_on() calls.

Fix: Use std:🧵:spawn to create a completely separate OS thread
with its own runtime, communicating via mpsc channel. This works from
any context: async, spawn_blocking, or sync.
2026-04-03 12:12:59 -03:00
21170faea9 fix: remove block_in_place wrappers that panic inside spawn_blocking
Some checks are pending
BotServer CI/CD / build (push) Waiting to run
Root cause: block_in_place + new_current_thread().block_on() panics when
called from within tokio::task::spawn_blocking because block_in_place is
designed for async worker threads, not blocking threads.

Fix: Remove all block_in_place wrappers and use new_current_thread().build().block_on()
directly. This works from both async contexts and spawn_blocking contexts.

Affected: utils.rs (get_database_url_sync, get_work_path)
2026-04-03 12:05:18 -03:00
c2982f2a33 fix: remove unused handle variable warning in get_database_url_sync
Some checks are pending
BotServer CI/CD / build (push) Waiting to run
2026-04-03 11:31:50 -03:00
263ca4ed11 fix: use new_current_thread runtime in get_database_url_sync to prevent nested block_on panic
All checks were successful
BotServer CI/CD / build (push) Successful in 6m30s
2026-04-03 09:26:23 -03:00
f6a864aa67 fix: replace nested runtime block_on with new_current_thread to prevent panic
All checks were successful
BotServer CI/CD / build (push) Successful in 5m32s
Root cause: Handle::current().block_on() panics inside multi_thread runtime
with 'Cannot start a runtime from within a runtime' error.

Fix: All sync-to-async bridges now use tokio::runtime::Builder::new_current_thread()
instead of Handle::current().block_on(). Also changed SECRETS_MANAGER from
tokio::sync::RwLock to std::sync::RwLock to eliminate unnecessary async overhead.

Files: 14 files across keywords, secrets, utils, state, calendar, analytics, email
Impact: Fixes production crash during bot loading phase
2026-04-03 09:17:23 -03:00
65e7db5acd Skip local service install/start when remote Vault detected
All checks were successful
BotServer CI/CD / build (push) Successful in 5m48s
- install_all() returns early if VAULT_ADDR is remote
- start_all() returns early if VAULT_ADDR is remote
- bootstrap.rs treats remote VAULT_ADDR as bootstrap_completed=true
- Prevents botserver from trying to install/start local services
  when all services are running in separate containers
2026-04-03 07:36:15 -03:00
e992ed3b39 Enforce Vault-only secrets: remove env var fallbacks, all secrets from Vault
Some checks are pending
BotServer CI/CD / build (push) Waiting to run
- Remove all std::env::var calls except VAULT_* and PORT
- get_from_env returns hardcoded defaults only (no env var reading)
- Auth config, rate limits, email, analytics, calendar all use Vault
- WORK_PATH replaced with get_work_path() helper reading from Vault
- .env on production cleaned to only VAULT_ADDR, VAULT_TOKEN, VAULT_CACERT, PORT
- All service IPs/credentials stored in Vault secret/gbo/*
2026-04-03 07:11:40 -03:00
5d88013ee3 Fix get_from_env: read actual env vars instead of hardcoded localhost values
All checks were successful
BotServer CI/CD / build (push) Successful in 4m3s
2026-04-02 21:17:19 -03:00
98b204b12e Fix health checks: replace nc with ss -tln for non-root environments
Some checks failed
BotServer CI/CD / build (push) Has been cancelled
2026-04-02 18:15:07 -03:00
dae0feb6a5 fix: SecretPaths match Vault seeding paths (gbo/cache not gbo/system/cache)
All checks were successful
BotServer CI/CD / build (push) Successful in 3m49s
- Root cause: Vault seeding writes to secret/gbo/cache but code reads gbo/system/cache
- kv2::read prepends secret/ so it looks for secret/gbo/system/cache (wrong)
- Fix: update SecretPaths to match seeding paths (gbo/cache, gbo/drive, etc.)
- Testing: compiles clean, paths now match vault kv list output
2026-04-02 07:16:32 -03:00
3c9e4ba6e7 fix: cache_health_check uses ss instead of nc (nc missing in prod container)
All checks were successful
BotServer CI/CD / build (push) Successful in 4m42s
- Root cause: prod container lacks nc (netcat), causing fallback to valkey-cli ping
- valkey-cli ping hangs indefinitely when Valkey requires password auth
- Fix: use ss -tlnp as primary check (always available), nc as fallback
- Testing: verified ss is available in prod, nc is not
2026-04-01 20:06:13 -03:00
318367d439 fix: Valkey health check uses nc first (avoids password hang)
All checks were successful
BotServer CI/CD / build (push) Successful in 3m58s
- nc -z checks port connectivity instantly (no auth needed)
- valkey-cli ping as fallback (hangs when password required)
- Fixes bootstrap hang on production where Valkey has Vault password
2026-04-01 18:52:04 -03:00
c26e483cc9 fix: All services check health before starting (idempotent bootstrap)
All checks were successful
BotServer CI/CD / build (push) Successful in 4m9s
- Tables (PostgreSQL): pg_isready health check before start
- Drive (MinIO): /minio/health/live check before start
- ALM (Forgejo): HTTP health check before start
- ALM CI (Forgejo Runner): pgrep check before start
- Valkey: health check uses absolute path to valkey-cli
- Vault, Qdrant, Zitadel: already had health checks
- Result: no duplicate starts, no hangs on restart
2026-04-01 18:28:54 -03:00
ba7f1ba5eb fix: Valkey health check uses absolute path to valkey-cli
Some checks failed
BotServer CI/CD / build (push) Has been cancelled
- Use BOTSERVER_STACK_PATH/bin/cache/bin/valkey-cli instead of relying on PATH
- Remove bash /dev/tcp fallback (unreliable in restricted environments)
- Falls back to redis-cli and nc if valkey-cli unavailable
2026-04-01 18:11:26 -03:00
68ef554132 fix: Vault as single source of truth - credentials + location for all services
All checks were successful
BotServer CI/CD / build (push) Successful in 4m53s
- Qdrant health check: recognize 'healthz check passed' response (fixes 45s timeout)
- seed_vault_defaults: add host/port/url/grpc_port for ALL 10 services
- fetch_vault_credentials: fetch ALL services via generic loop (drive, cache, tables, vectordb, directory, llm, meet, alm, encryption)
- vectordb URL: fix https://localhost:6334 -> http://localhost:6333 in all config getters
- get_from_env: add host/port/grpc_port for vectordb fallback
- Tested: .reset (fresh install) + .restart (idempotent) - zero errors
2026-04-01 16:46:16 -03:00
fb2e5242da fix: Vault seeding, service health checks, and restart idempotency
All checks were successful
BotServer CI/CD / build (push) Successful in 55m52s
- Replace hardcoded passwords with generate_random_string() for all Vault-seeded services
- Add valkey-cli, nc to SafeCommand allowlist; fix PATH in all 4 execution methods
- Fix empty Vault KV values ('none' placeholder) preventing 'Failed to parse K=V' errors
- Fix special chars in generated passwords triggering shell injection false positives
- Add ALM app.ini creation with absolute paths for Forgejo CLI
- Increase Qdrant timeout 15s→45s, ALM wait 5s→20s
- Persist file_states and kb_states to disk for .bas/KB idempotency across restarts
- Add duplicate check to use_website registration (debug log for existing)
- Remove dead code (SERVER_START_EPOCH, server_epoch)
- Add generate_random_string() to shared mod.rs, remove duplicates
2026-04-01 12:22:57 -03:00
3e46a16469 fix: Seed default credentials into Vault after initialization
Some checks failed
BotServer CI/CD / build (push) Failing after 3h13m28s
- Add seed_vault_defaults() to write default creds for all components
  (drive, cache, tables, directory, email, llm, encryption, meet, vectordb, alm)
- Call seed_vault_defaults() after KV2 enable in initialize_vault_local()
- Call seed_vault_defaults() in recover_existing_vault() for recovery path
- Rewrite fetch_vault_credentials() to use SafeCommand directly instead of
  safe_sh_command, avoiding '//' shell injection false positive on URLs
- Components like Drive now get credentials from Vault instead of 403 errors
2026-03-31 22:19:09 -03:00
9919a8321c fix: Use SafeCommand directly for vault health check to avoid shell injection false positive
All checks were successful
BotServer CI/CD / build (push) Successful in 6m46s
- Replace safe_sh_command with SafeCommand::new("curl").args() in vault_health_check()
- The URL contains https:// which triggered '//' pattern detection in shell command
- Direct SafeCommand bypasses shell parsing, URL passed as single argument
- Add vault data directory existence check before recovery attempt
- Prevents 'Dangerous pattern // detected' errors during bootstrap
2026-03-31 21:34:04 -03:00
07a6c1edb3 Merge commit '582ea634'
All checks were successful
BotServer CI/CD / build (push) Successful in 7m38s
2026-03-31 21:10:25 -03:00
582ea634e7 fix: Vault bootstrap recovery for sealed but initialized instances
- Fix vault_health_check() stub that always returned false
- Add recover_existing_vault() to handle Vault with existing data but no init.json
- Add unseal_vault() helper to unseal with existing vault-unseal-keys
- Detect initialized Vault via health endpoint or data directory presence
- Prevents bootstrap failure when reset.sh deletes init.json but Vault data persists

Root cause: vault_health_check() was a stub returning false, causing bootstrap
to always try vault operator init on already-initialized (but sealed) Vault,
which failed with connection refused. This cascaded to all services failing
to fetch credentials from Vault.
2026-03-31 20:49:29 -03:00
2fa59057fa fix: Resolve migration error, Vault 403, cache timeout, and shell injection false positives
Some checks failed
BotServer CI/CD / build (push) Has been cancelled
- Fix migration 6.2.5: Create lost_reason column before VIEW that references it
- Fix Vault 403: Enable KV2 secrets engine after initialization
- Fix cache timeout: Increase Valkey readiness wait from 12s to 30s
- Fix command_guard: Remove () from forbidden chars (safe in std::process::Command)
2026-03-31 19:55:16 -03:00
b83b4ffc4d fix: Remove server_epoch() from start_bas_executed Redis key
The epoch caused a new key to be created every second, bypassing
the 'already executed' check and running start.bas multiple times,
resulting in triplicated suggestions.
2026-03-21 20:40:25 -03:00
1132983064 feat(kb): add with_bot_config to load embedding from bot config
- Adds KnowledgeBaseManager::with_default_config() as alias to new()
- Adds KnowledgeBaseManager::with_bot_config() to load embedding_url,
  embedding_model, and qdrant config from bot's config.csv
- Updates bootstrap to use with_bot_config with default_bot_id
- Enables per-bot embedding configuration instead of global env vars
2026-03-21 18:55:36 -03:00
622f1222dc fix(websocket): force start.bas execution on connection to restore chat on page reload while preventing duplicate execution 2026-03-21 16:38:03 -03:00
d19984fa07 feat: Improve KB keywords and package manager installer 2026-03-20 17:38:47 -03:00
57a8b7f8f0 Fix: use pgrep to check valkey/qdrant running state
- valkey check_cmd: replaced valkey-cli ping (network) with pgrep -x valkey-server
- qdrant check_cmd: replaced curl https check (TLS error 35) with pgrep -x qdrant
- Prevents duplicate instances on each botserver restart
2026-03-20 15:40:22 -03:00
3bb115266b feat: Add GUID prefix to Qdrant collection names for KB security isolation 2026-03-19 19:51:28 -03:00
d6ebd0cf6e fix: send suggestions separately from TALK, clear Redis keys for refresh
- Remove suggestions fetching from TALK function
- WebSocket handler now fetches and sends suggestions after start.bas executes
- Clear suggestions and start_bas_executed keys to allow re-run on refresh
- Decouple TALK from suggestions handling
2026-03-19 09:53:39 -03:00
6e594d68dd Fix: Wait for send_task to be ready before executing start.bas 2026-03-18 14:38:46 -03:00
8f073a15fd Fix: Wait for send_task to be ready before executing start.bas so TALK messages work 2026-03-18 14:18:05 -03:00
346c83871a Fix Vault TLS certificate to include Subject Alternative Name for modern client compatibility 2026-03-18 09:30:27 -03:00
ed2a1d83f0 fix: include server epoch in start_bas_executed key to invalidate after restart 2026-03-17 15:45:02 -03:00