|
Deploy EternalAI / deploy (push) Has been cancelled
Details
|
||
|---|---|---|
| .gitea/workflows | ||
| deploy | ||
| docs | ||
| e2e | ||
| hermes-server | ||
| img | ||
| prisma | ||
| scripts | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| Eternal_AI_PRD_v1.docx | ||
| README.md | ||
| app.js | ||
| ecosystem.config.js | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.js | ||
| server.js | ||
| styles.css | ||
README.md
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
快速开始
本地开发
# 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 deploy/setup-server.sh
# 自动安装 Node.js / PostgreSQL / Nginx / PM2,创建 .env,推送 Schema
操作流程
1. 用户注册与登录
用户 → 首页 → 登录/注册视图
├─ 注册:填写账号 + 密码(≥6位)→ 自动登录,返回 JWT
└─ 登录:账号 + 密码 → 验证成功,返回 JWT
└─ JWT 存入 localStorage,后续请求携带 Authorization: Bearer <token>
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 操作
- 生成 API Key:创作者管理中心 → 设置 Tab → 点击「生成 API Key」→ 明文 Key 仅显示一次,请妥善保存
- 创建角色:创作者管理中心 → 角色 Tab → 新建角色 → 填写 4 步表单 → 发布
- 获取部署命令:角色卡片点击「Hermes 部署」→ 弹窗显示完整的 curl 命令模板(含服务器地址、角色 ID、API Key)→ 点击复制
Step 4-8:在 Hermes Agent 机器上操作
# 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/<role-id>/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/<role-id>/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 示例:
# 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) |
测试
# 运行全部 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