feat: CEO plan preview & confirm before company execution

- Add POST /companies/{id}/plan endpoint for stateless CEO plan preview (no DB write)
- execute()/execute_stream() accept optional confirmed ceo_plan to skip re-planning
- Frontend: plan preview dialog in CompanyBuilder to review/tweak analysis, dept goals & deliverables before running; previewCompanyPlan API with extended timeout
- Grant file_write tool to CEO/CTO presets; add echarts dependency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 00:40:22 +08:00
parent f2e65a8fbb
commit eef48ce831
8 changed files with 875 additions and 88 deletions

View File

@@ -16,6 +16,14 @@
所有服务通过 Docker Compose 编排,统一在 `aiagent-net` 桥接网络中通信。
> **重要:本项目在 101.43.95.130 的实际生产部署与本指南默认假设有三处差异,升级/运维前务必先看:**
>
> 1. **数据库是外部腾讯云 CloudDB(TDSQL-C),不是容器 MySQL。** `docker-compose.prod.yml` 里没有 mysql 服务,也就没有 `aiagent-mysql` 容器。凡是 `docker exec aiagent-mysql ...` 的命令都要改成直连外部实例(见第六、七、九节的「外部数据库」写法)。
> 2. **服务器在国内,`docker compose build` 常卡在 apt-get / PyPI(files.pythonhosted.org)超时。** 构建或装包需走国内镜像源(见第四节)。
> 3. **升级不要盲目 `alembic upgrade`。** 公司模块迁移 `d684c9b30c1c` 是 autogenerate 的破坏性迁移(会 drop 掉 tools/api_keys 等已有数据的表),且线上库对应表已存在。正确做法见第六节「增量升级」。
>
> 实际部署目录为 `/home/renjianbo/aiagent`(本指南示例用 `/opt/aiagent`,按需替换)。
---
## 二、服务器要求
@@ -173,6 +181,21 @@ docker compose -f docker-compose.prod.yml build --pull
docker compose -f docker-compose.prod.yml up -d
```
> **国内服务器注意(重要)**:在腾讯云等国内服务器上,`docker compose build` 经常卡在 `apt-get update` 或 `files.pythonhosted.org` 超时。处理办法:
>
> - **给 Docker 配镜像加速**(构建时拉基础镜像):编辑 `/etc/docker/daemon.json` 加入
> ```json
> { "registry-mirrors": ["https://mirror.ccs.tencentyun.com"] }
> ```
> 然后 `sudo systemctl restart docker`(`mirror.ccs.tencentyun.com` 为腾讯云内网加速地址)。
> - **给 pip 换国内源**:在 `backend/Dockerfile` 的 pip 安装步骤加
> `-i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com`。
> - **临时给已运行容器补一个 Python 包**(不想重建镜像时):
> ```bash
> docker exec <容器名> pip install -i https://mirrors.aliyun.com/pypi/simple/ \
> --trusted-host mirrors.aliyun.com <包名>==<版本>
> ```
### 4. 验证部署
```bash
@@ -206,6 +229,8 @@ aiagent-kibana Up
aiagent-filebeat Up
```
> **使用外部腾讯云数据库时**:没有 `aiagent-mysql` 容器(少一个)。核心服务确认 `aiagent-backend`、`aiagent-redis`、`aiagent-frontend`、两个 celery 均为 `Up`,且 `curl -s -o /dev/null -w '%{http_code}' http://localhost:8037/docs` 返回 `200` 即为正常。
---
## 五、访问地址
@@ -260,6 +285,14 @@ docker compose -f docker-compose.prod.yml up -d
### 增量升级
> **升级前必读(本项目实测坑)**:
> 1. **构建可能失败**:`docker compose build --pull` 在国内服务器常因 apt/PyPI 超时卡死,先按第四节配好国内镜像;急用时可用「docker cp 热更新 + 补依赖」绕过(见下方备用步骤 2B/3)。
> 2. **迁移要小心**:公司模块迁移 `d684c9b30c1c_add_company_tables` 是破坏性的(会 `drop_table` tools/api_keys/fcm_tokens 等)。若线上库里 companies/company_projects 等表已存在,**不要执行 `alembic upgrade`**,而是标记版本:
> ```bash
> docker exec aiagent-backend sh -c "cd /app && alembic stamp d684c9b30c1c"
> ```
> 3. **新依赖**:新代码引入了 `APScheduler==3.10.4`(公司调度用)。旧镜像若没有,backend 会 `ModuleNotFoundError: No module named 'apscheduler'` 崩溃,需按第四节临时装包(backend + 两个 celery 都要装)。
项目提供了 `upgrade.sh` 脚本实现零停机升级:
```bash
@@ -274,31 +307,66 @@ bash upgrade.sh
5. 清理旧镜像,释放磁盘空间
6. 验证后端健康状态
手动升级步骤(不使用脚本):
手动升级步骤(国内服务器 / 外部数据库实测流程):
```bash
# 拉取最新代码
cd /home/renjianbo/aiagent # 或 /opt/aiagent
# 1. 拉取最新代码
git pull
# 重新构建并启动
# 2A. 常规:重建镜像并重启(网络好、已配国内镜像时)
docker compose -f docker-compose.prod.yml build --pull
docker compose -f docker-compose.prod.yml up -d
# 2B. 备用:build 卡死时,热更新已运行容器的代码(不重建镜像)
docker cp backend/app aiagent-backend:/app/
docker cp backend/alembic aiagent-backend:/app/
docker cp backend/app aiagent-celery-worker:/app/
docker cp backend/app aiagent-celery-beat:/app/
# 3. 有新 Python 依赖时,用国内源补装(三个容器都装)
for c in aiagent-backend aiagent-celery-worker aiagent-celery-beat; do
docker exec $c pip install -i https://mirrors.aliyun.com/pypi/simple/ \
--trusted-host mirrors.aliyun.com -r /app/requirements.txt
done
# 4. 迁移:先看当前版本,破坏性迁移用 stamp(勿盲目 upgrade,见上方警告)
docker exec aiagent-backend sh -c "cd /app && alembic current"
# 5. 重启后端使代码生效并验证
docker compose -f docker-compose.prod.yml restart backend
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8037/docs # 期望 200
```
> 走 2B 热更新的改动只在容器可写层,`docker compose up`/重建容器会丢失;条件允许时仍应配好国内镜像走 2A 正式重建。
### 数据库备份
**A. 容器内 MySQL(本指南默认):**
```bash
# 备份到本地文件
docker exec aiagent-mysql mysqldump -u root -p<密码> agent_db > agent_db_backup.sql
```
# 定时备份(加入 crontab,每天凌晨 2 点)
# 0 2 * * * cd /opt/aiagent && docker exec aiagent-mysql mysqldump -u root -p<密码> agent_db > backups/agent_db_$(date +\%Y\%m\%d).sql
**B. 外部腾讯云 CloudDB(本项目实际用法,无 aiagent-mysql 容器):** 直连外部实例:
```bash
mysqldump -h gz-cynosdbmysql-grp-xxx.sql.tencentcdb.com -P 24936 \
-u root -p<密码> agent_db > agent_db_backup.sql
# 若本机没装 mysql 客户端,可借用 mysql 镜像执行:
# docker run --rm mysql:8.0 mysqldump -h <外部地址> -P 24936 -uroot -p<密码> agent_db > agent_db_backup.sql
# 定时备份(crontab,每天凌晨 2 点)
# 0 2 * * * mysqldump -h <外部地址> -P 24936 -uroot -p<密码> agent_db > /home/renjianbo/aiagent/backups/agent_db_$(date +\%Y\%m\%d).sql
```
### 数据库恢复
```bash
# 容器内 MySQL
docker exec -i aiagent-mysql mysql -u root -p<密码> agent_db < agent_db_backup.sql
# 外部腾讯云 CloudDB
mysql -h gz-cynosdbmysql-grp-xxx.sql.tencentcdb.com -P 24936 -u root -p<密码> agent_db < agent_db_backup.sql
```
---
@@ -392,17 +460,21 @@ free -h
### 数据库连接失败
**容器内 MySQL:**
```bash
# 确认 MySQL 容器是否健康
docker exec aiagent-mysql mysqladmin ping -h localhost
# 检查后端能否连接 MySQL
docker exec aiagent-backend sh -c "curl -s mysql:3306" || echo "无法连接"
# 查看 MySQL 日志
docker logs aiagent-mysql --tail 30
```
**外部腾讯云 CloudDB(本项目实际用法):** 从 backend 容器内验证能否连通外部库:
```bash
docker exec aiagent-backend python -c "import os,re,pymysql; \
u=os.environ['DATABASE_URL']; m=re.match(r'.*://([^:]+):([^@]+)@([^:]+):(\d+)/([^?]+)',u); \
pymysql.connect(host=m.group(3),user=m.group(1),password=m.group(2),port=int(m.group(4)),database=m.group(5)); \
print('DB OK')"
```
排查点:`.env` 的 `DATABASE_URL` 是否正确、腾讯云 CloudDB 安全组是否放行了本服务器的出口 IP、账号密码是否有效、库 `agent_db` 是否存在。
### DeepSeek API 返回 401
确认 `.env` 中 `DEEPSEEK_API_KEY` 已正确配置,密钥未过期。