"""
╔═══════════════════════════════════════════════════════════════════════════════╗
║                                                                               ║
║    ██╗  ██╗ ██████╗ ██╗     ██████╗                                          ║
║    ██║  ██║██╔═══██╗██║     ██╔══██╗                                         ║
║    ███████║██║   ██║██║     ██║  ██║                                         ║
║    ██╔══██║██║   ██║██║     ██║  ██║                                         ║
║    ██║  ██║╚██████╔╝███████╗██████╔╝                                         ║
║    ╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚═════╝                                          ║
║                                                                               ║
║    Inference-Level Halt Protocol for CASCADE-LATTICE                         ║
║                                                                               ║
║    "Pause the machine. See what it sees. Choose what it chooses."            ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝

HOLD is MODEL-AGNOSTIC. Works with ANY framework:
    - PyTorch, JAX, TensorFlow, scikit-learn
    - Hugging Face, OpenAI API, Anthropic API
    - Stable Baselines3, RLlib, custom RL
    - Any function that outputs probabilities

MINIMAL USAGE:
    >>> from cascade.hold import Hold
    >>> 
    >>> # Your model (any framework)
    >>> action_probs = your_model.predict(obs)  # numpy array
    >>> 
    >>> # HOLD at decision point
    >>> hold = Hold.get()
    >>> resolution = hold.yield_point(action_probs=action_probs)
    >>> 
    >>> # Use resolved action (AI choice or human override)
    >>> action = resolution.action

WITH VISUALIZATION:
    >>> from cascade.hold import HoldMeshServer
    >>> 
    >>> server = HoldMeshServer(port=8766)
    >>> server.start()
    >>> 
    >>> # In your loop:
    >>> server.update({
    ...     "action_probs": probs.tolist(),
    ...     "action_names": ["up", "down", "left", "right"],
    ... })
    >>> 
    >>> # Open http://localhost:8766 for 3D view

FULL EXAMPLE:
    >>> hold = Hold.get()
    >>> resolution = hold.yield_point(
    ...     action_probs=model_output,     # Required: probabilities
    ...     action_names=["a", "b", "c"],  # Optional: names
    ...     value=predicted_value,         # Optional: value estimate
    ...     observation={"state": s},      # Optional: context
    ...     brain_id="my_model"            # Optional: identifier
    ... )
    >>> 
    >>> action = resolution.action
    >>> was_override = resolution.was_override
"""

# Primitives
from cascade.hold.primitives import (
    HoldState,
    HoldPoint,
    HoldResolution,
    Hold,
    HoldAwareMixin,
)

# Arcade / Session Layer
from cascade.hold.session import (
    InferenceStep,
    HoldSession,
    ArcadeFeedback,
    CausationHold,
)

# Display
from cascade.hold.display import HoldDisplay

# Viewer (browser-based glass box)
from cascade.hold.viewer import HoldViewer, HoldViewerConfig, serve_hold

# Bridge (connects session to viewer)
from cascade.hold.bridge import HoldBridge, with_viewer, run_with_viewer

# glTF Export (universal mesh format for game engines)
from cascade.hold.gltf_export import (
    export_hold_to_gltf,
    export_hold,
    HoldGLTFExporter,
    TrajectoryMesh,
)

# Mesh Server (live streaming to games)
from cascade.hold.mesh_server import HoldMeshServer, serve_hold_meshes

__all__ = [
    # Primitives
    "HoldState",
    "HoldPoint",
    "HoldResolution",
    "Hold",
    "HoldAwareMixin",
    # Session / Arcade
    "InferenceStep",
    "HoldSession",
    "ArcadeFeedback",
    "CausationHold",
    # Display
    "HoldDisplay",
    # Viewer
    "HoldViewer",
    "HoldViewerConfig",
    "serve_hold",
    # Bridge
    "HoldBridge",
    "with_viewer",
    "run_with_viewer",
    # glTF Export
    "export_hold_to_gltf",
    "export_hold",
    "HoldGLTFExporter",
    "TrajectoryMesh",
    # Mesh Server
    "HoldMeshServer",
    "serve_hold_meshes",
]
