trans4 / docs /zh-CN /reference /http-api.md
Mayo
docs: update to match current implementation
725264a unverified
|
Raw
History Blame Contribute Delete
12.2 kB
---
title: HTTP API 参考
---
# HTTP API 参考
Koharu 在本地暴露 HTTP API:
```text
http://127.0.0.1:<PORT>/api/v1
```
桌面 UI 与 headless Web UI 使用的就是这套 API。
## 运行时模型
当前实现中的重要行为:
- API 与 GUI 或 headless 运行时由同一个进程提供
- 服务器默认绑定到 `127.0.0.1`;使用 `--host` 可绑定到其他地址
- API 与 MCP 服务器共享同一个已加载的项目、模型和管线状态
- 没有提供 `--port` 时,Koharu 会选择一个随机本地端口
- 在应用完成启动之前,除 `/api/v1/downloads``/api/v1/operations``/api/v1/events` 之外的所有路由都会返回 `503 Service Unavailable`
## 资源模型
API 是以项目为中心的。同一时间只会打开一个项目,它包含:
- 一组 `Pages`,按 `PageId` 索引
- 每个页面下的 `Nodes`(图像图层、掩码、文本块),通过 `NodeId` 引用
- 一个内容寻址的 `Blob` 存储,按 Blake3 哈希保存原始图像字节
- 由这些组件构建出的 `Scene` 快照,并通过 `epoch` 计数器递进
- 一段 `Op` 修改历史,可以撤销与重做
所有修改都必须经过历史层(`POST /history/apply`),以保证场景、自动保存和事件订阅者都保持同步。
## 常见响应类型
高频返回结构包括:
- `MetaInfo`:应用版本与 ML 设备
- `EngineCatalog`:每个管线阶段可安装的引擎 id
- `ProjectSummary`:id、名称、路径、页数、最近一次打开时间
- `SceneSnapshot``{ epoch, scene }`
- `LlmState`:当前 LLM 加载状态(status、target、error)
- `LlmCatalog`:按系列分组的本地 + 提供商模型
- `JobSummary``{ id, kind, status, error }`
- `DownloadProgress`:包 id、字节数、状态
## 端点
### 元信息
| 方法 | 路径 | 用途 |
| ----- | ---------- | ------------------------------- |
| `GET` | `/meta` | 获取应用版本与当前 ML 后端 |
| `GET` | `/engines` | 列出每个管线阶段已注册的引擎 |
### 字体
| 方法 | 路径 | 用途 |
| ------ | --------------------------------- | --------------------------------------------- |
| `GET` | `/fonts` | 系统字体 + Google Fonts 的合并目录,用于渲染 |
| `GET` | `/google-fonts` | 单独列出 Google Fonts 目录 |
| `POST` | `/google-fonts/{family}/fetch` | 下载并缓存某个 Google Fonts 字体族 |
| `GET` | `/google-fonts/{family}/{file}` | 提供已缓存的 TTF/WOFF 文件 |
### 项目
每个项目都位于受管理的 `{data.path}/projects/` 目录下;客户端永远不需要传入文件系统路径。
| 方法 | 路径 | 用途 |
| -------- | ----------------------------- | ------------------------------------------------- |
| `GET` | `/projects` | 列出受管理的项目 |
| `POST` | `/projects` | 创建新项目(请求体 `{ name }`) |
| `POST` | `/projects/import` | 把一个 `.khr` 归档解压到新目录并打开 |
| `PUT` | `/projects/current` | 通过 `id` 打开一个受管理项目 |
| `DELETE` | `/projects/current` | 关闭当前会话 |
| `POST` | `/projects/current/export` | 导出当前项目;返回二进制字节 |
`POST /projects/current/export` 接受 `{ format, pages? }`,其中 `format``khr``psd``rendered``inpainted` 之一。当某种格式会产生多个文件时,响应类型是 `application/zip`
### 页面
| 方法 | 路径 | 用途 |
| ------ | --------------------------------------- | --------------------------------------------------- |
| `POST` | `/pages` | 通过 multipart 上传 N 张图片创建页面 |
| `POST` | `/pages/from-paths` | Tauri 专用的快速通道,按绝对路径导入 |
| `POST` | `/pages/{id}/image-layers` | 从上传文件添加一个 Custom 图像节点 |
| `PUT` | `/pages/{id}/masks/{role}` | 用原始 PNG 字节 upsert 一个掩码节点 |
| `GET` | `/pages/{id}/thumbnail` | 获取页面缩略图(以 WebP 缓存) |
`role``segment``brushInpaint``POST /pages` 接受可选字段 `replace=true`;导入时会按文件名自然顺序排序。
### Scene 与 blobs
| 方法 | 路径 | 用途 |
| ----- | ------------------ | ----------------------------------------------------------------- |
| `GET` | `/scene.json` | 完整的场景快照,供 web/UI 客户端使用 |
| `GET` | `/scene.bin` | postcard 编码的 `Snapshot { epoch, scene }`,供 Tauri 客户端使用 |
| `GET` | `/blobs/{hash}` | 按 Blake3 哈希返回 blob 的原始字节 |
`/scene.bin` 会在 `x-koharu-epoch` 响应头里附带当前 epoch。
### 历史(修改)
所有场景修改都从这里走。每个响应都返回 `{ epoch }`
| 方法 | 路径 | 用途 |
| ------ | ------------------- | ------------------------------------- |
| `POST` | `/history/apply` | 应用一个 `Op`(包括 `Op::Batch`) |
| `POST` | `/history/undo` | 撤销上一次应用的 op |
| `POST` | `/history/redo` | 重新应用上一次撤销的 op |
`Op` 是一个带判别字段的联合类型,覆盖添加/删除/更新节点、添加/删除页面、批量操作以及其他场景过渡。请求体是带 JSON tag 的变体。
### 管线
| 方法 | 路径 | 用途 |
| ------ | ------------- | --------------------------------- |
| `POST` | `/pipelines` | 以 operation 形式启动一次管线运行 |
请求体字段:
- `steps`:按顺序执行的引擎 id(会与注册表校验)
- `pages`:可选的 `PageId` 子集;省略时处理整个项目
- `region`:可选的 inpainter 边界框(修复笔刷流程使用)
- `targetLanguage``systemPrompt``defaultFont`:每次运行可覆盖的可选参数
响应携带 `operationId`。进度与完成事件会通过 `/events``JobStarted``JobProgress``JobWarning``JobFinished` 推送。
### Operations
`/operations` 是正在运行和最近完成的任务(管线 + 下载)的统一登记表。
| 方法 | 路径 | 用途 |
| -------- | --------------------- | ---------------------------------------------------- |
| `GET` | `/operations` | 所有正在运行或最近的 operation 的快照 |
| `DELETE` | `/operations/{id}` | 取消一次管线运行;对下载尽力而为地清理 |
### Downloads
| 方法 | 路径 | 用途 |
| ------ | ------------- | ----------------------------------------------- |
| `GET` | `/downloads` | 所有正在进行或最近的下载快照 |
| `POST` | `/downloads` | 启动一次模型包下载(`{ modelId }`) |
`modelId` 是通过 `declare_hf_model_package!` 声明的包 id(例如 `"model:comic-text-detector:yolo-v5"`)。响应是 `{ operationId }`,其值复用包 id。
### LLM 控制
已加载模型是位于 `/llm/current` 的单例资源。
| 方法 | 路径 | 用途 |
| -------- | ---------------- | --------------------------------------------- |
| `GET` | `/llm/current` | 当前状态(status、target、error) |
| `PUT` | `/llm/current` | 加载指定的 target(local 或 provider) |
| `DELETE` | `/llm/current` | 卸载 / 释放当前模型 |
| `GET` | `/llm/catalog` | 列出可用的本地模型 + 提供商支持的模型 |
`PUT /llm/current` 接受 `LlmLoadRequest`
- provider target:`{ kind: "provider", providerId, modelId }`
- local target:`{ kind: "local", modelId }`
- 可选的 `options { temperature, maxTokens, customSystemPrompt }`
`PUT /llm/current` 在加载任务入队后立即返回 `204`。实际就绪状态会作为 `LlmLoaded` 事件发布到 `/events`
### 配置
| 方法 | 路径 | 用途 |
| -------- | --------------------------------- | ----------------------------------------------- |
| `GET` | `/config` | 读取当前 `AppConfig` |
| `PATCH` | `/config` | 应用 `ConfigPatch`;持久化并广播变更 |
| `PUT` | `/config/providers/{id}/secret` | 保存(或覆盖)某个 provider 的 API key |
| `DELETE` | `/config/providers/{id}/secret` | 清除某个 provider 已保存的 API key |
`AppConfig` 暴露顶层的 `data``http``pipeline``providers`
- `data.path`:本地数据目录,用于运行时、模型缓存与项目
- `http { connectTimeout, readTimeout, maxRetries }`:下载与 provider 请求共用的 HTTP 客户端
- `pipeline { detector, fontDetector, segmenter, bubbleSegmenter, ocr, translator, inpainter, renderer }`:每个阶段选用的引擎 id
- `providers[] { id, baseUrl?, apiKey? }`:保存的 API key 在往返中始终以遮蔽占位符 `"[REDACTED]"` 出现,绝不返回原始密钥
内置 provider id:
- `openai`
- `gemini`
- `claude`
- `deepseek`
- `deepl`
- `google-translate`
- `caiyun`
- `openai-compatible`
API key 保存在平台凭据存储中,而不是 `config.toml` 里。PATCH `apiKey: ""` 会清除已保存的 key;PATCH `"[REDACTED]"` 表示保持原值不变。专门的 `/config/providers/{id}/secret` 路由是显式管理某个 provider 密钥的非 PATCH 方式。
## 事件流
Koharu 通过以下地址暴露 Server-Sent Events:
```text
GET /events
```
行为:
- 全新连接(不带 `Last-Event-ID` 请求头)会先收到一个 `Snapshot` 事件,包含当前的任务和下载登记表
- 重连时,服务器会按顺序回放缓冲区中 `seq > Last-Event-ID` 的事件;如果请求的 id 已经从环形缓冲区中滚出,则会重新发送一个 `Snapshot`
- 每个实时事件都会用其 `seq` 作为 SSE `id:` 字段
- 维持 15 秒的 keep-alive
当前事件变体包括:
- `Snapshot`:用于全新客户端与延迟恢复客户端的完整状态种子
- `JobStarted``JobProgress``JobWarning``JobFinished`:管线任务生命周期
- `DownloadProgress`:包下载进度
- `ConfigChanged`:通过 `PATCH /config` 或 secret 路由应用了配置变更
- `LlmLoaded``LlmUnloaded`:LLM 生命周期切换
- `SceneAdvanced`:场景修改使 epoch 推进时触发
## 典型工作流
新建一个项目时常见的 API 调用顺序:
1. `POST /projects`:创建项目
2. `POST /pages`(或 Tauri 下的 `/pages/from-paths`):导入图片
3. `PUT /llm/current`:加载翻译模型(本地或 provider)
4. `POST /pipelines`:启动 `detect → ocr → translate → inpaint → render`
5. 监听 `GET /events` 直到 `JobFinished`
6. `POST /projects/current/export``format = "rendered"``"psd"`
如果你需要更精细的控制,可以直接 `POST /history/apply` 携带显式 `Op` 负载,而不是运行整条管线。
如果你更想用面向 Agent 的接口,而不是手动编排 HTTP 端点,请参见 [MCP 工具参考](mcp-tools.md)。