kiapi 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. kiapi/__init__.py +3 -0
  2. kiapi/__main__.py +4 -0
  3. kiapi/api/__init__.py +26 -0
  4. kiapi/api/_constants/require_auth.py +14 -0
  5. kiapi/api/_helpers/build_job_responses.py +73 -0
  6. kiapi/api/_helpers/build_openapi.py +55 -0
  7. kiapi/api/_helpers/build_train_responses.py +21 -0
  8. kiapi/api/_helpers/get_accept.py +20 -0
  9. kiapi/api/_helpers/get_ctx.py +7 -0
  10. kiapi/api/_helpers/get_worker.py +7 -0
  11. kiapi/api/_helpers/register_capability_endpoints.py +70 -0
  12. kiapi/api/_helpers/submit_and_maybe_wait.py +113 -0
  13. kiapi/api/_settings.py +50 -0
  14. kiapi/api/_views/async_job_response.py +21 -0
  15. kiapi/api/_views/capability_model_spec.py +49 -0
  16. kiapi/api/app.py +150 -0
  17. kiapi/api/audio/acestep/_views/extract_response.py +57 -0
  18. kiapi/api/audio/acestep/_views/track_response.py +57 -0
  19. kiapi/api/audio/acestep/router.py +190 -0
  20. kiapi/api/audio/audiogen/_views/audio_response.py +46 -0
  21. kiapi/api/audio/audiogen/router.py +77 -0
  22. kiapi/api/chat/_views/chat_completion_response.py +71 -0
  23. kiapi/api/chat/router.py +253 -0
  24. kiapi/api/embedding/_views/embedding_response.py +35 -0
  25. kiapi/api/embedding/router.py +82 -0
  26. kiapi/api/files/_operations/get_file.py +14 -0
  27. kiapi/api/files/_operations/get_file_id.py +18 -0
  28. kiapi/api/files/_views/file_delete_response.py +14 -0
  29. kiapi/api/files/_views/file_list_response.py +15 -0
  30. kiapi/api/files/router.py +105 -0
  31. kiapi/api/health/_views/health_response.py +26 -0
  32. kiapi/api/health/router.py +28 -0
  33. kiapi/api/image/depthpro/_views/estimate_response.py +70 -0
  34. kiapi/api/image/depthpro/router.py +81 -0
  35. kiapi/api/image/ernie/_views/image_response.py +50 -0
  36. kiapi/api/image/ernie/router.py +181 -0
  37. kiapi/api/image/flux2/_views/image_response.py +53 -0
  38. kiapi/api/image/flux2/router.py +197 -0
  39. kiapi/api/image/ideogram4/_views/image_response.py +55 -0
  40. kiapi/api/image/ideogram4/router.py +87 -0
  41. kiapi/api/image/qwen/_views/image_response.py +47 -0
  42. kiapi/api/image/qwen/router.py +141 -0
  43. kiapi/api/image/seedvr2/_views/image_response.py +50 -0
  44. kiapi/api/image/seedvr2/router.py +83 -0
  45. kiapi/api/image/zimage/_views/image_response.py +49 -0
  46. kiapi/api/image/zimage/router.py +131 -0
  47. kiapi/api/jobs/_operations/get_job_id.py +18 -0
  48. kiapi/api/jobs/_views/job_delete_response.py +19 -0
  49. kiapi/api/jobs/_views/job_list_response.py +15 -0
  50. kiapi/api/jobs/router.py +62 -0
  51. kiapi/api/models/_schemas/openai_model_spec.py +26 -0
  52. kiapi/api/models/_views/model_list_response.py +15 -0
  53. kiapi/api/models/router.py +29 -0
  54. kiapi/api/video/ltx2/_views/__init__.py +1 -0
  55. kiapi/api/video/ltx2/_views/video_response.py +59 -0
  56. kiapi/api/video/ltx2/router.py +89 -0
  57. kiapi/api/web/_views/__init__.py +7 -0
  58. kiapi/api/web/_views/fetch_api_request.py +26 -0
  59. kiapi/api/web/_views/fetch_error_response.py +25 -0
  60. kiapi/api/web/router.py +302 -0
  61. kiapi/capabilities/__init__.py +24 -0
  62. kiapi/capabilities/_exceptions/CapabilityError.py +2 -0
  63. kiapi/capabilities/_exceptions/ValidationError.py +2 -0
  64. kiapi/capabilities/_helpers/attach_mflux_progress.py +50 -0
  65. kiapi/capabilities/_helpers/get_file_path.py +20 -0
  66. kiapi/capabilities/_helpers/resolve_file_ref.py +16 -0
  67. kiapi/capabilities/acestep/README.ja.md +174 -0
  68. kiapi/capabilities/acestep/README.md +167 -0
  69. kiapi/capabilities/acestep/__init__.py +37 -0
  70. kiapi/capabilities/acestep/_constants/description.py +122 -0
  71. kiapi/capabilities/acestep/_exceptions/ace_step_engine_error.py +2 -0
  72. kiapi/capabilities/acestep/_helpers/register.py +96 -0
  73. kiapi/capabilities/acestep/_models/acestep.py +105 -0
  74. kiapi/capabilities/acestep/_operations/handle_cover.py +23 -0
  75. kiapi/capabilities/acestep/_operations/handle_extract.py +38 -0
  76. kiapi/capabilities/acestep/_operations/handle_generate.py +18 -0
  77. kiapi/capabilities/acestep/_operations/handle_repaint.py +25 -0
  78. kiapi/capabilities/acestep/_operations/resolve_ace_step_paths.py +30 -0
  79. kiapi/capabilities/acestep/_operations/resolve_cover_params.py +21 -0
  80. kiapi/capabilities/acestep/_operations/resolve_engine.py +10 -0
  81. kiapi/capabilities/acestep/_operations/resolve_extract_params.py +24 -0
  82. kiapi/capabilities/acestep/_operations/resolve_generate_params.py +18 -0
  83. kiapi/capabilities/acestep/_operations/resolve_repaint_params.py +22 -0
  84. kiapi/capabilities/acestep/_schemas/ace_step_paths.py +29 -0
  85. kiapi/capabilities/acestep/_services/ace_step_engine.py +143 -0
  86. kiapi/capabilities/acestep/_settings.py +82 -0
  87. kiapi/capabilities/acestep/_views/ace_step_base.py +61 -0
  88. kiapi/capabilities/acestep/_views/cover_params.py +26 -0
  89. kiapi/capabilities/acestep/_views/cover_request.py +49 -0
  90. kiapi/capabilities/acestep/_views/extract_params.py +24 -0
  91. kiapi/capabilities/acestep/_views/extract_request.py +33 -0
  92. kiapi/capabilities/acestep/_views/generate_params.py +25 -0
  93. kiapi/capabilities/acestep/_views/generate_request.py +54 -0
  94. kiapi/capabilities/acestep/_views/repaint_params.py +27 -0
  95. kiapi/capabilities/acestep/_views/repaint_request.py +51 -0
  96. kiapi/capabilities/acestep/_views/track_params.py +7 -0
  97. kiapi/capabilities/acestep/worker_subprocess.py +247 -0
  98. kiapi/capabilities/audiogen/README.ja.md +49 -0
  99. kiapi/capabilities/audiogen/README.md +48 -0
  100. kiapi/capabilities/audiogen/__init__.py +25 -0
  101. kiapi/capabilities/audiogen/_constants/description.py +60 -0
  102. kiapi/capabilities/audiogen/_helpers/attach_audiogen_progress.py +27 -0
  103. kiapi/capabilities/audiogen/_helpers/register.py +42 -0
  104. kiapi/capabilities/audiogen/_helpers/validate_generate.py +14 -0
  105. kiapi/capabilities/audiogen/_models/audiogen.py +98 -0
  106. kiapi/capabilities/audiogen/_operations/handle_generate.py +27 -0
  107. kiapi/capabilities/audiogen/_operations/resolve_generate_params.py +25 -0
  108. kiapi/capabilities/audiogen/_settings.py +34 -0
  109. kiapi/capabilities/audiogen/_views/generate_params.py +14 -0
  110. kiapi/capabilities/audiogen/_views/generate_request.py +96 -0
  111. kiapi/capabilities/chat/README.ja.md +822 -0
  112. kiapi/capabilities/chat/README.md +806 -0
  113. kiapi/capabilities/chat/__init__.py +25 -0
  114. kiapi/capabilities/chat/_constants/description.py +163 -0
  115. kiapi/capabilities/chat/_helpers/register.py +67 -0
  116. kiapi/capabilities/chat/_models/qwen3_5.py +183 -0
  117. kiapi/capabilities/chat/_models/qwen3_omni.py +242 -0
  118. kiapi/capabilities/chat/_operations/apply_template.py +74 -0
  119. kiapi/capabilities/chat/_operations/completed_hermes_tool_call_text.py +9 -0
  120. kiapi/capabilities/chat/_operations/emit_streaming_response.py +297 -0
  121. kiapi/capabilities/chat/_operations/ensure_streaming_detokenizer_compat.py +49 -0
  122. kiapi/capabilities/chat/_operations/format_response.py +72 -0
  123. kiapi/capabilities/chat/_operations/handle_chat.py +25 -0
  124. kiapi/capabilities/chat/_operations/parse_hermes_tool_calls.py +63 -0
  125. kiapi/capabilities/chat/_operations/parse_json_tool_calls.py +66 -0
  126. kiapi/capabilities/chat/_operations/parse_messages.py +326 -0
  127. kiapi/capabilities/chat/_operations/resolve_chat_params.py +50 -0
  128. kiapi/capabilities/chat/_operations/stream_text_from_tokens.py +32 -0
  129. kiapi/capabilities/chat/_operations/strip_tool_calls.py +15 -0
  130. kiapi/capabilities/chat/_settings.py +74 -0
  131. kiapi/capabilities/chat/_utils/apply_parallel_tool_call_policy.py +17 -0
  132. kiapi/capabilities/chat/_utils/apply_seed.py +8 -0
  133. kiapi/capabilities/chat/_utils/load_audio_mono.py +31 -0
  134. kiapi/capabilities/chat/_utils/load_mlx_vlm.py +12 -0
  135. kiapi/capabilities/chat/_utils/warmup_params.py +26 -0
  136. kiapi/capabilities/chat/_views/chat_params.py +34 -0
  137. kiapi/capabilities/chat/_views/chat_request.py +153 -0
  138. kiapi/capabilities/depthpro/README.ja.md +131 -0
  139. kiapi/capabilities/depthpro/README.md +124 -0
  140. kiapi/capabilities/depthpro/__init__.py +23 -0
  141. kiapi/capabilities/depthpro/_constants/description.py +39 -0
  142. kiapi/capabilities/depthpro/_helpers/register.py +46 -0
  143. kiapi/capabilities/depthpro/_helpers/validate_estimate.py +32 -0
  144. kiapi/capabilities/depthpro/_models/depthpro.py +144 -0
  145. kiapi/capabilities/depthpro/_operations/handle_estimate.py +50 -0
  146. kiapi/capabilities/depthpro/_operations/is_quantize_override.py +12 -0
  147. kiapi/capabilities/depthpro/_operations/resolve_estimate_params.py +24 -0
  148. kiapi/capabilities/depthpro/_settings.py +46 -0
  149. kiapi/capabilities/depthpro/_views/estimate_params.py +21 -0
  150. kiapi/capabilities/depthpro/_views/estimate_request.py +63 -0
  151. kiapi/capabilities/embedding/README.ja.md +137 -0
  152. kiapi/capabilities/embedding/README.md +128 -0
  153. kiapi/capabilities/embedding/__init__.py +24 -0
  154. kiapi/capabilities/embedding/_constants/description.py +47 -0
  155. kiapi/capabilities/embedding/_helpers/register.py +66 -0
  156. kiapi/capabilities/embedding/_models/qwen3_text.py +53 -0
  157. kiapi/capabilities/embedding/_models/qwen3_vl.py +97 -0
  158. kiapi/capabilities/embedding/_operations/format_response.py +24 -0
  159. kiapi/capabilities/embedding/_operations/handle_embed.py +24 -0
  160. kiapi/capabilities/embedding/_operations/parse_inputs.py +108 -0
  161. kiapi/capabilities/embedding/_operations/resolve_embed_params.py +18 -0
  162. kiapi/capabilities/embedding/_settings.py +27 -0
  163. kiapi/capabilities/embedding/_utils/to_vector.py +20 -0
  164. kiapi/capabilities/embedding/_views/embed_params.py +17 -0
  165. kiapi/capabilities/embedding/_views/embed_request.py +39 -0
  166. kiapi/capabilities/ernie/README.ja.md +242 -0
  167. kiapi/capabilities/ernie/README.md +223 -0
  168. kiapi/capabilities/ernie/__init__.py +34 -0
  169. kiapi/capabilities/ernie/_constants/description.py +71 -0
  170. kiapi/capabilities/ernie/_helpers/register.py +60 -0
  171. kiapi/capabilities/ernie/_helpers/validate_edit.py +19 -0
  172. kiapi/capabilities/ernie/_helpers/validate_generate.py +8 -0
  173. kiapi/capabilities/ernie/_models/ernie.py +356 -0
  174. kiapi/capabilities/ernie/_operations/handle_edit.py +39 -0
  175. kiapi/capabilities/ernie/_operations/handle_generate.py +38 -0
  176. kiapi/capabilities/ernie/_operations/handle_train.py +77 -0
  177. kiapi/capabilities/ernie/_operations/is_quantize_override.py +16 -0
  178. kiapi/capabilities/ernie/_operations/resolve_edit_params.py +44 -0
  179. kiapi/capabilities/ernie/_operations/resolve_generate_params.py +40 -0
  180. kiapi/capabilities/ernie/_operations/resolve_lora_params.py +23 -0
  181. kiapi/capabilities/ernie/_operations/resolve_train_params.py +43 -0
  182. kiapi/capabilities/ernie/_operations/validate_common.py +33 -0
  183. kiapi/capabilities/ernie/_schemas/lora_ref.py +27 -0
  184. kiapi/capabilities/ernie/_settings.py +151 -0
  185. kiapi/capabilities/ernie/_views/edit_params.py +36 -0
  186. kiapi/capabilities/ernie/_views/edit_request.py +142 -0
  187. kiapi/capabilities/ernie/_views/generate_params.py +32 -0
  188. kiapi/capabilities/ernie/_views/generate_request.py +127 -0
  189. kiapi/capabilities/ernie/_views/train_params.py +28 -0
  190. kiapi/capabilities/ernie/_views/train_request.py +96 -0
  191. kiapi/capabilities/flux2/README.ja.md +260 -0
  192. kiapi/capabilities/flux2/README.md +241 -0
  193. kiapi/capabilities/flux2/__init__.py +36 -0
  194. kiapi/capabilities/flux2/_constants/description.py +81 -0
  195. kiapi/capabilities/flux2/_helpers/register.py +98 -0
  196. kiapi/capabilities/flux2/_helpers/validate_edit.py +12 -0
  197. kiapi/capabilities/flux2/_helpers/validate_generate.py +8 -0
  198. kiapi/capabilities/flux2/_models/flux2.py +396 -0
  199. kiapi/capabilities/flux2/_operations/handle_edit.py +44 -0
  200. kiapi/capabilities/flux2/_operations/handle_generate.py +46 -0
  201. kiapi/capabilities/flux2/_operations/handle_train.py +105 -0
  202. kiapi/capabilities/flux2/_operations/is_quantize_override.py +16 -0
  203. kiapi/capabilities/flux2/_operations/resolve_edit_params.py +43 -0
  204. kiapi/capabilities/flux2/_operations/resolve_generate_params.py +44 -0
  205. kiapi/capabilities/flux2/_operations/resolve_lora_params.py +23 -0
  206. kiapi/capabilities/flux2/_operations/resolve_train_params.py +42 -0
  207. kiapi/capabilities/flux2/_operations/role_spec.py +13 -0
  208. kiapi/capabilities/flux2/_operations/split_repo.py +11 -0
  209. kiapi/capabilities/flux2/_operations/validate_common.py +35 -0
  210. kiapi/capabilities/flux2/_schemas/lora_ref.py +27 -0
  211. kiapi/capabilities/flux2/_settings.py +181 -0
  212. kiapi/capabilities/flux2/_views/edit_params.py +36 -0
  213. kiapi/capabilities/flux2/_views/edit_request.py +145 -0
  214. kiapi/capabilities/flux2/_views/generate_params.py +36 -0
  215. kiapi/capabilities/flux2/_views/generate_request.py +150 -0
  216. kiapi/capabilities/flux2/_views/train_params.py +32 -0
  217. kiapi/capabilities/flux2/_views/train_request.py +102 -0
  218. kiapi/capabilities/ideogram4/README.ja.md +230 -0
  219. kiapi/capabilities/ideogram4/README.md +219 -0
  220. kiapi/capabilities/ideogram4/__init__.py +24 -0
  221. kiapi/capabilities/ideogram4/_constants/description.py +65 -0
  222. kiapi/capabilities/ideogram4/_helpers/register.py +44 -0
  223. kiapi/capabilities/ideogram4/_helpers/validate_generate.py +31 -0
  224. kiapi/capabilities/ideogram4/_models/ideogram4.py +120 -0
  225. kiapi/capabilities/ideogram4/_operations/handle_generate.py +30 -0
  226. kiapi/capabilities/ideogram4/_operations/is_quantize_override.py +12 -0
  227. kiapi/capabilities/ideogram4/_operations/resolve_generate_params.py +30 -0
  228. kiapi/capabilities/ideogram4/_settings.py +89 -0
  229. kiapi/capabilities/ideogram4/_views/generate_params.py +27 -0
  230. kiapi/capabilities/ideogram4/_views/generate_request.py +118 -0
  231. kiapi/capabilities/ltx2/README.ja.md +287 -0
  232. kiapi/capabilities/ltx2/README.md +274 -0
  233. kiapi/capabilities/ltx2/__init__.py +26 -0
  234. kiapi/capabilities/ltx2/_constants/description.py +81 -0
  235. kiapi/capabilities/ltx2/_helpers/register.py +58 -0
  236. kiapi/capabilities/ltx2/_helpers/validate_generate.py +42 -0
  237. kiapi/capabilities/ltx2/_models/ltx2.py +106 -0
  238. kiapi/capabilities/ltx2/_operations/detect_mode.py +19 -0
  239. kiapi/capabilities/ltx2/_operations/handle_generate.py +52 -0
  240. kiapi/capabilities/ltx2/_operations/resolve_generate_params.py +31 -0
  241. kiapi/capabilities/ltx2/_settings.py +93 -0
  242. kiapi/capabilities/ltx2/_views/generate_params.py +34 -0
  243. kiapi/capabilities/ltx2/_views/generate_request.py +151 -0
  244. kiapi/capabilities/qwen/README.ja.md +251 -0
  245. kiapi/capabilities/qwen/README.md +235 -0
  246. kiapi/capabilities/qwen/__init__.py +30 -0
  247. kiapi/capabilities/qwen/_constants/description.py +53 -0
  248. kiapi/capabilities/qwen/_helpers/register.py +60 -0
  249. kiapi/capabilities/qwen/_helpers/validate_edit.py +12 -0
  250. kiapi/capabilities/qwen/_helpers/validate_generate.py +12 -0
  251. kiapi/capabilities/qwen/_models/qwen.py +224 -0
  252. kiapi/capabilities/qwen/_operations/handle_edit.py +44 -0
  253. kiapi/capabilities/qwen/_operations/handle_generate.py +46 -0
  254. kiapi/capabilities/qwen/_operations/is_quantize_override.py +15 -0
  255. kiapi/capabilities/qwen/_operations/resolve_edit_params.py +35 -0
  256. kiapi/capabilities/qwen/_operations/resolve_generate_params.py +39 -0
  257. kiapi/capabilities/qwen/_operations/resolve_lora_params.py +23 -0
  258. kiapi/capabilities/qwen/_operations/validate_common.py +32 -0
  259. kiapi/capabilities/qwen/_schemas/lora_ref.py +27 -0
  260. kiapi/capabilities/qwen/_settings.py +107 -0
  261. kiapi/capabilities/qwen/_views/edit_params.py +36 -0
  262. kiapi/capabilities/qwen/_views/edit_request.py +138 -0
  263. kiapi/capabilities/qwen/_views/generate_params.py +37 -0
  264. kiapi/capabilities/qwen/_views/generate_request.py +149 -0
  265. kiapi/capabilities/seedvr2/README.ja.md +234 -0
  266. kiapi/capabilities/seedvr2/README.md +219 -0
  267. kiapi/capabilities/seedvr2/__init__.py +24 -0
  268. kiapi/capabilities/seedvr2/_constants/description.py +46 -0
  269. kiapi/capabilities/seedvr2/_helpers/register.py +60 -0
  270. kiapi/capabilities/seedvr2/_helpers/validate_upscale.py +52 -0
  271. kiapi/capabilities/seedvr2/_models/seedvr2.py +140 -0
  272. kiapi/capabilities/seedvr2/_operations/handle_upscale.py +42 -0
  273. kiapi/capabilities/seedvr2/_operations/is_quantize_override.py +12 -0
  274. kiapi/capabilities/seedvr2/_operations/resolve_upscale_params.py +30 -0
  275. kiapi/capabilities/seedvr2/_settings.py +74 -0
  276. kiapi/capabilities/seedvr2/_views/upscale_params.py +27 -0
  277. kiapi/capabilities/seedvr2/_views/upscale_request.py +94 -0
  278. kiapi/capabilities/web/README.ja.md +187 -0
  279. kiapi/capabilities/web/README.md +171 -0
  280. kiapi/capabilities/web/__init__.py +30 -0
  281. kiapi/capabilities/web/_constants/description.py +38 -0
  282. kiapi/capabilities/web/_exceptions/FetchError.py +24 -0
  283. kiapi/capabilities/web/_exceptions/SearchBackendError.py +11 -0
  284. kiapi/capabilities/web/_helpers/register.py +59 -0
  285. kiapi/capabilities/web/_models/crawl4ai.py +32 -0
  286. kiapi/capabilities/web/_models/searxng.py +44 -0
  287. kiapi/capabilities/web/_operations/handle_fetch.py +145 -0
  288. kiapi/capabilities/web/_operations/handle_search.py +56 -0
  289. kiapi/capabilities/web/_operations/resolve_fetch_params.py +19 -0
  290. kiapi/capabilities/web/_operations/resolve_search_params.py +34 -0
  291. kiapi/capabilities/web/_operations/resolve_searxng_config_dir.py +21 -0
  292. kiapi/capabilities/web/_services/__init__.py +1 -0
  293. kiapi/capabilities/web/_services/web_backend_process.py +144 -0
  294. kiapi/capabilities/web/_settings.py +138 -0
  295. kiapi/capabilities/web/_views/fetch_params.py +27 -0
  296. kiapi/capabilities/web/_views/fetch_request.py +29 -0
  297. kiapi/capabilities/web/_views/fetch_result.py +20 -0
  298. kiapi/capabilities/web/_views/search_params.py +43 -0
  299. kiapi/capabilities/web/_views/search_request.py +93 -0
  300. kiapi/capabilities/web/_views/search_response.py +49 -0
  301. kiapi/capabilities/web/resources/__init__.py +0 -0
  302. kiapi/capabilities/web/resources/searxng/__init__.py +0 -0
  303. kiapi/capabilities/web/resources/searxng/settings.yml +11 -0
  304. kiapi/capabilities/zimage/README.ja.md +249 -0
  305. kiapi/capabilities/zimage/README.md +231 -0
  306. kiapi/capabilities/zimage/__init__.py +34 -0
  307. kiapi/capabilities/zimage/_constants/description.py +73 -0
  308. kiapi/capabilities/zimage/_helpers/register.py +62 -0
  309. kiapi/capabilities/zimage/_helpers/validate_generate.py +37 -0
  310. kiapi/capabilities/zimage/_models/zimage.py +278 -0
  311. kiapi/capabilities/zimage/_operations/handle_generate.py +38 -0
  312. kiapi/capabilities/zimage/_operations/handle_train.py +78 -0
  313. kiapi/capabilities/zimage/_operations/is_quantize_override.py +11 -0
  314. kiapi/capabilities/zimage/_operations/resolve_generate_params.py +39 -0
  315. kiapi/capabilities/zimage/_operations/resolve_lora_params.py +23 -0
  316. kiapi/capabilities/zimage/_operations/resolve_train_params.py +38 -0
  317. kiapi/capabilities/zimage/_schemas/lora_ref.py +27 -0
  318. kiapi/capabilities/zimage/_settings.py +166 -0
  319. kiapi/capabilities/zimage/_views/generate_params.py +23 -0
  320. kiapi/capabilities/zimage/_views/generate_request.py +127 -0
  321. kiapi/capabilities/zimage/_views/train_params.py +22 -0
  322. kiapi/capabilities/zimage/_views/train_request.py +101 -0
  323. kiapi/cli/__init__.py +11 -0
  324. kiapi/cli/_helpers/dedupe_resources.py +12 -0
  325. kiapi/cli/_helpers/register_all_capabilities.py +36 -0
  326. kiapi/cli/_helpers/run_resources.py +24 -0
  327. kiapi/cli/_helpers/select_specs.py +67 -0
  328. kiapi/cli/activate/_operations/preflight_hf_access.py +129 -0
  329. kiapi/cli/activate/cli.py +37 -0
  330. kiapi/cli/check/_helpers/check_audio_acestep_turbo.py +22 -0
  331. kiapi/cli/check/_helpers/check_audio_acestep_xl_base.py +22 -0
  332. kiapi/cli/check/_helpers/check_audio_audiogen_medium.py +24 -0
  333. kiapi/cli/check/_helpers/check_chat_chat_qwen3_6_27b.py +19 -0
  334. kiapi/cli/check/_helpers/check_chat_chat_qwen3_omni.py +19 -0
  335. kiapi/cli/check/_helpers/check_embedding_embedding_qwen3_embedding_8b.py +14 -0
  336. kiapi/cli/check/_helpers/check_embedding_embedding_qwen3_vl_embedding_2b.py +19 -0
  337. kiapi/cli/check/_helpers/check_image_depthpro_base.py +21 -0
  338. kiapi/cli/check/_helpers/check_image_ernie_base.py +23 -0
  339. kiapi/cli/check/_helpers/check_image_ernie_turbo.py +23 -0
  340. kiapi/cli/check/_helpers/check_image_flux2_klein_9b.py +23 -0
  341. kiapi/cli/check/_helpers/check_image_flux2_klein_base_4b.py +23 -0
  342. kiapi/cli/check/_helpers/check_image_flux2_klein_base_9b.py +23 -0
  343. kiapi/cli/check/_helpers/check_image_ideogram4_fp8.py +23 -0
  344. kiapi/cli/check/_helpers/check_image_qwen_edit_2509.py +27 -0
  345. kiapi/cli/check/_helpers/check_image_qwen_image.py +23 -0
  346. kiapi/cli/check/_helpers/check_image_seedvr2_3b.py +23 -0
  347. kiapi/cli/check/_helpers/check_image_seedvr2_7b.py +23 -0
  348. kiapi/cli/check/_helpers/check_image_zimage_base.py +23 -0
  349. kiapi/cli/check/_helpers/check_image_zimage_turbo.py +23 -0
  350. kiapi/cli/check/_helpers/check_video_ltx2_distilled.py +26 -0
  351. kiapi/cli/check/_helpers/check_web_web_fetch.py +14 -0
  352. kiapi/cli/check/_helpers/check_web_web_search.py +14 -0
  353. kiapi/cli/check/_operations/build_check_result.py +20 -0
  354. kiapi/cli/check/_operations/check_context.py +10 -0
  355. kiapi/cli/check/_operations/create_sample_image.py +46 -0
  356. kiapi/cli/check/_schemas/check_result.py +12 -0
  357. kiapi/cli/check/cli.py +89 -0
  358. kiapi/cli/cli.py +29 -0
  359. kiapi/cli/config/cli.py +17 -0
  360. kiapi/cli/config/edit/cli.py +32 -0
  361. kiapi/cli/config/init/cli.py +33 -0
  362. kiapi/cli/config/show/cli.py +13 -0
  363. kiapi/cli/config/template/cli.py +36 -0
  364. kiapi/cli/deactivate/cli.py +49 -0
  365. kiapi/cli/run/asgi.py +16 -0
  366. kiapi/cli/run/cli.py +59 -0
  367. kiapi/cli/service/__init__.py +5 -0
  368. kiapi/cli/service/_services/service_manager.py +107 -0
  369. kiapi/cli/service/cli.py +19 -0
  370. kiapi/cli/service/install/cli.py +17 -0
  371. kiapi/cli/service/start/cli.py +22 -0
  372. kiapi/cli/service/status/cli.py +81 -0
  373. kiapi/cli/service/stop/cli.py +19 -0
  374. kiapi/cli/service/uninstall/cli.py +16 -0
  375. kiapi/cli/status/cli.py +226 -0
  376. kiapi/core/app/__init__.py +16 -0
  377. kiapi/core/app/_schemas/app_context.py +28 -0
  378. kiapi/core/app/_services/user_directory.py +59 -0
  379. kiapi/core/app/_settings.py +46 -0
  380. kiapi/core/capability/__init__.py +11 -0
  381. kiapi/core/capability/_schemas/capability_spec.py +17 -0
  382. kiapi/core/capability/_services/capability_spec_registry.py +21 -0
  383. kiapi/core/config/__init__.py +11 -0
  384. kiapi/core/config/_exceptions/user_config_error.py +2 -0
  385. kiapi/core/config/_helpers/get_user_settings_path.py +7 -0
  386. kiapi/core/config/_helpers/load_user_settings.py +54 -0
  387. kiapi/core/file/__init__.py +37 -0
  388. kiapi/core/file/_helpers/create_file_store.py +7 -0
  389. kiapi/core/file/_helpers/resolve_file_ref.py +90 -0
  390. kiapi/core/file/_schemas/file_data_url_ref.py +19 -0
  391. kiapi/core/file/_schemas/file_id_ref.py +16 -0
  392. kiapi/core/file/_schemas/file_record.py +46 -0
  393. kiapi/core/file/_schemas/file_url_ref.py +16 -0
  394. kiapi/core/file/_services/file_store.py +138 -0
  395. kiapi/core/file/_settings.py +22 -0
  396. kiapi/core/file/_types/file_id.py +2 -0
  397. kiapi/core/file/_types/file_ref.py +12 -0
  398. kiapi/core/file/_views/resolved_file_ref.py +16 -0
  399. kiapi/core/job/__init__.py +24 -0
  400. kiapi/core/job/_enums/job_status.py +9 -0
  401. kiapi/core/job/_helpers/creep_progress.py +123 -0
  402. kiapi/core/job/_models/job.py +121 -0
  403. kiapi/core/job/_services/job_store.py +33 -0
  404. kiapi/core/job/_services/progress_reporter.py +79 -0
  405. kiapi/core/job/_types/job_id.py +3 -0
  406. kiapi/core/job/_types/job_result.py +5 -0
  407. kiapi/core/job/_types/job_type.py +4 -0
  408. kiapi/core/logging/__init__.py +14 -0
  409. kiapi/core/logging/_helpers/get_log_level.py +8 -0
  410. kiapi/core/logging/_helpers/setup_logger.py +14 -0
  411. kiapi/core/logging/_settings.py +34 -0
  412. kiapi/core/logging/_types/log_level.py +3 -0
  413. kiapi/core/memory/__init__.py +21 -0
  414. kiapi/core/memory/_exceptions/memory_budget_error.py +2 -0
  415. kiapi/core/memory/_helpers/create_memory_manager.py +17 -0
  416. kiapi/core/memory/_operations/log_memory_limit.py +29 -0
  417. kiapi/core/memory/_operations/resolve_effective_memory_limit_gb.py +13 -0
  418. kiapi/core/memory/_operations/resolve_framework_strategy.py +42 -0
  419. kiapi/core/memory/_schemas/framework_strategy.py +14 -0
  420. kiapi/core/memory/_schemas/memory_stats.py +24 -0
  421. kiapi/core/memory/_schemas/resident_model.py +14 -0
  422. kiapi/core/memory/_schemas/resident_model_stats.py +49 -0
  423. kiapi/core/memory/_services/memory_manager.py +257 -0
  424. kiapi/core/memory/_settings.py +36 -0
  425. kiapi/core/memory/_types/framework_name.py +4 -0
  426. kiapi/core/memory/_types/resident_key.py +4 -0
  427. kiapi/core/model/__init__.py +36 -0
  428. kiapi/core/model/_exceptions/unknown_model_error.py +2 -0
  429. kiapi/core/model/_schemas/model_spec.py +145 -0
  430. kiapi/core/model/_services/model_registry.py +85 -0
  431. kiapi/core/model/_types/model_alias.py +2 -0
  432. kiapi/core/model/_types/model_domain.py +6 -0
  433. kiapi/core/model/_types/model_family.py +5 -0
  434. kiapi/core/model/_types/model_key.py +8 -0
  435. kiapi/core/model/_types/model_name.py +4 -0
  436. kiapi/core/model/_types/model_repo.py +3 -0
  437. kiapi/core/net/__init__.py +16 -0
  438. kiapi/core/net/_exceptions/unsafe_url_error.py +7 -0
  439. kiapi/core/net/_helpers/verify_public_url.py +68 -0
  440. kiapi/core/net/_settings.py +28 -0
  441. kiapi/core/setup/__init__.py +25 -0
  442. kiapi/core/setup/_exceptions/setup_required_error.py +2 -0
  443. kiapi/core/setup/_schemas/docker_image_resource.py +37 -0
  444. kiapi/core/setup/_schemas/hf_snapshot_resource.py +50 -0
  445. kiapi/core/setup/_schemas/local_path_resource.py +43 -0
  446. kiapi/core/setup/_schemas/python_package_resource.py +58 -0
  447. kiapi/core/setup/_schemas/python_venv_resource.py +63 -0
  448. kiapi/core/setup/_schemas/setup_status.py +7 -0
  449. kiapi/core/setup/_schemas/url_file_resource.py +43 -0
  450. kiapi/core/setup/_services/setup_manager.py +331 -0
  451. kiapi/core/setup/_types/setup_resource.py +21 -0
  452. kiapi/core/setup/_types/setup_target.py +11 -0
  453. kiapi/core/workdir/__init__.py +8 -0
  454. kiapi/core/workdir/_helpers/create_work_dir.py +11 -0
  455. kiapi/core/workdir/_settings.py +21 -0
  456. kiapi/core/worker/__init__.py +23 -0
  457. kiapi/core/worker/_helpers/create_worker.py +9 -0
  458. kiapi/core/worker/_services/worker.py +165 -0
  459. kiapi/core/worker/_settings.py +36 -0
  460. kiapi/core/worker/_types/job_thunk.py +6 -0
  461. kiapi-0.1.0.dist-info/METADATA +337 -0
  462. kiapi-0.1.0.dist-info/RECORD +465 -0
  463. kiapi-0.1.0.dist-info/WHEEL +4 -0
  464. kiapi-0.1.0.dist-info/entry_points.txt +2 -0
  465. kiapi-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,81 @@
1
+ """Image API (depthpro): ``POST /v1/image/depthpro/estimate``."""
2
+
3
+ from fastapi import APIRouter, Depends, HTTPException
4
+ from fastapi.responses import Response
5
+
6
+ from kiapi.api import (
7
+ REQUIRE_AUTH,
8
+ build_job_responses,
9
+ get_accept,
10
+ get_ctx,
11
+ get_worker,
12
+ register_capability_endpoints,
13
+ submit_and_maybe_wait,
14
+ )
15
+ from kiapi.capabilities.depthpro import (
16
+ EstimateRequest,
17
+ ValidationError,
18
+ handle_estimate,
19
+ validate_estimate,
20
+ )
21
+ from kiapi.core.app import AppContext
22
+ from kiapi.core.model import UnknownModelError, model_registry
23
+ from kiapi.core.worker import Worker
24
+
25
+ from ._views.estimate_response import EstimateResponse
26
+
27
+ router = APIRouter(dependencies=REQUIRE_AUTH)
28
+
29
+
30
+ @router.post(
31
+ "/v1/image/depthpro/estimate",
32
+ responses=build_job_responses("image/png", result_model=EstimateResponse),
33
+ )
34
+ async def estimate(
35
+ req: EstimateRequest,
36
+ accept: str | None = Depends(get_accept),
37
+ ctx: AppContext = Depends(get_ctx),
38
+ worker: Worker = Depends(get_worker),
39
+ ) -> Response:
40
+ """Estimate a depth map from one image (Depth Pro, image-to-depth).
41
+
42
+ Produces a grayscale depth PNG (near = bright, far = dark) and, unless
43
+ `include_depth_data` is false, a compressed NPZ holding the raw float depth
44
+ array plus min/max depth. The same endpoint serves both `sync` and `async`
45
+ via `mode`.
46
+
47
+ Sync content negotiation: when exactly one artifact is produced (i.e.
48
+ `include_depth_data=false`) and the client does not ask for JSON, the raw PNG
49
+ bytes are returned with `X-Kiapi-File-Id` / `X-Kiapi-Job-Id` headers — so
50
+ `curl -o depth.png` just works. Otherwise (JSON requested, two artifacts, or
51
+ async) the Job JSON is returned, whose `result` follows EstimateResponse.
52
+
53
+ A `quantize` value differing from the resident model runs a one-off transient
54
+ model (slower, not reused). Async returns 202 immediately; poll
55
+ GET /v1/jobs/{job_id} and fetch artifacts via GET /v1/files/{file_id}.
56
+ """
57
+ try:
58
+ spec = model_registry.resolve("depthpro", req.model)
59
+ except UnknownModelError as exc:
60
+ raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
61
+
62
+ try:
63
+ validate_estimate(req)
64
+ except ValidationError as exc:
65
+ raise HTTPException(status_code=422, detail=str(exc)) # noqa: B904
66
+
67
+ def thunk(): # type: ignore
68
+ return handle_estimate(ctx, req)
69
+
70
+ return await submit_and_maybe_wait(
71
+ ctx,
72
+ worker,
73
+ type="depthpro",
74
+ params=req.gen_params() | {"model": spec.name, "mode": req.mode},
75
+ thunk=thunk,
76
+ mode=req.mode,
77
+ accept=accept,
78
+ )
79
+
80
+
81
+ register_capability_endpoints(router, name="depthpro", base_path="/v1/image/depthpro")
@@ -0,0 +1,50 @@
1
+ """``/v1/image/ernie/{generate,edit}`` result payload (the Job ``result`` shape).
2
+
3
+ Mirrors the dict returned by ``capabilities/ernie/_models/ernie._store_image`` so
4
+ the produced image result is self-describing in OpenAPI. It is an output-side
5
+ projection of the model result (not a model-coupled view), so it lives under
6
+ ``api/image/ernie/_views``. ``generate`` and ``edit`` produce the same shape, so
7
+ both endpoints share this one view.
8
+
9
+ ``ImageResponse`` is the sole public element; nested pieces stay private.
10
+ """
11
+
12
+ from typing import Any
13
+
14
+ from pydantic import BaseModel, Field
15
+
16
+
17
+ class _Timings(BaseModel):
18
+ total_s: float = Field(
19
+ description="Wall-clock generation time in seconds (model run only)."
20
+ )
21
+
22
+
23
+ class ImageResponse(BaseModel):
24
+ """Capability-specific ``result`` for a succeeded ernie generate/edit job."""
25
+
26
+ model: str = Field(
27
+ description="Resolved model variant that produced the image (turbo | base)."
28
+ )
29
+ prompt: str = Field(description="The prompt used for the run.")
30
+
31
+ file_id: str = Field(
32
+ description=(
33
+ "Files-API id of the produced image. Fetch metadata at "
34
+ "GET /v1/files/{id} or bytes at /download. This is also the artifact "
35
+ "returned as raw bytes by a single-artifact sync call."
36
+ )
37
+ )
38
+ image_bytes: int = Field(description="Size of the produced image in bytes.")
39
+
40
+ width: int = Field(description="Width in pixels of the produced image.")
41
+ height: int = Field(description="Height in pixels of the produced image.")
42
+
43
+ params: dict[str, Any] = Field(
44
+ description=(
45
+ "Resolved parameters actually used for the run (model, seed, steps, "
46
+ "guidance, quantize, scheduler, format, quality, loras, …), so the "
47
+ "result is reproducible."
48
+ )
49
+ )
50
+ timings: _Timings = Field(description="kiapi extension: server-side timing.")
@@ -0,0 +1,181 @@
1
+ """Image API (ernie): ERNIE-Image generate/edit/train."""
2
+
3
+ from fastapi import APIRouter, Depends, HTTPException
4
+ from fastapi.responses import Response
5
+
6
+ from kiapi.api import (
7
+ REQUIRE_AUTH,
8
+ build_job_responses,
9
+ build_train_responses,
10
+ get_accept,
11
+ get_ctx,
12
+ get_worker,
13
+ register_capability_endpoints,
14
+ submit_and_maybe_wait,
15
+ )
16
+ from kiapi.capabilities.ernie import (
17
+ EditRequest,
18
+ GenerateRequest,
19
+ TrainRequest,
20
+ ValidationError,
21
+ handle_edit,
22
+ handle_generate,
23
+ handle_train,
24
+ validate_edit,
25
+ validate_generate,
26
+ )
27
+ from kiapi.core.app import AppContext
28
+ from kiapi.core.file import FileIDRef
29
+ from kiapi.core.model import UnknownModelError, model_registry
30
+ from kiapi.core.worker import Worker
31
+
32
+ from ._views.image_response import ImageResponse
33
+
34
+ router = APIRouter(dependencies=REQUIRE_AUTH)
35
+
36
+
37
+ @router.post(
38
+ "/v1/image/ernie/generate",
39
+ responses=build_job_responses(
40
+ "image/png", "image/jpeg", "image/webp", result_model=ImageResponse
41
+ ),
42
+ )
43
+ async def generate_ernie_endpoint(
44
+ req: GenerateRequest,
45
+ accept: str | None = Depends(get_accept),
46
+ ctx: AppContext = Depends(get_ctx),
47
+ worker: Worker = Depends(get_worker),
48
+ ) -> Response:
49
+ """Generate an image from a text prompt (ERNIE-Image, text-to-image).
50
+
51
+ No input image — use `/v1/image/ernie/edit` for image-to-image. The same
52
+ endpoint serves both `sync` and `async` via `mode`. Variant defaults differ:
53
+ `turbo` (default) is fast and uses few steps; `base` is higher quality and
54
+ slower.
55
+
56
+ Sync content negotiation: a single image is produced, so unless the client
57
+ asks for JSON the raw image bytes are returned with `X-Kiapi-File-Id` /
58
+ `X-Kiapi-Job-Id` headers — `curl -o out.png` just works. With
59
+ `Accept: application/json` (or async) the Job JSON is returned, whose
60
+ `result` follows ImageResponse.
61
+
62
+ Any `loras` or a `quantize` differing from the resident model runs a one-off
63
+ transient model (slower, not reused). Async returns 202 immediately; poll
64
+ GET /v1/jobs/{job_id} and fetch the artifact via GET /v1/files/{file_id}.
65
+ """
66
+ try:
67
+ spec = model_registry.resolve("ernie", req.model)
68
+ except UnknownModelError as exc:
69
+ raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
70
+ try:
71
+ validate_generate(req, variant=spec.name)
72
+ except ValidationError as exc:
73
+ raise HTTPException(status_code=422, detail=str(exc)) # noqa: B904
74
+
75
+ def thunk(): # type: ignore
76
+ return handle_generate(ctx, req)
77
+
78
+ return await submit_and_maybe_wait(
79
+ ctx,
80
+ worker,
81
+ type="ernie",
82
+ params=req.gen_params() | {"model": spec.name, "mode": req.mode},
83
+ thunk=thunk,
84
+ mode=req.mode,
85
+ accept=accept,
86
+ )
87
+
88
+
89
+ @router.post(
90
+ "/v1/image/ernie/edit",
91
+ responses=build_job_responses(
92
+ "image/png", "image/jpeg", "image/webp", result_model=ImageResponse
93
+ ),
94
+ )
95
+ async def edit_ernie_endpoint(
96
+ req: EditRequest,
97
+ accept: str | None = Depends(get_accept),
98
+ ctx: AppContext = Depends(get_ctx),
99
+ worker: Worker = Depends(get_worker),
100
+ ) -> Response:
101
+ """Edit a single input image with a prompt (ERNIE-Image, image-to-image).
102
+
103
+ Takes one `image` (FileRef) plus a `prompt`; `image_strength` controls how
104
+ much of the input is preserved (lower = closer to input). Output must be
105
+ square by default (a guard around an mflux 0.18.0 non-square img2img issue),
106
+ overrideable via `KIAPI_ERNIE_EDIT_REQUIRE_SQUARE=0`. The same endpoint
107
+ serves both `sync` and `async` via `mode`.
108
+
109
+ Sync content negotiation, transient-model behavior (`loras` / `quantize`
110
+ override), and the ImageResponse `result` shape match
111
+ `/v1/image/ernie/generate`.
112
+ """
113
+ try:
114
+ spec = model_registry.resolve("ernie", req.model)
115
+ except UnknownModelError as exc:
116
+ raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
117
+ try:
118
+ validate_edit(req, variant=spec.name)
119
+ except ValidationError as exc:
120
+ raise HTTPException(status_code=422, detail=str(exc)) # noqa: B904
121
+
122
+ def thunk(): # type: ignore
123
+ return handle_edit(ctx, req)
124
+
125
+ return await submit_and_maybe_wait(
126
+ ctx,
127
+ worker,
128
+ type="ernie-edit",
129
+ params=req.gen_params() | {"model": spec.name, "mode": req.mode},
130
+ thunk=thunk,
131
+ mode=req.mode,
132
+ accept=accept,
133
+ )
134
+
135
+
136
+ @router.post("/v1/image/ernie/train", responses=build_train_responses())
137
+ async def train_ernie_endpoint(
138
+ req: TrainRequest,
139
+ ctx: AppContext = Depends(get_ctx),
140
+ worker: Worker = Depends(get_worker),
141
+ ) -> Response:
142
+ """Train a LoRA adapter on a captioned image set (ERNIE-Image, always async).
143
+
144
+ Long-running, so this endpoint is always async: it returns 202 with a
145
+ job_id — poll GET /v1/jobs/{job_id}. The `dataset` is a Files-API ZIP whose
146
+ images each have a same-stem `.txt` caption. On success the job's `result`
147
+ holds `adapter_file_id` (the trained `.safetensors`, also the artifact),
148
+ `adapter_bytes`, `num_images`, the resolved `config`, `lora_targets`, and
149
+ `timings`; the adapter can then be passed back via `loras` on generate/edit.
150
+ """
151
+ try:
152
+ spec = model_registry.resolve("ernie", req.model)
153
+ except UnknownModelError as exc:
154
+ raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
155
+ if (
156
+ isinstance(req.dataset, FileIDRef)
157
+ and ctx.file_store.get(req.dataset.file_id) is None
158
+ ):
159
+ raise HTTPException(
160
+ status_code=400, detail=f"unknown dataset file_id {req.dataset.file_id!r}"
161
+ )
162
+
163
+ def thunk(): # type: ignore
164
+ return handle_train(ctx, req)
165
+
166
+ return await submit_and_maybe_wait(
167
+ ctx,
168
+ worker,
169
+ type="ernie-train",
170
+ params={
171
+ "model": spec.name,
172
+ "dataset": req.dataset.model_dump(mode="json"),
173
+ "num_epochs": req.num_epochs,
174
+ "lora_rank": req.lora_rank,
175
+ },
176
+ thunk=thunk,
177
+ mode="async",
178
+ )
179
+
180
+
181
+ register_capability_endpoints(router, name="ernie", base_path="/v1/image/ernie")
@@ -0,0 +1,53 @@
1
+ """``/v1/image/flux2/{generate,edit}`` result payload (the Job ``result`` shape).
2
+
3
+ Mirrors the dict returned by ``capabilities/flux2/_models/flux2._store_image`` so
4
+ the produced image result is self-describing in OpenAPI. It is an output-side
5
+ projection of the model result (not a model-coupled view), so it lives under
6
+ ``api/image/flux2/_views``. ``generate`` and ``edit`` produce the same shape, so
7
+ both endpoints share this one view.
8
+
9
+ ``ImageResponse`` is the sole public element; nested pieces stay private.
10
+ """
11
+
12
+ from typing import Any
13
+
14
+ from pydantic import BaseModel, Field
15
+
16
+
17
+ class _Timings(BaseModel):
18
+ total_s: float = Field(
19
+ description="Wall-clock generation time in seconds (model run only)."
20
+ )
21
+
22
+
23
+ class ImageResponse(BaseModel):
24
+ """Capability-specific ``result`` for a succeeded flux2 generate/edit job."""
25
+
26
+ model: str = Field(
27
+ description=(
28
+ "Resolved model variant that produced the image "
29
+ "(klein-9b | klein-base-4b | klein-base-9b)."
30
+ )
31
+ )
32
+ prompt: str = Field(description="The prompt used for the run.")
33
+
34
+ file_id: str = Field(
35
+ description=(
36
+ "Files-API id of the produced image. Fetch metadata at "
37
+ "GET /v1/files/{id} or bytes at /download. This is also the artifact "
38
+ "returned as raw bytes by a single-artifact sync call."
39
+ )
40
+ )
41
+ image_bytes: int = Field(description="Size of the produced image in bytes.")
42
+
43
+ width: int = Field(description="Width in pixels of the produced image.")
44
+ height: int = Field(description="Height in pixels of the produced image.")
45
+
46
+ params: dict[str, Any] = Field(
47
+ description=(
48
+ "Resolved parameters actually used for the run (model, seed, steps, "
49
+ "guidance, quantize, scheduler, format, quality, loras, …), so the "
50
+ "result is reproducible."
51
+ )
52
+ )
53
+ timings: _Timings = Field(description="kiapi extension: server-side timing.")
@@ -0,0 +1,197 @@
1
+ """Image API (flux2): FLUX.2 generate/edit/train."""
2
+
3
+ from fastapi import APIRouter, Depends, HTTPException
4
+ from fastapi.responses import Response
5
+
6
+ from kiapi.api import (
7
+ REQUIRE_AUTH,
8
+ build_job_responses,
9
+ build_train_responses,
10
+ get_accept,
11
+ get_ctx,
12
+ get_worker,
13
+ register_capability_endpoints,
14
+ submit_and_maybe_wait,
15
+ )
16
+ from kiapi.capabilities.flux2 import (
17
+ EditRequest,
18
+ GenerateRequest,
19
+ TrainRequest,
20
+ ValidationError,
21
+ handle_edit,
22
+ handle_generate,
23
+ handle_train,
24
+ settings_manager,
25
+ validate_edit,
26
+ validate_generate,
27
+ )
28
+ from kiapi.core.app import AppContext
29
+ from kiapi.core.file import FileIDRef
30
+ from kiapi.core.model import UnknownModelError, model_registry
31
+ from kiapi.core.worker import Worker
32
+
33
+ from ._views.image_response import ImageResponse
34
+
35
+ router = APIRouter(dependencies=REQUIRE_AUTH)
36
+
37
+
38
+ @router.post(
39
+ "/v1/image/flux2/generate",
40
+ responses=build_job_responses(
41
+ "image/png", "image/jpeg", "image/webp", result_model=ImageResponse
42
+ ),
43
+ )
44
+ async def generate_flux2_endpoint(
45
+ req: GenerateRequest,
46
+ accept: str | None = Depends(get_accept),
47
+ ctx: AppContext = Depends(get_ctx),
48
+ worker: Worker = Depends(get_worker),
49
+ ) -> Response:
50
+ """Generate an image from a text prompt (FLUX.2 Klein, text-to-image / img2img).
51
+
52
+ Plain text-to-image by default; supply `init_image` (+ optional
53
+ `image_strength`) to run img2img instead — use `/v1/image/flux2/edit` for
54
+ multi-reference editing. The same endpoint serves both `sync` and `async` via
55
+ `mode`. Variant defaults differ: `klein-9b` (default) is distilled and fast
56
+ (few steps, unquantized); `klein-base-4b` / `klein-base-9b` are slower base
57
+ variants (more steps, q8).
58
+
59
+ Sync content negotiation: a single image is produced, so unless the client
60
+ asks for JSON the raw image bytes are returned with `X-Kiapi-File-Id` /
61
+ `X-Kiapi-Job-Id` headers — `curl -o out.png` just works. With
62
+ `Accept: application/json` (or async) the Job JSON is returned, whose
63
+ `result` follows ImageResponse.
64
+
65
+ Any `loras` or a `quantize` differing from the resident model runs a one-off
66
+ transient model (slower, not reused). Async returns 202 immediately; poll
67
+ GET /v1/jobs/{job_id} and fetch the artifact via GET /v1/files/{file_id}.
68
+ """
69
+ try:
70
+ spec = model_registry.resolve("flux2", req.model)
71
+ except UnknownModelError as exc:
72
+ raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
73
+ try:
74
+ validate_generate(req, variant=spec.name)
75
+ except ValidationError as exc:
76
+ raise HTTPException(status_code=422, detail=str(exc)) # noqa: B904
77
+
78
+ def thunk(): # type: ignore
79
+ return handle_generate(ctx, req)
80
+
81
+ return await submit_and_maybe_wait(
82
+ ctx,
83
+ worker,
84
+ type="flux2",
85
+ params=req.gen_params() | {"model": spec.name, "mode": req.mode},
86
+ thunk=thunk,
87
+ mode=req.mode,
88
+ accept=accept,
89
+ )
90
+
91
+
92
+ @router.post(
93
+ "/v1/image/flux2/edit",
94
+ responses=build_job_responses(
95
+ "image/png", "image/jpeg", "image/webp", result_model=ImageResponse
96
+ ),
97
+ )
98
+ async def edit_flux2_endpoint(
99
+ req: EditRequest,
100
+ accept: str | None = Depends(get_accept),
101
+ ctx: AppContext = Depends(get_ctx),
102
+ worker: Worker = Depends(get_worker),
103
+ ) -> Response:
104
+ """Edit / combine one or more reference images with a prompt (FLUX.2 Klein).
105
+
106
+ Takes a list of `images` (FileRefs, multi-reference editing) plus a `prompt`;
107
+ `image_strength` controls how much of the input is preserved (lower = closer
108
+ to input). For plain image-to-image from a single seed image, use `init_image`
109
+ on `/v1/image/flux2/generate` instead. The same endpoint serves both `sync`
110
+ and `async` via `mode`.
111
+
112
+ Sync content negotiation, transient-model behavior (`loras` / `quantize`
113
+ override), and the ImageResponse `result` shape match
114
+ `/v1/image/flux2/generate`.
115
+ """
116
+ try:
117
+ spec = model_registry.resolve("flux2", req.model)
118
+ except UnknownModelError as exc:
119
+ raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
120
+ try:
121
+ validate_edit(req, variant=spec.name)
122
+ except ValidationError as exc:
123
+ raise HTTPException(status_code=422, detail=str(exc)) # noqa: B904
124
+
125
+ def thunk(): # type: ignore
126
+ return handle_edit(ctx, req)
127
+
128
+ return await submit_and_maybe_wait(
129
+ ctx,
130
+ worker,
131
+ type="flux2-edit",
132
+ params=req.gen_params() | {"model": spec.name, "mode": req.mode},
133
+ thunk=thunk,
134
+ mode=req.mode,
135
+ accept=accept,
136
+ )
137
+
138
+
139
+ @router.post("/v1/image/flux2/train", responses=build_train_responses())
140
+ async def train_flux2_endpoint(
141
+ req: TrainRequest,
142
+ ctx: AppContext = Depends(get_ctx),
143
+ worker: Worker = Depends(get_worker),
144
+ ) -> Response:
145
+ """Train a LoRA adapter on an image dataset (FLUX.2 Klein base, always async).
146
+
147
+ Long-running, so this endpoint is always async: it returns 202 with a
148
+ job_id — poll GET /v1/jobs/{job_id}. Only the base variants
149
+ (`klein-base-4b` default, `klein-base-9b`) are trainable. `training_mode`
150
+ selects the dataset layout: `text` uses captioned images (same-stem `.txt`),
151
+ `edit` uses `*_in.*` / `*_out.*` pairs with `*_in.txt` prompts; the `dataset`
152
+ is a Files-API ZIP. On success the job's `result` holds `adapter_file_id`
153
+ (the trained `.safetensors`, also the artifact), `adapter_bytes`,
154
+ `training_mode`, the resolved `config`, `lora_targets`, `checkpoint`, and
155
+ `timings`; the adapter can then be passed back via `loras` on generate/edit.
156
+ """
157
+ settings = settings_manager.get_settings()
158
+
159
+ try:
160
+ spec = model_registry.resolve(
161
+ "flux2", req.model or settings.train_default_model
162
+ )
163
+ except UnknownModelError as exc:
164
+ raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
165
+ if "base" not in spec.name:
166
+ raise HTTPException(
167
+ status_code=400,
168
+ detail="Flux2 training requires klein-base-4b or klein-base-9b",
169
+ )
170
+ if (
171
+ isinstance(req.dataset, FileIDRef)
172
+ and ctx.file_store.get(req.dataset.file_id) is None
173
+ ):
174
+ raise HTTPException(
175
+ status_code=400, detail=f"unknown dataset file_id {req.dataset.file_id!r}"
176
+ )
177
+
178
+ def thunk(): # type: ignore
179
+ return handle_train(ctx, req)
180
+
181
+ return await submit_and_maybe_wait(
182
+ ctx,
183
+ worker,
184
+ type="flux2-train",
185
+ params={
186
+ "model": spec.name,
187
+ "dataset": req.dataset.model_dump(mode="json"),
188
+ "training_mode": req.training_mode,
189
+ "num_epochs": req.num_epochs,
190
+ "lora_rank": req.lora_rank,
191
+ },
192
+ thunk=thunk,
193
+ mode="async",
194
+ )
195
+
196
+
197
+ register_capability_endpoints(router, name="flux2", base_path="/v1/image/flux2")
@@ -0,0 +1,55 @@
1
+ """``/v1/image/ideogram4/generate`` result payload (the Job ``result`` shape).
2
+
3
+ Mirrors the dict returned by ``capabilities/ideogram4/_models/ideogram4._store_image``
4
+ so the produced image result is self-describing in OpenAPI. It is an output-side
5
+ projection of the model result (not a model-coupled view), so it lives under
6
+ ``api/image/ideogram4/_views``.
7
+
8
+ ``ImageResponse`` is the sole public element; nested pieces stay private.
9
+ """
10
+
11
+ from typing import Any
12
+
13
+ from pydantic import BaseModel, Field
14
+
15
+
16
+ class _Timings(BaseModel):
17
+ total_s: float = Field(
18
+ description="Wall-clock generation time in seconds (model run only)."
19
+ )
20
+
21
+
22
+ class ImageResponse(BaseModel):
23
+ """Capability-specific ``result`` for a succeeded ideogram4 generate job."""
24
+
25
+ model: str = Field(description="Resolved model variant that produced the image.")
26
+ prompt: str | dict[str, Any] = Field(
27
+ description="The prompt used for the run (plain text or JSON caption)."
28
+ )
29
+
30
+ file_id: str = Field(
31
+ description=(
32
+ "Files-API id of the produced image. Fetch metadata at "
33
+ "GET /v1/files/{id} or bytes at /download. This is also the artifact "
34
+ "returned as raw bytes by a single-artifact sync call."
35
+ )
36
+ )
37
+ image_bytes: int = Field(description="Size of the produced image in bytes.")
38
+
39
+ width: int = Field(description="Width in pixels of the produced image.")
40
+ height: int = Field(description="Height in pixels of the produced image.")
41
+
42
+ params: dict[str, Any] = Field(
43
+ description=(
44
+ "Resolved parameters actually used for the run (model, prompt, preset, "
45
+ "seed, width, height, quantize, format, quality, …), so the result is "
46
+ "reproducible."
47
+ )
48
+ )
49
+ safety_filter_note: str = Field(
50
+ description=(
51
+ "Reminder that Ideogram 4 may return an 'Image blocked by safety filter' "
52
+ "image, which kiapi stores as the artifact rather than raising an error."
53
+ )
54
+ )
55
+ timings: _Timings = Field(description="kiapi extension: server-side timing.")