File size: 15,280 Bytes
e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a c1298ea 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 725264a e84bff1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | ---
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 はプロジェクト中心です。一度に開けるプロジェクトは 1 つで、次のものを含みます。
- `PageId` でインデックスされた `Pages` のリスト
- `NodeId` で参照されるページごとの `Nodes` (画像レイヤー、マスク、テキストブロック)
- 画像のバイト列を Blake3 ハッシュで保存する content-addressed な `Blob` ストア
- それらから組み立てられる `Scene` スナップショット (`epoch` カウンタで進む)
- undo/redo 可能な `Op` 変更の履歴
すべてのシーン変更は履歴レイヤー (`POST /history/apply`) を経由するため、シーン、自動保存、イベント購読者は常に同期されます。
## よく使うレスポンス型
頻出するレスポンス型には次があります。
- `MetaInfo` — アプリバージョンと ML デバイスラベル
- `EngineCatalog` — パイプライン段階ごとにインストール可能な engine id
- `ProjectSummary` — id、name、path、ページ数、最終オープン日時
- `SceneSnapshot` — `{ epoch, scene }`
- `LlmState` — 現在の LLM 読み込み状態 (status、target、error)
- `LlmCatalog` — ローカルおよびプロバイダのモデルを family ごとにまとめたもの
- `JobSummary` — `{ id, kind, status, error }`
- `DownloadProgress` — パッケージ id、バイト数、ステータス
## エンドポイント
### Meta
| Method | Path | 目的 |
| ------ | ----------- | ---------------------------------------------------- |
| `GET` | `/meta` | アプリバージョンと有効な ML バックエンドを取得する |
| `GET` | `/engines` | 段階ごとに登録済みのパイプライン engine を一覧する |
### フォント
| Method | Path | 目的 |
| ------ | ------------------------------------- | ------------------------------------------------------------- |
| `GET` | `/fonts` | レンダリング用に system + Google Fonts を統合したカタログ |
| `GET` | `/google-fonts` | Google Fonts カタログを単体で取得する |
| `POST` | `/google-fonts/{family}/fetch` | Google Fonts の family を 1 つダウンロードしてキャッシュする |
| `GET` | `/google-fonts/{family}/{file}` | キャッシュ済みの TTF/WOFF ファイルを返す |
### Projects
すべてのプロジェクトは管理対象の `{data.path}/projects/` 配下に置かれ、クライアントがファイルシステムパスを渡すことはありません。
| Method | Path | 目的 |
| -------- | --------------------------------- | ----------------------------------------------------------------- |
| `GET` | `/projects` | 管理されているプロジェクトを一覧する |
| `POST` | `/projects` | 新しいプロジェクトを作成する (body `{ 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` になります。
### Pages
| Method | Path | 目的 |
| ------ | --------------------------------------- | --------------------------------------------------------------- |
| `POST` | `/pages` | アップロードされた N 枚の画像からページを作る (multipart) |
| `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` フィールドを受け付け、取り込みはファイル名を natural order で整列して行われます。
### Scene と blob
| Method | Path | 目的 |
| ------ | ------------------- | ---------------------------------------------------------------------- |
| `GET` | `/scene.json` | Web/UI クライアント用のフルシーンスナップショット |
| `GET` | `/scene.bin` | Tauri クライアント用に postcard エンコードされた `Snapshot { epoch, scene }` |
| `GET` | `/blobs/{hash}` | Blake3 ハッシュで指定した blob の生バイト |
`/scene.bin` は現在の epoch をレスポンスヘッダ `x-koharu-epoch` に含めて返します。
### History (mutations)
シーンの変更はすべてここを通します。各レスポンスは `{ epoch }` を返します。
| Method | Path | 目的 |
| ------ | ------------------- | ------------------------------------------------- |
| `POST` | `/history/apply` | `Op` を適用する (`Op::Batch` を含む) |
| `POST` | `/history/undo` | 最後に適用された op を取り消す |
| `POST` | `/history/redo` | 最後に取り消された op を再適用する |
`Op` はノードの追加/削除/更新、ページの追加/削除、batch などのシーン遷移を表す discriminated union です。body は JSON タグ付きの variant を渡します。
### Pipelines
| Method | Path | 目的 |
| ------ | ------------- | ------------------------------------------------- |
| `POST` | `/pipelines` | パイプライン実行を operation として開始する |
body のフィールド:
- `steps` — 順に実行する engine id (レジストリで検証される)
- `pages` — 任意の `PageId` 部分集合。省略するとプロジェクト全体が対象
- `region` — inpainter 用の任意のバウンディングボックス (repair-brush フロー)
- `targetLanguage`、`systemPrompt`、`defaultFont` — この実行のみの任意上書き
レスポンスは `operationId` を返します。進捗と完了は `/events` から `JobStarted`、`JobProgress`、`JobWarning`、`JobFinished` として届きます。
### Operations
`/operations` は実行中および直近完了したジョブ (パイプラインとダウンロード) を統一的に扱うレジストリです。
| Method | Path | 目的 |
| -------- | --------------------- | ------------------------------------------------------------------- |
| `GET` | `/operations` | 実行中または直近の operation 一覧スナップショット |
| `DELETE` | `/operations/{id}` | パイプライン実行をキャンセル。ダウンロードは best-effort で除去 |
### Downloads
| Method | Path | 目的 |
| ------ | ------------------- | ------------------------------------------------- |
| `GET` | `/downloads` | 実行中または直近のダウンロードのスナップショット |
| `POST` | `/downloads` | モデルパッケージのダウンロードを開始する (`{ modelId }`) |
`modelId` は `declare_hf_model_package!` で宣言されたパッケージ id (例: `"model:comic-text-detector:yolo-v5"`) です。レスポンスはパッケージ id を再利用した `{ operationId }` を返します。
### LLM 制御
ロード済みモデルは `/llm/current` に対するシングルトンリソースとして扱われます。
| Method | Path | 目的 |
| -------- | ---------------- | ---------------------------------------------------------- |
| `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` を返します。実際のロード完了状態は `/events` の `LlmLoaded` で通知されます。
### Config
| Method | Path | 目的 |
| -------- | --------------------------------------- | ---------------------------------------------------------- |
| `GET` | `/config` | 現在の `AppConfig` を取得する |
| `PATCH` | `/config` | `ConfigPatch` を適用する。永続化と broadcast を行う |
| `PUT` | `/config/providers/{id}/secret` | プロバイダの API キーを保存 (上書き) する |
| `DELETE` | `/config/providers/{id}/secret` | プロバイダに保存された API キーを削除する |
`AppConfig` はトップレベルに `data`、`http`、`pipeline`、`providers` を持ちます。
- `data.path` — ランタイム、モデルキャッシュ、プロジェクトに使うローカルデータディレクトリ
- `http { connectTimeout, readTimeout, maxRetries }` — ダウンロードと provider リクエストで共有される HTTP クライアント
- `pipeline { detector, fontDetector, segmenter, bubbleSegmenter, ocr, translator, inpainter, renderer }` — 各段階で選ばれた engine id
- `providers[] { id, baseUrl?, apiKey? }` — 保存された API キーは生値ではなく、マスク済みプレースホルダ `"[REDACTED]"` で往復する
組み込みの provider id:
- `openai`
- `gemini`
- `claude`
- `deepseek`
- `deepl`
- `google-translate`
- `caiyun`
- `openai-compatible`
API キーはプラットフォームの credential store に保存され、`config.toml` には書き出されません。`apiKey: ""` を PATCH すると保存済みキーが削除され、`"[REDACTED]"` を PATCH するとそのまま維持されます。`/config/providers/{id}/secret` は、PATCH を介さずに 1 プロバイダのシークレットを明示的に管理するための専用ルートです。
## Events stream
Koharu は次の URL で Server-Sent Events を公開しています。
```text
GET /events
```
挙動:
- 新規接続 (`Last-Event-ID` ヘッダなし) では、最初に現在のジョブとダウンロードのレジストリを含む `Snapshot` イベントを送る
- 再接続時は `seq > Last-Event-ID` のバッファ済みイベントを順に再送する。要求された id が ring からスクロールアウトしている場合はサーバーが再度 `Snapshot` を送る
- 各ライブイベントは SSE の `id:` フィールドに `seq` を付けて発行される
- 15 秒ごとに keep-alive を送信する
現在のイベント variant:
- `Snapshot` — 新規接続および遅延回復クライアント用の完全な状態シード
- `JobStarted`、`JobProgress`、`JobWarning`、`JobFinished` — パイプライン job のライフサイクル
- `DownloadProgress` — パッケージダウンロード進捗
- `ConfigChanged` — `PATCH /config` または secret ルートで config が更新された
- `LlmLoaded`、`LlmUnloaded` — LLM ライフサイクル遷移
- `SceneAdvanced` — シーン変更により epoch が進んだときに発行される
## 典型的なワークフロー
新規プロジェクト 1 件分の通常の API 呼び出し順は次の通りです。
1. `POST /projects` — プロジェクトを作成する
2. `POST /pages` (または Tauri からは `/pages/from-paths`) — 画像を取り込む
3. `PUT /llm/current` — 翻訳用モデルをロードする (local または provider)
4. `POST /pipelines` — `detect → ocr → translate → inpaint → render` を開始する
5. `JobFinished` まで `GET /events` を tail する
6. `format = "rendered"` または `"psd"` を指定して `POST /projects/current/export`
より細かく制御したい場合は、フルパイプラインを実行する代わりに、明示的な `Op` ペイロードで `POST /history/apply` を呼びます。
HTTP エンドポイントを順に叩く代わりに、エージェント向けのアクセスが欲しい場合は [MCP ツールリファレンス](mcp-tools.md) を参照してください。
|