File size: 13,089 Bytes
33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 725264a 33ae6b5 | 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: Referência da API HTTP
---
# Referência da API HTTP
O Koharu expõe uma API HTTP local em:
```text
http://127.0.0.1:<PORT>/api/v1
```
Esta é a mesma API usada pela UI desktop e pela Web UI em modo headless.
## Modelo de runtime
Comportamento atual importante:
- a API é servida pelo mesmo processo da GUI ou do runtime headless
- o servidor faz bind em `127.0.0.1` por padrão; use `--host` para fazer bind em outro lugar
- a API e o servidor MCP compartilham o mesmo projeto carregado, modelos e estado do pipeline
- quando nenhum `--port` é fornecido, o Koharu escolhe uma porta local aleatória
- tudo, exceto `/api/v1/downloads`, `/api/v1/operations` e `/api/v1/events`, retorna `503 Service Unavailable` até o app terminar a inicialização
## Modelo de recursos
A API é centrada em projetos. Apenas um projeto fica aberto por vez e contém:
- uma lista de `Pages` indexada por `PageId`
- `Nodes` por página (camadas de imagem, máscaras, blocos de texto) referenciados por `NodeId`
- um armazenamento `Blob` endereçado por conteúdo, que guarda os bytes brutos das imagens por hash Blake3
- um snapshot de `Scene` montado a partir dessas peças, avançado por um contador `epoch`
- um histórico de mutações `Op` que podem ser desfeitas ou refeitas
As mutações sempre passam pela camada de histórico (`POST /history/apply`), de modo que a cena, o autosave e os assinantes de eventos permaneçam sincronizados.
## Formatos comuns de response
Tipos de response frequentemente usados incluem:
- `MetaInfo` — versão do app e label do dispositivo de ML
- `EngineCatalog` — ids das engines instaláveis por etapa do pipeline
- `ProjectSummary` — id, nome, caminho, contagem de páginas, último acesso
- `SceneSnapshot` — `{ epoch, scene }`
- `LlmState` — estado atual de carga do LLM (status, target, error)
- `LlmCatalog` — modelos locais + de provedor agrupados por família
- `JobSummary` — `{ id, kind, status, error }`
- `DownloadProgress` — id do pacote, contagens de bytes, status
## Endpoints
### Meta
| Método | Path | Finalidade |
| ------ | ----------- | --------------------------------------------------- |
| `GET` | `/meta` | obtém a versão do app e o backend de ML ativo |
| `GET` | `/engines` | lista as engines de pipeline registradas por etapa |
### Fontes
| Método | Path | Finalidade |
| ------ | ------------------------------------- | ---------------------------------------------------------------- |
| `GET` | `/fonts` | catálogo combinado de fontes do sistema + Google Fonts para render |
| `GET` | `/google-fonts` | catálogo do Google Fonts como uma lista isolada |
| `POST` | `/google-fonts/{family}/fetch` | baixa e faz cache de uma família do Google Fonts |
| `GET` | `/google-fonts/{family}/{file}` | serve o arquivo TTF/WOFF em cache |
### Projetos
Todo projeto vive sob o diretório gerenciado `{data.path}/projects/`; clientes nunca fornecem caminhos do filesystem.
| Método | Path | Finalidade |
| -------- | --------------------------------- | ------------------------------------------------------------------- |
| `GET` | `/projects` | lista os projetos gerenciados |
| `POST` | `/projects` | cria um novo projeto (body `{ name }`) |
| `POST` | `/projects/import` | extrai um arquivo `.khr` em um diretório novo e o abre |
| `PUT` | `/projects/current` | abre um projeto gerenciado por `id` |
| `DELETE` | `/projects/current` | fecha a sessão atual |
| `POST` | `/projects/current/export` | exporta o projeto atual; retorna bytes binários |
`POST /projects/current/export` aceita `{ format, pages? }` onde `format` é um de `khr`, `psd`, `rendered`, `inpainted`. Quando o formato produz múltiplos arquivos, a response é `application/zip`.
### Páginas
| Método | Path | Finalidade |
| ------ | --------------------------------------- | ----------------------------------------------------------- |
| `POST` | `/pages` | cria páginas a partir de N arquivos de imagem enviados (multipart) |
| `POST` | `/pages/from-paths` | caminho rápido só para Tauri que importa por caminho absoluto |
| `POST` | `/pages/{id}/image-layers` | adiciona um node de imagem Custom a partir de um arquivo enviado |
| `PUT` | `/pages/{id}/masks/{role}` | faz upsert de um node de máscara a partir de bytes PNG brutos |
| `GET` | `/pages/{id}/thumbnail` | obtém a thumbnail da página (cache em WebP) |
`role` é `segment` ou `brushInpaint`. `POST /pages` aceita um campo opcional `replace=true`; a importação é ordenada pelo nome de arquivo em ordem natural.
### Cena e blobs
| Método | Path | Finalidade |
| ------ | ------------------- | ----------------------------------------------------------------------- |
| `GET` | `/scene.json` | snapshot completo da cena para clientes web/UI |
| `GET` | `/scene.bin` | `Snapshot { epoch, scene }` codificado em postcard para o cliente Tauri |
| `GET` | `/blobs/{hash}` | bytes brutos do blob por hash Blake3 |
`/scene.bin` inclui o epoch atual no header de response `x-koharu-epoch`.
### Histórico (mutações)
Todas as mutações da cena passam por aqui. Cada response retorna `{ epoch }`.
| Método | Path | Finalidade |
| ------ | ------------------- | ------------------------------------------- |
| `POST` | `/history/apply` | aplica um `Op` (incluindo `Op::Batch`) |
| `POST` | `/history/undo` | reverte a última op aplicada |
| `POST` | `/history/redo` | reaplica a última op desfeita |
`Op` é a união discriminada que cobre add/remove/update node, add/remove page, batch e outras transições da cena. O body é a variante com tag JSON.
### Pipelines
| Método | Path | Finalidade |
| ------ | ------------- | ------------------------------------------------ |
| `POST` | `/pipelines` | inicia uma execução de pipeline como uma operação |
Campos do body:
- `steps` — ids das engines a executar em ordem (validados contra o registry)
- `pages` — subconjunto opcional de `PageId`s; omita para processar o projeto inteiro
- `region` — bounding box opcional para o inpainter (fluxo de pincel de reparo)
- `targetLanguage`, `systemPrompt`, `defaultFont` — overrides opcionais por execução
A response carrega um `operationId`. O progresso e a conclusão chegam em `/events` como `JobStarted`, `JobProgress`, `JobWarning` e `JobFinished`.
### Operações
`/operations` é o registry unificado para jobs em andamento e recém-concluídos (pipelines + downloads).
| Método | Path | Finalidade |
| -------- | --------------------- | ------------------------------------------------------------------ |
| `GET` | `/operations` | snapshot de toda operação em andamento ou recente |
| `DELETE` | `/operations/{id}` | cancela uma execução de pipeline; remoção best-effort para downloads |
### Downloads
| Método | Path | Finalidade |
| ------ | ------------------- | ------------------------------------------------ |
| `GET` | `/downloads` | snapshot de todo download ativo ou recente |
| `POST` | `/downloads` | inicia o download de um pacote de modelo (`{ modelId }`) |
`modelId` é um id de pacote declarado via `declare_hf_model_package!` (ex.: `"model:comic-text-detector:yolo-v5"`). A response é `{ operationId }`, reutilizando o id do pacote.
### Controle do LLM
O modelo carregado é um recurso singleton em `/llm/current`.
| Método | Path | Finalidade |
| -------- | ---------------- | ------------------------------------------------ |
| `GET` | `/llm/current` | estado atual (status, target, error) |
| `PUT` | `/llm/current` | carrega o target informado (local ou de provedor) |
| `DELETE` | `/llm/current` | descarrega / libera o modelo |
| `GET` | `/llm/catalog` | lista os modelos locais + de provedor disponíveis |
`PUT /llm/current` aceita um `LlmLoadRequest`:
- targets de provedor — `{ kind: "provider", providerId, modelId }`
- targets locais — `{ kind: "local", modelId }`
- `options { temperature, maxTokens, customSystemPrompt }` opcional
`PUT /llm/current` retorna `204` assim que a tarefa de carga é enfileirada. O estado pronto efetivo é publicado como `LlmLoaded` em `/events`.
### Configuração
| Método | Path | Finalidade |
| -------- | --------------------------------------- | --------------------------------------------------- |
| `GET` | `/config` | lê o `AppConfig` atual |
| `PATCH` | `/config` | aplica um `ConfigPatch`; persiste e faz broadcast |
| `PUT` | `/config/providers/{id}/secret` | salva (ou sobrescreve) a chave de API de um provedor |
| `DELETE` | `/config/providers/{id}/secret` | limpa a chave de API armazenada de um provedor |
`AppConfig` expõe os top-level `data`, `http`, `pipeline` e `providers`:
- `data.path` — diretório de dados local usado para runtime, cache de modelos e projetos
- `http { connectTimeout, readTimeout, maxRetries }` — client HTTP compartilhado usado por downloads e requests baseados em provedor
- `pipeline { detector, fontDetector, segmenter, bubbleSegmenter, ocr, translator, inpainter, renderer }` — id da engine selecionada para cada etapa
- `providers[] { id, baseUrl?, apiKey? }` — chaves de API salvas vão e voltam como o placeholder redatado `"[REDACTED]"`; nunca o segredo bruto
Ids de provedores embutidos:
- `openai`
- `gemini`
- `claude`
- `deepseek`
- `deepl`
- `google-translate`
- `caiyun`
- `openai-compatible`
As chaves de API ficam armazenadas no credential store da plataforma, não em `config.toml`. Fazer PATCH de `apiKey: ""` limpa a chave salva; fazer PATCH de `"[REDACTED]"` mantém o valor inalterado. As rotas dedicadas `/config/providers/{id}/secret` são a forma explícita, fora do PATCH, de gerenciar o segredo de um provedor.
## Stream de eventos
O Koharu expõe um stream de Server-Sent Events em:
```text
GET /events
```
Comportamento:
- uma conexão nova (sem header `Last-Event-ID`) começa com um evento `Snapshot` contendo os registries atuais de jobs e downloads
- na reconexão, o servidor reenvia, em ordem, os eventos com `seq > Last-Event-ID` que ainda estão no buffer; se o id solicitado já saiu do ring, o servidor reenvia um `Snapshot`
- cada evento ao vivo é emitido com seu `seq` no campo `id:` do SSE
- um keepalive de 15 segundos é mantido
As variantes de evento atualmente incluem:
- `Snapshot` — estado completo inicial para clientes novos e em recuperação de atraso
- `JobStarted`, `JobProgress`, `JobWarning`, `JobFinished` — ciclo de vida do job de pipeline
- `DownloadProgress` — ticks de progresso de download de pacote
- `ConfigChanged` — config foi aplicada via `PATCH /config` ou via uma rota de segredo
- `LlmLoaded`, `LlmUnloaded` — transições do ciclo de vida do LLM
- `SceneAdvanced` — emitido quando uma mutação de cena avança o epoch
## Workflow típico
A ordem normal da API para um projeto novo é:
1. `POST /projects` — cria o projeto
2. `POST /pages` (ou `/pages/from-paths` no Tauri) — importa as imagens
3. `PUT /llm/current` — carrega um modelo de tradução (local ou de provedor)
4. `POST /pipelines` — dispara `detect → ocr → translate → inpaint → render`
5. acompanha `GET /events` até `JobFinished`
6. `POST /projects/current/export` com `format = "rendered"` ou `"psd"`
Para controle mais fino, faça `POST /history/apply` com payloads `Op` explícitos em vez de rodar um pipeline completo.
Se você prefere acesso orientado a agentes em vez de orquestrar endpoints HTTP, veja a [Referência das ferramentas MCP](mcp-tools.md).
|