- 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
- Add hear_channels: HashMap<Uuid, SyncSender<String>> to AppState
- HEAR now blocks the spawn_blocking thread via sync_channel recv()
- deliver_hear_input() called at top of stream_response() to unblock
- Script continues from exact HEAR position, no side-effect re-execution
- All three HEAR variants (basic, AS TYPE, AS MENU) use same mechanism
- Store last_sent timestamp in Redis (whatsapp:last_sent:<phone>)
- Always wait 6 seconds between messages to same recipient
- Persists across restarts
- Add Redis-backed message queue with per-recipient tracking
- Enforce 1 message per 6 seconds per recipient (0.17 msg/s)
- Support burst mode: up to 45 messages in 6-second window
- Implement proportional cooldown after burst
- Add exponential backoff retry on error 131056 (4^X seconds)
- Update botbook with official Meta rate limits
- Add unit tests for burst mode and rate limiting
- Fix config inheritance bug: delete all keys before sync
- Move system_prompt retrieval inside spawn_blocking closure
- Include system_prompt in the return tuple to fix scope issue
- Add trace logging for debugging system-prompt loading
- GLM-5 and other LLM providers now correctly receive custom system prompts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Split list detection into numbered and bullet list items
- Add looks_like_list_start() to detect when list is beginning
- Add looks_like_list_end() to detect when list has ended
- Add split_text_before_list() to separate text before list
- Add split_list_from_text() to separate list from text after
- Update streaming logic to send lists as isolated messages
- Add code block removal (triple backticks and inline backticks)
- Add comprehensive unit tests for list detection functions
Resolves: Lists being mixed with other text in WhatsApp messages
Resolves: JavaScript/C# code leaking into WhatsApp messages
- Lower score_threshold in kb_indexer.rs from 0.5 to 0.3
- Lower website search threshold in kb_context.rs from 0.6 to 0.4
- Lower KB search threshold in kb_context.rs from 0.7 to 0.5
- Add Cloudflare AI (/ai/run/) URL detection in cache.rs
- Add Cloudflare AI request format ({"text": ...}) in cache.rs
- Add Cloudflare AI response parsing (result.data) in cache.rs
This fixes the issue where KB search returned 0 results even with
114 chunks indexed. The high thresholds were filtering out all results.
- Lower score_threshold in kb_indexer.rs from 0.5 to 0.3
- Lower website search threshold in kb_context.rs from 0.6 to 0.4
- Lower KB search threshold in kb_context.rs from 0.7 to 0.5
- Add Cloudflare AI (/ai/run/) URL detection in cache.rs
- Add Cloudflare AI request format ({"text": ...}) in cache.rs
- Add Cloudflare AI response parsing (result.data) in cache.rs
This fixes the issue where KB search returned 0 results even with
114 chunks indexed. The high thresholds were filtering out all results.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated get_tool_bas_path to look in /opt/gbo/data (source) first
- Then check botserver-stack/data/system/work (compiled) second
- Removed incorrect $HOME/data and $HOME/gb/work paths
- Fixes 'Tool file not found' error when executing inscricao tool
According to AGENTS.md architecture:
- Bots are in /opt/gbo/data primary
- They are compiled into work directory by local_file_monitor
- tool_executor was looking in wrong directories
- Add detailed logging for all 5 pipeline stages (PLAN, BUILD, REVIEW, DEPLOY, MONITOR)
- Log stage start/complete events with agent IDs and progress details
- Add resource creation/deletion logging in drive_handlers
- Improve pipeline summary logging with task ID, nodes, resources, and URL
This addresses the requirement for textual progress in console logs.
Added logic to create botserver-stack/data/system/work directory
if it doesn't exist. This ensures production deployments work
without manual directory setup.
Changes:
- Added fs::create_dir_all() in use_tool.rs
- Added fs::create_dir_all() in tool_context.rs
- Logs when directory is created
- Fixes production deployment where /system/work may not exist
This ensures the tool loading works in fresh production environments
where the work folder hasn't been populated yet.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed tool loading to use relative path from current directory instead
of hardcoded HOME/gb path. This makes the code portable across different
deployment environments.
- Updated use_tool.rs to use std::env::current_dir()
- Updated tool_context.rs to use std::env::current_dir()
- Added PathBuf import to both files
- Tools now load from botserver-stack/data/system/work/
Fixes issue where tools weren't being loaded because .mcp.json files
were in a different location than expected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fixed RCE vulnerability in trusted_shell_script_arg execution
- Fixed SSRF vulnerability in GET command with internal IP blocking
- Updated SafeCommand to use explicit positional arguments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Track tool_was_executed flag in stream_response
- Send empty content in final is_complete message when tool already sent results
- Prevents the LLM's pre-tool text from appearing twice in the chat UI
- DB message saving is unaffected (uses full_response_clone before the check)
- Add tool_call_buffer to accumulate JSON chunks across multiple LLM responses
- Handle incomplete tool call JSON that spans multiple chunks
- Convert SELECT...CASE/END SELECT to Rhai match expressions
- Fix NOT IN operator conversion to !in for IF conditions
Fixed issue where LLM tool calls returned as JSON arrays were not being
detected and were displayed as raw JSON in the chat instead of being executed.
The parse_tool_call method now handles:
- Single tool call objects
- Arrays of tool calls (OpenAI standard format)
This prevents tool call JSON from appearing in the chat window and ensures
tools are executed properly.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add error and warning logs to help diagnose why session tools are not
working in production. Logs now show:
- Number of tools loaded successfully
- Detailed error messages when tool loading fails
- Bot name lookup failures
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This loads and sends the available tools to the client when establishing
a WebSocket connection. Tools are loaded based on the bot configuration
and sent in the initial welcome message.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed default model from 'gpt-3.5-turbo' to 'DeepSeek-R1-Distill-Qwen-1.5B-Q3_K_M.gguf'
in bot message handler. This ensures the local llama-server receives the correct model
name and can process requests properly.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Escape format placeholders in designer_ai.rs ({{botname}})
- Remove undefined 'prefix' filter in drive_monitor
- Fix type mismatch in use_tool.rs (str vs &String)
- Remove unused TextExpressionMethods import
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add Redis-based tracking to prevent start.bas from running repeatedly
when clicking suggestion buttons. start.bas now executes only once per
session with a 24-hour expiration on the tracking key.
- Add generic tool executor (ToolExecutor) for parsing and executing
tool calls from any LLM provider. Works with Claude, OpenAI, and
other providers that use standard tool calling formats.
- Update both start.bas execution paths (WebSocket handler and LLM
message handler) to check Redis before executing.
- Fix suggestion duplication by clearing suggestions from Redis after
fetching them.
- Add rate limiter for LLM API calls.
- Improve error handling and logging throughout.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix ConfigManager to treat 'none', 'null', 'n/a', and empty values as placeholders
and fall back to default bot's configuration instead of using these as literal values
- Fix ConfigManager to detect local file paths (e.g., .gguf, .bin, ../) and fall back
to default bot's model when using remote API, allowing bots to keep local model
config for local LLM server while automatically using remote model for API calls
- Fix get_default_bot() to return the bot actually named 'default' instead of
the first active bot by ID, ensuring consistent fallback behavior
- Add comprehensive debug logging to trace LLM configuration from database to API call
This fixes the issue where bots with incomplete or local LLM configuration would
fail with 401/400 errors when trying to use remote API, instead of automatically
falling back to the default bot's configuration from config.csv.
Closes: #llm-config-fallback
- Extract bot_name from WebSocket query parameters
- Look up bot_id from bot_name using database
- Pass bot_id to WebSocket message handler
- Use session's bot_id for LLM configuration instead of client-provided bot_id
- Fixes issue where client sends 'default' bot_id when accessing /edu