Compare commits
No commits in common. "main" and "azure-arm-automation" have entirely different histories.
main
...
azure-arm-
2
.deployment
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[config]
|
||||
command = deploy.cmd
|
||||
|
|
@ -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
|
||||
36
.env.example
|
|
@ -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
|
||||
|
|
@ -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/
|
||||
|
|
@ -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
|
||||
9
.github/ISSUE_TEMPLATE.md
vendored
Normal 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
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: Custom issue template
|
||||
about: Describe this issue template's purpose here.
|
||||
|
||||
---
|
||||
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal 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
|
|
@ -0,0 +1,2 @@
|
|||
**Description**
|
||||
A clear and concise description of what the requirement is.
|
||||
16
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal 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 added
|
||||
- [ ] 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
|
|
@ -0,0 +1,3 @@
|
|||
isOutside: true
|
||||
# Team Name
|
||||
team: contributors
|
||||
44
.github/settings.yml
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
repository:
|
||||
name: botserver
|
||||
description: botserver
|
||||
homepage: http://pragmatismo.io/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
|
||||
29
.gitignore
vendored
|
|
@ -1,16 +1,13 @@
|
|||
.tmp*
|
||||
.tmp/*
|
||||
*.log
|
||||
target*
|
||||
.env
|
||||
*.env
|
||||
work
|
||||
*.out
|
||||
bin
|
||||
botserver-stack
|
||||
*logfile*
|
||||
*-log*
|
||||
docs/book
|
||||
*.rdb
|
||||
botserver-installers/*
|
||||
!botserver-installers/.gitkeep
|
||||
node_modules
|
||||
/packages/default.gbui/build
|
||||
/dist
|
||||
/guaribas.sqlite
|
||||
/guaribas.log
|
||||
/work
|
||||
/tmp
|
||||
/docs
|
||||
/.env
|
||||
/chart.html
|
||||
/chart.png
|
||||
/chart.svg
|
||||
/gbtrace.log
|
||||
|
|
|
|||
5
.npmignore
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
node_modules
|
||||
/packages/default.gbui/build
|
||||
/guaribas.sqlite
|
||||
/guaribas.log
|
||||
/work
|
||||
41
.vscode/launch.json
vendored
|
|
@ -1,41 +1,20 @@
|
|||
{
|
||||
"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"],
|
||||
"name": "Debug Program",
|
||||
"program": "${workspaceRoot}/dist/src/app.js",
|
||||
"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"
|
||||
},
|
||||
"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":["--no-deprecation"],
|
||||
"skipFiles": ["node_modules/**/*.js"],
|
||||
"outFiles": ["${workspaceRoot}/dist/*.js"],
|
||||
"stopOnEntry": false,
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
4
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
224
3rdparty.toml
|
|
@ -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 = ""
|
||||
47
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# 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, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using 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
|
||||
* 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
|
||||
|
||||
## 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 project team at security@pragmatismo.io. 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]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
59
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# 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.io 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.io. 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"
|
||||
|
||||
## Running (and adding) the Tests
|
||||
|
||||
*Coming soon*
|
||||
8200
Cargo.lock
generated
287
Cargo.toml
|
|
@ -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
|
||||
|
|
@ -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.io
|
||||
informing your Customer ID.
|
||||
|
||||
If you modify this Program, or any covered work, by combining it
|
||||
678
PROMPT.md
|
|
@ -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
|
||||
}
|
||||
```
|
||||
293
README.md
|
|
@ -1,154 +1,235 @@
|
|||
# General Bots - Enterprise-Grade LLM Orchestrator
|
||||
** **Checkout our FREE [Intranet Quickstart Bot](https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai)** **
|
||||
|
||||

|
||||
Welcome to General Bot Community Edition
|
||||
----------------
|
||||
|
||||
**A strongly-typed LLM conversational platform focused on convention over configuration and code-less approaches.**
|
||||

|
||||
|
||||
## Quick Links
|
||||
General Bot is a 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.
|
||||
In this [MSDN](https://blogs.msdn.microsoft.com/buckwoody/2018/09/25/applied-ai-using-a-bot-for-password-reset/) article you can have an overview of a General Bots application.
|
||||
|
||||
- **[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?
|
||||
### What is a Bot Server?
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
## Quick Start
|
||||
Everyone can create bots by just copying and pasting some files and using their
|
||||
favorite tools like Excel (or any text editor) or Photoshop (or any image
|
||||
editor).
|
||||
|
||||
### Prerequisites
|
||||
Package Quick Reference
|
||||
------------
|
||||
|Whatsapp|Web|Core|KB|
|
||||
|----|-----|----|----|
|
||||
|[whatsapp.gblib](https://github.com/pragmatismo-io/BotServer/tree/master/packages/whatsapp.gblib)|[default.gbui](https://github.com/pragmatismo-io/BotServer/tree/master/packages/default.gbui)|[core.gbapp](https://github.com/pragmatismo-io/BotServer/tree/master/packages/core.gbapp)|[kb.gbapp](https://github.com/pragmatismo-io/BotServer/tree/master/packages/kb.gbapp)|
|
||||
|
||||
- **Rust** (1.75+) - [Install from rustup.rs](https://rustup.rs/)
|
||||
- **Git** - [Download from git-scm.com](https://git-scm.com/downloads)
|
||||

|
||||
|
||||
### Installation
|
||||
### The same build process for everyone
|
||||
|
||||
```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.
|
||||
GeneralBots aims to delivery bots in azure in a very easy and fast fashion. Use
|
||||
Office tools like Word or Excel to edit your Bot - using code (JavaScript or TypeScript) just to empower custom requirements.
|
||||
|
||||
The server will be available at `http://localhost:8080`.
|
||||
|
||||
## Documentation
|
||||
#### Use Excel for (Hierarchical) Knowledge Base Editing
|
||||
|
||||
```
|
||||
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
|
||||
#### Use Visual Studio for a complete .gbai package building system
|
||||
|
||||
### 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
|
||||
How To
|
||||
------
|
||||
|
||||
```basic
|
||||
' customer-support.bas
|
||||
USE KB "support-docs"
|
||||
USE TOOL "create-ticket"
|
||||
USE TOOL "check-order"
|
||||
### Run the server locally
|
||||
|
||||
SET CONTEXT "support" AS "You are a helpful customer support agent."
|
||||
1. Install [Node.js](https://www.npmjs.com/get-npm) the current generation General Bot code execution platform;
|
||||
2. Open a **Terminal** on Linux and Mac or a **Command Prompt** window on Windows;
|
||||
3. Type `npm install -g botserver` and press *ENTER*;
|
||||
4. Type `gbot` to run the server core.
|
||||
|
||||
TALK "Welcome! How can I help you today?"
|
||||
```
|
||||
Notes:
|
||||
|
||||
## Command-Line Options
|
||||
* [*nodejs.install* Chocolatey Package](https://chocolatey.org/packages/nodejs.install) is also available.
|
||||
* The zip source code of General Bot is also available for [Download](https://codeload.github.com/pragmatismo-io/BotServer/zip/master);
|
||||
|
||||
```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
|
||||
```
|
||||
### Configure the server to deploy specific directory
|
||||
|
||||
## Environment Variables
|
||||
1. Create/Edit the .env file and add the ADDITIONAL_DEPLOY_PATH key pointing to the .gbai local parent folder of .gbapp, .gbot, .gbtheme, .gbkb package directories.
|
||||
2. Specify STORAGE_SYNC to TRUE so database sync is run when the server is run.
|
||||
3. In case of Microsoft SQL Server add the following keys: STORAGE_SERVER, STORAGE_NAME, STORAGE_USERNAME, STORAGE_PASSWORD, STORAGE_DIALECT to `mssql`.
|
||||
|
||||
Only directory service variables are required:
|
||||
Note:
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `DIRECTORY_URL` | Zitadel instance URL |
|
||||
| `DIRECTORY_CLIENT_ID` | OAuth client ID |
|
||||
| `DIRECTORY_CLIENT_SECRET` | OAuth client secret |
|
||||
* You can specify several bots separated by semicolon, the BotServer will serve all of them at once.
|
||||
|
||||
All service credentials are managed automatically. See [Configuration](docs/reference/configuration.md) for details.
|
||||
## Setup development environment (Windows)
|
||||
|
||||
## Current Status
|
||||
1. [Optional] Install [Chocolatey](https://chocolatey.org/install), a Windows Package Manager;
|
||||
2. Install [git](`https://git-scm.com/`), a Software Configuration Management (SCM).;
|
||||
3. Install [Node.js](npmjs.com/get-npm), a [Runtime system](https://en.wikipedia.org/wiki/Runtime_system).
|
||||
(https://www.npmjs.com/get-npm) (suggested: LTS 8.x.x);
|
||||
4. Install [Visual Studio Code](https://chocolatey.org/packages/nodejs.install), Brackets or Atom as an editor of your choice;
|
||||
5. [Fork](https://en.wikipedia.org/wiki/Fork_(software_development)) by visiting https://github.com/pragmatismo-io/BotServer/fork
|
||||
6. Clone the just forked repository by running `git clone <your-forked-repository-url>/BotServer.git` ;
|
||||
7. Run `npm install -g typescript`;
|
||||
8. Run `npm install` on Command Prompt or PowerShell on the General Bot source-code folder;
|
||||
9. Enter './packages/default.gbui' folder;
|
||||
10. Run `npm install` folled by `npm run build` (To build default Bot UI);
|
||||
11. Enter the On the downloaded folder (../..);
|
||||
12. Compile the bot server by `tsc`.
|
||||
13. Run the bot server by `npm start`.
|
||||
|
||||
**Version:** 6.0.8
|
||||
**Build Status:** SUCCESS
|
||||
**Production Ready:** YES
|
||||
Note:
|
||||
|
||||
## Deployment
|
||||
* Whenever you are ready to turn your open-source bot ideas in form of .gbapp (source-code) and artifacts like .gbkb, .gbtheme, .gbot or the .gbai full package read [CONTRIBUTING.md](https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md) about performing Pull Requests (PR) and creating other public custom packages repositories of your own personal or organization General Bot Community Edition powered packages.
|
||||
|
||||
See [Deployment Guide](docs/guides/deployment.md) for:
|
||||
### Running unit tests
|
||||
|
||||
- Single server setup
|
||||
- Docker Compose
|
||||
- LXC containers
|
||||
- Kubernetes
|
||||
- Reverse proxy configuration
|
||||
1. Enter the BotServer root folder.
|
||||
2. Run tests by `npm test`.
|
||||
|
||||
## Contributing
|
||||
### Just copy the source code to your machine
|
||||
|
||||
We welcome contributions! Please read our contributing guidelines before submitting PRs.
|
||||
1. [Download] the Zip file of (https://codeload.github.com/pragmatismo-io/BotServer/zip/master)
|
||||
|
||||
## Security
|
||||
### Updating the Bot Knoledge Base (.gbkb folder)
|
||||
|
||||
Security issues should be reported to: **security@pragmatismo.com.br**
|
||||
The subjects.json file contains all information related to the subject tree and can be used to build the menu carrousel as well give a set of words to be used as subject catcher in the conversation. A hierarchy can be specified.
|
||||
|
||||
## License
|
||||
### Creating a new Theme folder (.gbtheme folder)
|
||||
|
||||
General Bot Copyright (c) pragmatismo.com.br. All rights reserved.
|
||||
Licensed under the **AGPL-3.0**.
|
||||
A theme is composed of some CSS files and images. That set of files can change
|
||||
everything in the General Bot UI. Use them extensively before going to change
|
||||
the UI application itself (HTML & JS).
|
||||
|
||||
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.
|
||||
Package Types
|
||||
-------------
|
||||
|
||||
## 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)
|
||||
### .gbai
|
||||
|
||||
## Contributors
|
||||
Embraces all packages types (content, logic & conversation) into a pluggable bot
|
||||
directory. [A sample .gbai is available](https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai).
|
||||
|
||||
<a href="https://github.com/generalbots/botserver/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=generalbots/botserver" />
|
||||
</a>
|
||||
### .gbapp
|
||||
|
||||
---
|
||||
The artificial intelligence extensions in form of pluggable apps. Dialogs,
|
||||
Services and all model related to data. A set of interactions, use cases,
|
||||
integrations in form of conversationals dialogs.
|
||||
The .gbapp adds the General Bot base library (botlib) for building Node.js TypeScript Apps packages.
|
||||
|
||||
**General Bots Code Name:** [Guaribas](https://en.wikipedia.org/wiki/Guaribas)
|
||||
|
||||
> "No one should have to do work that can be done by a machine." - Roberto Mangabeira Unger
|
||||
Four components builds up a General Bot App:
|
||||
|
||||
* dialogs
|
||||
* models
|
||||
* services
|
||||
* tests
|
||||
|
||||
#### Dialogs
|
||||
|
||||
All code contained in a dialog builds the flow to custom conversations in
|
||||
built-in and additional packages .
|
||||
|
||||
|
||||
#### Models
|
||||
|
||||
Models builds the foundation of data relationships in form of entities.
|
||||
|
||||
|
||||
#### Services
|
||||
|
||||
Services are a façade for bot back-end logic and other custom processing.
|
||||
|
||||
#### Tests
|
||||
|
||||
Tests try to automate code execution validation before crashing in production.
|
||||
|
||||
|
||||
### .gbot
|
||||
|
||||
An expression of an artificial inteligence entity. A .gbot file defines
|
||||
all bots dependencies related to services and other resources.
|
||||
|
||||
### .gbtheme
|
||||
|
||||
A theme of a bot at a given time. CSS files & images that can compose all UI
|
||||
presentation and using it a branding can be done. [A sample .gbtheme is available](https://github.com/pragmatismo-io/Office365.gbtheme)
|
||||
|
||||
### .gbkb
|
||||
|
||||
A set of subjects that bot knows in a form of hierarchical menu-based QnA. [A sample .gbkb is available](https://github.com/pragmatismo-io/ProjectOnline.gbkb).
|
||||
|
||||
### .gblib
|
||||
|
||||
Shared code that can be used across bot apps.
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
### GeneralBots admin commands
|
||||
|
||||
General Bot can be controlled by the same chat window people talk to, so
|
||||
here is a list of admin commands related to deploying .gb* files.
|
||||
|
||||
| Command | Description |
|
||||
|-----------------|-----------------------------------------------------------------------------------------------------------------|
|
||||
| deployPackage | Deploy a KB package. Usage **deployPackage** [package-name]. Then, you need to run rebuildIndex. |
|
||||
| undeployPackage | Undeploy a KB. Usage **undeployPackage** [package-name]. |
|
||||
| redeployPackage | Undeploy and then deploys the KB. Usage **redeployPackage** [package-name]. Then, you need to run rebuildIndex. |
|
||||
| setupSecurity | Setup connection to user directories. |
|
||||
|
||||
Discontinued commands:
|
||||
|
||||
| Command | Description |Reason |
|
||||
|-----------------| -----------------------------------------------------------------------------------------------------------------|------|
|
||||
| rebuildIndex | Rebuild Azure Search indexes, must be run after **deployPackage** or **redeployPackage**. | Now it is called automatically |
|
||||
|
||||
### Credits & Inspiration
|
||||
|
||||
* Rodrigo Rodriguez (me@rodrigorodriguez.com) - Coding, Docs & Architecture.
|
||||
* David Lerner (david.lerner@hotmail.com) - UI, UX & Theming.
|
||||
* Eduardo Romeiro (eromeirosp@outlook.com) - Content & UX.
|
||||
* Jorge Ramos (jramos@pobox.com) - Coding, Docs & Architecture.
|
||||
|
||||
Powered by Microsoft [BOT Framework](https://dev.botframework.com/) and [Azure](http://www.azure.com).
|
||||
|
||||
General Bot Code Name is [Guaribas](https://en.wikipedia.org/wiki/Guaribas), the name of a city in Brasil, 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".
|
||||
|
||||
|
||||
## License & Warranty
|
||||
|
||||
General Bot Copyright (c) Pragmatismo.io. 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.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.
|
||||
|
|
|
|||
112
VERSION.md
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
# Release History
|
||||
|
||||
## Version 0.1.8
|
||||
|
||||
* Republishing.
|
||||
|
||||
## Version 0.1.7
|
||||
|
||||
* 100% automated development environement setup.
|
||||
* Azure Deployer based on ARM done - setup is easy as F5 in Visual Studio.
|
||||
* Auto-ngrok - No more reverse proxy manual configuration.
|
||||
* Strategy to replicate itself in several subscriptions done.
|
||||
|
||||
## Version 0.1.6
|
||||
|
||||
* Updated packages references.
|
||||
|
||||
## Version 0.1.5
|
||||
|
||||
* Updated packages references.
|
||||
|
||||
## Version 0.1.4
|
||||
|
||||
* Error handling improved and logging enriched as well.
|
||||
* Setting DATABASE_ is now STORAGE_.
|
||||
|
||||
|
||||
## Version 0.1.3
|
||||
|
||||
* FIX: Admin now is internationalized.
|
||||
* FIX: Webchat now receives a private token.
|
||||
* FIX: OAuth2 now has got revised and included state to avoid CSRF attacks.
|
||||
* FIX: Now server will only start with a secure administration password.
|
||||
|
||||
## Version 0.1.2
|
||||
|
||||
* NEW: kb.gbapp now has a complete browser of excel articles.
|
||||
* FIX: Some security improved.
|
||||
* NEW: Protocol changes for exchanging questions between UI and Bot Server.
|
||||
|
||||
## Version 0.1.0
|
||||
|
||||
- NEW: Migration to Bot Framework v4.
|
||||
|
||||
## Version 0.0.31
|
||||
|
||||
- FIX: Updated dependencies versions.
|
||||
|
||||
## Version 0.0.30
|
||||
|
||||
- FIX: Packages updated.
|
||||
- NEW: DATABASE_SYNC_ALTER environment parameter.
|
||||
- NEW: DATABASE_SYNC_FORCE environment parameter.
|
||||
- NEW: Define constraint names in MSSQL.
|
||||
|
||||
## Version 0.0.29
|
||||
|
||||
- NEW: Added STT and TTS capabilities to default.gbui.
|
||||
|
||||
## Version 0.0.28
|
||||
|
||||
- FIX: gbui packages updated.
|
||||
|
||||
## Version 0.0.27
|
||||
|
||||
- FIX: Packages updated.
|
||||
|
||||
## Version 0.0.26
|
||||
|
||||
- FIX: Packages updated.
|
||||
- NEW: If a bot package's name begins with '.', then it is ignored.
|
||||
- NEW: Created DATABASE_LOGGING environment parameter.
|
||||
|
||||
## Version 0.0.25
|
||||
|
||||
- FIX: Whastapp line now can be turned off;
|
||||
- FIX: More error logging on BuildMin.
|
||||
|
||||
## Version 0.0.24
|
||||
|
||||
- FIX: AskDialog compilation error.
|
||||
- FIX: More Whatsapp line adjustments: Duplicated 'Hi!' & log enrichment.
|
||||
|
||||
## Version 0.0.23
|
||||
|
||||
- FIX: Duplicated asking on main loop removed.
|
||||
- FIX: Whatsapp log phrase correction.
|
||||
- FIX: Directline can now receive messages sent in not-in-conversation, projector-only fashion.
|
||||
|
||||
## Version 0.0.22
|
||||
|
||||
- NEW: Auto-dispatch to dialog based on intent name.
|
||||
|
||||
## Version 0.0.21
|
||||
|
||||
- FIX: Whatsapp directline client improved.
|
||||
|
||||
## Version 0.0.20
|
||||
|
||||
- NEW: Whatsapp directline client is now working in preview.
|
||||
|
||||
## Version 0.0.19
|
||||
|
||||
- NEW: Whatsapp directline client started.
|
||||
- NEW: Console directline client.
|
||||
- NEW: Now each .gbapp has it own set of syspackages loaded.
|
||||
- NEW: Added support for Whatsapp external service key on bot instance model.
|
||||
|
||||
## Version 0.0.18
|
||||
|
||||
- FIX: .gbapp files now correctly loaded before other package types so custom models can be used to sync DB.
|
||||
- NEW: Removed Boot Package feature. Now every .gbot found on deploy folders are deployed on startup.
|
||||
89
add-req.sh
|
|
@ -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
askama.toml
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
148
deploy.cmd
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
@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 [GUARIBASDEPLOYER] 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 [GUARIBASDEPLOYER] Installing packages for default.gbui.
|
||||
call :ExecuteCmd !NPM_CMD! install
|
||||
echo [GUARIBASDEPLOYER] Building default.gbui.
|
||||
call :ExecuteCmd !NPM_CMD! run build
|
||||
IF !ERRORLEVEL! NEQ 0 goto error
|
||||
popd
|
||||
)
|
||||
|
||||
:: 4. Install typescript
|
||||
echo [GUARIBASDEPLOYER] 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%"
|
||||
|
||||
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[migrations_directory]
|
||||
dir = "migrations"
|
||||
|
||||
[print_schema]
|
||||
file = "src/shared/schema.rs"
|
||||
BIN
docs/images/general-bots-block-architecture.png
Normal file
|
After Width: | Height: | Size: 1 MiB |
BIN
docs/images/general-bots-composing-subjects-json-and-excel.gif
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 78 KiB |
BIN
docs/images/general-bots-stack.png
Normal file
|
After Width: | Height: | Size: 1,013 KiB |
BIN
docs/images/generalbots-open-core-starting-from-scratch.gif
Normal file
|
After Width: | Height: | Size: 27 KiB |
865
docs/reference/assets/css/main.css
Normal file
|
|
@ -0,0 +1,865 @@
|
|||
/*! normalize.css v1.1.3 | MIT License | git.io/normalize */
|
||||
/* ========================================================================== HTML5 display definitions ========================================================================== */
|
||||
/** Correct `block` display not defined in IE 6/7/8/9 and Firefox 3. */
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
|
||||
|
||||
/** Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. */
|
||||
audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
|
||||
|
||||
/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
|
||||
audio:not([controls]) { display: none; height: 0; }
|
||||
|
||||
/** Address styling not present in IE 7/8/9, Firefox 3, and Safari 4. Known issue: no IE 6 support. */
|
||||
[hidden] { display: none; }
|
||||
|
||||
/* ========================================================================== Base ========================================================================== */
|
||||
/** 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using `em` units. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
|
||||
html { font-size: 100%; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ font-family: sans-serif; }
|
||||
|
||||
/** Address `font-family` inconsistency between `textarea` and other form elements. */
|
||||
button, input, select, textarea { font-family: sans-serif; }
|
||||
|
||||
/** Address margins handled incorrectly in IE 6/7. */
|
||||
body { margin: 0; }
|
||||
|
||||
/* ========================================================================== Links ========================================================================== */
|
||||
/** Address `outline` inconsistency between Chrome and other browsers. */
|
||||
a:focus { outline: thin dotted; }
|
||||
a:active, a:hover { outline: 0; }
|
||||
|
||||
/** Improve readability when focused and also mouse hovered in all browsers. */
|
||||
/* ========================================================================== Typography ========================================================================== */
|
||||
/** Address font sizes and margins set differently in IE 6/7. Address font sizes within `section` and `article` in Firefox 4+, Safari 5, and Chrome. */
|
||||
h1 { font-size: 2em; margin: 0.67em 0; }
|
||||
|
||||
h2 { font-size: 1.5em; margin: 0.83em 0; }
|
||||
|
||||
h3 { font-size: 1.17em; margin: 1em 0; }
|
||||
|
||||
h4, .tsd-index-panel h3 { font-size: 1em; margin: 1.33em 0; }
|
||||
|
||||
h5 { font-size: 0.83em; margin: 1.67em 0; }
|
||||
|
||||
h6 { font-size: 0.67em; margin: 2.33em 0; }
|
||||
|
||||
/** Address styling not present in IE 7/8/9, Safari 5, and Chrome. */
|
||||
abbr[title] { border-bottom: 1px dotted; }
|
||||
|
||||
/** Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. */
|
||||
b, strong { font-weight: bold; }
|
||||
|
||||
blockquote { margin: 1em 40px; }
|
||||
|
||||
/** Address styling not present in Safari 5 and Chrome. */
|
||||
dfn { font-style: italic; }
|
||||
|
||||
/** Address differences between Firefox and other browsers. Known issue: no IE 6/7 normalization. */
|
||||
hr { box-sizing: content-box; height: 0; }
|
||||
|
||||
/** Address styling not present in IE 6/7/8/9. */
|
||||
mark { background: #ff0; color: #000; }
|
||||
|
||||
/** Address margins set differently in IE 6/7. */
|
||||
p, pre { margin: 1em 0; }
|
||||
|
||||
/** Correct font family set oddly in IE 6, Safari 4/5, and Chrome. */
|
||||
code, kbd, pre, samp { font-family: monospace, serif; _font-family: "courier new", monospace; font-size: 1em; }
|
||||
|
||||
/** Improve readability of pre-formatted text in all browsers. */
|
||||
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
|
||||
|
||||
/** Address CSS quotes not supported in IE 6/7. */
|
||||
q { quotes: none; }
|
||||
q:before, q:after { content: ""; content: none; }
|
||||
|
||||
/** Address `quotes` property not supported in Safari 4. */
|
||||
/** Address inconsistent and variable font size in all browsers. */
|
||||
small { font-size: 80%; }
|
||||
|
||||
/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
|
||||
sub { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
||||
|
||||
sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; top: -0.5em; }
|
||||
|
||||
sub { bottom: -0.25em; }
|
||||
|
||||
/* ========================================================================== Lists ========================================================================== */
|
||||
/** Address margins set differently in IE 6/7. */
|
||||
dl, menu, ol, ul { margin: 1em 0; }
|
||||
|
||||
dd { margin: 0 0 0 40px; }
|
||||
|
||||
/** Address paddings set differently in IE 6/7. */
|
||||
menu, ol, ul { padding: 0 0 0 40px; }
|
||||
|
||||
/** Correct list images handled incorrectly in IE 7. */
|
||||
nav ul, nav ol { list-style: none; list-style-image: none; }
|
||||
|
||||
/* ========================================================================== Embedded content ========================================================================== */
|
||||
/** 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3. 2. Improve image quality when scaled in IE 7. */
|
||||
img { border: 0; /* 1 */ -ms-interpolation-mode: bicubic; }
|
||||
|
||||
/* 2 */
|
||||
/** Correct overflow displayed oddly in IE 9. */
|
||||
svg:not(:root) { overflow: hidden; }
|
||||
|
||||
/* ========================================================================== Figures ========================================================================== */
|
||||
/** Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. */
|
||||
figure, form { margin: 0; }
|
||||
|
||||
/* ========================================================================== Forms ========================================================================== */
|
||||
/** Correct margin displayed oddly in IE 6/7. */
|
||||
/** Define consistent border, margin, and padding. */
|
||||
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
|
||||
|
||||
/** 1. Correct color not being inherited in IE 6/7/8/9. 2. Correct text not wrapping in Firefox 3. 3. Correct alignment displayed oddly in IE 6/7. */
|
||||
legend { border: 0; /* 1 */ padding: 0; white-space: normal; /* 2 */ *margin-left: -7px; }
|
||||
|
||||
/* 3 */
|
||||
/** 1. Correct font size not being inherited in all browsers. 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5, and Chrome. 3. Improve appearance and consistency in all browsers. */
|
||||
button, input, select, textarea { font-size: 100%; /* 1 */ margin: 0; /* 2 */ vertical-align: baseline; /* 3 */ *vertical-align: middle; }
|
||||
|
||||
/* 3 */
|
||||
/** Address Firefox 3+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
|
||||
button, input { line-height: normal; }
|
||||
|
||||
/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+. Correct `select` style inheritance in Firefox 4+ and Opera. */
|
||||
button, select { text-transform: none; }
|
||||
|
||||
/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. 4. Remove inner spacing in IE 7 without affecting normal text inputs. Known issue: inner spacing remains in IE 6. */
|
||||
button, html input[type="button"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ *overflow: visible; }
|
||||
|
||||
/* 4 */
|
||||
input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ *overflow: visible; }
|
||||
|
||||
/* 4 */
|
||||
/** Re-set default cursor for disabled elements. */
|
||||
button[disabled], html input[disabled] { cursor: default; }
|
||||
|
||||
/** 1. Address box sizing set to content-box in IE 8/9. 2. Remove excess padding in IE 8/9. 3. Remove excess padding in IE 7. Known issue: excess padding remains in IE 6. */
|
||||
input { /* 3 */ }
|
||||
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ *height: 13px; /* 3 */ *width: 13px; }
|
||||
input[type="search"] { -webkit-appearance: textfield; /* 1 */ /* 2 */ box-sizing: content-box; }
|
||||
input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
|
||||
|
||||
/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */
|
||||
/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */
|
||||
/** Remove inner padding and border in Firefox 3+. */
|
||||
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
|
||||
|
||||
/** 1. Remove default vertical scrollbar in IE 6/7/8/9. 2. Improve readability and alignment in all browsers. */
|
||||
textarea { overflow: auto; /* 1 */ vertical-align: top; }
|
||||
|
||||
/* 2 */
|
||||
/* ========================================================================== Tables ========================================================================== */
|
||||
/** Remove most spacing between table cells. */
|
||||
table { border-collapse: collapse; border-spacing: 0; }
|
||||
|
||||
/* Visual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name> */
|
||||
.hljs { display: inline-block; padding: 0.5em; background: white; color: black; }
|
||||
|
||||
.hljs-comment, .hljs-annotation, .hljs-template_comment, .diff .hljs-header, .hljs-chunk, .apache .hljs-cbracket { color: #008000; }
|
||||
|
||||
.hljs-keyword, .hljs-id, .hljs-built_in, .css .smalltalk .hljs-class, .hljs-winutils, .bash .hljs-variable, .tex .hljs-command, .hljs-request, .hljs-status, .nginx .hljs-title { color: #00f; }
|
||||
|
||||
.xml .hljs-tag { color: #00f; }
|
||||
.xml .hljs-tag .hljs-value { color: #00f; }
|
||||
|
||||
.hljs-string, .hljs-title, .hljs-parent, .hljs-tag .hljs-value, .hljs-rules .hljs-value { color: #a31515; }
|
||||
|
||||
.ruby .hljs-symbol { color: #a31515; }
|
||||
.ruby .hljs-symbol .hljs-string { color: #a31515; }
|
||||
|
||||
.hljs-template_tag, .django .hljs-variable, .hljs-addition, .hljs-flow, .hljs-stream, .apache .hljs-tag, .hljs-date, .tex .hljs-formula, .coffeescript .hljs-attribute { color: #a31515; }
|
||||
|
||||
.ruby .hljs-string, .hljs-decorator, .hljs-filter .hljs-argument, .hljs-localvars, .hljs-array, .hljs-attr_selector, .hljs-pseudo, .hljs-pi, .hljs-doctype, .hljs-deletion, .hljs-envvar, .hljs-shebang, .hljs-preprocessor, .hljs-pragma, .userType, .apache .hljs-sqbracket, .nginx .hljs-built_in, .tex .hljs-special, .hljs-prompt { color: #2b91af; }
|
||||
|
||||
.hljs-phpdoc, .hljs-javadoc, .hljs-xmlDocTag { color: #808080; }
|
||||
|
||||
.vhdl .hljs-typename { font-weight: bold; }
|
||||
.vhdl .hljs-string { color: #666666; }
|
||||
.vhdl .hljs-literal { color: #a31515; }
|
||||
.vhdl .hljs-attribute { color: #00b0e8; }
|
||||
|
||||
.xml .hljs-attribute { color: #f00; }
|
||||
|
||||
.col > :first-child, .col-1 > :first-child, .col-2 > :first-child, .col-3 > :first-child, .col-4 > :first-child, .col-5 > :first-child, .col-6 > :first-child, .col-7 > :first-child, .col-8 > :first-child, .col-9 > :first-child, .col-10 > :first-child, .col-11 > :first-child, .tsd-panel > :first-child, ul.tsd-descriptions > li > :first-child, .col > :first-child > :first-child, .col-1 > :first-child > :first-child, .col-2 > :first-child > :first-child, .col-3 > :first-child > :first-child, .col-4 > :first-child > :first-child, .col-5 > :first-child > :first-child, .col-6 > :first-child > :first-child, .col-7 > :first-child > :first-child, .col-8 > :first-child > :first-child, .col-9 > :first-child > :first-child, .col-10 > :first-child > :first-child, .col-11 > :first-child > :first-child, .tsd-panel > :first-child > :first-child, ul.tsd-descriptions > li > :first-child > :first-child, .col > :first-child > :first-child > :first-child, .col-1 > :first-child > :first-child > :first-child, .col-2 > :first-child > :first-child > :first-child, .col-3 > :first-child > :first-child > :first-child, .col-4 > :first-child > :first-child > :first-child, .col-5 > :first-child > :first-child > :first-child, .col-6 > :first-child > :first-child > :first-child, .col-7 > :first-child > :first-child > :first-child, .col-8 > :first-child > :first-child > :first-child, .col-9 > :first-child > :first-child > :first-child, .col-10 > :first-child > :first-child > :first-child, .col-11 > :first-child > :first-child > :first-child, .tsd-panel > :first-child > :first-child > :first-child, ul.tsd-descriptions > li > :first-child > :first-child > :first-child { margin-top: 0; }
|
||||
.col > :last-child, .col-1 > :last-child, .col-2 > :last-child, .col-3 > :last-child, .col-4 > :last-child, .col-5 > :last-child, .col-6 > :last-child, .col-7 > :last-child, .col-8 > :last-child, .col-9 > :last-child, .col-10 > :last-child, .col-11 > :last-child, .tsd-panel > :last-child, ul.tsd-descriptions > li > :last-child, .col > :last-child > :last-child, .col-1 > :last-child > :last-child, .col-2 > :last-child > :last-child, .col-3 > :last-child > :last-child, .col-4 > :last-child > :last-child, .col-5 > :last-child > :last-child, .col-6 > :last-child > :last-child, .col-7 > :last-child > :last-child, .col-8 > :last-child > :last-child, .col-9 > :last-child > :last-child, .col-10 > :last-child > :last-child, .col-11 > :last-child > :last-child, .tsd-panel > :last-child > :last-child, ul.tsd-descriptions > li > :last-child > :last-child, .col > :last-child > :last-child > :last-child, .col-1 > :last-child > :last-child > :last-child, .col-2 > :last-child > :last-child > :last-child, .col-3 > :last-child > :last-child > :last-child, .col-4 > :last-child > :last-child > :last-child, .col-5 > :last-child > :last-child > :last-child, .col-6 > :last-child > :last-child > :last-child, .col-7 > :last-child > :last-child > :last-child, .col-8 > :last-child > :last-child > :last-child, .col-9 > :last-child > :last-child > :last-child, .col-10 > :last-child > :last-child > :last-child, .col-11 > :last-child > :last-child > :last-child, .tsd-panel > :last-child > :last-child > :last-child, ul.tsd-descriptions > li > :last-child > :last-child > :last-child { margin-bottom: 0; }
|
||||
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 0 40px; }
|
||||
@media (max-width: 640px) { .container { padding: 0 20px; } }
|
||||
|
||||
.container-main { padding-bottom: 200px; }
|
||||
|
||||
.row { position: relative; margin: 0 -10px; }
|
||||
.row:after { visibility: hidden; display: block; content: ""; clear: both; height: 0; }
|
||||
|
||||
.col, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11 { box-sizing: border-box; float: left; padding: 0 10px; }
|
||||
|
||||
.col-1 { width: 8.33333%; }
|
||||
|
||||
.offset-1 { margin-left: 8.33333%; }
|
||||
|
||||
.col-2 { width: 16.66667%; }
|
||||
|
||||
.offset-2 { margin-left: 16.66667%; }
|
||||
|
||||
.col-3 { width: 25%; }
|
||||
|
||||
.offset-3 { margin-left: 25%; }
|
||||
|
||||
.col-4 { width: 33.33333%; }
|
||||
|
||||
.offset-4 { margin-left: 33.33333%; }
|
||||
|
||||
.col-5 { width: 41.66667%; }
|
||||
|
||||
.offset-5 { margin-left: 41.66667%; }
|
||||
|
||||
.col-6 { width: 50%; }
|
||||
|
||||
.offset-6 { margin-left: 50%; }
|
||||
|
||||
.col-7 { width: 58.33333%; }
|
||||
|
||||
.offset-7 { margin-left: 58.33333%; }
|
||||
|
||||
.col-8 { width: 66.66667%; }
|
||||
|
||||
.offset-8 { margin-left: 66.66667%; }
|
||||
|
||||
.col-9 { width: 75%; }
|
||||
|
||||
.offset-9 { margin-left: 75%; }
|
||||
|
||||
.col-10 { width: 83.33333%; }
|
||||
|
||||
.offset-10 { margin-left: 83.33333%; }
|
||||
|
||||
.col-11 { width: 91.66667%; }
|
||||
|
||||
.offset-11 { margin-left: 91.66667%; }
|
||||
|
||||
.tsd-kind-icon { display: block; position: relative; padding-left: 20px; text-indent: -20px; }
|
||||
.tsd-kind-icon:before { content: ''; display: inline-block; vertical-align: middle; width: 17px; height: 17px; margin: 0 3px 2px 0; background-image: url(../images/icons.png); }
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .tsd-kind-icon:before { background-image: url(../images/icons@2x.png); background-size: 238px 204px; } }
|
||||
|
||||
.tsd-signature.tsd-kind-icon:before { background-position: 0 -153px; }
|
||||
|
||||
.tsd-kind-object-literal > .tsd-kind-icon:before { background-position: 0px -17px; }
|
||||
.tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -17px; }
|
||||
.tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -17px; }
|
||||
|
||||
.tsd-kind-class > .tsd-kind-icon:before { background-position: 0px -34px; }
|
||||
.tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -34px; }
|
||||
.tsd-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -34px; }
|
||||
|
||||
.tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: 0px -51px; }
|
||||
.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -51px; }
|
||||
.tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -51px; }
|
||||
|
||||
.tsd-kind-interface > .tsd-kind-icon:before { background-position: 0px -68px; }
|
||||
.tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -68px; }
|
||||
.tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -68px; }
|
||||
|
||||
.tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: 0px -85px; }
|
||||
.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -85px; }
|
||||
.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -85px; }
|
||||
|
||||
.tsd-kind-module > .tsd-kind-icon:before { background-position: 0px -102px; }
|
||||
.tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -102px; }
|
||||
.tsd-kind-module.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -102px; }
|
||||
|
||||
.tsd-kind-external-module > .tsd-kind-icon:before { background-position: 0px -102px; }
|
||||
.tsd-kind-external-module.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -102px; }
|
||||
.tsd-kind-external-module.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -102px; }
|
||||
|
||||
.tsd-kind-enum > .tsd-kind-icon:before { background-position: 0px -119px; }
|
||||
.tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -119px; }
|
||||
.tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -119px; }
|
||||
|
||||
.tsd-kind-enum-member > .tsd-kind-icon:before { background-position: 0px -136px; }
|
||||
.tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -136px; }
|
||||
.tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -136px; }
|
||||
|
||||
.tsd-kind-signature > .tsd-kind-icon:before { background-position: 0px -153px; }
|
||||
.tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -153px; }
|
||||
.tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -153px; }
|
||||
|
||||
.tsd-kind-type-alias > .tsd-kind-icon:before { background-position: 0px -170px; }
|
||||
.tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -170px; }
|
||||
.tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -170px; }
|
||||
|
||||
.tsd-kind-variable > .tsd-kind-icon:before { background-position: -136px -0px; }
|
||||
.tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -0px; }
|
||||
.tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -0px; }
|
||||
|
||||
.tsd-kind-property > .tsd-kind-icon:before { background-position: -136px -0px; }
|
||||
.tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -0px; }
|
||||
.tsd-kind-property.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -0px; }
|
||||
|
||||
.tsd-kind-get-signature > .tsd-kind-icon:before { background-position: -136px -17px; }
|
||||
.tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -17px; }
|
||||
.tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -17px; }
|
||||
|
||||
.tsd-kind-set-signature > .tsd-kind-icon:before { background-position: -136px -34px; }
|
||||
.tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -34px; }
|
||||
.tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -34px; }
|
||||
|
||||
.tsd-kind-accessor > .tsd-kind-icon:before { background-position: -136px -51px; }
|
||||
.tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -51px; }
|
||||
.tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -51px; }
|
||||
|
||||
.tsd-kind-function > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-method > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-call-signature > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: -136px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -85px; }
|
||||
|
||||
.tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: -136px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -85px; }
|
||||
|
||||
.tsd-kind-constructor > .tsd-kind-icon:before { background-position: -136px -102px; }
|
||||
.tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -102px; }
|
||||
.tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -102px; }
|
||||
|
||||
.tsd-kind-constructor-signature > .tsd-kind-icon:before { background-position: -136px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -102px; }
|
||||
|
||||
.tsd-kind-index-signature > .tsd-kind-icon:before { background-position: -136px -119px; }
|
||||
.tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -119px; }
|
||||
.tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -119px; }
|
||||
|
||||
.tsd-kind-event > .tsd-kind-icon:before { background-position: -136px -136px; }
|
||||
.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -136px; }
|
||||
.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -136px; }
|
||||
|
||||
.tsd-is-static > .tsd-kind-icon:before { background-position: -136px -153px; }
|
||||
.tsd-is-static.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -153px; }
|
||||
.tsd-is-static.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -153px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-function > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-method > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-event > .tsd-kind-icon:before { background-position: -136px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -187px; }
|
||||
|
||||
.no-transition { transition: none !important; }
|
||||
|
||||
@-webkit-keyframes fade-in { from { opacity: 0; }
|
||||
to { opacity: 1; } }
|
||||
|
||||
@keyframes fade-in { from { opacity: 0; }
|
||||
to { opacity: 1; } }
|
||||
@-webkit-keyframes fade-out { from { opacity: 1; visibility: visible; }
|
||||
to { opacity: 0; } }
|
||||
@keyframes fade-out { from { opacity: 1; visibility: visible; }
|
||||
to { opacity: 0; } }
|
||||
@-webkit-keyframes fade-in-delayed { 0% { opacity: 0; }
|
||||
33% { opacity: 0; }
|
||||
100% { opacity: 1; } }
|
||||
@keyframes fade-in-delayed { 0% { opacity: 0; }
|
||||
33% { opacity: 0; }
|
||||
100% { opacity: 1; } }
|
||||
@-webkit-keyframes fade-out-delayed { 0% { opacity: 1; visibility: visible; }
|
||||
66% { opacity: 0; }
|
||||
100% { opacity: 0; } }
|
||||
@keyframes fade-out-delayed { 0% { opacity: 1; visibility: visible; }
|
||||
66% { opacity: 0; }
|
||||
100% { opacity: 0; } }
|
||||
@-webkit-keyframes shift-to-left { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
||||
to { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } }
|
||||
@keyframes shift-to-left { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
||||
to { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } }
|
||||
@-webkit-keyframes unshift-to-left { from { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@keyframes unshift-to-left { from { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@-webkit-keyframes pop-in-from-right { from { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@keyframes pop-in-from-right { from { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@-webkit-keyframes pop-out-to-right { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); visibility: visible; }
|
||||
to { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } }
|
||||
@keyframes pop-out-to-right { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); visibility: visible; }
|
||||
to { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } }
|
||||
body { background: #fdfdfd; font-family: "Segoe UI", sans-serif; font-size: 16px; color: #222; }
|
||||
|
||||
a { color: #4da6ff; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
code, pre { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; padding: 0.2em; margin: 0; font-size: 14px; background-color: rgba(0, 0, 0, 0.04); }
|
||||
|
||||
pre { padding: 10px; }
|
||||
pre code { padding: 0; font-size: 100%; background-color: transparent; }
|
||||
|
||||
.tsd-typography { line-height: 1.333em; }
|
||||
.tsd-typography ul { list-style: square; padding: 0 0 0 20px; margin: 0; }
|
||||
.tsd-typography h4, .tsd-typography .tsd-index-panel h3, .tsd-index-panel .tsd-typography h3, .tsd-typography h5, .tsd-typography h6 { font-size: 1em; margin: 0; }
|
||||
.tsd-typography h5, .tsd-typography h6 { font-weight: normal; }
|
||||
.tsd-typography p, .tsd-typography ul, .tsd-typography ol { margin: 1em 0; }
|
||||
|
||||
@media (min-width: 901px) and (max-width: 1024px) { html.default .col-content { width: 72%; }
|
||||
html.default .col-menu { width: 28%; }
|
||||
html.default .tsd-navigation { padding-left: 10px; } }
|
||||
@media (max-width: 900px) { html.default .col-content { float: none; width: 100%; }
|
||||
html.default .col-menu { position: fixed !important; overflow: auto; -webkit-overflow-scrolling: touch; overflow-scrolling: touch; z-index: 1024; top: 0 !important; bottom: 0 !important; left: auto !important; right: 0 !important; width: 100%; padding: 20px 20px 0 0; max-width: 450px; visibility: hidden; background-color: #fff; -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
html.default .col-menu > *:last-child { padding-bottom: 20px; }
|
||||
html.default .overlay { content: ""; display: block; position: fixed; z-index: 1023; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.75); visibility: hidden; }
|
||||
html.default.to-has-menu .overlay { -webkit-animation: fade-in 0.4s; animation: fade-in 0.4s; }
|
||||
html.default.to-has-menu header, html.default.to-has-menu footer, html.default.to-has-menu .col-content { -webkit-animation: shift-to-left 0.4s; animation: shift-to-left 0.4s; }
|
||||
html.default.to-has-menu .col-menu { -webkit-animation: pop-in-from-right 0.4s; animation: pop-in-from-right 0.4s; }
|
||||
html.default.from-has-menu .overlay { -webkit-animation: fade-out 0.4s; animation: fade-out 0.4s; }
|
||||
html.default.from-has-menu header, html.default.from-has-menu footer, html.default.from-has-menu .col-content { -webkit-animation: unshift-to-left 0.4s; animation: unshift-to-left 0.4s; }
|
||||
html.default.from-has-menu .col-menu { -webkit-animation: pop-out-to-right 0.4s; animation: pop-out-to-right 0.4s; }
|
||||
html.default.has-menu body { overflow: hidden; }
|
||||
html.default.has-menu .overlay { visibility: visible; }
|
||||
html.default.has-menu header, html.default.has-menu footer, html.default.has-menu .col-content { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
html.default.has-menu .col-menu { visibility: visible; -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
|
||||
.tsd-page-title { padding: 70px 0 20px 0; margin: 0 0 40px 0; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, 0.35); }
|
||||
.tsd-page-title h1 { margin: 0; }
|
||||
|
||||
.tsd-breadcrumb { margin: 0; padding: 0; color: #808080; }
|
||||
.tsd-breadcrumb a { color: #808080; text-decoration: none; }
|
||||
.tsd-breadcrumb a:hover { text-decoration: underline; }
|
||||
.tsd-breadcrumb li { display: inline; }
|
||||
.tsd-breadcrumb li:after { content: " / "; }
|
||||
|
||||
html.minimal .container { margin: 0; }
|
||||
html.minimal .container-main { padding-top: 50px; padding-bottom: 0; }
|
||||
html.minimal .content-wrap { padding-left: 300px; }
|
||||
html.minimal .tsd-navigation { position: fixed !important; overflow: auto; -webkit-overflow-scrolling: touch; overflow-scrolling: touch; box-sizing: border-box; z-index: 1; left: 0; top: 40px; bottom: 0; width: 300px; padding: 20px; margin: 0; }
|
||||
html.minimal .tsd-member .tsd-member { margin-left: 0; }
|
||||
html.minimal .tsd-page-toolbar { position: fixed; z-index: 2; }
|
||||
html.minimal #tsd-filter .tsd-filter-group { right: 0; -webkit-transform: none; transform: none; }
|
||||
html.minimal footer { background-color: transparent; }
|
||||
html.minimal footer .container { padding: 0; }
|
||||
html.minimal .tsd-generator { padding: 0; }
|
||||
@media (max-width: 900px) { html.minimal .tsd-navigation { display: none; }
|
||||
html.minimal .content-wrap { padding-left: 0; } }
|
||||
|
||||
dl.tsd-comment-tags { overflow: hidden; }
|
||||
dl.tsd-comment-tags dt { clear: both; float: left; padding: 1px 5px; margin: 0 10px 0 0; border-radius: 4px; border: 1px solid #808080; color: #808080; font-size: 0.8em; font-weight: normal; }
|
||||
dl.tsd-comment-tags dd { margin: 0 0 10px 0; }
|
||||
dl.tsd-comment-tags p { margin: 0; }
|
||||
|
||||
.tsd-panel.tsd-comment .lead { font-size: 1.1em; line-height: 1.333em; margin-bottom: 2em; }
|
||||
.tsd-panel.tsd-comment .lead:last-child { margin-bottom: 0; }
|
||||
|
||||
.toggle-protected .tsd-is-private { display: none; }
|
||||
|
||||
.toggle-public .tsd-is-private, .toggle-public .tsd-is-protected, .toggle-public .tsd-is-private-protected { display: none; }
|
||||
|
||||
.toggle-inherited .tsd-is-inherited { display: none; }
|
||||
|
||||
.toggle-only-exported .tsd-is-not-exported { display: none; }
|
||||
|
||||
.toggle-externals .tsd-is-external { display: none; }
|
||||
|
||||
#tsd-filter { position: relative; display: inline-block; height: 40px; vertical-align: bottom; }
|
||||
.no-filter #tsd-filter { display: none; }
|
||||
#tsd-filter .tsd-filter-group { display: inline-block; height: 40px; vertical-align: bottom; white-space: nowrap; }
|
||||
#tsd-filter input { display: none; }
|
||||
@media (max-width: 900px) { #tsd-filter .tsd-filter-group { display: block; position: absolute; top: 40px; right: 20px; height: auto; background-color: #fff; visibility: hidden; -webkit-transform: translate(50%, 0); transform: translate(50%, 0); box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
.has-options #tsd-filter .tsd-filter-group { visibility: visible; }
|
||||
.to-has-options #tsd-filter .tsd-filter-group { -webkit-animation: fade-in 0.2s; animation: fade-in 0.2s; }
|
||||
.from-has-options #tsd-filter .tsd-filter-group { -webkit-animation: fade-out 0.2s; animation: fade-out 0.2s; }
|
||||
#tsd-filter label, #tsd-filter .tsd-select { display: block; padding-right: 20px; } }
|
||||
|
||||
footer { border-top: 1px solid #eee; background-color: #fff; }
|
||||
footer.with-border-bottom { border-bottom: 1px solid #eee; }
|
||||
footer .tsd-legend-group { font-size: 0; }
|
||||
footer .tsd-legend { display: inline-block; width: 25%; padding: 0; font-size: 16px; list-style: none; line-height: 1.333em; vertical-align: top; }
|
||||
@media (max-width: 900px) { footer .tsd-legend { width: 50%; } }
|
||||
|
||||
.tsd-hierarchy { list-style: square; padding: 0 0 0 20px; margin: 0; }
|
||||
.tsd-hierarchy .target { font-weight: bold; }
|
||||
|
||||
.tsd-index-panel .tsd-index-content { margin-bottom: -30px !important; }
|
||||
.tsd-index-panel .tsd-index-section { margin-bottom: 30px !important; }
|
||||
.tsd-index-panel h3 { margin: 0 -20px 10px -20px; padding: 0 20px 10px 20px; border-bottom: 1px solid #eee; }
|
||||
.tsd-index-panel ul.tsd-index-list { -webkit-column-count: 3; -moz-column-count: 3; -ms-column-count: 3; -o-column-count: 3; column-count: 3; -webkit-column-gap: 20px; -moz-column-gap: 20px; -ms-column-gap: 20px; -o-column-gap: 20px; column-gap: 20px; padding: 0; list-style: none; line-height: 1.333em; }
|
||||
@media (max-width: 900px) { .tsd-index-panel ul.tsd-index-list { -webkit-column-count: 1; -moz-column-count: 1; -ms-column-count: 1; -o-column-count: 1; column-count: 1; } }
|
||||
@media (min-width: 901px) and (max-width: 1024px) { .tsd-index-panel ul.tsd-index-list { -webkit-column-count: 2; -moz-column-count: 2; -ms-column-count: 2; -o-column-count: 2; column-count: 2; } }
|
||||
.tsd-index-panel ul.tsd-index-list li { -webkit-column-break-inside: avoid; -moz-column-break-inside: avoid; -ms-column-break-inside: avoid; -o-column-break-inside: avoid; column-break-inside: avoid; -webkit-page-break-inside: avoid; -moz-page-break-inside: avoid; -ms-page-break-inside: avoid; -o-page-break-inside: avoid; page-break-inside: avoid; }
|
||||
.tsd-index-panel a, .tsd-index-panel .tsd-parent-kind-module a { color: #9600ff; }
|
||||
.tsd-index-panel .tsd-parent-kind-interface a { color: #7da01f; }
|
||||
.tsd-index-panel .tsd-parent-kind-enum a { color: #cc9900; }
|
||||
.tsd-index-panel .tsd-parent-kind-class a { color: #4da6ff; }
|
||||
.tsd-index-panel .tsd-kind-module a { color: #9600ff; }
|
||||
.tsd-index-panel .tsd-kind-interface a { color: #7da01f; }
|
||||
.tsd-index-panel .tsd-kind-enum a { color: #cc9900; }
|
||||
.tsd-index-panel .tsd-kind-class a { color: #4da6ff; }
|
||||
.tsd-index-panel .tsd-is-private a { color: #808080; }
|
||||
|
||||
.tsd-flag { display: inline-block; padding: 1px 5px; border-radius: 4px; color: #fff; background-color: #808080; text-indent: 0; font-size: 14px; font-weight: normal; }
|
||||
|
||||
.tsd-anchor { position: absolute; top: -100px; }
|
||||
|
||||
.tsd-member { position: relative; }
|
||||
.tsd-member .tsd-anchor + h3 { margin-top: 0; margin-bottom: 0; border-bottom: none; }
|
||||
|
||||
.tsd-navigation { padding: 0 0 0 40px; }
|
||||
.tsd-navigation a { display: block; padding-top: 2px; padding-bottom: 2px; border-left: 2px solid transparent; color: #222; text-decoration: none; transition: border-left-color 0.1s; }
|
||||
.tsd-navigation a:hover { text-decoration: underline; }
|
||||
.tsd-navigation ul { margin: 0; padding: 0; list-style: none; }
|
||||
.tsd-navigation li { padding: 0; }
|
||||
|
||||
.tsd-navigation.primary { padding-bottom: 40px; }
|
||||
.tsd-navigation.primary a { display: block; padding-top: 6px; padding-bottom: 6px; }
|
||||
.tsd-navigation.primary ul li a { padding-left: 5px; }
|
||||
.tsd-navigation.primary ul li li a { padding-left: 25px; }
|
||||
.tsd-navigation.primary ul li li li a { padding-left: 45px; }
|
||||
.tsd-navigation.primary ul li li li li a { padding-left: 65px; }
|
||||
.tsd-navigation.primary ul li li li li li a { padding-left: 85px; }
|
||||
.tsd-navigation.primary ul li li li li li li a { padding-left: 105px; }
|
||||
.tsd-navigation.primary > ul { border-bottom: 1px solid #eee; }
|
||||
.tsd-navigation.primary li { border-top: 1px solid #eee; }
|
||||
.tsd-navigation.primary li.current > a { font-weight: bold; }
|
||||
.tsd-navigation.primary li.label span { display: block; padding: 20px 0 6px 5px; color: #808080; }
|
||||
.tsd-navigation.primary li.globals + li > span, .tsd-navigation.primary li.globals + li > a { padding-top: 20px; }
|
||||
|
||||
.tsd-navigation.secondary ul { transition: opacity 0.2s; }
|
||||
.tsd-navigation.secondary ul li a { padding-left: 25px; }
|
||||
.tsd-navigation.secondary ul li li a { padding-left: 45px; }
|
||||
.tsd-navigation.secondary ul li li li a { padding-left: 65px; }
|
||||
.tsd-navigation.secondary ul li li li li a { padding-left: 85px; }
|
||||
.tsd-navigation.secondary ul li li li li li a { padding-left: 105px; }
|
||||
.tsd-navigation.secondary ul li li li li li li a { padding-left: 125px; }
|
||||
.tsd-navigation.secondary ul.current a { border-left-color: #eee; }
|
||||
.tsd-navigation.secondary li.focus > a, .tsd-navigation.secondary ul.current li.focus > a { border-left-color: #000; }
|
||||
.tsd-navigation.secondary li.current { margin-top: 20px; margin-bottom: 20px; border-left-color: #eee; }
|
||||
.tsd-navigation.secondary li.current > a { font-weight: bold; }
|
||||
|
||||
@media (min-width: 901px) { .menu-sticky-wrap { position: static; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky { position: fixed; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-current { position: fixed; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-current ul.before-current, .no-csspositionsticky .menu-sticky-wrap.sticky-current ul.after-current { opacity: 0; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-bottom { position: absolute; top: auto !important; left: auto !important; bottom: 0; right: 0; }
|
||||
.csspositionsticky .menu-sticky-wrap.sticky { position: -webkit-sticky; position: sticky; }
|
||||
.csspositionsticky .menu-sticky-wrap.sticky-current { position: -webkit-sticky; position: sticky; } }
|
||||
|
||||
.tsd-panel { margin: 20px 0; padding: 20px; background-color: #fff; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
.tsd-panel:empty { display: none; }
|
||||
.tsd-panel > h1, .tsd-panel > h2, .tsd-panel > h3 { margin: 1.5em -20px 10px -20px; padding: 0 20px 10px 20px; border-bottom: 1px solid #eee; }
|
||||
.tsd-panel > h1.tsd-before-signature, .tsd-panel > h2.tsd-before-signature, .tsd-panel > h3.tsd-before-signature { margin-bottom: 0; border-bottom: 0; }
|
||||
.tsd-panel table { display: block; width: 100%; overflow: auto; margin-top: 10px; word-break: normal; word-break: keep-all; }
|
||||
.tsd-panel table th { font-weight: bold; }
|
||||
.tsd-panel table th, .tsd-panel table td { padding: 6px 13px; border: 1px solid #ddd; }
|
||||
.tsd-panel table tr { background-color: #fff; border-top: 1px solid #ccc; }
|
||||
.tsd-panel table tr:nth-child(2n) { background-color: #f8f8f8; }
|
||||
|
||||
.tsd-panel-group { margin: 60px 0; }
|
||||
.tsd-panel-group > h1, .tsd-panel-group > h2, .tsd-panel-group > h3 { padding-left: 20px; padding-right: 20px; }
|
||||
|
||||
#tsd-search { transition: background-color 0.2s; }
|
||||
#tsd-search .title { position: relative; z-index: 2; }
|
||||
#tsd-search .field { position: absolute; left: 0; top: 0; right: 40px; height: 40px; }
|
||||
#tsd-search .field input { box-sizing: border-box; position: relative; top: -50px; z-index: 1; width: 100%; padding: 0 10px; opacity: 0; outline: 0; border: 0; background: transparent; color: #222; }
|
||||
#tsd-search .field label { position: absolute; overflow: hidden; right: -40px; }
|
||||
#tsd-search .field input, #tsd-search .title { transition: opacity 0.2s; }
|
||||
#tsd-search .results { position: absolute; visibility: hidden; top: 40px; width: 100%; margin: 0; padding: 0; list-style: none; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
#tsd-search .results li { padding: 0 10px; background-color: #fdfdfd; }
|
||||
#tsd-search .results li:nth-child(even) { background-color: #fff; }
|
||||
#tsd-search .results li.state { display: none; }
|
||||
#tsd-search .results li.current, #tsd-search .results li:hover { background-color: #eee; }
|
||||
#tsd-search .results a { display: block; }
|
||||
#tsd-search .results a:before { top: 10px; }
|
||||
#tsd-search .results span.parent { color: #808080; font-weight: normal; }
|
||||
#tsd-search.has-focus { background-color: #eee; }
|
||||
#tsd-search.has-focus .field input { top: 0; opacity: 1; }
|
||||
#tsd-search.has-focus .title { z-index: 0; opacity: 0; }
|
||||
#tsd-search.has-focus .results { visibility: visible; }
|
||||
#tsd-search.loading .results li.state.loading { display: block; }
|
||||
#tsd-search.failure .results li.state.failure { display: block; }
|
||||
|
||||
.tsd-signature { margin: 0 0 1em 0; padding: 10px; border: 1px solid #eee; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; }
|
||||
.tsd-signature.tsd-kind-icon { padding-left: 30px; }
|
||||
.tsd-signature.tsd-kind-icon:before { top: 10px; left: 10px; }
|
||||
.tsd-panel > .tsd-signature { margin-left: -20px; margin-right: -20px; border-width: 1px 0; }
|
||||
.tsd-panel > .tsd-signature.tsd-kind-icon { padding-left: 40px; }
|
||||
.tsd-panel > .tsd-signature.tsd-kind-icon:before { left: 20px; }
|
||||
|
||||
.tsd-signature-symbol { color: #808080; font-weight: normal; }
|
||||
|
||||
.tsd-signature-type { font-style: italic; font-weight: normal; }
|
||||
|
||||
.tsd-signatures { padding: 0; margin: 0 0 1em 0; border: 1px solid #eee; }
|
||||
.tsd-signatures .tsd-signature { margin: 0; border-width: 1px 0 0 0; transition: background-color 0.1s; }
|
||||
.tsd-signatures .tsd-signature:first-child { border-top-width: 0; }
|
||||
.tsd-signatures .tsd-signature.current { background-color: #eee; }
|
||||
.tsd-signatures.active > .tsd-signature { cursor: pointer; }
|
||||
.tsd-panel > .tsd-signatures { margin-left: -20px; margin-right: -20px; border-width: 1px 0; }
|
||||
.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon { padding-left: 40px; }
|
||||
.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before { left: 20px; }
|
||||
.tsd-panel > a.anchor + .tsd-signatures { border-top-width: 0; margin-top: -20px; }
|
||||
|
||||
ul.tsd-descriptions { position: relative; overflow: hidden; transition: height 0.3s; padding: 0; list-style: none; }
|
||||
ul.tsd-descriptions.active > .tsd-description { display: none; }
|
||||
ul.tsd-descriptions.active > .tsd-description.current { display: block; }
|
||||
ul.tsd-descriptions.active > .tsd-description.fade-in { -webkit-animation: fade-in-delayed 0.3s; animation: fade-in-delayed 0.3s; }
|
||||
ul.tsd-descriptions.active > .tsd-description.fade-out { -webkit-animation: fade-out-delayed 0.3s; animation: fade-out-delayed 0.3s; position: absolute; display: block; top: 0; left: 0; right: 0; opacity: 0; visibility: hidden; }
|
||||
ul.tsd-descriptions h4, ul.tsd-descriptions .tsd-index-panel h3, .tsd-index-panel ul.tsd-descriptions h3 { font-size: 16px; margin: 1em 0 0.5em 0; }
|
||||
|
||||
ul.tsd-parameters, ul.tsd-type-parameters { list-style: square; margin: 0; padding-left: 20px; }
|
||||
ul.tsd-parameters > li.tsd-parameter-siganture, ul.tsd-type-parameters > li.tsd-parameter-siganture { list-style: none; margin-left: -20px; }
|
||||
ul.tsd-parameters h5, ul.tsd-type-parameters h5 { font-size: 16px; margin: 1em 0 0.5em 0; }
|
||||
ul.tsd-parameters .tsd-comment, ul.tsd-type-parameters .tsd-comment { margin-top: -0.5em; }
|
||||
|
||||
.tsd-sources { font-size: 14px; color: #808080; margin: 0 0 1em 0; }
|
||||
.tsd-sources a { color: #808080; text-decoration: underline; }
|
||||
.tsd-sources ul, .tsd-sources p { margin: 0 !important; }
|
||||
.tsd-sources ul { list-style: none; padding: 0; }
|
||||
|
||||
.tsd-page-toolbar { position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 40px; color: #333; background: #fff; border-bottom: 1px solid #eee; }
|
||||
.tsd-page-toolbar a { color: #333; text-decoration: none; }
|
||||
.tsd-page-toolbar a.title { font-weight: bold; }
|
||||
.tsd-page-toolbar a.title:hover { text-decoration: underline; }
|
||||
.tsd-page-toolbar .table-wrap { display: table; width: 100%; height: 40px; }
|
||||
.tsd-page-toolbar .table-cell { display: table-cell; position: relative; white-space: nowrap; line-height: 40px; }
|
||||
.tsd-page-toolbar .table-cell:first-child { width: 100%; }
|
||||
|
||||
.tsd-widget:before, .tsd-select .tsd-select-label:before, .tsd-select .tsd-select-list li:before { content: ""; display: inline-block; width: 40px; height: 40px; margin: 0 -8px 0 0; background-image: url(../images/widgets.png); background-repeat: no-repeat; text-indent: -1024px; vertical-align: bottom; }
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .tsd-widget:before, .tsd-select .tsd-select-label:before, .tsd-select .tsd-select-list li:before { background-image: url(../images/widgets@2x.png); background-size: 320px 40px; } }
|
||||
|
||||
.tsd-widget { display: inline-block; overflow: hidden; opacity: 0.6; height: 40px; transition: opacity 0.1s, background-color 0.2s; vertical-align: bottom; cursor: pointer; }
|
||||
.tsd-widget:hover { opacity: 0.8; }
|
||||
.tsd-widget.active { opacity: 1; background-color: #eee; }
|
||||
.tsd-widget.no-caption { width: 40px; }
|
||||
.tsd-widget.no-caption:before { margin: 0; }
|
||||
.tsd-widget.search:before { background-position: 0 0; }
|
||||
.tsd-widget.menu:before { background-position: -40px 0; }
|
||||
.tsd-widget.options:before { background-position: -80px 0; }
|
||||
.tsd-widget.options, .tsd-widget.menu { display: none; }
|
||||
@media (max-width: 900px) { .tsd-widget.options, .tsd-widget.menu { display: inline-block; } }
|
||||
input[type=checkbox] + .tsd-widget:before { background-position: -120px 0; }
|
||||
input[type=checkbox]:checked + .tsd-widget:before { background-position: -160px 0; }
|
||||
|
||||
.tsd-select { position: relative; display: inline-block; height: 40px; transition: opacity 0.1s, background-color 0.2s; vertical-align: bottom; cursor: pointer; }
|
||||
.tsd-select .tsd-select-label { opacity: 0.6; transition: opacity 0.2s; }
|
||||
.tsd-select .tsd-select-label:before { background-position: -240px 0; }
|
||||
.tsd-select.active .tsd-select-label { opacity: 0.8; }
|
||||
.tsd-select.active .tsd-select-list { visibility: visible; opacity: 1; transition-delay: 0s; }
|
||||
.tsd-select .tsd-select-list { position: absolute; visibility: hidden; top: 40px; left: 0; margin: 0; padding: 0; opacity: 0; list-style: none; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); transition: visibility 0s 0.2s, opacity 0.2s; }
|
||||
.tsd-select .tsd-select-list li { padding: 0 20px 0 0; background-color: #fdfdfd; }
|
||||
.tsd-select .tsd-select-list li:before { background-position: 40px 0; }
|
||||
.tsd-select .tsd-select-list li:nth-child(even) { background-color: #fff; }
|
||||
.tsd-select .tsd-select-list li:hover { background-color: #eee; }
|
||||
.tsd-select .tsd-select-list li.selected:before { background-position: -200px 0; }
|
||||
@media (max-width: 900px) { .tsd-select .tsd-select-list { top: 0; left: auto; right: 100%; margin-right: -5px; }
|
||||
.tsd-select .tsd-select-label:before { background-position: -280px 0; } }
|
||||
|
||||
img { max-width: 100%; }
|
||||
7
docs/reference/assets/css/main.css.map
Normal file
BIN
docs/reference/assets/images/icons.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
docs/reference/assets/images/icons@2x.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
docs/reference/assets/images/widgets.png
Normal file
|
After Width: | Height: | Size: 480 B |
BIN
docs/reference/assets/images/widgets@2x.png
Normal file
|
After Width: | Height: | Size: 855 B |
5
docs/reference/assets/js/main.js
Normal file
3
docs/reference/assets/js/search.js
Normal file
237
docs/reference/classes/_src_app_.gbserver.html
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>GBServer | botserver</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../assets/css/main.css">
|
||||
</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.js" 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">botserver</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>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</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">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="../globals.html">Globals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="../modules/_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="_src_app_.gbserver.html">GBServer</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>Class GBServer</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel tsd-comment">
|
||||
<div class="tsd-comment tsd-typography">
|
||||
<div class="lead">
|
||||
<p>General Bots open-core entry point.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-hierarchy">
|
||||
<h3>Hierarchy</h3>
|
||||
<ul class="tsd-hierarchy">
|
||||
<li>
|
||||
<span class="target">GBServer</span>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section ">
|
||||
<h3>Methods</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-static"><a href="_src_app_.gbserver.html#run" class="tsd-kind-icon">run</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group ">
|
||||
<h2>Methods</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class tsd-is-static">
|
||||
<a name="run" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagStatic">Static</span> run</h3>
|
||||
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class tsd-is-static">
|
||||
<li class="tsd-signature tsd-kind-icon">run<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">void</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-descriptions">
|
||||
<li class="tsd-description">
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/app.ts#L70">src/app.ts:70</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<div class="tsd-comment tsd-typography">
|
||||
<div class="lead">
|
||||
<p> Program entry-point.</p>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="../globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="current tsd-kind-external-module">
|
||||
<a href="../modules/_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
<ul class="current">
|
||||
<li class="current tsd-kind-class tsd-parent-kind-external-module">
|
||||
<a href="_src_app_.gbserver.html" class="tsd-kind-icon">GBServer</a>
|
||||
<ul>
|
||||
<li class=" tsd-kind-method tsd-parent-kind-class tsd-is-static">
|
||||
<a href="_src_app_.gbserver.html#run" class="tsd-kind-icon">run</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="after-current">
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#apppackages" class="tsd-kind-icon">app<wbr>Packages</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#bodyparser" class="tsd-kind-icon">body<wbr>Parser</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#express" class="tsd-kind-icon">express</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#logger" class="tsd-kind-icon">logger</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="../modules/_src_app_.html#opn" class="tsd-kind-icon">opn</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-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<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>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</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-call-signature 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="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="../assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
340
docs/reference/globals.html
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>botserver</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="assets/css/main.css">
|
||||
</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.js" 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">botserver</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>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</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">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="globals.html">Globals</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1> botserver</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section ">
|
||||
<h3>External modules</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_admin_gbapp_dialogs_admindialog_.html" class="tsd-kind-icon">"packages/admin.gbapp/dialogs/<wbr>Admin<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_admin_gbapp_index_.html" class="tsd-kind-icon">"packages/admin.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_admin_gbapp_models_adminmodel_.html" class="tsd-kind-icon">"packages/admin.gbapp/models/<wbr>Admin<wbr>Model"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_admin_gbapp_services_gbadminservice_.html" class="tsd-kind-icon">"packages/admin.gbapp/services/GBAdmin<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_admin_gbapp_strings_.html" class="tsd-kind-icon">"packages/admin.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_analytics_gblib_index_.html" class="tsd-kind-icon">"packages/analytics.gblib/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_analytics_gblib_models_index_.html" class="tsd-kind-icon">"packages/analytics.gblib/models/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_analytics_gblib_services_analyticsservice_.html" class="tsd-kind-icon">"packages/analytics.gblib/services/<wbr>Analytics<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_azuredeployer_gbapp_dialogs_botfarmdialog_.html" class="tsd-kind-icon">"packages/azuredeployer.gbapp/dialogs/<wbr>Bot<wbr>Farm<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_azuredeployer_gbapp_index_.html" class="tsd-kind-icon">"packages/azuredeployer.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_azuredeployer_gbapp_services_azuredeployerservice_.html" class="tsd-kind-icon">"packages/azuredeployer.gbapp/services/<wbr>Azure<wbr>Deployer<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_azuredeployer_gbapp_strings_.html" class="tsd-kind-icon">"packages/azuredeployer.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_console_gblib_index_.html" class="tsd-kind-icon">"packages/console.gblib/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_console_gblib_services_consoledirectline_.html" class="tsd-kind-icon">"packages/console.gblib/services/<wbr>Console<wbr>Direct<wbr>Line"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_dialogs_welcomedialog_.html" class="tsd-kind-icon">"packages/core.gbapp/dialogs/<wbr>Welcome<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_dialogs_whoamidialog_.html" class="tsd-kind-icon">"packages/core.gbapp/dialogs/<wbr>Who<wbr>AmIDialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_index_.html" class="tsd-kind-icon">"packages/core.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_models_gbmodel_.html" class="tsd-kind-icon">"packages/core.gbapp/models/GBModel"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_services_gbconfigservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBConfig<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_services_gbconversationalservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBConversational<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_services_gbcoreservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBCore<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_services_gbdeployer_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBDeployer"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_services_gbimporter_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBImporter"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_services_gbminservice_.html" class="tsd-kind-icon">"packages/core.gbapp/services/GBMin<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_core_gbapp_strings_.html" class="tsd-kind-icon">"packages/core.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_customer_satisfaction_gbapp_dialogs_feedbackdialog_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Feedback<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_customer_satisfaction_gbapp_dialogs_qualitydialog_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Quality<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_customer_satisfaction_gbapp_index_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_customer_satisfaction_gbapp_models_index_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/models/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_customer_satisfaction_gbapp_services_csservice_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/services/CSService"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_customer_satisfaction_gbapp_strings_.html" class="tsd-kind-icon">"packages/customer-<wbr>satisfaction.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_kb_gbapp_dialogs_askdialog_.html" class="tsd-kind-icon">"packages/kb.gbapp/dialogs/<wbr>Ask<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_kb_gbapp_dialogs_faqdialog_.html" class="tsd-kind-icon">"packages/kb.gbapp/dialogs/<wbr>Faq<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_kb_gbapp_dialogs_menudialog_.html" class="tsd-kind-icon">"packages/kb.gbapp/dialogs/<wbr>Menu<wbr>Dialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_kb_gbapp_index_.html" class="tsd-kind-icon">"packages/kb.gbapp/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_kb_gbapp_models_index_.html" class="tsd-kind-icon">"packages/kb.gbapp/models/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_kb_gbapp_services_kbservice_.html" class="tsd-kind-icon">"packages/kb.gbapp/services/KBService"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_kb_gbapp_strings_.html" class="tsd-kind-icon">"packages/kb.gbapp/strings"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_security_gblib_index_.html" class="tsd-kind-icon">"packages/security.gblib/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_security_gblib_models_index_.html" class="tsd-kind-icon">"packages/security.gblib/models/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_security_gblib_services_secservice_.html" class="tsd-kind-icon">"packages/security.gblib/services/<wbr>Sec<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_whatsapp_gblib_index_.html" class="tsd-kind-icon">"packages/whatsapp.gblib/index"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_packages_whatsapp_gblib_services_whatsappdirectline_.html" class="tsd-kind-icon">"packages/whatsapp.gblib/services/<wbr>Whatsapp<wbr>Direct<wbr>Line"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_src_app_.html" class="tsd-kind-icon">"src/app"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_src_logger_.html" class="tsd-kind-icon">"src/logger"</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals current ">
|
||||
<a href="globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_dialogs_admindialog_.html">"packages/admin.gbapp/dialogs/<wbr>Admin<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_index_.html">"packages/admin.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_models_adminmodel_.html">"packages/admin.gbapp/models/<wbr>Admin<wbr>Model"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_services_gbadminservice_.html">"packages/admin.gbapp/services/GBAdmin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_strings_.html">"packages/admin.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_analytics_gblib_index_.html">"packages/analytics.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_analytics_gblib_models_index_.html">"packages/analytics.gblib/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_analytics_gblib_services_analyticsservice_.html">"packages/analytics.gblib/services/<wbr>Analytics<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_dialogs_botfarmdialog_.html">"packages/azuredeployer.gbapp/dialogs/<wbr>Bot<wbr>Farm<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_index_.html">"packages/azuredeployer.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_services_azuredeployerservice_.html">"packages/azuredeployer.gbapp/services/<wbr>Azure<wbr>Deployer<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_strings_.html">"packages/azuredeployer.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_console_gblib_index_.html">"packages/console.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_console_gblib_services_consoledirectline_.html">"packages/console.gblib/services/<wbr>Console<wbr>Direct<wbr>Line"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_dialogs_welcomedialog_.html">"packages/core.gbapp/dialogs/<wbr>Welcome<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_dialogs_whoamidialog_.html">"packages/core.gbapp/dialogs/<wbr>Who<wbr>AmIDialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_index_.html">"packages/core.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_models_gbmodel_.html">"packages/core.gbapp/models/GBModel"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbconfigservice_.html">"packages/core.gbapp/services/GBConfig<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbconversationalservice_.html">"packages/core.gbapp/services/GBConversational<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbcoreservice_.html">"packages/core.gbapp/services/GBCore<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbdeployer_.html">"packages/core.gbapp/services/GBDeployer"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbimporter_.html">"packages/core.gbapp/services/GBImporter"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbminservice_.html">"packages/core.gbapp/services/GBMin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_strings_.html">"packages/core.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_dialogs_feedbackdialog_.html">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Feedback<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_dialogs_qualitydialog_.html">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Quality<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_index_.html">"packages/customer-<wbr>satisfaction.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_models_index_.html">"packages/customer-<wbr>satisfaction.gbapp/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_services_csservice_.html">"packages/customer-<wbr>satisfaction.gbapp/services/CSService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_strings_.html">"packages/customer-<wbr>satisfaction.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_askdialog_.html">"packages/kb.gbapp/dialogs/<wbr>Ask<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_faqdialog_.html">"packages/kb.gbapp/dialogs/<wbr>Faq<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_menudialog_.html">"packages/kb.gbapp/dialogs/<wbr>Menu<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_index_.html">"packages/kb.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_models_index_.html">"packages/kb.gbapp/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_services_kbservice_.html">"packages/kb.gbapp/services/KBService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_strings_.html">"packages/kb.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_security_gblib_index_.html">"packages/security.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_security_gblib_models_index_.html">"packages/security.gblib/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_security_gblib_services_secservice_.html">"packages/security.gblib/services/<wbr>Sec<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_whatsapp_gblib_index_.html">"packages/whatsapp.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_whatsapp_gblib_services_whatsappdirectline_.html">"packages/whatsapp.gblib/services/<wbr>Whatsapp<wbr>Direct<wbr>Line"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_src_logger_.html">"src/logger"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</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-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<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>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</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-call-signature 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="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
286
docs/reference/index.html
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>botserver</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="assets/css/main.css">
|
||||
</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.js" 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">botserver</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>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</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">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="globals.html">Globals</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1> botserver</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<div class="tsd-panel tsd-typography">
|
||||
<p><em>This is a General Bots open core package, more information can be found on the <a href="https://github.com/pragmatismo-io/BotServer">BotServer</a> repository.</em></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_dialogs_admindialog_.html">"packages/admin.gbapp/dialogs/<wbr>Admin<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_index_.html">"packages/admin.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_models_adminmodel_.html">"packages/admin.gbapp/models/<wbr>Admin<wbr>Model"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_services_gbadminservice_.html">"packages/admin.gbapp/services/GBAdmin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_admin_gbapp_strings_.html">"packages/admin.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_analytics_gblib_index_.html">"packages/analytics.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_analytics_gblib_models_index_.html">"packages/analytics.gblib/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_analytics_gblib_services_analyticsservice_.html">"packages/analytics.gblib/services/<wbr>Analytics<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_dialogs_botfarmdialog_.html">"packages/azuredeployer.gbapp/dialogs/<wbr>Bot<wbr>Farm<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_index_.html">"packages/azuredeployer.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_services_azuredeployerservice_.html">"packages/azuredeployer.gbapp/services/<wbr>Azure<wbr>Deployer<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_azuredeployer_gbapp_strings_.html">"packages/azuredeployer.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_console_gblib_index_.html">"packages/console.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_console_gblib_services_consoledirectline_.html">"packages/console.gblib/services/<wbr>Console<wbr>Direct<wbr>Line"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_dialogs_welcomedialog_.html">"packages/core.gbapp/dialogs/<wbr>Welcome<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_dialogs_whoamidialog_.html">"packages/core.gbapp/dialogs/<wbr>Who<wbr>AmIDialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_index_.html">"packages/core.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_models_gbmodel_.html">"packages/core.gbapp/models/GBModel"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbconfigservice_.html">"packages/core.gbapp/services/GBConfig<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbconversationalservice_.html">"packages/core.gbapp/services/GBConversational<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbcoreservice_.html">"packages/core.gbapp/services/GBCore<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbdeployer_.html">"packages/core.gbapp/services/GBDeployer"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbimporter_.html">"packages/core.gbapp/services/GBImporter"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_services_gbminservice_.html">"packages/core.gbapp/services/GBMin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_core_gbapp_strings_.html">"packages/core.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_dialogs_feedbackdialog_.html">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Feedback<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_dialogs_qualitydialog_.html">"packages/customer-<wbr>satisfaction.gbapp/dialogs/<wbr>Quality<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_index_.html">"packages/customer-<wbr>satisfaction.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_models_index_.html">"packages/customer-<wbr>satisfaction.gbapp/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_services_csservice_.html">"packages/customer-<wbr>satisfaction.gbapp/services/CSService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_customer_satisfaction_gbapp_strings_.html">"packages/customer-<wbr>satisfaction.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_askdialog_.html">"packages/kb.gbapp/dialogs/<wbr>Ask<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_faqdialog_.html">"packages/kb.gbapp/dialogs/<wbr>Faq<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_dialogs_menudialog_.html">"packages/kb.gbapp/dialogs/<wbr>Menu<wbr>Dialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_index_.html">"packages/kb.gbapp/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_models_index_.html">"packages/kb.gbapp/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_services_kbservice_.html">"packages/kb.gbapp/services/KBService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_kb_gbapp_strings_.html">"packages/kb.gbapp/strings"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_security_gblib_index_.html">"packages/security.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_security_gblib_models_index_.html">"packages/security.gblib/models/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_security_gblib_services_secservice_.html">"packages/security.gblib/services/<wbr>Sec<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_whatsapp_gblib_index_.html">"packages/whatsapp.gblib/index"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_packages_whatsapp_gblib_services_whatsappdirectline_.html">"packages/whatsapp.gblib/services/<wbr>Whatsapp<wbr>Direct<wbr>Line"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_src_logger_.html">"src/logger"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</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-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<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>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</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-call-signature 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="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
248
docs/reference/modules/_src_app_.html
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>"src/app" | botserver</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../assets/css/main.css">
|
||||
</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.js" 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">botserver</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>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</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">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="../globals.html">Globals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>External module "src/app"</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section ">
|
||||
<h3>Classes</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-class tsd-parent-kind-external-module"><a href="../classes/_src_app_.gbserver.html" class="tsd-kind-icon">GBServer</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-index-section tsd-is-not-exported">
|
||||
<h3>Variables</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#apppackages" class="tsd-kind-icon">app<wbr>Packages</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#bodyparser" class="tsd-kind-icon">body<wbr>Parser</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#express" class="tsd-kind-icon">express</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#logger" class="tsd-kind-icon">logger</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_app_.html#opn" class="tsd-kind-icon">opn</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group tsd-is-not-exported">
|
||||
<h2>Variables</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="apppackages" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagLet">Let</span> app<wbr>Packages</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">app<wbr>Packages<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol"> = new Array<IGBPackage>()</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/app.ts#L59">src/app.ts:59</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="bodyparser" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> body<wbr>Parser</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">body<wbr>Parser<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = require("body-parser")</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/app.ts#L38">src/app.ts:38</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="express" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> express</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">express<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = require("express")</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/app.ts#L37">src/app.ts:37</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="logger" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> logger</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">logger<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = require("./logger")</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/app.ts#L36">src/app.ts:36</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="opn" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> opn</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">opn<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = require('opn')</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/app.ts#L39">src/app.ts:39</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="../globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="current tsd-kind-external-module">
|
||||
<a href="_src_app_.html">"src/app"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
<li class=" tsd-kind-class tsd-parent-kind-external-module">
|
||||
<a href="../classes/_src_app_.gbserver.html" class="tsd-kind-icon">GBServer</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#apppackages" class="tsd-kind-icon">app<wbr>Packages</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#bodyparser" class="tsd-kind-icon">body<wbr>Parser</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#express" class="tsd-kind-icon">express</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#logger" class="tsd-kind-icon">logger</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_app_.html#opn" class="tsd-kind-icon">opn</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-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<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>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</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-call-signature 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="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="../assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
427
docs/reference/modules/_src_logger_.html
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>"src/logger" | botserver</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../assets/css/main.css">
|
||||
</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.js" 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">botserver</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>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</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">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="../globals.html">Globals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="_src_logger_.html">"src/logger"</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>External module "src/logger"</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section tsd-is-not-exported">
|
||||
<h3>Variables</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#createlogger" class="tsd-kind-icon">create<wbr>Logger</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#format" class="tsd-kind-icon">format</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#logger" class="tsd-kind-icon">logger</a></li>
|
||||
<li class="tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#transports" class="tsd-kind-icon">transports</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tsd-index-section tsd-is-not-exported">
|
||||
<h3>Object literals</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-object-literal tsd-parent-kind-external-module tsd-is-not-exported"><a href="_src_logger_.html#config" class="tsd-kind-icon">config</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group tsd-is-not-exported">
|
||||
<h2>Variables</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="createlogger" class="tsd-anchor"></a>
|
||||
<h3>create<wbr>Logger</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">create<wbr>Logger<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L33">src/logger.ts:33</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="format" class="tsd-anchor"></a>
|
||||
<h3>format</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">format<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L33">src/logger.ts:33</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="logger" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> logger</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">logger<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol"> = createLogger({format: format.combine(format.colorize(),format.simple(),format.label({ label: 'GeneralBots' }),format.timestamp(),format.printf(nfo => {return `${nfo.timestamp} [${nfo.label}] ${nfo.level}: ${nfo.message}`})),levels: config.levels,transports: [new transports.Console()]})</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L58">src/logger.ts:58</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="transports" class="tsd-anchor"></a>
|
||||
<h3>transports</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">transports<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">any</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L33">src/logger.ts:33</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel-group tsd-member-group tsd-is-not-exported">
|
||||
<h2>Object literals</h2>
|
||||
<section class="tsd-panel tsd-member tsd-kind-object-literal tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a name="config" class="tsd-anchor"></a>
|
||||
<h3><span class="tsd-flag ts-flagConst">Const</span> config</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">config<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">object</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L35">src/logger.ts:35</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<section class="tsd-panel tsd-member tsd-kind-object-literal tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors" class="tsd-anchor"></a>
|
||||
<h3>colors</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">colors<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">object</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L46">src/logger.ts:46</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.custom" class="tsd-anchor"></a>
|
||||
<h3>custom</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">custom<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "yellow"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L54">src/logger.ts:54</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.data" class="tsd-anchor"></a>
|
||||
<h3>data</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">data<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "grey"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L50">src/logger.ts:50</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.debug" class="tsd-anchor"></a>
|
||||
<h3>debug</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">debug<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "blue"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L48">src/logger.ts:48</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.error" class="tsd-anchor"></a>
|
||||
<h3>error</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">error<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "red"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L47">src/logger.ts:47</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.info" class="tsd-anchor"></a>
|
||||
<h3>info</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">info<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "green"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L51">src/logger.ts:51</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.silly" class="tsd-anchor"></a>
|
||||
<h3>silly</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">silly<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "magenta"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L53">src/logger.ts:53</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.verbose" class="tsd-anchor"></a>
|
||||
<h3>verbose</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">verbose<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "cyan"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L52">src/logger.ts:52</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.colors.warn" class="tsd-anchor"></a>
|
||||
<h3>warn</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">warn<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = "yellow"</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L49">src/logger.ts:49</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-object-literal tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels" class="tsd-anchor"></a>
|
||||
<h3>levels</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">levels<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">object</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L36">src/logger.ts:36</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.custom-1" class="tsd-anchor"></a>
|
||||
<h3>custom</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">custom<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 7</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L44">src/logger.ts:44</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.data-1" class="tsd-anchor"></a>
|
||||
<h3>data</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">data<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 3</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L40">src/logger.ts:40</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.debug-1" class="tsd-anchor"></a>
|
||||
<h3>debug</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">debug<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 1</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L38">src/logger.ts:38</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.error-1" class="tsd-anchor"></a>
|
||||
<h3>error</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">error<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 0</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L37">src/logger.ts:37</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.info-1" class="tsd-anchor"></a>
|
||||
<h3>info</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">info<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 4</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L41">src/logger.ts:41</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.silly-1" class="tsd-anchor"></a>
|
||||
<h3>silly</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">silly<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 6</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L43">src/logger.ts:43</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.verbose-1" class="tsd-anchor"></a>
|
||||
<h3>verbose</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">verbose<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 5</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L42">src/logger.ts:42</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
<section class="tsd-panel tsd-member tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported">
|
||||
<a name="config.levels.warn-1" class="tsd-anchor"></a>
|
||||
<h3>warn</h3>
|
||||
<div class="tsd-signature tsd-kind-icon">warn<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span><span class="tsd-signature-symbol"> = 2</span></div>
|
||||
<aside class="tsd-sources">
|
||||
<ul>
|
||||
<li>Defined in <a href="https://github.com/pragmatismo-io/botserver/blob/ecf2ba3/src/logger.ts#L39">src/logger.ts:39</a></li>
|
||||
</ul>
|
||||
</aside>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="../globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="current tsd-kind-external-module">
|
||||
<a href="_src_logger_.html">"src/logger"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#createlogger" class="tsd-kind-icon">create<wbr>Logger</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#format" class="tsd-kind-icon">format</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#logger" class="tsd-kind-icon">logger</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#transports" class="tsd-kind-icon">transports</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-object-literal tsd-parent-kind-external-module tsd-is-not-exported">
|
||||
<a href="_src_logger_.html#config" class="tsd-kind-icon">config</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-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<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>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</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-call-signature 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="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="../assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="../assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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"
|
||||
2
gbot.cmd
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
@echo off
|
||||
node dist/src/app.js
|
||||
|
|
@ -1 +0,0 @@
|
|||
{}
|
||||
BIN
logo.png
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 7.6 KiB |
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
DROP INDEX idx_bot_memories_key;
|
||||
DROP INDEX idx_bot_memories_bot_id;
|
||||
DROP TABLE bot_memories;
|
||||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
|
|
@ -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';
|
||||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
@ -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';
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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';
|
||||
|
|
@ -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
|
||||
|
|
@ -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)';
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
-- Drop session_website_associations table and related indexes
|
||||
DROP TABLE IF EXISTS session_website_associations;
|
||||
|
||||
-- Drop website_crawls table and related objects
|
||||
DROP TRIGGER IF EXISTS website_crawls_updated_at_trigger ON website_crawls;
|
||||
DROP FUNCTION IF EXISTS update_website_crawls_updated_at();
|
||||
DROP TABLE IF EXISTS website_crawls;
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
-- Create website_crawls table for tracking crawled websites
|
||||
CREATE TABLE IF NOT EXISTS website_crawls (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bot_id UUID NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
last_crawled TIMESTAMPTZ,
|
||||
next_crawl TIMESTAMPTZ,
|
||||
expires_policy VARCHAR(20) NOT NULL DEFAULT '1d',
|
||||
max_depth INTEGER DEFAULT 3,
|
||||
max_pages INTEGER DEFAULT 100,
|
||||
crawl_status SMALLINT DEFAULT 0, -- 0=pending, 1=success, 2=processing, 3=error
|
||||
pages_crawled INTEGER DEFAULT 0,
|
||||
error_message TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
-- Ensure unique URL per bot
|
||||
CONSTRAINT unique_bot_url UNIQUE (bot_id, url),
|
||||
|
||||
-- Foreign key to bots table
|
||||
CONSTRAINT fk_website_crawls_bot
|
||||
FOREIGN KEY (bot_id)
|
||||
REFERENCES bots(id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Create indexes for efficient queries
|
||||
CREATE INDEX IF NOT EXISTS idx_website_crawls_bot_id ON website_crawls(bot_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_website_crawls_next_crawl ON website_crawls(next_crawl);
|
||||
CREATE INDEX IF NOT EXISTS idx_website_crawls_url ON website_crawls(url);
|
||||
CREATE INDEX IF NOT EXISTS idx_website_crawls_status ON website_crawls(crawl_status);
|
||||
|
||||
-- Create trigger to update updated_at timestamp
|
||||
CREATE OR REPLACE FUNCTION update_website_crawls_updated_at()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER website_crawls_updated_at_trigger
|
||||
BEFORE UPDATE ON website_crawls
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_website_crawls_updated_at();
|
||||
|
||||
-- Create session_website_associations table for tracking websites added to sessions
|
||||
-- Similar to session_kb_associations but for websites
|
||||
CREATE TABLE IF NOT EXISTS session_website_associations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL,
|
||||
bot_id UUID NOT NULL,
|
||||
website_url TEXT NOT NULL,
|
||||
collection_name TEXT NOT NULL,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
added_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
added_by_tool VARCHAR(255),
|
||||
|
||||
-- Ensure unique website per session
|
||||
CONSTRAINT unique_session_website UNIQUE (session_id, website_url),
|
||||
|
||||
-- Foreign key to sessions table
|
||||
CONSTRAINT fk_session_website_session
|
||||
FOREIGN KEY (session_id)
|
||||
REFERENCES user_sessions(id)
|
||||
ON DELETE CASCADE,
|
||||
|
||||
-- Foreign key to bots table
|
||||
CONSTRAINT fk_session_website_bot
|
||||
FOREIGN KEY (bot_id)
|
||||
REFERENCES bots(id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Create indexes for efficient queries
|
||||
CREATE INDEX IF NOT EXISTS idx_session_website_associations_session_id
|
||||
ON session_website_associations(session_id) WHERE is_active = true;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_session_website_associations_bot_id
|
||||
ON session_website_associations(bot_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_session_website_associations_url
|
||||
ON session_website_associations(website_url);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_session_website_associations_collection
|
||||
ON session_website_associations(collection_name);
|
||||
|
|
@ -1,248 +0,0 @@
|
|||
-- Rollback Migration: 6.1.0 Enterprise Features
|
||||
-- WARNING: This will delete all enterprise feature data!
|
||||
-- NOTE: TABLES AND INDEXES ONLY - No views, triggers, or functions per project standards
|
||||
-- Includes rollback for: config ID fixes, connected accounts, bot hierarchy, monitors
|
||||
|
||||
-- ============================================================================
|
||||
-- ROLLBACK: Bot Hierarchy and Monitors (from 6.1.3)
|
||||
-- ============================================================================
|
||||
|
||||
-- Drop comments first
|
||||
COMMENT ON TABLE public.user_organizations IS NULL;
|
||||
COMMENT ON TABLE public.email_received_events IS NULL;
|
||||
COMMENT ON TABLE public.folder_change_events IS NULL;
|
||||
COMMENT ON TABLE public.folder_monitors IS NULL;
|
||||
COMMENT ON TABLE public.email_monitors IS NULL;
|
||||
COMMENT ON COLUMN public.bots.inherit_parent_config IS NULL;
|
||||
COMMENT ON COLUMN public.bots.enabled_tabs_json IS NULL;
|
||||
COMMENT ON COLUMN public.bots.parent_bot_id IS NULL;
|
||||
COMMENT ON TABLE public.system_automations IS NULL;
|
||||
|
||||
-- Drop user organizations table
|
||||
DROP INDEX IF EXISTS idx_user_orgs_default;
|
||||
DROP INDEX IF EXISTS idx_user_orgs_org;
|
||||
DROP INDEX IF EXISTS idx_user_orgs_user;
|
||||
DROP TABLE IF EXISTS public.user_organizations;
|
||||
|
||||
-- Drop email received events table
|
||||
DROP INDEX IF EXISTS idx_email_events_received;
|
||||
DROP INDEX IF EXISTS idx_email_events_processed;
|
||||
DROP INDEX IF EXISTS idx_email_events_monitor;
|
||||
DROP TABLE IF EXISTS public.email_received_events;
|
||||
|
||||
-- Drop folder change events table
|
||||
DROP INDEX IF EXISTS idx_folder_events_created;
|
||||
DROP INDEX IF EXISTS idx_folder_events_processed;
|
||||
DROP INDEX IF EXISTS idx_folder_events_monitor;
|
||||
DROP TABLE IF EXISTS public.folder_change_events;
|
||||
|
||||
-- Drop folder monitors table
|
||||
DROP INDEX IF EXISTS idx_folder_monitors_account_email;
|
||||
DROP INDEX IF EXISTS idx_folder_monitors_active;
|
||||
DROP INDEX IF EXISTS idx_folder_monitors_provider;
|
||||
DROP INDEX IF EXISTS idx_folder_monitors_bot_id;
|
||||
DROP TABLE IF EXISTS public.folder_monitors;
|
||||
|
||||
-- Drop email monitors table
|
||||
DROP INDEX IF EXISTS idx_email_monitors_active;
|
||||
DROP INDEX IF EXISTS idx_email_monitors_email;
|
||||
DROP INDEX IF EXISTS idx_email_monitors_bot_id;
|
||||
DROP TABLE IF EXISTS public.email_monitors;
|
||||
|
||||
-- Remove bot hierarchy columns
|
||||
DROP INDEX IF EXISTS idx_bots_parent_bot_id;
|
||||
ALTER TABLE public.bots DROP COLUMN IF EXISTS inherit_parent_config;
|
||||
ALTER TABLE public.bots DROP COLUMN IF EXISTS enabled_tabs_json;
|
||||
ALTER TABLE public.bots DROP COLUMN IF EXISTS parent_bot_id;
|
||||
|
||||
-- ============================================================================
|
||||
-- ROLLBACK: Connected Accounts (from 6.1.2)
|
||||
-- ============================================================================
|
||||
|
||||
DROP INDEX IF EXISTS idx_account_sync_items_unique;
|
||||
DROP INDEX IF EXISTS idx_account_sync_items_embedding;
|
||||
DROP INDEX IF EXISTS idx_account_sync_items_date;
|
||||
DROP INDEX IF EXISTS idx_account_sync_items_type;
|
||||
DROP INDEX IF EXISTS idx_account_sync_items_account;
|
||||
DROP TABLE IF EXISTS account_sync_items;
|
||||
|
||||
DROP INDEX IF EXISTS idx_session_account_assoc_unique;
|
||||
DROP INDEX IF EXISTS idx_session_account_assoc_active;
|
||||
DROP INDEX IF EXISTS idx_session_account_assoc_account;
|
||||
DROP INDEX IF EXISTS idx_session_account_assoc_session;
|
||||
DROP TABLE IF EXISTS session_account_associations;
|
||||
|
||||
DROP INDEX IF EXISTS idx_connected_accounts_bot_email;
|
||||
DROP INDEX IF EXISTS idx_connected_accounts_status;
|
||||
DROP INDEX IF EXISTS idx_connected_accounts_provider;
|
||||
DROP INDEX IF EXISTS idx_connected_accounts_email;
|
||||
DROP INDEX IF EXISTS idx_connected_accounts_user_id;
|
||||
DROP INDEX IF EXISTS idx_connected_accounts_bot_id;
|
||||
DROP TABLE IF EXISTS connected_accounts;
|
||||
|
||||
-- ============================================================================
|
||||
-- ROLLBACK: Config ID Type Fixes (from 6.1.1)
|
||||
-- Revert UUID columns back to TEXT
|
||||
-- ============================================================================
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'bot_configuration'
|
||||
AND column_name = 'id'
|
||||
AND data_type = 'uuid') THEN
|
||||
ALTER TABLE bot_configuration
|
||||
ALTER COLUMN id TYPE TEXT USING id::text;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'server_configuration'
|
||||
AND column_name = 'id'
|
||||
AND data_type = 'uuid') THEN
|
||||
ALTER TABLE server_configuration
|
||||
ALTER COLUMN id TYPE TEXT USING id::text;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'tenant_configuration'
|
||||
AND column_name = 'id'
|
||||
AND data_type = 'uuid') THEN
|
||||
ALTER TABLE tenant_configuration
|
||||
ALTER COLUMN id TYPE TEXT USING id::text;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'model_configurations'
|
||||
AND column_name = 'id'
|
||||
AND data_type = 'uuid') THEN
|
||||
ALTER TABLE model_configurations
|
||||
ALTER COLUMN id TYPE TEXT USING id::text;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'connection_configurations'
|
||||
AND column_name = 'id'
|
||||
AND data_type = 'uuid') THEN
|
||||
ALTER TABLE connection_configurations
|
||||
ALTER COLUMN id TYPE TEXT USING id::text;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'component_installations'
|
||||
AND column_name = 'id'
|
||||
AND data_type = 'uuid') THEN
|
||||
ALTER TABLE component_installations
|
||||
ALTER COLUMN id TYPE TEXT USING id::text;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'component_logs'
|
||||
AND column_name = 'id'
|
||||
AND data_type = 'uuid') THEN
|
||||
ALTER TABLE component_logs
|
||||
ALTER COLUMN id TYPE TEXT USING id::text;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'gbot_config_sync'
|
||||
AND column_name = 'id'
|
||||
AND data_type = 'uuid') THEN
|
||||
ALTER TABLE gbot_config_sync
|
||||
ALTER COLUMN id TYPE TEXT USING id::text;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- ============================================================================
|
||||
-- ROLLBACK: Original 6.1.0 Enterprise Features
|
||||
-- ============================================================================
|
||||
|
||||
-- Drop test support tables
|
||||
DROP TABLE IF EXISTS test_execution_logs;
|
||||
DROP TABLE IF EXISTS test_accounts;
|
||||
|
||||
-- Drop calendar tables
|
||||
DROP TABLE IF EXISTS calendar_shares;
|
||||
DROP TABLE IF EXISTS calendar_resource_bookings;
|
||||
DROP TABLE IF EXISTS calendar_resources;
|
||||
|
||||
-- Drop task tables
|
||||
DROP TABLE IF EXISTS task_recurrence;
|
||||
DROP TABLE IF EXISTS task_time_entries;
|
||||
DROP TABLE IF EXISTS task_dependencies;
|
||||
|
||||
-- Drop collaboration tables
|
||||
DROP TABLE IF EXISTS document_presence;
|
||||
|
||||
-- Drop drive tables
|
||||
DROP TABLE IF EXISTS storage_quotas;
|
||||
DROP TABLE IF EXISTS file_sync_status;
|
||||
DROP TABLE IF EXISTS file_trash;
|
||||
DROP TABLE IF EXISTS file_activities;
|
||||
DROP TABLE IF EXISTS file_shares;
|
||||
DROP TABLE IF EXISTS file_comments;
|
||||
DROP TABLE IF EXISTS file_versions;
|
||||
|
||||
-- Drop meet tables
|
||||
DROP TABLE IF EXISTS user_virtual_backgrounds;
|
||||
DROP TABLE IF EXISTS meeting_captions;
|
||||
DROP TABLE IF EXISTS meeting_waiting_room;
|
||||
DROP TABLE IF EXISTS meeting_questions;
|
||||
DROP TABLE IF EXISTS meeting_polls;
|
||||
DROP TABLE IF EXISTS meeting_breakout_rooms;
|
||||
DROP TABLE IF EXISTS meeting_recordings;
|
||||
|
||||
-- Drop email tables (order matters due to foreign keys)
|
||||
DROP TABLE IF EXISTS shared_mailbox_members;
|
||||
DROP TABLE IF EXISTS shared_mailboxes;
|
||||
DROP TABLE IF EXISTS distribution_lists;
|
||||
DROP TABLE IF EXISTS email_label_assignments;
|
||||
DROP TABLE IF EXISTS email_labels;
|
||||
DROP TABLE IF EXISTS email_rules;
|
||||
DROP TABLE IF EXISTS email_auto_responders;
|
||||
DROP TABLE IF EXISTS email_templates;
|
||||
DROP TABLE IF EXISTS scheduled_emails;
|
||||
DROP TABLE IF EXISTS email_signatures;
|
||||
DROP TABLE IF EXISTS global_email_signatures;
|
||||
-- Drop triggers and functions
|
||||
DROP TRIGGER IF EXISTS external_connections_updated_at_trigger ON external_connections;
|
||||
DROP FUNCTION IF EXISTS update_external_connections_updated_at();
|
||||
|
||||
DROP TRIGGER IF EXISTS dynamic_table_definitions_updated_at_trigger ON dynamic_table_definitions;
|
||||
DROP FUNCTION IF EXISTS update_dynamic_table_definitions_updated_at();
|
||||
|
||||
-- Drop indexes
|
||||
DROP INDEX IF EXISTS idx_external_connections_name;
|
||||
DROP INDEX IF EXISTS idx_external_connections_bot_id;
|
||||
|
||||
DROP INDEX IF EXISTS idx_dynamic_table_fields_name;
|
||||
DROP INDEX IF EXISTS idx_dynamic_table_fields_table_id;
|
||||
|
||||
DROP INDEX IF EXISTS idx_dynamic_table_definitions_connection;
|
||||
DROP INDEX IF EXISTS idx_dynamic_table_definitions_name;
|
||||
DROP INDEX IF EXISTS idx_dynamic_table_definitions_bot_id;
|
||||
|
||||
-- Drop tables (order matters due to foreign keys)
|
||||
DROP TABLE IF EXISTS external_connections;
|
||||
DROP TABLE IF EXISTS dynamic_table_fields;
|
||||
DROP TABLE IF EXISTS dynamic_table_definitions;
|
||||
7696
package-lock.json
generated
Normal file
97
package.json
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"name": "botserver",
|
||||
"version": "0.1.8",
|
||||
"description": "General Bot Community Edition open-core server.",
|
||||
"main": "./src/app.ts",
|
||||
"homepage": "http://www.generalbot.com",
|
||||
"contributors": [
|
||||
"Rodrigo Rodriguez <me@rodrigorodriguez.com>",
|
||||
"Jorge Ramos <jramos@pobox.com>"
|
||||
],
|
||||
"license": "AGPL-3.0",
|
||||
"preferGlobal": true,
|
||||
"bin": {
|
||||
"gbot": "./dist/src/app.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pragmatismo-io/BotServer.git"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"start": "node ./dist/src/app.js",
|
||||
"startIde": "npm-run-all clean --parallel watch:build watch:server --print-label",
|
||||
"watch:build": "tsc --watch",
|
||||
"watch:server": "nodemon './dist/index.js' --watch './dist'",
|
||||
"test": "mocha -r ts-node/register src/**/*.test.ts",
|
||||
"build-docs": "typedoc --options typedoc.json src/"
|
||||
},
|
||||
"engines": {
|
||||
"node": "=8.11.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/microsoft-graph-client": "1.3.0",
|
||||
"@types/chai": "4.1.7",
|
||||
"@types/mocha": "5.2.5",
|
||||
"@types/sequelize": "4.27.30",
|
||||
"@types/url-join": "0.8.2",
|
||||
"@types/winston": "2.4.4",
|
||||
"adal-node": "0.1.28",
|
||||
"async": "2.6.1",
|
||||
"async-promises": "0.2.1",
|
||||
"azure-arm-cognitiveservices": "2.2.0",
|
||||
"azure-arm-resource": "7.0.1",
|
||||
"azure-arm-search": "^1.2.0-preview",
|
||||
"azure-arm-sql": "5.3.0",
|
||||
"azure-arm-website": "5.4.0",
|
||||
"body-parser": "1.18.3",
|
||||
"botbuilder": "^4.1.3",
|
||||
"botbuilder-ai": "^4.1.3",
|
||||
"botbuilder-azure": "^4.1.3",
|
||||
"botbuilder-choices": "^4.0.0-preview1.2",
|
||||
"botbuilder-dialogs": "^4.1.3",
|
||||
"botbuilder-prompts": "^4.0.0-preview1.2",
|
||||
"botlib": "0.1.6",
|
||||
"chai": "4.2.0",
|
||||
"child_process": "^1.0.2",
|
||||
"chokidar": "2.0.4",
|
||||
"cli-spinner": "^0.2.8",
|
||||
"csv-parse": "3.1.3",
|
||||
"dotenv-extended": "2.3.0",
|
||||
"express": "4.16.4",
|
||||
"express-promise-router": "3.0.3",
|
||||
"fs-extra": "7.0.0",
|
||||
"fs-walk": "0.0.2",
|
||||
"ip": "^1.1.5",
|
||||
"localize": "0.4.7",
|
||||
"marked": "0.5.1",
|
||||
"mocha": "5.2.0",
|
||||
"mocha-typescript": "1.1.17",
|
||||
"ms": "2.1.1",
|
||||
"ms-rest-azure": "2.5.9",
|
||||
"nexmo": "2.4.0",
|
||||
"ngrok": "^3.1.0",
|
||||
"opn": "^5.4.0",
|
||||
"pragmatismo-io-framework": "1.0.18",
|
||||
"process-exists": "^3.1.0",
|
||||
"public-ip": "^2.4.0",
|
||||
"reflect-metadata": "0.1.12",
|
||||
"request-promise-native": "1.0.5",
|
||||
"scanf": "^1.0.2",
|
||||
"sequelize": "4.41.0",
|
||||
"sequelize-typescript": "0.6.6",
|
||||
"simple-git": "^1.106.0",
|
||||
"sqlite3": "4.0.3",
|
||||
"strict-password-generator": "^1.1.1",
|
||||
"swagger-client": "3.8.21",
|
||||
"tedious": "3.0.1",
|
||||
"ts-node": "7.0.1",
|
||||
"tslint": "^5.11.0",
|
||||
"typedoc": "0.13.0",
|
||||
"typescript": "3.1.6",
|
||||
"url-join": "4.0.0",
|
||||
"wait-until": "0.0.2",
|
||||
"walk-promise": "0.2.0",
|
||||
"winston": "3.1.0"
|
||||
}
|
||||
}
|
||||
168
packages/admin.gbapp/dialogs/AdminDialog.ts
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
const UrlJoin = require("url-join");
|
||||
import { GBMinInstance } from "botlib";
|
||||
import { IGBDialog } from "botlib";
|
||||
import { GBDeployer } from "../../core.gbapp/services/GBDeployer";
|
||||
import { GBImporter } from "../../core.gbapp/services/GBImporter";
|
||||
import { GBConfigService } from "../../core.gbapp/services/GBConfigService";
|
||||
import { BotAdapter } from "botbuilder";
|
||||
import { GBAdminService } from "../services/GBAdminService";
|
||||
import { Messages } from "../strings";
|
||||
import { WaterfallDialog } from "botbuilder-dialogs";
|
||||
|
||||
/**
|
||||
* Dialogs for administration tasks.
|
||||
*/
|
||||
export class AdminDialog extends IGBDialog {
|
||||
static async createFarmCommand(text: any, min: GBMinInstance) {}
|
||||
|
||||
static async undeployPackageCommand(text: any, min: GBMinInstance) {
|
||||
let packageName = text.split(" ")[1];
|
||||
let importer = new GBImporter(min.core);
|
||||
let deployer = new GBDeployer(min.core, importer);
|
||||
await deployer.undeployPackageFromLocalPath(
|
||||
min.instance,
|
||||
UrlJoin("packages", packageName)
|
||||
);
|
||||
}
|
||||
|
||||
static async deployPackageCommand(text: string, deployer: GBDeployer) {
|
||||
let packageName = text.split(" ")[1];
|
||||
let additionalPath = GBConfigService.get("ADDITIONAL_DEPLOY_PATH");
|
||||
await deployer.deployPackageFromLocalPath(
|
||||
UrlJoin(additionalPath, packageName)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Setup dialogs flows and define services call.
|
||||
*
|
||||
* @param bot The bot adapter.
|
||||
* @param min The minimal bot instance data.
|
||||
*/
|
||||
static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||
// Setup services.
|
||||
|
||||
let importer = new GBImporter(min.core);
|
||||
let deployer = new GBDeployer(min.core, importer);
|
||||
|
||||
min.dialogs.add(
|
||||
new WaterfallDialog("/admin", [
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
const prompt = Messages[locale].authenticate;
|
||||
await step.prompt("textPrompt", prompt);
|
||||
return await step.next();
|
||||
},
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
let password = step.result;
|
||||
if (
|
||||
password === GBConfigService.get("ADMIN_PASS") &&
|
||||
GBAdminService.StrongRegex.test(password)
|
||||
) {
|
||||
await step.context.sendActivity(Messages[locale].welcome);
|
||||
await step.prompt("textPrompt", Messages[locale].which_task);
|
||||
} else {
|
||||
await step.prompt("textPrompt", Messages[locale].wrong_password);
|
||||
await step.endDialog();
|
||||
}
|
||||
return await step.next();
|
||||
},
|
||||
async step => {
|
||||
const locale = step.context.activity.locale;
|
||||
var text = step.result;
|
||||
let cmdName = text.split(" ")[0];
|
||||
|
||||
step.context.sendActivity(Messages[locale].working(cmdName));
|
||||
let unknownCommand = false;
|
||||
|
||||
if (text === "quit") {
|
||||
await step.replaceDialog("/");
|
||||
} else if (cmdName === "createFarm") {
|
||||
await AdminDialog.createFarmCommand(text, deployer);
|
||||
await step.replaceDialog("/admin", { firstRun: false });
|
||||
} else if (cmdName === "deployPackage") {
|
||||
await AdminDialog.deployPackageCommand(text, deployer);
|
||||
await step.replaceDialog("/admin", { firstRun: false });
|
||||
} else if (cmdName === "redeployPackage") {
|
||||
await AdminDialog.undeployPackageCommand(text, min);
|
||||
await AdminDialog.deployPackageCommand(text, deployer);
|
||||
await step.replaceDialog("/admin", { firstRun: false });
|
||||
} else if (cmdName === "undeployPackage") {
|
||||
await AdminDialog.undeployPackageCommand(text, min);
|
||||
await step.replaceDialog("/admin", { firstRun: false });
|
||||
} else if (cmdName === "setupSecurity") {
|
||||
await AdminDialog.setupSecurity(min, step);
|
||||
} else {
|
||||
unknownCommand = true;
|
||||
}
|
||||
|
||||
if (unknownCommand) {
|
||||
await step.context.sendActivity(Messages[locale].unknown_command);
|
||||
} else {
|
||||
await step.context.sendActivity(
|
||||
Messages[locale].finshed_working(cmdName)
|
||||
);
|
||||
}
|
||||
await step.endDialog();
|
||||
await step.replaceDialog("/answer", { query: text });
|
||||
return await step.next();
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
private static async setupSecurity(min: any, step: any) {
|
||||
const locale = step.activity.locale;
|
||||
let state = `${min.instance.instanceId}${Math.floor(
|
||||
Math.random() * 1000000000
|
||||
)}`;
|
||||
await min.adminService.setValue(
|
||||
min.instance.instanceId,
|
||||
"AntiCSRFAttackState",
|
||||
state
|
||||
);
|
||||
let url = `https://login.microsoftonline.com/${
|
||||
min.instance.authenticatorTenant
|
||||
}/oauth2/authorize?client_id=${
|
||||
min.instance.authenticatorClientId
|
||||
}&response_type=code&redirect_uri=${min.instance.botEndpoint}/${
|
||||
min.instance.botId
|
||||
}/token&state=${state}&response_mode=query`;
|
||||
|
||||
await step.sendActivity(Messages[locale].consent(url));
|
||||
}
|
||||
}
|
||||
64
packages/admin.gbapp/index.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
const UrlJoin = require('url-join')
|
||||
|
||||
import { AdminDialog } from './dialogs/AdminDialog'
|
||||
import { GBMinInstance, IGBPackage, IGBCoreService } from 'botlib'
|
||||
|
||||
import { Sequelize } from 'sequelize-typescript'
|
||||
import { GuaribasAdmin } from './models/AdminModel';
|
||||
|
||||
export class GBAdminPackage implements IGBPackage {
|
||||
sysPackages: IGBPackage[] = null
|
||||
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
core.sequelize.addModels([
|
||||
GuaribasAdmin
|
||||
])
|
||||
}
|
||||
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
}
|
||||
|
||||
loadBot(min: GBMinInstance): void {
|
||||
AdminDialog.setup(min.bot, min)
|
||||
}
|
||||
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
}
|
||||
|
||||
onNewSession(min: GBMinInstance, step: any): void {
|
||||
}
|
||||
}
|
||||
64
packages/admin.gbapp/models/AdminModel.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import {
|
||||
Table,
|
||||
Column,
|
||||
Model,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
} from "sequelize-typescript";
|
||||
|
||||
|
||||
@Table
|
||||
export class GuaribasAdmin extends Model<GuaribasAdmin>
|
||||
{
|
||||
|
||||
@Column
|
||||
instanceId: number;
|
||||
|
||||
@Column
|
||||
key: string;
|
||||
|
||||
@Column
|
||||
value: string;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedAt: Date;
|
||||
}
|
||||
188
packages/admin.gbapp/services/GBAdminService.ts
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { GuaribasAdmin } from "../models/AdminModel";
|
||||
import { IGBCoreService } from "botlib";
|
||||
import { AuthenticationContext, TokenResponse } from "adal-node";
|
||||
const UrlJoin = require("url-join");
|
||||
const msRestAzure = require("ms-rest-azure");
|
||||
const PasswordGenerator = require("strict-password-generator").default;
|
||||
|
||||
export class GBAdminService {
|
||||
|
||||
static GB_PROMPT: string = "GeneralBots: "
|
||||
|
||||
static generateUuid(): string {
|
||||
return msRestAzure.generateUuid();
|
||||
}
|
||||
static masterBotInstanceId = 0;
|
||||
|
||||
public static StrongRegex = new RegExp(
|
||||
"^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*+_-])(?=.{8,})"
|
||||
);
|
||||
|
||||
core: IGBCoreService;
|
||||
|
||||
constructor(core: IGBCoreService) {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public async setValue(
|
||||
instanceId: number,
|
||||
key: string,
|
||||
value: string
|
||||
): Promise<GuaribasAdmin> {
|
||||
let options = { where: {} };
|
||||
options.where = { key: key };
|
||||
let admin = await GuaribasAdmin.findOne(options);
|
||||
if (admin == null) {
|
||||
admin = new GuaribasAdmin();
|
||||
admin.key = key;
|
||||
}
|
||||
admin.value = value;
|
||||
admin.instanceId = instanceId;
|
||||
return admin.save();
|
||||
}
|
||||
|
||||
public async getValue(instanceId: number, key: string) {
|
||||
let options = { where: {} };
|
||||
options.where = { key: key, instanceId: instanceId };
|
||||
let obj = await GuaribasAdmin.findOne(options);
|
||||
return Promise.resolve(obj.value);
|
||||
}
|
||||
|
||||
public async acquireElevatedToken(instanceId): Promise<string> {
|
||||
return new Promise<string>(async (resolve, reject) => {
|
||||
let instance = await this.core.loadInstanceById(instanceId);
|
||||
|
||||
let expiresOn = new Date(await this.getValue(instanceId, "expiresOn"));
|
||||
if (expiresOn.getTime() > new Date().getTime()) {
|
||||
let accessToken = await this.getValue(instanceId, "accessToken");
|
||||
resolve(accessToken);
|
||||
} else {
|
||||
let authorizationUrl = UrlJoin(
|
||||
instance.authenticatorAuthorityHostUrl,
|
||||
instance.authenticatorTenant,
|
||||
"/oauth2/authorize"
|
||||
);
|
||||
|
||||
let refreshToken = await this.getValue(instanceId, "refreshToken");
|
||||
let resource = "https://graph.microsoft.com";
|
||||
var authenticationContext = new AuthenticationContext(authorizationUrl);
|
||||
authenticationContext.acquireTokenWithRefreshToken(
|
||||
refreshToken,
|
||||
instance.authenticatorClientId,
|
||||
instance.authenticatorClientSecret,
|
||||
resource,
|
||||
async (err, res) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
let token = res as TokenResponse;
|
||||
await this.setValue(
|
||||
instanceId,
|
||||
"accessToken",
|
||||
token.accessToken
|
||||
);
|
||||
await this.setValue(
|
||||
instanceId,
|
||||
"refreshToken",
|
||||
token.refreshToken
|
||||
);
|
||||
await this.setValue(
|
||||
instanceId,
|
||||
"expiresOn",
|
||||
token.expiresOn.toString()
|
||||
);
|
||||
resolve(token.accessToken);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static async getADALTokenFromUsername(
|
||||
username: string,
|
||||
password: string
|
||||
) {
|
||||
let credentials = await GBAdminService.getADALCredentialsFromUsername(
|
||||
username,
|
||||
password
|
||||
);
|
||||
let accessToken = credentials.tokenCache._entries[0].accessToken;
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public static async getADALCredentialsFromUsername(
|
||||
username: string,
|
||||
password: string
|
||||
) {
|
||||
let credentials = await msRestAzure.loginWithUsernamePassword(
|
||||
username,
|
||||
password
|
||||
);
|
||||
return credentials;
|
||||
}
|
||||
|
||||
public static getRndPassword() {
|
||||
const passwordGenerator = new PasswordGenerator();
|
||||
const options = {
|
||||
upperCaseAlpha: true,
|
||||
lowerCaseAlpha: true,
|
||||
number: true,
|
||||
specialCharacter: true,
|
||||
minimumLength: 12,
|
||||
maximumLength: 14
|
||||
};
|
||||
let password = passwordGenerator.generatePassword(options);
|
||||
password = password.replace(/@[=:;\?]/g, "#");
|
||||
return password;
|
||||
}
|
||||
|
||||
public static getRndReadableIdentifier() {
|
||||
const passwordGenerator = new PasswordGenerator();
|
||||
const options = {
|
||||
upperCaseAlpha: false,
|
||||
lowerCaseAlpha: true,
|
||||
number: false,
|
||||
specialCharacter: false,
|
||||
minimumLength: 12,
|
||||
maximumLength: 14
|
||||
};
|
||||
let name = passwordGenerator.generatePassword(options);
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
22
packages/admin.gbapp/strings.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export const Messages = {
|
||||
"en-US": {
|
||||
authenticate: "Please, authenticate:",
|
||||
welcome: "Welcome to Pragmatismo.io GeneralBots Administration.",
|
||||
which_task: "Which task do you wanna run now?",
|
||||
working:(command)=> `I'm working on ${command}...`,
|
||||
finshed_working:"Done.",
|
||||
unknown_command: text =>
|
||||
`Well, but ${text} is not a administrative General Bots command, I will try to search for it.`,
|
||||
hi: text => `Hello, ${text}.`,
|
||||
undeployPackage: text => `Undeploying package ${text}...`,
|
||||
deployPackage: text => `Deploying package ${text}...`,
|
||||
redeployPackage: text => `Redeploying package ${text}...`,
|
||||
packageUndeployed: text => `Package ${text} undeployed...`,
|
||||
consent: (url)=>`Please, consent access to this app at: [Microsoft Online](${url}).`,
|
||||
wrong_password: "Sorry, wrong password. Please, try again."
|
||||
},
|
||||
"pt-BR": {
|
||||
show_video: "Vou te mostrar um vídeo. Por favor, aguarde...",
|
||||
hi: msg => `Oi, ${msg}.`
|
||||
}
|
||||
};
|
||||
62
packages/analytics.gblib/index.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict"
|
||||
|
||||
const UrlJoin = require("url-join")
|
||||
|
||||
|
||||
|
||||
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
|
||||
|
||||
import { Sequelize } from "sequelize-typescript"
|
||||
|
||||
export class GBAnalyticsPackage implements IGBPackage {
|
||||
|
||||
sysPackages: IGBPackage[] = null
|
||||
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
|
||||
}
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
|
||||
}
|
||||
loadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
onNewSession(min: GBMinInstance, step: any): void {
|
||||
|
||||
}
|
||||
}
|
||||
146
packages/analytics.gblib/models/index.ts
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict"
|
||||
|
||||
import {
|
||||
DataTypes,
|
||||
DataTypeUUIDv4,
|
||||
DataTypeDate,
|
||||
DataTypeDecimal
|
||||
} from "sequelize"
|
||||
|
||||
import {
|
||||
Sequelize,
|
||||
Table,
|
||||
Column,
|
||||
Model,
|
||||
HasMany,
|
||||
BelongsTo,
|
||||
BelongsToMany,
|
||||
Length,
|
||||
ForeignKey,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
DataType,
|
||||
IsUUID,
|
||||
PrimaryKey,
|
||||
AutoIncrement
|
||||
} from "sequelize-typescript"
|
||||
|
||||
import { GuaribasSubject } from "../../kb.gbapp/models"
|
||||
import { GuaribasUser } from "../../security.gblib/models"
|
||||
import { GuaribasChannel, GuaribasInstance } from "../../core.gbapp/models/GBModel"
|
||||
|
||||
@Table
|
||||
export class GuaribasConversation extends Model<GuaribasConversation> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
conversationId: number
|
||||
|
||||
@ForeignKey(() => GuaribasSubject)
|
||||
@Column
|
||||
startSubjectId: number
|
||||
|
||||
@BelongsTo(() => GuaribasSubject)
|
||||
startSubject: GuaribasSubject
|
||||
|
||||
@ForeignKey(() => GuaribasChannel)
|
||||
@Column
|
||||
channelId: string
|
||||
|
||||
@Column rateDate: Date
|
||||
|
||||
@Column(DataType.FLOAT)
|
||||
@Column
|
||||
rate: number
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
createdAt: Date
|
||||
|
||||
@Column text: string
|
||||
|
||||
@HasMany(() => GuaribasConversationMessage)
|
||||
conversationMessage: GuaribasConversationMessage[]
|
||||
|
||||
@ForeignKey(() => GuaribasUser)
|
||||
@Column
|
||||
startedByUserId: number
|
||||
|
||||
@BelongsTo(() => GuaribasUser)
|
||||
startedBy: GuaribasUser
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasConversationMessage extends Model<GuaribasConversationMessage> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
conversationMessageId: number
|
||||
|
||||
@ForeignKey(() => GuaribasSubject)
|
||||
@Column
|
||||
subjectId: number
|
||||
|
||||
@Column(DataType.TEXT)
|
||||
content: string
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
createdAt: Date
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedAt: Date
|
||||
|
||||
@ForeignKey(() => GuaribasConversation)
|
||||
@Column
|
||||
conversationId: number
|
||||
|
||||
@BelongsTo(() => GuaribasConversation)
|
||||
conversation: GuaribasConversation
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
instanceId: number
|
||||
|
||||
@ForeignKey(() => GuaribasUser)
|
||||
@Column
|
||||
userId: number
|
||||
|
||||
@BelongsTo(() => GuaribasUser)
|
||||
user: GuaribasUser
|
||||
}
|
||||
67
packages/analytics.gblib/services/AnalyticsService.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
import { GuaribasUser } from "../../security.gblib/models"
|
||||
import { GuaribasConversation, GuaribasConversationMessage } from "../models"
|
||||
|
||||
export class AnalyticsService {
|
||||
async createConversation(
|
||||
user: GuaribasUser
|
||||
): Promise<GuaribasConversation> {
|
||||
return new Promise<GuaribasConversation>(
|
||||
(resolve, reject) => {
|
||||
let conversation = new GuaribasConversation()
|
||||
conversation.startedBy = user
|
||||
conversation.startedByUserId = user.userId
|
||||
conversation.save().then((value: GuaribasConversation) => {
|
||||
resolve(value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
createMessage(
|
||||
conversation: GuaribasConversation,
|
||||
user: GuaribasUser,
|
||||
content: string
|
||||
): Promise<GuaribasConversationMessage> {
|
||||
return new Promise<GuaribasConversationMessage>(
|
||||
(resolve, reject) => {
|
||||
let message = GuaribasConversationMessage.build()
|
||||
message.conversation = conversation
|
||||
message.user = user
|
||||
message.content = content
|
||||
message.save().then((value: GuaribasConversationMessage) => {
|
||||
resolve(value)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
67
packages/azuredeployer.gbapp/dialogs/BotFarmDialog.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { GBMinInstance } from "botlib";
|
||||
import { IGBDialog } from "botlib";
|
||||
import { BotAdapter } from "botbuilder";
|
||||
import { Messages } from "../strings";
|
||||
|
||||
export class BotFarmDialog extends IGBDialog {
|
||||
|
||||
|
||||
/**
|
||||
* Setup dialogs flows and define services call.
|
||||
*
|
||||
* @param bot The bot adapter.
|
||||
* @param min The minimal bot instance data.
|
||||
*/
|
||||
static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||
min.dialogs.add("/createBotFarm", [
|
||||
async step => {
|
||||
let locale = step.context.activity.locale;
|
||||
await step.prompt("choicePrompt", Messages[locale].what_about_me, [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5"
|
||||
]);
|
||||
},
|
||||
async step => {
|
||||
let locale = step.context.activity.locale;
|
||||
await step.context.sendActivity(Messages[locale].thanks);
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
61
packages/azuredeployer.gbapp/index.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict"
|
||||
|
||||
const UrlJoin = require("url-join")
|
||||
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
|
||||
import { Sequelize } from "sequelize-typescript"
|
||||
|
||||
|
||||
export class GBWhatsappPackage implements IGBPackage {
|
||||
|
||||
sysPackages: IGBPackage[] = null
|
||||
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
}
|
||||
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
|
||||
}
|
||||
|
||||
loadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
|
||||
}
|
||||
onNewSession(min: GBMinInstance, step: any): void {
|
||||
|
||||
}
|
||||
}
|
||||
909
packages/azuredeployer.gbapp/services/AzureDeployerService.ts
Normal file
|
|
@ -0,0 +1,909 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { GBService, IGBInstance } from "botlib";
|
||||
import {
|
||||
ResourceManagementClient,
|
||||
SubscriptionClient
|
||||
} from "azure-arm-resource";
|
||||
import { WebSiteManagementClient } from "azure-arm-website";
|
||||
import { SqlManagementClient } from "azure-arm-sql";
|
||||
import { CognitiveServicesManagementClient } from "azure-arm-cognitiveservices";
|
||||
import { CognitiveServicesAccount } from "azure-arm-cognitiveservices/lib/models";
|
||||
import { SearchManagementClient } from "azure-arm-search";
|
||||
import { WebResource, ServiceClient, HttpMethods } from "ms-rest-js";
|
||||
import * as simplegit from "simple-git/promise";
|
||||
import { AppServicePlan } from "azure-arm-website/lib/models";
|
||||
import { GBConfigService } from "../../../packages/core.gbapp/services/GBConfigService";
|
||||
import { GBAdminService } from "../../../packages/admin.gbapp/services/GBAdminService";
|
||||
import { GBCorePackage } from "../../../packages/core.gbapp";
|
||||
import { GBDeployer } from "packages/core.gbapp/services/GBDeployer";
|
||||
|
||||
const Spinner = require("cli-spinner").Spinner;
|
||||
const scanf = require("scanf");
|
||||
const git = simplegit();
|
||||
const logger = require("../../../src/logger");
|
||||
const UrlJoin = require("url-join");
|
||||
const iconUrl =
|
||||
"https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png";
|
||||
const publicIp = require("public-ip");
|
||||
|
||||
export class AzureDeployerService extends GBService {
|
||||
instance: IGBInstance;
|
||||
resourceClient: ResourceManagementClient.ResourceManagementClient;
|
||||
webSiteClient: WebSiteManagementClient;
|
||||
storageClient: SqlManagementClient;
|
||||
cognitiveClient: CognitiveServicesManagementClient;
|
||||
searchClient: SearchManagementClient;
|
||||
provider = "Microsoft.BotService";
|
||||
subscriptionClient: SubscriptionClient.SubscriptionClient;
|
||||
accessToken: string;
|
||||
location: string;
|
||||
public subscriptionId: string;
|
||||
static apiVersion = "2017-12-01";
|
||||
farmName: any;
|
||||
deployer: GBDeployer;
|
||||
|
||||
constructor(deployer: GBDeployer){
|
||||
super();
|
||||
this.deployer = deployer;
|
||||
}
|
||||
public static async getSubscriptions(credentials) {
|
||||
let subscriptionClient = new SubscriptionClient.default(credentials);
|
||||
return subscriptionClient.subscriptions.list();
|
||||
}
|
||||
|
||||
public async deployFarm(proxyAddress: string): Promise<IGBInstance> {
|
||||
let culture = "en-us";
|
||||
|
||||
// Tries do get information from .env file otherwise asks in command-line.
|
||||
|
||||
let instance: IGBInstance = {};
|
||||
instance = await this.ensureConfiguration(instance);
|
||||
instance.marketplacePassword = GBAdminService.getRndPassword();
|
||||
|
||||
let spinner = new Spinner("%s");
|
||||
spinner.start();
|
||||
spinner.setSpinnerString("|/-\\");
|
||||
|
||||
let keys: any;
|
||||
let name = instance.botId;
|
||||
|
||||
logger.info(`Deploying Deploy Group (It may take a few minutes)...`);
|
||||
await this.createDeployGroup(name, instance.cloudLocation);
|
||||
|
||||
logger.info(`Deploying Bot Server...`);
|
||||
let serverFarm = await this.createHostingPlan(
|
||||
name,
|
||||
`${name}-server-plan`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
await this.createServer(
|
||||
serverFarm.id,
|
||||
name,
|
||||
`${name}-server`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
|
||||
logger.info(`Deploying Bot Storage...`);
|
||||
let administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`;
|
||||
let administratorPassword = GBAdminService.getRndPassword();
|
||||
let storageServer = `${name}-storage-server`;
|
||||
let storageName = `${name}-storage`;
|
||||
await this.createStorageServer(
|
||||
name,
|
||||
storageServer,
|
||||
administratorLogin,
|
||||
administratorPassword,
|
||||
storageServer,
|
||||
instance.cloudLocation
|
||||
);
|
||||
await this.createStorage(
|
||||
name,
|
||||
storageServer,
|
||||
storageName,
|
||||
instance.cloudLocation
|
||||
);
|
||||
instance.storageUsername = administratorLogin;
|
||||
instance.storagePassword = administratorPassword;
|
||||
instance.storageName = storageName;
|
||||
instance.storageDialect = "mssql";
|
||||
instance.storageServer = storageServer;
|
||||
|
||||
logger.info(`Deploying Search...`);
|
||||
let searchName = `${name}-search`;
|
||||
await this.createSearch(name, searchName, instance.cloudLocation);
|
||||
let searchKeys = await this.searchClient.adminKeys.get(
|
||||
name,
|
||||
searchName
|
||||
);
|
||||
instance.searchHost = `${searchName}.search.windows.net`;
|
||||
instance.searchIndex = "azuresql-index";
|
||||
instance.searchIndexer = "azuresql-indexer";
|
||||
instance.searchKey = searchKeys.primaryKey;
|
||||
this.deployer.rebuildIndex(instance);
|
||||
|
||||
logger.info(`Deploying Speech...`);
|
||||
let speech = await this.createSpeech(
|
||||
name,
|
||||
`${name}-speech`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(name, speech.name);
|
||||
instance.speechKeyEndpoint = speech.endpoint;
|
||||
instance.speechKey = keys.key1;
|
||||
|
||||
logger.info(`Deploying SpellChecker...`);
|
||||
let spellChecker = await this.createSpellChecker(
|
||||
name,
|
||||
`${name}-spellchecker`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(
|
||||
name,
|
||||
spellChecker.name
|
||||
);
|
||||
instance.spellCheckerKey = keys.key1;
|
||||
instance.spellCheckerEndpoint = spellChecker.endpoint;
|
||||
|
||||
logger.info(`Deploying Text Analytics...`);
|
||||
let textAnalytics = await this.createTextAnalytics(
|
||||
name,
|
||||
`${name}-textanalytics`,
|
||||
instance.cloudLocation
|
||||
);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(
|
||||
name,
|
||||
textAnalytics.name
|
||||
);
|
||||
instance.textAnalyticsEndpoint = textAnalytics.endpoint;
|
||||
instance.textAnalyticsKey = keys.key1;
|
||||
|
||||
logger.info(`Deploying NLP...`);
|
||||
let nlp = await this.createNLP(name, `${name}-nlp`, instance.cloudLocation);
|
||||
keys = await this.cognitiveClient.accounts.listKeys(name, nlp.name);
|
||||
let nlpAppId = await this.createLUISApp(
|
||||
name,
|
||||
name,
|
||||
instance.cloudLocation,
|
||||
culture,
|
||||
instance.nlpAuthoringKey
|
||||
);
|
||||
|
||||
instance.nlpEndpoint = nlp.endpoint;
|
||||
instance.nlpKey = keys.key1;
|
||||
instance.nlpAppId = nlpAppId;
|
||||
|
||||
logger.info(`Deploying Bot...`);
|
||||
instance = await this.deployBootBot(
|
||||
instance,
|
||||
name,
|
||||
`${proxyAddress}/api/messages/${name}`,
|
||||
instance.nlpAppId,
|
||||
instance.nlpKey,
|
||||
instance.cloudSubscriptionId
|
||||
);
|
||||
|
||||
|
||||
spinner.stop();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public async openStorageFirewall(groupName, serverName) {
|
||||
let username = GBConfigService.get("CLOUD_USERNAME");
|
||||
let password = GBConfigService.get("CLOUD_PASSWORD");
|
||||
let subscriptionId = GBConfigService.get("CLOUD_SUBSCRIPTIONID");
|
||||
|
||||
let credentials = await GBAdminService.getADALCredentialsFromUsername(
|
||||
username,
|
||||
password
|
||||
);
|
||||
let storageClient = new SqlManagementClient(credentials, subscriptionId);
|
||||
|
||||
let ip = await publicIp.v4();
|
||||
let params = {
|
||||
startIpAddress: ip,
|
||||
endIpAddress: ip
|
||||
};
|
||||
|
||||
await storageClient.firewallRules.createOrUpdate(
|
||||
groupName,
|
||||
serverName,
|
||||
"gb",
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
private async ensureConfiguration(instance: IGBInstance) {
|
||||
let username = GBConfigService.get("CLOUD_USERNAME");
|
||||
let password = GBConfigService.get("CLOUD_PASSWORD");
|
||||
let subscriptionId = GBConfigService.get("CLOUD_SUBSCRIPTIONID");
|
||||
let location = GBConfigService.get("CLOUD_LOCATION");
|
||||
let botId = GBConfigService.get("BOT_ID");
|
||||
|
||||
// No .env so asks for cloud credentials to start a new farm.
|
||||
if (!username || !password || !subscriptionId || !location || !botId) {
|
||||
process.stdout.write(
|
||||
"A empty enviroment is detected. To start automatic deploy, please enter some information:\n"
|
||||
);
|
||||
}
|
||||
let retriveUsername = () => {
|
||||
if (!username) {
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}CLOUD_USERNAME:`);
|
||||
username = scanf("%s").replace(/(\n|\r)+$/, "");
|
||||
}
|
||||
};
|
||||
let retrivePassword = () => {
|
||||
if (!password) {
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}CLOUD_PASSWORD:`);
|
||||
password = scanf("%s").replace(/(\n|\r)+$/, "");
|
||||
}
|
||||
};
|
||||
let retrieveBotId = () => {
|
||||
if (!botId) {
|
||||
process.stdout.write(
|
||||
`${GBAdminService.GB_PROMPT}Bot Id must only contain lowercase letters, digits or dashes, cannot start or end with or contain consecutive dashes and is limited from 4 to 42 characters long.\n`
|
||||
);
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}BOT_ID:`);
|
||||
botId = scanf("%s").replace(/(\n|\r)+$/, ""); // TODO: Update this regexp to match description of it.
|
||||
}
|
||||
};
|
||||
let authoringKey = GBConfigService.get("NLP_AUTHORING_KEY");
|
||||
let retriveAuthoringKey = () => {
|
||||
if (!authoringKey) {
|
||||
process.stdout.write(
|
||||
`${GBAdminService.GB_PROMPT}Due to this opened issue: https://github.com/Microsoft/botbuilder-tools/issues/550\n`
|
||||
);
|
||||
process.stdout.write(`${GBAdminService.GB_PROMPT}Please enter your LUIS Authoring Key:`);
|
||||
authoringKey = scanf("%s").replace(/(\n|\r)+$/, "");
|
||||
}
|
||||
};
|
||||
while (!authoringKey) {
|
||||
retriveAuthoringKey();
|
||||
}
|
||||
while (!botId) {
|
||||
retrieveBotId();
|
||||
}
|
||||
while (!username) {
|
||||
retriveUsername();
|
||||
}
|
||||
while (!password) {
|
||||
retrivePassword();
|
||||
}
|
||||
|
||||
// Connects to the cloud and retrives subscriptions.
|
||||
|
||||
let credentials = await GBAdminService.getADALCredentialsFromUsername(
|
||||
username,
|
||||
password
|
||||
);
|
||||
if (!subscriptionId) {
|
||||
let map = {};
|
||||
let index = 1;
|
||||
let list = await AzureDeployerService.getSubscriptions(credentials);
|
||||
list.forEach(element => {
|
||||
console.log(
|
||||
`${index}: ${element.displayName} (${element.subscriptionId})`
|
||||
);
|
||||
map[index++] = element;
|
||||
});
|
||||
let subscriptionIndex;
|
||||
let retrieveSubscription = () => {
|
||||
if (!subscriptionIndex) {
|
||||
process.stdout.write("CLOUD_SUBSCRIPTIONID (type a number):");
|
||||
subscriptionIndex = scanf("%d");
|
||||
}
|
||||
};
|
||||
while (!subscriptionIndex) {
|
||||
retrieveSubscription();
|
||||
}
|
||||
subscriptionId = map[subscriptionIndex].subscriptionId;
|
||||
}
|
||||
let retriveLocation = () => {
|
||||
if (!location) {
|
||||
process.stdout.write("CLOUD_LOCATION (eg. 'westus'):");
|
||||
location = scanf("%s");
|
||||
}
|
||||
};
|
||||
while (!location) {
|
||||
retriveLocation();
|
||||
}
|
||||
|
||||
// Prepares the first instance on bot farm.
|
||||
|
||||
instance.botId = botId;
|
||||
instance.cloudUsername = username;
|
||||
instance.cloudPassword = password;
|
||||
instance.cloudSubscriptionId = subscriptionId;
|
||||
instance.cloudLocation = location;
|
||||
instance.nlpAuthoringKey = authoringKey;
|
||||
instance.adminPass = GBAdminService.getRndPassword();
|
||||
|
||||
this.resourceClient = new ResourceManagementClient.default(
|
||||
credentials,
|
||||
subscriptionId
|
||||
);
|
||||
this.webSiteClient = new WebSiteManagementClient(
|
||||
credentials,
|
||||
subscriptionId
|
||||
);
|
||||
this.storageClient = new SqlManagementClient(credentials, subscriptionId);
|
||||
this.cognitiveClient = new CognitiveServicesManagementClient(
|
||||
credentials,
|
||||
subscriptionId
|
||||
);
|
||||
|
||||
this.searchClient = new SearchManagementClient(credentials, subscriptionId);
|
||||
this.accessToken = credentials.tokenCache._entries[0].accessToken;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public async deployBootBot(
|
||||
instance,
|
||||
botId,
|
||||
endpoint,
|
||||
nlpAppId,
|
||||
nlpKey,
|
||||
subscriptionId
|
||||
) {
|
||||
let appId = GBConfigService.get("MARKETPLACE_ID");
|
||||
let appPassword = GBConfigService.get("MARKETPLACE_SECRET");
|
||||
|
||||
if (!appId || !appPassword) {
|
||||
process.stdout.write(
|
||||
"Sorry, this part cannot be automated yet due to Microsoft schedule, please go to https://apps.dev.microsoft.com/portal/register-app to generate manually an App ID and App Secret.\n"
|
||||
);
|
||||
}
|
||||
|
||||
let retriveAppId = () => {
|
||||
if (!appId) {
|
||||
process.stdout.write("Generated Application Id (MARKETPLACE_ID):");
|
||||
appId = scanf("%s").replace(/(\n|\r)+$/, "");
|
||||
}
|
||||
};
|
||||
|
||||
let retriveAppPassword = () => {
|
||||
if (!appPassword) {
|
||||
process.stdout.write("Generated Password (MARKETPLACE_SECRET):");
|
||||
appPassword = scanf("%s").replace(/(\n|\r)+$/, "");
|
||||
}
|
||||
};
|
||||
|
||||
retriveAppId();
|
||||
retriveAppPassword();
|
||||
|
||||
await this.internalDeployBot(
|
||||
instance,
|
||||
this.accessToken,
|
||||
botId,
|
||||
botId,
|
||||
botId,
|
||||
"General BootBot",
|
||||
endpoint,
|
||||
"global",
|
||||
nlpAppId,
|
||||
nlpKey,
|
||||
appId,
|
||||
appPassword,
|
||||
subscriptionId
|
||||
);
|
||||
instance.marketplaceId = appId;
|
||||
instance.marketplacePassword = appPassword;
|
||||
instance.botId = botId;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private async createStorageServer(
|
||||
group,
|
||||
name,
|
||||
administratorLogin,
|
||||
administratorPassword,
|
||||
serverName,
|
||||
location
|
||||
) {
|
||||
var params = {
|
||||
location: location,
|
||||
administratorLogin: administratorLogin,
|
||||
administratorLoginPassword: administratorPassword,
|
||||
fullyQualifiedDomainName: `${serverName}.database.windows.net`
|
||||
};
|
||||
|
||||
return this.storageClient.servers.createOrUpdate(group, name, params);
|
||||
}
|
||||
|
||||
private async registerProviders(subscriptionId, baseUrl, accessToken) {
|
||||
let query = `subscriptions/${subscriptionId}/providers/${
|
||||
this.provider
|
||||
}/register?api-version=2018-02-01`;
|
||||
let requestUrl = UrlJoin(baseUrl, query);
|
||||
|
||||
let req = new WebResource();
|
||||
req.method = "POST";
|
||||
req.url = requestUrl;
|
||||
req.headers = {};
|
||||
req.headers["Content-Type"] = "application/json; charset=utf-8";
|
||||
req.headers["accept-language"] = "*";
|
||||
req.headers["Authorization"] = "Bearer " + accessToken;
|
||||
|
||||
let httpClient = new ServiceClient();
|
||||
let res = await httpClient.sendRequest(req);
|
||||
// TODO: Check res for error.
|
||||
}
|
||||
/**
|
||||
* @see https://github.com/Azure/azure-rest-api-specs/blob/master/specification/botservice/resource-manager/Microsoft.BotService/preview/2017-12-01/botservice.json
|
||||
*/
|
||||
private async internalDeployBot(
|
||||
instance,
|
||||
accessToken,
|
||||
botId,
|
||||
name,
|
||||
group,
|
||||
description,
|
||||
endpoint,
|
||||
location,
|
||||
nlpAppId,
|
||||
nlpKey,
|
||||
appId,
|
||||
appPassword,
|
||||
subscriptionId
|
||||
) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let baseUrl = `https://management.azure.com/`;
|
||||
await this.registerProviders(subscriptionId, baseUrl, accessToken);
|
||||
|
||||
instance.marketplaceId = appId;
|
||||
instance.marketplacePassword = appPassword;
|
||||
instance.engineName = GBCorePackage.CurrentEngineName;
|
||||
|
||||
let parameters = {
|
||||
location: location,
|
||||
sku: {
|
||||
name: "F0"
|
||||
},
|
||||
name: botId,
|
||||
kind: "bot",
|
||||
properties: {
|
||||
description: description,
|
||||
displayName: name,
|
||||
endpoint: endpoint,
|
||||
iconUrl: iconUrl,
|
||||
luisAppIds: [nlpAppId],
|
||||
luisKey: nlpKey,
|
||||
msaAppId: appId,
|
||||
msaAppPassword: appPassword,
|
||||
enabledChannels: ["webchat"], // , "skype", "facebook"],
|
||||
configuredChannels: ["webchat"] // , "skype", "facebook"]
|
||||
}
|
||||
};
|
||||
|
||||
let httpClient = new ServiceClient();
|
||||
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
|
||||
this.provider
|
||||
}/botServices/${botId}?api-version=${AzureDeployerService.apiVersion}`;
|
||||
let url = UrlJoin(baseUrl, query);
|
||||
let req = this.createRequestObject(
|
||||
url,
|
||||
accessToken,
|
||||
"PUT",
|
||||
JSON.stringify(parameters)
|
||||
);
|
||||
let res = await httpClient.sendRequest(req);
|
||||
if (!(res.bodyAsJson as any).id) {
|
||||
reject(res.bodyAsText);
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${
|
||||
AzureDeployerService.apiVersion
|
||||
}`;
|
||||
url = UrlJoin(baseUrl, query);
|
||||
req = this.createRequestObject(
|
||||
url,
|
||||
accessToken,
|
||||
"GET",
|
||||
JSON.stringify(parameters)
|
||||
);
|
||||
let resChannel = await httpClient.sendRequest(req);
|
||||
let key = (resChannel.bodyAsJson as any).properties.properties
|
||||
.sites[0].key;
|
||||
instance.webchatKey = key;
|
||||
resolve(instance);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}, 20000);
|
||||
});
|
||||
}
|
||||
|
||||
public async updateBotProxy(botId, group, endpoint) {
|
||||
let baseUrl = `https://management.azure.com/`;
|
||||
let username = GBConfigService.get("CLOUD_USERNAME");
|
||||
let password = GBConfigService.get("CLOUD_PASSWORD");
|
||||
let subscriptionId = GBConfigService.get("CLOUD_SUBSCRIPTIONID");
|
||||
|
||||
let accessToken = await GBAdminService.getADALTokenFromUsername(
|
||||
username,
|
||||
password
|
||||
);
|
||||
let httpClient = new ServiceClient();
|
||||
|
||||
let parameters = {
|
||||
properties: {
|
||||
endpoint: endpoint
|
||||
}
|
||||
};
|
||||
|
||||
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
|
||||
this.provider
|
||||
}/botServices/${botId}?api-version=${AzureDeployerService.apiVersion}`;
|
||||
let url = UrlJoin(baseUrl, query);
|
||||
let req = this.createRequestObject(
|
||||
url,
|
||||
accessToken,
|
||||
"PATCH",
|
||||
JSON.stringify(parameters)
|
||||
);
|
||||
let res = await httpClient.sendRequest(req);
|
||||
if (!(res.bodyAsJson as any).id) {
|
||||
throw res.bodyAsText;
|
||||
}
|
||||
logger.info(`Bot proxy updated at: ${endpoint}.`);
|
||||
}
|
||||
|
||||
private createRequestObject(
|
||||
url: string,
|
||||
accessToken: string,
|
||||
verb: HttpMethods,
|
||||
body: string
|
||||
) {
|
||||
let req = new WebResource();
|
||||
req.method = verb;
|
||||
req.url = url;
|
||||
req.headers = {};
|
||||
req.headers["Content-Type"] = "application/json";
|
||||
req.headers["accept-language"] = "*";
|
||||
req.headers["Authorization"] = "Bearer " + accessToken;
|
||||
req.body = body;
|
||||
return req;
|
||||
}
|
||||
|
||||
private async createLUISApp(
|
||||
name: string,
|
||||
description: string,
|
||||
location: string,
|
||||
culture: string,
|
||||
authoringKey: string
|
||||
) {
|
||||
let parameters = {
|
||||
name: name,
|
||||
description: description,
|
||||
culture: culture
|
||||
};
|
||||
|
||||
let body = JSON.stringify(parameters);
|
||||
let apps = await this.makeNlpRequest(
|
||||
location,
|
||||
authoringKey,
|
||||
null,
|
||||
"GET",
|
||||
"apps"
|
||||
);
|
||||
let app = (apps.bodyAsJson as any).filter(x => x.name == name)[0];
|
||||
let id: string;
|
||||
if (!app) {
|
||||
let res = await this.makeNlpRequest(
|
||||
location,
|
||||
authoringKey,
|
||||
body,
|
||||
"POST",
|
||||
"apps"
|
||||
);
|
||||
id = res.bodyAsText;
|
||||
} else {
|
||||
id = app.id;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private async makeNlpRequest(
|
||||
location: string,
|
||||
authoringKey: string,
|
||||
body: string,
|
||||
method: HttpMethods,
|
||||
resource: string
|
||||
) {
|
||||
let req = new WebResource();
|
||||
req.method = method;
|
||||
req.url = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/${resource}`;
|
||||
req.headers = {};
|
||||
req.headers["Content-Type"] = "application/json";
|
||||
req.headers["accept-language"] = "*";
|
||||
req.headers["Ocp-Apim-Subscription-Key"] = authoringKey;
|
||||
req.body = body;
|
||||
let httpClient = new ServiceClient();
|
||||
let res = await httpClient.sendRequest(req);
|
||||
return res;
|
||||
}
|
||||
|
||||
private async createSearch(group, name, location) {
|
||||
var params = {
|
||||
sku: { name: "free" },
|
||||
location: location
|
||||
};
|
||||
|
||||
return this.searchClient.services.createOrUpdate(group, name, params);
|
||||
}
|
||||
|
||||
private async createStorage(group, serverName, name, location) {
|
||||
var params = {
|
||||
sku: { name: "Free" },
|
||||
createMode: "Default",
|
||||
location: location
|
||||
};
|
||||
|
||||
return this.storageClient.databases.createOrUpdate(
|
||||
group,
|
||||
serverName,
|
||||
name,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
private async createCognitiveServices(
|
||||
group,
|
||||
name,
|
||||
location,
|
||||
kind
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
let params = {
|
||||
sku: { name: "F0" },
|
||||
createMode: "Default",
|
||||
location: location,
|
||||
kind: kind,
|
||||
properties: {}
|
||||
};
|
||||
|
||||
return await this.cognitiveClient.accounts.create(group, name, params);
|
||||
}
|
||||
|
||||
private async createSpeech(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
return await this.createCognitiveServices(
|
||||
group,
|
||||
name,
|
||||
location,
|
||||
"SpeechServices"
|
||||
);
|
||||
}
|
||||
|
||||
private async createNLP(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
return await this.createCognitiveServices(group, name, location, "LUIS");
|
||||
}
|
||||
|
||||
private async createSpellChecker(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
return await this.createCognitiveServices(
|
||||
group,
|
||||
name,
|
||||
"global",
|
||||
"Bing.SpellCheck.v7"
|
||||
);
|
||||
}
|
||||
|
||||
private async createTextAnalytics(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<CognitiveServicesAccount> {
|
||||
return await this.createCognitiveServices(
|
||||
group,
|
||||
name,
|
||||
location,
|
||||
"TextAnalytics"
|
||||
);
|
||||
}
|
||||
|
||||
private async createDeployGroup(name, location) {
|
||||
var params = { location: location };
|
||||
return this.resourceClient.resourceGroups.createOrUpdate(name, params);
|
||||
}
|
||||
|
||||
private async createHostingPlan(
|
||||
group,
|
||||
name,
|
||||
location
|
||||
): Promise<AppServicePlan> {
|
||||
let params = {
|
||||
serverFarmWithRichSkuName: name,
|
||||
location: location,
|
||||
sku: {
|
||||
name: "F1",
|
||||
capacity: 1,
|
||||
tier: "Free"
|
||||
}
|
||||
};
|
||||
|
||||
return this.webSiteClient.appServicePlans.createOrUpdate(
|
||||
group,
|
||||
name,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
private async createServer(farmId, group, name, location) {
|
||||
var parameters = {
|
||||
location: location,
|
||||
serverFarmId: farmId
|
||||
};
|
||||
return this.webSiteClient.webApps.createOrUpdate(group, name, parameters);
|
||||
}
|
||||
|
||||
private async updateWebisteConfig(group, serverFarmId, name, location) {
|
||||
var siteConfig = {
|
||||
location: location,
|
||||
serverFarmId: serverFarmId,
|
||||
numberOfWorkers: 1,
|
||||
phpVersion: "5.5"
|
||||
};
|
||||
|
||||
// TODO: Copy .env to app settings.
|
||||
|
||||
return this.webSiteClient.webApps.createOrUpdateConfiguration(
|
||||
group,
|
||||
name,
|
||||
siteConfig
|
||||
);
|
||||
}
|
||||
|
||||
async deployGeneralBotsToAzure() {
|
||||
let status = await git.status();
|
||||
// TODO: Copy github to webapp.
|
||||
}
|
||||
|
||||
static getKBSearchSchema(indexName) {
|
||||
return {
|
||||
name: indexName,
|
||||
fields: [
|
||||
{
|
||||
name: "questionId",
|
||||
type: "Edm.String",
|
||||
searchable: false,
|
||||
filterable: false,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: true
|
||||
},
|
||||
{
|
||||
name: "subject1",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "subject2",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "subject3",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "subject4",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "content",
|
||||
type: "Edm.String",
|
||||
searchable: true,
|
||||
filterable: false,
|
||||
retrievable: false,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "answerId",
|
||||
type: "Edm.Int32",
|
||||
searchable: false,
|
||||
filterable: false,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "instanceId",
|
||||
type: "Edm.Int32",
|
||||
searchable: false,
|
||||
filterable: true,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
},
|
||||
{
|
||||
name: "packageId",
|
||||
type: "Edm.Int32",
|
||||
searchable: false,
|
||||
filterable: true,
|
||||
retrievable: true,
|
||||
sortable: false,
|
||||
facetable: false,
|
||||
key: false
|
||||
}
|
||||
],
|
||||
scoringProfiles: [],
|
||||
defaultScoringProfile: null,
|
||||
corsOptions: null
|
||||
};
|
||||
}
|
||||
}
|
||||
8
packages/azuredeployer.gbapp/strings.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export const Messages = {
|
||||
"en-US": {
|
||||
about_suggestions: "Suggestions are welcomed and improve my quality...",
|
||||
},
|
||||
"pt-BR": {
|
||||
about_suggestions: "Sugestões melhoram muito minha qualidade...",
|
||||
}
|
||||
};
|
||||
61
packages/console.gblib/index.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict"
|
||||
|
||||
const UrlJoin = require("url-join")
|
||||
|
||||
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
|
||||
|
||||
import { Sequelize } from 'sequelize-typescript'
|
||||
import { ConsoleDirectLine } from "./services/ConsoleDirectLine"
|
||||
|
||||
export class GBConsolePackage implements IGBPackage {
|
||||
sysPackages: IGBPackage[] = null
|
||||
channel: ConsoleDirectLine
|
||||
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
}
|
||||
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
}
|
||||
|
||||
loadBot(min: GBMinInstance): void {
|
||||
this.channel = new ConsoleDirectLine(min.instance.webchatKey)
|
||||
}
|
||||
|
||||
unloadBot(min: GBMinInstance): void {
|
||||
}
|
||||
|
||||
onNewSession(min: GBMinInstance, step: any): void {
|
||||
}
|
||||
}
|
||||
194
packages/console.gblib/services/ConsoleDirectLine.ts
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| General Bots Copyright (c) Pragmatismo.io. 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 Bots" 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. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
const Path = require("path")
|
||||
const Fs = require("fs")
|
||||
const _ = require("lodash")
|
||||
const Parse = require("csv-parse")
|
||||
const Async = require("async")
|
||||
const UrlJoin = require("url-join")
|
||||
const Walk = require("fs-walk")
|
||||
const logger = require("../../../src/logger")
|
||||
const Swagger = require('swagger-client')
|
||||
const rp = require('request-promise')
|
||||
import { GBService } from "botlib"
|
||||
|
||||
export class ConsoleDirectLine extends GBService {
|
||||
|
||||
pollInterval = 1000
|
||||
directLineSecret = ''
|
||||
directLineClientName = 'DirectLineClient'
|
||||
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json'
|
||||
|
||||
constructor(directLineSecret) {
|
||||
super()
|
||||
|
||||
this.directLineSecret = directLineSecret
|
||||
|
||||
|
||||
// TODO: Migrate to Swagger 3.
|
||||
let directLineClient = rp(this.directLineSpecUrl)
|
||||
.then(function (spec) {
|
||||
return new Swagger({
|
||||
spec: JSON.parse(spec.trim()),
|
||||
usePromise: true
|
||||
})
|
||||
})
|
||||
.then(function (client) {
|
||||
client.clientAuthorizations.add('AuthorizationBotConnector',
|
||||
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'))
|
||||
return client
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error('Error initializing DirectLine client', err)
|
||||
})
|
||||
|
||||
// TODO: Remove *this* issue.
|
||||
let _this_ = this
|
||||
directLineClient.then((client)=> {
|
||||
client.Conversations.Conversations_StartConversation()
|
||||
.then(function (response) {
|
||||
return response.obj.conversationId
|
||||
})
|
||||
.then(function (conversationId) {
|
||||
_this_.sendMessagesFromConsole(client, conversationId)
|
||||
_this_.pollMessages(client, conversationId)
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error('Error starting conversation', err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
sendMessagesFromConsole(client, conversationId) {
|
||||
let _this_ = this
|
||||
process.stdin.resume()
|
||||
var stdin = process.stdin
|
||||
process.stdout.write('Command> ')
|
||||
stdin.addListener('data', function (e) {
|
||||
var input = e.toString().trim()
|
||||
if (input) {
|
||||
// exit
|
||||
if (input.toLowerCase() === 'exit') {
|
||||
return process.exit()
|
||||
}
|
||||
|
||||
client.Conversations.Conversations_PostActivity(
|
||||
{
|
||||
conversationId: conversationId,
|
||||
activity: {
|
||||
textFormat: 'plain',
|
||||
text: input,
|
||||
type: 'message',
|
||||
from: {
|
||||
id: _this_.directLineClientName,
|
||||
name: _this_.directLineClientName
|
||||
}
|
||||
}
|
||||
}).catch(function (err) {
|
||||
console.error('Error sending message:', err)
|
||||
})
|
||||
|
||||
process.stdout.write('Command> ')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** TBD: Poll Messages from conversation using DirectLine client */
|
||||
pollMessages(client, conversationId) {
|
||||
let _this_ = this
|
||||
console.log('Starting polling message for conversationId: ' + conversationId)
|
||||
var watermark = null
|
||||
setInterval(function () {
|
||||
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
|
||||
.then(function (response) {
|
||||
watermark = response.obj.watermark // use watermark so subsequent requests skip old messages
|
||||
return response.obj.activities
|
||||
})
|
||||
.then(_this_.printMessages, _this_.directLineClientName)
|
||||
}, this.pollInterval)
|
||||
}
|
||||
|
||||
printMessages(activities, directLineClientName) {
|
||||
|
||||
if (activities && activities.length) {
|
||||
// ignore own messages
|
||||
activities = activities.filter(function (m) { return m.from.id !== directLineClientName })
|
||||
|
||||
if (activities.length) {
|
||||
|
||||
// print other messages
|
||||
activities.forEach(activity => {
|
||||
console.log(activity.text)
|
||||
}, this)
|
||||
|
||||
process.stdout.write('Command> ')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printMessage(activity) {
|
||||
if (activity.text) {
|
||||
console.log(activity.text)
|
||||
}
|
||||
|
||||
if (activity.attachments) {
|
||||
activity.attachments.forEach(function (attachment) {
|
||||
switch (attachment.contentType) {
|
||||
case "application/vnd.microsoft.card.hero":
|
||||
this.renderHeroCard(attachment)
|
||||
break
|
||||
|
||||
case "image/png":
|
||||
console.log('Opening the requested image ' + attachment.contentUrl)
|
||||
open(attachment.contentUrl)
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
renderHeroCard(attachment) {
|
||||
var width = 70
|
||||
var contentLine = function (content) {
|
||||
return ' '.repeat((width - content.length) / 2) +
|
||||
content +
|
||||
' '.repeat((width - content.length) / 2)
|
||||
}
|
||||
|
||||
console.log('/' + '*'.repeat(width + 1))
|
||||
console.log('*' + contentLine(attachment.content.title) + '*')
|
||||
console.log('*' + ' '.repeat(width) + '*')
|
||||
console.log('*' + contentLine(attachment.content.text) + '*')
|
||||
console.log('*'.repeat(width + 1) + '/')
|
||||
}
|
||||
}
|
||||
1
packages/core.gbapp/README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
*This is a General Bots open core package, more information can be found on the [BotServer](https://github.com/pragmatismo-io/BotServer) repository.*
|
||||