AndrewRqy commited on
Commit
dd4200b
·
1 Parent(s): 7d8efb5

Add ORACLES_VISUAL_MODE toggle — lean default, full enabled via --full or env var

Browse files
Files changed (3) hide show
  1. Dockerfile +2 -1
  2. app.py +101 -49
  3. run.sh +21 -0
Dockerfile CHANGED
@@ -29,6 +29,7 @@ EXPOSE 7860
29
  ENV GRADIO_SERVER_NAME=0.0.0.0 \
30
  GRADIO_SERVER_PORT=7860 \
31
  GRADIO_ANALYTICS_ENABLED=False \
32
- PYTHONUNBUFFERED=1
 
33
 
34
  CMD ["python", "app.py"]
 
29
  ENV GRADIO_SERVER_NAME=0.0.0.0 \
30
  GRADIO_SERVER_PORT=7860 \
31
  GRADIO_ANALYTICS_ENABLED=False \
32
+ PYTHONUNBUFFERED=1 \
33
+ ORACLES_VISUAL_MODE=lean
34
 
35
  CMD ["python", "app.py"]
app.py CHANGED
@@ -75,6 +75,23 @@ _PARALLAX_PNG = _HERE / "assets" / "parallax" / "banner_near.png"
75
  _GRIMOIRE_TEXTURE_PNG = _HERE / "assets" / "sprites" / "grimoire_page_texture.png"
76
 
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  # ---------------------------------------------------------------------------
79
  # Pixel-art book frame: leather binding (via CSS border-image 9-slice), a
80
  # vertical spine with raised bands and stitching, and a red ribbon bookmark.
@@ -298,13 +315,12 @@ def _grimoire_texture_css() -> str:
298
  texture as a background-image on .grimoire-page, if the PNG exists.
299
  Returns empty string otherwise (so the CSS-only gradients still apply).
300
 
301
- PERF: this currently returns "" unconditionally. The texture is ~70 KB
302
- base64-inlined into the initial CSS. HF Space's slow egress made every
303
- cold load pay that cost. The PNG file stays on disk; re-enabling means
304
- just deleting the early return below.
305
  """
306
- return ""
307
- # ---- disabled — leaving the original implementation below ----
308
  if not _GRIMOIRE_TEXTURE_PNG.exists():
309
  return ""
310
  try:
@@ -502,11 +518,19 @@ def _grimoire_summary_html(state: GameState) -> str:
502
  for o in state.oracles:
503
  text = (o.text or "").strip() or blank_label
504
  items.append(f"<li><em>{_md_safe(text)}</em></li>")
505
- # PERF: skip the open-book illustration above the five-oracle summary.
506
- # The PNG was ~200-300 KB and added an extra slow HTTP fetch to the
507
- # closing-grimoire spread. The numbered list with the strong heading
508
- # carries the meaning on its own.
509
- book_img = ""
 
 
 
 
 
 
 
 
510
  header = _md_safe(_t("summary_five_sealed", lang))
511
  return (
512
  "<div class='grimoire-summary'>"
@@ -545,11 +569,14 @@ def _pipeline_demo_html(state: Optional[GameState] = None) -> str:
545
  # Pixel-art sprites + backdrop pre-loaded as data URIs. The
546
  # `_sprite_data_uri_app` helper caches per name, so reading the same
547
  # sprite twice in this function only hits disk once.
548
- # PERF: skip the demo card backdrop image. The PNG was the complex
549
- # painted background behind the wizard's three pipeline-mode dream
550
- # panels; ~200-400 KB. The panels still have their own CSS borders
551
- # and shading so the layout still reads.
552
- bg_style = ""
 
 
 
553
  tag_inscribes = _t("demo_tag_inscribes", lang)
554
  tag_meets = _t("demo_tag_meets", lang)
555
  tag_somehow = _t("demo_tag_somehow", lang)
@@ -693,10 +720,10 @@ def _inscribe_decoration_html(state: Optional[GameState] = None) -> str:
693
  _sprite_data_uri_app(f"hero_{theme_key_for_sprites}")
694
  or _sprite_data_uri_app("hero")
695
  )
696
- # PERF: skip the wizard-desk backdrop image. The PNG is ~200-400 KB
697
- # and was being loaded behind the mentor/apprentice figures on the
698
- # front page. Replaced with a CSS gradient via empty desk_uri.
699
- desk_uri = ""
700
  if not wizard_uri or not hero_uri:
701
  fallback = (
702
  "<div class='oracle-inscribe-figs' style='text-align:center;"
@@ -819,19 +846,28 @@ def _banner_html(state: Optional[GameState] = None) -> str:
819
  is_compact = mode in ("trial", "epilogue", "send_off")
820
  extra_cls = " oracle-banner-compact" if is_compact else ""
821
 
822
- # PERF: parallax PNG bypassed. The PNG is ~455 KB and was eating
823
- # 30+ seconds per first page-load over the HF Space's slow egress
824
- # bandwidth (~15 KB/s). Use the CSS-gradient fallback unconditionally.
825
- # The PNG file is left on disk so it can be restored later by removing
826
- # this hard-coded gradient branch.
827
- result = (
828
- f"<div class='oracle-banner{extra_cls}' style='background:"
829
- "linear-gradient(180deg,var(--w-panel) 0%, var(--w-night) 100%);'>"
830
- "<div class='oracle-banner-overlay'>"
831
- f"<div class='oracle-banner-title'>{title}</div>"
832
- f"<div class='oracle-banner-sub'>{subtitle}</div>"
833
- "</div></div>"
834
- )
 
 
 
 
 
 
 
 
 
835
  _BANNER_HTML_CACHE[cache_key] = result
836
  return result
837
 
@@ -912,14 +948,34 @@ def _global_sprite_vars_html() -> str:
912
 
913
 
914
  def _phase_backdrop_styles_html() -> str:
915
- """One-time ``<style>`` block wiring per-phase pixel-art ambient textures.
916
-
917
- PERF: disabled. The four backdrop PNGs were 200-500 KB each and got
918
- fetched on first paint of the matching phase. CSS gradients elsewhere
919
- in the stylesheet still apply on the phase Groups. Sprites stay on
920
- disk; re-enable by removing the early return.
 
 
 
 
921
  """
922
- return ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
923
 
924
 
925
  def _theme_style_overrides_html(state: Optional[GameState] = None) -> str:
@@ -3395,18 +3451,14 @@ def _composed_scene_html(state: GameState) -> str:
3395
  return landscape
3396
  return _sprite_data_uri_app(category) or ""
3397
 
3398
- # PERF: skip the env (landscape) backdrop. Each scene_<theme>_landscape
3399
- # PNG is ~200-500 KB and triggers an extra HTTP request that's slow over
3400
- # HF Space's egress. The hero + obstacle sprites still load (small,
3401
- # narratively essential). The scene gets a CSS-gradient sky instead.
3402
- env_uri = ""
3403
  hero_uri = _theme_pick("hero")
3404
  ob_uri = _theme_pick(ob_name) if ob_name else ""
3405
 
3406
- # No early bailout — we now always render the composed scene with a
3407
- # CSS-gradient backdrop, even with env_uri empty. Hero + obstacle
3408
- # carry the visual load.
3409
-
3410
  dragon_attr = ' data-dragon="true"' if is_dragon else ""
3411
  hero_img = (
3412
  f"<img class='scene-hero' src='{hero_uri}' alt='hero'/>"
 
75
  _GRIMOIRE_TEXTURE_PNG = _HERE / "assets" / "sprites" / "grimoire_page_texture.png"
76
 
77
 
78
+ def _full_visual_mode() -> bool:
79
+ """Visual-mode toggle. Read from $ORACLES_VISUAL_MODE on every call so
80
+ it stays accurate across reloads.
81
+
82
+ - ``lean`` (default, HF Space): skip heavy decorative PNGs — parallax
83
+ banner, grimoire parchment, the four phase backdrops, the scene
84
+ landscapes, the wizard-desk backdrop, the open-book illustration,
85
+ and the pipeline-demo card backdrop. Total saving: ~2-3 MB per
86
+ cold load on HF Space's slow egress bandwidth.
87
+ - ``full``: enable everything. Use locally where bandwidth is fast.
88
+
89
+ To run locally in full mode: ``ORACLES_VISUAL_MODE=full ./run.sh``
90
+ or pass ``--full`` to ``run.sh`` (which sets the env var).
91
+ """
92
+ return os.environ.get("ORACLES_VISUAL_MODE", "lean").strip().lower() == "full"
93
+
94
+
95
  # ---------------------------------------------------------------------------
96
  # Pixel-art book frame: leather binding (via CSS border-image 9-slice), a
97
  # vertical spine with raised bands and stitching, and a red ribbon bookmark.
 
315
  texture as a background-image on .grimoire-page, if the PNG exists.
316
  Returns empty string otherwise (so the CSS-only gradients still apply).
317
 
318
+ Skipped entirely in lean mode (default) the texture is ~70 KB
319
+ base64-inlined into the initial CSS, which on HF Space's slow egress
320
+ adds noticeable cold-load time. Set ORACLES_VISUAL_MODE=full to enable.
 
321
  """
322
+ if not _full_visual_mode():
323
+ return ""
324
  if not _GRIMOIRE_TEXTURE_PNG.exists():
325
  return ""
326
  try:
 
518
  for o in state.oracles:
519
  text = (o.text or "").strip() or blank_label
520
  items.append(f"<li><em>{_md_safe(text)}</em></li>")
521
+ # Lean mode (default for HF Space): skip the open-book illustration
522
+ # the PNG was ~200-300 KB. The heading + numbered list carry the
523
+ # meaning. Full mode restores the illustration above the list.
524
+ if _full_visual_mode():
525
+ book_uri = _sprite_data_uri_app("open_book_spread")
526
+ alt_text = _t("alt_sealed_grimoire", lang)
527
+ book_img = (
528
+ f"<img class='grimoire-summary-book' src='{book_uri}' "
529
+ f"alt='{_md_safe(alt_text)}'/>"
530
+ if book_uri else ""
531
+ )
532
+ else:
533
+ book_img = ""
534
  header = _md_safe(_t("summary_five_sealed", lang))
535
  return (
536
  "<div class='grimoire-summary'>"
 
569
  # Pixel-art sprites + backdrop pre-loaded as data URIs. The
570
  # `_sprite_data_uri_app` helper caches per name, so reading the same
571
  # sprite twice in this function only hits disk once.
572
+ # Lean mode (default for HF Space): skip the demo card painted
573
+ # backdrop (~200-400 KB). Panels still have CSS borders + shading.
574
+ # Full mode restores the painted background.
575
+ if _full_visual_mode():
576
+ bg = _sprite_data_uri_app("demo_card_backdrop")
577
+ bg_style = f"background-image:url('{bg}');" if bg else ""
578
+ else:
579
+ bg_style = ""
580
  tag_inscribes = _t("demo_tag_inscribes", lang)
581
  tag_meets = _t("demo_tag_meets", lang)
582
  tag_somehow = _t("demo_tag_somehow", lang)
 
720
  _sprite_data_uri_app(f"hero_{theme_key_for_sprites}")
721
  or _sprite_data_uri_app("hero")
722
  )
723
+ # Lean mode (default for HF Space): skip the wizard-desk backdrop
724
+ # the PNG is ~200-400 KB. Full mode restores it as a fade-behind
725
+ # layer for the mentor/apprentice figures.
726
+ desk_uri = _sprite_data_uri_app("wizard_desk_scene") if _full_visual_mode() else ""
727
  if not wizard_uri or not hero_uri:
728
  fallback = (
729
  "<div class='oracle-inscribe-figs' style='text-align:center;"
 
846
  is_compact = mode in ("trial", "epilogue", "send_off")
847
  extra_cls = " oracle-banner-compact" if is_compact else ""
848
 
849
+ # Lean mode (default for HF Space): use a CSS gradient instead of the
850
+ # ~455 KB parallax PNG. Full mode loads the PNG via Gradio's file
851
+ # route so the browser caches it after the first request.
852
+ if _full_visual_mode() and _PARALLAX_PNG.exists():
853
+ src = f"/gradio_api/file={_PARALLAX_PNG.as_posix()}"
854
+ result = (
855
+ f"<div class='oracle-banner{extra_cls}'>"
856
+ f"<img src='{src}' alt='banner'/>"
857
+ "<div class='oracle-banner-overlay'>"
858
+ f"<div class='oracle-banner-title'>{title}</div>"
859
+ f"<div class='oracle-banner-sub'>{subtitle}</div>"
860
+ "</div></div>"
861
+ )
862
+ else:
863
+ result = (
864
+ f"<div class='oracle-banner{extra_cls}' style='background:"
865
+ "linear-gradient(180deg,var(--w-panel) 0%, var(--w-night) 100%);'>"
866
+ "<div class='oracle-banner-overlay'>"
867
+ f"<div class='oracle-banner-title'>{title}</div>"
868
+ f"<div class='oracle-banner-sub'>{subtitle}</div>"
869
+ "</div></div>"
870
+ )
871
  _BANNER_HTML_CACHE[cache_key] = result
872
  return result
873
 
 
948
 
949
 
950
  def _phase_backdrop_styles_html() -> str:
951
+ """One-time ``<style>`` block (built at app startup) that wires the
952
+ per-phase pixel-art ambient textures onto the phase Group wrappers via
953
+ their ``elem_id`` attributes. Returns an empty string if any expected
954
+ texture is missing from disk OR if visual mode is lean.
955
+
956
+ Mapping:
957
+ #oracle-inscribe-grp ← grimoire_cover_texture
958
+ #oracle-send-off-grp ← stormy_plain_texture
959
+ #oracle-trial-grp ← night_sky_texture
960
+ #oracle-epilogue-grp ← forest_dusk_texture
961
  """
962
+ if not _full_visual_mode():
963
+ return ""
964
+ mapping = {
965
+ "oracle-inscribe-grp": "grimoire_cover_texture",
966
+ "oracle-send-off-grp": "stormy_plain_texture",
967
+ "oracle-trial-grp": "night_sky_texture",
968
+ "oracle-epilogue-grp": "forest_dusk_texture",
969
+ }
970
+ rules = []
971
+ for elem_id, sprite_name in mapping.items():
972
+ uri = _sprite_data_uri_app(sprite_name)
973
+ if not uri:
974
+ continue
975
+ rules.append(f"#{elem_id} {{ background-image: url('{uri}') !important; }}")
976
+ if not rules:
977
+ return ""
978
+ return "<style data-phase-backdrops>\n" + "\n".join(rules) + "\n</style>"
979
 
980
 
981
  def _theme_style_overrides_html(state: Optional[GameState] = None) -> str:
 
3451
  return landscape
3452
  return _sprite_data_uri_app(category) or ""
3453
 
3454
+ # Lean mode (default for HF Space): skip the env (landscape) backdrop
3455
+ # — each scene_<theme>_landscape PNG is ~200-500 KB and slow over HF's
3456
+ # egress. The hero + obstacle sprites still load and the panel uses a
3457
+ # CSS gradient sky. Full mode restores the landscape.
3458
+ env_uri = _theme_pick(env_name, is_env=True) if _full_visual_mode() else ""
3459
  hero_uri = _theme_pick("hero")
3460
  ob_uri = _theme_pick(ob_name) if ob_name else ""
3461
 
 
 
 
 
3462
  dragon_attr = ' data-dragon="true"' if is_dragon else ""
3463
  hero_img = (
3464
  f"<img class='scene-hero' src='{hero_uri}' alt='hero'/>"
run.sh CHANGED
@@ -19,10 +19,20 @@
19
  # under DIR (default: ./traces/). Drop the file into
20
  # an HF dataset repo for the Sharing-is-Caring badge.
21
  # --self-test Pass-through to app.py for the scripted walkthrough.
 
 
 
 
 
 
 
 
22
  #
23
  # Env vars:
24
  # ORACLES_LLM_MODEL=llm request base model
25
  # ORACLES_LLM_MODEL=oracle-wizard-lora (default) request fine-tune
 
 
26
  # KEEP_LLM_WARM=1 keep Modal LLM running
27
  # ORACLES_GGUF_PATH=/path/to/model.gguf used in --local-llama mode
28
  # ORACLES_LOCAL_LLAMA_PORT=8080 (default) llama-server port
@@ -53,6 +63,8 @@ for arg in "$@"; do
53
  --local-llama) USE_LOCAL_LLAMA="1" ;;
54
  --save-trace) SAVE_TRACE_DIR="./traces" ;;
55
  --save-trace=*) SAVE_TRACE_DIR="${arg#--save-trace=}" ;;
 
 
56
  *) APP_ARGS+=("$arg") ;;
57
  esac
58
  done
@@ -63,6 +75,15 @@ if [ -n "$SAVE_TRACE_DIR" ]; then
63
  echo "[run.sh] --save-trace: appending LLM exchanges to $SAVE_TRACE_DIR/oracles-trace-<session>.jsonl"
64
  fi
65
 
 
 
 
 
 
 
 
 
 
66
  # -----------------------------------------------------------------------------
67
  # Load .env.local — look in both the project root and oracles_app/ so
68
  # shared credentials are picked up.
 
19
  # under DIR (default: ./traces/). Drop the file into
20
  # an HF dataset repo for the Sharing-is-Caring badge.
21
  # --self-test Pass-through to app.py for the scripted walkthrough.
22
+ # --full Enable ALL decorative PNGs (parallax banner,
23
+ # parchment, phase backdrops, scene landscapes,
24
+ # wizard-desk, open-book, demo-card backdrop).
25
+ # Recommended for local runs on fast connections.
26
+ # --lean (default) Skip the heavy decorative PNGs. Used by
27
+ # the HF Space deployment because its egress
28
+ # bandwidth (~15 KB/s) makes the full set add
29
+ # multi-megabytes to every cold load.
30
  #
31
  # Env vars:
32
  # ORACLES_LLM_MODEL=llm request base model
33
  # ORACLES_LLM_MODEL=oracle-wizard-lora (default) request fine-tune
34
+ # ORACLES_VISUAL_MODE=full same as --full
35
+ # ORACLES_VISUAL_MODE=lean (default) same as --lean
36
  # KEEP_LLM_WARM=1 keep Modal LLM running
37
  # ORACLES_GGUF_PATH=/path/to/model.gguf used in --local-llama mode
38
  # ORACLES_LOCAL_LLAMA_PORT=8080 (default) llama-server port
 
63
  --local-llama) USE_LOCAL_LLAMA="1" ;;
64
  --save-trace) SAVE_TRACE_DIR="./traces" ;;
65
  --save-trace=*) SAVE_TRACE_DIR="${arg#--save-trace=}" ;;
66
+ --full) export ORACLES_VISUAL_MODE="full" ;;
67
+ --lean) export ORACLES_VISUAL_MODE="lean" ;;
68
  *) APP_ARGS+=("$arg") ;;
69
  esac
70
  done
 
75
  echo "[run.sh] --save-trace: appending LLM exchanges to $SAVE_TRACE_DIR/oracles-trace-<session>.jsonl"
76
  fi
77
 
78
+ # Visual-mode banner. The app defaults to lean; --full overrides for local
79
+ # bandwidth-rich runs that want the parallax banner, parchment texture,
80
+ # phase backdrops, scene landscapes, etc.
81
+ if [ "${ORACLES_VISUAL_MODE:-lean}" = "full" ]; then
82
+ echo "[run.sh] --full: ORACLES_VISUAL_MODE=full (all PNGs / textures / backdrops enabled)"
83
+ else
84
+ echo "[run.sh] lean mode (default) — pass --full to enable all visuals"
85
+ fi
86
+
87
  # -----------------------------------------------------------------------------
88
  # Load .env.local — look in both the project root and oracles_app/ so
89
  # shared credentials are picked up.