Compare commits
27 commits
66f54677bf
...
3ea4c562e1
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ea4c562e1 | |||
| cae2dda8ee | |||
| 3a133e10d4 | |||
| c54b7333d2 | |||
| a0ef7d8488 | |||
| 8fc44928a6 | |||
| 9fa5058470 | |||
| 03ec4c301c | |||
| c15b194ade | |||
| a2a6e53bcb | |||
| 5ff03af1a6 | |||
| 52b54ffae5 | |||
| c909db7aaf | |||
| 613db5748e | |||
| 1d46122dc5 | |||
| c10c2e0b78 | |||
| 8c5ee3f3e3 | |||
| 5226c771f8 | |||
| e496ac11e2 | |||
| 704bbb22a5 | |||
| 375c3780c2 | |||
| e5bf8ec75a | |||
| ae8b830773 | |||
| 5cab98b459 | |||
| 027c7c77b8 | |||
| c6b21149b1 | |||
| 68cd0d6bf3 |
15 changed files with 223 additions and 5 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -49,3 +49,4 @@ node_modules/
|
|||
/playwright/.cache/
|
||||
/playwright/.auth/
|
||||
config/directory_config.json
|
||||
# CI cache bust: Fri Feb 13 22:33:51 UTC 2026
|
||||
|
|
|
|||
87
README.md
87
README.md
|
|
@ -35,6 +35,35 @@ For comprehensive documentation, see **[docs.pragmatismo.com.br](https://docs.pr
|
|||
- **Env file:** `botserver/.env`
|
||||
- **Stack:** `botserver-stack/`
|
||||
- **UI Files:** `botui/ui/suite/`
|
||||
- **Local Bot Data:** `/opt/gbo/data/` (place `.gbai` packages here)
|
||||
|
||||
### Local Bot Data Directory
|
||||
|
||||
Place local bot packages in `/opt/gbo/data/` for automatic loading and monitoring:
|
||||
|
||||
**Directory Structure:**
|
||||
```
|
||||
/opt/gbo/data/
|
||||
└── mybot.gbai/
|
||||
├── mybot.gbdialog/
|
||||
│ ├── start.bas
|
||||
│ └── main.bas
|
||||
└── mybot.gbot/
|
||||
└── config.csv
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- **Auto-loading:** Bots automatically mounted on server startup
|
||||
- **Auto-compilation:** `.bas` files compiled to `.ast` on change
|
||||
- **Auto-creation:** New bots automatically added to database
|
||||
- **Hot-reload:** Changes trigger immediate recompilation
|
||||
- **Monitored by:** LocalFileMonitor and ConfigWatcher services
|
||||
|
||||
**Usage:**
|
||||
1. Create bot directory structure in `/opt/gbo/data/`
|
||||
2. Add `.bas` files to `<bot_name>.gbai/<bot_name>.gbdialog/`
|
||||
3. Server automatically detects and loads the bot
|
||||
4. Optional: Add `config.csv` for bot configuration
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -439,6 +468,64 @@ cargo test -p bottest
|
|||
3. Run [Weekly Maintenance Tasks](#-weekly-maintenance-tasks) to keep codebase healthy
|
||||
4. Read project-specific READMEs in [Project-Specific Guidelines](#-project-specific-guidelines)
|
||||
|
||||
## 🎭 Playwright Browser Testing - YOLO Mode
|
||||
|
||||
### YOLO Mode Instructions for LLMs
|
||||
|
||||
**When user requests to start YOLO mode with Playwright:**
|
||||
|
||||
1. **Start the browser** - Use `mcp__playwright__browser_navigate` to open http://localhost:3000
|
||||
2. **Take snapshot** - Use `mcp__playwright__browser_snapshot` to see current page state
|
||||
3. **Test user flows** - Use click, type, fill_form, etc. to interact with UI
|
||||
4. **Verify results** - Check for expected content, errors in console, network requests
|
||||
5. **Report findings** - Always include screenshot evidence with `browser_take_screenshot`
|
||||
|
||||
**Available Playwright MCP Tools:**
|
||||
- `browser_navigate` - Navigate to URL
|
||||
- `browser_snapshot` - Get accessibility tree (better than screenshots for analysis)
|
||||
- `browser_take_screenshot` - Capture visual state
|
||||
- `browser_click` - Click elements (provide ref from snapshot)
|
||||
- `browser_type` - Type text into inputs
|
||||
- `browser_fill_form` - Fill multiple form fields at once
|
||||
- `browser_console_messages` - Check for JavaScript errors
|
||||
- `browser_network_requests` - Inspect API calls
|
||||
- `browser_close` - Close browser when done
|
||||
|
||||
**YOLO Testing Workflow:**
|
||||
```
|
||||
1. Navigate → http://localhost:3000
|
||||
2. Snapshot → Analyze page structure
|
||||
3. Click → Target element using ref from snapshot
|
||||
4. Wait → For navigation/updates (browser_wait_for)
|
||||
5. Verify → Console messages, network status
|
||||
6. Screenshot → Document test results
|
||||
```
|
||||
|
||||
**Testing Checklist:**
|
||||
- ✅ UI loads without errors
|
||||
- ✅ Navigation works between sections
|
||||
- ✅ Forms submit correctly
|
||||
- ✅ WebSocket connections establish
|
||||
- ✅ Console shows no JavaScript errors
|
||||
- ✅ Network requests return 200/201/204
|
||||
|
||||
**Critical Test Flows:**
|
||||
- **Login/Authentication** → Navigate, enter credentials, verify session
|
||||
- **Bot Creation** → Click "New Bot", fill form, verify creation
|
||||
- **Chat Interface** → Send message, verify WebSocket response
|
||||
- **File Upload** → Upload .bas file, verify compilation
|
||||
- **Drive Sync** → Trigger sync, verify files appear
|
||||
|
||||
**Error Handling in YOLO Mode:**
|
||||
- If navigation fails: Check if servers running (`ps aux | grep botserver`)
|
||||
- If element not found: Take snapshot to debug current page state
|
||||
- If console errors: Extract and report to user for fixing
|
||||
- If network failures: Check API endpoints and CORS configuration
|
||||
|
||||
### Integration Testing
|
||||
|
||||
For automated test suites, prefer `cargo test -p bottest` for backend logic and Playwright YOLO mode for full-stack UI testing.
|
||||
|
||||
## 🧪 Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
|
|
|
|||
2
botbook
2
botbook
|
|
@ -1 +1 @@
|
|||
Subproject commit 3e418df1a854fb2c98258b0c454082cd751a8123
|
||||
Subproject commit 6d48dbba1b21f7fdefd4dfa30d0e33e2879980bb
|
||||
2
botlib
2
botlib
|
|
@ -1 +1 @@
|
|||
Subproject commit 38dc7c050d9b82c822999ff432600faa0b389df9
|
||||
Subproject commit 5759fdcd5b528c6f3474cf48f067af4c371e9234
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 5ea171d12617751283c50c955635135a10a52ad7
|
||||
Subproject commit dec3a086abd2df28452f44f8f8986a3e3ae27005
|
||||
2
botui
2
botui
|
|
@ -1 +1 @@
|
|||
Subproject commit af78f3156594c3bdbb9d76c31b26bcaf30abf77c
|
||||
Subproject commit 4f654dd95daeb8e21c7977f6f4762fdac392b2d3
|
||||
19
console-errors.txt
Normal file
19
console-errors.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Total messages: 587 (Errors: 16, Warnings: 4)
|
||||
Returning 16 messages for level "error"
|
||||
|
||||
[ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/public/themes/vapordream.css:0
|
||||
[ERROR] ✗ Failed: 💭 Vapor Dream @ http://localhost:3000/cristo/suite/js/theme-manager.js:85
|
||||
[ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/public/themes/saturdaycartoons.css:0
|
||||
[ERROR] ✗ Failed: 📺 Cartoons @ http://localhost:3000/cristo/suite/js/theme-manager.js:85
|
||||
[ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3000/public/themes/cyberpunk.css:0
|
||||
[ERROR] ✗ Failed: 🌃 Cyberpunk @ http://localhost:3000/cristo/suite/js/theme-manager.js:85
|
||||
[ERROR] WebSocket connection to 'ws://localhost:3000/ws/chat?session_id=f48dd5f0-662b-49bb-a9a6-4039f6e143e7&user_id=9f6c12e7-15b7-4443-bb4a-15b8e17ba076&bot_name=cristo' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ :819
|
||||
[ERROR] WebSocket error: Event @ :879
|
||||
[ERROR] WebSocket connection to 'ws://localhost:3000/ws/chat?session_id=f48dd5f0-662b-49bb-a9a6-4039f6e143e7&user_id=9f6c12e7-15b7-4443-bb4a-15b8e17ba076&bot_name=cristo' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ :819
|
||||
[ERROR] WebSocket error: Event @ :879
|
||||
[ERROR] WebSocket connection to 'ws://localhost:3000/ws/chat?session_id=f48dd5f0-662b-49bb-a9a6-4039f6e143e7&user_id=9f6c12e7-15b7-4443-bb4a-15b8e17ba076&bot_name=cristo' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ :819
|
||||
[ERROR] WebSocket error: Event @ :879
|
||||
[ERROR] WebSocket connection to 'ws://localhost:3000/ws/chat?session_id=f48dd5f0-662b-49bb-a9a6-4039f6e143e7&user_id=9f6c12e7-15b7-4443-bb4a-15b8e17ba076&bot_name=cristo' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ :819
|
||||
[ERROR] WebSocket error: Event @ :879
|
||||
[ERROR] WebSocket connection to 'ws://localhost:3000/ws/chat?session_id=f48dd5f0-662b-49bb-a9a6-4039f6e143e7&user_id=9f6c12e7-15b7-4443-bb4a-15b8e17ba076&bot_name=cristo' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED @ :819
|
||||
[ERROR] WebSocket error: Event @ :879
|
||||
7
console-i18n.json
Normal file
7
console-i18n.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Total messages: 36 (Errors: 0, Warnings: 4)
|
||||
Returning 4 messages for level "warning"
|
||||
|
||||
[WARNING] [GBSecurity] NO TOKEN - request will be unauthenticated @ https://chat.pragmatismo.com.br/suite/js/security-bootstrap.js?v=20260207b:157
|
||||
[WARNING] i18n: Missing translation key: chat-mention-title @ https://chat.pragmatismo.com.br/suite/js/i18n.js:129
|
||||
[WARNING] i18n: Missing translation key: chat-mention-title @ https://chat.pragmatismo.com.br/suite/js/i18n.js:129
|
||||
[WARNING] i18n: Missing translation key: chat-mention-title @ https://chat.pragmatismo.com.br/suite/js/i18n.js:129
|
||||
33
console-output-after-fix.txt
Normal file
33
console-output-after-fix.txt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
Total messages: 31 (Errors: 0, Warnings: 1)
|
||||
|
||||
[LOG] [GBSecurity] HTMX interceptor registered @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:172
|
||||
[LOG] [GBSecurity] Fetch interceptor registered @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:224
|
||||
[LOG] [GBSecurity] XHR interceptor registered @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:269
|
||||
[LOG] [GBSecurity] Security bootstrap initialized @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:125
|
||||
[LOG] [GBSecurity] Current token: NONE @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:126
|
||||
[LOG] [ErrorReporter] Client-side error reporting initialized @ http://localhost:3000/suite/js/error-reporter.js?v=20260207c:102
|
||||
[LOG] [GBSecurity] fetch intercepted: /api/i18n/en token: NONE @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:184
|
||||
[LOG] [GBSecurity] fetch intercepted: /api/product token: NONE @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:184
|
||||
[LOG] [GBSecurity] fetch intercepted: /api/product token: NONE @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:184
|
||||
[LOG] [NavigationLogger] Navigation tracking initialized @ http://localhost:3000/suite/js/error-reporter.js?v=20260207c:152
|
||||
[LOG] Initializing HTMX application... @ http://localhost:3000/cristo/suite/js/htmx-app.js:560
|
||||
[LOG] ✓ Theme Manager initialized @ http://localhost:3000/cristo/suite/js/theme-manager.js:130
|
||||
[LOG] HTMX application initialized @ http://localhost:3000/cristo/suite/js/htmx-app.js:580
|
||||
[LOG] 🤖 Bot detected from path: cristo @ http://localhost:3000/cristo/suite/js/suite_app.js:722
|
||||
[LOG] 🚀 Initializing General Bots with HTMX... @ http://localhost:3000/cristo/suite/js/suite_app.js:748
|
||||
[LOG] [GBSecurity] fetch intercepted: /api/bot/config?bot_name=cristo token: NONE @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:184
|
||||
[LOG] No auth token found - user is signed out @ http://localhost:3000/cristo/suite/js/suite_app.js:1296
|
||||
[LOG] ✓ Theme loaded: ☀️ Light @ http://localhost:3000/cristo/suite/js/theme-manager.js:79
|
||||
[LOG] ✅ Bot 'cristo' is public - authentication not required @ http://localhost:3000/cristo/suite/js/suite_app.js:737
|
||||
[LOG] [GBSecurity] htmx:configRequest for: /suite/chat/chat.html token: NONE @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:146
|
||||
[WARNING] [GBSecurity] NO TOKEN - request will be unauthenticated @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:157
|
||||
[LOG] [GBSecurity] fetch intercepted: /api/bot/config?bot_name=cristo token: NONE @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:184
|
||||
[LOG] [GBSecurity] fetch intercepted: /api/auth?bot_name=cristo token: NONE @ http://localhost:3000/suite/js/security-bootstrap.js?v=20260207b:184
|
||||
[LOG] Chat module initialized with @ mentions support @ :1048
|
||||
[LOG] Bot config loaded: {color1: #3b82f6, color2: #f5deb3, title: cristo} @ :936
|
||||
[LOG] Auth: {currentUserId: 042f12c8-7151-4bf3-bd7b-5f8cfd560735, currentSessionId: ecc69ce7-2419-4da7-a149-3c62a1a0af90, currentBotId: 11873f09-9251-4e92-92fa-8de8cabaae7a, currentBotName: cristo} @ :961
|
||||
[LOG] WebSocket connected @ :822
|
||||
[LOG] Chat WebSocket received: {bot_id: 11873f09-9251-4e92-92fa-8de8cabaae7a, message: Connected to bot server, session_id: ecc69ce7-2419-4da7-a149-3c62a1a0af90, type: connected, user_id: 042f12c8-7151-4bf3-bd7b-5f8cfd560735} @ :830
|
||||
[LOG] Chat WebSocket received: {bot_id: 11873f09-9251-4e92-92fa-8de8cabaae7a, user_id: 042f12c8-7151-4bf3-bd7b-5f8cfd560735, session_id: ecc69ce7-2419-4da7-a149-3c62a1a0af90, channel: web, content: Olá! Sou o assistente virtual do Santuário Cristo …sobre celebrações, eventos, visitação ou orações?} @ :830
|
||||
[LOG] Processing bot response: {bot_id: 11873f09-9251-4e92-92fa-8de8cabaae7a, user_id: 042f12c8-7151-4bf3-bd7b-5f8cfd560735, session_id: ecc69ce7-2419-4da7-a149-3c62a1a0af90, channel: web, content: Olá! Sou o assistente virtual do Santuário Cristo …sobre celebrações, eventos, visitação ou orações?} @ :858
|
||||
[LOG] Rendering 10 suggestions @ :707
|
||||
2
prod-console-test.json
Normal file
2
prod-console-test.json
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Total messages: 36 (Errors: 0, Warnings: 4)
|
||||
Returning 0 messages for level "error"
|
||||
2
prod-console.json
Normal file
2
prod-console.json
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Total messages: 34 (Errors: 0, Warnings: 4)
|
||||
Returning 0 messages for level "error"
|
||||
5
prod-network.json
Normal file
5
prod-network.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
[GET] https://chat.pragmatismo.com.br/api/product => [200]
|
||||
[GET] https://chat.pragmatismo.com.br/api/product => [200]
|
||||
[GET] https://chat.pragmatismo.com.br/suite/chat/chat.html => [200]
|
||||
[GET] https://chat.pragmatismo.com.br/api/bot/config?bot_name=default => [200]
|
||||
[GET] https://chat.pragmatismo.com.br/api/auth?bot_name=default => [200]
|
||||
33
restart.sh
33
restart.sh
|
|
@ -2,9 +2,10 @@
|
|||
set -e
|
||||
|
||||
echo "🛑 Stopping existing processes..."
|
||||
pkill -f botserver || true
|
||||
pkill -f "botserver --noconsole" || true
|
||||
pkill -f botui || true
|
||||
pkill -f rustc || true
|
||||
# Note: PostgreSQL, Vault, and Valkey are managed by botserver bootstrap, don't kill them
|
||||
|
||||
echo "🧹 Cleaning logs..."
|
||||
rm -f botserver.log botui.log
|
||||
|
|
@ -15,10 +16,40 @@ cargo build -p botserver
|
|||
echo "🔨 Building botui..."
|
||||
cargo build -p botui
|
||||
|
||||
echo "🗄️ Starting PostgreSQL..."
|
||||
./botserver-stack/bin/tables/bin/postgres -D botserver-stack/data/tables/pgdata -c config_file=botserver-stack/conf/postgresql.conf > botserver-stack/logs/tables/postgres.log 2>&1 &
|
||||
echo " PostgreSQL PID: $!"
|
||||
sleep 2
|
||||
|
||||
echo "🔑 Starting Valkey (cache)..."
|
||||
./botserver-stack/bin/cache/valkey-server --daemonize no --dir botserver-stack/data/cache > /dev/null 2>&1 &
|
||||
echo " Valkey started"
|
||||
sleep 2
|
||||
|
||||
echo "🚀 Starting botserver..."
|
||||
export VAULT_ADDR="https://localhost:8200"
|
||||
export VAULT_TOKEN="hvs.JjKHlEzycO2jvKdhhlRAoODu"
|
||||
export VAULT_CACERT="./botserver-stack/conf/system/certificates/ca/ca.crt"
|
||||
export VAULT_CACHE_TTL="300"
|
||||
RUST_LOG=info ./target/debug/botserver --noconsole > botserver.log 2>&1 &
|
||||
BOTSERVER_PID=$!
|
||||
|
||||
echo "⏳ Waiting for Vault to start (unsealing in background)..."
|
||||
(
|
||||
sleep 8
|
||||
echo "🔓 Unsealing Vault..."
|
||||
UNSEAL_KEY=$(python3 -c "import json; print(json.load(open('botserver-stack/conf/vault/init.json'))['unseal_keys_b64'][0])" 2>/dev/null)
|
||||
if [ -n "$UNSEAL_KEY" ]; then
|
||||
curl -s --cacert botserver-stack/conf/system/certificates/ca/ca.crt \
|
||||
-X POST \
|
||||
-H "X-Vault-Token: hvs.JjKHlEzycO2jvKdhhlRAoODu" \
|
||||
-d "{\"key\": \"$UNSEAL_KEY\"}" \
|
||||
https://localhost:8200/v1/sys/unseal 2>/dev/null && echo "✅ Vault unsealed" || echo "⚠️ Unseal failed"
|
||||
else
|
||||
echo "⚠️ Could not extract unseal key"
|
||||
fi
|
||||
) &
|
||||
|
||||
echo "🚀 Starting botui..."
|
||||
BOTSERVER_URL="https://localhost:8088" ./target/debug/botui > botui.log 2>&1 &
|
||||
BOTUI_PID=$!
|
||||
|
|
|
|||
26
start-and-unseal.sh
Executable file
26
start-and-unseal.sh
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "🔓 Unsealing Vault..."
|
||||
UNSEAL_KEY="$(cat botserver-stack/conf/vault/init.json | grep -o '"unseal_keys_b64":\["[^"]*"' | cut -d'"' -f4)"
|
||||
|
||||
# Wait for Vault to start
|
||||
for i in {1..30}; do
|
||||
if curl -sfk --cacert botserver-stack/conf/system/certificates/ca/ca.crt \
|
||||
https://localhost:8200/v1/sys/health > /dev/null 2>&1; then
|
||||
echo "✅ Vault is running"
|
||||
break
|
||||
fi
|
||||
echo "⏳ Waiting for Vault... ($i/30)"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Unseal Vault
|
||||
echo "🔓 Unsealing..."
|
||||
curl -s --cacert botserver-stack/conf/system/certificates/ca/ca.crt \
|
||||
-X POST \
|
||||
-H "X-Vault-Token: hvs.JjKHlEzycO2jvKdhhlRAoODu" \
|
||||
-d "{\"key\": \"$UNSEAL_KEY\"}" \
|
||||
https://localhost:8200/v1/sys/unseal
|
||||
|
||||
echo "✅ Vault unsealed"
|
||||
5
vault-unseal-keys
Normal file
5
vault-unseal-keys
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Unseal Key 1: JDWcTlskyqgKO5dNghRZyVCrdvH9MsJsfmS/nQhpfUyl
|
||||
Unseal Key 2: UuCsxt0MdaKm0z9ki7oHdLxu7CW47yBnUSrQ2/RiafnT
|
||||
Unseal Key 3: 5g9WTB3Yg5iwEodnaFM8fUH7DzqGfKMO7Wj8rO6YuJdO
|
||||
Unseal Key 4: Y5UQzF1PjgeJZ7/3J6fyvTkrNM2W6+hXCyk/5iyOp+0e
|
||||
Unseal Key 5: f6lFx6B4+RJeKdz3B9r/YNKaTdolenU7PuixDwXMXeJ/
|
||||
Loading…
Add table
Reference in a new issue