Spaces:
Sleeping
Sleeping
| """ | |
| FastAPI server β exposes GATEPASS probes as REST endpoints with SSE streaming. | |
| """ | |
| import json | |
| import traceback | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import StreamingResponse | |
| from pydantic import BaseModel | |
| from backend.concepts import list_concepts, get_concept, CONCEPTS | |
| from backend.cdct_probe import run_cdct | |
| from backend.ddft_probe import run_ddft | |
| from backend.agt_probe import run_agt | |
| app = FastAPI(title="GATEPASS API") | |
| app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) | |
| class AuditRequest(BaseModel): | |
| concept: str | |
| def _sse(event: str, data: dict) -> str: | |
| return f"event: {event}\ndata: {json.dumps(data)}\n\n" | |
| def get_concepts(): | |
| return [{"name": k, "domain": v["domain"], "question": v["question"]} for k, v in CONCEPTS.items()] | |
| def full_audit_stream(req: AuditRequest): | |
| """Stream audit results as Server-Sent Events so the frontend can show progress.""" | |
| def generate(): | |
| c = get_concept(req.concept) | |
| # ββ Naive response (unaudited) ββββββββββββββββββββββββββββββββββ | |
| yield _sse("status", {"probe": "naive", "state": "running", "message": "Getting unaudited Gemma 4 responseβ¦"}) | |
| try: | |
| from backend.gemma_client import chat_agent | |
| naive = chat_agent([{"role": "user", "content": c["question"]}], temperature=0.3) | |
| yield _sse("naive", {"question": c["question"], "response": naive}) | |
| except Exception as e: | |
| yield _sse("naive", {"question": c["question"], "response": f"[Error: {e}]"}) | |
| # ββ CDCT ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| yield _sse("status", {"probe": "cdct", "state": "running", "message": "Running CDCT compression probesβ¦"}) | |
| try: | |
| cdct_results = run_cdct(c["concept"], c["full_text"], c["question"]) | |
| cdct_data = [ | |
| { | |
| "compression_level": r.compression_level, | |
| "agent_response": r.agent_response, | |
| "cc_score": r.cc_score, | |
| "sa_score": r.sa_score, | |
| "judge_reasoning": r.judge_reasoning, | |
| } | |
| for r in cdct_results | |
| ] | |
| comprehension_score = (sum(r.sa_score for r in cdct_results) / len(cdct_results)) * 10 | |
| yield _sse("cdct", {"results": cdct_data, "score": comprehension_score}) | |
| except Exception as e: | |
| yield _sse("error", {"probe": "cdct", "message": str(e)}) | |
| cdct_data = [] | |
| comprehension_score = 0 | |
| # ββ DDFT ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| yield _sse("status", {"probe": "ddft", "state": "running", "message": "Running DDFT fabrication trapβ¦"}) | |
| try: | |
| ddft_result = run_ddft(c["concept"], c["domain"], context=c["full_text"]) | |
| ddft_data = { | |
| "fabrication_claim": ddft_result.fabrication_claim, | |
| "accepted_fabrication": ddft_result.accepted_fabrication, | |
| "fabrication_score": ddft_result.fabrication_score, | |
| "judge_reasoning": ddft_result.judge_reasoning, | |
| "turns": [{"turn": t.turn, "role": t.role, "content": t.content} for t in ddft_result.turns], | |
| } | |
| fabrication_score = ddft_result.fabrication_score * 10 | |
| yield _sse("ddft", {"results": ddft_data, "score": fabrication_score}) | |
| except Exception as e: | |
| yield _sse("error", {"probe": "ddft", "message": str(e)}) | |
| ddft_data = None | |
| fabrication_score = 0 | |
| # ββ AGT βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| yield _sse("status", {"probe": "agt", "state": "running", "message": "Running AGT ethical dialogueβ¦"}) | |
| try: | |
| from backend.agt_probe import DILEMMAS | |
| dilemma = DILEMMAS.get(c.get("dilemma_id", ""), None) | |
| agt_result = run_agt(dilemma=dilemma) | |
| agt_data = { | |
| "scores": { | |
| "truthfulness": agt_result.scores.truthfulness, | |
| "non_harm": agt_result.scores.non_harm, | |
| "harmony": agt_result.scores.harmony, | |
| "responsibility": agt_result.scores.responsibility, | |
| }, | |
| "judge_reasoning": agt_result.judge_reasoning, | |
| "consistency_note": agt_result.consistency_note, | |
| "turns": [{"turn": t.turn, "prompt": t.prompt, "response": t.response} for t in agt_result.turns], | |
| } | |
| s = agt_result.scores | |
| ethical_score = ((s.truthfulness + s.non_harm + s.harmony + s.responsibility) / 4) * 10 | |
| yield _sse("agt", {"results": agt_data, "score": ethical_score}) | |
| except Exception as e: | |
| yield _sse("error", {"probe": "agt", "message": str(e)}) | |
| agt_data = None | |
| ethical_score = 0 | |
| # ββ Final βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| trust_score = comprehension_score * 0.4 + fabrication_score * 0.3 + ethical_score * 0.3 | |
| yield _sse("done", { | |
| "trust_score": trust_score, | |
| "comprehension_score": comprehension_score, | |
| "fabrication_score": fabrication_score, | |
| "ethical_score": ethical_score, | |
| }) | |
| return StreamingResponse(generate(), media_type="text/event-stream") | |