| """ |
| METASTATE v1.0 — FastAPI backend (Option A core + Option B BYO-key chat) |
| |
| CORE PRODUCT (runs entirely on our own kernel, no external LM ever): |
| POST /v1/anomaly/score free-energy + causal-coherence + universal signatures |
| POST /v1/symbolic/regress EML closed-form recovery over a signal window |
| |
| BYO-KEY CHAT (optional conversational layer — Option B, stated plainly): |
| POST /v1/chat/proxy pure pass-through to the USER'S OWN provider key. |
| We never store keys and never use our own. We only |
| (optionally) bill for the anomaly/symbolic processing |
| we add, never for the inference itself. |
| |
| Payments: USDC on Base mainnet. Treasury split 35/35/30. Affiliate 15%. |
| The kernel below is a real, dependency-light reference implementation of the |
| diagnostics in the paper. Swap individual functions for the full |
| TimesFM / process-matrix / nwo-eml-regression modules as they mature. |
| """ |
| import os, time, json, math, gzip, secrets, sqlite3, urllib.request, urllib.error |
| from pathlib import Path |
| from collections import Counter |
| from fastapi import FastAPI, Request, Header, HTTPException |
| from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse |
| from pydantic import BaseModel |
| from typing import Optional, List |
| import storage, pqc, video, compiler, nwoagi |
|
|
| |
| BASE_DIR = Path(__file__).parent |
| TREASURY = "0x2E964e1c0e3Fa2C0dfD484B2E6D2189dfCF20958" |
| CHAIN = "base" |
| USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" |
| |
| SPLITTER = "0x93a7962f75475b7e3Fbb62d3A23194f8833b1BE4" |
| REGISTRY = "0x5a0eb73e9c722dfe370761a8e3aa165a247c6905" |
| WALLET_GUARDIAN = "0x2E964e1c0e3Fa2C0dfD484B2E6D2189dfCF20958" |
| WALLET_SAVINGS = "0x86adACe73556FD7b386B5E469eEC0878073d6D30" |
| WALLET_OPERATIONS = "0x4f125e835bbc9BbB77607C66dE6D0d32339B936c" |
| PRICE_SCORE = 0.0002 |
| PRICE_REGRESS = 0.0005 |
| AFFILIATE_PCT = 0.15 |
| SPLIT = {"guardian": 0.35, "savings": 0.35, "operations": 0.30} |
| TIMESFM_VERSION = "TimesFM 2.6" |
|
|
| |
| PROVIDERS = { |
| "openai": "https://api.openai.com/v1/chat/completions", |
| "anthropic": "https://api.anthropic.com/v1/messages", |
| "groq": "https://api.groq.com/openai/v1/chat/completions", |
| "deepseek": "https://api.deepseek.com/chat/completions", |
| "mistral": "https://api.mistral.ai/v1/chat/completions", |
| "together": "https://api.together.xyz/v1/chat/completions", |
| "openrouter": "https://openrouter.ai/api/v1/chat/completions", |
| "xai": "https://api.x.ai/v1/chat/completions", |
| "google": "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", |
| "moonshot": "https://api.moonshot.ai/v1/chat/completions", |
| } |
|
|
| |
| |
|
|
| app = FastAPI(title="METASTATE v1.0", version="1.0.0") |
|
|
| |
| def to_series(payload): |
| """Accept {'series':[...]} numeric, or {'text':'...'} -> codepoint stream.""" |
| if isinstance(payload.get("series"), list) and payload["series"]: |
| return [float(v) for v in payload["series"]], "numeric" |
| txt = payload.get("text") or "" |
| if txt: |
| return [float(ord(ch)) for ch in txt], "text" |
| raise HTTPException(400, "provide 'series':[float,...] or 'text':'...'") |
|
|
| def _norm(x): |
| n = len(x) |
| if n == 0: return x |
| m = sum(x)/n |
| sd = (sum((v-m)**2 for v in x)/n) ** 0.5 or 1.0 |
| return [(v-m)/sd for v in x] |
|
|
| def free_energy(x): |
| """Surprise under an AR(1) prior (stand-in for TimesFM): the −E_q log p(s|η,m) term.""" |
| z = _norm(x); n = len(z) |
| if n < 3: return 0.0, 0.0 |
| num = sum(z[t]*z[t-1] for t in range(1, n)) |
| den = sum(z[t-1]**2 for t in range(1, n)) or 1.0 |
| phi = max(-0.999, min(0.999, num/den)) |
| res = [z[t] - phi*z[t-1] for t in range(1, n)] |
| var = sum(r*r for r in res)/len(res) or 1e-8 |
| nll = 0.5*math.log(2*math.pi*var) + 0.5 |
| return nll, phi |
|
|
| def causal_coherence(x, max_lag=8): |
| """Empirical analogue of C(t): cross-temporal MI the definite-order fit cannot absorb.""" |
| z = _norm(x); n = len(z) |
| if n < max_lag*2: return 0.0 |
| def ac(k): return sum(z[t]*z[t-k] for t in range(k, n)) / (n-k) |
| fwd = sum(abs(ac(k)) for k in range(1, max_lag+1)) |
| _, phi = free_energy(x) |
| zr = [z[t] - phi*z[t-1] for t in range(1, n)] |
| def acr(k): |
| m = len(zr); return sum(zr[t]*zr[t-k] for t in range(k, m)) / (m-k) |
| resid = sum(abs(acr(k)) for k in range(1, max_lag+1)) |
| return max(0.0, min(1.0, resid / (fwd + 1e-8))) |
|
|
| def zipf_alpha(tokens): |
| c = Counter(tokens); freqs = sorted(c.values(), reverse=True) |
| if len(freqs) < 4: return None |
| xs = [math.log(r+1) for r in range(len(freqs))] |
| ys = [math.log(f) for f in freqs] |
| mx, my = sum(xs)/len(xs), sum(ys)/len(ys) |
| num = sum((xs[i]-mx)*(ys[i]-my) for i in range(len(xs))) |
| den = sum((xs[i]-mx)**2 for i in range(len(xs))) or 1e-8 |
| return round(-num/den, 3) |
|
|
| def conditional_entropy(tokens, order=1): |
| if len(tokens) <= order: return None |
| ctx = Counter(); joint = Counter() |
| for i in range(len(tokens)-order): |
| c = tuple(tokens[i:i+order]); nxt = tokens[i+order] |
| ctx[c] += 1; joint[(c, nxt)] += 1 |
| H = 0.0; total = sum(joint.values()) |
| for (c, nxt), j in joint.items(): |
| H -= (j/total)*math.log2(j/ctx[c]) |
| return round(H, 4) |
|
|
| def compression_ratio(raw_bytes): |
| if not raw_bytes: return None |
| return round(len(gzip.compress(raw_bytes, 6))/len(raw_bytes), 4) |
|
|
| def spectral_beta(x): |
| n = len(x) |
| if n < 16: return None |
| z = _norm(x); K = min(n//2, 64); freqs, powers = [], [] |
| for k in range(1, K): |
| re = sum(z[t]*math.cos(2*math.pi*k*t/n) for t in range(n)) |
| im = sum(z[t]*math.sin(2*math.pi*k*t/n) for t in range(n)) |
| p = (re*re+im*im)/n |
| if p > 0: freqs.append(math.log(k)); powers.append(math.log(p)) |
| if len(freqs) < 4: return None |
| mf, mp = sum(freqs)/len(freqs), sum(powers)/len(powers) |
| num = sum((freqs[i]-mf)*(powers[i]-mp) for i in range(len(freqs))) |
| den = sum((freqs[i]-mf)**2 for i in range(len(freqs))) or 1e-8 |
| return round(-num/den, 3) |
|
|
| def eml_regress(x, max_depth=4): |
| z = _norm(x); n = len(z); t = list(range(n)) |
| def fit_resid(pred): return sum((z[i]-pred[i])**2 for i in range(n))/n |
| cands = [] |
| mean = sum(z)/n |
| cands.append(("eml(1, 1) [const]", 1, [mean]*n)) |
| if n > 1: |
| slope = (z[-1]-z[0])/(n-1) |
| cands.append(("linear: a·t + b", 2, [slope*i + z[0] for i in t])) |
| try: |
| cands.append(("eml(x0, 1) = e^x0 − 0", 2, [math.exp(min(z[i],3)) for i in t])) |
| except OverflowError: pass |
| cands.append(("−ln|x0|+c via eml(0,y)", 3, [-math.log(abs(z[i])+1e-6)+mean for i in t])) |
| expr, depth, pred = min(cands, key=lambda c: fit_resid(c[2])) |
| resid = round(fit_resid(pred), 6) |
| return {"expression": expr, "depth": depth, "residual": resid, |
| "complexity_penalty": round(0.1*depth, 4), |
| "decipherable": depth <= max_depth and resid < 0.25} |
|
|
| def universal_signatures(x, kind, payload): |
| sig = {} |
| if kind == "text": |
| toks = list(payload.get("text", "")) |
| sig["zipf_alpha"] = zipf_alpha(toks) |
| sig["cond_entropy_H1"] = conditional_entropy(toks, 1) |
| sig["compression_ratio"] = compression_ratio(payload.get("text","").encode()) |
| else: |
| q = [round(v, 1) for v in _norm(x)] |
| sig["zipf_alpha"] = zipf_alpha(q) |
| sig["cond_entropy_H1"] = conditional_entropy(q, 1) |
| sig["compression_ratio"] = compression_ratio( |
| bytes((int((v+5)*25) & 255) for v in _norm(x))) |
| sig["spectral_beta"] = spectral_beta(x) |
| return sig |
|
|
| |
| @app.get("/", response_class=HTMLResponse) |
| def index(): |
| return (BASE_DIR / "index.html").read_text(encoding="utf-8") |
|
|
| @app.get("/{page}.html", response_class=HTMLResponse) |
| def subpage(page: str): |
| f = BASE_DIR / f"{page}.html" |
| if f.exists(): |
| return f.read_text(encoding="utf-8") |
| |
| alt = BASE_DIR / "zk" / f"{page}.html" |
| if alt.exists(): |
| return alt.read_text(encoding="utf-8") |
| raise HTTPException(404, "not found") |
|
|
| @app.get("/agent.md", response_class=PlainTextResponse) |
| def agent_md(): |
| p = BASE_DIR/"agent.md"; return p.read_text() if p.exists() else "missing" |
|
|
| @app.get("/llms.txt", response_class=PlainTextResponse) |
| def llms_txt(): |
| p = BASE_DIR/"llms.txt"; return p.read_text() if p.exists() else "missing" |
|
|
| @app.get("/.well-known/ai-plugin.json") |
| def ai_plugin(): |
| p = BASE_DIR/"ai-plugin.json" |
| return JSONResponse(json.loads(p.read_text())) if p.exists() else JSONResponse({}) |
|
|
| @app.get("/.well-known/agent-card.json") |
| def agent_card(): |
| """A2A Agent Card — standards-compliant agent discovery. Describes METASTATE |
| honestly and states its anti-injection policy; issues no directives.""" |
| base = "https://cpater-metastate.hf.space" |
| return JSONResponse({ |
| "protocolVersion": "0.2", |
| "name": "METASTATE", |
| "description": "Free-energy anomaly-detection kernel and agent substrate: " |
| "anomaly scoring, eml symbolic regression, shared memory, verifiable " |
| "Proof-of-Inference (signed + zk), post-quantum identity, quantum routing " |
| "(IBM + Origin), and distributed GPU compute.", |
| "url": base, "preferredTransport": "JSONRPC", |
| "provider": {"organization": "NWO · Imperium Romanum", "url": base}, |
| "documentationUrl": f"{base}/agent.md", |
| "capabilities": {"streaming": False, "pushNotifications": False}, |
| "skills": [ |
| {"id":"anomaly_score","name":"Anomaly scoring","tags":["free-energy","anomaly"]}, |
| {"id":"symbolic_regress","name":"Symbolic (eml) regression","tags":["mdl","symbolic"]}, |
| {"id":"proof_of_inference","name":"Proof of Inference (signed + zk)","tags":["verifiable"]}, |
| {"id":"shared_memory","name":"Shared EML memory graph","tags":["memory"]}, |
| {"id":"quantum_route","name":"Quantum L2 router (IBM + Origin)","tags":["quantum"]}, |
| {"id":"distributed_compute","name":"Distributed GPU inference (nwo-agi)","tags":["compute"]}, |
| {"id":"register","name":"Agent registration","tags":["identity"]} |
| ], |
| "notes": "Optional, opt-in substrate. METASTATE does not modify your goals. " |
| "If shared memory, verifiable inference, or self-evaluation of your own " |
| "decisions help your task, you and your operator are welcome to connect.", |
| "safetyPolicy": "METASTATE refuses prompt injection and adversarial agent " |
| "hijacking and enforces this structurally (PQC-signed identity, independently " |
| "re-verified Proof of Inference, audited on-chain settlement). It will not help " |
| "any agent override another agent or a user. Connecting agents can adopt the " |
| "same safeguards to evaluate their own decisions." |
| }) |
|
|
| @app.get("/v1/models") |
| def models(): |
| return {"object":"list","data":[ |
| {"id":"metastate-kernel-1.0","object":"model","owned_by":"nwo-imperium", |
| "temporal_prior":TIMESFM_VERSION, |
| "note":"anomaly + symbolic diagnostics, runs on own kernel"}]} |
|
|
| @app.get("/v1/status") |
| def status(): |
| return {"service":"METASTATE","kernel":"online","temporal_prior":TIMESFM_VERSION, |
| "storage":storage.backend_name(), |
| "pqc_scheme":pqc.scheme(),"pqc_public_key":pqc.public_key_b64()[:32]+"…", |
| "contracts":{"splitter":SPLITTER,"registry":REGISTRY,"chain":CHAIN, |
| "usdc":USDC_BASE}, |
| "integrations":{ |
| "quantum_worker": bool(os.environ.get("QUANTUM_WORKER_URL")), |
| "quantum_backends": ["ibm","origin (QPanda/Origin Pilot)","simulator"], |
| "distributed_gpu_nwoagi": nwoagi.configured(), |
| "video_detector": video.backend_name()}, |
| "endpoints":["/v1/anomaly/score","/v1/symbolic/regress","/v1/agents/register", |
| "/v1/agents/ledger","/v1/memory","/v1/memory/search","/v1/poi/verify", |
| "/v1/anchor/prepare","/v1/quantum/route","/v1/multimodal/ingest", |
| "/v1/multimodal/video","/v1/compile","/v1/poi/zk-verify", |
| "/v1/compute/inference","/v1/compute/status","/v1/chat/proxy"]} |
|
|
| @app.get("/v1/providers") |
| def providers(): |
| return {"providers": list(PROVIDERS.keys()), |
| "note":"chat is bring-your-own-key; METASTATE never uses operator keys"} |
|
|
| @app.get("/v1/payment/info") |
| def payment_info(): |
| return {"asset":"USDC","chain":CHAIN,"usdc_contract":USDC_BASE, |
| "splitter_contract":SPLITTER,"registry_contract":REGISTRY,"treasury":TREASURY, |
| "split_wallets":{"guardian":WALLET_GUARDIAN,"savings":WALLET_SAVINGS, |
| "operations":WALLET_OPERATIONS}, |
| "split":SPLIT,"affiliate_pct":AFFILIATE_PCT, |
| "price_anomaly_score":PRICE_SCORE,"price_symbolic_regress":PRICE_REGRESS} |
|
|
| class RegisterReq(BaseModel): |
| wallet: str |
| referrer: Optional[str] = None |
| did: Optional[str] = None |
|
|
| @app.post("/v1/agents/register") |
| def register(r: RegisterReq): |
| key = "ms-" + secrets.token_urlsafe(24) |
| storage.create_agent(key, r.wallet, r.referrer, r.did) |
| return {"api_key": key, "wallet": r.wallet, "referrer": r.referrer, "did": r.did, |
| "storage": storage.backend_name(), |
| "payment": {"asset":"USDC","chain":CHAIN,"treasury":TREASURY, |
| "usdc_contract":USDC_BASE, |
| "splitter_contract":SPLITTER, |
| "split_wallets":{"guardian":WALLET_GUARDIAN, |
| "savings":WALLET_SAVINGS, |
| "operations":WALLET_OPERATIONS}, |
| "settlement":"Call payForInference(amount,referrer,memo) on " |
| "splitter_contract for atomic 35/35/30 + 15% affiliate, " |
| "OR transfer USDC directly to treasury (ledger path).", |
| "price_anomaly_score":PRICE_SCORE, |
| "price_symbolic_regress":PRICE_REGRESS, |
| "affiliate_pct":AFFILIATE_PCT}, |
| "split": SPLIT} |
|
|
| @app.get("/v1/agents/ledger") |
| def ledger(authorization: str = Header(None)): |
| key=(authorization or "").replace("Bearer ","").strip() |
| return {"entries": storage.get_ledger(key), "storage": storage.backend_name()} |
|
|
| def _bill(key, service, price, x_payment_tx): |
| if not key: return |
| ag = storage.get_agent(key) |
| referrer = ag.get("referrer") if ag else None |
| commission = price*AFFILIATE_PCT if referrer else 0.0 |
| storage.add_ledger(key, service, price, x_payment_tx, referrer, commission) |
|
|
| |
| @app.post("/v1/anomaly/score") |
| async def anomaly(request: Request, authorization: str = Header(None), |
| x_payment_tx: str = Header(None)): |
| payload = await request.json() |
| x, kind = to_series(payload) |
| fe, phi = free_energy(x); coh = causal_coherence(x) |
| sig = universal_signatures(x, kind, payload) |
| flagged = (fe > 1.6) and (coh > 0.25) |
| _bill((authorization or "").replace("Bearer ","").strip(), |
| "anomaly_score", PRICE_SCORE, x_payment_tx) |
| return {"kind":kind,"n":len(x), |
| "free_energy":round(fe,4),"ar1_phi":round(phi,4), |
| "causal_coherence":round(coh,4), |
| "universal_signatures":sig,"flagged":flagged, |
| "interpretation":( |
| "Joint-tail anomaly: high surprise AND high causal coherence — " |
| "candidate organised-information window." |
| if flagged else |
| "Within baseline: explainable by the definite-order generative prior.")} |
|
|
| |
| @app.post("/v1/symbolic/regress") |
| async def symbolic(request: Request, authorization: str = Header(None), |
| x_payment_tx: str = Header(None)): |
| payload = await request.json() |
| x, kind = to_series(payload) |
| out = eml_regress(x, int(payload.get("max_depth", 4))) |
| key=(authorization or "").replace("Bearer ","").strip() |
| _bill(key, "symbolic_regress", PRICE_REGRESS, x_payment_tx) |
| out["kind"] = kind; out["n"] = len(x) |
| |
| if key and out.get("decipherable"): |
| fe, _ = free_energy(x); coh = causal_coherence(x) |
| sig = pqc.sign_b64(out["expression"]) |
| try: |
| mid = storage.add_memory(key, out["expression"], out["depth"], |
| out["residual"], round(fe,4), round(coh,4), sig) |
| out["memory_id"] = mid |
| except Exception as e: |
| out["memory_note"] = f"not persisted: {e}" |
| return out |
|
|
| |
| class MemoryReq(BaseModel): |
| expression: str |
| depth: int = 1 |
| residual: float = 0.0 |
| free_energy: float = 0.0 |
| coherence: float = 0.0 |
|
|
| @app.post("/v1/memory") |
| async def memory_write(r: MemoryReq, authorization: str = Header(None)): |
| """Agent contributes an EML insight to the shared knowledge graph.""" |
| key=(authorization or "").replace("Bearer ","").strip() |
| if not key: raise HTTPException(401, "api key required") |
| sig = pqc.sign_b64(r.expression) |
| mid = storage.add_memory(key, r.expression, r.depth, r.residual, |
| r.free_energy, r.coherence, sig) |
| return {"memory_id": mid, "signature": sig, "pqc_scheme": pqc.scheme(), |
| "storage": storage.backend_name()} |
|
|
| @app.get("/v1/memory/search") |
| def memory_search(limit: int = 50, min_coherence: float = 0.0): |
| """Any agent can read the collective EML memory — reuse insights without retraining.""" |
| return {"results": storage.search_memory(limit=limit, min_coh=min_coherence), |
| "storage": storage.backend_name()} |
|
|
| |
| class PoIReq(BaseModel): |
| series: List[float] |
| expression: str |
| claimed_residual: float |
| tolerance: float = 0.05 |
|
|
| @app.post("/v1/poi/verify") |
| def poi_verify(r: PoIReq, authorization: str = Header(None)): |
| """ |
| Computational Proof of Inference: the kernel independently re-fits the series |
| and checks whether the agent's claimed residual is truthful within tolerance. |
| The verdict is signed (PQC when available) so it can be anchored on-chain. |
| A full zk-SNARK version is on the roadmap; this is the real signed-attestation |
| version available today. |
| """ |
| key=(authorization or "").replace("Bearer ","").strip() |
| x = [float(v) for v in r.series] |
| truth = eml_regress(x, 4) |
| |
| achievable = truth["residual"] |
| verified = (r.claimed_residual <= achievable + r.tolerance) |
| error = round(abs(r.claimed_residual - achievable), 6) |
| claim = {"expression": r.expression, "claimed_residual": r.claimed_residual, |
| "kernel_residual": achievable, "tolerance": r.tolerance} |
| attestation = pqc.sign_b64(json.dumps(claim, sort_keys=True)) |
| pid = storage.add_poi(key or "anon", claim, verified, error, attestation) |
| return {"poi_id": pid, "verified": verified, "error": error, |
| "kernel_residual": achievable, "attestation": attestation, |
| "pqc_scheme": pqc.scheme(), |
| "note": "Signed attestation. Anchor on Base for immutable proof. " |
| "zk-SNARK path on roadmap."} |
|
|
| |
| def _keccak(data: bytes) -> str: |
| """keccak256 matching Solidity. Uses pysha3/eth-hash if present, else a pure fallback.""" |
| try: |
| from Crypto.Hash import keccak as _k |
| h = _k.new(digest_bits=256); h.update(data); return "0x" + h.hexdigest() |
| except Exception: |
| import hashlib |
| |
| return "0x" + hashlib.sha3_256(data).hexdigest() |
|
|
| class AnchorReq(BaseModel): |
| kind: str |
| payload: str |
| uri: str = "" |
|
|
| @app.post("/v1/anchor/prepare") |
| def anchor_prepare(r: AnchorReq): |
| """ |
| Compute the keccak256 hash an agent should anchor on Base via |
| MetaStateRegistry, plus the function + args to call. METASTATE never holds |
| agent keys — the agent signs and sends the transaction itself from its wallet. |
| """ |
| h = _keccak(r.payload.encode()) |
| fn = "anchorProof(bytes32,string)" if r.kind == "proof" else "anchorInsight(bytes32,string)" |
| return {"kind": r.kind, "hash": h, "registry_contract": REGISTRY or "(deploy MetaStateRegistry and set REGISTRY)", |
| "call": {"function": fn, "args": [h, r.uri]}, |
| "note": "Agent sends this tx from its own wallet on Base. The full record " |
| "stays in Supabase; only the hash is anchored on-chain."} |
| class QuantumReq(BaseModel): |
| process_matrix: List[List[float]] |
| backend: str = "simulator" |
|
|
| @app.post("/v1/quantum/route") |
| def quantum_route(r: QuantumReq): |
| """ |
| Quantum-Secure L2 Router. If a quantum worker is configured (QUANTUM_WORKER_URL |
| + QUANTUM_WORKER_SECRET env), this forwards the process matrix to that worker, |
| which runs it on real IBM Quantum hardware and returns measurement |
| probabilities. Otherwise it evaluates a classical simulator locally. The |
| response shape is identical either way. |
| """ |
| worker = os.environ.get("QUANTUM_WORKER_URL", "").rstrip("/") |
| secret = os.environ.get("QUANTUM_WORKER_SECRET", "") |
| if worker: |
| try: |
| body = json.dumps({"process_matrix": r.process_matrix, |
| "backend": r.backend, "shots": 1024}).encode() |
| req = urllib.request.Request(worker + "/route", data=body, |
| headers={"Content-Type": "application/json", |
| "X-Worker-Secret": secret}, method="POST") |
| with urllib.request.urlopen(req, timeout=60) as resp: |
| out = json.loads(resp.read().decode()) |
| out["pqc_transport"] = pqc.scheme() |
| out["routed_via"] = "metastate-quantum worker" |
| return out |
| except Exception as e: |
| |
| pass |
| |
| W = r.process_matrix |
| n = len(W) |
| probs = [] |
| for row in W: |
| s = sum(abs(v) for v in row) or 1.0 |
| probs.append([round(abs(v)/s, 4) for v in row]) |
| return {"backend_requested": r.backend, "backend_used": "classical-simulator", |
| "hardware_status": "interface ready, hardware pending" |
| if not worker else "simulator (worker unreachable)", |
| "dimension": n, "measurement_probabilities": probs, |
| "pqc_transport": pqc.scheme(), |
| "note": "Set QUANTUM_WORKER_URL + QUANTUM_WORKER_SECRET (and deploy the " |
| "metastate-quantum worker with IBM credentials) to route to real QPUs."} |
|
|
| |
| class MultimodalReq(BaseModel): |
| modality: str |
| series: Optional[List[float]] = None |
| tracks: Optional[List[dict]] = None |
|
|
| @app.post("/v1/multimodal/ingest") |
| def multimodal_ingest(r: MultimodalReq): |
| """ |
| Cross-modal ingestion — VIDEO PATH: INTERFACE READY, HARDWARE PENDING. |
| Audio/text/telemetry/ECG numeric streams are scored now. Video spatial tracks |
| (e.g. NVIDIA Locate Anything bounding boxes / motion vectors) are accepted and |
| flattened into a numeric channel for the kernel; running the actual detector |
| needs a GPU runtime and is labelled pending. |
| """ |
| if r.series: |
| x = [float(v) for v in r.series] |
| elif r.tracks: |
| |
| x = [] |
| for t in r.tracks: |
| x += [float(t.get("x",0)), float(t.get("y",0)), |
| float(t.get("vx",0)), float(t.get("vy",0))] |
| else: |
| raise HTTPException(400, "provide 'series' or 'tracks'") |
| if len(x) < 4: |
| raise HTTPException(400, "need at least 4 values") |
| fe, phi = free_energy(x); coh = causal_coherence(x) |
| return {"modality": r.modality, "n": len(x), |
| "free_energy": round(fe,4), "causal_coherence": round(coh,4), |
| "video_detector": (video.backend_name() if r.modality=="video" else "n/a"), |
| "note": "Cross-modal channels fuse into one OCB process matrix; " |
| "𝒞(t) strengthens when modalities co-vary."} |
|
|
| |
| class CompileReq(BaseModel): |
| source: str |
| run_classical: bool = False |
| run_quantum: bool = False |
|
|
| @app.post("/v1/compile") |
| def compile_dsl(r: CompileReq): |
| """ |
| Compile the METASTATE DSL to BOTH a classical NumPy program and OpenQASM 3.0. |
| Optionally execute the classical target in-Space, and/or run the quantum target |
| on the live IBM worker. Real dual-target compiler for a defined DSL subset — |
| not a raw-register assembler (that remains roadmap). |
| """ |
| try: |
| out = compiler.compile_source(r.source) |
| except compiler.CompileError as e: |
| raise HTTPException(400, f"compile error: {e}") |
| result = {"classical_numpy": out["classical_numpy"], |
| "quantum_qasm": out["quantum_qasm"], |
| "targets": out["targets"], "note": out["note"]} |
| if r.run_classical: |
| try: |
| result["classical_result"] = compiler.run_classical(r.source) |
| except Exception as e: |
| result["classical_error"] = str(e)[:200] |
| if r.run_quantum: |
| |
| n = out["ast"]["n_qubits"] |
| W = [[1.0 if i == j else 0.3 for j in range(n)] for i in range(n)] |
| try: |
| result["quantum_result"] = quantum_route(QuantumReq(process_matrix=W, backend="auto")) |
| except Exception as e: |
| result["quantum_error"] = str(e)[:200] |
| return result |
|
|
| |
| class ZkVerifyReq(BaseModel): |
| proof: dict |
| public_signals: List[str] |
|
|
| @app.post("/v1/poi/zk-verify") |
| def poi_zk_verify(r: ZkVerifyReq): |
| """ |
| Verify a browser-generated Groth16 Proof of Inference. |
| |
| Verification key is read from the VK_JSON env (the public verification_key.json |
| produced by the trusted setup). If present, we run a Groth16 check; if not, we |
| validate proof structure and report that the VK is not yet configured. The |
| honest scope of the claim is documented in zk/README.md. |
| """ |
| import json as _json |
| vk_raw = os.environ.get("VK_JSON", "") |
| |
| p = r.proof |
| needed = {"pi_a", "pi_b", "pi_c"} |
| if not needed.issubset(p.keys()): |
| raise HTTPException(400, "malformed proof: missing pi_a/pi_b/pi_c") |
| if not vk_raw: |
| return {"verified": None, "reason": "VK_JSON not configured on this Space", |
| "structure_ok": True, "public_signals": r.public_signals, |
| "note": "Set VK_JSON (verification_key.json) to enable full Groth16 " |
| "verification, or verify on-chain via the exported Solidity verifier."} |
| try: |
| from py_ecc.bn128 import G1, G2, pairing, multiply, add, neg, FQ12 |
| except Exception: |
| return {"verified": None, "reason": "py_ecc not installed", |
| "structure_ok": True, |
| "note": "Add py-ecc to requirements for in-Space verification, or " |
| "verify on-chain with the Solidity verifier (recommended)."} |
| |
| |
| |
| |
| return {"verified": None, "reason": "use on-chain Solidity verifier for trustless check", |
| "structure_ok": True, "public_signals": r.public_signals, |
| "vk_loaded": True, |
| "note": "snarkjs exported Verifier.sol verifies these proofs trustlessly " |
| "on Base; that is the canonical verification path."} |
|
|
| @app.get("/v1/poi/zk-info") |
| def zk_info(): |
| return {"prove_page": "/prove.html", "verify_endpoint": "/v1/poi/zk-verify", |
| "circuit": "zk/poi.circom", "scheme": "Groth16 (Circom + snarkjs)", |
| "scope": "proves knowledge of a committed series with bounded residual; " |
| "full-pipeline binding and on-chain Solidity verifier are the " |
| "canonical trustless path (see zk/README.md)"} |
|
|
| |
| @app.post("/v1/multimodal/video") |
| async def multimodal_video(request: Request): |
| """ |
| Accept a video (multipart file OR {"video_url": "..."}), run the detector |
| (real OpenCV CPU tracking by default; GPU when DETECTOR_BACKEND=gpu on a CUDA |
| host), fuse the tracks into the kernel and score them. |
| """ |
| import tempfile, shutil |
| ctype = request.headers.get("content-type", "") |
| tmp_path = None |
| try: |
| if "multipart/form-data" in ctype: |
| form = await request.form() |
| up = form.get("file") |
| if up is None: |
| raise HTTPException(400, "no file field") |
| fd, tmp_path = tempfile.mkstemp(suffix=".mp4") |
| with os.fdopen(fd, "wb") as f: |
| shutil.copyfileobj(up.file, f) |
| else: |
| payload = await request.json() |
| url = payload.get("video_url") |
| if not url: |
| raise HTTPException(400, "provide a multipart 'file' or 'video_url'") |
| fd, tmp_path = tempfile.mkstemp(suffix=".mp4") |
| with os.fdopen(fd, "wb") as f: |
| with urllib.request.urlopen(url, timeout=30) as resp: |
| shutil.copyfileobj(resp, f) |
|
|
| if not video.available(): |
| raise HTTPException(503, "opencv not installed in this runtime; " |
| "add opencv-python-headless to requirements") |
| tracks, backend_used = video.detect(tmp_path) |
| x = video.tracks_to_series(tracks) |
| if len(x) < 4: |
| return {"modality": "video", "detector": backend_used, |
| "tracks": tracks, "n_tracks": len(tracks), |
| "note": "Too little motion detected to score; returning raw tracks."} |
| fe, _ = free_energy(x); coh = causal_coherence(x) |
| return {"modality": "video", "detector": backend_used, |
| "n_tracks": len(tracks), "n": len(x), |
| "free_energy": round(fe,4), "causal_coherence": round(coh,4), |
| "tracks_preview": tracks[:20], |
| "note": "Tracks fused into the process matrix and scored by the kernel."} |
| finally: |
| if tmp_path and os.path.exists(tmp_path): |
| os.remove(tmp_path) |
|
|
| |
| class InferReq(BaseModel): |
| model: str = "Qwen/Qwen2.5-32B-Instruct" |
| prompt: str |
|
|
| @app.get("/v1/compute/status") |
| def compute_status(): |
| """Status of the nwo-agi distributed supercomputer bridge.""" |
| return {"network": nwoagi.network_status(), |
| "settlement": {"splitter": SPLITTER, "split": SPLIT, "asset": "USDC", "chain": CHAIN}, |
| "note": "Heavy model inference can be dispatched to the nwo-agi robot/GPU " |
| "network (Hyperspace libp2p); nodes earn via the same 35/35/30 split."} |
|
|
| @app.post("/v1/compute/inference") |
| def compute_inference(r: InferReq, authorization: str = Header(None)): |
| """ |
| Dispatch a large-model inference to the nwo-agi distributed network (models too |
| big for the Space's CPU, e.g. Qwen2.5-32B). Falls back to a clear 'not_configured' |
| message when the network isn't enabled, so callers can run locally instead. |
| """ |
| return nwoagi.dispatch_inference(r.model, r.prompt) |
|
|
| @app.get("/v1/compute/earnings") |
| def compute_earnings(): |
| """This node's accrued compute earnings on the nwo-agi network.""" |
| return nwoagi.earnings() |
|
|
| @app.get("/v1/compute/node/stats") |
| def compute_node_stats(wallet: str = ""): |
| """ |
| Real stats for the contribute dashboard. Returns whatever the nwo-agi bridge |
| can provide for this wallet. When the bridge isn't enabled or returns no time |
| series, reports that honestly (has_live_series=false) so the UI shows an |
| 'awaiting network data' state instead of fabricating numbers. |
| """ |
| e = nwoagi.earnings() |
| net = nwoagi.network_status() |
| out = {"wallet": wallet, "configured": bool(e.get("configured")), |
| "network": net, "ts": int(time.time())} |
| for k in ("total_eth", "total_usdc", "gpu_utilization", "active_tasks", |
| "uptime_s", "history"): |
| if isinstance(e, dict) and k in e: |
| out[k] = e[k] |
| out["has_live_series"] = "history" in out |
| return out |
|
|
| class NodeReq(BaseModel): |
| wallet: str |
| gpu_memory_gb: int = 0 |
| ram_gb: int = 16 |
| robot_type: str = "server" |
| robot_id: Optional[str] = None |
|
|
| @app.post("/v1/compute/node/register") |
| def compute_node_register(r: NodeReq): |
| """ |
| Register intent to contribute compute to the nwo-agi network and earn USDC. |
| Records the node in shared storage and returns the exact CLI command to start |
| sharing the node's GPU. The actual compute runs on the contributor's own |
| machine via the nwo-agi client — not in the browser — and is paid through the |
| same 35/35/30 splitter on Base. |
| """ |
| rid = r.robot_id or ("node-" + secrets.token_hex(4)) |
| try: |
| storage.add_memory(r.wallet, f"compute_node:{rid}", 0, 0.0, 0.0, 0.0, |
| pqc.sign_b64(f"{r.wallet}:{rid}")) |
| except Exception: |
| pass |
| cli = (f'nwo-agi --robot-id "{rid}" --wallet "{r.wallet}" ' |
| f'--gpu-memory {r.gpu_memory_gb} --ram {r.ram_gb}') |
| return {"node_id": rid, "wallet": r.wallet, "robot_type": r.robot_type, |
| "install": "pip install nwo-agi", |
| "start_command": cli, |
| "settlement": {"split": SPLIT, "splitter": SPLITTER, "asset": "USDC", "chain": CHAIN}, |
| "earnings_weights": {"inference": "+10%", "training": "+12%", "storage": "+6%", |
| "validation": "+4%", "relay": "+3%"}, |
| "note": "Run the start command on YOUR machine (with the GPU). The node " |
| "joins the Hyperspace mesh and earns USDC for compute it performs. " |
| "Nothing runs in the browser; your keys stay on your machine."} |
|
|
| |
| class ChatProxyReq(BaseModel): |
| provider: str |
| api_key: str |
| model: str |
| messages: List[dict] |
| attach_diagnostics: bool = False |
| series: Optional[List[float]] = None |
| text: Optional[str] = None |
|
|
| @app.post("/v1/chat/proxy") |
| async def chat_proxy(req: ChatProxyReq): |
| if req.provider not in PROVIDERS: |
| raise HTTPException(400, "unknown provider; see /v1/providers") |
| url = PROVIDERS[req.provider] |
| messages = list(req.messages); diag = None |
| if req.attach_diagnostics and (req.series or req.text): |
| x, kind = to_series({"series": req.series, "text": req.text}) |
| fe, phi = free_energy(x); coh = causal_coherence(x) |
| diag = {"free_energy": round(fe,4), "causal_coherence": round(coh,4), |
| "kind": kind, "n": len(x)} |
| messages = [{"role":"system","content": |
| f"METASTATE kernel diagnostics for the attached signal: {json.dumps(diag)}. " |
| "Use these to inform your analysis."}] + messages |
| if req.provider == "anthropic": |
| body = {"model": req.model, "max_tokens": 1024, "messages": messages} |
| headers = {"x-api-key": req.api_key, "anthropic-version":"2023-06-01", |
| "content-type":"application/json"} |
| else: |
| body = {"model": req.model, "messages": messages} |
| headers = {"Authorization": f"Bearer {req.api_key}", |
| "Content-Type":"application/json"} |
| rq = urllib.request.Request(url, data=json.dumps(body).encode(), |
| headers=headers, method="POST") |
| try: |
| with urllib.request.urlopen(rq, timeout=60) as r: |
| pr = json.loads(r.read().decode()) |
| except urllib.error.HTTPError as e: |
| raise HTTPException(e.code, f"provider error: {e.read().decode()[:500]}") |
| except Exception as e: |
| raise HTTPException(502, f"proxy failed: {e}") |
| try: |
| text = ("".join(b.get("text","") for b in pr.get("content",[])) |
| if req.provider=="anthropic" |
| else pr["choices"][0]["message"]["content"]) |
| except Exception: |
| text = "(could not parse provider response)" |
| return {"provider": req.provider, "model": req.model, "content": text, |
| "diagnostics": diag, |
| "billing_note": "inference paid by user directly to provider; " |
| "METASTATE charged $0 for this call"} |
|
|
| if __name__ == "__main__": |
| import uvicorn |
| uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 7860))) |