omnius 1.0.22 → 1.0.24

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.
package/dist/index.js CHANGED
@@ -250342,6 +250342,12 @@ import { spawn as spawn9 } from "node:child_process";
250342
250342
  import { existsSync as existsSync23, statSync as statSync8 } from "node:fs";
250343
250343
  import { chmod as chmod3, mkdir as mkdir11, writeFile as writeFile16 } from "node:fs/promises";
250344
250344
  import { join as join36, resolve as resolve18 } from "node:path";
250345
+ function officialBflModel(model) {
250346
+ return `${OFFICIAL_BFL_ORG}/${model}`;
250347
+ }
250348
+ function normalizeImageGenerationModel(model) {
250349
+ return IMAGE_GENERATION_MODEL_REPLACEMENTS.get(model) ?? model;
250350
+ }
250345
250351
  function parsePercent(text) {
250346
250352
  const match = text.match(/\b(\d{1,3})%\b/);
250347
250353
  if (!match)
@@ -250404,7 +250410,8 @@ function isBackend(value2) {
250404
250410
  function getImageGenerationPreset(model) {
250405
250411
  if (!model)
250406
250412
  return void 0;
250407
- return IMAGE_GENERATION_MODEL_PRESETS.find((preset) => preset.id === model);
250413
+ const resolved = normalizeImageGenerationModel(model);
250414
+ return IMAGE_GENERATION_MODEL_PRESETS.find((preset) => preset.id === resolved);
250408
250415
  }
250409
250416
  function imageGenerationQualityLadder() {
250410
250417
  return IMAGE_GENERATION_QUALITY_LADDER.map((id) => getImageGenerationPreset(id)).filter((preset) => Boolean(preset));
@@ -250412,32 +250419,35 @@ function imageGenerationQualityLadder() {
250412
250419
  function imageGenerationFallbackAlternates(model) {
250413
250420
  if (!model)
250414
250421
  return [];
250415
- return IMAGE_GENERATION_MODEL_PRESETS.filter((preset) => preset.fallbackFor?.includes(model));
250422
+ const resolved = normalizeImageGenerationModel(model);
250423
+ return IMAGE_GENERATION_MODEL_PRESETS.filter((preset) => preset.fallbackFor?.includes(resolved));
250416
250424
  }
250417
250425
  function inferImageGenerationBackend(model, requested) {
250418
250426
  if (requested && isBackend(requested))
250419
250427
  return requested;
250420
250428
  if (!model || model === "auto")
250421
250429
  return "auto";
250422
- const preset = getImageGenerationPreset(model);
250430
+ const resolved = normalizeImageGenerationModel(model);
250431
+ const preset = getImageGenerationPreset(resolved);
250423
250432
  if (preset)
250424
250433
  return preset.backend;
250425
- if (model.startsWith("x/"))
250434
+ if (resolved.startsWith("x/"))
250426
250435
  return "ollama";
250427
- if (model === "sdcpp" || model.startsWith("sdcpp:"))
250436
+ if (resolved === "sdcpp" || resolved.startsWith("sdcpp:"))
250428
250437
  return "sdcpp";
250429
- if (model.startsWith("/") || model.endsWith(".gguf") || model.endsWith(".safetensors") || model.endsWith(".ckpt"))
250438
+ if (resolved.startsWith("/") || resolved.endsWith(".gguf") || resolved.endsWith(".safetensors") || resolved.endsWith(".ckpt"))
250430
250439
  return "sdcpp";
250431
250440
  return "diffusers";
250432
250441
  }
250433
250442
  function imageCandidateFor(model, requestedBackend) {
250434
- let backend = inferImageGenerationBackend(model, requestedBackend);
250443
+ const resolved = normalizeImageGenerationModel(model);
250444
+ let backend = inferImageGenerationBackend(resolved, requestedBackend);
250435
250445
  if (backend === "auto")
250436
250446
  backend = "diffusers";
250437
250447
  return {
250438
- model,
250448
+ model: resolved,
250439
250449
  backend,
250440
- preset: getImageGenerationPreset(model)
250450
+ preset: getImageGenerationPreset(resolved)
250441
250451
  };
250442
250452
  }
250443
250453
  function imageGenerationFallbackCandidates(requestedModel, requestedBackend, allowFallback = true) {
@@ -250460,7 +250470,8 @@ function imageGenerationFallbackCandidates(requestedModel, requestedBackend, all
250460
250470
  }
250461
250471
  if (!allowFallback)
250462
250472
  return candidates.length ? candidates : [imageCandidateFor(DEFAULT_DIFFUSERS_IMAGE_MODEL, requestedBackend)];
250463
- const primaryIndex = requestedModel ? ladder.findIndex((preset) => preset.id === requestedModel) : requestedBackend && requestedBackend !== "auto" ? ladder.findIndex((preset) => preset.backend === requestedBackend) : 0;
250473
+ const normalizedRequestedModel = requestedModel ? normalizeImageGenerationModel(requestedModel) : void 0;
250474
+ const primaryIndex = normalizedRequestedModel ? ladder.findIndex((preset) => preset.id === normalizedRequestedModel) : requestedBackend && requestedBackend !== "auto" ? ladder.findIndex((preset) => preset.backend === requestedBackend) : 0;
250464
250475
  const fallbackTail = primaryIndex >= 0 ? ladder.slice(primaryIndex) : ladder;
250465
250476
  for (const preset of fallbackTail) {
250466
250477
  add2(imageCandidateFor(preset.id));
@@ -250762,13 +250773,34 @@ function parseRunnerJson(stdout) {
250762
250773
  }
250763
250774
  return null;
250764
250775
  }
250765
- var DEFAULT_DIFFUSERS_IMAGE_MODEL, DEFAULT_OLLAMA_IMAGE_MODEL, DIFFUSERS_PYTHON_PACKAGES, SDCPP_PYTHON_PACKAGES, IMAGE_GENERATION_MODEL_PRESETS, IMAGE_GENERATION_QUALITY_LADDER, OLLAMA_IMAGE_MODELS, DIFFUSERS_RUNNER, SDCPP_RUNNER, ImageGenerateTool;
250776
+ var DEFAULT_DIFFUSERS_IMAGE_MODEL, DEFAULT_OLLAMA_IMAGE_MODEL, SECONDARY_FLUX_DEV_MODEL, SECONDARY_FLUX_DEV_MIRROR_MODEL, SECONDARY_FLUX_DEV_COMFY_MODEL, SECONDARY_FLUX_FILL_MODEL, SECONDARY_FLUX_FILL_FP8_MODEL, SECONDARY_FLUX2_MODEL, OFFICIAL_BFL_ORG, IMAGE_GENERATION_MODEL_REPLACEMENTS, DIFFUSERS_PYTHON_PACKAGES, SDCPP_PYTHON_PACKAGES, IMAGE_GENERATION_MODEL_PRESETS, IMAGE_GENERATION_QUALITY_LADDER, OLLAMA_IMAGE_MODELS, DIFFUSERS_RUNNER, SDCPP_RUNNER, ImageGenerateTool;
250766
250777
  var init_image_generate = __esm({
250767
250778
  "packages/execution/dist/tools/image-generate.js"() {
250768
250779
  "use strict";
250769
250780
  init_venv_paths();
250770
250781
  DEFAULT_DIFFUSERS_IMAGE_MODEL = "stabilityai/sdxl-turbo";
250771
250782
  DEFAULT_OLLAMA_IMAGE_MODEL = "x/z-image-turbo";
250783
+ SECONDARY_FLUX_DEV_MODEL = "lllyasviel/flux1-dev-bnb-nf4";
250784
+ SECONDARY_FLUX_DEV_MIRROR_MODEL = "ChuckMcSneed/FLUX.1-dev";
250785
+ SECONDARY_FLUX_DEV_COMFY_MODEL = "Comfy-Org/flux1-dev";
250786
+ SECONDARY_FLUX_FILL_MODEL = "diffusers/FLUX.1-Fill-dev-nf4";
250787
+ SECONDARY_FLUX_FILL_FP8_MODEL = "boricuapab/flux1-fill-dev-fp8";
250788
+ SECONDARY_FLUX2_MODEL = "x/flux2-klein";
250789
+ OFFICIAL_BFL_ORG = "black-forest-labs";
250790
+ IMAGE_GENERATION_MODEL_REPLACEMENTS = /* @__PURE__ */ new Map([
250791
+ [officialBflModel("FLUX.1-dev"), SECONDARY_FLUX_DEV_MODEL],
250792
+ [officialBflModel("FLUX.1-dev-FP8"), SECONDARY_FLUX_DEV_MODEL],
250793
+ [officialBflModel("FLUX.1-Krea-dev"), SECONDARY_FLUX_DEV_COMFY_MODEL],
250794
+ [officialBflModel("FLUX.1-schnell"), SECONDARY_FLUX_DEV_MODEL],
250795
+ [officialBflModel("FLUX.1-Fill-dev"), SECONDARY_FLUX_FILL_MODEL],
250796
+ [officialBflModel("FLUX.1-Kontext-dev"), SECONDARY_FLUX_DEV_MODEL],
250797
+ [officialBflModel("FLUX.1-Kontext-dev-NVFP4"), SECONDARY_FLUX_DEV_MODEL],
250798
+ [officialBflModel("FLUX.2-klein-4B"), SECONDARY_FLUX2_MODEL],
250799
+ [officialBflModel("FLUX.2-klein-4b-fp8"), SECONDARY_FLUX2_MODEL],
250800
+ [officialBflModel("FLUX.2-klein-4b-nvfp4"), SECONDARY_FLUX2_MODEL],
250801
+ [officialBflModel("FLUX.2-klein-base-4b-fp8"), SECONDARY_FLUX2_MODEL],
250802
+ [officialBflModel("FLUX.2-klein-base-4b-nvfp4"), SECONDARY_FLUX2_MODEL]
250803
+ ]);
250772
250804
  DIFFUSERS_PYTHON_PACKAGES = [
250773
250805
  "torch",
250774
250806
  "torchvision",
@@ -250802,7 +250834,7 @@ var init_image_generate = __esm({
250802
250834
  note: "Modern fast image model; good default when available in Ollama."
250803
250835
  },
250804
250836
  {
250805
- id: "x/flux2-klein",
250837
+ id: SECONDARY_FLUX2_MODEL,
250806
250838
  label: "FLUX.2 Klein",
250807
250839
  backend: "ollama",
250808
250840
  install: "ollama pull x/flux2-klein",
@@ -250818,93 +250850,92 @@ var init_image_generate = __esm({
250818
250850
  note: "Compact FLUX-family Ollama path for interactive local generation."
250819
250851
  },
250820
250852
  {
250821
- id: "black-forest-labs/FLUX.1-dev",
250822
- label: "FLUX.1 dev",
250853
+ id: SECONDARY_FLUX_DEV_MODEL,
250854
+ label: "FLUX.1 dev BNB NF4",
250823
250855
  backend: "diffusers",
250824
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model black-forest-labs/FLUX.1-dev --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250856
+ install: 'python3 .omnius/image-gen/diffusers_text2image.py --model lllyasviel/flux1-dev-bnb-nf4 --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250825
250857
  category: "Primary hyper-realistic baseline",
250826
- sizeClass: "12B rectified-flow transformer",
250827
- quality: "Top-tier open-weight photorealism, prompt adherence, texture detail, composition, and typography.",
250828
- minVramGB: 24,
250829
- recommendedVramGB: 48,
250830
- deployment: "Heavy. Best with Diffusers CPU offload, FP8/quantized variants, ComfyUI, multi-GPU, or cloud GPU workers.",
250858
+ sizeClass: "12B FLUX.1 dev NF4",
250859
+ quality: "Traceable lower-memory FLUX.1 dev secondary-source route with strong photorealism and prompt adherence; avoids gated official BFL downloads.",
250860
+ minVramGB: 12,
250861
+ recommendedVramGB: 16,
250862
+ deployment: "Best with BNB-aware Diffusers/Forge-style runtimes. Falls through cleanly if the current runner cannot load it.",
250831
250863
  steps: 28,
250832
250864
  guidance: 3.5,
250833
250865
  width: 1024,
250834
250866
  height: 1024,
250835
- note: "Primary serious-generation baseline for maximum photorealism."
250867
+ note: "Primary serious-generation FLUX route using the secondary-source NF4 weights from the research package."
250836
250868
  },
250837
250869
  {
250838
- id: "black-forest-labs/FLUX.1-dev-FP8",
250839
- label: "FLUX.1 dev FP8",
250870
+ id: SECONDARY_FLUX_DEV_MIRROR_MODEL,
250871
+ label: "FLUX.1 dev mirror",
250840
250872
  backend: "diffusers",
250841
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model black-forest-labs/FLUX.1-dev-FP8 --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250842
- category: "Official FLUX fallback",
250843
- sizeClass: "12B FLUX.1 dev FP8",
250844
- quality: "Official lower-precision FLUX.1 dev route; best first fallback when full FLUX.1 dev is unavailable or too heavy.",
250845
- minVramGB: 16,
250846
- recommendedVramGB: 24,
250847
- deployment: "Prefer this before third-party mirrors when loader support is available.",
250873
+ install: 'python3 .omnius/image-gen/diffusers_text2image.py --model ChuckMcSneed/FLUX.1-dev --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250874
+ category: "Traceable FLUX fallback",
250875
+ sizeClass: "12B FLUX.1 dev mirror",
250876
+ quality: "Full FLUX.1 dev mirror fallback from the secondary-source inventory; higher trust than anonymous mirrors, lower priority than quantized routes.",
250877
+ minVramGB: 24,
250878
+ recommendedVramGB: 48,
250879
+ deployment: "Use after the NF4 route if full-weight mirror provenance and license terms are acceptable.",
250848
250880
  steps: 28,
250849
250881
  guidance: 3.5,
250850
250882
  width: 1024,
250851
250883
  height: 1024,
250852
- fallbackFor: ["black-forest-labs/FLUX.1-dev"],
250853
- note: "Official BFL FP8 fallback for FLUX.1 dev."
250884
+ fallbackFor: [SECONDARY_FLUX_DEV_MODEL],
250885
+ note: "Traceable mirror fallback for FLUX.1 dev from the research package."
250854
250886
  },
250855
250887
  {
250856
- id: "black-forest-labs/FLUX.1-Krea-dev",
250857
- label: "FLUX.1 Krea dev",
250888
+ id: SECONDARY_FLUX_DEV_COMFY_MODEL,
250889
+ label: "FLUX.1 dev Comfy-Org",
250858
250890
  backend: "diffusers",
250859
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model black-forest-labs/FLUX.1-Krea-dev --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250860
- category: "Official FLUX fallback",
250861
- sizeClass: "12B FLUX.1 dev-family",
250862
- quality: "Official FLUX.1 dev-family aesthetic variant; useful when the base dev repo is unavailable and the requested task tolerates an opinionated realism bias.",
250863
- minVramGB: 24,
250864
- recommendedVramGB: 48,
250865
- deployment: "Heavy Diffusers/ComfyUI route with FLUX.1 dev-family license considerations.",
250891
+ install: 'python3 .omnius/image-gen/diffusers_text2image.py --model Comfy-Org/flux1-dev --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250892
+ category: "Traceable FLUX fallback",
250893
+ sizeClass: "12B FLUX.1 dev single-file/FP8 family",
250894
+ quality: "ComfyUI-oriented secondary-source FLUX.1 dev route; useful when the quantized/default loader path is unavailable.",
250895
+ minVramGB: 16,
250896
+ recommendedVramGB: 24,
250897
+ deployment: "Best in ComfyUI/single-file workflows; the generic Diffusers runner will try it and fall through if the repo layout is incompatible.",
250866
250898
  steps: 28,
250867
250899
  guidance: 3.5,
250868
250900
  width: 1024,
250869
250901
  height: 1024,
250870
- fallbackFor: ["black-forest-labs/FLUX.1-dev"],
250871
- note: "Official aesthetic FLUX.1 fallback."
250902
+ fallbackFor: [SECONDARY_FLUX_DEV_MODEL, SECONDARY_FLUX_DEV_MIRROR_MODEL],
250903
+ note: "Traceable Comfy-Org FLUX.1 fallback from the research package."
250872
250904
  },
250873
250905
  {
250874
- id: "lllyasviel/flux1-dev-bnb-nf4",
250875
- label: "FLUX.1 dev BNB NF4",
250906
+ id: SECONDARY_FLUX_FILL_MODEL,
250907
+ label: "FLUX.1 Fill dev NF4",
250876
250908
  backend: "diffusers",
250877
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model lllyasviel/flux1-dev-bnb-nf4 --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250909
+ install: 'python3 .omnius/image-gen/diffusers_text2image.py --model diffusers/FLUX.1-Fill-dev-nf4 --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250878
250910
  category: "Traceable FLUX fallback",
250879
- sizeClass: "12B FLUX.1 dev NF4",
250880
- quality: "Lower-memory community quantization; useful after official BFL sources, with some possible quality loss and loader brittleness.",
250911
+ sizeClass: "12B FLUX.1 Fill NF4",
250912
+ quality: "Lower-memory fill/inpainting secondary-source route; listed for FLUX-family coverage rather than generic text-to-image priority.",
250881
250913
  minVramGB: 12,
250882
250914
  recommendedVramGB: 16,
250883
- deployment: "Best with BNB-aware Diffusers/Forge-style runtimes. Falls through cleanly if the current runner cannot load it.",
250915
+ deployment: "Best for fill/inpainting workflows. The generic text-to-image runner may not be the ideal loader, so it is not in the default ladder.",
250884
250916
  steps: 28,
250885
250917
  guidance: 3.5,
250886
250918
  width: 1024,
250887
250919
  height: 1024,
250888
- fallbackFor: ["black-forest-labs/FLUX.1-dev", "black-forest-labs/FLUX.1-dev-FP8"],
250889
- note: "Traceable low-VRAM NF4 fallback for FLUX.1 dev."
250920
+ note: "Traceable NF4 fallback for FLUX.1 Fill dev from the research package."
250890
250921
  },
250891
250922
  {
250892
- id: "ChuckMcSneed/FLUX.1-dev",
250893
- label: "FLUX.1 dev mirror",
250923
+ id: SECONDARY_FLUX_FILL_FP8_MODEL,
250924
+ label: "FLUX.1 Fill dev FP8",
250894
250925
  backend: "diffusers",
250895
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model ChuckMcSneed/FLUX.1-dev --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250926
+ install: 'python3 .omnius/image-gen/diffusers_text2image.py --model boricuapab/flux1-fill-dev-fp8 --steps 28 --guidance 3.5 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250896
250927
  category: "Traceable FLUX fallback",
250897
- sizeClass: "12B FLUX.1 dev mirror",
250898
- quality: "Lower-priority mirror fallback for FLUX.1 dev. Use only after official and reputable quantized options fail.",
250899
- minVramGB: 24,
250900
- recommendedVramGB: 48,
250901
- deployment: "Treat as lower-trust than official BFL and well-known quantized conversions; verify provenance and license before relying on it.",
250928
+ sizeClass: "12B FLUX.1 Fill FP8",
250929
+ quality: "Traceable FP8 fill/inpainting conversion from the secondary-source inventory; gated status can vary.",
250930
+ minVramGB: 12,
250931
+ recommendedVramGB: 16,
250932
+ deployment: "Best for fill/inpainting workflows when accepted access terms allow the repo.",
250902
250933
  steps: 28,
250903
250934
  guidance: 3.5,
250904
250935
  width: 1024,
250905
250936
  height: 1024,
250906
- fallbackFor: ["black-forest-labs/FLUX.1-dev", "black-forest-labs/FLUX.1-dev-FP8"],
250907
- note: "Traceable mirror fallback for FLUX.1 dev."
250937
+ fallbackFor: [SECONDARY_FLUX_FILL_MODEL],
250938
+ note: "Traceable FP8 fallback for FLUX.1 Fill dev from the research package."
250908
250939
  },
250909
250940
  {
250910
250941
  id: "stabilityai/stable-diffusion-3.5-large",
@@ -250923,23 +250954,6 @@ var init_image_generate = __esm({
250923
250954
  height: 1024,
250924
250955
  note: "Primary serious-generation baseline for the Stable Diffusion ecosystem."
250925
250956
  },
250926
- {
250927
- id: "black-forest-labs/FLUX.1-schnell",
250928
- label: "FLUX.1 schnell",
250929
- backend: "diffusers",
250930
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model black-forest-labs/FLUX.1-schnell --steps 4 --guidance 0 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250931
- category: "Fast large-model iteration",
250932
- sizeClass: "12B rectified-flow transformer",
250933
- quality: "FLUX-style output with fewer steps; better for rapid iteration than absolute peak quality.",
250934
- minVramGB: 16,
250935
- recommendedVramGB: 24,
250936
- deployment: "Use for fast prompt iteration; verify current license terms before commercial use.",
250937
- steps: 4,
250938
- guidance: 0,
250939
- width: 1024,
250940
- height: 1024,
250941
- note: "Fast FLUX-family iteration path."
250942
- },
250943
250957
  {
250944
250958
  id: "stabilityai/stable-diffusion-3.5-large-turbo",
250945
250959
  label: "SD3.5 Large Turbo",
@@ -250990,56 +251004,6 @@ var init_image_generate = __esm({
250990
251004
  height: 1024,
250991
251005
  note: "Efficient modern large image model."
250992
251006
  },
250993
- {
250994
- id: "black-forest-labs/FLUX.2-klein-4B",
250995
- label: "FLUX.2 Klein 4B",
250996
- backend: "diffusers",
250997
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model black-forest-labs/FLUX.2-klein-4B --steps 8 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
250998
- category: "Modern deployable",
250999
- sizeClass: "4B compact FLUX-family",
251000
- quality: "Bridge between practical deployment and modern FLUX-family visual quality.",
251001
- minVramGB: 12,
251002
- recommendedVramGB: 16,
251003
- deployment: "Better fit for consumer GPU experimentation than 8B-12B baselines.",
251004
- steps: 8,
251005
- width: 1024,
251006
- height: 1024,
251007
- note: "More deployable compact FLUX-family model."
251008
- },
251009
- {
251010
- id: "black-forest-labs/FLUX.2-klein-4b-fp8",
251011
- label: "FLUX.2 Klein 4B FP8",
251012
- backend: "diffusers",
251013
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model black-forest-labs/FLUX.2-klein-4b-fp8 --steps 8 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
251014
- category: "Official FLUX fallback",
251015
- sizeClass: "4B compact FLUX-family FP8",
251016
- quality: "Official lower-precision FLUX.2 Klein route with better deployment fit than full-precision 4B.",
251017
- minVramGB: 8,
251018
- recommendedVramGB: 12,
251019
- deployment: "Preferred lower-memory official FLUX.2 fallback when compatible with the current loader.",
251020
- steps: 8,
251021
- width: 1024,
251022
- height: 1024,
251023
- fallbackFor: ["black-forest-labs/FLUX.2-klein-4B", "x/flux2-klein"],
251024
- note: "Official FP8 fallback for FLUX.2 Klein."
251025
- },
251026
- {
251027
- id: "black-forest-labs/FLUX.2-klein-4b-nvfp4",
251028
- label: "FLUX.2 Klein 4B NVFP4",
251029
- backend: "diffusers",
251030
- install: 'python3 .omnius/image-gen/diffusers_text2image.py --model black-forest-labs/FLUX.2-klein-4b-nvfp4 --steps 8 --width 1024 --height 1024 --prompt "..." --output .omnius/images/out.png',
251031
- category: "Official FLUX fallback",
251032
- sizeClass: "4B compact FLUX-family NVFP4",
251033
- quality: "Official NVIDIA-oriented low-precision FLUX.2 Klein fallback.",
251034
- minVramGB: 8,
251035
- recommendedVramGB: 12,
251036
- deployment: "Use when the runtime/GPU supports the NVFP4 path; otherwise the fallback ladder continues.",
251037
- steps: 8,
251038
- width: 1024,
251039
- height: 1024,
251040
- fallbackFor: ["black-forest-labs/FLUX.2-klein-4B", "x/flux2-klein", "black-forest-labs/FLUX.2-klein-4b-fp8"],
251041
- note: "Official NVFP4 fallback for FLUX.2 Klein."
251042
- },
251043
251007
  {
251044
251008
  id: "deepseek-ai/Janus-Pro-7B",
251045
251009
  label: "Janus-Pro-7B",
@@ -251193,13 +251157,12 @@ var init_image_generate = __esm({
251193
251157
  }
251194
251158
  ];
251195
251159
  IMAGE_GENERATION_QUALITY_LADDER = [
251196
- "black-forest-labs/FLUX.1-dev",
251197
- "stabilityai/stable-diffusion-3.5-large",
251160
+ SECONDARY_FLUX_DEV_MODEL,
251161
+ SECONDARY_FLUX_DEV_MIRROR_MODEL,
251162
+ SECONDARY_FLUX_DEV_COMFY_MODEL,
251198
251163
  DEFAULT_OLLAMA_IMAGE_MODEL,
251199
- "black-forest-labs/FLUX.1-schnell",
251200
- "stabilityai/stable-diffusion-3.5-large-turbo",
251201
251164
  "Tongyi-MAI/Z-Image-Turbo",
251202
- "black-forest-labs/FLUX.2-klein-4B",
251165
+ SECONDARY_FLUX2_MODEL,
251203
251166
  DEFAULT_DIFFUSERS_IMAGE_MODEL,
251204
251167
  "Efficient-Large-Model/Sana_Sprint_0.6B_1024px_diffusers",
251205
251168
  "SimianLuo/LCM_Dreamshaper_v7",
@@ -516440,6 +516403,7 @@ __export(dist_exports, {
516440
516403
  addProjectConstraint: () => addProjectConstraint,
516441
516404
  addSessionConstraint: () => addSessionConstraint,
516442
516405
  applyPatch: () => applyPatch,
516406
+ audioGenerationDir: () => audioGenerationDir,
516443
516407
  audioGenerationSetupPlan: () => audioGenerationSetupPlan,
516444
516408
  audioGenerationVenvDir: () => audioGenerationVenvDir,
516445
516409
  audioOutputDir: () => audioOutputDir,
@@ -566652,7 +566616,7 @@ ${tuiBgSeq()}`);
566652
566616
  render2();
566653
566617
  }
566654
566618
  } else if (seq === "\x1B[3~" && opts.onDelete) {
566655
- if (!isSkippable(cursor) && matchSet.has(cursor) && items[cursor].key !== activeKey) {
566619
+ if (!isSkippable(cursor) && matchSet.has(cursor) && (opts.allowDeleteActive || items[cursor].key !== activeKey)) {
566656
566620
  deleteConfirmIdx = cursor;
566657
566621
  deleteConfirmSel = false;
566658
566622
  render2();
@@ -566715,6 +566679,10 @@ ${tuiBgSeq()}`);
566715
566679
  }
566716
566680
  scrollOffset = 0;
566717
566681
  render2();
566682
+ } else if (opts.backspaceDeletes && opts.onDelete && !isSkippable(cursor) && matchSet.has(cursor) && (opts.allowDeleteActive || items[cursor].key !== activeKey)) {
566683
+ deleteConfirmIdx = cursor;
566684
+ deleteConfirmSel = false;
566685
+ render2();
566718
566686
  } else if (hasBreadcrumbs) {
566719
566687
  cleanup();
566720
566688
  resolve48({ confirmed: false, key: "__back__", index: cursor });
@@ -586430,6 +586398,58 @@ function renderImageModelList() {
586430
586398
  }
586431
586399
  }
586432
586400
  }
586401
+ function modelCacheSlug(model) {
586402
+ if (!model || !model.includes("/")) return null;
586403
+ return `models--${model.replace(/\//g, "--")}`;
586404
+ }
586405
+ function cacheCandidatePaths(root, model) {
586406
+ const slug = modelCacheSlug(model);
586407
+ if (!slug) return [];
586408
+ return [
586409
+ join110(root, "huggingface", "hub", slug),
586410
+ join110(root, "huggingface", "transformers", slug),
586411
+ join110(root, "huggingface", "diffusers", slug),
586412
+ join110(root, "cache", "huggingface", "hub", slug)
586413
+ ];
586414
+ }
586415
+ function removeCachedModelPaths(root, model) {
586416
+ const removed = [];
586417
+ for (const path11 of cacheCandidatePaths(root, model)) {
586418
+ if (!existsSync96(path11)) continue;
586419
+ rmSync3(path11, { recursive: true, force: true });
586420
+ removed.push(path11);
586421
+ }
586422
+ return removed;
586423
+ }
586424
+ function ollamaApiBase(ctx3) {
586425
+ return String(ctx3.config.backendUrl || "http://localhost:11434").replace(/\/v1\/?$/, "").replace(/\/$/, "");
586426
+ }
586427
+ async function deleteOllamaWeights(ctx3, model) {
586428
+ const resp = await fetch(`${ollamaApiBase(ctx3)}/api/delete`, {
586429
+ method: "DELETE",
586430
+ headers: { "Content-Type": "application/json" },
586431
+ body: JSON.stringify({ name: model }),
586432
+ signal: AbortSignal.timeout(3e4)
586433
+ });
586434
+ if (resp.status === 404) return `Ollama model not present: ${model}`;
586435
+ if (!resp.ok) {
586436
+ const text = await resp.text().catch(() => "");
586437
+ throw new Error(`Ollama delete failed: HTTP ${resp.status}${text ? ` - ${text.slice(0, 300)}` : ""}`);
586438
+ }
586439
+ return `Deleted Ollama model weights: ${model}`;
586440
+ }
586441
+ async function deleteImageModelWeights(ctx3, preset) {
586442
+ const messages2 = [];
586443
+ if (preset.backend === "ollama") {
586444
+ messages2.push(await deleteOllamaWeights(ctx3, preset.id));
586445
+ } else if (preset.backend === "diffusers") {
586446
+ const removed = removeCachedModelPaths(imageGenerationDir(ctx3.repoRoot), preset.id);
586447
+ messages2.push(removed.length > 0 ? `Deleted ${removed.length} cached image model path(s) for ${preset.id}.` : `No cached image weights found for ${preset.id}.`);
586448
+ } else {
586449
+ messages2.push("stable-diffusion.cpp uses explicit local checkpoint paths; remove the chosen checkpoint file directly if needed.");
586450
+ }
586451
+ return messages2;
586452
+ }
586433
586453
  async function showImageModelsMenu(ctx3, hasLocal) {
586434
586454
  const settings = resolveSettings(ctx3.repoRoot);
586435
586455
  const specs = detectSystemSpecs();
@@ -586454,7 +586474,29 @@ async function showImageModelsMenu(ctx3, hasLocal) {
586454
586474
  skipKeys: ["hdr:models"],
586455
586475
  rl: ctx3.rl,
586456
586476
  availableRows: ctx3.availableContentRows?.(),
586457
- customKeyHint: " Enter to select"
586477
+ customKeyHint: " Enter select Del/Backspace delete weights",
586478
+ backspaceDeletes: true,
586479
+ allowDeleteActive: true,
586480
+ onDelete: (item, done) => {
586481
+ if (!item.key.startsWith("model:")) {
586482
+ done(false);
586483
+ return;
586484
+ }
586485
+ const model = item.key.slice("model:".length);
586486
+ const preset = IMAGE_GENERATION_MODEL_PRESETS.find((candidate) => candidate.id === model);
586487
+ if (!preset) {
586488
+ renderWarning(`No image preset found for ${model}`);
586489
+ done(false);
586490
+ return;
586491
+ }
586492
+ deleteImageModelWeights(ctx3, preset).then((messages2) => {
586493
+ for (const message2 of messages2) renderInfo(message2);
586494
+ done(false);
586495
+ }).catch((err) => {
586496
+ renderError(`Image weight delete failed: ${err instanceof Error ? err.message : String(err)}`);
586497
+ done(false);
586498
+ });
586499
+ }
586458
586500
  });
586459
586501
  if (!result.confirmed || !result.key) return;
586460
586502
  if (result.key.startsWith("setup:")) {
@@ -586674,6 +586716,13 @@ function renderAudioModelList(kind) {
586674
586716
  }
586675
586717
  }
586676
586718
  }
586719
+ async function deleteAudioModelWeights(ctx3, preset) {
586720
+ if (preset.backend === "project") {
586721
+ return ["Project audio generation profiles do not own a managed model-weight cache."];
586722
+ }
586723
+ const removed = removeCachedModelPaths(audioGenerationDir(ctx3.repoRoot), preset.id);
586724
+ return [removed.length > 0 ? `Deleted ${removed.length} cached ${preset.kind} model path(s) for ${preset.id}.` : `No cached ${preset.kind} weights found for ${preset.id}.`];
586725
+ }
586677
586726
  async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
586678
586727
  const settings = resolveSettings(ctx3.repoRoot);
586679
586728
  const specs = detectSystemSpecs();
@@ -586709,7 +586758,29 @@ async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
586709
586758
  skipKeys: ["hdr:models"],
586710
586759
  rl: ctx3.rl,
586711
586760
  availableRows: ctx3.availableContentRows?.(),
586712
- customKeyHint: " Enter to select"
586761
+ customKeyHint: " Enter select Del/Backspace delete weights",
586762
+ backspaceDeletes: true,
586763
+ allowDeleteActive: true,
586764
+ onDelete: (item, done) => {
586765
+ if (!item.key.startsWith("model:")) {
586766
+ done(false);
586767
+ return;
586768
+ }
586769
+ const model = item.key.slice("model:".length);
586770
+ const preset = AUDIO_GENERATION_MODEL_PRESETS.find((candidate) => candidate.kind === kind && candidate.id === model);
586771
+ if (!preset) {
586772
+ renderWarning(`No ${kind} preset found for ${model}`);
586773
+ done(false);
586774
+ return;
586775
+ }
586776
+ deleteAudioModelWeights(ctx3, preset).then((messages2) => {
586777
+ for (const message2 of messages2) renderInfo(message2);
586778
+ done(false);
586779
+ }).catch((err) => {
586780
+ renderError(`${kind} weight delete failed: ${err instanceof Error ? err.message : String(err)}`);
586781
+ done(false);
586782
+ });
586783
+ }
586713
586784
  });
586714
586785
  if (!result.confirmed || !result.key) return;
586715
586786
  if (result.key.startsWith("setup:")) {
@@ -597213,6 +597284,7 @@ function buildTelegramCreativeTools(repoRoot, chatId, backendUrl, imageDefaults
597213
597284
  ensureManifest(root);
597214
597285
  return [
597215
597286
  scopedTool(new FileWriteTool(root), root, "create"),
597287
+ scopedTool(new FileEditTool(root), root, "edit"),
597216
597288
  scopedTool(new StructuredFileTool(root), root, "create"),
597217
597289
  scopedTool(new ImageGenerateTool(root, backendUrl, imageDefaults), root, "generate"),
597218
597290
  scopedTool(new AudioGenerateTool(root, audioDefaults), root, "generate"),
@@ -597279,6 +597351,7 @@ function scopedTool(base3, root, mode) {
597279
597351
  }
597280
597352
  }
597281
597353
  const pathKey = PATH_KEYS.find((key) => typeof next[key] === "string" && String(next[key]).trim());
597354
+ let restoredEditPath = null;
597282
597355
  if (pathKey) {
597283
597356
  const guarded = guardPath(rootAbs, String(next[pathKey]));
597284
597357
  if (!guarded.ok) return denied(guarded.error);
@@ -597289,6 +597362,14 @@ function scopedTool(base3, root, mode) {
597289
597362
  if (mode === "edit" && !manifestHas(rootAbs, guarded.path.rel)) {
597290
597363
  return denied(`Public Telegram creative tools can only edit files created in this chat workspace: ${guarded.path.rel}`);
597291
597364
  }
597365
+ if (mode === "edit" && !existsSync104(guarded.path.abs)) {
597366
+ const materialized = materializeTelegramCreativeArtifactForSend(rootAbs, guarded.path.rel);
597367
+ if (!materialized.ok) return denied(materialized.error);
597368
+ mkdirSync59(dirname33(guarded.path.abs), { recursive: true });
597369
+ writeFileSync55(guarded.path.abs, readFileSync85(materialized.path));
597370
+ materialized.cleanup?.();
597371
+ restoredEditPath = guarded.path.abs;
597372
+ }
597292
597373
  if (mode === "create" && existsSync104(guarded.path.abs) && !manifestHas(rootAbs, guarded.path.rel)) {
597293
597374
  return denied(`Refusing to overwrite a file that is not owned by this chat workspace manifest: ${guarded.path.rel}`);
597294
597375
  }
@@ -597297,9 +597378,14 @@ function scopedTool(base3, root, mode) {
597297
597378
  return denied(`${base3.name} requires a path inside the public creative workspace.`);
597298
597379
  }
597299
597380
  const result = await base3.execute(next);
597300
- if (result.success && mode === "create" && pathKey) {
597381
+ if (result.success && (mode === "create" || mode === "edit") && pathKey) {
597301
597382
  const guarded = guardPath(rootAbs, String(args[pathKey]));
597302
597383
  if (guarded.ok) rememberCreated(rootAbs, guarded.path.abs);
597384
+ } else if (restoredEditPath) {
597385
+ try {
597386
+ unlinkSync19(restoredEditPath);
597387
+ } catch {
597388
+ }
597303
597389
  }
597304
597390
  if (result.success) {
597305
597391
  for (const path11 of collectGeneratedArtifactPathsFromText(result.output, rootAbs)) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.22",
9
+ "version": "1.0.24",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",