# Eternal AI AI 陪伴平台 — 人设创作者设定并发布角色,自动生成 Hermes Agent 可用的配置文件(SOUL.md + config.yaml),支持跨机器 CLI 拉取部署。 ## 架构 ``` ┌──────────────────────────────────────────────────────────┐ │ 浏览器 (SPA) │ │ index.html + app.js + styles.css │ │ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌───────────┐ │ │ │ 认证视图 │ │ 角色库 │ │ 创作者中心 │ │ 角色编辑器 │ │ │ └──────────┘ └──────────┘ └───────────┘ └───────────┘ │ └──────────────────────┬───────────────────────────────────┘ │ HTTP / JSON ┌──────────────────────▼───────────────────────────────────┐ │ Express.js 服务端 (server.js) │ │ ┌─────────┐ ┌─────────┐ ┌──────────┐ ┌───────────────┐ │ │ │ /api/auth│ │/api/roles│ │/api/apikeys│ │ /api/hermes │ │ │ └────┬────┘ └────┬────┘ └─────┬────┘ └──────┬────────┘ │ │ │ │ │ │ │ │ ┌────▼───────────▼────────────▼──────────────▼────────┐ │ │ │ 认证中间件 (src/lib/auth.js) │ │ │ │ JWT 认证 (authMiddleware) + API Key 认证 │ │ │ │ (apiKeyMiddleware, eak_ 前缀, SHA-256 哈希) │ │ │ └─────────────────────┬───────────────────────────────┘ │ └────────────────────────┼─────────────────────────────────┘ │ Prisma ORM ┌────────────────────────▼─────────────────────────────────┐ │ PostgreSQL 数据库 │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ User │ │ Role │ │ ApiKey │ │ Order │ │ │ └────────┘ └────────┘ └────────┘ └────────┘ │ └──────────────────────────────────────────────────────────┘ ``` ### 技术栈 | 层 | 技术 | |----|------| | 前端 | 原生 HTML5 SPA(IIFE 模式,无框架)、玻璃拟态 UI | | 后端 | Node.js + Express 5.x | | 数据库 | PostgreSQL 15 + Prisma ORM 5.x | | 认证 | JWT(7 天有效期)+ API Key(`eak_` 前缀,SHA-256 哈希存储) | | 密码 | bcryptjs(10 轮盐) | | 测试 | Playwright E2E(35 个测试用例) | | 部署 | PM2 + Nginx 反向代理 | ### 项目结构 ``` EternalAI/ ├── server.js # Express 入口,注册路由 + 静态文件 ├── app.js # 前端 SPA 逻辑(路由、状态、表单、API 调用) ├── index.html # 单页应用入口(9 个视图) ├── styles.css # 玻璃拟态样式 ├── prisma/ │ └── schema.prisma # 数据模型定义(User / Role / ApiKey / Order) ├── src/ │ ├── lib/ │ │ ├── auth.js # JWT + API Key 认证中间件 │ │ └── prisma.js # Prisma Client 单例 │ └── routes/ │ ├── auth.js # 注册 / 登录 / 用户信息 / 设置 │ ├── roles.js # 角色 CRUD + 角色库 │ ├── apikeys.js # API Key 生成 / 列表 / 删除 │ └── hermes.js # Hermes 配置拉取端点(SOUL.md / config.yaml) ├── deploy/ │ ├── setup-server.sh # 服务器一键初始化脚本 │ ├── deploy.sh # CI/CD 部署脚本 │ └── nginx.conf # Nginx 反向代理配置 ├── e2e/ # Playwright E2E 测试 ├── docs/ # 需求文档与规划 └── package.json ``` ## 快速开始 ### 本地开发 ```bash # 1. 安装依赖 npm install # 2. 配置环境变量 cp .env.example .env # 编辑 .env,设置 DATABASE_URL 和 JWT_SECRET # JWT_SECRET 可用 openssl rand -hex 32 生成 # 3. 初始化数据库 npx prisma db push npx prisma generate # 4. 启动开发服务器 npm run dev # → http://localhost:3001 ``` ### 服务器部署 ```bash # 在服务器上执行一键初始化脚本 bash deploy/setup-server.sh # 自动安装 Node.js / PostgreSQL / Nginx / PM2,创建 .env,推送 Schema ``` ## 操作流程 ### 1. 用户注册与登录 ``` 用户 → 首页 → 登录/注册视图 ├─ 注册:填写账号 + 密码(≥6位)→ 自动登录,返回 JWT └─ 登录:账号 + 密码 → 验证成功,返回 JWT └─ JWT 存入 localStorage,后续请求携带 Authorization: Bearer ``` ### 2. 创作者入驻与角色设定 ``` 登录用户 → 创作者入驻页 → 开通创作者身份 → 创作者管理中心(三个 Tab) ├─ 角色 Tab:新建 / 编辑角色 ├─ 收入 Tab:余额 + 付费流水 └─ 设置 Tab:昵称 / 角色库名 / API Key 管理 新建角色(4 步表单): Step 1 → 基础信息(名称、性别、年龄、关系) Step 2 → 性格设定(性格、背景、说话风格、喜好) Step 3 → 模型配置(模型、温度、最大 Token、记忆/工具开关) Step 4 → 发布设置(问候语、价格、描述) → 提交后自动生成 SOUL.md + config.yaml 存入数据库 → 角色上架到角色库 ``` ### 3. 角色库浏览与购买 ``` 任意用户 → 角色库 → 浏览已上架角色 → 点击角色卡片 → 查看详情 → 付款 → 创建订单 → 解锁角色 ``` ## 与 Hermes Agent 交互流程 EternalAI 生成的角色配置(SOUL.md + config.yaml)可通过 CLI 拉取命令部署到任意 Hermes Agent 机器上,支持跨机器部署。 ### 架构图 ``` 服务器 A (EternalAI) 服务器 B (Hermes Agent) ┌───────────────────────┐ ┌───────────────────────┐ │ 1. 设置页生成 API Key │ │ │ │ (eak_xxxxxxxxxx) │ │ 5. hermes profile │ │ │ │ create role-mio │ │ 2. 创建角色 → 发布 │ │ │ │ 生成 SOUL.md + │ │ 6. curl 拉取文件 │ │ config.yaml │ │ SOUL.md │ │ │ │ config.yaml │ │ 3. 角色管理页显示 │ 4. 用户复制 │ │ │ curl 命令模板 │──── curl ────▶│ 7. 配置 .env │ │ (含 API Key) │ 命令执行 │ (API 密钥) │ │ │ │ │ │ │ │ 8. role-mio chat │ └───────────────────────┘ └───────────────────────┘ ``` ### 步骤详解 #### Step 1-3:在 EternalAI Web UI 操作 1. **生成 API Key**:创作者管理中心 → 设置 Tab → 点击「生成 API Key」→ 明文 Key 仅显示一次,请妥善保存 2. **创建角色**:创作者管理中心 → 角色 Tab → 新建角色 → 填写 4 步表单 → 发布 3. **获取部署命令**:角色卡片点击「Hermes 部署」→ 弹窗显示完整的 curl 命令模板(含服务器地址、角色 ID、API Key)→ 点击复制 #### Step 4-8:在 Hermes Agent 机器上操作 ```bash # 4. 复制 curl 命令到 Hermes 机器执行 # 5. 创建 Hermes profile hermes profile create role-mio # 6. 拉取 SOUL.md curl -H "Authorization: Bearer eak_xxx" \ https://your-eternalai-domain.com/api/hermes/roles//SOUL.md \ -o ~/.hermes/profiles/role-mio/SOUL.md # 7. 拉取 config.yaml curl -H "Authorization: Bearer eak_xxx" \ https://your-eternalai-domain.com/api/hermes/roles//config.yaml \ -o ~/.hermes/profiles/role-mio/config.yaml # 8. 配置 API 密钥并启动 echo "OPENROUTER_API_KEY=sk-or-xxx" > ~/.hermes/profiles/role-mio/.env role-mio chat ``` ### config.yaml 格式适配 EternalAI 角色数据自动转换为 Hermes config.yaml 格式: | EternalAI 字段 | Hermes config.yaml 字段 | |---|---| | `role.model` | `model:` | | `role.temperature` | `temperature:` | | `role.maxTokens` | `max_tokens:` | | `role.enableMemory` | `memory.enabled:` | | `role.enableTools` | `tools.enabled:` | 生成的 config.yaml 示例: ```yaml # Hermes Agent Config — generated by EternalAI # Character: Mio # Agent ID: default # Generated at: 2026-06-21T12:00:00.000Z model: "gpt-4o" temperature: 0.85 max_tokens: 2048 memory: enabled: true storage: local tools: enabled: true toolsets: - memory terminal: backend: local ``` ### API Key 安全机制 - **格式**:`eak_` + 32 位随机 hex(128 位熵) - **存储**:SHA-256 哈希存储,明文仅在生成时返回一次 - **脱敏显示**:列表中仅显示前 12 位(如 `eak_a1b2c3d4`) - **认证**:通过 `Authorization: Bearer eak_xxx` 头传递 - **权限**:API Key 只能拉取所属用户创建的角色配置 - **可吊销**:随时在设置页删除,删除后立即失效 ## API 参考 ### 认证 API | 方法 | 路径 | 认证 | 说明 | |------|------|------|------| | POST | `/api/auth/register` | 无 | 注册(账号 + 密码) | | POST | `/api/auth/login` | 无 | 登录 | | GET | `/api/auth/me` | JWT | 获取当前用户信息 | | PUT | `/api/auth/settings` | JWT | 更新用户设置 | ### 角色 API | 方法 | 路径 | 认证 | 说明 | |------|------|------|------| | GET | `/api/roles` | 无 | 获取角色库(已上架) | | GET | `/api/roles/:id` | 无 | 获取角色详情 | | GET | `/api/roles/my/roles` | JWT | 获取我创建的角色 | | POST | `/api/roles` | JWT | 发布新角色 | | PUT | `/api/roles/:id` | JWT | 编辑角色 | | GET | `/api/roles/:id/full` | JWT | 获取角色完整信息(含 SOUL.md) | ### API Key 管理 | 方法 | 路径 | 认证 | 说明 | |------|------|------|------| | POST | `/api/apikeys` | JWT | 生成 API Key(明文仅返回一次) | | GET | `/api/apikeys` | JWT | 列出所有 API Key(脱敏) | | DELETE | `/api/apikeys/:id` | JWT | 删除 API Key | ### Hermes 配置拉取 | 方法 | 路径 | 认证 | 说明 | |------|------|------|------| | GET | `/api/hermes/roles/:id/SOUL.md` | API Key / JWT | 拉取 SOUL.md(text/plain) | | GET | `/api/hermes/roles/:id/config.yaml` | API Key / JWT | 拉取 config.yaml(text/plain) | ## 测试 ```bash # 运行全部 E2E 测试(35 个用例) npm test # 查看测试报告 npx playwright show-report ``` 测试覆盖:认证流程、角色发布/编辑、角色库浏览、导航与可访问性。 ## 安全 - **JWT 密钥**:生产环境必须设置 `JWT_SECRET` 环境变量,未设置时 fail-fast 抛错 - **密码存储**:bcrypt 哈希(10 轮盐),不存明文 - **API Key 存储**:SHA-256 哈希存储,明文仅显示一次 - **XSS 防护**:所有用户可控数据通过 `escapeHtml()` 转义后插入 DOM - **YAML 注入防护**:config.yaml 生成时对用户可控字段做双引号转义和换行符过滤 - **所有权校验**:所有角色操作验证 `creatorId === req.userId` - **.env 文件权限**:部署脚本自动设置 `chmod 600` ## License MIT