Test CI / Check Duplicate Run (push) Failing after 2s
E2E CI / Check Duplicate Run (push) Failing after 2s
E2E CI / Test Web App (push) Has been skipped
Test CI / Test Packages (push) Has been skipped
Test CI / Test App (shard 2/3) (push) Has been skipped
Test CI / Test App (shard 3/3) (push) Has been skipped
Test CI / Test App (shard 1/3) (push) Has been skipped
🔄 Branch Synchronization / sync-branches (push) Failing after 9s
Test CI / Test Desktop App (push) Has been skipped
Test CI / Test Database (push) Has been skipped
Test CI / Merge and Upload App Coverage (push) Has been skipped
Claude Auto Testing Coverage / add-tests (push) Failing after 1m47s
197 lines
12 KiB
Markdown
197 lines
12 KiB
Markdown
# Enterprise AI Workspace
|
||
|
||
> 本仓库 = **上游 LobeChat 源码** + **自建 Enterprise Gateway (gateway/)** + **docker-compose 编排**。
|
||
>
|
||
> 目标是在本地 Docker 跑一套企业 AI 工作台原型:权限/身份/数据范围/字段脱敏/审计 全部由 `gateway/` 承担,LobeChat 作为对话 UI。
|
||
>
|
||
> **本地原型**,不上云、不 push 部署、不对外开放。所有敏感字段仅存本地 `.env`。
|
||
|
||
---
|
||
|
||
## 与上游 LobeChat 的差异(完整清单)
|
||
|
||
### 新增目录 / 文件(全部是本项目新增的)
|
||
|
||
| 路径 | 作用 |
|
||
|---|---|
|
||
| `gateway/` | Fastify + Prisma + Postgres 实现的 **Enterprise Gateway**。16 工具、9 张企业表、capabilities + identity_map + data_scope + field_policies + audit 全链路。 |
|
||
| `gateway/src/routes/admin/*` | 后台管理 API:users / roles / tools / data-scopes / identity-map / audit / tool-schemas |
|
||
| `gateway/src/routes/admin/ui.ts` | 极简管理员 HTML UI(`/admin` + `/admin/login` 等 6 页,带 CSRF) |
|
||
| `gateway/src/routes/lobechatPlugin.ts` | 动态 LobeChat plugin manifest + tool-gateway 桥接 |
|
||
| `gateway/src/routes/metrics.ts` | Prometheus `/metrics`(super_admin 或 `Bearer METRICS_TOKEN`) |
|
||
| `gateway/src/core/{gateway,filter,masking,audit,capabilities,cache,auditQueue,metrics,rateLimiter,scopeDsl}.ts` | Gateway 核心流水 |
|
||
| `gateway/src/auth/{devAuth,casdoor,casdoorM2M,middleware}.ts` | 开发 header 认证 + Casdoor JWKS Bearer + M2M client_credentials |
|
||
| `gateway/src/tools/*` | 8 类工具适配器:gongdan / xiaoshou / cloudcost / kb / aiSearch (Serper) / sandbox (Daytona) / docGenerate |
|
||
| `gateway/prisma/schema.prisma` + `seed.ts` | 企业侧 9 张表 schema + 种子 |
|
||
| `gateway/scripts/acceptance.sh` | 43 条自动化验收(T1–T24) |
|
||
| `gateway/scripts/pilot-{gongdan,kb,xiaoshou,cloudcost,casdoor,ai-search,sandbox,doc,all}.sh` | 真实上游 pilot + 统一入口 |
|
||
| `docker-compose.yml` | 全栈编排:db (pgvector) + redis + gateway + lobechat |
|
||
| `db-init/01-create-dbs.sql` | 同一 Postgres 内建两个逻辑库:`enterprise_gateway` + `lobechat` |
|
||
| `lobechat-plugin-manifest/` | 给 LobeChat 用的 plugin manifest + 指引 |
|
||
| `docs/DELIVERY.md` | 交付清单 + 测试报告 |
|
||
| `docs/PRODUCTION-SECRETS.md` | 所有密钥的轮换与风险等级 |
|
||
| `docs/CASDOOR-SETUP.md` | Casdoor Application 配置手册 |
|
||
| `AI-BRAIN-API.md` / `EXTERNAL_SERVICES.md` / `SUPER_OPS_API.md` / `工单接口.md` | 四份上游系统对接文档(用户提供) |
|
||
| `.omc/plans/autopilot-impl.md` + `.omc/autopilot/spec.md` | 原始实施规划 |
|
||
| `README.gateway.md` + `README.lobechat.md` | 归档:旧的 Gateway-only README 与上游 LobeChat README |
|
||
|
||
### 修改了哪些上游 LobeChat 源码
|
||
|
||
| 路径 | 改动 |
|
||
|---|---|
|
||
| `packages/business/const/src/branding.ts` | `BRANDING_NAME='Enterprise AI Workspace'`、`ORG_NAME='Enterprise AI'`、`SOCIAL_URL=''`、`BRANDING_LOGO_URL='/brand/logo.svg'`、邮箱/链接全清 |
|
||
| `src/routes/(main)/settings/about/features/About.tsx` | 移除 Discord/GitHub/X/YouTube/Blog/RSS 自推广卡片,保留版本号 + 中性说明 |
|
||
| `src/routes/(main)/settings/about/index.tsx` | 移除 `<Analytics />`(LobeHub analytics 开关) |
|
||
| `src/services/marketApi.ts::getSkillDownloadUrl` | 默认 `https://market.lobehub.com` → `''`;不设 env 则不加载 LobeHub 市场插件 |
|
||
| `src/libs/next/config/define-config.ts` | `/discover` 重定向目标从 `/community` 改为 `/` |
|
||
| `packages/builtin-agents/src/agents/agent-builder/systemRole.ts` | 开场白去品牌 |
|
||
| `packages/builtin-agents/src/agents/group-supervisor/systemRole.ts` | 同上 |
|
||
| `public/favicon.ico` + `favicon-32x32.ico` + 18 个 .ico 变体 + `apple-touch-icon.png` + `public/icons/icon-*.png` | 换成 EAI 中性 logo |
|
||
| `public/brand/logo.svg` | 新建(EAI 灰色圆角方块) |
|
||
| `locales/**/*.json` | 批量替换 `LobeHub` / `LobeChat` → `Enterprise AI Workspace`、`LobeHub CLI` → `Enterprise AI CLI`、邮箱 `*@lobehub.com` → `support@enterprise-ai.local`。**242 个文件 / 760 处替换**。i18n key 名未改。 |
|
||
| `packages/database/migrations/0090_enable_pg_search.sql` | **注释为空 migration**:pg_search 扩展在 `pgvector/pgvector:pg16` 镜像里不存在;此原型用 pgvector 做向量 RAG 就够,BM25 全文搜索暂不启用。 |
|
||
| `packages/database/migrations/0093_add_bm25_indexes_with_icu.sql` | 同上,依赖 0090 的空操作 |
|
||
|
||
### 其他配置
|
||
|
||
- `.env.example` / `.env`(本地 gitignore)包含全部 env 变量模板 + 真实凭据(只在本地)
|
||
- `Dockerfile` 未改(直接用上游;构建参数 `USE_CN_MIRROR=true` 开启 npmmirror 国内源加速)
|
||
- `.gitignore` 补了 `.env` / `.env.pilot` / `.env.auth` / `.env.local` 确保密钥不入库
|
||
|
||
---
|
||
|
||
## 架构
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────────┐
|
||
│ 浏览器 http://localhost:3010 ─ 对话 / Admin UI (gateway) │
|
||
│ │ │
|
||
│ ┌──────────────┐ ┌──▼──────────────┐ │
|
||
│ │ lobechat │ tool │ Enterprise │ │
|
||
│ │ (Next.js) │ bridge │ Gateway │ ◀── 企业 SSOT │
|
||
│ │ :3210 ├────────▶│ :3001 │ │
|
||
│ └──────┬───────┘ │ Fastify+Prisma │ │
|
||
│ │ └───┬──────────┬──┘ │
|
||
│ │ │ │ │
|
||
│ ▼ ▼ ▼ │
|
||
│ ┌────────┐ ┌─────────┐ ┌─────────┐ │
|
||
│ │Postgres│◀──────────┤ Redis │ │ 8 类上游│ │
|
||
│ │pgvector│ │ cache + │ │ (HTTP) │ │
|
||
│ │pg16 │ │ BullMQ │ └─────────┘ │
|
||
│ └────────┘ └─────────┘ │
|
||
└────────────────────────────────────────────────────────────┘
|
||
db (企业DB + lobechat DB) gongdan / xiaoshou /
|
||
cloudcost / kb / serper /
|
||
daytona / doc-agent
|
||
```
|
||
|
||
---
|
||
|
||
## 端口
|
||
|
||
| 服务 | 本机 | 容器内 |
|
||
|---|---|---|
|
||
| LobeChat UI | `localhost:3010` | `3210` |
|
||
| Gateway | `localhost:3001` | `3001` |
|
||
| Postgres | `localhost:5432` | `5432` |
|
||
| Redis | (只在 compose 网络内) | `6379` |
|
||
|
||
---
|
||
|
||
## 启动
|
||
|
||
```bash
|
||
# 1. 填 .env(用 .env.example 作模板;本地已填真实凭据)
|
||
cp .env.example .env # 如果还没有
|
||
|
||
# 2. 生成生产级 secret(可选,开发默认值能跑)
|
||
for k in KEY_VAULTS_SECRET AUTH_SECRET TOKEN_ENCRYPTION_KEY ADMIN_CSRF_SECRET METRICS_TOKEN; do
|
||
echo "$k=$(openssl rand -base64 32)" >> .env
|
||
done
|
||
|
||
# 3. 起栈(LobeChat 镜像从本仓库根 Dockerfile 源码构建,首次 20+ 分钟)
|
||
docker compose build --build-arg USE_CN_MIRROR=true
|
||
docker compose up -d
|
||
|
||
# 4. 验收
|
||
curl -sf http://localhost:3001/health # {"status":"ok","db":"ok"}
|
||
curl -sI http://localhost:3010/ # 200 或 307
|
||
bash gateway/scripts/acceptance.sh # 43/43
|
||
bash gateway/scripts/pilot-all.sh # 8 个上游 pilot
|
||
```
|
||
|
||
Admin 后台登录:浏览器开 `http://localhost:3001/admin`,用户 `sa`/`pa` 等 dev 用户名(dev 模式)。
|
||
|
||
---
|
||
|
||
## 开发/测试用户(seed)
|
||
|
||
| 用户名 | 角色 | 能看到的工具 |
|
||
|---|---|---|
|
||
| `sa` | super_admin | 全部 |
|
||
| `pa` | permission_admin | 仅 Admin 后台 |
|
||
| `sales1` | internal_sales | xiaoshou * 4 + kb + ai_search + doc |
|
||
| `ops1` | internal_ops | gongdan * 2 + cloudcost * 2 + xiaoshou + kb + doc |
|
||
| `tech1` | internal_tech | gongdan.get_ticket + kb + ai_search + sandbox + doc |
|
||
| `cust1` | customer | kb + ai_search + sandbox + doc + gongdan.create_ticket + gongdan.get_own_tickets |
|
||
|
||
dev 模式传头 `X-Dev-User: <username>` 即切换身份。
|
||
|
||
---
|
||
|
||
## Pilot 脚本(本地真实上游验证)
|
||
|
||
`bash gateway/scripts/pilot-all.sh` 一把跑:
|
||
|
||
| 脚本 | 目标 | 需要的 env |
|
||
|---|---|---|
|
||
| pilot-gongdan.sh | 工单真 upstream + identity_map 过滤 | `GONGDAN_API_KEY` |
|
||
| pilot-kb.sh | 知识库真 upstream + 60s Redis 缓存 | `KB_API_KEY` |
|
||
| pilot-ai-search.sh | Serper.dev 真 upstream | `AI_SEARCH_KEY` |
|
||
| pilot-sandbox.sh | Daytona workspace 列表(真 auth) | `SANDBOX_KEY` |
|
||
| pilot-doc.sh | 文档 agent 生成 docx(真 upstream) | `DOC_AGENT_KEY` |
|
||
| pilot-xiaoshou.sh | xiaoshou super-ops(若无 key clean-skip) | `SUPER_OPS_API_KEY`(待发) |
|
||
| pilot-cloudcost.sh | cloudcost Casdoor M2M(条件 pass) | `CLOUDCOST_M2M_*` |
|
||
| pilot-casdoor.sh | JWKS Bearer 路径(内置 mock IdP) | 无 |
|
||
|
||
---
|
||
|
||
## 已实现(摘要)
|
||
|
||
- Casdoor OIDC 代码 ready:dev 双路径 + JWKS Bearer 验证 + DB 角色 fallback + M2M client_credentials(AES-256-GCM 加密缓存到 Redis)
|
||
- **16 工具** 全部注册;gongdan/kb/serper/daytona auth/doc 已跑过真 upstream
|
||
- 管理后台:`/admin/*` 六页 + CSRF + dev 登录
|
||
- 权限栈:deny-wins capability + identity_map 过滤 + data_scope DSL(白名单 + `$in`/`$contains`/`$regex`)+ field_policies(drop/mask/hash + 通配)+ BullMQ 异步审计(sync 兜底)
|
||
- 速率限制:全局 300/min、tool 60/min、admin mutate 30/min
|
||
- Prometheus `/metrics`:tool_call 计数+直方图、audit 队列深度、cache 命中/未命中、identity_map 缺失
|
||
- 43 条 acceptance + 8 条 pilot
|
||
- LobeChat 源码级去品牌:brand 常量 + logo + 字体 + favicon + 默认 agent + About 页 + locales 760 处 + market 默认 URL 置空 + /discover 重定向
|
||
|
||
## 已知限制 / 需用户手工
|
||
|
||
1. **Casdoor Application** 需要用户在 Casdoor 后台创建(详见 `docs/CASDOOR-SETUP.md`),拿 Client ID / Client Secret 写入 `.env` 才能端到端 SSO。此前留的 admin 密钥已存入 `.env`。
|
||
2. **SUPER_OPS_API_KEY** 由 xiaoshou 系统管理员分发;无 key 时 pilot-xiaoshou 自动 skip。
|
||
3. **CLOUDCOST_M2M_CLIENT_ID/SECRET** 要在 Casdoor 另建 M2M App;无则 pilot-cloudcost 返回条件 pass。
|
||
4. **pg_search / BM25 全文搜索未启用**:`pgvector/pgvector:pg16` 镜像不带 `pg_search.control`。原型用 pgvector 做向量 RAG,本项未启用 BM25 索引。要启用需切 `paradedb/paradedb` 镜像并同步 pg 大版本(需数据迁移,非原型阶段范围)。
|
||
5. **Daytona sandbox 真 exec 闭环**要求账号侧先注册 `daytonaio/workspace-project:latest` snapshot;我们的 pilot 以"documented unsupported"形式通过。
|
||
6. **生产用 secret** 请先用 `openssl rand -base64 32` 替换 `.env` 里的 `replace_me_*` 占位值(`docs/PRODUCTION-SECRETS.md` 有清单)。
|
||
|
||
---
|
||
|
||
## 故障排查速查
|
||
|
||
```bash
|
||
docker compose ps -a # 容器 / 端口状态
|
||
docker logs lobechat-gateway-1 --tail 50
|
||
docker logs lobechat-lobechat-1 --tail 50
|
||
docker exec lobechat-db-1 psql -U eg -d enterprise_gateway -c "\dt enterprise_*"
|
||
docker exec lobechat-redis-1 redis-cli keys 'cap:v1:*' # 查看权限缓存
|
||
bash gateway/scripts/acceptance.sh | grep FAIL
|
||
```
|
||
|
||
---
|
||
|
||
## 清理
|
||
|
||
`docker compose down` 保留数据卷;`docker compose down -v` 连 pgdata 一起清。本原型**建议不要 down**,让用户人工核验。
|