This commit is contained in:
dataeaseShu
2025-07-31 14:22:55 +08:00
6 changed files with 106 additions and 21 deletions
+21 -5
View File
@@ -15,17 +15,33 @@ SQLBot 是一款基于大模型和 RAG 的智能问数系统。SQLBot 的优势
## 快速开始
准备一台 Linux 机器,执行一键安装脚本:
### 安装部署
```
docker run -d --name=sqlbot --restart=always -p 8080:8080 -v ~/.sqlbot:/var/lib/postgresql/data -v ~/.python-packages:/opt/sqlbot/app/sandbox/python-packages registry.fit2cloud.com/sqlbot/sqlbot
准备一台 Linux 服务器,执行以下一键安装脚本。
在运行 SQLBot 前,请确保已安装好 [Docker](https://docs.docker.com/get-docker/) 和 [Docker Compose](https://docs.docker.com/compose/install/)。
# 用户名: admin
# 密码: SQLBot@123..
```bash
# 创建目录
mkdir -p /opt/sqlbot
cd /opt/sqlbot
# 下载 docker-compose.yaml
curl -o docker-compose.yaml https://raw.githubusercontent.com/dataease/SQLBot/main/docker-compose.yaml
# 启动服务
docker compose up -d
```
你也可以通过 [1Panel 应用商店](https://apps.fit2cloud.com/1panel) 快速部署 SQLBot;
### 访问方式
- 在浏览器中打开: http://<你的服务器IP>:8000/
- 用户名: admin
- 密码: SQLBot@123456
### 联系我们
如你有更多问题,可以加入我们的技术交流群与我们交流。
TBD: 交流群二维码
+14
View File
@@ -1,3 +1,4 @@
from functools import lru_cache
import json
from abc import ABC, abstractmethod
from typing import Optional, Dict, Any, Type
@@ -21,6 +22,18 @@ class LLMConfig(BaseModel):
api_key: Optional[str] = None
api_base_url: Optional[str] = None
additional_params: Dict[str, Any] = {}
class Config:
frozen = True
def __hash__(self):
return hash((
self.model_id,
self.model_type,
self.model_name,
self.api_key,
self.api_base_url,
frozenset(self.additional_params.items())
))
class BaseLLM(ABC):
@@ -66,6 +79,7 @@ class LLMFactory:
}
@classmethod
@lru_cache(maxsize=32)
def create_llm(cls, config: LLMConfig) -> BaseLLM:
llm_class = cls._llm_types.get(config.model_type)
if not llm_class:
+1 -5
View File
@@ -27,12 +27,8 @@ async def check_llm(info: AiModelCreator, trans: Trans):
additional_params=additional_params,
)
llm_instance = LLMFactory.create_llm(config)
res = llm_instance.llm.stream("who are you?")
for chunk in res:
async for chunk in llm_instance.llm.astream("1+1=?"):
if chunk and chunk.content:
SQLBotLogUtil.info(chunk)
yield json.dumps({"content": chunk.content}) + "\n"
except Exception as e:
+62
View File
@@ -0,0 +1,62 @@
services:
sqlbot:
image: dataease/sqlbot:v0.9.3
container_name: sqlbot
restart: always
networks:
- sqlbot-network
ports:
- 8000:8000
- 8001:8001
environment:
# Database configuration
POSTGRES_SERVER: sqlbot-db
POSTGRES_PORT: 5432
POSTGRES_DB: sqlbot
POSTGRES_USER: sqlbot
POSTGRES_PASSWORD: sqlbot
# Project basic settings
PROJECT_NAME: "SQLBot"
DEFAULT_PWD: "SQLBot@123456"
# MCP settings
MCP_IMAGE_PATH: /opt/sqlbot/images
MCP_IMAGE_HOST: http://localhost:3000
SERVER_IMAGE_HOST: https://sqlbot.fit2cloud.cn/images/
# Auth & Security
TOKEN_KEY: "X-SQLBOT-TOKEN"
ASSISTANT_TOKEN_KEY: "X-SQLBOT-ASSISTANT-TOKEN"
SECRET_KEY: y5txe1mRmS_JpOrUzFzHEu-kIQn3lf7ll0AOv9DQh0s
# CORS settings
BACKEND_CORS_ORIGINS: "http://localhost,http://localhost:5173,https://localhost,https://localhost:5173"
# Logging
LOG_LEVEL: "INFO"
LOG_DIR: "/opt/sqlbot/logs"
LOG_FORMAT: "%(asctime)s - %(name)s - %(levelname)s:%(lineno)d - %(message)s"
SQL_DEBUG: False
volumes:
- ./data/sqlbot/excel:/opt/sqlbot/data/excel
- ./data/sqlbot/images:/opt/sqlbot/images
- ./data/sqlbot/logs:/opt/sqlbot/logs
depends_on:
sqlbot-db:
condition: service_healthy
sqlbot-db:
image: postgres:17.5
container_name: sqlbot-db
restart: always
networks:
- sqlbot-network
volumes:
- ./data/postgresql:/var/lib/postgresql/data
environment:
POSTGRES_DB: sqlbot
POSTGRES_USER: sqlbot
POSTGRES_PASSWORD: sqlbot
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 3s
timeout: 5s
retries: 5
networks:
sqlbot-network:
+7 -7
View File
@@ -1,7 +1,7 @@
{
"menu": {
"Data Q&A": "Data Q&A",
"Data Connections": "Data Connections",
"Data Connections": "Data Sources",
"Dashboard": "Dashboard",
"AI Model Configuration": "AI Model Configuration"
},
@@ -98,8 +98,8 @@
},
"qa": {
"new_chat": "New Chat",
"start_sqlbot": "Start SQLBot",
"title": "Smart Data Query",
"start_sqlbot": "New Chat",
"title": "Data Q&A",
"placeholder": "Please enter your question",
"ask": "Ask",
"loading": "Loading...",
@@ -111,7 +111,7 @@
"select_datasource": "Select Data Source",
"view_more": "View More",
"selected_datasource": "Selected Data Source",
"empty_datasource": "No data sources available. Please create one before starting Smart Data Query!",
"empty_datasource": "No data sources available. Please create one before starting Data Q&A!",
"datasource_not_exist": "Data source does not exist",
"guess_u_ask": "You might want to ask:",
"continue_to_ask": "Continue asking:",
@@ -130,7 +130,7 @@
"copied": "Copied"
},
"ds": {
"title": "Data Source",
"title": "Data Sources",
"add": "Add Data Source",
"delete": "Delete Data Source",
"name": "Data Source Name",
@@ -225,7 +225,7 @@
"search": "Search",
"all_types": "All types",
"new_data_source": "New data source",
"open_query": "Open query",
"open_query": "New Chat",
"edit": "Edit",
"source_connection_failed": "Data source connection failed",
"confirm": "Confirm",
@@ -365,7 +365,7 @@
"add_successfully": "Add successfully",
"member_management": "Member management",
"permission_configuration": "Permission configuration",
"set": "Set",
"set": "Settings",
"operate_with_caution": "After deletion, the users under the workspace will be removed and all resources will be deleted. Please operate with caution."
},
"permission": {
+1 -4
View File
@@ -35,7 +35,7 @@ const activeName = ref('')
const activeType = ref('')
const modelFormRef = ref()
const cardRefs = ref<any[]>([])
// const showCardError = ref(true) // if you don`t want card mask error, just change this to false
const showCardError = ref(false) // if you don`t want card mask error, just change this to false
reactive({
form: {
id: '',
@@ -71,8 +71,6 @@ const defaultModelListWithSearch = computed(() => {
})
const modelCheckHandler = async (item: any) => {
console.log(item)
/**
const response = await modelApi.check(item)
const reader = response.body.getReader()
const decoder = new TextDecoder()
@@ -112,7 +110,6 @@ const modelCheckHandler = async (item: any) => {
currentRef?.showErrorMask(checkMsg)
}
})
*/
}
const duplicateName = async (item: any) => {
const res = await modelApi.queryAll()