Commit 9601a1a8 by Archer Committed by GitHub

fix(chat): restore v1 completion value types (#7330)

* fix(chat): restore v1 completion value types

* submodule

* doc

* doc

* perf: base64
parent 8d29adcd
......@@ -180,7 +180,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -183,7 +183,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
# ${{vec.config}}
x-vec-config: &x-vec-config # ${{vec.config}}
services:
# ${{vec.db}}
......@@ -185,16 +185,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -239,7 +239,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -262,7 +262,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -301,7 +301,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -356,10 +356,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -401,7 +401,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -430,7 +430,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -448,7 +448,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -171,7 +171,7 @@ These variables are mainly validated by `packages/service/env.ts` and apply to `
| `PASSWORD_LOGIN_LOCK_SECONDS` | `120` | Lock duration after failed password login attempts, in seconds. |
| `MAX_LOGIN_SESSION` | `10` | Maximum login clients per account. |
| `ALLOWED_ORIGINS` | Empty | Allowed CORS origins. Use commas to separate multiple origins. Empty allows all origins by default. |
| `MULTIPLE_DATA_TO_BASE64` | `true` | Whether images are forced into base64 before being sent to models. |
| `MULTIPLE_DATA_TO_BASE64` | `false` | Whether images are forced into base64 before being sent to models. |
| `DISABLE_CACHE` | `false` | Whether system cache hits are disabled, mainly for debugging. |
| `HTTP_PROXY` | Empty | Outbound HTTP proxy for Node and workers. |
| `HTTPS_PROXY` | Empty | Outbound HTTPS proxy for Node and workers. |
......
......@@ -171,7 +171,7 @@ description: projects/app、projects/code-sandbox 与 pro/admin 环境变量说
| `PASSWORD_LOGIN_LOCK_SECONDS` | `120` | 密码登录错误后的锁定时长,单位秒。 |
| `MAX_LOGIN_SESSION` | `10` | 单账号最大登录客户端数量。 |
| `ALLOWED_ORIGINS` | 空 | 允许跨域来源,多个来源使用英文逗号分隔;为空默认允许所有跨域。 |
| `MULTIPLE_DATA_TO_BASE64` | `true` | 是否强制将图片转成 base64 传递给模型。 |
| `MULTIPLE_DATA_TO_BASE64` | `false` | 是否强制将图片转成 base64 传递给模型。 |
| `DISABLE_CACHE` | `false` | 是否关闭系统缓存命中,主要用于调试。 |
| `HTTP_PROXY` | 空 | Node/worker 出站 HTTP 代理。 |
| `HTTPS_PROXY` | 空 | Node/worker 出站 HTTPS 代理。 |
......
---
title: 'V4.15.2(进行中)'
title: 'V4.15.2'
description: 'FastGPT V4.15.2 更新说明'
---
......
---
title: 'V4.15.3'
description: 'FastGPT V4.15.3 Release Notes'
---
## 📦 Upgrade Guide
### Image Updates
- Update the fastgpt-app (FastGPT main service) image tag to v4.15.3.
- Update the fastgpt-pro (FastGPT commercial edition) image tag to v4.15.3.
## 🐛 Fixes
1. Fixed rapid polling in the WeChat publishing channel when the WeChat API returns certain errors.
2. Restored the legacy `type` field for `/v1/chat/completions` responses when `stream=false` and `detail=true`.
---
title: 'V4.15.3'
description: 'FastGPT V4.15.3 更新说明'
---
## 📦 升级指南
### 镜像变更
- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.15.3
- 更新 fastgpt-pro(fastgpt 商业版) 镜像 tag: v4.15.3
## 🐛 修复
1. 微信发布渠道,微信接口特殊异常时,会导致快速轮询。
2. v1 接口 stream=false,detail=true,补回 type 兼容。
{
"title": "4.15.x",
"description": "",
"pages": ["4152", "4151", "41500", "41507", "41506", "41505", "41504", "41503", "41502", "41501"]
"pages": ["4153", "4152", "4151", "41500", "41507", "41506", "41505", "41504", "41503", "41502", "41501"]
}
{
"title": "4.15.x",
"description": "",
"pages": ["4152", "4151", "41500", "41507", "41506", "41505", "41504", "41503", "41502", "41501"]
"pages": ["4153", "4152", "4151", "41500", "41507", "41506", "41505", "41504", "41503", "41502", "41501"]
}
......@@ -162,6 +162,7 @@ description: FastGPT Toc
- [/en/self-host/upgrading/4-15/41507](/en/self-host/upgrading/4-15/41507)
- [/en/self-host/upgrading/4-15/4151](/en/self-host/upgrading/4-15/4151)
- [/en/self-host/upgrading/4-15/4152](/en/self-host/upgrading/4-15/4152)
- [/en/self-host/upgrading/4-15/4153](/en/self-host/upgrading/4-15/4153)
- [/en/self-host/upgrading/outdated/40](/en/self-host/upgrading/outdated/40)
- [/en/self-host/upgrading/outdated/41](/en/self-host/upgrading/outdated/41)
- [/en/self-host/upgrading/outdated/4100](/en/self-host/upgrading/outdated/4100)
......
......@@ -165,6 +165,7 @@ description: FastGPT 文档目录
- [/self-host/upgrading/4-15/41507](/self-host/upgrading/4-15/41507)
- [/self-host/upgrading/4-15/4151](/self-host/upgrading/4-15/4151)
- [/self-host/upgrading/4-15/4152](/self-host/upgrading/4-15/4152)
- [/self-host/upgrading/4-15/4153](/self-host/upgrading/4-15/4153)
- [/self-host/upgrading/outdated/40](/self-host/upgrading/outdated/40)
- [/self-host/upgrading/outdated/41](/self-host/upgrading/outdated/41)
- [/self-host/upgrading/outdated/4100](/self-host/upgrading/outdated/4100)
......
......@@ -123,16 +123,16 @@
"content/guide/dataset/third-party/yuque_dataset.mdx": "2026-05-07T15:06:40+08:00",
"content/guide/dataset/websync.en.mdx": "2026-05-07T15:06:40+08:00",
"content/guide/dataset/websync.mdx": "2026-05-07T15:06:40+08:00",
"content/guide/getting-started/index.en.mdx": "2026-07-17T13:35:26+08:00",
"content/guide/getting-started/index.mdx": "2026-07-17T13:35:26+08:00",
"content/guide/getting-started/index.en.mdx": "2026-07-17T19:17:14+08:00",
"content/guide/getting-started/index.mdx": "2026-07-17T19:17:14+08:00",
"content/guide/getting-started/quick-start.en.mdx": "2026-07-01T17:20:32+08:00",
"content/guide/getting-started/quick-start.mdx": "2026-07-01T17:20:32+08:00",
"content/guide/index.en.mdx": "2026-05-07T15:06:40+08:00",
"content/guide/index.mdx": "2026-05-07T15:06:40+08:00",
"content/guide/version/cloud/faq.en.mdx": "2026-07-17T13:35:26+08:00",
"content/guide/version/cloud/faq.mdx": "2026-07-17T13:35:26+08:00",
"content/guide/version/cloud/intro.en.mdx": "2026-07-17T13:35:26+08:00",
"content/guide/version/cloud/intro.mdx": "2026-07-17T13:35:26+08:00",
"content/guide/version/cloud/faq.en.mdx": "2026-07-17T19:17:14+08:00",
"content/guide/version/cloud/faq.mdx": "2026-07-17T19:17:14+08:00",
"content/guide/version/cloud/intro.en.mdx": "2026-07-17T19:17:14+08:00",
"content/guide/version/cloud/intro.mdx": "2026-07-17T19:17:14+08:00",
"content/guide/version/cloud/privacy.en.mdx": "2026-05-07T15:06:40+08:00",
"content/guide/version/cloud/privacy.mdx": "2026-05-07T15:06:40+08:00",
"content/guide/version/cloud/terms.en.mdx": "2026-05-07T15:06:40+08:00",
......@@ -167,8 +167,8 @@
"content/plugin/model-presets.mdx": "2026-06-04T16:10:15+08:00",
"content/plugin/system-tool-development.en.mdx": "2026-07-02T11:54:55+08:00",
"content/plugin/system-tool-development.mdx": "2026-07-02T11:54:55+08:00",
"content/self-host/config/env.en.mdx": "2026-07-17T11:33:16+08:00",
"content/self-host/config/env.mdx": "2026-07-17T11:33:16+08:00",
"content/self-host/config/env.en.mdx": "2026-07-17T19:17:14+08:00",
"content/self-host/config/env.mdx": "2026-07-17T19:17:14+08:00",
"content/self-host/config/model/intro.en.mdx": "2026-06-04T16:10:15+08:00",
"content/self-host/config/model/intro.mdx": "2026-06-04T16:10:15+08:00",
"content/self-host/config/model/minimax.en.mdx": "2026-06-03T10:40:17+08:00",
......@@ -209,8 +209,8 @@
"content/self-host/deploy/sealos.mdx": "2026-06-30T22:10:03+08:00",
"content/self-host/design/dataset.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/design/dataset.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/dev.en.mdx": "2026-07-17T13:35:26+08:00",
"content/self-host/dev.mdx": "2026-07-17T13:35:26+08:00",
"content/self-host/dev.en.mdx": "2026-07-17T19:17:14+08:00",
"content/self-host/dev.mdx": "2026-07-17T19:17:14+08:00",
"content/self-host/index.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/index.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/migration/docker_db.en.mdx": "2026-04-26T21:08:47+08:00",
......@@ -320,8 +320,10 @@
"content/self-host/upgrading/4-15/41507.mdx": "2026-06-30T17:31:43+08:00",
"content/self-host/upgrading/4-15/4151.en.mdx": "2026-07-07T21:14:28+08:00",
"content/self-host/upgrading/4-15/4151.mdx": "2026-07-07T21:14:28+08:00",
"content/self-host/upgrading/4-15/4152.en.mdx": "2026-07-17T16:16:34+08:00",
"content/self-host/upgrading/4-15/4152.mdx": "2026-07-17T17:55:20+08:00",
"content/self-host/upgrading/4-15/4152.en.mdx": "2026-07-17T19:17:14+08:00",
"content/self-host/upgrading/4-15/4152.mdx": "2026-07-17T19:34:15+08:00",
"content/self-host/upgrading/4-15/4153.en.mdx": "2026-07-18T11:22:45+08:00",
"content/self-host/upgrading/4-15/4153.mdx": "2026-07-18T11:22:45+08:00",
"content/self-host/upgrading/outdated/40.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/outdated/40.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/outdated/41.en.mdx": "2026-04-26T21:08:47+08:00",
......@@ -462,6 +464,6 @@
"content/self-host/upgrading/outdated/499.mdx": "2026-05-07T15:06:40+08:00",
"content/self-host/upgrading/upgrade-intruction.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/upgrade-intruction.mdx": "2026-04-26T21:08:47+08:00",
"content/toc.en.mdx": "2026-07-08T22:37:19+08:00",
"content/toc.mdx": "2026-07-06T22:53:13+08:00"
"content/toc.en.mdx": "2026-07-18T11:22:45+08:00",
"content/toc.mdx": "2026-07-18T11:22:45+08:00"
}
\ No newline at end of file
......@@ -238,7 +238,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -216,7 +216,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -200,7 +200,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -198,7 +198,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -203,7 +203,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -179,7 +179,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -238,7 +238,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -216,7 +216,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -200,7 +200,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -198,7 +198,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -203,7 +203,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -179,7 +179,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -240,7 +240,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -218,7 +218,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -202,7 +202,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -200,7 +200,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -205,7 +205,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -183,7 +183,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -240,7 +240,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -218,7 +218,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -202,7 +202,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -200,7 +200,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -205,7 +205,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -183,7 +183,7 @@ services:
# Invoke 反向调用 JWT 密钥,至少 32 位
INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min
# 强制将图片转成 base64 传递给模型
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
# ==================== 服务地址与集成 ====================
# plugin 地址
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,10 +165,10 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
MILVUS_ADDRESS: http://fastgpt-vector:19530
x-vec-config: &x-vec-config # MILVUS_ADDRESS: http://fastgpt-vector:19530
MILVUS_TOKEN: none
services:
fastgpt-milvus-minio:
container_name: fastgpt-milvus-minio
......@@ -242,16 +242,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -296,7 +296,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -319,7 +319,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -359,7 +359,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -414,10 +414,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -459,7 +459,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -488,7 +488,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -506,7 +506,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
OCEANBASE_URL: mysql://root%40tenantname:tenantpassword@fastgpt-vector:2881/mysql
x-vec-config: &x-vec-config # OCEANBASE_URL: mysql://root%40tenantname:tenantpassword@fastgpt-vector:2881/mysql
services:
fastgpt-vector:
......@@ -220,16 +220,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -274,7 +274,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -297,7 +297,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -337,7 +337,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -392,10 +392,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -437,7 +437,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -466,7 +466,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -484,7 +484,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
OPENGAUSS_URL: postgresql://gaussdb:FastGPT@123@fastgpt-vector:5432/fastgpt
x-vec-config: &x-vec-config # OPENGAUSS_URL: postgresql://gaussdb:FastGPT@123@fastgpt-vector:5432/fastgpt
services:
fastgpt-vector:
......@@ -204,16 +204,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -258,7 +258,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -281,7 +281,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -321,7 +321,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -376,10 +376,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -421,7 +421,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -450,7 +450,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -468,7 +468,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
PG_URL: postgresql://username:password@fastgpt-vector:5432/postgres
x-vec-config: &x-vec-config # PG_URL: postgresql://username:password@fastgpt-vector:5432/postgres
services:
fastgpt-vector:
......@@ -202,16 +202,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -256,7 +256,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -279,7 +279,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -319,7 +319,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -374,10 +374,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -419,7 +419,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -448,7 +448,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -466,7 +466,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
SEEKDB_URL: mysql://root:seekdbpassword@fastgpt-vector:2881/mysql
x-vec-config: &x-vec-config # SEEKDB_URL: mysql://root:seekdbpassword@fastgpt-vector:2881/mysql
services:
fastgpt-vector:
......@@ -207,16 +207,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -261,7 +261,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -284,7 +284,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -324,7 +324,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -379,10 +379,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -424,7 +424,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -453,7 +453,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -471,7 +471,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,10 +165,10 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
MILVUS_ADDRESS: zilliz_cloud_address
x-vec-config: &x-vec-config # MILVUS_ADDRESS: zilliz_cloud_address
MILVUS_TOKEN: zilliz_cloud_token
services:
fastgpt-mongo:
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mongo:5.0.32 # cpu 不支持 AVX 时候使用 4.4.29
......@@ -185,16 +185,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -239,7 +239,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -262,7 +262,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -300,7 +300,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -355,10 +355,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -400,7 +400,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -429,7 +429,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -447,7 +447,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,10 +165,10 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
MILVUS_ADDRESS: http://fastgpt-vector:19530
x-vec-config: &x-vec-config # MILVUS_ADDRESS: http://fastgpt-vector:19530
MILVUS_TOKEN: none
services:
fastgpt-milvus-minio:
container_name: fastgpt-milvus-minio
......@@ -242,16 +242,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -296,7 +296,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -319,7 +319,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -359,7 +359,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -414,10 +414,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -459,7 +459,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -488,7 +488,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -506,7 +506,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
OCEANBASE_URL: mysql://root%40tenantname:tenantpassword@fastgpt-vector:2881/mysql
x-vec-config: &x-vec-config # OCEANBASE_URL: mysql://root%40tenantname:tenantpassword@fastgpt-vector:2881/mysql
services:
fastgpt-vector:
......@@ -220,16 +220,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -274,7 +274,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -297,7 +297,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -337,7 +337,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -392,10 +392,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -437,7 +437,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -466,7 +466,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -484,7 +484,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
OPENGAUSS_URL: postgresql://gaussdb:FastGPT@123@fastgpt-vector:5432/fastgpt
x-vec-config: &x-vec-config # OPENGAUSS_URL: postgresql://gaussdb:FastGPT@123@fastgpt-vector:5432/fastgpt
services:
fastgpt-vector:
......@@ -204,16 +204,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -258,7 +258,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -281,7 +281,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -321,7 +321,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -376,10 +376,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -421,7 +421,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -450,7 +450,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -468,7 +468,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
PG_URL: postgresql://username:password@fastgpt-vector:5432/postgres
x-vec-config: &x-vec-config # PG_URL: postgresql://username:password@fastgpt-vector:5432/postgres
services:
fastgpt-vector:
......@@ -202,16 +202,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -256,7 +256,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -279,7 +279,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -319,7 +319,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -374,10 +374,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -419,7 +419,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -448,7 +448,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -466,7 +466,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,8 +165,8 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
SEEKDB_URL: mysql://root:seekdbpassword@fastgpt-vector:2881/mysql
x-vec-config: &x-vec-config # SEEKDB_URL: mysql://root:seekdbpassword@fastgpt-vector:2881/mysql
services:
fastgpt-vector:
......@@ -207,16 +207,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -261,7 +261,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -284,7 +284,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -324,7 +324,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -379,10 +379,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -424,7 +424,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -453,7 +453,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -471,7 +471,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -5,23 +5,23 @@
# - 建议修改账密后再运行
# root 默认密码(重启后会强制重置该密码成环境变量值)
x-default-root-psw: &x-default-root-psw "1234"
x-default-root-psw: &x-default-root-psw '1234'
# 系统最高密钥凭证
x-system-key: &x-system-key "fastgpt-xxx"
x-system-key: &x-system-key 'fastgpt-xxx'
# 文件阅读 token 密钥
x-file-token-key: &x-file-token-key "filetokenkey"
x-file-token-key: &x-file-token-key 'filetokenkey'
# 密钥加密 key
x-aes256-secret-key: &x-aes256-secret-key "fastgptsecret"
x-aes256-secret-key: &x-aes256-secret-key 'fastgptsecret'
# Invoke 反向调用 JWT 密钥,至少 32 位
x-invoke-token-secret: &x-invoke-token-secret "fastgpt_invoke_token_secret_32_chars_min"
x-invoke-token-secret: &x-invoke-token-secret 'fastgpt_invoke_token_secret_32_chars_min'
# plugin auth token,v4.15 plugin 服务要求至少 32 位
x-plugin-auth-token: &x-plugin-auth-token "fastgpt-plugin-token-please-change"
x-plugin-auth-token: &x-plugin-auth-token 'fastgpt-plugin-token-please-change'
# code sandbox token
x-code-sandbox-token: &x-code-sandbox-token "codesandbox"
x-code-sandbox-token: &x-code-sandbox-token 'codesandbox'
# agent sandbox proxy secret,必须与 FastGPT 主站环境变量保持一致,且至少 32 位
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret "default_fastgpt_agent_sandbox_proxy_secret"
x-agent-sandbox-proxy-secret: &x-agent-sandbox-proxy-secret 'default_fastgpt_agent_sandbox_proxy_secret'
# aiproxy token
x-aiproxy-token: &x-aiproxy-token "token"
x-aiproxy-token: &x-aiproxy-token 'token'
# 数据库连接相关配置
x-share-db-config: &x-share-db-config
MONGODB_URI: mongodb://myusername:mypassword@fastgpt-mongo:27017/fastgpt?authSource=admin
......@@ -120,7 +120,7 @@ x-service-env-config: &x-service-env-config
FILE_TOKEN_KEY: *x-file-token-key
AES256_SECRET_KEY: *x-aes256-secret-key
INVOKE_TOKEN_SECRET: *x-invoke-token-secret
MULTIPLE_DATA_TO_BASE64: true
MULTIPLE_DATA_TO_BASE64: false
USE_IP_LIMIT: false
CHECK_INTERNAL_IP: false
AUTH_COOKIE_SECURE: false
......@@ -165,10 +165,10 @@ x-service-env-config: &x-service-env-config
WORKFLOW_HTTP_IGNORE_HTTPS_CERT: false
# 向量库相关配置
x-vec-config: &x-vec-config
MILVUS_ADDRESS: zilliz_cloud_address
x-vec-config: &x-vec-config # MILVUS_ADDRESS: zilliz_cloud_address
MILVUS_TOKEN: zilliz_cloud_token
services:
fastgpt-mongo:
image: mongo:5.0.32 # cpu 不支持 AVX 时候使用 4.4.29
......@@ -185,16 +185,16 @@ services:
healthcheck:
test:
[
"CMD",
"mongo",
"-u",
"myusername",
"-p",
"mypassword",
"--authenticationDatabase",
"admin",
"--eval",
"db.adminCommand('ping')",
'CMD',
'mongo',
'-u',
'myusername',
'-p',
'mypassword',
'--authenticationDatabase',
'admin',
'--eval',
"db.adminCommand('ping')"
]
interval: 10s
timeout: 5s
......@@ -239,7 +239,7 @@ services:
command: |
redis-server --requirepass mypassword --loglevel warning --maxclients 10000 --appendonly yes --save 60 10 --maxmemory 4gb --maxmemory-policy noeviction
healthcheck:
test: ["CMD", "redis-cli", "-a", "mypassword", "ping"]
test: ['CMD', 'redis-cli', '-a', 'mypassword', 'ping']
interval: 10s
timeout: 3s
retries: 3
......@@ -262,7 +262,7 @@ services:
- fastgpt-minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
interval: 30s
timeout: 20s
retries: 3
......@@ -300,7 +300,7 @@ services:
*x-fastgpt-service-config,
*x-agent-sandbox-config,
*x-service-env-config,
*x-app-env-config,
*x-app-env-config
]
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
FE_DOMAIN:
......@@ -355,10 +355,10 @@ services:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })",
'CMD',
'node',
'-e',
"fetch('http://localhost:3000/health').then((res) => { if (!res.ok) throw new Error(String(res.status)); })"
]
interval: 30s
timeout: 20s
......@@ -400,7 +400,7 @@ services:
fastgpt-minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health']
interval: 30s
timeout: 20s
retries: 3
......@@ -429,7 +429,7 @@ services:
# 不需要严格检测模型
DISABLE_MODEL_CONFIG: true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/status"]
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
interval: 5s
timeout: 5s
retries: 10
......@@ -447,7 +447,7 @@ services:
POSTGRES_DB: aiproxy
POSTGRES_PASSWORD: aiproxy
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "aiproxy"]
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
interval: 5s
timeout: 5s
retries: 10
......
......@@ -13,9 +13,20 @@ const nullishToUndefined = <T extends z.ZodTypeAny>(schema: T) =>
z.preprocess((v) => v ?? undefined, schema);
const WebCompletionsSchema = z.object({
chatId: nullishToUndefined(z.string().max(1024).optional()).meta({
description: '会话 ID,传入的话会自动获取会话中的对话,不传入则认为是新会话'
}),
chatId: z
.preprocess(
(value) =>
value === null || value === undefined || (typeof value === 'string' && !value.trim())
? undefined
: value,
z
.string()
.max(1024)
.default(() => getNanoid(24))
)
.meta({
description: '会话 ID;未传入或传入空字符串时自动生成新会话 ID'
}),
appId: nullishToUndefined(ObjectIdSchema.optional()).meta({
description:
'应用 ID。推荐在请求体中传入;APIKey 调用时优先级为 body.appId > Authorization 中的 apiKey-appId 后缀 > 旧 APIKey 绑定 appId。apiKey-appId 仅用于兼容 OpenAI SDK,不会写入数据库'
......@@ -105,7 +116,7 @@ const ChatCompletionResponseMessageSchema = z.object({
role: z.literal('assistant').meta({ description: '消息角色' }),
content: z.any().meta({
description:
'消息内容。普通对话为字符串;detail=true 或工作流命中交互节点时,可能为按字段名区分的对象数组(如 text / interactive / tool / file / reasoning)。当元素包含 interactive 字段时,形如 { interactive: { type, params } },只返回交互展示配置,不返回 entryNodeIds / memoryEdges / nodeOutputs 等内部运行态字段'
'消息内容。普通对话为字符串;detail=true 或工作流命中交互节点时,可能为按字段名区分的对象数组(如 text / interactive / tool / file / reasoning)。v1 会额外补充 type 字段,取值为 text / interactive / tool / file / reasoning;v2 不补充 type。当元素包含 interactive 字段时,只返回交互展示配置,不返回 entryNodeIds / memoryEdges / nodeOutputs 等内部运行态字段'
}),
reasoning_content: z.string().optional().meta({ description: '思考过程内容(仅推理模型有)' })
});
......
......@@ -153,8 +153,8 @@ const detailTrueStreamFalseExample = {
]
};
// 交互节点-用户选择 (非流式响应,从 choices 中获取 interactive 字段)
const interactiveUserSelectResponseExample = {
/** 构造交互节点用户选择的非流式响应示例,v1 额外包含兼容 type 字段。 */
const createInteractiveUserSelectResponseExample = (includeLegacyType: boolean) => ({
id: 'chatId',
model: '',
usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 1 },
......@@ -164,6 +164,7 @@ const interactiveUserSelectResponseExample = {
role: 'assistant',
content: [
{
...(includeLegacyType && { type: 'interactive' }),
interactive: {
type: 'userSelect',
params: {
......@@ -181,10 +182,10 @@ const interactiveUserSelectResponseExample = {
index: 0
}
]
};
});
// 交互节点-表单输入 (非流式响应)
const interactiveUserInputResponseExample = {
/** 构造交互节点表单输入的非流式响应示例,v1 额外包含兼容 type 字段。 */
const createInteractiveUserInputResponseExample = (includeLegacyType: boolean) => ({
id: 'chatId',
model: '',
usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 1 },
......@@ -194,6 +195,7 @@ const interactiveUserInputResponseExample = {
role: 'assistant',
content: [
{
...(includeLegacyType && { type: 'interactive' }),
interactive: {
type: 'userInput',
params: {
......@@ -231,7 +233,12 @@ const interactiveUserInputResponseExample = {
index: 0
}
]
};
});
const v1InteractiveUserSelectResponseExample = createInteractiveUserSelectResponseExample(true);
const v1InteractiveUserInputResponseExample = createInteractiveUserInputResponseExample(true);
const v2InteractiveUserSelectResponseExample = createInteractiveUserSelectResponseExample(false);
const v2InteractiveUserInputResponseExample = createInteractiveUserInputResponseExample(false);
// detail=false, stream=true
// 注:示例为简化版,省略了 object/created 等占位字段;真实响应每行还会带这些字段
......@@ -446,13 +453,13 @@ ${interactiveStreamExample}
summary: '交互节点-用户选择 响应',
description:
'工作流命中用户选择交互节点。从 choices[].message.content 中获取包含 interactive 字段的元素',
value: interactiveUserSelectResponseExample
value: v1InteractiveUserSelectResponseExample
},
interactiveUserInput: {
summary: '交互节点-表单输入 响应',
description:
'工作流命中表单输入交互节点。从 choices[].message.content 中获取包含 interactive 字段的元素',
value: interactiveUserInputResponseExample
value: v1InteractiveUserInputResponseExample
}
}
},
......@@ -609,13 +616,13 @@ ${interactiveStreamExample}
summary: '交互节点-用户选择 响应',
description:
'工作流命中用户选择交互节点。从 choices[].message.content 中获取包含 interactive 字段的元素',
value: interactiveUserSelectResponseExample
value: v2InteractiveUserSelectResponseExample
},
interactiveUserInput: {
summary: '交互节点-表单输入 响应',
description:
'工作流命中表单输入交互节点。从 choices[].message.content 中获取包含 interactive 字段的元素',
value: interactiveUserInputResponseExample
value: v2InteractiveUserInputResponseExample
}
}
},
......
import { CompletionsPropsSchema } from '@fastgpt/global/openapi/core/chat/completion/api';
import { describe, expect, it } from 'vitest';
describe('CompletionsPropsSchema chatId', () => {
it.each([{ input: undefined }, { input: null }, { input: '' }, { input: ' ' }])(
'generates a chatId for empty input: $input',
({ input }) => {
const result = CompletionsPropsSchema.parse({ chatId: input });
expect(result.chatId).toHaveLength(24);
}
);
it('preserves an explicit chatId', () => {
const result = CompletionsPropsSchema.parse({ chatId: 'existing-chat-id' });
expect(result.chatId).toBe('existing-chat-id');
});
});
......@@ -120,18 +120,14 @@ const AgentSkillsSchema = new Schema({
}
});
try {
// 名称和描述用于列表页搜索。
AgentSkillsSchema.index({ teamId: 1, name: 'text', description: 'text' });
// 列表页按来源、团队、删除状态和创建时间过滤排序。
AgentSkillsSchema.index({ source: 1, teamId: 1, deleteTime: 1, createTime: -1 });
// 分类筛选。
AgentSkillsSchema.index({ category: 1 });
// 文件夹树查询。
AgentSkillsSchema.index({ teamId: 1, parentId: 1, deleteTime: 1 });
} catch (error) {
console.log('AgentSkill index error:', error);
}
// 名称和描述用于列表页搜索。
AgentSkillsSchema.index({ teamId: 1, name: 'text', description: 'text' });
// 列表页按来源、团队、删除状态和创建时间过滤排序。
AgentSkillsSchema.index({ source: 1, teamId: 1, deleteTime: 1, createTime: -1 });
// 分类筛选。
AgentSkillsSchema.index({ category: 1 });
// 文件夹树查询。
AgentSkillsSchema.index({ teamId: 1, parentId: 1, deleteTime: 1 });
export const MongoAgentSkills = getMongoModel<MongoAgentSkillSchemaType>(
agentSkillsCollectionName,
......
......@@ -51,12 +51,8 @@ const AgentSkillsVersionSchema = new Schema({
}
});
try {
// 版本列表按 skillId 查询并按创建时间倒序展示。
AgentSkillsVersionSchema.index({ skillId: 1, createdAt: -1, _id: -1 });
} catch (error) {
console.log('SkillVersion index error:', error);
}
// 版本列表按 skillId 查询并按创建时间倒序展示。
AgentSkillsVersionSchema.index({ skillId: 1, createdAt: -1, _id: -1 });
export const MongoAgentSkillsVersion = getMongoModel<AgentSkillsVersionSchemaType>(
agentSkillsVersionCollectionName,
......
......@@ -10,6 +10,9 @@ import type { AppSchemaType } from '@fastgpt/global/core/app/type';
import { AppToolSourceEnum } from '@fastgpt/global/core/app/tool/constants';
import { replaceEditorVariable } from '../workflow/dispatch/utils/replaceEditorVariable';
import FormData from 'form-data';
import { getLogger, LogCategories } from '../../common/logger';
const logger = getLogger(LogCategories.MODULE.APP.HTTP_TOOLS);
export type RunHTTPToolParams = {
baseUrl: string;
......@@ -179,7 +182,7 @@ export const runHTTPTool = async ({
return { data };
} catch (error) {
console.log(error);
logger.warn('HTTP tool request failed', { error });
return { errorMsg: getErrText(error) };
}
};
......
import type {
ChatCompletionContentPart,
ChatCompletionMessageParam
} from '@fastgpt/global/core/ai/llm/type';
import type { ChatSourceTypeEnum } from '@fastgpt/global/core/chat/constants';
import { UserError } from '@fastgpt/global/common/error/utils';
import { getFileMaxSize } from '../../common/file/utils';
import { isValidImageContentType } from '../../common/file/image/utils';
import { getS3ChatSource } from '../../common/s3/sources/chat';
import { serviceEnv } from '../../env';
type NormalizeCompletionMessagesProps = {
messages: ChatCompletionMessageParam[];
sourceType: ChatSourceTypeEnum;
sourceId: string;
chatId: string;
uid: string;
};
/**
* 从最后一条用户消息提取文本;没有用户消息时原样返回调用方提供的 fallback。
*/
export const getCompletionStartHookText = ({
messages,
fallback
}: {
messages: ChatCompletionMessageParam[];
fallback: string;
}) => {
const latestMessage = messages.at(-1);
if (latestMessage?.role !== 'user') return fallback;
if (typeof latestMessage.content === 'string') return latestMessage.content;
return latestMessage.content
.filter((item) => item.type === 'text')
.map((item) => item.text)
.join('');
};
const imageExtensionMap: Record<string, string> = {
'image/jpeg': 'jpg',
'image/jpg': 'jpg',
'image/svg+xml': 'svg',
'image/vnd.microsoft.icon': 'ico',
'image/x-icon': 'ico'
};
/**
* 解析图片 Data URL,并在解码前校验格式和大小,避免超大 base64 产生额外内存峰值。
*/
const parseImageDataUrl = (dataUrl: string) => {
const match = dataUrl.match(/^data:([^;,]+);base64,([A-Za-z0-9+/=\r\n]+)$/i);
if (!match) {
throw new UserError('Invalid image base64 data URL');
}
const contentType = match[1].toLowerCase();
if (!isValidImageContentType(contentType)) {
throw new UserError(`Unsupported image content type: ${contentType}`);
}
const base64 = match[2].replace(/[\r\n]/g, '');
const paddingLength = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0;
const decodedSize = Math.floor((base64.length * 3) / 4) - paddingLength;
const maxSize = getFileMaxSize();
if (decodedSize <= 0 || decodedSize > maxSize) {
throw new UserError(`Image size exceeds limit: ${decodedSize} bytes, maximum ${maxSize} bytes`);
}
const body = Buffer.from(base64, 'base64');
if (body.length !== decodedSize) {
throw new UserError('Invalid image base64 data');
}
const subtype = contentType.split('/')[1];
const extension = imageExtensionMap[contentType] ?? subtype;
return {
body,
contentType,
filename: `image.${extension}`
};
};
/**
* 规范化 completions 消息中的 base64 图片。
*
* 当模型允许直接使用 URL 时,先把 Data URL 上传到当前会话的私有 S3 路径,再用临时预览
* URL 覆写运行态消息,并附带稳定 key。运行结束后聊天持久化只保存 key,不保存 base64 或
* 过期签名 URL。同一请求中重复出现的 Data URL 只上传一次。
*/
export const normalizeCompletionMessages = async ({
messages,
sourceType,
sourceId,
chatId,
uid
}: NormalizeCompletionMessagesProps): Promise<ChatCompletionMessageParam[]> => {
if (serviceEnv.MULTIPLE_DATA_TO_BASE64) return messages;
const chatS3 = getS3ChatSource();
const uploadCache = new Map<string, Promise<{ key: string; url: string }>>();
const normalizeImagePart = async (
part: Extract<ChatCompletionContentPart, { type: 'image_url' }>
): Promise<typeof part> => {
const dataUrl = part.image_url.url;
if (!/^data:image\//i.test(dataUrl)) return part;
const uploadResult = (() => {
const cached = uploadCache.get(dataUrl);
if (cached) return cached;
const upload = (async () => {
const { body, contentType, filename } = parseImageDataUrl(dataUrl);
const { key, accessUrl } = await chatS3.uploadChatFile({
sourceType,
sourceId,
chatId,
uId: uid,
filename,
body,
contentType
});
return { key, url: accessUrl.url };
})();
uploadCache.set(dataUrl, upload);
return upload;
})();
const { key, url } = await uploadResult;
return {
...part,
key,
image_url: {
...part.image_url,
url
}
};
};
return Promise.all(
messages.map(async (message) => {
if (message.role !== 'user' || !Array.isArray(message.content)) return message;
const content = await Promise.all(
message.content.map((part) =>
part.type === 'image_url' ? normalizeImagePart(part) : Promise.resolve(part)
)
);
return {
...message,
content
};
})
);
};
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
import { getNanoid } from '@fastgpt/global/common/string/tools';
import {
ChatGenerateStatusEnum,
ChatRoleEnum,
ChatSourceTypeEnum
} from '@fastgpt/global/core/chat/constants';
import { ChatGenerateStatusEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
import type { ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
import type { AIChatItemType, UserChatItemType } from '@fastgpt/global/core/chat/type';
import type { WorkflowInteractiveResponseType } from '@fastgpt/global/core/workflow/template/system/interactive/type';
......@@ -132,12 +128,22 @@ export const prepareChatRound = async (
};
}
stripUserContentFileUrls(params.userContent);
params.userContent.dataId = responseChatItemId;
const now = new Date();
const userPayload: UserChatItemType & { dataId: string; obj: typeof ChatRoleEnum.Human } = {
...params.userContent,
value: params.userContent.value.map((item) =>
item.file?.key
? {
...item,
file: {
...item.file,
url: ''
}
}
: item
),
dataId: responseChatItemId,
obj: ChatRoleEnum.Human
};
......
......@@ -72,7 +72,6 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
}
try {
console.dir(modelConstantsData, { depth: null });
aiChatVision = modelConstantsData.vision && aiChatVision;
aiChatAudio = modelConstantsData.audio && aiChatAudio;
aiChatVideo = modelConstantsData.video && aiChatVideo;
......
......@@ -7,6 +7,7 @@ export type NormalizeDatasetSearchInputResult = {
};
const httpUrlReg = /^https?:\/\//i;
const dataUrlReg = /^data:/i;
const pushUnique = <T>(list: T[], seen: Set<T>, value: T) => {
if (!seen.has(value)) {
......@@ -16,11 +17,12 @@ const pushUnique = <T>(list: T[], seen: Set<T>, value: T) => {
};
const isHttpUrl = (input: string) => httpUrlReg.test(input);
const isDataUrl = (input: string) => dataUrlReg.test(input);
/**
* 将数据集搜索输入拆成文本查询和图片查询。
* datasetSearchInput 会同时接收用户问题和 userFiles;这里只把普通 http(s) URL
* 作为文件候选继续判断,非 http(s) 输入都保留为文本检索 query。
* datasetSearchInput 会同时接收用户问题和 userFiles;http(s) URL 和 Data URL
* 作为文件候选继续判断,其他输入保留为文本检索 query。
*/
export const normalizeDatasetSearchInput = (
inputList: string[]
......@@ -34,7 +36,7 @@ export const normalizeDatasetSearchInput = (
const input = rawInput.trim();
if (!input) continue;
if (!isHttpUrl(input)) {
if (!isHttpUrl(input) && !isDataUrl(input)) {
pushUnique(textQueries, seenTextQueries, input);
continue;
}
......
......@@ -254,7 +254,7 @@ export const serviceEnv = createEnv({
.string()
.optional()
.meta({ description: '自定义跨域;不配置时默认允许所有跨域(逗号分割)' }),
MULTIPLE_DATA_TO_BASE64: BoolSchema.default(true).meta({
MULTIPLE_DATA_TO_BASE64: BoolSchema.default(false).meta({
description: '是否强制将图片、音频、视频转成 base64 传递给模型'
}),
......
import type { ChatCompletionMessageParam } from '@fastgpt/global/core/ai/llm/type';
import { ChatSourceTypeEnum } from '@fastgpt/global/core/chat/constants';
import { beforeEach, describe, expect, it, vi } from 'vitest';
const mocks = vi.hoisted(() => ({
uploadChatFile: vi.fn()
}));
vi.mock('@fastgpt/service/common/s3/sources/chat', () => ({
getS3ChatSource: () => mocks
}));
import {
getCompletionStartHookText,
normalizeCompletionMessages
} from '@fastgpt/service/core/chat/completionMessage';
import { serviceEnv } from '@fastgpt/service/env';
const normalize = (messages: ChatCompletionMessageParam[]) =>
normalizeCompletionMessages({
messages,
sourceType: ChatSourceTypeEnum.app,
sourceId: '507f1f77bcf86cd799439011',
chatId: 'chat-1',
uid: 'user-1'
});
describe('getCompletionStartHookText', () => {
it('returns text from the latest user message', () => {
expect(
getCompletionStartHookText({
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'describe ' },
{ type: 'image_url', image_url: { url: 'data:image/png;base64,aW1hZ2U=' } },
{ type: 'text', text: 'this image' }
]
}
],
fallback: 'plugin fallback'
})
).toBe('describe this image');
});
it('returns fallback without a user message', () => {
expect(
getCompletionStartHookText({
messages: [],
fallback: '{"city":"Shanghai","count":2}'
})
).toBe('{"city":"Shanghai","count":2}');
});
});
describe('normalizeCompletionMessages', () => {
beforeEach(() => {
vi.clearAllMocks();
serviceEnv.MULTIPLE_DATA_TO_BASE64 = false;
global.feConfigs.uploadFileMaxSize = 10;
mocks.uploadChatFile.mockResolvedValue({
key: 'chat/app/507f1f77bcf86cd799439011/user-1/chat-1/image_123456.jpg',
accessUrl: {
bucket: 'private',
key: 'chat/app/507f1f77bcf86cd799439011/user-1/chat-1/image_123456.jpg',
url: 'https://s3.example.com/image.jpg'
}
});
});
it('uploads base64 images once and rewrites every matching message part', async () => {
const dataUrl = `data:image/jpeg;base64,${Buffer.from('image-content').toString('base64')}`;
const messages: ChatCompletionMessageParam[] = [
{
role: 'user',
content: [
{ type: 'text', text: 'describe it' },
{ type: 'image_url', image_url: { url: dataUrl, detail: 'high' } }
]
},
{
role: 'user',
content: [{ type: 'image_url', image_url: { url: dataUrl } }]
}
];
const result = await normalize(messages);
expect(mocks.uploadChatFile).toHaveBeenCalledTimes(1);
expect(mocks.uploadChatFile).toHaveBeenCalledWith({
sourceType: ChatSourceTypeEnum.app,
sourceId: '507f1f77bcf86cd799439011',
chatId: 'chat-1',
uId: 'user-1',
filename: 'image.jpg',
body: Buffer.from('image-content'),
contentType: 'image/jpeg'
});
expect(result[0]).toEqual({
role: 'user',
content: [
{ type: 'text', text: 'describe it' },
{
type: 'image_url',
key: 'chat/app/507f1f77bcf86cd799439011/user-1/chat-1/image_123456.jpg',
image_url: { url: 'https://s3.example.com/image.jpg', detail: 'high' }
}
]
});
expect(result[1]).toEqual({
role: 'user',
content: [
{
type: 'image_url',
key: 'chat/app/507f1f77bcf86cd799439011/user-1/chat-1/image_123456.jpg',
image_url: { url: 'https://s3.example.com/image.jpg' }
}
]
});
expect(messages[0]).toEqual({
role: 'user',
content: [
{ type: 'text', text: 'describe it' },
{ type: 'image_url', image_url: { url: dataUrl, detail: 'high' } }
]
});
});
it('keeps messages unchanged when base64 model input is enabled', async () => {
serviceEnv.MULTIPLE_DATA_TO_BASE64 = true;
const messages: ChatCompletionMessageParam[] = [
{
role: 'user',
content: [
{
type: 'image_url',
image_url: { url: 'data:image/png;base64,aW1hZ2U=' }
}
]
}
];
const result = await normalize(messages);
expect(result).toBe(messages);
expect(mocks.uploadChatFile).not.toHaveBeenCalled();
});
it('keeps remote images and non-user messages without uploading', async () => {
const messages: ChatCompletionMessageParam[] = [
{
role: 'system',
content: 'system prompt'
},
{
role: 'user',
content: [
{ type: 'text', text: 'question' },
{ type: 'image_url', image_url: { url: 'https://example.com/image.png' } }
]
}
];
await expect(normalize(messages)).resolves.toEqual(messages);
expect(mocks.uploadChatFile).not.toHaveBeenCalled();
});
it('rejects malformed and unsupported image Data URLs', async () => {
await expect(
normalize([
{
role: 'user',
content: [{ type: 'image_url', image_url: { url: 'data:image/png;base64,***' } }]
}
])
).rejects.toThrow('Invalid image base64 data URL');
await expect(
normalize([
{
role: 'user',
content: [{ type: 'image_url', image_url: { url: 'data:image/unknown;base64,YQ==' } }]
}
])
).rejects.toThrow('Unsupported image content type');
});
it('rejects decoded images larger than the upload limit', async () => {
global.feConfigs.uploadFileMaxSize = 0.000001;
await expect(
normalize([
{
role: 'user',
content: [
{
type: 'image_url',
image_url: {
url: `data:image/png;base64,${Buffer.from('too-large').toString('base64')}`
}
}
]
}
])
).rejects.toThrow('Image size exceeds limit');
expect(mocks.uploadChatFile).not.toHaveBeenCalled();
});
});
......@@ -493,7 +493,7 @@ describe('prepare chat round', () => {
obj: ChatRoleEnum.Human
});
expect(humanItem?.value[0].file?.url).toBe('');
expect(params.userContent.value[0].file?.url).toBe('');
expect(params.userContent.value[0].file?.url).toBe('https://signed-url.example/report.pdf');
});
it('should only strip file URL when file key exists', () => {
......
......@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest';
import { normalizeDatasetSearchInput } from '../../../../../core/workflow/dispatch/dataset/utils';
describe('normalizeDatasetSearchInput', () => {
it('should split text queries and http image urls', () => {
it('should split text queries and image urls', () => {
const result = normalizeDatasetSearchInput([
' black high heels ',
'temp/team-1/search-image.png',
......@@ -18,10 +18,24 @@ describe('normalizeDatasetSearchInput', () => {
'black high heels',
'temp/team-1/search-image.png',
'chat/team-1/manual.pdf',
'data:image/png;base64,abc',
'dataset/team-1/photo.webp'
]);
expect(result.imageQueries).toEqual(['https://example.com/current.png']);
expect(result.imageQueries).toEqual([
'https://example.com/current.png',
'data:image/png;base64,abc'
]);
});
it('should classify image Data URLs and discard other Data URLs', () => {
const result = normalizeDatasetSearchInput([
'data:IMAGE/JPEG;base64,/9j/4AAQ',
'data:IMAGE/JPEG;base64,/9j/4AAQ',
'data:application/pdf;base64,JVBERi0xLjQK',
'data:invalid'
]);
expect(result.textQueries).toEqual([]);
expect(result.imageQueries).toEqual(['data:IMAGE/JPEG;base64,/9j/4AAQ']);
});
it('should only classify http image urls by parsed file type', () => {
......
Subproject commit 34302711ede80fa71b76eb93290babf6e88b7f40
Subproject commit ec193812c120166b135f4ce6acaa44d9c853ac8f
......@@ -23,6 +23,7 @@ import {
GetPaginationRecordsResponseSchema,
type GetPaginationRecordsResponseType
} from '@fastgpt/global/openapi/core/chat/record/api';
import { getChatItemValueType } from '@/service/core/chat/utils';
export async function handler(req: ApiRequestProps): Promise<GetPaginationRecordsResponseType> {
const {
......@@ -112,27 +113,10 @@ export async function handler(req: ApiRequestProps): Promise<GetPaginationRecord
}
// Add value type(适配旧版)
item.value = item.value.map((v) => {
enum ChatItemValueTypeEnum {
text = 'text',
file = 'file',
tool = 'tool',
interactive = 'interactive',
reasoning = 'reasoning'
}
const type = (() => {
if (v.text) return ChatItemValueTypeEnum.text;
if ('file' in v) return ChatItemValueTypeEnum.file;
if ('tool' in v || 'tools' in v) return ChatItemValueTypeEnum.tool;
if ('interactive' in v) return ChatItemValueTypeEnum.interactive;
if ('reasoning' in v) return ChatItemValueTypeEnum.reasoning;
return ChatItemValueTypeEnum.text;
})();
return {
...v,
type
};
});
item.value = item.value.map((value) => ({
...value,
type: getChatItemValueType(value)
}));
});
return GetPaginationRecordsResponseSchema.parse({
......
......@@ -16,7 +16,7 @@ import {
getLastInteractiveValue
} from '@fastgpt/global/core/workflow/runtime/utils';
import { workflowSseEvent } from '@fastgpt/global/core/workflow/runtime/sse';
import { GPTMessages2Chats, chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt';
import { getChatItems } from '@fastgpt/service/core/chat/controller';
import {
type Props as SaveChatProps,
......@@ -77,6 +77,10 @@ import {
type WorkflowStreamResponseContext
} from '@fastgpt/service/core/workflow/utils/streamResponseContext';
import { authChatCompletionHeaderRequest } from '@/service/support/permission/auth/chatCompletion';
import {
getCompletionStartHookText,
normalizeCompletionMessages
} from '@fastgpt/service/core/chat/completionMessage';
const logger = getLogger(LogCategories.MODULE.CHAT.ITEM);
......@@ -88,15 +92,15 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
customUid,
outLinkAuthData,
stream = false,
stream,
showSkillReferences,
messages = [],
responseChatItemId = getNanoid(),
metadata,
authProxy
} = completionProps;
const { retainDatasetCite = false } = completionProps;
let { detail = false, variables = {} } = completionProps;
const { retainDatasetCite } = completionProps;
let { detail, variables = {} } = completionProps;
const shareId = outLinkAuthData?.shareId;
const outLinkUid = outLinkAuthData?.outLinkUid;
......@@ -117,23 +121,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
}
/*
Web params: chatId + [Human]
API params: chatId + [Human]
API params: [histories, Human]
*/
const chatMessages = GPTMessages2Chats({ messages });
// Computed start hook params
const startHookText = (() => {
// Chat
const userQuestion = chatMessages[chatMessages.length - 1] as UserChatItemType;
if (userQuestion) return chatValue2RuntimePrompt(userQuestion.value).text;
// plugin
return JSON.stringify(variables);
})();
/*
1. auth app permission
2. auth balance
3. get app
......@@ -158,6 +145,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
return Promise.reject(ChatErrEnum.unAuthChat);
}
const startHookText = getCompletionStartHookText({
messages,
fallback: JSON.stringify(variables)
});
return authShareChat({
shareId,
outLinkUid,
......@@ -187,6 +179,16 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
return;
}
const chatMessages = GPTMessages2Chats({
messages: await normalizeCompletionMessages({
messages,
sourceType: ChatSourceTypeEnum.app,
sourceId: String(app._id),
chatId,
uid: String(outLinkUserId || tmbId)
})
});
pushTrack.teamChatQPM({ teamId });
const { workflowRetainDatasetCite, jsonRetainDatasetCite } = getWorkflowDatasetCiteRetention({
......@@ -470,7 +472,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
const formatResponseContent = removeAIResponseCite(assistantResponses, jsonRetainDatasetCite);
const formattdResponse = formatCompletionResponseContent({
responseContent: formatResponseContent,
detail
detail,
includeLegacyType: true
});
const error =
......@@ -616,8 +619,8 @@ const authShareChat = async ({
export const config = {
api: {
bodyParser: {
sizeLimit: '20mb'
sizeLimit: '10mb'
},
responseLimit: '20mb'
responseLimit: '10mb'
}
};
......@@ -16,7 +16,7 @@ import {
getLastInteractiveValue
} from '@fastgpt/global/core/workflow/runtime/utils';
import { workflowSseEvent } from '@fastgpt/global/core/workflow/runtime/sse';
import { GPTMessages2Chats, chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt';
import { getChatItems } from '@fastgpt/service/core/chat/controller';
import {
type Props as SaveChatProps,
......@@ -77,6 +77,10 @@ import {
} from '@fastgpt/service/core/workflow/utils/streamResponseContext';
import { authChatCompletionHeaderRequest } from '@/service/support/permission/auth/chatCompletion';
import { buildChatSourceQuery } from '@fastgpt/service/core/chat/source';
import {
getCompletionStartHookText,
normalizeCompletionMessages
} from '@fastgpt/service/core/chat/completionMessage';
const logger = getLogger(LogCategories.MODULE.CHAT.ITEM);
async function handler(req: NextApiRequest, res: NextApiResponse) {
......@@ -117,23 +121,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
}
/*
Web params: chatId + [Human]
API params: chatId + [Human]
API params: [histories, Human]
*/
const chatMessages = GPTMessages2Chats({ messages });
// Computed start hook params
const startHookText = (() => {
// Chat
const userQuestion = chatMessages[chatMessages.length - 1] as UserChatItemType;
if (userQuestion) return chatValue2RuntimePrompt(userQuestion.value).text;
// plugin
return JSON.stringify(variables);
})();
/*
1. auth app permission
2. auth balance
3. get app
......@@ -158,6 +145,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
return Promise.reject(ChatErrEnum.unAuthChat);
}
const startHookText = getCompletionStartHookText({
messages,
fallback: JSON.stringify(variables)
});
return authShareChat({
shareId,
outLinkUid,
......@@ -186,6 +178,16 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
return;
}
const chatMessages = GPTMessages2Chats({
messages: await normalizeCompletionMessages({
messages,
sourceType: ChatSourceTypeEnum.app,
sourceId: String(app._id),
chatId,
uid: String(outLinkUserId || tmbId)
})
});
pushTrack.teamChatQPM({ teamId });
const { workflowRetainDatasetCite, jsonRetainDatasetCite } = getWorkflowDatasetCiteRetention({
......@@ -473,7 +475,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
const formatResponseContent = removeAIResponseCite(assistantResponses, jsonRetainDatasetCite);
const formattdResponse = formatCompletionResponseContent({
responseContent: formatResponseContent,
detail
detail,
includeLegacyType: false
});
res.json({
......@@ -616,8 +619,8 @@ const authShareChat = async ({
export const config = {
api: {
bodyParser: {
sizeLimit: '20mb'
sizeLimit: '10mb'
},
responseLimit: '20mb'
responseLimit: '10mb'
}
};
......@@ -2,9 +2,41 @@ import type { DatasetCiteItemType } from '@fastgpt/global/core/dataset/type';
import type { AIChatItemValueItemType } from '@fastgpt/global/core/chat/type';
import type { WorkflowInteractiveResponseType } from '@fastgpt/global/core/workflow/template/system/interactive/type';
/* ===== 兼容性代码 ===== */
export enum ChatItemValueTypeEnum {
text = 'text',
file = 'file',
tool = 'tool',
interactive = 'interactive',
reasoning = 'reasoning'
}
type ChatItemValueTypeInput = {
text?: unknown;
file?: unknown;
tool?: unknown;
tools?: unknown;
interactive?: unknown;
reasoning?: unknown;
};
/**
* 根据聊天 value 的实际内容推断旧版兼容 type。
*
* text 优先级最高,以兼容同时包含 reasoning 和 text 的 AI 回复;未知或空对象回退为 text。
*/
export const getChatItemValueType = (item: ChatItemValueTypeInput): ChatItemValueTypeEnum => {
if (item.text) return ChatItemValueTypeEnum.text;
if ('file' in item) return ChatItemValueTypeEnum.file;
if (item.tool || item.tools) return ChatItemValueTypeEnum.tool;
if (item.interactive) return ChatItemValueTypeEnum.interactive;
if (item.reasoning) return ChatItemValueTypeEnum.reasoning;
return ChatItemValueTypeEnum.text;
};
/* ===== 兼容性代码 ===== */
export type PublicCompletionInteractive = Pick<WorkflowInteractiveResponseType, 'type' | 'params'>;
export type CompletionDetailValueItem = Omit<AIChatItemValueItemType, 'interactive'> & {
type?: ChatItemValueTypeEnum;
interactive?: PublicCompletionInteractive;
};
......@@ -19,14 +51,17 @@ export type CompletionResponseContent =
* 格式化 completions 非流式响应的 choices[].message.content。
*
* 普通单条文本保持 OpenAI 兼容字符串;detail=true 且包含交互、工具、文件或多段 value 时,
* 返回按字段名区分的 value 数组,确保交互节点可从 choices 中被客户端识别。
* 返回按字段名区分的 value 数组。v1 可通过 includeLegacyType 补充 type,兼容既有客户端;
* v2 保持不带 type 的新结构。
*/
export const formatCompletionResponseContent = ({
responseContent,
detail
detail,
includeLegacyType
}: {
responseContent: AIChatItemValueItemType[];
detail: boolean;
includeLegacyType: boolean;
}): CompletionResponseContent => {
const MAX_COMPLETION_INTERACTIVE_EXTRACT_DEPTH = 20;
......@@ -84,7 +119,8 @@ export const formatCompletionResponseContent = ({
...item,
...(item.interactive && {
interactive: formatPublicCompletionInteractive(item.interactive)
})
}),
...(includeLegacyType && { type: getChatItemValueType(item) })
}));
const shouldReturnDetailValueList = ({
......
import { describe, expect, it } from 'vitest';
import { formatCompletionResponseContent } from '@/service/core/chat/utils';
import {
ChatItemValueTypeEnum,
formatCompletionResponseContent,
getChatItemValueType
} from '@/service/core/chat/utils';
import type { AIChatItemValueItemType } from '@fastgpt/global/core/chat/type';
describe('getChatItemValueType', () => {
it('infers every legacy chat value type and keeps text as the highest priority', () => {
expect(getChatItemValueType({ reasoning: {}, text: {} })).toBe(ChatItemValueTypeEnum.text);
expect(getChatItemValueType({ file: undefined })).toBe(ChatItemValueTypeEnum.file);
expect(getChatItemValueType({ tool: {} })).toBe(ChatItemValueTypeEnum.tool);
expect(getChatItemValueType({ tools: [] })).toBe(ChatItemValueTypeEnum.tool);
expect(getChatItemValueType({ interactive: {} })).toBe(ChatItemValueTypeEnum.interactive);
expect(getChatItemValueType({ reasoning: {} })).toBe(ChatItemValueTypeEnum.reasoning);
expect(getChatItemValueType({})).toBe(ChatItemValueTypeEnum.text);
});
});
describe('formatCompletionResponseContent', () => {
it('keeps plain single text response OpenAI compatible', () => {
const result = formatCompletionResponseContent({
detail: true,
includeLegacyType: false,
responseContent: [
{
text: {
......@@ -21,7 +38,7 @@ describe('formatCompletionResponseContent', () => {
});
});
it('returns single interactive response as field-keyed content array when detail is enabled', () => {
it('adds type to v1 interactive detail values', () => {
const interactive = {
type: 'userSelect',
params: {
......@@ -32,6 +49,7 @@ describe('formatCompletionResponseContent', () => {
const result = formatCompletionResponseContent({
detail: true,
includeLegacyType: true,
responseContent: [
{
interactive
......@@ -41,11 +59,93 @@ describe('formatCompletionResponseContent', () => {
expect(result).toEqual([
{
type: 'interactive',
interactive
}
]);
});
it('adds type to v1 mixed text and tool detail values', () => {
const tool = {
id: 'call_1',
toolName: 'Test tool',
toolAvatar: '',
functionName: 'test_tool',
params: '{}',
response: 'ok'
};
const result = formatCompletionResponseContent({
detail: true,
includeLegacyType: true,
responseContent: [
{
reasoning: { content: 'Need to call a tool' },
text: { content: 'Calling tool' }
},
{
tools: [tool]
},
{
reasoning: { content: 'Tool call completed' },
text: { content: 'Done' }
}
]
});
expect(result).toEqual([
{
type: 'text',
reasoning: { content: 'Need to call a tool' },
text: { content: 'Calling tool' }
},
{
type: 'tool',
tools: [tool]
},
{
type: 'text',
reasoning: { content: 'Tool call completed' },
text: { content: 'Done' }
}
]);
});
it('keeps v2 mixed detail values without type', () => {
const tool = {
id: 'call_v2',
toolName: 'V2 tool',
toolAvatar: '',
functionName: 'v2_tool',
params: '{}',
response: 'ok'
};
const result = formatCompletionResponseContent({
detail: true,
includeLegacyType: false,
responseContent: [
{
reasoning: { content: 'Need to call a tool' },
text: { content: 'Calling tool' }
},
{
tools: [tool]
}
]
});
expect(result).toEqual([
{
reasoning: { content: 'Need to call a tool' },
text: { content: 'Calling tool' }
},
{
tools: [tool]
}
]);
});
it('returns only public interactive fields and extracts deepest child interactive', () => {
const interactive = {
type: 'childrenInteractive',
......@@ -71,6 +171,7 @@ describe('formatCompletionResponseContent', () => {
const result = formatCompletionResponseContent({
detail: true,
includeLegacyType: false,
responseContent: [
{
interactive
......@@ -100,6 +201,7 @@ describe('formatCompletionResponseContent', () => {
const result = formatCompletionResponseContent({
detail: true,
includeLegacyType: false,
responseContent: [
{
interactive: interactive as AIChatItemValueItemType['interactive']
......@@ -120,6 +222,7 @@ describe('formatCompletionResponseContent', () => {
it('joins multiple text and reasoning values when detail is disabled', () => {
const result = formatCompletionResponseContent({
detail: false,
includeLegacyType: false,
responseContent: [
{
reasoning: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment