diff --git a/Docs/api/rest-api.md b/Docs/api/rest-api.md new file mode 100644 index 0000000..d08792d --- /dev/null +++ b/Docs/api/rest-api.md @@ -0,0 +1,278 @@ +# Cyrene v2 — REST API 参考 + +> **Base URL**: `http://localhost:8080/api/v1` +> **认证方式**: Bearer Token (JWT) + +--- + +## 认证 + +所有认证端点无需 Token。受保护端点需在 Header 中携带 `Authorization: Bearer `。 + +### `POST /auth/register` + +注册新用户。 + +```bash +curl -X POST http://localhost:8080/api/v1/auth/register \ + -H 'Content-Type: application/json' \ + -d '{"username":"myuser","password":"mypassword"}' +``` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| username | string | ✅ | 用户名,不可重复 | +| password | string | ✅ | 密码,最少 6 位 | + +**成功响应** (201) +```json +{"token": "eyJhbGciOiJIUzI1NiIs..."} +``` + +**错误** +| 状态码 | 说明 | +|--------|------| +| 400 | 用户名已存在 / 密码太短 | + +--- + +### `POST /auth/login` + +登录获取 Token。 + +```bash +curl -X POST http://localhost:8080/api/v1/auth/login \ + -H 'Content-Type: application/json' \ + -d '{"username":"admin","password":"admin12345"}' +``` + +**成功响应** (200) +```json +{"token": "eyJhbGciOiJIUzI1NiIs..."} +``` + +**错误** +| 状态码 | 说明 | +|--------|------| +| 401 | 用户名或密码错误 | + +--- + +### `GET /health` + +健康检查(无需认证)。 + +```bash +curl http://localhost:8080/api/v1/health +``` + +**响应** (200) +```json +{"status":"ok","service":"cyrene-gateway","version":"2.0.0-dev"} +``` + +--- + +## 会话管理 + +### `POST /sessions` + +创建新会话。 + +```bash +curl -X POST http://localhost:8080/api/v1/sessions \ + -H 'Authorization: Bearer ' +``` + +**响应** (201) +```json +{"session_id": "a1b2c3d4e5f6"} +``` + +### `GET /sessions` + +获取会话列表。 + +**响应** (200) +```json +{"sessions": []} +``` + +### `DELETE /sessions/:id` + +删除指定会话。 + +**响应** (204) — 无内容 + +--- + +## 记忆管理 + +### `GET /memory` + +获取当前用户的记忆列表。 + +```bash +curl http://localhost:8080/api/v1/memory \ + -H 'Authorization: Bearer ' +``` + +**响应** (200) +```json +{ + "data": [{ + "id": "uuid", + "user_id": "admin", + "content": "喜欢咖啡", + "summary": "喜欢咖啡", + "keywords": ["喜欢", "咖啡"], + "category": "preference", + "priority": 0.8 + }] +} +``` + +### `POST /memory` + +创建新记忆。支持自动去重。 + +```bash +curl -X POST http://localhost:8080/api/v1/memory \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + -d '{"content":"用户喜欢喝咖啡","category":"preference","priority":0.8}' +``` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| content | string | ✅ | 记忆内容 | +| category | string | | 分类:fact/preference/event/plan (默认 fact) | +| priority | float | | 优先级 0.0-1.0 (默认 0.5) | + +**响应** (201) — 返回创建的完整记忆对象 + +### `GET /memory/:id` + +获取单条记忆。 + +**错误** — 404 Not Found + +### `DELETE /memory/:id` + +删除单条记忆。 + +**响应** (204) — 无内容 + +### `GET /memory/search?q=关键词` + +搜索记忆(关键词匹配)。 + +```bash +curl "http://localhost:8080/api/v1/memory/search?q=咖啡" \ + -H 'Authorization: Bearer ' +``` + +**响应** (200) — 返回匹配的记忆列表 + +--- + +## 语音服务 + +### `POST /voice/stt` + +语音识别(Speech to Text)。 + +```bash +curl -X POST http://localhost:8080/api/v1/voice/stt \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + -d '{"audio_data":"base64..."}' +``` + +**响应** (200) +```json +{"text": "你好世界"} +``` + +> ⚠️ 当前为 stub 实现。生产环境需配置 DashScope API Key。 + +### `POST /voice/tts` + +文字转语音(Text to Speech)。 + +```bash +curl -X POST http://localhost:8080/api/v1/voice/tts \ + -H 'Authorization: Bearer ' \ + -H 'Content-Type: application/json' \ + -d '{"text":"你好","voice":"zh-CN-XiaoxiaoNeural"}' +``` + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| text | string | — | 要转换的文本 | +| voice | string | zh-CN-XiaoxiaoNeural | 语音角色 | + +**响应** (200) +```json +{"audio_size": 0} +``` + +--- + +## 管理面板 + +### `GET /admin/dashboard` + +获取系统状态(需 admin 角色)。 + +```bash +curl http://localhost:8080/api/v1/admin/dashboard \ + -H 'Authorization: Bearer ' +``` + +**响应** (200) +```json +{ + "dashboard": { + "status": "running", + "version": "2.0.0-dev", + "uptime_sec": 3600, + "services": { + "memory": true, + "voice": true, + "ai_core": true + } + } +} +``` + +--- + +## WebSocket + +### `GET /ws/chat?token=` + +升级到 WebSocket 连接。详见 [WebSocket 协议文档](websocket.md)。 + +--- + +## 错误码总览 + +| 状态码 | 含义 | 常见场景 | +|--------|------|---------| +| 200 | 成功 | GET/PUT 请求 | +| 201 | 已创建 | POST 成功 | +| 204 | 无内容 | DELETE 成功 | +| 400 | 请求错误 | 参数缺失/格式错误 | +| 401 | 未认证 | Token 无效或过期 | +| 403 | 无权限 | 非 admin 访问管理端点 | +| 404 | 未找到 | 资源不存在 | +| 405 | 方法不允许 | 用了错误的 HTTP 方法 | +| 429 | 限流 | 请求频率过高 | +| 500 | 服务器错误 | 内部异常 | +| 503 | 服务不可用 | 依赖服务未就绪 | + +**错误响应格式** +```json +{"error": "错误描述"} +``` diff --git a/Docs/api/websocket.md b/Docs/api/websocket.md new file mode 100644 index 0000000..80285f9 --- /dev/null +++ b/Docs/api/websocket.md @@ -0,0 +1,146 @@ +# Cyrene v2 — WebSocket 协议 + +> **端点**: `ws://localhost:8080/ws/chat?token=` +> **协议**: JSON 文本帧 + +--- + +## 连接 + +``` +ws://localhost:8080/ws/chat?token=eyJhbGciOi... +``` + +Token 通过 query 参数传递,需先通过 `/api/v1/auth/login` 获取。 + +--- + +## 客户端 → 服务端 + +### 发送消息 + +```json +{ + "type": "message", + "content": "你好呀", + "session_id": "abc123", + "timestamp": 1234567890 +} +``` + +| 字段 | 类型 | 说明 | +|------|------|------| +| type | string | 固定 `"message"` | +| content | string | 用户输入文本 | +| session_id | string | 会话 ID(需先通过 REST 创建) | +| timestamp | number | Unix 毫秒时间戳 | + +--- + +## 服务端 → 客户端 + +### `stream_chunk` — 流式输出 + +LLM 逐 token 推送。前端应累积拼接。 + +```json +{ + "type": "stream_chunk", + "content": "你", + "session_id": "abc123" +} +``` + +### `stream_end` — 流式结束 + +```json +{ + "type": "stream_end", + "session_id": "abc123" +} +``` + +### `response` — 独立消息 + +审查后的 action/chat 分段或系统响应。 + +```json +{ + "type": "response", + "content": "你好呀~ 有什么可以帮你的吗?", + "session_id": "abc123" +} +``` + +> **action 消息**:当 content 包含 `[Intent: xxxx]` 前缀时,前端应居中斜体渲染。 + +### `device_update` — IoT 状态广播 + +```json +{ + "type": "device_update", + "devices": [ + {"id": "light-livingroom", "name": "客厅灯", "type": "light", "state": {"power": true}, "online": true} + ] +} +``` + +### `notification` — 推送通知 + +```json +{ + "type": "notification", + "title": "提醒", + "body": "你设置的闹钟时间到了" +} +``` + +### `error` — 错误消息 + +```json +{ + "type": "error", + "error": "AI 引擎未配置" +} +``` + +--- + +## 完整对话流程 + +``` +1. 浏览器 → POST /api/v1/auth/login → 获得 JWT Token +2. 浏览器 → POST /api/v1/sessions → 获得 session_id +3. 浏览器 → WS /ws/chat?token= → WebSocket 连接建立 +4. 浏览器 → 发送 {"type":"message","content":"打开客厅灯","session_id":"..."} +5. 服务端 → stream_chunk: "好" +6. 服务端 → stream_chunk: "的" +7. 服务端 → stream_chunk: "~" +8. 服务端 → response: "[Intent: iot_control]" +9. 服务端 → response: "客厅灯已经打开啦♪" +10. 服务端 → stream_end +``` + +--- + +## 重连策略 + +前端应实现指数退避自动重连: + +| 重试次数 | 等待时间 | +|---------|---------| +| 1 | 1s | +| 2 | 2s | +| 3 | 4s | +| 4 | 8s | +| 5+ | 30s (上限) | + +重连后需重新发送 `session_id` 绑定消息。 + +--- + +## 注意事项 + +- 单连接单会话:一个 WebSocket 连接对应一个 `session_id` +- Token 过期:服务端返回 `{"type":"error","error":"invalid token"}` 后关闭连接,前端应重新登录 +- 心跳:暂时无 ping/pong 协议,TCP 层保活。