trans2 / ui /openapi.json
Mayo
fix: per-block translate
01d8941 unverified
{
"openapi": "3.1.0",
"info": {
"title": "",
"version": ""
},
"paths": {
"/ai/codex/auth/device-code": {
"post": {
"operationId": "start_codex_device_login",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CodexDeviceLogin"
}
}
}
}
}
}
},
"/ai/codex/auth/session": {
"delete": {
"operationId": "delete_codex_session",
"responses": {
"204": {
"description": ""
}
}
}
},
"/ai/codex/auth/status": {
"get": {
"operationId": "get_codex_auth_status",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CodexAuthStatus"
}
}
}
}
}
}
},
"/ai/codex/images": {
"post": {
"operationId": "start_codex_image_generation",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CodexImageGenerationOptions"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CodexImageGenerationResponse"
}
}
}
}
}
}
},
"/blobs/{hash}": {
"get": {
"operationId": "get_blob",
"parameters": [
{
"name": "hash",
"in": "path",
"description": "Blake3 hash of the blob",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/octet-stream": {}
}
}
}
}
},
"/config": {
"get": {
"operationId": "get_config",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AppConfig"
}
}
}
}
}
},
"patch": {
"operationId": "patch_config",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ConfigPatch"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AppConfig"
}
}
}
}
}
}
},
"/config/providers/{id}/secret": {
"put": {
"summary": "Save (or overwrite) the keyring secret for a provider. Creates the\nprovider entry in `config.providers` if it didn't exist. `PUT` because\nsetting the secret is idempotent for the same body.",
"operationId": "set_provider_secret",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Provider id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProviderSecretRequest"
}
}
},
"required": true
},
"responses": {
"204": {
"description": ""
}
}
},
"delete": {
"summary": "Clear a provider's keyring secret. The provider entry itself is kept.",
"operationId": "clear_provider_secret",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Provider id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": ""
}
}
}
},
"/downloads": {
"get": {
"operationId": "list_downloads",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ListDownloadsResponse"
}
}
}
}
}
},
"post": {
"operationId": "start_download",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StartDownloadRequest"
}
}
},
"required": true
},
"responses": {
"202": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StartDownloadResponse"
}
}
}
}
}
}
},
"/engines": {
"get": {
"operationId": "get_engine_catalog",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EngineCatalog"
}
}
}
}
}
}
},
"/events": {
"get": {
"operationId": "events",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AppEvent"
}
}
}
}
}
}
},
"/fonts": {
"get": {
"operationId": "list_fonts",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/FontFaceInfo"
}
}
}
}
}
}
}
},
"/google-fonts": {
"get": {
"operationId": "get_google_fonts_catalog",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GoogleFontCatalog"
}
}
}
}
}
}
},
"/google-fonts/{family}/fetch": {
"post": {
"operationId": "fetch_google_font",
"parameters": [
{
"name": "family",
"in": "path",
"description": "Google Fonts family name",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": ""
}
}
}
},
"/google-fonts/{family}/{file}": {
"get": {
"operationId": "get_google_font_file",
"parameters": [
{
"name": "family",
"in": "path",
"description": "Google Fonts family name",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "file",
"in": "path",
"description": "Font filename",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"font/ttf": {}
}
}
}
}
},
"/history/apply": {
"post": {
"operationId": "apply_command",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Op"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HistoryResult"
}
}
}
}
}
}
},
"/history/redo": {
"post": {
"operationId": "redo",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HistoryResult"
}
}
}
}
}
}
},
"/history/undo": {
"post": {
"operationId": "undo",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HistoryResult"
}
}
}
}
}
}
},
"/llm/catalog": {
"get": {
"operationId": "get_catalog",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LlmCatalog"
}
}
}
}
}
}
},
"/llm/current": {
"get": {
"operationId": "get_current_llm",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LlmState"
}
}
}
}
}
},
"put": {
"operationId": "put_current_llm",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LlmLoadRequest"
}
}
},
"required": true
},
"responses": {
"204": {
"description": ""
}
}
},
"delete": {
"operationId": "delete_current_llm",
"responses": {
"204": {
"description": ""
}
}
}
},
"/meta": {
"get": {
"operationId": "get_meta",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MetaInfo"
}
}
}
}
}
}
},
"/operations": {
"get": {
"operationId": "list_operations",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ListOperationsResponse"
}
}
}
}
}
}
},
"/operations/{id}": {
"delete": {
"operationId": "cancel_operation",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Operation id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": ""
}
}
}
},
"/pages": {
"post": {
"operationId": "create_pages",
"requestBody": {
"content": {
"multipart/form-data": {}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreatePagesResponse"
}
}
}
}
}
}
},
"/pages/from-paths": {
"post": {
"summary": "Create pages by reading image files from absolute paths on the server's\nfilesystem. This is the Tauri desktop import path — the webview picker\nreturns paths, and the backend reads + decodes + hashes them in parallel\nwithout a round-trip through JS memory or a multipart upload body.",
"description": "Web clients should keep using `POST /pages` with multipart.",
"operationId": "create_pages_from_paths",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreatePagesFromPathsRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreatePagesResponse"
}
}
}
}
}
}
},
"/pages/{id}/image-layers": {
"post": {
"operationId": "add_image_layer",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Page id",
"required": true,
"schema": {
"$ref": "#/components/schemas/PageId"
}
}
],
"requestBody": {
"content": {
"multipart/form-data": {}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AddImageLayerResponse"
}
}
}
}
}
}
},
"/pages/{id}/masks/{role}": {
"put": {
"summary": "Upsert the `Mask { role }` node on a page with the raw image bytes in\nthe body. Emits `Op::UpdateNode` if a mask of that role exists, else\n`Op::AddNode`. Used by the repair-brush / segment-edit flow; the\nfollow-up localized inpaint is a separate `POST /pipelines` call.",
"operationId": "put_mask",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Page id",
"required": true,
"schema": {
"$ref": "#/components/schemas/PageId"
}
},
{
"name": "role",
"in": "path",
"description": "Mask role (segment|brushInpaint)",
"required": true,
"schema": {
"$ref": "#/components/schemas/MaskRole"
}
}
],
"requestBody": {
"content": {
"image/png": {}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PutMaskResponse"
}
}
}
}
}
}
},
"/pages/{id}/thumbnail": {
"get": {
"operationId": "get_page_thumbnail",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Page id",
"required": true,
"schema": {
"$ref": "#/components/schemas/PageId"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"image/webp": {}
}
}
}
}
},
"/pipelines": {
"post": {
"operationId": "start_pipeline",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StartPipelineRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StartPipelineResponse"
}
}
}
}
}
}
},
"/projects": {
"get": {
"operationId": "list_projects",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ListProjectsResponse"
}
}
}
}
}
},
"post": {
"operationId": "create_project",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateProjectRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProjectSummary"
}
}
}
}
}
}
},
"/projects/current": {
"put": {
"operationId": "put_current_project",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OpenProjectRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProjectSummary"
}
}
}
}
}
},
"delete": {
"operationId": "delete_current_project",
"responses": {
"204": {
"description": ""
}
}
}
},
"/projects/current/export": {
"post": {
"operationId": "export_current_project",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExportProjectRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Export bytes. Content-Type is `application/zip` when the format produces multiple files.",
"content": {
"application/octet-stream": {}
}
}
}
}
},
"/projects/import": {
"post": {
"operationId": "import_project",
"requestBody": {
"content": {
"application/zip": {}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProjectSummary"
}
}
}
}
}
}
},
"/scene.bin": {
"get": {
"operationId": "get_scene_bin",
"responses": {
"200": {
"description": "",
"content": {
"application/octet-stream": {}
}
}
}
}
},
"/scene.json": {
"get": {
"operationId": "get_scene_json",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SceneSnapshot"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"AddImageLayerResponse": {
"type": "object",
"required": ["node"],
"properties": {
"node": {
"$ref": "#/components/schemas/NodeId"
}
}
},
"AppConfig": {
"type": "object",
"properties": {
"data": {
"oneOf": [
{
"$ref": "#/components/schemas/DataConfig"
}
],
"default": {
"path": "C:\\Users\\Mayo\\AppData\\Local\\Koharu"
}
},
"http": {
"oneOf": [
{
"$ref": "#/components/schemas/HttpConfig"
}
],
"default": {
"connect_timeout": 20,
"max_retries": 3,
"read_timeout": 300
}
},
"pipeline": {
"oneOf": [
{
"$ref": "#/components/schemas/PipelineConfig"
}
],
"default": {
"bubble_segmenter": "speech-bubble-segmentation",
"detector": "pp-doclayout-v3",
"font_detector": "yuzumarker-font-detection",
"inpainter": "lama-manga",
"ocr": "paddle-ocr-vl-1.5",
"renderer": "koharu-renderer",
"segmenter": "comic-text-detector-seg",
"translator": "llm"
}
},
"providers": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ProviderConfig"
},
"default": []
}
}
},
"AppEvent": {
"oneOf": [
{
"type": "object",
"required": ["id", "kind", "event"],
"properties": {
"event": {
"type": "string",
"enum": ["jobStarted"]
},
"id": {
"type": "string"
},
"kind": {
"type": "string"
}
}
},
{
"allOf": [
{
"$ref": "#/components/schemas/PipelineProgress"
},
{
"type": "object",
"required": ["event"],
"properties": {
"event": {
"type": "string",
"enum": ["jobProgress"]
}
}
}
]
},
{
"allOf": [
{
"$ref": "#/components/schemas/JobWarningEvent",
"description": "A single step on one page failed but the pipeline kept running.\nEmitted per failed step so clients can show a non-fatal warning while\nthe job continues with the next page."
},
{
"type": "object",
"required": ["event"],
"properties": {
"event": {
"type": "string",
"enum": ["jobWarning"]
}
}
}
],
"description": "A single step on one page failed but the pipeline kept running.\nEmitted per failed step so clients can show a non-fatal warning while\nthe job continues with the next page."
},
{
"allOf": [
{
"$ref": "#/components/schemas/JobFinishedEvent"
},
{
"type": "object",
"required": ["event"],
"properties": {
"event": {
"type": "string",
"enum": ["jobFinished"]
}
}
}
]
},
{
"allOf": [
{
"$ref": "#/components/schemas/DownloadProgress"
},
{
"type": "object",
"required": ["event"],
"properties": {
"event": {
"type": "string",
"enum": ["downloadProgress"]
}
}
}
]
},
{
"type": "object",
"required": ["target", "event"],
"properties": {
"event": {
"type": "string",
"enum": ["llmLoading"]
},
"target": {
"$ref": "#/components/schemas/LlmTarget"
}
}
},
{
"type": "object",
"required": ["target", "event"],
"properties": {
"event": {
"type": "string",
"enum": ["llmLoaded"]
},
"target": {
"$ref": "#/components/schemas/LlmTarget"
}
}
},
{
"type": "object",
"required": ["event"],
"properties": {
"event": {
"type": "string",
"enum": ["llmFailed"]
},
"target": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/LlmTarget"
}
]
}
}
},
{
"type": "object",
"required": ["event"],
"properties": {
"event": {
"type": "string",
"enum": ["llmUnloaded"]
}
}
},
{
"allOf": [
{
"$ref": "#/components/schemas/SnapshotEvent"
},
{
"type": "object",
"required": ["event"],
"properties": {
"event": {
"type": "string",
"enum": ["snapshot"]
}
}
}
]
}
]
},
"BlobRef": {
"type": "string",
"description": "Hex-encoded blake3 hash of an immutable blob."
},
"CodexAuthAttemptStatus": {
"type": "string",
"enum": ["pending", "succeeded", "failed"]
},
"CodexAuthStatus": {
"type": "object",
"required": ["signedIn"],
"properties": {
"accountId": {
"type": ["string", "null"]
},
"login": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/CodexDeviceLoginStatus"
}
]
},
"signedIn": {
"type": "boolean"
}
}
},
"CodexDeviceLogin": {
"type": "object",
"required": ["loginId", "verificationUrl", "userCode", "intervalSeconds", "timeoutSeconds"],
"properties": {
"intervalSeconds": {
"type": "integer",
"format": "int64",
"minimum": 0
},
"loginId": {
"type": "string"
},
"timeoutSeconds": {
"type": "integer",
"format": "int64",
"minimum": 0
},
"userCode": {
"type": "string"
},
"verificationUrl": {
"type": "string"
}
}
},
"CodexDeviceLoginStatus": {
"type": "object",
"required": ["loginId", "status"],
"properties": {
"accountId": {
"type": ["string", "null"]
},
"error": {
"type": ["string", "null"]
},
"loginId": {
"type": "string"
},
"status": {
"$ref": "#/components/schemas/CodexAuthAttemptStatus"
}
}
},
"CodexImageGenerationOptions": {
"type": "object",
"required": ["pageId", "prompt"],
"properties": {
"instructions": {
"type": ["string", "null"]
},
"model": {
"type": ["string", "null"]
},
"pageId": {
"$ref": "#/components/schemas/PageId"
},
"prompt": {
"type": "string"
},
"quality": {
"type": ["string", "null"]
},
"size": {
"type": ["string", "null"]
}
}
},
"CodexImageGenerationResponse": {
"type": "object",
"required": ["operationId"],
"properties": {
"operationId": {
"type": "string"
}
}
},
"ConfigPatch": {
"type": "object",
"description": "Sparse patch for `koharu_app::AppConfig`. Missing fields mean \"leave\nas-is\". The `providers` field, if present, replaces the whole provider\nlist — we do not merge by id because ordering is meaningful.",
"properties": {
"data": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/DataConfigPatch"
}
]
},
"http": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/HttpConfigPatch"
}
]
},
"pipeline": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/PipelineConfigPatch"
}
]
},
"providers": {
"type": ["array", "null"],
"items": {
"$ref": "#/components/schemas/ProviderPatch"
},
"description": "If present, replaces the entire list. Api_key values of `\"[REDACTED]\"`\nare interpreted as \"leave the existing secret alone\"."
}
}
},
"CreatePagesFromPathsRequest": {
"type": "object",
"required": ["paths"],
"properties": {
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"replace": {
"type": "boolean"
}
}
},
"CreatePagesResponse": {
"type": "object",
"required": ["pages"],
"properties": {
"pages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PageId"
}
}
}
},
"CreateProjectRequest": {
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string"
}
}
},
"DataConfig": {
"type": "object",
"required": ["path"],
"properties": {
"path": {
"type": "string"
}
}
},
"DataConfigPatch": {
"type": "object",
"properties": {
"path": {
"type": ["string", "null"]
}
}
},
"DownloadProgress": {
"type": "object",
"required": ["id", "filename", "downloaded", "status"],
"properties": {
"downloaded": {
"type": "integer",
"format": "int64",
"minimum": 0
},
"filename": {
"type": "string"
},
"id": {
"type": "string"
},
"status": {
"$ref": "#/components/schemas/DownloadStatus"
},
"total": {
"type": ["integer", "null"],
"format": "int64",
"minimum": 0
}
}
},
"DownloadStatus": {
"oneOf": [
{
"type": "object",
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["started"]
}
}
},
{
"type": "object",
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["downloading"]
}
}
},
{
"type": "object",
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["completed"]
}
}
},
{
"type": "object",
"required": ["reason", "status"],
"properties": {
"reason": {
"type": "string"
},
"status": {
"type": "string",
"enum": ["failed"]
}
}
}
]
},
"EngineCatalog": {
"type": "object",
"required": [
"detectors",
"fontDetectors",
"segmenters",
"bubbleSegmenters",
"ocr",
"translators",
"inpainters",
"renderers"
],
"properties": {
"bubbleSegmenters": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EngineCatalogEntry"
}
},
"detectors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EngineCatalogEntry"
}
},
"fontDetectors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EngineCatalogEntry"
}
},
"inpainters": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EngineCatalogEntry"
}
},
"ocr": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EngineCatalogEntry"
}
},
"renderers": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EngineCatalogEntry"
}
},
"segmenters": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EngineCatalogEntry"
}
},
"translators": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EngineCatalogEntry"
}
}
}
},
"EngineCatalogEntry": {
"type": "object",
"required": ["id", "name", "produces"],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"produces": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"ExportFormat": {
"type": "string",
"enum": ["khr", "psd", "rendered", "inpainted"]
},
"ExportProjectRequest": {
"type": "object",
"required": ["format"],
"properties": {
"format": {
"$ref": "#/components/schemas/ExportFormat"
},
"pages": {
"type": ["array", "null"],
"items": {
"$ref": "#/components/schemas/PageId"
},
"description": "Optional subset of pages; defaults to every page."
}
}
},
"FontFaceInfo": {
"type": "object",
"required": ["familyName", "postScriptName", "source", "cached"],
"properties": {
"cached": {
"type": "boolean"
},
"category": {
"type": ["string", "null"]
},
"familyName": {
"type": "string"
},
"postScriptName": {
"type": "string"
},
"source": {
"$ref": "#/components/schemas/FontSource"
}
}
},
"FontPrediction": {
"type": "object",
"required": [
"topFonts",
"namedFonts",
"direction",
"textColor",
"strokeColor",
"fontSizePx",
"strokeWidthPx",
"lineHeight",
"angleDeg"
],
"properties": {
"angleDeg": {
"type": "number",
"format": "float"
},
"direction": {
"$ref": "#/components/schemas/TextDirection"
},
"fontSizePx": {
"type": "number",
"format": "float"
},
"lineHeight": {
"type": "number",
"format": "float"
},
"namedFonts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NamedFontPrediction"
}
},
"strokeColor": {
"type": "array",
"items": {
"type": "integer",
"format": "int32",
"minimum": 0
}
},
"strokeWidthPx": {
"type": "number",
"format": "float"
},
"textColor": {
"type": "array",
"items": {
"type": "integer",
"format": "int32",
"minimum": 0
}
},
"topFonts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TopFont"
}
}
}
},
"FontSource": {
"type": "string",
"enum": ["system", "google"]
},
"GoogleFontCatalog": {
"type": "object",
"required": ["fonts"],
"properties": {
"fonts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GoogleFontEntry"
}
}
}
},
"GoogleFontEntry": {
"type": "object",
"required": ["family", "category", "subsets", "variants"],
"properties": {
"category": {
"type": "string"
},
"family": {
"type": "string"
},
"subsets": {
"type": "array",
"items": {
"type": "string"
}
},
"variants": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GoogleFontVariant"
}
}
}
},
"GoogleFontVariant": {
"type": "object",
"required": ["style", "weight", "filename"],
"properties": {
"filename": {
"type": "string"
},
"style": {
"type": "string"
},
"weight": {
"type": "integer",
"format": "int32",
"minimum": 0
}
}
},
"HistoryResult": {
"type": "object",
"properties": {
"epoch": {
"type": ["integer", "null"],
"format": "int64",
"description": "New epoch. `None` only for a no-op undo/redo at the stack boundary.",
"minimum": 0
}
}
},
"HttpConfig": {
"type": "object",
"properties": {
"connect_timeout": {
"type": "integer",
"format": "int64",
"default": 20,
"minimum": 0
},
"max_retries": {
"type": "integer",
"format": "int32",
"default": 3,
"minimum": 0
},
"read_timeout": {
"type": "integer",
"format": "int64",
"default": 300,
"minimum": 0
}
}
},
"HttpConfigPatch": {
"type": "object",
"properties": {
"connectTimeout": {
"type": ["integer", "null"],
"format": "int64",
"minimum": 0
},
"maxRetries": {
"type": ["integer", "null"],
"format": "int32",
"minimum": 0
},
"readTimeout": {
"type": ["integer", "null"],
"format": "int64",
"minimum": 0
}
}
},
"ImageData": {
"type": "object",
"required": ["role", "blob", "naturalWidth", "naturalHeight"],
"properties": {
"blob": {
"$ref": "#/components/schemas/BlobRef"
},
"name": {
"type": ["string", "null"]
},
"naturalHeight": {
"type": "integer",
"format": "int32",
"minimum": 0
},
"naturalWidth": {
"type": "integer",
"format": "int32",
"minimum": 0
},
"opacity": {
"type": "number",
"format": "float"
},
"role": {
"$ref": "#/components/schemas/ImageRole",
"description": "Role tags differentiate source / inpainted / rendered / user-imported images.\nRole is immutable on an existing node — switching roles = delete + add."
}
}
},
"ImageDataPatch": {
"type": "object",
"properties": {
"blob": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/BlobRef"
}
]
},
"name": {
"type": ["string", "null"]
},
"naturalHeight": {
"type": ["integer", "null"],
"format": "int32",
"minimum": 0
},
"naturalWidth": {
"type": ["integer", "null"],
"format": "int32",
"minimum": 0
},
"opacity": {
"type": ["number", "null"],
"format": "float"
}
}
},
"ImageRole": {
"type": "string",
"enum": ["source", "inpainted", "rendered", "custom"]
},
"JobFinishedEvent": {
"type": "object",
"required": ["id", "status"],
"properties": {
"error": {
"type": ["string", "null"]
},
"id": {
"type": "string"
},
"status": {
"$ref": "#/components/schemas/JobStatus"
}
}
},
"JobStatus": {
"type": "string",
"enum": ["running", "completed", "completed_with_errors", "cancelled", "failed"]
},
"JobSummary": {
"type": "object",
"required": ["id", "kind", "status"],
"properties": {
"error": {
"type": ["string", "null"]
},
"id": {
"type": "string"
},
"kind": {
"type": "string"
},
"status": {
"$ref": "#/components/schemas/JobStatus"
}
}
},
"JobWarningEvent": {
"type": "object",
"description": "A non-fatal step failure during a pipeline run. The pipeline recovers by\nskipping the rest of the current page's steps and moving on to the next\npage; the UI accumulates these into a list during the job.",
"required": ["jobId", "pageIndex", "totalPages", "stepId", "message"],
"properties": {
"jobId": {
"type": "string"
},
"message": {
"type": "string"
},
"pageIndex": {
"type": "integer",
"description": "0-based page index where the failure happened.",
"minimum": 0
},
"stepId": {
"type": "string",
"description": "Engine id (e.g. `\"lama-manga\"`) of the step that failed."
},
"totalPages": {
"type": "integer",
"minimum": 0
}
}
},
"ListDownloadsResponse": {
"type": "object",
"required": ["downloads"],
"properties": {
"downloads": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DownloadProgress"
}
}
}
},
"ListOperationsResponse": {
"type": "object",
"required": ["operations"],
"properties": {
"operations": {
"type": "array",
"items": {
"$ref": "#/components/schemas/JobSummary"
}
}
}
},
"ListProjectsResponse": {
"type": "object",
"required": ["projects"],
"properties": {
"projects": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ProjectSummary"
}
}
}
},
"LlmCatalog": {
"type": "object",
"required": ["localModels", "providers"],
"properties": {
"localModels": {
"type": "array",
"items": {
"$ref": "#/components/schemas/LlmCatalogModel"
}
},
"providers": {
"type": "array",
"items": {
"$ref": "#/components/schemas/LlmProviderCatalog"
}
}
}
},
"LlmCatalogModel": {
"type": "object",
"required": ["target", "name", "languages"],
"properties": {
"languages": {
"type": "array",
"items": {
"type": "string"
}
},
"name": {
"type": "string"
},
"target": {
"$ref": "#/components/schemas/LlmTarget"
}
}
},
"LlmGenerationOptions": {
"type": "object",
"properties": {
"customSystemPrompt": {
"type": ["string", "null"]
},
"maxTokens": {
"type": ["integer", "null"],
"format": "int32",
"minimum": 0
},
"temperature": {
"type": ["number", "null"],
"format": "double"
}
}
},
"LlmLoadRequest": {
"type": "object",
"required": ["target"],
"properties": {
"options": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/LlmGenerationOptions"
}
]
},
"target": {
"$ref": "#/components/schemas/LlmTarget"
}
}
},
"LlmProviderCatalog": {
"type": "object",
"required": [
"id",
"name",
"requiresApiKey",
"requiresBaseUrl",
"hasApiKey",
"status",
"models"
],
"properties": {
"baseUrl": {
"type": ["string", "null"]
},
"error": {
"type": ["string", "null"]
},
"hasApiKey": {
"type": "boolean"
},
"id": {
"type": "string"
},
"models": {
"type": "array",
"items": {
"$ref": "#/components/schemas/LlmCatalogModel"
}
},
"name": {
"type": "string"
},
"requiresApiKey": {
"type": "boolean"
},
"requiresBaseUrl": {
"type": "boolean"
},
"status": {
"$ref": "#/components/schemas/LlmProviderCatalogStatus"
}
}
},
"LlmProviderCatalogStatus": {
"type": "string",
"enum": ["ready", "missing_configuration", "discovery_failed"]
},
"LlmState": {
"type": "object",
"required": ["status"],
"properties": {
"error": {
"type": ["string", "null"]
},
"status": {
"$ref": "#/components/schemas/LlmStateStatus"
},
"target": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/LlmTarget"
}
]
}
}
},
"LlmStateStatus": {
"type": "string",
"enum": ["empty", "loading", "ready", "failed"]
},
"LlmTarget": {
"type": "object",
"required": ["kind", "modelId"],
"properties": {
"kind": {
"$ref": "#/components/schemas/LlmTargetKind"
},
"modelId": {
"type": "string"
},
"providerId": {
"type": ["string", "null"]
}
}
},
"LlmTargetKind": {
"type": "string",
"enum": ["local", "provider"]
},
"MaskData": {
"type": "object",
"required": ["role", "blob"],
"properties": {
"blob": {
"$ref": "#/components/schemas/BlobRef"
},
"role": {
"$ref": "#/components/schemas/MaskRole"
}
}
},
"MaskDataPatch": {
"type": "object",
"properties": {
"blob": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/BlobRef"
}
]
}
}
},
"MaskRole": {
"type": "string",
"enum": ["brushInpaint", "segment", "bubble"]
},
"MetaInfo": {
"type": "object",
"required": ["version", "mlDevice"],
"properties": {
"mlDevice": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"NamedFontPrediction": {
"type": "object",
"required": ["index", "name", "probability", "serif"],
"properties": {
"index": {
"type": "integer",
"minimum": 0
},
"language": {
"type": ["string", "null"]
},
"name": {
"type": "string"
},
"probability": {
"type": "number",
"format": "float"
},
"serif": {
"type": "boolean"
}
}
},
"Node": {
"type": "object",
"required": ["id", "visible", "kind"],
"properties": {
"id": {
"$ref": "#/components/schemas/NodeId"
},
"kind": {
"$ref": "#/components/schemas/NodeKind"
},
"transform": {
"$ref": "#/components/schemas/Transform"
},
"visible": {
"type": "boolean"
}
}
},
"NodeDataPatch": {
"oneOf": [
{
"type": "object",
"required": ["text"],
"properties": {
"text": {
"$ref": "#/components/schemas/TextDataPatch"
}
}
},
{
"type": "object",
"required": ["image"],
"properties": {
"image": {
"$ref": "#/components/schemas/ImageDataPatch"
}
}
},
{
"type": "object",
"required": ["mask"],
"properties": {
"mask": {
"$ref": "#/components/schemas/MaskDataPatch"
}
}
}
]
},
"NodeId": {
"type": "string",
"format": "uuid"
},
"NodeKind": {
"oneOf": [
{
"type": "object",
"required": ["image"],
"properties": {
"image": {
"$ref": "#/components/schemas/ImageData"
}
}
},
{
"type": "object",
"required": ["text"],
"properties": {
"text": {
"$ref": "#/components/schemas/TextData"
}
}
},
{
"type": "object",
"required": ["mask"],
"properties": {
"mask": {
"$ref": "#/components/schemas/MaskData"
}
}
}
]
},
"NodePatch": {
"type": "object",
"properties": {
"data": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/NodeDataPatch"
}
]
},
"transform": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/Transform"
}
]
},
"visible": {
"type": ["boolean", "null"]
}
}
},
"Op": {
"oneOf": [
{
"type": "object",
"required": ["updateProjectMeta"],
"properties": {
"updateProjectMeta": {
"type": "object",
"required": ["patch"],
"properties": {
"patch": {
"$ref": "#/components/schemas/ProjectMetaPatch"
},
"prev": {
"$ref": "#/components/schemas/ProjectMetaPatch"
}
}
}
}
},
{
"type": "object",
"required": ["addPage"],
"properties": {
"addPage": {
"type": "object",
"required": ["page", "at"],
"properties": {
"at": {
"type": "integer",
"minimum": 0
},
"page": {
"$ref": "#/components/schemas/Page"
}
}
}
}
},
{
"type": "object",
"required": ["removePage"],
"properties": {
"removePage": {
"type": "object",
"required": ["id", "prev_page", "prev_index"],
"properties": {
"id": {
"$ref": "#/components/schemas/PageId"
},
"prev_index": {
"type": "integer",
"minimum": 0
},
"prev_page": {
"$ref": "#/components/schemas/Page"
}
}
}
}
},
{
"type": "object",
"required": ["updatePage"],
"properties": {
"updatePage": {
"type": "object",
"required": ["id", "patch"],
"properties": {
"id": {
"$ref": "#/components/schemas/PageId"
},
"patch": {
"$ref": "#/components/schemas/PagePatch"
},
"prev": {
"$ref": "#/components/schemas/PagePatch"
}
}
}
}
},
{
"type": "object",
"required": ["reorderPages"],
"properties": {
"reorderPages": {
"type": "object",
"required": ["order", "prev_order"],
"properties": {
"order": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PageId"
}
},
"prev_order": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PageId"
}
}
}
}
}
},
{
"type": "object",
"required": ["addNode"],
"properties": {
"addNode": {
"type": "object",
"required": ["page", "node", "at"],
"properties": {
"at": {
"type": "integer",
"minimum": 0
},
"node": {
"$ref": "#/components/schemas/Node"
},
"page": {
"$ref": "#/components/schemas/PageId"
}
}
}
}
},
{
"type": "object",
"required": ["removeNode"],
"properties": {
"removeNode": {
"type": "object",
"required": ["page", "id", "prev_node", "prev_index"],
"properties": {
"id": {
"$ref": "#/components/schemas/NodeId"
},
"page": {
"$ref": "#/components/schemas/PageId"
},
"prev_index": {
"type": "integer",
"minimum": 0
},
"prev_node": {
"$ref": "#/components/schemas/Node"
}
}
}
}
},
{
"type": "object",
"required": ["updateNode"],
"properties": {
"updateNode": {
"type": "object",
"required": ["page", "id", "patch"],
"properties": {
"id": {
"$ref": "#/components/schemas/NodeId"
},
"page": {
"$ref": "#/components/schemas/PageId"
},
"patch": {
"$ref": "#/components/schemas/NodePatch"
},
"prev": {
"$ref": "#/components/schemas/NodePatch"
}
}
}
}
},
{
"type": "object",
"required": ["reorderNodes"],
"properties": {
"reorderNodes": {
"type": "object",
"required": ["page", "order", "prev_order"],
"properties": {
"order": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NodeId"
}
},
"page": {
"$ref": "#/components/schemas/PageId"
},
"prev_order": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NodeId"
}
}
}
}
}
},
{
"type": "object",
"required": ["batch"],
"properties": {
"batch": {
"type": "object",
"required": ["ops", "label"],
"properties": {
"label": {
"type": "string"
},
"ops": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Op"
}
}
}
}
}
}
]
},
"OpenProjectRequest": {
"type": "object",
"required": ["id"],
"properties": {
"id": {
"type": "string",
"description": "`.khrproj/` directory basename (no extension). Must exist under the\nmanaged projects directory."
}
}
},
"Page": {
"type": "object",
"required": ["id", "name", "width", "height", "nodes"],
"properties": {
"height": {
"type": "integer",
"format": "int32",
"minimum": 0
},
"id": {
"$ref": "#/components/schemas/PageId"
},
"name": {
"type": "string"
},
"nodes": {
"type": "object",
"description": "Stacking = insertion order. Bottom-first: `source` is typically first,\n`rendered` typically last.",
"additionalProperties": {
"$ref": "#/components/schemas/Node"
},
"propertyNames": {
"type": "string",
"format": "uuid"
}
},
"width": {
"type": "integer",
"format": "int32",
"minimum": 0
}
}
},
"PageId": {
"type": "string",
"format": "uuid"
},
"PagePatch": {
"type": "object",
"properties": {
"height": {
"type": ["integer", "null"],
"format": "int32",
"minimum": 0
},
"name": {
"type": ["string", "null"]
},
"width": {
"type": ["integer", "null"],
"format": "int32",
"minimum": 0
}
}
},
"PipelineConfig": {
"type": "object",
"description": "Engine selection for each pipeline stage.\nValues are engine IDs (e.g. \"pp-doclayout-v3\", \"comic-text-detector\").\nEmpty string means use default.",
"properties": {
"bubble_segmenter": {
"type": "string",
"default": "speech-bubble-segmentation"
},
"detector": {
"type": "string",
"default": "pp-doclayout-v3"
},
"font_detector": {
"type": "string",
"default": "yuzumarker-font-detection"
},
"inpainter": {
"type": "string",
"default": "lama-manga"
},
"ocr": {
"type": "string",
"default": "paddle-ocr-vl-1.5"
},
"renderer": {
"type": "string",
"default": "koharu-renderer"
},
"segmenter": {
"type": "string",
"default": "comic-text-detector-seg"
},
"translator": {
"type": "string",
"default": "llm"
}
}
},
"PipelineConfigPatch": {
"type": "object",
"properties": {
"bubbleSegmenter": {
"type": ["string", "null"]
},
"detector": {
"type": ["string", "null"]
},
"fontDetector": {
"type": ["string", "null"]
},
"inpainter": {
"type": ["string", "null"]
},
"ocr": {
"type": ["string", "null"]
},
"renderer": {
"type": ["string", "null"]
},
"segmenter": {
"type": ["string", "null"]
},
"translator": {
"type": ["string", "null"]
}
}
},
"PipelineProgress": {
"type": "object",
"required": [
"jobId",
"status",
"currentPage",
"totalPages",
"currentStepIndex",
"totalSteps",
"overallPercent"
],
"properties": {
"currentPage": {
"type": "integer",
"minimum": 0
},
"currentStepIndex": {
"type": "integer",
"minimum": 0
},
"jobId": {
"type": "string"
},
"overallPercent": {
"type": "integer",
"format": "int32",
"minimum": 0
},
"status": {
"$ref": "#/components/schemas/PipelineStatus"
},
"step": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/PipelineStep"
}
]
},
"totalPages": {
"type": "integer",
"minimum": 0
},
"totalSteps": {
"type": "integer",
"minimum": 0
}
}
},
"PipelineStatus": {
"oneOf": [
{
"type": "object",
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["running"]
}
}
},
{
"type": "object",
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["completed"]
}
}
},
{
"type": "object",
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["cancelled"]
}
}
},
{
"type": "object",
"required": ["reason", "status"],
"properties": {
"reason": {
"type": "string"
},
"status": {
"type": "string",
"enum": ["failed"]
}
}
}
]
},
"PipelineStep": {
"type": "string",
"enum": ["detect", "ocr", "inpaint", "llmGenerate", "render"]
},
"ProjectMeta": {
"type": "object",
"required": ["name", "createdAt", "updatedAt"],
"properties": {
"createdAt": {
"type": "string",
"format": "date-time"
},
"name": {
"type": "string"
},
"style": {
"$ref": "#/components/schemas/ProjectStyle"
},
"updatedAt": {
"type": "string",
"format": "date-time"
}
}
},
"ProjectMetaPatch": {
"type": "object",
"properties": {
"name": {
"type": ["string", "null"]
},
"style": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/ProjectStyle"
}
]
},
"updatedAt": {
"type": ["string", "null"],
"format": "date-time"
}
}
},
"ProjectStyle": {
"type": "object",
"properties": {
"defaultFont": {
"type": ["string", "null"]
}
}
},
"ProjectSummary": {
"type": "object",
"required": ["id", "name", "path"],
"properties": {
"id": {
"type": "string",
"description": "Stable identifier — the `.khrproj` directory basename (without the\nextension). Clients address projects by this."
},
"name": {
"type": "string"
},
"path": {
"type": "string",
"description": "Absolute filesystem path. Informational; clients never need to pass\nit back in — they use `id`."
},
"updatedAtMs": {
"type": "integer",
"format": "int64",
"description": "Last modification time of the project directory on disk (ms since\nUNIX epoch). Used for \"recent projects\" ordering.",
"minimum": 0
}
}
},
"ProviderConfig": {
"type": "object",
"required": ["id"],
"properties": {
"api_key": {
"type": ["string", "null"],
"description": "Populated from credential storage on `load()`, never written to config.toml.\nSerializes as `\"[REDACTED]\"` in API responses."
},
"base_url": {
"type": ["string", "null"]
},
"id": {
"type": "string"
}
}
},
"ProviderPatch": {
"type": "object",
"required": ["id"],
"properties": {
"apiKey": {
"type": ["string", "null"],
"description": "`\"[REDACTED]\"` → keep existing keyring secret; empty → clear; otherwise save."
},
"baseUrl": {
"type": ["string", "null"]
},
"id": {
"type": "string"
}
}
},
"ProviderSecretRequest": {
"type": "object",
"required": ["secret"],
"properties": {
"secret": {
"type": "string"
}
}
},
"PutMaskResponse": {
"type": "object",
"required": ["node", "blob"],
"properties": {
"blob": {
"$ref": "#/components/schemas/BlobRef"
},
"node": {
"$ref": "#/components/schemas/NodeId"
}
}
},
"Region": {
"type": "object",
"required": ["x", "y", "width", "height"],
"properties": {
"height": {
"type": "integer",
"format": "int32",
"minimum": 0
},
"width": {
"type": "integer",
"format": "int32",
"minimum": 0
},
"x": {
"type": "integer",
"format": "int32",
"minimum": 0
},
"y": {
"type": "integer",
"format": "int32",
"minimum": 0
}
}
},
"Scene": {
"type": "object",
"required": ["project", "pages"],
"properties": {
"pages": {
"type": "object",
"description": "Pages in insertion order; `IndexMap` ordering *is* the page order.",
"additionalProperties": {
"$ref": "#/components/schemas/Page"
},
"propertyNames": {
"type": "string",
"format": "uuid"
}
},
"project": {
"$ref": "#/components/schemas/ProjectMeta"
}
}
},
"SceneSnapshot": {
"type": "object",
"description": "JSON-shaped scene snapshot for the UI (no postcard decoder in JS).",
"required": ["epoch", "scene"],
"properties": {
"epoch": {
"type": "integer",
"format": "int64",
"minimum": 0
},
"scene": {
"$ref": "#/components/schemas/Scene"
}
}
},
"SnapshotEvent": {
"type": "object",
"required": ["jobs", "downloads"],
"properties": {
"downloads": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DownloadProgress"
}
},
"jobs": {
"type": "array",
"items": {
"$ref": "#/components/schemas/JobSummary"
}
}
}
},
"StartDownloadRequest": {
"type": "object",
"required": ["modelId"],
"properties": {
"modelId": {
"type": "string",
"description": "Package id, as declared via `declare_hf_model_package!`\n(e.g. `\"model:comic-text-detector:yolo-v5\"`)."
}
}
},
"StartDownloadResponse": {
"type": "object",
"required": ["operationId"],
"properties": {
"operationId": {
"type": "string",
"description": "Operation id. Reusing the package id keeps ids meaningful for clients\nwatching progress events."
}
}
},
"StartPipelineRequest": {
"type": "object",
"required": ["steps"],
"properties": {
"defaultFont": {
"type": ["string", "null"]
},
"pages": {
"type": ["array", "null"],
"items": {
"$ref": "#/components/schemas/PageId"
},
"description": "`None` → whole project, `Some(pages)` → just those pages."
},
"region": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/Region",
"description": "Optional bounding-box hint for inpainter engines (repair-brush)."
}
]
},
"steps": {
"type": "array",
"items": {
"type": "string"
},
"description": "Engine ids (`inventory::submit!` ids) to run in order."
},
"systemPrompt": {
"type": ["string", "null"]
},
"targetLanguage": {
"type": ["string", "null"]
},
"textNodeIds": {
"type": ["array", "null"],
"items": {
"$ref": "#/components/schemas/NodeId"
},
"description": "Optional text-node ids for engines that can operate on individual blocks."
}
}
},
"StartPipelineResponse": {
"type": "object",
"required": ["operationId"],
"properties": {
"operationId": {
"type": "string"
}
}
},
"TextAlign": {
"type": "string",
"enum": ["left", "center", "right"]
},
"TextData": {
"type": "object",
"properties": {
"confidence": {
"type": "number",
"format": "float"
},
"detectedFontSizePx": {
"type": ["number", "null"],
"format": "float"
},
"detector": {
"type": ["string", "null"]
},
"fontPrediction": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/FontPrediction"
}
]
},
"linePolygons": {
"type": ["array", "null"],
"items": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number",
"format": "float"
}
}
}
},
"lockLayoutBox": {
"type": "boolean"
},
"renderedDirection": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextDirection"
}
]
},
"rotationDeg": {
"type": ["number", "null"],
"format": "float"
},
"sourceDirection": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextDirection"
}
]
},
"sourceLang": {
"type": ["string", "null"]
},
"sprite": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/BlobRef",
"description": "Renderer-produced sprite for this block."
}
]
},
"spriteTransform": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/Transform",
"description": "Sprite placement when the renderer expands past the bubble geometry."
}
]
},
"style": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextStyle"
}
]
},
"text": {
"type": ["string", "null"]
},
"translation": {
"type": ["string", "null"]
}
}
},
"TextDataPatch": {
"type": "object",
"description": "For fields where \"set to None\" is meaningful (e.g. clearing a translation),\nthe outer `Option` is \"patch present\", the inner is \"value present\".",
"properties": {
"confidence": {
"type": ["number", "null"],
"format": "float"
},
"detectedFontSizePx": {
"type": ["number", "null"],
"format": "float"
},
"detector": {
"type": ["string", "null"]
},
"fontPrediction": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/FontPrediction"
}
]
},
"linePolygons": {
"type": ["array", "null"],
"items": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number",
"format": "float"
}
}
}
},
"lockLayoutBox": {
"type": ["boolean", "null"]
},
"renderedDirection": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextDirection"
}
]
},
"rotationDeg": {
"type": ["number", "null"],
"format": "float"
},
"sourceDirection": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextDirection"
}
]
},
"sourceLang": {
"type": ["string", "null"]
},
"sprite": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/BlobRef"
}
]
},
"spriteTransform": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/Transform"
}
]
},
"style": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextStyle"
}
]
},
"text": {
"type": ["string", "null"]
},
"translation": {
"type": ["string", "null"]
}
}
},
"TextDirection": {
"type": "string",
"description": "Reading axis of a text block.",
"enum": ["horizontal", "vertical"]
},
"TextShaderEffect": {
"type": "object",
"properties": {
"bold": {
"type": "boolean"
},
"italic": {
"type": "boolean"
}
}
},
"TextStrokeStyle": {
"type": "object",
"properties": {
"color": {
"type": "array",
"items": {
"type": "integer",
"format": "int32",
"minimum": 0
}
},
"enabled": {
"type": "boolean"
},
"widthPx": {
"type": ["number", "null"],
"format": "float"
}
}
},
"TextStyle": {
"type": "object",
"required": ["fontFamilies", "color"],
"properties": {
"color": {
"type": "array",
"items": {
"type": "integer",
"format": "int32",
"minimum": 0
}
},
"effect": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextShaderEffect"
}
]
},
"fontFamilies": {
"type": "array",
"items": {
"type": "string"
}
},
"fontSize": {
"type": ["number", "null"],
"format": "float"
},
"stroke": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextStrokeStyle"
}
]
},
"textAlign": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TextAlign"
}
]
}
}
},
"TopFont": {
"type": "object",
"required": ["index", "score"],
"properties": {
"index": {
"type": "integer",
"minimum": 0
},
"score": {
"type": "number",
"format": "float"
}
}
},
"Transform": {
"type": "object",
"required": ["x", "y", "width", "height"],
"properties": {
"height": {
"type": "number",
"format": "float"
},
"rotationDeg": {
"type": "number",
"format": "float"
},
"width": {
"type": "number",
"format": "float"
},
"x": {
"type": "number",
"format": "float"
},
"y": {
"type": "number",
"format": "float"
}
}
}
}
}
}