inline-core 1.2.69__tar.gz → 1.2.71__tar.gz
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.
- {inline_core-1.2.69 → inline_core-1.2.71}/PKG-INFO +1 -1
- {inline_core-1.2.69 → inline_core-1.2.71}/pyproject.toml +1 -1
- inline_core-1.2.71/src/inline_core/characters/__init__.py +35 -0
- inline_core-1.2.71/src/inline_core/characters/apply.py +145 -0
- inline_core-1.2.71/src/inline_core/characters/charfile.py +216 -0
- inline_core-1.2.71/src/inline_core/characters/encode.py +232 -0
- inline_core-1.2.71/src/inline_core/characters/library.py +136 -0
- inline_core-1.2.71/src/inline_core/characters/scoring.py +331 -0
- inline_core-1.2.71/src/inline_core/characters/weights.py +98 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/cache.py +17 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/registry.py +10 -1
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/runners.py +18 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/catalog.py +18 -5
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/flux2/runner.py +47 -1
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/pipeline.py +30 -8
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/runner.py +17 -1
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/pipeline_runtime.py +23 -1
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/app.py +55 -0
- inline_core-1.2.71/src/inline_core/studio/characters.py +252 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/generation.py +24 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/graph_build.py +60 -10
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/handlers.py +18 -0
- inline_core-1.2.71/tests/reference/lookalike_faces.json +91 -0
- inline_core-1.2.71/tests/test_characters_encode.py +243 -0
- inline_core-1.2.71/tests/test_characters_library.py +105 -0
- inline_core-1.2.71/tests/test_characters_rpc.py +199 -0
- inline_core-1.2.71/tests/test_characters_scoring.py +267 -0
- inline_core-1.2.71/tests/test_characters_wiring.py +201 -0
- inline_core-1.2.71/tests/test_charfile.py +161 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_flux2_runner.py +22 -0
- inline_core-1.2.71/tests/test_ltx25_wired_refs.py +55 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_minimaxh3_nodes.py +57 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_graph_build.py +50 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/uv.lock +89 -5
- {inline_core-1.2.69 → inline_core-1.2.71}/.gitignore +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/.python-version +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/CLAUDE.md +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/README.md +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/main.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/scripts/flux2_train_matrix.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/scripts/minimax_h3_lora_check.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/scripts/minimax_h3_train_matrix.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/scripts/reference.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/components/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/components/conditioning.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/components/interfaces.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/config.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/device/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/device/auto.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/device/detect.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/device/memory.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/device/policy.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/device/probe.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/device/types.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/errors.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/api.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/constraints.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/fetch.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/handlers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/importer.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/install.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/loader.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/manifest.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/models.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/paths.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/resolve.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/scanner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/state.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/extensions/tools.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/ffmpeg.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/descriptor.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/executor.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/loader_runners.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/primitives.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/schema.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/topo.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/graph/validate.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/media.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/checkpoint.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/controlspace.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/flux2/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/flux2/controlnet.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/flux2/embeds.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/flux2/provider.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/flux2/requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/flux2/variants.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/keymap.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/krea2/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/krea2/convert.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/krea2/depth_control.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/krea2/img2img.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/krea2/provider.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/krea2/requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/krea2/runner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/loaders.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/lora.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/lora_keys.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/memory.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/provider.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/allocator_trim_strategy.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/batch_split.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/block_fetcher.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/builder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/disk.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/pool.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/provider.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/source.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/stream_sync.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/utils.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/block_streaming/wrapper.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/color/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/color/audio_mux.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/color/hlg.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/color/primaries.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/color/yuv.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/components/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/components/diffusion_steps.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/components/guiders.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/components/noisers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/components/patchifiers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/components/protocols.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/components/schedulers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/exceptions.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/item.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/mask_utils.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/attention_strength_wrapper.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/keyframe_cond.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/keyframe_slots.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/latent_cond.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/mask_cond.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/noise_mask_cond.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/reference_audio_cond.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/conditioning/types/reference_video_cond.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/devices.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/duration_head/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/duration_head/duration_head.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/duration_head/model_configurator.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/guidance/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/guidance/perturbations.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/hdr.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/attention_ops.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/fuse_loras.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/helpers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/kernels.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/module_ops.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/primitives.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/registry.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/sd_ops.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/sft_loader.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/loader/single_gpu_model_builder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/modality_tiling.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/attention.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/audio_vae.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/causal_conv_2d.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/causality_axis.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/downsample.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/model_configurator.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/ops.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/resnet.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/upsample.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/audio_vae/vocoder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/common/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/common/normalization.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/disposable.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/model_protocol.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/adaln.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/attention.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/compiling.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/cudagraph_capture.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/feed_forward.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/gelu_approx.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/modality.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/model.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/model_configurator.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/ops.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/rope.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/text_projection.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/timestep_embedding.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/transformer.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/transformer/transformer_args.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/upsampler/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/upsampler/blur_downsample.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/upsampler/model.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/upsampler/model_configurator.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/upsampler/pixel_shuffle.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/upsampler/res_block.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/upsampler/spatial_rational_resampler.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/attention.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/conv_video_decoder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/convolution.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/diffusion_tiling.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/diffusion_video_decoder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/enums.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/memory_efficient_decode.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/model_configurator.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/normalization.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/ops.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/resnet.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/sampling.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/apply.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/attention.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/blocks.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/chunked/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/chunked/attn.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/chunked/block.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/chunked/context.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/chunked/mlp.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/combined/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/combined/attn.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/combined/block.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/combined/context.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/combined/mlp.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/compiling.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/config.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/det_attn_rope.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/dsl_kernels/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/dsl_kernels/apply_dsl.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/dsl_kernels/attn.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/dsl_kernels/block.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/dsl_kernels/chain.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/fallback_na/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/fallback_na/eager.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/fallback_na/triton_na.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/layers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/qkv.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/rope.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/rope_math.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/transformer/swiglu.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/model/video_vae/video_vae.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/gemma/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/gemma/accelerate_wrapper.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/gemma/batch_parallel_wrapper.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/gemma/broadcast_wrapper.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/gemma/loader.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/sharded_sd.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/transformer/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/transformer/attention.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/transformer/sequence_parallel.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/transformer/tiled_data_parallel.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/vae/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/multigpu/vae/distributed_decoder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/blockwise/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/blockwise/_impl.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/fp8_cast.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/fp8_scaled_mm.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/nvfp4/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/nvfp4/convert.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/nvfp4/fuse.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/nvfp4/linear.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/nvfp4/prequant.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/nvfp4/types.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/quantization/policy.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/embeddings_connector.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/embeddings_processor.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/encoders/base_encoder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/encoders/encoder_configurator.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/encoders/prompts/gemma3_i2v_system_prompt.txt +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/encoders/prompts/gemma3_t2v_system_prompt.txt +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/encoders/prompts/gemma4_i2v_system_prompt.txt +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/encoders/prompts/gemma4_t2v_system_prompt.txt +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/feature_extractor.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/gemma_assets.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/text_encoders/gemma/tokenizer.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/tiling.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/tools.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/types.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_core/utils.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/a2vid_two_stage.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/dfr_layout.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/dfr_pipeline.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/distilled.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/distilled_mgpu.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/dubit.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/hdr_ic_lora.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/ic_lora.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/iclora_utils.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/keyframe_interpolation.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/_broadcast.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/bp_gemma_builder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/controller.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/delegating_builder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/fleet.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/gemma_builders.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/nccl_groups.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/runner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/sp_builder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/tdp_builder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/vae_builders.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/multigpu/weight_tracker.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/retake.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/t2a_one_stage.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/ti2vid_one_stage.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/ti2vid_two_stages.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/ti2vid_two_stages_hq.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/ti2vid_two_stages_hq_mgpu.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/ti2vid_two_stages_mgpu.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/args.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/blocks.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/constants.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/denoisers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/gpu_model.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/helpers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/media_io/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/media_io/color_config.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/media_io/decode.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/media_io/encode.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/media_io/exr.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/media_io/range_map.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/media_io/resize.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/model_paths.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/quantization_factory.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/res2s.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/samplers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/ltx25/vendor/ltx_pipelines/utils/types.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/adaln.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/keys.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/load.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/lora_keys.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/pipeline.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/provider.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/runner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vae_keys.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/autoencoder_kl_minimax_h3.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/autoencoder_kl_minimax_h3_audio.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/before_denoise.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/before_encoder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/decoders.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/denoise.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/encoders.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/modular_blocks_minimax_h3.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/modular_pipeline.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/packing.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/packing_ref2va.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/scheduling_minimax_h3.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/minimaxh3/vendor/transformer_minimax_h3.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/offload.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/prepared.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/preprocess/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/preprocess/requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/preprocess/runner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/references.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/sampling.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/video_params.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/zimage/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/zimage/primitives.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/zimage/provider.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/zimage/requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/models/zimage/runner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/parallel/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/parallel/config.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/parallel/group.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/parallel/launch.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/parallel/protocol.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/parallel/registry.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/parallel/worker.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/runtime/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/runtime/context.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/runtime/file_store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/runtime/progress.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/runtime/run.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/runtime/store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/runtime/video_encode.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/sampling/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/sampling/batch.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/__main__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/assets.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/bootstrap.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/frontend.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/manager.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/rpc.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/run_store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/server/serialize.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/activity.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/assets.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/config.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/dataset_import.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/fal.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/frames.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/image_meta.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/models.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/moodboard.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/peaks.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/recipe.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/schema.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/system_stats.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/timeline/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/timeline/compose.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/timeline/ffmpeg.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/timeline/render.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/timeline/resolve.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/training.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/studio/training_store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/takes.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/__init__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/__main__.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/arch.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/cache.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/caption.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/dataset.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/h3.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/ltx25.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/models.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/precache_store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/protocol.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/src/inline_core/training/trainer.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/conftest.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/helpers.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_cache.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_catalog.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_checkpoint.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_clip_grid_parity.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_config.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_dataset_import.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_device_detect.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_encoder_parking.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_executor.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_extension_api.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_extension_install.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_extension_manifest.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_extension_resolve.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_extension_scanner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_extension_spine.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_extension_state.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_file_store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_flux2_controlnet.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_flux2_folder.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_flux2_resolve.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_flux2_training.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_flux2_variants.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_frontend_serving.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_hidden_nodes.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_keymap.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_krea2_convert.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_krea2_depth_control.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_krea2_requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_krea2_runner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_loader_runners.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_loaders.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_lora.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_lora_download.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_ltx25_lora_keys.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_ltx25_nodes.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_ltx25_requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_ltx25_training.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_manager_queue.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_memory_policy.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_minimaxh3_adaln.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_minimaxh3_keys.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_minimaxh3_load.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_minimaxh3_lora_keys.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_minimaxh3_training.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_model_requirements.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_offload_prepared.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_output_kind_contract.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_parallel_group.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_pipeline_cache.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_precache_store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_primitives.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_recipe.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_references.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_rpc_bridge.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_run_store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_sampling.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_schema.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_server.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_staged_residency.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_activity.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_assets.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_fal.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_frames.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_generation.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_models.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_moodboard.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_multi_reference.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_node_size.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_peaks.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_rpc.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_schema.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_store.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_timeline.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_studio_training.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_take_bytes.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_topo.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_training_arch.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_training_dataset.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_training_models.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_training_resolve.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_training_snapshots.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_validate.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_video_encode.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_video_params.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_webui_install.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_xfuser_sampler.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_zimage_primitives.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_zimage_resolve.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/tests/test_zimage_runner.py +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/webui.bat +0 -0
- {inline_core-1.2.69 → inline_core-1.2.71}/webui.sh +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Persistent characters: the ``.char`` container, its compiled payloads, and identity scoring."""
|
|
2
|
+
|
|
3
|
+
from .charfile import (
|
|
4
|
+
FORMAT_VERSION,
|
|
5
|
+
MAGIC,
|
|
6
|
+
SIGNATURE,
|
|
7
|
+
CharDoc,
|
|
8
|
+
CharFileError,
|
|
9
|
+
Manifest,
|
|
10
|
+
centroid_valid,
|
|
11
|
+
looks_like_char,
|
|
12
|
+
member_name,
|
|
13
|
+
payload_valid,
|
|
14
|
+
read,
|
|
15
|
+
refs_fingerprint,
|
|
16
|
+
sha256_bytes,
|
|
17
|
+
write,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"FORMAT_VERSION",
|
|
22
|
+
"MAGIC",
|
|
23
|
+
"SIGNATURE",
|
|
24
|
+
"CharDoc",
|
|
25
|
+
"CharFileError",
|
|
26
|
+
"Manifest",
|
|
27
|
+
"centroid_valid",
|
|
28
|
+
"looks_like_char",
|
|
29
|
+
"member_name",
|
|
30
|
+
"payload_valid",
|
|
31
|
+
"read",
|
|
32
|
+
"refs_fingerprint",
|
|
33
|
+
"sha256_bytes",
|
|
34
|
+
"write",
|
|
35
|
+
]
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""``char_apply``: a character turned into the references and prompt text a run needs.
|
|
2
|
+
|
|
3
|
+
Payload PNGs are extracted from the zip once, keyed by content hash so an edit lands in a new
|
|
4
|
+
directory rather than mutating one a running graph is reading.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
import shutil
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from ..config import data_dir
|
|
15
|
+
from ..takes import AssetRef
|
|
16
|
+
from . import charfile as cf
|
|
17
|
+
from . import encode, library
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger("inline_core.characters")
|
|
20
|
+
|
|
21
|
+
#: Extracted payload bytes to keep. Tiny next to a checkpoint, so this holds many characters.
|
|
22
|
+
_CACHE_LIMIT_BYTES = 2 * 1024**3
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AppliedCharacter:
|
|
26
|
+
"""What a runner needs: ordered reference handles, plus the prompt text that names them."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, name: str, refs: list[AssetRef], description: str) -> None:
|
|
29
|
+
self.name = name
|
|
30
|
+
self.refs = refs
|
|
31
|
+
self.description = description
|
|
32
|
+
|
|
33
|
+
def prompt_prefix(self, first_position: int) -> str:
|
|
34
|
+
"""Text naming the positions the character lands on, so ordinal prompting resolves."""
|
|
35
|
+
if not self.refs:
|
|
36
|
+
return ""
|
|
37
|
+
positions = [str(first_position + i) for i in range(len(self.refs))]
|
|
38
|
+
if len(positions) == 1:
|
|
39
|
+
which = f"Image {positions[0]} shows"
|
|
40
|
+
else:
|
|
41
|
+
which = f"Images {', '.join(positions[:-1])} and {positions[-1]} show"
|
|
42
|
+
line = f"{which} {self.name}, the same character in every image."
|
|
43
|
+
detail = " ".join(self.description.split())
|
|
44
|
+
if not detail:
|
|
45
|
+
return f"{line} "
|
|
46
|
+
# Prose, not comma tags: without this it runs into the user's prompt unpunctuated.
|
|
47
|
+
if detail[-1] not in ".!?":
|
|
48
|
+
detail += "."
|
|
49
|
+
return f"{line} {detail} "
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _cache_root() -> Path:
|
|
53
|
+
return data_dir() / "characters"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def char_apply(chosen: str) -> AppliedCharacter | None:
|
|
57
|
+
"""References and prompt text for a pick, or None when none. An unreadable pick raises rather
|
|
58
|
+
than silently generating the wrong person."""
|
|
59
|
+
name = str(chosen or "").strip()
|
|
60
|
+
if not name:
|
|
61
|
+
return None
|
|
62
|
+
path = library.resolve(name)
|
|
63
|
+
if path is None:
|
|
64
|
+
raise FileNotFoundError(
|
|
65
|
+
f"Character {name!r} is not in models/characters/. Pick another in the node's settings."
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
doc = cf.read(path)
|
|
69
|
+
digest = library.content_hash(path)
|
|
70
|
+
arch = encode.FLUX2_KLEIN_ARCH
|
|
71
|
+
|
|
72
|
+
if not cf.payload_valid(doc.manifest, arch, encode.PAYLOAD_ENCODER_VERSION):
|
|
73
|
+
doc = _recompile(doc, path)
|
|
74
|
+
digest = library.content_hash(path)
|
|
75
|
+
|
|
76
|
+
refs = _extract(doc, digest, arch)
|
|
77
|
+
description = _description(doc)
|
|
78
|
+
return AppliedCharacter(doc.manifest.name or path.stem, refs, description)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _description(doc: cf.CharDoc) -> str:
|
|
82
|
+
raw = doc.members.get(str(doc.manifest.text.get("path") or ""))
|
|
83
|
+
return raw.decode("utf-8", errors="replace") if raw else ""
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _recompile(doc: cf.CharDoc, path: Path) -> cf.CharDoc:
|
|
87
|
+
"""Rebuild a stale payload from ``refs/``. Payloads are cache, so this always works."""
|
|
88
|
+
logger.info("Recompiling the %s payload for %s", encode.FLUX2_KLEIN_ARCH, path.name)
|
|
89
|
+
import io
|
|
90
|
+
|
|
91
|
+
from PIL import Image
|
|
92
|
+
|
|
93
|
+
images: list[Any] = []
|
|
94
|
+
for ref in doc.manifest.refs:
|
|
95
|
+
raw = doc.members.get(str(ref.get("path")))
|
|
96
|
+
if raw is None:
|
|
97
|
+
raise cf.CharFileError(
|
|
98
|
+
f"{path.name} is missing reference {ref.get('path')}, so it cannot be rebuilt."
|
|
99
|
+
)
|
|
100
|
+
images.append(Image.open(io.BytesIO(raw)).convert("RGB"))
|
|
101
|
+
|
|
102
|
+
encode.build_payload(doc.manifest, doc.members, images)
|
|
103
|
+
cf.write(path, doc)
|
|
104
|
+
return doc
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _extract(doc: cf.CharDoc, digest: str, arch: str) -> list[AssetRef]:
|
|
108
|
+
payload = doc.manifest.payloads.get(arch) or {}
|
|
109
|
+
files = [str(entry.get("path")) for entry in payload.get("files") or []]
|
|
110
|
+
if not files:
|
|
111
|
+
return []
|
|
112
|
+
|
|
113
|
+
root = _cache_root() / digest
|
|
114
|
+
marker = root / ".complete"
|
|
115
|
+
if not marker.is_file():
|
|
116
|
+
staging = root.with_name(f"{digest}.part")
|
|
117
|
+
shutil.rmtree(staging, ignore_errors=True)
|
|
118
|
+
staging.mkdir(parents=True, exist_ok=True)
|
|
119
|
+
for member in files:
|
|
120
|
+
data = doc.members.get(member)
|
|
121
|
+
if data is None:
|
|
122
|
+
raise cf.CharFileError(f"Character payload is missing {member}.")
|
|
123
|
+
(staging / Path(member).name).write_bytes(data)
|
|
124
|
+
(staging / ".complete").write_text("ok")
|
|
125
|
+
shutil.rmtree(root, ignore_errors=True)
|
|
126
|
+
staging.replace(root)
|
|
127
|
+
_prune(_cache_root())
|
|
128
|
+
|
|
129
|
+
return [AssetRef(ref="path", path=str(root / Path(member).name)) for member in files]
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _prune(root: Path) -> None:
|
|
133
|
+
"""Oldest-first eviction against a size cap, the same shape as the prompt-embed cache."""
|
|
134
|
+
if not root.is_dir():
|
|
135
|
+
return
|
|
136
|
+
entries = sorted(
|
|
137
|
+
(p for p in root.iterdir() if p.is_dir()),
|
|
138
|
+
key=lambda p: p.stat().st_mtime,
|
|
139
|
+
reverse=True,
|
|
140
|
+
)
|
|
141
|
+
total = 0
|
|
142
|
+
for entry in entries:
|
|
143
|
+
total += sum(f.stat().st_size for f in entry.rglob("*") if f.is_file())
|
|
144
|
+
if total > _CACHE_LIMIT_BYTES:
|
|
145
|
+
shutil.rmtree(entry, ignore_errors=True)
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"""The ``.char`` container: a persistent character as one portable zip.
|
|
2
|
+
|
|
3
|
+
::
|
|
4
|
+
|
|
5
|
+
Ada.char
|
|
6
|
+
manifest.json first member; the signature is at byte 0
|
|
7
|
+
refs/000.png user-provided reference images, immutable
|
|
8
|
+
derived/face_000.png auto-generated crops
|
|
9
|
+
text/description.md the locked character description
|
|
10
|
+
payloads/<arch>/ compiled per model family, pure cache
|
|
11
|
+
scoring/ identity centroids, one per scoring encoder
|
|
12
|
+
|
|
13
|
+
Refs and text are truth; payloads and centroids are cache, and must be regenerable from ``refs/``.
|
|
14
|
+
Torch-free and network-free, so a core install can read a character.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import hashlib
|
|
20
|
+
import json
|
|
21
|
+
import os
|
|
22
|
+
import zipfile
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
#: A reader refuses anything above this rather than half-loading the wrong face.
|
|
28
|
+
FORMAT_VERSION = 1
|
|
29
|
+
|
|
30
|
+
MAGIC = "INLINECHAR"
|
|
31
|
+
|
|
32
|
+
#: Valid JSON *and* a signature, so a file is identifiable from 32 bytes without parsing.
|
|
33
|
+
SIGNATURE = f'{{"magic":"{MAGIC}","format_version":'.encode()
|
|
34
|
+
|
|
35
|
+
MANIFEST_NAME = "manifest.json"
|
|
36
|
+
|
|
37
|
+
#: Fixed so the signature lands at byte 0 and two writes produce identical bytes.
|
|
38
|
+
_KEY_ORDER = (
|
|
39
|
+
"magic", "format_version", "char_id", "name", "created_at", "modified_at", "app",
|
|
40
|
+
"app_version", "refs", "derived", "text", "payloads", "scoring", "hints", "reserved",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class CharFileError(Exception):
|
|
45
|
+
"""A ``.char`` that cannot be trusted. The message is shown to the user."""
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class Manifest:
|
|
50
|
+
char_id: str
|
|
51
|
+
name: str
|
|
52
|
+
created_at: int
|
|
53
|
+
modified_at: int
|
|
54
|
+
app_version: str = ""
|
|
55
|
+
refs: list[dict[str, Any]] = field(default_factory=list)
|
|
56
|
+
derived: list[dict[str, Any]] = field(default_factory=list)
|
|
57
|
+
text: dict[str, Any] = field(default_factory=dict)
|
|
58
|
+
payloads: dict[str, Any] = field(default_factory=dict)
|
|
59
|
+
scoring: dict[str, Any] = field(default_factory=dict)
|
|
60
|
+
hints: list[str] = field(default_factory=list)
|
|
61
|
+
reserved: dict[str, Any] = field(
|
|
62
|
+
default_factory=lambda: {"adapters": {}, "video_payloads": {}, "members": []}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def to_json(self) -> dict[str, Any]:
|
|
66
|
+
return {
|
|
67
|
+
"magic": MAGIC,
|
|
68
|
+
"format_version": FORMAT_VERSION,
|
|
69
|
+
"char_id": self.char_id,
|
|
70
|
+
"name": self.name,
|
|
71
|
+
"created_at": self.created_at,
|
|
72
|
+
"modified_at": self.modified_at,
|
|
73
|
+
"app": "inline-studio",
|
|
74
|
+
"app_version": self.app_version,
|
|
75
|
+
"refs": self.refs,
|
|
76
|
+
"derived": self.derived,
|
|
77
|
+
"text": self.text,
|
|
78
|
+
"payloads": self.payloads,
|
|
79
|
+
"scoring": self.scoring,
|
|
80
|
+
"hints": self.hints,
|
|
81
|
+
"reserved": self.reserved,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@classmethod
|
|
85
|
+
def from_json(cls, raw: dict[str, Any]) -> Manifest:
|
|
86
|
+
return cls(
|
|
87
|
+
char_id=str(raw.get("char_id", "")),
|
|
88
|
+
name=str(raw.get("name", "")),
|
|
89
|
+
created_at=int(raw.get("created_at", 0)),
|
|
90
|
+
modified_at=int(raw.get("modified_at", 0)),
|
|
91
|
+
app_version=str(raw.get("app_version", "")),
|
|
92
|
+
refs=list(raw.get("refs") or []),
|
|
93
|
+
derived=list(raw.get("derived") or []),
|
|
94
|
+
text=dict(raw.get("text") or {}),
|
|
95
|
+
payloads=dict(raw.get("payloads") or {}),
|
|
96
|
+
scoring=dict(raw.get("scoring") or {}),
|
|
97
|
+
hints=list(raw.get("hints") or []),
|
|
98
|
+
reserved=dict(raw.get("reserved") or {}),
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class CharDoc:
|
|
104
|
+
"""A whole character in memory: the manifest plus every member's bytes."""
|
|
105
|
+
|
|
106
|
+
manifest: Manifest
|
|
107
|
+
members: dict[str, bytes] = field(default_factory=dict)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def sha256_bytes(data: bytes) -> str:
|
|
111
|
+
return hashlib.sha256(data).hexdigest()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def member_name(prefix: str, index: int, suffix: str) -> str:
|
|
115
|
+
"""``refs/000.png`` - always ASCII, since a user's filename may not extract on Windows."""
|
|
116
|
+
return f"{prefix}/{index:03d}{suffix}"
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def dumps_manifest(manifest: Manifest) -> bytes:
|
|
120
|
+
"""Manifest bytes with the signature at byte 0."""
|
|
121
|
+
raw = manifest.to_json()
|
|
122
|
+
ordered = {key: raw[key] for key in _KEY_ORDER if key in raw}
|
|
123
|
+
data = json.dumps(ordered, ensure_ascii=True, separators=(",", ":")).encode()
|
|
124
|
+
if not data.startswith(SIGNATURE):
|
|
125
|
+
raise CharFileError("Character manifest lost its signature; the key order is wrong.")
|
|
126
|
+
return data
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def looks_like_char(data: bytes) -> bool:
|
|
130
|
+
"""Whether a manifest blob carries our signature. Cheap enough for an upload gate."""
|
|
131
|
+
return data.startswith(SIGNATURE)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def read(path: Path | str) -> CharDoc:
|
|
135
|
+
"""Load a ``.char``. Raises `CharFileError` with user-facing copy on anything unreadable."""
|
|
136
|
+
target = Path(path)
|
|
137
|
+
try:
|
|
138
|
+
with zipfile.ZipFile(target, "r") as archive:
|
|
139
|
+
names = archive.namelist()
|
|
140
|
+
if MANIFEST_NAME not in names:
|
|
141
|
+
raise CharFileError(f"{target.name} is not a character file (no manifest).")
|
|
142
|
+
raw = archive.read(MANIFEST_NAME)
|
|
143
|
+
members = {
|
|
144
|
+
n: archive.read(n)
|
|
145
|
+
for n in names
|
|
146
|
+
if n != MANIFEST_NAME and not n.endswith("/")
|
|
147
|
+
}
|
|
148
|
+
except zipfile.BadZipFile as error:
|
|
149
|
+
raise CharFileError(f"{target.name} is not a readable character file.") from error
|
|
150
|
+
|
|
151
|
+
if not looks_like_char(raw):
|
|
152
|
+
raise CharFileError(f"{target.name} is not a character file (bad signature).")
|
|
153
|
+
try:
|
|
154
|
+
parsed = json.loads(raw)
|
|
155
|
+
except json.JSONDecodeError as error:
|
|
156
|
+
raise CharFileError(f"{target.name} has a corrupt manifest.") from error
|
|
157
|
+
|
|
158
|
+
version = int(parsed.get("format_version", 0))
|
|
159
|
+
if version > FORMAT_VERSION:
|
|
160
|
+
raise CharFileError(
|
|
161
|
+
f"{target.name} was written by a newer version of Inline Studio "
|
|
162
|
+
f"(character format {version}, this build reads {FORMAT_VERSION}). Update to open it."
|
|
163
|
+
)
|
|
164
|
+
return CharDoc(manifest=Manifest.from_json(parsed), members=members)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def write(path: Path | str, doc: CharDoc) -> Path:
|
|
168
|
+
"""Write atomically. The archive closes before the replace, or Windows refuses it."""
|
|
169
|
+
target = Path(path)
|
|
170
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
171
|
+
staging = target.with_name(target.name + ".part")
|
|
172
|
+
try:
|
|
173
|
+
with zipfile.ZipFile(staging, "w", zipfile.ZIP_DEFLATED) as archive:
|
|
174
|
+
# Manifest first so a reader can identify the file from the front of the stream.
|
|
175
|
+
archive.writestr(MANIFEST_NAME, dumps_manifest(doc.manifest))
|
|
176
|
+
for name in sorted(doc.members):
|
|
177
|
+
# PNGs are already compressed; deflating them again costs time and saves nothing.
|
|
178
|
+
compress = zipfile.ZIP_STORED if name.endswith(".png") else zipfile.ZIP_DEFLATED
|
|
179
|
+
archive.writestr(name, doc.members[name], compress_type=compress)
|
|
180
|
+
os.replace(staging, target)
|
|
181
|
+
except Exception:
|
|
182
|
+
staging.unlink(missing_ok=True)
|
|
183
|
+
raise
|
|
184
|
+
return target
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def refs_fingerprint(manifest: Manifest, policy: dict[str, Any]) -> str:
|
|
188
|
+
"""Ordered ref hashes plus policy, so a reorder or a resize-budget change both invalidate."""
|
|
189
|
+
parts = [str(ref.get("sha256", "")) for ref in manifest.refs]
|
|
190
|
+
parts.append(json.dumps(policy, sort_keys=True, separators=(",", ":")))
|
|
191
|
+
return hashlib.sha256("\x1f".join(parts).encode()).hexdigest()
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def payload_valid(manifest: Manifest, arch: str, encoder_version: str) -> bool:
|
|
195
|
+
"""Whether ``payloads/<arch>/`` can be used as-is, or must be recompiled from ``refs/``."""
|
|
196
|
+
payload = manifest.payloads.get(arch)
|
|
197
|
+
if not isinstance(payload, dict):
|
|
198
|
+
return False
|
|
199
|
+
encoder = payload.get("encoder")
|
|
200
|
+
if not isinstance(encoder, dict) or str(encoder.get("version", "")) != encoder_version:
|
|
201
|
+
return False
|
|
202
|
+
policy = payload.get("policy")
|
|
203
|
+
if not isinstance(policy, dict):
|
|
204
|
+
return False
|
|
205
|
+
return str(payload.get("source_sha256", "")) == refs_fingerprint(manifest, policy)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def centroid_valid(manifest: Manifest, encoder_id: str, encoder_version: str) -> bool:
|
|
209
|
+
"""Cosine similarity across two encoder builds is meaningless, so the version must match."""
|
|
210
|
+
encoders = manifest.scoring.get("encoders")
|
|
211
|
+
if not isinstance(encoders, list):
|
|
212
|
+
return False
|
|
213
|
+
for entry in encoders:
|
|
214
|
+
if isinstance(entry, dict) and str(entry.get("id")) == encoder_id:
|
|
215
|
+
return str(entry.get("version", "")) == encoder_version
|
|
216
|
+
return False
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""``char_encode``: reference images plus a description compiled into one ``.char``.
|
|
2
|
+
|
|
3
|
+
Refs go in untouched apart from EXIF rotation, because everything else is derived from them.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import io
|
|
9
|
+
import time
|
|
10
|
+
import uuid
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from . import charfile as cf
|
|
15
|
+
from . import scoring
|
|
16
|
+
|
|
17
|
+
#: The payload compiler's version. Bumping it recompiles every character's ref set on next use.
|
|
18
|
+
PAYLOAD_ENCODER_VERSION = "1"
|
|
19
|
+
PAYLOAD_ENCODER_ID = "flux2-klein-refset"
|
|
20
|
+
FLUX2_KLEIN_ARCH = "flux2-klein"
|
|
21
|
+
|
|
22
|
+
#: Done here so the pixels the pipeline sees are the pixels we hashed, once per character.
|
|
23
|
+
PAYLOAD_POLICY: dict[str, Any] = {"max_pixels": 1024 * 1024, "multiple_of": 16}
|
|
24
|
+
|
|
25
|
+
#: Enough pixels for SFace without carrying a full reference into the file.
|
|
26
|
+
FACE_CROP_SIZE = 512
|
|
27
|
+
|
|
28
|
+
_FACE_EMBEDS = f"scoring/embeds_{scoring.SFACE_ID}.json"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _open(path: Path) -> Any:
|
|
32
|
+
from PIL import Image, ImageOps
|
|
33
|
+
|
|
34
|
+
with Image.open(path) as handle:
|
|
35
|
+
# Without EXIF rotation every downstream crop and centroid is wrong the same invisible way.
|
|
36
|
+
return ImageOps.exif_transpose(handle).convert("RGB")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _png_bytes(image: Any) -> bytes:
|
|
40
|
+
buffer = io.BytesIO()
|
|
41
|
+
image.save(buffer, format="PNG")
|
|
42
|
+
return buffer.getvalue()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def normalise_reference(image: Any, policy: dict[str, Any] | None = None) -> Any:
|
|
46
|
+
"""A reference resized into FLUX.2's budget, on the grid, preserving aspect."""
|
|
47
|
+
rules = policy or PAYLOAD_POLICY
|
|
48
|
+
max_pixels = int(rules["max_pixels"])
|
|
49
|
+
grid = int(rules["multiple_of"])
|
|
50
|
+
width, height = image.width, image.height
|
|
51
|
+
if width * height > max_pixels:
|
|
52
|
+
scale = (max_pixels / (width * height)) ** 0.5
|
|
53
|
+
width, height = int(width * scale), int(height * scale)
|
|
54
|
+
width = max(grid, (width // grid) * grid)
|
|
55
|
+
height = max(grid, (height // grid) * grid)
|
|
56
|
+
if (width, height) == (image.width, image.height):
|
|
57
|
+
return image
|
|
58
|
+
from PIL import Image
|
|
59
|
+
|
|
60
|
+
return image.resize((width, height), Image.LANCZOS)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def strength_hints(sizes: list[tuple[int, int]]) -> list[str]:
|
|
64
|
+
"""One nudge per distinct gap. Creation is never gated on any of these.
|
|
65
|
+
|
|
66
|
+
Takes sizes rather than images so it can be recomputed from a manifest, which is what keeps a
|
|
67
|
+
rule change from leaving every existing character showing the advice it was encoded with.
|
|
68
|
+
"""
|
|
69
|
+
hints: list[str] = []
|
|
70
|
+
# Escalating, never stacked: at one reference "add another angle" and "add a profile view" are
|
|
71
|
+
# the same request worded twice, which reads as two chores instead of one.
|
|
72
|
+
if len(sizes) == 1:
|
|
73
|
+
hints.append("Add a second angle")
|
|
74
|
+
elif len(sizes) == 2:
|
|
75
|
+
hints.append("Add a profile view")
|
|
76
|
+
elif len(sizes) < 4:
|
|
77
|
+
hints.append("Add a different outfit or setting")
|
|
78
|
+
ratios = [w / h for w, h in sizes if h]
|
|
79
|
+
if len(sizes) >= 2 and ratios and abs(max(ratios) - min(ratios)) < 0.05:
|
|
80
|
+
hints.append("Add a wider or tighter crop")
|
|
81
|
+
return hints
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def flags_for(doc: cf.CharDoc) -> dict[str, Any]:
|
|
85
|
+
"""Reference agreement recomputed from the stored embeddings, so a floor change reaches
|
|
86
|
+
characters already on disk. Falls back to what was recorded at encode time."""
|
|
87
|
+
refs = scoring.load_embeds(doc.members, str(doc.manifest.scoring.get("faceEmbeds") or ""))
|
|
88
|
+
if not refs:
|
|
89
|
+
return {
|
|
90
|
+
"refAgreement": list(doc.manifest.scoring.get("refAgreement") or []),
|
|
91
|
+
"flaggedRefs": list(doc.manifest.scoring.get("flaggedRefs") or []),
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
"refAgreement": scoring.reference_agreement(refs),
|
|
95
|
+
"flaggedRefs": scoring.flagged_references(refs),
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def hints_for(manifest: cf.Manifest) -> list[str]:
|
|
100
|
+
"""Hints recomputed from the manifest, so they never go stale against the current rules."""
|
|
101
|
+
return strength_hints(
|
|
102
|
+
[(int(r.get("width") or 0), int(r.get("height") or 0)) for r in manifest.refs]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def char_encode(
|
|
107
|
+
refs: list[Path | str],
|
|
108
|
+
*,
|
|
109
|
+
name: str,
|
|
110
|
+
description: str = "",
|
|
111
|
+
app_version: str = "",
|
|
112
|
+
char_id: str | None = None,
|
|
113
|
+
created_at: int | None = None,
|
|
114
|
+
) -> cf.CharDoc:
|
|
115
|
+
"""Compile reference images into a `CharDoc`. The caller writes it wherever it belongs."""
|
|
116
|
+
paths = [Path(p) for p in refs]
|
|
117
|
+
if not paths:
|
|
118
|
+
raise ValueError("A character needs at least one reference image.")
|
|
119
|
+
missing = [p.name for p in paths if not p.is_file()]
|
|
120
|
+
if missing:
|
|
121
|
+
raise ValueError(f"Reference image not found: {', '.join(missing)}")
|
|
122
|
+
|
|
123
|
+
now = int(time.time())
|
|
124
|
+
images = [_open(p) for p in paths]
|
|
125
|
+
members: dict[str, bytes] = {}
|
|
126
|
+
manifest = cf.Manifest(
|
|
127
|
+
char_id=char_id or str(uuid.uuid4()),
|
|
128
|
+
name=name.strip() or "Character",
|
|
129
|
+
created_at=created_at or now,
|
|
130
|
+
modified_at=now,
|
|
131
|
+
app_version=app_version,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
for index, (path, image) in enumerate(zip(paths, images, strict=True)):
|
|
135
|
+
member = cf.member_name("refs", index, ".png")
|
|
136
|
+
data = _png_bytes(image)
|
|
137
|
+
members[member] = data
|
|
138
|
+
manifest.refs.append(
|
|
139
|
+
{
|
|
140
|
+
"path": member,
|
|
141
|
+
"sha256": cf.sha256_bytes(data),
|
|
142
|
+
"width": image.width,
|
|
143
|
+
"height": image.height,
|
|
144
|
+
"source_name": path.name,
|
|
145
|
+
}
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
text_member = "text/description.md"
|
|
149
|
+
text_bytes = (description or "").encode("utf-8")
|
|
150
|
+
members[text_member] = text_bytes
|
|
151
|
+
manifest.text = {"path": text_member, "sha256": cf.sha256_bytes(text_bytes)}
|
|
152
|
+
|
|
153
|
+
crops: list[Any | None] = []
|
|
154
|
+
for index, image in enumerate(images):
|
|
155
|
+
crop = scoring.face_crop(image)
|
|
156
|
+
crops.append(crop)
|
|
157
|
+
if crop is None:
|
|
158
|
+
continue
|
|
159
|
+
crop = crop.resize((FACE_CROP_SIZE, FACE_CROP_SIZE))
|
|
160
|
+
member = f"derived/face_{index:03d}.png"
|
|
161
|
+
data = _png_bytes(crop)
|
|
162
|
+
members[member] = data
|
|
163
|
+
manifest.derived.append(
|
|
164
|
+
{
|
|
165
|
+
"path": member,
|
|
166
|
+
"kind": "face_crop",
|
|
167
|
+
"from": cf.member_name("refs", index, ".png"),
|
|
168
|
+
"producer": "yunet",
|
|
169
|
+
"producer_version": scoring.weights.YUNET_VERSION,
|
|
170
|
+
"sha256": cf.sha256_bytes(data),
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
build_payload(manifest, members, images)
|
|
175
|
+
_build_centroids(manifest, members, images, crops)
|
|
176
|
+
manifest.hints = strength_hints([(im.width, im.height) for im in images])
|
|
177
|
+
return cf.CharDoc(manifest=manifest, members=members)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def build_payload(manifest: cf.Manifest, members: dict[str, bytes], images: list[Any]) -> None:
|
|
181
|
+
"""(Re)compile the flux2-klein reference set. Public because ``apply`` rebuilds stale ones."""
|
|
182
|
+
for stale in [m for m in members if m.startswith(f"payloads/{FLUX2_KLEIN_ARCH}/")]:
|
|
183
|
+
members.pop(stale, None)
|
|
184
|
+
files: list[dict[str, Any]] = []
|
|
185
|
+
for index, image in enumerate(images):
|
|
186
|
+
member = f"payloads/{FLUX2_KLEIN_ARCH}/ref_{index:03d}.png"
|
|
187
|
+
data = _png_bytes(normalise_reference(image))
|
|
188
|
+
members[member] = data
|
|
189
|
+
files.append({"path": member, "sha256": cf.sha256_bytes(data)})
|
|
190
|
+
manifest.payloads[FLUX2_KLEIN_ARCH] = {
|
|
191
|
+
"payload_version": 1,
|
|
192
|
+
"encoder": {"id": PAYLOAD_ENCODER_ID, "version": PAYLOAD_ENCODER_VERSION},
|
|
193
|
+
"source_sha256": cf.refs_fingerprint(manifest, PAYLOAD_POLICY),
|
|
194
|
+
"policy": dict(PAYLOAD_POLICY),
|
|
195
|
+
"files": files,
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _build_centroids(
|
|
200
|
+
manifest: cf.Manifest,
|
|
201
|
+
members: dict[str, bytes],
|
|
202
|
+
images: list[Any],
|
|
203
|
+
crops: list[Any | None],
|
|
204
|
+
) -> None:
|
|
205
|
+
centroids: dict[str, str] = {}
|
|
206
|
+
|
|
207
|
+
# Whole frame, not the crop: SFace self-aligns, and mismatching the two sides costs ~10 points.
|
|
208
|
+
face_vectors = [v for image in images if (v := scoring.embed_face(image))]
|
|
209
|
+
face_centroid = scoring.mean_vector(face_vectors)
|
|
210
|
+
if face_centroid:
|
|
211
|
+
member = f"scoring/centroid_{scoring.SFACE_ID}.json"
|
|
212
|
+
members[member] = scoring.dump_centroid(face_centroid, len(face_vectors))
|
|
213
|
+
centroids[scoring.SFACE_ID] = member
|
|
214
|
+
# Every view kept, not just their mean: the face term matches the best-fitting one.
|
|
215
|
+
members[_FACE_EMBEDS] = scoring.dump_embeds(face_vectors)
|
|
216
|
+
|
|
217
|
+
subject_vectors = [v for image in images if (v := scoring.embed_subject(image))]
|
|
218
|
+
subject_centroid = scoring.mean_vector(subject_vectors)
|
|
219
|
+
if subject_centroid:
|
|
220
|
+
member = f"scoring/centroid_{scoring.DINOV2_ID}.json"
|
|
221
|
+
members[member] = scoring.dump_centroid(subject_centroid, len(subject_vectors))
|
|
222
|
+
centroids[scoring.DINOV2_ID] = member
|
|
223
|
+
|
|
224
|
+
manifest.scoring = {
|
|
225
|
+
"encoders": scoring.encoder_versions(),
|
|
226
|
+
"centroids": centroids,
|
|
227
|
+
"faceEmbeds": _FACE_EMBEDS if face_centroid else "",
|
|
228
|
+
"refAgreement": scoring.reference_agreement(face_vectors),
|
|
229
|
+
"flaggedRefs": scoring.flagged_references(face_vectors),
|
|
230
|
+
"face_bearing": bool(face_centroid),
|
|
231
|
+
"blend": {"face": scoring.FACE_WEIGHT, "subject": scoring.SUBJECT_WEIGHT},
|
|
232
|
+
}
|