Spaces:
Sleeping
Sleeping
| # 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. | |
| """ | |
| FastAPI application for the Axiomforgeai Environment. | |
| This module creates an HTTP server that exposes the AxiomforgeaiEnvironment | |
| over HTTP and WebSocket endpoints, compatible with EnvClient. | |
| Endpoints: | |
| - POST /reset: Reset the environment | |
| - POST /step: Execute an action | |
| - GET /state: Get current environment state | |
| - GET /schema: Get action/observation schemas | |
| - WS /ws: WebSocket endpoint for persistent sessions | |
| Usage: | |
| # Development (with auto-reload): | |
| uvicorn server.app:app --reload --host 0.0.0.0 --port 8000 | |
| # Production: | |
| uvicorn server.app:app --host 0.0.0.0 --port 8000 --workers 4 | |
| # Or run directly: | |
| python -m server.app | |
| """ | |
| from fastapi import Request | |
| from fastapi.responses import HTMLResponse | |
| try: | |
| from openenv.core.env_server.http_server import create_app | |
| except Exception as e: # pragma: no cover | |
| raise ImportError( | |
| "openenv is required for the web interface. Install dependencies with '\n uv sync\n'" | |
| ) from e | |
| try: | |
| from ..models import AxiomforgeaiAction, AxiomforgeaiObservation | |
| from .AxiomForgeAI_environment import AxiomforgeaiEnvironment | |
| except ImportError: | |
| from models import AxiomforgeaiAction, AxiomforgeaiObservation | |
| from server.AxiomForgeAI_environment import AxiomforgeaiEnvironment | |
| # Create the app with web interface and README integration | |
| app = create_app( | |
| AxiomforgeaiEnvironment, | |
| AxiomforgeaiAction, | |
| AxiomforgeaiObservation, | |
| env_name="AxiomForgeAI", | |
| max_concurrent_envs=1, # increase this number to allow more concurrent WebSocket sessions | |
| ) | |
| _HOMEPAGE_HTML = """<!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
| <title>AxiomForgeAI — Math RL Environment</title> | |
| <style> | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| background: #0f0f1a; | |
| color: #e2e8f0; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| padding: 3rem 1.5rem; | |
| } | |
| .hero { | |
| text-align: center; | |
| margin-bottom: 3rem; | |
| } | |
| .badge { | |
| display: inline-block; | |
| background: linear-gradient(135deg, #6366f1, #ec4899); | |
| color: white; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| letter-spacing: 0.08em; | |
| text-transform: uppercase; | |
| padding: 0.3rem 0.8rem; | |
| border-radius: 999px; | |
| margin-bottom: 1.2rem; | |
| } | |
| h1 { | |
| font-size: 2.8rem; | |
| font-weight: 800; | |
| background: linear-gradient(135deg, #818cf8, #f472b6); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| margin-bottom: 1rem; | |
| } | |
| .subtitle { | |
| color: #94a3b8; | |
| font-size: 1.1rem; | |
| max-width: 600px; | |
| line-height: 1.7; | |
| margin: 0 auto; | |
| } | |
| .grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); | |
| gap: 1.25rem; | |
| width: 100%; | |
| max-width: 900px; | |
| margin-bottom: 2.5rem; | |
| } | |
| .card { | |
| background: #1e1e2e; | |
| border: 1px solid #2d2d44; | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| transition: border-color 0.2s, transform 0.2s; | |
| } | |
| .card:hover { | |
| border-color: #6366f1; | |
| transform: translateY(-2px); | |
| } | |
| .card-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| margin-bottom: 0.75rem; | |
| } | |
| .method { | |
| font-size: 0.7rem; | |
| font-weight: 700; | |
| padding: 0.2rem 0.5rem; | |
| border-radius: 4px; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| } | |
| .post { background: #1a3a2a; color: #4ade80; border: 1px solid #4ade8040; } | |
| .get { background: #1a2a4a; color: #60a5fa; border: 1px solid #60a5fa40; } | |
| .ws { background: #2a1a3a; color: #c084fc; border: 1px solid #c084fc40; } | |
| .endpoint { | |
| font-family: "Fira Code", "Cascadia Code", monospace; | |
| font-size: 1rem; | |
| font-weight: 600; | |
| color: #e2e8f0; | |
| } | |
| .card p { | |
| color: #94a3b8; | |
| font-size: 0.9rem; | |
| line-height: 1.6; | |
| } | |
| .links { | |
| display: flex; | |
| gap: 1rem; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| } | |
| .btn { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| padding: 0.65rem 1.4rem; | |
| border-radius: 8px; | |
| font-size: 0.9rem; | |
| font-weight: 600; | |
| text-decoration: none; | |
| transition: opacity 0.2s; | |
| } | |
| .btn:hover { opacity: 0.85; } | |
| .btn-primary { background: linear-gradient(135deg, #6366f1, #ec4899); color: white; } | |
| .btn-outline { border: 1px solid #2d2d44; color: #94a3b8; background: #1e1e2e; } | |
| footer { | |
| margin-top: 3rem; | |
| color: #475569; | |
| font-size: 0.8rem; | |
| text-align: center; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="hero"> | |
| <div class="badge">OpenEnv Hackathon India 2026</div> | |
| <h1>AxiomForgeAI</h1> | |
| <p class="subtitle"> | |
| A self-improving math RL environment. The model practices on verified problems, | |
| generates new challenges when ready, and learns from solution attempts whose | |
| reasoning steps and final answers agree. | |
| </p> | |
| </div> | |
| <div class="grid"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <span class="method post">POST</span> | |
| <span class="endpoint">/reset</span> | |
| </div> | |
| <p>Start a new episode. Returns a math question with topic and difficulty metadata.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <span class="method post">POST</span> | |
| <span class="endpoint">/step</span> | |
| </div> | |
| <p>Submit a solution for the current question. Returns reward, feedback, and scoring breakdown.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <span class="method get">GET</span> | |
| <span class="endpoint">/state</span> | |
| </div> | |
| <p>Get the current episode state including episode ID and step count.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <span class="method get">GET</span> | |
| <span class="endpoint">/schema</span> | |
| </div> | |
| <p>Returns JSON schemas for action and observation types.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <span class="method get">GET</span> | |
| <span class="endpoint">/health</span> | |
| </div> | |
| <p>Health check endpoint. Returns server status and environment availability.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <span class="method ws">WS</span> | |
| <span class="endpoint">/ws</span> | |
| </div> | |
| <p>WebSocket endpoint for persistent sessions. Supports concurrent multi-agent connections.</p> | |
| </div> | |
| </div> | |
| <div class="links"> | |
| <a class="btn btn-primary" href="/docs">Swagger UI</a> | |
| <a class="btn btn-outline" href="/redoc">ReDoc</a> | |
| <a class="btn btn-outline" href="https://github.com/Prem01-cyber/AxiomForgeAI" target="_blank">GitHub</a> | |
| <a class="btn btn-outline" href="https://huggingface.co/spaces/jampuramprem/AxiomForgeAI" target="_blank">HF Space</a> | |
| </div> | |
| <footer>Engineered for the OpenEnv Hackathon India 2026 — Powered by OpenEnv</footer> | |
| </body> | |
| </html> | |
| """ | |
| async def homepage(_request: Request) -> HTMLResponse: | |
| return HTMLResponse(content=_HOMEPAGE_HTML) | |
| def main(host: str = "0.0.0.0", port: int = 8000): | |
| """ | |
| Entry point for direct execution via uv run or python -m. | |
| This function enables running the server without Docker: | |
| uv run --project . server | |
| uv run --project . server --port 8001 | |
| python -m AxiomForgeAI.server.app | |
| Args: | |
| host: Host address to bind to (default: "0.0.0.0") | |
| port: Port number to listen on (default: 8000) | |
| For production deployments, consider using uvicorn directly with | |
| multiple workers: | |
| uvicorn AxiomForgeAI.server.app:app --workers 4 | |
| """ | |
| import uvicorn | |
| uvicorn.run(app, host=host, port=port) | |
| if __name__ == "__main__": | |
| main() | |