multi-agent-lab / src /ui /fishbowl /__init__.py
agharsallah
feat: add Fishbowl Gradio app shell + integrator (Unit 9)
a8039c4
Raw
History Blame Contribute Delete
1.81 kB
"""Fishbowl UI presenter β€” turns engine events into the design's view-model.
Pure and transport-agnostic (no Gradio import here): the same snapshot feeds the
``gr.HTML`` stage now and a future ``gr.Server`` JSON endpoint (ADR-0021). This
package depends only on the engine's public read surface β€” ``ledger.events``,
``rebuild_stage``, ``governor.stats``, agent manifests β€” and the engine never imports
it, so ``tests/test_modularity.py`` and the four contracts are untouched.
Layers:
* ``cast_state`` β€” ``derive_cast_state`` : per-agent {said, thought, mood} ledger view (G1)
* ``adapter`` β€” engine vocabulary β†’ the design's say/narrate/poke/verdict + hue/tier/voice
* ``view_model`` β€” ``view_model_at`` : a JSON-serialisable snapshot at any scrubbed step k
The Gradio shell (``build_app`` / ``demo``) also lives in this package (``app`` module),
but is exposed **lazily** via :pep:`562` ``__getattr__`` so that importing the package
stays Gradio-free β€” the pure presenter above must remain importable without Gradio for
``tests/test_modularity.py`` and the JSON-endpoint path.
"""
from typing import TYPE_CHECKING
from src.ui.fishbowl.cast_state import CastMemberState, derive_cast_state
from src.ui.fishbowl.view_model import view_model_at
if TYPE_CHECKING: # for type-checkers only; no runtime Gradio import
from src.ui.fishbowl.app import build_app, demo
__all__ = ["CastMemberState", "derive_cast_state", "view_model_at", "build_app", "demo"]
def __getattr__(name: str):
"""Lazily expose the Gradio shell so ``import src.ui.fishbowl`` stays Gradio-free."""
if name in ("build_app", "demo"):
from src.ui.fishbowl import app as _app
return getattr(_app, name)
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")