openenv/repl
1
1# Copyright (c) Meta Platforms, Inc. and affiliates.2# All rights reserved.3#4# This source code is licensed under the BSD-style license found in the5# LICENSE file in the root directory of this source tree.6 7"""8FastAPI application for the REPL Environment.9 10This module creates an HTTP server that exposes the REPLEnvironment11over HTTP and WebSocket endpoints, compatible with EnvClient.12 13The server includes llm_query and llm_query_batched support via HuggingFace Inference API,14enabling the Recursive Language Model (RLM) paradigm.15 16LLM Token Configuration:17 1. Client can pass `hf_token` in reset() - RECOMMENDED18 2. Server fallback: HF_TOKEN environment variable19 20LLM functions are created dynamically in REPLEnvironment.reset() based on the21available token (client or server).22 23Usage:24 # Development (with auto-reload):25 uvicorn server.app:app --reload --host 0.0.0.0 --port 800026 27 # Production:28 uvicorn server.app:app --host 0.0.0.0 --port 8000 --workers 429 30 # Or run directly:31 uv run --project . server32 33Environment Variables:34 HF_TOKEN: Fallback HuggingFace API token (client token takes priority)35 LLM_MODEL: Model to use for llm_query/llm_query_batched (default: Qwen/Qwen3.5-9B)36"""37 38import inspect39import logging40import os41 42try:43 from openenv.core.env_server.http_server import create_app44 45 from ..models import REPLAction, REPLObservation46 from .gradio_ui import build_repl_gradio_app47 from .repl_environment import REPLEnvironment48except ImportError:49 from models import REPLAction, REPLObservation50 from openenv.core.env_server.http_server import create_app51 from server.gradio_ui import build_repl_gradio_app52 from server.repl_environment import REPLEnvironment53 54 55# ============== CONFIGURATION ==============56LLM_MODEL = os.environ.get("LLM_MODEL", "Qwen/Qwen3.5-9B")57HF_TOKEN = os.environ.get("HF_TOKEN")58REPL_MAX_ITERATIONS = int(os.environ.get("REPL_MAX_ITERATIONS", "30"))59REPL_MAX_OUTPUT_LENGTH = int(os.environ.get("REPL_MAX_OUTPUT_LENGTH", "8192"))60REPL_CONTEXT_PREVIEW_LENGTH = int(os.environ.get("REPL_CONTEXT_PREVIEW_LENGTH", "500"))61REPL_RLM_MAX_DEPTH = int(os.environ.get("REPL_RLM_MAX_DEPTH", "2"))62REPL_RLM_MAX_ITERATIONS = int(os.environ.get("REPL_RLM_MAX_ITERATIONS", "30"))63# ==========================================64 65_logger = logging.getLogger(__name__)66 67# Log LLM configuration68if HF_TOKEN:69 print("[REPL Server] LLM support ENABLED (server token configured)")70 print(f"[REPL Server] Default model: {LLM_MODEL}")71else:72 print("[REPL Server] No server HF_TOKEN configured")73 print(74 "[REPL Server] LLM functions will be enabled if client passes hf_token in reset()"75 )76 77 78def create_repl_environment() -> REPLEnvironment:79 """Factory function that creates REPLEnvironment with server config.80 81 LLM functions are created dynamically during `reset()` when a client82 passes `hf_token`. Rewards are computed via the default `REPLRubric`;83 pass `expected_answer` at reset time for outcome-based scoring.84 """85 return REPLEnvironment(86 max_iterations=REPL_MAX_ITERATIONS,87 max_output_length=REPL_MAX_OUTPUT_LENGTH,88 context_preview_length=REPL_CONTEXT_PREVIEW_LENGTH,89 rlm_max_depth=REPL_RLM_MAX_DEPTH,90 rlm_max_iterations=REPL_RLM_MAX_ITERATIONS,91 )92 93 94# Create the app with web interface and README integration.95_sig = inspect.signature(create_app)96if "gradio_builder" in _sig.parameters:97 app = create_app(98 create_repl_environment,99 REPLAction,100 REPLObservation,101 env_name="repl_env",102 max_concurrent_envs=8,103 gradio_builder=build_repl_gradio_app,104 )105else:106 _logger.warning(107 "Installed openenv-core does not support gradio_builder; "108 "custom REPL Gradio tab will not be available."109 )110 app = create_app(111 create_repl_environment,112 REPLAction,113 REPLObservation,114 env_name="repl_env",115 max_concurrent_envs=8,116 )117 118 119def main():120 """121 Entry point for direct execution via uv run or python -m.122 123 This function enables running the server without Docker:124 uv run --project . server125 python -m envs.repl_env.server.app126 openenv serve repl_env127 """128 import uvicorn129 130 uvicorn.run(app, host="0.0.0.0", port=8000)131 132 133if __name__ == "__main__":134 main()135 