|
|
|
|
|
from fastapi import APIRouter, Depends |
|
|
import numpy as np |
|
|
from typing import List |
|
|
from consensus.topo import TopologicalConsciousness |
|
|
from consensus.metrics import weighted_average_text |
|
|
from api.schemas import AskRequest, AskResponse |
|
|
from adapters.base import BaseModelAdapter |
|
|
|
|
|
router = APIRouter(prefix="/consensus", tags=["consensus"]) |
|
|
|
|
|
def get_models() -> List[BaseModelAdapter]: |
|
|
from adapters.openai_adapter import OpenAIAdapter |
|
|
from adapters.anthropic_adapter import AnthropicAdapter |
|
|
|
|
|
return [OpenAIAdapter(), AnthropicAdapter()] |
|
|
|
|
|
@router.post("/ask", response_model=AskResponse) |
|
|
def ask(req: AskRequest, models: List[BaseModelAdapter] = Depends(get_models)): |
|
|
tc = TopologicalConsciousness(n_anyons=len(models), central_charge=627) |
|
|
responses = [m.generate(req.prompt) for m in models] |
|
|
embs = [np.array(m.embed_text(r), dtype=float) for r in responses] |
|
|
pc = tc.calculate_coherence(embs) |
|
|
if pc < req.min_confidence: |
|
|
return AskResponse(answer=None, confidence=pc, |
|
|
warning="Models disagree - low confidence") |
|
|
E = np.stack(embs); sims = E @ E.T |
|
|
w = sims.mean(axis=1); w = np.clip(w, 0, None); w = w/(w.sum()+1e-12) |
|
|
return AskResponse(answer=weighted_average_text(responses, w), |
|
|
confidence=pc, weights=w.tolist()) |
|
|
|