HTTP API 参考¶
Koharu 在本地暴露 HTTP API:
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:每个管线阶段可安装的引擎 idProjectSummary: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 }:每个阶段选用的引擎 idproviders[] { id, baseUrl?, apiKey? }:保存的 API key 在往返中始终以遮蔽占位符"[REDACTED]"出现,绝不返回原始密钥
内置 provider id:
openaigeminiclaudedeepseekdeeplgoogle-translatecaiyunopenai-compatible
API key 保存在平台凭据存储中,而不是 config.toml 里。PATCH apiKey: "" 会清除已保存的 key;PATCH "[REDACTED]" 表示保持原值不变。专门的 /config/providers/{id}/secret 路由是显式管理某个 provider 密钥的非 PATCH 方式。
事件流¶
Koharu 通过以下地址暴露 Server-Sent Events:
GET /events
行为:
- 全新连接(不带
Last-Event-ID请求头)会先收到一个Snapshot事件,包含当前的任务和下载登记表 - 重连时,服务器会按顺序回放缓冲区中
seq > Last-Event-ID的事件;如果请求的 id 已经从环形缓冲区中滚出,则会重新发送一个Snapshot - 每个实时事件都会用其
seq作为 SSEid:字段 - 维持 15 秒的 keep-alive
当前事件变体包括:
Snapshot:用于全新客户端与延迟恢复客户端的完整状态种子JobStarted、JobProgress、JobWarning、JobFinished:管线任务生命周期DownloadProgress:包下载进度ConfigChanged:通过PATCH /config或 secret 路由应用了配置变更LlmLoaded、LlmUnloaded:LLM 生命周期切换SceneAdvanced:场景修改使 epoch 推进时触发
典型工作流¶
新建一个项目时常见的 API 调用顺序:
POST /projects:创建项目POST /pages(或 Tauri 下的/pages/from-paths):导入图片PUT /llm/current:加载翻译模型(本地或 provider)POST /pipelines:启动detect → ocr → translate → inpaint → render- 监听
GET /events直到JobFinished POST /projects/current/export,format = "rendered"或"psd"
如果你需要更精细的控制,可以直接 POST /history/apply 携带显式 Op 负载,而不是运行整条管线。
如果你更想用面向 Agent 的接口,而不是手动编排 HTTP 端点,请参见 MCP 工具参考。