A newer version of the Gradio SDK is available: 6.20.0
Modal Architecture
Glass-Box Agent is structured so the UI is a thin client and Modal owns the durable/compute-heavy pieces.
Flow
flowchart LR
UI["Gradio UI"] --> Model["Modal model service"]
UI --> Trace["Modal trace store"]
Trace --> Dataset["RL feedback dataset"]
Dataset --> Tune["Modal RL tuning job"]
Tune --> Checkpoint["Modal checkpoint"]
Checkpoint --> Model
1. Model served by Modal
modal_service.py exposes reason_next, a Modal web function that accepts:
{
"task": "User task",
"step": 3,
"memory": ["recent trace observations"],
"model_id": "checkpoint-abc123 or base model id"
}
The Gradio app uses this when Reasoner is set to Modal served model.
Configuration options:
export GLASS_BOX_MODAL_MODEL_URL="https://...--reason-next.modal.run"
export GLASS_BOX_MODAL_TRACE_URL="https://...--store-trace.modal.run"
export GLASS_BOX_MODAL_TUNE_URL="https://...--start-rl-tune.modal.run"
If URLs are not configured, the app can call deployed Modal functions by name when the Modal SDK is authenticated:
export GLASS_BOX_MODAL_APP="glass-box-agent-modal"
export GLASS_BOX_MODAL_MODEL_FUNCTION="reason_next"
export GLASS_BOX_MODAL_TRACE_FUNCTION="store_trace"
export GLASS_BOX_MODAL_TUNE_FUNCTION="start_rl_tune"
export GLASS_BOX_MODAL_TRACE_ENABLED=1
2. Traces stored by Modal
Every server-side trace mutation calls store_trace when Modal trace storage is configured:
- run start and streamed trace updates
- retry branch
- replay downstream
- mark/clear labels
- fork selected node
- export trace
- export RL data
- preference feedback
Client-side visual edits also post to GLASS_BOX_MODAL_TRACE_URL when that endpoint is configured.
Traces are written to the Modal Volume:
/data/traces/<trace_id>/<timestamp>-<artifact>-<event>.json
/data/traces/<trace_id>/latest.json
Modal Volumes require explicit volume.commit() to persist writes; modal_service.py commits after every write.
3. RL feedback and tuning
The Training signal panel records branch preferences:
{
"dpo": {
"prompt": "Task and upstream trace context",
"chosen": "Better branch continuation",
"rejected": "Weaker branch continuation"
}
}
Export RL data writes a local JSON artifact and stores the trace snapshot through Modal.
RL tune on Modal calls start_rl_tune, which stores:
/data/rl-feedback/<trace_id>/<checkpoint_id>/dataset.json
/data/checkpoints/<checkpoint_id>/manifest.json
The current implementation creates a checkpoint manifest scaffold. The intended next step is to replace the body of start_rl_tune with TRL/LoRA training and write adapter weights beside manifest.json.
4. Using checkpoints
After a tuning run returns a checkpoint such as:
checkpoint-a1b2c3d4e5
put that value in the Small model field and keep Reasoner set to Modal served model. reason_next will look for:
/data/checkpoints/checkpoint-a1b2c3d4e5/manifest.json
and can load adapter weights from that directory once the tuning scaffold is replaced with real training.
Deploy
modal deploy modal_service.py
For local development with live URLs:
modal serve modal_service.py
Modal web endpoints use @modal.fastapi_endpoint(method="POST"), and durable trace/checkpoint files use modal.Volume.