Compare commits

..

1 commit

Author SHA1 Message Date
90baa2dae7
Update CODE_OF_CONDUCT-pt-br.md 2024-10-31 19:11:02 -03:00
614 changed files with 707107 additions and 138968 deletions

2
.deployment Normal file
View file

@ -0,0 +1,2 @@
[config]
command = bash ./deploy.sh

View file

@ -1,52 +0,0 @@
# BotServer Embedded Configuration
# For Orange Pi, Raspberry Pi, and other ARM SBCs
# Server
HOST=0.0.0.0
PORT=8088
RUST_LOG=info
# Database (SQLite for embedded, no PostgreSQL needed)
DATABASE_URL=sqlite:///opt/botserver/data/botserver.db
# LLM Configuration - Local llama.cpp
LLM_PROVIDER=llamacpp
LLM_API_URL=http://127.0.0.1:8080
LLM_MODEL=tinyllama
# Alternative: Use remote API
# LLM_PROVIDER=openai
# LLM_API_URL=https://api.openai.com/v1
# LLM_API_KEY=sk-...
# Alternative: Ollama (if installed)
# LLM_PROVIDER=ollama
# LLM_API_URL=http://127.0.0.1:11434
# LLM_MODEL=tinyllama
# Memory limits for embedded
MAX_CONTEXT_TOKENS=2048
MAX_RESPONSE_TOKENS=512
STREAMING_ENABLED=true
# Embedded UI
STATIC_FILES_PATH=/opt/botserver/ui
DEFAULT_UI=embedded
# WebSocket
WS_PING_INTERVAL=30
WS_TIMEOUT=300
# Security (change in production!)
JWT_SECRET=embedded-change-me-in-production
CORS_ORIGINS=*
# Logging
LOG_FILE=/opt/botserver/data/botserver.log
LOG_MAX_SIZE=10M
LOG_RETENTION=7
# Performance tuning for low-memory devices
# Uncomment for <2GB RAM devices
# RUST_BACKTRACE=0
# MALLOC_ARENA_MAX=2

View file

@ -1,36 +0,0 @@
# BotServer Environment Configuration
# =====================================
#
# ONLY VAULT VARIABLES ARE ALLOWED IN THIS FILE!
# All secrets (DATABASE_URL, API keys, etc.) MUST be stored in Vault.
# NO LEGACY FALLBACK - Vault is mandatory.
#
# Vault paths for secrets:
# - gbo/tables - PostgreSQL credentials (host, port, database, username, password)
# - gbo/drive - MinIO/S3 credentials (accesskey, secret)
# - gbo/cache - Redis credentials (password)
# - gbo/directory - Zitadel credentials (url, project_id, client_id, client_secret)
# - gbo/email - Email credentials (username, password)
# - gbo/llm - LLM API keys (openai_key, anthropic_key, groq_key)
# - gbo/encryption - Encryption keys (master_key)
# - gbo/meet - LiveKit credentials (api_key, api_secret)
# - gbo/alm - Forgejo credentials (url, admin_password, runner_token)
# - gbo/vectordb - Qdrant credentials (url, api_key)
# - gbo/observability - InfluxDB credentials (url, org, bucket, token)
# =====================
# VAULT CONFIGURATION - ONLY THESE VARS ARE ALLOWED
# =====================
# Vault server address
VAULT_ADDR=https://localhost:8200
# Vault authentication token (generated during vault init)
# This will be populated automatically after first bootstrap
VAULT_TOKEN=
# Skip TLS verification for development (set to false in production)
VAULT_SKIP_VERIFY=true
# Cache TTL for secrets in seconds (default: 300 = 5 minutes)
VAULT_CACHE_TTL=300

View file

@ -1,242 +0,0 @@
name: GBCI Bundle
on:
push:
branches: ["main"]
tags: ["v*"]
pull_request:
branches: ["main"]
workflow_dispatch:
env:
CARGO_HOME: /root/.cargo
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
jobs:
build-bundle:
if: false # Workflow disabled - keep file for reference
runs-on: gbo
steps:
- name: Disable SSL verification (temporary)
run: git config --global http.sslVerify false
- uses: actions/checkout@v4
- name: Clone dependencies
run: |
git clone --depth 1 https://github.com/GeneralBots/botlib.git ../botlib
git clone --depth 1 https://github.com/GeneralBots/botui.git ../botui
git clone --depth 1 https://github.com/GeneralBots/botbook.git ../botbook
git clone --depth 1 https://github.com/GeneralBots/botmodels.git ../botmodels
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-bundle-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-bundle-
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "/root/.cargo/bin" >> $GITHUB_PATH
/root/.cargo/bin/rustup target add x86_64-unknown-linux-gnu
/root/.cargo/bin/rustup target add aarch64-unknown-linux-gnu
/root/.cargo/bin/rustup target add x86_64-pc-windows-gnu
- name: Install cross-compilation dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
gcc-mingw-w64-x86-64 \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
zip
- name: Setup environment
run: sudo cp /opt/gbo/bin/system/.env .
# ============================================
# Download Python portable distributions
# ============================================
- name: Download Python portables
run: |
PYTHON_VERSION="3.12.7"
mkdir -p python-installers
# Linux x86_64 - python-build-standalone
curl -L -o python-installers/python-${PYTHON_VERSION}-linux-x86_64.tar.gz \
"https://github.com/indygreg/python-build-standalone/releases/download/20241016/cpython-${PYTHON_VERSION}+20241016-x86_64-unknown-linux-gnu-install_only.tar.gz"
# Linux ARM64 - python-build-standalone
curl -L -o python-installers/python-${PYTHON_VERSION}-linux-arm64.tar.gz \
"https://github.com/indygreg/python-build-standalone/releases/download/20241016/cpython-${PYTHON_VERSION}+20241016-aarch64-unknown-linux-gnu-install_only.tar.gz"
# Windows x86_64 - python-build-standalone
curl -L -o python-installers/python-${PYTHON_VERSION}-windows-x86_64.tar.gz \
"https://github.com/indygreg/python-build-standalone/releases/download/20241016/cpython-${PYTHON_VERSION}+20241016-x86_64-pc-windows-msvc-install_only.tar.gz"
# macOS x86_64 - python-build-standalone
curl -L -o python-installers/python-${PYTHON_VERSION}-macos-x86_64.tar.gz \
"https://github.com/indygreg/python-build-standalone/releases/download/20241016/cpython-${PYTHON_VERSION}+20241016-x86_64-apple-darwin-install_only.tar.gz"
# macOS ARM64 - python-build-standalone
curl -L -o python-installers/python-${PYTHON_VERSION}-macos-arm64.tar.gz \
"https://github.com/indygreg/python-build-standalone/releases/download/20241016/cpython-${PYTHON_VERSION}+20241016-aarch64-apple-darwin-install_only.tar.gz"
ls -la python-installers/
# ============================================
# Build botserver for all platforms
# ============================================
- name: Build botserver - Linux x86_64
run: /root/.cargo/bin/cargo build --release --locked --target x86_64-unknown-linux-gnu
- name: Build botserver - Linux ARM64
env:
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
run: /root/.cargo/bin/cargo build --release --locked --target aarch64-unknown-linux-gnu
- name: Build botserver - Windows x86_64
env:
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc
run: /root/.cargo/bin/cargo build --release --locked --target x86_64-pc-windows-gnu
# ============================================
# Build botui for all platforms
# ============================================
- name: Build botui - Linux x86_64
run: |
cd ../botui
/root/.cargo/bin/cargo build --release --locked --target x86_64-unknown-linux-gnu
- name: Build botui - Linux ARM64
env:
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
run: |
cd ../botui
/root/.cargo/bin/cargo build --release --locked --target aarch64-unknown-linux-gnu
- name: Build botui - Windows x86_64
env:
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc
run: |
cd ../botui
/root/.cargo/bin/cargo build --release --locked --target x86_64-pc-windows-gnu
# ============================================
# Build botbook documentation
# ============================================
- name: Install mdBook
run: |
if ! command -v mdbook &> /dev/null; then
/root/.cargo/bin/cargo install mdbook
fi
- name: Build botbook
run: |
cd ../botbook
mdbook build
# ============================================
# Create bundle directories
# Structure:
# botserver(.exe) <- root binary
# botserver-components/
# botui(.exe)
# botmodels/
# botbook/
# botserver-installers/
# python-<version>-<platform>.tar.gz
# postgresql, valkey, vault, minio, zitadel, llama, models...
# ============================================
- name: Create bundle structure
run: |
BUNDLE_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
PYTHON_VERSION="3.12.7"
# Linux x86_64 bundle
mkdir -p bundle/linux-x86_64/botserver-components
mkdir -p bundle/linux-x86_64/botserver-installers
cp ./target/x86_64-unknown-linux-gnu/release/botserver bundle/linux-x86_64/botserver || true
cp ../botui/target/x86_64-unknown-linux-gnu/release/botui bundle/linux-x86_64/botserver-components/ || true
cp python-installers/python-${PYTHON_VERSION}-linux-x86_64.tar.gz bundle/linux-x86_64/botserver-installers/
# Linux ARM64 bundle
mkdir -p bundle/linux-arm64/botserver-components
mkdir -p bundle/linux-arm64/botserver-installers
cp ./target/aarch64-unknown-linux-gnu/release/botserver bundle/linux-arm64/botserver || true
cp ../botui/target/aarch64-unknown-linux-gnu/release/botui bundle/linux-arm64/botserver-components/ || true
cp python-installers/python-${PYTHON_VERSION}-linux-arm64.tar.gz bundle/linux-arm64/botserver-installers/
# Windows x86_64 bundle
mkdir -p bundle/windows-x86_64/botserver-components
mkdir -p bundle/windows-x86_64/botserver-installers
cp ./target/x86_64-pc-windows-gnu/release/botserver.exe bundle/windows-x86_64/botserver.exe || true
cp ../botui/target/x86_64-pc-windows-gnu/release/botui.exe bundle/windows-x86_64/botserver-components/ || true
cp python-installers/python-${PYTHON_VERSION}-windows-x86_64.tar.gz bundle/windows-x86_64/botserver-installers/
# ============================================
# Copy shared components to all bundles
# ============================================
- name: Copy botmodels to bundles
run: |
for platform in linux-x86_64 linux-arm64 windows-x86_64; do
mkdir -p bundle/$platform/botserver-components/botmodels
cp -r ../botmodels/* bundle/$platform/botserver-components/botmodels/
done
- name: Copy botbook to bundles
run: |
for platform in linux-x86_64 linux-arm64 windows-x86_64; do
mkdir -p bundle/$platform/botserver-components/botbook
cp -r ../botbook/book/* bundle/$platform/botserver-components/botbook/
done
- name: Copy installers to bundles
run: |
for platform in linux-x86_64 linux-arm64 windows-x86_64; do
cp -r ./botserver-installers/* bundle/$platform/botserver-installers/
done
# ============================================
# Create ZIP archives
# ============================================
- name: Create release archives
run: |
BUNDLE_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
cd bundle
for platform in linux-x86_64 linux-arm64 windows-x86_64; do
if [ -f "$platform/botserver" ] || [ -f "$platform/botserver.exe" ]; then
zip -r "botserver-bundle-${BUNDLE_VERSION}-${platform}.zip" "$platform"
echo "Created: botserver-bundle-${BUNDLE_VERSION}-${platform}.zip"
fi
done
cd ..
# ============================================
# Deploy bundles
# ============================================
- name: Deploy bundle releases
run: |
BUNDLE_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
sudo mkdir -p /opt/gbo/releases/botserver-bundle
sudo cp bundle/*.zip /opt/gbo/releases/botserver-bundle/ || true
# Also keep unpacked bundles for direct access
sudo mkdir -p /opt/gbo/releases/botserver-bundle/unpacked
sudo cp -r bundle/linux-x86_64 /opt/gbo/releases/botserver-bundle/unpacked/ || true
sudo cp -r bundle/linux-arm64 /opt/gbo/releases/botserver-bundle/unpacked/ || true
sudo cp -r bundle/windows-x86_64 /opt/gbo/releases/botserver-bundle/unpacked/ || true
sudo chmod -R 755 /opt/gbo/releases/botserver-bundle/
echo "Bundle releases deployed to /opt/gbo/releases/botserver-bundle/"
ls -la /opt/gbo/releases/botserver-bundle/

View file

@ -1,71 +0,0 @@
name: GBCI
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
env:
CARGO_BUILD_JOBS: 1
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
jobs:
build:
runs-on: gbo
steps:
- name: Disable SSL verification
run: git config --global http.sslVerify false
- uses: actions/checkout@v4
- name: Clone botlib dependency
run: git clone --depth 1 https://github.com/GeneralBots/botlib.git ../botlib
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-debug-
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libpq-dev libssl-dev liblzma-dev pkg-config
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Setup environment
run: sudo cp /opt/gbo/bin/system/.env . 2>/dev/null || true
- name: Build debug
run: |
cargo build --locked -j 1 2>&1 | tee /tmp/build.log
ls -lh target/debug/botserver
- name: Save build log
if: always()
run: |
sudo mkdir -p /opt/gbo/logs
sudo cp /tmp/build.log /opt/gbo/logs/botserver-$(date +%Y%m%d-%H%M%S).log || true
- name: Deploy
run: |
sudo mkdir -p /opt/gbo/releases/botserver/linux
sudo cp target/debug/botserver /opt/gbo/releases/botserver/linux/botserver-x86_64
sudo chmod 755 /opt/gbo/releases/botserver/linux/botserver-x86_64
lxc exec bot:pragmatismo-system -- systemctl stop system || true
sudo cp target/debug/botserver /opt/gbo/bin/system/botserver
sudo chmod +x /opt/gbo/bin/system/botserver
lxc exec bot:pragmatismo-system -- systemctl start system || true

3
.gitattributes vendored Normal file
View file

@ -0,0 +1,3 @@
* text=auto
*.js eol=lf
*.ts eol=lf

9
.github/ISSUE_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,9 @@
<!-- File a GitHub issue only for bugs or feature requests related to the code **in this repository**. For other topics you can get more information in the README file. -->
### Observed Results:
<!-- This could be a description, error output, steps to reproduce, a feature missed, etc. -->
### Expected behavior:
<!-- What did you expect to happen? -->

35
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,35 @@
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

7
.github/ISSUE_TEMPLATE/custom.md vendored Normal file
View file

@ -0,0 +1,7 @@
---
name: Custom issue template
about: Describe this issue template's purpose here.
---

View file

@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

2
.github/ISSUE_TEMPLATE/requirement vendored Normal file
View file

@ -0,0 +1,2 @@
**Description**
A clear and concise description of what the requirement is.

16
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,16 @@
### Changes description
<!-- Describe results, user mentions, screenshots, screencast (gif) -->
### Checklist
Please check if your PR fulfills the following specifications:
- [ ] Tests for the changes have been done
- [ ] Docs have been added/updated
### References
<!-- issues related (for reference or to be closed) and/or links of discuss -->
Closes #N/A

3
.github/invite-contributors.yml vendored Normal file
View file

@ -0,0 +1,3 @@
isOutside: true
# Team Name
team: contributors

44
.github/settings.yml vendored Normal file
View file

@ -0,0 +1,44 @@
repository:
name: botserver
description: botserver
homepage: http://pragmatismo.cloud/general-bots
topics: node-module
private: false
has_issues: true
has_wiki: false
has_downloads: true
default_branch: develop
allow_squash_merge: true
allow_merge_commit: false
allow_rebase_merge: true
labels:
- name: bug
color: f44336
- name: build
color: 795548
- name: ci
color: fbca04
- name: documentation
color: 607d8b
- name: duplicate
color: 9e9e9e
- name: feature
color: 3f51b5
- name: invalid
color: cddc39
- name: performance
color: 009688
- name: question
color: ff5722
- name: refactor
color: 9c27b0
- name: style
color: 2196f3
- name: test
color: 8bc34a
- name: wontfix
color: ffffff
- name: help wanted
color: 33aa3f
- name: good first issue
color: 7057ff

45
.gitignore vendored
View file

@ -1,16 +1,33 @@
.tmp*
.tmp/*
*.log
target*
/.coveralls.yml
/.env
/.npmrc
/.nyc_output
/coverage
/dist
/docs
/guaribas.log
/guaribas.sqlite
/node_modules
/packages/default.gbui/build
/packages/default.gbui/.env
/packages/default.gbui/node_modules
/packages/default.gbui/package-lock.json
/packages/default.gbui/yarn-lock.json
/work
*.vbs.compiled
*.vbs.js
*.vbs.ts
.env
*.env
work
*.out
bin
botserver-stack
*logfile*
*-log*
docs/book
*.rdb
botserver-installers/*
!botserver-installers/.gitkeep
.vscode/launch.json
.wwebjs_auth
GB.log
gb.log
GB.log.json
yarn-error.log
package-lock.json
yarn-lock.json
logo.svg
screenshot.png
data.db
.wwebjs_cache

9
.hintrc Normal file
View file

@ -0,0 +1,9 @@
{
"extends": [
"development"
],
"hints": {
"typescript-config/strict": "off",
"typescript-config/consistent-casing": "off"
}
}

15
.npmignore Normal file
View file

@ -0,0 +1,15 @@
# This file must be a copy of .gitignore except for the WILLSHIP commented lines below.
/.coveralls.yml
/.env
/.npmrc
# WILLSHIP /.nyc_output
/coverage
# WILLSHIP /dist
/guaribas.log
/guaribas.sqlite
/node_modules
# WILLSHIP /packages/default.gbui/build
/packages/default.gbui/.env
/packages/default.gbui/node_modules
/tmp
/work

8
.prettierrc Normal file
View file

@ -0,0 +1,8 @@
{
"trailingComma": "none",
"tabWidth": 2,
"printWidth": 120,
"arrowParens": "avoid",
"semi": true,
"singleQuote": true
}

47
.test-init.ts Normal file
View file

@ -0,0 +1,47 @@
import { expect, test } from 'vitest';
import { GBServer } from './src/app';
import { RootData } from './src/RootData';
import { GBMinInstance } from 'botlib';
import { Mutex } from 'async-mutex';
export default function init() {
const min = {
packages: null,
appPackages: null,
botId: 'gbtest',
instance: {botId: 'gbtest'},
core: {},
conversationalService: {},
kbService: {},
adminService: {},
deployService: {},
textServices: {},
bot: {},
dialogs: {},
userState: {},
userProfile: {},
whatsAppDirectLine: {},
cbMap: {},
scriptMap: {},
sandBoxMap: {},
gbappServices: {}
}
GBServer.globals = new RootData();
GBServer.globals.server = null;
GBServer.globals.httpsServer = null;
GBServer.globals.webSessions = {};
GBServer.globals.processes = [0, { pid: 1, proc: {step: {}}}];
GBServer.globals.files = {};
GBServer.globals.appPackages = [];
GBServer.globals.sysPackages = [];
GBServer.globals.minInstances = [min];
GBServer.globals.minBoot = min;
GBServer.globals.wwwroot = null;
GBServer.globals.entryPointDialog = null;
GBServer.globals.debuggers = [];
GBServer.globals.indexSemaphore = new Mutex();
GBServer.globals.users = {1: {userId: 1}};
}

33
.travis.yml Normal file
View file

@ -0,0 +1,33 @@
dist: focal
language: node_js
node_js:
- 19.7.0
notifications:
email: false
before_script:
- npm run build
branches:
only:
- main
- /^greenkeeper/.*$/
except:
- /^v\d+\.\d+\.\d+$/
after_success:
- npm install -g travis-deploy-once
- npm run travis-deploy-once "npm run semantic-release"
- npm pack
deploy:
- provider: pages
skip_cleanup: true
local_dir: docs/reference
github_token: $GITHUB_TOKEN
on:
tags: false
branch: main

53
.vscode/launch.json vendored
View file

@ -1,41 +1,30 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"type": "node",
"request": "launch",
"name": "Debug executable 'botserver'",
"cargo": {
"args": ["build", "--bin=botserver", "--package=botserver"],
"filter": {
"name": "botserver",
"kind": "bin"
}
},
"args": ["--desktop"],
"sourceMaps": true,
"name": "Debug Program",
"runtimeExecutable": "node",
"program": "${workspaceRoot}/boot.mjs",
"cwd": "${workspaceRoot}",
"env": {
"RUST_LOG": "trace,aws_sigv4=off,aws_smithy_checksums=off,mio=off,reqwest=off,aws_runtime=off,aws_smithy_http_client=off,rustls=off,hyper_util=off,aws_smithy_runtime=off,aws_smithy_runtime_api=off,tracing=off,aws_sdk_s3=off"
"NODE_ENV": "development",
"NODE_NO_WARNINGS": "1"
},
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'botserver'",
"cargo": {
"args": ["test", "--no-run", "--bin=botserver", "--package=botserver"],
"filter": {
"name": "botserver",
"kind": "bin"
}
},
"args": [],
"env": {
"RUST_LOG": "trace"
},
"cwd": "${workspaceFolder}"
"args": [
"--require", "${workspaceRoot}/suppress-node-warnings.cjs"
],
"skipFiles": [
"node_modules/**/*.js",
"<node_internals>/**"
],
"outFiles": [
"${workspaceRoot}/dist/**/*.js"
],
"stopOnEntry": false,
"console": "integratedTerminal"
}
]
}
}

4
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"git.ignoreLimitWarning": true,
"cmake.ignoreCMakeListsMissing": true
}

30
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,30 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"problemMatcher": [
"$tsc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

View file

@ -1,16 +0,0 @@
[
{
"label": "Debug BotServer",
"build": {
"command": "rm -rf .env ./botserver-stack && cargo",
"args": ["build"]
},
"program": "$ZED_WORKTREE_ROOT/target/debug/botserver",
"env": {
"RUST_LOG": "trace"
},
"sourceLanguages": ["rust"],
"request": "launch",
"adapter": "CodeLLDB"
}
]

View file

@ -1,224 +0,0 @@
# Third-Party Dependencies Configuration
# ======================================
# This file lists all external downloads required by botserver.
#
# Caching Behavior:
# - On first run, files are downloaded from the URLs below
# - Downloaded files are cached in ./botserver-installers/
# - On subsequent runs, cached files are used instead of downloading
# - To force re-download, delete the cached file
#
# Offline Installation:
# - Pre-download all files to ./botserver-installers/
# - The installer will use cached files automatically
# - You can safely delete ./botserver-stack/ without losing downloads
[cache_settings]
# Directory where downloaded files are cached (relative to botserver root)
cache_dir = "botserver-installers"
# Components
# ==========
# Each component has:
# - url: Download URL
# - filename: Local filename in cache
# - sha256: Optional checksum for verification (empty = skip verification)
[components.drive]
name = "MinIO Object Storage"
url = "https://dl.min.io/server/minio/release/linux-amd64/minio"
filename = "minio"
sha256 = ""
[components.tables]
name = "PostgreSQL Database"
url = "https://github.com/theseus-rs/postgresql-binaries/releases/download/17.2.0/postgresql-17.2.0-x86_64-unknown-linux-gnu.tar.gz"
filename = "postgresql-17.2.0-x86_64-unknown-linux-gnu.tar.gz"
sha256 = ""
[components.cache]
name = "Valkey Cache (Redis-compatible)"
# Valkey requires compilation from source - no prebuilt binaries available
# The installer will run 'make' to build valkey-server and valkey-cli
# Requires: gcc, make (usually available on most Linux systems)
url = "https://github.com/valkey-io/valkey/archive/refs/tags/8.0.2.tar.gz"
filename = "valkey-8.0.2.tar.gz"
sha256 = ""
[components.llm]
name = "Llama.cpp Server"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-ubuntu-x64.zip"
filename = "llama-b7345-bin-ubuntu-x64.zip"
sha256 = "91b066ecc53c20693a2d39703c12bc7a69c804b0768fee064d47df702f616e52"
[components.email]
name = "Stalwart Mail Server"
url = "https://github.com/stalwartlabs/mail-server/releases/download/v0.10.7/stalwart-mail-x86_64-linux.tar.gz"
filename = "stalwart-mail-x86_64-linux.tar.gz"
sha256 = ""
[components.proxy]
name = "Caddy Web Server"
url = "https://github.com/caddyserver/caddy/releases/download/v2.9.1/caddy_2.9.1_linux_amd64.tar.gz"
filename = "caddy_2.9.1_linux_amd64.tar.gz"
sha256 = ""
[components.directory]
name = "Zitadel Identity Provider"
url = "https://github.com/zitadel/zitadel/releases/download/v2.70.4/zitadel-linux-amd64.tar.gz"
filename = "zitadel-linux-amd64.tar.gz"
sha256 = ""
[components.alm]
name = "Forgejo Git Server"
url = "https://codeberg.org/forgejo/forgejo/releases/download/v10.0.2/forgejo-10.0.2-linux-amd64"
filename = "forgejo-10.0.2-linux-amd64"
sha256 = ""
[components.alm_ci]
name = "Forgejo Actions Runner"
url = "https://code.forgejo.org/forgejo/runner/releases/download/v6.3.1/forgejo-runner-6.3.1-linux-amd64"
filename = "forgejo-runner-6.3.1-linux-amd64"
sha256 = ""
[components.dns]
name = "CoreDNS Server"
url = "https://github.com/coredns/coredns/releases/download/v1.11.1/coredns_1.11.1_linux_amd64.tgz"
filename = "coredns_1.11.1_linux_amd64.tgz"
sha256 = ""
[components.webmail]
name = "Roundcube Webmail"
url = "https://github.com/roundcube/roundcubemail/releases/download/1.6.6/roundcubemail-1.6.6-complete.tar.gz"
filename = "roundcubemail-1.6.6-complete.tar.gz"
sha256 = ""
[components.meet]
name = "LiveKit Media Server"
url = "https://github.com/livekit/livekit/releases/download/v2.8.2/livekit_2.8.2_linux_amd64.tar.gz"
filename = "livekit_2.8.2_linux_amd64.tar.gz"
sha256 = ""
[components.table_editor]
name = "NocoDB"
url = "http://get.nocodb.com/linux-x64"
filename = "nocodb-linux-x64"
sha256 = ""
[components.vector_db]
name = "Qdrant Vector Database"
url = "https://github.com/qdrant/qdrant/releases/latest/download/qdrant-x86_64-unknown-linux-gnu.tar.gz"
filename = "qdrant-x86_64-unknown-linux-gnu.tar.gz"
sha256 = ""
[components.timeseries_db]
name = "InfluxDB Time Series Database"
url = "https://download.influxdata.com/influxdb/releases/influxdb2-2.7.5-linux-amd64.tar.gz"
filename = "influxdb2-2.7.5-linux-amd64.tar.gz"
sha256 = ""
[components.vault]
name = "HashiCorp Vault"
url = "https://releases.hashicorp.com/vault/1.15.4/vault_1.15.4_linux_amd64.zip"
filename = "vault_1.15.4_linux_amd64.zip"
sha256 = ""
[components.observability]
name = "Vector Log Aggregator"
url = "https://packages.timber.io/vector/0.35.0/vector-0.35.0-x86_64-unknown-linux-gnu.tar.gz"
filename = "vector-0.35.0-x86_64-unknown-linux-gnu.tar.gz"
sha256 = ""
# LLM Models
# ==========
# Large model files for AI/ML functionality
[models.deepseek_small]
name = "DeepSeek R1 Distill Qwen 1.5B (Q3_K_M)"
url = "https://huggingface.co/bartowski/DeepSeek-R1-Distill-Qwen-1.5B-GGUF/resolve/main/DeepSeek-R1-Distill-Qwen-1.5B-Q3_K_M.gguf"
filename = "DeepSeek-R1-Distill-Qwen-1.5B-Q3_K_M.gguf"
sha256 = ""
[models.bge_embedding]
name = "BGE Small EN v1.5 Embedding Model"
url = "https://huggingface.co/CompendiumLabs/bge-small-en-v1.5-gguf/resolve/main/bge-small-en-v1.5-f32.gguf"
filename = "bge-small-en-v1.5-f32.gguf"
sha256 = ""
# Platform-specific llama.cpp variants
# =====================================
# These are alternative builds for different platforms/GPU support
[components.llm_linux_vulkan]
name = "Llama.cpp Server (Linux Vulkan)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-ubuntu-vulkan-x64.zip"
filename = "llama-b7345-bin-ubuntu-vulkan-x64.zip"
sha256 = "03f0b3acbead2ddc23267073a8f8e0207937c849d3704c46c61cf167c1001442"
[components.llm_linux_s390x]
name = "Llama.cpp Server (Linux s390x)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-ubuntu-s390x.zip"
filename = "llama-b7345-bin-ubuntu-s390x.zip"
sha256 = "688ddad6996b1166eaaa76d5025e304c684116efe655e6e881d877505ecffccb"
[components.llm_macos_arm64]
name = "Llama.cpp Server (macOS ARM64)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-macos-arm64.zip"
filename = "llama-b7345-bin-macos-arm64.zip"
sha256 = "72ae9b4a4605aa1223d7aabaa5326c66c268b12d13a449fcc06f61099cd02a52"
[components.llm_macos_x64]
name = "Llama.cpp Server (macOS x64)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-macos-x64.zip"
filename = "llama-b7345-bin-macos-x64.zip"
sha256 = "bec6b805cf7533f66b38f29305429f521dcb2be6b25dbce73a18df448ec55cc5"
[components.llm_win_cpu_x64]
name = "Llama.cpp Server (Windows x64 CPU)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-win-cpu-x64.zip"
filename = "llama-b7345-bin-win-cpu-x64.zip"
sha256 = "ea449082c8e808a289d9a1e8331f90a0379ead4dd288a1b9a2d2c0a7151836cd"
[components.llm_win_cpu_arm64]
name = "Llama.cpp Server (Windows ARM64 CPU)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-win-cpu-arm64.zip"
filename = "llama-b7345-bin-win-cpu-arm64.zip"
sha256 = "91e3ff43c123c7c30decfe5a44c291827c1e47359abaa2fbad1eb5392b3a0d85"
[components.llm_win_cuda12]
name = "Llama.cpp Server (Windows CUDA 12.4)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-win-cuda-12.4-x64.zip"
filename = "llama-b7345-bin-win-cuda-12.4-x64.zip"
sha256 = "7a82aba2662fa7d4477a7a40894de002854bae1ab8b0039888577c9a2ca24cae"
[components.llm_win_cuda13]
name = "Llama.cpp Server (Windows CUDA 13.1)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-win-cuda-13.1-x64.zip"
filename = "llama-b7345-bin-win-cuda-13.1-x64.zip"
sha256 = "06ea715cefb07e9862394e6d1ffa066f4c33add536b1f1aa058723f86ae05572"
[components.llm_win_vulkan]
name = "Llama.cpp Server (Windows Vulkan)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/llama-b7345-bin-win-vulkan-x64.zip"
filename = "llama-b7345-bin-win-vulkan-x64.zip"
sha256 = "3e948bee438f46c8ea0a3faf0416549391ee945ffa624b25bc1f73d60d668679"
# CUDA runtime libraries (required for CUDA builds on Windows)
[components.cudart_win_cuda12]
name = "CUDA Runtime (Windows CUDA 12.4)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/cudart-llama-bin-win-cuda-12.4-x64.zip"
filename = "cudart-llama-bin-win-cuda-12.4-x64.zip"
sha256 = "8c79a9b226de4b3cacfd1f83d24f962d0773be79f1e7b75c6af4ded7e32ae1d6"
[components.cudart_win_cuda13]
name = "CUDA Runtime (Windows CUDA 13.1)"
url = "https://github.com/ggml-org/llama.cpp/releases/download/b7345/cudart-llama-bin-win-cuda-13.1-x64.zip"
filename = "cudart-llama-bin-win-cuda-13.1-x64.zip"
sha256 = "f96935e7e385e3b2d0189239077c10fe8fd7e95690fea4afec455b1b6c7e3f18"
# Optional larger models (uncomment to include)
# [models.gpt_oss_20b]
# name = "GPT-OSS 20B F16 (requires 16GB+ VRAM)"
# url = "https://huggingface.co/unsloth/gpt-oss-20b-GGUF/resolve/main/gpt-oss-20b-F16.gguf"
# filename = "gpt-oss-20b-F16.gguf"
# sha256 = ""

2492
CHANGELOG.md Normal file

File diff suppressed because it is too large Load diff

48
CODE_OF_CONDUCT-pt-br.md Normal file
View file

@ -0,0 +1,48 @@
# Código de Conduta do Convênio do Colaborador
## Nosso Compromisso
No interesse de promover um ambiente aberto e acolhedor, nós, como colaboradores e mantenedores, nos comprometemos a tornar a participação em nosso projeto e em nossa comunidade uma experiência livre de assédio para todos, independentemente de idade, raça, etnia, origem nacional, ascendência, sexo, sexo identidade ou apresentação, orientação sexual, aparência física, afiliação religiosa, credo, estado civil ou familiar, não tolerará abuso ou assédio discriminatório ou sexual contra qualquer pessoa durante quaisquer atividades relacionadas à conferência, incluindo, entre outros, envio, revisão, tutoriais, oficinas ou eventos sociais. O abuso inclui qualquer ação dirigida a um indivíduo que (a) interfira substancialmente na participação dessa pessoa ou (b) faça com que essa pessoa tema por sua segurança pessoal. Isso inclui ameaças, intimidação, intimidação, perseguição ou outros tipos de abuso. Assédio discriminatório inclui qualquer conduta que discrimine ou denigra um indivíduo com base em idade, raça, etnia, nacionalidade, ascendência, gênero, identidade ou apresentação de gênero, orientação sexual, aparência física, afiliação religiosa, credo, estado civil ou familiar, deficiência , características pessoais ou quaisquer outros fatores diferenciadores, bem como qualquer outra característica protegida por lei no local onde ocorre a atividade da conferência. Assédio sexual inclui (mas não se limita a) investidas sexuais indesejadas repetidas, pedidos de favores sexuais ou outra conduta verbal ou física de natureza sexual, deficiência, características pessoais ou quaisquer outros fatores de diferenciação, bem como qualquer outra característica protegida por lei no local onde a atividade ocorre.
## Nossos Padrões
Exemplos de comportamento que contribuem para criar um ambiente positivo incluem:
* Usando linguagem padrão (sem expressões idiomáticas), acolhedora e inclusiva
* Ser respeitoso com os diferentes pontos de vista e experiências
* Aceitar graciosamente críticas construtivas
* Focar no que é melhor para a comunidade
* Mostrar empatia para com outros membros da comunidade
* Escrever trechos gerais de código para que possam ser amplamente utilizados.
Exemplos de comportamento inaceitável por parte dos participantes incluem:
* O uso de linguagem ou imagens sexualizadas e atenção ou avanços sexuais indesejados
* Trolling, comentários insultuosos/depreciativos e ataques pessoais ou políticos
* Assédio (harassment) público ou privado / perseguição (stalking) / intimidação (bullying) / mobbing (group bullying or gang stalking)
* Publicar informações privadas de outras pessoas, como endereço físico ou eletrônico, sem permissão explícita
* Outra conduta que possa ser razoavelmente considerada inadequada em um ambiente profissional
* Chamar uma pessoa de nome diferente do declarado pela pessoa
## Nossas responsabilidades
Os mantenedores do projeto são responsáveis por elucidar os padrões de comportamento aceitável e devem tomar ações corretivas apropriadas e justas em resposta a quaisquer instâncias de comportamento inaceitável.
Os mantenedores do projeto têm o direito e a responsabilidade de remover, editar ou rejeitar comentários, confirmações, códigos, edições wiki, problemas e outras contribuições que não estejam alinhadas com este Código de Conduta, ou banir temporária ou permanentemente qualquer colaborador por outros comportamentos que eles considerem inapropriado, ameaçador, ofensivo ou prejudicial.
## Escopo
Este Código de Conduta se aplica tanto em espaços do projeto quanto em espaços públicos quando um indivíduo representa o projeto ou sua comunidade. Exemplos de representação de um projeto ou comunidade incluem o uso de um endereço de e-mail oficial do projeto, postagem por meio de uma conta de mídia social oficial ou atuação como um representante nomeado em um evento online ou offline. A representação de um projeto pode ser posteriormente definida e esclarecida pelos mantenedores do projeto.
## Aplicação
Instâncias de comportamento abusivo, de assédio ou inaceitável podem ser relatadas entrando em contato com a equipe de segurança da Pragmatismo em c. A equipe do projeto analisará e investigará todas as reclamações e responderá da maneira que julgar apropriada às circunstâncias. A equipe do projeto é obrigada a manter a confidencialidade em relação ao relator de um incidente. Mais detalhes sobre políticas de execução específicas podem ser publicados separadamente.
Os mantenedores do projeto que não seguirem ou aplicarem o Código de Conduta de boa fé podem enfrentar repercussões temporárias ou permanentes conforme determinado por outros membros da liderança do projeto.
## Atribuição
Este Código de Conduta foi adaptado do [Acordo do Colaborador][homepage], versão 1.4, disponível em [http://contributor-covenant.org/version/1/4][version] e Código de Conduta ICAPS.
[página inicial]: http://contributor-covenant.org
[versão]: http://contributor-covenant.org/version/1/4/

49
CODE_OF_CONDUCT.md Normal file
View file

@ -0,0 +1,49 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, race, ethnicity, national origin, ancestry, gender, gender identity or presentation, sexual orientation, physical appearance, religious affiliation, creed, marital or familial status, will not tolerate abuse or discriminatory or sexual harassment toward any person during any conference-related activities, including but not limited to submission, reviewing, tutorials, workshops, or social events. Abuse includes any action directed at an individual that (a) interferes substantially with that persons participation or (b) causes that person to fear for their personal safety. This includes threats, intimidation, bullying, stalking, or other types of abuse. Discriminatory harassment includes any conduct that discriminates or denigrates an individual on the basis of age, race, ethnicity, national origin, ancestry, gender, gender identity or presentation, sexual orientation, physical appearance, religious affiliation, creed, marital or familial status, disability, personal characteristics, or any other differentiating factors, as well as any other characteristic protected by law in the location where conference activity takes place. Sexual harassment includes (but is not limited to) repeated unwelcome sexual advances, requests for sexual favors, or other verbal or physical conduct of a sexual nature, disability, personal characteristics, or any other differentiating factors, as well as any other characteristic protected by law in the location where activity takes place.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using standard(no idiomatic expressions), welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
* Writing general pieces of code so it can be widely used.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment / stalking / bullying / mobbing (group bullying or gang stalking)
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
* Call a person other name than that declared by the person
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Pragmatismo security team at c. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] and ICAPS Code of Conduct.
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

84
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,84 @@
# Instructions for Logging Issues
## 1. Search for Duplicates
[Search the existing issues](https://github.com/pragmatismo-io/BotServer/issues) before logging a new one.
## 2. Do you have a question?
Please use the issue tracker for bugs and suggestions.
If you have a *question*, please use [Stack Overflow](https://stackoverflow.com/questions/tagged/botserver)
## 3. Did you find a bug?
We are not surprised, we're still in early preview so there are plenty of them right now.
When logging a bug, please be sure to include the following:
* The platform you were using
* If at all possible, an *isolated* way to reproduce the behavior
* The behavior you expect to see, and the actual behavior
## 4. Do you have a suggestion?
We also accept suggestions in the issue tracker.
In general, things we find useful when reviewing suggestions are:
* A description of the problem you're trying to solve
* An overview of the suggested solution
* Examples of how the suggestion would work in various places
# Instructions for Contributing Code
## Contributing bug fixes
General Bots is current in early preview. We're still accepting contributions in the form of bug fixes.
A bug must have an issue tracking it in the issue tracker that has been approved by the pragmatismo.cloud team. Your pull request should include a link to the bug that you are fixing. If you've submitted a PR for a bug, please post a comment in the bug to avoid duplication of effort.
## Contributing features
Please open an issue with the `Schema` label to get a discussion started.
## Legal
We appreciate community contributions to code repositories open sourced by pragmatismo.cloud. By signing a contributor license agreement, we ensure that the community is free to use your contributions.
## Housekeeping
Your pull request should:
* Include a description of what your change intends to do
* Be a child commit of a reasonably recent commit in the **master** branch
* Requests need not be a single commit, but should be a linear sequence of commits (i.e. no merge commits in your PR)
* Have clear commit messages
* e.g. "Refactor feature", "Fix issue", "Add tests for issue"
## You need to be able to run your system
from: http://catern.com/run.html
When developing a system, it is important to be able to run the system in its entirety.
"Run the unit tests" doesn't count. The complexity of your system is in the interactions between the units.
"Run an individual service against mocks" doesn't count. A mock will rarely behave identically to the real dependency, and the behavior of the individual service will be unrealistic. You need to run the actual system.
"Run an individual service in a shared stateful development environment running all the other services" doesn't count. A shared development environment will be unreliable as it diverges more and more from the real system.
"Run most services in a mostly-isolated development environment, calling out to a few hard-to-run external services" doesn't count. Those few external services on the edge of the mostly-isolated development environment are often the most crucial ones; without the ability to run modified versions of them, your development process is crippled. Furthermore, being dependent on external services greatly complicates where and how you can run the system; it's much harder to, for example, run tests with the system on every commit if that will access external services.
"Run all the services that make up the system in an isolated development environment" counts; it's the bare minimum requirement. Bonus points if this can be done completely on localhost, without using an off-host cluster deployment system.
Without the ability to actually run the entire system in this way while developing, many evil practices will tend to become common.
Testing is harder and far less representative, and therefore many issues can only be found when changes are deployed to production.
In turn, production deployment will cause issues more often, and so deployment will be more slow and less frequent.
Deploying the system to new environments is more difficult, since the developers aren't able to actually run the system. Existing practices in production will be cargo-culted and copied around indefinitely, even when they are unnecessary or actively harmful.
Exploratory usage of the system is very difficult, so it will be harder to consider using the system for purposes outside what it was originally developed for, and new use cases will become rare.
Downstream clients who depend on the system will also suffer all these issues, since without the ability to run the upstream system in development, they can't run their own entire system, which is a superset of the upstream system.
Running the entire system during development is the first step to preventing these issues. Further steps include writing automated tests for the system (which can be run repeatedly during development), and using, as much as possible, the same code to run the system in development and in production.
Developers of large or legacy systems that cannot already be run in their entirety during development often believe that it is impractical to run the entire system during development. They'll talk about the many dependencies of their system, how it requires careful configuration of a large number of hosts, or how it's too complex to get reliable behavior.
In my experience, they're always wrong. These systems can be run locally during development with a relatively small investment of effort. Typically, these systems are just ultimately not as complicated as people think they are; once the system's dependencies are actually known and understood rather than being cargo-culted or assumed, running the system, and all its dependencies, is straightforward.
Being able to run your entire system during development is just about the most basic requirement for a software project. It's not, on its own, sufficient for your development practices to be high quality; but if you can't do this, then you're not even in the running.

8200
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,287 +0,0 @@
[package]
name = "botserver"
version = "6.1.0"
edition = "2021"
keywords = ["chatbot", "ai", "llm", "automation", "bot-framework"]
categories = ["web-programming", "api-bindings", "development-tools"]
authors = [
"Pragmatismo.com.br ",
"General Bots Community ",
"Alan Perdomo",
"Ana Paula Gil",
"Arenas.io",
"Atylla L",
"Christopher de Castilho",
"Dario Junior",
"David Lerner",
"Experimentation Garage",
"Flavio Andrade",
"Heraldo Almeida",
"Joao Parana",
"Jonathas C",
"J Ramos",
"Lucas Picanco",
"Marcos Velasco",
"Matheus 39x",
"Oerlabs Henrique",
"Othon Lima",
"PH Nascimento",
"Phpussente",
"Robson Dantas",
"Rodrigo Rodriguez ",
"Sarah Lourenco",
"Thi Patriota",
"Webgus",
"Zuilho Se",
]
description = "General Bots Server - Open-source bot platform by Pragmatismo.com.br"
license = "AGPL-3.0"
repository = "https://github.com/GeneralBots/BotServer"
[dependencies.botlib]
path = "../botlib"
features = ["database"]
[features]
# ===== DEFAULT FEATURE SET =====
default = ["console", "chat", "automation", "tasks", "drive", "llm", "cache", "progress-bars", "directory"]
# ===== UI FEATURES =====
console = ["dep:crossterm", "dep:ratatui", "monitoring"]
# ===== CORE INTEGRATIONS =====
vectordb = ["dep:qdrant-client"]
llm = []
nvidia = []
# ===== COMMUNICATION CHANNELS =====
email = ["dep:imap", "dep:lettre", "dep:mailparse", "dep:native-tls"]
whatsapp = []
instagram = []
msteams = []
# ===== PRODUCTIVITY FEATURES =====
chat = []
drive = ["dep:aws-config", "dep:aws-sdk-s3", "dep:pdf-extract", "dep:zip", "dep:downloader", "dep:mime_guess", "dep:flate2", "dep:tar"]
tasks = ["dep:cron"]
calendar = []
meet = ["dep:livekit"]
mail = ["email"]
# ===== ENTERPRISE FEATURES =====
compliance = ["dep:csv"]
attendance = []
directory = []
weba = []
timeseries = []
# ===== OPTIONAL INFRASTRUCTURE =====
cache = ["dep:redis"]
monitoring = ["dep:sysinfo"]
automation = ["dep:rhai"]
grpc = ["dep:tonic"]
progress-bars = ["dep:indicatif"]
# ===== META FEATURES (BUNDLES) =====
full = [
"console",
"vectordb", "llm", "nvidia", "timeseries",
"email", "whatsapp", "instagram", "msteams",
"chat", "drive", "tasks", "calendar", "meet", "mail",
"compliance", "attendance", "directory", "weba",
"cache", "monitoring", "automation", "grpc", "progress-bars"
]
communications = ["email", "whatsapp", "instagram", "msteams", "chat", "cache"]
productivity = ["chat", "drive", "tasks", "calendar", "meet", "mail", "cache"]
enterprise = ["compliance", "attendance", "directory", "llm", "vectordb", "monitoring", "timeseries"]
minimal = ["chat"]
lightweight = ["chat", "drive", "tasks"]
[dependencies]
# === CORE RUNTIME (Always Required) ===
aes-gcm = "0.10"
anyhow = "1.0"
argon2 = "0.5"
async-lock = "2.8.0"
async-stream = "0.3"
async-trait = "0.1"
axum = { version = "0.7.5", features = ["ws", "multipart", "macros"] }
axum-server = { version = "0.7", features = ["tls-rustls"] }
base64 = "0.22"
bytes = "1.8"
chrono = { version = "0.4", features = ["serde"] }
color-eyre = "0.6.5"
diesel = { version = "2.1", features = ["postgres", "uuid", "chrono", "serde_json", "r2d2"] }
diesel_migrations = "2.1.0"
dotenvy = "0.15"
env_logger = "0.11"
futures = "0.3"
futures-util = "0.3"
hex = "0.4"
hmac = "0.12.1"
hyper = { version = "0.14", features = ["full"] }
hyper-rustls = { version = "0.24", features = ["http2"] }
log = "0.4"
num-format = "0.4"
once_cell = "1.18.0"
rand = "0.9.2"
regex = "1.11"
reqwest = { version = "0.12", features = ["json", "stream", "multipart", "rustls-tls", "rustls-tls-native-roots"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
toml = "0.8"
sha2 = "0.10.9"
tokio = { version = "1.41", features = ["full"] }
tokio-stream = "0.1"
tower = "0.4"
tower-http = { version = "0.5", features = ["cors", "fs", "trace"] }
tracing = "0.1"
askama = "0.12"
askama_axum = "0.4"
tracing-subscriber = { version = "0.3", features = ["fmt"] }
urlencoding = "2.1"
uuid = { version = "1.11", features = ["serde", "v4"] }
# === TLS/SECURITY DEPENDENCIES ===
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] }
rustls-pemfile = "2.0"
tokio-rustls = "0.26"
rcgen = { version = "0.14", features = ["pem"] }
x509-parser = "0.15"
rustls-native-certs = "0.6"
webpki-roots = "0.25"
ring = "0.17"
time = { version = "0.3", features = ["formatting", "parsing"] }
jsonwebtoken = "9.3"
tower-cookies = "0.10"
# === FEATURE-SPECIFIC DEPENDENCIES (Optional) ===
# Email Integration (email feature)
imap = { version = "3.0.0-alpha.15", optional = true }
lettre = { version = "0.11", features = ["smtp-transport", "builder", "tokio1", "tokio1-native-tls"], optional = true }
mailparse = { version = "0.15", optional = true }
native-tls = { version = "0.2", optional = true }
# Video Meetings (meet feature)
livekit = { version = "0.7", optional = true }
# Vector Database (vectordb feature)
qdrant-client = { version = "1.12", optional = true }
# File Storage & Drive (drive feature)
aws-config = { version = "1.8.8", optional = true }
aws-sdk-s3 = { version = "1.109.0", features = ["behavior-version-latest"], optional = true }
pdf-extract = { version = "0.10.0", optional = true }
zip = { version = "2.2", optional = true }
downloader = { version = "0.2", optional = true }
mime_guess = { version = "2.0", optional = true }
flate2 = { version = "1.0", optional = true }
tar = { version = "0.4", optional = true }
# Task Management (tasks feature)
cron = { version = "0.15.0", optional = true }
# Automation & Scripting (automation feature)
rhai = { git = "https://github.com/therealprof/rhai.git", branch = "features/use-web-time", features = ["sync"], optional = true }
# Compliance & Reporting (compliance feature)
csv = { version = "1.3", optional = true }
# Console/TUI (console feature)
crossterm = { version = "0.29.0", optional = true }
ratatui = { version = "0.30.0-beta.0", optional = true }
# QR Code Generation (using png directly to avoid image's ravif/paste dependency)
png = "0.18"
qrcode = { version = "0.14", default-features = false }
# Excel/Spreadsheet Support
calamine = "0.26"
rust_xlsxwriter = "0.79"
# Error handling
thiserror = "2.0"
# Caching/Sessions (cache feature)
redis = { version = "0.27", features = ["tokio-comp"], optional = true }
# System Monitoring (monitoring feature)
sysinfo = { version = "0.37.2", optional = true }
# Networking/gRPC (grpc feature)
tonic = { version = "0.14.2", features = ["transport"], optional = true }
# UI Enhancement (progress-bars feature)
indicatif = { version = "0.18.0", optional = true }
smartstring = "1.0.1"
scopeguard = "1.2.0"
# Vault secrets management
vaultrs = "0.7"
# Calendar standards (RFC 5545)
icalendar = "0.17"
# Layered configuration
figment = { version = "0.10", features = ["toml", "env", "json"] }
# Rate limiting
governor = "0.10"
# RSS feed parsing
rss = "2.0"
# HTML parsing/web scraping
scraper = "0.25"
[dev-dependencies]
mockito = "1.7.0"
tempfile = "3"
# === SECURITY AND CODE QUALITY CONFIGURATION ===
[lints.rust]
unused_imports = "warn"
unused_variables = "warn"
unused_mut = "warn"
unsafe_code = "deny"
missing_debug_implementations = "warn"
[lints.clippy]
all = "warn"
pedantic = "warn"
nursery = "warn"
cargo = "warn"
unwrap_used = "warn"
expect_used = "warn"
panic = "warn"
todo = "warn"
[profile.release]
lto = true
opt-level = "z"
strip = true
panic = "abort"
codegen-units = 1
overflow-checks = true
[profile.ci]
inherits = "release"
lto = false
codegen-units = 16
debug = false
[profile.low-memory]
inherits = "release"
lto = "thin"
codegen-units = 16
debug = false
incremental = false
opt-level = "s"
[profile.dev]
debug = 0
incremental = true
codegen-units = 256
opt-level = 0

148
DATABASE-CHANGES.md Normal file
View file

@ -0,0 +1,148 @@
# 2.0.0
``` SQL
ALTER TABLE dbo.GuaribasUser ADD
agentSystemId nvarchar(16) NULL,
agentMode nvarchar(16) NULL,
agentContacted datetime NULL
GO
ALTER TABLE [dbo].[GuaribasUser] DROP COLUMN [phone]
GO
ALTER TABLE [dbo].[GuaribasUser] DROP COLUMN [internalAddress]
GO
ALTER TABLE [dbo].[GuaribasUser] DROP COLUMN [currentBotId]
GO
ALTER TABLE [dbo].[GuaribasInstance] DROP COLUMN [authenticatorClientId]
GO
ALTER TABLE [dbo].[GuaribasInstance] DROP COLUMN [authenticatorClientSecret]
GO
ALTER TABLE dbo.GuaribasUser ADD
locale nvarchar(5) NULL
GO
ALTER TABLE dbo.GuaribasInstance ADD
translatorKey nvarchar(64) NULL
translatorEndpoint nvarchar(64) NULL
GO
ALTER TABLE dbo.GuaribasInstance ADD
activationCode nvarchar(16) NULL
GO
ALTER TABLE dbo.GuaribasInstance ADD
params nvarchar(4000) NULL
GO
ALTER TABLE dbo.GuaribasInstance ADD
state nvarchar(16) NULL
GO
UPDATE dbo.GuaribasInstance SET state= 'active'
# 2.0.3
``` SQL
ALTER TABLE dbo.GuaribasPackage ADD
params custom(512) NULL
GO
```
# 2.0.56
ALTER TABLE dbo.GuaribasUser ADD
hearOnDialog nvarchar(64) NULL
GO
ALTER TABLE dbo.GuaribasConversation ADD
instanceId int,
feedback nvarchar(512) NULL
GO
ALTER TABLE [dbo].[GuaribasInstance] DROP COLUMN [translatorendpoint]
GO
ALTER TABLE dbo.GuaribasInstance ADD
translatorEndpoint nvarchar(128) NULL
GO
# 2.0.108
ALTER TABLE [dbo].[GuaribasInstance] DROP COLUMN [agentSystemId]
GO
ALTER TABLE dbo.GuaribasUser ADD
agentSystemId nvarchar(255) NULL,
GO
# 2.0.115
ALTER TABLE dbo.GuaribasQuestion ADD
skipIndex bit NULL
GO
# 2.0.116 >
ALTER TABLE dbo.GuaribasInstance ADD
googleBotKey nvarchar(255) NULL,
googleChatApiKey nvarchar(255) NULL,
googleChatSubscriptionName nvarchar(255) NULL,
googleClientEmail nvarchar(255) NULL,
googlePrivateKey nvarchar(4000) NULL,
googleProjectId nvarchar(255) NULL
GO
# 2.0.119
ALTER TABLE dbo.GuaribasInstance ADD
facebookWorkplaceVerifyToken nvarchar(255) NULL,
facebookWorkplaceAppSecret nvarchar(255) NULL,
facebookWorkplaceAccessToken nvarchar(512) NULL
GO
# 2.0.140
/****** Object: Table [dbo].[GuaribasSchedule] Script Date: 25/08/2021 03:53:15 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[GuaribasSchedule]
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](255) NULL,
[schedule] [nvarchar](255) NULL,
[instanceId] [int] NULL,
[createdAt] [datetimeoffset](7) NULL,
[updatedAt] [datetimeoffset](7) NULL
GO
ALTER TABLE dbo.GuaribasInstance ADD botKey nvarchar(64) NULL;
# 2.3.9
GO
ALTER TABLE dbo.GuaribasUser ADD
params nvarchar(4000) NULL
GO

8
FEATURES.md Normal file
View file

@ -0,0 +1,8 @@
# General Bots Features
| Feature | BF | GB |
|----------------------------------------------------------------------------|----|----|
| Use of conversational administration to manage bot packages (Talk to admin)| - | X |
| F5 to run on VSCode | - | X |
| Isolated code on packages | - | X |
| Breaking changes protected | - | X |

View file

@ -1,5 +1,5 @@
General Bots is licensed under a dual license. To check which license
edition of General bots you have installed, please ask info@pragmatismo.com.br
edition of General bots you have installed, please ask info@pragmatismo.cloud
informing your Customer ID.
If you modify this Program, or any covered work, by combining it

7
LOCALIZATION.md Normal file
View file

@ -0,0 +1,7 @@
# Localization in General Bots
## .gbapp
The localization is done by adding a strings.ts file to the root of the .gbapp package.

678
PROMPT.md
View file

@ -1,678 +0,0 @@
# botserver Development Prompt Guide
**Version:** 6.1.0
**Purpose:** Consolidated LLM context for botserver development
---
## Build Rules - IMPORTANT
**Always use debug builds during development and testing:**
```bash
# CORRECT - debug build (fast compilation)
cargo build
cargo check
# WRONG - do NOT use release builds unless explicitly requested
# cargo build --release
```
Debug builds compile much faster and are sufficient for testing functionality.
Only use `--release` when building final binaries for deployment.
---
## Weekly Maintenance - EVERY MONDAY
### Package Review Checklist
**Every Monday, review the following:**
1. **Dependency Updates**
```bash
cargo outdated
cargo audit
```
2. **Package Consolidation Opportunities**
- Check if new crates can replace custom code
- Look for crates that combine multiple dependencies
- Review `Cargo.toml` for redundant dependencies
3. **Code Reduction Candidates**
- Custom implementations that now have crate equivalents
- Boilerplate that can be replaced with derive macros
- Manual serialization that `serde` can handle
4. **Security Updates**
```bash
cargo audit fix
```
### Packages to Watch
| Area | Potential Packages | Purpose |
|------|-------------------|---------|
| Validation | `validator` | Replace manual validation |
| Date/Time | `chrono`, `time` | Consolidate time handling |
| Email | `lettre` | Simplify email sending |
| File Watching | `notify` | Replace polling with events |
| Background Jobs | `tokio-cron-scheduler` | Simplify scheduling |
---
## Version Management - CRITICAL
**Current version is 6.1.0 - DO NOT CHANGE without explicit approval!**
```bash
# Check current version
grep "^version" Cargo.toml
```
### Rules
1. **Version is 6.1.0 across ALL workspace crates**
2. **NEVER change version without explicit user approval**
3. **All migrations use 6.1.0_* prefix**
4. **Migration folder naming: `6.1.0_{feature_name}/`**
---
## Database Standards - CRITICAL
### TABLES AND INDEXES ONLY
**NEVER create in migrations:**
- ❌ Views (`CREATE VIEW`)
- ❌ Triggers (`CREATE TRIGGER`)
- ❌ Functions (`CREATE FUNCTION`)
- ❌ Stored Procedures
**ALWAYS use:**
- ✅ Tables (`CREATE TABLE IF NOT EXISTS`)
- ✅ Indexes (`CREATE INDEX IF NOT EXISTS`)
- ✅ Constraints (inline in table definitions)
### Why?
- Diesel ORM compatibility
- Simpler rollbacks
- Better portability
- Easier testing
### JSON Storage Pattern
Use TEXT columns with `_json` suffix instead of JSONB:
```sql
-- CORRECT
members_json TEXT DEFAULT '[]'
-- WRONG
members JSONB DEFAULT '[]'::jsonb
```
---
## Official Icons - MANDATORY
**NEVER generate icons with LLM. ALWAYS use official SVG icons from assets.**
Icons are stored in two locations (kept in sync):
- `botui/ui/suite/assets/icons/` - Runtime icons for UI
- `botbook/src/assets/icons/` - Documentation icons
### Available Icons
| Icon | File | Usage |
|------|------|-------|
| Logo | `gb-logo.svg` | Main GB branding |
| Bot | `gb-bot.svg` | Bot/assistant representation |
| Analytics | `gb-analytics.svg` | Charts, metrics, dashboards |
| Calendar | `gb-calendar.svg` | Scheduling, events |
| Chat | `gb-chat.svg` | Conversations, messaging |
| Compliance | `gb-compliance.svg` | Security, auditing |
| Designer | `gb-designer.svg` | Workflow automation |
| Drive | `gb-drive.svg` | File storage, documents |
| Mail | `gb-mail.svg` | Email functionality |
| Meet | `gb-meet.svg` | Video conferencing |
| Paper | `gb-paper.svg` | Document editing |
| Research | `gb-research.svg` | Search, investigation |
| Sources | `gb-sources.svg` | Knowledge bases |
| Tasks | `gb-tasks.svg` | Task management |
### Icon Guidelines
- All icons use `stroke="currentColor"` for CSS theming
- ViewBox: `0 0 24 24`
- Stroke width: `1.5`
- Rounded line caps and joins
**DO NOT:**
- Generate new icons with AI/LLM
- Use emoji or unicode symbols as icons
- Use external icon libraries
- Create inline SVG content
---
## Project Overview
botserver is the core backend for General Bots - an open-source conversational AI platform built in Rust. It provides:
- **Bootstrap System**: Auto-installs PostgreSQL, MinIO, Redis, LLM servers
- **Package Manager**: Manages bot deployments and service lifecycle
- **BASIC Interpreter**: Executes conversation scripts via Rhai
- **Multi-Channel Support**: Web, WhatsApp, Teams, Email
- **Knowledge Base**: Document ingestion with vector search
### Workspace Structure
```
botserver/ # Main server (this project)
botlib/ # Shared library - types, utilities, HTTP client
botui/ # Web/Desktop UI (Axum + Tauri)
botapp/ # Desktop app wrapper (Tauri)
botbook/ # Documentation (mdBook)
botmodels/ # Data models visualization
botplugin/ # Browser extension
```
---
## Database Migrations
### Creating New Migrations
```bash
# 1. Version is always 6.1.0
# 2. List existing migrations
ls -la migrations/
# 3. Create new migration folder
mkdir migrations/6.1.0_my_feature
# 4. Create up.sql and down.sql (TABLES AND INDEXES ONLY)
```
### Migration Structure
```
migrations/
├── 6.0.0_initial_schema/
├── 6.0.1_bot_memories/
├── ...
├── 6.1.0_enterprise_features/
│ ├── up.sql
│ └── down.sql
└── 6.1.0_next_feature/ # YOUR NEW MIGRATION
├── up.sql
└── down.sql
```
### Migration Best Practices
- Use `IF NOT EXISTS` for all CREATE TABLE statements
- Use `IF EXISTS` for all DROP statements in down.sql
- Always create indexes for foreign keys
- **NO triggers** - handle updated_at in application code
- **NO views** - use queries in application code
- **NO functions** - use application logic
- Use TEXT with `_json` suffix for JSON data (not JSONB)
---
## LLM Workflow Strategy
### Two Types of LLM Work
1. **Execution Mode (Fazer)**
- Pre-annotate phrases and send for execution
- Focus on automation freedom
- Less concerned with code details
- Primary concern: Is the LLM destroying something?
- Trust but verify output doesn't break existing functionality
2. **Review Mode (Conferir)**
- Read generated code with full attention
- Line-by-line verification
- Check for correctness, security, performance
- Validate against requirements
### Development Process
1. **One requirement at a time** with sequential commits
2. **Start with docs** - explain user behavior before coding
3. **Design first** - spend time on architecture
4. **On unresolved error** - stop and consult with web search enabled
### LLM Fallback Strategy (After 3 attempts / 10 minutes)
1. DeepSeek-V3-0324 (good architect, reliable)
2. gpt-5-chat (slower but thorough)
3. gpt-oss-120b (final validation)
4. Claude Web (for complex debugging, unit tests, UI)
---
## Code Generation Rules
### CRITICAL REQUIREMENTS
```
- KISS, NO TALK, SECURED ENTERPRISE GRADE THREAD SAFE CODE ONLY
- Use rustc 1.90.0 (1159e78c4 2025-09-14)
- No placeholders, never comment/uncomment code, no explanations
- All code must be complete, professional, production-ready
- REMOVE ALL COMMENTS FROM GENERATED CODE
- Always include full updated code files - never partial
- Only return files that have actual changes
- DO NOT WRITE ERROR HANDLING CODE - LET IT CRASH
- Return 0 warnings - review unused imports!
- NO DEAD CODE - implement real functionality, never use _ for unused
```
### Documentation Rules
```
- Rust code examples ONLY in docs/reference/architecture.md (gbapp chapter)
- All other docs: BASIC, bash, JSON, SQL, YAML only
- Scan for ALL_CAPS.md files created at wrong places - delete or integrate to docs/
- Keep only README.md and PROMPT.md at project root level
```
### Frontend Rules
```
- Use HTMX to minimize JavaScript - delegate logic to Rust server
- NO external CDN - all JS/CSS must be local in vendor/ folders
- Server-side rendering with Askama templates returning HTML
- Endpoints return HTML fragments, not JSON (for HTMX)
```
### Rust Patterns
```rust
// Use rand::rng() instead of rand::thread_rng()
let mut rng = rand::rng();
// Use diesel for database (NOT sqlx)
use diesel::prelude::*;
// All config from AppConfig - no hardcoded values
let url = config.drive.endpoint.clone();
// Logging (all-in-one-line, unique messages)
info!("Processing request id={} user={}", req_id, user_id);
```
### Dependency Management
```
- Use diesel - remove any sqlx references
- After adding to Cargo.toml: cargo audit must show 0 warnings
- If audit fails, find alternative library
- Minimize redundancy - check existing libs before adding new ones
- Review src/ to identify reusable patterns and libraries
```
### botserver Specifics
```
- Sessions MUST be retrieved by id when session_id is present
- Never suggest installing software - bootstrap/package_manager handles it
- Configuration stored in .gbot/config and database bot_configuration table
- Pay attention to shared::utils and shared::models for reuse
```
---
## Documentation Validation
### Chapter Validation Process
For each documentation chapter:
1. Read the chapter instructions step by step
2. Check if source code accomplishes each instruction
3. Verify paths exist and are correct
4. Ensure 100% alignment between docs and implementation
5. Fix either docs or code to match
### Documentation Structure
```
docs/
├── api/ # API documentation (no Rust code)
├── guides/ # How-to guides (no Rust code)
└── reference/
├── architecture.md # ONLY place for Rust code examples
├── basic-language.md # BASIC only
└── configuration.md # Config examples only
```
---
## Adding New Features
### Adding a Rhai Keyword
```rust
pub fn my_keyword(state: &AppState, engine: &mut Engine) {
let db = state.db_custom.clone();
engine.register_custom_syntax(
["MY", "KEYWORD", "$expr$"],
true,
{
let db = db.clone();
move |context, inputs| {
let value = context.eval_expression_tree(&inputs[0])?;
let binding = db.as_ref().unwrap();
let fut = execute_my_keyword(binding, value);
let result = tokio::task::block_in_place(||
tokio::runtime::Handle::current().block_on(fut))
.map_err(|e| format!("DB error: {}", e))?;
Ok(Dynamic::from(result))
}
}
).unwrap();
}
pub async fn execute_my_keyword(
pool: &PgPool,
value: String,
) -> Result<Value, Box<dyn std::error::Error>> {
info!("Executing my_keyword value={}", value);
use diesel::prelude::*;
let result = diesel::insert_into(my_table::table)
.values(&NewRecord { value })
.execute(pool)?;
Ok(json!({ "rows_affected": result }))
}
```
### Adding a Data Model
```rust
use chrono::{DateTime, Utc};
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Queryable, Selectable, Insertable, Serialize, Deserialize)]
#[diesel(table_name = crate::schema::users)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct User {
pub id: Uuid,
pub status: i16,
pub email: String,
pub age: Option<i16>,
pub metadata: Vec<u8>,
pub created_at: DateTime<Utc>,
}
```
### Adding a Service/Endpoint (HTMX Pattern)
```rust
use axum::{routing::get, Router, extract::State, response::Html};
use askama::Template;
#[derive(Template)]
#[template(path = "partials/items.html")]
struct ItemsTemplate {
items: Vec<Item>,
}
pub fn configure() -> Router<AppState> {
Router::new()
.route("/api/items", get(list_handler))
}
async fn list_handler(
State(state): State<Arc<AppState>>,
) -> Html<String> {
let conn = state.conn.get().unwrap();
let items = items::table.load::<Item>(&conn).unwrap();
let template = ItemsTemplate { items };
Html(template.render().unwrap())
}
```
---
## Final Steps Before Commit
```bash
# Check for warnings
cargo check 2>&1 | grep warning
# Audit dependencies (must be 0 warnings)
cargo audit
# Build release
cargo build --release
# Run tests
cargo test
# Verify no dead code with _ prefixes
grep -r "let _" src/ --include="*.rs"
# Verify version is 6.1.0
grep "^version" Cargo.toml | grep "6.1.0"
# Verify no views/triggers/functions in migrations
grep -r "CREATE VIEW\|CREATE TRIGGER\|CREATE FUNCTION" migrations/
```
### Pre-Commit Checklist
1. Version is 6.1.0 in all workspace Cargo.toml files
2. No views, triggers, or functions in migrations
3. All JSON columns use TEXT with `_json` suffix
---
## Output Format
### Shell Script Format
```sh
#!/bin/bash
cat > src/module/file.rs << 'EOF'
use std::io;
pub fn my_function() -> Result<(), io::Error> {
Ok(())
}
EOF
```
### Rules
- Only return MODIFIED files
- Never return unchanged files
- Use `cat > path << 'EOF'` format
- Include complete file content
- No partial snippets
---
## Key Files Reference
```
src/main.rs # Entry point, bootstrap, Axum server
src/lib.rs # Module exports, feature gates
src/core/
bootstrap/mod.rs # Auto-install services
session/mod.rs # Session management
bot/mod.rs # Bot orchestration
config/mod.rs # Configuration management
package_manager/ # Service lifecycle
src/basic/ # BASIC/Rhai interpreter
src/shared/
state.rs # AppState definition
utils.rs # Utility functions
models.rs # Database models
```
---
## Dependencies (Key Libraries)
| Library | Version | Purpose |
|---------|---------|---------|
| axum | 0.7.5 | Web framework |
| diesel | 2.1 | PostgreSQL ORM (NOT sqlx) |
| tokio | 1.41 | Async runtime |
| rhai | git | BASIC scripting |
| reqwest | 0.12 | HTTP client |
| serde | 1.0 | Serialization |
| askama | 0.12 | HTML Templates |
---
## Remember
- **Two LLM modes**: Execution (fazer) vs Review (conferir)
- **Rust code**: Only in architecture.md documentation
- **HTMX**: Minimize JS, delegate to server
- **Local assets**: No CDN, all vendor files local
- **Dead code**: Never use _ prefix, implement real code
- **cargo audit**: Must pass with 0 warnings
- **diesel**: No sqlx references
- **Sessions**: Always retrieve by ID when present
- **Config**: Never hardcode values, use AppConfig
- **Bootstrap**: Never suggest manual installation
- **Warnings**: Target zero warnings before commit
- **Version**: Always 6.1.0 - do not change without approval
- **Migrations**: TABLES AND INDEXES ONLY - no views, triggers, functions
- **Stalwart**: Use Stalwart IMAP/JMAP API for email features (sieve, filters, etc.)
- **JSON**: Use TEXT columns with `_json` suffix, not JSONB
---
## Monitor Keywords (ON EMAIL, ON CHANGE)
These keywords register event-driven monitors similar to `SET SCHEDULER`, but triggered by external events.
### ON EMAIL - Email Monitoring
Triggers a script when an email arrives at the specified address.
```basic
' Basic usage - trigger on any email to address
ON EMAIL "support@company.com"
email = GET LAST "email_received_events"
TALK "New email from " + email.from_address + ": " + email.subject
END ON
' With FROM filter - only trigger for specific sender
ON EMAIL "orders@company.com" FROM "supplier@vendor.com"
' Process supplier orders
END ON
' With SUBJECT filter - only trigger for matching subjects
ON EMAIL "alerts@company.com" SUBJECT "URGENT"
' Handle urgent alerts
END ON
```
**Database Tables:**
- `email_monitors` - Configuration for email monitoring
- `email_received_events` - Log of received emails to process
**TriggerKind:** `EmailReceived = 5`
### ON CHANGE - Folder Monitoring
Triggers a script when files change in cloud storage folders (GDrive, OneDrive, Dropbox) or local filesystem.
**Uses same `account://` syntax as COPY, MOVE, and other file operations.**
```basic
' Using account:// syntax (recommended) - auto-detects provider from email
ON CHANGE "account://user@gmail.com/Documents/invoices"
file = GET LAST "folder_change_events"
TALK "File changed: " + file.file_name + " (" + file.event_type + ")"
END ON
' OneDrive via account://
ON CHANGE "account://user@outlook.com/Business/contracts"
' Process OneDrive changes
END ON
' Direct provider syntax (without account)
ON CHANGE "gdrive:///shared/reports"
' Process Google Drive changes (requires USE ACCOUNT first)
END ON
ON CHANGE "onedrive:///documents"
' Process OneDrive changes
END ON
ON CHANGE "dropbox:///team/assets"
' Process Dropbox changes
END ON
' Local filesystem monitoring
ON CHANGE "/var/uploads/incoming"
' Process local filesystem changes
END ON
' With specific event types filter
ON CHANGE "account://user@gmail.com/uploads" EVENTS "create, modify"
' Only trigger on create and modify, ignore delete
END ON
' Watch for deletions only
ON CHANGE "gdrive:///archive" EVENTS "delete"
' Log when files are removed from archive
END ON
```
**Path Syntax:**
- `account://email@domain.com/path` - Uses connected account (auto-detects provider)
- `gdrive:///path` - Google Drive direct
- `onedrive:///path` - OneDrive direct
- `dropbox:///path` - Dropbox direct
- `/local/path` - Local filesystem
**Provider Auto-Detection (from email):**
- `@gmail.com`, `@google.com` → Google Drive
- `@outlook.com`, `@hotmail.com`, `@live.com` → OneDrive
- Other emails → Default to Google Drive
**Event Types:**
- `create` - New file created
- `modify` - File content changed
- `delete` - File deleted
- `rename` - File renamed
- `move` - File moved to different folder
**Database Tables:**
- `folder_monitors` - Configuration for folder monitoring
- `folder_change_events` - Log of detected changes to process
**TriggerKind:** `FolderChange = 6`
### TriggerKind Enum Values
```rust
pub enum TriggerKind {
Scheduled = 0, // SET SCHEDULER
TableUpdate = 1, // ON UPDATE OF "table"
TableInsert = 2, // ON INSERT OF "table"
TableDelete = 3, // ON DELETE OF "table"
Webhook = 4, // WEBHOOK
EmailReceived = 5, // ON EMAIL
FolderChange = 6, // ON CHANGE
}
```

263
README.md
View file

@ -1,154 +1,121 @@
# General Bots - Enterprise-Grade LLM Orchestrator
![General Bot Logo](https://github.com/GeneralBots/botserver/blob/main/logo.png?raw=true)
**A strongly-typed LLM conversational platform focused on convention over configuration and code-less approaches.**
## Quick Links
- **[Getting Started](docs/guides/getting-started.md)** - Installation and first bot
- **[API Reference](docs/api/README.md)** - REST and WebSocket endpoints
- **[BASIC Language](docs/reference/basic-language.md)** - Dialog scripting reference
## What is General Bots?
General Bots is a **self-hosted AI automation platform** that provides:
- **Multi-Vendor LLM API** - Unified interface for OpenAI, Groq, Claude, Anthropic
- **MCP + LLM Tools Generation** - Instant tool creation from code/functions
- **Semantic Caching** - Intelligent response caching (70% cost reduction)
- **Web Automation Engine** - Browser automation + AI intelligence
- **Enterprise Data Connectors** - CRM, ERP, database native integrations
- **Git-like Version Control** - Full history with rollback capabilities
## Quick Start
### Prerequisites
- **Rust** (1.75+) - [Install from rustup.rs](https://rustup.rs/)
- **Git** - [Download from git-scm.com](https://git-scm.com/downloads)
### Installation
```bash
git clone https://github.com/GeneralBots/botserver
cd botserver
cargo run
```
On first run, botserver automatically sets up PostgreSQL, S3 storage, Redis cache, and downloads AI models.
The server will be available at `http://localhost:8080`.
## Documentation
```
docs/
├── api/ # API documentation
│ ├── README.md # API overview
│ ├── rest-endpoints.md # HTTP endpoints
│ └── websocket.md # Real-time communication
├── guides/ # How-to guides
│ ├── getting-started.md # Quick start
│ ├── deployment.md # Production setup
│ └── templates.md # Using templates
└── reference/ # Technical reference
├── basic-language.md # BASIC keywords
├── configuration.md # Config options
└── architecture.md # System design
```
## Key Features
### 4 Essential Keywords
```basic
USE KB "kb-name" ' Load knowledge base into vector database
CLEAR KB "kb-name" ' Remove KB from session
USE TOOL "tool-name" ' Make tool available to LLM
CLEAR TOOLS ' Remove all tools from session
```
### Example Bot
```basic
' customer-support.bas
USE KB "support-docs"
USE TOOL "create-ticket"
USE TOOL "check-order"
SET CONTEXT "support" AS "You are a helpful customer support agent."
TALK "Welcome! How can I help you today?"
```
## Command-Line Options
```bash
cargo run # Default: console UI + web server
cargo run -- --noconsole # Background service mode
cargo run -- --desktop # Desktop application (Tauri)
cargo run -- --tenant <name> # Specify tenant
cargo run -- --container # LXC container mode
```
## Environment Variables
Only directory service variables are required:
| Variable | Purpose |
|----------|---------|
| `DIRECTORY_URL` | Zitadel instance URL |
| `DIRECTORY_CLIENT_ID` | OAuth client ID |
| `DIRECTORY_CLIENT_SECRET` | OAuth client secret |
All service credentials are managed automatically. See [Configuration](docs/reference/configuration.md) for details.
## Current Status
**Version:** 6.0.8
**Build Status:** SUCCESS
**Production Ready:** YES
## Deployment
See [Deployment Guide](docs/guides/deployment.md) for:
- Single server setup
- Docker Compose
- LXC containers
- Kubernetes
- Reverse proxy configuration
## Contributing
We welcome contributions! Please read our contributing guidelines before submitting PRs.
## Security
Security issues should be reported to: **security@pragmatismo.com.br**
## License
General Bot Copyright (c) pragmatismo.com.br. All rights reserved.
Licensed under the **AGPL-3.0**.
According to our dual licensing model, this program can be used either under the terms of the GNU Affero General Public License, version 3, or under a proprietary license.
## Support
- **GitHub Issues:** [github.com/GeneralBots/botserver/issues](https://github.com/GeneralBots/botserver/issues)
- **Stack Overflow:** Tag questions with `generalbots`
- **Video Tutorial:** [7 AI General Bots LLM Templates](https://www.youtube.com/watch?v=KJgvUPXi3Fw)
## Contributors
<a href="https://github.com/generalbots/botserver/graphs/contributors">
<img src="https://contrib.rocks/image?repo=generalbots/botserver" />
</a>
---
**General Bots Code Name:** [Guaribas](https://en.wikipedia.org/wiki/Guaribas)
| Area | Status |
|------------------------------|----------------------------------------------------------------------------------------------------|
| Releases | [![General Bots](https://img.shields.io/npm/dt/botserver.svg?logo=npm&label=botserver)](https://www.npmjs.com/package/botserver/) [![.gbapp lib](https://img.shields.io/npm/dt/botlib.svg?logo=npm&label=botlib)](https://www.npmjs.com/package/botlib/) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)|
| Community | [![StackExchange](https://img.shields.io/stackexchange/stackoverflow/t/generalbots.svg)](https://stackoverflow.com/questions/tagged/generalbots) [![Open-source](https://badges.frapsoft.com/os/v2/open-source.svg)](https://badges.frapsoft.com) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) [![License](https://img.shields.io/badge/license-AGPL-blue.svg)](https://github.com/GeneralBots/BotServer/blob/master/LICENSE.txt)|
| Management | [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://gitHub.com/GeneralBots/BotServer/graphs/commit-activity) |
| Security | [![Known Vulnerabilities](https://snyk.io/test/github/GeneralBots/BotServer/badge.svg)](https://snyk.io/test/github/GeneralBots/BotServer) |
| Building & Quality | [![Build Status](https://travis-ci.com/GeneralBots/BotServer.svg?branch=master)](https://app.travis-ci.com/github/GeneralBots/BotServer) [![Coverage Status](https://coveralls.io/repos/github/GeneralBots/BotServer/badge.svg)](https://coveralls.io/github/GeneralBots/BotServer) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) |
| Packaging | [![forthebadge](https://badge.fury.io/js/botserver.svg)](https://badge.fury.io) [![ZipFile](https://camo.githubusercontent.com/0150c0f148d50fe9750ebc5d313581da699a8c50/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7a69702d646f776e6c6f61642d626c75652e737667)](https://github.com/GeneralBots/BotServer/releases/latest) [![Dependencies](https://david-dm.org/GeneralBots/botserver.svg)](https://david-dm.org) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) |
| Samples | [VBA](https://github.com/GeneralBots/BotServer/tree/master/packages/default.gbdialog) or [![TypeScript](https://badges.frapsoft.com/typescript/code/typescript.svg?v=101)](https://github.com/GeneralBots/AzureADPasswordReset.gbapp)
| [Docker Image](https://github.com/lpicanco/docker-botserver) | ![Docker Automated build](https://img.shields.io/docker/automated/lpicanco/botserver.svg) ![Docker Build Status](https://img.shields.io/docker/build/lpicanco/botserver.svg) ![MicroBadger Size](https://img.shields.io/microbadger/image-size/lpicanco/botserver.svg) ![MicroBadger Layers](https://img.shields.io/microbadger/layers/lpicanco/botserver.svg) ![Docker Pulls](https://img.shields.io/docker/pulls/lpicanco/botserver.svg) <br/> *Provided by [@lpicanco](https://github.com/lpicanco/docker-botserver)* |
> "No one should have to do work that can be done by a machine." - Roberto Mangabeira Unger
General Bots
------------------
![General Bot Logo](https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/logo.png)
General Bot is a strongly typed package based chat bot server focused in convention over configuration and code-less approaches, which brings software packages and application server concepts to help parallel bot development.
## What is a Bot Server?
Bot Server accelerates the process of developing a bot. It provisions all code
base, resources and deployment to the cloud, and gives you templates you can
choose from whenever you need a new bot. The server has a database and service
backend allowing you to further modify your bot package directly by downloading
a zip file, editing and uploading it back to the server (deploying process) with
no code. The Bot Server also provides a framework to develop bot packages in a more
advanced fashion writing custom code in editors like Visual Studio Code, Atom or Brackets.
Everyone can create bots by just copying and pasting some files and using their
favorite tools from Office (or any text editor) or Photoshop (or any image
editor). BASIC can be used to build custom dialogs so Bot can be extended just like VBA for Excel (currently in alpha).
![General Bot Reference Architecture](https://raw.githubusercontent.com/GeneralBots/BotBook/master/images/general-bots-reference-architecture.png)
## Samples
Several samples, including a Bot for AD Password Reset, are avaiable on the [repository list](https://github.com/GeneralBots).
### Using complete General Bots Conversational Data Analytics
![](https://user-images.githubusercontent.com/14840374/178154826-8188029e-b4f4-48aa-bc0d-126307ce5121.png)
```
TALK "General Bots Labs presents FISCAL DATA SHOW BY BASIC"
TALK "Gift Contributions to Reduce the Public Debt API (https://fiscaldata.treasury.gov/datasets/gift-contributions-reduce-debt-held-by-public/gift-contributions-to-reduce-the-public-debt)"
result = GET "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/gift_contributions?page[size]=500"
data = result.data
data = SELECT YEAR(record_date) as Yr, SUM(CAST(contribution_amt AS NUMBER)) AS Amount FROM data GROUP BY YEAR(record_date)
TALK "Demonstration of Gift Contributions with AS IMAGE keyword"
SET THEME dark
png = data as IMAGE
SEND FILE png
DELAY 5
TALK " Demonstration of Gift Contributions CHART keyword"
img = CHART "bar", data
SEND FILE img
```
## Guide
[Read the General Bots BotBook Guide](https://github.com/GeneralBots/BotBook/tree/master/book).
# Videos
Now with the General Bots server you can press F5 on Visual Studio to get a bot factory on your environment* published on November 10th, 2018.
[![General Bot Video](https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/video-01-thumb.jpg)](https://www.youtube.com/watch?v=AfKTwljoMOs)
See how easy is to use 'hear' and 'talk' to build Microsoft BOT Framework v4 logic with plain BASIC * published on December 3rd, 2018.
[![See how easy is to use 'hear' and 'talk' to build Microsoft BOT Framework v4 logic with plain BASIC](https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/video-02-thumb.jpg)](https://www.youtube.com/watch?v=yX1sF9n9628)
# Contributing
This project welcomes contributions and suggestions.
See our [Contribution Guidelines](https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md) for more details.
# Reporting Security Issues
Security issues and bugs should be reported privately, via email, to the pragmatismo.cloud Security
team at [security@pragmatismo.cloud](mailto:security@pragmatismo.cloud). You should
receive a response within 24 hours. If for some reason you do not, please follow up via
email to ensure we received your original message.
# License & Warranty
General Bot Copyright (c) pragmatismo.cloud. All rights reserved.
Licensed under the AGPL-3.0.
According to our dual licensing model, this program can be used either
under the terms of the GNU Affero General Public License, version 3,
or under a proprietary license.
The texts of the GNU Affero General Public License with an additional
permission and of our proprietary license can be found at and
in the LICENSE file you have received along with this program.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
"General Bot" is a registered trademark of pragmatismo.cloud.
The licensing of the program under the AGPLv3 does not imply a
trademark license. Therefore any rights, title and interest in
our trademarks remain entirely with us.
<a href="https://stackoverflow.com/questions/ask?tags=generalbots">:speech_balloon: Ask a question</a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="https://github.com/GeneralBots/BotBook">:book: Read the Docs</a>
Team pictures made with [contrib.rocks](https://contrib.rocks).
General Bots Code Name is [Guaribas](https://en.wikipedia.org/wiki/Guaribas), the name of a city in Brazil, state of Piaui.
[Roberto Mangabeira Unger](http://www.robertounger.com/en/): "No one should have to do work that can be done by a machine".

6
ROADMAP.md Normal file
View file

@ -0,0 +1,6 @@
# Roadmap
| Title | Priority | Release | Status |
|-------------------------------|------------------------------------------------------------------------------------------------------------|---------|--------|
| Isolation of .gbapp per .gbot | Today .gbapp loaded is shared across all bot instances and must be associated to one or more individually. | Medium | 2019Q4 |
| Python based .gbapps | Write conversational login in Python | Low | - |

7
SAMPLES.md Normal file
View file

@ -0,0 +1,7 @@
# General Bots Server Samples
| Sample | Description |
|--------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| [IntranetBotQuickStart-gbai](https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai) | Free modules from General Bots Intranet based bot. |
| [AzureADPasswordReset-gbapp](https://github.com/pragmatismo-io/AzureADPasswordReset.gbapp) | Custom General Bot App (gbapp) for resetting an user password in Azure Active Directory, Office 365, Dynamics 365 or any app published through Azure AD. |
| [ProjectOnline.gbkb](https://github.com/pragmatismo-io/ProjectOnline.gbkb) | The .gbkb file demonstring a Knowledge Base for pragmatismo.cloud KBot for Microsoft Project. |

61
SECURITY.md Normal file
View file

@ -0,0 +1,61 @@
# General Bots Security Policy
## Overview
Request your free IT security evaluation
• Reduce the risk of IT problems
• Plan for problems and deal with them when they happen
• Keep working if something does go wrong
• Protect company, client and employee data
• Keep valuable company information, such as plans and designs, secret
• Meet our legal obligations under the General Data Protection Regulation and other laws
• Meet our professional obligations towards our clients and customers
This IT security policy helps us:
• Rodrigo Rodriguez is the director with overall responsibility for IT security strategy.
• Microsoft is the IT partner organisation we use to help with our planning and support.
• Microsoft is the data protection officer to advise on data protection laws and best practices
Review process
We will review this policy yearly.
In the meantime, if you have any questions, suggestions
or feedback, please contact security@pragmatismo.cloud
We will only classify information which is necessary for the completion of our duties. We will also limit
access to personal data to only those that need it for processing. We classify information into different
categories so that we can ensure that it is protected properly and that we allocate security resources
appropriately:
• Unclassified. This is information that can be made public without any implications for the company,
such as information that is already in the public domain.
• Employee confidential. This includes information such as medical records, pay and so on.
• Company confidential. Such as contracts, source code, business plans, passwords for critical IT
systems, client contact records, accounts etc.
• Client confidential. This includes personally identifiable information such as name or address,
passwords to client systems, client business plans, new product information, market sensitive
information etc.
Employees joining and leaving
We will provide training to new staff and support for existing staff to implement this policy. This includes:
• An initial introduction to IT security, covering the risks, basic security measures, company policies
and where to get help
• Each employee will complete the National Archives Responsible for Information training course
(approximately 75 minutes)
• Training on how to use company systems and security software properly
• On request, a security health check on their computer, tablet or phone
When people leave a project or leave the company, we will promptly revoke their access privileges to
The company will ensure the data protection office is given all appropriate resources to carry out their
tasks and maintain their expert knowledge.
The Data Protection Officer reports directly to the highest level of management and must not carry out
any other tasks that could result in a conflict of interest.
## Reporting a Vulnerability
You can expect to get an update on a reported vulnerability in a day or two.
security@pragmatismo.cloud

79
WARNINGS.md Normal file
View file

@ -0,0 +1,79 @@
# default.gbui
https://github.com/microsoft/BotFramework-WebChat/pull/4524
warning botframework-directlinejs > core-js@3.15.2: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
warning botframework-webchat > botframework-webchat-component > @emotion/css > @emotion/babel-plugin > @babel/plugin-syntax-jsx@7.18.6" has unmet peer dependency "@babel/core@^7.0.0-0".
warning botframework-webchat > botframework-webchat-component > @emotion/css > @emotion/babel-plugin@11.10.5" has unmet peer dependency "@babel/core@^7.0.0".
warning botframework-webchat > botframework-webchat-component > react-film > core-js@3.12.1: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
warning botframework-webchat > botframework-webchat-component > react-scroll-to-bottom > core-js@3.18.3: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
warning botframework-webchat > botframework-webchat-core > redux-devtools-extension@2.13.9: Package moved to @redux-devtools/extension.
warning botframework-webchat > microsoft-cognitiveservices-speech-sdk > asn1.js-rfc2560@5.0.1" has unmet peer dependency "asn1.js@^5.0.0".
warning botframework-webchat > web-speech-cognitive-services@7.1.2" has incorrect peer dependency "microsoft-cognitiveservices-speech-sdk@~1.17.0".
https://github.com/microsoft/powerbi-client-react
warning react-powerbi@0.9.1" has incorrect peer dependency "react@^16.8.0".
warning react-scripts > @svgr/webpack > @svgr/plugin-svgo > svgo > stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
warning react-scripts > @svgr/webpack > @svgr/plugin-svgo > svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x.
warning react-scripts > css-minimizer-webpack-plugin > cssnano > cssnano-preset-default > postcss-svgo > svgo > stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
warning react-scripts > eslint-config-react-app > @typescript-eslint/eslint-plugin > tsutils@3.21.0" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta".
warning react-scripts > eslint-config-react-app > eslint-plugin-flowtype@8.0.3" has unmet peer dependency "@babel/plugin-syntax-flow@^7.14.5".
warning react-scripts > eslint-config-react-app > eslint-plugin-flowtype@8.0.3" has unmet peer dependency "@babel/plugin-transform-react-jsx@^7.14.9".
warning react-scripts > jest > @jest/core > jest-config > jest-environment-jsdom > jsdom > w3c-hr-time@1.0.2: Use your platform's native performance.now() and performance.timeOrigin.
warning react-scripts > react-dev-utils > fork-ts-checker-webpack-plugin@6.5.2" has unmet peer dependency "typescript@>= 2.7".
# BotServer
docxtemplater is not working in more modern versions. Stay with 3.9.7.
nodejs/node-gyp#2756
warning npm > node-gyp > make-fetch-happen > cacache > @npmcli/move-file@2.0.1: This functionality has been moved to @npmcli/fs
vasyas/typescript-rest-rpc#20
warning typescript-rest-rpc > ts-morph > globby > fast-glob > micromatch > snapdragon > source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
#279
warning tslint@6.1.3: TSLint has been deprecated in favor of ESLint. Please see palantir/tslint#4534 for more information.
AlaSQL/alasql#1541
warning alasql > request@2.88.2: request has been deprecated, see request/request#3142
#281
warning c3-chart-maker > data-forge > promised-mongo > mongodb-core > bson@0.4.23: Fixed a critical issue with BSON serialization documented in CVE-2019-2391, see https://bit.ly/2KcpXdo for more details
#280
warning swagger-client > url > querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
bahmutov/ggit#157
warning ban-sensitive-files > ggit > debug@3.2.6: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (debug-js/debug#797)
#283
warning nexmo > uuid@2.0.3: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
https://github.com/microsoft/botbuilder-js/issues/4370
warning botbuilder-ai > @azure/cognitiveservices-luis-runtime > @azure/ms-rest-js > uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
https://github.com/Azure/azure-sdk-for-node/issues/5221
warning ms-rest-azure > request@2.88.2: request has been deprecated, see request/request#3142
https://github.com/MontassarLaribi/ssr-for-bots/issues/1
warning ssr-for-bots > tslint@6.1.3: TSLint has been deprecated in favor of ESLint. Please see palantir/tslint#4534 for more information.
https://github.com/vasyas/typescript-rest-rpc/issues/20
warning typescript-rest-rpc > ts-morph > globby > fast-glob > micromatch > snapdragon > source-map-resolve > urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
https://github.com/ash-developer/winston-logs-display/issues/8
warning winston-logs-display > jade > transformers@2.1.0: Deprecated, use jstransformer
https://github.com/softwarescales/git-issues/issues/29
warning git-issues > request@2.88.2: request has been deprecated, see request/request#3142
https://github.com/GeneralBots/BotServer/issues/284
warning license-checker > read-installed > readdir-scoped-modules@1.1.0: This functionality has been moved to @npmcli/fs
https://github.com/semantic-release/semantic-release/issues/1260
warning semantic-release > @semantic-release/npm > npm > readdir-scoped-modules@1.1.0: This functionality has been moved to @npmcli/fs
https://github.com/GeneralBots/BotServer/issues/277
warning travis-deploy-once@3.3.0: We recommend to use Travis Build Stages instead

View file

@ -1,89 +0,0 @@
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$SCRIPT_DIR"
OUTPUT_FILE="/tmp/prompt.out"
echo "Consolidated LLM Context" > "$OUTPUT_FILE"
prompts=(
"./prompts/dev/platform/shared.md"
"./prompts/dev/platform/cli.md"
"./prompts/dev/platform/ide.md"
"./Cargo.toml"
)
for file in "${prompts[@]}"; do
if [ -f "$file" ]; then
cat "$file" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
fi
done
dirs=(
"auth"
#"automation"
#"basic"
#"bootstrap"
"bot"
#"channels"
#"config"
#"context"
#"drive_monitor"
"email"
"file"
#"kb"
"llm"
#"llm_models"
"meet"
#"org"
#"package_manager"
#"riot_compiler"
"session"
"shared"
#"tests"
#"tools"
#"ui"
#"ui_tree"
#"web_server"
#"web_automation"
)
for dir in "${dirs[@]}"; do
find "$PROJECT_ROOT/src/$dir" -name "*.rs" | while read -r file; do
echo "$file" >> "$OUTPUT_FILE"
cat "$file" >> "$OUTPUT_FILE"
done
done
# Additional specific files
files=(
"$PROJECT_ROOT/src/main.rs"
#"$PROJECT_ROOT/src/basic/keywords/mod.rs"
)
for file in "${files[@]}"; do
echo "$file" >> "$OUTPUT_FILE"
cat "$file" >> "$OUTPUT_FILE"
done
# Remove all blank lines and reduce whitespace greater than 1 space
sed -i 's/[[:space:]]*$//' "$OUTPUT_FILE"
sed -i '/^$/d' "$OUTPUT_FILE"
sed -i 's/ \+/ /g' "$OUTPUT_FILE"
# Calculate and display token count (approximation: words * 1.3)
WORD_COUNT=$(wc -w < "$OUTPUT_FILE")
TOKEN_COUNT=$(echo "$WORD_COUNT * 1.3 / 1" | bc)
FILE_SIZE=$(wc -c < "$OUTPUT_FILE")
echo "" >> "$OUTPUT_FILE"
echo "Approximate token count: $TOKEN_COUNT"
echo "Context size: $FILE_SIZE bytes"
cat "$OUTPUT_FILE" | xclip -selection clipboard
echo "Content copied to clipboard (xclip)"
rm -f "$OUTPUT_FILE"

14
api-template.json Normal file
View file

@ -0,0 +1,14 @@
{
"openapi": "3.0.0",
"info": {
"title": "General Bots API",
"description": "General Bots API description in Swagger format",
"version": "1.0"
},
"servers": [
{
"url": "https://gb.pragmatismo.cloud/api",
"description": "General Bots Online"
}
]
}

View file

@ -1,14 +0,0 @@
[general]
# Configure Askama to look for templates in ui/ directory
dirs = ["ui"]
# Enable syntax highlighting hints for editors
syntax = [{ name = "html", ext = ["html"] }]
# Escape HTML by default for security
escape = "html"
# Custom filters module path
[custom]
# Register custom filters from the web::filters module
filters = "crate::web::filters"

BIN
blank.docx Normal file

Binary file not shown.

BIN
blank.xlsx Normal file

Binary file not shown.

57
boot.mjs Normal file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env node
process.stdout.write(`General Bots VM: node@${process.version.replace('v', '')}, ${process.platform} ${process.arch} `);
import fs from 'fs/promises';
import os from 'node:os';
import path from 'path';
import { exec } from 'child_process';
import {GBUtil} from './dist/src/util.js'
// Displays version of Node JS being used at runtime and others attributes.
console.log(`\nLoading General Bots VM...`);
var __dirname = process.env.PWD || process.cwd();
try {
var run = async () => {
import('./dist/src/app.js').then(async (gb)=> {
await gb.GBServer.run()
});
};
var processDist = async () => {
if (!await GBUtil.exists('dist')) {
console.log(`\n`);
console.log(`General Bots: Compiling...`);
exec(path.join(__dirname, 'node_modules/.bin/tsc'), async (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
await run();
});
} else {
await run();
}
};
// Installing modules if it has not been done yet.
if (!await GBUtil.exists('node_modules')) {
console.log(`\n`);
console.log(`General Bots: Installing modules for the first time, please wait...`);
exec('npm install', async (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
await processDist();
});
} else {
await processDist();
}
} catch (e) {
console.log(e);
}

View file

@ -1,20 +0,0 @@
{
"base_url": "http://localhost:8300",
"default_org": {
"id": "351468402772017166",
"name": "default",
"domain": "default.localhost"
},
"default_user": {
"id": "admin",
"username": "admin",
"email": "admin@localhost",
"password": "",
"first_name": "Admin",
"last_name": "User"
},
"admin_token": "2YJqHuenWddFpMw4vqw6vEHtgSF5jbvSG4NxTANnV9KJJMnaDSuvbUNSGsS06-QLFZnpFbw",
"project_id": "",
"client_id": "351468407201267726",
"client_secret": "vLxjxWiPv8fVvown7zBOqKdb7RPntqVW8fNfphaiMWtkXFI8fXQX8WoyBE5KmhJA"
}

View file

@ -1,101 +0,0 @@
{
"llama_cpp": {
"version": "b7345",
"base_url": "https://github.com/ggml-org/llama.cpp/releases/download",
"binaries": {
"linux": {
"x64": {
"cpu": "llama-{version}-bin-ubuntu-x64.zip",
"cpu_tar": "llama-{version}-bin-ubuntu-x64.tar.gz",
"vulkan": "llama-{version}-bin-ubuntu-vulkan-x64.zip",
"vulkan_tar": "llama-{version}-bin-ubuntu-vulkan-x64.tar.gz"
},
"s390x": {
"cpu": "llama-{version}-bin-ubuntu-s390x.zip",
"cpu_tar": "llama-{version}-bin-ubuntu-s390x.tar.gz"
}
},
"macos": {
"arm64": {
"cpu": "llama-{version}-bin-macos-arm64.zip",
"cpu_tar": "llama-{version}-bin-macos-arm64.tar.gz"
},
"x64": {
"cpu": "llama-{version}-bin-macos-x64.zip",
"cpu_tar": "llama-{version}-bin-macos-x64.tar.gz"
}
},
"windows": {
"x64": {
"cpu": "llama-{version}-bin-win-cpu-x64.zip",
"cuda_12": "llama-{version}-bin-win-cuda-12.4-x64.zip",
"cuda_13": "llama-{version}-bin-win-cuda-13.1-x64.zip",
"vulkan": "llama-{version}-bin-win-vulkan-x64.zip",
"sycl": "llama-{version}-bin-win-sycl-x64.zip",
"hip": "llama-{version}-bin-win-hip-radeon-x64.zip"
},
"arm64": {
"cpu": "llama-{version}-bin-win-cpu-arm64.zip",
"opencl_adreno": "llama-{version}-bin-win-opencl-adreno-arm64.zip"
}
},
"ios": {
"xcframework": "llama-{version}-xcframework.zip",
"xcframework_tar": "llama-{version}-xcframework.tar.gz"
}
},
"cuda_runtime": {
"windows": {
"cuda_12": "cudart-llama-bin-win-cuda-12.4-x64.zip",
"cuda_13": "cudart-llama-bin-win-cuda-13.1-x64.zip"
}
},
"checksums": {
"llama-b7345-bin-ubuntu-x64.zip": "sha256:91b066ecc53c20693a2d39703c12bc7a69c804b0768fee064d47df702f616e52",
"llama-b7345-bin-ubuntu-x64.tar.gz": "sha256:c5f4c8111887072a5687b42e0700116e93eddf14c5401fa7eba3ab0b8481ff4e",
"llama-b7345-bin-ubuntu-vulkan-x64.zip": "sha256:03f0b3acbead2ddc23267073a8f8e0207937c849d3704c46c61cf167c1001442",
"llama-b7345-bin-ubuntu-vulkan-x64.tar.gz": "sha256:9b02b406106cd20ea0568c43c28c587d7e4908b5b649e943adebb0e1ae726076",
"llama-b7345-bin-ubuntu-s390x.zip": "sha256:688ddad6996b1166eaaa76d5025e304c684116efe655e6e881d877505ecffccb",
"llama-b7345-bin-ubuntu-s390x.tar.gz": "sha256:118011b38b02fee21596ab5b1c40b56369da514645394b6528a466e18f4336f5",
"llama-b7345-bin-macos-arm64.zip": "sha256:72ae9b4a4605aa1223d7aabaa5326c66c268b12d13a449fcc06f61099cd02a52",
"llama-b7345-bin-macos-arm64.tar.gz": "sha256:dc7c6b64848180259db19eb5d8ee8424cffcbb053960e5c45d79db6b9ac4f40d",
"llama-b7345-bin-macos-x64.zip": "sha256:bec6b805cf7533f66b38f29305429f521dcb2be6b25dbce73a18df448ec55cc5",
"llama-b7345-bin-macos-x64.tar.gz": "sha256:9267a292f39a86b2ee5eaa553a06f4a2fda2aee35142cde40a9099432b304313",
"llama-b7345-bin-win-cpu-x64.zip": "sha256:ea449082c8e808a289d9a1e8331f90a0379ead4dd288a1b9a2d2c0a7151836cd",
"llama-b7345-bin-win-cpu-arm64.zip": "sha256:91e3ff43c123c7c30decfe5a44c291827c1e47359abaa2fbad1eb5392b3a0d85",
"llama-b7345-bin-win-cuda-12.4-x64.zip": "sha256:7a82aba2662fa7d4477a7a40894de002854bae1ab8b0039888577c9a2ca24cae",
"llama-b7345-bin-win-cuda-13.1-x64.zip": "sha256:06ea715cefb07e9862394e6d1ffa066f4c33add536b1f1aa058723f86ae05572",
"llama-b7345-bin-win-vulkan-x64.zip": "sha256:3e948bee438f46c8ea0a3faf0416549391ee945ffa624b25bc1f73d60d668679",
"llama-b7345-bin-win-sycl-x64.zip": "sha256:708ddb786cdeb43ceadaa57c0ca669ce05b86753bf859f5a95012c2ea481f9da",
"llama-b7345-bin-win-hip-radeon-x64.zip": "sha256:ba1fe643e27bae8dcdf6d7be459a6dc5d8385f179e71e749c53f52083c68e107",
"llama-b7345-bin-win-opencl-adreno-arm64.zip": "sha256:59d625d21fb64294b075c61ec1a5f01d394baf826bee2df847d0ea3ed21fa3f3",
"llama-b7345-xcframework.zip": "sha256:c94e870ba844e4938d6fccf0bfd64c9fe57884a14a3e2a4966e56e35a6cbaef4",
"llama-b7345-xcframework.tar.gz": "sha256:a542ceace2621d9d860f2ec64c1b2294ac71f292106b95dcaf239aec0a06dd55",
"cudart-llama-bin-win-cuda-12.4-x64.zip": "sha256:8c79a9b226de4b3cacfd1f83d24f962d0773be79f1e7b75c6af4ded7e32ae1d6",
"cudart-llama-bin-win-cuda-13.1-x64.zip": "sha256:f96935e7e385e3b2d0189239077c10fe8fd7e95690fea4afec455b1b6c7e3f18"
}
},
"models": {
"default_llm": {
"name": "DeepSeek-R1-Distill-Qwen-1.5B",
"url": "https://huggingface.co/bartowski/DeepSeek-R1-Distill-Qwen-1.5B-GGUF/resolve/main/DeepSeek-R1-Distill-Qwen-1.5B-Q3_K_M.gguf",
"filename": "DeepSeek-R1-Distill-Qwen-1.5B-Q3_K_M.gguf",
"size_mb": 1100,
"description": "Small reasoning model, good for CPU or minimal GPU (4GB VRAM)"
},
"default_embedding": {
"name": "BGE Small EN v1.5",
"url": "https://huggingface.co/CompendiumLabs/bge-small-en-v1.5-gguf/resolve/main/bge-small-en-v1.5-f32.gguf",
"filename": "bge-small-en-v1.5-f32.gguf",
"size_mb": 130,
"description": "Embedding model for vector search"
},
"large_llm": {
"name": "GPT-OSS 20B",
"url": "https://huggingface.co/unsloth/gpt-oss-20b-GGUF/resolve/main/gpt-oss-20b-F16.gguf",
"filename": "gpt-oss-20b-F16.gguf",
"size_mb": 40000,
"description": "Large model for GPU with 16GB+ VRAM"
}
}
}

150
deploy.cmd Normal file
View file

@ -0,0 +1,150 @@
@if "%SCM_TRACE_LEVEL%" NEQ "4" @echo off
:: ----------------------
:: General Bots deployment.
:: -------------
:: Verify node.js installed
where node 2>nul >nul
IF %ERRORLEVEL% NEQ 0 (
echo Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment.
goto error
)
:: Setup
:: -----
setlocal enabledelayedexpansion
SET ARTIFACTS=%~dp0%..\artifacts
IF NOT DEFINED DEPLOYMENT_SOURCE (
SET DEPLOYMENT_SOURCE=%~dp0%.
)
IF NOT DEFINED DEPLOYMENT_TARGET (
SET DEPLOYMENT_TARGET=%ARTIFACTS%\wwwroot
)
IF NOT DEFINED NEXT_MANIFEST_PATH (
SET NEXT_MANIFEST_PATH=%ARTIFACTS%\manifest
IF NOT DEFINED PREVIOUS_MANIFEST_PATH (
SET PREVIOUS_MANIFEST_PATH=%ARTIFACTS%\manifest
)
)
IF NOT DEFINED KUDU_SYNC_CMD (
:: Install kudu sync
echo Installing Kudu Sync
call npm install kudusync -g --silent
IF !ERRORLEVEL! NEQ 0 goto error
:: Locally just running "kuduSync" would also work
SET KUDU_SYNC_CMD=%appdata%\npm\kuduSync.cmd
)
goto Deployment
:: Utility Functions
:: -----------------
:SelectNodeVersion
IF DEFINED KUDU_SELECT_NODE_VERSION_CMD (
:: The following are done only on Windows Azure Websites environment
call %KUDU_SELECT_NODE_VERSION_CMD% "%DEPLOYMENT_SOURCE%" "%DEPLOYMENT_TARGET%" "%DEPLOYMENT_TEMP%"
IF !ERRORLEVEL! NEQ 0 goto error
IF EXIST "%DEPLOYMENT_TEMP%\__nodeVersion.tmp" (
SET /p NODE_EXE=<"%DEPLOYMENT_TEMP%\__nodeVersion.tmp"
IF !ERRORLEVEL! NEQ 0 goto error
)
IF EXIST "%DEPLOYMENT_TEMP%\__npmVersion.tmp" (
SET /p NPM_JS_PATH=<"%DEPLOYMENT_TEMP%\__npmVersion.tmp"
IF !ERRORLEVEL! NEQ 0 goto error
)
IF NOT DEFINED NODE_EXE (
SET NODE_EXE=node
)
SET NPM_CMD="!NODE_EXE!" "!NPM_JS_PATH!"
) ELSE (
SET NPM_CMD=npm
SET NODE_EXE=node
)
goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Deployment
:: ----------
:Deployment
echo Handling node.js deployment.
:: 1. KuduSync
IF /I "%IN_PLACE_DEPLOYMENT%" NEQ "1" (
call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_SOURCE%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd"
IF !ERRORLEVEL! NEQ 0 goto error
)
:: 2. Select node version
call :SelectNodeVersion
:: 3. Install npm packages
IF EXIST "%DEPLOYMENT_TARGET%\package.json" (
pushd "%DEPLOYMENT_TARGET%"
echo [General Bots Deployer] Installing packages for server...
call :ExecuteCmd !NPM_CMD! install --production
IF !ERRORLEVEL! NEQ 0 goto error
popd
)
:: 3.1 Install npm packages on UI
IF EXIST "%DEPLOYMENT_TARGET%\deploy\default.gbui\package.json" (
call :ExecuteCmd !NPM_CMD! config set scripts-prepend-node-path true
pushd "%DEPLOYMENT_TARGET%\deploy\default.gbui"
echo [General Bots Deployer] Installing packages for default.gbui...
call :ExecuteCmd !NPM_CMD! install
echo [General Bots Deployer] Building default.gbui...
call :ExecuteCmd !NPM_CMD! run build
IF !ERRORLEVEL! NEQ 0 goto error
RMDIR /s /q "%DEPLOYMENT_TARGET%\deploy\default.gbui\node_modules"
popd
)
:: 4. Install TypeScript
echo [General Bots Deployer] Transpiling...
call :ExecuteCmd node %DEPLOYMENT_TARGET%\node_modules\typescript\bin\tsc -v
call :ExecuteCmd node %DEPLOYMENT_TARGET%\node_modules\typescript\bin\tsc -p "%DEPLOYMENT_TARGET%"
echo [General Bots Deployer] Deployment Finished.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
goto end
:: Execute command routine that will echo out when error
:ExecuteCmd
setlocal
set _CMD_=%*
call %_CMD_%
if "%ERRORLEVEL%" NEQ "0" echo Failed exitCode=%ERRORLEVEL%, command=%_CMD_%
exit /b %ERRORLEVEL%
:error
endlocal
echo An error has occurred during web site deployment.
call :exitSetErrorLevel
call :exitFromFunction 2>nul
:exitSetErrorLevel
exit /b 1
:exitFromFunction
()
:end
endlocal
echo Finished successfully.

96
deploy.sh Normal file
View file

@ -0,0 +1,96 @@
#!/bin/bash
# ------------------------
# General Bots deployment.
# ------------------------
# Helpers
# -------
exitWithMessageOnError () {
if [ ! $? -eq 0 ]; then
echo "[General Bots Deployer]An error has occurred during web site deployment."
echo $1
exit 1
fi
}
# Prerequisites
# -------------
# Verify node.js installed
hash node 2>/dev/null
exitWithMessageOnError "Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment."
# Setup
# -----
SCRIPT_DIR="${BASH_SOURCE[0]%\\*}"
SCRIPT_DIR="${SCRIPT_DIR%/*}"
ARTIFACTS=$SCRIPT_DIR/../artifacts
KUDU_SYNC_CMD=${KUDU_SYNC_CMD//\"}
if [[ ! -n "$DEPLOYMENT_SOURCE" ]]; then
DEPLOYMENT_SOURCE=$SCRIPT_DIR
fi
if [[ ! -n "$NEXT_MANIFEST_PATH" ]]; then
NEXT_MANIFEST_PATH=$ARTIFACTS/manifest
if [[ ! -n "$PREVIOUS_MANIFEST_PATH" ]]; then
PREVIOUS_MANIFEST_PATH=$NEXT_MANIFEST_PATH
fi
fi
if [[ ! -n "$DEPLOYMENT_TARGET" ]]; then
DEPLOYMENT_TARGET=$ARTIFACTS/wwwroot
else
KUDU_SERVICE=true
fi
if [[ ! -n "$KUDU_SYNC_CMD" ]]; then
# Install kudu sync
echo Installing Kudu Sync
npm install kudusync -g --silent
exitWithMessageOnError "npm failed"
if [[ ! -n "$KUDU_SERVICE" ]]; then
# In case we are running locally this is the correct location of kuduSync
KUDU_SYNC_CMD=kuduSync
else
# In case we are running on kudu service this is the correct location of kuduSync
KUDU_SYNC_CMD=$APPDATA/npm/node_modules/kuduSync/bin/kuduSync
fi
fi
##################################################################################################################################
# Deployment
# ----------
# 1. Install npm packages
if [ -e "$DEPLOYMENT_SOURCE/package.json" ]; then
echo "[General Bots Deployer] Running npm install..."
cd "$DEPLOYMENT_SOURCE"
eval npm install
echo "[General Bots Deployer] OK."
exitWithMessageOnError "npm failed"
cd - > /dev/null
fi
# 2. Install TypeScript
echo "[General Bots Deployer] Transpiling..."
eval ./node_modules/typescript/bin/tsc -v
eval ./node_modules/typescript/bin/tsc -p "$DEPLOYMENT_SOURCE"
echo "[General Bots Deployer] OK."
# 4. KuduSync
if [[ "$IN_PLACE_DEPLOYMENT" -ne "1" ]]; then
"$KUDU_SYNC_CMD" -v 50 -f "$DEPLOYMENT_SOURCE" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.sh"
exitWithMessageOnError "Kudu Sync failed"
fi
##################################################################################################################################
echo "[General Bots Deployer] Finished successfully."

View file

@ -1,539 +0,0 @@
# General Bots Kubernetes Deployment Configuration
# This file contains the core deployment resources for running General Bots
# in a Kubernetes cluster.
#
# Usage:
# kubectl apply -f deployment.yaml
#
# Prerequisites:
# - Kubernetes cluster 1.24+
# - kubectl configured
# - Secrets created (see secrets.yaml)
# - PersistentVolumeClaim for data (optional)
---
apiVersion: v1
kind: Namespace
metadata:
name: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: namespace
---
# ConfigMap for non-sensitive configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: botserver-config
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: config
data:
# Server configuration
SERVER_HOST: "0.0.0.0"
SERVER_PORT: "8080"
# LLM configuration
LLM_SERVER_HOST: "0.0.0.0"
LLM_SERVER_PORT: "8081"
LLM_SERVER_CTX_SIZE: "4096"
LLM_SERVER_N_PREDICT: "1024"
LLM_SERVER_PARALLEL: "6"
LLM_SERVER_CONT_BATCHING: "true"
LLM_CACHE: "true"
LLM_CACHE_TTL: "3600"
# Embedding configuration
EMBEDDING_PORT: "8082"
# Multi-agent configuration
A2A_ENABLED: "true"
A2A_TIMEOUT: "30"
A2A_MAX_HOPS: "5"
# Memory configuration
USER_MEMORY_ENABLED: "true"
USER_MEMORY_MAX_KEYS: "1000"
EPISODIC_MEMORY_ENABLED: "true"
# Hybrid RAG configuration
RAG_HYBRID_ENABLED: "true"
RAG_DENSE_WEIGHT: "0.7"
RAG_SPARSE_WEIGHT: "0.3"
# Observability
OBSERVABILITY_ENABLED: "true"
OBSERVABILITY_METRICS_INTERVAL: "60"
# Sandbox configuration
SANDBOX_RUNTIME: "process" # Use 'lxc' or 'docker' if available
SANDBOX_TIMEOUT: "30"
SANDBOX_MEMORY_MB: "512"
---
# Main botserver Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: botserver
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: botserver
app.kubernetes.io/version: "6.1.1"
spec:
replicas: 3
selector:
matchLabels:
app: botserver
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: botserver
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: botserver
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: botserver
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
# Init container to wait for dependencies
initContainers:
- name: wait-for-postgres
image: busybox:1.35
command: ['sh', '-c', 'until nc -z postgres-service 5432; do echo waiting for postgres; sleep 2; done']
- name: wait-for-qdrant
image: busybox:1.35
command: ['sh', '-c', 'until nc -z qdrant-service 6333; do echo waiting for qdrant; sleep 2; done']
containers:
- name: botserver
image: generalbots/botserver:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: metrics
containerPort: 9090
protocol: TCP
envFrom:
- configMapRef:
name: botserver-config
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: botserver-secrets
key: database-url
- name: QDRANT_URL
valueFrom:
secretKeyRef:
name: botserver-secrets
key: qdrant-url
- name: LLM_KEY
valueFrom:
secretKeyRef:
name: botserver-secrets
key: llm-api-key
optional: true
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "2000m"
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 30
volumeMounts:
- name: data
mountPath: /data
- name: models
mountPath: /models
readOnly: true
- name: gbai-packages
mountPath: /packages
volumes:
- name: data
persistentVolumeClaim:
claimName: botserver-data
- name: models
persistentVolumeClaim:
claimName: llm-models
- name: gbai-packages
persistentVolumeClaim:
claimName: gbai-packages
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- botserver
topologyKey: kubernetes.io/hostname
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app: botserver
---
# LLM Server Deployment (for local model inference)
apiVersion: apps/v1
kind: Deployment
metadata:
name: llm-server
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: llm-server
spec:
replicas: 2
selector:
matchLabels:
app: llm-server
template:
metadata:
labels:
app: llm-server
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: llm-server
spec:
containers:
- name: llm-server
image: generalbots/llm-server:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8081
protocol: TCP
env:
- name: MODEL_PATH
value: "/models/DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf"
- name: CTX_SIZE
value: "4096"
- name: N_PREDICT
value: "1024"
- name: PARALLEL
value: "6"
- name: CONT_BATCHING
value: "true"
- name: GPU_LAYERS
value: "35" # Adjust based on available GPU memory
resources:
requests:
memory: "8Gi"
cpu: "2000m"
# Uncomment for GPU support
# nvidia.com/gpu: 1
limits:
memory: "24Gi"
cpu: "8000m"
# nvidia.com/gpu: 1
volumeMounts:
- name: models
mountPath: /models
readOnly: true
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 120
periodSeconds: 30
timeoutSeconds: 10
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
volumes:
- name: models
persistentVolumeClaim:
claimName: llm-models
# Schedule on nodes with GPU
# nodeSelector:
# nvidia.com/gpu.present: "true"
tolerations:
- key: "nvidia.com/gpu"
operator: "Exists"
effect: "NoSchedule"
---
# Service for botserver
apiVersion: v1
kind: Service
metadata:
name: botserver-service
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: service
spec:
type: ClusterIP
selector:
app: botserver
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
- name: metrics
port: 9090
targetPort: 9090
protocol: TCP
---
# Service for LLM server
apiVersion: v1
kind: Service
metadata:
name: llm-server-service
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: llm-service
spec:
type: ClusterIP
selector:
app: llm-server
ports:
- name: http
port: 8081
targetPort: 8081
protocol: TCP
---
# Headless service for StatefulSet-like DNS (if needed)
apiVersion: v1
kind: Service
metadata:
name: botserver-headless
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: headless-service
spec:
clusterIP: None
selector:
app: botserver
ports:
- name: http
port: 8080
targetPort: 8080
---
# Ingress for external access
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: botserver-ingress
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/websocket-services: "botserver-service"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- bot.example.com
secretName: botserver-tls
rules:
- host: bot.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: botserver-service
port:
number: 80
---
# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: botserver
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: serviceaccount
---
# Role for botserver
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: botserver-role
namespace: generalbots
rules:
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: botserver-rolebinding
namespace: generalbots
subjects:
- kind: ServiceAccount
name: botserver
namespace: generalbots
roleRef:
kind: Role
name: botserver-role
apiGroup: rbac.authorization.k8s.io
---
# PodDisruptionBudget for high availability
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: botserver-pdb
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: botserver
---
# PersistentVolumeClaim for botserver data
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: botserver-data
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: storage
spec:
accessModes:
- ReadWriteMany
storageClassName: standard
resources:
requests:
storage: 50Gi
---
# PersistentVolumeClaim for LLM models
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: llm-models
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: storage
spec:
accessModes:
- ReadOnlyMany
storageClassName: standard
resources:
requests:
storage: 100Gi
---
# PersistentVolumeClaim for .gbai packages
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gbai-packages
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: storage
spec:
accessModes:
- ReadWriteMany
storageClassName: standard
resources:
requests:
storage: 20Gi

View file

@ -1,331 +0,0 @@
# General Bots Kubernetes HorizontalPodAutoscaler Configuration
# This file contains autoscaling configurations for General Bots components.
#
# Usage:
# kubectl apply -f hpa.yaml
#
# Prerequisites:
# - Metrics Server installed in cluster
# - deployment.yaml already applied
---
# HPA for botserver - scales based on CPU and memory
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: botserver-hpa
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: botserver
minReplicas: 3
maxReplicas: 20
metrics:
# Scale based on CPU utilization
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
# Scale based on memory utilization
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
# Scale based on requests per second (requires custom metrics)
# Uncomment if using Prometheus Adapter
# - type: Pods
# pods:
# metric:
# name: http_requests_per_second
# target:
# type: AverageValue
# averageValue: 100
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 5 minutes cooldown before scaling down
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Min # Use the most conservative policy
scaleUp:
stabilizationWindowSeconds: 60 # 1 minute before scaling up
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
selectPolicy: Max # Scale up aggressively when needed
---
# HPA for LLM server - scales based on CPU (inference is CPU/GPU bound)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: llm-server-hpa
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: llm-server
minReplicas: 2
maxReplicas: 10
metrics:
# Scale based on CPU utilization
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # Lower threshold for LLM - inference is expensive
# Scale based on memory utilization
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
# Scale based on inference queue length (requires custom metrics)
# Uncomment if using Prometheus Adapter
# - type: Pods
# pods:
# metric:
# name: llm_inference_queue_length
# target:
# type: AverageValue
# averageValue: 5
behavior:
scaleDown:
stabilizationWindowSeconds: 600 # 10 minutes - LLM pods are expensive to recreate
policies:
- type: Pods
value: 1
periodSeconds: 120
selectPolicy: Min
scaleUp:
stabilizationWindowSeconds: 120 # 2 minutes
policies:
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Max
---
# HPA for embedding server (if deployed separately)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: embedding-server-hpa
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: embedding-server
minReplicas: 2
maxReplicas: 8
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
selectPolicy: Min
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 2
periodSeconds: 30
selectPolicy: Max
---
# Vertical Pod Autoscaler for botserver (optional - requires VPA installed)
# Automatically adjusts resource requests/limits
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: botserver-vpa
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: botserver
updatePolicy:
updateMode: "Auto" # Options: Off, Initial, Recreate, Auto
resourcePolicy:
containerPolicies:
- containerName: botserver
minAllowed:
cpu: 250m
memory: 512Mi
maxAllowed:
cpu: 4000m
memory: 8Gi
controlledResources: ["cpu", "memory"]
controlledValues: RequestsAndLimits
---
# Vertical Pod Autoscaler for LLM server
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: llm-server-vpa
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: llm-server
updatePolicy:
updateMode: "Off" # Manual for LLM - too disruptive to auto-update
resourcePolicy:
containerPolicies:
- containerName: llm-server
minAllowed:
cpu: 2000m
memory: 8Gi
maxAllowed:
cpu: 16000m
memory: 64Gi
controlledResources: ["cpu", "memory"]
controlledValues: RequestsOnly # Only adjust requests, not limits
---
# Custom metrics for HPA (requires Prometheus + Prometheus Adapter)
# This ServiceMonitor tells Prometheus to scrape botserver metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: botserver-metrics
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: monitoring
spec:
selector:
matchLabels:
app: botserver
endpoints:
- port: metrics
interval: 30s
path: /metrics
namespaceSelector:
matchNames:
- generalbots
---
# PrometheusRule for alerting on scaling events
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: botserver-scaling-alerts
namespace: generalbots
labels:
app.kubernetes.io/name: generalbots
app.kubernetes.io/component: alerts
spec:
groups:
- name: botserver-scaling
rules:
# Alert when approaching max replicas
- alert: BotserverNearMaxReplicas
expr: |
kube_horizontalpodautoscaler_status_current_replicas{horizontalpodautoscaler="botserver-hpa"}
/ kube_horizontalpodautoscaler_spec_max_replicas{horizontalpodautoscaler="botserver-hpa"}
> 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Botserver near maximum replicas"
description: "Botserver HPA is at {{ $value | humanizePercentage }} of max replicas"
# Alert when at max replicas
- alert: BotserverAtMaxReplicas
expr: |
kube_horizontalpodautoscaler_status_current_replicas{horizontalpodautoscaler="botserver-hpa"}
== kube_horizontalpodautoscaler_spec_max_replicas{horizontalpodautoscaler="botserver-hpa"}
for: 10m
labels:
severity: critical
annotations:
summary: "Botserver at maximum replicas"
description: "Botserver HPA has been at max replicas for 10 minutes - consider increasing max"
# Alert on rapid scaling
- alert: BotserverRapidScaling
expr: |
increase(kube_horizontalpodautoscaler_status_current_replicas{horizontalpodautoscaler="botserver-hpa"}[10m])
> 5
for: 1m
labels:
severity: warning
annotations:
summary: "Botserver scaling rapidly"
description: "Botserver has scaled by {{ $value }} replicas in 10 minutes"
# Alert on LLM server max replicas
- alert: LLMServerAtMaxReplicas
expr: |
kube_horizontalpodautoscaler_status_current_replicas{horizontalpodautoscaler="llm-server-hpa"}
== kube_horizontalpodautoscaler_spec_max_replicas{horizontalpodautoscaler="llm-server-hpa"}
for: 5m
labels:
severity: critical
annotations:
summary: "LLM Server at maximum replicas"
description: "LLM Server HPA is at max - inference capacity may be constrained"

View file

@ -1,5 +0,0 @@
[migrations_directory]
dir = "migrations"
[print_schema]
file = "src/shared/schema.rs"

1263
directline-v2.json Normal file

File diff suppressed because one or more lines are too long

1
docs/_config.yml Normal file
View file

@ -0,0 +1 @@
theme: jekyll-theme-minimal

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
window.searchData = {"kinds":{"128":"Class","512":"Constructor","1024":"Property","2048":"Method"},"rows":[{"id":0,"kind":128,"name":"RootData","url":"classes/rootdata.html","classes":"tsd-kind-class"},{"id":1,"kind":512,"name":"constructor","url":"classes/rootdata.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"RootData"},{"id":2,"kind":1024,"name":"publicAddress","url":"classes/rootdata.html#publicaddress","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":3,"kind":1024,"name":"server","url":"classes/rootdata.html#server","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":4,"kind":1024,"name":"sysPackages","url":"classes/rootdata.html#syspackages","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":5,"kind":1024,"name":"appPackages","url":"classes/rootdata.html#apppackages","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":6,"kind":1024,"name":"minService","url":"classes/rootdata.html#minservice","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":7,"kind":1024,"name":"bootInstance","url":"classes/rootdata.html#bootinstance","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":8,"kind":1024,"name":"minInstances","url":"classes/rootdata.html#mininstances","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":9,"kind":1024,"name":"minBoot","url":"classes/rootdata.html#minboot","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":10,"kind":1024,"name":"wwwroot","url":"classes/rootdata.html#wwwroot","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":11,"kind":1024,"name":"entryPointDialog","url":"classes/rootdata.html#entrypointdialog","classes":"tsd-kind-property tsd-parent-kind-class","parent":"RootData"},{"id":12,"kind":128,"name":"GBServer","url":"classes/gbserver.html","classes":"tsd-kind-class"},{"id":13,"kind":1024,"name":"globals","url":"classes/gbserver.html#globals","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-static","parent":"GBServer"},{"id":14,"kind":2048,"name":"run","url":"classes/gbserver.html#run","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"GBServer"},{"id":15,"kind":512,"name":"constructor","url":"classes/gbserver.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"GBServer"}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,3.075]],["parent/0",[]],["name/1",[1,19.169]],["parent/1",[0,0.291]],["name/2",[2,24.277]],["parent/2",[0,0.291]],["name/3",[3,24.277]],["parent/3",[0,0.291]],["name/4",[4,24.277]],["parent/4",[0,0.291]],["name/5",[5,24.277]],["parent/5",[0,0.291]],["name/6",[6,24.277]],["parent/6",[0,0.291]],["name/7",[7,24.277]],["parent/7",[0,0.291]],["name/8",[8,24.277]],["parent/8",[0,0.291]],["name/9",[9,24.277]],["parent/9",[0,0.291]],["name/10",[10,24.277]],["parent/10",[0,0.291]],["name/11",[11,24.277]],["parent/11",[0,0.291]],["name/12",[12,13.291]],["parent/12",[]],["name/13",[13,24.277]],["parent/13",[12,1.256]],["name/14",[14,24.277]],["parent/14",[12,1.256]],["name/15",[1,19.169]],["parent/15",[12,1.256]]],"invertedIndex":[["apppackages",{"_index":5,"name":{"5":{}},"parent":{}}],["bootinstance",{"_index":7,"name":{"7":{}},"parent":{}}],["constructor",{"_index":1,"name":{"1":{},"15":{}},"parent":{}}],["entrypointdialog",{"_index":11,"name":{"11":{}},"parent":{}}],["gbserver",{"_index":12,"name":{"12":{}},"parent":{"13":{},"14":{},"15":{}}}],["globals",{"_index":13,"name":{"13":{}},"parent":{}}],["minboot",{"_index":9,"name":{"9":{}},"parent":{}}],["mininstances",{"_index":8,"name":{"8":{}},"parent":{}}],["minservice",{"_index":6,"name":{"6":{}},"parent":{}}],["publicaddress",{"_index":2,"name":{"2":{}},"parent":{}}],["rootdata",{"_index":0,"name":{"0":{}},"parent":{"1":{},"2":{},"3":{},"4":{},"5":{},"6":{},"7":{},"8":{},"9":{},"10":{},"11":{}}}],["run",{"_index":14,"name":{"14":{}},"parent":{}}],["server",{"_index":3,"name":{"3":{}},"parent":{}}],["syspackages",{"_index":4,"name":{"4":{}},"parent":{}}],["wwwroot",{"_index":10,"name":{"10":{}},"parent":{}}]],"pipeline":[]}}

213
docs/reference/index.html Normal file
View file

@ -0,0 +1,213 @@
<!doctype html>
<html class="default no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>General Bots Open Core</title>
<meta name="description" content="Documentation for General Bots Open Core">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/css/main.css">
<script async src="assets/js/search.js" id="search-script"></script>
</head>
<body>
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-index="assets/js/search.json" data-base=".">
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
<input id="tsd-search-field" type="text" />
</div>
<ul class="results">
<li class="state loading">Preparing search index...</li>
<li class="state failure">The search index is not available</li>
</ul>
<a href="index.html" class="title">General Bots Open Core</a>
</div>
<div class="table-cell" id="tsd-widgets">
<div id="tsd-filter">
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
<div class="tsd-filter-group">
<div class="tsd-select" id="tsd-filter-visibility">
<span class="tsd-select-label">All</span>
<ul class="tsd-select-list">
<li data-value="public">Public</li>
<li data-value="protected">Public/Protected</li>
<li data-value="private" class="selected">All</li>
</ul>
</div>
<input type="checkbox" id="tsd-filter-inherited" checked />
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
<input type="checkbox" id="tsd-filter-externals" checked />
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
</div>
</div>
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
</div>
</div>
</div>
</div>
<div class="tsd-page-title">
<div class="container">
<h1>General Bots Open Core</h1>
</div>
</div>
</header>
<div class="container container-main">
<div class="row">
<div class="col-8 col-content">
<div class="tsd-panel tsd-typography">
<table>
<thead>
<tr>
<th>Area</th>
<th>Status</th>
</tr>
</thead>
<tbody><tr>
<td>Releases</td>
<td><a href="https://www.npmjs.com/package/botserver/"><img src="https://img.shields.io/npm/dt/botserver.svg?logo=npm&label=botserver" alt="General Bots"></a> <a href="https://www.npmjs.com/package/botlib/"><img src="https://img.shields.io/npm/dt/botlib.svg?logo=npm&label=botlib" alt=".gbapp lib"></a> <a href="https://github.com/semantic-release/semantic-release"><img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg" alt="semantic-release"></a></td>
</tr>
<tr>
<td>Community</td>
<td><a href="https://stackoverflow.com/questions/tagged/generalbots"><img src="https://img.shields.io/stackexchange/stackoverflow/t/generalbots.svg" alt="StackExchange"></a> <a href="https://badges.frapsoft.com"><img src="https://badges.frapsoft.com/os/v2/open-source.svg" alt="Open-source"></a> <a href="http://makeapullrequest.com"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square" alt="PRs Welcome"></a> <a href="https://github.com/GeneralBots/BotServer/blob/master/LICENSE.txt"><img src="https://img.shields.io/badge/license-AGPL-blue.svg" alt="License"></a></td>
</tr>
<tr>
<td>Management</td>
<td><a href="https://gitHub.com/GeneralBots/BotServer/graphs/commit-activity"><img src="https://img.shields.io/badge/Maintained%3F-yes-green.svg" alt="Maintenance"></a></td>
</tr>
<tr>
<td>Security</td>
<td><a href="https://snyk.io/test/github/GeneralBots/BotServer"><img src="https://snyk.io/test/github/GeneralBots/BotServer/badge.svg" alt="Known Vulnerabilities"></a></td>
</tr>
<tr>
<td>Building &amp; Quality</td>
<td><a href="https://travis-ci.com/GeneralBots/BotServer"><img src="https://travis-ci.com/GeneralBots/BotServer.svg?branch=master" alt="Build Status"></a> <a href="https://coveralls.io/github/GeneralBots/BotServer"><img src="https://coveralls.io/repos/github/GeneralBots/BotServer/badge.svg" alt="Coverage Status"></a> <a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square" alt="code style: prettier"></a></td>
</tr>
<tr>
<td>Packaging</td>
<td><a href="https://badge.fury.io"><img src="https://badge.fury.io/js/botserver.svg" alt="forthebadge"></a> <a href="https://github.com/GeneralBots/BotServer/releases/latest"><img src="https://camo.githubusercontent.com/0150c0f148d50fe9750ebc5d313581da699a8c50/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7a69702d646f776e6c6f61642d626c75652e737667" alt="ZipFile"></a> <a href="https://david-dm.org"><img src="https://david-dm.org/GeneralBots/botserver.svg" alt="Dependencies"></a> <a href="http://commitizen.github.io/cz-cli/"><img src="https://img.shields.io/badge/commitizen-friendly-brightgreen.svg" alt="Commitizen friendly"></a></td>
</tr>
<tr>
<td>Samples</td>
<td><a href="https://github.com/GeneralBots/BotServer/tree/master/packages/default.gbdialog">VBA</a> or <a href="https://github.com/GeneralBots/AzureADPasswordReset.gbapp"><img src="https://badges.frapsoft.com/typescript/code/typescript.svg?v=101" alt="TypeScript"></a></td>
</tr>
<tr>
<td><a href="https://github.com/lpicanco/docker-botserver">Docker Image</a></td>
<td><img src="https://img.shields.io/docker/automated/lpicanco/botserver.svg" alt="Docker Automated build"> <img src="https://img.shields.io/docker/build/lpicanco/botserver.svg" alt="Docker Build Status"> <img src="https://img.shields.io/microbadger/image-size/lpicanco/botserver.svg" alt="MicroBadger Size"> <img src="https://img.shields.io/microbadger/layers/lpicanco/botserver.svg" alt="MicroBadger Layers"> <img src="https://img.shields.io/docker/pulls/lpicanco/botserver.svg" alt="Docker Pulls"> <br/> <em>Provided by <a href="https://github.com/lpicanco/docker-botserver">@lpicanco</a></em></td>
</tr>
</tbody></table>
<a href="#general-bots" id="general-bots" style="color: inherit; text-decoration: none;">
<h2>General Bots</h2>
</a>
<p><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/logo.png" alt="General Bot Logo"></p>
<p>General Bot is a strongly typed package based chat bot server focused in convention over configuration and code-less approaches, which brings software packages and application server concepts to help parallel bot development.</p>
<a href="#what-is-a-bot-server" id="what-is-a-bot-server" style="color: inherit; text-decoration: none;">
<h2>What is a Bot Server?</h2>
</a>
<p>Bot Server accelerates the process of developing a bot. It provisions all code
base, resources and deployment to the cloud, and gives you templates you can
choose from whenever you need a new bot. The server has a database and service
backend allowing you to further modify your bot package directly by downloading
a zip file, editing and uploading it back to the server (deploying process) with
no code. The Bot Server also provides a framework to develop bot packages in a more
advanced fashion writing custom code in editors like Visual Studio Code, Atom or Brackets.</p>
<p>Everyone can create bots by just copying and pasting some files and using their
favorite tools from Office (or any text editor) or Photoshop (or any image
editor). BASIC can be used to build custom dialogs so Bot can be extended just like VBA for Excel (currently in alpha).</p>
<p><img src="https://raw.githubusercontent.com/GeneralBots/BotBook/master/images/general-bots-reference-architecture.png" alt="General Bot Reference Architecture"></p>
<a href="#samples" id="samples" style="color: inherit; text-decoration: none;">
<h2>Samples</h2>
</a>
<p>Several samples, including a Bot for AD Password Reset, are avaiable on the <a href="https://github.com/GeneralBots">repository list</a>.</p>
<a href="#guide" id="guide" style="color: inherit; text-decoration: none;">
<h2>Guide</h2>
</a>
<p><a href="https://github.com/GeneralBots/BotBook/tree/master/book">Read the General Bots BotBook Guide</a>.</p>
<a href="#videos" id="videos" style="color: inherit; text-decoration: none;">
<h1>Videos</h1>
</a>
<p>Now with the General Bots server you can press F5 on Visual Studio to get a bot factory on your environment* published on November 10th, 2018.</p>
<p><a href="https://www.youtube.com/watch?v=AfKTwljoMOs"><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/video-01-thumb.jpg" alt="General Bot Video"></a></p>
<p>See how easy is to use &#39;hear&#39; and &#39;talk&#39; to build Microsoft BOT Framework v4 logic with plain BASIC * published on December 3rd, 2018.</p>
<p><a href="https://www.youtube.com/watch?v=yX1sF9n9628"><img src="https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/video-02-thumb.jpg" alt="See how easy is to use &#39;hear&#39; and &#39;talk&#39; to build Microsoft BOT Framework v4 logic with plain BASIC"></a></p>
<a href="#contributing" id="contributing" style="color: inherit; text-decoration: none;">
<h1>Contributing</h1>
</a>
<p>This project welcomes contributions and suggestions.
See our <a href="https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md">Contribution Guidelines</a> for more details.</p>
<a href="#reporting-security-issues" id="reporting-security-issues" style="color: inherit; text-decoration: none;">
<h1>Reporting Security Issues</h1>
</a>
<p>Security issues and bugs should be reported privately, via email, to the Pragmatismo.io Security
team at <a href="mailto:security@pragmatismo.io">security@pragmatismo.io</a>. You should
receive a response within 24 hours. If for some reason you do not, please follow up via
email to ensure we received your original message. </p>
<a href="#license-amp-warranty" id="license-amp-warranty" style="color: inherit; text-decoration: none;">
<h1>License &amp; Warranty</h1>
</a>
<p>General Bot Copyright (c) Pragmatismo.io. All rights reserved.
Licensed under the AGPL-3.0. </p>
<p>According to our dual licensing model, this program can be used either
under the terms of the GNU Affero General Public License, version 3,
or under a proprietary license. </p>
<p>The texts of the GNU Affero General Public License with an additional
permission and of our proprietary license can be found at and
in the LICENSE file you have received along with this program.</p>
<p>This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.</p>
<p>&quot;General Bot&quot; is a registered trademark of Pragmatismo.io.
The licensing of the program under the AGPLv3 does not imply a
trademark license. Therefore any rights, title and interest in
our trademarks remain entirely with us.</p>
<p><a href="https://stackoverflow.com/questions/ask?tags=generalbots">:speech_balloon: Ask a question</a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="https://github.com/GeneralBots/BotBook">:book: Read the Docs</a></p>
<p>General Bots Code Name is <a href="https://en.wikipedia.org/wiki/Guaribas">Guaribas</a>, the name of a city in Brazil, state of Piaui.
<a href="http://www.robertounger.com/en/">Roberto Mangabeira Unger</a>: &quot;No one should have to do work that can be done by a machine&quot;.</p>
</div>
</div>
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
<nav class="tsd-navigation primary">
<ul>
<li class=" ">
<a href="modules.html">Exports</a>
</li>
</ul>
</nav>
<nav class="tsd-navigation secondary menu-sticky">
<ul class="before-current">
<li class=" tsd-kind-class">
<a href="classes/gbserver.html" class="tsd-kind-icon">GBServer</a>
</li>
<li class=" tsd-kind-class">
<a href="classes/rootdata.html" class="tsd-kind-icon">Root<wbr>Data</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<footer class="with-border-bottom">
<div class="container">
<h2>Legend</h2>
<div class="tsd-legend-group">
<ul class="tsd-legend">
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
</ul>
<ul class="tsd-legend">
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
</ul>
</div>
</div>
</footer>
<div class="container tsd-generator">
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
</div>
<div class="overlay"></div>
<script src="assets/js/main.js"></script>
</body>
</html>

382
extensions.json Normal file
View file

@ -0,0 +1,382 @@
[
{
"extension": "aac",
"description": "AAC audio",
"category": "Music"
},
{
"extension": "abw",
"description": "AbiWord document",
"category": "Document"
},
{
"extension": "arc",
"description": "Archive document (multiple files embedded)",
"category": "Document"
},
{
"extension": "avif",
"description": "AVIF image",
"category": "Image"
},
{
"extension": "avi",
"description": "AVI: Audio Video Interleave",
"category": "Movie"
},
{
"extension": "azw",
"description": "Amazon Kindle eBook format",
"category": "Document"
},
{
"extension": "bin",
"description": "Any kind of binary data",
"category": "Other"
},
{
"extension": "bmp",
"description": "Windows OS/2 Bitmap Graphics",
"category": "Image"
},
{
"extension": "bz",
"description": "BZip archive",
"category": "Other"
},
{
"extension": "bz2",
"description": "BZip2 archive",
"category": "Other"
},
{
"extension": "cda",
"description": "CD audio",
"category": "Music"
},
{
"extension": "csh",
"description": "C-Shell script",
"category": "Executable"
},
{
"extension": "css",
"description": "Cascading Style Sheets (CSS)",
"category": "Other"
},
{
"extension": "csv",
"description": "Comma-separated values (CSV)",
"category": "Document"
},
{
"extension": "doc",
"description": "Microsoft Word",
"category": "Document"
},
{
"extension": "docx",
"description": "Microsoft Word (OpenXML)",
"category": "Document"
},
{
"extension": "eot",
"description": "MS Embedded OpenType fonts",
"category": "Other"
},
{
"extension": "epub",
"description": "Electronic publication (EPUB)",
"category": "Document"
},
{
"extension": "gz",
"description": "GZip Compressed Archive",
"category": "Other"
},
{
"extension": "gif",
"description": "Graphics Interchange Format (GIF)",
"category": "Image"
},
{
"extension": "htm",
"description": "HyperText Markup Language (HTML)",
"category": "Other"
},
{
"extension": "html",
"description": "HyperText Markup Language (HTML)",
"category": "Other"
},
{
"extension": "ico",
"description": "Icon format",
"category": "Image"
},
{
"extension": "ics",
"description": "iCalendar format",
"category": "Document"
},
{
"extension": "jar",
"description": "Java Archive (JAR)",
"category": "Executable"
},
{
"extension": "jpeg",
"description": "JPEG images",
"category": "Image"
},
{
"extension": "jpg",
"description": "JPEG images",
"category": "Image"
},
{
"extension": "js",
"description": "JavaScript",
"category": "Other"
},
{
"extension": "json",
"description": "JSON format",
"category": "Other"
},
{
"extension": "jsonld",
"description": "JSON-LD format",
"category": "Other"
},
{
"extension": "mid",
"description": "Musical Instrument Digital Interface (MIDI)",
"category": "Music"
},
{
"extension": "midi",
"description": "Musical Instrument Digital Interface (MIDI)",
"category": "Music"
},
{
"extension": "mjs",
"description": "JavaScript module",
"category": "Other"
},
{
"extension": "mp3",
"description": "MP3 audio",
"category": "Music"
},
{
"extension": "mp4",
"description": "MP4 video",
"category": "Movie"
},
{
"extension": "mpeg",
"description": "MPEG Video",
"category": "Movie"
},
{
"extension": "mpkg",
"description": "Apple Installer Package",
"category": "Application"
},
{
"extension": "odp",
"description": "OpenDocument presentation document",
"category": "Presentation"
},
{
"extension": "ods",
"description": "OpenDocument spreadsheet document",
"category": "Document"
},
{
"extension": "odt",
"description": "OpenDocument text document",
"category": "Document"
},
{
"extension": "oga",
"description": "OGG audio",
"category": "Music"
},
{
"extension": "ogv",
"description": "OGG video",
"category": "Movie"
},
{
"extension": "ogx",
"description": "OGG",
"category": "Other"
},
{
"extension": "opus",
"description": "Opus audio",
"category": "Music"
},
{
"extension": "otf",
"description": "OpenType font",
"category": "Other"
},
{
"extension": "png",
"description": "Portable Network Graphics",
"category": "Image"
},
{
"extension": "pdf",
"description": "Adobe Portable Document Format (PDF)",
"category": "PDF"
},
{
"extension": "php",
"description": "Hypertext Preprocessor (Personal Home Page)",
"category": "Other"
},
{
"extension": "ppt",
"description": "Microsoft PowerPoint",
"category": "Presentation"
},
{
"extension": "pptx",
"description": "Microsoft PowerPoint (OpenXML)",
"category": "Presentation"
},
{
"extension": "rar",
"description": "RAR archive",
"category": "Other"
},
{
"extension": "rtf",
"description": "Rich Text Format (RTF)",
"category": "Document"
},
{
"extension": "sh",
"description": "Bourne shell script",
"category": "Executable"
},
{
"extension": "svg",
"description": "Scalable Vector Graphics (SVG)",
"category": "Image"
},
{
"extension": "tar",
"description": "Tape Archive (TAR)",
"category": "Other"
},
{
"extension": "tif",
"description": "Tagged Image File Format (TIFF)",
"category": "Image"
},
{
"extension": "tiff",
"description": "Tagged Image File Format (TIFF)",
"category": "Image"
},
{
"extension": "ts",
"description": "MPEG transport stream",
"category": "Movie"
},
{
"extension": "ttf",
"description": "TrueType Font",
"category": "Other"
},
{
"extension": "txt",
"description": "Text, (generally ASCII or ISO 8859-n)",
"category": "Text"
},
{
"extension": "vsd",
"description": "Microsoft Visio",
"category": "Application"
},
{
"extension": "wav",
"description": "Waveform Audio Format",
"category": "Music"
},
{
"extension": "weba",
"description": "WEBM audio",
"category": "Music"
},
{
"extension": "webm",
"description": "WEBM video",
"category": "Movie"
},
{
"extension": "webp",
"description": "WEBP image",
"category": "Image"
},
{
"extension": "woff",
"description": "Web Open Font Format (WOFF)",
"category": "Other"
},
{
"extension": "woff2",
"description": "Web Open Font Format (WOFF)",
"category": "Other"
},
{
"extension": "xhtml",
"description": "XHTML",
"category": "Other"
},
{
"extension": "xls",
"description": "Microsoft Excel",
"category": "Document"
},
{
"extension": "xlsx",
"description": "Microsoft Excel (OpenXML)",
"category": "Document"
},
{
"extension": "xml",
"description": "XML",
"category": "Document"
},
{
"extension": "xul",
"description": "XUL",
"category": "Application"
},
{
"extension": "zip",
"description": "ZIP archive",
"category": "Application"
},
{
"extension": "3gp",
"description": "3GPP audio/video container",
"category": "Movie"
},
{
"extension": "3g2",
"description": "3GPP2 audio/video container",
"category": "Movie"
},
{
"extension": "7z",
"description": "7-zip archive",
"category": "Application"
}
]

View file

@ -1,98 +0,0 @@
#!/bin/bash
set -e # Exit on error
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$SCRIPT_DIR"
OUTPUT_FILE="/tmp/prompt.out"
# Check required commands
command -v cargo >/dev/null 2>&1 || { echo "cargo is required but not installed" >&2; exit 1; }
command -v xclip >/dev/null 2>&1 || { echo "xclip is required but not installed" >&2; exit 1; }
echo "Please, fix this consolidated LLM Context" > "$OUTPUT_FILE"
prompts=(
"./prompts/dev/platform/fix-errors.md"
"./prompts/dev/platform/shared.md"
"./Cargo.toml"
)
# Validate files exist
for file in "${prompts[@]}"; do
if [ ! -f "$file" ]; then
echo "Required file not found: $file" >&2
exit 1
fi
done
for file in "${prompts[@]}"; do
cat "$file" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
done
dirs=(
# "auth"
# "automation"
#"basic"
# "bot"
"bootstrap"
# "package_manager"
# "channels"
# "config"
# "context"
# "email"
# "file"
# "llm"
"drive_monitor"
# "llm_legacy"
# "org"
# "session"
"file"
"kb"
"shared"
#"tests"
# "tools"
# "web_automation"
# "whatsapp"
)
for dir in "${dirs[@]}"; do
if [ -d "$PROJECT_ROOT/src/$dir" ]; then
find "$PROJECT_ROOT/src/$dir" -name "*.rs" | while read -r file; do
if [ -f "$file" ]; then
echo "$file" >> "$OUTPUT_FILE"
cat "$file" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
fi
done
fi
done
# Also append the specific files you mentioned
echo "$PROJECT_ROOT/src/main.rs" >> "$OUTPUT_FILE"
cat "$PROJECT_ROOT/src/main.rs" >> "$OUTPUT_FILE"
echo "$PROJECT_ROOT/src/basic/keywords/get.rs" >> "$OUTPUT_FILE"
cat "$PROJECT_ROOT/src/basic/keywords/get.rs" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
echo "Compiling..."
cargo build --message-format=short 2>&1 | grep -E 'error' >> "$OUTPUT_FILE"
# Calculate and display token count (approximation: words * 1.3)
WORD_COUNT=$(wc -w < "$OUTPUT_FILE") || { echo "Error counting words" >&2; exit 1; }
TOKEN_COUNT=$(echo "$WORD_COUNT * 1.3 / 1" | bc) || { echo "Error calculating tokens" >&2; exit 1; }
FILE_SIZE=$(wc -c < "$OUTPUT_FILE") || { echo "Error getting file size" >&2; exit 1; }
echo "" >> "$OUTPUT_FILE"
echo "Approximate token count: $TOKEN_COUNT"
echo "Context size: $FILE_SIZE bytes"
if ! cat "$OUTPUT_FILE" | xclip -selection clipboard; then
echo "Error copying to clipboard" >&2
exit 1
fi
echo "Content copied to clipboard (xclip)"
rm -f "$OUTPUT_FILE"

15
gbot.cmd Normal file
View file

@ -0,0 +1,15 @@
@ECHO off
ECHO General Bots Command Line
IF EXIST node_modules goto COMPILE
ECHO Installing Packages for the first time use (it may take several minutes)...
CALL npm install --silent
:COMPILE
IF EXIST dist goto ALLSET
ECHO Compiling...
npm run build
:ALLSET
npm run start

2
gbot.sh Executable file
View file

@ -0,0 +1,2 @@
echo Starting General Bots...
npm run start

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
{}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

10
greenkeeper.json Normal file
View file

@ -0,0 +1,10 @@
{
"groups": {
"default": {
"packages": [
"package.json",
"packages/default.gbui/package.json"
]
}
}
}

View file

@ -1,12 +0,0 @@
DROP TABLE public.usage_analytics;
DROP TABLE public.message_history;
DROP TABLE public.context_injections;
DROP TABLE public.whatsapp_numbers;
DROP TABLE public.user_sessions;
DROP TABLE public.bot_channels;
DROP TABLE public.users;
DROP TABLE public.tools;
DROP TABLE public.system_automations;
DROP TABLE public.organizations;
DROP TABLE public.clicks;
DROP TABLE public.bots;

View file

@ -1,242 +0,0 @@
CREATE TABLE public.bots (
id uuid DEFAULT gen_random_uuid() NOT NULL,
"name" varchar(255) NOT NULL,
description text NULL,
llm_provider varchar(100) NOT NULL,
llm_config jsonb DEFAULT '{}'::jsonb NOT NULL,
context_provider varchar(100) NOT NULL,
context_config jsonb DEFAULT '{}'::jsonb NOT NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
is_active bool DEFAULT true NULL,
CONSTRAINT bots_pkey PRIMARY KEY (id)
);
-- public.clicks definition
-- Drop table
-- DROP TABLE public.clicks;
CREATE TABLE public.clicks (
campaign_id text NOT NULL,
email text NOT NULL,
updated_at timestamptz DEFAULT now() NULL,
CONSTRAINT clicks_campaign_id_email_key UNIQUE (campaign_id, email)
);
-- public.organizations definition
-- Drop table
-- DROP TABLE public.organizations;
CREATE TABLE public.organizations (
org_id uuid DEFAULT gen_random_uuid() NOT NULL,
"name" varchar(255) NOT NULL,
slug varchar(255) NOT NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT organizations_pkey PRIMARY KEY (org_id),
CONSTRAINT organizations_slug_key UNIQUE (slug)
);
CREATE INDEX idx_organizations_created_at ON public.organizations USING btree (created_at);
CREATE INDEX idx_organizations_slug ON public.organizations USING btree (slug);
-- public.system_automations definition
-- Drop table
-- DROP TABLE public.system_automations;
CREATE TABLE public.system_automations (
id uuid DEFAULT gen_random_uuid() NOT NULL,
bot_id uuid NOT NULL,
kind int4 NOT NULL,
"target" varchar(32) NULL,
schedule bpchar(20) NULL,
param varchar(32) NOT NULL,
is_active bool DEFAULT true NOT NULL,
last_triggered timestamptz NULL,
created_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT system_automations_pkey PRIMARY KEY (id)
);
CREATE INDEX idx_system_automations_active ON public.system_automations USING btree (kind) WHERE is_active;
-- public.tools definition
-- Drop table
-- DROP TABLE public.tools;
CREATE TABLE public.tools (
id uuid DEFAULT gen_random_uuid() NOT NULL,
"name" varchar(255) NOT NULL,
description text NOT NULL,
parameters jsonb DEFAULT '{}'::jsonb NOT NULL,
script text NOT NULL,
is_active bool DEFAULT true NULL,
created_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT tools_name_key UNIQUE (name),
CONSTRAINT tools_pkey PRIMARY KEY (id)
);
-- public.users definition
-- Drop table
-- DROP TABLE public.users;
CREATE TABLE public.users (
id uuid DEFAULT gen_random_uuid() NOT NULL,
username varchar(255) NOT NULL,
email varchar(255) NOT NULL,
password_hash varchar(255) NOT NULL,
phone_number varchar(50) NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
is_active bool DEFAULT true NULL,
CONSTRAINT users_email_key UNIQUE (email),
CONSTRAINT users_pkey PRIMARY KEY (id),
CONSTRAINT users_username_key UNIQUE (username)
);
-- public.bot_channels definition
-- Drop table
-- DROP TABLE public.bot_channels;
CREATE TABLE public.bot_channels (
id uuid DEFAULT gen_random_uuid() NOT NULL,
bot_id uuid NOT NULL,
channel_type int4 NOT NULL,
config jsonb DEFAULT '{}'::jsonb NOT NULL,
is_active bool DEFAULT true NULL,
created_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT bot_channels_bot_id_channel_type_key UNIQUE (bot_id, channel_type),
CONSTRAINT bot_channels_pkey PRIMARY KEY (id),
CONSTRAINT bot_channels_bot_id_fkey FOREIGN KEY (bot_id) REFERENCES public.bots(id) ON DELETE CASCADE
);
CREATE INDEX idx_bot_channels_type ON public.bot_channels USING btree (channel_type) WHERE is_active;
-- public.user_sessions definition
-- Drop table
-- DROP TABLE public.user_sessions;
CREATE TABLE public.user_sessions (
id uuid DEFAULT gen_random_uuid() NOT NULL,
user_id uuid NOT NULL,
bot_id uuid NOT NULL,
title varchar(500) DEFAULT 'New Conversation'::character varying NOT NULL,
answer_mode int4 DEFAULT 0 NOT NULL,
context_data jsonb DEFAULT '{}'::jsonb NOT NULL,
current_tool varchar(255) NULL,
message_count int4 DEFAULT 0 NOT NULL,
total_tokens int4 DEFAULT 0 NOT NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
last_activity timestamptz DEFAULT now() NOT NULL,
CONSTRAINT user_sessions_pkey PRIMARY KEY (id),
CONSTRAINT user_sessions_bot_id_fkey FOREIGN KEY (bot_id) REFERENCES public.bots(id) ON DELETE CASCADE,
CONSTRAINT user_sessions_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE
);
CREATE INDEX idx_user_sessions_updated_at ON public.user_sessions USING btree (updated_at);
CREATE INDEX idx_user_sessions_user_bot ON public.user_sessions USING btree (user_id, bot_id);
-- public.whatsapp_numbers definition
-- Drop table
-- DROP TABLE public.whatsapp_numbers;
CREATE TABLE public.whatsapp_numbers (
id uuid DEFAULT gen_random_uuid() NOT NULL,
bot_id uuid NOT NULL,
phone_number varchar(50) NOT NULL,
is_active bool DEFAULT true NULL,
created_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT whatsapp_numbers_phone_number_bot_id_key UNIQUE (phone_number, bot_id),
CONSTRAINT whatsapp_numbers_pkey PRIMARY KEY (id),
CONSTRAINT whatsapp_numbers_bot_id_fkey FOREIGN KEY (bot_id) REFERENCES public.bots(id) ON DELETE CASCADE
);
-- public.context_injections definition
-- Drop table
-- DROP TABLE public.context_injections;
CREATE TABLE public.context_injections (
id uuid DEFAULT gen_random_uuid() NOT NULL,
session_id uuid NOT NULL,
injected_by uuid NOT NULL,
context_data jsonb NOT NULL,
reason text NULL,
created_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT context_injections_pkey PRIMARY KEY (id),
CONSTRAINT context_injections_injected_by_fkey FOREIGN KEY (injected_by) REFERENCES public.users(id) ON DELETE CASCADE,
CONSTRAINT context_injections_session_id_fkey FOREIGN KEY (session_id) REFERENCES public.user_sessions(id) ON DELETE CASCADE
);
-- public.message_history definition
-- Drop table
-- DROP TABLE public.message_history;
CREATE TABLE public.message_history (
id uuid DEFAULT gen_random_uuid() NOT NULL,
session_id uuid NOT NULL,
user_id uuid NOT NULL,
"role" int4 NOT NULL,
content_encrypted text NOT NULL,
message_type int4 DEFAULT 0 NOT NULL,
media_url text NULL,
token_count int4 DEFAULT 0 NOT NULL,
processing_time_ms int4 NULL,
llm_model varchar(100) NULL,
created_at timestamptz DEFAULT now() NOT NULL,
message_index int4 NOT NULL,
CONSTRAINT message_history_pkey PRIMARY KEY (id),
CONSTRAINT message_history_session_id_fkey FOREIGN KEY (session_id) REFERENCES public.user_sessions(id) ON DELETE CASCADE,
CONSTRAINT message_history_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE
);
CREATE INDEX idx_message_history_created_at ON public.message_history USING btree (created_at);
CREATE INDEX idx_message_history_session_id ON public.message_history USING btree (session_id);
-- public.usage_analytics definition
-- Drop table
-- DROP TABLE public.usage_analytics;
CREATE TABLE public.usage_analytics (
id uuid DEFAULT gen_random_uuid() NOT NULL,
user_id uuid NOT NULL,
bot_id uuid NOT NULL,
session_id uuid NOT NULL,
"date" date DEFAULT CURRENT_DATE NOT NULL,
message_count int4 DEFAULT 0 NOT NULL,
total_tokens int4 DEFAULT 0 NOT NULL,
total_processing_time_ms int4 DEFAULT 0 NOT NULL,
CONSTRAINT usage_analytics_pkey PRIMARY KEY (id),
CONSTRAINT usage_analytics_bot_id_fkey FOREIGN KEY (bot_id) REFERENCES public.bots(id) ON DELETE CASCADE,
CONSTRAINT usage_analytics_session_id_fkey FOREIGN KEY (session_id) REFERENCES public.user_sessions(id) ON DELETE CASCADE,
CONSTRAINT usage_analytics_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE
);
CREATE INDEX idx_usage_analytics_date ON public.usage_analytics USING btree (date);

View file

@ -1,3 +0,0 @@
DROP INDEX idx_bot_memories_key;
DROP INDEX idx_bot_memories_bot_id;
DROP TABLE bot_memories;

View file

@ -1,13 +0,0 @@
CREATE TABLE bot_memories (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
key TEXT NOT NULL,
value TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(bot_id, key)
);
CREATE INDEX idx_bot_memories_bot_id ON bot_memories(bot_id);
CREATE INDEX idx_bot_memories_key ON bot_memories(key);

View file

@ -1,23 +0,0 @@
-- Drop triggers
DROP TRIGGER IF EXISTS update_basic_tools_updated_at ON basic_tools;
DROP TRIGGER IF EXISTS update_kb_collections_updated_at ON kb_collections;
DROP TRIGGER IF EXISTS update_kb_documents_updated_at ON kb_documents;
-- Drop function
DROP FUNCTION IF EXISTS update_updated_at_column;
-- Drop indexes
DROP INDEX IF EXISTS idx_basic_tools_active;
DROP INDEX IF EXISTS idx_basic_tools_name;
DROP INDEX IF EXISTS idx_basic_tools_bot_id;
DROP INDEX IF EXISTS idx_kb_collections_name;
DROP INDEX IF EXISTS idx_kb_collections_bot_id;
DROP INDEX IF EXISTS idx_kb_documents_indexed_at;
DROP INDEX IF EXISTS idx_kb_documents_hash;
DROP INDEX IF EXISTS idx_kb_documents_collection;
DROP INDEX IF EXISTS idx_kb_documents_bot_id;
-- Drop tables
DROP TABLE IF EXISTS basic_tools;
DROP TABLE IF EXISTS kb_collections;
DROP TABLE IF EXISTS kb_documents;

View file

@ -1,102 +0,0 @@
-- Migration: Create KB and Tools tables
-- Description: Tables for Knowledge Base management and BASIC tools compilation
-- Table for KB documents metadata
CREATE TABLE IF NOT EXISTS kb_documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL,
collection_name TEXT NOT NULL,
file_path TEXT NOT NULL,
file_size BIGINT NOT NULL DEFAULT 0,
file_hash TEXT NOT NULL,
first_published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_modified_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
indexed_at TIMESTAMPTZ,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(bot_id, collection_name, file_path)
);
-- Index for faster lookups
CREATE INDEX IF NOT EXISTS idx_kb_documents_bot_id ON kb_documents(bot_id);
CREATE INDEX IF NOT EXISTS idx_kb_documents_collection ON kb_documents(collection_name);
CREATE INDEX IF NOT EXISTS idx_kb_documents_hash ON kb_documents(file_hash);
CREATE INDEX IF NOT EXISTS idx_kb_documents_indexed_at ON kb_documents(indexed_at);
-- Table for KB collections
CREATE TABLE IF NOT EXISTS kb_collections (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL,
name TEXT NOT NULL,
folder_path TEXT NOT NULL,
qdrant_collection TEXT NOT NULL,
document_count INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(bot_id, name)
);
-- Index for KB collections
CREATE INDEX IF NOT EXISTS idx_kb_collections_bot_id ON kb_collections(bot_id);
CREATE INDEX IF NOT EXISTS idx_kb_collections_name ON kb_collections(name);
-- Table for compiled BASIC tools
CREATE TABLE IF NOT EXISTS basic_tools (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL,
tool_name TEXT NOT NULL,
file_path TEXT NOT NULL,
ast_path TEXT NOT NULL,
mcp_json JSONB,
tool_json JSONB,
compiled_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(bot_id, tool_name)
);
-- Index for BASIC tools
CREATE INDEX IF NOT EXISTS idx_basic_tools_bot_id ON basic_tools(bot_id);
CREATE INDEX IF NOT EXISTS idx_basic_tools_name ON basic_tools(tool_name);
CREATE INDEX IF NOT EXISTS idx_basic_tools_active ON basic_tools(is_active);
-- Function to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Triggers for updating updated_at
DROP TRIGGER IF EXISTS update_kb_documents_updated_at ON kb_documents;
CREATE TRIGGER update_kb_documents_updated_at
BEFORE UPDATE ON kb_documents
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_kb_collections_updated_at ON kb_collections;
CREATE TRIGGER update_kb_collections_updated_at
BEFORE UPDATE ON kb_collections
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_basic_tools_updated_at ON basic_tools;
CREATE TRIGGER update_basic_tools_updated_at
BEFORE UPDATE ON basic_tools
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- Comments for documentation
COMMENT ON TABLE kb_documents IS 'Stores metadata about documents in Knowledge Base collections';
COMMENT ON TABLE kb_collections IS 'Stores information about KB collections and their Qdrant mappings';
COMMENT ON TABLE basic_tools IS 'Stores compiled BASIC tools with their MCP and OpenAI tool definitions';
COMMENT ON COLUMN kb_documents.file_hash IS 'SHA256 hash of file content for change detection';
COMMENT ON COLUMN kb_documents.indexed_at IS 'Timestamp when document was last indexed in Qdrant';
COMMENT ON COLUMN kb_collections.qdrant_collection IS 'Name of corresponding Qdrant collection';
COMMENT ON COLUMN basic_tools.mcp_json IS 'Model Context Protocol tool definition';
COMMENT ON COLUMN basic_tools.tool_json IS 'OpenAI-compatible tool definition';

View file

@ -1,11 +0,0 @@
-- Drop indexes
DROP INDEX IF EXISTS idx_session_tool_name;
DROP INDEX IF EXISTS idx_session_tool_session;
DROP INDEX IF EXISTS idx_user_kb_website;
DROP INDEX IF EXISTS idx_user_kb_name;
DROP INDEX IF EXISTS idx_user_kb_bot_id;
DROP INDEX IF EXISTS idx_user_kb_user_id;
-- Drop tables
DROP TABLE IF EXISTS session_tool_associations;
DROP TABLE IF EXISTS user_kb_associations;

View file

@ -1,33 +0,0 @@
-- Migration 6.0.3: Additional KB and session tables
-- This migration adds user_kb_associations and session_tool_associations tables
-- Note: kb_documents, kb_collections, and basic_tools are already created in 6.0.2
-- Table for user KB associations (which KBs are active for a user)
CREATE TABLE IF NOT EXISTS user_kb_associations (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
bot_id TEXT NOT NULL,
kb_name TEXT NOT NULL,
is_website INTEGER NOT NULL DEFAULT 0,
website_url TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
UNIQUE(user_id, bot_id, kb_name)
);
CREATE INDEX IF NOT EXISTS idx_user_kb_user_id ON user_kb_associations(user_id);
CREATE INDEX IF NOT EXISTS idx_user_kb_bot_id ON user_kb_associations(bot_id);
CREATE INDEX IF NOT EXISTS idx_user_kb_name ON user_kb_associations(kb_name);
CREATE INDEX IF NOT EXISTS idx_user_kb_website ON user_kb_associations(is_website);
-- Table for session tool associations (which tools are available in a session)
CREATE TABLE IF NOT EXISTS session_tool_associations (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
tool_name TEXT NOT NULL,
added_at TEXT NOT NULL,
UNIQUE(session_id, tool_name)
);
CREATE INDEX IF NOT EXISTS idx_session_tool_session ON session_tool_associations(session_id);
CREATE INDEX IF NOT EXISTS idx_session_tool_name ON session_tool_associations(tool_name);

View file

@ -1,54 +0,0 @@
-- Drop indexes first
DROP INDEX IF EXISTS idx_gbot_sync_bot;
DROP INDEX IF EXISTS idx_component_logs_created;
DROP INDEX IF EXISTS idx_component_logs_level;
DROP INDEX IF EXISTS idx_component_logs_component;
DROP INDEX IF EXISTS idx_component_status;
DROP INDEX IF EXISTS idx_component_name;
DROP INDEX IF EXISTS idx_connection_config_active;
DROP INDEX IF EXISTS idx_connection_config_name;
DROP INDEX IF EXISTS idx_connection_config_bot;
DROP INDEX IF EXISTS idx_model_config_default;
DROP INDEX IF EXISTS idx_model_config_active;
DROP INDEX IF EXISTS idx_model_config_type;
DROP INDEX IF EXISTS idx_bot_config_key;
DROP INDEX IF EXISTS idx_bot_config_bot;
DROP INDEX IF EXISTS idx_tenant_config_key;
DROP INDEX IF EXISTS idx_tenant_config_tenant;
DROP INDEX IF EXISTS idx_server_config_type;
DROP INDEX IF EXISTS idx_server_config_key;
-- Drop tables
DROP TABLE IF EXISTS gbot_config_sync;
DROP TABLE IF EXISTS component_logs;
DROP TABLE IF EXISTS component_installations;
DROP TABLE IF EXISTS connection_configurations;
DROP TABLE IF EXISTS model_configurations;
DROP TABLE IF EXISTS bot_configuration;
DROP TABLE IF EXISTS tenant_configuration;
DROP TABLE IF EXISTS server_configuration;
-- Remove added columns if they exist
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'user_sessions' AND column_name = 'tenant_id'
) THEN
ALTER TABLE user_sessions DROP COLUMN tenant_id;
END IF;
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'bots' AND column_name = 'tenant_id'
) THEN
ALTER TABLE bots DROP COLUMN tenant_id;
END IF;
END $$;
-- Drop tenant indexes if they exist
DROP INDEX IF EXISTS idx_user_sessions_tenant;
DROP INDEX IF EXISTS idx_bots_tenant;
-- Remove default tenant
DELETE FROM tenants WHERE slug = 'default';

View file

@ -1,231 +0,0 @@
-- Migration 6.0.4: Configuration Management System
-- Eliminates .env dependency by storing all configuration in database
-- ============================================================================
-- SERVER CONFIGURATION TABLE
-- Stores server-wide configuration (replaces .env variables)
-- ============================================================================
CREATE TABLE IF NOT EXISTS server_configuration (
id TEXT PRIMARY KEY,
config_key TEXT NOT NULL UNIQUE,
config_value TEXT NOT NULL,
config_type TEXT NOT NULL DEFAULT 'string', -- string, integer, boolean, encrypted
description TEXT,
is_encrypted BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_server_config_key ON server_configuration(config_key);
CREATE INDEX IF NOT EXISTS idx_server_config_type ON server_configuration(config_type);
-- ============================================================================
-- TENANT CONFIGURATION TABLE
-- Stores tenant-level configuration (multi-tenancy support)
-- ============================================================================
CREATE TABLE IF NOT EXISTS tenant_configuration (
id TEXT PRIMARY KEY,
tenant_id UUID NOT NULL,
config_key TEXT NOT NULL,
config_value TEXT NOT NULL,
config_type TEXT NOT NULL DEFAULT 'string',
is_encrypted BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(tenant_id, config_key)
);
CREATE INDEX IF NOT EXISTS idx_tenant_config_tenant ON tenant_configuration(tenant_id);
CREATE INDEX IF NOT EXISTS idx_tenant_config_key ON tenant_configuration(config_key);
-- ============================================================================
-- BOT CONFIGURATION TABLE
-- Stores bot-specific configuration (replaces bot config JSON)
-- ============================================================================
CREATE TABLE IF NOT EXISTS bot_configuration (
id TEXT PRIMARY KEY,
bot_id UUID NOT NULL,
config_key TEXT NOT NULL,
config_value TEXT NOT NULL,
config_type TEXT NOT NULL DEFAULT 'string',
is_encrypted BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(bot_id, config_key)
);
CREATE INDEX IF NOT EXISTS idx_bot_config_bot ON bot_configuration(bot_id);
CREATE INDEX IF NOT EXISTS idx_bot_config_key ON bot_configuration(config_key);
-- ============================================================================
-- MODEL CONFIGURATIONS TABLE
-- Stores LLM and Embedding model configurations
-- ============================================================================
CREATE TABLE IF NOT EXISTS model_configurations (
id TEXT PRIMARY KEY,
model_name TEXT NOT NULL UNIQUE, -- Friendly name: "deepseek-1.5b", "gpt-oss-20b"
model_type TEXT NOT NULL, -- 'llm' or 'embed'
provider TEXT NOT NULL, -- 'openai', 'groq', 'local', 'ollama', etc.
endpoint TEXT NOT NULL,
api_key TEXT, -- Encrypted
model_id TEXT NOT NULL, -- Actual model identifier
context_window INTEGER,
max_tokens INTEGER,
temperature REAL DEFAULT 0.7,
is_active BOOLEAN NOT NULL DEFAULT true,
is_default BOOLEAN NOT NULL DEFAULT false,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_model_config_type ON model_configurations(model_type);
CREATE INDEX IF NOT EXISTS idx_model_config_active ON model_configurations(is_active);
CREATE INDEX IF NOT EXISTS idx_model_config_default ON model_configurations(is_default);
-- ============================================================================
-- CONNECTION CONFIGURATIONS TABLE
-- Stores custom database connections (replaces CUSTOM_* env vars)
-- ============================================================================
CREATE TABLE IF NOT EXISTS connection_configurations (
id TEXT PRIMARY KEY,
bot_id UUID NOT NULL,
connection_name TEXT NOT NULL, -- Used in BASIC: FIND "conn1.table"
connection_type TEXT NOT NULL, -- 'postgres', 'mysql', 'mssql', 'mongodb', etc.
host TEXT NOT NULL,
port INTEGER NOT NULL,
database_name TEXT NOT NULL,
username TEXT NOT NULL,
password TEXT NOT NULL, -- Encrypted
ssl_enabled BOOLEAN NOT NULL DEFAULT false,
additional_params JSONB DEFAULT '{}'::jsonb,
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(bot_id, connection_name)
);
CREATE INDEX IF NOT EXISTS idx_connection_config_bot ON connection_configurations(bot_id);
CREATE INDEX IF NOT EXISTS idx_connection_config_name ON connection_configurations(connection_name);
CREATE INDEX IF NOT EXISTS idx_connection_config_active ON connection_configurations(is_active);
-- ============================================================================
-- COMPONENT INSTALLATIONS TABLE
-- Tracks installed components (postgres, minio, qdrant, etc.)
-- ============================================================================
CREATE TABLE IF NOT EXISTS component_installations (
id TEXT PRIMARY KEY,
component_name TEXT NOT NULL UNIQUE, -- 'tables', 'drive', 'vectordb', 'cache', 'llm'
component_type TEXT NOT NULL, -- 'database', 'storage', 'vector', 'cache', 'compute'
version TEXT NOT NULL,
install_path TEXT NOT NULL, -- Relative to botserver-stack
binary_path TEXT, -- Path to executable
data_path TEXT, -- Path to data directory
config_path TEXT, -- Path to config file
log_path TEXT, -- Path to log directory
status TEXT NOT NULL DEFAULT 'stopped', -- 'running', 'stopped', 'error', 'installing'
port INTEGER,
pid INTEGER,
auto_start BOOLEAN NOT NULL DEFAULT true,
metadata JSONB DEFAULT '{}'::jsonb,
installed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_started_at TIMESTAMPTZ,
last_stopped_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_component_name ON component_installations(component_name);
CREATE INDEX IF NOT EXISTS idx_component_status ON component_installations(status);
-- ============================================================================
-- TENANTS TABLE
-- Multi-tenancy support
-- ============================================================================
CREATE TABLE IF NOT EXISTS tenants (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL UNIQUE,
slug TEXT NOT NULL UNIQUE,
is_active BOOLEAN NOT NULL DEFAULT true,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_tenants_slug ON tenants(slug);
CREATE INDEX IF NOT EXISTS idx_tenants_active ON tenants(is_active);
-- ============================================================================
-- BOT SESSIONS ENHANCEMENT
-- Add tenant_id to existing sessions if column doesn't exist
-- ============================================================================
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'user_sessions' AND column_name = 'tenant_id'
) THEN
ALTER TABLE user_sessions ADD COLUMN tenant_id UUID;
CREATE INDEX idx_user_sessions_tenant ON user_sessions(tenant_id);
END IF;
END $$;
-- ============================================================================
-- BOTS TABLE ENHANCEMENT
-- Add tenant_id if it doesn't exist
-- ============================================================================
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'bots' AND column_name = 'tenant_id'
) THEN
ALTER TABLE bots ADD COLUMN tenant_id UUID;
CREATE INDEX idx_bots_tenant ON bots(tenant_id);
END IF;
END $$;
INSERT INTO tenants (id, name, slug, is_active) VALUES
(gen_random_uuid(), 'Default Tenant', 'default', true)
ON CONFLICT (slug) DO NOTHING;
-- ============================================================================
-- DEFAULT MODELS
-- Add some default model configurations
-- ============================================================================
INSERT INTO model_configurations (id, model_name, model_type, provider, endpoint, model_id, context_window, max_tokens, is_default) VALUES
(gen_random_uuid()::text, 'gpt-4', 'llm', 'openai', 'http://localhost:8081/v1', 'gpt-4', 8192, 4096, true),
(gen_random_uuid()::text, 'gpt-3.5-turbo', 'llm', 'openai', 'http://localhost:8081/v1', 'gpt-3.5-turbo', 4096, 2048, false),
(gen_random_uuid()::text, 'bge-large', 'embed', 'local', 'http://localhost:8081', 'BAAI/bge-large-en-v1.5', 512, 1024, true)
ON CONFLICT (model_name) DO NOTHING;
-- ============================================================================
-- COMPONENT LOGGING TABLE
-- Track component lifecycle events
-- ============================================================================
CREATE TABLE IF NOT EXISTS component_logs (
id TEXT PRIMARY KEY,
component_name TEXT NOT NULL,
log_level TEXT NOT NULL, -- 'info', 'warning', 'error', 'debug'
message TEXT NOT NULL,
details JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_component_logs_component ON component_logs(component_name);
CREATE INDEX IF NOT EXISTS idx_component_logs_level ON component_logs(log_level);
CREATE INDEX IF NOT EXISTS idx_component_logs_created ON component_logs(created_at);
-- ============================================================================
-- GBOT CONFIG SYNC TABLE
-- Tracks .gbot/config.csv file changes and last sync
-- ============================================================================
CREATE TABLE IF NOT EXISTS gbot_config_sync (
id TEXT PRIMARY KEY,
bot_id UUID NOT NULL UNIQUE,
config_file_path TEXT NOT NULL,
last_sync_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
file_hash TEXT NOT NULL,
sync_count INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_gbot_sync_bot ON gbot_config_sync(bot_id);

View file

@ -1,26 +0,0 @@
-- Revert clicks table changes
CREATE TABLE IF NOT EXISTS public.old_clicks (
campaign_id text NOT NULL,
email text NOT NULL,
updated_at timestamptz DEFAULT now() NULL,
CONSTRAINT clicks_campaign_id_email_key UNIQUE (campaign_id, email)
);
INSERT INTO public.old_clicks (campaign_id, email, updated_at)
SELECT campaign_id, email, updated_at FROM public.clicks;
DROP TABLE public.clicks;
ALTER TABLE public.old_clicks RENAME TO clicks;
-- Remove system_automations constraints and indexes
DROP INDEX IF EXISTS idx_system_automations_bot_kind_param;
ALTER TABLE public.system_automations DROP CONSTRAINT IF EXISTS system_automations_bot_kind_param_unique;
DROP INDEX IF EXISTS idx_system_automations_bot_id;
ALTER TABLE public.system_automations DROP COLUMN IF EXISTS bot_id;
DROP INDEX IF EXISTS idx_system_automations_name;
ALTER TABLE public.system_automations DROP COLUMN IF EXISTS name;
-- Remove bot_configuration constraint
ALTER TABLE bot_configuration DROP CONSTRAINT IF EXISTS bot_configuration_config_key_unique;

View file

@ -1,55 +0,0 @@
-- Migration 6.0.5: Add update-summary.bas scheduled automation
-- Description: Creates a scheduled automation that runs every minute to update summaries
-- This replaces the announcements system in legacy mode
-- Note: Bots are now created dynamically during bootstrap based on template folders
-- Add name column to system_automations if it doesn't exist
ALTER TABLE public.system_automations ADD COLUMN IF NOT EXISTS name VARCHAR(255);
-- Create index on name column for faster lookups
CREATE INDEX IF NOT EXISTS idx_system_automations_name ON public.system_automations(name);
-- Note: bot_configuration already has UNIQUE(bot_id, config_key) from migration 6.0.4
-- Do NOT add a global unique constraint on config_key alone as that breaks multi-bot configs
-- Migration 6.0.9: Add bot_id column to system_automations
-- Description: Introduces a bot_id column to associate automations with a specific bot.
-- The column is added as UUID and indexed for efficient queries.
-- Add bot_id column if it does not exist
ALTER TABLE public.system_automations
ADD COLUMN IF NOT EXISTS bot_id UUID NOT NULL;
-- Create an index on bot_id for faster lookups
CREATE INDEX IF NOT EXISTS idx_system_automations_bot_id
ON public.system_automations (bot_id);
ALTER TABLE public.system_automations
ADD CONSTRAINT system_automations_bot_kind_param_unique
UNIQUE (bot_id, kind, param);
-- Add index for the new constraint
CREATE INDEX IF NOT EXISTS idx_system_automations_bot_kind_param
ON public.system_automations (bot_id, kind, param);
-- Migration 6.0.7: Fix clicks table primary key
-- Required by Diesel before we can run other migrations
-- Create new table with proper structure
CREATE TABLE IF NOT EXISTS public.new_clicks (
id SERIAL PRIMARY KEY,
campaign_id text NOT NULL,
email text NOT NULL,
updated_at timestamptz DEFAULT now() NULL,
CONSTRAINT new_clicks_campaign_id_email_key UNIQUE (campaign_id, email)
);
-- Copy data from old table
INSERT INTO public.new_clicks (campaign_id, email, updated_at)
SELECT campaign_id, email, updated_at FROM public.clicks;
-- Drop old table and rename new one
DROP TABLE public.clicks;
ALTER TABLE public.new_clicks RENAME TO clicks;

View file

@ -1,19 +0,0 @@
-- Drop login tokens table
DROP TABLE IF EXISTS public.user_login_tokens;
-- Drop user preferences table
DROP TABLE IF EXISTS public.user_preferences;
-- Remove session enhancement
ALTER TABLE public.user_sessions
DROP CONSTRAINT IF EXISTS user_sessions_email_account_id_fkey,
DROP COLUMN IF EXISTS active_email_account_id;
-- Drop email folders table
DROP TABLE IF EXISTS public.email_folders;
-- Drop email drafts table
DROP TABLE IF EXISTS public.email_drafts;
-- Drop user email accounts table
DROP TABLE IF EXISTS public.user_email_accounts;

View file

@ -1,102 +0,0 @@
-- Add user_email_accounts table for storing user email credentials
CREATE TABLE public.user_email_accounts (
id uuid DEFAULT gen_random_uuid() NOT NULL,
user_id uuid NOT NULL,
email varchar(255) NOT NULL,
display_name varchar(255) NULL,
imap_server varchar(255) NOT NULL,
imap_port int4 DEFAULT 993 NOT NULL,
smtp_server varchar(255) NOT NULL,
smtp_port int4 DEFAULT 587 NOT NULL,
username varchar(255) NOT NULL,
password_encrypted text NOT NULL,
is_primary bool DEFAULT false NOT NULL,
is_active bool DEFAULT true NOT NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT user_email_accounts_pkey PRIMARY KEY (id),
CONSTRAINT user_email_accounts_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE,
CONSTRAINT user_email_accounts_user_email_key UNIQUE (user_id, email)
);
CREATE INDEX idx_user_email_accounts_user_id ON public.user_email_accounts USING btree (user_id);
CREATE INDEX idx_user_email_accounts_active ON public.user_email_accounts USING btree (is_active) WHERE is_active;
-- Add email drafts table
CREATE TABLE public.email_drafts (
id uuid DEFAULT gen_random_uuid() NOT NULL,
user_id uuid NOT NULL,
account_id uuid NOT NULL,
to_address text NOT NULL,
cc_address text NULL,
bcc_address text NULL,
subject varchar(500) NULL,
body text NULL,
attachments jsonb DEFAULT '[]'::jsonb NOT NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT email_drafts_pkey PRIMARY KEY (id),
CONSTRAINT email_drafts_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE,
CONSTRAINT email_drafts_account_id_fkey FOREIGN KEY (account_id) REFERENCES public.user_email_accounts(id) ON DELETE CASCADE
);
CREATE INDEX idx_email_drafts_user_id ON public.email_drafts USING btree (user_id);
CREATE INDEX idx_email_drafts_account_id ON public.email_drafts USING btree (account_id);
-- Add email folders metadata table (for caching and custom folders)
CREATE TABLE public.email_folders (
id uuid DEFAULT gen_random_uuid() NOT NULL,
account_id uuid NOT NULL,
folder_name varchar(255) NOT NULL,
folder_path varchar(500) NOT NULL,
unread_count int4 DEFAULT 0 NOT NULL,
total_count int4 DEFAULT 0 NOT NULL,
last_synced timestamptz NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT email_folders_pkey PRIMARY KEY (id),
CONSTRAINT email_folders_account_id_fkey FOREIGN KEY (account_id) REFERENCES public.user_email_accounts(id) ON DELETE CASCADE,
CONSTRAINT email_folders_account_path_key UNIQUE (account_id, folder_path)
);
CREATE INDEX idx_email_folders_account_id ON public.email_folders USING btree (account_id);
-- Add sessions table enhancement for storing current email account
ALTER TABLE public.user_sessions
ADD COLUMN IF NOT EXISTS active_email_account_id uuid NULL,
ADD CONSTRAINT user_sessions_email_account_id_fkey
FOREIGN KEY (active_email_account_id) REFERENCES public.user_email_accounts(id) ON DELETE SET NULL;
-- Add user preferences table
CREATE TABLE public.user_preferences (
id uuid DEFAULT gen_random_uuid() NOT NULL,
user_id uuid NOT NULL,
preference_key varchar(100) NOT NULL,
preference_value jsonb NOT NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT user_preferences_pkey PRIMARY KEY (id),
CONSTRAINT user_preferences_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE,
CONSTRAINT user_preferences_user_key_unique UNIQUE (user_id, preference_key)
);
CREATE INDEX idx_user_preferences_user_id ON public.user_preferences USING btree (user_id);
-- Add login tokens table for session management
CREATE TABLE public.user_login_tokens (
id uuid DEFAULT gen_random_uuid() NOT NULL,
user_id uuid NOT NULL,
token_hash varchar(255) NOT NULL,
expires_at timestamptz NOT NULL,
created_at timestamptz DEFAULT now() NOT NULL,
last_used timestamptz DEFAULT now() NOT NULL,
user_agent text NULL,
ip_address varchar(50) NULL,
is_active bool DEFAULT true NOT NULL,
CONSTRAINT user_login_tokens_pkey PRIMARY KEY (id),
CONSTRAINT user_login_tokens_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE,
CONSTRAINT user_login_tokens_token_hash_key UNIQUE (token_hash)
);
CREATE INDEX idx_user_login_tokens_user_id ON public.user_login_tokens USING btree (user_id);
CREATE INDEX idx_user_login_tokens_expires ON public.user_login_tokens USING btree (expires_at) WHERE is_active;

View file

@ -1,9 +0,0 @@
-- Migration 6.0.7: Session KB Tracking (ROLLBACK)
-- Drops session KB tracking table
DROP INDEX IF EXISTS idx_session_kb_active;
DROP INDEX IF EXISTS idx_session_kb_name;
DROP INDEX IF EXISTS idx_session_kb_bot_id;
DROP INDEX IF EXISTS idx_session_kb_session_id;
DROP TABLE IF EXISTS session_kb_associations;

View file

@ -1,29 +0,0 @@
-- Migration 6.0.7: Session KB Tracking
-- Adds table to track which KBs are active in each conversation session
-- Table for tracking KBs active in a session (set by ADD_KB in .bas tools)
CREATE TABLE IF NOT EXISTS session_kb_associations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID NOT NULL REFERENCES user_sessions(id) ON DELETE CASCADE,
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
kb_name TEXT NOT NULL,
kb_folder_path TEXT NOT NULL,
qdrant_collection TEXT NOT NULL,
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
added_by_tool TEXT,
is_active BOOLEAN NOT NULL DEFAULT true,
UNIQUE(session_id, kb_name)
);
CREATE INDEX IF NOT EXISTS idx_session_kb_session_id ON session_kb_associations(session_id);
CREATE INDEX IF NOT EXISTS idx_session_kb_bot_id ON session_kb_associations(bot_id);
CREATE INDEX IF NOT EXISTS idx_session_kb_name ON session_kb_associations(kb_name);
CREATE INDEX IF NOT EXISTS idx_session_kb_active ON session_kb_associations(is_active) WHERE is_active = true;
-- Comments
COMMENT ON TABLE session_kb_associations IS 'Tracks which Knowledge Base collections are active in each conversation session';
COMMENT ON COLUMN session_kb_associations.kb_name IS 'Name of the KB folder (e.g., "circular", "comunicado", "geral")';
COMMENT ON COLUMN session_kb_associations.kb_folder_path IS 'Full path to KB folder: work/{bot}/{bot}.gbkb/{kb_name}';
COMMENT ON COLUMN session_kb_associations.qdrant_collection IS 'Qdrant collection name for this KB';
COMMENT ON COLUMN session_kb_associations.added_by_tool IS 'Name of the .bas tool that added this KB (e.g., "change-subject.bas")';
COMMENT ON COLUMN session_kb_associations.is_active IS 'Whether this KB is currently active in the session';

View file

@ -1,23 +0,0 @@
-- Drop triggers
DROP TRIGGER IF EXISTS update_directory_users_updated_at ON public.directory_users;
DROP TRIGGER IF EXISTS update_oauth_applications_updated_at ON public.oauth_applications;
-- Drop function if no other triggers use it
DROP FUNCTION IF EXISTS update_updated_at_column() CASCADE;
-- Drop tables in reverse order of dependencies
DROP TABLE IF EXISTS public.bot_access CASCADE;
DROP TABLE IF EXISTS public.oauth_applications CASCADE;
DROP TABLE IF EXISTS public.directory_users CASCADE;
-- Drop indexes
DROP INDEX IF EXISTS idx_bots_org_id;
-- Remove columns from bots table
ALTER TABLE public.bots
DROP CONSTRAINT IF EXISTS bots_org_id_fkey,
DROP COLUMN IF EXISTS org_id,
DROP COLUMN IF EXISTS is_default;
-- Note: We don't delete the default organization or bot data as they may have other relationships
-- The application should handle orphaned data appropriately

View file

@ -1,246 +0,0 @@
-- Add organization relationship to bots
ALTER TABLE public.bots
ADD COLUMN IF NOT EXISTS org_id UUID,
ADD COLUMN IF NOT EXISTS is_default BOOLEAN DEFAULT false;
-- Add foreign key constraint to organizations
ALTER TABLE public.bots
ADD CONSTRAINT bots_org_id_fkey
FOREIGN KEY (org_id) REFERENCES public.organizations(org_id) ON DELETE CASCADE;
-- Create index for org_id lookups
CREATE INDEX IF NOT EXISTS idx_bots_org_id ON public.bots(org_id);
-- Create directory_users table to map directory (Zitadel) users to our system
CREATE TABLE IF NOT EXISTS public.directory_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
directory_id VARCHAR(255) NOT NULL UNIQUE, -- Zitadel user ID
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
org_id UUID NOT NULL REFERENCES public.organizations(org_id) ON DELETE CASCADE,
bot_id UUID REFERENCES public.bots(id) ON DELETE SET NULL,
first_name VARCHAR(255),
last_name VARCHAR(255),
is_admin BOOLEAN DEFAULT false,
is_bot_user BOOLEAN DEFAULT false, -- true for bot service accounts
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
-- Create indexes for directory_users
CREATE INDEX IF NOT EXISTS idx_directory_users_org_id ON public.directory_users(org_id);
CREATE INDEX IF NOT EXISTS idx_directory_users_bot_id ON public.directory_users(bot_id);
CREATE INDEX IF NOT EXISTS idx_directory_users_email ON public.directory_users(email);
CREATE INDEX IF NOT EXISTS idx_directory_users_directory_id ON public.directory_users(directory_id);
-- Create bot_access table to manage which users can access which bots
CREATE TABLE IF NOT EXISTS public.bot_access (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL REFERENCES public.bots(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES public.directory_users(id) ON DELETE CASCADE,
access_level VARCHAR(50) NOT NULL DEFAULT 'user', -- 'owner', 'admin', 'user', 'viewer'
granted_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
granted_by UUID REFERENCES public.directory_users(id),
UNIQUE(bot_id, user_id)
);
-- Create indexes for bot_access
CREATE INDEX IF NOT EXISTS idx_bot_access_bot_id ON public.bot_access(bot_id);
CREATE INDEX IF NOT EXISTS idx_bot_access_user_id ON public.bot_access(user_id);
-- Create OAuth application registry for directory integrations
CREATE TABLE IF NOT EXISTS public.oauth_applications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL REFERENCES public.organizations(org_id) ON DELETE CASCADE,
project_id VARCHAR(255),
client_id VARCHAR(255) NOT NULL UNIQUE,
client_secret_encrypted TEXT NOT NULL, -- Store encrypted
redirect_uris TEXT[] NOT NULL DEFAULT '{}',
application_name VARCHAR(255) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
-- Create index for OAuth applications
CREATE INDEX IF NOT EXISTS idx_oauth_applications_org_id ON public.oauth_applications(org_id);
CREATE INDEX IF NOT EXISTS idx_oauth_applications_client_id ON public.oauth_applications(client_id);
-- Insert default organization if it doesn't exist
INSERT INTO public.organizations (org_id, name, slug, created_at, updated_at)
VALUES (
'f47ac10b-58cc-4372-a567-0e02b2c3d479'::uuid, -- Fixed UUID for default org
'Default Organization',
'default',
NOW(),
NOW()
) ON CONFLICT (slug) DO NOTHING;
-- Insert default bot for the default organization
DO $$
DECLARE
v_org_id UUID;
v_bot_id UUID;
BEGIN
-- Get the default organization ID
SELECT org_id INTO v_org_id FROM public.organizations WHERE slug = 'default';
-- Generate or use fixed UUID for default bot
v_bot_id := 'f47ac10b-58cc-4372-a567-0e02b2c3d480'::uuid;
-- Insert default bot if it doesn't exist
INSERT INTO public.bots (
id,
org_id,
name,
description,
llm_provider,
llm_config,
context_provider,
context_config,
is_default,
is_active,
created_at,
updated_at
)
VALUES (
v_bot_id,
v_org_id,
'Default Bot',
'Default bot for the default organization',
'openai',
'{"model": "gpt-4", "temperature": 0.7}'::jsonb,
'none',
'{}'::jsonb,
true,
true,
NOW(),
NOW()
) ON CONFLICT (id) DO UPDATE
SET org_id = EXCLUDED.org_id,
is_default = true,
updated_at = NOW();
-- Insert default admin user (admin@default)
INSERT INTO public.directory_users (
directory_id,
username,
email,
org_id,
bot_id,
first_name,
last_name,
is_admin,
is_bot_user,
created_at,
updated_at
)
VALUES (
'admin-default-001', -- Will be replaced with actual Zitadel ID
'admin',
'admin@default',
v_org_id,
v_bot_id,
'Admin',
'Default',
true,
false,
NOW(),
NOW()
) ON CONFLICT (email) DO UPDATE
SET org_id = EXCLUDED.org_id,
bot_id = EXCLUDED.bot_id,
is_admin = true,
updated_at = NOW();
-- Insert default regular user (user@default)
INSERT INTO public.directory_users (
directory_id,
username,
email,
org_id,
bot_id,
first_name,
last_name,
is_admin,
is_bot_user,
created_at,
updated_at
)
VALUES (
'user-default-001', -- Will be replaced with actual Zitadel ID
'user',
'user@default',
v_org_id,
v_bot_id,
'User',
'Default',
false,
false,
NOW(),
NOW()
) ON CONFLICT (email) DO UPDATE
SET org_id = EXCLUDED.org_id,
bot_id = EXCLUDED.bot_id,
is_admin = false,
updated_at = NOW();
-- Grant bot access to admin user
INSERT INTO public.bot_access (bot_id, user_id, access_level, granted_at)
SELECT
v_bot_id,
id,
'owner',
NOW()
FROM public.directory_users
WHERE email = 'admin@default'
ON CONFLICT (bot_id, user_id) DO UPDATE
SET access_level = 'owner',
granted_at = NOW();
-- Grant bot access to regular user
INSERT INTO public.bot_access (bot_id, user_id, access_level, granted_at)
SELECT
v_bot_id,
id,
'user',
NOW()
FROM public.directory_users
WHERE email = 'user@default'
ON CONFLICT (bot_id, user_id) DO UPDATE
SET access_level = 'user',
granted_at = NOW();
END $$;
-- Create function to update updated_at timestamps
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
-- Add triggers for updated_at columns if they don't exist
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_directory_users_updated_at') THEN
CREATE TRIGGER update_directory_users_updated_at
BEFORE UPDATE ON public.directory_users
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'update_oauth_applications_updated_at') THEN
CREATE TRIGGER update_oauth_applications_updated_at
BEFORE UPDATE ON public.oauth_applications
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF;
END $$;
-- Add comment documentation
COMMENT ON TABLE public.directory_users IS 'Maps directory (Zitadel) users to the system and their associated bots';
COMMENT ON TABLE public.bot_access IS 'Controls which users have access to which bots and their permission levels';
COMMENT ON TABLE public.oauth_applications IS 'OAuth application configurations for directory integration';
COMMENT ON COLUMN public.bots.is_default IS 'Indicates if this is the default bot for an organization';
COMMENT ON COLUMN public.directory_users.is_bot_user IS 'True if this user is a service account for bot operations';
COMMENT ON COLUMN public.bot_access.access_level IS 'Access level: owner (full control), admin (manage), user (use), viewer (read-only)';

Some files were not shown because too many files have changed in this diff Show more