Files
NotesAgentic/docs/contracts/后端接口契约-开发版.md

190 lines
8.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 后端接口契约(开发版)
> 更新日期:2026-08-31。本文档记录当前前后端联调使用的已实现接口;机器可读字段、校验规则和响应模型以 FastAPI 运行时生成的 OpenAPI 为准。第二阶段尚未实现的规划接口见 `第二阶段接口契约-开发版.md`,不要将规划路径视为当前服务能力。
## 契约入口
- Swagger UI`GET /docs`
- OpenAPI`GET /openapi.json`
- 所有普通接口使用 JSON。
- Chat 和 Agent 实时事件使用 `text/event-stream`SSE)。
- 内部时间统一使用 UTC ISO 8601。
- ID 使用稳定业务 ID,不使用文件路径代替 ID。
## 接口清单
### System
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/health` | Sidecar 健康检查 |
| GET | `/api/status` | 获取服务名称、版本和环境 |
### Notes 与 Search
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/api/notes` | 获取笔记列表 |
| POST | `/api/notes` | 创建笔记 |
| GET | `/api/notes/{note_id}` | 获取笔记及 Block |
| PATCH | `/api/notes/{note_id}` | 更新笔记 |
| DELETE | `/api/notes/{note_id}` | 删除笔记 |
| POST | `/api/notes/{note_id}/move` | 移动笔记 |
| POST | `/api/notes/{note_id}/rename` | 重命名笔记文件并保留 Note/Block 身份 |
| POST | `/api/search` | FTS、Vector 或 Hybrid 检索 |
### Workspace
Web 联调阶段只暴露后端通过 `APP_VAULT_PATH` 配置的单一 Vault,不接受浏览器传入任意本地目录。桌面多 Vault 与目录选择仍由后续 Tauri Host 提供。
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/api/workspace` | 获取当前 Vault、文件数和索引同步状态 |
| POST | `/api/workspace/open` | 打开配置的 Vault;磁盘路径集变化时重建索引 |
| GET | `/api/workspace/tree` | 获取真实 Markdown 文件和目录树 |
| POST | `/api/workspace/folders` | 新建目录 |
| POST | `/api/workspace/folders/rename` | 重命名目录并同步 Note 路径 |
| POST | `/api/workspace/folders/delete` | 删除目录及其 Note、Block、FTS 和向量记录 |
### Chat、Agent 与 Tool
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| POST | `/api/chat` | 发起聊天并返回 ModelEvent SSE |
| GET | `/api/agent/runs` | 获取 Agent Run 列表 |
| POST | `/api/agent/runs` | 创建 Agent Run |
| GET | `/api/agent/runs/{run_id}` | 获取 Agent Run 状态与 Trace 摘要 |
| POST | `/api/agent/runs/{run_id}/cancel` | 取消 Agent Run |
| GET | `/api/agent/runs/{run_id}/events` | 订阅 AgentEvent SSE,支持 `Last-Event-ID` / `after_sequence` 恢复 |
| GET | `/api/agent/runs/{run_id}/trace` | 分页读取持久化 Trace、摘要和运行配置快照 |
| POST | `/api/agent/runs/{run_id}/permissions/{request_id}` | 响应 Tool 权限确认 |
| GET | `/api/tools` | 获取已注册 Tool Definition |
### Skill 与 Plugin
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/api/skills` | 获取 Skill 列表及状态 |
| POST | `/api/skills/install` | 安装 Skill |
| GET | `/api/skills/{skill_id}` | 获取 Skill Manifest 与状态 |
| POST | `/api/skills/{skill_id}/enable` | 启用 Skill |
| POST | `/api/skills/{skill_id}/disable` | 停用 Skill |
| DELETE | `/api/skills/{skill_id}` | 卸载 Skill |
| GET | `/api/plugins` | 获取 Plugin 列表及状态 |
| POST | `/api/plugins/install` | 安装 Plugin |
| GET | `/api/plugins/{plugin_id}` | 获取 Plugin Manifest 与状态 |
| POST | `/api/plugins/{plugin_id}/enable` | 启用 Plugin |
| POST | `/api/plugins/{plugin_id}/disable` | 停用 Plugin |
| PUT | `/api/plugins/{plugin_id}/permissions` | 设置 Plugin 已授权权限 |
| DELETE | `/api/plugins/{plugin_id}` | 卸载 Plugin |
### Provider
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/api/providers` | 获取 Provider 配置列表 |
| GET | `/api/providers/presets` | 获取 OpenAI、DeepSeek 与 Ollama 配置预设 |
| POST | `/api/providers` | 新建 Provider 配置 |
| GET | `/api/providers/{provider_id}` | 获取 Provider 配置 |
| PATCH | `/api/providers/{provider_id}` | 更新 Provider 配置 |
| DELETE | `/api/providers/{provider_id}` | 删除 Provider 配置 |
| GET | `/api/providers/{provider_id}/models` | 获取模型及 Capability 列表 |
| POST | `/api/providers/test` | 测试 Provider 连接 |
| GET | `/api/credentials/{credential_id}` | 查询凭据是否已配置,不返回明文 |
| PUT | `/api/credentials/{credential_id}` | 加密保存开发阶段 API Key |
| DELETE | `/api/credentials/{credential_id}` | 删除已保存凭据 |
Provider Contract 只传递 `credential_id` 或临时 `credential_context_id`。当前前后端开发阶段通过独立的 `PUT /api/credentials/{credential_id}` 接收 API Key,并立即加密落盘;该接口只返回配置状态,不返回密钥。Provider CRUD、模型列表和测试接口均不携带明文 API Key。Tauri 集成后由 Stronghold 接管存储实现。
### Tasks、Media 与 Index
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/api/tasks` | 获取任务列表 |
| POST | `/api/tasks` | 创建任务 |
| GET | `/api/tasks/{task_id}` | 获取任务 |
| PATCH | `/api/tasks/{task_id}` | 更新任务 |
| DELETE | `/api/tasks/{task_id}` | 删除任务 |
| POST | `/api/media/transcriptions` | 创建音频转写任务 |
| GET | `/api/media/transcriptions/{job_id}` | 获取转写任务状态 |
| GET | `/api/index/status` | 获取索引服务状态 |
| POST | `/api/index/rebuild` | 创建索引重建任务 |
| GET | `/api/index/jobs/{job_id}` | 获取索引任务状态 |
## 统一错误
所有普通 HTTP 错误统一返回:
```json
{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Resource was not found.",
"details": {}
}
}
```
当前接口主要返回:
- `422 VALIDATION_ERROR`:请求字段不符合 Pydantic Contract
- `404 RESOURCE_NOT_FOUND`:路由或资源不存在。
- `409`:资源冲突、依赖缺失或扩展尚未获得权限;
- `429 AGENT_CAPACITY_EXCEEDED`:活动 Agent Run 达到上限。
前端只根据 `error.code` 判断业务错误,不解析第三方 SDK 的原始异常文本。
## SSE 约定
每条 SSE 包含事件名和对应 JSON Contract
```text
event: TextDelta
data: {"event":"TextDelta","sequence":1,"data":{"text":"..."},"timestamp":"..."}
```
ModelEvent 类型:
```text
TextDelta
ThinkingDelta
ToolCallStart
ToolCallDelta
ToolCallEnd
Usage
Error
Done
```
AgentEvent 类型:
```text
RunStarted
TextDelta
ThinkingDelta
ToolCall
ToolResult
PermissionRequired
Usage
Citation
RunCompleted
RunFailed
RunCancelled
```
## 当前实现状态
更新至 2026-09-01:后端 81 项回归测试通过。
- Chat、Agent Run、Agent Events、Tool 列表、Provider 配置生命周期、模型列表和连接测试已经接入 AI Core。
- Agent Run/Event 已持久化到 SQLiteSSE 帧携带 sequence `id`,断线后可以回放缺失事件。Trace API 与 Benchmark 共用同一事件事实,并在入库前执行 Secret 脱敏和结果限长。
- Provider Adapter 当前包含 Mock、真正增量 SSE 的 OpenAI-Compatible Chat Completions,以及 Ollama JSONL Streaming。
- Notes、Search、Index、Skills、Plugins、Tasks 和 Provider 生命周期均已接入业务服务。
- Workspace 已接入后端配置的真实 Vault;文件树、笔记读写、文件/目录新建、重命名和删除不再使用前端 Mock Fallback。
- Note Move 保留 `note_id`;Citation 的字符偏移统一使用 UTF-16 code unit,供浏览器编辑器直接定位。
- Plugin 启用前必须通过权限接口记录授权,未知权限默认拒绝。
- Attachment Tool 读取 Host 管理的 `attachments` 目录;音频接口读取 Host 生成的转写文本,真实本地语音模型在第二阶段接入。
- 接入业务模块时保持当前路径和 Contract,不在 Router 中直接实现数据库、Provider 或 Agent 逻辑。
第二阶段开发保持本文件中已有路径兼容,并按 `第二阶段接口契约-开发版.md` 增加子资源、可选字段和事件。接口完成后先更新 OpenAPI 与本文件,再将第二阶段文档中的状态改为已实现。