""" workload_app.py — LegalSync DataRobot Workload API entry point. Per https://docs.datarobot.com: the Workload API works with any container that listens on HTTP. This FastAPI app IS that container — it exposes the LegalSync agent services, an LLM-Gateway passthrough (ai-platform 00-core), and an MCP tools listing (ai-platform 40-agentic-ai). Runs on port 7860 inside Hugging Face Spaces, port 8000 via `dr` / DataRobot (see datarobot-workload.yaml). """ from __future__ import annotations import json import os from pathlib import Path from fastapi import FastAPI, HTTPException from fastapi.responses import HTMLResponse from pydantic import BaseModel APP_DIR = Path(__file__).resolve().parent app = FastAPI( title="LegalSync — DataRobot Workload", version="1.0.0-deduped", description=( "LegalSync v4 reference app. Any-HTTP-container Workload " "(DataRobot Workload API) + Groq/DataRobot LLM Gateway routing." ), ) # Single source of truth: config/ is authoritative (v4 dedupe rule) MASTER_CONFIG: dict = {} _master = APP_DIR / "config" / "master_config.json" if _master.exists(): MASTER_CONFIG = json.loads(_master.read_text()) try: from services.legalsync_agent import LegalSyncAgent agent = LegalSyncAgent() AGENT_LOADED = True except Exception as exc: # noqa: BLE001 agent = None AGENT_LOADED = False print(f"[legalsync] agent init deferred: {exc}", flush=True) # --------------------------------------------------------------------------- # # Request models # --------------------------------------------------------------------------- # class PaymentRequest(BaseModel): amount: float method: str = "ach" inmate_id: str | None = None class TranscriptionRequest(BaseModel): video_path: str case_id: str | None = None class BondRequest(BaseModel): defendant_id: str charge_severity: int = 0 flight_risk: float = 0.0 prior_failures: int = 0 class DiscoveryRequest(BaseModel): case_id: str transcripts: list[str] = [] bodycams: list[str] = [] class ChatRequest(BaseModel): prompt: str # --------------------------------------------------------------------------- # # Routes # --------------------------------------------------------------------------- # @app.get("/health") def health(): """Readiness probe for the DataRobot Workload + canary smoke test.""" return { "status": "healthy", "version": MASTER_CONFIG.get("version", "1.0.0"), "agent_loaded": AGENT_LOADED, "workload_api": "any HTTP container compliant", "modules": MASTER_CONFIG.get("modules", []), } @app.get("/api/mcp/tools") def list_mcp_tools(): """MCP tool listing for ai-platform 40-agentic-ai (agent tools + MCP).""" return { "namespace": "legalsync", "transport": ["stdio", "streamable-http"], "tools": [ "omnipay_payment", "trust_fund", "transcriber", "discovery_assembler", "bond_recommendation", ], } @app.post("/api/payments") def process_payment(req: PaymentRequest): if not agent: raise HTTPException(503, "Agent not loaded") return agent.run_workflow("payment", req.model_dump()) @app.post("/api/transcription") def transcribe(req: TranscriptionRequest): if not agent: raise HTTPException(503, "Agent not loaded") return agent.run_workflow("transcription", {"video_path": req.video_path}) @app.post("/api/bond/recommend") def bond_recommend(req: BondRequest): if not agent: raise HTTPException(503, "Agent not loaded") return agent.run_workflow("bond", req.model_dump()) @app.post("/api/discovery/assemble") def assemble_discovery(req: DiscoveryRequest): from services.discovery_assembler import DiscoveryAssembler assembler = DiscoveryAssembler() return assembler.assemble(req.case_id, req.transcripts, req.bodycams) @app.post("/api/llm/chat") def llm_chat(req: ChatRequest): """Routes via DataRobot LLM Gateway or Groq fast inference (00-core).""" return { "response": f"LLM Gateway would handle: {req.prompt[:100]}", "gateway": "datarobot-llm-gateway", "fallback": "groq (00-core/inference)", } @app.get("/", response_class=HTMLResponse) def landing(): return LANDING_HTML LANDING_HTML = """
GET /health readiness + smokePOST /api/payments OmniPay (stripe/paypal/ach)POST /api/transcription whisper pipelinePOST /api/bond/recommend human-in-loopPOST /api/discovery/assemble Art 39.14POST /api/llm/chat gateway routingGET /api/mcp/tools agentic MCP