repl / server /gradio_ui.py
burtenshaw's picture
burtenshaw HF Staff
Upload folder using huggingface_hub
b74674a verified
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
"""Custom Gradio tab for the REPL environment."""
from __future__ import annotations
import json
from typing import Any, Dict, List, Optional
import gradio as gr
from openenv.core.env_server.types import EnvironmentMetadata
def _code_block(title: str, content: str) -> str:
if not content:
return ""
return f"**{title}:**\n```text\n{content}\n```"
def _format_repl_response(data: Dict[str, Any]) -> str:
"""Render REPL observations in a compact Markdown view."""
observation = data.get("observation", {})
result = observation.get("result", {})
sections: List[str] = ["# REPL Session"]
context_preview = observation.get("context_preview")
if context_preview:
sections.append(_code_block("Context Preview", context_preview))
task_prompt = observation.get("task_prompt")
if task_prompt:
sections.append(_code_block("Task Prompt", task_prompt))
available_variables = observation.get("available_variables") or []
if available_variables:
sections.append(
"**Available Variables:** " + ", ".join(f"`{name}`" for name in available_variables)
)
if result.get("locals_snapshot"):
sections.append(
"**Locals Snapshot:**\n```json\n"
+ json.dumps(result["locals_snapshot"], indent=2, sort_keys=True)
+ "\n```"
)
stdout = result.get("stdout", "")
stderr = result.get("stderr", "")
sections.append(_code_block("Stdout", stdout))
sections.append(_code_block("Stderr", stderr))
reward = data.get("reward")
done = data.get("done")
sections.append(f"**Reward:** `{reward}`")
sections.append(f"**Done:** `{done}`")
return "\n\n".join(section for section in sections if section)
def build_repl_gradio_app(
web_manager: Any,
action_fields: List[Dict[str, Any]],
metadata: Optional[EnvironmentMetadata],
is_chat_env: bool,
title: str,
quick_start_md: str,
) -> gr.Blocks:
"""Build the REPL-specific Gradio tab."""
del action_fields, is_chat_env, metadata, quick_start_md
async def reset_repl(
context: str,
task_prompt: str,
hf_token: str,
llm_model: str,
):
reset_kwargs: Dict[str, Any] = {}
if context.strip():
reset_kwargs["context"] = context
if task_prompt.strip():
reset_kwargs["task_prompt"] = task_prompt
if hf_token.strip():
reset_kwargs["hf_token"] = hf_token
if llm_model.strip():
reset_kwargs["llm_model"] = llm_model
try:
data = await web_manager.reset_environment(reset_kwargs)
state = web_manager.get_state()
return (
_format_repl_response(data),
json.dumps(data, indent=2, sort_keys=True),
json.dumps(state, indent=2, sort_keys=True),
"REPL reset complete.",
)
except Exception as exc:
return ("", "", "", f"Error: {exc}")
async def run_code(code: str):
if not code.strip():
return ("", "", "", "Enter Python code to run.")
try:
data = await web_manager.step_environment({"code": code})
state = web_manager.get_state()
return (
_format_repl_response(data),
json.dumps(data, indent=2, sort_keys=True),
json.dumps(state, indent=2, sort_keys=True),
"Code executed.",
)
except Exception as exc:
return ("", "", "", f"Error: {exc}")
def get_state_sync():
try:
return json.dumps(web_manager.get_state(), indent=2, sort_keys=True)
except Exception as exc:
return f"Error: {exc}"
with gr.Blocks(title=f"{title} - REPL") as blocks:
gr.Markdown(
"# REPL Control Panel\n\n"
"Load a problem into the REPL, execute Python, and inspect state without "
"leaving the Space."
)
with gr.Row():
with gr.Column(scale=2):
context = gr.Textbox(
label="Context",
placeholder="Problem context or source text...",
lines=8,
)
task_prompt = gr.Textbox(
label="Task Prompt",
placeholder="What should the agent solve?",
lines=3,
)
with gr.Accordion("Optional Model Settings", open=False):
hf_token = gr.Textbox(
label="Hugging Face Token",
placeholder="Used only for this reset; not persisted in state",
type="password",
)
llm_model = gr.Textbox(
label="LLM Model",
placeholder="Optional override for llm_query / rlm_query",
)
code = gr.Textbox(
label="Python Code",
placeholder="count = len(context.split())",
lines=10,
)
with gr.Row():
reset_btn = gr.Button("Reset", variant="secondary")
run_btn = gr.Button("Run", variant="primary")
state_btn = gr.Button("Get state", variant="secondary")
status = gr.Textbox(label="Status", interactive=False)
with gr.Column(scale=3):
session_view = gr.Markdown(
value="# REPL Session\n\nReset the environment to start."
)
raw_json = gr.Code(
label="Raw JSON response",
language="json",
interactive=False,
)
state_json = gr.Code(
label="Session state",
language="json",
interactive=False,
)
reset_btn.click(
fn=reset_repl,
inputs=[context, task_prompt, hf_token, llm_model],
outputs=[session_view, raw_json, state_json, status],
)
run_btn.click(
fn=run_code,
inputs=[code],
outputs=[session_view, raw_json, state_json, status],
)
code.submit(
fn=run_code,
inputs=[code],
outputs=[session_view, raw_json, state_json, status],
)
state_btn.click(fn=get_state_sync, outputs=[state_json])
return blocks