fix(config): layer root and env compose files with expanded overrides
Load agent/cursor env overrides in config loader; pass root .env plus environment-specific env files in env-service; align compose env_file mounts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
.doc
|
||||
docs
|
||||
data
|
||||
.regulations
|
||||
.tmp
|
||||
web/node_modules
|
||||
web/dist
|
||||
web/.vite
|
||||
|
||||
+17
-14
@@ -3,14 +3,12 @@
|
||||
#
|
||||
# 使用说明:
|
||||
# 1. 复制为 .env 并填写密钥:cp .env.example .env && chmod 600 .env
|
||||
# 2. 本文件供 Go 后端 (bin/server)、launch.sh 默认 compose 变量替换使用
|
||||
# 3. 若通过 ./scripts/env-service.sh dev start 启容器,还需同步密钥到 configs/.env.dev
|
||||
# (见 configs/.env.dev.example 第 6 节)
|
||||
# 2. 本文件供 Go 后端、launch.sh 与 env-service.sh 作为公共配置源
|
||||
# 3. configs/.env.<环境> 只保存端口、数据库等环境差异,且优先级高于本文件
|
||||
# =============================================================================
|
||||
|
||||
# --- 1. 运行环境与基础目录 ---
|
||||
ENV=dev
|
||||
COMPOSE_PROJECT_NAME=agent-dev
|
||||
DATA_DIR=./data/dev
|
||||
APP_PUBLISH_HOST=127.0.0.1
|
||||
HTTP_PORT=8080
|
||||
@@ -42,7 +40,7 @@ PI_AGENT_RUNNER_PORT=18865
|
||||
# 宿主 bin/server 直连本机 pi-agent 容器时启用;容器内 app 服务由 compose 注入 http://pi-agent:18865
|
||||
# PI_AGENT_RUNNER_URL=http://127.0.0.1:18865
|
||||
# Runner 服务间认证(main 必填;dev 可留空)
|
||||
# RUNNER_AUTH_TOKEN=
|
||||
RUNNER_AUTH_TOKEN=
|
||||
|
||||
# --- 7. 本机 Pi CLI 回退(不使用容器 runner 时)---
|
||||
PI_AGENT_BIN=/opt/homebrew/bin/pi
|
||||
@@ -54,17 +52,15 @@ PI_AGENT_MODEL=MiniMax-M2.7-highspeed
|
||||
KB_DB_HOST=127.0.0.1
|
||||
KB_DB_PORT=5432
|
||||
KB_DB_USER=regkb
|
||||
KB_DB_PASSWORD=shared_kb_secret_pass
|
||||
KB_DB_PASSWORD=
|
||||
KB_DB_NAME=regulations
|
||||
|
||||
# --- 9. 向量 Embedding / Reranker(Go 宿主 KB 检索;容器 app 当前未透传,宿主模式必填)---
|
||||
# --- 9. 向量 Embedding / Reranker(Go 宿主与容器 app 的 KB 检索)---
|
||||
EMBEDDING_ENDPOINT_URL=https://www.dmxapi.cn/v1/embeddings
|
||||
EMBEDDING_PROVIDER=openai_compatible
|
||||
EMBEDDING_MODEL=bge-m3
|
||||
EMBEDDING_API_KEY=
|
||||
|
||||
RERANKER_ENDPOINT_URL=https://www.dmxapi.cn/v1/rerank
|
||||
RERANKER_PROVIDER=openai_compatible
|
||||
RERANKER_MODEL=bge-reranker-v2-m3-free
|
||||
RERANKER_API_KEY=
|
||||
|
||||
@@ -87,8 +83,15 @@ ADMIN_PASSWORD=admin-secret-password-123
|
||||
AUTH_REGISTRATION_ENABLED=true
|
||||
AUTH_REQUIRE_APPROVAL=false
|
||||
|
||||
# --- 12. 可选:CORS / 内存降级 ---
|
||||
# dev/test 未配置时 CORS 由代码填充 localhost 默认值
|
||||
# CORS_ALLOWED_ORIGINS=http://localhost:5173,http://127.0.0.1:8080
|
||||
# 生产必须为 false;main 启动时若 true 将拒绝加载
|
||||
# ALLOW_IN_MEMORY=false
|
||||
# --- 12. 安全、缓存与意图路由开关 ---
|
||||
# 留空时 dev/test 由代码补 localhost;生产留空代表不允许跨 Origin
|
||||
CORS_ALLOWED_ORIGINS=
|
||||
# 生产强制 false;main compose 不接受覆盖
|
||||
ALLOW_IN_MEMORY=false
|
||||
CACHE_ENABLED=true
|
||||
INTENT_V2_SHADOW=false
|
||||
INTENT_V2_DECISION=false
|
||||
INTENT_V2_DECISION_TIER=none
|
||||
WORKFLOW_INTENTS_ENABLED=true
|
||||
MULTI_INTENT_ENABLED=true
|
||||
SEMANTIC_FALLBACK_ENABLED=false
|
||||
|
||||
@@ -1,25 +1,18 @@
|
||||
# =============================================================================
|
||||
# 开发环境 Compose 专用配置模板 (configs/.env.dev)
|
||||
# 作用域:./scripts/env-service.sh dev * 与 docker compose --env-file configs/.env.dev
|
||||
# 作用域:./scripts/env-service.sh dev * 的环境差异覆盖
|
||||
#
|
||||
# 重要:本文件与根目录 .env 分工不同
|
||||
# - 根 .env → Go bin/server、launch.sh 默认 compose
|
||||
# - 本文件 → env-service.sh 启停 dev 容器组
|
||||
# 密钥(MINIMAX_API_KEY / TAVILY_API_KEYS 等)须与根 .env 保持一致,否则 pi-agent 容器无 Token!
|
||||
# 根 .env 提供公共模型、检索、认证配置;本文件只覆盖 dev 差异。
|
||||
# =============================================================================
|
||||
|
||||
ENV=dev
|
||||
COMPOSE_PROJECT_NAME=agent-dev
|
||||
|
||||
# 1. 业务 HTTP 服务
|
||||
HTTP_PORT=8080
|
||||
APP_PUBLISH_HOST=127.0.0.1
|
||||
ADMIN_TOKEN=dev-admin-token-change-me
|
||||
ALLOW_INSECURE_ADMIN=1
|
||||
|
||||
# 2. 对话数据与工作区(禁止跨环境共享)
|
||||
DATA_DIR=./data/dev
|
||||
AUX_FILE_DSN=file:/var/lib/feishu/outbox_dev.db?_journal_mode=WAL&_busy_timeout=5000
|
||||
|
||||
# 3. 开发环境专属数据库
|
||||
SYSTEM_DB_USER=app
|
||||
@@ -29,7 +22,6 @@ SYSTEM_DB_PUBLISH_PORT=5433
|
||||
|
||||
# 4. 共享知识库(容器 app 经 shuimu-kb-shared 访问)
|
||||
KB_DB_USER=regkb
|
||||
KB_DB_PASSWORD=shared_kb_secret_pass
|
||||
KB_DB_NAME=regulations
|
||||
KB_DB_HOST=shuimu-kb-shared
|
||||
KB_DB_PORT=5432
|
||||
@@ -40,12 +32,4 @@ PI_AGENT_RUNNER_PORT=18865
|
||||
AGENT_BACKEND=pi-agent
|
||||
AGENT_TIMEOUT=60m
|
||||
|
||||
# 6. Pi-Agent / MiniMax / Tavily(pi-agent 容器必填;从根 .env 复制)
|
||||
MINIMAX_ENDPOINT_URL=https://api.minimaxi.com/v1
|
||||
MINIMAX_API_KEY=
|
||||
MINIMAX_MODEL_ID=MiniMax-M2.7-highspeed
|
||||
MINIMAX_API_TYPE=openai-compatible
|
||||
PI_AGENT_PROVIDER=minimax
|
||||
PI_AGENT_MODEL=MiniMax-M2.7-highspeed
|
||||
TAVILY_API_KEYS=
|
||||
# RUNNER_AUTH_TOKEN=
|
||||
# 6. Pi-Agent / MiniMax / Tavily / Runner 密钥统一读取根 .env
|
||||
|
||||
@@ -1,39 +1,37 @@
|
||||
# =============================================================================
|
||||
# 生产/主分支环境 (main) 环境变量配置模板 (configs/.env.main)
|
||||
# 作用域:main 分支正式线上发布与生产运营
|
||||
# 根 .env 提供公共模型与检索配置;本文件覆盖生产端口、数据库和生产密钥。
|
||||
# =============================================================================
|
||||
|
||||
ENV=prod
|
||||
COMPOSE_PROJECT_NAME=agent-main
|
||||
|
||||
# 1. 业务 HTTP 服务
|
||||
HTTP_PORT=8000
|
||||
APP_PUBLISH_HOST=0.0.0.0
|
||||
ADMIN_TOKEN=main-prod-admin-token-super-secure
|
||||
ALLOW_INSECURE_ADMIN=0
|
||||
AUTH_REGISTRATION_ENABLED=false
|
||||
AUTH_REQUIRE_APPROVAL=true
|
||||
|
||||
# 2. 对话数据与工作区隔离目录 (禁止跨环境共享)
|
||||
DATA_DIR=./data/main
|
||||
AUX_FILE_DSN=file:/var/lib/feishu/outbox_main.db?_journal_mode=WAL&_busy_timeout=5000
|
||||
|
||||
# 3. 生产环境专属数据库 (禁止与 dev/test 共享)
|
||||
SYSTEM_DB_USER=app
|
||||
SYSTEM_DB_PASSWORD=prod_highly_secure_db_pass
|
||||
SYSTEM_DB_PASSWORD=
|
||||
SYSTEM_DB_NAME=agent_system_main
|
||||
SYSTEM_DB_PUBLISH_PORT=5435
|
||||
|
||||
# 4. 共享知识库连接 (只读检索共享数据)
|
||||
KB_DB_USER=regkb
|
||||
KB_DB_PASSWORD=shared_kb_secret_pass
|
||||
KB_DB_NAME=regulations
|
||||
KB_DB_HOST=shuimu-kb-shared
|
||||
KB_DB_PORT=5432
|
||||
|
||||
# 5. Cursor / LLM Agent Runner 服务
|
||||
CURSOR_RUNNER_PORT=18767
|
||||
AGENT_BACKEND=stub
|
||||
PI_AGENT_RUNNER_PORT=18867
|
||||
AGENT_BACKEND=pi-agent
|
||||
AGENT_TIMEOUT=60m
|
||||
# 生产必填(不可使用 shared_kb_secret_pass / admin-secret-password-123 等默认值)
|
||||
RUNNER_AUTH_TOKEN=change-me-runner-token
|
||||
KB_DB_PASSWORD=change-me-kb-prod-secret
|
||||
ADMIN_PASSWORD=change-me-admin-prod-secret
|
||||
RUNNER_AUTH_TOKEN=
|
||||
ADMIN_PASSWORD=
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
# =============================================================================
|
||||
# 共享基础设施环境变量配置模板 (configs/.env.shared)
|
||||
# 作用域:所有分支与环境共享的知识库、向量检索与底层公共网络
|
||||
# KB_DB_PASSWORD 统一在根 .env 配置,本文件只覆盖共享服务差异。
|
||||
# =============================================================================
|
||||
|
||||
COMPOSE_PROJECT_NAME=agent-infra
|
||||
|
||||
# 共享知识库 PostgreSQL (带 pgvector)
|
||||
KB_DB_USER=regkb
|
||||
KB_DB_PASSWORD=shared_kb_secret_pass
|
||||
KB_DB_NAME=regulations
|
||||
KB_PUBLISH_PORT=5432
|
||||
KB_DATA_DIR=./data/shared/kb
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
# =============================================================================
|
||||
# 测试环境 (test) 环境变量配置模板 (configs/.env.test)
|
||||
# 作用域:test 分支阶段集成、长期部署实测与运维验证
|
||||
# 根 .env 提供公共模型、检索、认证配置;本文件只覆盖 test 差异。
|
||||
# =============================================================================
|
||||
|
||||
ENV=test
|
||||
COMPOSE_PROJECT_NAME=agent-test
|
||||
|
||||
# 1. 业务 HTTP 服务
|
||||
HTTP_PORT=8081
|
||||
APP_PUBLISH_HOST=0.0.0.0
|
||||
ADMIN_TOKEN=test-admin-token-secure-key
|
||||
ALLOW_INSECURE_ADMIN=0
|
||||
|
||||
# 2. 对话数据与工作区隔离目录 (禁止跨环境共享)
|
||||
DATA_DIR=./data/test
|
||||
AUX_FILE_DSN=file:/var/lib/feishu/outbox_test.db?_journal_mode=WAL&_busy_timeout=5000
|
||||
|
||||
# 3. 测试环境专属数据库 (禁止与 dev/main 共享)
|
||||
SYSTEM_DB_USER=app
|
||||
@@ -24,7 +21,6 @@ SYSTEM_DB_PUBLISH_PORT=5434
|
||||
|
||||
# 4. 共享知识库连接 (只读检索共享数据)
|
||||
KB_DB_USER=regkb
|
||||
KB_DB_PASSWORD=shared_kb_secret_pass
|
||||
KB_DB_NAME=regulations
|
||||
KB_DB_HOST=shuimu-kb-shared
|
||||
KB_DB_PORT=5432
|
||||
@@ -32,7 +28,7 @@ KB_DB_PORT=5432
|
||||
# 5. Cursor / LLM Agent Runner 服务
|
||||
CURSOR_RUNNER_PORT=18766
|
||||
PI_AGENT_RUNNER_PORT=18866
|
||||
AGENT_BACKEND=stub
|
||||
AGENT_BACKEND=pi-agent
|
||||
AGENT_TIMEOUT=60m
|
||||
# app 与 pi-agent 容器共享(test 环境建议设置非空值)
|
||||
# RUNNER_AUTH_TOKEN=test-runner-shared-secret
|
||||
|
||||
+22
-4
@@ -60,7 +60,6 @@ services:
|
||||
MINIMAX_API_TYPE: ${MINIMAX_API_TYPE:-openai-compatible}
|
||||
MINIMAX_PROVIDER: minimax
|
||||
TAVILY_API_KEYS: ${TAVILY_API_KEYS:-}
|
||||
TAVILY_API_KEY: ${TAVILY_API_KEY:-}
|
||||
RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:-}
|
||||
ports:
|
||||
- "127.0.0.1:${PI_AGENT_RUNNER_PORT:-18865}:18865"
|
||||
@@ -94,19 +93,38 @@ services:
|
||||
HTTP_PORT: "${HTTP_PORT:-8080}"
|
||||
HTTP_HOST: "0.0.0.0"
|
||||
AGENT_BACKEND: ${AGENT_BACKEND:-pi-agent}
|
||||
AGENT_TIMEOUT: ${AGENT_TIMEOUT:-30m}
|
||||
MAX_CONCURRENT_AGENTS: ${MAX_CONCURRENT_AGENTS:-8}
|
||||
DATA_DIR: /app/data
|
||||
# 独占业务与对话库
|
||||
APP_DB_DSN: postgres://${SYSTEM_DB_USER:-app}:${SYSTEM_DB_PASSWORD:-dev_secret_db_pass}@system-db:5432/${SYSTEM_DB_NAME:-agent_system_dev}?sslmode=disable
|
||||
# 共享知识库
|
||||
POSTGRES_SHARED_KB_DSN: postgres://${KB_DB_USER:-regkb}:${KB_DB_PASSWORD:-shared_kb_secret_pass}@shuimu-kb-shared:5432/${KB_DB_NAME:-regulations}?sslmode=disable
|
||||
POSTGRES_SHARED_KB_DSN: postgres://${KB_DB_USER:-regkb}:${KB_DB_PASSWORD:?KB_DB_PASSWORD is required}@shuimu-kb-shared:5432/${KB_DB_NAME:-regulations}?sslmode=disable
|
||||
CURSOR_RUNNER_URL: http://cursor-agent:18765
|
||||
PI_AGENT_RUNNER_URL: http://pi-agent:18865
|
||||
PI_AGENT_RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:-}
|
||||
PI_AGENT_PROVIDER: ${PI_AGENT_PROVIDER:-minimax}
|
||||
PI_AGENT_MODEL: ${PI_AGENT_MODEL:-MiniMax-M2.7-highspeed}
|
||||
RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:-}
|
||||
ALLOW_IN_MEMORY: "false"
|
||||
AUX_FILE_DSN: file:/var/lib/feishu/outbox_dev.db?_journal_mode=WAL&_busy_timeout=5000
|
||||
EMBEDDING_ENDPOINT_URL: ${EMBEDDING_ENDPOINT_URL:-}
|
||||
EMBEDDING_MODEL: ${EMBEDDING_MODEL:-bge-m3}
|
||||
EMBEDDING_API_KEY: ${EMBEDDING_API_KEY:-}
|
||||
RERANKER_ENDPOINT_URL: ${RERANKER_ENDPOINT_URL:-}
|
||||
RERANKER_MODEL: ${RERANKER_MODEL:-bge-reranker-v2-m3-free}
|
||||
RERANKER_API_KEY: ${RERANKER_API_KEY:-}
|
||||
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
|
||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin-secret-password-123}
|
||||
AUTH_REGISTRATION_ENABLED: ${AUTH_REGISTRATION_ENABLED:-true}
|
||||
AUTH_REQUIRE_APPROVAL: ${AUTH_REQUIRE_APPROVAL:-false}
|
||||
CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-}
|
||||
ALLOW_IN_MEMORY: ${ALLOW_IN_MEMORY:-false}
|
||||
CACHE_ENABLED: ${CACHE_ENABLED:-true}
|
||||
INTENT_V2_SHADOW: ${INTENT_V2_SHADOW:-false}
|
||||
INTENT_V2_DECISION: ${INTENT_V2_DECISION:-false}
|
||||
INTENT_V2_DECISION_TIER: ${INTENT_V2_DECISION_TIER:-none}
|
||||
WORKFLOW_INTENTS_ENABLED: ${WORKFLOW_INTENTS_ENABLED:-true}
|
||||
MULTI_INTENT_ENABLED: ${MULTI_INTENT_ENABLED:-true}
|
||||
SEMANTIC_FALLBACK_ENABLED: ${SEMANTIC_FALLBACK_ENABLED:-false}
|
||||
ports:
|
||||
- "${APP_PUBLISH_HOST:-127.0.0.1}:${HTTP_PORT:-8080}:${HTTP_PORT:-8080}"
|
||||
healthcheck:
|
||||
|
||||
+24
-5
@@ -14,7 +14,7 @@ services:
|
||||
command: ["postgres", "-c", "shared_buffers=512MB", "-c", "max_connections=300"]
|
||||
environment:
|
||||
POSTGRES_USER: ${SYSTEM_DB_USER:-app}
|
||||
POSTGRES_PASSWORD: ${SYSTEM_DB_PASSWORD:-prod_highly_secure_db_pass}
|
||||
POSTGRES_PASSWORD: ${SYSTEM_DB_PASSWORD:?SYSTEM_DB_PASSWORD is required for main/production}
|
||||
POSTGRES_DB: ${SYSTEM_DB_NAME:-agent_system_main}
|
||||
ports:
|
||||
- "127.0.0.1:${SYSTEM_DB_PUBLISH_PORT:-5435}:5432"
|
||||
@@ -60,7 +60,6 @@ services:
|
||||
MINIMAX_API_TYPE: ${MINIMAX_API_TYPE:-openai-compatible}
|
||||
MINIMAX_PROVIDER: minimax
|
||||
TAVILY_API_KEYS: ${TAVILY_API_KEYS:-}
|
||||
TAVILY_API_KEY: ${TAVILY_API_KEY:-}
|
||||
RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:?RUNNER_AUTH_TOKEN is required for main/production}
|
||||
ports:
|
||||
- "127.0.0.1:${PI_AGENT_RUNNER_PORT:-18867}:18867"
|
||||
@@ -92,19 +91,39 @@ services:
|
||||
HTTP_PORT: "${HTTP_PORT:-8000}"
|
||||
HTTP_HOST: "0.0.0.0"
|
||||
AGENT_BACKEND: ${AGENT_BACKEND:-pi-agent}
|
||||
AGENT_TIMEOUT: ${AGENT_TIMEOUT:-30m}
|
||||
MAX_CONCURRENT_AGENTS: ${MAX_CONCURRENT_AGENTS:-8}
|
||||
DATA_DIR: /app/data
|
||||
# 独占生产业务与对话库
|
||||
APP_DB_DSN: postgres://${SYSTEM_DB_USER:-app}:${SYSTEM_DB_PASSWORD:-prod_highly_secure_db_pass}@system-db:5432/${SYSTEM_DB_NAME:-agent_system_main}?sslmode=disable
|
||||
APP_DB_DSN: postgres://${SYSTEM_DB_USER:-app}:${SYSTEM_DB_PASSWORD:?SYSTEM_DB_PASSWORD is required for main/production}@system-db:5432/${SYSTEM_DB_NAME:-agent_system_main}?sslmode=disable
|
||||
# 共享知识库
|
||||
POSTGRES_SHARED_KB_DSN: postgres://${KB_DB_USER:-regkb}:${KB_DB_PASSWORD:-shared_kb_secret_pass}@shuimu-kb-shared:5432/${KB_DB_NAME:-regulations}?sslmode=disable
|
||||
POSTGRES_SHARED_KB_DSN: postgres://${KB_DB_USER:-regkb}:${KB_DB_PASSWORD:?KB_DB_PASSWORD is required for main/production}@shuimu-kb-shared:5432/${KB_DB_NAME:-regulations}?sslmode=disable
|
||||
CURSOR_RUNNER_URL: http://cursor-agent:18767
|
||||
PI_AGENT_RUNNER_URL: http://pi-agent:18867
|
||||
PI_AGENT_RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:?RUNNER_AUTH_TOKEN is required for main/production}
|
||||
PI_AGENT_PROVIDER: ${PI_AGENT_PROVIDER:-minimax}
|
||||
PI_AGENT_MODEL: ${PI_AGENT_MODEL:-${MINIMAX_MODEL_ID:-MiniMax-M3}}
|
||||
RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:?RUNNER_AUTH_TOKEN is required for main/production}
|
||||
KB_DB_PASSWORD: ${KB_DB_PASSWORD:?KB_DB_PASSWORD is required for main/production}
|
||||
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
|
||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?ADMIN_PASSWORD is required for main/production}
|
||||
AUTH_REGISTRATION_ENABLED: ${AUTH_REGISTRATION_ENABLED:-true}
|
||||
AUTH_REQUIRE_APPROVAL: ${AUTH_REQUIRE_APPROVAL:-false}
|
||||
EMBEDDING_ENDPOINT_URL: ${EMBEDDING_ENDPOINT_URL:-}
|
||||
EMBEDDING_MODEL: ${EMBEDDING_MODEL:-bge-m3}
|
||||
EMBEDDING_API_KEY: ${EMBEDDING_API_KEY:-}
|
||||
RERANKER_ENDPOINT_URL: ${RERANKER_ENDPOINT_URL:-}
|
||||
RERANKER_MODEL: ${RERANKER_MODEL:-bge-reranker-v2-m3-free}
|
||||
RERANKER_API_KEY: ${RERANKER_API_KEY:-}
|
||||
CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-}
|
||||
ALLOW_IN_MEMORY: "false"
|
||||
AUX_FILE_DSN: file:/var/lib/feishu/outbox_main.db?_journal_mode=WAL&_busy_timeout=5000
|
||||
CACHE_ENABLED: ${CACHE_ENABLED:-true}
|
||||
INTENT_V2_SHADOW: ${INTENT_V2_SHADOW:-false}
|
||||
INTENT_V2_DECISION: ${INTENT_V2_DECISION:-false}
|
||||
INTENT_V2_DECISION_TIER: ${INTENT_V2_DECISION_TIER:-none}
|
||||
WORKFLOW_INTENTS_ENABLED: ${WORKFLOW_INTENTS_ENABLED:-true}
|
||||
MULTI_INTENT_ENABLED: ${MULTI_INTENT_ENABLED:-true}
|
||||
SEMANTIC_FALLBACK_ENABLED: ${SEMANTIC_FALLBACK_ENABLED:-false}
|
||||
ports:
|
||||
- "${APP_PUBLISH_HOST:-0.0.0.0}:${HTTP_PORT:-8000}:${HTTP_PORT:-8000}"
|
||||
healthcheck:
|
||||
|
||||
@@ -10,7 +10,7 @@ services:
|
||||
container_name: shuimu-kb-shared
|
||||
environment:
|
||||
POSTGRES_USER: ${KB_DB_USER:-regkb}
|
||||
POSTGRES_PASSWORD: ${KB_DB_PASSWORD:-shared_kb_secret_pass}
|
||||
POSTGRES_PASSWORD: ${KB_DB_PASSWORD:?KB_DB_PASSWORD is required}
|
||||
POSTGRES_DB: ${KB_DB_NAME:-regulations}
|
||||
ports:
|
||||
- "127.0.0.1:${KB_PUBLISH_PORT:-5432}:5432"
|
||||
@@ -29,7 +29,7 @@ services:
|
||||
networks:
|
||||
shared-net:
|
||||
name: chat-agent-shared-net
|
||||
driver: bridge
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
shared-kb-pgdata:
|
||||
|
||||
+24
-4
@@ -60,7 +60,6 @@ services:
|
||||
MINIMAX_API_TYPE: ${MINIMAX_API_TYPE:-openai-compatible}
|
||||
MINIMAX_PROVIDER: minimax
|
||||
TAVILY_API_KEYS: ${TAVILY_API_KEYS:-}
|
||||
TAVILY_API_KEY: ${TAVILY_API_KEY:-}
|
||||
RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:-}
|
||||
ports:
|
||||
- "127.0.0.1:${PI_AGENT_RUNNER_PORT:-18866}:18866"
|
||||
@@ -92,17 +91,38 @@ services:
|
||||
HTTP_PORT: "${HTTP_PORT:-8081}"
|
||||
HTTP_HOST: "0.0.0.0"
|
||||
AGENT_BACKEND: ${AGENT_BACKEND:-pi-agent}
|
||||
AGENT_TIMEOUT: ${AGENT_TIMEOUT:-30m}
|
||||
MAX_CONCURRENT_AGENTS: ${MAX_CONCURRENT_AGENTS:-8}
|
||||
DATA_DIR: /app/data
|
||||
# 独占测试业务与对话库
|
||||
APP_DB_DSN: postgres://${SYSTEM_DB_USER:-app}:${SYSTEM_DB_PASSWORD:-test_secret_db_pass}@system-db:5432/${SYSTEM_DB_NAME:-agent_system_test}?sslmode=disable
|
||||
# 共享知识库
|
||||
POSTGRES_SHARED_KB_DSN: postgres://${KB_DB_USER:-regkb}:${KB_DB_PASSWORD:-shared_kb_secret_pass}@shuimu-kb-shared:5432/${KB_DB_NAME:-regulations}?sslmode=disable
|
||||
POSTGRES_SHARED_KB_DSN: postgres://${KB_DB_USER:-regkb}:${KB_DB_PASSWORD:?KB_DB_PASSWORD is required}@shuimu-kb-shared:5432/${KB_DB_NAME:-regulations}?sslmode=disable
|
||||
CURSOR_RUNNER_URL: http://cursor-agent:18766
|
||||
PI_AGENT_RUNNER_URL: http://pi-agent:18866
|
||||
PI_AGENT_RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:-}
|
||||
PI_AGENT_PROVIDER: ${PI_AGENT_PROVIDER:-minimax}
|
||||
PI_AGENT_MODEL: ${PI_AGENT_MODEL:-${MINIMAX_MODEL_ID:-MiniMax-M3}}
|
||||
RUNNER_AUTH_TOKEN: ${RUNNER_AUTH_TOKEN:-}
|
||||
ALLOW_IN_MEMORY: "false"
|
||||
AUX_FILE_DSN: file:/var/lib/feishu/outbox_test.db?_journal_mode=WAL&_busy_timeout=5000
|
||||
EMBEDDING_ENDPOINT_URL: ${EMBEDDING_ENDPOINT_URL:-}
|
||||
EMBEDDING_MODEL: ${EMBEDDING_MODEL:-bge-m3}
|
||||
EMBEDDING_API_KEY: ${EMBEDDING_API_KEY:-}
|
||||
RERANKER_ENDPOINT_URL: ${RERANKER_ENDPOINT_URL:-}
|
||||
RERANKER_MODEL: ${RERANKER_MODEL:-bge-reranker-v2-m3-free}
|
||||
RERANKER_API_KEY: ${RERANKER_API_KEY:-}
|
||||
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
|
||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin-secret-password-123}
|
||||
AUTH_REGISTRATION_ENABLED: ${AUTH_REGISTRATION_ENABLED:-true}
|
||||
AUTH_REQUIRE_APPROVAL: ${AUTH_REQUIRE_APPROVAL:-false}
|
||||
CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-}
|
||||
ALLOW_IN_MEMORY: ${ALLOW_IN_MEMORY:-false}
|
||||
CACHE_ENABLED: ${CACHE_ENABLED:-true}
|
||||
INTENT_V2_SHADOW: ${INTENT_V2_SHADOW:-false}
|
||||
INTENT_V2_DECISION: ${INTENT_V2_DECISION:-false}
|
||||
INTENT_V2_DECISION_TIER: ${INTENT_V2_DECISION_TIER:-none}
|
||||
WORKFLOW_INTENTS_ENABLED: ${WORKFLOW_INTENTS_ENABLED:-true}
|
||||
MULTI_INTENT_ENABLED: ${MULTI_INTENT_ENABLED:-true}
|
||||
SEMANTIC_FALLBACK_ENABLED: ${SEMANTIC_FALLBACK_ENABLED:-false}
|
||||
ports:
|
||||
- "${APP_PUBLISH_HOST:-0.0.0.0}:${HTTP_PORT:-8081}:${HTTP_PORT:-8081}"
|
||||
healthcheck:
|
||||
|
||||
@@ -252,9 +252,29 @@ func Load(path string) (*Config, error) {
|
||||
if v := os.Getenv("AGENT_BACKEND"); v != "" {
|
||||
cfg.AgentBackend = v
|
||||
}
|
||||
if v := os.Getenv("AGENT_TIMEOUT"); v != "" {
|
||||
if d, err := time.ParseDuration(v); err == nil {
|
||||
cfg.AgentTimeout = d
|
||||
}
|
||||
}
|
||||
if v := os.Getenv("CURSOR_API_KEY"); v != "" {
|
||||
cfg.CursorAPIKey = v
|
||||
}
|
||||
if v := os.Getenv("CURSOR_MODEL"); v != "" {
|
||||
cfg.CursorModel = v
|
||||
}
|
||||
if v := os.Getenv("CURSOR_BIN"); v != "" {
|
||||
cfg.CursorBin = v
|
||||
}
|
||||
if v := os.Getenv("CURSOR_BRIDGE_BIN"); v != "" {
|
||||
cfg.CursorBridgeBin = v
|
||||
}
|
||||
if v := os.Getenv("PI_AGENT_BIN"); v != "" {
|
||||
cfg.PiAgentBin = v
|
||||
}
|
||||
if v := os.Getenv("PI_AGENT_BRIDGE_BIN"); v != "" {
|
||||
cfg.PiAgentBridgeBin = v
|
||||
}
|
||||
if v := os.Getenv("PI_AGENT_PROVIDER"); v != "" {
|
||||
cfg.PiAgentProvider = v
|
||||
}
|
||||
@@ -398,7 +418,7 @@ func validateProductionSecrets(cfg *Config) error {
|
||||
"CONTEXT_DB_PASSWORD": cfg.ContextDbPassword,
|
||||
"ADMIN_PASSWORD": cfg.AdminPassword,
|
||||
}
|
||||
defaults := []string{"shared_kb_secret_pass", "dev_secret_db_pass", "admin-secret-password-123"}
|
||||
defaults := []string{"shared_kb_secret_pass", "dev_secret_db_pass", "prod_highly_secure_db_pass", "admin-secret-password-123"}
|
||||
for envKey, val := range weak {
|
||||
if strings.TrimSpace(val) == "" {
|
||||
return fmt.Errorf("%s must be set in %s environment", envKey, cfg.Env)
|
||||
@@ -482,4 +502,3 @@ func (c *Config) KbDSN() string {
|
||||
func (c *Config) ContextDSN() string {
|
||||
return "postgres://" + c.ContextDbUser + ":" + c.ContextDbPassword + "@" + c.ContextDbHost + ":" + strconv.Itoa(c.ContextDbPort) + "/" + c.ContextDbName + "?sslmode=disable"
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,35 @@ func TestConfigLoadDSNOverrides(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigLoadRuntimeEnvironmentOverrides(t *testing.T) {
|
||||
t.Setenv("ENV", "dev")
|
||||
t.Setenv("AGENT_TIMEOUT", "47m")
|
||||
t.Setenv("CURSOR_API_KEY", "cursor-test-key")
|
||||
t.Setenv("CURSOR_MODEL", "cursor-test-model")
|
||||
t.Setenv("CURSOR_BIN", "/test/cursor")
|
||||
t.Setenv("CURSOR_BRIDGE_BIN", "/test/cursor-bridge.mjs")
|
||||
t.Setenv("PI_AGENT_BRIDGE_BIN", "/test/pi-bridge.mjs")
|
||||
t.Setenv("EMBEDDING_MODEL", "embedding-test-model")
|
||||
t.Setenv("RERANKER_MODEL", "reranker-test-model")
|
||||
|
||||
cfg, err := config.Load("/dev/null")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error loading config: %v", err)
|
||||
}
|
||||
if cfg.AgentTimeout != 47*time.Minute {
|
||||
t.Fatalf("expected environment AgentTimeout 47m, got %v", cfg.AgentTimeout)
|
||||
}
|
||||
if cfg.CursorAPIKey != "cursor-test-key" || cfg.CursorModel != "cursor-test-model" || cfg.CursorBin != "/test/cursor" || cfg.CursorBridgeBin != "/test/cursor-bridge.mjs" {
|
||||
t.Fatalf("cursor environment overrides were not applied")
|
||||
}
|
||||
if cfg.PiAgentBridgeBin != "/test/pi-bridge.mjs" {
|
||||
t.Fatalf("pi bridge environment override was not applied")
|
||||
}
|
||||
if cfg.EmbeddingModel != "embedding-test-model" || cfg.RerankerModel != "reranker-test-model" {
|
||||
t.Fatalf("retrieval model environment overrides were not applied")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigLoadCORSDefaultsForDev(t *testing.T) {
|
||||
cfg, err := config.Load("/dev/null")
|
||||
if err != nil {
|
||||
@@ -103,3 +132,15 @@ func TestConfigLoadRejectsWeakSecretsOutsideDev(t *testing.T) {
|
||||
t.Fatal("expected config load to fail for missing secrets in main env")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigLoadRejectsProductionDatabasePlaceholder(t *testing.T) {
|
||||
t.Setenv("ENV", "prod")
|
||||
t.Setenv("KB_DB_PASSWORD", "kb-prod-secret-xyz")
|
||||
t.Setenv("CONTEXT_DB_PASSWORD", "prod_highly_secure_db_pass")
|
||||
t.Setenv("ADMIN_PASSWORD", "admin-prod-secret-xyz")
|
||||
|
||||
_, err := config.Load("/dev/null")
|
||||
if err == nil {
|
||||
t.Fatal("expected config load to reject the documented production database placeholder")
|
||||
}
|
||||
}
|
||||
|
||||
+13
-12
@@ -90,44 +90,45 @@ run_compose() {
|
||||
prepare_env_file "${target}"
|
||||
fi
|
||||
|
||||
local env_arg=""
|
||||
local env_args=()
|
||||
# 根 .env 提供跨环境共用的模型、检索与认证配置;环境文件仅覆盖端口、
|
||||
# 数据库和其他环境差异。后声明的 env-file 优先级更高。
|
||||
if [[ -f ".env" ]]; then
|
||||
env_args+=(--env-file ".env")
|
||||
fi
|
||||
if [[ -f "${env_file}" ]]; then
|
||||
env_arg="--env-file ${env_file}"
|
||||
env_args+=(--env-file "${env_file}")
|
||||
fi
|
||||
|
||||
case "${act}" in
|
||||
start)
|
||||
if [[ "${target}" != "shared" ]]; then
|
||||
ensure_shared_network
|
||||
fi
|
||||
echo "==> [${target}] 启动服务 (${compose_file})..."
|
||||
docker compose -f "${compose_file}" ${env_arg} up -d
|
||||
docker compose -f "${compose_file}" "${env_args[@]}" up -d
|
||||
echo "==> [${target}] 服务已启动"
|
||||
;;
|
||||
stop)
|
||||
echo "==> [${target}] 停止服务..."
|
||||
docker compose -f "${compose_file}" ${env_arg} stop
|
||||
docker compose -f "${compose_file}" "${env_args[@]}" stop
|
||||
;;
|
||||
restart)
|
||||
if [[ "${target}" != "shared" ]]; then
|
||||
ensure_shared_network
|
||||
fi
|
||||
echo "==> [${target}] 重启服务..."
|
||||
docker compose -f "${compose_file}" ${env_arg} restart
|
||||
docker compose -f "${compose_file}" "${env_args[@]}" restart
|
||||
;;
|
||||
status|ps)
|
||||
echo "------------------------------------------------------------"
|
||||
echo "环境: [${target}] (编排: ${compose_file})"
|
||||
echo "------------------------------------------------------------"
|
||||
docker compose -f "${compose_file}" ${env_arg} ps
|
||||
docker compose -f "${compose_file}" "${env_args[@]}" ps
|
||||
echo ""
|
||||
;;
|
||||
logs)
|
||||
docker compose -f "${compose_file}" ${env_arg} logs -f --tail=100
|
||||
docker compose -f "${compose_file}" "${env_args[@]}" logs -f --tail=100
|
||||
;;
|
||||
down)
|
||||
echo "==> [${target}] 清理并下线容器..."
|
||||
docker compose -f "${compose_file}" ${env_arg} down
|
||||
docker compose -f "${compose_file}" "${env_args[@]}" down
|
||||
;;
|
||||
*)
|
||||
echo "[错误] 未知操作: ${act}"
|
||||
|
||||
Reference in New Issue
Block a user