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.
- kiapi/__init__.py +3 -0
- kiapi/__main__.py +4 -0
- kiapi/api/__init__.py +26 -0
- kiapi/api/_constants/require_auth.py +14 -0
- kiapi/api/_helpers/build_job_responses.py +73 -0
- kiapi/api/_helpers/build_openapi.py +55 -0
- kiapi/api/_helpers/build_train_responses.py +21 -0
- kiapi/api/_helpers/get_accept.py +20 -0
- kiapi/api/_helpers/get_ctx.py +7 -0
- kiapi/api/_helpers/get_worker.py +7 -0
- kiapi/api/_helpers/register_capability_endpoints.py +70 -0
- kiapi/api/_helpers/submit_and_maybe_wait.py +113 -0
- kiapi/api/_settings.py +50 -0
- kiapi/api/_views/async_job_response.py +21 -0
- kiapi/api/_views/capability_model_spec.py +49 -0
- kiapi/api/app.py +150 -0
- kiapi/api/audio/acestep/_views/extract_response.py +57 -0
- kiapi/api/audio/acestep/_views/track_response.py +57 -0
- kiapi/api/audio/acestep/router.py +190 -0
- kiapi/api/audio/audiogen/_views/audio_response.py +46 -0
- kiapi/api/audio/audiogen/router.py +77 -0
- kiapi/api/chat/_views/chat_completion_response.py +71 -0
- kiapi/api/chat/router.py +253 -0
- kiapi/api/embedding/_views/embedding_response.py +35 -0
- kiapi/api/embedding/router.py +82 -0
- kiapi/api/files/_operations/get_file.py +14 -0
- kiapi/api/files/_operations/get_file_id.py +18 -0
- kiapi/api/files/_views/file_delete_response.py +14 -0
- kiapi/api/files/_views/file_list_response.py +15 -0
- kiapi/api/files/router.py +105 -0
- kiapi/api/health/_views/health_response.py +26 -0
- kiapi/api/health/router.py +28 -0
- kiapi/api/image/depthpro/_views/estimate_response.py +70 -0
- kiapi/api/image/depthpro/router.py +81 -0
- kiapi/api/image/ernie/_views/image_response.py +50 -0
- kiapi/api/image/ernie/router.py +181 -0
- kiapi/api/image/flux2/_views/image_response.py +53 -0
- kiapi/api/image/flux2/router.py +197 -0
- kiapi/api/image/ideogram4/_views/image_response.py +55 -0
- kiapi/api/image/ideogram4/router.py +87 -0
- kiapi/api/image/qwen/_views/image_response.py +47 -0
- kiapi/api/image/qwen/router.py +141 -0
- kiapi/api/image/seedvr2/_views/image_response.py +50 -0
- kiapi/api/image/seedvr2/router.py +83 -0
- kiapi/api/image/zimage/_views/image_response.py +49 -0
- kiapi/api/image/zimage/router.py +131 -0
- kiapi/api/jobs/_operations/get_job_id.py +18 -0
- kiapi/api/jobs/_views/job_delete_response.py +19 -0
- kiapi/api/jobs/_views/job_list_response.py +15 -0
- kiapi/api/jobs/router.py +62 -0
- kiapi/api/models/_schemas/openai_model_spec.py +26 -0
- kiapi/api/models/_views/model_list_response.py +15 -0
- kiapi/api/models/router.py +29 -0
- kiapi/api/video/ltx2/_views/__init__.py +1 -0
- kiapi/api/video/ltx2/_views/video_response.py +59 -0
- kiapi/api/video/ltx2/router.py +89 -0
- kiapi/api/web/_views/__init__.py +7 -0
- kiapi/api/web/_views/fetch_api_request.py +26 -0
- kiapi/api/web/_views/fetch_error_response.py +25 -0
- kiapi/api/web/router.py +302 -0
- kiapi/capabilities/__init__.py +24 -0
- kiapi/capabilities/_exceptions/CapabilityError.py +2 -0
- kiapi/capabilities/_exceptions/ValidationError.py +2 -0
- kiapi/capabilities/_helpers/attach_mflux_progress.py +50 -0
- kiapi/capabilities/_helpers/get_file_path.py +20 -0
- kiapi/capabilities/_helpers/resolve_file_ref.py +16 -0
- kiapi/capabilities/acestep/README.ja.md +174 -0
- kiapi/capabilities/acestep/README.md +167 -0
- kiapi/capabilities/acestep/__init__.py +37 -0
- kiapi/capabilities/acestep/_constants/description.py +122 -0
- kiapi/capabilities/acestep/_exceptions/ace_step_engine_error.py +2 -0
- kiapi/capabilities/acestep/_helpers/register.py +96 -0
- kiapi/capabilities/acestep/_models/acestep.py +105 -0
- kiapi/capabilities/acestep/_operations/handle_cover.py +23 -0
- kiapi/capabilities/acestep/_operations/handle_extract.py +38 -0
- kiapi/capabilities/acestep/_operations/handle_generate.py +18 -0
- kiapi/capabilities/acestep/_operations/handle_repaint.py +25 -0
- kiapi/capabilities/acestep/_operations/resolve_ace_step_paths.py +30 -0
- kiapi/capabilities/acestep/_operations/resolve_cover_params.py +21 -0
- kiapi/capabilities/acestep/_operations/resolve_engine.py +10 -0
- kiapi/capabilities/acestep/_operations/resolve_extract_params.py +24 -0
- kiapi/capabilities/acestep/_operations/resolve_generate_params.py +18 -0
- kiapi/capabilities/acestep/_operations/resolve_repaint_params.py +22 -0
- kiapi/capabilities/acestep/_schemas/ace_step_paths.py +29 -0
- kiapi/capabilities/acestep/_services/ace_step_engine.py +143 -0
- kiapi/capabilities/acestep/_settings.py +82 -0
- kiapi/capabilities/acestep/_views/ace_step_base.py +61 -0
- kiapi/capabilities/acestep/_views/cover_params.py +26 -0
- kiapi/capabilities/acestep/_views/cover_request.py +49 -0
- kiapi/capabilities/acestep/_views/extract_params.py +24 -0
- kiapi/capabilities/acestep/_views/extract_request.py +33 -0
- kiapi/capabilities/acestep/_views/generate_params.py +25 -0
- kiapi/capabilities/acestep/_views/generate_request.py +54 -0
- kiapi/capabilities/acestep/_views/repaint_params.py +27 -0
- kiapi/capabilities/acestep/_views/repaint_request.py +51 -0
- kiapi/capabilities/acestep/_views/track_params.py +7 -0
- kiapi/capabilities/acestep/worker_subprocess.py +247 -0
- kiapi/capabilities/audiogen/README.ja.md +49 -0
- kiapi/capabilities/audiogen/README.md +48 -0
- kiapi/capabilities/audiogen/__init__.py +25 -0
- kiapi/capabilities/audiogen/_constants/description.py +60 -0
- kiapi/capabilities/audiogen/_helpers/attach_audiogen_progress.py +27 -0
- kiapi/capabilities/audiogen/_helpers/register.py +42 -0
- kiapi/capabilities/audiogen/_helpers/validate_generate.py +14 -0
- kiapi/capabilities/audiogen/_models/audiogen.py +98 -0
- kiapi/capabilities/audiogen/_operations/handle_generate.py +27 -0
- kiapi/capabilities/audiogen/_operations/resolve_generate_params.py +25 -0
- kiapi/capabilities/audiogen/_settings.py +34 -0
- kiapi/capabilities/audiogen/_views/generate_params.py +14 -0
- kiapi/capabilities/audiogen/_views/generate_request.py +96 -0
- kiapi/capabilities/chat/README.ja.md +822 -0
- kiapi/capabilities/chat/README.md +806 -0
- kiapi/capabilities/chat/__init__.py +25 -0
- kiapi/capabilities/chat/_constants/description.py +163 -0
- kiapi/capabilities/chat/_helpers/register.py +67 -0
- kiapi/capabilities/chat/_models/qwen3_5.py +183 -0
- kiapi/capabilities/chat/_models/qwen3_omni.py +242 -0
- kiapi/capabilities/chat/_operations/apply_template.py +74 -0
- kiapi/capabilities/chat/_operations/completed_hermes_tool_call_text.py +9 -0
- kiapi/capabilities/chat/_operations/emit_streaming_response.py +297 -0
- kiapi/capabilities/chat/_operations/ensure_streaming_detokenizer_compat.py +49 -0
- kiapi/capabilities/chat/_operations/format_response.py +72 -0
- kiapi/capabilities/chat/_operations/handle_chat.py +25 -0
- kiapi/capabilities/chat/_operations/parse_hermes_tool_calls.py +63 -0
- kiapi/capabilities/chat/_operations/parse_json_tool_calls.py +66 -0
- kiapi/capabilities/chat/_operations/parse_messages.py +326 -0
- kiapi/capabilities/chat/_operations/resolve_chat_params.py +50 -0
- kiapi/capabilities/chat/_operations/stream_text_from_tokens.py +32 -0
- kiapi/capabilities/chat/_operations/strip_tool_calls.py +15 -0
- kiapi/capabilities/chat/_settings.py +74 -0
- kiapi/capabilities/chat/_utils/apply_parallel_tool_call_policy.py +17 -0
- kiapi/capabilities/chat/_utils/apply_seed.py +8 -0
- kiapi/capabilities/chat/_utils/load_audio_mono.py +31 -0
- kiapi/capabilities/chat/_utils/load_mlx_vlm.py +12 -0
- kiapi/capabilities/chat/_utils/warmup_params.py +26 -0
- kiapi/capabilities/chat/_views/chat_params.py +34 -0
- kiapi/capabilities/chat/_views/chat_request.py +153 -0
- kiapi/capabilities/depthpro/README.ja.md +131 -0
- kiapi/capabilities/depthpro/README.md +124 -0
- kiapi/capabilities/depthpro/__init__.py +23 -0
- kiapi/capabilities/depthpro/_constants/description.py +39 -0
- kiapi/capabilities/depthpro/_helpers/register.py +46 -0
- kiapi/capabilities/depthpro/_helpers/validate_estimate.py +32 -0
- kiapi/capabilities/depthpro/_models/depthpro.py +144 -0
- kiapi/capabilities/depthpro/_operations/handle_estimate.py +50 -0
- kiapi/capabilities/depthpro/_operations/is_quantize_override.py +12 -0
- kiapi/capabilities/depthpro/_operations/resolve_estimate_params.py +24 -0
- kiapi/capabilities/depthpro/_settings.py +46 -0
- kiapi/capabilities/depthpro/_views/estimate_params.py +21 -0
- kiapi/capabilities/depthpro/_views/estimate_request.py +63 -0
- kiapi/capabilities/embedding/README.ja.md +137 -0
- kiapi/capabilities/embedding/README.md +128 -0
- kiapi/capabilities/embedding/__init__.py +24 -0
- kiapi/capabilities/embedding/_constants/description.py +47 -0
- kiapi/capabilities/embedding/_helpers/register.py +66 -0
- kiapi/capabilities/embedding/_models/qwen3_text.py +53 -0
- kiapi/capabilities/embedding/_models/qwen3_vl.py +97 -0
- kiapi/capabilities/embedding/_operations/format_response.py +24 -0
- kiapi/capabilities/embedding/_operations/handle_embed.py +24 -0
- kiapi/capabilities/embedding/_operations/parse_inputs.py +108 -0
- kiapi/capabilities/embedding/_operations/resolve_embed_params.py +18 -0
- kiapi/capabilities/embedding/_settings.py +27 -0
- kiapi/capabilities/embedding/_utils/to_vector.py +20 -0
- kiapi/capabilities/embedding/_views/embed_params.py +17 -0
- kiapi/capabilities/embedding/_views/embed_request.py +39 -0
- kiapi/capabilities/ernie/README.ja.md +242 -0
- kiapi/capabilities/ernie/README.md +223 -0
- kiapi/capabilities/ernie/__init__.py +34 -0
- kiapi/capabilities/ernie/_constants/description.py +71 -0
- kiapi/capabilities/ernie/_helpers/register.py +60 -0
- kiapi/capabilities/ernie/_helpers/validate_edit.py +19 -0
- kiapi/capabilities/ernie/_helpers/validate_generate.py +8 -0
- kiapi/capabilities/ernie/_models/ernie.py +356 -0
- kiapi/capabilities/ernie/_operations/handle_edit.py +39 -0
- kiapi/capabilities/ernie/_operations/handle_generate.py +38 -0
- kiapi/capabilities/ernie/_operations/handle_train.py +77 -0
- kiapi/capabilities/ernie/_operations/is_quantize_override.py +16 -0
- kiapi/capabilities/ernie/_operations/resolve_edit_params.py +44 -0
- kiapi/capabilities/ernie/_operations/resolve_generate_params.py +40 -0
- kiapi/capabilities/ernie/_operations/resolve_lora_params.py +23 -0
- kiapi/capabilities/ernie/_operations/resolve_train_params.py +43 -0
- kiapi/capabilities/ernie/_operations/validate_common.py +33 -0
- kiapi/capabilities/ernie/_schemas/lora_ref.py +27 -0
- kiapi/capabilities/ernie/_settings.py +151 -0
- kiapi/capabilities/ernie/_views/edit_params.py +36 -0
- kiapi/capabilities/ernie/_views/edit_request.py +142 -0
- kiapi/capabilities/ernie/_views/generate_params.py +32 -0
- kiapi/capabilities/ernie/_views/generate_request.py +127 -0
- kiapi/capabilities/ernie/_views/train_params.py +28 -0
- kiapi/capabilities/ernie/_views/train_request.py +96 -0
- kiapi/capabilities/flux2/README.ja.md +260 -0
- kiapi/capabilities/flux2/README.md +241 -0
- kiapi/capabilities/flux2/__init__.py +36 -0
- kiapi/capabilities/flux2/_constants/description.py +81 -0
- kiapi/capabilities/flux2/_helpers/register.py +98 -0
- kiapi/capabilities/flux2/_helpers/validate_edit.py +12 -0
- kiapi/capabilities/flux2/_helpers/validate_generate.py +8 -0
- kiapi/capabilities/flux2/_models/flux2.py +396 -0
- kiapi/capabilities/flux2/_operations/handle_edit.py +44 -0
- kiapi/capabilities/flux2/_operations/handle_generate.py +46 -0
- kiapi/capabilities/flux2/_operations/handle_train.py +105 -0
- kiapi/capabilities/flux2/_operations/is_quantize_override.py +16 -0
- kiapi/capabilities/flux2/_operations/resolve_edit_params.py +43 -0
- kiapi/capabilities/flux2/_operations/resolve_generate_params.py +44 -0
- kiapi/capabilities/flux2/_operations/resolve_lora_params.py +23 -0
- kiapi/capabilities/flux2/_operations/resolve_train_params.py +42 -0
- kiapi/capabilities/flux2/_operations/role_spec.py +13 -0
- kiapi/capabilities/flux2/_operations/split_repo.py +11 -0
- kiapi/capabilities/flux2/_operations/validate_common.py +35 -0
- kiapi/capabilities/flux2/_schemas/lora_ref.py +27 -0
- kiapi/capabilities/flux2/_settings.py +181 -0
- kiapi/capabilities/flux2/_views/edit_params.py +36 -0
- kiapi/capabilities/flux2/_views/edit_request.py +145 -0
- kiapi/capabilities/flux2/_views/generate_params.py +36 -0
- kiapi/capabilities/flux2/_views/generate_request.py +150 -0
- kiapi/capabilities/flux2/_views/train_params.py +32 -0
- kiapi/capabilities/flux2/_views/train_request.py +102 -0
- kiapi/capabilities/ideogram4/README.ja.md +230 -0
- kiapi/capabilities/ideogram4/README.md +219 -0
- kiapi/capabilities/ideogram4/__init__.py +24 -0
- kiapi/capabilities/ideogram4/_constants/description.py +65 -0
- kiapi/capabilities/ideogram4/_helpers/register.py +44 -0
- kiapi/capabilities/ideogram4/_helpers/validate_generate.py +31 -0
- kiapi/capabilities/ideogram4/_models/ideogram4.py +120 -0
- kiapi/capabilities/ideogram4/_operations/handle_generate.py +30 -0
- kiapi/capabilities/ideogram4/_operations/is_quantize_override.py +12 -0
- kiapi/capabilities/ideogram4/_operations/resolve_generate_params.py +30 -0
- kiapi/capabilities/ideogram4/_settings.py +89 -0
- kiapi/capabilities/ideogram4/_views/generate_params.py +27 -0
- kiapi/capabilities/ideogram4/_views/generate_request.py +118 -0
- kiapi/capabilities/ltx2/README.ja.md +287 -0
- kiapi/capabilities/ltx2/README.md +274 -0
- kiapi/capabilities/ltx2/__init__.py +26 -0
- kiapi/capabilities/ltx2/_constants/description.py +81 -0
- kiapi/capabilities/ltx2/_helpers/register.py +58 -0
- kiapi/capabilities/ltx2/_helpers/validate_generate.py +42 -0
- kiapi/capabilities/ltx2/_models/ltx2.py +106 -0
- kiapi/capabilities/ltx2/_operations/detect_mode.py +19 -0
- kiapi/capabilities/ltx2/_operations/handle_generate.py +52 -0
- kiapi/capabilities/ltx2/_operations/resolve_generate_params.py +31 -0
- kiapi/capabilities/ltx2/_settings.py +93 -0
- kiapi/capabilities/ltx2/_views/generate_params.py +34 -0
- kiapi/capabilities/ltx2/_views/generate_request.py +151 -0
- kiapi/capabilities/qwen/README.ja.md +251 -0
- kiapi/capabilities/qwen/README.md +235 -0
- kiapi/capabilities/qwen/__init__.py +30 -0
- kiapi/capabilities/qwen/_constants/description.py +53 -0
- kiapi/capabilities/qwen/_helpers/register.py +60 -0
- kiapi/capabilities/qwen/_helpers/validate_edit.py +12 -0
- kiapi/capabilities/qwen/_helpers/validate_generate.py +12 -0
- kiapi/capabilities/qwen/_models/qwen.py +224 -0
- kiapi/capabilities/qwen/_operations/handle_edit.py +44 -0
- kiapi/capabilities/qwen/_operations/handle_generate.py +46 -0
- kiapi/capabilities/qwen/_operations/is_quantize_override.py +15 -0
- kiapi/capabilities/qwen/_operations/resolve_edit_params.py +35 -0
- kiapi/capabilities/qwen/_operations/resolve_generate_params.py +39 -0
- kiapi/capabilities/qwen/_operations/resolve_lora_params.py +23 -0
- kiapi/capabilities/qwen/_operations/validate_common.py +32 -0
- kiapi/capabilities/qwen/_schemas/lora_ref.py +27 -0
- kiapi/capabilities/qwen/_settings.py +107 -0
- kiapi/capabilities/qwen/_views/edit_params.py +36 -0
- kiapi/capabilities/qwen/_views/edit_request.py +138 -0
- kiapi/capabilities/qwen/_views/generate_params.py +37 -0
- kiapi/capabilities/qwen/_views/generate_request.py +149 -0
- kiapi/capabilities/seedvr2/README.ja.md +234 -0
- kiapi/capabilities/seedvr2/README.md +219 -0
- kiapi/capabilities/seedvr2/__init__.py +24 -0
- kiapi/capabilities/seedvr2/_constants/description.py +46 -0
- kiapi/capabilities/seedvr2/_helpers/register.py +60 -0
- kiapi/capabilities/seedvr2/_helpers/validate_upscale.py +52 -0
- kiapi/capabilities/seedvr2/_models/seedvr2.py +140 -0
- kiapi/capabilities/seedvr2/_operations/handle_upscale.py +42 -0
- kiapi/capabilities/seedvr2/_operations/is_quantize_override.py +12 -0
- kiapi/capabilities/seedvr2/_operations/resolve_upscale_params.py +30 -0
- kiapi/capabilities/seedvr2/_settings.py +74 -0
- kiapi/capabilities/seedvr2/_views/upscale_params.py +27 -0
- kiapi/capabilities/seedvr2/_views/upscale_request.py +94 -0
- kiapi/capabilities/web/README.ja.md +187 -0
- kiapi/capabilities/web/README.md +171 -0
- kiapi/capabilities/web/__init__.py +30 -0
- kiapi/capabilities/web/_constants/description.py +38 -0
- kiapi/capabilities/web/_exceptions/FetchError.py +24 -0
- kiapi/capabilities/web/_exceptions/SearchBackendError.py +11 -0
- kiapi/capabilities/web/_helpers/register.py +59 -0
- kiapi/capabilities/web/_models/crawl4ai.py +32 -0
- kiapi/capabilities/web/_models/searxng.py +44 -0
- kiapi/capabilities/web/_operations/handle_fetch.py +145 -0
- kiapi/capabilities/web/_operations/handle_search.py +56 -0
- kiapi/capabilities/web/_operations/resolve_fetch_params.py +19 -0
- kiapi/capabilities/web/_operations/resolve_search_params.py +34 -0
- kiapi/capabilities/web/_operations/resolve_searxng_config_dir.py +21 -0
- kiapi/capabilities/web/_services/__init__.py +1 -0
- kiapi/capabilities/web/_services/web_backend_process.py +144 -0
- kiapi/capabilities/web/_settings.py +138 -0
- kiapi/capabilities/web/_views/fetch_params.py +27 -0
- kiapi/capabilities/web/_views/fetch_request.py +29 -0
- kiapi/capabilities/web/_views/fetch_result.py +20 -0
- kiapi/capabilities/web/_views/search_params.py +43 -0
- kiapi/capabilities/web/_views/search_request.py +93 -0
- kiapi/capabilities/web/_views/search_response.py +49 -0
- kiapi/capabilities/web/resources/__init__.py +0 -0
- kiapi/capabilities/web/resources/searxng/__init__.py +0 -0
- kiapi/capabilities/web/resources/searxng/settings.yml +11 -0
- kiapi/capabilities/zimage/README.ja.md +249 -0
- kiapi/capabilities/zimage/README.md +231 -0
- kiapi/capabilities/zimage/__init__.py +34 -0
- kiapi/capabilities/zimage/_constants/description.py +73 -0
- kiapi/capabilities/zimage/_helpers/register.py +62 -0
- kiapi/capabilities/zimage/_helpers/validate_generate.py +37 -0
- kiapi/capabilities/zimage/_models/zimage.py +278 -0
- kiapi/capabilities/zimage/_operations/handle_generate.py +38 -0
- kiapi/capabilities/zimage/_operations/handle_train.py +78 -0
- kiapi/capabilities/zimage/_operations/is_quantize_override.py +11 -0
- kiapi/capabilities/zimage/_operations/resolve_generate_params.py +39 -0
- kiapi/capabilities/zimage/_operations/resolve_lora_params.py +23 -0
- kiapi/capabilities/zimage/_operations/resolve_train_params.py +38 -0
- kiapi/capabilities/zimage/_schemas/lora_ref.py +27 -0
- kiapi/capabilities/zimage/_settings.py +166 -0
- kiapi/capabilities/zimage/_views/generate_params.py +23 -0
- kiapi/capabilities/zimage/_views/generate_request.py +127 -0
- kiapi/capabilities/zimage/_views/train_params.py +22 -0
- kiapi/capabilities/zimage/_views/train_request.py +101 -0
- kiapi/cli/__init__.py +11 -0
- kiapi/cli/_helpers/dedupe_resources.py +12 -0
- kiapi/cli/_helpers/register_all_capabilities.py +36 -0
- kiapi/cli/_helpers/run_resources.py +24 -0
- kiapi/cli/_helpers/select_specs.py +67 -0
- kiapi/cli/activate/_operations/preflight_hf_access.py +129 -0
- kiapi/cli/activate/cli.py +37 -0
- kiapi/cli/check/_helpers/check_audio_acestep_turbo.py +22 -0
- kiapi/cli/check/_helpers/check_audio_acestep_xl_base.py +22 -0
- kiapi/cli/check/_helpers/check_audio_audiogen_medium.py +24 -0
- kiapi/cli/check/_helpers/check_chat_chat_qwen3_6_27b.py +19 -0
- kiapi/cli/check/_helpers/check_chat_chat_qwen3_omni.py +19 -0
- kiapi/cli/check/_helpers/check_embedding_embedding_qwen3_embedding_8b.py +14 -0
- kiapi/cli/check/_helpers/check_embedding_embedding_qwen3_vl_embedding_2b.py +19 -0
- kiapi/cli/check/_helpers/check_image_depthpro_base.py +21 -0
- kiapi/cli/check/_helpers/check_image_ernie_base.py +23 -0
- kiapi/cli/check/_helpers/check_image_ernie_turbo.py +23 -0
- kiapi/cli/check/_helpers/check_image_flux2_klein_9b.py +23 -0
- kiapi/cli/check/_helpers/check_image_flux2_klein_base_4b.py +23 -0
- kiapi/cli/check/_helpers/check_image_flux2_klein_base_9b.py +23 -0
- kiapi/cli/check/_helpers/check_image_ideogram4_fp8.py +23 -0
- kiapi/cli/check/_helpers/check_image_qwen_edit_2509.py +27 -0
- kiapi/cli/check/_helpers/check_image_qwen_image.py +23 -0
- kiapi/cli/check/_helpers/check_image_seedvr2_3b.py +23 -0
- kiapi/cli/check/_helpers/check_image_seedvr2_7b.py +23 -0
- kiapi/cli/check/_helpers/check_image_zimage_base.py +23 -0
- kiapi/cli/check/_helpers/check_image_zimage_turbo.py +23 -0
- kiapi/cli/check/_helpers/check_video_ltx2_distilled.py +26 -0
- kiapi/cli/check/_helpers/check_web_web_fetch.py +14 -0
- kiapi/cli/check/_helpers/check_web_web_search.py +14 -0
- kiapi/cli/check/_operations/build_check_result.py +20 -0
- kiapi/cli/check/_operations/check_context.py +10 -0
- kiapi/cli/check/_operations/create_sample_image.py +46 -0
- kiapi/cli/check/_schemas/check_result.py +12 -0
- kiapi/cli/check/cli.py +89 -0
- kiapi/cli/cli.py +29 -0
- kiapi/cli/config/cli.py +17 -0
- kiapi/cli/config/edit/cli.py +32 -0
- kiapi/cli/config/init/cli.py +33 -0
- kiapi/cli/config/show/cli.py +13 -0
- kiapi/cli/config/template/cli.py +36 -0
- kiapi/cli/deactivate/cli.py +49 -0
- kiapi/cli/run/asgi.py +16 -0
- kiapi/cli/run/cli.py +59 -0
- kiapi/cli/service/__init__.py +5 -0
- kiapi/cli/service/_services/service_manager.py +107 -0
- kiapi/cli/service/cli.py +19 -0
- kiapi/cli/service/install/cli.py +17 -0
- kiapi/cli/service/start/cli.py +22 -0
- kiapi/cli/service/status/cli.py +81 -0
- kiapi/cli/service/stop/cli.py +19 -0
- kiapi/cli/service/uninstall/cli.py +16 -0
- kiapi/cli/status/cli.py +226 -0
- kiapi/core/app/__init__.py +16 -0
- kiapi/core/app/_schemas/app_context.py +28 -0
- kiapi/core/app/_services/user_directory.py +59 -0
- kiapi/core/app/_settings.py +46 -0
- kiapi/core/capability/__init__.py +11 -0
- kiapi/core/capability/_schemas/capability_spec.py +17 -0
- kiapi/core/capability/_services/capability_spec_registry.py +21 -0
- kiapi/core/config/__init__.py +11 -0
- kiapi/core/config/_exceptions/user_config_error.py +2 -0
- kiapi/core/config/_helpers/get_user_settings_path.py +7 -0
- kiapi/core/config/_helpers/load_user_settings.py +54 -0
- kiapi/core/file/__init__.py +37 -0
- kiapi/core/file/_helpers/create_file_store.py +7 -0
- kiapi/core/file/_helpers/resolve_file_ref.py +90 -0
- kiapi/core/file/_schemas/file_data_url_ref.py +19 -0
- kiapi/core/file/_schemas/file_id_ref.py +16 -0
- kiapi/core/file/_schemas/file_record.py +46 -0
- kiapi/core/file/_schemas/file_url_ref.py +16 -0
- kiapi/core/file/_services/file_store.py +138 -0
- kiapi/core/file/_settings.py +22 -0
- kiapi/core/file/_types/file_id.py +2 -0
- kiapi/core/file/_types/file_ref.py +12 -0
- kiapi/core/file/_views/resolved_file_ref.py +16 -0
- kiapi/core/job/__init__.py +24 -0
- kiapi/core/job/_enums/job_status.py +9 -0
- kiapi/core/job/_helpers/creep_progress.py +123 -0
- kiapi/core/job/_models/job.py +121 -0
- kiapi/core/job/_services/job_store.py +33 -0
- kiapi/core/job/_services/progress_reporter.py +79 -0
- kiapi/core/job/_types/job_id.py +3 -0
- kiapi/core/job/_types/job_result.py +5 -0
- kiapi/core/job/_types/job_type.py +4 -0
- kiapi/core/logging/__init__.py +14 -0
- kiapi/core/logging/_helpers/get_log_level.py +8 -0
- kiapi/core/logging/_helpers/setup_logger.py +14 -0
- kiapi/core/logging/_settings.py +34 -0
- kiapi/core/logging/_types/log_level.py +3 -0
- kiapi/core/memory/__init__.py +21 -0
- kiapi/core/memory/_exceptions/memory_budget_error.py +2 -0
- kiapi/core/memory/_helpers/create_memory_manager.py +17 -0
- kiapi/core/memory/_operations/log_memory_limit.py +29 -0
- kiapi/core/memory/_operations/resolve_effective_memory_limit_gb.py +13 -0
- kiapi/core/memory/_operations/resolve_framework_strategy.py +42 -0
- kiapi/core/memory/_schemas/framework_strategy.py +14 -0
- kiapi/core/memory/_schemas/memory_stats.py +24 -0
- kiapi/core/memory/_schemas/resident_model.py +14 -0
- kiapi/core/memory/_schemas/resident_model_stats.py +49 -0
- kiapi/core/memory/_services/memory_manager.py +257 -0
- kiapi/core/memory/_settings.py +36 -0
- kiapi/core/memory/_types/framework_name.py +4 -0
- kiapi/core/memory/_types/resident_key.py +4 -0
- kiapi/core/model/__init__.py +36 -0
- kiapi/core/model/_exceptions/unknown_model_error.py +2 -0
- kiapi/core/model/_schemas/model_spec.py +145 -0
- kiapi/core/model/_services/model_registry.py +85 -0
- kiapi/core/model/_types/model_alias.py +2 -0
- kiapi/core/model/_types/model_domain.py +6 -0
- kiapi/core/model/_types/model_family.py +5 -0
- kiapi/core/model/_types/model_key.py +8 -0
- kiapi/core/model/_types/model_name.py +4 -0
- kiapi/core/model/_types/model_repo.py +3 -0
- kiapi/core/net/__init__.py +16 -0
- kiapi/core/net/_exceptions/unsafe_url_error.py +7 -0
- kiapi/core/net/_helpers/verify_public_url.py +68 -0
- kiapi/core/net/_settings.py +28 -0
- kiapi/core/setup/__init__.py +25 -0
- kiapi/core/setup/_exceptions/setup_required_error.py +2 -0
- kiapi/core/setup/_schemas/docker_image_resource.py +37 -0
- kiapi/core/setup/_schemas/hf_snapshot_resource.py +50 -0
- kiapi/core/setup/_schemas/local_path_resource.py +43 -0
- kiapi/core/setup/_schemas/python_package_resource.py +58 -0
- kiapi/core/setup/_schemas/python_venv_resource.py +63 -0
- kiapi/core/setup/_schemas/setup_status.py +7 -0
- kiapi/core/setup/_schemas/url_file_resource.py +43 -0
- kiapi/core/setup/_services/setup_manager.py +331 -0
- kiapi/core/setup/_types/setup_resource.py +21 -0
- kiapi/core/setup/_types/setup_target.py +11 -0
- kiapi/core/workdir/__init__.py +8 -0
- kiapi/core/workdir/_helpers/create_work_dir.py +11 -0
- kiapi/core/workdir/_settings.py +21 -0
- kiapi/core/worker/__init__.py +23 -0
- kiapi/core/worker/_helpers/create_worker.py +9 -0
- kiapi/core/worker/_services/worker.py +165 -0
- kiapi/core/worker/_settings.py +36 -0
- kiapi/core/worker/_types/job_thunk.py +6 -0
- kiapi-0.1.0.dist-info/METADATA +337 -0
- kiapi-0.1.0.dist-info/RECORD +465 -0
- kiapi-0.1.0.dist-info/WHEEL +4 -0
- kiapi-0.1.0.dist-info/entry_points.txt +2 -0
- kiapi-0.1.0.dist-info/licenses/LICENSE +21 -0
kiapi/api/app.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from contextlib import asynccontextmanager
|
|
4
|
+
|
|
5
|
+
from fastapi import FastAPI
|
|
6
|
+
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
|
|
7
|
+
from fastapi.responses import HTMLResponse
|
|
8
|
+
|
|
9
|
+
from kiapi.api import build_openapi
|
|
10
|
+
from kiapi.core.app import AppContext
|
|
11
|
+
from kiapi.core.capability import capability_spec_registry
|
|
12
|
+
from kiapi.core.logging import setup_logger
|
|
13
|
+
from kiapi.core.model import model_registry
|
|
14
|
+
from kiapi.core.worker import create_worker
|
|
15
|
+
|
|
16
|
+
from .audio.acestep.router import router as acestep_router
|
|
17
|
+
from .audio.audiogen.router import router as audiogen_router
|
|
18
|
+
from .chat.router import router as chat_router
|
|
19
|
+
from .embedding.router import router as embedding_router
|
|
20
|
+
from .files.router import router as files_router
|
|
21
|
+
from .health.router import router as health_router
|
|
22
|
+
from .image.depthpro.router import router as depthpro_router
|
|
23
|
+
from .image.ernie.router import router as ernie_router
|
|
24
|
+
from .image.flux2.router import router as flux2_router
|
|
25
|
+
from .image.ideogram4.router import router as ideogram4_router
|
|
26
|
+
from .image.qwen.router import router as qwen_router
|
|
27
|
+
from .image.seedvr2.router import router as seedvr2_router
|
|
28
|
+
from .image.zimage.router import router as zimage_router
|
|
29
|
+
from .jobs.router import router as jobs_router
|
|
30
|
+
from .models.router import router as models_router
|
|
31
|
+
from .video.ltx2.router import router as ltx2_router
|
|
32
|
+
from .web.router import router as web_router
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
COMMON_OPENAPI_PATHS = (
|
|
37
|
+
"/health",
|
|
38
|
+
"/v1/files",
|
|
39
|
+
"/v1/jobs",
|
|
40
|
+
)
|
|
41
|
+
CAPABILITY_DESCRIPTION_DOMAIN_ORDER = (
|
|
42
|
+
"chat",
|
|
43
|
+
"embedding",
|
|
44
|
+
"image",
|
|
45
|
+
"audio",
|
|
46
|
+
"video",
|
|
47
|
+
"web",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@asynccontextmanager
|
|
52
|
+
async def lifespan(app: FastAPI): # type: ignore
|
|
53
|
+
setup_logger()
|
|
54
|
+
|
|
55
|
+
if not model_registry.list_specs() or not capability_spec_registry.list_specs():
|
|
56
|
+
raise RuntimeError(
|
|
57
|
+
"kiapi capabilities are not registered. "
|
|
58
|
+
"Start the server with `kiapi run` instead of importing the ASGI app directly."
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
ctx = AppContext.create()
|
|
62
|
+
worker = create_worker(ctx)
|
|
63
|
+
|
|
64
|
+
app.state.ctx = ctx
|
|
65
|
+
app.state.worker = worker
|
|
66
|
+
|
|
67
|
+
worker.start()
|
|
68
|
+
|
|
69
|
+
asyncio.create_task(worker.warmup()) # noqa: RUF006
|
|
70
|
+
|
|
71
|
+
yield
|
|
72
|
+
|
|
73
|
+
await worker.stop()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
app = FastAPI(title="kiapi", lifespan=lifespan, docs_url=None, redoc_url=None)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def root_openapi() -> dict:
|
|
80
|
+
return build_openapi(
|
|
81
|
+
app,
|
|
82
|
+
title="kiapi Common API",
|
|
83
|
+
description=_root_openapi_description(),
|
|
84
|
+
path_prefixes=COMMON_OPENAPI_PATHS,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _root_openapi_description() -> str:
|
|
89
|
+
lines = [
|
|
90
|
+
"Common kiapi endpoints.",
|
|
91
|
+
"",
|
|
92
|
+
"Capability-specific docs:",
|
|
93
|
+
]
|
|
94
|
+
specs = capability_spec_registry.list_specs()
|
|
95
|
+
for domain in CAPABILITY_DESCRIPTION_DOMAIN_ORDER:
|
|
96
|
+
domain_specs = [spec for spec in specs if spec.domain == domain]
|
|
97
|
+
if not domain_specs:
|
|
98
|
+
continue
|
|
99
|
+
lines.append(f"- **{domain}**")
|
|
100
|
+
for spec in domain_specs:
|
|
101
|
+
lines.append(
|
|
102
|
+
f" - **{spec.title}** - {spec.summary} "
|
|
103
|
+
f"[Swagger UI]({spec.docs_path}), "
|
|
104
|
+
f"[ReDoc]({spec.redoc_path}), "
|
|
105
|
+
f"[OpenAPI JSON]({spec.openapi_path})"
|
|
106
|
+
)
|
|
107
|
+
for spec in specs:
|
|
108
|
+
if spec.domain in CAPABILITY_DESCRIPTION_DOMAIN_ORDER:
|
|
109
|
+
continue
|
|
110
|
+
if f"- **{spec.domain}**" not in lines:
|
|
111
|
+
lines.append(f"- **{spec.domain}**")
|
|
112
|
+
lines.append(
|
|
113
|
+
f" - **{spec.title}** - {spec.summary} "
|
|
114
|
+
f"[Swagger UI]({spec.docs_path}), "
|
|
115
|
+
f"[ReDoc]({spec.redoc_path}), "
|
|
116
|
+
f"[OpenAPI JSON]({spec.openapi_path})"
|
|
117
|
+
)
|
|
118
|
+
return "\n".join(lines)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
app.openapi = root_openapi # type: ignore[method-assign]
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@app.get("/docs", include_in_schema=False)
|
|
125
|
+
async def root_docs() -> HTMLResponse:
|
|
126
|
+
return get_swagger_ui_html(openapi_url="/openapi.json", title="kiapi Common API")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@app.get("/redoc", include_in_schema=False)
|
|
130
|
+
async def root_redoc() -> HTMLResponse:
|
|
131
|
+
return get_redoc_html(openapi_url="/openapi.json", title="kiapi Common API")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
app.include_router(health_router)
|
|
135
|
+
app.include_router(files_router)
|
|
136
|
+
app.include_router(jobs_router)
|
|
137
|
+
app.include_router(chat_router)
|
|
138
|
+
app.include_router(models_router)
|
|
139
|
+
app.include_router(embedding_router)
|
|
140
|
+
app.include_router(depthpro_router)
|
|
141
|
+
app.include_router(ernie_router)
|
|
142
|
+
app.include_router(flux2_router)
|
|
143
|
+
app.include_router(ideogram4_router)
|
|
144
|
+
app.include_router(qwen_router)
|
|
145
|
+
app.include_router(seedvr2_router)
|
|
146
|
+
app.include_router(zimage_router)
|
|
147
|
+
app.include_router(acestep_router)
|
|
148
|
+
app.include_router(audiogen_router)
|
|
149
|
+
app.include_router(ltx2_router)
|
|
150
|
+
app.include_router(web_router)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""``/v1/audio/acestep/extract`` result payload (the Job ``result`` shape).
|
|
2
|
+
|
|
3
|
+
Mirrors the dict returned by ``capabilities/acestep/_operations/handle_extract``:
|
|
4
|
+
one job runs source separation for every requested target and collects one stem
|
|
5
|
+
per target. It is an output-side projection of the model result (not a
|
|
6
|
+
model-coupled view), so it lives under ``api/audio/acestep/_views``.
|
|
7
|
+
|
|
8
|
+
``ExtractResponse`` 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 separation time in seconds for this stem."
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class _Stem(BaseModel):
|
|
23
|
+
target: str = Field(description="Stem name, e.g. vocals / drums / bass / other.")
|
|
24
|
+
model: str = Field(description="Resolved preset that produced the stem.")
|
|
25
|
+
src: str = Field(description="Files-API id of the source track.")
|
|
26
|
+
|
|
27
|
+
file_id: str = Field(
|
|
28
|
+
description=(
|
|
29
|
+
"Files-API id of this stem's WAV. Fetch metadata at GET /v1/files/{id} "
|
|
30
|
+
"or bytes at /download."
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
audio_bytes: int = Field(description="Size of the stem WAV in bytes.")
|
|
34
|
+
|
|
35
|
+
params: dict[str, Any] = Field(
|
|
36
|
+
description="Resolved parameters used to separate this stem."
|
|
37
|
+
)
|
|
38
|
+
timings: _Timings = Field(description="kiapi extension: server-side timing.")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ExtractResponse(BaseModel):
|
|
42
|
+
"""Capability-specific ``result`` for a succeeded extract job.
|
|
43
|
+
|
|
44
|
+
A single job produces one stem per requested target; ``artifacts`` lists the
|
|
45
|
+
same file_ids in ``stems`` order.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
task: str = Field(description="Always `extract` for this endpoint.")
|
|
49
|
+
source_file_id: str = Field(
|
|
50
|
+
description="Files-API id of the source track that was separated."
|
|
51
|
+
)
|
|
52
|
+
targets: list[str] = Field(
|
|
53
|
+
description="The requested stems, in the order they appear in `stems`."
|
|
54
|
+
)
|
|
55
|
+
stems: list[_Stem] = Field(
|
|
56
|
+
description="One produced stem per target; each references its own WAV file_id."
|
|
57
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""``/v1/audio/acestep/{generate,cover,repaint}`` result payload (the Job ``result``).
|
|
2
|
+
|
|
3
|
+
Mirrors the dict returned by ``capabilities/acestep/_models/acestep.generate_track``
|
|
4
|
+
so the produced track is self-describing in OpenAPI. It is an output-side projection
|
|
5
|
+
of the model result (not a model-coupled view), so it lives under
|
|
6
|
+
``api/audio/acestep/_views``. The same single-track shape is returned by generate,
|
|
7
|
+
cover, and repaint; ``src`` is present only for cover/repaint.
|
|
8
|
+
|
|
9
|
+
``TrackResponse`` 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 (subprocess run only)."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TrackResponse(BaseModel):
|
|
24
|
+
"""Capability-specific ``result`` for a succeeded generate/cover/repaint job."""
|
|
25
|
+
|
|
26
|
+
task: str = Field(
|
|
27
|
+
description="Operation that produced the track: text2music, cover, or repaint."
|
|
28
|
+
)
|
|
29
|
+
model: str = Field(
|
|
30
|
+
description="Resolved preset that produced the track (xl-base or turbo)."
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
file_id: str = Field(
|
|
34
|
+
description=(
|
|
35
|
+
"Files-API id of the produced WAV. Fetch metadata at GET /v1/files/{id} "
|
|
36
|
+
"or bytes at /download. This is also the artifact returned as raw bytes "
|
|
37
|
+
"by a single-artifact sync call."
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
audio_bytes: int = Field(description="Size of the produced WAV in bytes.")
|
|
41
|
+
|
|
42
|
+
src: str | None = Field(
|
|
43
|
+
default=None,
|
|
44
|
+
description=(
|
|
45
|
+
"Files-API id of the source track. Present for cover/repaint; null for "
|
|
46
|
+
"generate (which takes no source)."
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
params: dict[str, Any] = Field(
|
|
51
|
+
description=(
|
|
52
|
+
"Resolved parameters actually used for the run (prompt, lyrics, duration, "
|
|
53
|
+
"seed, inference_steps, guidance_scale, shift, …), so the result is "
|
|
54
|
+
"reproducible."
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
timings: _Timings = Field(description="kiapi extension: server-side timing.")
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""Music API (acestep): ``POST /v1/audio/acestep/{generate,cover,repaint,extract}``.
|
|
2
|
+
|
|
3
|
+
Each endpoint is sync or async via ``mode``. generate validates the duration cap.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from fastapi import APIRouter, Depends, HTTPException
|
|
7
|
+
from fastapi.responses import Response
|
|
8
|
+
|
|
9
|
+
from kiapi.api import (
|
|
10
|
+
REQUIRE_AUTH,
|
|
11
|
+
build_job_responses,
|
|
12
|
+
get_accept,
|
|
13
|
+
get_ctx,
|
|
14
|
+
get_worker,
|
|
15
|
+
register_capability_endpoints,
|
|
16
|
+
submit_and_maybe_wait,
|
|
17
|
+
)
|
|
18
|
+
from kiapi.capabilities.acestep import (
|
|
19
|
+
CoverRequest,
|
|
20
|
+
ExtractRequest,
|
|
21
|
+
GenerateRequest,
|
|
22
|
+
RepaintRequest,
|
|
23
|
+
handle_cover,
|
|
24
|
+
handle_extract,
|
|
25
|
+
handle_generate,
|
|
26
|
+
handle_repaint,
|
|
27
|
+
settings_manager,
|
|
28
|
+
)
|
|
29
|
+
from kiapi.core.app import AppContext
|
|
30
|
+
from kiapi.core.model import UnknownModelError, model_registry
|
|
31
|
+
from kiapi.core.worker import Worker
|
|
32
|
+
|
|
33
|
+
from ._views.extract_response import ExtractResponse
|
|
34
|
+
from ._views.track_response import TrackResponse
|
|
35
|
+
|
|
36
|
+
router = APIRouter(dependencies=REQUIRE_AUTH)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _validate_model(model: str) -> None:
|
|
40
|
+
try:
|
|
41
|
+
model_registry.resolve("acestep", model)
|
|
42
|
+
except UnknownModelError as exc:
|
|
43
|
+
raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@router.post(
|
|
47
|
+
"/v1/audio/acestep/generate",
|
|
48
|
+
responses=build_job_responses("audio/wav", result_model=TrackResponse),
|
|
49
|
+
)
|
|
50
|
+
async def generate_music(
|
|
51
|
+
req: GenerateRequest,
|
|
52
|
+
accept: str | None = Depends(get_accept),
|
|
53
|
+
ctx: AppContext = Depends(get_ctx),
|
|
54
|
+
worker: Worker = Depends(get_worker),
|
|
55
|
+
) -> Response:
|
|
56
|
+
"""Generate a brand-new song from a style prompt + lyrics (text2music).
|
|
57
|
+
|
|
58
|
+
Takes no source track: `prompt` describes the SOUND, `lyrics` carries the
|
|
59
|
+
section-tagged words (or `[Instrumental]`), and `duration`/`lang` shape the
|
|
60
|
+
output. To restyle or edit an existing track use `/cover`, `/repaint`, or
|
|
61
|
+
`/extract` instead. The same endpoint serves both `sync` and `async` via
|
|
62
|
+
`mode`.
|
|
63
|
+
|
|
64
|
+
Sync content negotiation: one WAV is produced, so unless the client asks for
|
|
65
|
+
JSON the raw audio bytes are returned with `X-Kiapi-File-Id` / `X-Kiapi-Job-Id`
|
|
66
|
+
headers — `curl -o out.wav` just works. With `Accept: application/json` (or
|
|
67
|
+
async) the Job JSON is returned, whose `result` follows TrackResponse.
|
|
68
|
+
|
|
69
|
+
Async returns 202 immediately; poll GET /v1/jobs/{job_id} and fetch the
|
|
70
|
+
artifact via GET /v1/files/{file_id}.
|
|
71
|
+
"""
|
|
72
|
+
_validate_model(req.model)
|
|
73
|
+
cap = settings_manager.get_settings().max_duration
|
|
74
|
+
if req.duration > cap:
|
|
75
|
+
raise HTTPException(
|
|
76
|
+
status_code=422, detail=f"duration {req.duration}s exceeds max {cap}s"
|
|
77
|
+
)
|
|
78
|
+
return await submit_and_maybe_wait(
|
|
79
|
+
ctx,
|
|
80
|
+
worker,
|
|
81
|
+
type="acestep.generate",
|
|
82
|
+
params=req.gen_params() | {"model": req.model},
|
|
83
|
+
thunk=lambda: handle_generate(ctx, req),
|
|
84
|
+
mode=req.mode,
|
|
85
|
+
accept=accept,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@router.post(
|
|
90
|
+
"/v1/audio/acestep/cover",
|
|
91
|
+
responses=build_job_responses("audio/wav", result_model=TrackResponse),
|
|
92
|
+
)
|
|
93
|
+
async def cover_music(
|
|
94
|
+
req: CoverRequest,
|
|
95
|
+
accept: str | None = Depends(get_accept),
|
|
96
|
+
ctx: AppContext = Depends(get_ctx),
|
|
97
|
+
worker: Worker = Depends(get_worker),
|
|
98
|
+
) -> Response:
|
|
99
|
+
"""Re-style an existing track while preserving its structure (cover).
|
|
100
|
+
|
|
101
|
+
Requires a `source` track and a `prompt` describing the target style;
|
|
102
|
+
`strength` (0..1) trades creative freedom against faithfulness to the source.
|
|
103
|
+
To regenerate only a time range use `/repaint`; to make a song from scratch
|
|
104
|
+
use `/generate`. The same endpoint serves both `sync` and `async` via `mode`.
|
|
105
|
+
|
|
106
|
+
Sync content negotiation and the TrackResponse `result` shape match
|
|
107
|
+
`/v1/audio/acestep/generate` (one WAV artifact; `result.src` references the
|
|
108
|
+
source file_id).
|
|
109
|
+
"""
|
|
110
|
+
_validate_model(req.model)
|
|
111
|
+
return await submit_and_maybe_wait(
|
|
112
|
+
ctx,
|
|
113
|
+
worker,
|
|
114
|
+
type="acestep.cover",
|
|
115
|
+
params=req.gen_params() | {"model": req.model},
|
|
116
|
+
thunk=lambda: handle_cover(ctx, req),
|
|
117
|
+
mode=req.mode,
|
|
118
|
+
accept=accept,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@router.post(
|
|
123
|
+
"/v1/audio/acestep/repaint",
|
|
124
|
+
responses=build_job_responses("audio/wav", result_model=TrackResponse),
|
|
125
|
+
)
|
|
126
|
+
async def repaint_music(
|
|
127
|
+
req: RepaintRequest,
|
|
128
|
+
accept: str | None = Depends(get_accept),
|
|
129
|
+
ctx: AppContext = Depends(get_ctx),
|
|
130
|
+
worker: Worker = Depends(get_worker),
|
|
131
|
+
) -> Response:
|
|
132
|
+
"""Regenerate one time range of an existing track (repaint).
|
|
133
|
+
|
|
134
|
+
Requires a `source` track, a `prompt` for the section's style, and a
|
|
135
|
+
`start`/`end` window (`end=-1` runs to the end of the track); `strength`
|
|
136
|
+
(0..1) controls how aggressively that window is regenerated while it blends
|
|
137
|
+
into the rest. To restyle the whole track use `/cover`. The same endpoint
|
|
138
|
+
serves both `sync` and `async` via `mode`.
|
|
139
|
+
|
|
140
|
+
Sync content negotiation and the TrackResponse `result` shape match
|
|
141
|
+
`/v1/audio/acestep/generate` (one WAV artifact; `result.src` references the
|
|
142
|
+
source file_id).
|
|
143
|
+
"""
|
|
144
|
+
_validate_model(req.model)
|
|
145
|
+
return await submit_and_maybe_wait(
|
|
146
|
+
ctx,
|
|
147
|
+
worker,
|
|
148
|
+
type="acestep.repaint",
|
|
149
|
+
params=req.gen_params() | {"model": req.model},
|
|
150
|
+
thunk=lambda: handle_repaint(ctx, req),
|
|
151
|
+
mode=req.mode,
|
|
152
|
+
accept=accept,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@router.post(
|
|
157
|
+
"/v1/audio/acestep/extract",
|
|
158
|
+
responses=build_job_responses("audio/wav", result_model=ExtractResponse),
|
|
159
|
+
)
|
|
160
|
+
async def extract_music(
|
|
161
|
+
req: ExtractRequest,
|
|
162
|
+
accept: str | None = Depends(get_accept),
|
|
163
|
+
ctx: AppContext = Depends(get_ctx),
|
|
164
|
+
worker: Worker = Depends(get_worker),
|
|
165
|
+
) -> Response:
|
|
166
|
+
"""Separate a track into stems / source separation (extract).
|
|
167
|
+
|
|
168
|
+
Requires a `source` track and a list of `targets` (e.g. vocals / drums / bass
|
|
169
|
+
/ other). One job produces one WAV stem per target, so `artifacts` holds a
|
|
170
|
+
file_id per target. The same endpoint serves both `sync` and `async` via
|
|
171
|
+
`mode`.
|
|
172
|
+
|
|
173
|
+
Unlike the other operations this is a multi-artifact job, so sync always
|
|
174
|
+
returns the Job JSON (no raw-bytes shortcut). The `result` follows
|
|
175
|
+
ExtractResponse, whose `stems[]` carry one file_id each. Fetch each via
|
|
176
|
+
GET /v1/files/{file_id}.
|
|
177
|
+
"""
|
|
178
|
+
_validate_model(req.model)
|
|
179
|
+
return await submit_and_maybe_wait(
|
|
180
|
+
ctx,
|
|
181
|
+
worker,
|
|
182
|
+
type="acestep.extract",
|
|
183
|
+
params=req.gen_params() | {"model": req.model},
|
|
184
|
+
thunk=lambda: handle_extract(ctx, req),
|
|
185
|
+
mode=req.mode,
|
|
186
|
+
accept=accept,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
register_capability_endpoints(router, name="acestep", base_path="/v1/audio/acestep")
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""``/v1/audio/audiogen/generate`` result payload (the Job ``result``).
|
|
2
|
+
|
|
3
|
+
Mirrors the dict returned by ``capabilities/audiogen/_models/audiogen.run`` so the
|
|
4
|
+
produced WAV is self-describing in OpenAPI. It is an output-side projection of
|
|
5
|
+
the model result, so it lives under ``api/audio/audiogen/_views``.
|
|
6
|
+
|
|
7
|
+
``AudioResponse`` is the sole public element; nested pieces stay private.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class _Timings(BaseModel):
|
|
16
|
+
total_s: float = Field(description="Wall-clock generation time in seconds.")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AudioResponse(BaseModel):
|
|
20
|
+
"""Capability-specific ``result`` for a succeeded AudioGen generate job."""
|
|
21
|
+
|
|
22
|
+
file_id: str = Field(
|
|
23
|
+
description=(
|
|
24
|
+
"Files-API id of the produced WAV. Fetch metadata at GET /v1/files/{id} "
|
|
25
|
+
"or bytes at /download. This is also the artifact returned as raw bytes "
|
|
26
|
+
"by a single-artifact sync call."
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
audio_bytes: int = Field(description="Size of the produced WAV in bytes.")
|
|
30
|
+
|
|
31
|
+
model: str = Field(description="Resolved AudioGen variant that produced the WAV.")
|
|
32
|
+
prompt: str = Field(description="Prompt used to generate the sound effect.")
|
|
33
|
+
duration_s: float = Field(
|
|
34
|
+
description="Actual WAV duration in seconds, measured from the output samples."
|
|
35
|
+
)
|
|
36
|
+
sample_rate: int = Field(
|
|
37
|
+
description="Output sample rate in Hz. AudioGen-medium produces 16 kHz mono WAV."
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
params: dict[str, Any] = Field(
|
|
41
|
+
description=(
|
|
42
|
+
"Resolved parameters actually used for the run (model, prompt, duration, "
|
|
43
|
+
"seed, top_k, top_p, temperature, cfg_coef), so the result is reproducible."
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
timings: _Timings = Field(description="kiapi extension: server-side timing.")
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""Sound-effect API: ``POST /v1/audio/audiogen/generate`` (sync or async via ``mode``)."""
|
|
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.audiogen import (
|
|
16
|
+
GenerateRequest,
|
|
17
|
+
ValidationError,
|
|
18
|
+
handle_generate,
|
|
19
|
+
validate_generate,
|
|
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.audio_response import AudioResponse
|
|
26
|
+
|
|
27
|
+
router = APIRouter(dependencies=REQUIRE_AUTH)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@router.post(
|
|
31
|
+
"/v1/audio/audiogen/generate",
|
|
32
|
+
responses=build_job_responses("audio/wav", result_model=AudioResponse),
|
|
33
|
+
)
|
|
34
|
+
async def generate_se(
|
|
35
|
+
req: GenerateRequest,
|
|
36
|
+
accept: str | None = Depends(get_accept),
|
|
37
|
+
ctx: AppContext = Depends(get_ctx),
|
|
38
|
+
worker: Worker = Depends(get_worker),
|
|
39
|
+
) -> Response:
|
|
40
|
+
"""Generate a short non-musical sound effect from a text prompt.
|
|
41
|
+
|
|
42
|
+
Takes no source audio: `prompt` describes the sound event, environment, and
|
|
43
|
+
texture, while `duration` and the sampling knobs shape the clip. AudioGen is
|
|
44
|
+
for SFX/ambient audio such as rain, footsteps, impacts, machinery, or room
|
|
45
|
+
tone; use `/v1/audio/acestep/generate` for music. The same endpoint serves
|
|
46
|
+
both `sync` and `async` via `mode`.
|
|
47
|
+
|
|
48
|
+
Sync content negotiation: one WAV is produced, so unless the client asks for
|
|
49
|
+
JSON the raw audio bytes are returned with `X-Kiapi-File-Id` / `X-Kiapi-Job-Id`
|
|
50
|
+
headers. With `Accept: application/json` (or async) the Job JSON is returned,
|
|
51
|
+
whose `result` follows AudioResponse.
|
|
52
|
+
|
|
53
|
+
Async returns 202 immediately; poll GET /v1/jobs/{job_id} and fetch the
|
|
54
|
+
artifact via GET /v1/files/{file_id}.
|
|
55
|
+
"""
|
|
56
|
+
# Validate up front so async callers also get immediate 400/422.
|
|
57
|
+
try:
|
|
58
|
+
spec = model_registry.resolve("audiogen", req.model)
|
|
59
|
+
except UnknownModelError as exc:
|
|
60
|
+
raise HTTPException(status_code=400, detail=str(exc)) # noqa: B904
|
|
61
|
+
try:
|
|
62
|
+
validate_generate(req, variant=spec.name)
|
|
63
|
+
except ValidationError as exc:
|
|
64
|
+
raise HTTPException(status_code=422, detail=str(exc)) # noqa: B904
|
|
65
|
+
|
|
66
|
+
return await submit_and_maybe_wait(
|
|
67
|
+
ctx,
|
|
68
|
+
worker,
|
|
69
|
+
type="audiogen",
|
|
70
|
+
params=req.gen_params() | {"model": spec.name, "mode": req.mode},
|
|
71
|
+
thunk=lambda: handle_generate(ctx, req),
|
|
72
|
+
mode=req.mode,
|
|
73
|
+
accept=accept,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
register_capability_endpoints(router, name="audiogen", base_path="/v1/audio/audiogen")
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""OpenAI-compatible ``chat.completion`` response model.
|
|
2
|
+
|
|
3
|
+
Mirrors the dict shaped by ``capabilities/chat/_operations/format_response`` so
|
|
4
|
+
the non-streaming response 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/chat/_views``. Streaming responses use a separate ``chat.completion.chunk``
|
|
7
|
+
shape and are documented on the endpoint.
|
|
8
|
+
|
|
9
|
+
``ChatCompletionResponse`` is the sole public element; the nested pieces are
|
|
10
|
+
private since nothing references them on their own.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel, Field
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class _FunctionCall(BaseModel):
|
|
17
|
+
name: str = Field(description="Called function name, matching a request tool.")
|
|
18
|
+
arguments: str = Field(
|
|
19
|
+
description="Call arguments as a JSON-encoded string (OpenAI convention)."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class _ToolCall(BaseModel):
|
|
24
|
+
id: str = Field(description="Unique id for this tool call, e.g. `call_<hex>`.")
|
|
25
|
+
type: str = Field(default="function", description="Always `function`.")
|
|
26
|
+
function: _FunctionCall = Field(description="The function and its arguments.")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class _ResponseMessage(BaseModel):
|
|
30
|
+
role: str = Field(default="assistant", description="Always `assistant`.")
|
|
31
|
+
content: str | None = Field(
|
|
32
|
+
default=None,
|
|
33
|
+
description=(
|
|
34
|
+
"Assistant text. Null when the turn is only tool calls; may hold the "
|
|
35
|
+
"natural-language preamble that preceded a tool call."
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
tool_calls: list[_ToolCall] | None = Field(
|
|
39
|
+
default=None,
|
|
40
|
+
description="Tool calls the model requested, when any.",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class _Choice(BaseModel):
|
|
45
|
+
index: int = Field(description="Choice index (always 0; kiapi returns one).")
|
|
46
|
+
message: _ResponseMessage = Field(description="The generated assistant message.")
|
|
47
|
+
finish_reason: str = Field(
|
|
48
|
+
description="`stop` for normal completion, `tool_calls` when tools were called."
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class _Usage(BaseModel):
|
|
53
|
+
prompt_tokens: int = Field(description="Tokens in the prompt.")
|
|
54
|
+
completion_tokens: int = Field(description="Tokens generated.")
|
|
55
|
+
total_tokens: int = Field(description="Sum of prompt and completion tokens.")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class _Timings(BaseModel):
|
|
59
|
+
total_s: float = Field(description="Wall-clock generation time in seconds.")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ChatCompletionResponse(BaseModel):
|
|
63
|
+
id: str = Field(description="Completion id, e.g. `chatcmpl-<hex>`.")
|
|
64
|
+
object: str = Field(
|
|
65
|
+
default="chat.completion", description="Always `chat.completion`."
|
|
66
|
+
)
|
|
67
|
+
created: int = Field(description="Unix timestamp (seconds) when created.")
|
|
68
|
+
model: str = Field(description="Resolved model name that answered.")
|
|
69
|
+
choices: list[_Choice] = Field(description="Generated choices (one).")
|
|
70
|
+
usage: _Usage = Field(description="Token accounting for the request.")
|
|
71
|
+
timings: _Timings = Field(description="kiapi extension: server-side timing.")
|