- Split from botserver.

This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2025-12-03 19:56:35 -03:00
parent f686fb2785
commit afd45573cf
509 changed files with 103387 additions and 19507 deletions

6
.gitignore vendored
View file

@ -1,6 +1,2 @@
swa-cli.config.json
deploy.sh
site/build
site/.docusaurus
book
.env
node_modules

19
book.toml Normal file
View file

@ -0,0 +1,19 @@
[book]
title = "General Bots Documentation"
authors = ["General Bots Team"]
language = "en"
multilingual = false
src = "src"
[build]
build-dir = "book"
[output.html]
default-theme = "light"
preferred-dark-theme = "navy"
smart-punctuation = true
additional-css = ["src/custom.css", "src/whatsapp-chat.css"]
additional-js = ["src/theme-sync.js"]
[output.html.favicon]
png = "favicon.png"

20
site/.gitignore vendored
View file

@ -1,20 +0,0 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View file

@ -1,41 +0,0 @@
# Website
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
### Installation
```
$ yarn
```
### Local Development
```
$ yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
### Build
```
$ yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
### Deployment
Using SSH:
```
$ USE_SSH=true yarn deploy
```
Not using SSH:
```
$ GIT_USER=<Your GitHub username> yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

View file

@ -1,3 +0,0 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

View file

@ -1,11 +0,0 @@
---
sidebar_position: 1000
---
# Apendix I - Database Model
The database model can be seen on the picture bellow. In each .gbapp or .gblib
the folder **Model** will contain the Sequelize definition for each one of these
tables and their relationship.
![General Bots Database Model](./images/GeneralBotsDatabaseModel.png)

View file

@ -1,11 +0,0 @@
---
sidebar_position: 1000
---
# Apendix II - Network Diagrams
## Reverse Proxy for Development
When establishing a local development machine, an user can use the ngrok based proxy. The diagram shows how the localhost becomes accesible when the Bot Service need to connect, routing messages from the cloud to the local development server machine.
![General Bots Reverse Proxy](./images/GeneralBotsReverseProxy.png)

View file

@ -1,71 +0,0 @@
---
sidebar_position: 10
---
# Run and Talk
### Bot Development Stack
![General Bot Logo](https://github.com/GeneralBots/BotServer/blob/main/docs/images/general-bots-stack.png)
### Diagram Description
1. **gbapp** and **gblib** are folder extensions within the GeneralBots package type, responsible for GeneralBots services in a back-end development environment. A General Bot App comprises four components: dialogs, models, services, and tests.
2. The **.gbui** extension pertains to the GeneralBots front-end development environment. Angular, Riot, React, and HTML enable dynamic functionality for GeneralBots services.
3. The **.gtheme** extension is utilized by GeneralBots designers using CSS and PS technologies. A theme consists of CSS files and images.
4. **.gbDialog** is an extension responsible for GeneralBots' communication with end-users through bot services. **.gbkb** is a package for executing various types of media.
5. The **.gbot** extension refers to the GeneralBots service product.
6. **.gbai** denotes the architecture construction of the GeneralBots application.
### The Bot Factory
![General Bots Block Architecture](https://raw.githubusercontent.com/pragmatismo-io/BotServer/master/docs/images/general-bots-block-architecture.png)
GeneralBots aims to deliver bots on Azure in an easy and efficient manner. Utilize office tools like Word or Excel for editing your bot, leveraging code (JavaScript or TypeScript) only for custom requirements.
## How To
### Running the Server Locally
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** or PowerShell window on Windows.
3. Type `npm install -g botserver` and press **ENTER**.
4. Type `gbot` to start the server core.
### Notes:
- [*nodejs.install* Chocolatey Package](https://chocolatey.org/packages/nodejs.install) is also available (Chocolatey is a Windows package manager).
- The zip source code for General Bot is available for [Download](https://codeload.github.com/pragmatismo-io/BotServer/zip/master).
### Running Unit Tests
1. Navigate to the BotServer root folder.
2. Execute tests with `npm test`.
### Copying Source Code to Your Machine
1. [Download](https://codeload.github.com/pragmatismo-io/BotServer/zip/master) the zip file.
## Omnichannel
Omnichannel allows conversations to flow seamlessly regardless of the channel, as all interactions are recorded, preserving the consumer's history and profile.
## Spell Checker
GeneralBots performs spell-checking to identify and correct typographical errors.
## Speech to Text
Enable user speech recognition directly with GeneralBots.
## Branding
Branding encompasses all aspects of a company's identity management, including its name and corporate visual elements.
processing, and output through natural language.
---

View file

@ -1,94 +0,0 @@
---
sidebar_position: 20
---
# Package Based principles
Packages are folders in the file system, synced with cloud storages and
content management systems like SharePoint and even sent like .zip files on a e-mail.
Just to increse bot knowledge, intelligence and how they look to us. So working on a
General Bots project is like to split the work on several packages if needed and work
on a package at once or even share the work with collegues, agencies or development
companies to more advanced package building. Composite packages on GeneralBots:
![print packages](https://user-images.githubusercontent.com/65977273/94712159-7662fb80-031f-11eb-8217-1c0507bfe5d5.png)
# Your own data
You will see your data in .gbdata.
## How To
### Configure the server to deploy specific directory
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`.
Note:
- You can specify several bots separated by semicolon, the BotServer will serve all of them at once.
## Description of packages
### .gbai
Embraces all packages types (content, logic & conversation) into a pluggable bot
directory. [A sample .gbai is available](https://github.com/pragmatismo-io/IntranetBotQuickStart.gbai).
### .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.
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. GeneralBots also has the user's direct speech dialog, containing the spell checker.
#### 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.
all GeneralBots functionality comes down to services.
#### 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.
## System 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)|

View file

@ -1,61 +0,0 @@
---
sidebar_position: 30
---
# .gbkb Reference
![generalbots-2018](https://user-images.githubusercontent.com/65977273/94922431-949c3900-0490-11eb-800a-6b478d689f2a.png)
## Media Types
There are several media types that can be used in .gbkb package folder.
The table below shows the description of each one of them:
| Folder | File description |
|----------|----------------------------------------------------------------------------------------------------|
| tabular | .csv, .tsv or any tabular file used as an pair of question/answer and an optional hierarchy. |
| images | Images that can be used to enrich the answer to the user in the [Projector](./glossary.md) |
| videos | Videos used to answer questions made by users. |
| subjects | List of images of subjects that can be trated by the bot. |
| articles | Articles in .md that will be presented instead of text-only answers. |
## Presenting Answers
## With text
To answer with a text phrase, just type the answer in the Answer column. Whenever the
search engine elects the answer as the next thing to say, the text present in this
column will be talked.
## With an article
A Markdown (.md) file can be used as an answer instead of plain text, so the experience
will be more appealing whenever the channel allow the text to be present that way. The
answer column specifies the .md file to be presented whenever the question is elected
as matching the user intent.
## With a video
To display a video on the projector, just provide the Video URL to the desired question,
instead of specifing an text answer in the column **answer**.
The list of answers is a series of tabular files (.tsv, .csv, etc.) inside the **tabular** directory of the .gbkb.
## With a Script (PREVIEW)
To call a VBA script stored on a .gbdialog, just specify the script file name in a form of `script:<FILENAME>` instead of specifing an text answer in the column **answer**. When someone asks that match the **question**, the script will be invoked and the answer dialog will be started.
## Subject Menu
### Associating a [Subject Menu Item](glossary.md#subject-menu-item) to a Dialog
To call a dialog just when an answer would provide the desired question, just
use dialog:*dialogName* instead of specifing an text answer.
## How To
### Updating the Bot Knowledge Base (.gbkb folder)
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.
### Use Excel for (Hierarchical) Knowledge Base Editing
![General Bots Inside Excel can enable bot production the masses](https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/general-bots-composing-subjects-json-and-excel.gif)

View file

@ -1,19 +0,0 @@
---
sidebar_position: 40
---
# .gbtheme Reference
![generalbots-2018](https://user-images.githubusercontent.com/65977273/94922431-949c3900-0490-11eb-800a-6b478d689f2a.png)
## How To
### Creating a new Theme folder (.gbtheme folder)
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).
## Importance of the themes linked to the visual with user.
The css complements for the final visual with the user, aesthetics is linked to the general usability of GeneralBots which facilitates the interaction with the user. GeneralBots uses what is most current to improve its interface through css.

View file

@ -1,866 +0,0 @@
---
sidebar_position: 50
---
# .gbdialog Reference
![generalbots-2018](https://user-images.githubusercontent.com/65977273/94922431-949c3900-0490-11eb-800a-6b478d689f2a.png)
General Bots BASIC using HEAR and TALK keywords provides a easy to write bot language accessible to everyone and used as incomer for people willing to make their own bot.
It's crucial to emphasize just how easy and powerful the General Bots system is:
1. Rapid Development: With just a few lines of BASIC-like code, you can
create complex, AI-powered applications.
2. Automatic REST API: General Bots automatically generates REST API
endpoints for your dialogs, saving you significant development time.
3. Production-Ready: Simply by adding a BASIC text file, you get a General
Bots application running in production. No complex deployment processes
required.
4. Versatility: Whether you're building chatbots, process automation, or
data collection systems, General Bots can handle it all with the same
simple syntax.
5. Integration of LLMs: Seamlessly incorporate the power of Large Language
Models into your applications without dealing with complex AI frameworks.
General Bots truly revolutionizes the way we build AI-powered applications
and REST APIs. Its simplicity belies its power, making it accessible to
developers of all skill levels while providing the capabilities needed for
enterprise-grade applications.
## Architecture
##
A BASIC Isolated Virtual Machine Architecture, like creating a conversation Node.js application just using BASIC. All code will run isolated on a Node, (https://user-images.githubusercontent.com/14840374/200206510-9f5bd788-e710-4932-9ed8-a09599656cea.png).
One of the key security features of the General Bots platform is its use of isolated virtual machines (VMs) for each dialog. This architecture provides a robust layer of security and isolation, significantly reducing the risk of cross-contamination or unauthorized access between different bot interactions.
### How It Works
1. **Individual VM per Dialog**: Each time a user initiates a dialog with a bot, the platform spawns a new, isolated virtual machine dedicated to that specific interaction.
2. **Limited Capabilities**: These VMs are configured with restricted capabilities, adhering to the principle of least privilege. This means that each VM has only the minimum permissions and access necessary to perform its intended functions.
3. **Sandboxing**: The VM acts as a sandbox environment, containing the execution of bot logic and preventing it from affecting other parts of the system or other user interactions.
### Security Benefits
- **Isolation**: If a security breach occurs within one dialog, it remains contained within that specific VM, protecting other user interactions and the broader system.
- **Resource Control**: The VM architecture allows for fine-grained control over resource allocation, preventing any single interaction from monopolizing system resources.
- **Clean Slate**: Each new dialog starts with a fresh VM instance, eliminating the risk of data leakage between different user interactions.
- **Easier Updates and Patches**: Security updates can be applied to the VM template, ensuring that all new dialogs benefit from the latest security measures.
### Considerations for Bot Developers
1. **Performance Impact**: While the isolated VM approach significantly enhances security, it may introduce slight latency in bot responses. Developers should optimize their bot logic to work efficiently within this environment.
2. **Stateless Design**: Since each dialog runs in a new VM instance, developers should design their bots to be stateless or use external state management systems that can be securely accessed from within the VM.
3. **Resource Awareness**: Developers should be mindful of the limited resources available within each VM and design their bots accordingly, avoiding resource-intensive operations where possible.
4. **Security-First Mindset**: Even with the isolated VM architecture, developers should continue to follow security best practices in their bot development, such as input validation and secure handling of sensitive data.
By leveraging this isolated VM architecture, the General Bots platform provides a secure environment for bot interactions, giving both developers and users confidence in the system's integrity and data protection capabilities.
## Using Conversational BASIC
The following file types are loaded from a .gbdialog package: `.vbs`, `.vb`, `.basic` and `.bas`.
## General Bots BASIC reference
To organize the instructions functionally, I'll group them into five categories: **Basic Interaction**, **Data Handling**, **Web Automation**, **File Management**, and **Advanced Operations**. Each group will include relevant instructions with examples.
## Basic Interaction
| Instruction / Usage | Description | Example |
| ----------------------------------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| HEAR _variable_ | Hears something from the person into a _variable_ for later use. | <pre>HEAR name <br/>TALK "Your name is " + name.<br/></pre> |
| TALK _message_ | Talk the specified _message_ to the person. | <pre>TALK "Hello world."</pre> |
| CHART PROMPT _data_, _prompt_ | Generates dynamic charts using natural language | <pre>file = CHART PROMPT data, "product by month in bar chart <br/> SEND FILE TO mobile, file</pre> |
| WAIT _seconds_ | Wait a number of seconds before continuing the conversation. | <pre>WAIT 10 <br/> TALK "Waited for 10 seconds."</pre> |
| confirm _variable_ (Comming soon) | Waits for confirmation like 'yes', 'y', 'yeah' and returns true or false | <pre>HEAR confirm <br/>TALK "Please confirm if you want to proceed." <br/> if confirm THEN TALK "Confirmed." ELSE TALK "Not confirmed."</pre> |
| HEAR _variable_ AS EMAIL | Hears and validates an email address from the user. | <pre>HEAR email AS EMAIL <br/> TALK "Email received: " + email.</pre> |
| HEAR _variable_ AS DATE | Hears and validates a date from the user. | <pre>HEAR date AS DATE <br/> TALK "Date received: " + date.</pre> |
| HEAR _variable_ AS NAME | Hears and validates a name from the user. | <pre>HEAR name AS NAME <br/> TALK "Name received: " + name.</pre> |
| HEAR _variable_ AS INTEGER | Hears and validates an integer from the user. | <pre>HEAR age AS INTEGER <br/> TALK "Age received: " + age.</pre> |
| HEAR _variable_ AS BOOLEAN | Hears and validates a boolean (true/false) from the user. | <pre>HEAR agree AS BOOLEAN <br/> TALK "Agreement status: " + agree.</pre> |
| HEAR _variable_ AS HOUR | Hears and validates an hour from the user. | <pre>HEAR hour AS HOUR <br/> TALK "Hour received: " + hour.</pre> |
| HEAR _variable_ AS MONEY | Hears and validates a monetary amount from the user. | <pre>HEAR amount AS MONEY <br/> TALK "Amount received: " + amount.</pre> |
| HEAR _variable_ AS MOBILE | Hears and validates a mobile number from the user. | <pre>HEAR mobile AS MOBILE <br/> TALK "Mobile number received: " + mobile.</pre> |
| HEAR _variable_ AS ZIPCODE | Hears and validates a ZIP code from the user. | <pre>HEAR zipcode AS ZIPCODE <br/> TALK "ZIP Code received: " + zipcode.</pre> |
| HEAR _variable_ AS "Abacate", "Maçã", "Morango" | Displays the specified menu and waits for user selection. | <pre>HEAR fruit AS "Abacate", "Maçã", "Morango" <br/> TALK "You selected: " + fruit.</pre> |
| HEAR _variable_ AS LANGUAGE | Hears and validates a language code from the user. | <pre>HEAR language AS LANGUAGE <br/> TALK "Language selected: " + language.</pre> |
| HEAR _variable_ AS LOGIN (internal) | Waits for Active Directory login integration before proceeding. | <pre>HEAR user AS LOGIN <br/> TALK "User logged in: " + user.</pre> |
| HEAR _variable_ AS QRCODE | Hears and validates a QR code from a captured image. | <pre>TALK "Send me an image with a QR Code."<br/>HEAR qrcode AS QRCODE <br/> TALK "QR Code received: " + qrcode.</pre> |
## Data Handling
| Instruction / Usage | Description | Example |
| ------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| _variable_ = GET "_file_.xlsx", "_A1:A1_" | Gets the value of the cell specified in range address | <pre>name = GET "data.xlsx", "A1:A1" <br/> TALK "The value is " + name.</pre> |
| SET "_file_.xlsx", "_A1:A1_", 42 | Sets the value of the cell specified in range address | <pre>SET "data.xlsx", "A1:A1", 42 <br/> TALK "Value set in Excel."</pre> |
| _variable_ = GET "https://server/query" | Gets the value from the specified web service | <pre>result = GET "https://api.example.com/data" <br/> TALK "Data received: " + result.</pre> |
| POST "https://", _data_ | Sends data to the specified URL | <pre>POST "https://api.example.com/submit", "data" <br/> TALK "Data posted successfully."</pre> |
| data = SELECT a, SUM(b) AS b FROM data GROUP BY a | Use SQL to manipulate a data variable returned from FIND or an array | <pre>data = FIND "sales_data.xlsx", "A1:B10" <br/> result = SELECT product, SUM(amount) AS total FROM data GROUP BY product <br/> TALK "Query result: " + result.</pre> |
| file = data AS IMAGE | Converts a two-dimensional array into an image file. | <pre>file = data AS IMAGE <br/> SAVE file AS "sales_chart.png" <br/> TALK "Chart saved as image."</pre> |
| file = data AS PDF | Converts a two-dimensional array into a PDF file. | <pre>file = data AS PDF <br/> SAVE file AS "sales_report.pdf" <br/> TALK "Report saved as PDF."</pre> |
| file = CONVERT "mydesign.ai" | Converts a Adobe Illustrator to a HTML page. |
| NEW OBJECT | Creates a new object to be used with REST calls. | <pre>data = NEW OBJECT <br/> data.color = "blue" <br/> TALK "New object created."</pre> |
| NEW ARRAY | Creates a new array. | <pre>data = NEW ARRAY <br/> data[0] = "red" <br/> TALK "New array created."</pre> |
| QRCODE | Creates a QR code from specified text. | <pre>file = QRCODE "https://example.com" <br/> SAVE file AS "qrcode.png" <br/> TALK "QR Code generated."</pre> |
| FORMAT value, format | Formats a value according to the specified format. | <pre>d = FORMAT today, "YYYY-MM-dd" <br/> TALK "Formatted date: " + d.</pre> |
| ADD NOTE | Adds a note to a file named Notes.xls of .gbdata. | <pre>ADD NOTE "This is a new note." <br/> TALK "Note added."</pre> |
| ALLOW ROLE | Check if role specified in People sheet (.gbdata) will have access. | <pre>ALLOW ROLE "Admin" <br/> TALK "Role access granted."</pre> |
## Web Automation
| Instruction / Usage | Description | Example |
| --------------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| page = OPEN _url_ [AS #namedSession] | Web automation retrieval of a web page, saving the session for reuse. | <pre>page = OPEN "https://example.com" AS #session1 <br/> TALK "Page opened and session saved."</pre> |
| \* _variable_ = GET page, cssSelector, "body > img" | Retrieves an element within an IFRAME specified by selector. | <pre>image = GET page, "#profile-picture" <br/> TALK "Profile picture retrieved."</pre> |
| \* SET page, cssSelector, value | Defines a field to a value on the webpage specified by selector. | <pre>SET page, "#username", "user123" <br/> TALK "Username set."</pre> |
| \* CLICK page, cssSelector | Clicks on an element inside the web page being automated. | <pre>CLICK page, "#submit-button" <br/> TALK "Submit button clicked."</pre> |
| \* file = DOWNLOAD _url_ | Downloads a file from the specified URL. | <pre>file = DOWNLOAD "https://example.com/file.zip" <br/> SAVE file AS "downloads/file.zip" <br/> TALK "File downloaded."</pre> |
## File Management
| Instruction / Usage | Description | Example |
| ------------------------ | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| HEAR _variable_ AS FILE | Returns a file uploaded by the user to be saved. | <pre>HEAR file AS FILE <br/> SAVE file AS "uploads/myfile.pdf" <br/> TALK "File uploaded and saved."</pre> |
| HEAR _variable_ AS AUDIO | Returns an audio file uploaded by the user to be saved. | <pre>HEAR audio AS AUDIO <br/> SAVE audio AS "recordings/audiofile.mp3" <br/> TALK "Audio received and saved."</pre> |
| INCLUDE file | Includes a file into .gbdialog. | <pre>INCLUDE "script.gbdialog" <br/> TALK "File included."</pre> |
| UPLOAD file | Uploads a file to a storage blob, like Azure Storage. | <pre>UPLOAD "path/to/file.pdf" <br/> TALK "File uploaded to cloud storage."</pre> |
| DIR path | Returns a list of files in the specified directory. | <pre>files = DIR "uploads/" <br/> TALK "Files in directory: " + files.</pre> |
| FILL | Fills data into a Word document to be exported as images. | <pre>FILL "template.docx", data <br/> TALK "Document filled and exported."</pre> |
| SAVE _variable_ AS "path/file" | Saves the specified variable as a file at the given path. | <pre>SAVE file AS "path/to/save/file.pdf" <br/> TALK "File saved."</pre> |
## Advanced Operations
| Instruction / Usage | Description | Example |
| ------------------------ | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| TABLE name ON connection | Defines a TABLE on the specified storage (database) connection. | <pre>TABLE "Sales" ON "DBConnection" <br/> TALK "Table defined."</pre> |
| field AS dataType | Defines a field in TABLE. Eg.: name string(50). | <pre>field = "price" AS number(10,2) <br/> TALK "Field defined as number."</pre> |
| CONTINUATION TOKEN | Returns the value of the continuation token associated with the current dialog. | <pre>token = CONTINUATION TOKEN <br/> TALK "Continuation token: " + token.</pre> |
| NEW OBJECT | Creates a new object to be used with REST calls. | <pre>data = NEW OBJECT <br/> data.color = "blue" <br/> TALK "New object created."</pre> |
| NEW ARRAY | Creates a new array. | <pre>data = NEW ARRAY <br/> data[0] = "red" <br/> TALK "New array created."</pre> |
### Internal Variables and Functions.
These are variables that can be used in General Bots BASIC to faster dialog and services faster.
All values from .gbot Config.xlsx are also provided as variables, so it can be acessed directly in dialog.
| Instruction / Usage | Description |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| aadToken() | Auto generated variable that contains Azure AD Token useful for calling Microsoft Web Services. |
### Options
| Instruction / Usage | Description |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| SET PARAM name AS value | Defines a retrievable param in the storage in the scope of the user |
| GET PARAM name | Returns a previously user scoped param via SET PARAM from the storage. |
| SET HTTP HEADER _key = _value_ | Defines an HTTP header to be used to next GET call. |
| SET HTTP USERNAME = _value_ | Defines the HTTP username to be used to next GET call. |
| SET HTTP PASSWORD = _value_ | Defines the HTTP password to be used to next GET call. |
| * SET HEAR ON "mobile" | |
| SET MAX LINES _value_ | |
| SET SCHEDULE "2 * * * * *" | |
| SET LANGUAGE _value_ | |
| SET TRANSLATOR [ON or OFF] | |
| SET WHOLE WORD [TRUE or FALSE] | |
| SET THEME "dark" or "white" or "blue" | Defines the theme to the next content generation (PDF, images, vídeos, etc.) |
| SET OPERATOR [OR] | Defines OR operations on multiple FIND filters separated by comma, eg.: FIND "A1=2", "A3=4" |
| SET FILTER TYPE [comma separated list of types]| Uses the specified type in next FIND calls, disabling auto detection of filter type, eg.: SET FILTER TYPE date, string |
| SET PAGED "auto" or "none" | Defines auto pagging for HTTP REST GET calls. |
* = Work in progress.
## How To
### Use code in Excel
To reply as code in Excel, start the cell value with /basic followed by the code itself. Eg.:
```
/basic
TALK "Hello."
````
### Use General Bots computer vision
1. Develop a BASIC dialog and publish;
![image](https://user-images.githubusercontent.com/14840374/146782500-26f0dc27-e722-41aa-b79e-619d6403fa0d.png)
2. Test it in the conversation
![image](https://user-images.githubusercontent.com/14840374/146782691-7c28998b-7485-4d34-af33-da87d1b26088.png)
### Using General Bots Web Automation to ask humans about unreadable captchas
```BASIC
mobile = "5521000000000"
page = GET HTML "https://www.any-website.com/"
SET page, "#usuario", "user"
SET page, "#j_password", "xxxxxxxxxxx"
img = GET page, "[name=iCaptcha]", "body > img"
SEND FILE TO mobile, img
TALK TO mobile, "Digite o código da imagem para prosseguir:"
SET HEAR ON mobile
HEAR captcha
SET page, "#captcha", captcha
CLICK page, "#bt-login"
TALK TO mobile, "Login done, thanks."
````
### Using General Bots SQL and dynamic image and chart generation
On the fly table as images.
```BASIC
SET MAX LINES 1000
data = FIND "data.xlsx",
data = SELECT a, SUM(b) AS b FROM data GROUP BY a
SET THEME dark
png = data as IMAGE
SEND FILE png
```
On the fly charts
```BASIC
data = [10, 20, 30]
legends= "Steve;Yui;Carlos"
img = CHART "pie", data, legends
SEND FILE img
SAVE img as "folder/filename.jpg"
```
### Using General Bots Web Automation to custom notify about Google Calendar
```basic
REM Perform G. Login.
OPEN "https://accounts.google.com/ServiceLogin"
SET "#identifierId", "test@gmail.com"
PRESS ENTER
WAIT 3
SET "input[type='password']", "******"
PRESS ENTER
WAIT 5
REM Enter on the Calendar page and capture the calendar grid inside the page.
OPEN "https://calendar.google.com/calendar/u/0/r?tab=mc&pli=1"
file = SCREENSHOT "div.K2fuAf"
REM Notify all team members with the updated calendar image.
list = FIND "People.xlsx", "Calendar=Y"
index = 1
DO WHILE index < ubound(list)
row = list[index]
TALK TO row.Mobile, "Hello " + row.Name + ", here is your calendar:"
SEND FILE TO row.Mobile, file, "Calendar"
index = index + 1
LOOP
```
### Using complete General Bots Conversational Data Analytics
```BASIC
TALK "General Bots Labs presents FISCAL DATA SHOW BY BASIC"
TALK "Gift Contributions to Reduce the Public Debt API (https://fiscaldata.treasury.gov/datasets/gift-contributions-reduce-debt-held-by-public/gift-contributions-to-reduce-the-public-debt)"
result = GET "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/gift_contributions?page[size]=500"
data = result.data
data = SELECT YEAR(record_date) as Yr, SUM(CAST(contribution_amt AS NUMBER)) AS Amount FROM data GROUP BY YEAR(record_date)
TALK "Demonstration of Gift Contributions with AS IMAGE keyword"
SET THEME dark
png = data as IMAGE
SEND FILE png
DELAY 5
TALK " Demonstration of Gift Contributions CHART keyword"
img = CHART "bar", data
SEND FILE img
```
![image](https://user-images.githubusercontent.com/14840374/178154826-8188029e-b4f4-48aa-bc0d-126307ce5121.png)
### Using General Bots Office templates
```
data = FIND "Customer.xlsx", "Idade=25"
doc = TEMPLATE "template.docx" WITH data
SAVE doc AS "resume.docx"
SEND EMAIL "noreply@pragmatismo.io", "Subject", doc
```
### Automating GitHub Issue creation with General Bots Automation
```BASIC
REM Realiza login no GitHub.
page = GET HTML "https://github.com/login"
SET page, "#login_field", "username"
SET page, "#password", "*******"
PRESS ENTER ON page
REM Verifica 2FA.
SET HEAR ON "5521999999999"
TALK "Digite o código de dupla autenticação enviado..."
HEAR code
SET page, "#otp", code
PRESS ENTER ON page
REM Extrai cada Issue da planilha e cria no GitHub.
list = FIND "issues.xlsx"
index = 1
DO WHILE index <38
row = list[index]
page = GET HTML "https://github.com/GeneralBots/BotServer/issues/new"
SET page, "#issue_title", row.title
SET page, "#issue_body", row.body
CLICK page, "#new_issue > div > div > div.Layout-main > div > div.timeline-comment.color-bg-default.hx_comment-box--tip > div > div.flex-items-center.flex-justify-end.d-none.d-md-flex.mx-2.mb-2.px-0 > button"
TALK "Issue '" + row.title + "' criado."
WAIT 5
index = index + 1
LOOP
EXIT
```
## Turn an LLM into a REST API server
General Bots offers an incredibly simple way to transform a Large Language
Model (LLM) into a fully functional REST API server. With just a few lines
of our proprietary BASIC-like syntax, you can create sophisticated
AI-powered applications.
For example, here's how easy it is to create a chatbot for a store:
```basic
PARAM operator AS number LIKE 12312312
DESCRIPTION "Operator code."
DESCRIPTION It is a WebService of GB.
products = FIND "products.csv"
BEGIN SYSTEM PROMPT
You must act as a chatbot that will assist a store attendant by
following these rules: Whenever the attendant places an order, it must
include the table and the customer's name. Example: A 400ml Pineapple
Caipirinha for Rafael at table 10. Orders are based on the products and
sides from this product menu: ${JSON.stringify(products)}.
For each order placed, return a JSON containing the product name, the
table, and a list of sides with their respective ids.
END SYSTEM PROMPT
```
That's it! With just this simple BASIC code, you've created a fully
functional LLM-powered chatbot that can handle complex order processing.
The system automatically generates the necessary REST API endpoints:
```
pid = http://localhost:1111/llm-server/dialogs/start?operator=123&userSystemId=999
```
This call will return a process identifier or PID, a number like 24795078551392. This should be passed within call chain. So, it is
possible now to TALK to the bot, like an UI App input or microphone.
And the return will be the JSON, because BEGIN SYSTEM PROMPT in start
has told LLM to respond with a valid JSON.
TALK "PDF report generated and saved!"
```
http://localhost:1111/llm-server/dk/talk?pid=4893749837&text=add%20soda
```
So this call will act like talking to LLM, but in fact, it can be used
to anything that General Bots can do in a robotic conversation between systems mediated by LLM.
## Using dialogs as REST API Server
Creating a REST API server for any business process is equally
straightforward. Here's an example of an enrollment process:
```basic
PARAM name AS string LIKE "João Silva"
DESCRIPTION "Required full name of the individual."
PARAM birthday AS date LIKE "23/09/2001" DESCRIPTION "Required birth date of the individual in DD/MM/YYYY format."
PARAM email AS string LIKE "joao.silva@example.com" DESCRIPTION "Required email address for contact purposes."
PARAM personalid AS integer LIKE "12345678900" DESCRIPTION "Required Personal ID number of the individual (only numbers)."
PARAM address AS string LIKE "Rua das Flores, 123, São Paulo, SP" DESCRIPTION "Required full address of the individual."
DESCRIPTION "This is the enrollment process, called when the user wants to enroll. Once all information is collected, confirm the details and inform them that their enrollment request has been successfully submitted. Provide a polite and professional tone throughout the interaction."
SAVE "enrollments.csv", id, name, birthday, email, cpf, rg, address
```
Incredibly, this is all you need to create a full-fledged enrollment system
with data validation, user interaction, and data storage. The system
automatically generates a REST API endpoint that is called by LLM as a tool.
So LLM can answer with data of external model train data.
```
http://api.pragmatismo.cloud/llm-server/dialogs/enrollment?birthday...
```
### Using POST data
You can use POST passing a variable as the second param in the POST call. The example
bellow shows how to call POST using an object that is returned from the Excel file.
Given the Excel file with the following contents and saved to the standard .gbdialog folder:
| tokenId | token | comment |
| ------- | ---------------- | ------- |
| 29187 | AAMkAGEzMWIxMmI5 | Prod1 |
| 98739 | jZWYtNGQ3My1iNmM | Prod2 |
The Word bellow will invoke POST call by using line contents as object attributes:
```BASIC
obj = FIND "dados.xlsx", "tokenId=29187"
POST "https://server/query", obj
' obj here is {tokenId: 29187, token: "AAMkAGEzMWIxMmI5", comment: "Prod1"}
```
- OAuth2 is being implemented and no modification to previous calls will be necessary
as this configuration will be an administrative conversation to get the token setup.
### Generate a password for the person
```vb
talk "Let's generate a very dificult to guess password for the new bot:"
generate a password
talk "Your password is *" + password + "*. Keep it on a safe place only acessible to you."
```
### Get the list of cloud subscriptions
```vb
hear one of subscriptions with email, password into subscriptionId
talk "The subscription selected was: " + subscriptionId
```
# General Bots Simple and Complex Programs
These are sample programs in General Bots BASIC, each presented with a modern and engaging approach. The first 20 examples are simple, while the next 20 delve into more advanced concepts. Check the list
of [templates](https://github.com/GeneralBots/BotServer/tree/main/templates)
The set of 20 advanced General Bots BASIC programs that integrate web services, web automation, file handling, and dynamic interactions. These samples are designed to showcase the full potential of General Bots BASIC for advanced users. These advanced samples illustrate a range of functionalities that can be implemented with General Bots BASIC, from data manipulation and web automation to dynamic content generation and complex file handling.
## 1. **Retrieve and Save Web Data to Excel**
```basic
GET "https://api.example.com/data"
data = result.data
SAVE "data.xlsx", "A1:A" + UBOUND(data), data
TALK "Data retrieved and saved to data.xlsx successfully!"
```
## 2. **Automated Web Form Submission**
```basic
OPEN "https://example.com/form"
SET page, "#name", "John Doe"
SET page, "#email", "john.doe@example.com"
SET page, "#message", "This is a test message."
CLICK page, "#submit"
TALK "Form submitted successfully!"
```
## 3. **Generate and Save Dynamic Report as PDF**
```basic
data = FIND "report_data.xlsx", "A1:C10"
pdf = data AS PDF
SAVE pdf AS "report.pdf"
TALK "Dynamic report generated and saved as report.pdf!"
```
## 4. **Create and Upload Image from Data**
```basic
data = [10, 20, 30, 40]
labels = "Q1;Q2;Q3;Q4"
img = CHART "bar", data, labels
UPLOAD img
TALK "Chart image generated and uploaded!"
```
## 5. **Automate GitHub Issue Creation from Spreadsheet**
```basic
list = FIND "issues.xlsx"
index = 1
DO WHILE index <= UBOUND(list)
row = list[index]
page = GET HTML "https://github.com/GeneralBots/BotServer/issues/new"
SET page, "#issue_title", row.title
SET page, "#issue_body", row.body
CLICK page, "#new_issue > div > div > div.Layout-main > div > div.timeline-comment.color-bg-default.hx_comment-box--tip > div > div.flex-items-center.flex-justify-end.d-none.d-md-flex.mx-2.mb-2.px-0 > button"
TALK "Issue '" + row.title + "' created."
WAIT 5
index = index + 1
LOOP
```
## 6. **Extract and Save Web Page Content**
```basic
OPEN "https://example.com/page"
content = GET page, "body"
SAVE "page_content.txt", content
TALK "Page content saved as page_content.txt!"
```
## 7. **Interactive Poll Results Analysis**
```basic
HEAR poll_data AS FILE
data = LOAD poll_data
analysis = SELECT question, COUNT(*) AS responses FROM data GROUP BY question
SAVE "poll_analysis.xlsx", "A1:C" + UBOUND(analysis), analysis
TALK "Poll results analyzed and saved to poll_analysis.xlsx!"
```
## 8. **Send User-Specific Notifications**
```basic
list = FIND "users.xlsx", "Notify=Y"
index = 1
DO WHILE index <= UBOUND(list)
row = list[index]
SEND MAIL row.email, "Notification", "Hello " + row.name + ", you have a new notification!"
index = index + 1
LOOP
TALK "Notifications sent to all users."
```
## 9. **Automate Data Entry into Web Application**
```basic
OPEN "https://example.com/data-entry"
SET page, "#field1", "Value1"
SET page, "#field2", "Value2"
SET page, "#field3", "Value3"
CLICK page, "#submit"
TALK "Data entry completed successfully!"
```
## 10. **Generate and Save QR Codes for Multiple URLs**
```basic
urls = ["https://example1.com", "https://example2.com", "https://example3.com"]
index = 1
DO WHILE index <= UBOUND(urls)
file = QRCODE urls[index]
SAVE file AS "qrcode_" + index + ".png"
index = index + 1
LOOP
TALK "QR codes generated and saved!"
```
## 11. **Automate Google Calendar Event Creation**
```basic
OPEN "https://calendar.google.com/calendar/u/0/r?tab=mc&pli=1"
HEAR event_date AS DATE
HEAR event_details AS STRING
SET "#title", "New Event"
SET "#details", event_details
SET "#date", event_date
CLICK "#save"
TALK "Event created on Google Calendar for " + event_date
```
## 12. **Send Customized Reports to a List of Recipients**
```basic
data = FIND "reports.xlsx"
index = 1
DO WHILE index <= UBOUND(data)
row = data[index]
report = TEMPLATE "report_template.docx" WITH row
SEND MAIL row.email, "Your Report", report
index = index + 1
LOOP
TALK "Reports sent to all recipients."
```
## 13. **Create and Save Dynamic Chart with User Input**
```basic
HEAR user_data AS "10,20,30,40"
data = SPLIT(user_data, ",")
img = CHART "line", data
SAVE img AS "dynamic_chart.png"
TALK "Dynamic chart created and saved as dynamic_chart.png!"
```
## 14. **Extract and Save Image Metadata**
```basic
SEE TEXT OF "https://example.com/image.jpg" AS metadata
SAVE "image_metadata.txt", metadata
TALK "Image metadata extracted and saved as image_metadata.txt!"
```
## 15. **Automate Form Filling Based on Data from Excel**
```basic
data = FIND "form_data.xlsx", "A1:C1"
OPEN "https://example.com/form"
SET page, "#name", data[0].name
SET page, "#email", data[0].email
SET page, "#message", data[0].message
CLICK page, "#submit"
TALK "Form filled and submitted based on Excel data!"
```
## 16. **Generate PDF from Dynamic SQL Query Results**
```basic
data = FIND "database.xlsx", "A1:C100"
query = SELECT name, age, city FROM data WHERE age > 30
pdf = query AS PDF
SAVE pdf AS "filtered_data_report.pdf"
TALK "PDF report generated and saved!"
```
## 17. **Capture and Save Web Page Screenshot with Timestamp**
```basic
timestamp = FORMAT NOW(), "YYYY-MM-DD_HH-MM-SS"
OPEN "https://example.com"
file = SCREENSHOT "body"
SAVE file AS "screenshot_" + timestamp + ".png"
TALK "Screenshot captured and saved with timestamp!"
```
## 18. **Handle and Save User-Uploaded Files**
```basic
HEAR user_file AS FILE
SAVE user_file AS "uploads/user_file_" + FORMAT NOW(), "YYYY-MM-DD_HH-MM-SS" + ".pdf"
TALK "File uploaded and saved successfully!"
```
## 19. **Extract Data from Web Page and Save to Excel**
```basic
OPEN "https://example.com/data-page"
data = GET page, "#data-table"
SAVE "web_data.xlsx", "A1:A" + UBOUND(data), data
TALK "Data extracted from web page and saved to web_data.xlsx!"
```
## 20. **Perform Complex Data Analysis and Save Results**
```basic
data = FIND "complex_data.xlsx", "A1:D100"
analysis = SELECT category, SUM(amount) AS total FROM data GROUP BY category
SAVE "data_analysis.xlsx", "A1:B" + UBOUND(analysis), analysis
TALK "Data analysis completed and saved to data_analysis.xlsx!"
```
And even more simple examples can be seen in this list as begginers use BASIC
to understand code:
## 1. Welcome Message
```basic
HEAR name AS NAME
TALK "Hey " + name + ", welcome to our awesome service! 🎉"
```
## 2. Simple Password Generator
```basic
GENERATE A PASSWORD
TALK "Your new password is: " + password
```
## 3. Remind User to Take a Break
```basic
WAIT 3600
TALK "You've been working for an hour! Remember to take a break and stretch! 💪"
```
## 4. Get User's Favorite Fruit
```basic
HEAR fruit AS "Apple", "Banana", "Cherry"
TALK "Nice choice! " + fruit + " is a great fruit! 🍓"
```
## 5. Send a Calendar Invite
```basic
HEAR email AS EMAIL
HEAR date AS DATE
TALK "Sending a calendar invite for " + date + " to " + email
SEND MAIL email, "Calendar Invite", "You are invited to an event on " + date
```
## 6. Generate and Send QR Code
```basic
HEAR url AS "https://example.com"
file = QRCODE url
SEND FILE file
TALK "Here is your QR code for the URL: " + url
```
## 7. Weather Update
```basic
GET "https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=YOUR_LOCATION"
data = result.current
TALK "The current temperature is " + data.temp_c + "°C with " + data.condition.text
```
## 8. Todo List Reminder
```basic
HEAR task AS STRING
TALK "Got it! I'll remind you about: " + task
```
## 9. Send Motivational Quote
```basic
quotes = ["Keep going!", "You got this!", "Believe in yourself!"]
index = RANDOM(0, 2)
TALK quotes[index]
```
## 10. Capture and Send Screenshot
```basic
OPEN "https://example.com"
file = SCREENSHOT "body"
SEND FILE file
TALK "Here's a screenshot of the page."
```
## 11. Daily Affirmation
```basic
HEAR user AS NAME
TALK "Good morning " + user + "! Remember, today is going to be amazing! 🌟"
```
## 12. Send a Joke
```basic
jokes = ["Why dont scientists trust atoms? Because they make up everything!", "Why did the scarecrow win an award? Because he was outstanding in his field!"]
index = RANDOM(0, 1)
TALK jokes[index]
```
## 13. User Poll
```basic
HEAR choice AS "Option 1", "Option 2", "Option 3"
TALK "You selected " + choice + ". Thanks for your input! 🗳️"
```
## 14. Image Caption Extraction
```basic
SEE CAPTION OF "https://example.com/image.jpg" AS caption
TALK "The caption of the image is: " + caption
```
## 15. Send Reminder Email
```basic
HEAR email AS EMAIL
HEAR reminder AS STRING
SEND MAIL email, "Reminder", "Just a friendly reminder: " + reminder
```
## 16. Capture Text from Image
```basic
SEE TEXT OF "https://example.com/image-with-text.jpg" AS text
TALK "The text from the image is: " + text
```
## 17. Add a Note
```basic
HEAR note AS STRING
ADD NOTE note
TALK "Note added: " + note
```
## 18. Generate Dynamic Chart
```basic
data = [5, 15, 25]
labels = "Red;Green;Blue"
img = CHART "bar", data, labels
SEND FILE img
TALK "Heres your dynamic chart!"
```
## 19. Create and Send PDF Report
```basic
data = FIND "data.xlsx", "A1:B10"
pdf = data AS PDF
SEND FILE pdf
TALK "Here's your report in PDF format."
```
## 20. Interactive Game
```basic
TALK "Guess a number between 1 and 10."
HEAR guess AS INTEGER
IF guess == 7
TALK "Congratulations! You guessed the right number! 🎉"
ELSE
TALK "Oops! Try again next time!"
```
These examples demonstrate various capabilities of the language, from simple text manipulation to more complex tasks like image processing.

View file

@ -1,411 +0,0 @@
---
sidebar_position: 60
---
# .gbapp Reference
![generalbots-2018](https://user-images.githubusercontent.com/65977273/94922431-949c3900-0490-11eb-800a-6b478d689f2a.png)
## Section 1: Introduction to gbapp
### What is a gbapp?
A gbapp is an npm package designed to extend the functionality of General Bots. It serves as a plugin or module that can be integrated into the General Bots framework to add new features, capabilities, or customizations. Importantly, .gbapp is also the folder extension for the General Bots Application package type.
### Purpose and Benefits
The primary purpose of a gbapp is to provide a modular and flexible way to enhance General Bots. By using gbapps, developers can easily extend the core functionality of the bot platform without modifying the main codebase, allowing for greater customization and scalability. This approach promotes code reusability and maintainability.
### Integration with General Bots
Gbapps are designed to seamlessly integrate with the General Bots ecosystem. They can interact with the core services, access shared resources, and leverage existing functionalities while adding their own unique features to the bot framework. Anything inside a folder considered a .gbapp will be consumed by the server like a TypeScript application.
## Key Interfaces and Structure of a gbapp
### IGBCoreService Interface
The IGBCoreService interface is a crucial component of a gbapp. It defines the core service shared among bot packages, providing direct access to base services. This interface includes methods for database operations, instance management, storage initialization, and various system-level functionalities.
### IGBPackage Interface
The IGBPackage interface outlines the structure and lifecycle methods of a gbapp. It includes methods for loading and unloading the package, managing bot instances, handling dialogs, and exchanging data between the bot server and the gbapp. This interface ensures that all gbapps follow a consistent pattern for integration with General Bots.
### Conversational Application Structure
A .gbapp contains the source code for custom dialogs and behaviors for any .gbot that associates with this deployed .gbapp. This structure allows for the creation of conversational applications that can be reused across different bot instances, promoting modularity and flexibility in bot development.
## Developing and Implementing a gbapp
### Creating a gbapp Package
To create a gbapp, developers start by setting up an npm package with the necessary dependencies. A good way to start is by finding an existing npm package that provides the desired functionality. For example, a temperature conversion gbapp could be created by installing the 'temperature' package via `npm install temperature` and then implementing methods to call `convertToKelvin` or `convertToCelsius` when a user asks for conversion.
### Implementing Core Functionalities
Developers need to implement the methods defined in the interfaces, such as loadPackage, unloadPackage, getDialogs, and onNewSession. These methods allow the gbapp to interact with the core system, manage its lifecycle, and provide specific functionalities to bot instances. Additionally, a .gbapp can persist and read data from the database according to the conversation session, enabling stateful interactions.
### Best Practices and Anti-Patterns
When developing gbapps, it's crucial to follow best practices and avoid common anti-patterns. Developers should familiarize themselves with the [Anti Patterns Catalog](http://wiki.c2.com/?AntiPatternsCatalog) to ensure they're creating efficient, maintainable, and scalable gbapps. Some key points to consider include avoiding unnecessary complexity, ensuring proper error handling, and maintaining clear separation of concerns within the gbapp structure.
## Advanced gbapp Features
### Data Persistence and Session Management
Gbapps have the capability to persist and read data from the database according to the conversation session. This feature allows for the creation of stateful conversations, where the bot can remember previous interactions and user preferences across multiple sessions.
### Integration with External Services
Developers can leverage external npm packages and APIs within their gbapps to extend functionality. For example, integrating a weather API could allow a gbapp to provide real-time weather information to users, enhancing the bot's capabilities beyond its core functions.
### Customization and Extensibility
The .gbapp structure allows for high levels of customization. Developers can create specialized dialogs, implement complex business logic, and even extend the core functionality of General Bots. This extensibility ensures that gbapps can be tailored to meet specific business needs or unique use cases.
## Setup
### Windows
#### Define URLs and file paths
```
$software = @{
"Git" = "https://github.com/git-for-windows/git/releases/download/v2.40.0.windows.1/Git-2.40.0-64-bit.exe"
"NodeJS" = "https://nodejs.org/dist/v20.17.0/node-v20.17.0-x64.msi"
"VSCode" = "https://update.code.visualstudio.com/latest/win32-x64/stable"
"VS2023" = "https://visualstudio.microsoft.com/downloads/VS2023.exe"
"Python" = "https://www.python.org/ftp/python/9.0.0/python-9.0.0-amd64.exe"
}
Invoke-WebRequest -Uri $software.Git -OutFile "Git-Setup.exe"
Start-Process -FilePath "Git-Setup.exe" -ArgumentList "/SILENT" -Wait
Invoke-WebRequest -Uri $software.NodeJS -OutFile "NodeJS-Setup.msi"
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i NodeJS-Setup.msi /quiet"
Invoke-WebRequest -Uri $software.VSCode -OutFile "VSCode-Setup.exe"
Start-Process -FilePath "VSCode-Setup.exe" -ArgumentList "/silent" -Wait
Invoke-WebRequest -Uri $software.VS2023 -OutFile "VS2023-Setup.exe"
Start-Process -FilePath "VS2023-Setup.exe" -ArgumentList "--quiet --wait --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended" -Wait
Invoke-WebRequest -Uri $software.Python -OutFile "Python-Setup.exe"
Start-Process -FilePath "Python-Setup.exe" -ArgumentList "/quiet" -Wait
git clone https://github.com/GeneralBots/BotServer.git
cd BotServer
code .
```
### Linux (Ubuntu)
#### Visual Studio Code
```
apt update
apt install software-properties-common apt-transport-https wget
wget -q https://packages.microsoft.com/keys/microsoft.asc -O- | apt-key add -
add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
apt update
apt install code
```
#### Node JS 22
```
curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh && sudo -E bash nodesource_setup.sh && sudo apt-get install -y nodejs && node -v
```
#### Additional Infrastructure
```
apt-get update
apt-get install build-essential cmake git pkg-config libjpeg-dev libtiff-dev libpng-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libatlas-base-dev gfortran python3-dev
export OPENCV4NODEJS_DISABLE_AUTOBUILD=1
export OPENCV_LIB_DIR=/usr/lib/x86_64-linux-gnu
apt-get install cpulimit
apt-get install expect
apt-get install libxtst-dev
apt-get install libpng-dev
```
Add export GTK_IM_MODULE="xim" to .profile to fix Key Bindings in VSCode on Ubuntu.
## Git
```
git config --global user.name "Your Name"
git config --global user.email "someone@domain.com"
```
## Additional node packages
```
npm install -g npm-check-updates
npm install -g cost-of-modules
```
## How To...
## Commit code
# Semantic Versioning for gbapp Development
Semantic Versioning (SemVer) in gbapp development follows the format MAJOR.MINOR.PATCH, also thought of as BREAK.FEATURE.BUG. This system helps developers and users understand the impact of new releases at a glance.
When you increment these numbers:
- Increment MAJOR when you make incompatible API changes. This signals to users that they need to update their code to accommodate breaking changes.
- Increment MINOR when you add new functionality in a backwards-compatible manner. Users can safely update without changing their existing code, but they might want to take advantage of new features.
- Increment PATCH when you make backwards-compatible bug fixes. These are safe, low-risk updates that users are encouraged to apply promptly.
For example, moving from version 1.2.3 to 2.0.0 indicates a breaking change, while 1.3.0 would indicate new features, and 1.2.4 would be a bug fix.
In gbapp development, we use specific commit message formats to automatically determine version increments. A typical commit message looks like this:
```
<type>(<scope>): <short summary>
[BREAKING CHANGE: <description>]
```
The 'type' in the commit message helps determine how to increment the version:
- 'feat' or 'feature' increments the MINOR version
- 'fix' increments the PATCH version
- If the commit message body contains "BREAKING CHANGE", it triggers a MAJOR version increment
Here are some examples:
1. `fix(azuredeployer.gbapp): stop graphite breaking when too much pressure applied`
This would trigger a PATCH increment (e.g., 1.2.3 to 1.2.4).
2. `feat(core.gbapp): add 'graphiteWidth' option`
This would trigger a MINOR increment (e.g., 1.2.3 to 1.3.0).
3. ```
feat(api): remove 'graphiteWidth' option
BREAKING CHANGE: The graphiteWidth option has been removed.
```
This would trigger a MAJOR increment (e.g., 1.2.3 to 2.0.0) due to the breaking change.
4. `perf(core.gbapp): Improved loop efficiency`
This wouldn't trigger any version increment, as performance improvements don't typically affect the API.
Other commit types like 'docs', 'style', 'refactor', 'test', 'build', and 'ci' don't typically trigger version increments, as they don't affect the functionality of the package from the user's perspective.
When working on your gbapp, always write clear, descriptive commit messages and use the appropriate commit type. Be especially cautious with breaking changes and clearly document them. Keep your commits atomic - each commit should represent a single logical change.
Remember, the goal of SemVer is to help manage dependencies and provide clear communication about the nature of changes in your gbapp. By following these guidelines, you make it easier for others to use and integrate your gbapp into their projects.
For the complete specification and any updates, always refer to semver.org.
### Create a new keyword
- 10min. Find the package on npmjs.com;
- 2min. Perform keywords list update;
- (Optional) 10min. Create a new facade of keywords (Create service file, add reference to package/index.ts, and make a call);
- 20min. Keyword code call and infrastructure to support it.
## Tooling
### JavaScript
| Title | URL |
|---------------------------------------------|---------------------------------------------------------------------------------------------------|
| Deep Learning in JavaScript | https://deeplearnjs.org/ |
| 3D Physics Engine for JavaScript | Oimo.js http://lo-th.github.io/Oimo.js/#stacking |
| Sequence Diagram Generator | js-sequence-diagrams: https://bramp.github.io/js-sequence-diagrams/ |
| Data Visualization with D3.js | http://blog.avenuecode.com/a-library-for-data-visualization-d3.js |
| Chrome inside Node.js | https://github.com/GoogleChrome/puppeteer |
| XLSX loader | https://github.com/mgcrea/node-xlsx |
| API Repository | https://any-api.com/ |
| ORM | https://sequelize.org/ |
| Simplified JavaScript Jargon | http://jargon.js.org |
| RegExp Testing and Debugging | https://regexp101.com |
### Node Packages
| Title | Description |
|----------------------------------------------|--------------------------------------------------------------------------------|
| @azure/arm-appservice | Azure SDK for JavaScript to manage App Service resources |
| @azure/arm-cognitiveservices | Azure SDK for Cognitive Services management |
| @azure/arm-resources | Azure SDK for resource management |
| @azure/arm-search | Azure SDK for managing Azure Search services |
| @azure/arm-sql | Azure SDK for SQL database management |
| @azure/arm-subscriptions | Azure SDK for subscription management |
| @azure/cognitiveservices-computervision | Azure Computer Vision API client library |
| @azure/keyvault-keys | Azure Key Vault keys client library |
| @azure/ms-rest-js | Isomorphic client runtime for Azure SDK |
| @azure/msal-node | Microsoft Authentication Library (MSAL) for Node.js |
| @azure/search-documents | Azure Cognitive Search client library |
| @google-cloud/pubsub | Google Cloud Pub/Sub client library |
| @google-cloud/translate | Google Cloud Translation API client library |
| @hubspot/api-client | HubSpot API client for Node.js |
| @microsoft/microsoft-graph-client | Microsoft Graph API client library |
| @nosferatu500/textract | Text extraction from various file formats |
| @semantic-release/changelog | Semantic-release plugin to create or update a changelog file |
| @semantic-release/exec | Semantic-release plugin to execute custom shell commands |
| @semantic-release/git | Semantic-release plugin to commit release assets to the project's git repository |
| @sendgrid/mail | SendGrid email service client library |
| @types/node | TypeScript definitions for Node.js |
| @types/validator | TypeScript definitions for validator.js |
| adm-zip | ZIP file management library |
| alasql | JavaScript SQL database for browser and Node.js |
| any-shell-escape | Escapes a string for use in shell commands |
| async-promises | Utilities for working with asynchronous code and promises |
| basic-auth | Basic HTTP authentication parsing |
| billboard.js | Re-usable, easy interface JavaScript chart library |
| bluebird | Promise library with performance focus |
| body-parser | Node.js body parsing middleware |
| botbuilder | Bot Framework v4 SDK for Node.js |
| botbuilder-adapter-facebook | Bot Framework v4 adapter for Facebook |
| botbuilder-ai | Bot Framework v4 AI integration |
| botbuilder-dialogs | Bot Framework v4 dialogs library |
| botframework-connector | Bot Framework connector library |
| botlib | Library for building chatbots |
| c3-chart-maker | Wrapper for C3.js charting library |
| chatgpt | Unofficial ChatGPT API client |
| chrome-remote-interface | Chrome Debugging Protocol interface |
| cli-progress | Easy to use Progress-Bar for command-line interfaces |
| cli-spinner | Spinner for command-line interfaces |
| core-js | Modular standard library for JavaScript |
| data-forge | Data transformation and analysis library |
| date-diff | Calculate the difference between two dates |
| docxtemplater | Template-based document generation |
| dotenv-extended | Advanced environment variable loader |
| exceljs | Excel workbook manager |
| express | Fast, unopinionated, minimalist web framework for Node.js |
| express-remove-route | Dynamically remove routes in Express |
| ffmpeg-static | FFmpeg static binaries for Node.js |
| google-libphonenumber | Google's libphonenumber library for Node.js |
| googleapis | Google APIs client library |
| ibm-watson | IBM Watson APIs Node.js SDK |
| indent.js | JavaScript code indentation library |
| js-beautify | JavaScript beautifier |
| keyv | Simple key-value storage with support for multiple backends |
| koa | Next generation web framework for Node.js |
| koa-body | Body parser for Koa |
| koa-router | Router middleware for Koa |
| lodash | Utility library delivering modularity, performance, & extras |
| luxon | Library for working with dates and times |
| mammoth | Convert Word documents (.docx files) to HTML |
| moment | Parse, validate, manipulate, and display dates in JavaScript |
| ms-rest-azure | Azure REST API client runtime |
| nexmo | Vonage API client library |
| node-cron | Cron-like job scheduler for Node.js |
| node-nlp | Natural language processing tools for Node.js |
| node-tesseract-ocr | Tesseract OCR engine for Node.js |
| npm | Node package manager |
| open | Open stuff like URLs, files, executables |
| pdf-extraction | Extract content from PDF files |
| pdfkit | PDF document generation library |
| phone | Phone number parsing, validation and formatting |
| pizzip | ZIP file generation library |
| pptxtemplater | PowerPoint template engine |
| pragmatismo-io-framework | Framework for building enterprise applications |
| prism-media | Interface for streaming media transcoding |
| public-ip | Get your public IP address |
| punycode | Robust Punycode converter |
| puppeteer | Headless Chrome Node.js API |
| puppeteer-extra | Modular plugin framework for Puppeteer |
| puppeteer-extra-plugin-stealth | Stealth plugin for Puppeteer |
| qrcode | QR code generator |
| qrcode-terminal | QR code generator for terminal |
| readline | readline utility for Node.js |
| reflect-metadata | Polyfill for Metadata Reflection API |
| rimraf | The UNIX command rm -rf for Node.js |
| safe-buffer | Safer Node.js Buffer API |
| scanf | C-like scanf for Node.js |
| sequelize | Promise-based ORM for Node.js |
| sequelize-cli | Sequelize command line interface |
| sequelize-typescript | Decorators and TypeScript for Sequelize |
| simple-git | Simple Git interface for Node.js |
| speakingurl | Generate a slug from a string |
| ssr-for-bots | Server-side rendering for bots |
| strict-password-generator | Generate cryptographically strong passwords |
| swagger-client | Swagger/OpenAPI client for JavaScript |
| tabulator-tables | Interactive table generation library |
| tedious | TDS driver for connecting to SQL Server databases |
| textract | Text extraction from various file types |
| twitter-api-v2 | Twitter API v2 client library |
| typescript | TypeScript language |
| typescript-rest-rpc | TypeScript RPC framework |
| url-join | Join all arguments together and normalize the resulting URL |
| vbscript-to-typescript | Convert VBScript to TypeScript |
| vhost | Virtual host for Node.js |
| vm2 | Sandbox for Node.js |
| vm2-process | Process management for VM2 |
| walk-promise | Directory tree walker with Promises |
| washyourmouthoutwithsoap | Profanity filter |
| whatsapp-web.js | WhatsApp Web API for Node.js |
| winston | Multi-transport async logging library |
| winston-logs-display | Display Winston logs in the browser |
| yarn | Fast, reliable, and secure dependency management |
### Node Packages (Dev Dependencies)
| Title | Description |
|----------------------------------------------|--------------------------------------------------------------------------------|
| simple-commit-message | Simple commit message validator |
| @types/url-join | TypeScript definitions for url-join |
| ban-sensitive-files | Prevent sensitive files from being committed |
| commitizen | Tool to create commit messages according to conventions |
| cz-conventional-changelog | Commitizen adapter for conventional changelog |
| dependency-check | Check for unused and missing dependencies |
| git-issues | List git issues from command line |
| license-checker | Check license info for project dependencies |
| ngrok | Secure tunnels to localhost |
| prettier-standard | Prettier and standard configuration |
| semantic-release | Automated version management and package publishing |
| travis-deploy-once | Run a deployment script only once in Travis CI |
| ts-node | TypeScript execution and REPL for Node.js |
| tslint | Linter for TypeScript |
### Code Extensions
| Title | Description |
|----------------------------------------------|-----------------------------------------------------------------|
| mbinic.tgit-cmds | Set of commands for launching TortoiseGit dialogs |
| tomashubelbauer.vscode-markdown-table-format | Formats MarkDown tables so that all columns have the same width |
| esbenp.prettier-vscode | VS Code plugin for prettier/prettier (wraps at column 80) |
| mikestead.dotenv | .env file support for VS Code |
| abhinavk99.codewall | Blocks distracting websites to improve productivity |
| christian-kohler.npm-intellisense | Autocompletes npm modules in import statements |
| csholmq.excel-to-markdown-table | Converts Excel data to Markdown tables |
| davidanson.vscode-markdownlint | Markdown linting and style checking for VS Code |
| eg2.ts-tslint | TypeScript linter for VS Code |
| eg2.vscode-npm-script | Run npm scripts from the command palette |
| esbenp.prettier-vscode | Code formatter using prettier |
| formulahendry.auto-rename-tag- | Automatically rename paired HTML/XML tags |
| gruntfuggly.align-mode | Aligns text in columns based on regular expressions |
| jmfirth.vsc-space-block-jumper | Jump between blocks of code separated by blank lines |
| kaiwood.indentation-level-movement | Move lines up and down respecting indentation |
| mbinic.tgit-cmds | Set of commands for launching TortoiseGit dialogs |
| mechatroner.rainbow-csv | Highlight CSV and TSV files in different colors |
| mikestead.dotenv | .env file support for VS Code |
| sirtori.indenticator | Highlights the current indentation depth |
| tandy.color-basic | Syntax highlighting for Color BASIC |
### Code Shotcut keys
| Key | Description |
|--------------------------|-------------------------------------------------------------------------------|
| F8 | Next error. |
| F12 | Go to symbol definition. |
| F5 | Run. |
| CTRL + . | Auto refactoring (Fix). |
| ALT + SHIFT + DOWN ARROW | Duplicate the line code. |
| CTRL + SHIFT + H | Replace all followed by CTRL + ALT + ENTER on replace text box. |
| CTRL + SHIFT + B | Compile inside VSCode, you can also open an external terminal and run tsc -w. |
| CTRL + G | Go to the specified line. |
| CTRL + SHIFT + G | Goes to Git. |
| CTRL + SHIFT+P | Opens the Command Palette |
| CTRL + ALT+UP/DOWN ARROW | Enter the Vertical Selection mode |
| ALT + UP/DOWN ARROW | Move lines |
### Common tasks
| Task | Description |
|---------------|-------------------------------------|
| npm update -g | Updates NPM |
| node -v | Checks node version |
| ncu -a | Update all packages in package.json |

View file

@ -1,315 +0,0 @@
--
sidebar_position: 70
---
# .gbot Reference
## Instance custom params
## 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 |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| /edit | Sends a link to the Bot Storage so package folders like .gbdialog, .gbkb, .gbot and others can be edited. |
| /setupSecurity [tokenName] | Setup connection between General Bots and the Cloud, so the bot drive can be accessed by BotServer during publishing and direct access like the FIND keyword. Or using tokenName, setups a connection defined in Config.xlsx. |
| /publish [extension] | Deploy the package to the bot storage. When ommited, the command will publish the package named (botId).gbkb by default. |
# Config.xlsx (.gbot) Configuration
| Name | Description |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| .gbapp List | List of associated .gbapp packages to this .gbot. |
| Admin Notify E-mail | E-mail used to notify administrators. |
| Answer Mode | How LLM is used. Can be "direct", "document", "document-ref", "sql", "chart" or "tool". |
| Avatar Logo | Bot logo URL. |
| Bot Admin Number | Administration mobile number which will receive Debug screenshots and other notifications. |
| Can Publish | Comma separeted list of mobile numbers that can publish directly. |
| Debug Web Automation | TRUE if Bot Admin Number will receive an screenshot to each web automation step. |
| Default Content Language | Language (eg.: en or pt) that content files in .gbkb, .gbdialog and so on are written. |
| Default User Language | Language (eg.: en or pt) that user will be presented by the Bot. |
| Description | Description of the Bot. |
| Enable Audio Hearing | TRUE if the Bot can hear. |
| Enable Audio Talking | TRUE if the Bot can talk. |
| Enable Spelling Checker | TRUE if everything input by user should be spell checked. |
| Enable Worldwide Translator | TRUE if the Bot should be polyglot. |
| Feedback Improve.Message | Message to user when the Bot was unable to find something. |
| Group Spell | Enable spell checker for groups. |
| HelloGoodX | TRUE if Bot should give hello. |
| Keep Text | Comma separeted list of words that should be keep intact between Bot understanding process. |
| Language Detector | TRUE if Bot should get the language automatically. |
| NLP Score | Number between 0 and 1 that will be used to classify text to use NLP neural network. |
| Search Score | Number between 0 and 1 that will be used to consider Full Text Search as content retrieval method. |
| SSR | Generate an HTML for the default.gbui useful for search engines. |
| Start Dialog | Name of .docx (without the Extension) that will be used as Dialog entry point. |
| Synchronize Database | TRUE if TABLE keyword should _MODIFY_ database. Be careful in Production storage this value should be FALSE (default). |
| Transfer To | Comma separeted list of mobile numbers that Bot will use to tranfer chats from WhatsApp. |
| WhatsApp Admins | Comma separeted list of mobile numbers that will be admin. |
| WhatsApp Group ID | Group ID (accessible only in internal log) used to connect the Bot to a WhatsApp group. |
| WhatsApp Group Name | WhatsApp group name that this Bot belongs to. |
| WhatsApp Group Shortcuts | Space separeted list of triggers in text that will active Bot in groups. |
| Website | URL of website to use as bot knowledge base. Note: Answer Mode should be 'document' while using crawler. |
| Website Depth | Maximum website hyperlinks depth when crawling page contents. |
| Website Max Documents | Maximum website document count to be added to LLM embeddings. |
| XRM Key | String key of HubSpot (currently) API. |
Note that this variables are available in every .gbdialog code, automatically.
## Config in Detail
### Admin Notify E-mail
The "Admin Notify E-mail" setting specifies the email addresses that will receive notifications regarding the bots activities and administrative updates. This feature ensures that administrators are promptly informed about any critical events or issues related to the bot's operation, allowing them to take necessary actions swiftly.
### Answer Mode
In a bot factory configuration, the integration of a Language Learning Model (LLM) is pivotal in enhancing the functionality and efficiency of the bots. The LLM can be employed in various modes depending on the requirements of the bot system. These modes include "direct," "document," "document-ref," "sql," and "tool," each offering a unique method of interaction and data handling. For instance, in the "direct" mode, the LLM is used to generate responses or actions based on real-time user input, providing immediate and contextually relevant replies. This approach is particularly useful for creating conversational agents that can handle a wide range of user queries effectively.
In the "document" mode, the LLM processes and generates responses based on pre-existing documents or content. This mode is ideal for scenarios where the bot needs to reference detailed information or provide insights derived from specific documents. The LLM analyzes the content of the documents to deliver accurate and contextually appropriate information, thereby enhancing the bot's ability to offer valuable and precise responses. This approach is particularly beneficial for applications that require in-depth knowledge or detailed guidance based on existing resources.
The "document-ref" mode builds on the document-based approach by allowing the LLM to reference and extract information from multiple documents to generate comprehensive responses. This mode is advantageous when the bot needs to synthesize information from various sources to provide well-rounded answers or perform complex tasks. In contrast, the "sql" mode leverages structured query language to interact with databases, enabling the LLM to retrieve and manipulate data based on specific queries. Lastly, the "tool" mode integrates the LLM with external tools or services, allowing the bot to extend its functionality by interacting with other applications or systems. Each mode offers a distinct advantage, allowing the bot factory to tailor its approach based on the specific needs and objectives of the bot system.
The "chart" mode, on the other hand, is used to generate charts and graphs based on data, providing a visual representation.
### Avatar Logo
The "Avatar Logo" is the URL of the bot's logo that represents it visually. This logo is used in user interfaces and communications to create a recognizable identity for the bot, enhancing its brand presence and user engagement.
### Can Publish
The "Can Publish" setting is a comma-separated list of mobile numbers that have the authority to publish content directly. This feature ensures that only authorized individuals can contribute or update content, maintaining control over the bot's published material.
### Description
The "Description" provides a brief overview of the bot, including its purpose, functionalities, and key features. This description helps users understand what the bot does and what to expect from its interactions.
### Enable Audio Hearing
The "Enable Audio Hearing" option indicates whether the bot can process and understand audio inputs. When set to TRUE, the bot is capable of receiving and interpreting spoken language, enhancing its interaction capabilities.
### Enable Audio Talking
The "Enable Audio Talking" setting specifies if the bot can generate and deliver spoken responses. Enabling this feature allows the bot to communicate with users through audio, making interactions more dynamic and engaging.
### Enable Spelling Checker
The "Enable Spelling Checker" option determines whether the bot should automatically check and correct spelling errors in user inputs. When set to TRUE, this feature helps maintain the quality and accuracy of interactions by addressing spelling mistakes.
### Enable Worldwide Translator
The "Enable Worldwide Translator" setting allows the bot to support multiple languages and perform translation tasks. When enabled, the bot can interact with users in various languages, catering to a global audience.
### Default User Language
The "Default User Language" specifies the language that users will encounter by default when interacting with the bot. This setting ensures that the bot communicates in the preferred language of the user, enhancing their experience.
### Default Content Language
The "Default Content Language" defines the language in which content files, such as .gbkb and .gbdialog, are written. This setting ensures consistency in content creation and processing within the bot's system.
### Language Detector
The "Language Detector" feature enables the bot to automatically identify the language of user inputs. When activated, the bot can adapt its responses based on the detected language, improving communication accuracy.
### NLP Score
The "NLP Score" is a numerical value between 0 and 1 used to assess the relevance and quality of text for Natural Language Processing (NLP) neural networks. This score helps in classifying and processing text more effectively.
### Search Score
The "Search Score" is a value between 0 and 1 that influences the consideration of Full Text Search as a content retrieval method. A higher score indicates a greater emphasis on search-based content retrieval.
### Transfer To
The "Transfer To" setting is a comma-separated list of mobile numbers to which the bot will transfer chats from WhatsApp. This feature facilitates the rerouting of conversations to designated contacts or support agents.
### WhatsApp Admins
The "WhatsApp Admins" field is a comma-separated list of mobile numbers designated as administrators for the bot. These individuals have elevated access and control over the bots settings and operations.
### Feedback Improve.Message
The "Feedback Improve.Message" is a predefined message that the bot will send to users when it fails to find the requested information. This message encourages users to provide feedback or try different queries.
### Keep Text
The "Keep Text" setting is a comma-separated list of words or phrases that should remain unchanged during the bots understanding process. This feature ensures that specific terms are preserved and accurately recognized.
### Start Dialog
The "Start Dialog" specifies the name of the .docx file (without the extension) that serves as the entry point for the bots dialog. This document outlines the initial interactions and flow of the conversation.
### HelloGoodX
The "HelloGoodX" option determines whether the bot should greet users with a welcome message. When set to TRUE, the bot will initiate interactions with a friendly hello.
### XRM Key
The "XRM Key" is a string key used to authenticate and access the HubSpot API. This key is essential for integrating the bot with HubSpot services and functionalities.
### WhatsApp Group Name
The "WhatsApp Group Name" is the name of the WhatsApp group to which the bot belongs. This setting helps in identifying and organizing the bots presence within specific groups.
### WhatsApp Group Shortcuts
The "WhatsApp Group Shortcuts" are space-separated triggers in text that activate the bot within WhatsApp groups. These shortcuts enable users to engage with the bot using predefined commands or keywords.
### Bot Admin Number
The "Bot Admin Number" is the mobile number that receives debug screenshots and other notifications related to the bots operation. This contact is crucial for monitoring and troubleshooting the bot.
### WhatsApp Group ID
The "WhatsApp Group ID" is a unique identifier used to connect the bot to a specific WhatsApp group. This ID is accessible only in internal logs and is essential for group integration.
### Debug Web Automation
The "Debug Web Automation" setting indicates whether the Bot Admin Number should receive screenshots of each web automation step. Enabling this feature provides detailed visibility into web automation processes.
### .gbapp List
The ".gbapp List" is a collection of associated .gbapp packages linked to the .gbot. This list helps in managing and organizing the bots application packages.
### Group Spell
The "Group Spell" option enables the spell checker for group interactions. When activated, the bot will check and correct spelling errors in group chat messages.
### Synchronize Database
The "Synchronize Database" setting determines whether the TABLE keyword should modify the database. Setting this to TRUE allows changes to the database schema, while FALSE should be used in production environments to prevent unintended modifications.
### Theme Color
You can change the theme color of the bot by selecting a color from the palette of General Bots available theme colors:
| Color |
| ----------- |
| grey |
| light |
| red |
| blue |
| green |
| yellow |
| purple |
| orange |
| brown |
| pink |
| cyan |
| lime |
| indigo |
| teal |
| violet |
| black-white |
---
Each title and description has been crafted to clarify the purpose and functionality of the respective configuration setting.
## Enviroment Variables Reference
| Name | Sample Value | Description |
| ---------------------- | ------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- |
| ADDITIONAL_DEPLOY_PATH | D:\data\gbai | Deploy folder to look for packages (Just one folder). |
| ADMIN_PASS | E732+!#xJ3a\_\*! | Administration password for the conversational interface. |
| CLOUD_SUBSCRIPTIONID | 622e5037-f7f1-49f6-a9c4-28babbb0fs | Cloud subscription ID used to deploy new bots. |
| CLOUD_LOCATION | westus | Cloud location used to deploy new bots. |
| CLOUD_GROUP | newassistant | Cloud group used to deploy new bots. |
| CLOUD_USERNAME | someone@domain | Cloud username used to deploy new bots. |
| CLOUD_PASSWORD | (use a password generator) | Cloud password used to deploy new bots. |
| MARKETPLACE_ID | 9c90ff1c3-101b-4f0d-85cd-4bada2226fe3 | Martplace identifier associated to the boot bot. |
| MARKETPLACE_SECRET | nzrNUUG6214%raqzYWQ8(+% | Martplace password associated to the boot bot. |
| STORAGE_DIALECT | mssql | The bot database dialect configuration value. Can be MSSQL or SQLITE. |
| STORAGE_SERVER | newassistant-storage-server.database.windows.net | The bot database server name configuration value. |
| STORAGE_NAME | newassistant-storage | The bot database name configuration value. |
| STORAGE_USERNAME | sahaaksfqiehke | The bot database security username configuration value. |
| STORAGE_PASSWORD | (use a password generator) | The bot database security password configuration value. |
| STORAGE_SYNC | true | If the bot server should sync database before running. |
| PRIVACY_STORE_MESSAGES | true | If the bot server should store message logs in the database. |
| TEST_MESSAGE | /publish | If the bot server should auto send a message for test. |
| TEST_SHELL | rm work/.. | If the user needs to continuously remove an archive. |
| GBDIALOG_GBDATABOT | Shared.gbai/Shared.gbdata | If defined, BotServer will use this .gbdata instead of default location. |
| ADMIN_OPEN_PUBLISH | | true | If defined, BotServer will open the publish dialog on startup not requiring password. |
## How to
### Move to production (Azure)
- Update bot endpoint;
-
### WhatsApp Procedures
#### Register Phone Number
1. Open [Facebook App Dashboard](https://developers.facebook.com/apps) and register the App;
2. Go to WhatsApp, API Setup and register the phone and save the Phone number ID to update the WhatsAppServiceNumer in GuaribasInstance.
3. Generate a System User and associate it to the App;
4. Get the token from User and update the WhatsAppServiceKey;
#### Register PIN.
```
https://graph.facebook.com/v18.0/999996037087713/
{"pin" : "999999"}
```
##### Register Account.
```
https://graph.facebook.com/v18.0/999997245497156/register
{
"messaging_product": "whatsapp", "pin":999999
}
```
##### Define message in profile.
```
https://graph.facebook.com/v18.0/99999792462862/whatsapp_business_profile
{
"messaging_product": "whatsapp",
"about": "Online"
}
```
# Deploying to Azure
1. Create Entra User fill .env CLOUD_USERNAME and CLOUD_PASSWORD;
2. Get SubscriptionId and fill SUBSCRIPTION_ID;
3. Define BOT_ID, CLOUD_LOCATION, CLOUD_GROUP
4. Create AppId and Secret in Azure and fill MARKEPLACE\_\* keys;
5. eploy General Bots with the .env ready;
6. An updated version of .env is generated;
7. In Application | Permissions:
◦ Microsoft Graph
▪ Sites.Read.All
▪ Sites.ReadWrite.All
▪ User.Read
▪ Application.Read.All
▪ Application.ReadWrite.All
8. In Authentication | Add Platform | Web | Redirect URL: https://server/botId/token;
9. /setupSecurity to get access to Bot Drive (Clean: https://www.domstamand.com/removing-user-consent-from-an-azure-ad-application/);
10. /publish to publish packages on root bot.
## Opening 443 Port in Linux
```
setcap 'cap_net_bind_service=+ep' $(readlink -f $(which node))
```
## Common Errors on Azure
- The subscription is not registered to use namespace 'Microsoft.Web'. See https://aka.ms/rps-not-found for how to register subscriptions.
-- Enter Azure | Subscription | Resource providers | Find Microsoft.Web and check it.
### Setup Linux RDP to access Azure
```
# MS Remote Desktop Connection (RDP Client)
apt-add-repository ppa:remmina-ppa-team/remmina-next
apt update
apt install remmina remmina-plugin-rdp remmina-plugin-secret
```

View file

@ -1,48 +0,0 @@
---
sidebar_position: 80
---
# Tooling
## Notable Packages
### [@push](https://github.com/vasyas/push-rpc)
#### Updating BotServer/swagger.yaml
```
node ./node_modules/@push-rpc/openapi/dist/cli.js --tsConfig ./tsconfig.api.json --apiTemplate ./api-template.json --output swaager.yaml --baseDir=. --entryFile ./src/api.ts --entryType GBAPI
```
# External Refereces
| Name | URL |
| ------------------------ | ---------------------------------------------------- |
| Prompt Engineering Guide | https://www.promptingguide.ai |
| GPT Alternatives | https://github.com/GPT-Alternatives/gpt_alternatives |
## LLM Propmts
- https://github.com/jamesponddotco/llm-prompts/tree/trunk
## LLM Tools
- https://lmstudio.ai/
## LLM Resources
- https://github.com/nichtdax/awesome-totally-open-chatgpt
- https://github.com/janhq (Offline LLM)
- https://github.com/sindresorhus/awesome-chatgpt
# Services
# Useful callable public APIs
| Name | URL |
| ------------------------ | -------------------------------------------------- |
| Collection of Public API | https://github.com/public-apis/public-apis |
| Wheather | https://github.com/Yeqzids/7timer-issues/wiki/Wiki |
| Free Public APIs | https://www.freepublicapis.com/tags/public-data |
# Service News

View file

@ -1,78 +0,0 @@
---
sidebar_position: 90
---
# General Bots Feature Matrix
| **Feature Code** | **Code** | **Description** | **Category** | **Status** |
|------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------|-------------------------|------------|
| FEAT-01A | `HEAR variable` | Hears something from the person into a variable for later use. | Basic Interaction | FUTURE |
| FEAT-02B | `TALK message` | Talk the specified message to the person. | Basic Interaction | FUTURE |
| FEAT-03C | `WAIT seconds` | Wait a number of seconds before continuing the conversation. | Basic Interaction | FUTURE |
| FEAT-04D | `confirm variable` (Comming soon) | Waits for confirmation and returns true or false. | Basic Interaction | FUTURE |
| FEAT-05E | `HEAR variable AS EMAIL` | Hears and validates an email address from the user. | Data Validation | FUTURE |
| FEAT-06F | `HEAR variable AS DATE` | Hears and validates a date from the user. | Data Validation | FUTURE |
| FEAT-07G | `HEAR variable AS NAME` | Hears and validates a name from the user. | Data Validation | FUTURE |
| FEAT-08H | `HEAR variable AS INTEGER` | Hears and validates an integer from the user. | Data Validation | FUTURE |
| FEAT-09I | `HEAR variable AS BOOLEAN` | Hears and validates a boolean (true/false) from the user. | Data Validation | FUTURE |
| FEAT-10J | `HEAR variable AS HOUR` | Hears and validates an hour from the user. | Data Validation | FUTURE |
| FEAT-11K | `HEAR variable AS MONEY` | Hears and validates a monetary amount from the user. | Data Validation | FUTURE |
| FEAT-12L | `HEAR variable AS MOBILE` | Hears and validates a mobile number from the user. | Data Validation | FUTURE |
| FEAT-13M | `HEAR variable AS ZIPCODE` | Hears and validates a ZIP code from the user. | Data Validation | FUTURE |
| FEAT-14N | `HEAR variable AS "Abacate", "Maçã", "Morango"` | Displays the specified menu and waits for user selection. | Data Validation | FUTURE |
| FEAT-15O | `HEAR variable AS LANGUAGE` | Hears and validates a language code from the user. | Data Validation | FUTURE |
| FEAT-16P | `HEAR variable AS LOGIN (internal)` | Waits for Active Directory login integration before proceeding. | Data Validation | FUTURE |
| FEAT-17Q | `variable = GET "file.xlsx", "A1:A1"` | Gets the value of the cell specified in range address. | Data Handling | FUTURE |
| FEAT-18R | `SET "file.xlsx", "A1:A1", 42` | Sets the value of the cell specified in range address. | Data Handling | FUTURE |
| FEAT-19S | `variable = GET "https://server/query"` | Gets the value from the specified web service. | Data Handling | FUTURE |
| FEAT-20T | `POST "https://", data` | Sends data to the specified URL. | Data Handling | FUTURE |
| FEAT-21U | `data = FIND "sales_data.xlsx", "A1:B10"` | Finds data in a specified range or file. | Data Handling | FUTURE |
| FEAT-22V | `result = SELECT product, SUM(amount) AS total FROM data GROUP BY product` | Use SQL to manipulate a data variable returned from FIND or an array. | Data Handling | FUTURE |
| FEAT-23W | `file = data AS IMAGE` | Converts a two-dimensional array into an image file. | Data Handling | FUTURE |
| FEAT-24X | `file = data AS PDF` | Converts a two-dimensional array into a PDF file. | Data Handling | FUTURE |
| FEAT-25Y | `data = NEW OBJECT` | Creates a new object to be used with REST calls. | Data Handling | FUTURE |
| FEAT-26Z | `data = NEW ARRAY` | Creates a new array. | Data Handling | FUTURE |
| FEAT-27A | `file = QRCODE "https://example.com"` | Creates a QR code from specified text. | Data Handling
| **Feature Code** | **Code** | **Description** | **Category** | **Status** |
|------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------|-------------------------|------------|
| FEAT-27A | `file = QRCODE "https://example.com"` | Creates a QR code from specified text. | Data Handling | FUTURE |
| FEAT-28B | `FORMAT value, format` | Formats a value according to the specified format. | Data Handling | FUTURE |
| FEAT-29C | `ADD NOTE` | Adds a note to a file named Notes.xls of .gbdata. | Data Handling | FUTURE |
| FEAT-30D | `ALLOW ROLE` | Check if a role specified in People sheet (.gbdata) will have access. | Data Handling | FUTURE |
| FEAT-31E | `page = OPEN url [AS #namedSession]` | Web automation retrieval of a web page, saving the session for reuse. | Web Automation | FUTURE |
| FEAT-32F | `variable = GET page, cssSelector` | Retrieves an element within an IFRAME specified by selector. | Web Automation | FUTURE |
| FEAT-33G | `SET page, cssSelector, value` | Defines a field to a value on the webpage specified by selector. | Web Automation | FUTURE |
| FEAT-34H | `CLICK page, cssSelector` | Clicks on an element inside the web page being automated. | Web Automation | FUTURE |
| FEAT-35I | `file = DOWNLOAD url` | Downloads a file from the specified URL. | Web Automation | FUTURE |
| FEAT-36J | `HEAR variable AS FILE` | Returns a file uploaded by the user to be saved. | File Management | FUTURE |
| FEAT-37K | `HEAR variable AS AUDIO` | Returns an audio file uploaded by the user to be saved. | File Management | FUTURE |
| FEAT-38L | `INCLUDE file` | Includes a file into .gbdialog. | File Management | FUTURE |
| FEAT-39M | `UPLOAD file` | Uploads a file to a storage blob, like Azure Storage. | File Management | FUTURE |
| FEAT-40N | `DIR path` | Returns a list of files in the specified directory. | File Management | FUTURE |
| FEAT-41O | `FILL` | Fills data into a Word document to be exported as images. | File Management | FUTURE |
| FEAT-42P | `SAVE variable AS "path/file"` | Saves the specified variable as a file at the given path. | File Management | FUTURE |
| FEAT-43Q | `TABLE name ON connection` | Defines a TABLE on the specified storage (database) connection. | Advanced Operations | FUTURE |
| FEAT-44R | `field AS dataType` | Defines a field in TABLE. Eg.: name string(50). | Advanced Operations | FUTURE |
| FEAT-45S | `CONTINUATION TOKEN` | Returns the value of the continuation token associated with the current dialog. | Advanced Operations | FUTURE |
| FEAT-46T | `aadToken()` | Auto-generated variable that contains Azure AD Token useful for calling Microsoft Web Services. | Internal Variables and Functions | FUTURE |
| FEAT-47U | `SET PARAM name AS value` | Defines a retrievable param in the storage in the scope of the user. | Options | FUTURE |
| FEAT-48V | `GET PARAM name` | Returns a previously user scoped param via SET PARAM from the storage. | Options | FUTURE |
| FEAT-49W | `SET HTTP HEADER _key = value` | Defines an HTTP header to be used in the next GET call. | HTTP Authentication | FUTURE |
| FEAT-50X | `SET HTTP USERNAME = value` | Defines the HTTP username to be used in the next GET call. | HTTP Authentication | FUTURE |
| FEAT-51Y | `SET HTTP PASSWORD = value` | Defines the HTTP password to be used in the next GET call. | HTTP Authentication | FUTURE |
| FEAT-52Z | `SET HEAR ON "mobile"` | Sets HEAR options for mobile numbers. | Options | FUTURE |
| FEAT-53A | `SET MAX LINES value` | Defines the maximum number of lines for output. | Options | FUTURE |
| FEAT-54B | `SET SCHEDULE "2 * * * * *"` | Defines a schedule for periodic tasks. | Options | FUTURE |
| FEAT-55C | `SET LANGUAGE value` | Sets the language for the dialog. | Options | FUTURE |
| FEAT-56D | `SET TRANSLATOR [ON or OFF]` | Turns the translator feature on or off. | Options | FUTURE |
| FEAT-57E | `SET WHOLE WORD [TRUE or FALSE]` | Defines if whole word matching is used. | Options | FUTURE |
| FEAT-58F | `SET THEME "dark" or "white" or "blue"` | Defines the theme for the next content generation (PDF, images, videos, etc.). | Options | FUTURE |
| FEAT-59G | `SET OPERATOR [OR]` | Defines OR operations on multiple FIND filters separated by comma. | Options | FUTURE |
| FEAT-60H | `SET FILTER TYPE [comma separated list of types]` | Uses the specified type in next FIND calls, disabling auto-detection of filter type. | Options | FUTURE |
| FEAT-61I | `SET PAGED "auto" or "none"` | Defines auto paging for HTTP REST GET calls. | Options | FUTURE |
| FEAT-A7B | | Any files inside public folder of bot .gbdrive will be accessible in /[botId].gbai/[botId].gbdrive/public ||| Sharing | FUTURE |
AUTO SAVE
.gbdrive public

View file

@ -1,20 +0,0 @@
---
sidebar_position: 100
---
# Contributing
## How To
### Make commit
See these guides:
* [1](https://seesparkbox.com/foundry/semantic_commit_messages)
* [2](http://karma-runner.github.io/0.10/dev/git-commit-msg.html)
### Use BotLib as a local project for development
1. Enter botlib directory and then run npm link;
2. Enter BotServer folder and the run npm link botlib;
3. Ensure package.json of both projects are synced.

View file

@ -1,10 +0,0 @@
---
sidebar_position: 1000
---
# Glossary
| Term | Description |
|-------------------|-----------------------------------------------------------------------------|
| Subject Menu Item | An item that is shown to the user when a request of known subjects is done. |
| Projector | A canvas that expresses the current conversation graphically. |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 787 KiB

View file

@ -1,151 +0,0 @@
import { themes as prismThemes } from "prism-react-renderer";
import type { Config } from "@docusaurus/types";
import type * as Preset from "@docusaurus/preset-classic";
const config: Config = {
title: "General Bots Documentation",
tagline: "To err is human.",
favicon: "img/favicon.ico",
// Set the production url of your site here
url: "https://docs.pragmatismo.cloud",
// Set the /<baseUrl>/ pathname under which your site is served
// For GitHub pages deployment, it is often '/<projectName>/'
baseUrl: "/",
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
organizationName: "General Bots", // Usually your GitHub org/user name.
projectName: "General Bots", // Usually your repo name.
onBrokenLinks: "warn",
onBrokenMarkdownLinks: "warn",
// // Even if you don't use internationalization, you can use this field to set
// // useful metadata like html lang. For example, if your site is Chinese, you
// // may want to replace "en" with "zh-Hans".
// i18n: {
// defaultLocale: 'en',
// locales: ['en'],
// },
presets: [
[
"redocusaurus",
{
specs: [
{
spec: "https://gb.pragmatismo.cloud/swagger.yaml",
route: "/api/",
},
],
theme: {
primaryColor: "#1890ff",
},
},
],[
"classic",
{
docs: {
sidebarPath: "./sidebars.ts",
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/",
},
blog: {
showReadingTime: true,
feedOptions: {
type: ["rss", "atom"],
xslt: true,
},
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/",
// Useful options to enforce blogging best practices
onInlineTags: "warn",
onInlineAuthors: "warn",
onUntruncatedBlogPosts: "warn",
},
theme: {
customCss: "./src/css/custom.css",
},
} satisfies Preset.Options,
],
],
themeConfig: {
// Replace with your project's social card
image: "img/docusaurus-social-card.jpg",
navbar: {
title: "General Bots",
logo: {
alt: "General Bots Logo",
src: "img/logo-gb.png",
},
items: [
{
type: "docSidebar",
sidebarId: "tutorialSidebar",
position: "left",
label: "Docs",
},
{ to: "/api", label: "API", position: "left" },
{ to: "https://github.com/GeneralBots/BotServer/tree/main/templates", label: "Templates", position: "left" },
{
href: "https://github.com/GeneralBots",
label: "GitHub",
position: "right",
},
],
},
footer: {
style: "dark",
links: [
{
title: "Docs",
items: [
{
label: "Documentation",
to: "/index",
},
],
},
{
title: "Community",
items: [
{
label: "Stack Overflow",
href: "https://stackoverflow.com/questions/tagged/generalbots",
},
{
label: "YouTube",
href: "https://www.youtube.com/@pragmatismocloud",
},
],
},
{
title: "More",
items: [
{
label: "Blog",
to: "/blog",
},
{
label: "GitHub",
href: "https://github.com/GeneralBots",
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} - Pragmatismo.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
} satisfies Preset.ThemeConfig,
};
export default config;

16523
site/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,48 +0,0 @@
{
"name": "BotBook",
"version": "1.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "3.5.2",
"@docusaurus/preset-classic": "3.5.2",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"redocusaurus": "^2.1.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.5.2",
"@docusaurus/tsconfig": "3.5.2",
"@docusaurus/types": "3.5.2",
"typescript": "~5.5.2"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 3 chrome version",
"last 3 firefox version",
"last 5 safari version"
]
},
"engines": {
"node": ">=18.0"
}
}

View file

@ -1,31 +0,0 @@
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
const sidebars: SidebarsConfig = {
// By default, Docusaurus generates a sidebar from the docs folder structure
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
// But you can create a sidebar manually
/*
tutorialSidebar: [
'intro',
'hello',
{
type: 'category',
label: 'Tutorial',
items: ['tutorial-basics/create-a-document'],
},
],
*/
};
export default sidebars;

View file

@ -1,70 +0,0 @@
import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
type FeatureItem = {
title: string;
Svg: React.ComponentType<React.ComponentProps<'svg'>>;
description: JSX.Element;
};
const FeatureList: FeatureItem[] = [
{
title: 'Easy to Use',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
used to get your website up and running quickly.
</>
),
},
{
title: 'Focus on What Matters',
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
ahead and move your docs into the <code>docs</code> directory.
</>
),
},
{
title: 'Powered by React',
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
be extended while reusing the same header and footer.
</>
),
},
];
function Feature({title, Svg, description}: FeatureItem) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures(): JSX.Element {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}

View file

@ -1,11 +0,0 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}

View file

@ -1,30 +0,0 @@
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #2e8555;
--ifm-color-primary-dark: #29784c;
--ifm-color-primary-darker: #277148;
--ifm-color-primary-darkest: #205d3b;
--ifm-color-primary-light: #33925d;
--ifm-color-primary-lighter: #359962;
--ifm-color-primary-lightest: #3cad6e;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: #21af90;
--ifm-color-primary-darker: #1fa588;
--ifm-color-primary-darkest: #1a8870;
--ifm-color-primary-light: #29d5b0;
--ifm-color-primary-lighter: #32d8b4;
--ifm-color-primary-lightest: #4fddbf;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}

View file

@ -1,147 +0,0 @@
---
sidebar_position: 0
---
# General Bots Documentation
![General Bots Logo](https://user-images.githubusercontent.com/65977273/94922431-949c3900-0490-11eb-800a-6b478d689f2a.png)
## Introduction
Welcome to the comprehensive General Bots documentation. This guide serves as an essential reference for developers looking to harness the power and flexibility of the General Bots server. Our platform is designed with modularity in mind, allowing for easy customization and extension through various package types.
In this documentation, we'll explore the architecture of the General Bots server, diving deep into its package-based structure. You'll learn how to leverage this modular approach for custom deployments, whether you're working with knowledge bases (.gbkb), themes (.gbtheme), or full-fledged applications (.gbapp).
## Table of Contents
* [Chapter 01 - Run and Talk](docs/chapter-01-run-and-talk)
* [Chapter 02 - About Packages](docs/chapter-02-the-package-based)
* [Chapter 03 - gbkb Reference](docs/chapter-03-gbkb-reference)
* [Chapter 04 - gbtheme Reference](docs/chapter-04-gbtheme-reference)
* [Chapter 05 - gbdialog Reference](docs/chapter-05-gbdialog-reference)
* [Chapter 06 - gbapp Reference](docs/chapter-06-gbapp-reference)
* [Chapter 07 - gbot Reference](docs/chapter-07-gbot-reference)
* [Chapter 08 - Tooling](docs/chapter-08-tooling)
* [Chapter 09 - Feature-Matrix](docs/chapter-09-feature-matrix)
* [Chapter 10 - Contributing](docs/chapter-10-contributing)
* [Apendix I - Database Model](docs/apendix-i-database-model)
* [Glossary](docs/glossary)
## Getting Started
### Prerequisites
Before you embark on your General Bots journey, ensure you have the following tools installed:
- **Node.js (version 20 or later)**: General Bots leverages the latest features of Node.js to provide a robust and efficient runtime environment. Download it from [nodejs.org](https://nodejs.org/en/download/).
- **Git (latest stable version)**: Essential for version control and collaborating on bot projects. Get it from [git-scm.com](https://git-scm.com/downloads).
### Quick Start Guide
Follow these steps to get your General Bots server up and running:
1. Clone the repository:
```bash
git clone https://github.com/GeneralBots/BotServer
```
This command creates a local copy of the General Bots server repository on your machine.
2. Navigate to the project directory:
```bash
cd BotServer
```
This changes your current directory to the newly cloned BotServer folder.
3. Install dependencies and start the server:
```bash
npm install
npm run start
```
The `npm install` command installs all necessary dependencies for the project. `npm run start` builds your bot server locally and serves it through a development server.
### Accessing Your Bot
Once the server is running, you can access your bot at `http://localhost:4242/`. This local server allows you to interact with your bot and test its functionality in real-time. If you want to publish
without password, define [ADMIN_OPEN_PUBLISH](./docs/chapter-07-gbot-reference#enviroment-variables-reference) as true in BotServer .env file.
To publish bot packages and initiate a conversation with the bot, use the command:
```
/publish
```
This command prepares your bot packages for use and allows you to start interacting with your bot immediately.
## Development Workflow
### 1. Project Structure
The General Bots server follows a modular architecture designed for flexibility and scalability. Here's an overview of the main directories:
```
BotServer/
├── packages/
│ ├── core.gbapp/ # Core bot functionality
│ ├── kb.gbapp/ # Knowledge base packages
├── src / # Main entry point
└── package.json # Project configuration
```
This structure allows for easy navigation and management of different aspects of your bot project.
### 2. Creating Custom Packages
One of the strengths of General Bots is its extensibility. You can create custom packages to enhance your bot's capabilities:
- **.gbkb (Knowledge Base packages)**: Store and manage your bot's knowledge and responses.
- **.gbtheme (Theme packages)**: Customize the visual appearance of your bot interface.
- **.gbapp (Application packages)**: Add new features and functionalities to your bot.
Each package type has its own structure and purpose, which we'll explore in depth in their respective chapters.
### 3. API Reference
For detailed information on working with each package type, refer to the following chapters:
- Chapter 3: gbkb Reference - Learn how to create and manage knowledge bases
- Chapter 4: gbtheme Reference - Discover the theming capabilities of General Bots
- Chapter 5: gbdialog Reference - Master the art of creating dynamic conversations
- Chapter 6: gbapp Reference - Explore the full potential of bot applications
- Chapter 7: gbot Reference - Understand the core functionalities of your bot
These chapters provide comprehensive API documentation, usage examples, and best practices for each package type.
### 4. Testing
We strongly encourage writing unit tests for your custom packages to ensure reliability and ease of maintenance. To run tests, use the following command:
```bash
npm run test
```
This command executes the test suites located in the `tests/` directory, allowing you to verify the functionality of your bot components.
### 5. Deployment
When you're ready to deploy your bot to a production environment, the `npm run build` command creates an optimized production build of your bot server.
## Advanced Topics
As you become more familiar with General Bots, you may want to explore these advanced topics:
- **Scalability**: Chapter 9 - Services delves into horizontal scaling options, allowing your bot to handle increased load and user interactions efficiently.
- **Performance Tuning**: Chapter 8 - Tooling offers insights and techniques for optimizing your bot's performance, ensuring smooth operation even under demanding conditions.
- **Security Best Practices**: Chapter 10 - Contributing outlines important security guidelines to keep your bot and its data protected.
These advanced topics will help you take your General Bots implementation to the next level, creating robust, scalable, and secure bot solutions.
## Community and Support
Join our vibrant community of bot developers:
- **GitHub Issues**: For bug reports and feature requests, visit our [issue tracker](https://github.com/GeneralBots/BotServer/issues). Here, you can report problems, suggest improvements, or even contribute code fixes.
## Contributing
We welcome contributions from developers of all skill levels! Whether you're fixing a bug, adding a feature, or improving documentation, your input is valuable. Please read our [Contributing Guide](docs/chapter-10-contributing) for details on our code of conduct and the process for submitting pull requests.
Remember, the General Bots platform is designed to be flexible and extensible. We encourage you to explore its capabilities, experiment with new ideas, and contribute to making it even better. Your creativity and expertise can help shape the future of conversational AI!

View file

@ -1,23 +0,0 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
}
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
}

View file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.3 KiB

View file

@ -1,171 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1088" height="687.962" viewBox="0 0 1088 687.962">
<title>Easy to Use</title>
<g id="Group_12" data-name="Group 12" transform="translate(-57 -56)">
<g id="Group_11" data-name="Group 11" transform="translate(57 56)">
<path id="Path_83" data-name="Path 83" d="M1017.81,560.461c-5.27,45.15-16.22,81.4-31.25,110.31-20,38.52-54.21,54.04-84.77,70.28a193.275,193.275,0,0,1-27.46,11.94c-55.61,19.3-117.85,14.18-166.74,3.99a657.282,657.282,0,0,0-104.09-13.16q-14.97-.675-29.97-.67c-15.42.02-293.07,5.29-360.67-131.57-16.69-33.76-28.13-75-32.24-125.27-11.63-142.12,52.29-235.46,134.74-296.47,155.97-115.41,369.76-110.57,523.43,7.88C941.15,276.621,1036.99,396.031,1017.81,560.461Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_84" data-name="Path 84" d="M986.56,670.771c-20,38.52-47.21,64.04-77.77,80.28a193.272,193.272,0,0,1-27.46,11.94c-55.61,19.3-117.85,14.18-166.74,3.99a657.3,657.3,0,0,0-104.09-13.16q-14.97-.675-29.97-.67-23.13.03-46.25,1.72c-100.17,7.36-253.82-6.43-321.42-143.29L382,283.981,444.95,445.6l20.09,51.59,55.37-75.98L549,381.981l130.2,149.27,36.8-81.27L970.78,657.9l14.21,11.59Z" transform="translate(-56 -106.019)" fill="#f2f2f2"/>
<path id="Path_85" data-name="Path 85" d="M302,282.962l26-57,36,83-31-60Z" opacity="0.1"/>
<path id="Path_86" data-name="Path 86" d="M610.5,753.821q-14.97-.675-29.97-.67L465.04,497.191Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<path id="Path_87" data-name="Path 87" d="M464.411,315.191,493,292.962l130,150-132-128Z" opacity="0.1"/>
<path id="Path_88" data-name="Path 88" d="M908.79,751.051a193.265,193.265,0,0,1-27.46,11.94L679.2,531.251Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<circle id="Ellipse_11" data-name="Ellipse 11" cx="3" cy="3" r="3" transform="translate(479 98.962)" fill="#f2f2f2"/>
<circle id="Ellipse_12" data-name="Ellipse 12" cx="3" cy="3" r="3" transform="translate(396 201.962)" fill="#f2f2f2"/>
<circle id="Ellipse_13" data-name="Ellipse 13" cx="2" cy="2" r="2" transform="translate(600 220.962)" fill="#f2f2f2"/>
<circle id="Ellipse_14" data-name="Ellipse 14" cx="2" cy="2" r="2" transform="translate(180 265.962)" fill="#f2f2f2"/>
<circle id="Ellipse_15" data-name="Ellipse 15" cx="2" cy="2" r="2" transform="translate(612 96.962)" fill="#f2f2f2"/>
<circle id="Ellipse_16" data-name="Ellipse 16" cx="2" cy="2" r="2" transform="translate(736 192.962)" fill="#f2f2f2"/>
<circle id="Ellipse_17" data-name="Ellipse 17" cx="2" cy="2" r="2" transform="translate(858 344.962)" fill="#f2f2f2"/>
<path id="Path_89" data-name="Path 89" d="M306,121.222h-2.76v-2.76h-1.48v2.76H299V122.7h2.76v2.759h1.48V122.7H306Z" fill="#f2f2f2"/>
<path id="Path_90" data-name="Path 90" d="M848,424.222h-2.76v-2.76h-1.48v2.76H841V425.7h2.76v2.759h1.48V425.7H848Z" fill="#f2f2f2"/>
<path id="Path_91" data-name="Path 91" d="M1144,719.981c0,16.569-243.557,74-544,74s-544-57.431-544-74,243.557,14,544,14S1144,703.413,1144,719.981Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_92" data-name="Path 92" d="M1144,719.981c0,16.569-243.557,74-544,74s-544-57.431-544-74,243.557,14,544,14S1144,703.413,1144,719.981Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<ellipse id="Ellipse_18" data-name="Ellipse 18" cx="544" cy="30" rx="544" ry="30" transform="translate(0 583.962)" fill="#3f3d56"/>
<path id="Path_93" data-name="Path 93" d="M624,677.981c0,33.137-14.775,24-33,24s-33,9.137-33-24,33-96,33-96S624,644.844,624,677.981Z" transform="translate(-56 -106.019)" fill="#ff6584"/>
<path id="Path_94" data-name="Path 94" d="M606,690.66c0,15.062-6.716,10.909-15,10.909s-15,4.153-15-10.909,15-43.636,15-43.636S606,675.6,606,690.66Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<rect id="Rectangle_97" data-name="Rectangle 97" width="92" height="18" rx="9" transform="translate(489 604.962)" fill="#2f2e41"/>
<rect id="Rectangle_98" data-name="Rectangle 98" width="92" height="18" rx="9" transform="translate(489 586.962)" fill="#2f2e41"/>
<path id="Path_95" data-name="Path 95" d="M193,596.547c0,55.343,34.719,100.126,77.626,100.126" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_96" data-name="Path 96" d="M270.626,696.673c0-55.965,38.745-101.251,86.626-101.251" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_97" data-name="Path 97" d="M221.125,601.564c0,52.57,22.14,95.109,49.5,95.109" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_98" data-name="Path 98" d="M270.626,696.673c0-71.511,44.783-129.377,100.126-129.377" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_99" data-name="Path 99" d="M254.3,697.379s11.009-.339,14.326-2.7,16.934-5.183,17.757-1.395,16.544,18.844,4.115,18.945-28.879-1.936-32.19-3.953S254.3,697.379,254.3,697.379Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_100" data-name="Path 100" d="M290.716,710.909c-12.429.1-28.879-1.936-32.19-3.953-2.522-1.536-3.527-7.048-3.863-9.591l-.368.014s.7,8.879,4.009,10.9,19.761,4.053,32.19,3.953c3.588-.029,4.827-1.305,4.759-3.2C294.755,710.174,293.386,710.887,290.716,710.909Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_101" data-name="Path 101" d="M777.429,633.081c0,38.029,23.857,68.8,53.341,68.8" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_102" data-name="Path 102" d="M830.769,701.882c0-38.456,26.623-69.575,59.525-69.575" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_103" data-name="Path 103" d="M796.755,636.528c0,36.124,15.213,65.354,34.014,65.354" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_104" data-name="Path 104" d="M830.769,701.882c0-49.139,30.773-88.9,68.8-88.9" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_105" data-name="Path 105" d="M819.548,702.367s7.565-.233,9.844-1.856,11.636-3.562,12.2-.958,11.368,12.949,2.828,13.018-19.844-1.33-22.119-2.716S819.548,702.367,819.548,702.367Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_106" data-name="Path 106" d="M844.574,711.664c-8.54.069-19.844-1.33-22.119-2.716-1.733-1.056-2.423-4.843-2.654-6.59l-.253.01s.479,6.1,2.755,7.487,13.579,2.785,22.119,2.716c2.465-.02,3.317-.9,3.27-2.2C847.349,711.159,846.409,711.649,844.574,711.664Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_107" data-name="Path 107" d="M949.813,724.718s11.36-1.729,14.5-4.591,16.89-7.488,18.217-3.667,19.494,17.447,6.633,19.107-30.153,1.609-33.835-.065S949.813,724.718,949.813,724.718Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_108" data-name="Path 108" d="M989.228,734.173c-12.86,1.659-30.153,1.609-33.835-.065-2.8-1.275-4.535-6.858-5.2-9.45l-.379.061s1.833,9.109,5.516,10.783,20.975,1.725,33.835.065c3.712-.479,4.836-1.956,4.529-3.906C993.319,732.907,991.991,733.817,989.228,734.173Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_109" data-name="Path 109" d="M670.26,723.9s9.587-1.459,12.237-3.875,14.255-6.32,15.374-3.095,16.452,14.725,5.6,16.125-25.448,1.358-28.555-.055S670.26,723.9,670.26,723.9Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_110" data-name="Path 110" d="M703.524,731.875c-10.853,1.4-25.448,1.358-28.555-.055-2.367-1.076-3.827-5.788-4.39-7.976l-.32.051s1.547,7.687,4.655,9.1,17.7,1.456,28.555.055c3.133-.4,4.081-1.651,3.822-3.3C706.977,730.807,705.856,731.575,703.524,731.875Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_111" data-name="Path 111" d="M178.389,719.109s7.463-1.136,9.527-3.016,11.1-4.92,11.969-2.409,12.808,11.463,4.358,12.553-19.811,1.057-22.23-.043S178.389,719.109,178.389,719.109Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_112" data-name="Path 112" d="M204.285,725.321c-8.449,1.09-19.811,1.057-22.23-.043-1.842-.838-2.979-4.506-3.417-6.209l-.249.04s1.2,5.984,3.624,7.085,13.781,1.133,22.23.043c2.439-.315,3.177-1.285,2.976-2.566C206.973,724.489,206.1,725.087,204.285,725.321Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_113" data-name="Path 113" d="M439.7,707.337c0,30.22-42.124,20.873-93.7,20.873s-93.074,9.347-93.074-20.873,42.118-36.793,93.694-36.793S439.7,677.117,439.7,707.337Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<path id="Path_114" data-name="Path 114" d="M439.7,699.9c0,30.22-42.124,20.873-93.7,20.873s-93.074,9.347-93.074-20.873S295.04,663.1,346.616,663.1,439.7,669.676,439.7,699.9Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
</g>
<g id="docusaurus_keytar" transform="translate(312.271 493.733)">
<path id="Path_40" data-name="Path 40" d="M99,52h91.791V89.153H99Z" transform="translate(5.904 -14.001)" fill="#fff" fill-rule="evenodd"/>
<path id="Path_41" data-name="Path 41" d="M24.855,163.927A21.828,21.828,0,0,1,5.947,153a21.829,21.829,0,0,0,18.908,32.782H46.71V163.927Z" transform="translate(-3 -4.634)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_42" data-name="Path 42" d="M121.861,61.1l76.514-4.782V45.39A21.854,21.854,0,0,0,176.52,23.535H78.173L75.441,18.8a3.154,3.154,0,0,0-5.464,0l-2.732,4.732L64.513,18.8a3.154,3.154,0,0,0-5.464,0l-2.732,4.732L53.586,18.8a3.154,3.154,0,0,0-5.464,0L45.39,23.535c-.024,0-.046,0-.071,0l-4.526-4.525a3.153,3.153,0,0,0-5.276,1.414l-1.5,5.577-5.674-1.521a3.154,3.154,0,0,0-3.863,3.864L26,34.023l-5.575,1.494a3.155,3.155,0,0,0-1.416,5.278l4.526,4.526c0,.023,0,.046,0,.07L18.8,48.122a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,59.05a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,69.977a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,80.9a3.154,3.154,0,0,0,0,5.464L23.535,89.1,18.8,91.832a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,102.76a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,113.687a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,124.615a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,135.542a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,146.469a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,157.4a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,168.324a3.154,3.154,0,0,0,0,5.464l4.732,2.732A21.854,21.854,0,0,0,45.39,198.375H176.52a21.854,21.854,0,0,0,21.855-21.855V89.1l-76.514-4.782a11.632,11.632,0,0,1,0-23.219" transform="translate(-1.681 -17.226)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_43" data-name="Path 43" d="M143,186.71h32.782V143H143Z" transform="translate(9.984 -5.561)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_44" data-name="Path 44" d="M196.71,159.855a5.438,5.438,0,0,0-.7.07c-.042-.164-.081-.329-.127-.493a5.457,5.457,0,1,0-5.4-9.372q-.181-.185-.366-.367a5.454,5.454,0,1,0-9.384-5.4c-.162-.046-.325-.084-.486-.126a5.467,5.467,0,1,0-10.788,0c-.162.042-.325.08-.486.126a5.457,5.457,0,1,0-9.384,5.4,21.843,21.843,0,1,0,36.421,21.02,5.452,5.452,0,1,0,.7-10.858" transform="translate(10.912 -6.025)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_45" data-name="Path 45" d="M153,124.855h32.782V103H153Z" transform="translate(10.912 -9.271)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_46" data-name="Path 46" d="M194.855,116.765a2.732,2.732,0,1,0,0-5.464,2.811,2.811,0,0,0-.349.035c-.022-.082-.04-.164-.063-.246a2.733,2.733,0,0,0-1.052-5.253,2.7,2.7,0,0,0-1.648.566q-.09-.093-.184-.184a2.7,2.7,0,0,0,.553-1.633,2.732,2.732,0,0,0-5.245-1.07,10.928,10.928,0,1,0,0,21.031,2.732,2.732,0,0,0,5.245-1.07,2.7,2.7,0,0,0-.553-1.633q.093-.09.184-.184a2.7,2.7,0,0,0,1.648.566,2.732,2.732,0,0,0,1.052-5.253c.023-.081.042-.164.063-.246a2.814,2.814,0,0,0,.349.035" transform="translate(12.767 -9.377)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_47" data-name="Path 47" d="M65.087,56.891a2.732,2.732,0,0,1-2.732-2.732,8.2,8.2,0,0,0-16.391,0,2.732,2.732,0,0,1-5.464,0,13.659,13.659,0,0,1,27.319,0,2.732,2.732,0,0,1-2.732,2.732" transform="translate(0.478 -15.068)" fill-rule="evenodd"/>
<path id="Path_48" data-name="Path 48" d="M103,191.347h65.565a21.854,21.854,0,0,0,21.855-21.855V93H124.855A21.854,21.854,0,0,0,103,114.855Z" transform="translate(6.275 -10.199)" fill="#ffff50" fill-rule="evenodd"/>
<path id="Path_49" data-name="Path 49" d="M173.216,129.787H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0,21.855H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186m0,21.855H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0-54.434H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0,21.652H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186m0,21.855H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186M189.585,61.611c-.013,0-.024-.007-.037-.005-3.377.115-4.974,3.492-6.384,6.472-1.471,3.114-2.608,5.139-4.473,5.078-2.064-.074-3.244-2.406-4.494-4.874-1.436-2.835-3.075-6.049-6.516-5.929-3.329.114-4.932,3.053-6.346,5.646-1.5,2.762-2.529,4.442-4.5,4.364-2.106-.076-3.225-1.972-4.52-4.167-1.444-2.443-3.112-5.191-6.487-5.1-3.272.113-4.879,2.606-6.3,4.808-1.5,2.328-2.552,3.746-4.551,3.662-2.156-.076-3.27-1.65-4.558-3.472-1.447-2.047-3.077-4.363-6.442-4.251-3.2.109-4.807,2.153-6.224,3.954-1.346,1.709-2.4,3.062-4.621,2.977a1.093,1.093,0,0,0-.079,2.186c3.3.11,4.967-1.967,6.417-3.81,1.286-1.635,2.4-3.045,4.582-3.12,2.1-.09,3.091,1.218,4.584,3.327,1.417,2,3.026,4.277,6.263,4.394,3.391.114,5.022-2.42,6.467-4.663,1.292-2,2.406-3.734,4.535-3.807,1.959-.073,3.026,1.475,4.529,4.022,1.417,2.4,3.023,5.121,6.324,5.241,3.415.118,5.064-2.863,6.5-5.5,1.245-2.282,2.419-4.437,4.5-4.509,1.959-.046,2.981,1.743,4.492,4.732,1.412,2.79,3.013,5.95,6.365,6.071l.185,0c3.348,0,4.937-3.36,6.343-6.331,1.245-2.634,2.423-5.114,4.444-5.216Z" transform="translate(7.109 -13.11)" fill-rule="evenodd"/>
<path id="Path_50" data-name="Path 50" d="M83,186.71h43.71V143H83Z" transform="translate(4.42 -5.561)" fill="#3ecc5f" fill-rule="evenodd"/>
<g id="Group_8" data-name="Group 8" transform="matrix(0.966, -0.259, 0.259, 0.966, 109.327, 91.085)">
<rect id="Rectangle_3" data-name="Rectangle 3" width="92.361" height="36.462" rx="2" transform="translate(0 0)" fill="#d8d8d8"/>
<g id="Group_2" data-name="Group 2" transform="translate(1.531 23.03)">
<rect id="Rectangle_4" data-name="Rectangle 4" width="5.336" height="5.336" rx="1" transform="translate(16.797 0)" fill="#4a4a4a"/>
<rect id="Rectangle_5" data-name="Rectangle 5" width="5.336" height="5.336" rx="1" transform="translate(23.12 0)" fill="#4a4a4a"/>
<rect id="Rectangle_6" data-name="Rectangle 6" width="5.336" height="5.336" rx="1" transform="translate(29.444 0)" fill="#4a4a4a"/>
<rect id="Rectangle_7" data-name="Rectangle 7" width="5.336" height="5.336" rx="1" transform="translate(35.768 0)" fill="#4a4a4a"/>
<rect id="Rectangle_8" data-name="Rectangle 8" width="5.336" height="5.336" rx="1" transform="translate(42.091 0)" fill="#4a4a4a"/>
<rect id="Rectangle_9" data-name="Rectangle 9" width="5.336" height="5.336" rx="1" transform="translate(48.415 0)" fill="#4a4a4a"/>
<rect id="Rectangle_10" data-name="Rectangle 10" width="5.336" height="5.336" rx="1" transform="translate(54.739 0)" fill="#4a4a4a"/>
<rect id="Rectangle_11" data-name="Rectangle 11" width="5.336" height="5.336" rx="1" transform="translate(61.063 0)" fill="#4a4a4a"/>
<rect id="Rectangle_12" data-name="Rectangle 12" width="5.336" height="5.336" rx="1" transform="translate(67.386 0)" fill="#4a4a4a"/>
<path id="Path_51" data-name="Path 51" d="M1.093,0H14.518a1.093,1.093,0,0,1,1.093,1.093V4.243a1.093,1.093,0,0,1-1.093,1.093H1.093A1.093,1.093,0,0,1,0,4.243V1.093A1.093,1.093,0,0,1,1.093,0ZM75,0H88.426a1.093,1.093,0,0,1,1.093,1.093V4.243a1.093,1.093,0,0,1-1.093,1.093H75a1.093,1.093,0,0,1-1.093-1.093V1.093A1.093,1.093,0,0,1,75,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_3" data-name="Group 3" transform="translate(1.531 10.261)">
<path id="Path_52" data-name="Path 52" d="M1.093,0H6.218A1.093,1.093,0,0,1,7.31,1.093V4.242A1.093,1.093,0,0,1,6.218,5.335H1.093A1.093,1.093,0,0,1,0,4.242V1.093A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_13" data-name="Rectangle 13" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_14" data-name="Rectangle 14" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_15" data-name="Rectangle 15" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_16" data-name="Rectangle 16" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_17" data-name="Rectangle 17" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_18" data-name="Rectangle 18" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_19" data-name="Rectangle 19" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_20" data-name="Rectangle 20" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_21" data-name="Rectangle 21" width="5.336" height="5.336" rx="1" transform="translate(58.888 0)" fill="#4a4a4a"/>
<rect id="Rectangle_22" data-name="Rectangle 22" width="5.336" height="5.336" rx="1" transform="translate(65.212 0)" fill="#4a4a4a"/>
<rect id="Rectangle_23" data-name="Rectangle 23" width="5.336" height="5.336" rx="1" transform="translate(71.536 0)" fill="#4a4a4a"/>
<rect id="Rectangle_24" data-name="Rectangle 24" width="5.336" height="5.336" rx="1" transform="translate(77.859 0)" fill="#4a4a4a"/>
<rect id="Rectangle_25" data-name="Rectangle 25" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
</g>
<g id="Group_4" data-name="Group 4" transform="translate(91.05 9.546) rotate(180)">
<path id="Path_53" data-name="Path 53" d="M1.093,0H6.219A1.093,1.093,0,0,1,7.312,1.093v3.15A1.093,1.093,0,0,1,6.219,5.336H1.093A1.093,1.093,0,0,1,0,4.243V1.093A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_26" data-name="Rectangle 26" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_27" data-name="Rectangle 27" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_28" data-name="Rectangle 28" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_29" data-name="Rectangle 29" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_30" data-name="Rectangle 30" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_31" data-name="Rectangle 31" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_32" data-name="Rectangle 32" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_33" data-name="Rectangle 33" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_34" data-name="Rectangle 34" width="5.336" height="5.336" rx="1" transform="translate(58.889 0)" fill="#4a4a4a"/>
<rect id="Rectangle_35" data-name="Rectangle 35" width="5.336" height="5.336" rx="1" transform="translate(65.213 0)" fill="#4a4a4a"/>
<rect id="Rectangle_36" data-name="Rectangle 36" width="5.336" height="5.336" rx="1" transform="translate(71.537 0)" fill="#4a4a4a"/>
<rect id="Rectangle_37" data-name="Rectangle 37" width="5.336" height="5.336" rx="1" transform="translate(77.86 0)" fill="#4a4a4a"/>
<rect id="Rectangle_38" data-name="Rectangle 38" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
<rect id="Rectangle_39" data-name="Rectangle 39" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_40" data-name="Rectangle 40" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_41" data-name="Rectangle 41" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_42" data-name="Rectangle 42" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_43" data-name="Rectangle 43" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_44" data-name="Rectangle 44" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_45" data-name="Rectangle 45" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_46" data-name="Rectangle 46" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_47" data-name="Rectangle 47" width="5.336" height="5.336" rx="1" transform="translate(58.889 0)" fill="#4a4a4a"/>
<rect id="Rectangle_48" data-name="Rectangle 48" width="5.336" height="5.336" rx="1" transform="translate(65.213 0)" fill="#4a4a4a"/>
<rect id="Rectangle_49" data-name="Rectangle 49" width="5.336" height="5.336" rx="1" transform="translate(71.537 0)" fill="#4a4a4a"/>
<rect id="Rectangle_50" data-name="Rectangle 50" width="5.336" height="5.336" rx="1" transform="translate(77.86 0)" fill="#4a4a4a"/>
<rect id="Rectangle_51" data-name="Rectangle 51" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
</g>
<g id="Group_6" data-name="Group 6" transform="translate(1.531 16.584)">
<path id="Path_54" data-name="Path 54" d="M1.093,0h7.3A1.093,1.093,0,0,1,9.485,1.093v3.15A1.093,1.093,0,0,1,8.392,5.336h-7.3A1.093,1.093,0,0,1,0,4.243V1.094A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<g id="Group_5" data-name="Group 5" transform="translate(10.671 0)">
<rect id="Rectangle_52" data-name="Rectangle 52" width="5.336" height="5.336" rx="1" fill="#4a4a4a"/>
<rect id="Rectangle_53" data-name="Rectangle 53" width="5.336" height="5.336" rx="1" transform="translate(6.324 0)" fill="#4a4a4a"/>
<rect id="Rectangle_54" data-name="Rectangle 54" width="5.336" height="5.336" rx="1" transform="translate(12.647 0)" fill="#4a4a4a"/>
<rect id="Rectangle_55" data-name="Rectangle 55" width="5.336" height="5.336" rx="1" transform="translate(18.971 0)" fill="#4a4a4a"/>
<rect id="Rectangle_56" data-name="Rectangle 56" width="5.336" height="5.336" rx="1" transform="translate(25.295 0)" fill="#4a4a4a"/>
<rect id="Rectangle_57" data-name="Rectangle 57" width="5.336" height="5.336" rx="1" transform="translate(31.619 0)" fill="#4a4a4a"/>
<rect id="Rectangle_58" data-name="Rectangle 58" width="5.336" height="5.336" rx="1" transform="translate(37.942 0)" fill="#4a4a4a"/>
<rect id="Rectangle_59" data-name="Rectangle 59" width="5.336" height="5.336" rx="1" transform="translate(44.265 0)" fill="#4a4a4a"/>
<rect id="Rectangle_60" data-name="Rectangle 60" width="5.336" height="5.336" rx="1" transform="translate(50.589 0)" fill="#4a4a4a"/>
<rect id="Rectangle_61" data-name="Rectangle 61" width="5.336" height="5.336" rx="1" transform="translate(56.912 0)" fill="#4a4a4a"/>
<rect id="Rectangle_62" data-name="Rectangle 62" width="5.336" height="5.336" rx="1" transform="translate(63.236 0)" fill="#4a4a4a"/>
</g>
<path id="Path_55" data-name="Path 55" d="M1.094,0H8A1.093,1.093,0,0,1,9.091,1.093v3.15A1.093,1.093,0,0,1,8,5.336H1.093A1.093,1.093,0,0,1,0,4.243V1.094A1.093,1.093,0,0,1,1.093,0Z" transform="translate(80.428 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_7" data-name="Group 7" transform="translate(1.531 29.627)">
<rect id="Rectangle_63" data-name="Rectangle 63" width="5.336" height="5.336" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_64" data-name="Rectangle 64" width="5.336" height="5.336" rx="1" transform="translate(6.324 0)" fill="#4a4a4a"/>
<rect id="Rectangle_65" data-name="Rectangle 65" width="5.336" height="5.336" rx="1" transform="translate(12.647 0)" fill="#4a4a4a"/>
<rect id="Rectangle_66" data-name="Rectangle 66" width="5.336" height="5.336" rx="1" transform="translate(18.971 0)" fill="#4a4a4a"/>
<path id="Path_56" data-name="Path 56" d="M1.093,0H31.515a1.093,1.093,0,0,1,1.093,1.093V4.244a1.093,1.093,0,0,1-1.093,1.093H1.093A1.093,1.093,0,0,1,0,4.244V1.093A1.093,1.093,0,0,1,1.093,0ZM34.687,0h3.942a1.093,1.093,0,0,1,1.093,1.093V4.244a1.093,1.093,0,0,1-1.093,1.093H34.687a1.093,1.093,0,0,1-1.093-1.093V1.093A1.093,1.093,0,0,1,34.687,0Z" transform="translate(25.294 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_67" data-name="Rectangle 67" width="5.336" height="5.336" rx="1" transform="translate(66.003 0)" fill="#4a4a4a"/>
<rect id="Rectangle_68" data-name="Rectangle 68" width="5.336" height="5.336" rx="1" transform="translate(72.327 0)" fill="#4a4a4a"/>
<rect id="Rectangle_69" data-name="Rectangle 69" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
<path id="Path_57" data-name="Path 57" d="M5.336,0V1.18A1.093,1.093,0,0,1,4.243,2.273H1.093A1.093,1.093,0,0,1,0,1.18V0Z" transform="translate(83.59 2.273) rotate(180)" fill="#4a4a4a"/>
<path id="Path_58" data-name="Path 58" d="M5.336,0V1.18A1.093,1.093,0,0,1,4.243,2.273H1.093A1.093,1.093,0,0,1,0,1.18V0Z" transform="translate(78.255 3.063)" fill="#4a4a4a"/>
</g>
<rect id="Rectangle_70" data-name="Rectangle 70" width="88.927" height="2.371" rx="1.085" transform="translate(1.925 1.17)" fill="#4a4a4a"/>
<rect id="Rectangle_71" data-name="Rectangle 71" width="4.986" height="1.581" rx="0.723" transform="translate(4.1 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_72" data-name="Rectangle 72" width="4.986" height="1.581" rx="0.723" transform="translate(10.923 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_73" data-name="Rectangle 73" width="4.986" height="1.581" rx="0.723" transform="translate(16.173 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_74" data-name="Rectangle 74" width="4.986" height="1.581" rx="0.723" transform="translate(21.421 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_75" data-name="Rectangle 75" width="4.986" height="1.581" rx="0.723" transform="translate(26.671 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_76" data-name="Rectangle 76" width="4.986" height="1.581" rx="0.723" transform="translate(33.232 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_77" data-name="Rectangle 77" width="4.986" height="1.581" rx="0.723" transform="translate(38.48 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_78" data-name="Rectangle 78" width="4.986" height="1.581" rx="0.723" transform="translate(43.73 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_79" data-name="Rectangle 79" width="4.986" height="1.581" rx="0.723" transform="translate(48.978 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_80" data-name="Rectangle 80" width="4.986" height="1.581" rx="0.723" transform="translate(55.54 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_81" data-name="Rectangle 81" width="4.986" height="1.581" rx="0.723" transform="translate(60.788 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_82" data-name="Rectangle 82" width="4.986" height="1.581" rx="0.723" transform="translate(66.038 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_83" data-name="Rectangle 83" width="4.986" height="1.581" rx="0.723" transform="translate(72.599 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_84" data-name="Rectangle 84" width="4.986" height="1.581" rx="0.723" transform="translate(77.847 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_85" data-name="Rectangle 85" width="4.986" height="1.581" rx="0.723" transform="translate(83.097 1.566)" fill="#d8d8d8" opacity="0.136"/>
</g>
<path id="Path_59" data-name="Path 59" d="M146.71,159.855a5.439,5.439,0,0,0-.7.07c-.042-.164-.081-.329-.127-.493a5.457,5.457,0,1,0-5.4-9.372q-.181-.185-.366-.367a5.454,5.454,0,1,0-9.384-5.4c-.162-.046-.325-.084-.486-.126a5.467,5.467,0,1,0-10.788,0c-.162.042-.325.08-.486.126a5.457,5.457,0,1,0-9.384,5.4,21.843,21.843,0,1,0,36.421,21.02,5.452,5.452,0,1,0,.7-10.858" transform="translate(6.275 -6.025)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_60" data-name="Path 60" d="M83,124.855h43.71V103H83Z" transform="translate(4.42 -9.271)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_61" data-name="Path 61" d="M134.855,116.765a2.732,2.732,0,1,0,0-5.464,2.811,2.811,0,0,0-.349.035c-.022-.082-.04-.164-.063-.246a2.733,2.733,0,0,0-1.052-5.253,2.7,2.7,0,0,0-1.648.566q-.09-.093-.184-.184a2.7,2.7,0,0,0,.553-1.633,2.732,2.732,0,0,0-5.245-1.07,10.928,10.928,0,1,0,0,21.031,2.732,2.732,0,0,0,5.245-1.07,2.7,2.7,0,0,0-.553-1.633q.093-.09.184-.184a2.7,2.7,0,0,0,1.648.566,2.732,2.732,0,0,0,1.052-5.253c.023-.081.042-.164.063-.246a2.811,2.811,0,0,0,.349.035" transform="translate(7.202 -9.377)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_62" data-name="Path 62" d="M143.232,42.33a2.967,2.967,0,0,1-.535-.055,2.754,2.754,0,0,1-.514-.153,2.838,2.838,0,0,1-.471-.251,4.139,4.139,0,0,1-.415-.339,3.2,3.2,0,0,1-.338-.415A2.7,2.7,0,0,1,140.5,39.6a2.968,2.968,0,0,1,.055-.535,3.152,3.152,0,0,1,.152-.514,2.874,2.874,0,0,1,.252-.47,2.633,2.633,0,0,1,.753-.754,2.837,2.837,0,0,1,.471-.251,2.753,2.753,0,0,1,.514-.153,2.527,2.527,0,0,1,1.071,0,2.654,2.654,0,0,1,.983.4,4.139,4.139,0,0,1,.415.339,4.019,4.019,0,0,1,.339.415,2.786,2.786,0,0,1,.251.47,2.864,2.864,0,0,1,.208,1.049,2.77,2.77,0,0,1-.8,1.934,4.139,4.139,0,0,1-.415.339,2.722,2.722,0,0,1-1.519.459m21.855-1.366a2.789,2.789,0,0,1-1.935-.8,4.162,4.162,0,0,1-.338-.415,2.7,2.7,0,0,1-.459-1.519,2.789,2.789,0,0,1,.8-1.934,4.139,4.139,0,0,1,.415-.339,2.838,2.838,0,0,1,.471-.251,2.752,2.752,0,0,1,.514-.153,2.527,2.527,0,0,1,1.071,0,2.654,2.654,0,0,1,.983.4,4.139,4.139,0,0,1,.415.339,2.79,2.79,0,0,1,.8,1.934,3.069,3.069,0,0,1-.055.535,2.779,2.779,0,0,1-.153.514,3.885,3.885,0,0,1-.251.47,4.02,4.02,0,0,1-.339.415,4.138,4.138,0,0,1-.415.339,2.722,2.722,0,0,1-1.519.459" transform="translate(9.753 -15.532)" fill-rule="evenodd"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 31 KiB

View file

@ -1,170 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1041.277" height="554.141" viewBox="0 0 1041.277 554.141">
<title>Powered by React</title>
<g id="Group_24" data-name="Group 24" transform="translate(-440 -263)">
<g id="Group_23" data-name="Group 23" transform="translate(439.989 262.965)">
<path id="Path_299" data-name="Path 299" d="M1040.82,611.12q-1.74,3.75-3.47,7.4-2.7,5.67-5.33,11.12c-.78,1.61-1.56,3.19-2.32,4.77-8.6,17.57-16.63,33.11-23.45,45.89A73.21,73.21,0,0,1,942.44,719l-151.65,1.65h-1.6l-13,.14-11.12.12-34.1.37h-1.38l-17.36.19h-.53l-107,1.16-95.51,1-11.11.12-69,.75H429l-44.75.48h-.48l-141.5,1.53-42.33.46a87.991,87.991,0,0,1-10.79-.54h0c-1.22-.14-2.44-.3-3.65-.49a87.38,87.38,0,0,1-51.29-27.54C116,678.37,102.75,655,93.85,629.64q-1.93-5.49-3.6-11.12C59.44,514.37,97,380,164.6,290.08q4.25-5.64,8.64-11l.07-.08c20.79-25.52,44.1-46.84,68.93-62,44-26.91,92.75-34.49,140.7-11.9,40.57,19.12,78.45,28.11,115.17,30.55,3.71.24,7.42.42,11.11.53,84.23,2.65,163.17-27.7,255.87-47.29,3.69-.78,7.39-1.55,11.12-2.28,66.13-13.16,139.49-20.1,226.73-5.51a189.089,189.089,0,0,1,26.76,6.4q5.77,1.86,11.12,4c41.64,16.94,64.35,48.24,74,87.46q1.37,5.46,2.37,11.11C1134.3,384.41,1084.19,518.23,1040.82,611.12Z" transform="translate(-79.34 -172.91)" fill="#f2f2f2"/>
<path id="Path_300" data-name="Path 300" d="M576.36,618.52a95.21,95.21,0,0,1-1.87,11.12h93.7V618.52Zm-78.25,62.81,11.11-.09V653.77c-3.81-.17-7.52-.34-11.11-.52ZM265.19,618.52v11.12h198.5V618.52ZM1114.87,279h-74V191.51q-5.35-2.17-11.12-4V279H776.21V186.58c-3.73.73-7.43,1.5-11.12,2.28V279H509.22V236.15c-3.69-.11-7.4-.29-11.11-.53V279H242.24V217c-24.83,15.16-48.14,36.48-68.93,62h-.07v.08q-4.4,5.4-8.64,11h8.64V618.52h-83q1.66,5.63,3.6,11.12h79.39v93.62a87,87,0,0,0,12.2,2.79c1.21.19,2.43.35,3.65.49h0a87.991,87.991,0,0,0,10.79.54l42.33-.46v-97H498.11v94.21l11.11-.12V629.64H765.09V721l11.12-.12V629.64H1029.7v4.77c.76-1.58,1.54-3.16,2.32-4.77q2.63-5.45,5.33-11.12,1.73-3.64,3.47-7.4v-321h76.42Q1116.23,284.43,1114.87,279ZM242.24,618.52V290.08H498.11V618.52Zm267,0V290.08H765.09V618.52Zm520.48,0H776.21V290.08H1029.7Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_301" data-name="Path 301" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l46.65-28,93.6-.78,2-.01.66-.01,2-.03,44.94-.37,2.01-.01.64-.01,2-.01L315,509.3l.38-.01,35.55-.3h.29l277.4-2.34,6.79-.05h.68l5.18-.05,37.65-.31,2-.03,1.85-.02h.96l11.71-.09,2.32-.03,3.11-.02,9.75-.09,15.47-.13,2-.02,3.48-.02h.65l74.71-.64Z" fill="#65617d"/>
<path id="Path_302" data-name="Path 302" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l46.65-28,93.6-.78,2-.01.66-.01,2-.03,44.94-.37,2.01-.01.64-.01,2-.01L315,509.3l.38-.01,35.55-.3h.29l277.4-2.34,6.79-.05h.68l5.18-.05,37.65-.31,2-.03,1.85-.02h.96l11.71-.09,2.32-.03,3.11-.02,9.75-.09,15.47-.13,2-.02,3.48-.02h.65l74.71-.64Z" opacity="0.2"/>
<path id="Path_303" data-name="Path 303" d="M375.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<path id="Path_304" data-name="Path 304" d="M375.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_305" data-name="Path 305" d="M377.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<rect id="Rectangle_137" data-name="Rectangle 137" width="47.17" height="31.5" transform="translate(680.92 483.65)" fill="#3f3d56"/>
<rect id="Rectangle_138" data-name="Rectangle 138" width="47.17" height="31.5" transform="translate(680.92 483.65)" opacity="0.1"/>
<rect id="Rectangle_139" data-name="Rectangle 139" width="47.17" height="31.5" transform="translate(678.92 483.65)" fill="#3f3d56"/>
<path id="Path_306" data-name="Path 306" d="M298.09,483.65v4.97l-47.17,1.26v-6.23Z" opacity="0.1"/>
<path id="Path_307" data-name="Path 307" d="M460.69,485.27v168.2a4,4,0,0,1-3.85,3.95l-191.65,5.1h-.05a4,4,0,0,1-3.95-3.95V485.27a4,4,0,0,1,3.95-3.95h191.6a4,4,0,0,1,3.95,3.95Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_308" data-name="Path 308" d="M265.19,481.32v181.2h-.05a4,4,0,0,1-3.95-3.95V485.27a4,4,0,0,1,3.95-3.95Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_309" data-name="Path 309" d="M194.59,319.15h177.5V467.4l-177.5,4Z" fill="#39374d"/>
<path id="Path_310" data-name="Path 310" d="M726.09,483.65v6.41l-47.17-1.26v-5.15Z" opacity="0.1"/>
<path id="Path_311" data-name="Path 311" d="M867.69,485.27v173.3a4,4,0,0,1-4,3.95h0L672,657.42a4,4,0,0,1-3.85-3.95V485.27a4,4,0,0,1,3.95-3.95H863.7a4,4,0,0,1,3.99,3.95Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_312" data-name="Path 312" d="M867.69,485.27v173.3a4,4,0,0,1-4,3.95h0V481.32h0a4,4,0,0,1,4,3.95Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_313" data-name="Path 313" d="M775.59,319.15H598.09V467.4l177.5,4Z" fill="#39374d"/>
<path id="Path_314" data-name="Path 314" d="M663.19,485.27v168.2a4,4,0,0,1-3.85,3.95l-191.65,5.1h0a4,4,0,0,1-4-3.95V485.27a4,4,0,0,1,3.95-3.95h191.6A4,4,0,0,1,663.19,485.27Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_315" data-name="Path 315" d="M397.09,319.15h177.5V467.4l-177.5,4Z" fill="#4267b2"/>
<path id="Path_316" data-name="Path 316" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l202.51-1.33h.48l40.99-.28h.19l283.08-1.87h.29l.17-.01h.47l4.79-.03h1.46l74.49-.5,4.4-.02.98-.01Z" opacity="0.1"/>
<circle id="Ellipse_111" data-name="Ellipse 111" cx="51.33" cy="51.33" r="51.33" transform="translate(435.93 246.82)" fill="#fbbebe"/>
<path id="Path_317" data-name="Path 317" d="M617.94,550.07s-99.5,12-90,0c3.44-4.34,4.39-17.2,4.2-31.85-.06-4.45-.22-9.06-.45-13.65-1.1-22-3.75-43.5-3.75-43.5s87-41,77-8.5c-4,13.13-2.69,31.57.35,48.88.89,5.05,1.92,10,3,14.7a344.66,344.66,0,0,0,9.65,33.92Z" transform="translate(-79.34 -172.91)" fill="#fbbebe"/>
<path id="Path_318" data-name="Path 318" d="M585.47,546c11.51-2.13,23.7-6,34.53-1.54,2.85,1.17,5.47,2.88,8.39,3.86s6.12,1.22,9.16,1.91c10.68,2.42,19.34,10.55,24.9,20s8.44,20.14,11.26,30.72l6.9,25.83c6,22.45,12,45.09,13.39,68.3a2437.506,2437.506,0,0,1-250.84,1.43c5.44-10.34,11-21.31,10.54-33s-7.19-23.22-4.76-34.74c1.55-7.34,6.57-13.39,9.64-20.22,8.75-19.52,1.94-45.79,17.32-60.65,6.92-6.68,17-9.21,26.63-8.89,12.28.41,24.85,4.24,37,6.11C555.09,547.48,569.79,548.88,585.47,546Z" transform="translate(-79.34 -172.91)" fill="#ff6584"/>
<path id="Path_319" data-name="Path 319" d="M716.37,657.17l-.1,1.43v.1l-.17,2.3-1.33,18.51-1.61,22.3-.46,6.28-1,13.44v.17l-107,1-175.59,1.9v.84h-.14v-1.12l.45-14.36.86-28.06.74-23.79.07-2.37a10.53,10.53,0,0,1,11.42-10.17c4.72.4,10.85.89,18.18,1.41l3,.22c42.33,2.94,120.56,6.74,199.5,2,1.66-.09,3.33-.19,5-.31,12.24-.77,24.47-1.76,36.58-3a10.53,10.53,0,0,1,11.6,11.23Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_320" data-name="Path 320" d="M429.08,725.44v-.84l175.62-1.91,107-1h.3v-.17l1-13.44.43-6,1.64-22.61,1.29-17.9v-.44a10.617,10.617,0,0,0-.11-2.47.3.3,0,0,0,0-.1,10.391,10.391,0,0,0-2-4.64,10.54,10.54,0,0,0-9.42-4c-12.11,1.24-24.34,2.23-36.58,3-1.67.12-3.34.22-5,.31-78.94,4.69-157.17.89-199.5-2l-3-.22c-7.33-.52-13.46-1-18.18-1.41a10.54,10.54,0,0,0-11.24,8.53,11,11,0,0,0-.18,1.64l-.68,22.16L429.54,710l-.44,14.36v1.12Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<path id="Path_321" data-name="Path 321" d="M716.67,664.18l-1.23,15.33-1.83,22.85-.46,5.72-1,12.81-.06.64v.17h0l-.15,1.48.11-1.48h-.29l-107,1-175.65,1.9v-.28l.49-14.36,1-28.06.64-18.65A6.36,6.36,0,0,1,434.3,658a6.25,6.25,0,0,1,3.78-.9c2.1.17,4.68.37,7.69.59,4.89.36,10.92.78,17.94,1.22,13,.82,29.31,1.7,48,2.42,52,2,122.2,2.67,188.88-3.17,3-.26,6.1-.55,9.13-.84a6.26,6.26,0,0,1,3.48.66,5.159,5.159,0,0,1,.86.54,6.14,6.14,0,0,1,2,2.46,3.564,3.564,0,0,1,.25.61A6.279,6.279,0,0,1,716.67,664.18Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_322" data-name="Path 322" d="M377.44,677.87v3.19a6.13,6.13,0,0,1-3.5,5.54l-40.1.77a6.12,6.12,0,0,1-3.57-5.57v-3Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_323" data-name="Path 323" d="M298.59,515.57l-52.25,1V507.9l52.25-1Z" fill="#3f3d56"/>
<path id="Path_324" data-name="Path 324" d="M298.59,515.57l-52.25,1V507.9l52.25-1Z" opacity="0.1"/>
<path id="Path_325" data-name="Path 325" d="M300.59,515.57l-52.25,1V507.9l52.25-1Z" fill="#3f3d56"/>
<path id="Path_326" data-name="Path 326" d="M758.56,679.87v3.19a6.13,6.13,0,0,0,3.5,5.54l40.1.77a6.12,6.12,0,0,0,3.57-5.57v-3Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_327" data-name="Path 327" d="M678.72,517.57l52.25,1V509.9l-52.25-1Z" opacity="0.1"/>
<path id="Path_328" data-name="Path 328" d="M676.72,517.57l52.25,1V509.9l-52.25-1Z" fill="#3f3d56"/>
<path id="Path_329" data-name="Path 329" d="M534.13,486.79c.08,7-3.16,13.6-5.91,20.07a163.491,163.491,0,0,0-12.66,74.71c.73,11,2.58,22,.73,32.9s-8.43,21.77-19,24.9c17.53,10.45,41.26,9.35,57.76-2.66,8.79-6.4,15.34-15.33,21.75-24.11a97.86,97.86,0,0,1-13.31,44.75A103.43,103.43,0,0,0,637,616.53c4.31-5.81,8.06-12.19,9.72-19.23,3.09-13-1.22-26.51-4.51-39.5a266.055,266.055,0,0,1-6.17-33c-.43-3.56-.78-7.22.1-10.7,1-4.07,3.67-7.51,5.64-11.22,5.6-10.54,5.73-23.3,2.86-34.88s-8.49-22.26-14.06-32.81c-4.46-8.46-9.3-17.31-17.46-22.28-5.1-3.1-11-4.39-16.88-5.64l-25.37-5.43c-5.55-1.19-11.26-2.38-16.87-1.51-9.47,1.48-16.14,8.32-22,15.34-4.59,5.46-15.81,15.71-16.6,22.86-.72,6.59,5.1,17.63,6.09,24.58,1.3,9,2.22,6,7.3,11.52C532,478.05,534.07,482,534.13,486.79Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
</g>
<g id="docusaurus_keytar" transform="translate(670.271 615.768)">
<path id="Path_40" data-name="Path 40" d="M99,52h43.635V69.662H99Z" transform="translate(-49.132 -33.936)" fill="#fff" fill-rule="evenodd"/>
<path id="Path_41" data-name="Path 41" d="M13.389,158.195A10.377,10.377,0,0,1,4.4,153a10.377,10.377,0,0,0,8.988,15.584H23.779V158.195Z" transform="translate(-3 -82.47)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_42" data-name="Path 42" d="M66.967,38.083l36.373-2.273V30.615A10.389,10.389,0,0,0,92.95,20.226H46.2l-1.3-2.249a1.5,1.5,0,0,0-2.6,0L41,20.226l-1.3-2.249a1.5,1.5,0,0,0-2.6,0l-1.3,2.249-1.3-2.249a1.5,1.5,0,0,0-2.6,0l-1.3,2.249-.034,0-2.152-2.151a1.5,1.5,0,0,0-2.508.672L25.21,21.4l-2.7-.723a1.5,1.5,0,0,0-1.836,1.837l.722,2.7-2.65.71a1.5,1.5,0,0,0-.673,2.509l2.152,2.152c0,.011,0,.022,0,.033l-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6L20.226,41l-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3A10.389,10.389,0,0,0,30.615,103.34H92.95A10.389,10.389,0,0,0,103.34,92.95V51.393L66.967,49.12a5.53,5.53,0,0,1,0-11.038" transform="translate(-9.836 -17.226)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_43" data-name="Path 43" d="M143,163.779h15.584V143H143Z" transform="translate(-70.275 -77.665)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_44" data-name="Path 44" d="M173.779,148.389a2.582,2.582,0,0,0-.332.033c-.02-.078-.038-.156-.06-.234a2.594,2.594,0,1,0-2.567-4.455q-.086-.088-.174-.175a2.593,2.593,0,1,0-4.461-2.569c-.077-.022-.154-.04-.231-.06a2.6,2.6,0,1,0-5.128,0c-.077.02-.154.038-.231.06a2.594,2.594,0,1,0-4.461,2.569,10.384,10.384,0,1,0,17.314,9.992,2.592,2.592,0,1,0,.332-5.161" transform="translate(-75.08 -75.262)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_45" data-name="Path 45" d="M153,113.389h15.584V103H153Z" transform="translate(-75.08 -58.444)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_46" data-name="Path 46" d="M183.389,108.944a1.3,1.3,0,1,0,0-2.6,1.336,1.336,0,0,0-.166.017c-.01-.039-.019-.078-.03-.117a1.3,1.3,0,0,0-.5-2.5,1.285,1.285,0,0,0-.783.269q-.043-.044-.087-.087a1.285,1.285,0,0,0,.263-.776,1.3,1.3,0,0,0-2.493-.509,5.195,5.195,0,1,0,0,10,1.3,1.3,0,0,0,2.493-.509,1.285,1.285,0,0,0-.263-.776q.044-.043.087-.087a1.285,1.285,0,0,0,.783.269,1.3,1.3,0,0,0,.5-2.5c.011-.038.02-.078.03-.117a1.337,1.337,0,0,0,.166.017" transform="translate(-84.691 -57.894)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_47" data-name="Path 47" d="M52.188,48.292a1.3,1.3,0,0,1-1.3-1.3,3.9,3.9,0,0,0-7.792,0,1.3,1.3,0,1,1-2.6,0,6.493,6.493,0,0,1,12.987,0,1.3,1.3,0,0,1-1.3,1.3" transform="translate(-21.02 -28.41)" fill-rule="evenodd"/>
<path id="Path_48" data-name="Path 48" d="M103,139.752h31.168a10.389,10.389,0,0,0,10.389-10.389V93H113.389A10.389,10.389,0,0,0,103,103.389Z" transform="translate(-51.054 -53.638)" fill="#ffff50" fill-rule="evenodd"/>
<path id="Path_49" data-name="Path 49" d="M141.1,94.017H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0-25.877H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.293H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m7.782-47.993c-.006,0-.011,0-.018,0-1.605.055-2.365,1.66-3.035,3.077-.7,1.48-1.24,2.443-2.126,2.414-.981-.035-1.542-1.144-2.137-2.317-.683-1.347-1.462-2.876-3.1-2.819-1.582.054-2.344,1.451-3.017,2.684-.715,1.313-1.2,2.112-2.141,2.075-1-.036-1.533-.938-2.149-1.981-.686-1.162-1.479-2.467-3.084-2.423-1.555.053-2.319,1.239-2.994,2.286-.713,1.106-1.213,1.781-2.164,1.741-1.025-.036-1.554-.784-2.167-1.65-.688-.973-1.463-2.074-3.062-2.021a3.815,3.815,0,0,0-2.959,1.879c-.64.812-1.14,1.456-2.2,1.415a.52.52,0,0,0-.037,1.039,3.588,3.588,0,0,0,3.05-1.811c.611-.777,1.139-1.448,2.178-1.483,1-.043,1.47.579,2.179,1.582.674.953,1.438,2.033,2.977,2.089,1.612.054,2.387-1.151,3.074-2.217.614-.953,1.144-1.775,2.156-1.81.931-.035,1.438.7,2.153,1.912.674,1.141,1.437,2.434,3.006,2.491,1.623.056,2.407-1.361,3.09-2.616.592-1.085,1.15-2.109,2.14-2.143.931-.022,1.417.829,2.135,2.249.671,1.326,1.432,2.828,3.026,2.886l.088,0c1.592,0,2.347-1.6,3.015-3.01.592-1.252,1.152-2.431,2.113-2.479Z" transform="translate(-55.378 -38.552)" fill-rule="evenodd"/>
<path id="Path_50" data-name="Path 50" d="M83,163.779h20.779V143H83Z" transform="translate(-41.443 -77.665)" fill="#3ecc5f" fill-rule="evenodd"/>
<g id="Group_8" data-name="Group 8" transform="matrix(0.966, -0.259, 0.259, 0.966, 51.971, 43.3)">
<rect id="Rectangle_3" data-name="Rectangle 3" width="43.906" height="17.333" rx="2" transform="translate(0 0)" fill="#d8d8d8"/>
<g id="Group_2" data-name="Group 2" transform="translate(0.728 10.948)">
<rect id="Rectangle_4" data-name="Rectangle 4" width="2.537" height="2.537" rx="1" transform="translate(7.985 0)" fill="#4a4a4a"/>
<rect id="Rectangle_5" data-name="Rectangle 5" width="2.537" height="2.537" rx="1" transform="translate(10.991 0)" fill="#4a4a4a"/>
<rect id="Rectangle_6" data-name="Rectangle 6" width="2.537" height="2.537" rx="1" transform="translate(13.997 0)" fill="#4a4a4a"/>
<rect id="Rectangle_7" data-name="Rectangle 7" width="2.537" height="2.537" rx="1" transform="translate(17.003 0)" fill="#4a4a4a"/>
<rect id="Rectangle_8" data-name="Rectangle 8" width="2.537" height="2.537" rx="1" transform="translate(20.009 0)" fill="#4a4a4a"/>
<rect id="Rectangle_9" data-name="Rectangle 9" width="2.537" height="2.537" rx="1" transform="translate(23.015 0)" fill="#4a4a4a"/>
<rect id="Rectangle_10" data-name="Rectangle 10" width="2.537" height="2.537" rx="1" transform="translate(26.021 0)" fill="#4a4a4a"/>
<rect id="Rectangle_11" data-name="Rectangle 11" width="2.537" height="2.537" rx="1" transform="translate(29.028 0)" fill="#4a4a4a"/>
<rect id="Rectangle_12" data-name="Rectangle 12" width="2.537" height="2.537" rx="1" transform="translate(32.034 0)" fill="#4a4a4a"/>
<path id="Path_51" data-name="Path 51" d="M.519,0H6.9A.519.519,0,0,1,7.421.52v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0ZM35.653,0h6.383a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H35.652a.519.519,0,0,1-.519-.519V.519A.519.519,0,0,1,35.652,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_3" data-name="Group 3" transform="translate(0.728 4.878)">
<path id="Path_52" data-name="Path 52" d="M.519,0H2.956a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_13" data-name="Rectangle 13" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_14" data-name="Rectangle 14" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_15" data-name="Rectangle 15" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_16" data-name="Rectangle 16" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_17" data-name="Rectangle 17" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_18" data-name="Rectangle 18" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_19" data-name="Rectangle 19" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_20" data-name="Rectangle 20" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_21" data-name="Rectangle 21" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_22" data-name="Rectangle 22" width="2.537" height="2.537" rx="1" transform="translate(31 0)" fill="#4a4a4a"/>
<rect id="Rectangle_23" data-name="Rectangle 23" width="2.537" height="2.537" rx="1" transform="translate(34.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_24" data-name="Rectangle 24" width="2.537" height="2.537" rx="1" transform="translate(37.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_25" data-name="Rectangle 25" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
</g>
<g id="Group_4" data-name="Group 4" transform="translate(43.283 4.538) rotate(180)">
<path id="Path_53" data-name="Path 53" d="M.519,0H2.956a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_26" data-name="Rectangle 26" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_27" data-name="Rectangle 27" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_28" data-name="Rectangle 28" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_29" data-name="Rectangle 29" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_30" data-name="Rectangle 30" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_31" data-name="Rectangle 31" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_32" data-name="Rectangle 32" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_33" data-name="Rectangle 33" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_34" data-name="Rectangle 34" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_35" data-name="Rectangle 35" width="2.537" height="2.537" rx="1" transform="translate(31.001 0)" fill="#4a4a4a"/>
<rect id="Rectangle_36" data-name="Rectangle 36" width="2.537" height="2.537" rx="1" transform="translate(34.007 0)" fill="#4a4a4a"/>
<rect id="Rectangle_37" data-name="Rectangle 37" width="2.537" height="2.537" rx="1" transform="translate(37.013 0)" fill="#4a4a4a"/>
<rect id="Rectangle_38" data-name="Rectangle 38" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
<rect id="Rectangle_39" data-name="Rectangle 39" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_40" data-name="Rectangle 40" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_41" data-name="Rectangle 41" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_42" data-name="Rectangle 42" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_43" data-name="Rectangle 43" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_44" data-name="Rectangle 44" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_45" data-name="Rectangle 45" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_46" data-name="Rectangle 46" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_47" data-name="Rectangle 47" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_48" data-name="Rectangle 48" width="2.537" height="2.537" rx="1" transform="translate(31.001 0)" fill="#4a4a4a"/>
<rect id="Rectangle_49" data-name="Rectangle 49" width="2.537" height="2.537" rx="1" transform="translate(34.007 0)" fill="#4a4a4a"/>
<rect id="Rectangle_50" data-name="Rectangle 50" width="2.537" height="2.537" rx="1" transform="translate(37.013 0)" fill="#4a4a4a"/>
<rect id="Rectangle_51" data-name="Rectangle 51" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
</g>
<g id="Group_6" data-name="Group 6" transform="translate(0.728 7.883)">
<path id="Path_54" data-name="Path 54" d="M.519,0h3.47a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.52A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<g id="Group_5" data-name="Group 5" transform="translate(5.073 0)">
<rect id="Rectangle_52" data-name="Rectangle 52" width="2.537" height="2.537" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_53" data-name="Rectangle 53" width="2.537" height="2.537" rx="1" transform="translate(3.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_54" data-name="Rectangle 54" width="2.537" height="2.537" rx="1" transform="translate(6.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_55" data-name="Rectangle 55" width="2.537" height="2.537" rx="1" transform="translate(9.018 0)" fill="#4a4a4a"/>
<rect id="Rectangle_56" data-name="Rectangle 56" width="2.537" height="2.537" rx="1" transform="translate(12.025 0)" fill="#4a4a4a"/>
<rect id="Rectangle_57" data-name="Rectangle 57" width="2.537" height="2.537" rx="1" transform="translate(15.031 0)" fill="#4a4a4a"/>
<rect id="Rectangle_58" data-name="Rectangle 58" width="2.537" height="2.537" rx="1" transform="translate(18.037 0)" fill="#4a4a4a"/>
<rect id="Rectangle_59" data-name="Rectangle 59" width="2.537" height="2.537" rx="1" transform="translate(21.042 0)" fill="#4a4a4a"/>
<rect id="Rectangle_60" data-name="Rectangle 60" width="2.537" height="2.537" rx="1" transform="translate(24.049 0)" fill="#4a4a4a"/>
<rect id="Rectangle_61" data-name="Rectangle 61" width="2.537" height="2.537" rx="1" transform="translate(27.055 0)" fill="#4a4a4a"/>
<rect id="Rectangle_62" data-name="Rectangle 62" width="2.537" height="2.537" rx="1" transform="translate(30.061 0)" fill="#4a4a4a"/>
</g>
<path id="Path_55" data-name="Path 55" d="M.52,0H3.8a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.52A.519.519,0,0,1,.519,0Z" transform="translate(38.234 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_7" data-name="Group 7" transform="translate(0.728 14.084)">
<rect id="Rectangle_63" data-name="Rectangle 63" width="2.537" height="2.537" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_64" data-name="Rectangle 64" width="2.537" height="2.537" rx="1" transform="translate(3.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_65" data-name="Rectangle 65" width="2.537" height="2.537" rx="1" transform="translate(6.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_66" data-name="Rectangle 66" width="2.537" height="2.537" rx="1" transform="translate(9.018 0)" fill="#4a4a4a"/>
<path id="Path_56" data-name="Path 56" d="M.519,0H14.981A.519.519,0,0,1,15.5.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.018V.519A.519.519,0,0,1,.519,0Zm15.97,0h1.874a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H16.489a.519.519,0,0,1-.519-.519V.519A.519.519,0,0,1,16.489,0Z" transform="translate(12.024 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_67" data-name="Rectangle 67" width="2.537" height="2.537" rx="1" transform="translate(31.376 0)" fill="#4a4a4a"/>
<rect id="Rectangle_68" data-name="Rectangle 68" width="2.537" height="2.537" rx="1" transform="translate(34.382 0)" fill="#4a4a4a"/>
<rect id="Rectangle_69" data-name="Rectangle 69" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
<path id="Path_57" data-name="Path 57" d="M2.537,0V.561a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,.561V0Z" transform="translate(39.736 1.08) rotate(180)" fill="#4a4a4a"/>
<path id="Path_58" data-name="Path 58" d="M2.537,0V.561a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,.561V0Z" transform="translate(37.2 1.456)" fill="#4a4a4a"/>
</g>
<rect id="Rectangle_70" data-name="Rectangle 70" width="42.273" height="1.127" rx="0.564" transform="translate(0.915 0.556)" fill="#4a4a4a"/>
<rect id="Rectangle_71" data-name="Rectangle 71" width="2.37" height="0.752" rx="0.376" transform="translate(1.949 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_72" data-name="Rectangle 72" width="2.37" height="0.752" rx="0.376" transform="translate(5.193 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_73" data-name="Rectangle 73" width="2.37" height="0.752" rx="0.376" transform="translate(7.688 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_74" data-name="Rectangle 74" width="2.37" height="0.752" rx="0.376" transform="translate(10.183 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_75" data-name="Rectangle 75" width="2.37" height="0.752" rx="0.376" transform="translate(12.679 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_76" data-name="Rectangle 76" width="2.37" height="0.752" rx="0.376" transform="translate(15.797 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_77" data-name="Rectangle 77" width="2.37" height="0.752" rx="0.376" transform="translate(18.292 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_78" data-name="Rectangle 78" width="2.37" height="0.752" rx="0.376" transform="translate(20.788 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_79" data-name="Rectangle 79" width="2.37" height="0.752" rx="0.376" transform="translate(23.283 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_80" data-name="Rectangle 80" width="2.37" height="0.752" rx="0.376" transform="translate(26.402 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_81" data-name="Rectangle 81" width="2.37" height="0.752" rx="0.376" transform="translate(28.897 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_82" data-name="Rectangle 82" width="2.37" height="0.752" rx="0.376" transform="translate(31.393 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_83" data-name="Rectangle 83" width="2.37" height="0.752" rx="0.376" transform="translate(34.512 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_84" data-name="Rectangle 84" width="2.37" height="0.752" rx="0.376" transform="translate(37.007 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_85" data-name="Rectangle 85" width="2.37" height="0.752" rx="0.376" transform="translate(39.502 0.744)" fill="#d8d8d8" opacity="0.136"/>
</g>
<path id="Path_59" data-name="Path 59" d="M123.779,148.389a2.583,2.583,0,0,0-.332.033c-.02-.078-.038-.156-.06-.234a2.594,2.594,0,1,0-2.567-4.455q-.086-.088-.174-.175a2.593,2.593,0,1,0-4.461-2.569c-.077-.022-.154-.04-.231-.06a2.6,2.6,0,1,0-5.128,0c-.077.02-.154.038-.231.06a2.594,2.594,0,1,0-4.461,2.569,10.384,10.384,0,1,0,17.314,9.992,2.592,2.592,0,1,0,.332-5.161" transform="translate(-51.054 -75.262)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_60" data-name="Path 60" d="M83,113.389h20.779V103H83Z" transform="translate(-41.443 -58.444)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_61" data-name="Path 61" d="M123.389,108.944a1.3,1.3,0,1,0,0-2.6,1.338,1.338,0,0,0-.166.017c-.01-.039-.019-.078-.03-.117a1.3,1.3,0,0,0-.5-2.5,1.285,1.285,0,0,0-.783.269q-.043-.044-.087-.087a1.285,1.285,0,0,0,.263-.776,1.3,1.3,0,0,0-2.493-.509,5.195,5.195,0,1,0,0,10,1.3,1.3,0,0,0,2.493-.509,1.285,1.285,0,0,0-.263-.776q.044-.043.087-.087a1.285,1.285,0,0,0,.783.269,1.3,1.3,0,0,0,.5-2.5c.011-.038.02-.078.03-.117a1.335,1.335,0,0,0,.166.017" transform="translate(-55.859 -57.894)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_62" data-name="Path 62" d="M141.8,38.745a1.41,1.41,0,0,1-.255-.026,1.309,1.309,0,0,1-.244-.073,1.349,1.349,0,0,1-.224-.119,1.967,1.967,0,0,1-.2-.161,1.52,1.52,0,0,1-.161-.2,1.282,1.282,0,0,1-.218-.722,1.41,1.41,0,0,1,.026-.255,1.5,1.5,0,0,1,.072-.244,1.364,1.364,0,0,1,.12-.223,1.252,1.252,0,0,1,.358-.358,1.349,1.349,0,0,1,.224-.119,1.309,1.309,0,0,1,.244-.073,1.2,1.2,0,0,1,.509,0,1.262,1.262,0,0,1,.468.192,1.968,1.968,0,0,1,.2.161,1.908,1.908,0,0,1,.161.2,1.322,1.322,0,0,1,.12.223,1.361,1.361,0,0,1,.1.5,1.317,1.317,0,0,1-.379.919,1.968,1.968,0,0,1-.2.161,1.346,1.346,0,0,1-.223.119,1.332,1.332,0,0,1-.5.1m10.389-.649a1.326,1.326,0,0,1-.92-.379,1.979,1.979,0,0,1-.161-.2,1.282,1.282,0,0,1-.218-.722,1.326,1.326,0,0,1,.379-.919,1.967,1.967,0,0,1,.2-.161,1.351,1.351,0,0,1,.224-.119,1.308,1.308,0,0,1,.244-.073,1.2,1.2,0,0,1,.509,0,1.262,1.262,0,0,1,.468.192,1.967,1.967,0,0,1,.2.161,1.326,1.326,0,0,1,.379.919,1.461,1.461,0,0,1-.026.255,1.323,1.323,0,0,1-.073.244,1.847,1.847,0,0,1-.119.223,1.911,1.911,0,0,1-.161.2,1.967,1.967,0,0,1-.2.161,1.294,1.294,0,0,1-.722.218" transform="translate(-69.074 -26.006)" fill-rule="evenodd"/>
</g>
<g id="React-icon" transform="translate(906.3 541.56)">
<path id="Path_330" data-name="Path 330" d="M263.668,117.179c0-5.827-7.3-11.35-18.487-14.775,2.582-11.4,1.434-20.477-3.622-23.382a7.861,7.861,0,0,0-4.016-1v4a4.152,4.152,0,0,1,2.044.466c2.439,1.4,3.5,6.724,2.672,13.574-.2,1.685-.52,3.461-.914,5.272a86.9,86.9,0,0,0-11.386-1.954,87.469,87.469,0,0,0-7.459-8.965c5.845-5.433,11.332-8.41,15.062-8.41V78h0c-4.931,0-11.386,3.514-17.913,9.611-6.527-6.061-12.982-9.539-17.913-9.539v4c3.712,0,9.216,2.959,15.062,8.356a84.687,84.687,0,0,0-7.405,8.947,83.732,83.732,0,0,0-11.4,1.972c-.412-1.793-.717-3.532-.932-5.2-.843-6.85.2-12.175,2.618-13.592a3.991,3.991,0,0,1,2.062-.466v-4h0a8,8,0,0,0-4.052,1c-5.039,2.9-6.168,11.96-3.568,23.328-11.153,3.443-18.415,8.947-18.415,14.757,0,5.828,7.3,11.35,18.487,14.775-2.582,11.4-1.434,20.477,3.622,23.382a7.882,7.882,0,0,0,4.034,1c4.931,0,11.386-3.514,17.913-9.611,6.527,6.061,12.982,9.539,17.913,9.539a8,8,0,0,0,4.052-1c5.039-2.9,6.168-11.96,3.568-23.328C256.406,128.511,263.668,122.988,263.668,117.179Zm-23.346-11.96c-.663,2.313-1.488,4.7-2.421,7.083-.735-1.434-1.506-2.869-2.349-4.3-.825-1.434-1.7-2.833-2.582-4.2C235.517,104.179,237.974,104.645,240.323,105.219Zm-8.212,19.1c-1.4,2.421-2.833,4.716-4.321,6.85-2.672.233-5.379.359-8.1.359-2.708,0-5.415-.126-8.069-.341q-2.232-3.2-4.339-6.814-2.044-3.523-3.73-7.136c1.112-2.4,2.367-4.805,3.712-7.154,1.4-2.421,2.833-4.716,4.321-6.85,2.672-.233,5.379-.359,8.1-.359,2.708,0,5.415.126,8.069.341q2.232,3.2,4.339,6.814,2.044,3.523,3.73,7.136C234.692,119.564,233.455,121.966,232.11,124.315Zm5.792-2.331c.968,2.4,1.793,4.805,2.474,7.136-2.349.574-4.823,1.058-7.387,1.434.879-1.381,1.757-2.8,2.582-4.25C236.4,124.871,237.167,123.419,237.9,121.984ZM219.72,141.116a73.921,73.921,0,0,1-4.985-5.738c1.614.072,3.263.126,4.931.126,1.685,0,3.353-.036,4.985-.126A69.993,69.993,0,0,1,219.72,141.116ZM206.38,130.555c-2.546-.377-5-.843-7.352-1.417.663-2.313,1.488-4.7,2.421-7.083.735,1.434,1.506,2.869,2.349,4.3S205.5,129.192,206.38,130.555ZM219.63,93.241a73.924,73.924,0,0,1,4.985,5.738c-1.614-.072-3.263-.126-4.931-.126-1.686,0-3.353.036-4.985.126A69.993,69.993,0,0,1,219.63,93.241ZM206.362,103.8c-.879,1.381-1.757,2.8-2.582,4.25-.825,1.434-1.6,2.869-2.331,4.3-.968-2.4-1.793-4.805-2.474-7.136C201.323,104.663,203.8,104.179,206.362,103.8Zm-16.227,22.449c-6.348-2.708-10.454-6.258-10.454-9.073s4.106-6.383,10.454-9.073c1.542-.663,3.228-1.255,4.967-1.811a86.122,86.122,0,0,0,4.034,10.92,84.9,84.9,0,0,0-3.981,10.866C193.38,127.525,191.694,126.915,190.134,126.252Zm9.647,25.623c-2.439-1.4-3.5-6.724-2.672-13.574.2-1.686.52-3.461.914-5.272a86.9,86.9,0,0,0,11.386,1.954,87.465,87.465,0,0,0,7.459,8.965c-5.845,5.433-11.332,8.41-15.062,8.41A4.279,4.279,0,0,1,199.781,151.875Zm42.532-13.663c.843,6.85-.2,12.175-2.618,13.592a3.99,3.99,0,0,1-2.062.466c-3.712,0-9.216-2.959-15.062-8.356a84.689,84.689,0,0,0,7.405-8.947,83.731,83.731,0,0,0,11.4-1.972A50.194,50.194,0,0,1,242.313,138.212Zm6.9-11.96c-1.542.663-3.228,1.255-4.967,1.811a86.12,86.12,0,0,0-4.034-10.92,84.9,84.9,0,0,0,3.981-10.866c1.775.556,3.461,1.165,5.039,1.829,6.348,2.708,10.454,6.258,10.454,9.073C259.67,119.994,255.564,123.562,249.216,126.252Z" fill="#61dafb"/>
<path id="Path_331" data-name="Path 331" d="M320.8,78.4Z" transform="translate(-119.082 -0.328)" fill="#61dafb"/>
<circle id="Ellipse_112" data-name="Ellipse 112" cx="8.194" cy="8.194" r="8.194" transform="translate(211.472 108.984)" fill="#61dafb"/>
<path id="Path_332" data-name="Path 332" d="M520.5,78.1Z" transform="translate(-282.975 -0.082)" fill="#61dafb"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 35 KiB

View file

@ -1,40 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1129" height="663" viewBox="0 0 1129 663">
<title>Focus on What Matters</title>
<circle cx="321" cy="321" r="321" fill="#f2f2f2" />
<ellipse cx="559" cy="635.49998" rx="514" ry="27.50002" fill="#3f3d56" />
<ellipse cx="558" cy="627" rx="460" ry="22" opacity="0.2" />
<rect x="131" y="152.5" width="840" height="50" fill="#3f3d56" />
<path d="M166.5,727.3299A21.67009,21.67009,0,0,0,188.1701,749H984.8299A21.67009,21.67009,0,0,0,1006.5,727.3299V296h-840Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<path d="M984.8299,236H188.1701A21.67009,21.67009,0,0,0,166.5,257.6701V296h840V257.6701A21.67009,21.67009,0,0,0,984.8299,236Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<path d="M984.8299,236H188.1701A21.67009,21.67009,0,0,0,166.5,257.6701V296h840V257.6701A21.67009,21.67009,0,0,0,984.8299,236Z" transform="translate(-35.5 -118.5)" opacity="0.2" />
<circle cx="181" cy="147.5" r="13" fill="#3f3d56" />
<circle cx="217" cy="147.5" r="13" fill="#3f3d56" />
<circle cx="253" cy="147.5" r="13" fill="#3f3d56" />
<rect x="168" y="213.5" width="337" height="386" rx="5.33505" fill="#606060" />
<rect x="603" y="272.5" width="284" height="22" rx="5.47638" fill="#2e8555" />
<rect x="537" y="352.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="396.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="440.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="484.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="865" y="552.5" width="88" height="26" rx="7.02756" fill="#3ecc5f" />
<path d="M1088.60287,624.61594a30.11371,30.11371,0,0,0,3.98291-15.266c0-13.79652-8.54358-24.98081-19.08256-24.98081s-19.08256,11.18429-19.08256,24.98081a30.11411,30.11411,0,0,0,3.98291,15.266,31.248,31.248,0,0,0,0,30.53213,31.248,31.248,0,0,0,0,30.53208,31.248,31.248,0,0,0,0,30.53208,30.11408,30.11408,0,0,0-3.98291,15.266c0,13.79652,8.54353,24.98081,19.08256,24.98081s19.08256-11.18429,19.08256-24.98081a30.11368,30.11368,0,0,0-3.98291-15.266,31.248,31.248,0,0,0,0-30.53208,31.248,31.248,0,0,0,0-30.53208,31.248,31.248,0,0,0,0-30.53213Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<ellipse cx="1038.00321" cy="460.31783" rx="19.08256" ry="24.9808" fill="#3f3d56" />
<ellipse cx="1038.00321" cy="429.78574" rx="19.08256" ry="24.9808" fill="#3f3d56" />
<path d="M1144.93871,339.34489a91.61081,91.61081,0,0,0,7.10658-10.46092l-50.141-8.23491,54.22885.4033a91.566,91.566,0,0,0,1.74556-72.42605l-72.75449,37.74139,67.09658-49.32086a91.41255,91.41255,0,1,0-150.971,102.29805,91.45842,91.45842,0,0,0-10.42451,16.66946l65.0866,33.81447-69.40046-23.292a91.46011,91.46011,0,0,0,14.73837,85.83669,91.40575,91.40575,0,1,0,143.68892,0,91.41808,91.41808,0,0,0,0-113.02862Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M981.6885,395.8592a91.01343,91.01343,0,0,0,19.56129,56.51431,91.40575,91.40575,0,1,0,143.68892,0C1157.18982,436.82067,981.6885,385.60008,981.6885,395.8592Z" transform="translate(-35.5 -118.5)" opacity="0.1" />
<path d="M365.62,461.43628H477.094v45.12043H365.62Z" transform="translate(-35.5 -118.5)" fill="#fff" fill-rule="evenodd" />
<path d="M264.76252,608.74122a26.50931,26.50931,0,0,1-22.96231-13.27072,26.50976,26.50976,0,0,0,22.96231,39.81215H291.304V608.74122Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M384.17242,468.57061l92.92155-5.80726V449.49263a26.54091,26.54091,0,0,0-26.54143-26.54143H331.1161l-3.31768-5.74622a3.83043,3.83043,0,0,0-6.63536,0l-3.31768,5.74622-3.31767-5.74622a3.83043,3.83043,0,0,0-6.63536,0l-3.31768,5.74622L301.257,417.205a3.83043,3.83043,0,0,0-6.63536,0L291.304,422.9512c-.02919,0-.05573.004-.08625.004l-5.49674-5.49541a3.8293,3.8293,0,0,0-6.4071,1.71723l-1.81676,6.77338L270.607,424.1031a3.82993,3.82993,0,0,0-4.6912,4.69253l1.84463,6.89148-6.77072,1.81411a3.8315,3.8315,0,0,0-1.71988,6.40975l5.49673,5.49673c0,.02787-.004.05574-.004.08493l-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74621,3.31768L259.0163,466.081a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31767a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31767a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768L259.0163,558.976a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768A26.54091,26.54091,0,0,0,291.304,635.28265H450.55254A26.5409,26.5409,0,0,0,477.094,608.74122V502.5755l-92.92155-5.80727a14.12639,14.12639,0,0,1,0-28.19762" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M424.01111,635.28265h39.81214V582.19979H424.01111Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M490.36468,602.10586a6.60242,6.60242,0,0,0-.848.08493c-.05042-.19906-.09821-.39945-.15393-.59852A6.62668,6.62668,0,1,0,482.80568,590.21q-.2203-.22491-.44457-.44589a6.62391,6.62391,0,1,0-11.39689-6.56369c-.1964-.05575-.39414-.10218-.59056-.15262a6.63957,6.63957,0,1,0-13.10086,0c-.1964.05042-.39414.09687-.59056.15262a6.62767,6.62767,0,1,0-11.39688,6.56369,26.52754,26.52754,0,1,0,44.23127,25.52756,6.6211,6.6211,0,1,0,.848-13.18579" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M437.28182,555.65836H477.094V529.11693H437.28182Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M490.36468,545.70532a3.31768,3.31768,0,0,0,0-6.63536,3.41133,3.41133,0,0,0-.42333.04247c-.02655-.09953-.04911-.19907-.077-.29859a3.319,3.319,0,0,0-1.278-6.37923,3.28174,3.28174,0,0,0-2.00122.68742q-.10947-.11346-.22294-.22295a3.282,3.282,0,0,0,.67149-1.98265,3.31768,3.31768,0,0,0-6.37-1.2992,13.27078,13.27078,0,1,0,0,25.54082,3.31768,3.31768,0,0,0,6.37-1.2992,3.282,3.282,0,0,0-.67149-1.98265q.11347-.10947.22294-.22294a3.28174,3.28174,0,0,0,2.00122.68742,3.31768,3.31768,0,0,0,1.278-6.37923c.02786-.0982.05042-.19907.077-.29859a3.41325,3.41325,0,0,0,.42333.04246" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M317.84538,466.081a3.31768,3.31768,0,0,1-3.31767-3.31768,9.953,9.953,0,1,0-19.90608,0,3.31768,3.31768,0,1,1-6.63535,0,16.58839,16.58839,0,1,1,33.17678,0,3.31768,3.31768,0,0,1-3.31768,3.31768" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
<path d="M370.92825,635.28265h79.62429A26.5409,26.5409,0,0,0,477.094,608.74122v-92.895H397.46968a26.54091,26.54091,0,0,0-26.54143,26.54143Z" transform="translate(-35.5 -118.5)" fill="#ffff50" fill-rule="evenodd" />
<path d="M457.21444,556.98543H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,1,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,1,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0-66.10674H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.29459H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414M477.094,474.19076c-.01592,0-.0292-.008-.04512-.00663-4.10064.13934-6.04083,4.24132-7.75274,7.86024-1.78623,3.78215-3.16771,6.24122-5.43171,6.16691-2.50685-.09024-3.94007-2.92222-5.45825-5.91874-1.74377-3.44243-3.73438-7.34667-7.91333-7.20069-4.04227.138-5.98907,3.70784-7.70631,6.857-1.82738,3.35484-3.07084,5.39455-5.46887,5.30033-2.55727-.09289-3.91619-2.39536-5.48877-5.06013-1.75306-2.96733-3.77951-6.30359-7.8775-6.18946-3.97326.13669-5.92537,3.16507-7.64791,5.83912-1.82207,2.82666-3.09872,4.5492-5.52725,4.447-2.61832-.09289-3.9706-2.00388-5.53522-4.21611-1.757-2.4856-3.737-5.299-7.82308-5.16231-3.88567.13271-5.83779,2.61434-7.559,4.80135-1.635,2.07555-2.9116,3.71846-5.61218,3.615a1.32793,1.32793,0,1,0-.09555,2.65414c4.00377.134,6.03154-2.38873,7.79257-4.6275,1.562-1.9853,2.91027-3.69855,5.56441-3.78879,2.55594-.10882,3.75429,1.47968,5.56707,4.04093,1.7212,2.43385,3.67465,5.19416,7.60545,5.33616,4.11789.138,6.09921-2.93946,7.8536-5.66261,1.56861-2.43385,2.92221-4.53461,5.50734-4.62352,2.37944-.08892,3.67466,1.79154,5.50072,4.885,1.72121,2.91557,3.67069,6.21865,7.67977,6.36463,4.14709.14332,6.14965-3.47693,7.89475-6.68181,1.51155-2.77092,2.93814-5.38791,5.46621-5.4755,2.37944-.05573,3.62025,2.11668,5.45558,5.74622,1.71459,3.388,3.65875,7.22591,7.73019,7.37321l.22429.004c4.06614,0,5.99571-4.08074,7.70364-7.68905,1.51154-3.19825,2.94211-6.21069,5.3972-6.33411Z" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
<path d="M344.38682,635.28265h53.08286V582.19979H344.38682Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M424.01111,602.10586a6.60242,6.60242,0,0,0-.848.08493c-.05042-.19906-.09821-.39945-.15394-.59852A6.62667,6.62667,0,1,0,416.45211,590.21q-.2203-.22491-.44458-.44589a6.62391,6.62391,0,1,0-11.39689-6.56369c-.1964-.05575-.39413-.10218-.59054-.15262a6.63957,6.63957,0,1,0-13.10084,0c-.19641.05042-.39414.09687-.59055.15262a6.62767,6.62767,0,1,0-11.39689,6.56369,26.52755,26.52755,0,1,0,44.2313,25.52756,6.6211,6.6211,0,1,0,.848-13.18579" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M344.38682,555.65836h53.08286V529.11693H344.38682Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M410.74039,545.70532a3.31768,3.31768,0,1,0,0-6.63536,3.41133,3.41133,0,0,0-.42333.04247c-.02655-.09953-.04911-.19907-.077-.29859a3.319,3.319,0,0,0-1.278-6.37923,3.28174,3.28174,0,0,0-2.00122.68742q-.10947-.11346-.22294-.22295a3.282,3.282,0,0,0,.67149-1.98265,3.31768,3.31768,0,0,0-6.37-1.2992,13.27078,13.27078,0,1,0,0,25.54082,3.31768,3.31768,0,0,0,6.37-1.2992,3.282,3.282,0,0,0-.67149-1.98265q.11347-.10947.22294-.22294a3.28174,3.28174,0,0,0,2.00122.68742,3.31768,3.31768,0,0,0,1.278-6.37923c.02786-.0982.05042-.19907.077-.29859a3.41325,3.41325,0,0,0,.42333.04246" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M424.01111,447.8338a3.60349,3.60349,0,0,1-.65028-.06636,3.34415,3.34415,0,0,1-.62372-.18579,3.44679,3.44679,0,0,1-.572-.30522,5.02708,5.02708,0,0,1-.50429-.4114,3.88726,3.88726,0,0,1-.41007-.50428,3.27532,3.27532,0,0,1-.55737-1.84463,3.60248,3.60248,0,0,1,.06636-.65027,3.82638,3.82638,0,0,1,.18447-.62373,3.48858,3.48858,0,0,1,.30656-.57064,3.197,3.197,0,0,1,.91436-.91568,3.44685,3.44685,0,0,1,.572-.30523,3.344,3.344,0,0,1,.62372-.18578,3.06907,3.06907,0,0,1,1.30053,0,3.22332,3.22332,0,0,1,1.19436.491,5.02835,5.02835,0,0,1,.50429.41139,4.8801,4.8801,0,0,1,.41139.50429,3.38246,3.38246,0,0,1,.30522.57064,3.47806,3.47806,0,0,1,.25215,1.274A3.36394,3.36394,0,0,1,426.36,446.865a5.02708,5.02708,0,0,1-.50429.4114,3.3057,3.3057,0,0,1-1.84463.55737m26.54143-1.65884a3.38754,3.38754,0,0,1-2.35024-.96877,5.04185,5.04185,0,0,1-.41007-.50428,3.27532,3.27532,0,0,1-.55737-1.84463,3.38659,3.38659,0,0,1,.96744-2.34892,5.02559,5.02559,0,0,1,.50429-.41139,3.44685,3.44685,0,0,1,.572-.30523,3.3432,3.3432,0,0,1,.62373-.18579,3.06952,3.06952,0,0,1,1.30052,0,3.22356,3.22356,0,0,1,1.19436.491,5.02559,5.02559,0,0,1,.50429.41139,3.38792,3.38792,0,0,1,.96876,2.34892,3.72635,3.72635,0,0,1-.06636.65026,3.37387,3.37387,0,0,1-.18579.62373,4.71469,4.71469,0,0,1-.30522.57064,4.8801,4.8801,0,0,1-.41139.50429,5.02559,5.02559,0,0,1-.50429.41139,3.30547,3.30547,0,0,1-1.84463.55737" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

View file

@ -1,7 +0,0 @@
{
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": "."
}
}

124
src/README.md Normal file
View file

@ -0,0 +1,124 @@
<div align="center">
<img src="https://pragmatismo.com.br/icons/general-bots-text.svg" alt="General Bots" width="400">
</div>
# General Bots Documentation
Welcome to the General Bots documentation. This guide explains how to install, configure, extend, and deploy conversational AI bots using General Bots' template-based package system and BASIC scripting language.
## About This Documentation
This documentation has been recently updated to accurately reflect the actual implementation of General Bots version 6.0.8.
The following chapters now contain accurate, verified documentation: Chapter 02 covering the package system with its template-based `.gbai` structure, Chapter 06 documenting the Rust architecture including the single-crate structure and module overview, Chapter 09 explaining core features, and the Introduction providing architecture and capabilities overview.
Several areas have partial documentation that continues to improve. Chapter 05 on BASIC keywords includes working examples though the full reference needs expansion. Chapter 08 on tool integration has concepts documented while implementation details are being added. Chapter 11 on authentication reflects the implemented functionality but needs additional detail.
Documentation work continues on several modules. The UI module in `src/ui/`, the UI tree module in `src/ui_tree/`, the Riot compiler module in `src/riot_compiler/`, and the prompt manager in `src/prompt_manager/` all need comprehensive documentation. API endpoints, UI server routes, Drive integration details for S3-compatible storage, and LiveKit video conferencing integration are also being documented.
## What is General Bots?
General Bots is an open-source conversational AI platform written in Rust. The platform enables users to create intelligent chatbots through several integrated capabilities.
BASIC Scripting provides simple `.bas` scripts for defining conversation flows without requiring traditional programming expertise. Template Packages organize bots as `.gbai` directories containing dialogs, knowledge bases, and configuration in a portable structure. Vector Search enables semantic document retrieval using Qdrant for intelligent information access. LLM Integration connects to local models, cloud APIs, and custom providers for natural language understanding. Auto-Bootstrap handles automated installation of PostgreSQL, cache, drive storage, and other dependencies. Multi-Bot Hosting allows running multiple isolated bots on a single server instance.
## Quick Start
Getting started with General Bots follows a straightforward path. Begin with installation by following Chapter 01 on Run and Talk. Then explore the templates directory, particularly `templates/announcements.gbai/`, to see working examples. Create your own bot by copying a template and modifying it to suit your needs. Learn the BASIC scripting language through Chapter 05's reference documentation. Configure your bot by editing the `config.csv` file in your `.gbot/` directory. Finally, deploy by restarting General Bots to activate your changes.
## Table of Contents
### Part I - Getting Started
Chapter 01 on Run and Talk covers installation and your first conversation with a bot.
### Part II - Package System
Chapter 02 on About Packages provides an overview of the template-based package system. This includes the `.gbai` Architecture explaining package structure and lifecycle, `.gbdialog` Dialogs for BASIC scripts, `.gbkb` Knowledge Base for document collections, `.gbot` Configuration for bot parameters, `.gbtheme` UI Theming for web interface customization, and `.gbdrive` File Storage for S3-compatible drive integration.
### Part III - Knowledge Base
Chapter 03 on gbkb Reference covers semantic search and vector database functionality.
### Part IV - User Interface
Chapter 04 on .gbui Interface Reference documents HTML templates and UI components.
### Part V - Themes and Styling
Chapter 05 on gbtheme CSS Reference explains CSS-based theme customization.
### Part VI - BASIC Dialogs
Chapter 06 on gbdialog Reference provides the complete BASIC scripting reference including keywords like TALK, HEAR, LLM, SET CONTEXT, USE KB, and many more.
### Part VII - Extending General Bots
Chapter 07 on gbapp Architecture Reference documents the internal architecture. This includes the Architecture Overview explaining the bootstrap process, Building from Source for compilation and features, Module Structure describing single-crate organization, Service Layer with module descriptions, Creating Custom Keywords for extending BASIC, and Adding Dependencies for Cargo.toml management.
### Part VIII - Bot Configuration
Chapter 08 on gbot Reference covers configuration and parameters.
### Part IX - Tools and Integration
Chapter 09 on API and Tooling explains function calling and tool integration.
### Part X - Feature Deep Dive
Chapter 10 on Feature Reference provides the complete feature list including Core Features documenting platform capabilities.
### Part XI - Community
Chapter 11 on Contributing provides development and contribution guidelines.
### Part XII - Authentication and Security
Chapter 12 on Authentication documents security features.
### Appendices
Appendix I on Database Model provides schema reference. The Glossary defines terms used throughout the documentation.
## Architecture Overview
General Bots is a monolithic Rust application organized as a single crate with clearly defined modules serving different purposes.
### Core Modules
The core modules handle fundamental bot functionality. The auth module provides Argon2 password hashing and session token management. The bot module manages bot lifecycle and coordination. The session module maintains persistent conversation state across interactions. The basic module implements the BASIC interpreter powered by the Rhai scripting engine. The llm and llm_models modules handle LLM provider integration for multiple backends. The context module manages conversation memory and context window optimization.
### Infrastructure Modules
Infrastructure modules provide the foundation for bot operations. The bootstrap module handles auto-installation of all required components. The package_manager module manages PostgreSQL, cache, drive storage, and other services. The web_server module implements the Axum HTTP REST API. The drive module integrates S3-compatible storage and vector database access. The config module handles environment configuration loading and validation.
### Feature Modules
Feature modules add specific capabilities to the platform. The automation module provides cron scheduling and event-driven processing. The email module offers optional IMAP and SMTP integration. The meet module enables LiveKit video conferencing. The channels module supports multi-channel deployment across different platforms. The file module handles document processing for PDF and other formats. The drive_monitor module watches file system changes for automatic updates.
## Technology Stack
General Bots is built on a modern Rust technology stack. The application uses Rust 2021 edition for safety and performance. Web handling uses Axum combined with Tower middleware and Tokio async runtime. Database access uses the Diesel ORM with PostgreSQL as the backing store. Caching uses a Redis-compatible cache component for session and data caching. Storage uses the AWS SDK for S3-compatible drive operations. Vector database functionality uses Qdrant for semantic search when enabled. Scripting uses the Rhai engine to power the BASIC interpreter. Security uses Argon2 for password hashing and AES-GCM for encryption. Optional desktop deployment uses Tauri for native applications.
## Project Information
The current version is 6.0.8 released under the AGPL-3.0 license. The source repository is available at https://github.com/GeneralBots/botserver. The project is maintained by open-source contributors from Pragmatismo.com.br and the broader community.
## Documentation Status
This documentation is a living document that evolves alongside the codebase. Contributions are welcome from anyone who wants to improve it.
If you find inaccuracies or gaps in the documentation, the best approach is to check the source code in `src/` for the ground truth implementation. Submit documentation improvements via pull requests on GitHub. Report issues through the GitHub issue tracker so they can be tracked and addressed.
## Next Steps
Start with the Introduction for a comprehensive overview of General Bots concepts and capabilities. Alternatively, jump directly to Chapter 01 on Run and Talk to install and run General Bots immediately.

370
src/SUMMARY.md Normal file
View file

@ -0,0 +1,370 @@
# Summary
[Executive Vision](./executive-vision.md)
[Introduction](./introduction.md)
# Part I - Getting Started
- [Chapter 01: Run and Talk](./chapter-01/README.md)
- [Overview](./chapter-01/overview.md)
- [Quick Start](./chapter-01/quick-start.md)
- [Installation](./chapter-01/installation.md)
- [First Conversation](./chapter-01/first-conversation.md)
- [Sessions and Channels](./chapter-01/sessions.md)
# Part II - Package System
- [Chapter 02: About Packages](./chapter-02/README.md)
- [.gbai Architecture](./chapter-02/gbai.md)
- [.gbdialog Dialogs](./chapter-02/gbdialog.md)
- [.gbkb Knowledge Base](./chapter-02/gbkb.md)
- [.gbot Bot Configuration](./chapter-02/gbot.md)
- [.gbtheme UI Theming](./chapter-02/gbtheme.md)
- [.gbdrive File Storage](./chapter-02/gbdrive.md)
- [Bot Templates](./chapter-02/templates.md)
- [Template Samples & Conversations](./chapter-02/template-samples.md)
- [Template: Business Intelligence](./chapter-02/template-bi.md)
- [Template: Web Crawler](./chapter-02/template-crawler.md)
- [Template: Legal Documents](./chapter-02/template-law.md)
- [Template: LLM Server](./chapter-02/template-llm-server.md)
- [Template: LLM Tools](./chapter-02/template-llm-tools.md)
- [Template: API Client](./chapter-02/template-api-client.md)
- [Template: Platform Analytics](./chapter-02/template-analytics.md)
- [Template: Office Automation](./chapter-02/template-office.md)
- [Template: Reminders](./chapter-02/template-reminder.md)
- [Template: Sales CRM](./chapter-02/template-crm.md)
- [Template: CRM Contacts](./chapter-02/template-crm-contacts.md)
- [Template: Marketing](./chapter-02/template-marketing.md)
- [Template: Creating Templates](./chapter-02/template-template.md)
# Part III - Knowledge Base
- [Chapter 03: gbkb Reference](./chapter-03/README.md)
- [KB and Tools System](./chapter-03/kb-and-tools.md)
- [Vector Collections](./chapter-03/vector-collections.md)
- [Document Indexing](./chapter-03/indexing.md)
- [Semantic Search](./chapter-03/semantic-search.md)
- [Episodic Memory](./chapter-03/episodic-memory.md)
- [Semantic Caching](./chapter-03/caching.md)
# Part IV - User Interface
- [Chapter 04: .gbui Interface Reference](./chapter-04-gbui/README.md)
- [Suite User Manual](./chapter-04-gbui/suite-manual.md)
- [UI Structure](./chapter-04-gbui/ui-structure.md)
- [single.gbui - Simple Chat](./chapter-04-gbui/single-gbui.md)
- [Console Mode](./chapter-04-gbui/console-mode.md)
- [Monitoring Dashboard](./chapter-04-gbui/monitoring.md)
- [HTMX Architecture](./chapter-04-gbui/htmx-architecture.md)
- [Suite Applications](./chapter-04-gbui/apps/README.md)
- [Suite - Full Desktop](./chapter-04-gbui/apps/suite.md)
- [Chat - AI Assistant](./chapter-04-gbui/apps/chat.md)
- [Drive - File Management](./chapter-04-gbui/apps/drive.md)
- [Tasks - To-Do Lists](./chapter-04-gbui/apps/tasks.md)
- [Mail - Email Client](./chapter-04-gbui/apps/mail.md)
- [Calendar - Scheduling](./chapter-04-gbui/apps/calendar.md)
- [Meet - Video Calls](./chapter-04-gbui/apps/meet.md)
- [Player - Media Viewer](./chapter-04-gbui/apps/player.md)
- [Paper - AI Writing](./chapter-04-gbui/apps/paper.md)
- [Research - AI Search](./chapter-04-gbui/apps/research.md)
- [Analytics - Dashboards](./chapter-04-gbui/apps/analytics.md)
- [Designer - Visual Builder](./chapter-04-gbui/apps/designer.md)
- [Sources - Prompts & Templates](./chapter-04-gbui/apps/sources.md)
- [Compliance - Security Scanner](./chapter-04-gbui/apps/compliance.md)
- [Compliance API Reference](./chapter-04-gbui/apps/compliance-api.md)
- [How-To Tutorials](./chapter-04-gbui/how-to/README.md)
- [Create Your First Bot](./chapter-04-gbui/how-to/create-first-bot.md)
- [Write Your First Dialog](./chapter-04-gbui/how-to/write-first-dialog.md)
- [Add Documents to Knowledge Base](./chapter-04-gbui/how-to/add-kb-documents.md)
- [Connect WhatsApp](./chapter-04-gbui/how-to/connect-whatsapp.md)
- [Monitor Your Bot](./chapter-04-gbui/how-to/monitor-sessions.md)
# Part V - Themes and Styling
- [Chapter 05: gbtheme CSS Reference](./chapter-05-gbtheme/README.md)
- [Theme Structure](./chapter-05-gbtheme/structure.md)
- [CSS Customization](./chapter-05-gbtheme/css.md)
# Part VI - BASIC Dialogs
- [Chapter 06: gbdialog Reference](./chapter-06-gbdialog/README.md)
- [Dialog Basics](./chapter-06-gbdialog/basics.md)
- [Universal Messaging & Multi-Channel](./chapter-06-gbdialog/universal-messaging.md)
- [BASIC vs n8n/Zapier/Make](./chapter-06-gbdialog/basic-vs-automation-tools.md)
- [Template Variables](./chapter-06-gbdialog/template-variables.md)
- [Template Examples](./chapter-06-gbdialog/templates.md)
- [start.bas](./chapter-06-gbdialog/templates/start.md)
- [enrollment.bas](./chapter-06-gbdialog/templates/enrollment.md)
- [auth.bas](./chapter-06-gbdialog/templates/auth.md)
- [ai-search.bas](./chapter-06-gbdialog/templates/ai-search.md)
- [analytics-dashboard.bas](./chapter-06-gbdialog/templates/analytics-dashboard.md)
- [announcements.bas](./chapter-06-gbdialog/templates/announcements.md)
- [backup.bas](./chapter-06-gbdialog/templates/backup.md)
- [bank.bas](./chapter-06-gbdialog/templates/bank.md)
- [broadcast.bas](./chapter-06-gbdialog/templates/broadcast.md)
- [default.bas](./chapter-06-gbdialog/templates/default.md)
- [edu.bas](./chapter-06-gbdialog/templates/edu.md)
- [employees.bas](./chapter-06-gbdialog/templates/employees.md)
- [erp.bas](./chapter-06-gbdialog/templates/erp.md)
- [helpdesk.bas](./chapter-06-gbdialog/templates/helpdesk.md)
- [privacy.bas](./chapter-06-gbdialog/templates/privacy.md)
- [sales-pipeline.bas](./chapter-06-gbdialog/templates/sales-pipeline.md)
- [store.bas](./chapter-06-gbdialog/templates/store.md)
- [talk-to-data.bas](./chapter-06-gbdialog/templates/talk-to-data.md)
- [whatsapp.bas](./chapter-06-gbdialog/templates/whatsapp.md)
- [Consolidated Examples](./chapter-06-gbdialog/examples-consolidated.md)
- [Data Sync Tools](./chapter-06-gbdialog/tools-data-sync.md)
- [Keywords Reference](./chapter-06-gbdialog/keywords.md)
- [TALK](./chapter-06-gbdialog/keyword-talk.md)
- [HEAR](./chapter-06-gbdialog/keyword-hear.md)
- [SET CONTEXT](./chapter-06-gbdialog/keyword-set-context.md)
- [GET BOT MEMORY](./chapter-06-gbdialog/keyword-get-bot-memory.md)
- [SET BOT MEMORY](./chapter-06-gbdialog/keyword-set-bot-memory.md)
- [GET USER MEMORY](./chapter-06-gbdialog/keyword-get-user-memory.md)
- [SET USER MEMORY](./chapter-06-gbdialog/keyword-set-user-memory.md)
- [REMEMBER / RECALL](./chapter-06-gbdialog/keyword-remember.md)
- [BOOK / BOOK_MEETING](./chapter-06-gbdialog/keyword-book.md)
- [WEATHER / FORECAST](./chapter-06-gbdialog/keyword-weather.md)
- [ADD BOT](./chapter-06-gbdialog/keyword-add-bot.md)
- [ADD MEMBER](./chapter-06-gbdialog/keyword-add-member.md)
- [ADD SUGGESTION](./chapter-06-gbdialog/keyword-add-suggestion.md)
- [MODEL ROUTE](./chapter-06-gbdialog/keyword-model-route.md)
- [SEND TEMPLATE](./chapter-06-gbdialog/keyword-send-template.md)
- [SET USER](./chapter-06-gbdialog/keyword-set-user.md)
- [USE MODEL](./chapter-06-gbdialog/keyword-use-model.md)
- [DELEGATE TO BOT](./chapter-06-gbdialog/keyword-delegate-to-bot.md)
- [BOT REFLECTION](./chapter-06-gbdialog/keyword-bot-reflection.md)
- [RUN PYTHON / JAVASCRIPT / BASH](./chapter-06-gbdialog/keyword-run-code.md)
- [USE KB](./chapter-06-gbdialog/keyword-use-kb.md)
- [CLEAR KB](./chapter-06-gbdialog/keyword-clear-kb.md)
- [USE WEBSITE](./chapter-06-gbdialog/keyword-use-website.md)
- [USE TOOL](./chapter-06-gbdialog/keyword-use-tool.md)
- [CLEAR TOOLS](./chapter-06-gbdialog/keyword-clear-tools.md)
- [GET](./chapter-06-gbdialog/keyword-get.md)
- [SET](./chapter-06-gbdialog/keyword-set.md)
- [ON](./chapter-06-gbdialog/keyword-on.md)
- [SET SCHEDULE](./chapter-06-gbdialog/keyword-set-schedule.md)
- [CREATE SITE](./chapter-06-gbdialog/keyword-create-site.md)
- [CREATE DRAFT](./chapter-06-gbdialog/keyword-create-draft.md)
- [CREATE TASK](./chapter-06-gbdialog/keyword-create-task.md)
- [PRINT](./chapter-06-gbdialog/keyword-print.md)
- [WAIT](./chapter-06-gbdialog/keyword-wait.md)
- [FORMAT](./chapter-06-gbdialog/keyword-format.md)
- [FIRST](./chapter-06-gbdialog/keyword-first.md)
- [LAST](./chapter-06-gbdialog/keyword-last.md)
- [FOR EACH](./chapter-06-gbdialog/keyword-for-each.md)
- [EXIT FOR](./chapter-06-gbdialog/keyword-exit-for.md)
- [SEND MAIL](./chapter-06-gbdialog/keyword-send-mail.md)
- [FIND](./chapter-06-gbdialog/keyword-find.md)
- [INSTR](./chapter-06-gbdialog/keyword-instr.md)
- [IS NUMERIC](./chapter-06-gbdialog/keyword-is-numeric.md)
- [SWITCH](./chapter-06-gbdialog/keyword-switch.md)
- [WEBHOOK](./chapter-06-gbdialog/keyword-webhook.md)
- [TABLE](./chapter-06-gbdialog/keyword-table.md)
- [KB Statistics Keywords](./chapter-06-gbdialog/keywords-kb-statistics.md)
- [KB STATISTICS](./chapter-06-gbdialog/keyword-kb-statistics.md)
- [KB COLLECTION STATS](./chapter-06-gbdialog/keyword-kb-collection-stats.md)
- [KB DOCUMENTS COUNT](./chapter-06-gbdialog/keyword-kb-documents-count.md)
- [KB DOCUMENTS ADDED SINCE](./chapter-06-gbdialog/keyword-kb-documents-added-since.md)
- [KB LIST COLLECTIONS](./chapter-06-gbdialog/keyword-kb-list-collections.md)
- [KB STORAGE SIZE](./chapter-06-gbdialog/keyword-kb-storage-size.md)
- [Multi-Agent Keywords](./chapter-06-gbdialog/keywords-multi-agent.md)
- [Social Media Keywords](./chapter-06-gbdialog/keywords-social-media.md)
- [Lead Scoring Keywords](./chapter-06-gbdialog/keywords-lead-scoring.md)
- [HTTP & API Operations](./chapter-06-gbdialog/keywords-http.md)
- [POST](./chapter-06-gbdialog/keyword-post.md)
- [PUT](./chapter-06-gbdialog/keyword-put.md)
- [PATCH](./chapter-06-gbdialog/keyword-patch.md)
- [DELETE HTTP](./chapter-06-gbdialog/keyword-delete-http.md)
- [SET HEADER](./chapter-06-gbdialog/keyword-set-header.md)
- [GRAPHQL](./chapter-06-gbdialog/keyword-graphql.md)
- [SOAP](./chapter-06-gbdialog/keyword-soap.md)
- [Data Operations](./chapter-06-gbdialog/keywords-data.md)
- [SAVE](./chapter-06-gbdialog/keyword-save.md)
- [INSERT](./chapter-06-gbdialog/keyword-insert.md)
- [UPDATE](./chapter-06-gbdialog/keyword-update.md)
- [DELETE](./chapter-06-gbdialog/keyword-delete.md)
- [MERGE](./chapter-06-gbdialog/keyword-merge.md)
- [FILL](./chapter-06-gbdialog/keyword-fill.md)
- [MAP](./chapter-06-gbdialog/keyword-map.md)
- [FILTER](./chapter-06-gbdialog/keyword-filter.md)
- [AGGREGATE](./chapter-06-gbdialog/keyword-aggregate.md)
- [JOIN](./chapter-06-gbdialog/keyword-join.md)
- [PIVOT](./chapter-06-gbdialog/keyword-pivot.md)
- [GROUP BY](./chapter-06-gbdialog/keyword-group-by.md)
- [Media & Messaging](./chapter-06-gbdialog/keywords-media.md)
- [PLAY](./chapter-06-gbdialog/keyword-play.md)
- [QR CODE](./chapter-06-gbdialog/keyword-qrcode.md)
- [SEND SMS](./chapter-06-gbdialog/keyword-sms.md)
- [File Operations](./chapter-06-gbdialog/keywords-file.md)
- [READ](./chapter-06-gbdialog/keyword-read.md)
- [WRITE](./chapter-06-gbdialog/keyword-write.md)
- [DELETE FILE](./chapter-06-gbdialog/keyword-delete-file.md)
- [COPY](./chapter-06-gbdialog/keyword-copy.md)
- [MOVE](./chapter-06-gbdialog/keyword-move.md)
- [LIST](./chapter-06-gbdialog/keyword-list.md)
- [COMPRESS](./chapter-06-gbdialog/keyword-compress.md)
- [EXTRACT](./chapter-06-gbdialog/keyword-extract.md)
- [UPLOAD](./chapter-06-gbdialog/keyword-upload.md)
- [DOWNLOAD](./chapter-06-gbdialog/keyword-download.md)
- [GENERATE PDF](./chapter-06-gbdialog/keyword-generate-pdf.md)
- [MERGE PDF](./chapter-06-gbdialog/keyword-merge-pdf.md)
# Part VII - Extending General Bots
- [Chapter 07: gbapp Architecture Reference](./chapter-07-gbapp/README.md)
- [Architecture Overview](./chapter-07-gbapp/architecture.md)
- [Building from Source](./chapter-07-gbapp/building.md)
- [Container Deployment (LXC)](./chapter-07-gbapp/containers.md)
- [Docker Deployment](./chapter-07-gbapp/docker-deployment.md)
- [Scaling and Load Balancing](./chapter-07-gbapp/scaling.md)
- [Infrastructure Design](./chapter-07-gbapp/infrastructure.md)
- [Observability](./chapter-07-gbapp/observability.md)
- [Philosophy](./chapter-07-gbapp/philosophy.md)
- [Example gbapp](./chapter-07-gbapp/example-gbapp.md)
- [Module Structure](./chapter-07-gbapp/crates.md)
- [Service Layer](./chapter-07-gbapp/services.md)
- [Creating Custom Keywords](./chapter-07-gbapp/custom-keywords.md)
- [Adding Dependencies](./chapter-07-gbapp/dependencies.md)
# Part VIII - Bot Configuration
- [Chapter 08: gbot Reference](./chapter-08-config/README.md)
- [config.csv Format](./chapter-08-config/config-csv.md)
- [Bot Parameters](./chapter-08-config/parameters.md)
- [LLM Configuration](./chapter-08-config/llm-config.md)
- [Context Configuration](./chapter-08-config/context-config.md)
- [Drive Integration](./chapter-08-config/drive.md)
- [Multimodal Configuration](./chapter-08-config/multimodal.md)
- [Secrets Management](./chapter-08-config/secrets-management.md)
# Part IX - Tools and Integration
- [Chapter 09: API and Tooling](./chapter-09-api/README.md)
- [Tool Definition](./chapter-09-api/tool-definition.md)
- [PARAM Declaration](./chapter-09-api/param-declaration.md)
- [Tool Compilation](./chapter-09-api/compilation.md)
- [MCP Format](./chapter-09-api/mcp-format.md)
- [Tool Format](./chapter-09-api/openai-format.md)
- [GET Keyword Integration](./chapter-09-api/get-integration.md)
- [External APIs](./chapter-09-api/external-apis.md)
- [LLM REST Server](./chapter-09-api/llm-rest-server.md)
- [NVIDIA GPU Setup for LXC](./chapter-09-api/nvidia-gpu-setup.md)
- [Chapter 10: REST API Reference](./chapter-10-api/README.md)
- [Files API](./chapter-10-api/files-api.md)
- [Document Processing API](./chapter-10-api/document-processing.md)
- [Users API](./chapter-10-api/users-api.md)
- [User Security API](./chapter-10-api/user-security.md)
- [Groups API](./chapter-10-api/groups-api.md)
- [Group Membership API](./chapter-10-api/group-membership.md)
- [Conversations API](./chapter-10-api/conversations-api.md)
- [Calls API](./chapter-10-api/calls-api.md)
- [Whiteboard API](./chapter-10-api/whiteboard-api.md)
- [Email API](./chapter-10-api/email-api.md)
- [Notifications API](./chapter-10-api/notifications-api.md)
- [Calendar API](./chapter-10-api/calendar-api.md)
- [Tasks API](./chapter-10-api/tasks-api.md)
- [Storage API](./chapter-10-api/storage-api.md)
- [Backup API](./chapter-10-api/backup-api.md)
- [Analytics API](./chapter-10-api/analytics-api.md)
- [Reports API](./chapter-10-api/reports-api.md)
- [Admin API](./chapter-10-api/admin-api.md)
- [Monitoring API](./chapter-10-api/monitoring-api.md)
- [AI API](./chapter-10-api/ai-api.md)
- [ML API](./chapter-10-api/ml-api.md)
- [Security API](./chapter-10-api/security-api.md)
- [Compliance API](./chapter-10-api/compliance-api.md)
- [Example Integrations](./chapter-10-api/examples.md)
# Part X - Feature Deep Dive
- [Chapter 11: Feature Reference](./chapter-11-features/README.md)
- [Feature Editions](./chapter-11-features/editions.md)
- [Core Features](./chapter-11-features/core-features.md)
- [Conversation Management](./chapter-11-features/conversation.md)
- [AI and LLM](./chapter-11-features/ai-llm.md)
- [Knowledge Base](./chapter-11-features/knowledge-base.md)
- [Automation](./chapter-11-features/automation.md)
- [Email Integration](./chapter-11-features/email.md)
- [Storage and Data](./chapter-11-features/storage.md)
- [Multi-Channel Support](./chapter-11-features/channels.md)
- [Drive Monitor](./chapter-11-features/drive-monitor.md)
- [Platform Capabilities](./chapter-11-features/platform-comparison.md)
- [Enterprise Platform Migration](./chapter-11-features/m365-comparison.md)
- [Projects](./chapter-11-features/projects.md)
- [Multi-Agent Office Suite Design](./chapter-11-features/multi-agent-design.md)
- [What's New: Multi-Agent Features](./chapter-11-features/whats-new.md)
- [Multi-Agent Orchestration](./chapter-11-features/multi-agent-orchestration.md)
- [Memory Management](./chapter-11-features/memory-management.md)
- [Hybrid RAG Search](./chapter-11-features/hybrid-search.md)
# Part XI - Security
- [Chapter 12: Authentication & Permissions](./chapter-12-auth/README.md)
- [User Authentication](./chapter-12-auth/user-auth.md)
- [Password Security](./chapter-12-auth/password-security.md)
- [API Endpoints](./chapter-12-auth/api-endpoints.md)
- [Bot Authentication](./chapter-12-auth/bot-auth.md)
- [Security Features](./chapter-12-auth/security-features.md)
- [Security Policy](./chapter-12-auth/security-policy.md)
- [Compliance Requirements](./chapter-12-auth/compliance-requirements.md)
- [Permissions Matrix](./chapter-12-auth/permissions-matrix.md)
- [User Context vs System Context](./chapter-12-auth/user-system-context.md)
# Part XII - Community
- [Chapter 13: Contributing](./chapter-13-community/README.md)
- [Development Setup](./chapter-13-community/setup.md)
- [Testing Guide](./chapter-13-community/testing.md)
- [Documentation](./chapter-13-community/documentation.md)
- [Pull Requests](./chapter-13-community/pull-requests.md)
- [Community Guidelines](./chapter-13-community/community.md)
- [IDEs](./chapter-13-community/ide-extensions.md)
# Part XIII - Migration
- [Chapter 14: Migration Guide](./chapter-14-migration/README.md)
- [Migration Overview](./chapter-14-migration/overview.md)
- [Platform Comparison Matrix](./chapter-14-migration/comparison-matrix.md)
- [Migration Resources](./chapter-14-migration/resources.md)
- [Common Concepts](./chapter-14-migration/common-concepts.md)
- [Knowledge Base Migration](./chapter-14-migration/kb-migration.md)
- [Cloud Productivity Migration](./chapter-14-migration/google-workspace.md)
- [Enterprise Platform Migration](./chapter-14-migration/microsoft-365.md)
- [n8n Migration](./chapter-14-migration/n8n.md)
- [Notion Migration](./chapter-14-migration/notion.md)
- [Perplexity Migration](./chapter-14-migration/perplexity.md)
- [Zapier and Make Migration](./chapter-14-migration/zapier-make.md)
- [Intercom Migration](./chapter-14-migration/intercom.md)
- [Dialogflow Migration](./chapter-14-migration/dialogflow.md)
- [Botpress Migration](./chapter-14-migration/botpress.md)
- [Automation Migration](./chapter-14-migration/automation.md)
- [Validation and Testing](./chapter-14-migration/validation.md)
# Appendices
- [Appendix A: Database Model](./appendix-15/README.md)
- [Schema Overview](./appendix-15/schema.md)
- [Tables](./appendix-15/tables.md)
- [Relationships](./appendix-15/relationships.md)
- [Appendix B: External Services](./appendix-external-services/README.md)
- [Service Catalog](./appendix-external-services/catalog.md)
- [LLM Providers](./appendix-external-services/llm-providers.md)
- [Weather API](./appendix-external-services/weather.md)
- [Channel Integrations](./appendix-external-services/channels.md)
- [Storage Services](./appendix-external-services/storage.md)
- [Directory Services](./appendix-external-services/directory.md)
- [Attendance Queue](./appendix-external-services/attendance-queue.md)
- [Time-Series Database](./appendix-external-services/timeseries.md)
- [NVIDIA GPU](./appendix-external-services/nvidia.md)
- [Multimodal](./appendix-external-services/multimodal.md)
- [Console (XtreeUI)](./appendix-external-services/console.md)
- [Appendix C: Environment Variables](./appendix-env-vars/README.md)
- [Appendix D: Documentation Style](./appendix-docs-style/conversation-examples.md)
[Glossary](./glossary.md)
[Contact](./contact/README.md)

52
src/appendix-15/README.md Normal file
View file

@ -0,0 +1,52 @@
## Appendix I Database Model
<img src="./assets/schema-overview.svg" alt="Database Schema Overview" style="max-height: 400px; width: 100%; object-fit: contain;">
The core database schema for GeneralBots is defined in `src/shared/models.rs`. It uses **Diesel** with PostgreSQL and includes the following primary tables:
| Table | Description |
|-------|-------------|
| `users` | Stores user accounts, authentication tokens, and profile data. |
| `sessions` | Tracks active `BotSession` instances, their start/end timestamps, and associated user. |
| `knowledge_bases` | Metadata for each `.gbkb` collection (name, vector store configuration, creation date). |
| `messages` | Individual chat messages (role=user/assistant, content, timestamp, linked to a session). |
| `tools` | Registered custom tools per session (name, definition JSON, activation status). |
| `files` | References to files managed by the `.gbdrive` package (path, size, MIME type, storage location). |
### Relationships
- **User ↔ Sessions** Onetomany: a user can have many sessions.
- **Session ↔ Messages** Onetomany: each session contains a sequence of messages.
- **Session ↔ KnowledgeBase** Manytoone: a session uses a single knowledge base at a time.
- **Session ↔ Tools** Onetomany: tools are scoped to the session that registers them.
- **File ↔ KnowledgeBase** Optional link for documents stored in a knowledge base.
### Key Tables
**User Table**
- id: Integer primary key
- username: String
- email: String
- password_hash: String
- created_at: Timestamp
**Session Table**
- id: Integer primary key
- user_id: Foreign key to User
- started_at: Timestamp
- last_active: Timestamp
- knowledge_base_id: Integer
**Message Table**
- id: Integer primary key
- session_id: Foreign key to Session
- role: String ("user" or "assistant")
- content: Text
- timestamp: Timestamp
The schema is automatically migrated when the server starts.
---
<div align="center">
<img src="https://pragmatismo.com.br/icons/general-bots-text.svg" alt="General Bots" width="200">
</div>

View file

@ -0,0 +1,180 @@
# Database Relationships
This document describes the relationships between tables in the General Bots database schema.
## Entity Relationship Overview
The database follows a hierarchical structure with organizations at the top, containing bots, which in turn manage users, sessions, and content.
## Primary Relationships
### Organization Hierarchy
```
organizations
bots (1:N)
bot_configuration (1:N)
bot_memories (1:N)
kb_collections (1:N)
kb_documents (1:N)
basic_tools (1:N)
system_automations (1:N)
```
Each organization can have multiple bots, and each bot has its own configuration, memories, knowledge bases, tools, and automations. Cascade delete behavior means that deleting an organization removes all associated bots and their data.
### User and Session Management
```
users
user_sessions (1:N)
message_history (1:N)
clicks (1:N)
user_kb_associations (1:N)
session_tool_associations (1:N)
user_login_tokens (1:N)
user_preferences (1:1)
user_email_accounts (1:N)
email_drafts (1:N)
email_folders (1:N)
folder_messages (1:N)
```
Users can have multiple active sessions across different bots. Each session maintains its own message history and associations. Sessions link to both users and bots, forming a many-to-many relationship through the sessions table.
### Bot-User Interaction
```
bots ←→ user_sessions ←→ users
user_sessions:
message_history
user_kb_associations → kb_collections
session_tool_associations → basic_tools
bots:
kb_collections
basic_tools
```
Users interact with bots through sessions. Sessions dynamically associate with knowledge bases and tools as needed. Message history preserves the conversation context for continuity across interactions.
## Foreign Key Constraints
### Strong Relationships (CASCADE DELETE)
These relationships enforce referential integrity with cascade deletion.
The organizations to bots relationship means deleting an organization removes all its bots, with `bots.org_id` referencing `organizations.org_id`.
The bots to bot_configuration relationship means deleting a bot removes all its configuration, with `bot_configuration.bot_id` referencing `bots.id`.
The bots to bot_memories relationship means deleting a bot removes all its memories, with `bot_memories.bot_id` referencing `bots.id`.
The user_sessions to message_history relationship means ending a session removes its message history, with `message_history.session_id` referencing `user_sessions.id`.
### Weak Relationships (SET NULL/RESTRICT)
These relationships maintain data integrity without cascade deletion.
The users to user_sessions relationship sets `session.user_id` to NULL when a user is deleted, preserving conversation history for audit purposes while making the session anonymous.
The kb_collections to kb_documents relationship restricts deletion if documents exist, requiring explicit document deletion first to prevent accidental data loss.
The user_email_accounts to email_drafts relationship preserves drafts when an email account is deleted, allowing draft recovery or reassignment to other accounts.
## Many-to-Many Relationships
### Sessions ↔ Knowledge Bases
```
user_sessions ←→ user_kb_associations ←→ kb_collections
```
The `user_kb_associations` junction table allows dynamic KB activation per session. Multiple knowledge bases can be active simultaneously, enabling conversations that draw from several information sources.
### Sessions ↔ Tools
```
user_sessions ←→ session_tool_associations ←→ basic_tools
```
The `session_tool_associations` junction table enables tools to be loaded per session as needed. This supports dynamic tool discovery where available capabilities vary based on context.
## Relationship Cardinality
One-to-one relationships exist between users and user_preferences, where each user has exactly one preferences record.
One-to-many relationships include organizations to bots, bots to bot_configuration, bots to kb_collections, kb_collections to kb_documents, users to user_sessions, user_sessions to message_history, and user_email_accounts to email_drafts.
Many-to-many relationships exist between user_sessions and kb_collections through user_kb_associations, between user_sessions and basic_tools through session_tool_associations, and between users and bots through user_sessions.
## Referential Integrity Rules
### Insert Order
When inserting data, follow this sequence: organizations first, then bots, then bot_configuration. For user data, insert users first, then user_sessions, then message_history. Knowledge base data requires kb_collections before kb_documents. Tools require basic_tools before session_tool_associations.
### Delete Order (reverse of insert)
When deleting data, reverse the insert order: message_history first, then user_sessions, then users. For tools, delete session_tool_associations before basic_tools. For knowledge bases, delete kb_documents before kb_collections. For organizational data, delete bot_configuration, then bots, then organizations.
## Orphan Prevention
### Automatic Cleanup
Sessions expire based on the `expires_at` timestamp. Orphaned associations are cleaned by background jobs that run periodically. Temporary data has TTL settings that trigger automatic removal.
### Manual Cleanup Required
Some data requires manual cleanup. Unused kb_documents should be periodically reviewed and removed. Old message_history should be cleared based on retention policy. Expired user_login_tokens should be purged.
## Performance Implications
### Hot Paths
These relationships are frequently traversed and should be optimized.
The user_sessions to message_history path benefits from an index on `(session_id, created_at DESC)` and is used for conversation display.
The bots to bot_memories path benefits from an index on `(bot_id, key)` and is used by GET BOT MEMORY and SET BOT MEMORY operations.
The kb_collections to kb_documents path benefits from an index on `(collection_id, indexed)` and is used for semantic search.
### Join Optimization
Common join patterns benefit from composite indexes.
User session context queries join user_sessions with users on `user_sessions.user_id = users.id` and with bots on `user_sessions.bot_id = bots.id`.
Knowledge base loading joins user_kb_associations with kb_collections on `user_kb_associations.collection_id = kb_collections.id` and kb_documents on `kb_collections.id = kb_documents.collection_id`.
Tool discovery joins session_tool_associations with basic_tools on `session_tool_associations.tool_id = basic_tools.id` filtered by session_id and bot_id.
## Data Consistency Patterns
### Transaction Boundaries
Certain operations must be atomic.
Session creation requires inserting the user_session record, initializing default associations, and creating the initial message all within a single transaction.
Tool registration requires inserting the basic_tool record, updating bot_configuration, and refreshing active sessions together.
Document upload requires inserting the kb_document record, triggering the indexing job, and updating collection metadata atomically.
### Eventual Consistency
Some operations can be eventually consistent.
Vector embeddings allow document upload to complete first, with asynchronous indexing creating embeddings afterward. Search becomes available after processing completes.
Email synchronization saves account configuration immediately, then background sync fetches emails asynchronously. Folders and counts update as sync progresses.
## Best Practices
Always use foreign keys for data integrity to catch relationship violations at the database level. Index foreign key columns for join performance to avoid full table scans on relationship traversals. Use transactions for related updates to maintain consistency across multiple tables.
Implement soft deletes for audit trails where regulations require historical data retention. Monitor constraint violations in logs to catch application bugs early. Plan cascade paths carefully to avoid unintended data deletion.
Document relationship changes in migrations so the team understands schema evolution over time.

126
src/appendix-15/schema.md Normal file
View file

@ -0,0 +1,126 @@
# Database Schema Overview
General Bots uses PostgreSQL as its primary database with Diesel ORM for type-safe database operations. The schema is designed to support multi-tenant bot hosting with comprehensive session management, user authentication, and content storage.
## Core Architecture
The database schema follows several key design principles. All tables use UUID primary keys for globally unique identifiers that work across distributed systems. Created and updated timestamps provide audit trails for tracking data changes. Foreign key relationships maintain referential integrity between related entities. JSON fields offer flexible storage for dynamic configuration and metadata that doesn't fit rigid schema definitions.
## Database Schema Diagram
## Entity Relationship Overview
<img src="./assets/schema-overview.svg" alt="Database Schema Overview" style="max-height: 400px; width: 100%; object-fit: contain;">
### Core Tables Structure
## Detailed Schema
<img src="./assets/schema-detailed.svg" alt="Database Entity Details" style="max-height: 400px; width: 100%; object-fit: contain;">
## Schema Categories
### Organization & Bot Management
The `organizations` table provides multi-tenant organization support, isolating data between different customers or deployments. The `bots` table stores bot instances and their configurations. The `bot_configuration` table contains bot-specific settings and parameters. The `bot_memories` table provides persistent key-value storage for bots to maintain state across sessions.
### User & Authentication
The `users` table stores user accounts with secure password storage using Argon2 hashing. The `user_sessions` table tracks active user sessions with authentication tokens. The `user_login_tokens` table manages authentication tokens for login flows. The `user_preferences` table contains user-specific settings and customizations.
### Conversation & Messaging
The `message_history` table maintains complete conversation history between users and bots. The `clicks` table tracks user interaction events for analytics. The `system_automations` table stores scheduled tasks and automation rules that run without user intervention.
### Knowledge Base
The `kb_collections` table defines knowledge base collection containers. The `kb_documents` table stores documents within those collections. The `user_kb_associations` table manages user access permissions to knowledge bases. The `session_tool_associations` table tracks which tools are available within specific sessions.
### Tools & Integration
The `basic_tools` table stores BASIC script tool definitions compiled from `.bas` files. The `user_email_accounts` table manages email integration accounts for users. The `email_drafts` table stores draft emails being composed. The `email_folders` table organizes email folder structures.
## Table Relationships
### Session Flow
<img src="./assets/session-flow.svg" alt="Session Flow Diagram" style="max-height: 400px; width: 100%; object-fit: contain;">
### Knowledge Base Access
<img src="./assets/kb-access.svg" alt="Knowledge Base Access" style="max-height: 400px; width: 100%; object-fit: contain;">
### Primary Relationships
The bot hierarchy establishes that organizations contain multiple bots in a one-to-many relationship. Each bot has multiple configuration entries and memories associated with it.
User sessions connect users to bots through the session table. Users can have multiple sessions, and each session maintains its own message history. Bots also connect to sessions, enabling the many-to-many relationship between users and bots.
Knowledge management links bots to knowledge base collections, with each collection containing multiple documents. Sessions associate with knowledge bases through the user_kb_associations table.
Tool associations connect bots to their defined tools, and sessions link to available tools through the session_tool_associations junction table.
## Data Types
The schema uses several PostgreSQL data types throughout. UUID fields serve as primary keys and foreign key references for globally unique identification. Text fields store variable-length string data without length constraints. Varchar fields hold fixed-length strings for codes and identifiers. Timestamptz fields store timestamps with timezone information for accurate time tracking across regions. Jsonb fields provide JSON storage with indexing capabilities for flexible schemas. Boolean fields represent binary flags and settings. Integer fields store counters and numeric values.
## Indexing Strategy
Primary indexes exist on all id fields serving as primary keys. Foreign key relationships receive indexes for efficient joins. Timestamp fields are indexed to support time-based queries. Session tokens have indexes for fast authentication lookups.
Composite indexes optimize common query patterns. The combination of bot_id and user_id enables efficient session lookup. Collection_id with document_id accelerates knowledge retrieval. User_id paired with created_at supports history queries ordered by time.
## Migration Management
Database migrations are managed through Diesel's migration system. Migrations reside in the `migrations/` directory with each migration containing both up.sql and down.sql files for applying and reverting changes. Version tracking occurs in the `__diesel_schema_migrations` table. The bootstrap process automatically applies pending migrations on startup.
## Performance Considerations
### Connection Pooling
The default connection pool maintains 10 connections to balance resource usage with concurrency. Pool size is configurable via environment variables for different deployment scales. Automatic connection recycling prevents stale connections from causing issues.
### Query Optimization
Prepared statements cache query plans for repeated queries, improving performance. Batch operations handle bulk inserts efficiently rather than individual row insertions. Lazy loading defers loading of related entities until needed. Pagination limits result sets to manageable sizes for large tables.
### Data Retention
Message history retention is configurable to balance storage costs with historical needs. Automatic cleanup removes expired sessions to free resources. An archival strategy moves old conversations to cold storage while maintaining accessibility.
## Security Features
### Data Protection
Password hashing uses the Argon2 algorithm for strong protection against brute-force attacks. AES-GCM encryption protects sensitive fields at rest. Secure random token generation creates unpredictable session identifiers. Diesel's parameterized queries prevent SQL injection attacks.
### Access Control
Row-level security is implemented through application logic that filters queries by user context. User isolation ensures sessions only access their own data. Bot isolation separates data by organization to prevent cross-tenant access. Audit logging records sensitive operations for compliance and security review.
## Backup Strategy
### Backup Types
Full database dumps capture complete point-in-time snapshots. Incremental WAL archiving provides continuous backup with minimal storage overhead. Point-in-time recovery support enables restoration to any moment within the retention window. Cross-region replication offers disaster recovery capabilities for critical deployments.
### Restore Procedures
Automated restore testing validates backup integrity on a regular schedule. Version compatibility checks ensure backups restore correctly to the current schema. Data integrity validation confirms restored data matches expected checksums. Zero-downtime migration support enables schema changes without service interruption.
## Monitoring
### Key Metrics
Connection pool usage indicates whether the pool size needs adjustment. Query execution time reveals slow queries requiring optimization. Table sizes and growth rates inform capacity planning. Index effectiveness metrics show whether indexes are being utilized. Lock contention monitoring identifies concurrency bottlenecks.
### Health Checks
Database connectivity verification ensures the connection pool can reach PostgreSQL. Migration status checks confirm all migrations have been applied. Replication lag monitoring applies to deployments with read replicas. Storage usage tracking prevents disk space exhaustion.
## Best Practices
Always use migrations for schema changes rather than manual DDL to maintain consistency across environments. Never modify production data directly through SQL clients to avoid bypassing application logic. Test migrations in development first to catch issues before they affect production. Monitor performance metrics regularly to identify degradation early. Plan capacity based on growth projections to avoid emergency scaling. Document changes in migration files with comments explaining the purpose of each change. Use transactions for data consistency when multiple tables must be updated together. Implement retry logic for transient failures like connection timeouts or deadlocks.
## Future Considerations
Partitioning for large tables like message_history would improve query performance and enable efficient data archival. Read replicas could scale read-heavy workloads across multiple database instances. Time-series optimization for metrics data would support analytics features. Full-text search indexes would enable natural language queries against stored content. Graph relationships could support advanced queries for interconnected data like conversation flows.

275
src/appendix-15/tables.md Normal file
View file

@ -0,0 +1,275 @@
# Database Tables
This section documents all database tables in General Bots, their structures, and purposes.
## Core Tables
### organizations
Stores organization/tenant information for multi-tenant deployments.
| Column | Type | Description |
|--------|------|-------------|
| org_id | UUID | Primary key |
| name | TEXT | Organization name |
| slug | TEXT | URL-friendly identifier |
| created_at | TIMESTAMPTZ | Creation timestamp |
### bots
Bot instances and their basic configuration.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| name | TEXT | Bot name |
| org_id | UUID | Foreign key to organizations |
| created_at | TIMESTAMPTZ | Creation timestamp |
| updated_at | TIMESTAMPTZ | Last update timestamp |
### bot_configuration
Stores bot-specific configuration parameters from config.csv.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| bot_id | UUID | Foreign key to bots |
| key | TEXT | Configuration key |
| value | TEXT | Configuration value |
| created_at | TIMESTAMPTZ | Creation timestamp |
| updated_at | TIMESTAMPTZ | Last update timestamp |
### bot_memories
Persistent key-value storage for bots (used by GET BOT MEMORY/SET BOT MEMORY).
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| bot_id | UUID | Foreign key to bots |
| key | TEXT | Memory key |
| value | TEXT | Memory value |
| created_at | TIMESTAMPTZ | Creation timestamp |
| updated_at | TIMESTAMPTZ | Last update timestamp |
## User Management Tables
### users
User accounts with authentication credentials.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| username | TEXT | Unique username |
| email | TEXT | Email address |
| password_hash | TEXT | Argon2 hashed password |
| active | BOOLEAN | Account status |
| created_at | TIMESTAMPTZ | Registration timestamp |
| updated_at | TIMESTAMPTZ | Last update timestamp |
### user_sessions
Active user sessions for authentication and state management.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| user_id | UUID | Foreign key to users |
| bot_id | UUID | Foreign key to bots |
| session_token | TEXT | Unique session identifier |
| expires_at | TIMESTAMPTZ | Session expiration |
| created_at | TIMESTAMPTZ | Session start |
| updated_at | TIMESTAMPTZ | Last activity |
### user_login_tokens
Authentication tokens for login flows.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| user_id | UUID | Foreign key to users |
| token | TEXT | Login token |
| expires_at | TIMESTAMPTZ | Token expiration |
| used | BOOLEAN | Whether token was used |
| created_at | TIMESTAMPTZ | Token creation |
### user_preferences
User-specific settings and preferences.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| user_id | UUID | Foreign key to users |
| preferences | JSONB | Preferences data |
| created_at | TIMESTAMPTZ | Creation timestamp |
| updated_at | TIMESTAMPTZ | Last update |
## Conversation Tables
### message_history
Complete conversation history between users and bots.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| session_id | UUID | Foreign key to user_sessions |
| user_id | UUID | Foreign key to users |
| bot_id | UUID | Foreign key to bots |
| message | TEXT | Message content |
| sender | TEXT | 'user' or 'bot' |
| created_at | TIMESTAMPTZ | Message timestamp |
### clicks
Tracks user interactions with UI elements.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| session_id | UUID | Foreign key to user_sessions |
| element_id | TEXT | UI element identifier |
| timestamp | TIMESTAMPTZ | Click timestamp |
### system_automations
Scheduled tasks and automation rules.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| bot_id | UUID | Foreign key to bots |
| name | TEXT | Automation name |
| schedule | TEXT | Cron expression |
| script | TEXT | BASIC script to execute |
| active | BOOLEAN | Whether automation is active |
| created_at | TIMESTAMPTZ | Creation timestamp |
| updated_at | TIMESTAMPTZ | Last update |
## Knowledge Base Tables
### kb_collections
Knowledge base collection definitions.
| Column | Type | Description |
|--------|------|-------------|
| id | TEXT | Primary key (collection name) |
| bot_id | UUID | Foreign key to bots |
| name | TEXT | Collection display name |
| description | TEXT | Collection description |
| metadata | JSONB | Additional metadata |
| created_at | TIMESTAMPTZ | Creation timestamp |
| updated_at | TIMESTAMPTZ | Last update |
### kb_documents
Documents stored in knowledge base collections.
| Column | Type | Description |
|--------|------|-------------|
| id | TEXT | Primary key (document ID) |
| collection_id | TEXT | Foreign key to kb_collections |
| bot_id | UUID | Foreign key to bots |
| name | TEXT | Document name |
| content | TEXT | Document content |
| metadata | JSONB | Document metadata |
| embedding_id | TEXT | Vector embedding reference |
| indexed | BOOLEAN | Whether document is indexed |
| created_at | TIMESTAMPTZ | Upload timestamp |
| updated_at | TIMESTAMPTZ | Last update |
### user_kb_associations
Links user sessions to available knowledge bases.
| Column | Type | Description |
|--------|------|-------------|
| id | TEXT | Primary key |
| session_id | UUID | Foreign key to user_sessions |
| collection_id | TEXT | Foreign key to kb_collections |
| created_at | TIMESTAMPTZ | Association timestamp |
## Tool Tables
### basic_tools
BASIC script tool definitions.
| Column | Type | Description |
|--------|------|-------------|
| id | TEXT | Primary key (tool name) |
| bot_id | UUID | Foreign key to bots |
| name | TEXT | Tool display name |
| description | TEXT | Tool description |
| parameters | JSONB | Parameter definitions |
| script | TEXT | BASIC script implementation |
| metadata | JSONB | Additional metadata |
| created_at | TIMESTAMPTZ | Creation timestamp |
| updated_at | TIMESTAMPTZ | Last update |
### session_tool_associations
Links sessions to available tools.
| Column | Type | Description |
|--------|------|-------------|
| id | TEXT | Primary key |
| session_id | UUID | Foreign key to user_sessions |
| tool_id | TEXT | Foreign key to basic_tools |
| created_at | TIMESTAMPTZ | Association timestamp |
## Email Integration Tables
### user_email_accounts
Email accounts configured for users.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| user_id | UUID | Foreign key to users |
| email_address | TEXT | Email address |
| imap_server | TEXT | IMAP server address |
| imap_port | INTEGER | IMAP port |
| smtp_server | TEXT | SMTP server address |
| smtp_port | INTEGER | SMTP port |
| encrypted_password | TEXT | Encrypted email password |
| active | BOOLEAN | Account status |
| created_at | TIMESTAMPTZ | Configuration timestamp |
| updated_at | TIMESTAMPTZ | Last update |
### email_drafts
Draft emails created by users or bots.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| user_id | UUID | Foreign key to users |
| account_id | UUID | Foreign key to user_email_accounts |
| to_addresses | TEXT[] | Recipient addresses |
| cc_addresses | TEXT[] | CC addresses |
| bcc_addresses | TEXT[] | BCC addresses |
| subject | TEXT | Email subject |
| body | TEXT | Email body |
| attachments | JSONB | Attachment metadata |
| created_at | TIMESTAMPTZ | Draft creation |
| updated_at | TIMESTAMPTZ | Last edit |
### email_folders
Email folder organization.
| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| account_id | UUID | Foreign key to user_email_accounts |
| name | TEXT | Folder name |
| path | TEXT | IMAP folder path |
| parent_id | UUID | Parent folder ID |
| message_count | INTEGER | Number of messages |
| unread_count | INTEGER | Unread messages |
| created_at | TIMESTAMPTZ | Folder creation |
| updated_at | TIMESTAMPTZ | Last sync |
## Indexes
### Primary Indexes
- All `id` columns have primary key indexes
- All foreign key columns have indexes for joins
### Performance Indexes
- `user_sessions.session_token` - for session lookup
- `message_history.created_at` - for time-based queries
- `kb_documents.collection_id` - for collection queries
- `bot_memories(bot_id, key)` - composite for memory lookup
### Full-Text Search Indexes
- `kb_documents.content` - for document search (when enabled)
- `message_history.message` - for conversation search (when enabled)

View file

@ -0,0 +1,235 @@
# Conversation Examples Style Guide
> **Standard format for displaying bot-user conversations in documentation**
## Overview
All conversation examples in General Bots documentation use a WhatsApp-style chat format. This provides a consistent, familiar, and readable way to show bot interactions.
## CSS Include
The styling is defined in `/assets/wa-chat.css`. Include it in your mdBook or HTML output.
---
## Basic Structure
```html
<div class="wa-chat">
<div class="wa-message bot">
<div class="wa-bubble">
<p>Bot message here</p>
<div class="wa-time">10:30</div>
</div>
</div>
<div class="wa-message user">
<div class="wa-bubble">
<p>User message here</p>
<div class="wa-time">10:31</div>
</div>
</div>
</div>
```
---
## Message Types
### Bot Message
```html
<div class="wa-message bot">
<div class="wa-bubble">
<p>Hello! How can I help you today?</p>
<div class="wa-time">10:30</div>
</div>
</div>
```
### User Message
```html
<div class="wa-message user">
<div class="wa-bubble">
<p>What meetings do I have today?</p>
<div class="wa-time">10:31</div>
</div>
</div>
```
---
## Formatting Within Messages
### Multiple Paragraphs
```html
<div class="wa-bubble">
<p>You have 2 meetings scheduled:</p>
<p>• 2:00 PM - Team Standup (30 min)</p>
<p>• 4:00 PM - Project Review (1 hour)</p>
<div class="wa-time">10:31</div>
</div>
```
### Bold Text
```html
<p><strong>Name:</strong> John Smith</p>
<p><strong>Email:</strong> john@example.com</p>
```
### Emoji Usage
Emojis are encouraged to make conversations more expressive:
| Purpose | Emoji Examples |
|---------|----------------|
| Success | ✅ ✓ 🎉 |
| Warning | ⚠️ ⚡ |
| Error | ❌ 🔴 |
| Info | 📋 |
| File | 📄 📁 📎 |
| Calendar | 📅 🗓️ |
| Email | 📧 ✉️ |
| Person | 👤 👥 |
| Time | 🕐 ⏱️ |
### File Attachments
```html
<div class="wa-message user">
<div class="wa-bubble">
<p>Here's the report</p>
<p>📎 quarterly-report.pdf</p>
<div class="wa-time">10:32</div>
</div>
</div>
```
### Action Buttons (visual representation)
```html
<p>[📧 Send] [✏️ Edit] [🗑 Discard]</p>
```
---
## Complete Example
```html
<div class="wa-chat">
<div class="wa-message user">
<div class="wa-bubble">
<p>Schedule a meeting with Sarah tomorrow at 2pm</p>
<div class="wa-time">10:30</div>
</div>
</div>
<div class="wa-message bot">
<div class="wa-bubble">
<p>✅ Meeting scheduled!</p>
<p>👥 Meeting with Sarah</p>
<p>📅 Tomorrow at 2:00 PM</p>
<p>⏱️ Duration: 1 hour</p>
<p>Invitation sent to Sarah.</p>
<div class="wa-time">10:30</div>
</div>
</div>
</div>
```
**Rendered Output:**
<div class="wa-chat">
<div class="wa-message user">
<div class="wa-bubble">
<p>Schedule a meeting with Sarah tomorrow at 2pm</p>
<div class="wa-time">10:30</div>
</div>
</div>
<div class="wa-message bot">
<div class="wa-bubble">
<p>✅ Meeting scheduled!</p>
<p>👥 Meeting with Sarah</p>
<p>📅 Tomorrow at 2:00 PM</p>
<p>⏱️ Duration: 1 hour</p>
<p>Invitation sent to Sarah.</p>
<div class="wa-time">10:30</div>
</div>
</div>
</div>
---
## Variants
### Full Width
Add `wa-full-width` class for wider conversations:
```html
<div class="wa-chat wa-full-width">
...
</div>
```
### Compact
Add `wa-compact` class for tighter spacing:
```html
<div class="wa-chat wa-compact">
...
</div>
```
### Hide Timestamps
Add `wa-no-time` class to hide timestamps:
```html
<div class="wa-chat wa-no-time">
...
</div>
```
---
## Best Practices
1. **Keep messages concise** - Break long bot responses into multiple paragraphs
2. **Use consistent timestamps** - Use realistic times (10:30, 10:31, etc.)
3. **Start with user context** - Show what the user asked before the bot response
4. **Include visual feedback** - Use emojis for status (✅, ❌, 📋)
5. **Show realistic flows** - Include multi-turn conversations when appropriate
6. **Use semantic formatting** - Bold for labels, lists for options
---
## Files Using This Format
This format is used throughout the documentation:
- `chapter-02/template-crm-contacts.md`
- `chapter-04-gbui/apps/*.md`
- `chapter-06-gbdialog/basic-vs-automation-tools.md`
- And many more...
---
## See Also
- [UI Structure](../chapter-04-gbui/ui-structure.md)
- [Chat App Documentation](../chapter-04-gbui/apps/chat.md)
<style>
.wa-chat{background-color:#e5ddd5;border-radius:8px;padding:20px 15px;margin:20px 0;max-width:500px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:14px}
.wa-message{margin-bottom:10px}
.wa-message.user{text-align:right}
.wa-message.user .wa-bubble{background-color:#dcf8c6;display:inline-block;text-align:left}
.wa-message.bot .wa-bubble{background-color:#fff;display:inline-block}
.wa-bubble{padding:8px 12px;border-radius:8px;box-shadow:0 1px .5px rgba(0,0,0,.13);max-width:85%}
.wa-bubble p{margin:0 0 4px 0;line-height:1.4;color:#303030}
.wa-bubble p:last-child{margin-bottom:0}
.wa-time{font-size:11px;color:#8696a0;text-align:right;margin-top:4px}
</style>

View file

@ -0,0 +1,136 @@
# Appendix C: Environment Variables
General Bots uses a minimal set of environment variables. All configuration is managed through `config.csv` files within each bot's `.gbot` folder, with secrets stored securely in Vault.
## Required Environment Variables
Only Vault-related environment variables are used by General Bots:
### VAULT_* Variables
**Purpose**: HashiCorp Vault integration for secure secrets management.
| Variable | Description | Example |
|----------|-------------|---------|
| `VAULT_ADDR` | Vault server URL | `http://localhost:8200` |
| `VAULT_TOKEN` | Authentication token | Auto-generated during bootstrap |
| `VAULT_NAMESPACE` | Vault namespace (optional) | `admin` |
**Example**:
```bash
VAULT_ADDR=http://localhost:8200
VAULT_TOKEN=hvs.your-vault-token
```
## Auto-Managed Services
The following services are automatically configured through Vault:
| Service | Management |
|---------|------------|
| PostgreSQL | Connection credentials in Vault |
| S3-Compatible Storage | Access keys in Vault |
| Cache | Connection managed via Vault |
| Email (Stalwart) | Credentials in Vault |
| LLM API Keys | Stored in Vault |
You do **not** need to set environment variables for these services. Vault handles credential distribution and rotation automatically.
## What NOT to Use Environment Variables For
**All application configuration belongs in `config.csv`**:
| Configuration | Where to Configure |
|--------------|-------------------|
| Database connection | Managed by Vault |
| Storage credentials | Managed by Vault |
| LLM API keys | Managed by Vault |
| LLM provider | `config.csv`: `llm-url` |
| Email settings | `config.csv`: `email-*` |
| Channel tokens | `config.csv`: `whatsapp-*`, etc. |
| Bot settings | `config.csv`: all bot-specific settings |
| Feature flags | `config.csv`: various keys |
## Configuration Philosophy
General Bots follows these principles:
1. **Vault-First**: All secrets are managed by Vault
2. **Minimal Environment**: Only Vault address and token use environment variables
3. **config.csv for Settings**: All application configuration is in `config.csv`
4. **Per-Bot Configuration**: Each bot has its own `config.csv` in its `.gbot` folder
5. **No Hardcoded Secrets**: Never store secrets in code or config files
## Setting Environment Variables
### Linux/macOS
```bash
export VAULT_ADDR=http://localhost:8200
export VAULT_TOKEN=hvs.your-vault-token
```
### Systemd Service
```ini
[Service]
Environment="VAULT_ADDR=http://localhost:8200"
Environment="VAULT_TOKEN=hvs.your-vault-token"
```
### LXC Container
When using LXC deployment, environment variables are set in the container configuration:
```bash
lxc config set container-name environment.VAULT_ADDR="http://localhost:8200"
lxc config set container-name environment.VAULT_TOKEN="hvs.your-vault-token"
```
## Security Notes
1. **Never commit tokens**: Use `.env` files (gitignored) or secrets management
2. **Rotate regularly**: Vault tokens should be rotated periodically
3. **Limit access**: Only the botserver process needs these variables
4. **Use TLS**: Always use HTTPS for Vault in production
## Bootstrap Process
During bootstrap, General Bots:
1. Connects to Vault using `VAULT_*` variables
2. Retrieves credentials for all managed services
3. Configures database, storage, cache, and other services
4. Stores service endpoints securely
This eliminates the need for manual credential management.
## Troubleshooting
### Vault Connection Failed
```
Error: Failed to connect to Vault
```
Verify:
- `VAULT_ADDR` is set correctly
- Vault server is running and accessible
- `VAULT_TOKEN` is valid and not expired
- Network allows connection to Vault host
### Service Not Available
If a managed service (database, storage, cache) is unavailable:
1. Check Vault is running and unsealed
2. Verify secrets exist in Vault
3. Check service container/process status
4. Review logs for connection errors
## See Also
- [config.csv Format](../chapter-08-config/config-csv.md) - Bot configuration
- [Secrets Management](../chapter-08-config/secrets-management.md) - Vault integration details
- [Drive Integration](../chapter-08-config/drive.md) - Storage setup
- [Authentication](../chapter-12-auth/README.md) - Security features

View file

@ -0,0 +1,94 @@
# Appendix B: External Services
This appendix catalogs all external services that General Bots integrates with, including their configuration requirements, associated BASIC keywords, and API endpoints.
## Overview
General Bots connects to external services for extended functionality. All service credentials should be stored in `config.csv` within the bot's `.gbot` folder - never hardcoded in scripts.
Infrastructure services (database, storage, cache) are automatically managed by the Directory service (Zitadel).
## Service Categories
| Category | Services | Configuration Location |
|----------|----------|----------------------|
| LLM Providers | OpenAI, Groq, Anthropic, Azure OpenAI | `config.csv` |
| Weather | OpenWeatherMap | `config.csv` |
| Messaging Channels | WhatsApp, Teams, Instagram, Telegram | `config.csv` |
| Storage | S3-Compatible (MinIO, etc.) | Vault (automatic) |
| Directory | Zitadel | `VAULT_*` environment variables |
| Email | Stalwart / IMAP/SMTP | Vault (automatic) |
| Calendar | CalDAV servers | `config.csv` |
| Database | PostgreSQL | Vault (automatic) |
| Cache | Redis-compatible | Vault (automatic) |
## Quick Reference
### BASIC Keywords That Call External Services
| Keyword | Service | Config Key |
|---------|---------|-----------|
| `LLM` | LLM Provider | `llm-provider`, `llm-api-key` |
| `WEATHER` | OpenWeatherMap | `weather-api-key` |
| `SEND MAIL` | SMTP Server | Managed by Directory service |
| `SEND WHATSAPP` | WhatsApp Business API | `whatsapp-api-key`, `whatsapp-phone-number-id` |
| `SEND TEAMS` | Microsoft Teams | `teams-app-id`, `teams-app-password` |
| `SEND INSTAGRAM` | Instagram Graph API | `instagram-access-token`, `instagram-page-id` |
| `GET` (with http/https URL) | Any HTTP endpoint | N/A |
| `IMAGE` | BotModels (local) | `botmodels-enabled`, `botmodels-url` |
| `VIDEO` | BotModels (local) | `botmodels-enabled`, `botmodels-url` |
| `AUDIO` | BotModels (local) | `botmodels-enabled`, `botmodels-url` |
| `SEE` | BotModels (local) | `botmodels-enabled`, `botmodels-url` |
| `FIND` | Qdrant (local) | Internal service |
| `USE WEBSITE` | Web crawling | N/A |
## Service Configuration Template
Add these to your `config.csv`:
```csv
key,value
llm-provider,openai
llm-api-key,YOUR_API_KEY
llm-model,gpt-4o
weather-api-key,YOUR_OPENWEATHERMAP_KEY
whatsapp-api-key,YOUR_WHATSAPP_KEY
whatsapp-phone-number-id,YOUR_PHONE_ID
teams-app-id,YOUR_TEAMS_APP_ID
teams-app-password,YOUR_TEAMS_PASSWORD
instagram-access-token,YOUR_INSTAGRAM_TOKEN
instagram-page-id,YOUR_PAGE_ID
botmodels-enabled,true
botmodels-url,http://localhost:5000
```
## Auto-Managed Services
The following services are automatically configured by the Directory service (Zitadel):
| Service | What's Managed |
|---------|----------------|
| PostgreSQL | Connection credentials, database creation |
| S3-Compatible Storage | Access keys, bucket policies |
| Cache | Connection credentials |
| Stalwart Email | User accounts, SMTP/IMAP access |
You do **not** need to configure these services manually. The Directory service handles credential provisioning and rotation.
## Security Notes
1. **Never hardcode credentials** - Always use `config.csv` or `GET BOT MEMORY`
2. **Rotate keys regularly** - Update `config.csv` and restart the bot
3. **Use least privilege** - Only grant permissions needed by the bot
4. **Audit access** - Monitor external API usage through logs
5. **Infrastructure credentials** - Managed automatically by Directory service
## See Also
- [Service Catalog](./catalog.md) - Detailed service documentation
- [LLM Providers](./llm-providers.md) - AI model configuration
- [Weather API](./weather.md) - Weather service setup
- [Channel Integrations](./channels.md) - Messaging platform setup
- [Storage Services](./storage.md) - S3-compatible storage
- [Directory Services](./directory.md) - User authentication
- [Environment Variables](../appendix-env-vars/README.md) - DIRECTORY_* configuration

View file

@ -0,0 +1,78 @@
# Attendance Queue Module
Human-attendant queue management for hybrid bot/human support workflows.
## Overview
The attendance queue module manages handoffs from bot to human agents, tracking conversation queues, attendant availability, and real-time assignment.
## Configuration
Create `attendant.csv` in your bot's `.gbai` folder:
```csv
id,name,channel,preferences
att-001,John Smith,whatsapp,sales
att-002,Jane Doe,web,support
att-003,Bob Wilson,all,technical
```
## Queue Status
| Status | Description |
|--------|-------------|
| `waiting` | User waiting for attendant |
| `assigned` | Attendant assigned, not yet active |
| `active` | Conversation in progress |
| `resolved` | Conversation completed |
| `abandoned` | User left before assignment |
## Attendant Status
| Status | Description |
|--------|-------------|
| `online` | Available for new conversations |
| `busy` | Currently handling conversations |
| `away` | Temporarily unavailable |
| `offline` | Not working |
## REST API Endpoints
### GET /api/queue
List conversations in queue.
### POST /api/queue/assign
Assign conversation to attendant.
```json
{
"session_id": "uuid",
"attendant_id": "uuid"
}
```
### POST /api/queue/transfer
Transfer conversation between attendants.
```json
{
"session_id": "uuid",
"from_attendant_id": "uuid",
"to_attendant_id": "uuid",
"reason": "Specialist needed"
}
```
### GET /api/attendants
List all attendants with stats.
## BASIC Keywords
```basic
TRANSFER TO HUMAN "sales"
TRANSFER TO HUMAN "support", "high"
```
## See Also
- [Human Approval](../chapter-06-gbdialog/keyword-human-approval.md)

View file

@ -0,0 +1,273 @@
# Service Catalog
This catalog provides detailed information about every external service that General Bots integrates with.
## LLM Providers
### OpenAI
| Property | Value |
|----------|-------|
| **Service URL** | `https://api.openai.com/v1` |
| **Config Key** | `llm-provider=openai` |
| **API Key Config** | `llm-api-key` |
| **Documentation** | [platform.openai.com/docs](https://platform.openai.com/docs) |
| **BASIC Keywords** | `LLM` |
| **Supported Models** | `gpt-4o`, `gpt-4o-mini`, `gpt-4-turbo`, `gpt-3.5-turbo` |
### Groq
| Property | Value |
|----------|-------|
| **Service URL** | `https://api.groq.com/openai/v1` |
| **Config Key** | `llm-provider=groq` |
| **API Key Config** | `llm-api-key` |
| **Documentation** | [console.groq.com/docs](https://console.groq.com/docs) |
| **BASIC Keywords** | `LLM` |
| **Supported Models** | `llama-3.1-70b-versatile`, `llama-3.1-8b-instant`, `mixtral-8x7b-32768` |
### Anthropic
| Property | Value |
|----------|-------|
| **Service URL** | `https://api.anthropic.com/v1` |
| **Config Key** | `llm-provider=anthropic` |
| **API Key Config** | `llm-api-key` |
| **Documentation** | [docs.anthropic.com](https://docs.anthropic.com) |
| **BASIC Keywords** | `LLM` |
| **Supported Models** | `claude-3-5-sonnet`, `claude-3-opus`, `claude-3-haiku` |
### Azure OpenAI
| Property | Value |
|----------|-------|
| **Service URL** | `https://{resource}.openai.azure.com/` |
| **Config Key** | `llm-provider=azure` |
| **API Key Config** | `llm-api-key`, `azure-openai-endpoint` |
| **Documentation** | [learn.microsoft.com/azure/ai-services/openai](https://learn.microsoft.com/azure/ai-services/openai) |
| **BASIC Keywords** | `LLM` |
---
## Weather Services
### OpenWeatherMap
| Property | Value |
|----------|-------|
| **Service URL** | `https://api.openweathermap.org/data/2.5` |
| **Config Key** | `weather-api-key` |
| **Documentation** | [openweathermap.org/api](https://openweathermap.org/api) |
| **BASIC Keywords** | `WEATHER` |
| **Free Tier** | 1,000 calls/day |
| **Required Plan** | Free or higher |
**Example Usage:**
```basic
weather = WEATHER "Seattle"
TALK weather
```
---
## Messaging Channels
### WhatsApp Business API
| Property | Value |
|----------|-------|
| **Service URL** | `https://graph.facebook.com/v17.0` |
| **Config Keys** | `whatsapp-api-key`, `whatsapp-phone-number-id`, `whatsapp-business-account-id` |
| **Documentation** | [developers.facebook.com/docs/whatsapp](https://developers.facebook.com/docs/whatsapp) |
| **BASIC Keywords** | `SEND WHATSAPP`, `SEND FILE` (WhatsApp) |
| **Webhook URL** | `/api/channels/whatsapp/webhook` |
### Microsoft Teams
| Property | Value |
|----------|-------|
| **Service URL** | `https://smba.trafficmanager.net/apis` |
| **Config Keys** | `teams-app-id`, `teams-app-password`, `teams-tenant-id` |
| **Documentation** | [learn.microsoft.com/microsoftteams/platform](https://learn.microsoft.com/microsoftteams/platform) |
| **BASIC Keywords** | `SEND TEAMS`, `SEND FILE` (Teams) |
| **Webhook URL** | `/api/channels/teams/messages` |
### Instagram Messaging
| Property | Value |
|----------|-------|
| **Service URL** | `https://graph.facebook.com/v17.0` |
| **Config Keys** | `instagram-access-token`, `instagram-page-id`, `instagram-account-id` |
| **Documentation** | [developers.facebook.com/docs/instagram-api](https://developers.facebook.com/docs/instagram-api) |
| **BASIC Keywords** | `SEND INSTAGRAM` |
| **Webhook URL** | `/api/channels/instagram/webhook` |
### Telegram
| Property | Value |
|----------|-------|
| **Service URL** | `https://api.telegram.org/bot{token}` |
| **Config Keys** | `telegram-bot-token` |
| **Documentation** | [core.telegram.org/bots/api](https://core.telegram.org/bots/api) |
| **BASIC Keywords** | `SEND TELEGRAM` |
| **Webhook URL** | `/api/channels/telegram/webhook` |
---
## Storage Services
### S3-Compatible Storage
General Bots uses S3-compatible object storage. Configuration is **automatically managed** by the Directory service (Zitadel).
| Property | Value |
|----------|-------|
| **Local Default** | MinIO on port 9000 |
| **Management** | Directory service (automatic) |
| **Console Port** | 9001 (when using MinIO) |
| **BASIC Keywords** | `GET` (file retrieval) |
**Compatible Services:**
- MinIO (default local installation)
- Backblaze B2
- Wasabi
- DigitalOcean Spaces
- Cloudflare R2
- Any S3-compatible provider
Storage credentials are provisioned and rotated automatically by the Directory service. No manual configuration required.
---
## Directory Services
### Zitadel (Identity Provider)
| Property | Value |
|----------|-------|
| **Local Default** | Port 8080 |
| **Environment Variables** | `DIRECTORY_URL`, `DIRECTORY_CLIENT_ID`, `DIRECTORY_CLIENT_SECRET` |
| **Documentation** | [zitadel.com/docs](https://zitadel.com/docs) |
| **Purpose** | User authentication, SSO, OAuth2/OIDC, service credential management |
The Directory service manages:
- User authentication
- Service credentials (database, storage, cache)
- OAuth applications
- Role-based access control
---
## Email Services
### Stalwart Mail Server
| Property | Value |
|----------|-------|
| **Ports** | 25 (SMTP), 993 (IMAPS), 587 (Submission) |
| **Management** | Directory service (automatic) |
| **Documentation** | [stalw.art/docs](https://stalw.art/docs) |
| **BASIC Keywords** | `SEND MAIL` |
Email accounts are created and managed through the Directory service.
### External IMAP/SMTP
| Property | Value |
|----------|-------|
| **Config Keys** | `smtp-server`, `smtp-port`, `imap-server`, `imap-port`, `email-username`, `email-password` |
| **BASIC Keywords** | `SEND MAIL` |
| **Supported Providers** | Gmail, Outlook, custom SMTP/IMAP |
**Gmail Configuration Example (in config.csv):**
```csv
smtp-server,smtp.gmail.com
smtp-port,587
imap-server,imap.gmail.com
imap-port,993
```
---
## Local Services (BotModels)
### Image Generation
| Property | Value |
|----------|-------|
| **Service URL** | `http://localhost:5000` (default) |
| **Config Keys** | `botmodels-enabled`, `botmodels-url` |
| **BASIC Keywords** | `IMAGE` |
| **Requires** | BotModels service running |
### Video Generation
| Property | Value |
|----------|-------|
| **Service URL** | `http://localhost:5000` (default) |
| **Config Keys** | `botmodels-enabled`, `botmodels-url` |
| **BASIC Keywords** | `VIDEO` |
| **Requires** | BotModels service running, GPU recommended |
### Audio Generation (TTS)
| Property | Value |
|----------|-------|
| **Service URL** | `http://localhost:5000` (default) |
| **Config Keys** | `botmodels-enabled`, `botmodels-url` |
| **BASIC Keywords** | `AUDIO` |
| **Requires** | BotModels service running |
### Vision/Captioning
| Property | Value |
|----------|-------|
| **Service URL** | `http://localhost:5000` (default) |
| **Config Keys** | `botmodels-enabled`, `botmodels-url` |
| **BASIC Keywords** | `SEE` |
| **Requires** | BotModels service running |
---
## Internal Services
These services are deployed locally as part of the General Bots stack. All are managed by the Directory service:
| Service | Default Port | Purpose | Management |
|---------|-------------|---------|------------|
| PostgreSQL | 5432 | Primary database | Vault |
| Qdrant | 6333 | Vector storage for KB | Vault |
| Cache | 6379 | Caching | Vault |
| Stalwart | 25, 993 | Email server (optional) | Vault |
| BotModels | 5000 | AI model inference | config.csv |
---
## Service Health Checks
All services can be checked via the monitoring API:
```
GET /api/monitoring/services
```
Response includes status for all configured external services.
---
## Troubleshooting
### Common Issues
1. **API Key Invalid** - Verify key in `config.csv`, ensure no trailing whitespace
2. **Rate Limited** - Check service quotas, implement caching with `SET BOT MEMORY`
3. **Connection Timeout** - Verify network access to external URLs
4. **Service Unavailable** - Check service status pages
### Debug Logging
Enable trace logging to see external API calls:
```bash
RUST_LOG=trace ./botserver
```

View file

@ -0,0 +1 @@
# Channel Integrations

View file

@ -0,0 +1,114 @@
# Console Module (XtreeUI)
Terminal-based admin interface for managing General Bots instances.
## Overview
XtreeUI is a TUI (Terminal User Interface) for administering bots directly from the command line. It provides file browsing, log viewing, chat testing, and status monitoring in a single terminal window.
## Feature Flag
Enabled via Cargo feature:
```toml
[features]
console = []
```
## Panels
| Panel | Key | Description |
|-------|-----|-------------|
| File Tree | `1` | Browse bot files and packages |
| Editor | `2` | View/edit configuration files |
| Status | `3` | System status and metrics |
| Logs | `4` | Real-time log viewer |
| Chat | `5` | Test bot conversations |
## Keyboard Navigation
| Key | Action |
|-----|--------|
| `1-5` | Switch between panels |
| `Tab` | Cycle panels |
| `↑/↓` | Navigate within panel |
| `Enter` | Select/open item |
| `q` | Quit console |
| `?` | Show help |
## Components
### File Tree
Browse `.gbai` folder structure:
- View packages (.gbkb, .gbdialog, .gbtheme)
- Open config.csv for editing
- Navigate bot resources
### Status Panel
Real-time system metrics:
- CPU/memory usage
- Active connections
- Bot status
- Database connectivity
### Log Panel
Live log streaming with filtering:
- Error highlighting
- Log level filtering
- Search functionality
### Chat Panel
Interactive bot testing:
- Send messages to bot
- View responses
- Debug conversation flow
### Editor
Basic file editing:
- Syntax highlighting
- Save/reload files
- Config validation
## Starting the Console
```bash
./botserver --console
```
Or programmatically:
```rust
let mut ui = XtreeUI::new();
ui.set_app_state(app_state);
ui.start_ui()?;
```
## Progress Channel
Monitor background tasks:
```rust
let (tx, rx) = tokio::sync::mpsc::channel(100);
ui.set_progress_channel(rx);
// Send progress updates
tx.send(ProgressUpdate::new("Loading KB...", 50)).await;
```
## Use Cases
- Server administration without web UI
- SSH-based remote management
- Development and debugging
- Headless server deployments
- Quick configuration changes
## See Also
- [Building from Source](../chapter-07-gbapp/building.md)
- [Bot Configuration](../chapter-08-config/README.md)

View file

@ -0,0 +1 @@
# Directory Services

View file

@ -0,0 +1,437 @@
# LLM Providers
General Bots supports multiple Large Language Model (LLM) providers, both cloud-based services and local deployments. This guide helps you choose the right provider for your use case.
## Overview
LLMs are the intelligence behind General Bots' conversational capabilities. You can configure:
- **Cloud Providers** - External APIs (OpenAI, Anthropic, Groq, etc.)
- **Local Models** - Self-hosted models via llama.cpp
- **Hybrid** - Use local for simple tasks, cloud for complex reasoning
## Cloud Providers
### OpenAI (GPT Series)
The most widely known LLM provider, offering GPT-4 and GPT-4o models.
| Model | Context | Best For | Speed |
|-------|---------|----------|-------|
| GPT-4o | 128K | General purpose, vision | Fast |
| GPT-4o-mini | 128K | Cost-effective tasks | Very Fast |
| GPT-4 Turbo | 128K | Complex reasoning | Medium |
| o1-preview | 128K | Advanced reasoning, math | Slow |
| o1-mini | 128K | Code, logic tasks | Medium |
**Configuration:**
```csv
llm-provider,openai
llm-api-key,sk-xxxxxxxxxxxxxxxxxxxxxxxx
llm-model,gpt-4o
```
**Strengths:**
- Excellent general knowledge
- Strong code generation
- Good instruction following
- Vision capabilities (GPT-4o)
**Considerations:**
- API costs can add up
- Data sent to external servers
- Rate limits apply
### Anthropic (Claude Series)
Known for safety, helpfulness, and large context windows.
| Model | Context | Best For | Speed |
|-------|---------|----------|-------|
| Claude 3.5 Sonnet | 200K | Best balance of capability/speed | Fast |
| Claude 3.5 Haiku | 200K | Quick, everyday tasks | Very Fast |
| Claude 3 Opus | 200K | Most capable, complex tasks | Slow |
**Configuration:**
```csv
llm-provider,anthropic
llm-api-key,sk-ant-xxxxxxxxxxxxxxxx
llm-model,claude-3-5-sonnet-20241022
```
**Strengths:**
- Largest context window (200K tokens)
- Excellent at following complex instructions
- Strong coding abilities
- Better at refusing harmful requests
**Considerations:**
- Premium pricing
- No vision in all models
- Newer provider, smaller ecosystem
### Groq
Ultra-fast inference using custom LPU hardware. Offers open-source models at high speed.
| Model | Context | Best For | Speed |
|-------|---------|----------|-------|
| Llama 3.3 70B | 128K | Complex reasoning | Very Fast |
| Llama 3.1 8B | 128K | Quick responses | Extremely Fast |
| Mixtral 8x7B | 32K | Balanced performance | Very Fast |
| Gemma 2 9B | 8K | Lightweight tasks | Extremely Fast |
**Configuration:**
```csv
llm-provider,groq
llm-api-key,gsk_xxxxxxxxxxxxxxxx
llm-model,llama-3.3-70b-versatile
```
**Strengths:**
- Fastest inference speeds (500+ tokens/sec)
- Competitive pricing
- Open-source models
- Great for real-time applications
**Considerations:**
- Limited model selection
- Rate limits on free tier
- Models may be less capable than GPT-4/Claude
### Google (Gemini Series)
Google's multimodal AI models with strong reasoning capabilities.
| Model | Context | Best For | Speed |
|-------|---------|----------|-------|
| Gemini 1.5 Pro | 2M | Extremely long documents | Medium |
| Gemini 1.5 Flash | 1M | Fast multimodal | Fast |
| Gemini 2.0 Flash | 1M | Latest capabilities | Fast |
**Configuration:**
```csv
llm-provider,google
llm-api-key,AIzaxxxxxxxxxxxxxxxx
llm-model,gemini-1.5-pro
```
**Strengths:**
- Largest context window (2M tokens)
- Native multimodal (text, image, video, audio)
- Strong at structured data
- Good coding abilities
**Considerations:**
- Newer ecosystem
- Some features region-limited
- API changes more frequently
### Mistral AI
European AI company offering efficient, open-weight models.
| Model | Context | Best For | Speed |
|-------|---------|----------|-------|
| Mistral Large | 128K | Complex tasks | Medium |
| Mistral Medium | 32K | Balanced performance | Fast |
| Mistral Small | 32K | Cost-effective | Very Fast |
| Codestral | 32K | Code generation | Fast |
**Configuration:**
```csv
llm-provider,mistral
llm-api-key,xxxxxxxxxxxxxxxx
llm-model,mistral-large-latest
```
**Strengths:**
- European data sovereignty (GDPR)
- Excellent code generation (Codestral)
- Open-weight models available
- Competitive pricing
**Considerations:**
- Smaller context than competitors
- Less brand recognition
- Fewer fine-tuning options
### DeepSeek
Chinese AI company known for efficient, capable models.
| Model | Context | Best For | Speed |
|-------|---------|----------|-------|
| DeepSeek-V3 | 128K | General purpose | Fast |
| DeepSeek-R1 | 128K | Reasoning, math | Medium |
| DeepSeek-Coder | 128K | Programming | Fast |
**Configuration:**
```csv
llm-provider,deepseek
llm-api-key,sk-xxxxxxxxxxxxxxxx
llm-model,deepseek-chat
llm-server-url,https://api.deepseek.com
```
**Strengths:**
- Extremely cost-effective
- Strong reasoning (R1 model)
- Excellent code generation
- Open-weight versions available
**Considerations:**
- Data processed in China
- Newer provider
- May have content restrictions
## Local Models
Run models on your own hardware for privacy, cost control, and offline operation.
### Setting Up Local LLM
General Bots uses **llama.cpp** server for local inference:
```csv
llm-provider,local
llm-server-url,https://localhost:8081
llm-model,DeepSeek-R1-Distill-Qwen-1.5B
```
### Recommended Local Models
#### For High-End GPU (24GB+ VRAM)
| Model | Size | VRAM | Quality |
|-------|------|------|---------|
| GPT-OSS 120B Q4 | 70GB | 48GB+ | Excellent |
| Llama 3.1 70B Q4 | 40GB | 48GB+ | Excellent |
| DeepSeek-R1 32B Q4 | 20GB | 24GB | Very Good |
| Qwen 2.5 72B Q4 | 42GB | 48GB+ | Excellent |
#### For Mid-Range GPU (12-16GB VRAM)
| Model | Size | VRAM | Quality |
|-------|------|------|---------|
| GPT-OSS 20B F16 | 40GB | 16GB | Very Good |
| Llama 3.1 8B Q8 | 9GB | 12GB | Good |
| DeepSeek-R1-Distill 14B Q4 | 8GB | 12GB | Good |
| Mistral Nemo 12B Q4 | 7GB | 10GB | Good |
#### For Small GPU or CPU (8GB VRAM or less)
| Model | Size | VRAM | Quality |
|-------|------|------|---------|
| DeepSeek-R1-Distill 1.5B Q4 | 1GB | 4GB | Basic |
| Phi-3 Mini 3.8B Q4 | 2.5GB | 6GB | Acceptable |
| Gemma 2 2B Q8 | 3GB | 6GB | Acceptable |
| Qwen 2.5 3B Q4 | 2GB | 4GB | Basic |
### Model Download URLs
Add models to `installer.rs` data_download_list:
```rust
// GPT-OSS 20B - Recommended for small GPU
"https://huggingface.co/unsloth/gpt-oss-20b-GGUF/resolve/main/gpt-oss-20b-F16.gguf"
// DeepSeek R1 Distill - For CPU or minimal GPU
"https://huggingface.co/unsloth/DeepSeek-R1-Distill-Qwen-1.5B-GGUF/resolve/main/DeepSeek-R1-Distill-Qwen-1.5B-Q4_K_M.gguf"
// Llama 3.1 8B - Good balance
"https://huggingface.co/bartowski/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf"
```
### Embedding Models
For vector search, you need an embedding model:
```csv
embedding-provider,local
embedding-server-url,https://localhost:8082
embedding-model,bge-small-en-v1.5
```
Recommended embedding models:
| Model | Dimensions | Size | Quality |
|-------|------------|------|---------|
| bge-small-en-v1.5 | 384 | 130MB | Good |
| bge-base-en-v1.5 | 768 | 440MB | Better |
| bge-large-en-v1.5 | 1024 | 1.3GB | Best |
| nomic-embed-text | 768 | 550MB | Good |
## Hybrid Configuration
Use different models for different tasks:
```csv
# Primary model for complex conversations
llm-provider,anthropic
llm-model,claude-3-5-sonnet-20241022
# Fast model for simple tasks
llm-fast-provider,groq
llm-fast-model,llama-3.1-8b-instant
# Local fallback for offline operation
llm-fallback-provider,local
llm-fallback-model,DeepSeek-R1-Distill-Qwen-1.5B
# Embeddings always local
embedding-provider,local
embedding-model,bge-small-en-v1.5
```
## Model Selection Guide
### By Use Case
| Use Case | Recommended | Why |
|----------|-------------|-----|
| Customer support | Claude 3.5 Sonnet | Best at following guidelines |
| Code generation | DeepSeek-Coder, GPT-4o | Specialized for code |
| Document analysis | Gemini 1.5 Pro | 2M context window |
| Real-time chat | Groq Llama 3.1 8B | Fastest responses |
| Privacy-sensitive | Local DeepSeek-R1 | No external data transfer |
| Cost-sensitive | DeepSeek-V3, Local | Lowest cost per token |
| Complex reasoning | Claude 3 Opus, o1 | Best reasoning ability |
### By Budget
| Budget | Recommended Setup |
|--------|-------------------|
| Free | Local models only |
| Low ($10-50/mo) | Groq + Local fallback |
| Medium ($50-200/mo) | GPT-4o-mini + Claude Haiku |
| High ($200+/mo) | GPT-4o + Claude Sonnet |
| Enterprise | Private deployment + premium APIs |
## Configuration Reference
### Environment Variables
```bash
# Primary LLM
LLM_PROVIDER=openai
LLM_API_KEY=sk-xxx
LLM_MODEL=gpt-4o
LLM_SERVER_URL=https://api.openai.com
# Local LLM Server
LLM_LOCAL_URL=https://localhost:8081
LLM_LOCAL_MODEL=DeepSeek-R1-Distill-Qwen-1.5B
# Embedding
EMBEDDING_PROVIDER=local
EMBEDDING_URL=https://localhost:8082
EMBEDDING_MODEL=bge-small-en-v1.5
```
### config.csv Parameters
| Parameter | Description | Example |
|-----------|-------------|---------|
| `llm-provider` | Provider name | `openai`, `anthropic`, `local` |
| `llm-api-key` | API key for cloud providers | `sk-xxx` |
| `llm-model` | Model identifier | `gpt-4o` |
| `llm-server-url` | API endpoint | `https://api.openai.com` |
| `llm-server-ctx-size` | Context window size | `128000` |
| `llm-temperature` | Response randomness (0-2) | `0.7` |
| `llm-max-tokens` | Maximum response length | `4096` |
| `llm-cache-enabled` | Enable semantic caching | `true` |
| `llm-cache-ttl` | Cache time-to-live (seconds) | `3600` |
## Security Considerations
### Cloud Providers
- API keys should be stored in environment variables or secrets manager
- Consider data residency requirements (EU: Mistral, US: OpenAI)
- Review provider data retention policies
- Use separate keys for production/development
### Local Models
- All data stays on your infrastructure
- No internet required after model download
- Full control over model versions
- Consider GPU security for sensitive deployments
## Performance Optimization
### Caching
Enable semantic caching to reduce API calls:
```csv
llm-cache-enabled,true
llm-cache-ttl,3600
llm-cache-similarity-threshold,0.92
```
### Batching
For bulk operations, use batch APIs when available:
```csv
llm-batch-enabled,true
llm-batch-size,10
```
### Context Management
Optimize context window usage:
```csv
llm-context-compaction,true
llm-max-history-turns,10
llm-summarize-long-contexts,true
```
## Troubleshooting
### Common Issues
**API Key Invalid**
- Verify key is correct and not expired
- Check if key has required permissions
- Ensure billing is active
**Model Not Found**
- Check model name spelling
- Verify model is available in your region
- Some models require waitlist access
**Rate Limits**
- Implement exponential backoff
- Use caching to reduce calls
- Consider upgrading API tier
**Local Model Slow**
- Check GPU memory usage
- Reduce context size
- Use quantized models (Q4 instead of F16)
### Logging
Enable LLM logging for debugging:
```csv
llm-log-requests,true
llm-log-responses,false
llm-log-timing,true
```
## Next Steps
- [LLM Configuration](../chapter-08-config/llm-config.md) - Detailed configuration guide
- [Semantic Caching](../chapter-03/caching.md) - Cache configuration
- [NVIDIA GPU Setup](../chapter-09-api/nvidia-gpu-setup.md) - GPU configuration for local models

View file

@ -0,0 +1,143 @@
# Multimodal Module
Image, video, and audio generation with vision/captioning capabilities.
## Overview
The multimodal module connects to BotModels server for AI-powered media generation and analysis.
## BASIC Keywords
| Keyword | Purpose |
|---------|---------|
| `IMAGE` | Generate image from text prompt |
| `VIDEO` | Generate video from text prompt |
| `AUDIO` | Generate speech audio from text |
| `SEE` | Describe/caption an image or video |
## IMAGE
Generate an image from a text prompt:
```basic
url = IMAGE "A sunset over mountains with a lake"
TALK "Here's your image: " + url
```
Timeout: 300 seconds (5 minutes)
## VIDEO
Generate a video from a text prompt:
```basic
url = VIDEO "A cat playing with a ball of yarn"
TALK "Here's your video: " + url
```
Timeout: 600 seconds (10 minutes)
## AUDIO
Generate speech audio from text:
```basic
url = AUDIO "Welcome to our service. How can I help you today?"
PLAY url
```
## SEE
Get a description of an image or video:
```basic
description = SEE "path/to/image.jpg"
TALK "I see: " + description
```
## Configuration
Add to `config.csv`:
```csv
botmodels-enabled,true
botmodels-host,localhost
botmodels-port,5000
botmodels-api-key,your-api-key
botmodels-use-https,false
```
### Image Generation Config
```csv
botmodels-image-model,stable-diffusion
botmodels-image-steps,20
botmodels-image-width,512
botmodels-image-height,512
```
### Video Generation Config
```csv
botmodels-video-model,text2video
botmodels-video-frames,16
botmodels-video-fps,8
```
## BotModels Client
Rust API for direct integration:
```rust
let client = BotModelsClient::from_state(&state, &bot_id);
if client.is_enabled() {
let image_url = client.generate_image("A beautiful garden").await?;
let description = client.describe_image("path/to/photo.jpg").await?;
}
```
### Available Methods
| Method | Description |
|--------|-------------|
| `generate_image(prompt)` | Create image from text |
| `generate_video(prompt)` | Create video from text |
| `generate_audio(text)` | Create speech audio |
| `describe_image(path)` | Get image caption |
| `describe_video(path)` | Get video description |
| `speech_to_text(audio_path)` | Transcribe audio |
| `health_check()` | Check BotModels server status |
## Response Structures
### GenerationResponse
```json
{
"status": "success",
"file_path": "/path/to/generated/file.png",
"generation_time": 12.5,
"error": null
}
```
### DescribeResponse
```json
{
"description": "A golden retriever playing fetch in a park",
"confidence": 0.92
}
```
## Requirements
- BotModels server running (separate service)
- GPU recommended for generation tasks
- Sufficient disk space for generated media
## See Also
- [NVIDIA Module](./nvidia.md) - GPU monitoring
- [PLAY Keyword](../chapter-06-gbdialog/keyword-play.md) - Play generated audio

View file

@ -0,0 +1,76 @@
# NVIDIA GPU Module
System monitoring for NVIDIA GPU utilization and performance metrics.
## Overview
This module provides GPU monitoring capabilities when NVIDIA hardware is available, useful for tracking resource usage during LLM inference and multimodal generation tasks.
## Feature Flag
Enabled via Cargo feature:
```toml
[features]
nvidia = []
```
## Functions
### has_nvidia_gpu()
Check if NVIDIA GPU is available:
```rust
if nvidia::has_nvidia_gpu() {
// GPU acceleration available
}
```
Returns `true` if `nvidia-smi` command succeeds.
### get_gpu_utilization()
Get current GPU and memory utilization:
```rust
let util = nvidia::get_gpu_utilization()?;
let gpu_percent = util.get("gpu"); // GPU compute utilization %
let mem_percent = util.get("memory"); // GPU memory utilization %
```
### get_system_metrics()
Get combined CPU and GPU metrics:
```rust
let metrics = nvidia::get_system_metrics()?;
println!("CPU: {}%", metrics.cpu_usage);
if let Some(gpu) = metrics.gpu_usage {
println!("GPU: {}%", gpu);
}
```
## SystemMetrics Struct
| Field | Type | Description |
|-------|------|-------------|
| `cpu_usage` | `f32` | CPU utilization percentage |
| `gpu_usage` | `Option<f32>` | GPU utilization (None if no NVIDIA GPU) |
## Requirements
- NVIDIA GPU with driver installed
- `nvidia-smi` command available in PATH
## Use Cases
- Monitor GPU during image/video generation
- Track resource usage for LLM inference
- Capacity planning for bot deployments
- Performance dashboards
## See Also
- [Multimodal Module](./multimodal.md)
- [Time-Series Database](./timeseries.md) - Store GPU metrics over time

View file

@ -0,0 +1 @@
# Storage Services

View file

@ -0,0 +1,85 @@
# Time-Series Database Module
InfluxDB 3 integration for metrics, analytics, and operational data.
## Overview
High-performance time-series storage supporting 2.5M+ points/sec ingestion with async batching.
## Configuration
Add to `config.csv`:
```csv
influxdb-url,http://localhost:8086
influxdb-token,your-token
influxdb-org,pragmatismo
influxdb-bucket,metrics
```
Or environment variables:
```bash
INFLUXDB_URL=http://localhost:8086
INFLUXDB_TOKEN=your-token
INFLUXDB_ORG=pragmatismo
INFLUXDB_BUCKET=metrics
```
## Metric Points
Structure:
| Field | Description |
|-------|-------------|
| `measurement` | Metric name (e.g., "messages", "response_time") |
| `tags` | Indexed key-value pairs for filtering |
| `fields` | Actual metric values |
| `timestamp` | When the metric was recorded |
## Built-in Metrics
| Measurement | Tags | Fields |
|-------------|------|--------|
| `messages` | bot, channel, user | count |
| `response_time` | bot, endpoint | duration_ms |
| `llm_tokens` | bot, model, type | input, output, total |
| `kb_queries` | bot, collection | count, latency_ms |
| `errors` | bot, type, severity | count |
## Usage in Rust
```rust
let client = TimeSeriesClient::new(config).await?;
client.write_point(
MetricPoint::new("messages")
.tag("bot", "sales-bot")
.tag("channel", "whatsapp")
.field_i64("count", 1)
).await?;
```
## Querying
REST endpoint for analytics:
```
GET /api/analytics/timeseries/messages?range=24h
GET /api/analytics/timeseries/response_time?range=7d
```
## Installation
The timeseries_db component is installed via package manager:
```bash
gb install timeseries_db
```
Ports: 8086 (HTTP API), 8083 (RPC)
## See Also
- [Analytics Module](../chapter-04-gbui/apps/analytics.md)
- [Observability Setup](./observability.md)

View file

@ -0,0 +1,318 @@
# Weather API Integration
The `WEATHER` and `FORECAST` keywords provide real-time weather information and multi-day forecasts using the OpenWeatherMap API.
## Keywords Overview
| Keyword | Purpose |
|---------|---------|
| `WEATHER` | Get current weather conditions for a location |
| `FORECAST` | Get extended weather forecast for multiple days |
## WEATHER
Retrieves current weather conditions for a specified location.
### Syntax
```basic
result = WEATHER location
```
### Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `location` | String | City name, optionally with country code (e.g., "London" or "London,UK") |
### Return Value
Returns a formatted string containing:
- Temperature (current and feels-like)
- Weather conditions description
- Humidity percentage
- Wind speed and direction
- Visibility
- Atmospheric pressure
### Example
```basic
' Get current weather for London
weather = WEATHER "London"
TALK weather
' Output:
' Current weather in London:
' 🌡️ Temperature: 15.2°C (feels like 14.5°C)
' ☁️ Conditions: Partly cloudy
' 💧 Humidity: 65%
' 💨 Wind: 3.5 m/s NE
' 🔍 Visibility: 10.0 km
' 📊 Pressure: 1013 hPa
```
## FORECAST
Retrieves an extended weather forecast for multiple days.
### Syntax
```basic
result = FORECAST location, days
```
### Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `location` | String | City name, optionally with country code |
| `days` | Integer | Number of days to forecast (1-5, default: 5) |
### Example
```basic
' Get 5-day forecast for Paris
forecast = FORECAST "Paris,FR", 5
TALK forecast
' Output:
' Weather forecast for Paris:
'
' 📅 2024-03-15
' 🌡️ High: 18.5°C, Low: 12.3°C
' ☁️ Scattered clouds
' ☔ Rain chance: 20%
'
' 📅 2024-03-16
' 🌡️ High: 20.1°C, Low: 13.0°C
' ☁️ Clear sky
' ☔ Rain chance: 5%
' ...
```
## Complete Example: Weather Bot
```basic
' weather-assistant.bas
' A conversational weather assistant
TALK "Hello! I can help you with weather information."
TALK "Which city would you like to know about?"
HEAR city
TALK "Would you like the current weather or a forecast?"
HEAR choice
IF INSTR(LOWER(choice), "forecast") > 0 THEN
TALK "How many days? (1-5)"
HEAR days
IF NOT IS_NUMERIC(days) THEN
days = 5
END IF
result = FORECAST city, days
TALK result
ELSE
result = WEATHER city
TALK result
END IF
TALK "Is there another city you'd like to check?"
```
## Weather-Based Automation
```basic
' weather-alert.bas
' Send alerts based on weather conditions
cities = ["New York", "London", "Tokyo", "Sydney"]
FOR EACH city IN cities
weather = WEATHER city
' Check for extreme conditions
IF INSTR(weather, "storm") > 0 OR INSTR(weather, "heavy rain") > 0 THEN
SEND MAIL "alerts@company.com", "Weather Alert: " + city, weather
END IF
NEXT
```
## Daily Weather Report
```basic
' daily-weather.bas
' Generate a daily weather report for multiple locations
locations = ["San Francisco,US", "Austin,US", "Seattle,US"]
report = "☀️ Daily Weather Report\n\n"
FOR EACH loc IN locations
weather = WEATHER loc
report = report + weather + "\n\n---\n\n"
NEXT
' Send the compiled report
SEND MAIL "team@company.com", "Daily Weather Update", report
```
## Travel Planning Assistant
```basic
' travel-weather.bas
' Help users plan travel based on weather
TALK "Where are you planning to travel?"
HEAR destination
TALK "When are you planning to go? (Please provide a date)"
HEAR travel_date
' Get forecast for destination
forecast = FORECAST destination, 5
TALK "Here's the weather forecast for " + destination + ":"
TALK forecast
TALK "Based on the forecast, would you like packing suggestions?"
HEAR wants_suggestions
IF LOWER(wants_suggestions) = "yes" THEN
weather = WEATHER destination
IF INSTR(weather, "rain") > 0 THEN
TALK "🌂 Don't forget to pack an umbrella and rain jacket!"
END IF
IF INSTR(weather, "Temperature: 2") > 0 OR INSTR(weather, "Temperature: 3") > 0 THEN
TALK "🩳 It's warm! Pack light clothing and sunscreen."
ELSE IF INSTR(weather, "Temperature: 0") > 0 OR INSTR(weather, "Temperature: 1") > 0 THEN
TALK "🧥 It's cool. Bring a light jacket."
ELSE
TALK "🧣 It's cold! Pack warm layers and a coat."
END IF
END IF
```
## Weather Data Structure
The `WeatherData` object returned internally contains:
| Field | Type | Description |
|-------|------|-------------|
| `location` | String | Resolved location name |
| `temperature` | Float | Current temperature in Celsius |
| `temperature_unit` | String | Temperature unit (°C) |
| `description` | String | Weather condition description |
| `humidity` | Integer | Humidity percentage (0-100) |
| `wind_speed` | Float | Wind speed in m/s |
| `wind_direction` | String | Compass direction (N, NE, E, etc.) |
| `feels_like` | Float | "Feels like" temperature |
| `pressure` | Integer | Atmospheric pressure in hPa |
| `visibility` | Float | Visibility in kilometers |
| `uv_index` | Float (optional) | UV index if available |
| `forecast` | Array | Forecast data (for FORECAST keyword) |
## Forecast Day Structure
Each forecast day contains:
| Field | Type | Description |
|-------|------|-------------|
| `date` | String | Date in YYYY-MM-DD format |
| `temp_high` | Float | Maximum temperature |
| `temp_low` | Float | Minimum temperature |
| `description` | String | Weather conditions |
| `rain_chance` | Integer | Probability of precipitation (0-100%) |
## Configuration
To use the weather keywords, configure your OpenWeatherMap API key in `config.csv`:
| Key | Description | Required |
|-----|-------------|----------|
| `weather-api-key` | OpenWeatherMap API key | Yes |
### Getting an API Key
1. Visit [OpenWeatherMap](https://openweathermap.org/api)
2. Create a free account
3. Navigate to "API Keys" in your dashboard
4. Generate a new API key
5. Add to your bot's `config.csv`:
```csv
weather-api-key,your-api-key-here
```
## Wind Direction Compass
Wind direction is converted from degrees to compass directions:
| Degrees | Direction |
|---------|-----------|
| 0° | N (North) |
| 45° | NE (Northeast) |
| 90° | E (East) |
| 135° | SE (Southeast) |
| 180° | S (South) |
| 225° | SW (Southwest) |
| 270° | W (West) |
| 315° | NW (Northwest) |
## Error Handling
```basic
' Handle weather API errors gracefully
ON ERROR GOTO weather_error
weather = WEATHER "Unknown City XYZ"
TALK weather
END
weather_error:
TALK "Sorry, I couldn't get weather information for that location."
TALK "Please check the city name and try again."
END
```
## Rate Limits
The OpenWeatherMap free tier includes:
- 60 calls per minute
- 1,000,000 calls per month
For higher limits, consider upgrading to a paid plan.
## Best Practices
1. **Use country codes**: For accuracy, include country codes (e.g., "Paris,FR" instead of just "Paris").
2. **Cache results**: Weather data doesn't change frequently—consider caching results for 10-15 minutes.
3. **Handle timeouts**: Weather API calls have a 10-second timeout. Handle failures gracefully.
4. **Validate locations**: Check if the location is valid before making API calls.
5. **Localization**: Consider user preferences for temperature units (Celsius vs Fahrenheit).
## Fallback Behavior
If the OpenWeatherMap API is unavailable, the system will:
1. Log the error
2. Attempt a fallback weather service (if configured)
3. Return a user-friendly error message
## Related Keywords
- [GET](../chapter-06-gbdialog/keyword-get.md) - Make custom HTTP requests to weather APIs
- [SET SCHEDULE](../chapter-06-gbdialog/keyword-set-schedule.md) - Schedule regular weather checks
- [SEND MAIL](../chapter-06-gbdialog/keyword-send-mail.md) - Send weather alerts via email
- [SEND SMS](../chapter-06-gbdialog/keyword-sms.md) - Send weather alerts via SMS
## See Also
- [OpenWeatherMap API Documentation](https://openweathermap.org/api)
- [API Tool Generator](../chapter-06-gbdialog/keyword-use-tool.md) - Create custom weather integrations

View file

@ -0,0 +1,207 @@
<svg width="1400" height="800" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- Modern Gradients -->
<linearGradient id="gbGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:1" />
<stop offset="50%" style="stop-color:#8B5CF6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#A855F7;stop-opacity:1" />
</linearGradient>
<linearGradient id="cloudGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#64748B;stop-opacity:1" />
<stop offset="100%" style="stop-color:#94A3B8;stop-opacity:1" />
</linearGradient>
<linearGradient id="successGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#10B981;stop-opacity:1" />
<stop offset="100%" style="stop-color:#34D399;stop-opacity:1" />
</linearGradient>
<linearGradient id="headerGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#1E1B4B;stop-opacity:0.05" />
<stop offset="50%" style="stop-color:#312E81;stop-opacity:0.08" />
<stop offset="100%" style="stop-color:#1E1B4B;stop-opacity:0.05" />
</linearGradient>
<linearGradient id="flowLine" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:0.2" />
<stop offset="50%" style="stop-color:#8B5CF6;stop-opacity:0.6" />
<stop offset="100%" style="stop-color:#A855F7;stop-opacity:0.2" />
</linearGradient>
<filter id="softGlow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<filter id="dropShadow" x="-10%" y="-10%" width="120%" height="120%">
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-color="#000" flood-opacity="0.1"/>
</filter>
<!-- Arrow marker -->
<marker id="arrowGreen" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#10B981"/>
</marker>
</defs>
<style>
.main-text { fill: #1a1a1a; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.secondary-text { fill: #64748B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.white-text { fill: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.mono-text { fill: #475569; font-family: 'SF Mono', 'Fira Code', Consolas, monospace; }
.accent-text { fill: #6366F1; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
@media (prefers-color-scheme: dark) {
.main-text { fill: #F1F5F9; }
.secondary-text { fill: #94A3B8; }
.mono-text { fill: #CBD5E1; }
}
</style>
<!-- Background subtle pattern -->
<rect width="1400" height="800" fill="#FAFBFC"/>
<rect x="0" y="0" width="1400" height="120" fill="url(#headerGradient)"/>
<!-- Title Section -->
<text x="700" y="50" text-anchor="middle" font-size="28" font-weight="600" class="main-text">API Migration Matrix</text>
<text x="700" y="80" text-anchor="middle" font-size="16" class="secondary-text">Enterprise Cloud APIs → General Bots Keywords</text>
<!-- Platform Labels -->
<g transform="translate(100, 130)">
<!-- Cloud Platform Box -->
<rect x="0" y="0" width="180" height="50" rx="8" fill="url(#cloudGradient)" filter="url(#dropShadow)"/>
<text x="90" y="32" text-anchor="middle" font-size="16" font-weight="600" class="white-text">Cloud Platform</text>
</g>
<g transform="translate(1120, 130)">
<!-- General Bots Box -->
<rect x="0" y="0" width="180" height="50" rx="8" fill="url(#gbGradient)" filter="url(#dropShadow)"/>
<text x="90" y="32" text-anchor="middle" font-size="16" font-weight="600" class="white-text">General Bots</text>
</g>
<!-- Flow Arrow -->
<path d="M300 155 Q700 155 1100 155" stroke="url(#flowLine)" stroke-width="3" fill="none" stroke-dasharray="8,4"/>
<text x="700" y="150" text-anchor="middle" font-size="12" font-weight="500" class="accent-text">MIGRATION PATH</text>
<!-- Comparison Rows -->
<g transform="translate(50, 200)">
<!-- Row 1: Mail -->
<g transform="translate(0, 0)">
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
<circle cx="30" cy="30" r="8" fill="#10B981"/>
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Email / Mail</text>
<text x="55" y="44" font-size="11" class="mono-text">Messages, Send, Folders</text>
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text"></text>
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">SEND MAIL keyword</text>
<text x="900" y="44" font-size="11" class="mono-text">SEND MAIL TO email SUBJECT s BODY b</text>
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
</g>
<!-- Row 2: Calendar -->
<g transform="translate(0, 70)">
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1"/>
<circle cx="30" cy="30" r="8" fill="#10B981"/>
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Calendar Events</text>
<text x="55" y="44" font-size="11" class="mono-text">Events, Scheduling, Free/Busy</text>
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text"></text>
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">BOOK keyword + Calendar API</text>
<text x="900" y="44" font-size="11" class="mono-text">BOOK "Meeting" AT datetime</text>
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
</g>
<!-- Row 3: Drive/Files -->
<g transform="translate(0, 140)">
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
<circle cx="30" cy="30" r="8" fill="#10B981"/>
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Cloud Storage / Files</text>
<text x="55" y="44" font-size="11" class="mono-text">Files, Versions, Sharing</text>
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text"></text>
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">SeaweedFS + File Keywords</text>
<text x="900" y="44" font-size="11" class="mono-text">READ, WRITE, LIST, COPY, MOVE, DELETE</text>
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
</g>
<!-- Row 4: Tasks -->
<g transform="translate(0, 210)">
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1"/>
<circle cx="30" cy="30" r="8" fill="#10B981"/>
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Tasks / Planning</text>
<text x="55" y="44" font-size="11" class="mono-text">Tasks, Lists, Assignments</text>
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text"></text>
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">CREATE TASK + Projects</text>
<text x="900" y="44" font-size="11" class="mono-text">CREATE TASK "title" DUE date IN PROJECT id</text>
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
</g>
<!-- Row 5: Messaging -->
<g transform="translate(0, 280)">
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
<circle cx="30" cy="30" r="8" fill="#10B981"/>
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Team Messaging</text>
<text x="55" y="44" font-size="11" class="mono-text">Chat, Channels, Messages</text>
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text"></text>
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">TALK + Multi-Channel</text>
<text x="900" y="44" font-size="11" class="mono-text">Web, WhatsApp, Teams, Slack, Telegram</text>
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
</g>
<!-- Row 6: Users -->
<g transform="translate(0, 350)">
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1"/>
<circle cx="30" cy="30" r="8" fill="#10B981"/>
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Users / Directory</text>
<text x="55" y="44" font-size="11" class="mono-text">Users, Groups, Permissions</text>
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text"></text>
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">Zitadel IAM + Users API</text>
<text x="900" y="44" font-size="11" class="mono-text">OIDC/OAuth2 + SCIM provisioning</text>
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#successGradient)"/>
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">READY</text>
</g>
<!-- Row 7: Automation -->
<g transform="translate(0, 420)">
<rect x="0" y="0" width="1300" height="60" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
<circle cx="30" cy="30" r="8" fill="#10B981"/>
<text x="55" y="26" font-size="13" font-weight="600" class="main-text">Workflow Automation</text>
<text x="55" y="44" font-size="11" class="mono-text">Flows, Triggers, Connectors</text>
<text x="650" y="35" text-anchor="middle" font-size="20" class="accent-text"></text>
<text x="900" y="26" font-size="13" font-weight="600" class="main-text">BASIC Scripts + SET SCHEDULE</text>
<text x="900" y="44" font-size="11" class="mono-text">90+ keywords, webhooks, cron, full logic</text>
<rect x="1200" y="15" width="70" height="28" rx="14" fill="url(#gbGradient)"/>
<text x="1235" y="34" text-anchor="middle" font-size="11" font-weight="600" class="white-text">BETTER</text>
</g>
</g>
<!-- Summary Stats -->
<g transform="translate(100, 720)">
<rect x="0" y="0" width="250" height="60" rx="8" fill="#EEF2FF" stroke="#C7D2FE" stroke-width="1"/>
<text x="125" y="28" text-anchor="middle" font-size="24" font-weight="700" class="accent-text">100%</text>
<text x="125" y="48" text-anchor="middle" font-size="12" class="secondary-text">Feature Parity</text>
</g>
<g transform="translate(400, 720)">
<rect x="0" y="0" width="250" height="60" rx="8" fill="#ECFDF5" stroke="#A7F3D0" stroke-width="1"/>
<text x="125" y="28" text-anchor="middle" font-size="24" font-weight="700" fill="#10B981">90+</text>
<text x="125" y="48" text-anchor="middle" font-size="12" class="secondary-text">BASIC Keywords</text>
</g>
<g transform="translate(700, 720)">
<rect x="0" y="0" width="250" height="60" rx="8" fill="#FEF3C7" stroke="#FCD34D" stroke-width="1"/>
<text x="125" y="28" text-anchor="middle" font-size="24" font-weight="700" fill="#D97706">$0</text>
<text x="125" y="48" text-anchor="middle" font-size="12" class="secondary-text">Per-User Licensing</text>
</g>
<g transform="translate(1000, 720)">
<rect x="0" y="0" width="300" height="60" rx="8" fill="#F0FDF4" stroke="#86EFAC" stroke-width="1"/>
<text x="150" y="28" text-anchor="middle" font-size="24" font-weight="700" fill="#16A34A">Self-Hosted</text>
<text x="150" y="48" text-anchor="middle" font-size="12" class="secondary-text">Full Data Sovereignty</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,234 @@
<svg width="1200" height="500" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- Modern Gradients -->
<linearGradient id="primaryGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:1" />
<stop offset="100%" style="stop-color:#8B5CF6;stop-opacity:1" />
</linearGradient>
<linearGradient id="cyanGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#06B6D4;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0EA5E9;stop-opacity:1" />
</linearGradient>
<linearGradient id="greenGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#10B981;stop-opacity:1" />
<stop offset="100%" style="stop-color:#34D399;stop-opacity:1" />
</linearGradient>
<linearGradient id="orangeGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#F59E0B;stop-opacity:1" />
<stop offset="100%" style="stop-color:#FBBF24;stop-opacity:1" />
</linearGradient>
<linearGradient id="flowGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#6366F1;stop-opacity:0.2" />
<stop offset="50%" style="stop-color:#8B5CF6;stop-opacity:0.5" />
<stop offset="100%" style="stop-color:#A855F7;stop-opacity:0.2" />
</linearGradient>
<!-- Filters -->
<filter id="cardShadow" x="-10%" y="-10%" width="120%" height="130%">
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#6366F1" flood-opacity="0.15"/>
</filter>
<filter id="softGlow" x="-30%" y="-30%" width="160%" height="160%">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<!-- Arrow markers -->
<marker id="arrowPurple" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#8B5CF6"/>
</marker>
<!-- Dot pattern -->
<pattern id="dots" patternUnits="userSpaceOnUse" width="20" height="20">
<circle cx="10" cy="10" r="1" fill="#6366F1" opacity="0.08"/>
</pattern>
</defs>
<style>
.title-text { fill: #1E1B4B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.main-text { fill: #334155; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.secondary-text { fill: #64748B; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.white-text { fill: #FFFFFF; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.mono-text { fill: #475569; font-family: 'SF Mono', 'Fira Code', Consolas, monospace; }
@media (prefers-color-scheme: dark) {
.title-text { fill: #F1F5F9; }
.main-text { fill: #E2E8F0; }
.secondary-text { fill: #94A3B8; }
.mono-text { fill: #CBD5E1; }
}
</style>
<!-- Background -->
<rect width="1200" height="500" fill="#FAFBFC"/>
<rect width="1200" height="500" fill="url(#dots)"/>
<!-- Title -->
<text x="600" y="40" text-anchor="middle" font-size="22" font-weight="600" class="title-text">General Bots Architecture</text>
<text x="600" y="65" text-anchor="middle" font-size="13" class="secondary-text">Single binary • Zero dependencies • Production ready</text>
<!-- Input Layer -->
<g transform="translate(50, 100)">
<text x="80" y="0" text-anchor="middle" font-size="12" font-weight="600" class="secondary-text">CHANNELS</text>
<!-- Web -->
<rect x="0" y="20" width="160" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
<circle cx="30" cy="45" r="15" fill="url(#cyanGrad)"/>
<text x="28" y="50" text-anchor="middle" font-size="12" font-weight="700" class="white-text">W</text>
<text x="100" y="42" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Web Chat</text>
<text x="100" y="56" text-anchor="middle" font-size="10" class="mono-text">WebSocket</text>
<!-- WhatsApp -->
<rect x="0" y="80" width="160" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
<circle cx="30" cy="105" r="15" fill="url(#greenGrad)"/>
<text x="28" y="110" text-anchor="middle" font-size="12" font-weight="700" class="white-text">WA</text>
<text x="100" y="102" text-anchor="middle" font-size="12" font-weight="500" class="main-text">WhatsApp</text>
<text x="100" y="116" text-anchor="middle" font-size="10" class="mono-text">Business API</text>
<!-- Teams -->
<rect x="0" y="140" width="160" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
<circle cx="30" cy="165" r="15" fill="url(#primaryGrad)"/>
<text x="28" y="170" text-anchor="middle" font-size="12" font-weight="700" class="white-text">T</text>
<text x="100" y="162" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Teams</text>
<text x="100" y="176" text-anchor="middle" font-size="10" class="mono-text">Bot Framework</text>
<!-- Voice -->
<rect x="0" y="200" width="160" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
<circle cx="30" cy="225" r="15" fill="url(#orangeGrad)"/>
<text x="28" y="230" text-anchor="middle" font-size="12" font-weight="700" class="white-text">V</text>
<text x="100" y="222" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Voice</text>
<text x="100" y="236" text-anchor="middle" font-size="10" class="mono-text">LiveKit</text>
</g>
<!-- Flow Arrows to Core -->
<g stroke="url(#flowGrad)" stroke-width="2" fill="none">
<path d="M220 145 Q280 145 340 200" marker-end="url(#arrowPurple)"/>
<path d="M220 180 Q270 180 340 210" marker-end="url(#arrowPurple)"/>
<path d="M220 240 Q270 240 340 230" marker-end="url(#arrowPurple)"/>
<path d="M220 320 Q280 320 340 260" marker-end="url(#arrowPurple)"/>
</g>
<!-- Core Processing -->
<g transform="translate(350, 100)">
<text x="225" y="0" text-anchor="middle" font-size="12" font-weight="600" class="secondary-text">CORE RUNTIME</text>
<!-- Main processing box -->
<rect x="0" y="20" width="450" height="260" rx="12" fill="#FFFFFF" stroke="#C7D2FE" stroke-width="2" filter="url(#cardShadow)"/>
<rect x="0" y="20" width="450" height="40" rx="12" fill="url(#primaryGrad)"/>
<rect x="0" y="48" width="450" height="12" fill="url(#primaryGrad)"/>
<text x="225" y="47" text-anchor="middle" font-size="14" font-weight="600" class="white-text">BotServer (Rust)</text>
<!-- Session Manager -->
<rect x="20" y="75" width="200" height="45" rx="6" fill="#EEF2FF" stroke="#C7D2FE" stroke-width="1"/>
<text x="120" y="95" text-anchor="middle" font-size="11" font-weight="600" class="main-text">Session Manager</text>
<text x="120" y="110" text-anchor="middle" font-size="9" class="mono-text">Tokio Async Runtime</text>
<!-- BASIC Interpreter -->
<rect x="230" y="75" width="200" height="45" rx="6" fill="#FEF3C7" stroke="#FCD34D" stroke-width="1"/>
<text x="330" y="95" text-anchor="middle" font-size="11" font-weight="600" class="main-text">BASIC Interpreter</text>
<text x="330" y="110" text-anchor="middle" font-size="9" class="mono-text">90+ Keywords</text>
<!-- LLM Integration -->
<rect x="20" y="130" width="200" height="45" rx="6" fill="#F5F3FF" stroke="#DDD6FE" stroke-width="1"/>
<text x="120" y="150" text-anchor="middle" font-size="11" font-weight="600" class="main-text">LLM Integration</text>
<text x="120" y="165" text-anchor="middle" font-size="9" class="mono-text">OpenAI, Anthropic, Local</text>
<!-- Package Manager -->
<rect x="230" y="130" width="200" height="45" rx="6" fill="#ECFDF5" stroke="#A7F3D0" stroke-width="1"/>
<text x="330" y="150" text-anchor="middle" font-size="11" font-weight="600" class="main-text">Package Manager</text>
<text x="330" y="165" text-anchor="middle" font-size="9" class="mono-text">.gbai, .gbkb, .gbdialog</text>
<!-- RAG Engine -->
<rect x="20" y="185" width="130" height="40" rx="6" fill="#F0FDF4" stroke="#86EFAC" stroke-width="1"/>
<text x="85" y="202" text-anchor="middle" font-size="10" font-weight="600" class="main-text">RAG Engine</text>
<text x="85" y="216" text-anchor="middle" font-size="8" class="mono-text">Qdrant Vectors</text>
<!-- Tool Executor -->
<rect x="160" y="185" width="130" height="40" rx="6" fill="#FFF7ED" stroke="#FDBA74" stroke-width="1"/>
<text x="225" y="202" text-anchor="middle" font-size="10" font-weight="600" class="main-text">Tool Executor</text>
<text x="225" y="216" text-anchor="middle" font-size="8" class="mono-text">Function Calling</text>
<!-- API Server -->
<rect x="300" y="185" width="130" height="40" rx="6" fill="#EFF6FF" stroke="#93C5FD" stroke-width="1"/>
<text x="365" y="202" text-anchor="middle" font-size="10" font-weight="600" class="main-text">REST API</text>
<text x="365" y="216" text-anchor="middle" font-size="8" class="mono-text">Axum Server</text>
<!-- Data services bar -->
<rect x="20" y="235" width="410" height="35" rx="6" fill="#F8FAFC" stroke="#E2E8F0" stroke-width="1"/>
<text x="60" y="257" text-anchor="middle" font-size="9" class="mono-text">PostgreSQL</text>
<text x="140" y="257" text-anchor="middle" font-size="9" class="mono-text">SeaweedFS</text>
<text x="220" y="257" text-anchor="middle" font-size="9" class="mono-text">Valkey</text>
<text x="300" y="257" text-anchor="middle" font-size="9" class="mono-text">Zitadel</text>
<text x="380" y="257" text-anchor="middle" font-size="9" class="mono-text">Stalwart</text>
</g>
<!-- Flow Arrows to Output -->
<g stroke="url(#flowGrad)" stroke-width="2" fill="none">
<path d="M810 200 Q870 200 920 150" marker-end="url(#arrowPurple)"/>
<path d="M810 230 Q870 230 920 230" marker-end="url(#arrowPurple)"/>
<path d="M810 260 Q870 260 920 310" marker-end="url(#arrowPurple)"/>
</g>
<!-- Output Layer -->
<g transform="translate(930, 100)">
<text x="110" y="0" text-anchor="middle" font-size="12" font-weight="600" class="secondary-text">OUTPUT</text>
<!-- Responses -->
<rect x="0" y="30" width="220" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
<circle cx="30" cy="55" r="15" fill="url(#primaryGrad)"/>
<text x="28" y="60" text-anchor="middle" font-size="10" font-weight="700" class="white-text">💬</text>
<text x="130" y="52" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Conversations</text>
<text x="130" y="66" text-anchor="middle" font-size="10" class="mono-text">Text, Voice, Rich Media</text>
<!-- Actions -->
<rect x="0" y="95" width="220" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
<circle cx="30" cy="120" r="15" fill="url(#greenGrad)"/>
<text x="28" y="125" text-anchor="middle" font-size="10" font-weight="700" class="white-text"></text>
<text x="130" y="117" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Automations</text>
<text x="130" y="131" text-anchor="middle" font-size="10" class="mono-text">Webhooks, Schedules</text>
<!-- Data -->
<rect x="0" y="160" width="220" height="50" rx="8" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
<circle cx="30" cy="185" r="15" fill="url(#cyanGrad)"/>
<text x="28" y="190" text-anchor="middle" font-size="10" font-weight="700" class="white-text">📊</text>
<text x="130" y="182" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Data & Files</text>
<text x="130" y="196" text-anchor="middle" font-size="10" class="mono-text">Drive, Mail, Calendar</text>
</g>
<!-- Bottom stats bar -->
<g transform="translate(100, 420)">
<rect x="0" y="0" width="1000" height="60" rx="10" fill="#FFFFFF" stroke="#E2E8F0" stroke-width="1" filter="url(#cardShadow)"/>
<g transform="translate(50, 15)">
<rect x="0" y="0" width="150" height="30" rx="6" fill="#EEF2FF"/>
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">Single Binary</text>
</g>
<g transform="translate(230, 15)">
<rect x="0" y="0" width="150" height="30" rx="6" fill="#ECFDF5"/>
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">Self-Hosted</text>
</g>
<g transform="translate(410, 15)">
<rect x="0" y="0" width="150" height="30" rx="6" fill="#FEF3C7"/>
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">Open Source</text>
</g>
<g transform="translate(590, 15)">
<rect x="0" y="0" width="150" height="30" rx="6" fill="#F0FDF4"/>
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">AI-First</text>
</g>
<g transform="translate(770, 15)">
<rect x="0" y="0" width="150" height="30" rx="6" fill="#F5F3FF"/>
<text x="75" y="20" text-anchor="middle" font-size="12" font-weight="600" class="main-text">No Forms</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

226
src/assets/architecture.svg Normal file
View file

@ -0,0 +1,226 @@
<svg width="1400" height="900" xmlns="http://www.w3.org/2000/svg">
<style>
/* Light theme defaults */
.neon-blue { stroke: #4A90E2; stroke-width: 2.6; fill: none; }
.neon-orange { stroke: #F5A623; stroke-width: 2.6; fill: none; }
.neon-purple { stroke: #BD10E0; stroke-width: 2.6; fill: none; }
.neon-green { stroke: #7ED321; stroke-width: 2.6; fill: none; }
.neon-cyan { stroke: #50E3C2; stroke-width: 2.6; fill: none; }
.neon-gray { stroke: #666666; stroke-width: 2.6; fill: none; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.arrow-color { stroke: #666; fill: #666; }
/* Dark theme with subtle neon effects */
@media (prefers-color-scheme: dark) {
.neon-blue {
stroke: #00D4FF;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00D4FF) drop-shadow(0 0 8px #00A0FF);
}
.neon-orange {
stroke: #FF9500;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #FF9500) drop-shadow(0 0 8px #FF7700);
}
.neon-purple {
stroke: #E040FB;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #E040FB) drop-shadow(0 0 8px #D500F9);
}
.neon-green {
stroke: #00FF88;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00FF88) drop-shadow(0 0 8px #00E676);
}
.neon-cyan {
stroke: #00E5EA;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00E5EA) drop-shadow(0 0 8px #00BCD4);
}
.neon-gray {
stroke: #888888;
stroke-width: 2.8;
filter: drop-shadow(0 0 2px #888888);
}
.main-text { fill: #FFFFFF; }
.secondary-text { fill: #B0B0B0; }
.arrow-color { stroke: #B0B0B0; fill: #B0B0B0; }
}
</style>
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refX="11.7" refY="3.9" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,7.8 L11.7,3.9 z" class="arrow-color"/>
</marker>
<linearGradient id="flowGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#4A90E2;stop-opacity:0.3" />
<stop offset="25%" style="stop-color:#F5A623;stop-opacity:0.3" />
<stop offset="50%" style="stop-color:#BD10E0;stop-opacity:0.3" />
<stop offset="75%" style="stop-color:#7ED321;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#50E3C2;stop-opacity:0.3" />
</linearGradient>
</defs>
<!-- Title -->
<text x="700" y="45" text-anchor="middle" font-size="32" font-weight="600" class="main-text">General Bots Architecture</text>
<text x="700" y="75" text-anchor="middle" font-size="21" class="secondary-text">Single binary with everything included - no external dependencies</text>
<!-- Phase Labels -->
<text x="180" y="115" text-anchor="middle" font-size="21" font-weight="500" class="secondary-text">Interface Layer</text>
<text x="700" y="115" text-anchor="middle" font-size="21" font-weight="500" class="secondary-text">Core Runtime</text>
<text x="1220" y="115" text-anchor="middle" font-size="21" font-weight="500" class="secondary-text">Processing</text>
<!-- MAIN FLOW DIAGRAM (Upper Section) -->
<g id="main-flow">
<!-- Top Layer - Interface Components -->
<!-- Web Server -->
<rect x="50" y="140" width="130" height="60" class="neon-blue" rx="6.5"/>
<text x="115" y="178" text-anchor="middle" font-size="22" font-weight="500" class="main-text">Web Server</text>
<!-- Console UI -->
<rect x="200" y="140" width="130" height="60" class="neon-cyan" rx="6.5"/>
<text x="265" y="178" text-anchor="middle" font-size="22" font-weight="500" class="main-text">Console UI</text>
<!-- BASIC Interpreter -->
<rect x="480" y="140" width="180" height="60" class="neon-orange" rx="6.5"/>
<text x="570" y="178" text-anchor="middle" font-size="22" font-weight="500" class="main-text">BASIC Interpreter</text>
<!-- LLM Integration -->
<rect x="680" y="140" width="160" height="60" class="neon-purple" rx="6.5"/>
<text x="760" y="178" text-anchor="middle" font-size="22" font-weight="500" class="main-text">LLM Integration</text>
<!-- Package Manager -->
<rect x="860" y="140" width="170" height="60" class="neon-green" rx="6.5"/>
<text x="945" y="178" text-anchor="middle" font-size="22" font-weight="500" class="main-text">Package Manager</text>
<!-- BotModels -->
<rect x="1135" y="140" width="160" height="60" class="neon-purple" rx="6.5"/>
<text x="1215" y="178" text-anchor="middle" font-size="22" font-weight="500" class="main-text">BotModels (AI)</text>
<!-- Middle Layer - Session Manager -->
<rect x="350" y="280" width="400" height="60" class="neon-blue" rx="6.5"/>
<text x="550" y="318" text-anchor="middle" font-size="22" font-weight="500" class="main-text">Session Manager (Tokio Async Runtime)</text>
<!-- Channels Box -->
<rect x="800" y="280" width="150" height="60" class="neon-cyan" rx="6.5"/>
<text x="875" y="318" text-anchor="middle" font-size="22" font-weight="500" class="main-text">Channels</text>
<!-- External API -->
<rect x="980" y="280" width="140" height="60" class="neon-orange" rx="6.5"/>
<text x="1050" y="318" text-anchor="middle" font-size="22" font-weight="500" class="main-text">External API</text>
<!-- Data Layer Components -->
<!-- PostgreSQL -->
<rect x="50" y="420" width="140" height="60" class="neon-orange" rx="6.5"/>
<text x="120" y="458" text-anchor="middle" font-size="22" font-weight="500" class="main-text">PostgreSQL</text>
<!-- Valkey Cache -->
<rect x="210" y="420" width="140" height="60" class="neon-purple" rx="6.5"/>
<text x="280" y="458" text-anchor="middle" font-size="22" font-weight="500" class="main-text">Valkey Cache</text>
<!-- Qdrant Vectors -->
<rect x="370" y="420" width="150" height="60" class="neon-green" rx="6.5"/>
<text x="445" y="458" text-anchor="middle" font-size="22" font-weight="500" class="main-text">Qdrant Vectors</text>
<!-- SeaweedFS -->
<rect x="540" y="420" width="150" height="60" class="neon-cyan" rx="6.5"/>
<text x="615" y="458" text-anchor="middle" font-size="22" font-weight="500" class="main-text">SeaweedFS</text>
<!-- Storage Contents Box -->
<rect x="720" y="420" width="350" height="60" class="neon-gray" rx="6.5"/>
<text x="895" y="448" text-anchor="middle" font-size="18" class="secondary-text">.gbkb (Docs) | .gbdialog (Scripts) | .gbot (Config)</text>
<text x="895" y="470" text-anchor="middle" font-size="18" class="secondary-text">Templates | User Assets</text>
<!-- Directory Services -->
<rect x="1090" y="420" width="140" height="60" class="neon-blue" rx="6.5"/>
<text x="1160" y="458" text-anchor="middle" font-size="22" font-weight="500" class="main-text">Zitadel (IAM)</text>
</g>
<!-- Arrows -->
<g stroke="#666" stroke-width="2.6" fill="none" opacity="0.7">
<!-- Top layer to Session Manager -->
<line x1="115" y1="200" x2="400" y2="280" marker-end="url(#arrow)"/>
<line x1="265" y1="200" x2="450" y2="280" marker-end="url(#arrow)"/>
<line x1="570" y1="200" x2="550" y2="280" marker-end="url(#arrow)"/>
<line x1="760" y1="200" x2="650" y2="280" marker-end="url(#arrow)"/>
<line x1="945" y1="200" x2="750" y2="280" marker-end="url(#arrow)"/>
<!-- BotModels connection -->
<line x1="1215" y1="200" x2="1050" y2="280" stroke-dasharray="3.9,3.9" marker-end="url(#arrow)" opacity="0.5"/>
<!-- Session Manager to Data Layer -->
<line x1="400" y1="340" x2="120" y2="420" marker-end="url(#arrow)"/>
<line x1="450" y1="340" x2="280" y2="420" marker-end="url(#arrow)"/>
<line x1="550" y1="340" x2="445" y2="420" marker-end="url(#arrow)"/>
<line x1="650" y1="340" x2="615" y2="420" marker-end="url(#arrow)"/>
<line x1="700" y1="340" x2="820" y2="420" marker-end="url(#arrow)"/>
<!-- Channels/External connections -->
<line x1="875" y1="340" x2="920" y2="420" marker-end="url(#arrow)"/>
<line x1="1050" y1="340" x2="1160" y2="420" stroke-dasharray="3.9,3.9" marker-end="url(#arrow)" opacity="0.5"/>
</g>
<!-- PROGRESS INDICATOR (Lower Section) -->
<g id="progress-legend">
<!-- Background gradient bar -->
<rect x="50" y="560" width="1300" height="100" fill="url(#flowGradient)" rx="10" opacity="0.2"/>
<!-- Stage markers -->
<circle cx="150" cy="610" r="12" class="neon-blue"/>
<circle cx="400" cy="610" r="12" class="neon-orange"/>
<circle cx="650" cy="610" r="12" class="neon-purple"/>
<circle cx="900" cy="610" r="12" class="neon-green"/>
<circle cx="1150" cy="610" r="12" class="neon-cyan"/>
<!-- Connecting lines -->
<line x1="162" y1="610" x2="388" y2="610" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="412" y1="610" x2="638" y2="610" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="662" y1="610" x2="888" y2="610" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="912" y1="610" x2="1138" y2="610" class="arrow-color" stroke-width="2" opacity="0.4"/>
<!-- Stage labels -->
<text x="150" y="580" text-anchor="middle" font-size="18" font-weight="500" class="main-text">Request</text>
<text x="150" y="650" text-anchor="middle" font-size="16" class="secondary-text">Web/Console</text>
<text x="400" y="580" text-anchor="middle" font-size="18" font-weight="500" class="main-text">Process</text>
<text x="400" y="650" text-anchor="middle" font-size="16" class="secondary-text">BASIC + LLM</text>
<text x="650" y="580" text-anchor="middle" font-size="18" font-weight="500" class="main-text">Decide</text>
<text x="650" y="650" text-anchor="middle" font-size="16" class="secondary-text">AI Routing</text>
<text x="900" y="580" text-anchor="middle" font-size="18" font-weight="500" class="main-text">Execute</text>
<text x="900" y="650" text-anchor="middle" font-size="16" class="secondary-text">Tools + APIs</text>
<text x="1150" y="580" text-anchor="middle" font-size="18" font-weight="500" class="main-text">Respond</text>
<text x="1150" y="650" text-anchor="middle" font-size="16" class="secondary-text">Multi-Channel</text>
</g>
<!-- Legend -->
<g id="legend" transform="translate(50, 720)">
<text x="0" y="0" font-size="18" font-weight="500" class="main-text">Component Types:</text>
<rect x="0" y="20" width="24" height="24" class="neon-blue" rx="4"/>
<text x="35" y="38" font-size="16" class="secondary-text">Interface / Routing</text>
<rect x="200" y="20" width="24" height="24" class="neon-orange" rx="4"/>
<text x="235" y="38" font-size="16" class="secondary-text">Processing / Scripts</text>
<rect x="420" y="20" width="24" height="24" class="neon-purple" rx="4"/>
<text x="455" y="38" font-size="16" class="secondary-text">AI / ML / Decision</text>
<rect x="640" y="20" width="24" height="24" class="neon-green" rx="4"/>
<text x="675" y="38" font-size="16" class="secondary-text">Execution / Storage</text>
<rect x="870" y="20" width="24" height="24" class="neon-cyan" rx="4"/>
<text x="905" y="38" font-size="16" class="secondary-text">Output / Response</text>
</g>
<!-- Description -->
<text x="700" y="810" text-anchor="middle" font-size="21" class="secondary-text">
Rust-powered single binary serving web UI, BASIC scripting, LLM orchestration, and multi-channel messaging
</text>
<text x="700" y="845" text-anchor="middle" font-size="21" class="secondary-text">
Auto-installed infrastructure: PostgreSQL, Valkey, Qdrant, SeaweedFS, Zitadel - zero external dependencies
</text>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,79 @@
<svg width="900" height="600" xmlns="http://www.w3.org/2000/svg">
<!-- Main Container -->
<rect x="50" y="30" width="800" height="540" fill="none" stroke="#4A5568" stroke-width="3" rx="10"/>
<!-- Title Bar -->
<rect x="50" y="30" width="800" height="50" fill="none" stroke="#4A5568" stroke-width="2" rx="10 10 0 0"/>
<text x="450" y="60" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#E2E8F0">BotServer (Single Binary)</text>
<!-- Top Layer Components -->
<g id="top-components">
<!-- Web Server -->
<rect x="100" y="120" width="200" height="80" fill="none" stroke="#4299E1" stroke-width="2" rx="8"/>
<text x="200" y="150" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#63B3ED">Web Server</text>
<text x="200" y="175" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#90CDF4">(Axum)</text>
<!-- BASIC Interpreter -->
<rect x="350" y="120" width="200" height="80" fill="none" stroke="#F56565" stroke-width="2" rx="8"/>
<text x="450" y="150" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#FC8181">BASIC</text>
<text x="450" y="175" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#FEB2B2">Interpreter</text>
<text x="450" y="190" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" fill="#FBB6CE">(Rhai)</text>
<!-- LLM Integration -->
<rect x="600" y="120" width="200" height="80" fill="none" stroke="#B794F4" stroke-width="2" rx="8"/>
<text x="700" y="150" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#D6BCFA">LLM</text>
<text x="700" y="175" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#E9D8FD">Integration</text>
</g>
<!-- Connection Lines from Top to Middle -->
<g stroke="#718096" stroke-width="2" fill="none">
<line x1="200" y1="200" x2="200" y2="240" stroke-dasharray="5,5" opacity="0.6"/>
<line x1="450" y1="200" x2="450" y2="240" stroke-dasharray="5,5" opacity="0.6"/>
<line x1="700" y1="200" x2="700" y2="240" stroke-dasharray="5,5" opacity="0.6"/>
</g>
<!-- Session Manager -->
<rect x="100" y="240" width="700" height="60" fill="none" stroke="#48BB78" stroke-width="2" rx="8"/>
<text x="450" y="275" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#68D391">Session Manager (Tokio)</text>
<!-- Connection Lines from Middle to Data Layer -->
<g stroke="#718096" stroke-width="2" fill="none">
<line x1="250" y1="300" x2="250" y2="340" stroke-dasharray="5,5" opacity="0.6"/>
<line x1="450" y1="300" x2="450" y2="340" stroke-dasharray="5,5" opacity="0.6"/>
<line x1="650" y1="300" x2="650" y2="340" stroke-dasharray="5,5" opacity="0.6"/>
</g>
<!-- Data Layer Components -->
<g id="data-components">
<!-- PostgreSQL -->
<rect x="100" y="340" width="200" height="80" fill="none" stroke="#4A90E2" stroke-width="2" rx="8"/>
<text x="200" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#5BA0F2">PostgreSQL</text>
<text x="200" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#7BB4F6">Database</text>
<!-- Valkey Cache -->
<rect x="350" y="340" width="200" height="80" fill="none" stroke="#E53E3E" stroke-width="2" rx="8"/>
<text x="450" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#FC6B6B">Valkey</text>
<text x="450" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#FD8E8E">Cache</text>
<!-- Qdrant Vectors -->
<rect x="600" y="340" width="200" height="80" fill="none" stroke="#38D4B2" stroke-width="2" rx="8"/>
<text x="700" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#4EECC8">Qdrant</text>
<text x="700" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#6FF4D2">Vectors</text>
</g>
<!-- Object Storage -->
<rect x="100" y="450" width="700" height="100" fill="none" stroke="#38A169" stroke-width="2" rx="8"/>
<text x="450" y="480" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#48BB78">Object Storage (SeaweedFS/S3)</text>
<!-- Storage Items -->
<g id="storage-items">
<rect x="150" y="500" width="150" height="35" fill="none" stroke="#68D391" stroke-width="1" rx="5"/>
<text x="225" y="522" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#9AE6B4">Documents</text>
<rect x="375" y="500" width="150" height="35" fill="none" stroke="#68D391" stroke-width="1" rx="5"/>
<text x="450" y="522" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#9AE6B4">Templates</text>
<rect x="600" y="500" width="150" height="35" fill="none" stroke="#68D391" stroke-width="1" rx="5"/>
<text x="675" y="522" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" fill="#9AE6B4">Assets</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -0,0 +1,182 @@
<svg width="1400" height="900" xmlns="http://www.w3.org/2000/svg">
<style>
/* Light theme defaults */
.neon-blue { stroke: #4A90E2; stroke-width: 2.6; fill: none; }
.neon-orange { stroke: #F5A623; stroke-width: 2.6; fill: none; }
.neon-purple { stroke: #BD10E0; stroke-width: 2.6; fill: none; }
.neon-green { stroke: #7ED321; stroke-width: 2.6; fill: none; }
.neon-cyan { stroke: #50E3C2; stroke-width: 2.6; fill: none; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.arrow-color { stroke: #666; fill: #666; }
/* Dark theme with subtle neon effects */
@media (prefers-color-scheme: dark) {
.neon-blue {
stroke: #00D4FF;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00D4FF) drop-shadow(0 0 8px #00A0FF);
}
.neon-orange {
stroke: #FF9500;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #FF9500) drop-shadow(0 0 8px #FF7700);
}
.neon-purple {
stroke: #E040FB;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #E040FB) drop-shadow(0 0 8px #D500F9);
}
.neon-green {
stroke: #00FF88;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00FF88) drop-shadow(0 0 8px #00E676);
}
.neon-cyan {
stroke: #00E5EA;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00E5EA) drop-shadow(0 0 8px #00BCD4);
}
.main-text { fill: #FFFFFF; }
.secondary-text { fill: #B0B0B0; }
.arrow-color { stroke: #B0B0B0; fill: #B0B0B0; }
}
</style>
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refX="11.7" refY="3.9" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,7.8 L11.7,3.9 z" class="arrow-color"/>
</marker>
<linearGradient id="flowGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#4A90E2;stop-opacity:0.3" />
<stop offset="50%" style="stop-color:#BD10E0;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#7ED321;stop-opacity:0.3" />
</linearGradient>
</defs>
<!-- Title -->
<text x="700" y="45" text-anchor="middle" font-size="32" font-weight="600" class="main-text">BotServer ↔ BotModels Integration</text>
<text x="700" y="75" text-anchor="middle" font-size="18" class="secondary-text">Rust backend calling Python AI services over HTTPS</text>
<!-- MAIN ARCHITECTURE DIAGRAM -->
<g id="main-architecture">
<!-- BotServer Box (Left) -->
<rect x="80" y="120" width="400" height="380" class="neon-blue" rx="10"/>
<text x="280" y="155" text-anchor="middle" font-size="26" font-weight="600" class="main-text">botserver (Rust)</text>
<!-- BotServer Components -->
<rect x="110" y="180" width="160" height="55" class="neon-orange" rx="6.5"/>
<text x="190" y="215" text-anchor="middle" font-size="18" font-weight="500" class="main-text">BASIC Interpreter</text>
<rect x="290" y="180" width="160" height="55" class="neon-purple" rx="6.5"/>
<text x="370" y="215" text-anchor="middle" font-size="18" font-weight="500" class="main-text">LLM Integration</text>
<!-- BASIC Keywords -->
<rect x="110" y="260" width="340" height="120" class="neon-green" rx="6.5"/>
<text x="280" y="290" text-anchor="middle" font-size="18" font-weight="500" class="main-text">BASIC Keywords</text>
<text x="140" y="320" font-size="16" class="secondary-text">• IMAGE prompt</text>
<text x="140" y="345" font-size="16" class="secondary-text">• VIDEO prompt</text>
<text x="300" y="320" font-size="16" class="secondary-text">• AUDIO text</text>
<text x="300" y="345" font-size="16" class="secondary-text">• SEE image</text>
<text x="140" y="370" font-size="16" class="secondary-text">• HEAR AS AUDIO</text>
<!-- Config -->
<rect x="110" y="400" width="340" height="70" class="neon-cyan" rx="6.5"/>
<text x="280" y="430" text-anchor="middle" font-size="16" font-weight="500" class="main-text">config.csv</text>
<text x="280" y="455" text-anchor="middle" font-size="14" class="secondary-text">botmodels-url, botmodels-enabled</text>
<!-- BotModels Box (Right) -->
<rect x="920" y="120" width="400" height="380" class="neon-purple" rx="10"/>
<text x="1120" y="155" text-anchor="middle" font-size="26" font-weight="600" class="main-text">botmodels (Python)</text>
<!-- BotModels Services -->
<rect x="950" y="180" width="160" height="55" class="neon-orange" rx="6.5"/>
<text x="1030" y="208" text-anchor="middle" font-size="16" font-weight="500" class="main-text">Image Service</text>
<text x="1030" y="228" text-anchor="middle" font-size="12" class="secondary-text">Stable Diffusion</text>
<rect x="1130" y="180" width="160" height="55" class="neon-green" rx="6.5"/>
<text x="1210" y="208" text-anchor="middle" font-size="16" font-weight="500" class="main-text">Video Service</text>
<text x="1210" y="228" text-anchor="middle" font-size="12" class="secondary-text">Zeroscope</text>
<rect x="950" y="260" width="160" height="55" class="neon-cyan" rx="6.5"/>
<text x="1030" y="288" text-anchor="middle" font-size="16" font-weight="500" class="main-text">Speech Service</text>
<text x="1030" y="308" text-anchor="middle" font-size="12" class="secondary-text">TTS / Whisper</text>
<rect x="1130" y="260" width="160" height="55" class="neon-blue" rx="6.5"/>
<text x="1210" y="288" text-anchor="middle" font-size="16" font-weight="500" class="main-text">Vision Service</text>
<text x="1210" y="308" text-anchor="middle" font-size="12" class="secondary-text">BLIP2 / QRCode</text>
<!-- API Endpoints -->
<rect x="950" y="340" width="340" height="130" class="neon-orange" rx="6.5"/>
<text x="1120" y="370" text-anchor="middle" font-size="16" font-weight="500" class="main-text">FastAPI Endpoints</text>
<text x="980" y="400" font-size="14" class="secondary-text">/api/v1/image/generate</text>
<text x="980" y="422" font-size="14" class="secondary-text">/api/v1/video/generate</text>
<text x="980" y="444" font-size="14" class="secondary-text">/api/v1/speech/to-text</text>
<text x="980" y="466" font-size="14" class="secondary-text">/api/v1/vision/describe</text>
<!-- Connection Arrow -->
<line x1="480" y1="310" x2="920" y2="310" class="arrow-color" stroke-width="4" marker-end="url(#arrow)"/>
<rect x="600" y="280" width="120" height="60" fill="white" class="neon-cyan" rx="6.5"/>
<text x="660" y="305" text-anchor="middle" font-size="16" font-weight="600" class="main-text">HTTPS</text>
<text x="660" y="325" text-anchor="middle" font-size="12" class="secondary-text">JSON / Binary</text>
<!-- Outputs -->
<rect x="920" y="530" width="400" height="80" class="neon-green" rx="6.5"/>
<text x="1120" y="565" text-anchor="middle" font-size="18" font-weight="500" class="main-text">outputs/ (Generated Files)</text>
<text x="1120" y="590" text-anchor="middle" font-size="14" class="secondary-text">Images, Videos, Audio files served via /outputs</text>
<!-- Arrow from API to outputs -->
<line x1="1120" y1="470" x2="1120" y2="530" class="arrow-color" stroke-width="2.6" stroke-dasharray="3.9,3.9" marker-end="url(#arrow)" opacity="0.6"/>
</g>
<!-- PROGRESS INDICATOR -->
<g id="progress-legend">
<rect x="80" y="650" width="1240" height="80" fill="url(#flowGradient)" rx="10" opacity="0.2"/>
<!-- Stage markers -->
<circle cx="200" cy="690" r="12" class="neon-blue"/>
<circle cx="460" cy="690" r="12" class="neon-orange"/>
<circle cx="720" cy="690" r="12" class="neon-purple"/>
<circle cx="980" cy="690" r="12" class="neon-green"/>
<circle cx="1200" cy="690" r="12" class="neon-cyan"/>
<!-- Connecting lines -->
<line x1="212" y1="690" x2="448" y2="690" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="472" y1="690" x2="708" y2="690" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="732" y1="690" x2="968" y2="690" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="992" y1="690" x2="1188" y2="690" class="arrow-color" stroke-width="2" opacity="0.4"/>
<!-- Stage labels -->
<text x="200" y="720" text-anchor="middle" font-size="14" class="secondary-text">BASIC Keyword</text>
<text x="460" y="720" text-anchor="middle" font-size="14" class="secondary-text">HTTP Request</text>
<text x="720" y="720" text-anchor="middle" font-size="14" class="secondary-text">AI Processing</text>
<text x="980" y="720" text-anchor="middle" font-size="14" class="secondary-text">Generate</text>
<text x="1200" y="720" text-anchor="middle" font-size="14" class="secondary-text">Return URL</text>
</g>
<!-- Legend -->
<g id="legend" transform="translate(80, 770)">
<rect x="0" y="0" width="24" height="24" class="neon-blue" rx="4"/>
<text x="35" y="18" font-size="14" class="secondary-text">Rust Backend</text>
<rect x="180" y="0" width="24" height="24" class="neon-purple" rx="4"/>
<text x="215" y="18" font-size="14" class="secondary-text">Python AI</text>
<rect x="340" y="0" width="24" height="24" class="neon-orange" rx="4"/>
<text x="375" y="18" font-size="14" class="secondary-text">Processing</text>
<rect x="500" y="0" width="24" height="24" class="neon-green" rx="4"/>
<text x="535" y="18" font-size="14" class="secondary-text">Output</text>
<rect x="660" y="0" width="24" height="24" class="neon-cyan" rx="4"/>
<text x="695" y="18" font-size="14" class="secondary-text">Config/API</text>
</g>
<!-- Description -->
<text x="700" y="830" text-anchor="middle" font-size="18" class="secondary-text">
BotModels runs as a separate Python service for GPU-accelerated AI inference
</text>
<text x="700" y="855" text-anchor="middle" font-size="18" class="secondary-text">
Enable with: botmodels-enabled=true and botmodels-url=http://localhost:8001
</text>
</svg>

After

Width:  |  Height:  |  Size: 9.8 KiB

View file

@ -0,0 +1,98 @@
<svg width="800" height="900" viewBox="0 0 800 900" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#4B5563"/>
</marker>
</defs>
<!-- Title -->
<text x="400" y="25" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="#1F2937">Auto-Bootstrap Process</text>
<!-- Start: ./botserver (First Run) -->
<rect x="325" y="50" width="150" height="40" fill="none" stroke="#63B3ED" stroke-width="2" rx="8"/>
<text x="400" y="75" text-anchor="middle" font-family="monospace" font-size="20" fill="#1E40AF">./botserver</text>
<!-- Arrow down -->
<line x1="400" y1="90" x2="400" y2="120" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Detect System -->
<rect x="300" y="120" width="200" height="60" fill="none" stroke="#F6AD55" stroke-width="2" rx="8"/>
<text x="400" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EA580C">Detect System</text>
<text x="400" y="165" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1F2937">(Linux/Mac)</text>
<!-- Arrow down -->
<line x1="400" y1="180" x2="400" y2="210" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Main Process Container -->
<rect x="50" y="210" width="700" height="280" fill="none" stroke="#4A5568" stroke-width="2" rx="10" stroke-dasharray="5,5" opacity="0.6"/>
<text x="400" y="235" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#374151">Auto-Bootstrap Process</text>
<!-- Component Grid -->
<g id="components">
<!-- PostgreSQL -->
<rect x="100" y="260" width="140" height="100" fill="none" stroke="#4A90E2" stroke-width="2" rx="8"/>
<text x="170" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#2563EB">PostgreSQL</text>
<text x="170" y="305" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1E40AF">16.2</text>
<text x="170" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Install</text>
<text x="170" y="340" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Configure</text>
<text x="170" y="355" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Migrate</text>
<!-- Valkey -->
<rect x="260" y="260" width="140" height="100" fill="none" stroke="#E53E3E" stroke-width="2" rx="8"/>
<text x="330" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EF4444">Valkey</text>
<text x="330" y="305" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#DC2626">Cache</text>
<text x="330" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Install</text>
<text x="330" y="340" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Configure</text>
<text x="330" y="355" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Start</text>
<!-- SeaweedFS -->
<rect x="420" y="260" width="140" height="100" fill="none" stroke="#38A169" stroke-width="2" rx="8"/>
<text x="490" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#047857">SeaweedFS</text>
<text x="490" y="305" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#059669">Storage</text>
<text x="490" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Install</text>
<text x="490" y="340" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Configure</text>
<text x="490" y="355" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Start</text>
<!-- Qdrant -->
<rect x="580" y="260" width="140" height="100" fill="none" stroke="#38D4B2" stroke-width="2" rx="8"/>
<text x="650" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#0891B2">Qdrant</text>
<text x="650" y="305" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#0891B2">Vectors</text>
<text x="650" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Install</text>
<text x="650" y="340" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Configure</text>
<text x="650" y="355" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Start</text>
</g>
<!-- LLM Models -->
<rect x="150" y="380" width="500" height="80" fill="none" stroke="#B794F4" stroke-width="2" rx="8"/>
<text x="400" y="405" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#9333EA">LLM Models (Optional)</text>
<text x="400" y="430" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Download BGE embeddings</text>
<text x="400" y="445" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#059669">✓ Download Llama model (if local)</text>
<!-- Arrow down -->
<line x1="400" y1="490" x2="400" y2="520" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Generate .env file -->
<rect x="275" y="520" width="250" height="80" fill="none" stroke="#ED8936" stroke-width="2" rx="8"/>
<text x="400" y="545" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#D97706">Generate .env file</text>
<text x="400" y="565" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">• Secure passwords</text>
<text x="400" y="580" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">• Connection URLs</text>
<text x="400" y="595" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">• Port assignments</text>
<!-- Arrow down -->
<line x1="400" y1="600" x2="400" y2="630" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Load Templates -->
<rect x="275" y="630" width="250" height="80" fill="none" stroke="#9F7AEA" stroke-width="2" rx="8"/>
<text x="400" y="655" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#9333EA">Load Templates</text>
<text x="400" y="675" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">• Scan .gbai dirs</text>
<text x="400" y="690" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">• Create bots</text>
<text x="400" y="705" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">• Index documents</text>
<!-- Arrow down -->
<line x1="400" y1="710" x2="400" y2="740" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Start Web Server -->
<rect x="275" y="740" width="250" height="60" fill="none" stroke="#48BB78" stroke-width="2" rx="8"/>
<text x="400" y="765" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#059669">Start Web Server</text>
<text x="400" y="785" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#10B981">localhost:8080</text>
</svg>

After

Width:  |  Height:  |  Size: 7.5 KiB

View file

@ -0,0 +1,188 @@
<svg width="1400" height="900" xmlns="http://www.w3.org/2000/svg">
<style>
/* Light theme defaults */
.neon-blue { stroke: #4A90E2; stroke-width: 2.6; }
.neon-orange { stroke: #F5A623; stroke-width: 2.6; }
.neon-purple { stroke: #BD10E0; stroke-width: 2.6; }
.neon-green { stroke: #7ED321; stroke-width: 2.6; }
.neon-cyan { stroke: #50E3C2; stroke-width: 2.6; }
.main-text { fill: #1a1a1a; }
.secondary-text { fill: #666; }
.arrow-color { stroke: #666; fill: #666; }
/* Dark theme with subtle neon effects */
@media (prefers-color-scheme: dark) {
.neon-blue {
stroke: #00D4FF;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00D4FF) drop-shadow(0 0 8px #00A0FF);
}
.neon-orange {
stroke: #FF9500;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #FF9500) drop-shadow(0 0 8px #FF7700);
}
.neon-purple {
stroke: #E040FB;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #E040FB) drop-shadow(0 0 8px #D500F9);
}
.neon-green {
stroke: #00FF88;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00FF88) drop-shadow(0 0 8px #00E676);
}
.neon-cyan {
stroke: #00E5EA;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00E5EA) drop-shadow(0 0 8px #00BCD4);
}
.main-text { fill: #FFFFFF; }
.secondary-text { fill: #B0B0B0; }
.arrow-color { stroke: #B0B0B0; fill: #B0B0B0; }
}
</style>
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refX="11.7" refY="3.9" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,7.8 L11.7,3.9 z" class="arrow-color"/>
</marker>
<marker id="arrow-small" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" class="arrow-color"/>
</marker>
</defs>
<!-- Title (well separated from content) -->
<text x="700" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="600" class="main-text">Bootstrap Flow</text>
<!-- MAIN FLOW DIAGRAM (Upper Section) -->
<!-- Phase 1: Start -->
<g id="phase-start">
<rect x="40" y="100" width="160" height="70" fill="none" class="neon-blue" rx="6.5"/>
<text x="120" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="500" class="main-text">./botserver</text>
</g>
<!-- Arrow from Start to OS Detection -->
<line x1="200" y1="135" x2="250" y2="135" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Phase 2: OS Detection -->
<g id="phase-detection">
<rect x="250" y="100" width="180" height="70" fill="none" class="neon-orange" rx="6.5"/>
<text x="340" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="500" class="main-text">OS Detection</text>
</g>
<!-- Arrow from OS Detection to Component Installation -->
<line x1="430" y1="135" x2="490" y2="135" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Phase 3: Component Installation -->
<g id="phase-components">
<!-- Label -->
<text x="620" y="95" text-anchor="middle" font-family="Arial, sans-serif" font-size="21" font-weight="500" class="secondary-text">Component Installation</text>
<!-- Components in 2x2 grid with proper widths -->
<rect x="490" y="120" width="120" height="50" fill="none" class="neon-blue" rx="5"/>
<text x="550" y="151" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="main-text">PostgreSQL</text>
<rect x="630" y="120" width="120" height="50" fill="none" class="neon-purple" rx="5"/>
<text x="690" y="151" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="main-text">Valkey</text>
<rect x="490" y="190" width="120" height="50" fill="none" class="neon-green" rx="5"/>
<text x="550" y="221" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="main-text">SeaweedFS</text>
<rect x="630" y="190" width="120" height="50" fill="none" class="neon-cyan" rx="5"/>
<text x="690" y="221" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="main-text">Qdrant</text>
<!-- Merge lines -->
<g class="arrow-color" stroke-width="1.5" fill="none" opacity="0.5">
<line x1="550" y1="170" x2="550" y2="180"/>
<line x1="690" y1="170" x2="690" y2="180"/>
<line x1="550" y1="180" x2="690" y2="180"/>
<line x1="620" y1="180" x2="620" y2="260"/>
</g>
</g>
<!-- Arrow to Configuration -->
<line x1="620" y1="260" x2="620" y2="330" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Phase 4: Configuration & Setup -->
<g id="phase-config">
<rect x="490" y="330" width="260" height="70" fill="none" class="neon-purple" rx="6.5"/>
<text x="620" y="375" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="500" class="main-text">Configuration &amp; Setup</text>
</g>
<!-- Arrow from Configuration to Bot Deployment section -->
<line x1="750" y1="365" x2="820" y2="365" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Phase 5: Bot Deployment (vertical flow) -->
<g id="phase-deployment">
<!-- Label -->
<text x="1030" y="95" text-anchor="middle" font-family="Arial, sans-serif" font-size="21" font-weight="500" class="secondary-text">Bot Deployment</text>
<!-- Scan templates with proper width -->
<rect x="880" y="120" width="300" height="60" fill="none" class="neon-orange" rx="6.5"/>
<text x="1030" y="158" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" class="main-text">Scan templates/ directory</text>
<!-- Dashed arrow -->
<line x1="1030" y1="180" x2="1030" y2="230" class="arrow-color" stroke-width="2.6" stroke-dasharray="3.9,3.9" marker-end="url(#arrow)" opacity="0.5"/>
<!-- Load packages with proper width -->
<rect x="880" y="230" width="300" height="60" fill="none" class="neon-orange" rx="6.5"/>
<text x="1030" y="268" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" class="main-text">Load .gbai packages</text>
<!-- Arrow -->
<line x1="1030" y1="290" x2="1030" y2="340" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Start Web Server -->
<rect x="880" y="340" width="300" height="60" fill="none" class="neon-green" rx="6.5"/>
<text x="1030" y="378" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="500" class="main-text">Start Web Server</text>
</g>
<!-- PROGRESS INDICATOR (Bottom Section) -->
<g id="process-flow">
<!-- Large flow arrow at bottom -->
<defs>
<linearGradient id="flowGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#4A90E2;stop-opacity:0.3" />
<stop offset="50%" style="stop-color:#BD10E0;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#7ED321;stop-opacity:0.3" />
</linearGradient>
</defs>
<!-- Flow visualization bar -->
<rect x="120" y="500" width="1060" height="80" fill="url(#flowGradient)" rx="10" opacity="0.2"/>
<!-- Stage indicators -->
<circle cx="120" cy="540" r="8" class="neon-blue" fill="none"/>
<circle cx="340" cy="540" r="8" class="neon-orange" fill="none"/>
<circle cx="620" cy="540" r="8" class="neon-purple" fill="none"/>
<circle cx="1030" cy="540" r="8" class="neon-green" fill="none"/>
<!-- Connecting lines -->
<line x1="128" y1="540" x2="332" y2="540" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="348" y1="540" x2="612" y2="540" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="628" y1="540" x2="1022" y2="540" class="arrow-color" stroke-width="2" opacity="0.4"/>
<!-- Stage labels -->
<text x="120" y="610" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="secondary-text">Start</text>
<text x="340" y="610" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="secondary-text">Detect</text>
<text x="620" y="610" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="secondary-text">Install &amp; Configure</text>
<text x="1030" y="610" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="secondary-text">Deploy</text>
</g>
<!-- Description text (well-spaced at bottom) -->
<text x="700" y="720" text-anchor="middle" font-family="Arial, sans-serif" font-size="21" class="secondary-text">
Automatic bootstrap process: detect OS, install components, configure, and deploy
</text>
<text x="700" y="755" text-anchor="middle" font-family="Arial, sans-serif" font-size="21" class="secondary-text">
Zero configuration required - everything runs from a single binary
</text>
<!-- Optional: Add subtle grid/connection lines in background -->
<g opacity="0.05" class="arrow-color">
<line x1="120" y1="170" x2="120" y2="500" stroke-width="1" stroke-dasharray="2,4"/>
<line x1="340" y1="170" x2="340" y2="500" stroke-width="1" stroke-dasharray="2,4"/>
<line x1="620" y1="240" x2="620" y2="500" stroke-width="1" stroke-dasharray="2,4"/>
<line x1="1030" y1="400" x2="1030" y2="500" stroke-width="1" stroke-dasharray="2,4"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

@ -0,0 +1,188 @@
<svg width="1400" height="900" xmlns="http://www.w3.org/2000/svg">
<style>
/* Light theme defaults */
.neon-blue { stroke: #4A90E2; stroke-width: 2.6; }
.neon-orange { stroke: #F5A623; stroke-width: 2.6; }
.neon-purple { stroke: #BD10E0; stroke-width: 2.6; }
.neon-green { stroke: #7ED321; stroke-width: 2.6; }
.neon-cyan { stroke: #50E3C2; stroke-width: 2.6; }
.main-text { fill: #1a1a1a; }
.secondary-text { fill: #666; }
.arrow-color { stroke: #666; fill: #666; }
/* Dark theme with subtle neon effects */
@media (prefers-color-scheme: dark) {
.neon-blue {
stroke: #00D4FF;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00D4FF) drop-shadow(0 0 8px #00A0FF);
}
.neon-orange {
stroke: #FF9500;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #FF9500) drop-shadow(0 0 8px #FF7700);
}
.neon-purple {
stroke: #E040FB;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #E040FB) drop-shadow(0 0 8px #D500F9);
}
.neon-green {
stroke: #00FF88;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00FF88) drop-shadow(0 0 8px #00E676);
}
.neon-cyan {
stroke: #00E5EA;
stroke-width: 2.8;
filter: drop-shadow(0 0 4px #00E5EA) drop-shadow(0 0 8px #00BCD4);
}
.main-text { fill: #FFFFFF; }
.secondary-text { fill: #B0B0B0; }
.arrow-color { stroke: #B0B0B0; fill: #B0B0B0; }
}
</style>
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refX="11.7" refY="3.9" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,7.8 L11.7,3.9 z" class="arrow-color"/>
</marker>
<marker id="arrow-small" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" class="arrow-color"/>
</marker>
</defs>
<!-- Title (well separated from content) -->
<text x="700" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="32" font-weight="600" class="main-text">Bootstrap Flow</text>
<!-- MAIN FLOW DIAGRAM (Upper Section) -->
<!-- Phase 1: Start -->
<g id="phase-start">
<rect x="40" y="100" width="160" height="70" fill="none" class="neon-blue" rx="6.5"/>
<text x="120" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="500" class="main-text">./botserver</text>
</g>
<!-- Arrow from Start to OS Detection -->
<line x1="200" y1="135" x2="250" y2="135" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Phase 2: OS Detection -->
<g id="phase-detection">
<rect x="250" y="100" width="180" height="70" fill="none" class="neon-orange" rx="6.5"/>
<text x="340" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="500" class="main-text">OS Detection</text>
</g>
<!-- Arrow from OS Detection to Component Installation -->
<line x1="430" y1="135" x2="490" y2="135" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Phase 3: Component Installation -->
<g id="phase-components">
<!-- Label -->
<text x="620" y="95" text-anchor="middle" font-family="Arial, sans-serif" font-size="21" font-weight="500" class="secondary-text">Component Installation</text>
<!-- Components in 2x2 grid with proper widths -->
<rect x="490" y="120" width="120" height="50" fill="none" class="neon-blue" rx="5"/>
<text x="550" y="151" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="main-text">PostgreSQL</text>
<rect x="630" y="120" width="120" height="50" fill="none" class="neon-purple" rx="5"/>
<text x="690" y="151" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="main-text">Valkey</text>
<rect x="490" y="190" width="120" height="50" fill="none" class="neon-green" rx="5"/>
<text x="550" y="221" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="main-text">SeaweedFS</text>
<rect x="630" y="190" width="120" height="50" fill="none" class="neon-cyan" rx="5"/>
<text x="690" y="221" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="main-text">Qdrant</text>
<!-- Merge lines -->
<g class="arrow-color" stroke-width="1.5" fill="none" opacity="0.5">
<line x1="550" y1="170" x2="550" y2="180"/>
<line x1="690" y1="170" x2="690" y2="180"/>
<line x1="550" y1="180" x2="690" y2="180"/>
<line x1="620" y1="180" x2="620" y2="260"/>
</g>
</g>
<!-- Arrow to Configuration -->
<line x1="620" y1="260" x2="620" y2="330" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Phase 4: Configuration & Setup -->
<g id="phase-config">
<rect x="490" y="330" width="260" height="70" fill="none" class="neon-purple" rx="6.5"/>
<text x="620" y="375" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="500" class="main-text">Configuration &amp; Setup</text>
</g>
<!-- Arrow from Configuration to Bot Deployment section -->
<line x1="750" y1="365" x2="820" y2="365" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Phase 5: Bot Deployment (vertical flow) -->
<g id="phase-deployment">
<!-- Label -->
<text x="1030" y="95" text-anchor="middle" font-family="Arial, sans-serif" font-size="21" font-weight="500" class="secondary-text">Bot Deployment</text>
<!-- Scan templates with proper width -->
<rect x="880" y="120" width="300" height="60" fill="none" class="neon-orange" rx="6.5"/>
<text x="1030" y="158" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" class="main-text">Scan templates/ directory</text>
<!-- Dashed arrow -->
<line x1="1030" y1="180" x2="1030" y2="230" class="arrow-color" stroke-width="2.6" stroke-dasharray="3.9,3.9" marker-end="url(#arrow)" opacity="0.5"/>
<!-- Load packages with proper width -->
<rect x="880" y="230" width="300" height="60" fill="none" class="neon-orange" rx="6.5"/>
<text x="1030" y="268" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" class="main-text">Load .gbai packages</text>
<!-- Arrow -->
<line x1="1030" y1="290" x2="1030" y2="340" class="arrow-color" stroke-width="2.6" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Start Web Server -->
<rect x="880" y="340" width="300" height="60" fill="none" class="neon-green" rx="6.5"/>
<text x="1030" y="378" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="500" class="main-text">Start Web Server</text>
</g>
<!-- PROGRESS INDICATOR (Bottom Section) -->
<g id="process-flow">
<!-- Large flow arrow at bottom -->
<defs>
<linearGradient id="flowGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#4A90E2;stop-opacity:0.3" />
<stop offset="50%" style="stop-color:#BD10E0;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#7ED321;stop-opacity:0.3" />
</linearGradient>
</defs>
<!-- Flow visualization bar -->
<rect x="120" y="500" width="1060" height="80" fill="url(#flowGradient)" rx="10" opacity="0.2"/>
<!-- Stage indicators -->
<circle cx="120" cy="540" r="8" class="neon-blue" fill="none"/>
<circle cx="340" cy="540" r="8" class="neon-orange" fill="none"/>
<circle cx="620" cy="540" r="8" class="neon-purple" fill="none"/>
<circle cx="1030" cy="540" r="8" class="neon-green" fill="none"/>
<!-- Connecting lines -->
<line x1="128" y1="540" x2="332" y2="540" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="348" y1="540" x2="612" y2="540" class="arrow-color" stroke-width="2" opacity="0.4"/>
<line x1="628" y1="540" x2="1022" y2="540" class="arrow-color" stroke-width="2" opacity="0.4"/>
<!-- Stage labels -->
<text x="120" y="610" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="secondary-text">Start</text>
<text x="340" y="610" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="secondary-text">Detect</text>
<text x="620" y="610" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="secondary-text">Install &amp; Configure</text>
<text x="1030" y="610" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" class="secondary-text">Deploy</text>
</g>
<!-- Description text (well-spaced at bottom) -->
<text x="700" y="720" text-anchor="middle" font-family="Arial, sans-serif" font-size="21" class="secondary-text">
Automatic bootstrap process: detect OS, install components, configure, and deploy
</text>
<text x="700" y="755" text-anchor="middle" font-family="Arial, sans-serif" font-size="21" class="secondary-text">
Zero configuration required - everything runs from a single binary
</text>
<!-- Optional: Add subtle grid/connection lines in background -->
<g opacity="0.05" class="arrow-color">
<line x1="120" y1="170" x2="120" y2="500" stroke-width="1" stroke-dasharray="2,4"/>
<line x1="340" y1="170" x2="340" y2="500" stroke-width="1" stroke-dasharray="2,4"/>
<line x1="620" y1="240" x2="620" y2="500" stroke-width="1" stroke-dasharray="2,4"/>
<line x1="1030" y1="400" x2="1030" y2="500" stroke-width="1" stroke-dasharray="2,4"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

@ -0,0 +1,103 @@
<svg width="800" height="600" viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#4B5563"/>
</marker>
<marker id="arrow-double" markerWidth="10" markerHeight="10" refX="5" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L5,3 z" fill="#999"/>
<path d="M5,0 L5,6 L10,3 z" fill="#999"/>
</marker>
</defs>
<!-- Title -->
<text x="400" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="#1F2937">Session Manager Architecture</text>
<!-- User Input -->
<rect x="50" y="60" width="150" height="50" fill="none" stroke="#63B3ED" stroke-width="2" rx="8"/>
<text x="125" y="85" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1E40AF">User Input</text>
<!-- Bot Response -->
<rect x="600" y="60" width="150" height="50" fill="none" stroke="#68D391" stroke-width="2" rx="8"/>
<text x="675" y="85" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#10B981">Bot Response</text>
<!-- Arrows down from User Input and up to Bot Response -->
<line x1="125" y1="110" x2="125" y2="150" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="675" y1="150" x2="675" y2="110" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- WebSocket/HTTP boxes -->
<rect x="50" y="150" width="150" height="60" fill="none" stroke="#F6AD55" stroke-width="2" rx="6"/>
<text x="125" y="175" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EA580C">WebSocket</text>
<text x="125" y="195" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#FED7AA">/HTTP</text>
<rect x="600" y="150" width="150" height="60" fill="none" stroke="#F6AD55" stroke-width="2" rx="6"/>
<text x="675" y="175" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EA580C">WebSocket</text>
<text x="675" y="195" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#FED7AA">/HTTP</text>
<!-- Arrows to/from Session Manager -->
<line x1="125" y1="210" x2="125" y2="250" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="675" y1="250" x2="675" y2="210" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Session Manager Box -->
<rect x="100" y="250" width="600" height="130" fill="none" stroke="#B794F4" stroke-width="3" rx="10"/>
<text x="400" y="280" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#9333EA">Session Manager</text>
<!-- Session Manager Steps -->
<g font-family="Arial, sans-serif" font-size="18" fill="#7C3AED">
<text x="150" y="310">1. Validate Token</text>
<text x="150" y="330">2. Load Session</text>
<text x="150" y="350">3. Update State</text>
<text x="450" y="310">4. Execute BASIC</text>
<text x="450" y="330">5. Generate Response</text>
<text x="450" y="350">6. Save History</text>
</g>
<!-- Arrows down to databases -->
<line x1="250" y1="380" x2="250" y2="420" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="550" y1="380" x2="550" y2="420" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Database boxes -->
<rect x="150" y="420" width="200" height="80" fill="none" stroke="#E53E3E" stroke-width="2" rx="8"/>
<text x="250" y="450" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EF4444">Valkey</text>
<text x="250" y="470" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#DC2626">(Cache)</text>
<rect x="450" y="420" width="200" height="80" fill="none" stroke="#4A90E2" stroke-width="2" rx="8"/>
<text x="550" y="450" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#2563EB">PostgreSQL</text>
<text x="550" y="470" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1E40AF">(Persist)</text>
<!-- Sync arrow between databases -->
<path d="M 350 460 L 450 460" stroke="#888" stroke-width="2" marker-end="url(#arrow-double)" stroke-dasharray="5,5" opacity="0.7"/>
<text x="400" y="455" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">Sync Every</text>
<text x="400" y="475" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">Message</text>
<!-- Process Flow Numbers -->
<g font-family="Arial, sans-serif" font-size="16" fill="#374151">
<circle cx="125" cy="130" r="12" fill="none" stroke="#718096" stroke-width="1"/>
<text x="125" y="134" text-anchor="middle">1</text>
<circle cx="125" cy="230" r="12" fill="none" stroke="#718096" stroke-width="1"/>
<text x="125" y="234" text-anchor="middle">2</text>
<circle cx="400" cy="315" r="12" fill="none" stroke="#718096" stroke-width="1"/>
<text x="400" y="319" text-anchor="middle">3</text>
<circle cx="675" cy="230" r="12" fill="none" stroke="#718096" stroke-width="1"/>
<text x="675" y="234" text-anchor="middle">4</text>
<circle cx="675" cy="130" r="12" fill="none" stroke="#718096" stroke-width="1"/>
<text x="675" y="134" text-anchor="middle">5</text>
</g>
<!-- Features box -->
<g id="features" transform="translate(50, 520)">
<rect x="0" y="0" width="700" height="60" fill="none" stroke="#4A5568" stroke-width="1" rx="5" stroke-dasharray="2,2" opacity="0.5"/>
<text x="350" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#1F2937">Key Features</text>
<g font-family="Arial, sans-serif" font-size="16" fill="#374151">
<text x="50" y="45">• Real-time WebSocket support</text>
<text x="250" y="45">• Automatic session persistence</text>
<text x="450" y="45">• Redis-compatible caching</text>
<text x="600" y="45">• ACID compliance</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -0,0 +1,79 @@
<svg width="800" height="600" viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#4B5563"/>
</marker>
</defs>
<!-- Title -->
<text x="300" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="#1F2937">Session State Flow</text>
<!-- Browser Opens -->
<rect x="200" y="60" width="200" height="50" fill="none" stroke="#63B3ED" stroke-width="2" rx="8"/>
<text x="300" y="85" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1E40AF">Browser</text>
<text x="300" y="100" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1F2937">Opens</text>
<!-- Arrow down -->
<line x1="300" y1="110" x2="300" y2="150" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- CREATE State -->
<rect x="200" y="150" width="200" height="80" fill="none" stroke="#48BB78" stroke-width="2" rx="8"/>
<text x="300" y="175" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#059669">CREATE</text>
<text x="300" y="195" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#10B981">New UUID</text>
<text x="300" y="210" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#10B981">Token Gen</text>
<!-- Arrow down -->
<line x1="300" y1="230" x2="300" y2="270" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- ACTIVE State -->
<rect x="200" y="270" width="200" height="80" fill="none" stroke="#4299E1" stroke-width="2" rx="8"/>
<text x="300" y="295" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#2563EB">ACTIVE</text>
<text x="300" y="315" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1E40AF">Chatting</text>
<text x="300" y="330" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1E40AF">Messages</text>
<!-- Arrow down -->
<line x1="300" y1="350" x2="300" y2="390" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- IDLE State -->
<rect x="200" y="390" width="200" height="80" fill="none" stroke="#F6AD55" stroke-width="2" rx="8"/>
<text x="300" y="415" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EA580C">IDLE</text>
<text x="300" y="435" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#FED7AA">No Input</text>
<text x="300" y="450" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#FED7AA">30min Timer</text>
<!-- User Returns Loop -->
<path d="M 400 430 Q 480 360 480 310 Q 480 260 400 310"
stroke="#888" stroke-width="2" fill="none" marker-end="url(#arrow)" stroke-dasharray="5,5" opacity="0.7"/>
<text x="490" y="360" font-family="Arial, sans-serif" font-size="16" fill="#374151">User Returns</text>
<!-- Arrow down -->
<line x1="300" y1="470" x2="300" y2="510" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- EXPIRE State -->
<rect x="200" y="510" width="200" height="80" fill="none" stroke="#FC8181" stroke-width="2" rx="8"/>
<text x="300" y="535" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EF4444">EXPIRE</text>
<text x="300" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#DC2626">7d Anon</text>
<text x="300" y="570" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#DC2626">Never Auth</text>
<!-- Retry Loop -->
<path d="M 200 550 Q 120 400 120 200 Q 120 150 200 190"
stroke="#888" stroke-width="2" fill="none" marker-end="url(#arrow)" stroke-dasharray="5,5" opacity="0.7"/>
<text x="90" y="360" font-family="Arial, sans-serif" font-size="16" fill="#374151">Retry</text>
<!-- Arrow down -->
<line x1="300" y1="590" x2="300" y2="630" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- CLEANUP State -->
<rect x="200" y="630" width="200" height="80" fill="none" stroke="#718096" stroke-width="2" rx="8"/>
<text x="300" y="655" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#374151">CLEANUP</text>
<text x="300" y="675" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1F2937">Archive</text>
<text x="300" y="690" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1F2937">Delete</text>
<!-- State Duration Labels -->
<g id="durations" font-family="Arial, sans-serif" font-size="16" fill="#374151">
<text x="420" y="195" text-anchor="start">Instant</text>
<text x="420" y="315" text-anchor="start">Active use</text>
<text x="420" y="435" text-anchor="start">30 minutes</text>
<text x="420" y="555" text-anchor="start">7 days / Never</text>
<text x="420" y="675" text-anchor="start">Permanent</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5 KiB

View file

@ -0,0 +1,105 @@
<svg width="800" height="600" viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#4B5563"/>
</marker>
</defs>
<!-- Title -->
<text x="350" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="#1F2937">Tool Execution Flow</text>
<!-- User Input -->
<rect x="200" y="60" width="300" height="50" fill="none" stroke="#63B3ED" stroke-width="2" rx="8"/>
<text x="350" y="85" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" fill="#1E40AF">User: "I want to enroll in</text>
<text x="350" y="100" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" fill="#1E40AF">Computer Science"</text>
<!-- Arrow down -->
<line x1="350" y1="110" x2="350" y2="140" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- LLM Analyzes -->
<rect x="225" y="140" width="250" height="80" fill="none" stroke="#B794F4" stroke-width="2" rx="8"/>
<text x="350" y="165" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#9333EA">LLM Analyzes</text>
<text x="350" y="185" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#7C3AED">"enrollment need"</text>
<text x="350" y="200" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">Intent detection</text>
<!-- Arrow down -->
<line x1="350" y1="220" x2="350" y2="250" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Scan Available Tools -->
<rect x="175" y="250" width="350" height="100" fill="none" stroke="#F6AD55" stroke-width="2" rx="8"/>
<text x="350" y="275" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EA580C">Scan Available Tools</text>
<g font-family="monospace" font-size="18">
<text x="220" y="305" fill="#059669">• enrollment.bas ✓</text>
<text x="220" y="325" fill="#374151">• other-tools.bas</text>
</g>
<!-- Arrow down -->
<line x1="350" y1="350" x2="350" y2="380" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Collect Parameters -->
<rect x="175" y="380" width="350" height="120" fill="none" stroke="#4FD1C5" stroke-width="2" rx="8"/>
<text x="350" y="405" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#0891B2">Collect Parameters</text>
<g font-family="Arial, sans-serif" font-size="18" fill="#0E7490">
<text x="220" y="435">• name: (ask user)</text>
<text x="220" y="455">• email: (ask user)</text>
<text x="220" y="475">• course: "Comp Sci"</text>
</g>
<!-- Arrow down -->
<line x1="350" y1="500" x2="350" y2="530" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Execute enrollment.bas -->
<rect x="175" y="530" width="350" height="100" fill="none" stroke="#48BB78" stroke-width="2" rx="8"/>
<text x="350" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#059669">Execute enrollment.bas</text>
<g font-family="Arial, sans-serif" font-size="18" fill="#10B981">
<text x="220" y="585">• Save to CSV</text>
<text x="220" y="605">• Return confirmation</text>
</g>
<!-- Arrow down -->
<line x1="350" y1="630" x2="350" y2="660" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- Bot Response -->
<rect x="175" y="660" width="350" height="60" fill="none" stroke="#68D391" stroke-width="2" rx="8"/>
<text x="350" y="685" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" fill="#10B981">"Welcome to Computer Science!"</text>
<text x="350" y="705" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">Confirmation sent to user</text>
<!-- Side annotations -->
<g font-family="Arial, sans-serif" font-size="16" fill="#374151">
<!-- Time indicators -->
<text x="50" y="180" text-anchor="end">~100ms</text>
<text x="50" y="300" text-anchor="end">~50ms</text>
<text x="50" y="440" text-anchor="end">Interactive</text>
<text x="50" y="580" text-anchor="end">~200ms</text>
<text x="50" y="690" text-anchor="end">Instant</text>
<!-- Process descriptions -->
<text x="550" y="180">Natural language</text>
<text x="550" y="200">understanding</text>
<text x="550" y="300">Tool discovery</text>
<text x="550" y="320">and matching</text>
<text x="550" y="440">Smart parameter</text>
<text x="550" y="460">extraction</text>
<text x="550" y="580">BASIC script</text>
<text x="550" y="600">execution</text>
</g>
<!-- Tool example box -->
<g id="tool-example" transform="translate(50, 740)">
<rect x="0" y="0" width="600" height="120" fill="none" stroke="#4A5568" stroke-width="1" rx="5" stroke-dasharray="2,2" opacity="0.5"/>
<text x="300" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#1F2937">enrollment.bas</text>
<g font-family="monospace" font-size="16" fill="#374151">
<text x="20" y="45">' Student enrollment tool</text>
<text x="20" y="65">PARAM name, email, course</text>
<text x="20" y="85">SAVE "enrollments.csv", name, email, course, NOW()</text>
<text x="20" y="105">TALK "Welcome to " + course + ", " + name + "!"</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -0,0 +1,132 @@
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#4B5563"/>
</marker>
</defs>
<!-- Title -->
<text x="400" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="#1F2937">Package Structure</text>
<!-- Root Package -->
<rect x="300" y="60" width="200" height="50" fill="none" stroke="#4299E1" stroke-width="2" rx="8"/>
<text x="400" y="85" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#2563EB">my-bot.gbai/</text>
<text x="400" y="100" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1E40AF">(Package Root)</text>
<!-- Connection Lines from Root -->
<g stroke="#888" stroke-width="1" fill="none">
<line x1="400" y1="110" x2="400" y2="140"/>
<!-- Horizontal spread -->
<line x1="400" y1="140" x2="150" y2="140"/>
<line x1="400" y1="140" x2="650" y2="140"/>
<!-- Vertical lines to components -->
<line x1="150" y1="140" x2="150" y2="180"/>
<line x1="280" y1="140" x2="280" y2="180"/>
<line x1="400" y1="140" x2="400" y2="180"/>
<line x1="520" y1="140" x2="520" y2="180"/>
<line x1="650" y1="140" x2="650" y2="180"/>
</g>
<!-- Component Folders -->
<g id="folders">
<!-- .gbdialog -->
<rect x="70" y="180" width="160" height="80" fill="none" stroke="#F6AD55" stroke-width="2" rx="6"/>
<text x="150" y="205" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#EA580C">.gbdialog</text>
<text x="150" y="225" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#FED7AA">Dialog Scripts</text>
<text x="150" y="245" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">Conversation Logic</text>
<!-- .gbkb -->
<rect x="200" y="180" width="160" height="80" fill="none" stroke="#4FD1C5" stroke-width="2" rx="6"/>
<text x="280" y="205" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#0891B2">.gbkb</text>
<text x="280" y="225" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#0E7490">Knowledge Base</text>
<text x="280" y="245" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">Documents</text>
<!-- .gbot -->
<rect x="320" y="180" width="160" height="80" fill="none" stroke="#B794F4" stroke-width="2" rx="6"/>
<text x="400" y="205" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#9333EA">.gbot</text>
<text x="400" y="225" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C3AED">Configuration</text>
<text x="400" y="245" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">Bot Settings</text>
<!-- .gbtheme -->
<rect x="440" y="180" width="160" height="80" fill="none" stroke="#FC8181" stroke-width="2" rx="6"/>
<text x="520" y="205" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#EF4444">.gbtheme</text>
<text x="520" y="225" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#DC2626">(optional)</text>
<text x="520" y="245" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">UI Theme</text>
<!-- .gbdrive -->
<rect x="570" y="180" width="160" height="80" fill="none" stroke="#68D391" stroke-width="2" rx="6"/>
<text x="650" y="205" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#059669">.gbdrive</text>
<text x="650" y="225" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#10B981">(optional)</text>
<text x="650" y="245" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">File Storage</text>
</g>
<!-- Connection lines to file types -->
<g stroke="#888" stroke-width="1" fill="none" opacity="0.6">
<line x1="150" y1="260" x2="150" y2="300"/>
<line x1="280" y1="260" x2="280" y2="300"/>
<line x1="400" y1="260" x2="400" y2="300"/>
<line x1="520" y1="260" x2="520" y2="300"/>
<line x1="650" y1="260" x2="650" y2="300"/>
</g>
<!-- File Types -->
<g id="file-types">
<!-- Scripts -->
<rect x="80" y="300" width="140" height="60" fill="none" stroke="#F6AD55" stroke-width="1" rx="4" stroke-dasharray="3,3" opacity="0.7"/>
<text x="150" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#EA580C">Scripts</text>
<text x="150" y="345" text-anchor="middle" font-family="monospace" font-size="16" fill="#374151">.bas files</text>
<!-- Documents -->
<rect x="210" y="300" width="140" height="60" fill="none" stroke="#4FD1C5" stroke-width="1" rx="4" stroke-dasharray="3,3" opacity="0.7"/>
<text x="280" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#0891B2">Docs</text>
<text x="280" y="345" text-anchor="middle" font-family="monospace" font-size="16" fill="#374151">PDF/TXT</text>
<!-- Config -->
<rect x="330" y="300" width="140" height="60" fill="none" stroke="#B794F4" stroke-width="1" rx="4" stroke-dasharray="3,3" opacity="0.7"/>
<text x="400" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#9333EA">Config</text>
<text x="400" y="345" text-anchor="middle" font-family="monospace" font-size="16" fill="#374151">.csv</text>
<!-- Styles -->
<rect x="450" y="300" width="140" height="60" fill="none" stroke="#FC8181" stroke-width="1" rx="4" stroke-dasharray="3,3" opacity="0.7"/>
<text x="520" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#EF4444">Styles</text>
<text x="520" y="345" text-anchor="middle" font-family="monospace" font-size="16" fill="#374151">CSS/HTML</text>
<!-- Storage -->
<rect x="580" y="300" width="140" height="60" fill="none" stroke="#68D391" stroke-width="1" rx="4" stroke-dasharray="3,3" opacity="0.7"/>
<text x="650" y="325" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#059669">Storage</text>
<text x="650" y="345" text-anchor="middle" font-family="monospace" font-size="16" fill="#374151">S3 Link</text>
</g>
<!-- Example Structure -->
<g id="example" transform="translate(100, 400)">
<text x="0" y="0" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">Example Directory Structure:</text>
<g font-family="monospace" font-size="18" fill="#374151">
<text x="0" y="30">botname.gbai/</text>
<text x="20" y="50">├── botname.gbdialog/</text>
<text x="40" y="70">│ ├── start.bas</text>
<text x="40" y="90">│ ├── auth.bas</text>
<text x="40" y="110">│ └── tools/</text>
<text x="20" y="130">├── botname.gbkb/</text>
<text x="40" y="150">│ ├── collection1/</text>
<text x="40" y="170">│ └── collection2/</text>
<text x="20" y="190">├── botname.gbot/</text>
<text x="40" y="210">│ └── config.csv</text>
<text x="20" y="230">└── botname.gbtheme/</text>
<text x="40" y="250"> └── default.css</text>
</g>
</g>
<!-- Notes -->
<g id="notes" transform="translate(450, 430)">
<rect x="0" y="0" width="300" height="120" fill="none" stroke="#4A5568" stroke-width="1" rx="5" stroke-dasharray="2,2" opacity="0.5"/>
<text x="150" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#1F2937">Key Points</text>
<g font-family="Arial, sans-serif" font-size="16" fill="#374151">
<text x="10" y="45">• Folder name = Bot name</text>
<text x="10" y="65">• Only .gbdialog is required</text>
<text x="10" y="85">• start.bas is the entry point</text>
<text x="10" y="105">• Deploy by copying folder</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View file

@ -0,0 +1,83 @@
<svg width="600" height="800" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#4B5563"/>
</marker>
</defs>
<!-- Title -->
<text x="300" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="22" font-weight="bold" fill="#1F2937">Template Deployment Flow</text>
<!-- Templates folder -->
<rect x="225" y="60" width="150" height="50" fill="none" stroke="#63B3ED" stroke-width="2" rx="8"/>
<text x="300" y="85" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1E40AF">templates/</text>
<text x="300" y="100" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">Source folder</text>
<!-- Arrow down -->
<line x1="300" y1="110" x2="300" y2="140" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- SCAN -->
<rect x="200" y="140" width="200" height="70" fill="none" stroke="#F6AD55" stroke-width="2" rx="8"/>
<text x="300" y="165" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EA580C">SCAN</text>
<text x="300" y="185" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#FED7AA">Find all .gbai folders</text>
<!-- Arrow down -->
<line x1="300" y1="210" x2="300" y2="240" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- VALIDATE -->
<rect x="200" y="240" width="200" height="90" fill="none" stroke="#B794F4" stroke-width="2" rx="8"/>
<text x="300" y="265" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#9333EA">VALIDATE</text>
<text x="300" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C3AED">Check required structure</text>
<text x="300" y="300" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• start.bas exists?</text>
<text x="300" y="315" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Folders match name?</text>
<!-- Arrow down -->
<line x1="300" y1="330" x2="300" y2="360" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- UPLOAD -->
<rect x="200" y="360" width="200" height="90" fill="none" stroke="#48BB78" stroke-width="2" rx="8"/>
<text x="300" y="385" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#059669">UPLOAD</text>
<text x="300" y="405" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#10B981">Copy to object storage</text>
<text x="300" y="420" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Templates → S3/Drive</text>
<text x="300" y="435" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Assets → CDN paths</text>
<!-- Arrow down -->
<line x1="300" y1="450" x2="300" y2="480" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- INDEX -->
<rect x="200" y="480" width="200" height="90" fill="none" stroke="#4FD1C5" stroke-width="2" rx="8"/>
<text x="300" y="505" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#0891B2">INDEX</text>
<text x="300" y="525" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#0E7490">Process knowledge base</text>
<text x="300" y="540" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Extract text</text>
<text x="300" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Generate embeddings</text>
<text x="300" y="570" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Store in Qdrant</text>
<!-- Arrow down -->
<line x1="300" y1="580" x2="300" y2="610" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- REGISTER -->
<rect x="200" y="610" width="200" height="90" fill="none" stroke="#FBBF24" stroke-width="2" rx="8"/>
<text x="300" y="635" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#FCD34D">REGISTER</text>
<text x="300" y="655" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#FDE68A">Create in database</text>
<text x="300" y="670" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Bot record</text>
<text x="300" y="685" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Configuration</text>
<text x="300" y="700" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• URL mapping</text>
<!-- Arrow down -->
<line x1="300" y1="710" x2="300" y2="740" stroke="#888" stroke-width="2" marker-end="url(#arrow)"/>
<!-- ACTIVATE -->
<rect x="200" y="740" width="200" height="90" fill="none" stroke="#FC8181" stroke-width="2" rx="8"/>
<text x="300" y="765" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#EF4444">ACTIVATE</text>
<text x="300" y="785" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#DC2626">Start serving</text>
<text x="300" y="800" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• /bot-name endpoint</text>
<text x="300" y="815" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• WebSocket ready</text>
<text x="300" y="830" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">• Sessions enabled</text>
<!-- Process time indicator -->
<g id="time-indicator" transform="translate(450, 450)">
<circle cx="0" cy="0" r="40" fill="none" stroke="#4A5568" stroke-width="1" opacity="0.5"/>
<text x="0" y="0" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#1F2937">5-10s</text>
<text x="0" y="15" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#374151">per bot</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -0,0 +1,173 @@
<svg width="750" height="400" viewBox="0 0 750 400" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and effects -->
<defs>
<!-- Beautiful gradients with vibrant colors -->
<linearGradient id="userQueryGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:0.4" />
</linearGradient>
<linearGradient id="keyGenGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#f5576c;stop-opacity:0.4" />
</linearGradient>
<linearGradient id="valkeyGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#ff6b6b;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#ee5a24;stop-opacity:0.4" />
</linearGradient>
<linearGradient id="embedGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4facfe;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#00f2fe;stop-opacity:0.4" />
</linearGradient>
<linearGradient id="semanticGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#43e97b;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#38f9d7;stop-opacity:0.4" />
</linearGradient>
<linearGradient id="generateGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#fa709a;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#fee140;stop-opacity:0.4" />
</linearGradient>
<linearGradient id="storeGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#30cfd0;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#330867;stop-opacity:0.4" />
</linearGradient>
<!-- Hit path gradient -->
<linearGradient id="hitPathGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#10b981;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#34d399;stop-opacity:0.4" />
</linearGradient>
<!-- Miss path gradient -->
<linearGradient id="missPathGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#f59e0b;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#fbbf24;stop-opacity:0.4" />
</linearGradient>
<!-- Improved arrow marker with color -->
<marker id="arrowCache" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#4a5568" opacity="0.8"/>
</marker>
<marker id="arrowHit" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#10b981" opacity="0.9"/>
</marker>
<marker id="arrowMiss" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#f59e0b" opacity="0.9"/>
</marker>
<!-- Drop shadow effect -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/>
<feOffset dx="0" dy="3" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.2"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<!-- Glow effect for decision diamond -->
<filter id="glowEffect" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="4" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="750" height="400" fill="#fafafa"/>
<!-- Title with better padding -->
<rect x="200" y="10" width="350" height="35" fill="rgba(99, 102, 241, 0.05)" rx="8"/>
<text x="375" y="33" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="22" font-weight="600" fill="#1e293b">
Semantic Caching Architecture
</text>
<!-- User Query -->
<rect x="50" y="70" width="130" height="45" fill="url(#userQueryGrad)" stroke="#667eea" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="115" y="95" text-anchor="middle" font-family="system-ui" sans-serif" font-size="20" font-weight="600" fill="#1e293b">User Query</text>
<text x="115" y="108" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">"What's the policy?"</text>
<!-- Arrow to Generate Key -->
<path d="M 180 92 L 220 92" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrowCache)" opacity="0.7"/>
<!-- Generate Key -->
<rect x="220" y="70" width="130" height="45" fill="url(#keyGenGrad)" stroke="#f5576c" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="285" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">Generate Key</text>
<text x="285" y="108" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Hash + Embed</text>
<!-- Arrow to Check Valkey -->
<path d="M 350 92 L 390 92" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrowCache)" opacity="0.7"/>
<!-- Check Valkey -->
<rect x="390" y="70" width="130" height="45" fill="url(#valkeyGrad)" stroke="#ee5a24" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="455" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">Check Valkey</text>
<text x="455" y="108" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Memory Store</text>
<!-- Arrow to Decision -->
<path d="M 520 92 L 560 92" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrowCache)" opacity="0.7"/>
<!-- Hit/Miss Decision Diamond with glow -->
<g filter="url(#glowEffect)">
<path d="M 610 70 L 650 92 L 610 114 L 570 92 Z" fill="rgba(139, 92, 246, 0.2)" stroke="#8b5cf6" stroke-width="2.5"/>
<text x="610" y="97" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#1e293b">Hit?</text>
</g>
<!-- Arrow down from Generate Key to Embedding -->
<path d="M 285 115 L 285 160" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrowCache)" opacity="0.7"/>
<!-- Embedding Hash -->
<rect x="210" y="160" width="150" height="45" fill="url(#embedGrad)" stroke="#00f2fe" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="285" y="185" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">Embedding Hash</text>
<text x="285" y="198" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">384D Vector</text>
<!-- Arrow down from Embedding Hash -->
<path d="M 285 205 L 285 250" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrowCache)" opacity="0.7"/>
<!-- Semantic Search -->
<rect x="210" y="250" width="150" height="45" fill="url(#semanticGrad)" stroke="#38f9d7" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="285" y="275" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">Semantic Search</text>
<text x="285" y="288" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Similarity > 0.95</text>
<!-- Cache Hit path (success) -->
<path d="M 610 70 L 610 40 L 455 40" stroke="url(#hitPathGrad)" stroke-width="3" fill="none" opacity="0.8" stroke-linecap="round"/>
<rect x="330" y="25" width="125" height="30" fill="rgba(16, 185, 129, 0.1)" stroke="#10b981" stroke-width="1.5" stroke-dasharray="4,2" rx="6"/>
<text x="392" y="44" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#047857">✓ Cache Hit</text>
<!-- Miss path -->
<path d="M 610 114 L 610 160" stroke="url(#missPathGrad)" stroke-width="3" fill="none" marker-end="url(#arrowMiss)" opacity="0.8" stroke-linecap="round"/>
<text x="630" y="140" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#d97706">Miss</text>
<!-- Generate New Response -->
<rect x="530" y="160" width="150" height="45" fill="url(#generateGrad)" stroke="#fa709a" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="605" y="185" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">Generate New</text>
<text x="605" y="198" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">LLM Response</text>
<!-- Arrow down from Generate New -->
<path d="M 605 205 L 605 250" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrowCache)" opacity="0.7"/>
<!-- Store in Valkey -->
<rect x="510" y="250" width="190" height="45" fill="url(#storeGrad)" stroke="#330867" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="605" y="270" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">Store in Valkey</text>
<text x="605" y="285" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">TTL: 3600s</text>
<!-- Performance Metrics Box -->
<rect x="50" y="320" width="650" height="60" fill="rgba(99, 102, 241, 0.05)" stroke="#8b5cf6" stroke-width="1" stroke-dasharray="6,3" rx="8"/>
<text x="375" y="343" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">
Performance Metrics
</text>
<text x="200" y="365" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Hit Rate: ~85%</text>
<text x="375" y="365" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Latency: &lt;50ms</text>
<text x="550" y="365" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Cost Reduction: 95%</text>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,205 @@
<svg width="900" height="450" viewBox="0 0 900 450" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and effects -->
<defs>
<!-- Gradient for original documents -->
<linearGradient id="origGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#1e40af;stop-opacity:0.2" />
</linearGradient>
<!-- Gradient for vector DB -->
<linearGradient id="vectorGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#10b981;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#059669;stop-opacity:0.2" />
</linearGradient>
<!-- Gradient for multiplication factor -->
<linearGradient id="multiGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f59e0b;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#d97706;stop-opacity:0.2" />
</linearGradient>
<!-- Arrow marker -->
<marker id="arrowhead2" markerWidth="10" markerHeight="10" refX="5" refY="5" orient="auto">
<polygon points="0 0, 10 5, 0 10" fill="#4a5568"/>
</marker>
<!-- Drop shadow filter -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.15"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="900" height="450" fill="#fafafa"/>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="22" font-weight="600" fill="#1e293b">
Vector Database Storage Requirements: The Real Mathematics
</text>
<!-- Original Documents Section -->
<rect x="50" y="60" width="180" height="380" fill="url(#origGrad)" stroke="#3b82f6" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="140" y="85" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Original Documents
</text>
<text x="140" y="105" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#475569">
1 TB Total
</text>
<!-- File type breakdown -->
<rect x="70" y="120" width="140" height="30" fill="rgba(59, 130, 246, 0.05)" stroke="#93c5fd" stroke-width="1"/>
<text x="140" y="140" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#1e293b">
PDF: 400 GB
</text>
<rect x="70" y="155" width="140" height="25" fill="rgba(59, 130, 246, 0.05)" stroke="#93c5fd" stroke-width="1"/>
<text x="140" y="172" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#1e293b">
DOCX: 250 GB
</text>
<rect x="70" y="185" width="140" height="20" fill="rgba(59, 130, 246, 0.05)" stroke="#93c5fd" stroke-width="1"/>
<text x="140" y="200" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#1e293b">
XLSX: 150 GB
</text>
<rect x="70" y="210" width="140" height="15" fill="rgba(59, 130, 246, 0.05)" stroke="#93c5fd" stroke-width="1"/>
<text x="140" y="223" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#1e293b">
TXT: 100 GB
</text>
<rect x="70" y="230" width="140" height="15" fill="rgba(59, 130, 246, 0.05)" stroke="#93c5fd" stroke-width="1"/>
<text x="140" y="243" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#1e293b">
HTML: 50 GB
</text>
<rect x="70" y="250" width="140" height="10" fill="rgba(59, 130, 246, 0.05)" stroke="#93c5fd" stroke-width="1"/>
<text x="140" y="258" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Other: 50 GB
</text>
<!-- Arrow -->
<path d="M 240 250 L 290 250" stroke="#4a5568" stroke-width="3" fill="none" marker-end="url(#arrowhead2)" opacity="0.7"/>
<text x="265" y="240" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
Processing
</text>
<!-- Vector Database Storage -->
<rect x="300" y="60" width="250" height="380" fill="url(#vectorGrad)" stroke="#10b981" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="425" y="85" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Vector DB Storage
</text>
<text x="425" y="105" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#475569">
~3.5 TB Required
</text>
<!-- Storage breakdown -->
<rect x="320" y="120" width="210" height="50" fill="rgba(16, 185, 129, 0.05)" stroke="#86efac" stroke-width="1" stroke-dasharray="3,2"/>
<text x="425" y="135" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#1e293b">
Raw Text Extracted
</text>
<text x="425" y="150" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
~800 GB (cleaned)
</text>
<text x="425" y="163" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
Deduplication reduces 20%
</text>
<rect x="320" y="175" width="210" height="60" fill="rgba(16, 185, 129, 0.05)" stroke="#86efac" stroke-width="1" stroke-dasharray="3,2"/>
<text x="425" y="190" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#1e293b">
Vector Embeddings
</text>
<text x="425" y="205" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
~1.2 TB (384-dim floats)
</text>
<text x="425" y="218" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
4 bytes × 384 × ~800M chunks
</text>
<text x="425" y="230" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
= 1,228 GB
</text>
<rect x="320" y="240" width="210" height="55" fill="rgba(16, 185, 129, 0.05)" stroke="#86efac" stroke-width="1" stroke-dasharray="3,2"/>
<text x="425" y="255" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#1e293b">
HNSW Index
</text>
<text x="425" y="270" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
~600 GB
</text>
<text x="425" y="283" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
Graph structure + links
</text>
<rect x="320" y="300" width="210" height="50" fill="rgba(16, 185, 129, 0.05)" stroke="#86efac" stroke-width="1" stroke-dasharray="3,2"/>
<text x="425" y="315" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#1e293b">
Metadata + Positions
</text>
<text x="425" y="330" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
~400 GB
</text>
<text x="425" y="343" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
Doc refs, chunks, offsets
</text>
<rect x="320" y="355" width="210" height="45" fill="rgba(16, 185, 129, 0.05)" stroke="#86efac" stroke-width="1" stroke-dasharray="3,2"/>
<text x="425" y="370" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#1e293b">
Cache + Auxiliary
</text>
<text x="425" y="385" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
~500 GB
</text>
<text x="425" y="395" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
Query cache, temp indices
</text>
<!-- Total comparison -->
<rect x="570" y="150" width="300" height="200" fill="url(#multiGrad)" stroke="#f59e0b" stroke-width="2" stroke-dasharray="5,3" rx="8" filter="url(#shadow)"/>
<text x="720" y="175" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Storage Multiplication Factor
</text>
<text x="590" y="205" font-family="system-ui, sans-serif" font-size="18" fill="#1e293b">
Original Documents: 1.0 TB
</text>
<text x="590" y="230" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#1e293b">
Vector DB Total: 3.5 TB
</text>
<text x="590" y="255" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#dc2626">
Multiplication Factor: 3.5×
</text>
<text x="590" y="285" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
With redundancy/backup:
</text>
<text x="590" y="305" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#1e293b">
Production Total: 7.0 TB (2× replica)
</text>
<text x="720" y="335" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-style="italic" fill="#64748b">
Reality: You need 3.5-7× your document storage
</text>
<!-- Visual indicators -->
<g transform="translate(820, 80)">
<circle cx="0" cy="0" r="3" fill="#3b82f6"/>
<text x="10" y="4" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">Input</text>
</g>
<g transform="translate(820, 100)">
<circle cx="0" cy="0" r="3" fill="#10b981"/>
<text x="10" y="4" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">Storage</text>
</g>
<g transform="translate(820, 120)">
<circle cx="0" cy="0" r="3" fill="#f59e0b"/>
<text x="10" y="4" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">Factor</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.6 KiB

View file

@ -0,0 +1,150 @@
<svg width="800" height="600" viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and filters -->
<defs>
<!-- Gradient for input layer -->
<linearGradient id="inputGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:0.3" />
</linearGradient>
<!-- Gradient for processing layers -->
<linearGradient id="processGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#06ffa5;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#00d2ff;stop-opacity:0.3" />
</linearGradient>
<!-- Gradient for embedding layer -->
<linearGradient id="embedGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#f5576c;stop-opacity:0.3" />
</linearGradient>
<!-- Gradient for index layer -->
<linearGradient id="indexGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#fa709a;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#fee140;stop-opacity:0.3" />
</linearGradient>
<!-- Gradient for retrieval layer -->
<linearGradient id="retrievalGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#30cfd0;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#330867;stop-opacity:0.3" />
</linearGradient>
<!-- Arrow marker -->
<marker id="arrowhead" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#4a5568" opacity="0.8"/>
</marker>
<!-- Drop shadow filter -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.2"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="800" height="600" fill="#ffffff"/>
<!-- Title -->
<text x="400" y="30" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="26" font-weight="600" fill="#1a202c">
Knowledge Base Architecture Pipeline
</text>
<!-- Document Ingestion Layer -->
<rect x="100" y="60" width="600" height="60" fill="url(#inputGrad)" stroke="#667eea" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="85" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#2d3748">
Document Ingestion Layer
</text>
<text x="400" y="105" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#4a5568">
PDF • Word • Excel • Text • HTML • Markdown
</text>
<!-- Arrow -->
<path d="M 400 120 L 400 140" stroke="#4a5568" stroke-width="3" fill="none" marker-end="url(#arrowhead)" opacity="0.6"/>
<!-- Preprocessing Pipeline -->
<rect x="100" y="140" width="600" height="60" fill="url(#processGrad)" stroke="#00d2ff" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="165" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#2d3748">
Preprocessing Pipeline
</text>
<text x="400" y="185" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#4a5568">
Extraction • Cleaning • Normalization • Validation
</text>
<!-- Arrow -->
<path d="M 400 200 L 400 220" stroke="#4a5568" stroke-width="3" fill="none" marker-end="url(#arrowhead)" opacity="0.6"/>
<!-- Chunking Engine -->
<rect x="100" y="220" width="600" height="60" fill="url(#processGrad)" stroke="#06ffa5" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="245" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#2d3748">
Intelligent Chunking Engine
</text>
<text x="400" y="265" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#4a5568">
Semantic Segmentation • Overlap Management • Metadata Preservation
</text>
<!-- Arrow -->
<path d="M 400 280 L 400 300" stroke="#4a5568" stroke-width="3" fill="none" marker-end="url(#arrowhead)" opacity="0.6"/>
<!-- Embedding Generation -->
<rect x="100" y="300" width="600" height="60" fill="url(#embedGrad)" stroke="#f5576c" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="325" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#2d3748">
Embedding Generation
</text>
<text x="400" y="345" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#4a5568">
BGE Models • Transformer Architecture • Dimensionality: 384/768
</text>
<!-- Arrow -->
<path d="M 400 360 L 400 380" stroke="#4a5568" stroke-width="3" fill="none" marker-end="url(#arrowhead)" opacity="0.6"/>
<!-- Vector Index Layer -->
<rect x="100" y="380" width="600" height="60" fill="url(#indexGrad)" stroke="#fa709a" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="405" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#2d3748">
Vector Index Layer
</text>
<text x="400" y="425" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#4a5568">
HNSW Algorithm • Quantization • Distributed Sharding
</text>
<!-- Arrow -->
<path d="M 400 440 L 400 460" stroke="#4a5568" stroke-width="3" fill="none" marker-end="url(#arrowhead)" opacity="0.6"/>
<!-- Retrieval Engine -->
<rect x="100" y="460" width="600" height="60" fill="url(#retrievalGrad)" stroke="#30cfd0" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="485" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#2d3748">
Semantic Retrieval Engine
</text>
<text x="400" y="505" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#4a5568">
Cosine Similarity • Hybrid Search • Re-ranking • Context Injection
</text>
<!-- Side labels -->
<g transform="translate(50, 290)">
<text x="0" y="0" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#374151" transform="rotate(-90)">
Data Flow Direction
</text>
</g>
<!-- Stage indicators on the right -->
<text x="730" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#374151">Raw Docs</text>
<text x="730" y="175" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#374151">Clean Text</text>
<text x="730" y="255" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#374151">Chunks</text>
<text x="730" y="335" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#374151">Vectors</text>
<text x="730" y="415" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#374151">Index</text>
<text x="730" y="495" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#374151">Results</text>
<!-- Performance metrics -->
<rect x="100" y="540" width="600" height="40" fill="#f7fafc" stroke="#cbd5e0" stroke-width="1" stroke-dasharray="5,5" rx="4"/>
<text x="400" y="565" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#4a5568" font-style="italic">
Pipeline processes ~1000 documents/minute • Query latency &lt;50ms (p99) • 95% semantic accuracy
</text>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View file

@ -0,0 +1,165 @@
<svg width="900" height="500" viewBox="0 0 900 500" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and effects -->
<defs>
<!-- Gradient for query stage -->
<linearGradient id="queryGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:0.25" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:0.35" />
</linearGradient>
<!-- Gradient for embedding stage -->
<linearGradient id="embedSearchGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb;stop-opacity:0.25" />
<stop offset="100%" style="stop-color:#f5576c;stop-opacity:0.35" />
</linearGradient>
<!-- Gradient for search stage -->
<linearGradient id="searchGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4facfe;stop-opacity:0.25" />
<stop offset="100%" style="stop-color:#00f2fe;stop-opacity:0.35" />
</linearGradient>
<!-- Gradient for ranking stage -->
<linearGradient id="rankGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#43e97b;stop-opacity:0.25" />
<stop offset="100%" style="stop-color:#38f9d7;stop-opacity:0.35" />
</linearGradient>
<!-- Gradient for result stage -->
<linearGradient id="resultGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#fa709a;stop-opacity:0.25" />
<stop offset="100%" style="stop-color:#fee140;stop-opacity:0.35" />
</linearGradient>
<!-- Arrow marker -->
<marker id="searchArrow" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#4a5568" opacity="0.7"/>
</marker>
<!-- Glow effect -->
<filter id="glow">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<!-- Drop shadow -->
<filter id="dropShadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/>
<feOffset dx="0" dy="3" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.15"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background with subtle gradient -->
<rect x="0" y="0" width="900" height="500" fill="url(#bgGrad)"/>
<defs>
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#ffffff;stop-opacity:1" />
<stop offset="100%" style="stop-color:#f8f9fa;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Title -->
<text x="450" y="35" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="28" font-weight="600" fill="#1a202c">
Semantic Search Pipeline
</text>
<!-- Main flow container -->
<g transform="translate(0, 70)">
<!-- Stage 1: User Query -->
<g transform="translate(50, 0)">
<rect x="0" y="0" width="160" height="80" fill="url(#queryGrad)" stroke="#667eea" stroke-width="2" rx="10" filter="url(#dropShadow)"/>
<text x="80" y="30" text-anchor="middle" font-family="system-ui" font-size="20" font-weight="600" fill="#2d3748">User Query</text>
<text x="80" y="50" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">"What's the return</text>
<text x="80" y="65" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">policy?"</text>
</g>
<!-- Arrow 1 -->
<path d="M 210 40 L 250 40" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#searchArrow)" opacity="0.6"/>
<!-- Stage 2: Query Embedding -->
<g transform="translate(250, 0)">
<rect x="0" y="0" width="160" height="80" fill="url(#embedSearchGrad)" stroke="#f5576c" stroke-width="2" rx="10" filter="url(#dropShadow)"/>
<text x="80" y="30" text-anchor="middle" font-family="system-ui" font-size="20" font-weight="600" fill="#2d3748">Embedding</text>
<text x="80" y="50" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">Transform to</text>
<text x="80" y="65" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">384D vector</text>
</g>
<!-- Arrow 2 -->
<path d="M 410 40 L 450 40" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#searchArrow)" opacity="0.6"/>
<!-- Stage 3: Vector Search -->
<g transform="translate(450, 0)">
<rect x="0" y="0" width="180" height="80" fill="url(#searchGrad)" stroke="#00f2fe" stroke-width="2" rx="10" filter="url(#dropShadow)"/>
<text x="90" y="30" text-anchor="middle" font-family="system-ui" font-size="20" font-weight="600" fill="#2d3748">Vector Search</text>
<text x="90" y="50" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">Cosine similarity</text>
<text x="90" y="65" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">in vector space</text>
</g>
<!-- Arrow 3 -->
<path d="M 630 40 L 670 40" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#searchArrow)" opacity="0.6"/>
<!-- Stage 4: Ranking -->
<g transform="translate(670, 0)">
<rect x="0" y="0" width="160" height="80" fill="url(#rankGrad)" stroke="#38f9d7" stroke-width="2" rx="10" filter="url(#dropShadow)"/>
<text x="80" y="30" text-anchor="middle" font-family="system-ui" font-size="20" font-weight="600" fill="#2d3748">Re-ranking</text>
<text x="80" y="50" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">Score &amp; sort</text>
<text x="80" y="65" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">by relevance</text>
</g>
<!-- Collections being searched (below main flow) -->
<g transform="translate(450, 140)">
<rect x="0" y="0" width="180" height="60" fill="rgba(79, 172, 254, 0.1)" stroke="#4facfe" stroke-width="1.5" stroke-dasharray="5,5" rx="8"/>
<text x="90" y="25" text-anchor="middle" font-family="system-ui" font-size="18" font-weight="500" fill="#2d3748">Active Collections</text>
<text x="90" y="45" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">policies • procedures • faq</text>
</g>
<!-- Arrow from Vector Search to Collections -->
<path d="M 540 80 L 540 140" stroke="#4facfe" stroke-width="2" stroke-dasharray="4,4" fill="none" marker-end="url(#searchArrow)" opacity="0.4"/>
<!-- Results -->
<g transform="translate(350, 250)">
<rect x="0" y="0" width="380" height="100" fill="url(#resultGrad)" stroke="#fa709a" stroke-width="2" rx="10" filter="url(#dropShadow)"/>
<text x="190" y="30" text-anchor="middle" font-family="system-ui" font-size="20" font-weight="600" fill="#2d3748">Retrieved Context</text>
<text x="60" y="55" text-anchor="start" font-family="system-ui" font-size="16" fill="#4a5568">1. "Refund policy: 30 days..." (0.92)</text>
<text x="60" y="75" text-anchor="start" font-family="system-ui" font-size="16" fill="#4a5568">2. "Return procedures..." (0.87)</text>
<text x="60" y="95" text-anchor="start" font-family="system-ui" font-size="16" fill="#4a5568">3. "Warranty information..." (0.81)</text>
</g>
<!-- Arrow to Results -->
<path d="M 750 80 L 750 120 L 540 120 L 540 250" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#searchArrow)" opacity="0.6"/>
<!-- LLM Integration -->
<g transform="translate(350, 370)">
<rect x="0" y="0" width="380" height="60" fill="rgba(102, 126, 234, 0.1)" stroke="#667eea" stroke-width="2" stroke-dasharray="8,4" rx="10"/>
<text x="190" y="25" text-anchor="middle" font-family="system-ui" font-size="20" font-weight="600" fill="#2d3748">Context Injection to LLM</text>
<text x="190" y="45" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568">Retrieved chunks provided as context for response generation</text>
</g>
<!-- Arrow to LLM -->
<path d="M 540 350 L 540 370" stroke="#667eea" stroke-width="2.5" fill="none" marker-end="url(#searchArrow)" opacity="0.6"/>
</g>
<!-- Side annotations -->
<g transform="translate(40, 180)">
<text x="0" y="0" text-anchor="start" font-family="system-ui" font-size="16" fill="#374151" font-style="italic">Automatic</text>
<text x="0" y="15" text-anchor="start" font-family="system-ui" font-size="16" fill="#374151" font-style="italic">Process</text>
</g>
<!-- Performance metrics -->
<rect x="50" y="450" width="800" height="35" fill="rgba(203, 213, 224, 0.1)" stroke="#cbd5e0" stroke-width="1" stroke-dasharray="5,5" rx="6"/>
<text x="450" y="472" text-anchor="middle" font-family="system-ui" font-size="16" fill="#4a5568" font-style="italic">
Search latency: ~20ms • Embedding: BGE-small (384D) • Similarity threshold: 0.7 • Top-K: 5 chunks
</text>
</svg>

After

Width:  |  Height:  |  Size: 8.9 KiB

View file

@ -0,0 +1,235 @@
<svg width="900" height="500" viewBox="0 0 900 500" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and effects -->
<defs>
<!-- Gradient for original context -->
<linearGradient id="origContextGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#ef4444;stop-opacity:0.2" />
<stop offset="50%" style="stop-color:#f59e0b;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#eab308;stop-opacity:0.2" />
</linearGradient>
<!-- Gradient for compressed context -->
<linearGradient id="compContextGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#10b981;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#059669;stop-opacity:0.3" />
</linearGradient>
<!-- Gradients for technique boxes -->
<linearGradient id="tech1Grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#8b5cf6;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#7c3aed;stop-opacity:0.2" />
</linearGradient>
<linearGradient id="tech2Grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#2563eb;stop-opacity:0.2" />
</linearGradient>
<linearGradient id="tech3Grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#06b6d4;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#0891b2;stop-opacity:0.2" />
</linearGradient>
<linearGradient id="tech4Grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f59e0b;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#d97706;stop-opacity:0.2" />
</linearGradient>
<!-- Arrow marker -->
<marker id="arrowhead3" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto">
<polygon points="0 0, 10 5, 0 10" fill="#4a5568"/>
</marker>
<!-- Drop shadow filter -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.15"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="900" height="500" fill="#fafafa"/>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="22" font-weight="600" fill="#1e293b">
LLM Context Compression Strategies
</text>
<!-- Context Window Visualization -->
<g transform="translate(50, 60)">
<!-- Original context -->
<rect x="0" y="0" width="800" height="60" fill="url(#origContextGrad)" stroke="#dc2626" stroke-width="2" rx="6" filter="url(#shadow)"/>
<text x="10" y="20" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Original Context: 10,000 tokens
</text>
<rect x="10" y="30" width="780" height="20" fill="#fee2e2" rx="3"/>
<!-- Document chunks visualization -->
<rect x="10" y="30" width="100" height="20" fill="#fca5a5" rx="2"/>
<rect x="112" y="30" width="120" height="20" fill="#f87171" rx="2"/>
<rect x="234" y="30" width="90" height="20" fill="#fca5a5" rx="2"/>
<rect x="326" y="30" width="110" height="20" fill="#ef4444" rx="2"/>
<rect x="438" y="30" width="95" height="20" fill="#fca5a5" rx="2"/>
<rect x="535" y="30" width="105" height="20" fill="#f87171" rx="2"/>
<rect x="642" y="30" width="80" height="20" fill="#fca5a5" rx="2"/>
<rect x="724" y="30" width="66" height="20" fill="#ef4444" rx="2"/>
</g>
<!-- Arrow down -->
<path d="M 450 130 L 450 160" stroke="#4a5568" stroke-width="3" fill="none" marker-end="url(#arrowhead3)" opacity="0.7"/>
<text x="470" y="150" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#475569">
Compression Level 4
</text>
<!-- Compressed context -->
<g transform="translate(200, 170)">
<rect x="0" y="0" width="500" height="60" fill="url(#compContextGrad)" stroke="#10b981" stroke-width="2" rx="6" filter="url(#shadow)"/>
<text x="10" y="20" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Compressed Context: 4,096 tokens (fits LLM window)
</text>
<rect x="10" y="30" width="480" height="20" fill="#dcfce7" rx="3"/>
<!-- Compressed chunks -->
<rect x="10" y="30" width="80" height="20" fill="#86efac" rx="2"/>
<rect x="92" y="30" width="70" height="20" fill="#4ade80" rx="2"/>
<rect x="164" y="30" width="75" height="20" fill="#86efac" rx="2"/>
<rect x="241" y="30" width="85" height="20" fill="#22c55e" rx="2"/>
<rect x="328" y="30" width="90" height="20" fill="#4ade80" rx="2"/>
<rect x="420" y="30" width="70" height="20" fill="#86efac" rx="2"/>
</g>
<!-- Compression Techniques -->
<g transform="translate(50, 260)">
<text x="400" y="0" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#1e293b">
Compression Techniques (Level 4)
</text>
<!-- Technique 1: Semantic Deduplication -->
<g transform="translate(0, 30)">
<rect x="0" y="0" width="190" height="140" fill="url(#tech1Grad)" stroke="#8b5cf6" stroke-width="1.5" rx="6" filter="url(#shadow)"/>
<text x="95" y="20" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#1e293b">
Semantic Deduplication
</text>
<text x="10" y="40" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Remove redundant info
</text>
<text x="10" y="55" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Merge similar chunks
</text>
<text x="10" y="70" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Keep unique facts
</text>
<rect x="10" y="85" width="170" height="25" fill="rgba(139, 92, 246, 0.1)" rx="4"/>
<text x="95" y="102" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#7c3aed">
Reduction: 30-40%
</text>
<!-- Visual representation -->
<g transform="translate(95, 120)">
<circle cx="0" cy="0" r="8" fill="#8b5cf6" opacity="0.3"/>
<circle cx="-15" cy="0" r="8" fill="#8b5cf6" opacity="0.3"/>
<circle cx="15" cy="0" r="8" fill="#8b5cf6" opacity="0.3"/>
</g>
</g>
<!-- Technique 2: Relevance Scoring -->
<g transform="translate(205, 30)">
<rect x="0" y="0" width="190" height="140" fill="url(#tech2Grad)" stroke="#3b82f6" stroke-width="1.5" rx="6" filter="url(#shadow)"/>
<text x="95" y="20" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#1e293b">
Relevance Scoring
</text>
<text x="10" y="40" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Score by query match
</text>
<text x="10" y="55" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Keep top-k relevant
</text>
<text x="10" y="70" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Drop low scores
</text>
<rect x="10" y="85" width="170" height="25" fill="rgba(59, 130, 246, 0.1)" rx="4"/>
<text x="95" y="102" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#2563eb">
Reduction: 40-50%
</text>
<!-- Visual bars -->
<rect x="50" y="118" width="90" height="4" fill="#3b82f6" rx="2"/>
<rect x="50" y="124" width="70" height="4" fill="#60a5fa" rx="2"/>
<rect x="50" y="130" width="40" height="4" fill="#93c5fd" rx="2"/>
</g>
<!-- Technique 3: Hierarchical Summary -->
<g transform="translate(410, 30)">
<rect x="0" y="0" width="190" height="140" fill="url(#tech3Grad)" stroke="#06b6d4" stroke-width="1.5" rx="6" filter="url(#shadow)"/>
<text x="95" y="20" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#1e293b">
Hierarchical Summary
</text>
<text x="10" y="40" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Extract key points
</text>
<text x="10" y="55" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Create abstracts
</text>
<text x="10" y="70" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Preserve details
</text>
<rect x="10" y="85" width="170" height="25" fill="rgba(6, 182, 212, 0.1)" rx="4"/>
<text x="95" y="102" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#0891b2">
Reduction: 50-60%
</text>
<!-- Tree structure -->
<g transform="translate(95, 120)">
<circle cx="0" cy="-8" r="4" fill="#06b6d4"/>
<circle cx="-15" cy="8" r="3" fill="#67e8f9"/>
<circle cx="0" cy="8" r="3" fill="#67e8f9"/>
<circle cx="15" cy="8" r="3" fill="#67e8f9"/>
<line x1="0" y1="-4" x2="-15" y2="5" stroke="#06b6d4" stroke-width="1"/>
<line x1="0" y1="-4" x2="0" y2="5" stroke="#06b6d4" stroke-width="1"/>
<line x1="0" y1="-4" x2="15" y2="5" stroke="#06b6d4" stroke-width="1"/>
</g>
</g>
<!-- Technique 4: Token Optimization -->
<g transform="translate(615, 30)">
<rect x="0" y="0" width="185" height="140" fill="url(#tech4Grad)" stroke="#f59e0b" stroke-width="1.5" rx="6" filter="url(#shadow)"/>
<text x="92" y="20" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#1e293b">
Token Optimization
</text>
<text x="10" y="40" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Remove stopwords
</text>
<text x="10" y="55" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Compress phrases
</text>
<text x="10" y="70" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Use abbreviations
</text>
<rect x="10" y="85" width="165" height="25" fill="rgba(245, 158, 11, 0.1)" rx="4"/>
<text x="92" y="102" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#d97706">
Reduction: 20-30%
</text>
<!-- Text compression visual -->
<text x="92" y="122" text-anchor="middle" font-family="monospace" font-size="16" fill="#92400e">
ABCDEF → ABC
</text>
<text x="92" y="133" text-anchor="middle" font-family="monospace" font-size="16" fill="#92400e">
GHIJKL → GHI
</text>
</g>
</g>
<!-- Performance note -->
<rect x="50" y="440" width="800" height="40" fill="rgba(99, 102, 241, 0.05)" stroke="#6366f1" stroke-width="1.5" stroke-dasharray="6,3" rx="6"/>
<text x="450" y="465" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-style="italic" fill="#4f46e5">
Compression Level 4 achieves 60-75% reduction while maintaining 95%+ information retention
</text>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,127 @@
<svg width="900" height="400" viewBox="0 0 900 400" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and effects -->
<defs>
<!-- Gradient for bars -->
<linearGradient id="barGrad1" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#1e40af;stop-opacity:0.9" />
</linearGradient>
<linearGradient id="barGrad2" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#10b981;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#059669;stop-opacity:0.9" />
</linearGradient>
<linearGradient id="barGrad3" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#8b5cf6;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#6d28d9;stop-opacity:0.9" />
</linearGradient>
<linearGradient id="barGrad4" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#f59e0b;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#d97706;stop-opacity:0.9" />
</linearGradient>
<linearGradient id="barGrad5" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#ef4444;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#dc2626;stop-opacity:0.9" />
</linearGradient>
<linearGradient id="barGrad6" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#06b6d4;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#0891b2;stop-opacity:0.9" />
</linearGradient>
<!-- Drop shadow filter -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.2"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="900" height="400" fill="#fafafa"/>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="22" font-weight="600" fill="#1e293b">
Storage Components per 1TB of Documents
</text>
<!-- Chart area -->
<rect x="100" y="60" width="700" height="260" fill="none" stroke="#e2e8f0" stroke-width="1"/>
<!-- Grid lines -->
<line x1="100" y1="125" x2="800" y2="125" stroke="#e2e8f0" stroke-width="1" stroke-dasharray="2,2" opacity="0.5"/>
<line x1="100" y1="190" x2="800" y2="190" stroke="#e2e8f0" stroke-width="1" stroke-dasharray="2,2" opacity="0.5"/>
<line x1="100" y1="255" x2="800" y2="255" stroke="#e2e8f0" stroke-width="1" stroke-dasharray="2,2" opacity="0.5"/>
<!-- Axes -->
<line x1="100" y1="320" x2="800" y2="320" stroke="#475569" stroke-width="2"/>
<line x1="100" y1="60" x2="100" y2="320" stroke="#475569" stroke-width="2"/>
<!-- Y-axis labels -->
<text x="90" y="325" text-anchor="end" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">0 GB</text>
<text x="90" y="260" text-anchor="end" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">250 GB</text>
<text x="90" y="195" text-anchor="end" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">500 GB</text>
<text x="90" y="130" text-anchor="end" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">750 GB</text>
<text x="90" y="65" text-anchor="end" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">1000 GB</text>
<!-- Y-axis title -->
<text x="30" y="190" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#475569" transform="rotate(-90 30 190)">
Storage Size (GB)
</text>
<!-- Bars -->
<!-- Original -->
<rect x="150" y="60" width="80" height="260" fill="url(#barGrad1)" stroke="#3b82f6" stroke-width="2" rx="4" filter="url(#shadow)"/>
<text x="190" y="80" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="white">1000</text>
<text x="190" y="340" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">Original</text>
<text x="190" y="355" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">1000 GB</text>
<!-- Text Extracted -->
<rect x="260" y="112" width="80" height="208" fill="url(#barGrad2)" stroke="#10b981" stroke-width="2" rx="4" filter="url(#shadow)"/>
<text x="300" y="132" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="white">800</text>
<text x="300" y="340" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">Extracted</text>
<text x="300" y="355" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">800 GB</text>
<!-- Embeddings -->
<rect x="370" y="8" width="80" height="312" fill="url(#barGrad3)" stroke="#8b5cf6" stroke-width="2" rx="4" filter="url(#shadow)"/>
<text x="410" y="28" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="white">1200</text>
<text x="410" y="340" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">Embeddings</text>
<text x="410" y="355" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">1200 GB</text>
<!-- Index -->
<rect x="480" y="164" width="80" height="156" fill="url(#barGrad4)" stroke="#f59e0b" stroke-width="2" rx="4" filter="url(#shadow)"/>
<text x="520" y="184" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="white">600</text>
<text x="520" y="340" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">Index</text>
<text x="520" y="355" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">600 GB</text>
<!-- Metadata -->
<rect x="590" y="216" width="80" height="104" fill="url(#barGrad5)" stroke="#ef4444" stroke-width="2" rx="4" filter="url(#shadow)"/>
<text x="630" y="236" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="white">400</text>
<text x="630" y="340" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">Metadata</text>
<text x="630" y="355" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">400 GB</text>
<!-- Cache -->
<rect x="700" y="190" width="80" height="130" fill="url(#barGrad6)" stroke="#06b6d4" stroke-width="2" rx="4" filter="url(#shadow)"/>
<text x="740" y="210" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="white">500</text>
<text x="740" y="340" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">Cache</text>
<text x="740" y="355" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">500 GB</text>
<!-- Total line -->
<line x1="150" y1="45" x2="780" y2="45" stroke="#dc2626" stroke-width="3" stroke-dasharray="8,4"/>
<rect x="790" y="35" width="90" height="25" fill="#fee2e2" stroke="#dc2626" stroke-width="2" rx="4"/>
<text x="835" y="52" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#dc2626">3.5 TB Total</text>
<!-- Legend -->
<g transform="translate(120, 375)">
<text x="0" y="0" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Components contribute to 3.5× storage multiplication factor</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View file

@ -0,0 +1,157 @@
<svg width="900" height="450" viewBox="0 0 900 450" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and effects -->
<defs>
<!-- Gradient for embedding section -->
<linearGradient id="embeddingGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:0.2" />
</linearGradient>
<!-- Gradient for LLM section -->
<linearGradient id="llmGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#06ffa5;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#00d2ff;stop-opacity:0.2" />
</linearGradient>
<!-- Gradient for performance section -->
<linearGradient id="perfGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#f5576c;stop-opacity:0.2" />
</linearGradient>
<!-- Drop shadow filter -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.15"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="900" height="450" fill="#fafafa"/>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="22" font-weight="600" fill="#1e293b">
System Technical Specifications
</text>
<!-- Main container -->
<rect x="50" y="50" width="800" height="380" fill="none" stroke="#cbd5e1" stroke-width="2" rx="8"/>
<!-- Embedding Configuration Section -->
<g transform="translate(70, 80)">
<rect x="0" y="0" width="350" height="150" fill="url(#embeddingGrad)" stroke="#667eea" stroke-width="1.5" rx="6" filter="url(#shadow)"/>
<text x="175" y="25" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#1e293b">
Embedding Configuration
</text>
<text x="15" y="50" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">
Model: bge-small-en-v1.5-f32.gguf
</text>
<text x="15" y="70" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Dimensions: 384
</text>
<text x="15" y="90" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Format: GGUF (quantized)
</text>
<text x="15" y="110" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Server: localhost:8082
</text>
<text x="15" y="130" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Memory: ~200MB loaded
</text>
</g>
<!-- LLM Configuration Section -->
<g transform="translate(450, 80)">
<rect x="0" y="0" width="350" height="150" fill="url(#llmGrad)" stroke="#00d2ff" stroke-width="1.5" rx="6" filter="url(#shadow)"/>
<text x="175" y="25" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#1e293b">
LLM Configuration
</text>
<text x="15" y="50" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">
Model: DeepSeek-R1-Distill-Qwen-1.5B
</text>
<text x="15" y="70" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Context Size: 4096 tokens
</text>
<text x="15" y="90" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Max Predict: 1024 tokens
</text>
<text x="15" y="110" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Parallel Requests: 6
</text>
<text x="15" y="130" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Quantization: Q3_K_M
</text>
</g>
<!-- Performance Characteristics Section -->
<g transform="translate(70, 250)">
<rect x="0" y="0" width="730" height="150" fill="url(#perfGrad)" stroke="#f5576c" stroke-width="1.5" rx="6" filter="url(#shadow)"/>
<text x="365" y="25" text-anchor="middle" font-family="system-ui, sans-serif" font-size="19" font-weight="600" fill="#1e293b">
Performance Characteristics
</text>
<!-- Left column - Vector Index -->
<g transform="translate(15, 45)">
<text x="0" y="0" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">
Vector Index: HNSW Algorithm
</text>
<text x="0" y="20" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• M=16, ef_construction=200
</text>
<text x="0" y="40" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Distance: Cosine Similarity
</text>
<text x="0" y="60" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Build: ~1000 docs/minute
</text>
</g>
<!-- Middle column - Chunking Strategy -->
<g transform="translate(250, 45)">
<text x="0" y="0" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">
Chunking Strategy
</text>
<text x="0" y="20" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Chunk Size: 512 tokens
</text>
<text x="0" y="40" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Overlap: 50 tokens
</text>
<text x="0" y="60" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Prompt Compact: Level 4
</text>
</g>
<!-- Right column - Runtime Metrics -->
<g transform="translate(490, 45)">
<text x="0" y="0" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">
Runtime Metrics
</text>
<text x="0" y="20" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Query Latency: &lt;50ms p99
</text>
<text x="0" y="40" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Memory: ~1GB/million chunks
</text>
<text x="0" y="60" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Cache TTL: 3600 seconds
</text>
</g>
</g>
<!-- Additional specs indicators -->
<g transform="translate(820, 100)">
<circle cx="0" cy="0" r="3" fill="#10b981"/>
<circle cx="0" cy="20" r="3" fill="#3b82f6"/>
<circle cx="0" cy="40" r="3" fill="#f59e0b"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -0,0 +1,195 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #fafafa; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.card { fill: #fff; stroke: #ddd; stroke-width: 1; }
.metric-value { fill: #1a1a1a; font-family: Arial, sans-serif; font-weight: bold; }
.metric-label { fill: #666; font-family: Arial, sans-serif; }
.metric-change-up { fill: #7ED321; font-family: Arial, sans-serif; }
.metric-change-down { fill: #E74C3C; font-family: Arial, sans-serif; }
.chart-line { stroke: #4A90E2; stroke-width: 2; fill: none; }
.chart-area { fill: #4A90E2; opacity: 0.1; }
.chart-grid { stroke: #eee; stroke-width: 1; }
.bar { fill: #4A90E2; }
.bar-alt { fill: #BD10E0; }
.dropdown { fill: #fff; stroke: #ccc; stroke-width: 1; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.panel-bg { fill: #222; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.card { fill: #2a2a2a; stroke: #444; }
.metric-value { fill: #ffffff; }
.metric-label { fill: #aaa; }
.chart-grid { stroke: #333; }
.dropdown { fill: #2a2a2a; stroke: #444; }
.button { fill: #00D4FF; }
.chart-line { stroke: #00D4FF; }
.bar { fill: #00D4FF; }
.bar-alt { fill: #E040FB; }
.chart-area { fill: #00D4FF; opacity: 0.1; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Analytics - Dashboard Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Header -->
<rect x="30" y="50" width="840" height="50" rx="8" class="header-bg"/>
<rect x="30" y="92" width="840" height="8" class="bg"/>
<!-- Title and Controls -->
<text x="55" y="82" font-size="16" font-weight="600" class="main-text">📊 Analytics Dashboard</text>
<!-- Time Range Dropdown -->
<g transform="translate(550, 62)">
<rect x="0" y="0" width="120" height="30" rx="4" class="dropdown"/>
<text x="15" y="20" font-size="13" class="main-text">Last 24h ▼</text>
</g>
<!-- Refresh Button -->
<g transform="translate(680, 62)">
<rect x="0" y="0" width="80" height="30" rx="4" class="button"/>
<text x="40" y="20" text-anchor="middle" font-size="13" class="button-text">⟳ Refresh</text>
</g>
<!-- Divider -->
<line x1="30" y1="100" x2="870" y2="100" class="divider"/>
<!-- Metric Cards Row -->
<g transform="translate(50, 115)">
<!-- Card 1: Messages -->
<rect x="0" y="0" width="185" height="90" rx="8" class="card"/>
<text x="92" y="35" text-anchor="middle" font-size="28" class="metric-value">1,234</text>
<text x="92" y="55" text-anchor="middle" font-size="13" class="metric-label">Messages</text>
<text x="92" y="75" text-anchor="middle" font-size="12" class="metric-change-up">↑ +12%</text>
<!-- Card 2: Success Rate -->
<rect x="200" y="0" width="185" height="90" rx="8" class="card"/>
<text x="292" y="35" text-anchor="middle" font-size="28" class="metric-value">89%</text>
<text x="292" y="55" text-anchor="middle" font-size="13" class="metric-label">Success Rate</text>
<text x="292" y="75" text-anchor="middle" font-size="12" class="metric-change-up">↑ +3%</text>
<!-- Card 3: Avg Response Time -->
<rect x="400" y="0" width="185" height="90" rx="8" class="card"/>
<text x="492" y="35" text-anchor="middle" font-size="28" class="metric-value">2.3s</text>
<text x="492" y="55" text-anchor="middle" font-size="13" class="metric-label">Avg Response</text>
<text x="492" y="75" text-anchor="middle" font-size="12" class="metric-change-down">↓ -0.2s</text>
<!-- Card 4: Users Today -->
<rect x="600" y="0" width="185" height="90" rx="8" class="card"/>
<text x="692" y="35" text-anchor="middle" font-size="28" class="metric-value">45</text>
<text x="692" y="55" text-anchor="middle" font-size="13" class="metric-label">Users Today</text>
<text x="692" y="75" text-anchor="middle" font-size="12" class="metric-change-up">↑ +8</text>
</g>
<!-- Charts Row -->
<g transform="translate(50, 220)">
<!-- Line Chart: Messages Over Time -->
<rect x="0" y="0" width="480" height="200" rx="8" class="card"/>
<text x="20" y="25" font-size="14" font-weight="500" class="main-text">Messages Over Time</text>
<!-- Chart Grid -->
<g transform="translate(30, 45)">
<line x1="0" y1="0" x2="430" y2="0" class="chart-grid"/>
<line x1="0" y1="40" x2="430" y2="40" class="chart-grid"/>
<line x1="0" y1="80" x2="430" y2="80" class="chart-grid"/>
<line x1="0" y1="120" x2="430" y2="120" class="chart-grid"/>
<!-- Chart Area -->
<path d="M0,100 Q50,80 100,60 T200,40 T300,50 T400,20 L400,120 L0,120 Z" class="chart-area"/>
<!-- Chart Line -->
<path d="M0,100 Q50,80 100,60 T200,40 T300,50 T400,20" class="chart-line"/>
<!-- Data Points -->
<circle cx="0" cy="100" r="4" class="bar"/>
<circle cx="100" cy="60" r="4" class="bar"/>
<circle cx="200" cy="40" r="4" class="bar"/>
<circle cx="300" cy="50" r="4" class="bar"/>
<circle cx="400" cy="20" r="4" class="bar"/>
<!-- X-axis Labels -->
<text x="0" y="140" text-anchor="middle" font-size="10" class="secondary-text">Mon</text>
<text x="100" y="140" text-anchor="middle" font-size="10" class="secondary-text">Tue</text>
<text x="200" y="140" text-anchor="middle" font-size="10" class="secondary-text">Wed</text>
<text x="300" y="140" text-anchor="middle" font-size="10" class="secondary-text">Thu</text>
<text x="400" y="140" text-anchor="middle" font-size="10" class="secondary-text">Fri</text>
</g>
<!-- Bar Chart: Top Questions -->
<rect x="500" y="0" width="285" height="200" rx="8" class="card"/>
<text x="520" y="25" font-size="14" font-weight="500" class="main-text">Top Questions</text>
<g transform="translate(520, 45)">
<!-- Bar 1 -->
<text x="0" y="12" font-size="11" class="secondary-text">1. How do I reset...</text>
<rect x="0" y="18" width="200" height="16" rx="3" class="bar"/>
<!-- Bar 2 -->
<text x="0" y="52" font-size="11" class="secondary-text">2. What is the status...</text>
<rect x="0" y="58" width="160" height="16" rx="3" class="bar"/>
<!-- Bar 3 -->
<text x="0" y="92" font-size="11" class="secondary-text">3. Where can I find...</text>
<rect x="0" y="98" width="130" height="16" rx="3" class="bar"/>
<!-- Bar 4 -->
<text x="0" y="132" font-size="11" class="secondary-text">4. Help with login</text>
<rect x="0" y="138" width="100" height="16" rx="3" class="bar"/>
</g>
</g>
<!-- Quick Stats Row -->
<g transform="translate(50, 435)">
<rect x="0" y="0" width="785" height="45" rx="6" class="card"/>
<text x="20" y="28" font-size="12" class="secondary-text">📈 Peak Hour:</text>
<text x="100" y="28" font-size="12" font-weight="500" class="main-text">2:00 PM</text>
<line x1="160" y1="10" x2="160" y2="35" class="divider"/>
<text x="180" y="28" font-size="12" class="secondary-text">🔝 Top Intent:</text>
<text x="260" y="28" font-size="12" font-weight="500" class="main-text">Support Query</text>
<line x1="370" y1="10" x2="370" y2="35" class="divider"/>
<text x="390" y="28" font-size="12" class="secondary-text">⚡ Avg Session:</text>
<text x="480" y="28" font-size="12" font-weight="500" class="main-text">4.2 min</text>
<line x1="540" y1="10" x2="540" y2="35" class="divider"/>
<text x="560" y="28" font-size="12" class="secondary-text">🎯 Resolution:</text>
<text x="640" y="28" font-size="12" font-weight="500" class="main-text">94%</text>
<!-- Export Button -->
<rect x="700" y="8" width="70" height="28" rx="4" class="button"/>
<text x="735" y="27" text-anchor="middle" font-size="11" class="button-text">Export</text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<text x="0" y="0" font-size="11" class="secondary-text">Metrics: Real-time KPIs</text>
<text x="150" y="0" font-size="11" class="secondary-text">Charts: Trends & Distribution</text>
<text x="350" y="0" font-size="11" class="secondary-text">Time Range: Last 24h, 7d, 30d, Custom</text>
<text x="600" y="0" font-size="11" class="secondary-text">Shortcuts: R = Refresh | E = Export</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.9 KiB

View file

@ -0,0 +1,211 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.today { fill: #4A90E2; }
.event-bg { fill: #4A90E2; opacity: 0.8; }
.event-text { fill: #fff; font-family: Arial, sans-serif; }
.weekend { fill: #f0f0f0; }
.cell-border { stroke: #e0e0e0; stroke-width: 1; fill: none; }
.nav-btn { fill: #f0f0f0; stroke: #ccc; stroke-width: 1; }
.view-active { fill: #4A90E2; }
.view-inactive { fill: #e0e0e0; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.today { fill: #00D4FF; }
.event-bg { fill: #00D4FF; opacity: 0.8; }
.weekend { fill: #252525; }
.cell-border { stroke: #444; }
.nav-btn { fill: #333; stroke: #555; }
.button { fill: #00D4FF; }
.view-active { fill: #00D4FF; }
.view-inactive { fill: #333; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Calendar - Scheduling Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Header -->
<rect x="30" y="50" width="840" height="50" rx="8" class="header-bg"/>
<rect x="30" y="92" width="840" height="8" class="bg"/>
<!-- Navigation -->
<g transform="translate(50, 62)">
<!-- Prev/Next Buttons -->
<rect x="0" y="0" width="30" height="30" rx="4" class="nav-btn"/>
<text x="15" y="21" text-anchor="middle" font-size="16" class="icon-text"></text>
<rect x="40" y="0" width="30" height="30" rx="4" class="nav-btn"/>
<text x="55" y="21" text-anchor="middle" font-size="16" class="icon-text"></text>
<!-- Month/Year -->
<text x="100" y="22" font-size="18" font-weight="600" class="main-text">March 2024</text>
</g>
<!-- View Toggle -->
<g transform="translate(650, 62)">
<rect x="0" y="0" width="50" height="30" rx="4" class="view-inactive"/>
<text x="25" y="20" text-anchor="middle" font-size="12" class="main-text">Day</text>
<rect x="55" y="0" width="55" height="30" rx="4" class="view-inactive"/>
<text x="82" y="20" text-anchor="middle" font-size="12" class="main-text">Week</text>
<rect x="115" y="0" width="60" height="30" rx="4" class="view-active"/>
<text x="145" y="20" text-anchor="middle" font-size="12" fill="#fff">Month</text>
</g>
<!-- Divider -->
<line x1="30" y1="100" x2="870" y2="100" class="divider"/>
<!-- Calendar Grid -->
<g transform="translate(50, 110)">
<!-- Day Headers -->
<g>
<text x="55" y="20" text-anchor="middle" font-size="13" font-weight="500" class="secondary-text">Mon</text>
<text x="170" y="20" text-anchor="middle" font-size="13" font-weight="500" class="secondary-text">Tue</text>
<text x="285" y="20" text-anchor="middle" font-size="13" font-weight="500" class="secondary-text">Wed</text>
<text x="400" y="20" text-anchor="middle" font-size="13" font-weight="500" class="secondary-text">Thu</text>
<text x="515" y="20" text-anchor="middle" font-size="13" font-weight="500" class="secondary-text">Fri</text>
<text x="630" y="20" text-anchor="middle" font-size="13" font-weight="500" class="secondary-text">Sat</text>
<text x="745" y="20" text-anchor="middle" font-size="13" font-weight="500" class="secondary-text">Sun</text>
</g>
<!-- Grid Lines and Cells -->
<!-- Row 1 -->
<g transform="translate(0, 35)">
<rect x="0" y="0" width="115" height="65" class="cell-border"/>
<rect x="115" y="0" width="115" height="65" class="cell-border"/>
<rect x="230" y="0" width="115" height="65" class="cell-border"/>
<rect x="345" y="0" width="115" height="65" class="cell-border"/>
<text x="435" y="20" text-anchor="middle" font-size="14" class="main-text">1</text>
<rect x="460" y="0" width="115" height="65" class="cell-border"/>
<text x="550" y="20" text-anchor="middle" font-size="14" class="main-text">2</text>
<rect x="575" y="0" width="115" height="65" class="cell-border weekend"/>
<text x="665" y="20" text-anchor="middle" font-size="14" class="secondary-text">3</text>
<rect x="690" y="0" width="110" height="65" class="cell-border weekend"/>
</g>
<!-- Row 2 -->
<g transform="translate(0, 100)">
<rect x="0" y="0" width="115" height="65" class="cell-border"/>
<text x="15" y="20" font-size="14" class="main-text">4</text>
<rect x="115" y="0" width="115" height="65" class="cell-border"/>
<text x="130" y="20" font-size="14" class="main-text">5</text>
<!-- Event -->
<rect x="120" y="28" width="105" height="22" rx="3" class="event-bg"/>
<text x="125" y="43" font-size="11" class="event-text">Team Meeting</text>
<rect x="230" y="0" width="115" height="65" class="cell-border"/>
<text x="245" y="20" font-size="14" class="main-text">6</text>
<rect x="345" y="0" width="115" height="65" class="cell-border"/>
<text x="360" y="20" font-size="14" class="main-text">7</text>
<rect x="460" y="0" width="115" height="65" class="cell-border"/>
<text x="475" y="20" font-size="14" class="main-text">8</text>
<rect x="575" y="0" width="115" height="65" class="cell-border weekend"/>
<text x="590" y="20" font-size="14" class="secondary-text">9</text>
<rect x="690" y="0" width="110" height="65" class="cell-border weekend"/>
<text x="705" y="20" font-size="14" class="secondary-text">10</text>
</g>
<!-- Row 3 -->
<g transform="translate(0, 165)">
<rect x="0" y="0" width="115" height="65" class="cell-border"/>
<text x="15" y="20" font-size="14" class="main-text">11</text>
<rect x="115" y="0" width="115" height="65" class="cell-border"/>
<text x="130" y="20" font-size="14" class="main-text">12</text>
<rect x="230" y="0" width="115" height="65" class="cell-border"/>
<text x="245" y="20" font-size="14" class="main-text">13</text>
<!-- Event -->
<rect x="235" y="28" width="105" height="22" rx="3" class="event-bg"/>
<text x="240" y="43" font-size="11" class="event-text">Project Review</text>
<rect x="345" y="0" width="115" height="65" class="cell-border"/>
<text x="360" y="20" font-size="14" class="main-text">14</text>
<!-- Event -->
<rect x="350" y="28" width="105" height="22" rx="3" class="event-bg"/>
<text x="355" y="43" font-size="11" class="event-text">1:1 Meeting</text>
<rect x="460" y="0" width="115" height="65" class="cell-border"/>
<!-- Today -->
<circle cx="485" cy="18" r="14" class="today"/>
<text x="485" y="23" text-anchor="middle" font-size="14" fill="#fff">15</text>
<rect x="575" y="0" width="115" height="65" class="cell-border weekend"/>
<text x="590" y="20" font-size="14" class="secondary-text">16</text>
<rect x="690" y="0" width="110" height="65" class="cell-border weekend"/>
<text x="705" y="20" font-size="14" class="secondary-text">17</text>
</g>
<!-- Row 4 -->
<g transform="translate(0, 230)">
<rect x="0" y="0" width="115" height="65" class="cell-border"/>
<text x="15" y="20" font-size="14" class="main-text">18</text>
<rect x="115" y="0" width="115" height="65" class="cell-border"/>
<text x="130" y="20" font-size="14" class="main-text">19</text>
<rect x="230" y="0" width="115" height="65" class="cell-border"/>
<text x="245" y="20" font-size="14" class="main-text">20</text>
<rect x="345" y="0" width="115" height="65" class="cell-border"/>
<text x="360" y="20" font-size="14" class="main-text">21</text>
<rect x="460" y="0" width="115" height="65" class="cell-border"/>
<text x="475" y="20" font-size="14" class="main-text">22</text>
<rect x="575" y="0" width="115" height="65" class="cell-border weekend"/>
<text x="590" y="20" font-size="14" class="secondary-text">23</text>
<rect x="690" y="0" width="110" height="65" class="cell-border weekend"/>
<text x="705" y="20" font-size="14" class="secondary-text">24</text>
</g>
</g>
<!-- Add Event Button -->
<g transform="translate(750, 470)">
<circle cx="30" cy="30" r="28" class="button"/>
<text x="30" y="38" text-anchor="middle" font-size="28" fill="#fff">+</text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<circle cx="10" cy="-4" r="8" class="today"/>
<text x="25" y="0" font-size="11" class="secondary-text">Today</text>
<rect x="80" y="-10" width="40" height="14" rx="3" class="event-bg"/>
<text x="130" y="0" font-size="11" class="secondary-text">Event</text>
<rect x="200" y="-10" width="20" height="14" class="weekend"/>
<text x="230" y="0" font-size="11" class="secondary-text">Weekend</text>
<text x="400" y="0" font-size="11" class="secondary-text">Shortcuts: N = New event | T = Today | ← → = Navigate | D/W/M = View</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

View file

@ -0,0 +1,200 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #fafafa; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.button-secondary { fill: #fff; stroke: #ccc; stroke-width: 1; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.card { fill: #fff; stroke: #ddd; stroke-width: 1; }
.severity-critical { fill: #E74C3C; }
.severity-high { fill: #F5A623; }
.severity-medium { fill: #F1C40F; }
.severity-low { fill: #7ED321; }
.severity-info { fill: #4A90E2; }
.severity-text { fill: #fff; font-family: Arial, sans-serif; }
.row-bg { fill: #fff; }
.row-hover { fill: #fef6f6; }
.fix-btn { fill: #E74C3C; }
.review-btn { fill: #F5A623; }
.table-header { fill: #f5f5f5; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.panel-bg { fill: #222; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.card { fill: #2a2a2a; stroke: #444; }
.row-bg { fill: #2a2a2a; }
.row-hover { fill: #3a2a2a; }
.table-header { fill: #333; }
.button { fill: #00D4FF; }
.button-secondary { fill: #333; stroke: #555; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Compliance - Security Scanner Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Header -->
<rect x="30" y="50" width="840" height="50" rx="8" class="header-bg"/>
<rect x="30" y="92" width="840" height="8" class="bg"/>
<!-- Title and Controls -->
<text x="55" y="82" font-size="16" font-weight="600" class="main-text">🛡 Compliance Scanner</text>
<!-- Action Buttons -->
<g transform="translate(600, 60)">
<rect x="0" y="0" width="80" height="32" rx="4" class="button"/>
<text x="40" y="21" text-anchor="middle" font-size="13" class="button-text">Scan</text>
<rect x="90" y="0" width="80" height="32" rx="4" class="button-secondary"/>
<text x="130" y="21" text-anchor="middle" font-size="13" class="main-text">Export</text>
</g>
<!-- Divider -->
<line x1="30" y1="100" x2="870" y2="100" class="divider"/>
<!-- Severity Summary Cards -->
<g transform="translate(50, 115)">
<!-- Critical -->
<rect x="0" y="0" width="145" height="70" rx="8" class="card"/>
<rect x="10" y="15" width="50" height="40" rx="6" class="severity-critical"/>
<text x="35" y="42" text-anchor="middle" font-size="20" font-weight="bold" class="severity-text">2</text>
<text x="75" y="35" font-size="12" font-weight="500" class="main-text">Critical</text>
<text x="75" y="52" font-size="11" class="secondary-text">🔴 Immediate</text>
<!-- High -->
<rect x="160" y="0" width="145" height="70" rx="8" class="card"/>
<rect x="170" y="15" width="50" height="40" rx="6" class="severity-high"/>
<text x="195" y="42" text-anchor="middle" font-size="20" font-weight="bold" class="severity-text">5</text>
<text x="235" y="35" font-size="12" font-weight="500" class="main-text">High</text>
<text x="235" y="52" font-size="11" class="secondary-text">🟠 Priority</text>
<!-- Medium -->
<rect x="320" y="0" width="145" height="70" rx="8" class="card"/>
<rect x="330" y="15" width="50" height="40" rx="6" class="severity-medium"/>
<text x="355" y="42" text-anchor="middle" font-size="20" font-weight="bold" class="severity-text">3</text>
<text x="395" y="35" font-size="12" font-weight="500" class="main-text">Medium</text>
<text x="395" y="52" font-size="11" class="secondary-text">🟡 Review</text>
<!-- Low -->
<rect x="480" y="0" width="145" height="70" rx="8" class="card"/>
<rect x="490" y="15" width="50" height="40" rx="6" class="severity-low"/>
<text x="515" y="42" text-anchor="middle" font-size="20" font-weight="bold" class="severity-text">1</text>
<text x="555" y="35" font-size="12" font-weight="500" class="main-text">Low</text>
<text x="555" y="52" font-size="11" class="secondary-text">🟢 Minor</text>
<!-- Info -->
<rect x="640" y="0" width="145" height="70" rx="8" class="card"/>
<rect x="650" y="15" width="50" height="40" rx="6" class="severity-info"/>
<text x="675" y="42" text-anchor="middle" font-size="20" font-weight="bold" class="severity-text">0</text>
<text x="715" y="35" font-size="12" font-weight="500" class="main-text">Info</text>
<text x="715" y="52" font-size="11" class="secondary-text"> Notes</text>
</g>
<!-- Divider -->
<line x1="50" y1="200" x2="850" y2="200" class="divider"/>
<!-- Issues Table -->
<g transform="translate(50, 210)">
<!-- Table Header -->
<rect x="0" y="0" width="800" height="35" rx="4" class="table-header"/>
<text x="20" y="23" font-size="12" font-weight="500" class="secondary-text">Severity</text>
<text x="120" y="23" font-size="12" font-weight="500" class="secondary-text">Issue</text>
<text x="450" y="23" font-size="12" font-weight="500" class="secondary-text">File</text>
<text x="650" y="23" font-size="12" font-weight="500" class="secondary-text">Action</text>
<!-- Row 1 - Critical -->
<rect x="0" y="40" width="800" height="45" rx="4" class="row-hover"/>
<rect x="15" y="52" width="70" height="22" rx="4" class="severity-critical"/>
<text x="50" y="68" text-anchor="middle" font-size="11" class="severity-text">Critical</text>
<text x="120" y="68" font-size="13" class="main-text">Hardcoded password detected</text>
<text x="450" y="68" font-size="12" font-family="monospace" class="secondary-text">start.bas:15</text>
<rect x="650" y="52" width="55" height="24" rx="4" class="fix-btn"/>
<text x="677" y="69" text-anchor="middle" font-size="11" class="severity-text">Fix</text>
<!-- Row 2 - Critical -->
<rect x="0" y="90" width="800" height="45" rx="4" class="row-hover"/>
<rect x="15" y="102" width="70" height="22" rx="4" class="severity-critical"/>
<text x="50" y="118" text-anchor="middle" font-size="11" class="severity-text">Critical</text>
<text x="120" y="118" font-size="13" class="main-text">API key exposed in code</text>
<text x="450" y="118" font-size="12" font-family="monospace" class="secondary-text">api.bas:42</text>
<rect x="650" y="102" width="55" height="24" rx="4" class="fix-btn"/>
<text x="677" y="119" text-anchor="middle" font-size="11" class="severity-text">Fix</text>
<!-- Row 3 - High -->
<rect x="0" y="140" width="800" height="45" rx="4" class="row-bg"/>
<rect x="15" y="152" width="70" height="22" rx="4" class="severity-high"/>
<text x="50" y="168" text-anchor="middle" font-size="11" class="severity-text">High</text>
<text x="120" y="168" font-size="13" class="main-text">SQL injection risk in query</text>
<text x="450" y="168" font-size="12" font-family="monospace" class="secondary-text">data.bas:28</text>
<rect x="650" y="152" width="65" height="24" rx="4" class="review-btn"/>
<text x="682" y="169" text-anchor="middle" font-size="11" class="severity-text">Review</text>
<!-- Row 4 - High -->
<rect x="0" y="190" width="800" height="45" rx="4" class="row-bg"/>
<rect x="15" y="202" width="70" height="22" rx="4" class="severity-high"/>
<text x="50" y="218" text-anchor="middle" font-size="11" class="severity-text">High</text>
<text x="120" y="218" font-size="13" class="main-text">Insecure HTTP endpoint</text>
<text x="450" y="218" font-size="12" font-family="monospace" class="secondary-text">config.csv:8</text>
<rect x="650" y="202" width="65" height="24" rx="4" class="review-btn"/>
<text x="682" y="219" text-anchor="middle" font-size="11" class="severity-text">Review</text>
<!-- Row 5 - Medium -->
<rect x="0" y="240" width="800" height="45" rx="4" class="row-bg"/>
<rect x="15" y="252" width="70" height="22" rx="4" class="severity-medium"/>
<text x="50" y="268" text-anchor="middle" font-size="11" class="severity-text">Medium</text>
<text x="120" y="268" font-size="13" class="main-text">Missing input validation</text>
<text x="450" y="268" font-size="12" font-family="monospace" class="secondary-text">form.bas:55</text>
<rect x="650" y="252" width="65" height="24" rx="4" class="button-secondary"/>
<text x="682" y="269" text-anchor="middle" font-size="11" class="main-text">Review</text>
</g>
<!-- Footer Stats -->
<g transform="translate(50, 480)">
<text x="0" y="0" font-size="12" class="secondary-text">Last scan: 2 minutes ago</text>
<text x="200" y="0" font-size="12" class="secondary-text">Files scanned: 24</text>
<text x="380" y="0" font-size="12" class="secondary-text">Total issues: 11</text>
<!-- Pagination -->
<text x="600" y="0" font-size="12" class="secondary-text">Showing 1-5 of 11</text>
<rect x="720" y="-15" width="25" height="22" rx="4" class="button-secondary"/>
<text x="732" y="2" text-anchor="middle" font-size="12" class="main-text"></text>
<rect x="750" y="-15" width="25" height="22" rx="4" class="button-secondary"/>
<text x="762" y="2" text-anchor="middle" font-size="12" class="main-text"></text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<rect x="0" y="-10" width="14" height="14" rx="3" class="severity-critical"/>
<text x="20" y="0" font-size="11" class="secondary-text">Critical</text>
<rect x="70" y="-10" width="14" height="14" rx="3" class="severity-high"/>
<text x="90" y="0" font-size="11" class="secondary-text">High</text>
<rect x="130" y="-10" width="14" height="14" rx="3" class="severity-medium"/>
<text x="150" y="0" font-size="11" class="secondary-text">Medium</text>
<rect x="200" y="-10" width="14" height="14" rx="3" class="severity-low"/>
<text x="220" y="0" font-size="11" class="secondary-text">Low</text>
<text x="300" y="0" font-size="11" class="secondary-text">Fix = Auto-remediate | Review = Manual inspection needed</text>
<text x="650" y="0" font-size="11" class="secondary-text">LGPD • GDPR • CCPA</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,258 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #fafafa; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.canvas-bg { fill: #fff; }
.canvas-grid { stroke: #f0f0f0; stroke-width: 1; }
.node-talk { fill: #4A90E2; stroke: #3a7bc8; stroke-width: 2; }
.node-hear { fill: #7ED321; stroke: #6bc01a; stroke-width: 2; }
.node-if { fill: #F5A623; stroke: #d9911f; stroke-width: 2; }
.node-text { fill: #fff; font-family: Arial, sans-serif; }
.connector { stroke: #666; stroke-width: 2; fill: none; }
.connector-arrow { fill: #666; }
.toolbox-item { fill: #fff; stroke: #ddd; stroke-width: 1; }
.toolbox-item:hover { fill: #f0f7ff; }
.properties-panel { fill: #fafafa; }
.section-header { fill: #e8e8e8; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.panel-bg { fill: #222; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.canvas-bg { fill: #252525; }
.canvas-grid { stroke: #333; }
.toolbox-item { fill: #2a2a2a; stroke: #444; }
.properties-panel { fill: #222; }
.section-header { fill: #333; }
.connector { stroke: #888; }
.connector-arrow { fill: #888; }
.button { fill: #00D4FF; }
.node-talk { fill: #00D4FF; stroke: #00a8cc; }
.node-hear { fill: #00FF88; stroke: #00cc6d; }
.node-if { fill: #FF9500; stroke: #cc7700; }
}
</style>
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" class="connector-arrow"/>
</marker>
</defs>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Designer - Visual Builder Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Left Panel - Toolbox -->
<rect x="30" y="50" width="120" height="470" rx="8" class="panel-bg"/>
<line x1="150" y1="50" x2="150" y2="520" class="divider"/>
<!-- Toolbox Header -->
<rect x="30" y="50" width="120" height="30" rx="8" class="section-header"/>
<rect x="30" y="72" width="120" height="8" class="panel-bg"/>
<text x="90" y="70" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Toolbox</text>
<!-- Toolbox Items -->
<g transform="translate(40, 90)">
<!-- TALK -->
<rect x="0" y="0" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="23" font-size="14" class="icon-text">💬</text>
<text x="35" y="23" font-size="12" class="main-text">TALK</text>
<!-- HEAR -->
<rect x="0" y="45" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="68" font-size="14" class="icon-text">👂</text>
<text x="35" y="68" font-size="12" class="main-text">HEAR</text>
<!-- SET -->
<rect x="0" y="90" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="113" font-size="14" class="icon-text">📝</text>
<text x="35" y="113" font-size="12" class="main-text">SET</text>
<!-- Separator -->
<line x1="0" y1="140" x2="100" y2="140" class="divider"/>
<!-- IF -->
<rect x="0" y="155" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="178" font-size="14" class="icon-text">🔀</text>
<text x="35" y="178" font-size="12" class="main-text">IF</text>
<!-- FOR -->
<rect x="0" y="200" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="223" font-size="14" class="icon-text">🔄</text>
<text x="35" y="223" font-size="12" class="main-text">FOR</text>
<!-- SWITCH -->
<rect x="0" y="245" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="268" font-size="14" class="icon-text">🔃</text>
<text x="35" y="268" font-size="12" class="main-text">SWITCH</text>
<!-- Separator -->
<line x1="0" y1="295" x2="100" y2="295" class="divider"/>
<!-- CALL -->
<rect x="0" y="310" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="333" font-size="14" class="icon-text">📞</text>
<text x="35" y="333" font-size="12" class="main-text">CALL</text>
<!-- SEND -->
<rect x="0" y="355" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="378" font-size="14" class="icon-text">📧</text>
<text x="35" y="378" font-size="12" class="main-text">SEND</text>
<!-- SAVE -->
<rect x="0" y="400" width="100" height="35" rx="4" class="toolbox-item"/>
<text x="15" y="423" font-size="14" class="icon-text">💾</text>
<text x="35" y="423" font-size="12" class="main-text">SAVE</text>
</g>
<!-- Center Panel - Canvas -->
<rect x="150" y="50" width="560" height="470" class="canvas-bg"/>
<!-- Canvas Grid (subtle) -->
<g transform="translate(150, 50)">
<line x1="0" y1="100" x2="560" y2="100" class="canvas-grid"/>
<line x1="0" y1="200" x2="560" y2="200" class="canvas-grid"/>
<line x1="0" y1="300" x2="560" y2="300" class="canvas-grid"/>
<line x1="0" y1="400" x2="560" y2="400" class="canvas-grid"/>
<line x1="100" y1="0" x2="100" y2="470" class="canvas-grid"/>
<line x1="200" y1="0" x2="200" y2="470" class="canvas-grid"/>
<line x1="300" y1="0" x2="300" y2="470" class="canvas-grid"/>
<line x1="400" y1="0" x2="400" y2="470" class="canvas-grid"/>
<line x1="500" y1="0" x2="500" y2="470" class="canvas-grid"/>
</g>
<!-- Flow Diagram on Canvas -->
<g transform="translate(200, 80)">
<!-- Node 1: TALK "Hello!" -->
<rect x="0" y="0" width="120" height="60" rx="8" class="node-talk"/>
<text x="20" y="25" font-size="14" class="node-text">💬 TALK</text>
<text x="20" y="45" font-size="12" class="node-text">"Hello!"</text>
<!-- Connector 1 to 2 -->
<line x1="60" y1="60" x2="60" y2="100" class="connector" marker-end="url(#arrowhead)"/>
<!-- Node 2: HEAR name -->
<rect x="0" y="110" width="120" height="60" rx="8" class="node-hear"/>
<text x="20" y="135" font-size="14" class="node-text">👂 HEAR</text>
<text x="20" y="155" font-size="12" class="node-text">name</text>
<!-- Connector 2 to 3 -->
<line x1="120" y1="140" x2="180" y2="140" class="connector" marker-end="url(#arrowhead)"/>
<!-- Node 3: IF condition -->
<rect x="190" y="110" width="140" height="60" rx="8" class="node-if"/>
<text x="210" y="135" font-size="14" class="node-text">🔀 IF</text>
<text x="210" y="155" font-size="12" class="node-text">name = "Jo"</text>
<!-- Branch Labels -->
<text x="220" y="195" font-size="11" class="secondary-text">Yes</text>
<text x="310" y="195" font-size="11" class="secondary-text">No</text>
<!-- Connector to Yes branch -->
<path d="M220 170 L220 200 L220 230" class="connector" marker-end="url(#arrowhead)"/>
<!-- Connector to No branch -->
<path d="M310 170 L310 200 L310 230" class="connector" marker-end="url(#arrowhead)"/>
<!-- Node 4a: TALK "Hi Jo!" -->
<rect x="160" y="240" width="120" height="60" rx="8" class="node-talk"/>
<text x="180" y="265" font-size="14" class="node-text">💬 TALK</text>
<text x="180" y="285" font-size="12" class="node-text">"Hi Jo!"</text>
<!-- Node 4b: TALK "Hello!" -->
<rect x="290" y="240" width="120" height="60" rx="8" class="node-talk"/>
<text x="310" y="265" font-size="14" class="node-text">💬 TALK</text>
<text x="310" y="285" font-size="12" class="node-text">"Hello!"</text>
</g>
<!-- Right Panel - Properties -->
<rect x="710" y="50" width="160" height="470" rx="8" class="properties-panel"/>
<line x1="710" y1="50" x2="710" y2="520" class="divider"/>
<!-- Properties Header -->
<rect x="710" y="50" width="160" height="30" rx="8" class="section-header"/>
<rect x="710" y="72" width="160" height="8" class="properties-panel"/>
<text x="790" y="70" text-anchor="middle" font-size="12" font-weight="500" class="main-text">Properties</text>
<!-- Properties Content -->
<g transform="translate(720, 95)">
<text x="0" y="0" font-size="12" class="secondary-text">Node:</text>
<text x="0" y="20" font-size="14" font-weight="500" class="main-text">TALK</text>
<line x1="0" y1="35" x2="140" y2="35" class="divider"/>
<text x="0" y="55" font-size="12" class="secondary-text">Message:</text>
<rect x="0" y="65" width="140" height="60" rx="4" class="input-field"/>
<text x="10" y="85" font-size="12" class="main-text">"Hello!"</text>
<line x1="0" y1="140" x2="140" y2="140" class="divider"/>
<text x="0" y="160" font-size="12" class="secondary-text">Voice:</text>
<rect x="0" y="170" width="140" height="30" rx="4" class="input-field"/>
<text x="10" y="190" font-size="12" class="secondary-text">Default ▼</text>
<text x="0" y="220" font-size="12" class="secondary-text">Delay:</text>
<rect x="0" y="230" width="140" height="30" rx="4" class="input-field"/>
<text x="10" y="250" font-size="12" class="main-text">0ms</text>
<line x1="0" y1="275" x2="140" y2="275" class="divider"/>
<!-- Action Buttons -->
<rect x="0" y="290" width="65" height="30" rx="4" class="button"/>
<text x="32" y="310" text-anchor="middle" font-size="11" class="button-text">Apply</text>
<rect x="75" y="290" width="65" height="30" rx="4" class="input-field"/>
<text x="107" y="310" text-anchor="middle" font-size="11" class="main-text">Delete</text>
</g>
<!-- Canvas Controls (bottom) -->
<g transform="translate(160, 490)">
<rect x="0" y="0" width="30" height="25" rx="4" class="input-field"/>
<text x="15" y="17" text-anchor="middle" font-size="14" class="icon-text">+</text>
<rect x="35" y="0" width="30" height="25" rx="4" class="input-field"/>
<text x="50" y="17" text-anchor="middle" font-size="14" class="icon-text"></text>
<rect x="70" y="0" width="30" height="25" rx="4" class="input-field"/>
<text x="85" y="17" text-anchor="middle" font-size="12" class="icon-text"></text>
<text x="120" y="17" font-size="11" class="secondary-text">100%</text>
<rect x="480" y="0" width="60" height="25" rx="4" class="button"/>
<text x="510" y="17" text-anchor="middle" font-size="11" class="button-text">▶ Run</text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<rect x="0" y="-10" width="20" height="14" rx="3" class="node-talk"/>
<text x="28" y="0" font-size="11" class="secondary-text">Talk</text>
<rect x="60" y="-10" width="20" height="14" rx="3" class="node-hear"/>
<text x="88" y="0" font-size="11" class="secondary-text">Hear</text>
<rect x="120" y="-10" width="20" height="14" rx="3" class="node-if"/>
<text x="148" y="0" font-size="11" class="secondary-text">Condition</text>
<text x="250" y="0" font-size="11" class="secondary-text">Drag nodes from Toolbox → Canvas | Connect by dragging</text>
<text x="600" y="0" font-size="11" class="secondary-text">Shortcuts: Delete | Ctrl+D = Duplicate | Ctrl+Z = Undo</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,155 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #fafafa; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.row-hover { fill: #f0f7ff; }
.folder-icon { fill: #F5A623; }
.file-icon { fill: #4A90E2; }
.image-icon { fill: #7ED321; }
.sidebar-item { fill: none; }
.sidebar-item:hover { fill: #e8e8e8; }
.label-blue { fill: #4A90E2; }
.label-green { fill: #7ED321; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.panel-bg { fill: #222; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.row-hover { fill: #2a3a4a; }
.button { fill: #00D4FF; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Drive - File Management Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Toolbar -->
<rect x="30" y="50" width="840" height="45" rx="8" class="header-bg"/>
<rect x="30" y="87" width="840" height="8" class="bg"/>
<!-- New Button -->
<rect x="50" y="60" width="80" height="28" rx="4" class="button"/>
<text x="90" y="79" text-anchor="middle" font-size="13" class="button-text">+ New ▼</text>
<!-- Search Bar -->
<rect x="300" y="60" width="250" height="28" rx="14" class="input-field"/>
<text x="320" y="79" font-size="13" class="secondary-text">🔍 Search files...</text>
<!-- View Toggle -->
<g transform="translate(750, 60)">
<rect x="0" y="0" width="30" height="28" rx="4" class="input-field"/>
<text x="15" y="19" text-anchor="middle" font-size="14" class="icon-text"></text>
<rect x="35" y="0" width="30" height="28" rx="4" class="input-field"/>
<text x="50" y="19" text-anchor="middle" font-size="14" class="icon-text"></text>
</g>
<!-- Divider -->
<line x1="30" y1="95" x2="870" y2="95" class="divider"/>
<!-- Left Sidebar -->
<rect x="30" y="95" width="140" height="425" class="panel-bg"/>
<line x1="170" y1="95" x2="170" y2="520" class="divider"/>
<!-- Sidebar Items -->
<g transform="translate(45, 110)">
<rect x="-5" y="-5" width="120" height="28" rx="4" class="row-hover"/>
<text x="0" y="14" font-size="14" class="main-text">📁 My Drive</text>
<text x="0" y="50" font-size="14" class="secondary-text">⭐ Starred</text>
<text x="0" y="80" font-size="14" class="secondary-text">🕐 Recent</text>
<text x="0" y="110" font-size="14" class="secondary-text">🗑 Trash</text>
<line x1="-5" y1="130" x2="115" y2="130" class="divider"/>
<text x="0" y="155" font-size="12" font-weight="500" class="secondary-text">Labels</text>
<circle cx="10" cy="175" r="6" class="label-blue"/>
<text x="25" y="180" font-size="13" class="main-text">Work</text>
<circle cx="10" cy="200" r="6" class="label-green"/>
<text x="25" y="205" font-size="13" class="main-text">Personal</text>
</g>
<!-- Breadcrumb -->
<text x="190" y="120" font-size="13" class="secondary-text">📁 My Drive Projects 2024</text>
<!-- Column Headers -->
<g transform="translate(185, 140)">
<rect x="0" y="0" width="680" height="25" class="header-bg"/>
<text x="30" y="17" font-size="12" font-weight="500" class="secondary-text"></text>
<text x="60" y="17" font-size="12" font-weight="500" class="secondary-text">Name</text>
<text x="400" y="17" font-size="12" font-weight="500" class="secondary-text">Size</text>
<text x="520" y="17" font-size="12" font-weight="500" class="secondary-text">Modified</text>
</g>
<!-- File List -->
<g transform="translate(185, 170)">
<!-- Row 1 - Folder -->
<rect x="0" y="0" width="680" height="35" class="row-hover" opacity="0.5"/>
<text x="30" y="23" font-size="14" class="secondary-text"></text>
<text x="55" y="23" font-size="16" class="folder-icon">📁</text>
<text x="80" y="23" font-size="14" class="main-text">Reports</text>
<text x="400" y="23" font-size="13" class="secondary-text"></text>
<text x="520" y="23" font-size="13" class="secondary-text">Today</text>
<!-- Row 2 - Folder -->
<rect x="0" y="40" width="680" height="35" fill="none"/>
<text x="30" y="63" font-size="14" class="secondary-text"></text>
<text x="55" y="63" font-size="16" class="folder-icon">📁</text>
<text x="80" y="63" font-size="14" class="main-text">Presentations</text>
<text x="400" y="63" font-size="13" class="secondary-text"></text>
<text x="520" y="63" font-size="13" class="secondary-text">Yesterday</text>
<!-- Row 3 - Excel File -->
<rect x="0" y="80" width="680" height="35" fill="none"/>
<text x="30" y="103" font-size="14" class="secondary-text"></text>
<text x="55" y="103" font-size="16" class="file-icon">📄</text>
<text x="80" y="103" font-size="14" class="main-text">Budget.xlsx</text>
<text x="400" y="103" font-size="13" class="secondary-text">245 KB</text>
<text x="520" y="103" font-size="13" class="secondary-text">Mar 15</text>
<!-- Row 4 - Doc File -->
<rect x="0" y="120" width="680" height="35" fill="none"/>
<text x="30" y="143" font-size="14" class="secondary-text"></text>
<text x="55" y="143" font-size="16" class="file-icon">📄</text>
<text x="80" y="143" font-size="14" class="main-text">Notes.docx</text>
<text x="400" y="143" font-size="13" class="secondary-text">12 KB</text>
<text x="520" y="143" font-size="13" class="secondary-text">Mar 14</text>
<!-- Row 5 - Image File -->
<rect x="0" y="160" width="680" height="35" fill="none"/>
<text x="30" y="183" font-size="14" class="secondary-text"></text>
<text x="55" y="183" font-size="16" class="image-icon">🖼</text>
<text x="80" y="183" font-size="14" class="main-text">Logo.png</text>
<text x="400" y="183" font-size="13" class="secondary-text">89 KB</text>
<text x="520" y="183" font-size="13" class="secondary-text">Mar 10</text>
</g>
<!-- Drag & Drop Zone -->
<rect x="185" y="380" width="680" height="100" rx="8" fill="none" stroke="#4A90E2" stroke-width="2" stroke-dasharray="8,4"/>
<text x="525" y="425" text-anchor="middle" font-size="16" class="secondary-text">📤 Drag files here to upload</text>
<text x="525" y="450" text-anchor="middle" font-size="13" class="secondary-text">or click + New to create</text>
<!-- Legend -->
<g transform="translate(30, 535)">
<text x="0" y="0" font-size="11" class="secondary-text">Sidebar: Quick access, Labels</text>
<text x="200" y="0" font-size="11" class="secondary-text">Main: File browser with sort columns</text>
<text x="500" y="0" font-size="11" class="secondary-text">Actions: Upload, Create, Search, View toggle</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.3 KiB

View file

@ -0,0 +1,147 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #fafafa; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.unread-dot { fill: #4A90E2; }
.selected-row { fill: #e8f4fd; }
.row-bg { fill: #fff; }
.sidebar-active { fill: #e8f4fd; }
.badge { fill: #4A90E2; }
.action-btn { fill: #f0f0f0; stroke: #ccc; stroke-width: 1; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.panel-bg { fill: #222; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.unread-dot { fill: #00D4FF; }
.selected-row { fill: #2a3a4a; }
.row-bg { fill: #222; }
.sidebar-active { fill: #2a3a4a; }
.badge { fill: #00D4FF; }
.button { fill: #00D4FF; }
.action-btn { fill: #333; stroke: #555; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Mail - Email Client Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Left Sidebar -->
<rect x="30" y="50" width="130" height="470" rx="8" class="panel-bg"/>
<rect x="152" y="50" width="8" height="470" class="bg"/>
<!-- Compose Button -->
<rect x="45" y="65" width="100" height="35" rx="6" class="button"/>
<text x="95" y="88" text-anchor="middle" font-size="13" class="button-text">✏ Compose</text>
<!-- Sidebar Items -->
<g transform="translate(45, 120)">
<!-- Inbox - Active -->
<rect x="-5" y="-5" width="110" height="30" rx="4" class="sidebar-active"/>
<text x="0" y="14" font-size="14" class="main-text">📥 Inbox</text>
<rect x="75" y="2" width="22" height="16" rx="8" class="badge"/>
<text x="86" y="14" text-anchor="middle" font-size="11" fill="#fff">3</text>
<text x="0" y="50" font-size="14" class="secondary-text">📤 Sent</text>
<text x="0" y="80" font-size="14" class="secondary-text">📝 Drafts</text>
<text x="0" y="110" font-size="14" class="secondary-text">🗑 Trash</text>
</g>
<!-- Middle Panel - Email List -->
<rect x="160" y="50" width="220" height="470" class="panel-bg"/>
<line x1="380" y1="50" x2="380" y2="520" class="divider"/>
<!-- List Header -->
<rect x="160" y="50" width="220" height="35" class="header-bg"/>
<text x="175" y="73" font-size="14" font-weight="500" class="main-text">Inbox</text>
<!-- Email List Items -->
<g transform="translate(160, 90)">
<!-- Email 1 - Unread, Selected -->
<rect x="0" y="0" width="220" height="70" class="selected-row"/>
<circle cx="20" cy="20" r="5" class="unread-dot"/>
<text x="35" y="20" font-size="13" font-weight="600" class="main-text">Project Update</text>
<text x="35" y="38" font-size="12" class="secondary-text">from John</text>
<text x="175" y="20" font-size="11" class="secondary-text">10:30 AM</text>
<line x1="0" y1="70" x2="220" y2="70" class="divider"/>
<!-- Email 2 - Read -->
<rect x="0" y="70" width="220" height="70" class="row-bg"/>
<circle cx="20" cy="90" r="5" fill="none" stroke="#ccc"/>
<text x="35" y="90" font-size="13" class="main-text">Meeting Notes</text>
<text x="35" y="108" font-size="12" class="secondary-text">from Sarah</text>
<text x="175" y="90" font-size="11" class="secondary-text">Yesterday</text>
<line x1="0" y1="140" x2="220" y2="140" class="divider"/>
<!-- Email 3 - Read -->
<rect x="0" y="140" width="220" height="70" class="row-bg"/>
<circle cx="20" cy="160" r="5" fill="none" stroke="#ccc"/>
<text x="35" y="160" font-size="13" class="main-text">Invoice #1234</text>
<text x="35" y="178" font-size="12" class="secondary-text">from Vendor</text>
<text x="175" y="160" font-size="11" class="secondary-text">Mar 15</text>
<line x1="0" y1="210" x2="220" y2="210" class="divider"/>
</g>
<!-- Right Panel - Email Content -->
<rect x="380" y="50" width="490" height="470" rx="8" class="bg"/>
<!-- Email Header -->
<g transform="translate(400, 70)">
<text x="0" y="0" font-size="12" class="secondary-text">From:</text>
<text x="45" y="0" font-size="12" class="main-text">john@company.com</text>
<text x="0" y="25" font-size="12" class="secondary-text">Subject:</text>
<text x="55" y="25" font-size="14" font-weight="600" class="main-text">Project Update</text>
</g>
<!-- Divider -->
<line x1="400" y1="115" x2="850" y2="115" class="divider"/>
<!-- Email Body -->
<g transform="translate(400, 135)">
<text x="0" y="0" font-size="14" class="main-text">Hi,</text>
<text x="0" y="30" font-size="14" class="main-text">Here's the latest update on our project.</text>
<text x="0" y="55" font-size="14" class="main-text">We've completed the first milestone and</text>
<text x="0" y="80" font-size="14" class="main-text">are now moving to phase two.</text>
<text x="0" y="130" font-size="14" class="main-text">Best,</text>
<text x="0" y="155" font-size="14" class="main-text">John</text>
</g>
<!-- Action Buttons -->
<g transform="translate(400, 460)">
<rect x="0" y="0" width="80" height="35" rx="6" class="button"/>
<text x="40" y="23" text-anchor="middle" font-size="13" class="button-text">Reply</text>
<rect x="90" y="0" width="90" height="35" rx="6" class="action-btn"/>
<text x="135" y="23" text-anchor="middle" font-size="13" class="main-text">Forward</text>
<rect x="190" y="0" width="80" height="35" rx="6" class="action-btn"/>
<text x="230" y="23" text-anchor="middle" font-size="13" class="main-text">Delete</text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<text x="0" y="0" font-size="11" class="secondary-text">Sidebar: Folders</text>
<text x="150" y="0" font-size="11" class="secondary-text">List: Email threads</text>
<text x="320" y="0" font-size="11" class="secondary-text">Content: Read and reply</text>
<text x="550" y="0" font-size="11" class="secondary-text">Shortcuts: C = Compose | R = Reply | F = Forward</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -0,0 +1,139 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #1a1a1a; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #252525; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; font-family: Arial, sans-serif; }
.secondary-text { fill: #aaa; font-family: Arial, sans-serif; }
.icon-text { fill: #ddd; font-family: Arial, sans-serif; }
.divider { stroke: #444; stroke-width: 1; }
.video-frame { fill: #333; stroke: #444; stroke-width: 2; }
.avatar-bg { fill: #4A90E2; }
.control-btn { fill: #444; stroke: #555; stroke-width: 1; }
.control-btn-active { fill: #4A90E2; }
.control-btn-danger { fill: #E74C3C; }
.control-text { fill: #fff; font-family: Arial, sans-serif; }
.timer { fill: #7ED321; font-family: monospace; }
.participant-count { fill: #4A90E2; }
.chat-icon { fill: #fff; }
@media (prefers-color-scheme: light) {
.bg { fill: #2a2a2a; }
.frame { stroke: #444; }
.panel-bg { fill: #333; }
.header-bg { fill: #3a3a3a; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Meet - Video Calls Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Header Bar -->
<rect x="30" y="50" width="840" height="45" rx="8" class="header-bg"/>
<rect x="30" y="87" width="840" height="8" class="bg"/>
<!-- Meeting Title -->
<text x="55" y="78" font-size="16" font-weight="500" class="main-text">Meeting Room</text>
<!-- Timer -->
<text x="450" y="78" text-anchor="middle" font-size="16" class="timer">00:15:32</text>
<!-- Header Right Controls -->
<g transform="translate(720, 58)">
<!-- Participants -->
<rect x="0" y="0" width="45" height="30" rx="4" class="control-btn"/>
<text x="15" y="20" font-size="14" class="control-text">👥</text>
<text x="35" y="20" font-size="12" class="participant-count">3</text>
<!-- Chat -->
<rect x="55" y="0" width="35" height="30" rx="4" class="control-btn"/>
<text x="72" y="20" text-anchor="middle" font-size="14" class="chat-icon">💬</text>
</g>
<!-- Divider -->
<line x1="30" y1="95" x2="870" y2="95" class="divider"/>
<!-- Video Grid Area -->
<g transform="translate(50, 110)">
<!-- Main Participant 1 (You) -->
<rect x="0" y="0" width="380" height="220" rx="8" class="video-frame"/>
<circle cx="190" cy="90" r="45" class="avatar-bg"/>
<text x="190" y="100" text-anchor="middle" font-size="32" class="main-text">👤</text>
<text x="190" y="150" text-anchor="middle" font-size="16" class="main-text">You</text>
<text x="190" y="175" text-anchor="middle" font-size="13" class="secondary-text">(Camera)</text>
<!-- Name label -->
<rect x="10" y="190" width="60" height="22" rx="4" fill="#000" opacity="0.6"/>
<text x="40" y="206" text-anchor="middle" font-size="12" class="main-text">You</text>
<!-- Mute indicator -->
<circle cx="355" cy="195" r="12" fill="#E74C3C"/>
<text x="355" y="200" text-anchor="middle" font-size="10" class="main-text">🎤</text>
<!-- Main Participant 2 (John) -->
<rect x="400" y="0" width="380" height="220" rx="8" class="video-frame"/>
<circle cx="590" cy="90" r="45" class="avatar-bg"/>
<text x="590" y="100" text-anchor="middle" font-size="32" class="main-text">👤</text>
<text x="590" y="150" text-anchor="middle" font-size="16" class="main-text">John</text>
<text x="590" y="175" text-anchor="middle" font-size="13" class="secondary-text">(Camera)</text>
<!-- Name label -->
<rect x="410" y="190" width="60" height="22" rx="4" fill="#000" opacity="0.6"/>
<text x="440" y="206" text-anchor="middle" font-size="12" class="main-text">John</text>
<!-- Participant 3 (Sarah) - Smaller -->
<rect x="0" y="235" width="250" height="145" rx="8" class="video-frame"/>
<circle cx="125" cy="290" r="35" class="avatar-bg"/>
<text x="125" y="298" text-anchor="middle" font-size="26" class="main-text">👤</text>
<text x="125" y="340" text-anchor="middle" font-size="14" class="main-text">Sarah</text>
<!-- Name label -->
<rect x="10" y="355" width="55" height="20" rx="4" fill="#000" opacity="0.6"/>
<text x="37" y="369" text-anchor="middle" font-size="11" class="main-text">Sarah</text>
</g>
<!-- Control Bar -->
<rect x="30" y="470" width="840" height="50" rx="8" class="header-bg"/>
<rect x="30" y="470" width="840" height="8" class="bg"/>
<!-- Control Buttons -->
<g transform="translate(200, 480)">
<!-- Mute Button -->
<rect x="0" y="0" width="55" height="38" rx="6" class="control-btn-danger"/>
<text x="27" y="25" text-anchor="middle" font-size="18" class="control-text">🎤</text>
<!-- Video Button -->
<rect x="70" y="0" width="55" height="38" rx="6" class="control-btn-active"/>
<text x="97" y="25" text-anchor="middle" font-size="18" class="control-text">📹</text>
<!-- Share Screen Button -->
<rect x="140" y="0" width="55" height="38" rx="6" class="control-btn"/>
<text x="167" y="25" text-anchor="middle" font-size="18" class="control-text">🖥</text>
<!-- Record Button -->
<rect x="210" y="0" width="55" height="38" rx="6" class="control-btn"/>
<text x="237" y="25" text-anchor="middle" font-size="18" class="control-text">🔴</text>
<!-- Transcribe Button -->
<rect x="280" y="0" width="55" height="38" rx="6" class="control-btn"/>
<text x="307" y="25" text-anchor="middle" font-size="18" class="control-text">📝</text>
<!-- End Call Button -->
<rect x="365" y="0" width="70" height="38" rx="6" class="control-btn-danger"/>
<text x="400" y="25" text-anchor="middle" font-size="18" class="control-text">📞</text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<rect x="0" y="-10" width="20" height="14" rx="3" class="control-btn-active"/>
<text x="28" y="0" font-size="11" class="secondary-text">Active</text>
<rect x="80" y="-10" width="20" height="14" rx="3" class="control-btn-danger"/>
<text x="108" y="0" font-size="11" class="secondary-text">Muted/End</text>
<rect x="180" y="-10" width="20" height="14" rx="3" class="control-btn"/>
<text x="208" y="0" font-size="11" class="secondary-text">Available</text>
<text x="350" y="0" font-size="11" class="secondary-text">Shortcuts: M = Mute | V = Video | S = Share | Space = Push-to-talk</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

View file

@ -0,0 +1,179 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #fafafa; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.toolbar-bg { fill: #f0f0f0; }
.toolbar-btn { fill: #fff; stroke: #ccc; stroke-width: 1; }
.toolbar-btn-active { fill: #e0e0e0; stroke: #999; stroke-width: 1; }
.ai-btn { fill: #BD10E0; }
.ai-text { fill: #fff; font-family: Arial, sans-serif; }
.sidebar-item { fill: none; }
.sidebar-active { fill: #e8f4fd; }
.cursor { stroke: #4A90E2; stroke-width: 2; }
.doc-content { fill: #fff; stroke: #ddd; stroke-width: 1; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.panel-bg { fill: #222; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.toolbar-bg { fill: #333; }
.toolbar-btn { fill: #2a2a2a; stroke: #444; }
.toolbar-btn-active { fill: #444; stroke: #555; }
.sidebar-active { fill: #2a3a4a; }
.doc-content { fill: #2a2a2a; stroke: #444; }
.button { fill: #00D4FF; }
.ai-btn { fill: #E040FB; }
.cursor { stroke: #00D4FF; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Paper - AI Writing Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Left Sidebar - Document List -->
<rect x="30" y="50" width="140" height="470" rx="8" class="panel-bg"/>
<line x1="170" y1="50" x2="170" y2="520" class="divider"/>
<!-- Sidebar Header -->
<text x="50" y="78" font-size="14" font-weight="500" class="main-text">📄 Notes</text>
<line x1="40" y1="90" x2="160" y2="90" class="divider"/>
<!-- Document List -->
<g transform="translate(40, 100)">
<!-- Active Document -->
<rect x="-5" y="0" width="125" height="30" rx="4" class="sidebar-active"/>
<text x="0" y="20" font-size="13" class="main-text">Meeting Notes</text>
<text x="0" y="50" font-size="13" class="secondary-text">Project Plan</text>
<text x="0" y="80" font-size="13" class="secondary-text">Ideas</text>
<line x1="-5" y1="100" x2="115" y2="100" class="divider"/>
<text x="0" y="125" font-size="12" font-weight="500" class="secondary-text">Quick Start</text>
<text x="0" y="150" font-size="12" class="secondary-text">📄 Blank</text>
<text x="0" y="175" font-size="12" class="secondary-text">📋 Meeting</text>
<text x="0" y="200" font-size="12" class="secondary-text">✓ To-Do</text>
<text x="0" y="225" font-size="12" class="secondary-text">🔬 Research</text>
</g>
<!-- Main Editor Area -->
<rect x="170" y="50" width="700" height="470" class="bg"/>
<!-- Toolbar -->
<rect x="170" y="50" width="700" height="45" class="toolbar-bg"/>
<line x1="170" y1="95" x2="870" y2="95" class="divider"/>
<!-- Formatting Buttons -->
<g transform="translate(185, 58)">
<!-- Bold -->
<rect x="0" y="0" width="30" height="28" rx="4" class="toolbar-btn"/>
<text x="15" y="20" text-anchor="middle" font-size="14" font-weight="bold" class="icon-text">B</text>
<!-- Italic -->
<rect x="35" y="0" width="30" height="28" rx="4" class="toolbar-btn"/>
<text x="50" y="20" text-anchor="middle" font-size="14" font-style="italic" class="icon-text">I</text>
<!-- Underline -->
<rect x="70" y="0" width="30" height="28" rx="4" class="toolbar-btn"/>
<text x="85" y="20" text-anchor="middle" font-size="14" class="icon-text" text-decoration="underline">U</text>
<!-- Separator -->
<line x1="110" y1="5" x2="110" y2="25" class="divider"/>
<!-- H1 -->
<rect x="120" y="0" width="30" height="28" rx="4" class="toolbar-btn-active"/>
<text x="135" y="20" text-anchor="middle" font-size="12" font-weight="bold" class="icon-text">H1</text>
<!-- H2 -->
<rect x="155" y="0" width="30" height="28" rx="4" class="toolbar-btn"/>
<text x="170" y="20" text-anchor="middle" font-size="12" class="icon-text">H2</text>
<!-- Separator -->
<line x1="195" y1="5" x2="195" y2="25" class="divider"/>
<!-- Bullet List -->
<rect x="205" y="0" width="30" height="28" rx="4" class="toolbar-btn"/>
<text x="220" y="20" text-anchor="middle" font-size="14" class="icon-text"></text>
<!-- Horizontal Rule -->
<rect x="240" y="0" width="30" height="28" rx="4" class="toolbar-btn"/>
<text x="255" y="20" text-anchor="middle" font-size="14" class="icon-text"></text>
<!-- Link -->
<rect x="275" y="0" width="30" height="28" rx="4" class="toolbar-btn"/>
<text x="290" y="20" text-anchor="middle" font-size="14" class="icon-text">🔗</text>
<!-- Image -->
<rect x="310" y="0" width="30" height="28" rx="4" class="toolbar-btn"/>
<text x="325" y="20" text-anchor="middle" font-size="14" class="icon-text">📷</text>
<!-- AI Button -->
<rect x="360" y="0" width="70" height="28" rx="4" class="ai-btn"/>
<text x="395" y="19" text-anchor="middle" font-size="12" class="ai-text">AI ✨</text>
</g>
<!-- Document Content Area -->
<rect x="190" y="110" width="660" height="395" rx="4" class="doc-content"/>
<!-- Document Content -->
<g transform="translate(210, 135)">
<!-- Title -->
<text x="0" y="0" font-size="24" font-weight="bold" class="main-text">Project Proposal</text>
<line x1="0" y1="10" x2="200" y2="10" stroke="#4A90E2" stroke-width="3"/>
<!-- Section -->
<text x="0" y="55" font-size="18" font-weight="600" class="main-text">Introduction</text>
<line x1="0" y1="65" x2="100" y2="65" class="divider"/>
<!-- Body text -->
<text x="0" y="95" font-size="14" class="main-text">This document outlines our proposal for</text>
<text x="0" y="118" font-size="14" class="main-text">the upcoming project. We aim to deliver</text>
<text x="0" y="141" font-size="14" class="main-text">a comprehensive solution that addresses</text>
<text x="0" y="164" font-size="14" class="main-text">all stakeholder requirements.</text>
<!-- Cursor -->
<line x1="248" y1="150" x2="248" y2="170" class="cursor"/>
<!-- More content preview -->
<text x="0" y="210" font-size="18" font-weight="600" class="secondary-text">Key Objectives</text>
<text x="0" y="240" font-size="14" class="secondary-text">• Improve efficiency by 30%</text>
<text x="0" y="263" font-size="14" class="secondary-text">• Reduce costs through automation</text>
<text x="0" y="286" font-size="14" class="secondary-text">• Enhance user experience</text>
</g>
<!-- Word Count / Status Bar -->
<g transform="translate(190, 490)">
<text x="0" y="0" font-size="11" class="secondary-text">Words: 156</text>
<text x="100" y="0" font-size="11" class="secondary-text">Characters: 892</text>
<text x="250" y="0" font-size="11" class="secondary-text">Reading time: 1 min</text>
<text x="480" y="0" font-size="11" class="secondary-text">✓ Auto-saved 2 min ago</text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<rect x="0" y="-10" width="20" height="14" rx="3" class="ai-btn"/>
<text x="28" y="0" font-size="11" class="secondary-text">AI Assist</text>
<text x="100" y="0" font-size="11" class="secondary-text">Shortcuts: Ctrl+B = Bold | Ctrl+I = Italic | Ctrl+S = Save | Ctrl+/ = AI</text>
<text x="550" y="0" font-size="11" class="secondary-text">Markdown supported</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

@ -0,0 +1,168 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #fafafa; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.search-box { fill: #fff; stroke: #4A90E2; stroke-width: 2; }
.filter-active { fill: #4A90E2; }
.filter-inactive { fill: #e0e0e0; }
.result-card { fill: #fff; stroke: #ddd; stroke-width: 1; }
.source-link { fill: #4A90E2; font-family: Arial, sans-serif; }
.sidebar-item { fill: none; }
.sidebar-active { fill: #e8f4fd; }
.collection-icon { fill: #F5A623; }
.ai-highlight { fill: #f0e6ff; stroke: #BD10E0; stroke-width: 1; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.panel-bg { fill: #222; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.search-box { fill: #2a2a2a; stroke: #00D4FF; }
.filter-inactive { fill: #333; }
.result-card { fill: #2a2a2a; stroke: #444; }
.source-link { fill: #00D4FF; }
.sidebar-active { fill: #2a3a4a; }
.button { fill: #00D4FF; }
.filter-active { fill: #00D4FF; }
.ai-highlight { fill: #2a2040; stroke: #E040FB; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Research - AI Search Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Left Sidebar -->
<rect x="30" y="50" width="140" height="470" rx="8" class="panel-bg"/>
<line x1="170" y1="50" x2="170" y2="520" class="divider"/>
<!-- Sidebar Header -->
<text x="50" y="78" font-size="14" font-weight="500" class="main-text">🔍 Research</text>
<line x1="40" y1="90" x2="160" y2="90" class="divider"/>
<!-- Focus Filters -->
<g transform="translate(40, 105)">
<text x="0" y="0" font-size="12" font-weight="500" class="secondary-text">Focus:</text>
<!-- All - Active -->
<rect x="-5" y="10" width="115" height="26" rx="4" class="sidebar-active"/>
<text x="5" y="28" font-size="13" class="main-text">🌐 All</text>
<text x="5" y="58" font-size="13" class="secondary-text">📚 Academic</text>
<text x="5" y="83" font-size="13" class="secondary-text">💻 Code</text>
<text x="5" y="108" font-size="13" class="secondary-text">🏠 Internal</text>
<line x1="-5" y1="125" x2="115" y2="125" class="divider"/>
<!-- Collections -->
<text x="0" y="145" font-size="12" font-weight="500" class="secondary-text">Collections:</text>
<text x="5" y="170" font-size="13" class="collection-icon">📁</text>
<text x="25" y="170" font-size="13" class="main-text">Project A</text>
<text x="5" y="195" font-size="13" class="collection-icon">📁</text>
<text x="25" y="195" font-size="13" class="main-text">References</text>
<line x1="-5" y1="215" x2="115" y2="215" class="divider"/>
<!-- Recent Searches -->
<text x="0" y="235" font-size="12" font-weight="500" class="secondary-text">Recent:</text>
<text x="5" y="258" font-size="12" class="secondary-text">• market size</text>
<text x="5" y="278" font-size="12" class="secondary-text">• competitors</text>
<text x="5" y="298" font-size="12" class="secondary-text">• best practices</text>
</g>
<!-- Main Content Area -->
<rect x="170" y="50" width="700" height="470" class="bg"/>
<!-- Search Box -->
<g transform="translate(190, 70)">
<rect x="0" y="0" width="640" height="50" rx="25" class="search-box"/>
<text x="25" y="32" font-size="16" class="secondary-text">What are the best practices for...</text>
<circle cx="610" cy="25" r="18" class="button"/>
<text x="610" y="31" text-anchor="middle" font-size="16" fill="#fff"></text>
</g>
<!-- AI Answer Section -->
<g transform="translate(190, 140)">
<rect x="0" y="0" width="640" height="180" rx="8" class="ai-highlight"/>
<!-- Header -->
<text x="20" y="30" font-size="16" font-weight="600" class="main-text">AI Answer:</text>
<line x1="20" y1="42" x2="100" y2="42" stroke="#BD10E0" stroke-width="2"/>
<!-- Answer Content -->
<text x="20" y="70" font-size="14" class="main-text">Based on multiple sources, here are the key best practices:</text>
<text x="20" y="100" font-size="14" class="main-text">1. Start with clear requirements and objectives</text>
<text x="20" y="122" font-size="14" class="main-text">2. Use iterative development with frequent feedback</text>
<text x="20" y="144" font-size="14" class="main-text">3. Test early and often with real users</text>
<text x="20" y="166" font-size="14" class="main-text">4. Document decisions and maintain knowledge base</text>
</g>
<!-- Sources Section -->
<g transform="translate(190, 335)">
<text x="0" y="0" font-size="14" font-weight="600" class="main-text">Sources:</text>
<!-- Source Cards -->
<rect x="0" y="15" width="200" height="70" rx="6" class="result-card"/>
<text x="10" y="35" font-size="11" class="secondary-text">[1]</text>
<text x="30" y="35" font-size="12" class="source-link">industry-guide.com</text>
<text x="10" y="55" font-size="11" class="secondary-text">Best practices for software</text>
<text x="10" y="70" font-size="11" class="secondary-text">development in 2024...</text>
<rect x="215" y="15" width="200" height="70" rx="6" class="result-card"/>
<text x="225" y="35" font-size="11" class="secondary-text">[2]</text>
<text x="245" y="35" font-size="12" class="source-link">techblog.dev</text>
<text x="225" y="55" font-size="11" class="secondary-text">Modern development</text>
<text x="225" y="70" font-size="11" class="secondary-text">methodology overview...</text>
<rect x="430" y="15" width="200" height="70" rx="6" class="result-card"/>
<text x="440" y="35" font-size="11" class="secondary-text">[3]</text>
<text x="460" y="35" font-size="12" class="source-link">your-docs/guidelines.pdf</text>
<text x="440" y="55" font-size="11" class="secondary-text">📄 Internal document</text>
<text x="440" y="70" font-size="11" class="secondary-text">Company guidelines...</text>
</g>
<!-- Action Buttons -->
<g transform="translate(190, 430)">
<rect x="0" y="0" width="100" height="32" rx="6" class="button"/>
<text x="50" y="21" text-anchor="middle" font-size="12" class="button-text">📁 Save</text>
<rect x="110" y="0" width="100" height="32" rx="6" class="input-field"/>
<text x="160" y="21" text-anchor="middle" font-size="12" class="main-text">📤 Share</text>
<rect x="220" y="0" width="120" height="32" rx="6" class="input-field"/>
<text x="280" y="21" text-anchor="middle" font-size="12" class="main-text">🔄 Deep Dive</text>
<rect x="350" y="0" width="100" height="32" rx="6" class="input-field"/>
<text x="400" y="21" text-anchor="middle" font-size="12" class="main-text">📋 Copy</text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<rect x="0" y="-10" width="20" height="14" rx="3" class="ai-highlight"/>
<text x="28" y="0" font-size="11" class="secondary-text">AI Summary</text>
<rect x="100" y="-10" width="20" height="14" rx="3" class="result-card"/>
<text x="128" y="0" font-size="11" class="secondary-text">Sources</text>
<text x="220" y="0" font-size="11" class="secondary-text">Focus: Web • Academic • Code • Internal docs</text>
<text x="550" y="0" font-size="11" class="secondary-text">Enter = Search | Ctrl+S = Save</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8 KiB

View file

@ -0,0 +1,206 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.panel-bg { fill: #fafafa; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.tab-active { fill: #4A90E2; }
.tab-inactive { fill: #e0e0e0; }
.card { fill: #fff; stroke: #ddd; stroke-width: 1; }
.card-featured { fill: #fff; stroke: #4A90E2; stroke-width: 2; }
.sidebar-active { fill: #e8f4fd; }
.category-icon { fill: #666; }
.star-icon { fill: #F5A623; }
.tag { fill: #e8f4fd; stroke: #4A90E2; stroke-width: 1; }
.tag-text { fill: #4A90E2; font-family: Arial, sans-serif; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.panel-bg { fill: #222; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.tab-inactive { fill: #333; }
.card { fill: #2a2a2a; stroke: #444; }
.card-featured { fill: #2a2a2a; stroke: #00D4FF; }
.sidebar-active { fill: #2a3a4a; }
.button { fill: #00D4FF; }
.tab-active { fill: #00D4FF; }
.tag { fill: #1a2a3a; stroke: #00D4FF; }
.tag-text { fill: #00D4FF; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Sources - Prompts &amp; Templates Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Header -->
<rect x="30" y="50" width="840" height="50" rx="8" class="header-bg"/>
<rect x="30" y="92" width="840" height="8" class="bg"/>
<!-- Title -->
<text x="55" y="82" font-size="16" font-weight="600" class="main-text">Sources</text>
<!-- Search Bar -->
<g transform="translate(580, 60)">
<rect x="0" y="0" width="200" height="32" rx="16" class="input-field"/>
<text x="20" y="21" font-size="13" class="secondary-text">🔍 Search...</text>
</g>
<!-- Divider -->
<line x1="30" y1="100" x2="870" y2="100" class="divider"/>
<!-- Tabs -->
<g transform="translate(50, 110)">
<rect x="0" y="0" width="90" height="32" rx="4" class="tab-active"/>
<text x="45" y="21" text-anchor="middle" font-size="12" fill="#fff">Prompts</text>
<rect x="100" y="0" width="95" height="32" rx="4" class="tab-inactive"/>
<text x="147" y="21" text-anchor="middle" font-size="12" class="main-text">Templates</text>
<rect x="205" y="0" width="105" height="32" rx="4" class="tab-inactive"/>
<text x="257" y="21" text-anchor="middle" font-size="12" class="main-text">MCP Servers</text>
<rect x="320" y="0" width="95" height="32" rx="4" class="tab-inactive"/>
<text x="367" y="21" text-anchor="middle" font-size="12" class="main-text">LLM Tools</text>
<rect x="425" y="0" width="80" height="32" rx="4" class="tab-inactive"/>
<text x="465" y="21" text-anchor="middle" font-size="12" class="main-text">Models</text>
</g>
<!-- Divider -->
<line x1="50" y1="155" x2="850" y2="155" class="divider"/>
<!-- Left Sidebar - Categories -->
<rect x="30" y="155" width="130" height="365" class="panel-bg"/>
<line x1="160" y1="155" x2="160" y2="520" class="divider"/>
<!-- Categories -->
<g transform="translate(40, 170)">
<text x="0" y="0" font-size="12" font-weight="500" class="secondary-text">Categories</text>
<line x1="0" y1="10" x2="110" y2="10" class="divider"/>
<!-- Category Items -->
<rect x="-5" y="20" width="115" height="28" rx="4" class="sidebar-active"/>
<text x="5" y="39" font-size="13" class="main-text">📝 Writing</text>
<text x="5" y="70" font-size="13" class="secondary-text">📊 Analysis</text>
<text x="5" y="98" font-size="13" class="secondary-text">💼 Business</text>
<text x="5" y="126" font-size="13" class="secondary-text">💻 Code</text>
<text x="5" y="154" font-size="13" class="secondary-text">🎨 Creative</text>
<text x="5" y="182" font-size="13" class="secondary-text">🤖 Automation</text>
<text x="5" y="210" font-size="13" class="secondary-text">📞 Support</text>
</g>
<!-- Main Content Area -->
<g transform="translate(175, 170)">
<!-- Featured Section -->
<text x="0" y="0" font-size="14" font-weight="500" class="main-text">⭐ Featured</text>
<!-- Card 1: Customer Service -->
<rect x="0" y="20" width="210" height="150" rx="8" class="card-featured"/>
<text x="15" y="50" font-size="15" font-weight="500" class="main-text">Customer</text>
<text x="15" y="70" font-size="15" font-weight="500" class="main-text">Service</text>
<line x1="15" y1="80" x2="195" y2="80" class="divider"/>
<text x="15" y="100" font-size="12" class="secondary-text">Handle support</text>
<text x="15" y="118" font-size="12" class="secondary-text">inquiries with AI</text>
<text x="15" y="136" font-size="12" class="secondary-text">assistance</text>
<!-- Use Button -->
<rect x="15" y="145" width="60" height="24" rx="4" class="button"/>
<text x="45" y="162" text-anchor="middle" font-size="11" class="button-text">Use</text>
<!-- Star -->
<text x="180" y="50" font-size="14" class="star-icon"></text>
<!-- Card 2: Sales Assistant -->
<rect x="225" y="20" width="210" height="150" rx="8" class="card-featured"/>
<text x="240" y="50" font-size="15" font-weight="500" class="main-text">Sales</text>
<text x="240" y="70" font-size="15" font-weight="500" class="main-text">Assistant</text>
<line x1="240" y1="80" x2="420" y2="80" class="divider"/>
<text x="240" y="100" font-size="12" class="secondary-text">Qualify leads and</text>
<text x="240" y="118" font-size="12" class="secondary-text">schedule meetings</text>
<text x="240" y="136" font-size="12" class="secondary-text">automatically</text>
<!-- Use Button -->
<rect x="240" y="145" width="60" height="24" rx="4" class="button"/>
<text x="270" y="162" text-anchor="middle" font-size="11" class="button-text">Use</text>
<!-- Star -->
<text x="405" y="50" font-size="14" class="star-icon"></text>
<!-- Card 3: Code Helper -->
<rect x="450" y="20" width="210" height="150" rx="8" class="card"/>
<text x="465" y="50" font-size="15" font-weight="500" class="main-text">Code</text>
<text x="465" y="70" font-size="15" font-weight="500" class="main-text">Helper</text>
<line x1="465" y1="80" x2="645" y2="80" class="divider"/>
<text x="465" y="100" font-size="12" class="secondary-text">Generate and</text>
<text x="465" y="118" font-size="12" class="secondary-text">explain code</text>
<text x="465" y="136" font-size="12" class="secondary-text">snippets</text>
<!-- Use Button -->
<rect x="465" y="145" width="60" height="24" rx="4" class="button"/>
<text x="495" y="162" text-anchor="middle" font-size="11" class="button-text">Use</text>
<!-- More Templates Section -->
<text x="0" y="200" font-size="14" font-weight="500" class="main-text">All Prompts</text>
<!-- Smaller Cards Row -->
<rect x="0" y="220" width="155" height="100" rx="6" class="card"/>
<text x="15" y="245" font-size="13" font-weight="500" class="main-text">Meeting Notes</text>
<text x="15" y="265" font-size="11" class="secondary-text">Summarize meetings</text>
<rect x="15" y="280" width="50" height="22" rx="3" class="tag"/>
<text x="40" y="295" text-anchor="middle" font-size="10" class="tag-text">Writing</text>
<rect x="105" y="280" width="40" height="22" rx="4" class="button"/>
<text x="125" y="295" text-anchor="middle" font-size="10" class="button-text">Use</text>
<rect x="165" y="220" width="155" height="100" rx="6" class="card"/>
<text x="180" y="245" font-size="13" font-weight="500" class="main-text">Data Analyst</text>
<text x="180" y="265" font-size="11" class="secondary-text">Analyze datasets</text>
<rect x="180" y="280" width="55" height="22" rx="3" class="tag"/>
<text x="207" y="295" text-anchor="middle" font-size="10" class="tag-text">Analysis</text>
<rect x="270" y="280" width="40" height="22" rx="4" class="button"/>
<text x="290" y="295" text-anchor="middle" font-size="10" class="button-text">Use</text>
<rect x="330" y="220" width="155" height="100" rx="6" class="card"/>
<text x="345" y="245" font-size="13" font-weight="500" class="main-text">Email Writer</text>
<text x="345" y="265" font-size="11" class="secondary-text">Draft pro emails</text>
<rect x="345" y="280" width="55" height="22" rx="3" class="tag"/>
<text x="372" y="295" text-anchor="middle" font-size="10" class="tag-text">Business</text>
<rect x="435" y="280" width="40" height="22" rx="4" class="button"/>
<text x="455" y="295" text-anchor="middle" font-size="10" class="button-text">Use</text>
<rect x="495" y="220" width="155" height="100" rx="6" class="card"/>
<text x="510" y="245" font-size="13" font-weight="500" class="main-text">Story Writer</text>
<text x="510" y="265" font-size="11" class="secondary-text">Creative stories</text>
<rect x="510" y="280" width="55" height="22" rx="3" class="tag"/>
<text x="537" y="295" text-anchor="middle" font-size="10" class="tag-text">Creative</text>
<rect x="600" y="280" width="40" height="22" rx="4" class="button"/>
<text x="620" y="295" text-anchor="middle" font-size="10" class="button-text">Use</text>
</g>
<!-- Pagination -->
<g transform="translate(400, 500)">
<text x="0" y="0" font-size="12" class="secondary-text">Page 1 of 5</text>
<rect x="80" y="-15" width="30" height="22" rx="4" class="input-field"/>
<text x="95" y="2" text-anchor="middle" font-size="12" class="main-text"></text>
<rect x="115" y="-15" width="30" height="22" rx="4" class="input-field"/>
<text x="130" y="2" text-anchor="middle" font-size="12" class="main-text"></text>
</g>
<!-- Legend -->
<g transform="translate(30, 535)">
<text x="0" y="0" font-size="11" class="secondary-text">Tabs: Prompts, Templates, MCP Servers, LLM Tools, Models</text>
<text x="350" y="0" font-size="11" class="secondary-text">Categories filter content</text>
<text x="550" y="0" font-size="11" class="secondary-text">Click Use to apply prompt/template</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,82 @@
<svg width="800" height="500" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.header-bg { fill: #e0e0e0; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ccc; stroke-width: 1; }
.button { fill: #fff; stroke: #999; stroke-width: 1; rx: 4; }
.input-field { fill: #fff; stroke: #bbb; stroke-width: 1; }
.accent { fill: #4A90E2; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.button { fill: #333; stroke: #555; }
.input-field { fill: #2a2a2a; stroke: #444; }
.accent { fill: #00D4FF; }
}
</style>
<!-- Title -->
<text x="400" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Suite - Main Layout</text>
<!-- Main Frame -->
<rect x="50" y="50" width="700" height="420" rx="8" class="frame bg"/>
<!-- Header Bar -->
<rect x="50" y="50" width="700" height="50" rx="8" class="header-bg"/>
<rect x="50" y="92" width="700" height="8" class="bg"/>
<!-- Logo/Brand -->
<circle cx="85" cy="75" r="15" class="accent"/>
<text x="85" y="80" text-anchor="middle" font-size="14" fill="#fff">🤖</text>
<text x="115" y="80" font-size="16" font-weight="600" class="main-text">General Bots</text>
<!-- Header Right Controls -->
<g transform="translate(620, 60)">
<!-- Apps Menu -->
<rect x="0" y="0" width="35" height="30" rx="4" class="button"/>
<text x="17" y="20" text-anchor="middle" font-size="12" class="icon-text">⋮⋮⋮</text>
<!-- Theme Toggle -->
<rect x="45" y="0" width="35" height="30" rx="4" class="button"/>
<text x="62" y="20" text-anchor="middle" font-size="14" class="icon-text">🌙</text>
<!-- User Avatar -->
<circle cx="110" cy="15" r="15" class="accent"/>
<text x="110" y="20" text-anchor="middle" font-size="12" fill="#fff">U</text>
</g>
<!-- Divider -->
<line x1="50" y1="100" x2="750" y2="100" class="divider"/>
<!-- Main Chat Area -->
<rect x="70" y="120" width="660" height="280" rx="6" class="input-field"/>
<!-- Chat Area Label -->
<text x="400" y="200" text-anchor="middle" font-size="24" class="secondary-text">💬</text>
<text x="400" y="240" text-anchor="middle" font-size="18" class="main-text">Chat</text>
<text x="400" y="265" text-anchor="middle" font-size="14" class="secondary-text">(Main Area)</text>
<!-- Message Input -->
<rect x="70" y="420" width="580" height="40" rx="20" class="input-field"/>
<text x="100" y="445" font-size="14" class="secondary-text">Type your message here...</text>
<!-- Send Button -->
<rect x="660" y="420" width="70" height="40" rx="20" class="accent"/>
<text x="695" y="445" text-anchor="middle" font-size="14" fill="#fff">Send</text>
<!-- Legend -->
<g transform="translate(50, 480)">
<text x="0" y="0" font-size="11" class="secondary-text">Header: Navigation, Apps Menu, Theme, Profile</text>
<text x="400" y="0" font-size="11" class="secondary-text">Main: AI Chat Interface with Message Input</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -0,0 +1,151 @@
<svg width="900" height="550" xmlns="http://www.w3.org/2000/svg">
<style>
.bg { fill: #f5f5f5; }
.frame { fill: none; stroke: #333; stroke-width: 2; }
.header-bg { fill: #e8e8e8; }
.main-text { fill: #1a1a1a; font-family: Arial, sans-serif; }
.secondary-text { fill: #666; font-family: Arial, sans-serif; }
.icon-text { fill: #333; font-family: Arial, sans-serif; }
.divider { stroke: #ddd; stroke-width: 1; }
.button { fill: #4A90E2; }
.button-text { fill: #fff; font-family: Arial, sans-serif; }
.input-field { fill: #fff; stroke: #ccc; stroke-width: 1; }
.tab-active { fill: #4A90E2; }
.tab-inactive { fill: #e0e0e0; }
.priority-high { fill: #E74C3C; }
.priority-medium { fill: #F5A623; }
.priority-low { fill: #7ED321; }
.checkbox { fill: #fff; stroke: #999; stroke-width: 1.5; }
.checkbox-done { fill: #7ED321; stroke: #5cb318; stroke-width: 1.5; }
.task-done { fill: #999; text-decoration: line-through; }
.row-bg { fill: #fff; }
.row-hover { fill: #f0f7ff; }
@media (prefers-color-scheme: dark) {
.bg { fill: #1a1a1a; }
.frame { stroke: #555; }
.header-bg { fill: #2a2a2a; }
.main-text { fill: #ffffff; }
.secondary-text { fill: #aaa; }
.icon-text { fill: #ddd; }
.divider { stroke: #444; }
.input-field { fill: #2a2a2a; stroke: #444; }
.tab-inactive { fill: #333; }
.checkbox { fill: #2a2a2a; stroke: #666; }
.row-bg { fill: #222; }
.row-hover { fill: #2a3a4a; }
.button { fill: #00D4FF; }
.tab-active { fill: #00D4FF; }
}
</style>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="600" class="main-text">Tasks - To-Do Management Interface</text>
<!-- Main Frame -->
<rect x="30" y="50" width="840" height="470" rx="8" class="frame bg"/>
<!-- Header -->
<rect x="30" y="50" width="840" height="50" rx="8" class="header-bg"/>
<rect x="30" y="92" width="840" height="8" class="bg"/>
<!-- Title and Stats -->
<text x="55" y="82" font-size="18" font-weight="600" class="main-text">✓ Tasks</text>
<g transform="translate(600, 65)">
<text x="0" y="15" font-size="12" class="secondary-text">Total: </text>
<text x="40" y="15" font-size="12" font-weight="600" class="main-text">12</text>
<text x="70" y="15" font-size="12" class="secondary-text">Active: </text>
<text x="115" y="15" font-size="12" font-weight="600" class="main-text">5</text>
<text x="140" y="15" font-size="12" class="secondary-text">Done: </text>
<text x="180" y="15" font-size="12" font-weight="600" class="main-text">7</text>
</g>
<!-- Divider -->
<line x1="30" y1="100" x2="870" y2="100" class="divider"/>
<!-- Add Task Input -->
<g transform="translate(50, 115)">
<rect x="0" y="0" width="620" height="40" rx="6" class="input-field"/>
<text x="15" y="26" font-size="14" class="secondary-text">What needs to be done?</text>
<!-- Category Dropdown -->
<rect x="640" y="0" width="100" height="40" rx="6" class="input-field"/>
<text x="655" y="26" font-size="13" class="secondary-text">Category ▼</text>
<!-- Add Button -->
<rect x="755" y="0" width="60" height="40" rx="6" class="button"/>
<text x="785" y="26" text-anchor="middle" font-size="13" class="button-text">+ Add</text>
</g>
<!-- Divider -->
<line x1="50" y1="170" x2="850" y2="170" class="divider"/>
<!-- Filter Tabs -->
<g transform="translate(50, 185)">
<rect x="0" y="0" width="90" height="32" rx="4" class="tab-active"/>
<text x="45" y="21" text-anchor="middle" font-size="13" fill="#fff">📋 All (12)</text>
<rect x="100" y="0" width="100" height="32" rx="4" class="tab-inactive"/>
<text x="150" y="21" text-anchor="middle" font-size="13" class="main-text">⏳ Active (5)</text>
<rect x="210" y="0" width="120" height="32" rx="4" class="tab-inactive"/>
<text x="270" y="21" text-anchor="middle" font-size="13" class="main-text">✓ Completed (7)</text>
<rect x="340" y="0" width="100" height="32" rx="4" class="tab-inactive"/>
<text x="390" y="21" text-anchor="middle" font-size="13" class="main-text">⚡ Priority</text>
</g>
<!-- Divider -->
<line x1="50" y1="230" x2="850" y2="230" class="divider"/>
<!-- Task List -->
<g transform="translate(50, 245)">
<!-- Task 1 - High Priority -->
<rect x="0" y="0" width="800" height="45" rx="4" class="row-hover"/>
<rect x="15" y="12" width="20" height="20" rx="4" class="checkbox"/>
<text x="50" y="28" font-size="14" class="main-text">Review quarterly report</text>
<text x="550" y="28" font-size="13" class="secondary-text">📅 Today</text>
<circle cx="780" cy="22" r="8" class="priority-high"/>
<!-- Task 2 - Medium Priority -->
<rect x="0" y="50" width="800" height="45" rx="4" class="row-bg"/>
<rect x="15" y="62" width="20" height="20" rx="4" class="checkbox"/>
<text x="50" y="78" font-size="14" class="main-text">Call client about proposal</text>
<text x="550" y="78" font-size="13" class="secondary-text">📅 Today</text>
<circle cx="780" cy="72" r="8" class="priority-medium"/>
<!-- Task 3 - Low Priority -->
<rect x="0" y="100" width="800" height="45" rx="4" class="row-bg"/>
<rect x="15" y="112" width="20" height="20" rx="4" class="checkbox"/>
<text x="50" y="128" font-size="14" class="main-text">Update project documentation</text>
<text x="550" y="128" font-size="13" class="secondary-text">📅 Tomorrow</text>
<circle cx="780" cy="122" r="8" class="priority-low"/>
<!-- Task 4 - Completed -->
<rect x="0" y="150" width="800" height="45" rx="4" class="row-bg"/>
<rect x="15" y="162" width="20" height="20" rx="4" class="checkbox-done"/>
<text x="22" y="178" font-size="12" fill="#fff"></text>
<text x="50" y="178" font-size="14" class="task-done">Send meeting notes</text>
<text x="550" y="178" font-size="13" class="secondary-text">✓ Done</text>
<!-- Task 5 - Completed -->
<rect x="0" y="200" width="800" height="45" rx="4" class="row-bg"/>
<rect x="15" y="212" width="20" height="20" rx="4" class="checkbox-done"/>
<text x="22" y="228" font-size="12" fill="#fff"></text>
<text x="50" y="228" font-size="14" class="task-done">Complete expense report</text>
<text x="550" y="228" font-size="13" class="secondary-text">✓ Done</text>
</g>
<!-- Priority Legend -->
<g transform="translate(50, 505)">
<text x="0" y="0" font-size="12" font-weight="500" class="secondary-text">Priority:</text>
<circle cx="70" cy="-4" r="6" class="priority-high"/>
<text x="82" y="0" font-size="11" class="secondary-text">High</text>
<circle cx="130" cy="-4" r="6" class="priority-medium"/>
<text x="142" y="0" font-size="11" class="secondary-text">Medium</text>
<circle cx="210" cy="-4" r="6" class="priority-low"/>
<text x="222" y="0" font-size="11" class="secondary-text">Low</text>
<text x="350" y="0" font-size="11" class="secondary-text">Shortcuts: Enter = Add | Space = Toggle | Delete = Remove</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7 KiB

View file

@ -0,0 +1,175 @@
<svg width="800" height="420" viewBox="0 0 800 420" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and filters -->
<defs>
<!-- Soft glow filter -->
<filter id="glow">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<!-- Beautiful gradients with colors -->
<linearGradient id="userGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="llmGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#06ffa5;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#00d2ff;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="toolGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#ffa500;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#ff6b6b;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="responseGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4facfe;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#00f2fe;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="memoryGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#f5576c;stop-opacity:0.2" />
</linearGradient>
<linearGradient id="directPathGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#10b981;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#34d399;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="toolPathGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#f59e0b;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#fbbf24;stop-opacity:0.3" />
</linearGradient>
<!-- Arrow markers -->
<marker id="arrow" markerWidth="15" markerHeight="15" refX="14" refY="7.5" orient="auto">
<path d="M 0 0 L 15 7.5 L 0 15 L 5 7.5 Z" fill="#4a5568" opacity="0.7"/>
</marker>
<marker id="arrowGreen" markerWidth="15" markerHeight="15" refX="14" refY="7.5" orient="auto">
<path d="M 0 0 L 15 7.5 L 0 15 L 5 7.5 Z" fill="#10b981" opacity="0.8"/>
</marker>
<marker id="arrowOrange" markerWidth="15" markerHeight="15" refX="14" refY="7.5" orient="auto">
<path d="M 0 0 L 15 7.5 L 0 15 L 5 7.5 Z" fill="#f59e0b" opacity="0.8"/>
</marker>
<!-- Drop shadow effect -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.15"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="800" height="420" fill="#fafafa"/>
<!-- Background accent circles for depth -->
<circle cx="120" cy="90" r="45" fill="#667eea" opacity="0.04"/>
<circle cx="400" cy="90" r="65" fill="#00d2ff" opacity="0.04"/>
<circle cx="650" cy="90" r="40" fill="#ffa500" opacity="0.04"/>
<circle cx="650" cy="230" r="50" fill="#ff6b6b" opacity="0.04"/>
<circle cx="400" cy="330" r="55" fill="#4facfe" opacity="0.04"/>
<!-- Title with background -->
<rect x="250" y="15" width="300" height="35" fill="rgba(99, 102, 241, 0.05)" rx="8"/>
<text x="400" y="38" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="23" font-weight="600" fill="#1e293b">
BASIC LLM Tool Execution Flow
</text>
<!-- Stage 1: User Input -->
<rect x="50" y="70" width="140" height="55" fill="url(#userGrad)" stroke="#667eea" stroke-width="2" rx="10" filter="url(#shadow)"/>
<text x="120" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">USER</text>
<text x="120" y="112" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">"What's the policy?"</text>
<!-- Elegant flow arrow 1 -->
<path d="M 190 97 C 220 97, 230 97, 260 97" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrow)" opacity="0.7" stroke-linecap="round"/>
<!-- Stage 2: LLM Processing -->
<rect x="260" y="70" width="280" height="55" fill="url(#llmGrad)" stroke="#00d2ff" stroke-width="2" rx="10" filter="url(#shadow)"/>
<text x="400" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">LLM + CONTEXT</text>
<text x="400" y="112" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Understands intent + loaded KBs</text>
<!-- Elegant flow arrow 2 -->
<path d="M 540 97 C 560 97, 580 97, 600 97" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrow)" opacity="0.7" stroke-linecap="round"/>
<!-- Stage 3: Decision Diamond -->
<g filter="url(#glow)">
<path d="M 650 70 L 700 97 L 650 124 L 600 97 Z" fill="rgba(139, 92, 246, 0.15)" stroke="#8b5cf6" stroke-width="2.5"/>
<circle cx="650" cy="97" r="10" fill="#8b5cf6" opacity="0.3"/>
<text x="650" y="102" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="600" fill="#1e293b">Tool?</text>
</g>
<!-- Direct Response Path - graceful curve -->
<path d="M 650 70 C 650 40, 500 40, 400 40 C 280 40, 140 40, 140 170"
stroke="url(#directPathGrad)" stroke-width="2.5" fill="none" marker-end="url(#arrowGreen)"
stroke-dasharray="8,4" opacity="0.6" stroke-linecap="round"/>
<!-- Label for direct path -->
<rect x="350" y="25" width="100" height="22" fill="rgba(16, 185, 129, 0.1)" rx="5"/>
<text x="400" y="40" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#047857">Direct Answer</text>
<!-- Tool Path - smooth descent -->
<path d="M 650 124 C 650 160, 650 170, 650 200" stroke="url(#toolPathGrad)" stroke-width="3" fill="none" marker-end="url(#arrowOrange)" opacity="0.8" stroke-linecap="round"/>
<!-- Label for tool path -->
<text x="670" y="165" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#d97706">Call Tool</text>
<!-- Stage 4: BASIC Tool -->
<rect x="560" y="200" width="180" height="75" fill="url(#toolGrad)" stroke="#ff6b6b" stroke-width="2" rx="10" filter="url(#shadow)"/>
<text x="650" y="225" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">BASIC TOOL</text>
<text x="650" y="245" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">enrollment.bas</text>
<text x="650" y="260" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">PARAM name, course</text>
<!-- Tool Return Path - smooth curve -->
<path d="M 560 237 C 490 237, 430 220, 400 195" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrow)" opacity="0.6" stroke-linecap="round"/>
<!-- Stage 5: Response Generation -->
<rect x="310" y="170" width="180" height="55" fill="url(#responseGrad)" stroke="#4facfe" stroke-width="2" rx="10" filter="url(#shadow)"/>
<text x="400" y="195" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">RESPONSE</text>
<text x="400" y="212" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Generate natural answer</text>
<!-- Final Arrow -->
<path d="M 310 197 C 280 197, 240 197, 210 197" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrow)" opacity="0.7" stroke-linecap="round"/>
<!-- Stage 6: Bot Output -->
<rect x="50" y="170" width="140" height="55" fill="url(#userGrad)" stroke="#764ba2" stroke-width="2" rx="10" filter="url(#shadow)"/>
<text x="120" y="195" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">BOT</text>
<text x="120" y="212" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">"30-day return..."</text>
<!-- Memory Store - elegant and subtle -->
<rect x="350" y="290" width="320" height="55" fill="url(#memoryGrad)" stroke="#f5576c" stroke-width="1.5" stroke-dasharray="6,3" rx="10" opacity="0.8"/>
<text x="510" y="315" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="500" fill="#1e293b">MEMORY STORE</text>
<text x="510" y="332" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">BOT_MEMORY • Session State • Context</text>
<!-- Memory connection - delicate -->
<path d="M 650 275 L 650 290" stroke="#f5576c" stroke-width="1.5" stroke-dasharray="4,4" fill="none" opacity="0.4"/>
<path d="M 400 225 L 400 290" stroke="#4facfe" stroke-width="1.5" stroke-dasharray="4,4" fill="none" opacity="0.4"/>
<!-- Performance metrics -->
<rect x="50" y="370" width="700" height="35" fill="rgba(99, 102, 241, 0.05)" stroke="#8b5cf6" stroke-width="1" stroke-dasharray="6,3" rx="8"/>
<text x="400" y="392" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569" font-style="italic">
LLM decides tool calls • Zero IF/THEN logic • Natural conversation flow • Context-aware responses
</text>
<!-- Legend -->
<g transform="translate(50, 260)">
<text x="0" y="0" font-family="system-ui, sans-serif" font-size="16" font-weight="600" fill="#1e293b">Legend:</text>
<circle cx="10" cy="15" r="4" fill="#10b981"/>
<text x="20" y="19" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Direct response</text>
<circle cx="10" cy="30" r="4" fill="#f59e0b"/>
<text x="20" y="34" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Tool invocation</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,139 @@
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#666" opacity="0.8"/>
</marker>
<linearGradient id="gradient1" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#4A90E2;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#4A90E2;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="gradient2" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#50C878;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#50C878;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="gradient3" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#FF6B6B;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#FF6B6B;stop-opacity:0.3" />
</linearGradient>
</defs>
<!-- Title -->
<text x="400" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="#333">BotServer Data Flow Architecture</text>
<!-- User Input Layer -->
<g id="user-layer">
<rect x="50" y="60" width="700" height="80" fill="url(#gradient1)" stroke="#4A90E2" stroke-width="2" rx="8" opacity="0.8"/>
<text x="400" y="85" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#333">User Input Layer</text>
<!-- Input sources -->
<rect x="80" y="95" width="120" height="30" fill="white" stroke="#4A90E2" stroke-width="1" rx="4" opacity="0.9"/>
<text x="140" y="113" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#333">Web UI</text>
<rect x="220" y="95" width="120" height="30" fill="white" stroke="#4A90E2" stroke-width="1" rx="4" opacity="0.9"/>
<text x="280" y="113" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#333">WhatsApp</text>
<rect x="360" y="95" width="120" height="30" fill="white" stroke="#4A90E2" stroke-width="1" rx="4" opacity="0.9"/>
<text x="420" y="113" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#333">Teams</text>
<rect x="500" y="95" width="120" height="30" fill="white" stroke="#4A90E2" stroke-width="1" rx="4" opacity="0.9"/>
<text x="560" y="113" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#333">Email</text>
<rect x="640" y="95" width="80" height="30" fill="white" stroke="#4A90E2" stroke-width="1" rx="4" opacity="0.9"/>
<text x="680" y="113" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" fill="#333">API</text>
</g>
<!-- Arrows from User Layer to Processing -->
<line x1="400" y1="140" x2="400" y2="170" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- Processing Layer -->
<g id="processing-layer">
<rect x="50" y="170" width="700" height="200" fill="url(#gradient2)" stroke="#50C878" stroke-width="2" rx="8" opacity="0.8"/>
<text x="400" y="195" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#333">Core Processing Engine</text>
<!-- Session Manager -->
<rect x="80" y="210" width="150" height="60" fill="white" stroke="#50C878" stroke-width="1" rx="4" opacity="0.9"/>
<text x="155" y="235" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Session Manager</text>
<text x="155" y="252" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">User Context</text>
<!-- BASIC Interpreter -->
<rect x="250" y="210" width="150" height="60" fill="white" stroke="#50C878" stroke-width="1" rx="4" opacity="0.9"/>
<text x="325" y="235" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">BASIC Interpreter</text>
<text x="325" y="252" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">Script Execution</text>
<!-- LLM Integration -->
<rect x="420" y="210" width="150" height="60" fill="white" stroke="#50C878" stroke-width="1" rx="4" opacity="0.9"/>
<text x="495" y="235" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">LLM Integration</text>
<text x="495" y="252" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">AI Processing</text>
<!-- Knowledge Base -->
<rect x="590" y="210" width="130" height="60" fill="white" stroke="#50C878" stroke-width="1" rx="4" opacity="0.9"/>
<text x="655" y="235" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Knowledge Base</text>
<text x="655" y="252" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">Vector Search</text>
<!-- Internal flow arrows -->
<line x1="230" y1="240" x2="250" y2="240" stroke="#666" stroke-width="1" marker-end="url(#arrow)" opacity="0.5"/>
<line x1="400" y1="240" x2="420" y2="240" stroke="#666" stroke-width="1" marker-end="url(#arrow)" opacity="0.5"/>
<line x1="570" y1="240" x2="590" y2="240" stroke="#666" stroke-width="1" marker-end="url(#arrow)" opacity="0.5"/>
<!-- Tool System -->
<rect x="80" y="290" width="300" height="60" fill="white" stroke="#50C878" stroke-width="1" rx="4" opacity="0.9"/>
<text x="230" y="315" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Tool System</text>
<text x="230" y="332" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">External APIs &amp; Functions</text>
<!-- Cache Layer -->
<rect x="420" y="290" width="300" height="60" fill="white" stroke="#50C878" stroke-width="1" rx="4" opacity="0.9"/>
<text x="570" y="315" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Cache Layer</text>
<text x="570" y="332" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">Response Optimization</text>
</g>
<!-- Arrows from Processing to Storage -->
<line x1="400" y1="370" x2="400" y2="400" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- Storage Layer -->
<g id="storage-layer">
<rect x="50" y="400" width="700" height="120" fill="url(#gradient3)" stroke="#FF6B6B" stroke-width="2" rx="8" opacity="0.8"/>
<text x="400" y="425" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#333">Storage &amp; Persistence Layer</text>
<!-- Database -->
<rect x="80" y="450" width="140" height="50" fill="white" stroke="#FF6B6B" stroke-width="1" rx="4" opacity="0.9"/>
<text x="150" y="470" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Database</text>
<text x="150" y="487" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">User Data</text>
<!-- Vector DB -->
<rect x="240" y="450" width="140" height="50" fill="white" stroke="#FF6B6B" stroke-width="1" rx="4" opacity="0.9"/>
<text x="310" y="470" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Vector DB</text>
<text x="310" y="487" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">Embeddings</text>
<!-- Drive Storage -->
<rect x="400" y="450" width="140" height="50" fill="white" stroke="#FF6B6B" stroke-width="1" rx="4" opacity="0.9"/>
<text x="470" y="470" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Drive Storage</text>
<text x="470" y="487" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">Files &amp; Assets</text>
<!-- Cache -->
<rect x="560" y="450" width="140" height="50" fill="white" stroke="#FF6B6B" stroke-width="1" rx="4" opacity="0.9"/>
<text x="630" y="470" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Cache</text>
<text x="630" y="487" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#666">Fast Access</text>
</g>
<!-- Bidirectional arrows showing data flow -->
<g id="flow-arrows" opacity="0.4">
<!-- Vertical flows -->
<line x1="155" y1="270" x2="155" y2="450" stroke="#666" stroke-width="1" stroke-dasharray="5,5"/>
<line x1="325" y1="270" x2="310" y2="450" stroke="#666" stroke-width="1" stroke-dasharray="5,5"/>
<line x1="495" y1="270" x2="470" y2="450" stroke="#666" stroke-width="1" stroke-dasharray="5,5"/>
<line x1="655" y1="270" x2="630" y2="450" stroke="#666" stroke-width="1" stroke-dasharray="5,5"/>
</g>
<!-- Legend -->
<g id="legend" transform="translate(50, 540)">
<text x="0" y="0" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#333">Data Flow:</text>
<line x1="80" y1="-5" x2="120" y2="-5" stroke="#666" stroke-width="2" marker-end="url(#arrow)"/>
<text x="125" y="0" font-family="Arial, sans-serif" font-size="16" fill="#666">Request/Response</text>
<line x1="250" y1="-5" x2="290" y2="-5" stroke="#666" stroke-width="1" stroke-dasharray="5,5"/>
<text x="295" y="0" font-family="Arial, sans-serif" font-size="16" fill="#666">Data Access</text>
</g>
<!-- Performance Note -->
<text x="400" y="580" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#999">All components run in async Rust for maximum performance</text>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

View file

@ -0,0 +1,306 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1200" height="900" viewBox="0 0 1200 900" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- Gradients -->
<linearGradient id="headerGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#075e54"/>
<stop offset="100%" style="stop-color:#25d366"/>
</linearGradient>
<linearGradient id="userGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#667eea"/>
<stop offset="100%" style="stop-color:#764ba2"/>
</linearGradient>
<linearGradient id="botGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#11998e"/>
<stop offset="100%" style="stop-color:#38ef7d"/>
</linearGradient>
<linearGradient id="storageGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb"/>
<stop offset="100%" style="stop-color:#f5576c"/>
</linearGradient>
<linearGradient id="llmGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#4facfe"/>
<stop offset="100%" style="stop-color:#00f2fe"/>
</linearGradient>
<linearGradient id="dbGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#fa709a"/>
<stop offset="100%" style="stop-color:#fee140"/>
</linearGradient>
<!-- Arrow marker -->
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#666"/>
</marker>
<marker id="arrowheadGreen" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#25d366"/>
</marker>
<marker id="arrowheadBlue" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#4facfe"/>
</marker>
<marker id="arrowheadPink" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#f5576c"/>
</marker>
<!-- Drop shadow -->
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="2" dy="2" stdDeviation="3" flood-opacity="0.2"/>
</filter>
</defs>
<!-- Background -->
<rect width="1200" height="900" fill="#f8fafc"/>
<!-- Header -->
<rect x="0" y="0" width="1200" height="60" fill="url(#headerGradient)"/>
<text x="600" y="38" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="white" text-anchor="middle">
Data Traceability Diagram - General Bots Architecture
</text>
<!-- Legend -->
<g transform="translate(900, 80)">
<rect x="0" y="0" width="280" height="140" rx="8" fill="white" stroke="#e2e8f0" filter="url(#shadow)"/>
<text x="140" y="25" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="#1a1a1a" text-anchor="middle">Legend</text>
<line x1="20" y1="50" x2="60" y2="50" stroke="#25d366" stroke-width="2" marker-end="url(#arrowheadGreen)"/>
<text x="75" y="54" font-family="Arial, sans-serif" font-size="12" fill="#666">User Input Flow</text>
<line x1="20" y1="75" x2="60" y2="75" stroke="#4facfe" stroke-width="2" marker-end="url(#arrowheadBlue)"/>
<text x="75" y="79" font-family="Arial, sans-serif" font-size="12" fill="#666">LLM Processing</text>
<line x1="20" y1="100" x2="60" y2="100" stroke="#f5576c" stroke-width="2" marker-end="url(#arrowheadPink)"/>
<text x="75" y="104" font-family="Arial, sans-serif" font-size="12" fill="#666">Storage Operations</text>
<line x1="20" y1="125" x2="60" y2="125" stroke="#666" stroke-width="2" stroke-dasharray="5,5" marker-end="url(#arrowhead)"/>
<text x="75" y="129" font-family="Arial, sans-serif" font-size="12" fill="#666">Internal Flow</text>
</g>
<!-- User/Channels Section -->
<g transform="translate(50, 100)">
<rect x="0" y="0" width="200" height="280" rx="12" fill="url(#userGradient)" filter="url(#shadow)"/>
<text x="100" y="30" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white" text-anchor="middle">CHANNELS</text>
<!-- WhatsApp -->
<rect x="20" y="50" width="160" height="40" rx="6" fill="white" opacity="0.9"/>
<text x="100" y="75" font-family="Arial, sans-serif" font-size="13" fill="#333" text-anchor="middle">📱 WhatsApp</text>
<!-- Telegram -->
<rect x="20" y="100" width="160" height="40" rx="6" fill="white" opacity="0.9"/>
<text x="100" y="125" font-family="Arial, sans-serif" font-size="13" fill="#333" text-anchor="middle">✈️ Telegram</text>
<!-- Web UI -->
<rect x="20" y="150" width="160" height="40" rx="6" fill="white" opacity="0.9"/>
<text x="100" y="175" font-family="Arial, sans-serif" font-size="13" fill="#333" text-anchor="middle">🌐 Web UI / gbui</text>
<!-- API -->
<rect x="20" y="200" width="160" height="40" rx="6" fill="white" opacity="0.9"/>
<text x="100" y="225" font-family="Arial, sans-serif" font-size="13" fill="#333" text-anchor="middle">🔌 REST API</text>
<!-- Webhook -->
<rect x="20" y="250" width="160" height="20" rx="4" fill="white" opacity="0.7"/>
<text x="100" y="264" font-family="Arial, sans-serif" font-size="11" fill="#333" text-anchor="middle">🪝 Webhooks</text>
</g>
<!-- Bot Core -->
<g transform="translate(350, 120)">
<rect x="0" y="0" width="240" height="360" rx="12" fill="url(#botGradient)" filter="url(#shadow)"/>
<text x="120" y="30" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white" text-anchor="middle">BOTSERVER CORE</text>
<!-- BASIC Interpreter -->
<rect x="20" y="50" width="200" height="50" rx="6" fill="white" opacity="0.95"/>
<text x="120" y="72" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#333" text-anchor="middle">BASIC Interpreter</text>
<text x="120" y="88" font-family="Arial, sans-serif" font-size="10" fill="#666" text-anchor="middle">.bas scripts → Rhai engine</text>
<!-- Message Router -->
<rect x="20" y="110" width="200" height="50" rx="6" fill="white" opacity="0.95"/>
<text x="120" y="132" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#333" text-anchor="middle">Message Router</text>
<text x="120" y="148" font-family="Arial, sans-serif" font-size="10" fill="#666" text-anchor="middle">TALK / HEAR / SEND</text>
<!-- Scheduler -->
<rect x="20" y="170" width="200" height="50" rx="6" fill="white" opacity="0.95"/>
<text x="120" y="192" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#333" text-anchor="middle">Scheduler</text>
<text x="120" y="208" font-family="Arial, sans-serif" font-size="10" fill="#666" text-anchor="middle">SET SCHEDULE "every hour"</text>
<!-- Keywords Engine -->
<rect x="20" y="230" width="200" height="50" rx="6" fill="white" opacity="0.95"/>
<text x="120" y="252" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#333" text-anchor="middle">Keywords Engine</text>
<text x="120" y="268" font-family="Arial, sans-serif" font-size="10" fill="#666" text-anchor="middle">GET/POST/FIND/SAVE/LLM</text>
<!-- Session Manager -->
<rect x="20" y="290" width="200" height="50" rx="6" fill="white" opacity="0.95"/>
<text x="120" y="312" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#333" text-anchor="middle">Session Manager</text>
<text x="120" y="328" font-family="Arial, sans-serif" font-size="10" fill="#666" text-anchor="middle">user_id → bot_id → org_id</text>
</g>
<!-- LLM Section -->
<g transform="translate(680, 100)">
<rect x="0" y="0" width="200" height="200" rx="12" fill="url(#llmGradient)" filter="url(#shadow)"/>
<text x="100" y="30" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white" text-anchor="middle">LLM PROVIDERS</text>
<rect x="20" y="50" width="160" height="30" rx="4" fill="white" opacity="0.9"/>
<text x="100" y="70" font-family="Arial, sans-serif" font-size="11" fill="#333" text-anchor="middle">🧠 Claude Opus 4</text>
<rect x="20" y="90" width="160" height="30" rx="4" fill="white" opacity="0.9"/>
<text x="100" y="110" font-family="Arial, sans-serif" font-size="11" fill="#333" text-anchor="middle">🤖 GPT-4 Turbo</text>
<rect x="20" y="130" width="160" height="30" rx="4" fill="white" opacity="0.9"/>
<text x="100" y="150" font-family="Arial, sans-serif" font-size="11" fill="#333" text-anchor="middle">💎 Gemini Pro</text>
<rect x="20" y="170" width="160" height="20" rx="4" fill="white" opacity="0.7"/>
<text x="100" y="184" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">🦙 Local: Llama/Mistral</text>
</g>
<!-- Storage Section -->
<g transform="translate(680, 320)">
<rect x="0" y="0" width="200" height="200" rx="12" fill="url(#storageGradient)" filter="url(#shadow)"/>
<text x="100" y="30" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white" text-anchor="middle">STORAGE (MinIO)</text>
<rect x="20" y="50" width="160" height="35" rx="4" fill="white" opacity="0.9"/>
<text x="100" y="65" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#333" text-anchor="middle">📁 /{org}/{botname}/</text>
<text x="100" y="78" font-family="Arial, sans-serif" font-size="9" fill="#666" text-anchor="middle">Bucket per bot</text>
<rect x="20" y="95" width="75" height="30" rx="4" fill="white" opacity="0.85"/>
<text x="57" y="114" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">.gbdialog</text>
<rect x="105" y="95" width="75" height="30" rx="4" fill="white" opacity="0.85"/>
<text x="142" y="114" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">.gbkb</text>
<rect x="20" y="135" width="75" height="30" rx="4" fill="white" opacity="0.85"/>
<text x="57" y="154" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">.gbot</text>
<rect x="105" y="135" width="75" height="30" rx="4" fill="white" opacity="0.85"/>
<text x="142" y="154" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">.gbtheme</text>
<rect x="20" y="175" width="160" height="18" rx="3" fill="white" opacity="0.7"/>
<text x="100" y="188" font-family="Arial, sans-serif" font-size="9" fill="#666" text-anchor="middle">uploads/ | exports/ | cache/</text>
</g>
<!-- Database Section -->
<g transform="translate(950, 180)">
<rect x="0" y="0" width="200" height="280" rx="12" fill="url(#dbGradient)" filter="url(#shadow)"/>
<text x="100" y="30" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white" text-anchor="middle">DATABASE</text>
<rect x="20" y="50" width="160" height="35" rx="4" fill="white" opacity="0.9"/>
<text x="100" y="65" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#333" text-anchor="middle">🐘 PostgreSQL</text>
<text x="100" y="78" font-family="Arial, sans-serif" font-size="9" fill="#666" text-anchor="middle">Main database</text>
<rect x="20" y="95" width="160" height="25" rx="3" fill="white" opacity="0.85"/>
<text x="100" y="112" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">organizations</text>
<rect x="20" y="125" width="160" height="25" rx="3" fill="white" opacity="0.85"/>
<text x="100" y="142" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">bots</text>
<rect x="20" y="155" width="160" height="25" rx="3" fill="white" opacity="0.85"/>
<text x="100" y="172" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">users / sessions</text>
<rect x="20" y="185" width="160" height="25" rx="3" fill="white" opacity="0.85"/>
<text x="100" y="202" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">conversations</text>
<rect x="20" y="215" width="160" height="25" rx="3" fill="white" opacity="0.85"/>
<text x="100" y="232" font-family="Arial, sans-serif" font-size="10" fill="#333" text-anchor="middle">system_automations</text>
<rect x="20" y="250" width="160" height="20" rx="3" fill="white" opacity="0.7"/>
<text x="100" y="264" font-family="Arial, sans-serif" font-size="9" fill="#666" text-anchor="middle">🔴 Redis (cache/queue)</text>
</g>
<!-- Data Flow Arrows -->
<!-- Channels to Bot Core -->
<path d="M 250 240 L 350 300" stroke="#25d366" stroke-width="2" fill="none" marker-end="url(#arrowheadGreen)"/>
<path d="M 250 220 L 350 280" stroke="#25d366" stroke-width="2" fill="none" marker-end="url(#arrowheadGreen)"/>
<!-- Bot Core to LLM -->
<path d="M 590 200 L 680 200" stroke="#4facfe" stroke-width="2" fill="none" marker-end="url(#arrowheadBlue)"/>
<text x="635" y="190" font-family="Arial, sans-serif" font-size="9" fill="#4facfe">LLM</text>
<!-- LLM back to Bot Core -->
<path d="M 680 230 L 590 270" stroke="#4facfe" stroke-width="2" fill="none" marker-end="url(#arrowheadBlue)"/>
<!-- Bot Core to Storage -->
<path d="M 590 380 L 680 400" stroke="#f5576c" stroke-width="2" fill="none" marker-end="url(#arrowheadPink)"/>
<text x="620" y="375" font-family="Arial, sans-serif" font-size="9" fill="#f5576c">FILES</text>
<!-- Bot Core to Database -->
<path d="M 590 340 Q 750 340 950 340" stroke="#666" stroke-width="2" stroke-dasharray="5,5" fill="none" marker-end="url(#arrowhead)"/>
<text x="770" y="330" font-family="Arial, sans-serif" font-size="9" fill="#666">FIND/SAVE</text>
<!-- Storage to Database (metadata) -->
<path d="M 880 420 L 950 380" stroke="#666" stroke-width="1.5" stroke-dasharray="3,3" fill="none" marker-end="url(#arrowhead)"/>
<!-- Key Data Flows Section -->
<g transform="translate(50, 550)">
<rect x="0" y="0" width="1100" height="300" rx="12" fill="white" stroke="#e2e8f0" filter="url(#shadow)"/>
<text x="550" y="30" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#1a1a1a" text-anchor="middle">Key Data Flows</text>
<!-- Flow 1: User Message -->
<g transform="translate(30, 50)">
<rect x="0" y="0" width="320" height="100" rx="8" fill="#e8f5e9" stroke="#4caf50"/>
<text x="160" y="25" font-family="Arial, sans-serif" font-size="13" font-weight="bold" fill="#2e7d32" text-anchor="middle">1. User Message Flow</text>
<text x="10" y="50" font-family="monospace" font-size="10" fill="#333">Channel → Router → Session</text>
<text x="10" y="65" font-family="monospace" font-size="10" fill="#333">→ BASIC Script → LLM (if needed)</text>
<text x="10" y="80" font-family="monospace" font-size="10" fill="#333">→ Response → Channel</text>
<text x="10" y="95" font-family="Arial, sans-serif" font-size="9" fill="#666">Key: {org}_{bot}_{user}_{session}</text>
</g>
<!-- Flow 2: Scheduled Task -->
<g transform="translate(380, 50)">
<rect x="0" y="0" width="320" height="100" rx="8" fill="#e3f2fd" stroke="#2196f3"/>
<text x="160" y="25" font-family="Arial, sans-serif" font-size="13" font-weight="bold" fill="#1565c0" text-anchor="middle">2. Scheduled Task Flow</text>
<text x="10" y="50" font-family="monospace" font-size="10" fill="#333">Cron Trigger → Load Script</text>
<text x="10" y="65" font-family="monospace" font-size="10" fill="#333">→ Execute Keywords → External APIs</text>
<text x="10" y="80" font-family="monospace" font-size="10" fill="#333">→ Save Results → Log</text>
<text x="10" y="95" font-family="Arial, sans-serif" font-size="9" fill="#666">Key: {org}_{bot}_schedule_{name}</text>
</g>
<!-- Flow 3: File Operations -->
<g transform="translate(730, 50)">
<rect x="0" y="0" width="320" height="100" rx="8" fill="#fce4ec" stroke="#e91e63"/>
<text x="160" y="25" font-family="Arial, sans-serif" font-size="13" font-weight="bold" fill="#c2185b" text-anchor="middle">3. File Operations Flow</text>
<text x="10" y="50" font-family="monospace" font-size="10" fill="#333">UPLOAD/DOWNLOAD → MinIO</text>
<text x="10" y="65" font-family="monospace" font-size="10" fill="#333">Bucket: /{org}/{botname}/</text>
<text x="10" y="80" font-family="monospace" font-size="10" fill="#333">→ Metadata → PostgreSQL</text>
<text x="10" y="95" font-family="Arial, sans-serif" font-size="9" fill="#666">Path: s3://{org}/{bot}/{path}</text>
</g>
<!-- Flow 4: Knowledge Base -->
<g transform="translate(30, 165)">
<rect x="0" y="0" width="320" height="100" rx="8" fill="#fff3e0" stroke="#ff9800"/>
<text x="160" y="25" font-family="Arial, sans-serif" font-size="13" font-weight="bold" fill="#e65100" text-anchor="middle">4. Knowledge Base Flow</text>
<text x="10" y="50" font-family="monospace" font-size="10" fill="#333">USE KB "docs" → Load .gbkb</text>
<text x="10" y="65" font-family="monospace" font-size="10" fill="#333">→ Embed → Vector DB (pgvector)</text>
<text x="10" y="80" font-family="monospace" font-size="10" fill="#333">→ Semantic Search → LLM Context</text>
<text x="10" y="95" font-family="Arial, sans-serif" font-size="9" fill="#666">Key: {org}_{bot}_kb_{name}</text>
</g>
<!-- Flow 5: Webhook -->
<g transform="translate(380, 165)">
<rect x="0" y="0" width="320" height="100" rx="8" fill="#f3e5f5" stroke="#9c27b0"/>
<text x="160" y="25" font-family="Arial, sans-serif" font-size="13" font-weight="bold" fill="#7b1fa2" text-anchor="middle">5. Webhook Flow</text>
<text x="10" y="50" font-family="monospace" font-size="10" fill="#333">External POST → /webhook/{id}</text>
<text x="10" y="65" font-family="monospace" font-size="10" fill="#333">→ Validate → Trigger Script</text>
<text x="10" y="80" font-family="monospace" font-size="10" fill="#333">→ Process → Response/Notify</text>
<text x="10" y="95" font-family="Arial, sans-serif" font-size="9" fill="#666">Key: {org}_{bot}_webhook_{path}</text>
</g>
<!-- Flow 6: Bot Memory -->
<g transform="translate(730, 165)">
<rect x="0" y="0" width="320" height="100" rx="8" fill="#e0f2f1" stroke="#009688"/>
<text x="160" y="25" font-family="Arial, sans-serif" font-size="13" font-weight="bold" fill="#00695c" text-anchor="middle">6. Bot Memory Flow</text>
<text x="10" y="50" font-family="monospace" font-size="10" fill="#333">SET/GET BOT MEMORY → Redis</text>
<text x="10" y="65" font-family="monospace" font-size="10" fill="#333">→ Persist → PostgreSQL (backup)</text>
<text x="10" y="80" font-family="monospace" font-size="10" fill="#333">→ Scope: global | user | session</text>
<text x="10" y="95" font-family="Arial, sans-serif" font-size="9" fill="#666">Key: {org}_{bot}_mem_{scope}_{key}</text>
</g>
</g>
<!-- Footer -->
<text x="600" y="880" font-family="Arial, sans-serif" font-size="11" fill="#666" text-anchor="middle">
General Bots Data Traceability - All keys follow pattern: {org}_{botname}_{resource}_{identifier}
</text>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,135 @@
<svg width="900" height="800" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#666" opacity="0.8"/>
</marker>
<linearGradient id="inputGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#3B82F6;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="processGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#10B981;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#10B981;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="serviceGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#8B5CF6;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#8B5CF6;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="dataGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#F59E0B;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#F59E0B;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="outputGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#EF4444;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#EF4444;stop-opacity:0.3" />
</linearGradient>
</defs>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="#1F2937">Data Flow Through Modules</text>
<!-- User Input -->
<ellipse cx="450" cy="70" rx="80" ry="25" fill="url(#inputGradient)" stroke="#3B82F6" stroke-width="2" opacity="0.9"/>
<text x="450" y="75" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">User Input</text>
<!-- Arrow down -->
<line x1="450" y1="95" x2="450" y2="120" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- web_server/channels -->
<rect x="300" y="120" width="300" height="70" fill="url(#processGradient)" stroke="#10B981" stroke-width="2" rx="8" opacity="0.9"/>
<text x="450" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">web_server/ | channels/</text>
<text x="450" y="165" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Axum HTTP Server</text>
<text x="450" y="180" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Route to channel</text>
<!-- Arrow down -->
<line x1="450" y1="190" x2="450" y2="220" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- session/ -->
<rect x="300" y="220" width="300" height="70" fill="url(#processGradient)" stroke="#10B981" stroke-width="2" rx="8" opacity="0.9"/>
<text x="450" y="245" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">session/</text>
<text x="450" y="265" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Load/Create Session</text>
<text x="450" y="280" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Validate Token</text>
<!-- Arrow down -->
<line x1="450" y1="290" x2="450" y2="320" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- auth/ -->
<rect x="300" y="320" width="300" height="70" fill="url(#processGradient)" stroke="#10B981" stroke-width="2" rx="8" opacity="0.9"/>
<text x="450" y="345" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">auth/</text>
<text x="450" y="365" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Check Permissions</text>
<text x="450" y="380" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Apply RBAC</text>
<!-- Arrow down -->
<line x1="450" y1="390" x2="450" y2="420" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- bot/ -->
<rect x="300" y="420" width="300" height="70" fill="url(#serviceGradient)" stroke="#8B5CF6" stroke-width="2" rx="8" opacity="0.9"/>
<text x="450" y="445" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">bot/</text>
<text x="450" y="465" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C3AED">Route to Bot Instance</text>
<text x="450" y="480" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C3AED">Load Configuration</text>
<!-- Arrow down -->
<line x1="450" y1="490" x2="450" y2="520" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- basic/ -->
<rect x="300" y="520" width="300" height="70" fill="url(#serviceGradient)" stroke="#8B5CF6" stroke-width="2" rx="8" opacity="0.9"/>
<text x="450" y="545" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">basic/</text>
<text x="450" y="565" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C3AED">Execute BASIC Script</text>
<text x="450" y="580" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C3AED">Parse Keywords</text>
<!-- Multiple arrows branching out -->
<line x1="350" y1="590" x2="200" y2="640" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="400" y1="590" x2="350" y2="640" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="500" y1="590" x2="550" y2="640" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="550" y1="590" x2="700" y2="640" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- Data Layer Services -->
<!-- context/ -->
<rect x="120" y="640" width="140" height="60" fill="url(#dataGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="190" y="665" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">context/</text>
<text x="190" y="685" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C2D12">Load KB</text>
<!-- drive/ -->
<rect x="280" y="640" width="140" height="60" fill="url(#dataGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="350" y="665" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">drive/</text>
<text x="350" y="685" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C2D12">Get Files</text>
<!-- database/ -->
<rect x="480" y="640" width="140" height="60" fill="url(#dataGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="550" y="665" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">database/</text>
<text x="550" y="685" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C2D12">Query DB</text>
<!-- llm/ -->
<rect x="640" y="640" width="140" height="60" fill="url(#dataGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="710" y="665" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">llm/</text>
<text x="710" y="685" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#7C2D12">Call AI</text>
<!-- Convergence arrows -->
<line x1="190" y1="700" x2="400" y2="730" stroke="#666" stroke-width="1" opacity="0.5"/>
<line x1="350" y1="700" x2="420" y2="730" stroke="#666" stroke-width="1" opacity="0.5"/>
<line x1="550" y1="700" x2="480" y2="730" stroke="#666" stroke-width="1" opacity="0.5"/>
<line x1="710" y1="700" x2="500" y2="730" stroke="#666" stroke-width="1" opacity="0.5"/>
<!-- Arrow down -->
<line x1="450" y1="730" x2="450" y2="750" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- Bot Response -->
<ellipse cx="450" cy="780" rx="80" ry="25" fill="url(#outputGradient)" stroke="#EF4444" stroke-width="2" opacity="0.9"/>
<text x="450" y="785" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">Bot Response</text>
<!-- Side annotations -->
<g id="annotations" opacity="0.7">
<!-- Processing stages -->
<text x="50" y="75" text-anchor="start" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">1. Input Reception</text>
<text x="50" y="155" text-anchor="start" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">2. HTTP Routing</text>
<text x="50" y="255" text-anchor="start" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">3. Session Management</text>
<text x="50" y="355" text-anchor="start" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">4. Authorization</text>
<text x="50" y="455" text-anchor="start" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">5. Bot Routing</text>
<text x="50" y="555" text-anchor="start" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">6. Script Execution</text>
<text x="50" y="670" text-anchor="start" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">7. Data Processing</text>
<text x="50" y="785" text-anchor="start" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">8. Response Generation</text>
</g>
<!-- Performance note -->
<text x="450" y="820" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-style="italic" fill="#9CA3AF">All operations are async with Tokio runtime for maximum throughput</text>
</svg>

After

Width:  |  Height:  |  Size: 9.7 KiB

View file

@ -0,0 +1,133 @@
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#666" opacity="0.8"/>
</marker>
<linearGradient id="mainGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#3B82F6;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="coreGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#10B981;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#10B981;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="serviceGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#8B5CF6;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#8B5CF6;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="leafGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#F59E0B;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#F59E0B;stop-opacity:0.3" />
</linearGradient>
</defs>
<!-- Title -->
<text x="400" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="#1F2937">Module Dependency Graph</text>
<!-- main.rs (Entry Point) -->
<rect x="350" y="50" width="100" height="40" fill="url(#mainGradient)" stroke="#3B82F6" stroke-width="2" rx="8" opacity="0.9"/>
<text x="400" y="75" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#1F2937">main.rs</text>
<!-- Arrow to bootstrap -->
<line x1="400" y1="90" x2="400" y2="120" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- bootstrap/ -->
<rect x="330" y="120" width="140" height="40" fill="url(#coreGradient)" stroke="#10B981" stroke-width="2" rx="8" opacity="0.9"/>
<text x="400" y="145" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#1F2937">bootstrap/</text>
<!-- Arrows from bootstrap to core modules -->
<line x1="350" y1="160" x2="200" y2="210" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="400" y1="160" x2="400" y2="210" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="450" y1="160" x2="600" y2="210" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- Core Layer -->
<!-- package_manager/ -->
<rect x="120" y="210" width="160" height="40" fill="url(#coreGradient)" stroke="#10B981" stroke-width="2" rx="8" opacity="0.9"/>
<text x="200" y="235" text-anchor="middle" font-family="monospace" font-size="18" fill="#1F2937">package_manager/</text>
<!-- config/ -->
<rect x="320" y="210" width="160" height="40" fill="url(#coreGradient)" stroke="#10B981" stroke-width="2" rx="8" opacity="0.9"/>
<text x="400" y="235" text-anchor="middle" font-family="monospace" font-size="18" fill="#1F2937">config/</text>
<!-- database/ -->
<rect x="520" y="210" width="160" height="40" fill="url(#coreGradient)" stroke="#10B981" stroke-width="2" rx="8" opacity="0.9"/>
<text x="600" y="235" text-anchor="middle" font-family="monospace" font-size="18" fill="#1F2937">database/</text>
<!-- Convergence arrows to session -->
<line x1="400" y1="250" x2="400" y2="290" stroke="#666" stroke-width="1" opacity="0.5"/>
<line x1="600" y1="250" x2="450" y2="290" stroke="#666" stroke-width="1" opacity="0.5"/>
<!-- session/ -->
<rect x="350" y="290" width="100" height="40" fill="url(#serviceGradient)" stroke="#8B5CF6" stroke-width="2" rx="8" opacity="0.9"/>
<text x="400" y="315" text-anchor="middle" font-family="monospace" font-size="18" fill="#1F2937">session/</text>
<!-- web_server/ and bidirectional arrow with session -->
<rect x="180" y="290" width="120" height="40" fill="url(#serviceGradient)" stroke="#8B5CF6" stroke-width="2" rx="8" opacity="0.9"/>
<text x="240" y="315" text-anchor="middle" font-family="monospace" font-size="18" fill="#1F2937">web_server/</text>
<line x1="300" y1="310" x2="350" y2="310" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="350" y1="320" x2="300" y2="320" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- Arrow from package_manager to web_server -->
<line x1="200" y1="250" x2="240" y2="290" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- Service Layer branches -->
<line x1="240" y1="330" x2="140" y2="380" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="240" y1="330" x2="260" y2="380" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="240" y1="330" x2="380" y2="380" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="400" y1="330" x2="500" y2="380" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- Feature Modules -->
<!-- channels/ -->
<rect x="80" y="380" width="100" height="40" fill="url(#leafGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="130" y="405" text-anchor="middle" font-family="monospace" font-size="16" fill="#1F2937">channels/</text>
<!-- bot/ -->
<rect x="210" y="380" width="100" height="40" fill="url(#leafGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="260" y="405" text-anchor="middle" font-family="monospace" font-size="16" fill="#1F2937">bot/</text>
<!-- basic/ -->
<rect x="340" y="380" width="100" height="40" fill="url(#leafGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="390" y="405" text-anchor="middle" font-family="monospace" font-size="16" fill="#1F2937">basic/</text>
<!-- auth/ -->
<rect x="470" y="380" width="100" height="40" fill="url(#leafGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="520" y="405" text-anchor="middle" font-family="monospace" font-size="16" fill="#1F2937">auth/</text>
<!-- Convergence to LLM -->
<line x1="130" y1="420" x2="340" y2="470" stroke="#666" stroke-width="1" opacity="0.5"/>
<line x1="260" y1="420" x2="340" y2="470" stroke="#666" stroke-width="1" opacity="0.5"/>
<line x1="390" y1="420" x2="390" y2="470" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<line x1="520" y1="420" x2="430" y2="470" stroke="#666" stroke-width="1" opacity="0.5"/>
<!-- llm/ -->
<rect x="340" y="470" width="100" height="40" fill="url(#serviceGradient)" stroke="#8B5CF6" stroke-width="2" rx="8" opacity="0.9"/>
<text x="390" y="495" text-anchor="middle" font-family="monospace" font-size="18" fill="#1F2937">llm/</text>
<!-- Arrow to context -->
<line x1="390" y1="510" x2="390" y2="540" stroke="#666" stroke-width="2" marker-end="url(#arrow)" opacity="0.6"/>
<!-- context/ -->
<rect x="340" y="540" width="100" height="40" fill="url(#leafGradient)" stroke="#F59E0B" stroke-width="2" rx="8" opacity="0.9"/>
<text x="390" y="565" text-anchor="middle" font-family="monospace" font-size="18" fill="#1F2937">context/</text>
<!-- Legend -->
<g id="legend" transform="translate(580, 480)">
<text x="0" y="0" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#1F2937">Layers:</text>
<rect x="0" y="10" width="15" height="15" fill="url(#mainGradient)" stroke="#3B82F6" stroke-width="1" rx="2" opacity="0.8"/>
<text x="20" y="22" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Entry Point</text>
<rect x="0" y="30" width="15" height="15" fill="url(#coreGradient)" stroke="#10B981" stroke-width="1" rx="2" opacity="0.8"/>
<text x="20" y="42" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Core System</text>
<rect x="0" y="50" width="15" height="15" fill="url(#serviceGradient)" stroke="#8B5CF6" stroke-width="1" rx="2" opacity="0.8"/>
<text x="20" y="62" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Services</text>
<rect x="0" y="70" width="15" height="15" fill="url(#leafGradient)" stroke="#F59E0B" stroke-width="1" rx="2" opacity="0.8"/>
<text x="20" y="82" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Features</text>
</g>
<!-- Dependency Flow Note -->
<text x="50" y="580" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">Arrows indicate compile-time dependencies</text>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

View file

@ -0,0 +1,155 @@
<svg width="900" height="700" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 700" style="max-width: 100%; height: auto;">
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" fill="#666"/>
</marker>
</defs>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-family="Arial, sans-serif" font-size="26" font-weight="bold" fill="#1F2937">BotServer Architecture - Virtual Crates System</text>
<!-- Main Container -->
<rect x="40" y="50" width="820" height="620" fill="none" stroke="#E5E7EB" stroke-width="2" rx="12" stroke-opacity="0.5"/>
<!-- Binary Output -->
<rect x="350" y="70" width="200" height="40" fill="#EBF8FF" stroke="#2563EB" stroke-width="2" rx="8"/>
<text x="450" y="95" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">BotServer Binary</text>
<!-- Compilation Arrow -->
<line x1="450" y1="110" x2="450" y2="140" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)" stroke-dasharray="5,3" opacity="0.6"/>
<text x="470" y="130" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">compiles to</text>
<!-- Core Layer -->
<g id="core-layer">
<rect x="60" y="140" width="780" height="120" fill="#EBF8FF" fill-opacity="0.3" stroke="#2563EB" stroke-width="2" rx="8"/>
<text x="450" y="165" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">Core Engine (src/core/)</text>
<!-- Core Components -->
<rect x="80" y="185" width="140" height="55" fill="white" stroke="#2563EB" stroke-width="1" rx="4"/>
<text x="150" y="205" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">Bootstrap</text>
<text x="150" y="220" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">System Init</text>
<text x="150" y="232" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">Service Start</text>
<rect x="240" y="185" width="140" height="55" fill="white" stroke="#2563EB" stroke-width="1" rx="4"/>
<text x="310" y="205" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">Package Manager</text>
<text x="310" y="220" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">Component Registry</text>
<text x="310" y="232" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">Module Loader</text>
<rect x="400" y="185" width="140" height="55" fill="white" stroke="#2563EB" stroke-width="1" rx="4"/>
<text x="470" y="205" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">Session Manager</text>
<text x="470" y="220" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">Context Handling</text>
<text x="470" y="232" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">State Management</text>
<rect x="560" y="185" width="140" height="55" fill="white" stroke="#2563EB" stroke-width="1" rx="4"/>
<text x="630" y="205" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">Shared State</text>
<text x="630" y="220" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">AppState</text>
<text x="630" y="232" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">Configuration</text>
<rect x="720" y="185" width="100" height="55" fill="white" stroke="#2563EB" stroke-width="1" rx="4"/>
<text x="770" y="205" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">Utils</text>
<text x="770" y="220" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">Helpers</text>
<text x="770" y="232" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">Common</text>
</g>
<!-- Bidirectional Arrow -->
<line x1="450" y1="260" x2="450" y2="290" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)" opacity="0.6"/>
<line x1="460" y1="290" x2="460" y2="260" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)" opacity="0.6"/>
<!-- Virtual Crates Layer (gbapps) -->
<g id="gbapp-layer">
<rect x="60" y="290" width="780" height="180" fill="#D1FAE5" fill-opacity="0.3" stroke="#10B981" stroke-width="2" rx="8"/>
<text x="450" y="315" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">Virtual Crates (gbapp modules in src/)</text>
<!-- BASIC gbapp -->
<rect x="80" y="335" width="170" height="115" fill="white" stroke="#10B981" stroke-width="1" rx="4"/>
<text x="165" y="355" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">basic.gbapp</text>
<text x="165" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">src/basic/</text>
<line x1="90" y1="378" x2="240" y2="378" stroke="#E5E7EB" stroke-width="1"/>
<text x="165" y="393" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• BASIC Interpreter</text>
<text x="165" y="408" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Keywords Registry</text>
<text x="165" y="423" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Script Execution</text>
<text x="165" y="438" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Rhai Engine</text>
<!-- Channels gbapp -->
<rect x="270" y="335" width="170" height="115" fill="white" stroke="#10B981" stroke-width="1" rx="4"/>
<text x="355" y="355" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">channels.gbapp</text>
<text x="355" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">src/channels/</text>
<line x1="280" y1="378" x2="430" y2="378" stroke="#E5E7EB" stroke-width="1"/>
<text x="355" y="393" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• WhatsApp</text>
<text x="355" y="408" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Teams</text>
<text x="355" y="423" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Email</text>
<text x="355" y="438" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Web UI</text>
<!-- Storage gbapp -->
<rect x="460" y="335" width="170" height="115" fill="white" stroke="#10B981" stroke-width="1" rx="4"/>
<text x="545" y="355" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">storage.gbapp</text>
<text x="545" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">src/storage/</text>
<line x1="470" y1="378" x2="620" y2="378" stroke="#E5E7EB" stroke-width="1"/>
<text x="545" y="393" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Knowledge Base</text>
<text x="545" y="408" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Drive Integration</text>
<text x="545" y="423" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Vector DB</text>
<text x="545" y="438" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">• Cache</text>
<!-- Custom gbapp (Your Contribution) -->
<rect x="650" y="335" width="170" height="115" fill="#FEF3C7" stroke="#F59E0B" stroke-width="2" rx="4" stroke-dasharray="5,3"/>
<text x="735" y="355" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#1F2937">your_feature.gbapp</text>
<text x="735" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6B7280">src/your_feature/</text>
<line x1="660" y1="378" x2="810" y2="378" stroke="#E5E7EB" stroke-width="1"/>
<text x="735" y="393" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-style="italic" fill="#6B7280">• Your Keywords</text>
<text x="735" y="408" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-style="italic" fill="#6B7280">• Your Services</text>
<text x="735" y="423" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-style="italic" fill="#6B7280">• Your Models</text>
<text x="735" y="438" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#F59E0B">+ Add yours!</text>
</g>
<!-- Arrow from gbapp to AI -->
<line x1="450" y1="470" x2="450" y2="500" stroke="#666" stroke-width="2" marker-end="url(#arrowhead)" opacity="0.6"/>
<!-- AI/LLM Layer -->
<g id="ai-layer">
<rect x="60" y="500" width="380" height="80" fill="#EDE9FE" fill-opacity="0.3" stroke="#8B5CF6" stroke-width="2" rx="8"/>
<text x="250" y="525" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">AI &amp; LLM Integration</text>
<rect x="80" y="535" width="100" height="35" fill="white" stroke="#8B5CF6" stroke-width="1" rx="4"/>
<text x="130" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">LLM Service</text>
<rect x="195" y="535" width="100" height="35" fill="white" stroke="#8B5CF6" stroke-width="1" rx="4"/>
<text x="245" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">Embeddings</text>
<rect x="310" y="535" width="110" height="35" fill="white" stroke="#8B5CF6" stroke-width="1" rx="4"/>
<text x="365" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">Semantic Search</text>
</g>
<!-- Storage Layer -->
<g id="storage-layer">
<rect x="460" y="500" width="380" height="80" fill="#FEE2E2" fill-opacity="0.3" stroke="#EF4444" stroke-width="2" rx="8"/>
<text x="650" y="525" text-anchor="middle" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#1F2937">Persistence Layer</text>
<rect x="480" y="535" width="85" height="35" fill="white" stroke="#EF4444" stroke-width="1" rx="4"/>
<text x="522" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">Database</text>
<rect x="580" y="535" width="85" height="35" fill="white" stroke="#EF4444" stroke-width="1" rx="4"/>
<text x="622" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">Vector DB</text>
<rect x="680" y="535" width="70" height="35" fill="white" stroke="#EF4444" stroke-width="1" rx="4"/>
<text x="715" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">Drive</text>
<rect x="765" y="535" width="60" height="35" fill="white" stroke="#EF4444" stroke-width="1" rx="4"/>
<text x="795" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#1F2937">Cache</text>
</g>
<!-- Legend -->
<g id="legend" transform="translate(60, 600)">
<text x="0" y="0" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#1F2937">Key Concepts:</text>
<rect x="120" y="-12" width="15" height="15" fill="#D1FAE5" stroke="#10B981" stroke-width="1" rx="2"/>
<text x="140" y="0" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Virtual Crates = Modules in src/</text>
<rect x="320" y="-12" width="15" height="15" fill="#FEF3C7" stroke="#F59E0B" stroke-width="1" rx="2" stroke-dasharray="3,2"/>
<text x="340" y="0" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">Your Contribution Space</text>
<text x="500" y="0" font-family="Arial, sans-serif" font-size="16" fill="#4B5563">All compile to single optimized binary</text>
</g>
<!-- Philosophy Note -->
<text x="450" y="650" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-style="italic" fill="#6B7280">gbapp virtual crates: The bridge between old Node.js packages and new Rust modules</text>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,205 @@
<svg width="800" height="600" viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and effects -->
<defs>
<!-- Gradients for different layers -->
<linearGradient id="clientGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="gatewayGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#06ffa5;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#00d2ff;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="authGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#f5576c;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="businessGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4facfe;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#00f2fe;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="adminGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#fa709a;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#fee140;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="serviceGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#30cfd0;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#330867;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="dbGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#43e97b;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#38f9d7;stop-opacity:0.3" />
</linearGradient>
<!-- Arrow marker -->
<marker id="arrow" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#4a5568" opacity="0.7"/>
</marker>
<!-- Drop shadow filter -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.15"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="800" height="600" fill="#fafafa"/>
<!-- Title -->
<rect x="250" y="10" width="300" height="35" fill="rgba(99, 102, 241, 0.05)" rx="8"/>
<text x="400" y="33" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="24" font-weight="600" fill="#1e293b">
BotServer API Architecture
</text>
<!-- Client Applications Layer -->
<rect x="250" y="60" width="300" height="50" fill="url(#clientGrad)" stroke="#667eea" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="90" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Client Applications
</text>
<!-- Arrow down -->
<path d="M 400 110 L 400 130" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<!-- HTTP/HTTPS Layer -->
<rect x="300" y="130" width="200" height="45" fill="rgba(99, 102, 241, 0.08)" stroke="#8b5cf6" stroke-width="1.5" rx="6" filter="url(#shadow)"/>
<text x="400" y="150" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" font-weight="500" fill="#1e293b">
HTTP/HTTPS
</text>
<text x="400" y="165" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Port 8080
</text>
<!-- Arrow down -->
<path d="M 400 175 L 400 195" stroke="#4a5568" stroke-width="2.5" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<!-- API Gateway -->
<rect x="250" y="195" width="300" height="50" fill="url(#gatewayGrad)" stroke="#00d2ff" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="220" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
API Gateway
</text>
<text x="400" y="235" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/api/*
</text>
<!-- Arrows to endpoint groups -->
<path d="M 400 245 L 400 260 L 180 260 L 180 280" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<path d="M 400 245 L 400 280" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<path d="M 400 245 L 400 260 L 620 260 L 620 280" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Auth Endpoints -->
<rect x="80" y="280" width="200" height="80" fill="url(#authGrad)" stroke="#f5576c" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="180" y="305" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Auth Endpoints
</text>
<text x="180" y="325" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/auth/login
</text>
<text x="180" y="340" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/auth/logout
</text>
<text x="180" y="355" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/auth/token
</text>
<!-- Business Endpoints -->
<rect x="300" y="280" width="200" height="80" fill="url(#businessGrad)" stroke="#00f2fe" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="305" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Business Endpoints
</text>
<text x="400" y="325" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/files/* • /users/*
</text>
<text x="400" y="340" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/groups/* • /tasks/*
</text>
<text x="400" y="355" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/sessions/*
</text>
<!-- Admin Endpoints -->
<rect x="520" y="280" width="200" height="80" fill="url(#adminGrad)" stroke="#fa709a" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="620" y="305" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Admin Endpoints
</text>
<text x="620" y="325" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/admin/*
</text>
<text x="620" y="340" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/monitoring
</text>
<text x="620" y="355" text-anchor="middle" font-family="system-ui, monospace" font-size="16" fill="#475569">
/analytics
</text>
<!-- Arrows converging to service layer -->
<path d="M 180 360 L 180 380 L 400 380 L 400 400" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<path d="M 400 360 L 400 400" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<path d="M 620 360 L 620 380 L 400 380 L 400 400" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<!-- Service Layer -->
<rect x="250" y="400" width="300" height="70" fill="url(#serviceGrad)" stroke="#330867" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="425" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Service Layer
</text>
<text x="400" y="445" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Session Manager
</text>
<text x="400" y="460" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
• Auth Service • Bot Service
</text>
<!-- Arrows to databases -->
<path d="M 400 470 L 400 485 L 180 485 L 180 500" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<path d="M 400 470 L 400 500" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<path d="M 400 470 L 400 485 L 620 485 L 620 500" stroke="#4a5568" stroke-width="2" fill="none" marker-end="url(#arrow)" opacity="0.7"/>
<!-- PostgreSQL -->
<rect x="80" y="500" width="200" height="70" fill="url(#dbGrad)" stroke="#38f9d7" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="180" y="525" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
PostgreSQL
</text>
<text x="180" y="545" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Database
</text>
<text x="180" y="560" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
Sessions • Users • Config
</text>
<!-- Valkey Cache -->
<rect x="300" y="500" width="200" height="70" fill="url(#dbGrad)" stroke="#38f9d7" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="400" y="525" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Valkey
</text>
<text x="400" y="545" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Cache
</text>
<text x="400" y="560" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
Semantic • Session • Temp
</text>
<!-- Qdrant -->
<rect x="520" y="500" width="200" height="70" fill="url(#dbGrad)" stroke="#38f9d7" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="620" y="525" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Qdrant
</text>
<text x="620" y="545" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Vectors
</text>
<text x="620" y="560" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">
Embeddings • Search
</text>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,224 @@
<svg width="600" height="700" viewBox="0 0 600 700" xmlns="http://www.w3.org/2000/svg" style="max-width: 100%; height: auto;">
<!-- Define gradients and effects -->
<defs>
<!-- Gradients for different stages -->
<linearGradient id="requestGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="rateLimitGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f59e0b;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#d97706;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="authGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#ef4444;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#dc2626;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="routeGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#8b5cf6;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#7c3aed;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="validateGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#06b6d4;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#0891b2;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="processGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#10b981;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#059669;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="formatGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4facfe;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#00f2fe;stop-opacity:0.3" />
</linearGradient>
<linearGradient id="responseGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#43e97b;stop-opacity:0.2" />
<stop offset="100%" style="stop-color:#38f9d7;stop-opacity:0.3" />
</linearGradient>
<!-- Success path gradient -->
<linearGradient id="successPath" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#10b981;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#34d399;stop-opacity:0.3" />
</linearGradient>
<!-- Failure path gradient -->
<linearGradient id="failPath" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#ef4444;stop-opacity:0.8" />
<stop offset="100%" style="stop-color:#f87171;stop-opacity:0.3" />
</linearGradient>
<!-- Arrow markers -->
<marker id="arrow" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#4a5568" opacity="0.7"/>
</marker>
<marker id="arrowSuccess" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#10b981" opacity="0.8"/>
</marker>
<marker id="arrowFail" markerWidth="12" markerHeight="12" refX="11" refY="6" orient="auto">
<path d="M 0 0 L 12 6 L 0 12 L 3 6 Z" fill="#ef4444" opacity="0.8"/>
</marker>
<!-- Drop shadow filter -->
<filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="0" dy="2" result="offsetblur"/>
<feComponentTransfer>
<feFuncA type="linear" slope="0.15"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect x="0" y="0" width="600" height="700" fill="#fafafa"/>
<!-- Title -->
<rect x="150" y="10" width="300" height="35" fill="rgba(99, 102, 241, 0.05)" rx="8"/>
<text x="300" y="33" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="22" font-weight="600" fill="#1e293b">
API Request Flow
</text>
<!-- HTTP Request -->
<rect x="200" y="60" width="200" height="50" fill="url(#requestGrad)" stroke="#667eea" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="300" y="85" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
HTTP Request
</text>
<text x="300" y="100" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Client → Server
</text>
<!-- Arrow down -->
<path d="M 300 110 L 300 140" stroke="url(#successPath)" stroke-width="3" fill="none" marker-end="url(#arrowSuccess)" opacity="0.7"/>
<!-- Rate Limit -->
<rect x="200" y="140" width="200" height="60" fill="url(#rateLimitGrad)" stroke="#f59e0b" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="300" y="165" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Rate Limit
</text>
<text x="300" y="185" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Check request limits
</text>
<!-- Pass/Fail paths -->
<path d="M 300 200 L 300 230" stroke="url(#successPath)" stroke-width="3" fill="none" marker-end="url(#arrowSuccess)" opacity="0.7"/>
<text x="320" y="215" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#059669">Pass</text>
<path d="M 400 170 L 480 170 L 480 650" stroke="url(#failPath)" stroke-width="2" stroke-dasharray="5,3" fill="none" marker-end="url(#arrowFail)" opacity="0.5"/>
<text x="420" y="165" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" fill="#dc2626">429 Too Many</text>
<!-- Auth -->
<rect x="200" y="230" width="200" height="60" fill="url(#authGrad)" stroke="#ef4444" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="300" y="255" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Auth
</text>
<text x="300" y="275" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Validate token/session
</text>
<!-- Pass/Fail paths -->
<path d="M 300 290 L 300 320" stroke="url(#successPath)" stroke-width="3" fill="none" marker-end="url(#arrowSuccess)" opacity="0.7"/>
<text x="320" y="305" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#059669">Valid</text>
<path d="M 400 260 L 460 260 L 460 650" stroke="url(#failPath)" stroke-width="2" stroke-dasharray="5,3" fill="none" marker-end="url(#arrowFail)" opacity="0.5"/>
<text x="420" y="255" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" fill="#dc2626">401 Unauthorized</text>
<!-- Route -->
<rect x="200" y="320" width="200" height="60" fill="url(#routeGrad)" stroke="#8b5cf6" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="300" y="345" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Route
</text>
<text x="300" y="365" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Match endpoint pattern
</text>
<!-- Arrow down -->
<path d="M 300 380 L 300 410" stroke="url(#successPath)" stroke-width="3" fill="none" marker-end="url(#arrowSuccess)" opacity="0.7"/>
<path d="M 400 350 L 440 350 L 440 650" stroke="url(#failPath)" stroke-width="2" stroke-dasharray="5,3" fill="none" marker-end="url(#arrowFail)" opacity="0.5"/>
<text x="420" y="345" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" fill="#dc2626">404 Not Found</text>
<!-- Validate -->
<rect x="200" y="410" width="200" height="60" fill="url(#validateGrad)" stroke="#06b6d4" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="300" y="435" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Validate
</text>
<text x="300" y="455" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Check request body
</text>
<!-- Pass/Fail paths -->
<path d="M 300 470 L 300 500" stroke="url(#successPath)" stroke-width="3" fill="none" marker-end="url(#arrowSuccess)" opacity="0.7"/>
<text x="320" y="485" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#059669">Valid</text>
<path d="M 400 440 L 420 440 L 420 650" stroke="url(#failPath)" stroke-width="2" stroke-dasharray="5,3" fill="none" marker-end="url(#arrowFail)" opacity="0.5"/>
<text x="425" y="435" text-anchor="start" font-family="system-ui, sans-serif" font-size="16" fill="#dc2626">400 Bad Request</text>
<!-- Process -->
<rect x="200" y="500" width="200" height="60" fill="url(#processGrad)" stroke="#10b981" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="300" y="525" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Process
</text>
<text x="300" y="545" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Execute business logic
</text>
<!-- Arrow down -->
<path d="M 300 560 L 300 590" stroke="url(#successPath)" stroke-width="3" fill="none" marker-end="url(#arrowSuccess)" opacity="0.7"/>
<!-- Format -->
<rect x="200" y="590" width="200" height="60" fill="url(#formatGrad)" stroke="#00f2fe" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="300" y="615" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
Format
</text>
<text x="300" y="635" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
JSON response
</text>
<!-- Arrow down -->
<path d="M 300 650 L 300 680" stroke="url(#successPath)" stroke-width="3" fill="none" marker-end="url(#arrowSuccess)" opacity="0.7"/>
<!-- HTTP Response -->
<rect x="200" y="680" width="200" height="50" fill="url(#responseGrad)" stroke="#38f9d7" stroke-width="2" rx="8" filter="url(#shadow)"/>
<text x="300" y="705" text-anchor="middle" font-family="system-ui, sans-serif" font-size="20" font-weight="600" fill="#1e293b">
HTTP Response
</text>
<text x="300" y="720" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#475569">
Server → Client
</text>
<!-- Error Response box -->
<rect x="410" y="650" width="100" height="30" fill="rgba(239, 68, 68, 0.1)" stroke="#ef4444" stroke-width="1.5" rx="6"/>
<text x="460" y="670" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" font-weight="500" fill="#dc2626">
Error Response
</text>
<!-- Side labels -->
<g transform="translate(50, 380)">
<text x="0" y="0" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#64748b" transform="rotate(-90)">
Request Pipeline
</text>
</g>
<!-- Status indicators -->
<g transform="translate(80, 150)">
<circle cx="0" cy="0" r="4" fill="#10b981"/>
<text x="10" y="4" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Success path</text>
</g>
<g transform="translate(80, 170)">
<circle cx="0" cy="0" r="4" fill="#ef4444"/>
<text x="10" y="4" font-family="system-ui, sans-serif" font-size="16" fill="#475569">Error path</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

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