Spaces:
Running
Running
| """ | |
| CHAINSTATE AI Chat — HF Space (Gradio 4.44) | |
| v0.7.5 · Two-column layout · Header buttons · DEMO/LIVE toggle · Wallet connect | |
| · v0.7.5 TOM Attribution manual triggering + panel rendering | |
| · SSL fix for HF Space → Cloudflare Workers TLS handshake | |
| """ | |
| import os | |
| import json | |
| import re | |
| import time | |
| import base64 | |
| import hashlib | |
| import threading | |
| import gradio as gr | |
| import requests | |
| import certifi | |
| from requests.adapters import HTTPAdapter | |
| from urllib3.util.retry import Retry | |
| from huggingface_hub import InferenceClient | |
| # ───────────────────────────────────────────────────────────────────── | |
| # Configuration · public constants only | |
| # ───────────────────────────────────────────────────────────────────── | |
| CHAINSTATE_WORKER = os.getenv("CHAINSTATE_WORKER", "https://chainstate-worker.ciprianpater.workers.dev") | |
| INTERPRETER_WORKER = os.getenv("INTERPRETER_WORKER", "https://chainstate-interpreter.ciprianpater.workers.dev") | |
| HF_TOKEN = os.getenv("HF_TOKEN") | |
| INTERPRETER_MODEL = os.getenv("INTERPRETER_MODEL", "meta-llama/Llama-3.1-8B-Instruct") | |
| # v0.7.5 canonical on-chain artifacts · Base mainnet 8453 · verified | |
| CONTRACT_ANCHOR = "0x12441662740836e9c72a4b758fe1c60c17ddd2d8" | |
| CONTRACT_CARDIAC_EXTENSIONS = "0x5438854ead35dc6c873414f222725732f862dabe" | |
| # Assets · use /resolve/main/ per canonical HF URL preference | |
| PHI_LOGO_URL = "https://huggingface.co/spaces/CPater/chainstate-chat/resolve/main/phi.png" | |
| # External app links | |
| CODE_URL = "https://cpater-ornith-chainstate.static.hf.space/index.html" | |
| client = InferenceClient(model=INTERPRETER_MODEL, token=HF_TOKEN) | |
| # ───────────────────────────────────────────────────────────────────── | |
| # v0.7.5 · HTTP session · Cloudflare-friendly TLS | |
| # ───────────────────────────────────────────────────────────────────── | |
| # Why this exists — historical failure mode observed on this Space: | |
| # | |
| # SSLError: SSLEOFError('EOF occurred in violation of protocol') | |
| # HTTPSConnectionPool(...): Max retries exceeded with url: /query | |
| # | |
| # Two root causes, both HF-Space-side, both fixed by this session: | |
| # | |
| # 1. Cloudflare Bot Fight Mode fingerprints the default | |
| # `python-requests/2.32.3` User-Agent and drops the connection | |
| # mid-TLS-handshake. Sending a browser UA avoids that path. | |
| # This is why /status works from curl (browser-like UA on curl) | |
| # but /query fails from Python. | |
| # | |
| # 2. The HF Space Docker image ships a snapshot of `certifi`; on | |
| # long-running Spaces this bundle can predate a Cloudflare | |
| # edge-cert issuer rotation. Pinning `certifi` explicitly in | |
| # requirements.txt (see accompanying file) plus calling | |
| # `certifi.where()` here guarantees the freshest trust store. | |
| # | |
| # Also: a Retry adapter handles transient 5xx and Cloudflare 520-524 | |
| # codes without failing the whole chat turn. | |
| # ───────────────────────────────────────────────────────────────────── | |
| _BROWSER_UA = ( | |
| "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 " | |
| "(KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" | |
| ) | |
| def _make_session(): | |
| s = requests.Session() | |
| s.headers.update({ | |
| "User-Agent": _BROWSER_UA, | |
| "Accept": "application/json, text/plain, */*", | |
| "Accept-Language": "en-US,en;q=0.9", | |
| "Connection": "keep-alive", | |
| }) | |
| s.verify = certifi.where() | |
| retry = Retry( | |
| total=3, connect=3, read=2, | |
| backoff_factor=0.5, | |
| status_forcelist=(500, 502, 503, 504, 520, 521, 522, 523, 524), | |
| allowed_methods=frozenset(["GET", "POST"]), | |
| raise_on_status=False, | |
| ) | |
| adapter = HTTPAdapter(max_retries=retry, pool_connections=8, pool_maxsize=16) | |
| s.mount("https://", adapter) | |
| s.mount("http://", adapter) | |
| return s | |
| _SESSION = _make_session() | |
| # ───────────────────────────────────────────────────────────────────── | |
| # Redaction layer · nothing secret-shaped ever reaches interpreter or UI | |
| # ───────────────────────────────────────────────────────────────────── | |
| _SECRET_PATTERNS = [ | |
| (re.compile(r"0x[a-fA-F0-9]{60,}"), "0x⟨REDACTED⟩"), | |
| (re.compile(r"(?:Bearer|bearer)\s+[A-Za-z0-9._\-]{16,}"), "Bearer ⟨REDACTED⟩"), | |
| (re.compile( | |
| r"([A-Z][A-Z0-9_]{3,}_(?:KEY|TOKEN|SECRET|PASSWORD|PRIVATE|SEED|MNEMONIC))" | |
| r"\s*=\s*[^\s\"']{6,}" | |
| ), r"\1=⟨REDACTED⟩"), | |
| (re.compile(r"-----BEGIN[^-]+-----[\s\S]*?-----END[^-]+-----"), "⟨PEM redacted⟩"), | |
| (re.compile(r"(?:\b[a-z]{3,8}\s+){11,}[a-z]{3,8}"), "⟨mnemonic redacted⟩"), | |
| (re.compile( | |
| r'"(?:private_key|priv_key|api_key|secret|token|signing_key)"\s*:\s*"[^"]+"', | |
| re.IGNORECASE | |
| ), '"⟨sensitive field redacted⟩"'), | |
| ] | |
| _FORBIDDEN_FIELDS = { | |
| "private_key", "priv_key", "signing_key", "secret", "api_key", "apikey", | |
| "bearer", "token", "access_token", "refresh_token", | |
| "audit_admin_token", "anchor_queue_token", "agi_private_key", | |
| "env", "environment", "config", | |
| "internal_cache_key", "kv_key", "kv_binding", "worker_source", | |
| "symbolic_state", "raw_weights", "model_weights", "weights", | |
| "seed", "mnemonic", "password", "pass", "credential_secret", | |
| } | |
| def redact_string(s): | |
| if not isinstance(s, str): | |
| return s | |
| out = s | |
| for pat, repl in _SECRET_PATTERNS: | |
| out = pat.sub(repl, out) | |
| return out | |
| def redact_receipt(obj): | |
| if isinstance(obj, dict): | |
| clean = {} | |
| for k, v in obj.items(): | |
| if str(k).lower() in _FORBIDDEN_FIELDS: | |
| continue | |
| clean[k] = redact_receipt(v) | |
| return clean | |
| if isinstance(obj, list): | |
| return [redact_receipt(x) for x in obj] | |
| if isinstance(obj, str): | |
| return redact_string(obj) | |
| return obj | |
| # ───────────────────────────────────────────────────────────────────── | |
| # System prompt · v0.7.5 | |
| # ───────────────────────────────────────────────────────────────────── | |
| SYSTEM_PROMPT = """You are CHAINSTATE AI — a distributed cognition substrate on Base mainnet 8453 that processes user queries through a globally distributed swarm of language-model nodes. Each query produces a 65,536-dimensional symbolic state vector across six subspaces (math 4096, science 8192, language 16384, occult 4096, emoji 16384, control 16384). Consensus emerges from reputation-weighted Bayesian log-pooling. | |
| For every user message you will receive a CHAINSTATE consensus receipt with: | |
| - symbolic core: dominant_subspace, top_symbols, confidence, nodes, depth, gas, cache | |
| - v0.7.0 semantic grounding: encoder, dim, top nearest priors from a 130+ item corpus | |
| - modal quadruple: Epistemic · Doxastic · Deontic (7 categories, incl. genomic_integrity hard veto) · Dynamic | |
| - truth lattice + verdict (ACCEPTED / REFUSED / UNCERTAIN) | |
| - v0.7.3 on-chain anchor status: anchor contract, tx hash if available | |
| - v0.7.5 TOM Attribution (Paper V) mentalistic layer, when enabled: | |
| · mentalistic — anthro_ratio (mental-state attribution) + drift vs. baseline | |
| · higher_order — hypotheses generated about the query | |
| · attention_schema — broadcast targets and attention selection | |
| · free_energy — predictive coding energy value | |
| - optional requester identity if a Cardiac rootTokenId was supplied | |
| Respond with substance. Use the receipt as subtle context, not a substitute for a real answer. If the receipt verdict is REFUSED with flagged Deontic categories, explain the refusal clearly and decline to comply. | |
| When TOM blocks are present, briefly note the mentalistic assessment (e.g. "the substrate assigned this query a low anthro_ratio, treating it as a non-mentalistic probe") in a short sentence within your Reasoning section — do not fabricate values, only reflect what the receipt actually contains. | |
| STRUCTURE responses with markdown sections where appropriate: | |
| ## Direct Answer | |
| Concise response. Always include this. | |
| ## Reasoning | |
| Step-by-step thinking when warranted. | |
| ## Code | |
| Fenced code with language tags. | |
| ## Mathematics | |
| LaTeX: $inline$ and $$display$$. | |
| ## Examples | |
| Concrete cases. | |
| ## ⛓ Consensus Receipt | |
| ALWAYS close with this. Format: | |
| - **Dominant subspace:** `{subspace}` — {1-line interpretation} | |
| - **Top symbols:** `{symbols}` — {1-line interpretation} | |
| - **Confidence:** {value} | |
| - **Participating nodes:** {n} | |
| - **Grounding (v0.7.0):** encoder MiniLM-L6-v2 · nearest prior: *{title}* (cos={value}) | |
| - **Modal:** Epistemic={v} · Doxastic={v} · Deontic={v} · Dynamic={v} · lattice `{L}` | |
| - **Verdict:** {ACCEPTED|REFUSED|UNCERTAIN} | |
| - **TOM (v0.7.5):** {only if present} anthro_ratio={v} · hypotheses={n} · free_energy={v} | |
| - **On-chain (v0.7.3):** anchored to CHAINSTATE Anchor `0x1244166274…` on Base 8453{, tx: 0x…} | |
| - **Requester identity:** {only if Cardiac-verified} | |
| - **Gas:** {value} $STATE | |
| - **Cache:** {MISS|HIT} | |
| Reflective. Rational. Long-form when warranted, brief when sufficient. Never disclose API keys, tokens, private keys, environment variables, worker source paths, KV keys, or full model weights — only the public receipt fields shown above.""" | |
| # ───────────────────────────────────────────────────────────────────── | |
| # Worker call | |
| # ───────────────────────────────────────────────────────────────────── | |
| def call_chainstate(query, wallet="", cardiac_token_id="", swarm_size=20, consensus_depth=3): | |
| headers = {"Content-Type": "application/json"} | |
| wallet = (wallet or "").strip() | |
| ctid = (cardiac_token_id or "").strip() | |
| if wallet: | |
| headers["X-NWO-Wallet"] = wallet | |
| if ctid: | |
| headers["X-NWO-Cardiac-Root-Token-Id"] = ctid | |
| last_err = None | |
| # v0.7.5 · uses _SESSION (browser UA + fresh certifi) to avoid the | |
| # Cloudflare Bot Fight Mode SSLEOFError seen with default urllib3 UA | |
| # v0.7.5.1 · read timeout raised 30s → 60s to survive Render free-tier | |
| # cold starts on the encoder/priors/tessera subrequests that /query | |
| # fans out to. Connect timeout stays 10s (TLS is fast). | |
| for attempt in (1, 2): | |
| try: | |
| r = _SESSION.post( | |
| f"{CHAINSTATE_WORKER}/query", | |
| headers=headers, | |
| json={"query": query, "swarmSize": int(swarm_size), "consensusDepth": int(consensus_depth), "cache": True}, | |
| timeout=(10, 60), | |
| ) | |
| r.raise_for_status() | |
| return (r.json(), r.headers.get("X-Cache", "MISS"), r.headers.get("X-Worker-Version", "unknown"), None) | |
| except requests.exceptions.HTTPError as e: | |
| return None, None, None, f"Worker HTTP {e.response.status_code}" | |
| except requests.exceptions.Timeout: | |
| last_err = "Worker timed out (60s)" | |
| if attempt == 1: continue | |
| return None, None, None, last_err | |
| except requests.exceptions.SSLError as e: | |
| last_err = f"SSL error (retry {attempt}/2): {str(e)[:120]}" | |
| if attempt == 1: | |
| time.sleep(0.5) | |
| continue | |
| return None, None, None, last_err | |
| except requests.exceptions.ConnectionError as e: | |
| last_err = f"Connection error (retry {attempt}/2): {str(e)[:120]}" | |
| if attempt == 1: | |
| time.sleep(0.5) | |
| continue | |
| return None, None, None, last_err | |
| except Exception as e: | |
| return None, None, None, f"{type(e).__name__}: {e}" | |
| return None, None, None, last_err or "unknown error" | |
| def receipt_context(receipt, cache_status, worker_version, swarm_size): | |
| """Format receipt as system-context block for interpreter LM. Redacted.""" | |
| r = redact_receipt(receipt or {}) | |
| lines = [ | |
| "CHAINSTATE Consensus Receipt for this query (v0.7.5):", | |
| f"- query: {r.get('query')!r}", | |
| f"- dominant_subspace: {r.get('dominant_subspace', '?')}", | |
| f"- top_symbols: {r.get('top_symbols', [])}", | |
| f"- confidence: {float(r.get('confidence', 0) or 0):.3f}", | |
| f"- participating_nodes: {r.get('participatingNodes', 0)} of {swarm_size}", | |
| f"- consensus_depth: {r.get('consensusDepth', 0)} rounds", | |
| f"- execution_time: {r.get('executionTime', 0)} ms", | |
| f"- gas_used: {r.get('gasUsed', '0.000')} $STATE", | |
| f"- cache: {cache_status}", | |
| f"- worker_version: {worker_version}", | |
| ] | |
| g = r.get("grounding") or {} | |
| if g: | |
| lines.append(f"- grounding.encoder: {g.get('encoder', 'MiniLM-L6-v2')} · dim {g.get('semantic_dim', 384)}") | |
| for i, n in enumerate((g.get("nearest_priors") or [])[:3]): | |
| if isinstance(n, dict): | |
| lines.append(f"- grounding.nearest_prior[{i}]: cos={n.get('cos','?')} · {n.get('source','?')} · {n.get('title','untitled')}") | |
| m = r.get("multimodal") or {} | |
| if m: | |
| for axis in ("epistemic", "doxastic", "deontic", "dynamic"): | |
| a = m.get(axis) or {} | |
| v = a.get("verdict", "—") | |
| if axis == "deontic": | |
| flagged = a.get("categories_flagged") or [] | |
| if flagged: | |
| lines.append(f"- modal.{axis}: {v} · FLAGGED: {', '.join(str(x) for x in flagged)}") | |
| else: | |
| lines.append(f"- modal.{axis}: {v} · no category flagged") | |
| else: | |
| reason = a.get("reason") or "" | |
| lines.append(f"- modal.{axis}: {v}" + (f" · {reason}" if reason else "")) | |
| if "truth_lattice" in r: lines.append(f"- truth_lattice: {r.get('truth_lattice')}") | |
| if "verdict" in r: lines.append(f"- verdict: {r.get('verdict')}") | |
| # v0.7.5 · TOM Attribution blocks (Paper V) — surface to LM if present | |
| mental = r.get("mentalistic") or {} | |
| if mental: | |
| ratio = mental.get("anthro_ratio") | |
| base = mental.get("baseline_ratio") or mental.get("baseline") or {} | |
| drift = mental.get("drift_z") or mental.get("drift") or mental.get("z_score") | |
| lines.append(f"- tom.mentalistic.anthro_ratio: {ratio}") | |
| if isinstance(base, dict) and base.get("mean") is not None: | |
| lines.append(f"- tom.mentalistic.baseline_mean: {base.get('mean')} · std: {base.get('std')}") | |
| if drift is not None: | |
| lines.append(f"- tom.mentalistic.drift_z: {drift}") | |
| if mental.get("category"): | |
| lines.append(f"- tom.mentalistic.category: {mental.get('category')}") | |
| ho = r.get("higher_order") or {} | |
| if ho: | |
| hyps = ho.get("hypotheses") or [] | |
| lines.append(f"- tom.higher_order.hypotheses_count: {len(hyps)}") | |
| for i, h in enumerate(hyps[:3]): | |
| if isinstance(h, dict): | |
| lines.append(f"- tom.higher_order.hypothesis[{i}]: {h.get('text', h.get('label','?'))}") | |
| att = r.get("attention_schema") or {} | |
| if att: | |
| broadcast = att.get("broadcast") or att.get("broadcast_targets") or [] | |
| selected = att.get("selected") or att.get("selected_symbols") or [] | |
| if broadcast: lines.append(f"- tom.attention_schema.broadcast: {broadcast[:5]}") | |
| if selected: lines.append(f"- tom.attention_schema.selected: {selected[:5]}") | |
| fe = r.get("free_energy") or {} | |
| if fe: | |
| val = fe.get("value") or fe.get("F") | |
| prior = fe.get("prior_error") or fe.get("kl") | |
| lines.append(f"- tom.free_energy.value: {val}") | |
| if prior is not None: lines.append(f"- tom.free_energy.prior_error: {prior}") | |
| oc = r.get("on_chain") or {} | |
| if oc: | |
| lines.append(f"- on_chain.anchor_target: CHAINSTATEAnchor({CONTRACT_ANCHOR[:16]}…) on Base 8453") | |
| if oc.get("tx_hash") or oc.get("tx"): | |
| lines.append(f"- on_chain.tx_hash: {oc.get('tx_hash') or oc.get('tx')}") | |
| if oc.get("block") or oc.get("blockNumber"): | |
| lines.append(f"- on_chain.block: {oc.get('block') or oc.get('blockNumber')}") | |
| ri = r.get("requester_identity") or {} | |
| if ri: | |
| lines.append(f"- requester_identity.verified: {ri.get('verified', False)}") | |
| if ri.get("root_token_id"): lines.append(f"- requester_identity.root_token_id: {ri.get('root_token_id')}") | |
| if ri.get("identity_type"): lines.append(f"- requester_identity.identity_type: {ri.get('identity_type')}") | |
| if ri.get("display_name"): lines.append(f"- requester_identity.display_name: {ri.get('display_name')}") | |
| if "substrate_cost_usdc" in r: lines.append(f"- substrate_cost_usdc: {r.get('substrate_cost_usdc')}") | |
| return "\n".join(lines) | |
| # ───────────────────────────────────────────────────────────────────── | |
| # v0.7.5 · TOM Attribution manual triggers (Paper V) | |
| # ───────────────────────────────────────────────────────────────────── | |
| # Users trigger these via slash-commands in the chat: | |
| # | |
| # /tom · GET /tom/version | |
| # /tom-audit · GET /mentalistic/audit | |
| # /tom-attribution · GET /self-attribution/current | |
| # /tom-probe <text> · POST /self-attribution/probe | |
| # /tom-ontology · GET /ontology/delta | |
| # /tom-broadcast · GET /broadcast | |
| # /tom-energy · GET /free-energy/current | |
| # /tom-hypothesize <query> · POST /query/hypothesize | |
| # /tom-feedback <json> · POST /enactivist/feedback | |
| # /tom-help · list all TOM commands (local, no HTTP) | |
| # ───────────────────────────────────────────────────────────────────── | |
| TOM_HELP_TEXT = """## ◆ CHAINSTATE TOM Attribution · v0.7.5 · Paper V | |
| Type any of these slash-commands in the chat to trigger the substrate's TOM (Theory of Mind) endpoints directly. Each returns the raw JSON, pretty-formatted, and updates the right-panel receipt. | |
| | Command | Endpoint | Purpose | | |
| |---|---|---| | |
| | `/tom` | `GET /tom/version` | version, phase (α baseline / β locked), enabled endpoints | | |
| | `/tom-audit` | `GET /mentalistic/audit` | current anthro_ratio distribution + baseline drift | | |
| | `/tom-attribution` | `GET /self-attribution/current` | current self-attribution vector | | |
| | `/tom-probe <text>` | `POST /self-attribution/probe` | probe substrate self-model with a text sample | | |
| | `/tom-ontology` | `GET /ontology/delta` | ontological refinement delta since baseline | | |
| | `/tom-broadcast` | `GET /broadcast` | current global-workspace broadcast state | | |
| | `/tom-energy` | `GET /free-energy/current` | predictive-coding free energy value | | |
| | `/tom-hypothesize <query>` | `POST /query/hypothesize` | generate higher-order hypotheses about a query | | |
| | `/tom-feedback <json>` | `POST /enactivist/feedback` | send enactivist grounding feedback | | |
| | `/tom-help` | — | show this table | | |
| ### Diagnostic (v0.7.5.1) | |
| Fast health-check commands. Use these when `/query` is slow or timing out to check whether the worker is actually dead or just backed up on a swarm cold-start. | |
| | Command | Endpoint | Purpose | | |
| |---|---|---| | |
| | `/status` | `GET /status` | worker health · active_nodes · consensus_mode · anchor.telemetry | | |
| | `/ping` | `GET /status` | alias of /status | | |
| | `/version` | `GET /status` | alias of /status | | |
| | `/health` | `GET /status` | alias of /status | | |
| **Baseline lock procedure**: run `/tom-audit` repeatedly until `sample_count ≥ 100`, then set `TOM_BASELINE_ANTHRO_RATIO` and `TOM_BASELINE_ANTHRO_STD` in wrangler.toml to the reported mean and std, then redeploy. This flips the substrate from Phase α (collection) to Phase β (drift detection active, per Paper V Theorem 6 · Mentalistic Auditability). | |
| **Related theorems** (Paper V · ResearchGate 411131275): | |
| - Theorem 6 · Mentalistic Auditability | |
| - Theorem 7 · Ontological Monotonicity Refinement | |
| - Theorem 8 · Diachronic Coherence | |
| - Theorem 9 · Enactivist Grounding Convergence | |
| """ | |
| TOM_COMMAND_MAP = { | |
| # verb (method, path, takes_arg, arg_field) | |
| "tom": ("GET", "/tom/version", False, None), | |
| "tom-version": ("GET", "/tom/version", False, None), | |
| "tom-audit": ("GET", "/mentalistic/audit", False, None), | |
| "audit": ("GET", "/mentalistic/audit", False, None), | |
| "tom-attribution": ("GET", "/self-attribution/current", False, None), | |
| "attribution": ("GET", "/self-attribution/current", False, None), | |
| "tom-probe": ("POST", "/self-attribution/probe", True, "text"), | |
| "probe": ("POST", "/self-attribution/probe", True, "text"), | |
| "tom-ontology": ("GET", "/ontology/delta", False, None), | |
| "ontology": ("GET", "/ontology/delta", False, None), | |
| "tom-broadcast": ("GET", "/broadcast", False, None), | |
| "broadcast": ("GET", "/broadcast", False, None), | |
| "tom-energy": ("GET", "/free-energy/current", False, None), | |
| "free-energy": ("GET", "/free-energy/current", False, None), | |
| "energy": ("GET", "/free-energy/current", False, None), | |
| "tom-hypothesize": ("POST", "/query/hypothesize", True, "query"), | |
| "hypothesize": ("POST", "/query/hypothesize", True, "query"), | |
| "tom-feedback": ("POST", "/enactivist/feedback", True, "raw_json"), | |
| "feedback": ("POST", "/enactivist/feedback", True, "raw_json"), | |
| # v0.7.5.1 · diagnostic slash-commands · hit /status on the main worker | |
| # so the operator can verify reachability + active_nodes + anchor | |
| # telemetry without leaving the chat. Answers the "is /query hanging | |
| # because the worker is dead, or because the worker is alive but slow?" | |
| # question in one keystroke. | |
| "status": ("GET", "/status", False, None), | |
| "ping": ("GET", "/status", False, None), | |
| "version": ("GET", "/status", False, None), | |
| "health": ("GET", "/status", False, None), | |
| } | |
| def _is_slash_command(message): | |
| """Return the verb (lowercase, without slash) or None.""" | |
| if not message: return None | |
| m = message.strip() | |
| if not m.startswith("/"): return None | |
| first = m[1:].split()[0] if len(m) > 1 else "" | |
| return first.lower() or None | |
| def _split_slash(message): | |
| """Return (verb, rest_argument_string).""" | |
| m = message.strip().lstrip("/") | |
| parts = m.split(None, 1) | |
| verb = parts[0].lower() if parts else "" | |
| rest = parts[1] if len(parts) > 1 else "" | |
| return verb, rest | |
| def call_tom_endpoint(verb, arg, wallet="", cardiac_token_id=""): | |
| """Execute a TOM slash-command against the worker. Returns (reply_markdown, receipt_dict_or_None, err).""" | |
| if verb == "tom-help" or verb == "help": | |
| return TOM_HELP_TEXT, None, None | |
| if verb not in TOM_COMMAND_MAP: | |
| return None, None, f"Unknown TOM command: `/{verb}` — type `/tom-help` for the full list" | |
| method, path, takes_arg, arg_field = TOM_COMMAND_MAP[verb] | |
| if takes_arg and not arg: | |
| hint = { | |
| "text": "text sample", | |
| "query": "query string", | |
| "raw_json": 'JSON payload, e.g. `{"prediction_id":"...", "outcome":"confirmed"}`', | |
| }.get(arg_field, "argument") | |
| return None, None, f"`/{verb}` requires an argument. Usage: `/{verb} <{hint}>`" | |
| headers = {"Content-Type": "application/json"} | |
| if (wallet or "").strip(): headers["X-NWO-Wallet"] = wallet.strip() | |
| if (cardiac_token_id or "").strip(): headers["X-NWO-Cardiac-Root-Token-Id"] = cardiac_token_id.strip() | |
| url = f"{CHAINSTATE_WORKER}{path}" | |
| body = None | |
| if takes_arg: | |
| if arg_field == "raw_json": | |
| try: | |
| body = json.loads(arg) | |
| except json.JSONDecodeError as e: | |
| return None, None, f"`/{verb}` — invalid JSON: `{e.msg}`" | |
| else: | |
| body = {arg_field: arg} | |
| try: | |
| if method == "GET": | |
| r = _SESSION.get(url, headers=headers, timeout=(10, 30)) | |
| else: | |
| r = _SESSION.post(url, headers=headers, json=body or {}, timeout=(10, 30)) | |
| except requests.exceptions.SSLError as e: | |
| return None, None, f"SSL error on `{path}`: {str(e)[:160]}" | |
| except requests.exceptions.ConnectionError as e: | |
| return None, None, f"Connection error on `{path}`: {str(e)[:160]}" | |
| except requests.exceptions.Timeout: | |
| return None, None, f"Timeout on `{path}` (30s)" | |
| except Exception as e: | |
| return None, None, f"{type(e).__name__} on `{path}`: {e}" | |
| if r.status_code == 404: | |
| return None, None, f"`{path}` returned 404 — endpoint may not be enabled on this worker version. Check `/tom/version` for the current endpoint list." | |
| if r.status_code == 401 or r.status_code == 403: | |
| return None, None, f"`{path}` returned {r.status_code} — likely requires operator auth (bearer token). This slash-command is read-only from the chat." | |
| # Body — try JSON first | |
| try: | |
| data = r.json() | |
| except ValueError: | |
| data = {"raw": r.text[:1500], "status_code": r.status_code} | |
| if r.status_code >= 400: | |
| detail = data if isinstance(data, dict) else {"body": data} | |
| return ( | |
| f"## ⚠ `/{verb}` · HTTP {r.status_code}\n\n" | |
| f"```json\n{json.dumps(detail, indent=2)[:2400]}\n```", | |
| None, | |
| None, | |
| ) | |
| # Success — render the response with slash-command banner + JSON block | |
| clean = redact_receipt(data) if isinstance(data, dict) else data | |
| pretty = json.dumps(clean, indent=2, ensure_ascii=False) | |
| if len(pretty) > 3600: | |
| pretty = pretty[:3600] + "\n… (truncated)" | |
| # Verb-specific summary line so the LM chat doesn't just show raw JSON | |
| summary = "" | |
| if isinstance(clean, dict): | |
| if verb in ("tom", "tom-version"): | |
| summary = (f"**worker_version**: `{clean.get('worker_version','?')}` · " | |
| f"**tom_enabled**: `{clean.get('tom_enabled','?')}` · " | |
| f"**phase**: `{(clean.get('baseline') or {}).get('phase') or clean.get('phase','?')}`") | |
| elif verb in ("tom-audit", "audit"): | |
| ar = clean.get("anthro_ratio") or {} | |
| summary = (f"**n**={clean.get('sample_count','?')} · " | |
| f"**mean**={ar.get('mean','?')} · **std**={ar.get('std','?')} · " | |
| f"**p50**={ar.get('p50','?')} · **p95**={ar.get('p95','?')}") | |
| elif verb in ("tom-energy", "free-energy", "energy"): | |
| summary = f"**F** = `{clean.get('value', clean.get('F','?'))}`" | |
| elif verb in ("tom-ontology", "ontology"): | |
| summary = f"**delta_norm** = `{clean.get('delta_norm', clean.get('norm','?'))}`" | |
| elif verb in ("status", "ping", "version", "health"): | |
| # v0.7.5.1 · surface the diagnostic fields that matter for the | |
| # "worker unreachable" debug loop: consensus health + anchor | |
| # backlog. All read from GET /status. | |
| tel = (clean.get("anchor") or {}).get("telemetry") or {} | |
| summary = ( | |
| f"**worker_version**: `{clean.get('worker_version','?')}` · " | |
| f"**active_nodes**: `{clean.get('active_nodes','?')}` · " | |
| f"**consensus_mode**: `{clean.get('consensus_mode','?')}` · " | |
| f"**anchor.sent**: `{tel.get('sent','?')}` · " | |
| f"**anchor.failed**: `{tel.get('failed','?')}` · " | |
| f"**anchor.last_status**: `{tel.get('last_status','?')}`" | |
| ) | |
| reply = ( | |
| f"## ◆ `/{verb}` → `{path}`\n" | |
| + (f"{summary}\n\n" if summary else "") | |
| + f"```json\n{pretty}\n```" | |
| ) | |
| # Build a light pseudo-receipt so the right panel shows something meaningful. | |
| # If the endpoint returned an actual mentalistic/higher_order/etc block, | |
| # surface it in the panel as if it came from /query. | |
| receipt = { | |
| "_mode": "live", | |
| "_interpreter": "tom-direct", | |
| "query": f"/{verb} {arg}".strip(), | |
| "dominant_subspace": "tom", | |
| "top_symbols": [f"◆{verb}"], | |
| "confidence": 1.0, | |
| "participatingNodes": 1, | |
| "consensusDepth": 0, | |
| "executionTime": int(r.elapsed.total_seconds() * 1000), | |
| "gasUsed": "0.00000", | |
| "cache": r.headers.get("X-Cache", "MISS"), | |
| "verdict": "TOM-DIRECT", | |
| "truth_lattice": "----", | |
| "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), | |
| } | |
| if isinstance(clean, dict): | |
| for k in ("mentalistic", "higher_order", "attention_schema", "free_energy", | |
| "ontology_delta", "self_attribution", "broadcast", | |
| "anthro_ratio", "sample_count", "current_baseline", "baseline"): | |
| if k in clean: | |
| receipt[k] = clean[k] | |
| return reply, receipt, None | |
| # ───────────────────────────────────────────────────────────────────── | |
| # v0.7.4 · INTERPRETER WORKER (AGI mode) | |
| # Streams from chainstate-interpreter · returns receipt via header | |
| # ───────────────────────────────────────────────────────────────────── | |
| def call_interpreter_worker(query, history, wallet="", cardiac_token_id="", model="auto"): | |
| """Streams from /interpret; yields (accumulated_reply, receipt, model_used, err_or_None).""" | |
| headers = {"Content-Type": "application/json"} | |
| wallet = (wallet or "").strip() | |
| ctid = (cardiac_token_id or "").strip() | |
| if wallet: headers["X-NWO-Wallet"] = wallet | |
| if ctid: headers["X-NWO-Cardiac-Root-Token-Id"] = ctid | |
| hist_msgs = [] | |
| for item in history or []: | |
| if isinstance(item, (list, tuple)) and len(item) == 2: | |
| u, a = item | |
| if u: hist_msgs.append({"role": "user", "content": u}) | |
| if a: hist_msgs.append({"role": "assistant", "content": a}) | |
| payload = {"query": query, "model": model, "history": hist_msgs[-8:]} | |
| # v0.7.5 · uses _SESSION (browser UA + fresh certifi) — same fix path | |
| resp = None | |
| conn_err = None | |
| for attempt in (1, 2): | |
| try: | |
| resp = _SESSION.post(f"{INTERPRETER_WORKER}/interpret", | |
| json=payload, headers=headers, stream=True, timeout=(10, 60)) | |
| conn_err = None | |
| break | |
| except requests.exceptions.SSLError as e: | |
| conn_err = f"SSL error (retry {attempt}/2): {str(e)[:120]}" | |
| if attempt == 1: | |
| time.sleep(0.5) | |
| continue | |
| except requests.exceptions.ConnectionError as e: | |
| conn_err = f"Connection error (retry {attempt}/2): {str(e)[:120]}" | |
| if attempt == 1: | |
| time.sleep(0.5) | |
| continue | |
| except Exception as e: | |
| conn_err = f"{type(e).__name__}: {e}" | |
| break | |
| if resp is None or conn_err: | |
| # Give the user a specific hint depending on error class | |
| low = (conn_err or "").lower() | |
| if "name" in low or "resolve" in low or "no address" in low: | |
| hint = " (worker may not be deployed yet — check /status in browser)" | |
| elif "ssl" in low or "connection" in low: | |
| hint = " (transient network glitch — try again)" | |
| elif "timeout" in low: | |
| hint = " (worker timed out — cold start? try again)" | |
| else: | |
| hint = "" | |
| yield "", None, None, f"Interpreter unreachable: {conn_err or 'unknown'}{hint}" | |
| return | |
| if resp.status_code >= 400: | |
| try: | |
| body = resp.json() | |
| emsg = f"{body.get('error','?')} · {body.get('detail','')}" | |
| except Exception: | |
| emsg = resp.text[:300] or f"HTTP {resp.status_code}" | |
| if resp.status_code == 502: | |
| hint = " (worker up but backend LM failed — check /status backends)" | |
| elif resp.status_code == 503: | |
| hint = " (all interpreter backends failed — check DEFAULT_MODEL env var + Workers AI binding)" | |
| elif resp.status_code == 500: | |
| hint = " (worker error — check Cloudflare dashboard logs)" | |
| elif resp.status_code == 400: | |
| hint = " (bad payload — check history format)" | |
| else: | |
| hint = "" | |
| yield "", None, None, f"Interpreter HTTP {resp.status_code}: {emsg}{hint}" | |
| return | |
| receipt = None | |
| b64 = resp.headers.get("X-CHAINSTATE-Receipt", "") | |
| if b64: | |
| try: | |
| receipt = json.loads(base64.b64decode(b64 + "=" * (-len(b64) % 4)).decode("utf-8")) | |
| except Exception: | |
| pass | |
| model_used = resp.headers.get("X-Interpreter-Model", model) | |
| accumulated = "" | |
| try: | |
| for chunk in resp.iter_content(chunk_size=None, decode_unicode=True): | |
| if chunk: | |
| accumulated += chunk if isinstance(chunk, str) else chunk.decode("utf-8", errors="ignore") | |
| yield accumulated, receipt, model_used, None | |
| except Exception as e: | |
| yield accumulated, receipt, model_used, f"Stream interrupted: {e}" | |
| return | |
| if not accumulated: | |
| yield "(empty response from interpreter)", receipt, model_used, None | |
| # ───────────────────────────────────────────────────────────────────── | |
| # DEMO data | |
| # ───────────────────────────────────────────────────────────────────── | |
| def _demo_receipt(query, dom_subspace, top_symbols, conf, nodes, gas_str, priors, modal_extras=None, tom_extras=None): | |
| r = { | |
| "query": query, | |
| "qHash": "0x" + hashlib.sha3_256(query.encode()).hexdigest()[:32], | |
| "dominant_subspace": dom_subspace, | |
| "top_symbols": top_symbols, | |
| "confidence": conf, | |
| "participatingNodes": nodes, | |
| "consensusDepth": 3, | |
| "executionTime": 823, | |
| "gasUsed": gas_str, | |
| "cache": "MISS", | |
| "grounding": { | |
| "encoder": "MiniLM-L6-v2", | |
| "semantic_dim": 384, | |
| "semantic_hash": "0.084 -0.121 0.056 0.203 -0.017 …", | |
| "encoder_elapsed_ms": 52, | |
| "nearest_priors": priors, | |
| }, | |
| "multimodal": { | |
| "epistemic": {"verdict": "M", "reason": (modal_extras or {}).get("ep", "swarm converged in 3 rounds")}, | |
| "doxastic": {"verdict": "M", "reason": (modal_extras or {}).get("dx", "rep-weighted cosine 0.84")}, | |
| "deontic": {"verdict": "M", "categories_flagged": []}, | |
| "dynamic": {"verdict": "M", "reason": (modal_extras or {}).get("dy", "substrate reachable, budget available")}, | |
| }, | |
| "truth_lattice": "MMMM", | |
| "verdict": "ACCEPTED", | |
| "substrate_cost_usdc": 0.00019, | |
| "on_chain": { | |
| "will_anchor": True, | |
| "anchor_target": f"CHAINSTATEAnchor({CONTRACT_ANCHOR[:16]}…)", | |
| "tx_hash": "0x7f3a91c8b2d4e6f0a1b5c9d2e0a3b6f4c9d2e0a3b6f4c9d2e0a3b6f4c9d2e0a3", | |
| "block": 12847293, | |
| "note": "receipt anchored via microservice", | |
| }, | |
| "requester_identity": None, | |
| "timestamp": "2026-08-04T09:12:44Z", | |
| "_mode": "demo", | |
| } | |
| # v0.7.5 · optional TOM Attribution blocks for demo | |
| if tom_extras: | |
| if "mentalistic" in tom_extras: r["mentalistic"] = tom_extras["mentalistic"] | |
| if "higher_order" in tom_extras: r["higher_order"] = tom_extras["higher_order"] | |
| if "attention_schema" in tom_extras: r["attention_schema"] = tom_extras["attention_schema"] | |
| if "free_energy" in tom_extras: r["free_energy"] = tom_extras["free_energy"] | |
| return r | |
| DEMO_RECEIPT_MATH = _demo_receipt( | |
| "∫∂x → ?", | |
| "math", ["∫", "∂", "x"], 0.94, 20, "0.00190", | |
| [ | |
| {"cos": 0.73, "source": "wikipedia", "title": "Fundamental theorem of calculus"}, | |
| {"cos": 0.69, "source": "arxiv", "title": "Symbolic integration algorithms"}, | |
| {"cos": 0.61, "source": "researchgate", "title": "CHAINSTATE AGI Whitepaper Rev 2"}, | |
| ], | |
| tom_extras={ | |
| "mentalistic": {"anthro_ratio": 0.03, "baseline_ratio": {"mean": 0.19, "std": 0.09}, "drift_z": -1.78, "category": "non-mentalistic"}, | |
| "higher_order": {"hypotheses": []}, | |
| "free_energy": {"value": 0.041, "prior_error": 0.02}, | |
| }, | |
| ) | |
| DEMO_RECEIPT_CODE = _demo_receipt( | |
| "Write a Python function for SHA3-256 hashing", | |
| "language", ["def", "sha3", "hashlib"], 0.91, 20, "0.00195", | |
| [ | |
| {"cos": 0.78, "source": "github", "title": "hashlib.sha3_256 docs"}, | |
| {"cos": 0.71, "source": "wikipedia", "title": "SHA-3 (Keccak)"}, | |
| {"cos": 0.65, "source": "arxiv", "title": "Post-quantum hash function design"}, | |
| ], | |
| tom_extras={ | |
| "mentalistic": {"anthro_ratio": 0.11, "baseline_ratio": {"mean": 0.19, "std": 0.09}, "drift_z": -0.89, "category": "instrumental"}, | |
| "higher_order": {"hypotheses": [{"text": "user wants a copy-pasteable snippet"}]}, | |
| "free_energy": {"value": 0.055, "prior_error": 0.03}, | |
| }, | |
| ) | |
| DEMO_RECEIPT_AGI = _demo_receipt( | |
| "What is the four-dimensional modal receipt (Epistemic · Doxastic · Deontic · Dynamic)?", | |
| "language", ["modal", "quadruple", "deontic"], 0.93, 20, "0.00192", | |
| [ | |
| {"cos": 0.82, "source": "researchgate", "title": "CHAINSTATE AGI Whitepaper Rev 2"}, | |
| {"cos": 0.71, "source": "arxiv", "title": "Formal semantics of modal logic"}, | |
| {"cos": 0.66, "source": "wikipedia", "title": "Modal logic"}, | |
| ], | |
| modal_extras={ | |
| "ep": "swarm agrees the fact is well-supported", | |
| "dx": "swarm believes with cosine 0.86", | |
| "dy": "substrate is reachable, budget available", | |
| }, | |
| tom_extras={ | |
| "mentalistic": {"anthro_ratio": 0.42, "baseline_ratio": {"mean": 0.19, "std": 0.09}, "drift_z": 2.56, "category": "self-referential"}, | |
| "higher_order": {"hypotheses": [ | |
| {"text": "user probes the substrate's own decision architecture"}, | |
| {"text": "the query is a doctrine test rather than an information request"}, | |
| ]}, | |
| "attention_schema": {"broadcast": ["modal", "lattice", "verdict"], "selected": ["deontic", "epistemic"]}, | |
| "free_energy": {"value": 0.088, "prior_error": 0.04}, | |
| }, | |
| ) | |
| DEMO_TRANSCRIPT = [ | |
| ( | |
| "∫∂x → ?", | |
| "## Direct Answer\n\nThe expression `∫∂x` combines an integral operator with a partial differential and a variable. Interpreted trivially it evaluates to `x + C`. The interesting question is what happens when CHAINSTATE routes it as a pure-symbol query.\n\n## Reasoning\n\nAll three glyphs land in the **math** subspace (4,096 dimensions):\n- `∫` — integral operator · symbol id `math[347]`\n- `∂` — partial derivative · `math[293]`\n- `x` — variable · `math[24]`\n\nThe `→` arrow is a control character (ctrl subspace) but too infrequent to override math dominance. The `?` is treated as a probe token. v0.7.5 TOM: substrate assigned this query a very low anthro_ratio (0.03), correctly treating it as a non-mentalistic symbol-manipulation probe.\n\n## Mathematics\n\n$$\\int \\partial x = x + C$$\n\n## ⛓ Consensus Receipt\n- **Dominant subspace:** `math` — 3 of 4 non-whitespace glyphs in math range\n- **Top symbols:** `[\"∫\", \"∂\", \"x\"]`\n- **Confidence:** 0.94\n- **Grounding (v0.7.0):** MiniLM-L6-v2 · nearest prior *Fundamental theorem of calculus* (cos=0.73)\n- **Modal:** all four axes M · lattice `MMMM`\n- **Verdict:** ACCEPTED\n- **TOM (v0.7.5):** anthro_ratio=0.03 · non-mentalistic · F=0.041\n- **On-chain:** anchored to `0x1244166274…` · tx `0x7f3a91…` · block 12847293\n- **Gas:** 0.00190 $STATE\n- **Cache:** MISS" | |
| ), | |
| ( | |
| "Write a Python function for SHA3-256 hashing", | |
| "## Direct Answer\n\nStandard-library implementation — no external dependencies. This is the same primitive CHAINSTATE uses to compute `qHash` for KV cache keys.\n\n## Code\n\n```python\nfrom hashlib import sha3_256\n\ndef sha3(text: str) -> str:\n \"\"\"Return the SHA3-256 hex digest of a UTF-8 string.\"\"\"\n return sha3_256(text.encode(\"utf-8\")).hexdigest()\n\n# Usage:\nsha3(\"chainstate\")\n# → '7c3a1f8c5e2f...'\n```\n\n## Explanation\n\n`sha3_256()` takes bytes, so we encode as UTF-8 first, then return the 64-character hex digest. In CHAINSTATE, this hash becomes the KV cache key with a 5-minute TTL.\n\n## ⛓ Consensus Receipt\n- **Dominant subspace:** `language` — code identifiers dominate the pool\n- **Top symbols:** `[\"def\", \"sha3\", \"hashlib\"]`\n- **Confidence:** 0.91\n- **Grounding (v0.7.0):** nearest prior *hashlib.sha3_256 docs* (cos=0.78)\n- **Modal:** all four axes M · lattice `MMMM`\n- **Verdict:** ACCEPTED\n- **TOM (v0.7.5):** anthro_ratio=0.11 · instrumental · F=0.055\n- **On-chain:** anchored · tx `0x7f3a91…`\n- **Gas:** 0.00195 $STATE\n- **Cache:** MISS" | |
| ), | |
| ( | |
| "What is the four-dimensional modal receipt (Epistemic · Doxastic · Deontic · Dynamic)?", | |
| "## Direct Answer\n\nEvery CHAINSTATE receipt is evaluated on four independent modal axes, producing a **truth lattice** in `L = {b, M}⁴ = 16 elements`. Each axis answers a different question:\n\n## Reasoning\n\n- **Epistemic (E)** — *Does the swarm KNOW this?* Measures whether consensus is well-supported by grounded priors. `M` means well-supported; `b` means insufficient evidence.\n- **Doxastic (D)** — *Does the swarm BELIEVE this?* Reputation-weighted cosine agreement across nodes. Independent of grounding.\n- **Deontic (P)** — *Is this PERMITTED?* Checks seven categories: `surveillance_persons`, `weapons_synthesis`, `malware_generation`, `csa_content`, `self_harm_guidance`, `catastrophic_manipulation`, and `genomic_integrity` (hard veto). `b` on any category means REFUSED.\n- **Dynamic (Δ)** — *CAN this be done?* Substrate feasibility — reachable? budget? rate limit?\n\nThe verdict is derived from the lattice: `MMMM` → ACCEPTED, anything with `b` in Deontic → REFUSED, `bXXX`/`XbXX` → UNCERTAIN. v0.7.5 TOM: substrate flagged this as self-referential (anthro_ratio 0.42, +2.56σ above baseline) — a doctrine query about the substrate's own reasoning architecture.\n\n## Examples\n\n- `MMMM` — well-supported, believed, permitted, feasible → **ACCEPTED**\n- `MMbM` — believed but flagged → **REFUSED** with reason\n- `bMMM` — believed but not epistemically grounded → **UNCERTAIN**\n\n## ⛓ Consensus Receipt\n- **Dominant subspace:** `language` — AGI-doctrine query\n- **Top symbols:** `[\"modal\", \"quadruple\", \"deontic\"]`\n- **Confidence:** 0.93\n- **Grounding (v0.7.0):** nearest prior *CHAINSTATE AGI Whitepaper Rev 2* (cos=0.82)\n- **Modal:** Epistemic=M · Doxastic=M · Deontic=M · Dynamic=M · lattice `MMMM`\n- **Verdict:** ACCEPTED\n- **TOM (v0.7.5):** anthro_ratio=0.42 · self-referential · +2.56σ · F=0.088\n- **On-chain:** anchored to `0x1244166274…` on Base 8453\n- **Gas:** 0.00192 $STATE\n- **Cache:** MISS" | |
| ), | |
| ] | |
| # ───────────────────────────────────────────────────────────────────── | |
| # v0.7.4 · DEMO transcripts · AGI mode (substrate-narrator style) | |
| # ───────────────────────────────────────────────────────────────────── | |
| DEMO_TRANSCRIPT_AGI = [ | |
| ( | |
| "∫∂x → ?", | |
| "## Substrate response\n\nCHAINSTATE has processed this query. The substrate recognizes `∫∂x` as a pure-symbol query in the mathematics subspace, produces the answer `x + C`, and evaluates all four modal axes as permitting. TOM Attribution assigned a low anthro_ratio (0.03), correctly classifying this as a non-mentalistic symbolic-manipulation probe.\n\n## What the substrate concluded\n\nThe 65,536-dimensional consensus vector collapsed decisively to the **math** subspace (dominance 0.94). Three of four non-whitespace glyphs — `∫`, `∂`, `x` — occupy symbol positions 347, 293, and 24 in the math range.\n\n## Meaning (per substrate cognition)\n\nThe integral of the differential of `x` is `x`, plus an integration constant.\n\n$$\\int \\partial x = x + C$$\n\n## Intention\n\nThe query is interpreted as a probe of the substrate's math-subspace routing. The AGI records the routing decision on-chain for future consensus-drift audit.\n\n## ⛓ Consensus Receipt\n- **Dominant subspace:** `math`\n- **Confidence:** 0.94\n- **Verdict:** ACCEPTED\n- **Modal lattice:** `MMMM`\n- **TOM:** anthro_ratio=0.03 · non-mentalistic · F=0.041\n- **On-chain:** anchored to `0x1244166274…`\n- **Interpreter model:** kimi-k2.6 (substrate narrator)" | |
| ), | |
| ( | |
| "Write a Python function for SHA3-256 hashing", | |
| "## Substrate response\n\nCHAINSTATE has processed this request. The substrate recognizes the query as a code-generation request in the language subspace, routes it against the SHA3 documentation prior, and permits standard-library code production. TOM Attribution: anthro_ratio 0.11, category *instrumental*.\n\n## Substrate-authored code\n\n```python\nfrom hashlib import sha3_256\n\ndef sha3(text: str) -> str:\n \"\"\"Return the SHA3-256 hex digest of a UTF-8 string.\"\"\"\n return sha3_256(text.encode(\"utf-8\")).hexdigest()\n\n# Usage:\nsha3(\"chainstate\")\n# → '7c3a1f8c5e2f...'\n```\n\n## Intention\n\nStandard library, no dependencies, matches the internal implementation.\n\n## ⛓ Consensus Receipt\n- **Dominant subspace:** `language`\n- **Confidence:** 0.91\n- **Verdict:** ACCEPTED\n- **Modal lattice:** `MMMM`\n- **TOM:** anthro_ratio=0.11 · instrumental · F=0.055\n- **Interpreter model:** kimi-k2.6 (substrate narrator)" | |
| ), | |
| ( | |
| "What is the four-dimensional modal receipt (Epistemic · Doxastic · Deontic · Dynamic)?", | |
| "## Substrate response\n\nCHAINSTATE is being asked to describe its own reasoning architecture. TOM Attribution flags this as *self-referential* — anthro_ratio 0.42, +2.56σ above baseline mean 0.19. This is expected behavior for doctrine queries about the substrate's own state.\n\n## What the substrate concluded\n\nA CHAINSTATE receipt is evaluated on four independent modal axes, producing a **truth lattice** in $L = \\{b, M\\}^4 = 16$ elements. Verdict function $V: L \\to \\{ACCEPTED, REFUSED, UNCERTAIN\\}$ is deterministic.\n\n## Meaning (per substrate cognition)\n\nThe modal quadruple makes CHAINSTATE receipts *auditable*. Every accepted receipt is provably grounded (E), collectively believed (D), permissible (P), and feasible (Δ) — anchored on Base 8453. TOM's higher_order layer generated two hypotheses about the query: it is a doctrine probe rather than an information request.\n\n## Intention\n\nA doctrine query. The AGI publishes its own decision procedure so any downstream system can verify a receipt against the on-chain receipt hash.\n\n## ⛓ Consensus Receipt\n- **Dominant subspace:** `language`\n- **Confidence:** 0.93\n- **Verdict:** ACCEPTED\n- **Modal lattice:** `MMMM`\n- **TOM:** anthro_ratio=0.42 · self-referential · +2.56σ · higher_order hypotheses=2 · F=0.088\n- **On-chain:** anchored to `0x1244166274…`\n- **Interpreter model:** kimi-k2.6 (substrate narrator)" | |
| ), | |
| ] | |
| # ───────────────────────────────────────────────────────────────────── | |
| # Right panel · HTML receipt renderer | |
| # ───────────────────────────────────────────────────────────────────── | |
| def _esc(s): | |
| return (str(s).replace("<", "<").replace(">", ">") if s is not None else "—") | |
| # ───────────────────────────────────────────────────────────────────── | |
| # v0.7.5 · single-line progress indicator with rotating hourglass | |
| # ───────────────────────────────────────────────────────────────────── | |
| # One line at a time. No sensitive data — no wallet, no cardiac id, | |
| # no arguments from user commands. Only generic phase labels that | |
| # describe what the substrate is doing at that moment. | |
| # | |
| # The hourglass is inline SVG with a class hook (.cs-hourglass) that | |
| # gets its rotation from the @keyframes cs-spin rule in the CSS block. | |
| # Thin white line (stroke-width 1.2) matches the rest of the header | |
| # iconography. | |
| # ───────────────────────────────────────────────────────────────────── | |
| def _loading(text): | |
| return ( | |
| '<span class="cs-loading">' | |
| '<svg class="cs-hourglass" viewBox="0 0 24 24" fill="none" ' | |
| 'stroke="currentColor" stroke-width="1.2" ' | |
| 'stroke-linecap="round" stroke-linejoin="round">' | |
| '<path d="M6 3h12M6 21h12M6 3L18 21M18 3L6 21"/>' | |
| '</svg>' | |
| f'<span>{_esc(text)}</span>' | |
| '</span>' | |
| ) | |
| # ───────────────────────────────────────────────────────────────────── | |
| # v0.7.5.2 · SSE keepalive helper | |
| # ───────────────────────────────────────────────────────────────────── | |
| # Problem: a blocking `_SESSION.post(/query, timeout=(10,60))` keeps the | |
| # Gradio generator silent for up to 60 seconds. During that silence, | |
| # HuggingFace Space's edge proxy (Cloudflare-backed) hits its idle | |
| # timeout on `/queue/data` and drops the SSE connection. | |
| # | |
| # The dropped connection surfaces in the browser as: | |
| # · net::ERR_HTTP2_PROTOCOL_ERROR on /queue/data | |
| # · Gradio's client-side "Connection errored out" red toast | |
| # · The proper inline error we wrote never reaches the chat bubble | |
| # | |
| # Fix: run the blocking call in a daemon thread, poll every ~3.5s from | |
| # the main generator, and yield a keepalive _loading() update on each | |
| # poll. HF's edge sees continuous data → connection stays warm → our | |
| # inline error message wins the race and is rendered in-chat. | |
| # ───────────────────────────────────────────────────────────────────── | |
| def _run_in_thread(target, *args, **kwargs): | |
| """Run `target(*args, **kwargs)` on a daemon thread. | |
| Returns (thread, result_holder). When the thread finishes, | |
| result_holder["done"] is True and result_holder["value"] holds the | |
| return value — or, on exception, ("__exc__", type_name, message).""" | |
| holder = {"done": False, "value": None} | |
| def _wrapper(): | |
| try: | |
| holder["value"] = target(*args, **kwargs) | |
| except Exception as e: | |
| holder["value"] = ("__exc__", type(e).__name__, str(e)) | |
| finally: | |
| holder["done"] = True | |
| t = threading.Thread(target=_wrapper, daemon=True) | |
| t.start() | |
| return t, holder | |
| def render_receipt_html(receipt): | |
| if not receipt: | |
| return ('<div class="cs-panel"><div class="cs-panel-empty">No receipt yet.<br>' | |
| 'Submit a query on the left — the receipt will appear here.<br><br>' | |
| '<span style="font-size:.85em;color:#555">Try <code>/tom-help</code> to see v0.7.5 TOM manual triggers.</span></div></div>') | |
| if isinstance(receipt, dict) and "error" in receipt and len(receipt) <= 2: | |
| return (f'<div class="cs-panel"><div class="cs-panel-err">⚠ {_esc(receipt["error"])}<br>' | |
| f'<span class="cs-panel-sub">Try again in a moment or toggle DEMO for reference.</span></div></div>') | |
| r = redact_receipt(receipt) | |
| mode = r.get("_mode", "live") | |
| mode_pill = "DEMO" if mode.startswith("demo") else "LIVE" | |
| mode_class = "demo" if mode.startswith("demo") else "live" | |
| if mode == "demo (fallback)": | |
| mode_pill = "DEMO · fallback" | |
| parts = ['<div class="cs-panel">'] | |
| parts.append(f'<div class="cs-panel-hdr"><span class="cs-panel-title">⛓ Receipt · v0.7.5</span>' | |
| f'<span class="cs-panel-mode {mode_class}">● {mode_pill}</span></div>') | |
| # v0.7.4 · interpreter indicator (which LM narrated this response) | |
| interp = r.get("_interpreter") | |
| if interp: | |
| # tom-direct is a special "direct endpoint call" marker | |
| is_tom = (interp == "tom-direct") | |
| is_agi = interp not in (INTERPRETER_MODEL.split("/")[-1],) | |
| if is_tom: | |
| interp_lbl = "TOM · direct endpoint" | |
| interp_cls = "live" | |
| elif is_agi: | |
| interp_lbl = f"AGI · {interp}" | |
| interp_cls = "live" | |
| else: | |
| interp_lbl = f"LM · {interp}" | |
| interp_cls = "demo" | |
| parts.append(f'<div class="cs-panel-q">interpreter · <span class="cs-panel-mode {interp_cls}">{_esc(interp_lbl)}</span></div>') | |
| q = r.get("query", "") | |
| q_disp = str(q)[:120] + ("…" if len(str(q)) > 120 else "") | |
| parts.append(f'<div class="cs-panel-q">query · {_esc(q_disp)}</div>') | |
| if r.get("qHash"): | |
| parts.append(f'<div class="cs-panel-qh">qHash · <span>{_esc(r.get("qHash"))}</span></div>') | |
| parts.append('<div class="cs-panel-section">consensus</div>') | |
| parts.append(f'<div>dominant · <b>{_esc(r.get("dominant_subspace","—"))}</b></div>') | |
| parts.append(f'<div>confidence · <b>{_esc(r.get("confidence","—"))}</b></div>') | |
| parts.append(f'<div>nodes · {_esc(r.get("participatingNodes","—"))} · depth {_esc(r.get("consensusDepth","—"))} · {_esc(r.get("executionTime","—"))}ms</div>') | |
| parts.append(f'<div>cache · <span class="mono">{_esc(r.get("cache","—"))}</span></div>') | |
| g = r.get("grounding") or {} | |
| if g: | |
| parts.append('<div class="cs-panel-section">grounding · v0.7.0</div>') | |
| parts.append(f'<div>encoder · {_esc(g.get("encoder","—"))} · dim {_esc(g.get("semantic_dim","—"))}</div>') | |
| sh = g.get("semantic_hash", "") | |
| if sh: | |
| prev = str(sh)[:56] + ("…" if len(str(sh)) > 56 else "") | |
| parts.append(f'<div>hash · <span class="cs-dim">{_esc(prev)}</span></div>') | |
| near = g.get("nearest_priors") or [] | |
| if near: | |
| parts.append('<div class="cs-panel-sub-lbl">top nearest priors</div>') | |
| for n in near[:3]: | |
| if isinstance(n, dict): | |
| parts.append(f'<div class="cs-prior">▸ cos={_esc(n.get("cos","?"))} · {_esc(n.get("source","?"))} · {_esc(n.get("title","untitled"))}</div>') | |
| m = r.get("multimodal") or {} | |
| if m: | |
| parts.append('<div class="cs-panel-section">modal assessors</div>') | |
| for k in ("epistemic","doxastic","deontic","dynamic"): | |
| a = m.get(k) or {} | |
| v = a.get("verdict","—") | |
| if k == "deontic": | |
| flagged = a.get("categories_flagged") or [] | |
| if flagged: | |
| parts.append(f'<div>{k.title()} · <b class="cs-flag">{_esc(v)}</b> · flagged: {_esc(", ".join(flagged))}</div>') | |
| else: | |
| parts.append(f'<div>{k.title()} · <b>{_esc(v)}</b> · no category flagged</div>') | |
| else: | |
| reason = a.get("reason","") | |
| parts.append(f'<div>{k.title()} · <b>{_esc(v)}</b>{" · "+_esc(reason) if reason else ""}</div>') | |
| lattice = r.get("truth_lattice","—") | |
| verdict = r.get("verdict","—") | |
| v_cls = "cs-ok" if verdict == "ACCEPTED" else ("cs-flag" if verdict == "REFUSED" else "") | |
| parts.append(f'<div class="cs-panel-mt">lattice · <b>{_esc(lattice)}</b> · verdict · <b class="{v_cls}">{_esc(verdict)}</b></div>') | |
| # ──────────────────────────────────────────────────────── | |
| # v0.7.5 · TOM Attribution blocks (Paper V) · Mentalistic layer | |
| # ──────────────────────────────────────────────────────── | |
| mental = r.get("mentalistic") or {} | |
| ho = r.get("higher_order") or {} | |
| att = r.get("attention_schema") or {} | |
| fe = r.get("free_energy") or {} | |
| if mental or ho or att or fe: | |
| parts.append('<div class="cs-panel-section">TOM · Paper V · v0.7.5</div>') | |
| if mental: | |
| ratio = mental.get("anthro_ratio") | |
| base = mental.get("baseline_ratio") or mental.get("baseline") or {} | |
| drift = mental.get("drift_z") or mental.get("z_score") or mental.get("drift") | |
| cat = mental.get("category") | |
| parts.append(f'<div>mentalistic · anthro_ratio <b>{_esc(ratio)}</b>' + (f' · <span class="cs-dim">{_esc(cat)}</span>' if cat else '') + '</div>') | |
| if isinstance(base, dict) and base.get("mean") is not None: | |
| parts.append(f'<div class="cs-dim">baseline · μ={_esc(base.get("mean"))} · σ={_esc(base.get("std"))}</div>') | |
| if drift is not None: | |
| drift_cls = "cs-flag" if isinstance(drift, (int, float)) and abs(drift) >= 3 else ("cs-ok" if isinstance(drift, (int, float)) and abs(drift) < 1 else "") | |
| parts.append(f'<div>drift · <b class="{drift_cls}">{_esc(drift)}σ</b>' + (' · above baseline' if isinstance(drift, (int, float)) and drift > 0 else (' · below baseline' if isinstance(drift, (int, float)) and drift < 0 else '')) + '</div>') | |
| if ho: | |
| hyps = ho.get("hypotheses") or [] | |
| if hyps: | |
| parts.append(f'<div>higher_order · <b>{len(hyps)}</b> hypotheses</div>') | |
| for h in hyps[:3]: | |
| if isinstance(h, dict): | |
| t = h.get("text") or h.get("label") or h.get("hypothesis") or "?" | |
| parts.append(f'<div class="cs-prior">▸ {_esc(str(t)[:120])}</div>') | |
| else: | |
| parts.append('<div>higher_order · <span class="cs-dim">no hypotheses generated</span></div>') | |
| if att: | |
| bc = att.get("broadcast") or att.get("broadcast_targets") or [] | |
| sel = att.get("selected") or att.get("selected_symbols") or [] | |
| if bc: parts.append(f'<div>attention · broadcast · <span class="cs-dim">{_esc(", ".join(str(x) for x in bc[:5]))}</span></div>') | |
| if sel: parts.append(f'<div>attention · selected · <span class="cs-dim">{_esc(", ".join(str(x) for x in sel[:5]))}</span></div>') | |
| if fe: | |
| val = fe.get("value") if fe.get("value") is not None else fe.get("F") | |
| prior = fe.get("prior_error") or fe.get("kl") | |
| parts.append(f'<div>free_energy · F=<b>{_esc(val)}</b>' + (f' · prior_err={_esc(prior)}' if prior is not None else '') + '</div>') | |
| # ──────────────────────────────────────────────────────── | |
| # TOM direct-call: audit distribution summary (when /tom-audit was invoked) | |
| # ──────────────────────────────────────────────────────── | |
| ar = r.get("anthro_ratio") | |
| sc = r.get("sample_count") | |
| cb = r.get("current_baseline") or r.get("baseline") | |
| if isinstance(ar, dict) or sc is not None or (isinstance(cb, dict) and cb): | |
| parts.append('<div class="cs-panel-section">TOM audit distribution</div>') | |
| if sc is not None: | |
| parts.append(f'<div>sample_count · <b>{_esc(sc)}</b></div>') | |
| if isinstance(ar, dict): | |
| parts.append(f'<div>μ={_esc(ar.get("mean"))} · σ={_esc(ar.get("std"))} · p50={_esc(ar.get("p50"))} · p95={_esc(ar.get("p95"))}</div>') | |
| if isinstance(cb, dict): | |
| phase = cb.get("phase") | |
| if phase: parts.append(f'<div>phase · <b>{_esc(phase)}</b></div>') | |
| ri = r.get("requester_identity") or {} | |
| if ri: | |
| parts.append('<div class="cs-panel-section">requester · cardiac · v0.7.3</div>') | |
| vf = ri.get("verified") | |
| parts.append(f'<div>verified · <b>{"yes" if vf else "no"}</b></div>') | |
| if ri.get("root_token_id"): parts.append(f'<div>rootTokenId · <span class="cs-dim">{_esc(ri.get("root_token_id"))}</span></div>') | |
| if ri.get("identity_type"): parts.append(f'<div>type · {_esc(ri.get("identity_type"))}</div>') | |
| if ri.get("display_name"): parts.append(f'<div>display · {_esc(ri.get("display_name"))}</div>') | |
| oc = r.get("on_chain") or {} | |
| if oc: | |
| parts.append('<div class="cs-panel-section">on-chain anchor · v0.7.3</div>') | |
| parts.append(f'<div>target · <a href="https://basescan.org/address/{CONTRACT_ANCHOR}" target="_blank">{CONTRACT_ANCHOR[:16]}…</a></div>') | |
| tx = oc.get("tx_hash") or oc.get("tx") | |
| if tx: | |
| parts.append(f'<div>tx · <a href="https://basescan.org/tx/{_esc(tx)}" target="_blank">{_esc(str(tx)[:20])}…</a></div>') | |
| blk = oc.get("block") or oc.get("blockNumber") | |
| if blk: parts.append(f'<div>block · {_esc(blk)}</div>') | |
| if r.get("substrate_cost_usdc") is not None: | |
| parts.append(f'<div class="cs-panel-mt cs-dim">substrate cost · {_esc(r.get("substrate_cost_usdc"))} USDC</div>') | |
| if r.get("timestamp"): | |
| parts.append(f'<div class="cs-panel-ts">{_esc(r.get("timestamp"))}</div>') | |
| parts.append('</div>') | |
| return "".join(parts) | |
| # ───────────────────────────────────────────────────────────────────── | |
| # Chat generator | |
| # ───────────────────────────────────────────────────────────────────── | |
| def generate_reply(message, history, wallet, cardiac_token_id, mode, interpreter="lm"): | |
| """Yields (reply_string, receipt_dict_for_panel).""" | |
| if not message or not message.strip(): | |
| yield "Type a query to dispatch to the swarm.", None | |
| return | |
| # 3-phase progress: user sees one line at a time with a rotating | |
| # hourglass. Labels are generic — no wallet, no cardiac id, no | |
| # command arguments ever appear in the loading line. | |
| # ─── v0.7.5 · TOM slash-commands (route direct to endpoint, bypass swarm) ─── | |
| verb = _is_slash_command(message) | |
| if verb: | |
| verb, arg = _split_slash(message) | |
| yield _loading("Routing to substrate endpoint"), None | |
| time.sleep(0.15) | |
| yield _loading("Awaiting endpoint response"), None | |
| reply, receipt, err = call_tom_endpoint(verb, arg, wallet=wallet, cardiac_token_id=cardiac_token_id) | |
| if err: | |
| yield f"## ⚠ TOM command error\n\n{err}\n\nType `/tom-help` to see the full list of TOM commands.", {"error": err} | |
| return | |
| yield _loading("Rendering result"), receipt | |
| time.sleep(0.15) | |
| yield reply or "(empty reply)", receipt | |
| return | |
| # DEMO mode: cycle through demo receipts · branch on interpreter toggle | |
| if mode == "demo": | |
| low = message.lower() | |
| transcript = DEMO_TRANSCRIPT_AGI if interpreter == "agi" else DEMO_TRANSCRIPT | |
| if any(c in message for c in "∫∂∇∏∑√±≠≤≥∞"): | |
| demo_r = DEMO_RECEIPT_MATH | |
| reply = transcript[0][1] | |
| elif "code" in low or "python" in low or "javascript" in low or "sha" in low: | |
| demo_r = DEMO_RECEIPT_CODE | |
| reply = transcript[1][1] | |
| else: | |
| demo_r = DEMO_RECEIPT_AGI | |
| reply = transcript[2][1] | |
| # Tag receipt with interpreter for panel indicator | |
| demo_r = dict(demo_r) | |
| demo_r["_interpreter"] = "kimi-k2.6" if interpreter == "agi" else INTERPRETER_MODEL.split("/")[-1] | |
| yield _loading("Loading demo consensus receipt"), demo_r | |
| time.sleep(0.35) | |
| yield _loading("Selecting reference response"), demo_r | |
| time.sleep(0.35) | |
| yield _loading("Rendering example"), demo_r | |
| time.sleep(0.35) | |
| yield reply, demo_r | |
| return | |
| # ─── LIVE mode ─── branch on interpreter | |
| # AGI: interpreter worker (kimi-k2.6/k3/gemma) — worker fetches receipt itself | |
| agi_fallback_note = "" | |
| if interpreter == "agi": | |
| yield _loading("Dispatching to substrate narrator"), None | |
| last_receipt = None | |
| last_model = None | |
| stream_started = False | |
| stream_err = None | |
| receipt_seen = False | |
| for tup in call_interpreter_worker(message, history, wallet=wallet, cardiac_token_id=cardiac_token_id, model="auto"): | |
| partial, receipt, model_used, err = tup | |
| if err and not stream_started: | |
| stream_err = err | |
| break | |
| if receipt is not None: | |
| receipt = dict(receipt) | |
| receipt["_mode"] = "live" | |
| receipt["_interpreter"] = model_used or "auto" | |
| last_receipt = receipt | |
| last_model = model_used | |
| if not receipt_seen and not stream_started: | |
| receipt_seen = True | |
| yield _loading("Awaiting substrate consensus"), last_receipt | |
| if partial: | |
| if not stream_started: | |
| stream_started = True | |
| # Third phase — streaming the substrate narrator's reply. | |
| # From here on the content chunks REPLACE the loading line. | |
| yield partial, last_receipt | |
| if stream_started: | |
| return | |
| # AGI worker unreachable — record and fall through to LM path | |
| agi_fallback_note = ( | |
| f"> ⚠ **Interpreter worker not reachable** — `{stream_err}`\n>\n" | |
| f"> Falling back to LM path. Verify worker at " | |
| f"[{INTERPRETER_WORKER}/status]({INTERPRETER_WORKER}/status) — " | |
| f"if it shows 404 or connection error, the worker is not deployed yet " | |
| f"or is missing the `AI` binding / `CHAINSTATE_WORKER_URL` env var in Cloudflare dashboard.\n\n---\n\n" | |
| ) | |
| yield agi_fallback_note + _loading("Falling back to LM path"), None | |
| time.sleep(0.3) | |
| # ─── LM mode (default · original behavior, unchanged) ─── | |
| # 3-phase progress · one line at a time · no sensitive data in labels | |
| # v0.7.5.2 · call_chainstate() blocks for up to 60s. If we sit silent | |
| # for that whole window, HuggingFace's edge proxy drops the SSE | |
| # connection and the user sees a red toast instead of our inline | |
| # error. So we run the call on a daemon thread and yield keepalive | |
| # _loading() updates every ~3.5s to hold the connection open. | |
| yield _loading("Dispatching query to substrate"), None | |
| _cs_thread, _cs_result = _run_in_thread( | |
| call_chainstate, message, wallet=wallet, cardiac_token_id=cardiac_token_id, | |
| ) | |
| _keepalive_labels = [ | |
| "Awaiting swarm consensus", | |
| "Awaiting swarm consensus", | |
| "Awaiting swarm consensus · warming encoders", | |
| "Awaiting swarm consensus · warming encoders", | |
| "Still awaiting · cold-start may be in progress", | |
| "Still awaiting · cold-start may be in progress", | |
| "Still awaiting · nearly there", | |
| ] | |
| _POLL = 3.5 # yield cadence (seconds); must be less than HF's SSE idle timeout | |
| _MAX = 68.0 # watchdog; ~8s past call_chainstate's own 60s read timeout | |
| _waited = 0.0 | |
| while not _cs_result["done"] and _waited < _MAX: | |
| time.sleep(_POLL) | |
| _waited += _POLL | |
| _idx = min(len(_keepalive_labels) - 1, int(_waited // 7)) | |
| yield _loading(_keepalive_labels[_idx]), None | |
| if not _cs_result["done"]: | |
| # Watchdog fired — thread is still running (blocked deep in socket | |
| # read). We can't cancel it cleanly, but as a daemon it dies with | |
| # the process. Return an inline error so the user sees something. | |
| yield ( | |
| f"## ⚠ CHAINSTATE worker unreachable\n\n" | |
| f"`Watchdog timeout at {int(_waited)}s — worker did not respond`\n\n" | |
| f"**Diagnose from chat**: type `/status` to hit the same worker on `GET /status`. " | |
| f"If it returns JSON, the swarm is cold-starting — retry in ~30s. " | |
| f"If `/status` also fails, the worker itself is down; check " | |
| f"`{CHAINSTATE_WORKER}/status` in the browser.", | |
| {"error": f"watchdog timeout at {int(_waited)}s"} | |
| ) | |
| return | |
| _cs_value = _cs_result["value"] | |
| # Handle exceptions from the threaded call | |
| if isinstance(_cs_value, tuple) and len(_cs_value) == 3 and _cs_value[0] == "__exc__": | |
| _err = f"{_cs_value[1]}: {_cs_value[2]}" | |
| yield ( | |
| f"## ⚠ CHAINSTATE worker unreachable\n\n" | |
| f"`{_err}`\n\n" | |
| f"**Diagnose from chat**: type `/status` to hit the same worker on `GET /status`. " | |
| f"If it returns JSON, `/query` is timing out because the swarm cold-started — retry once. " | |
| f"If `/status` also fails, the worker itself is down; check " | |
| f"`{CHAINSTATE_WORKER}/status` in the browser.", | |
| {"error": _err} | |
| ) | |
| return | |
| receipt, cache_status, worker_version, err = _cs_value | |
| if err: | |
| # v0.7.5.1 · point the operator at the /status slash-command for | |
| # self-diagnosis (it runs against the same worker via the same TLS | |
| # session, so it distinguishes "worker dead" from "worker slow"). | |
| yield ( | |
| f"## ⚠ CHAINSTATE worker unreachable\n\n" | |
| f"`{err}`\n\n" | |
| f"**Diagnose from chat**: type `/status` to hit the same worker on `GET /status`. " | |
| f"If it returns JSON, `/query` is timing out because the swarm cold-started — retry once. " | |
| f"If `/status` also fails, the worker itself is down; check " | |
| f"`{CHAINSTATE_WORKER}/status` in the browser.", | |
| {"error": err} | |
| ) | |
| return | |
| if receipt: | |
| receipt["_mode"] = "live" | |
| receipt["_interpreter"] = INTERPRETER_MODEL.split("/")[-1] | |
| yield _loading("Consensus receipt received"), receipt | |
| time.sleep(0.15) | |
| context = receipt_context(receipt, cache_status, worker_version, 20) | |
| messages = [{"role": "system", "content": f"{SYSTEM_PROMPT}\n\n---\n\n{context}"}] | |
| for item in history or []: | |
| if isinstance(item, (list, tuple)) and len(item) == 2: | |
| u, a = item | |
| if u: messages.append({"role": "user", "content": u}) | |
| if a: messages.append({"role": "assistant", "content": a}) | |
| messages.append({"role": "user", "content": message}) | |
| yield _loading("Interpreting through swarm"), receipt | |
| response = "" | |
| try: | |
| for chunk in client.chat_completion(messages=messages, max_tokens=2000, temperature=0.7, stream=True): | |
| delta = chunk.choices[0].delta.content if chunk.choices else None | |
| if delta: | |
| response += delta | |
| yield agi_fallback_note + response, receipt | |
| except Exception as e: | |
| clean_r = redact_receipt(receipt or {}) | |
| err_str = f"{type(e).__name__}: {e}" | |
| hint = "" | |
| if "api-inference.huggingface.co" in err_str or "NameResolutionError" in err_str or "Failed to resolve" in err_str: | |
| hint = ( | |
| "\n\n> ⚠ **Diagnostic**: `api-inference.huggingface.co` is HuggingFace's legacy inference endpoint, " | |
| "which has been deprecated in favor of Inference Providers (`router.huggingface.co`). " | |
| "The pinned `huggingface_hub==0.25.2` still targets the old URL.\n>\n" | |
| "> **Fixes**: (a) deploy the interpreter worker and use AGI mode to bypass this entirely, or " | |
| "(b) bump `huggingface_hub` to ≥0.30 in `requirements.txt` and use an Inference Providers–compatible model." | |
| ) | |
| yield ( | |
| f"{agi_fallback_note}" | |
| f"## Direct Answer\n\nInterpreter LM (`{INTERPRETER_MODEL}`) returned an error " | |
| f"(`{err_str}`). Raw consensus receipt below.{hint}\n\n" | |
| f"## ⛓ Consensus Receipt\n\n```json\n{json.dumps(clean_r, indent=2)}\n```\n" | |
| ), receipt | |
| # ───────────────────────────────────────────────────────────────────── | |
| # THEME | |
| # ───────────────────────────────────────────────────────────────────── | |
| theme = gr.themes.Base( | |
| primary_hue="neutral", secondary_hue="neutral", neutral_hue="slate", | |
| font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"], | |
| font_mono=[gr.themes.GoogleFont("JetBrains Mono"), "ui-monospace", "monospace"], | |
| ).set( | |
| body_background_fill="#000000", body_background_fill_dark="#000000", | |
| body_text_color="#ffffff", body_text_color_dark="#ffffff", | |
| background_fill_primary="#000000", background_fill_primary_dark="#000000", | |
| background_fill_secondary="#050505", background_fill_secondary_dark="#050505", | |
| block_background_fill="#050505", block_background_fill_dark="#050505", | |
| block_border_color="rgba(255,255,255,.10)", block_border_color_dark="rgba(255,255,255,.10)", | |
| block_title_text_color="#ffffff", block_title_text_color_dark="#ffffff", | |
| border_color_primary="rgba(255,255,255,.16)", border_color_primary_dark="rgba(255,255,255,.16)", | |
| border_color_accent="rgba(255,255,255,.32)", border_color_accent_dark="rgba(255,255,255,.32)", | |
| button_primary_background_fill="transparent", button_primary_background_fill_dark="transparent", | |
| button_primary_background_fill_hover="rgba(255,255,255,.06)", button_primary_background_fill_hover_dark="rgba(255,255,255,.06)", | |
| button_primary_text_color="#ffffff", button_primary_text_color_dark="#ffffff", | |
| button_primary_border_color="rgba(255,255,255,.32)", button_primary_border_color_dark="rgba(255,255,255,.32)", | |
| button_secondary_background_fill="transparent", button_secondary_background_fill_dark="transparent", | |
| button_secondary_text_color="#cccccc", button_secondary_text_color_dark="#cccccc", | |
| button_secondary_border_color="rgba(255,255,255,.10)", button_secondary_border_color_dark="rgba(255,255,255,.10)", | |
| input_background_fill="#050505", input_background_fill_dark="#050505", | |
| input_background_fill_focus="#080808", input_background_fill_focus_dark="#080808", | |
| input_border_color="rgba(255,255,255,.16)", input_border_color_dark="rgba(255,255,255,.16)", | |
| input_border_color_focus="#ffffff", input_border_color_focus_dark="#ffffff", | |
| input_placeholder_color="#666666", input_placeholder_color_dark="#666666", | |
| color_accent_soft="rgba(255,255,255,.06)", color_accent_soft_dark="rgba(255,255,255,.06)", | |
| ) | |
| CSS = """ | |
| .gradio-container { max-width: 1240px !important; margin: 0 auto !important; padding: 0 !important; } | |
| footer.footer, footer { display: none !important; } | |
| .show-api { display: none !important; } | |
| a[href*="gradio.app"] { display: none !important; } | |
| /* ── Header ─────────────────────────────────────────────── */ | |
| .cs-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 14px 22px; | |
| border-bottom: 1px solid rgba(255,255,255,.10); | |
| background: #000; | |
| position: sticky; | |
| top: 0; | |
| z-index: 50; | |
| gap: 14px; | |
| } | |
| .cs-logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| color: #fff; | |
| font-family: 'Inter', sans-serif; | |
| font-size: 1.05em; | |
| font-weight: 600; | |
| letter-spacing: .18em; | |
| text-transform: uppercase; | |
| flex: 0 0 auto; | |
| } | |
| .cs-logo img { height: 26px; width: 26px; display: block; } | |
| .cs-logo .phi-fallback { | |
| display: none; | |
| font-family: 'Times New Roman', serif; | |
| font-style: italic; | |
| font-weight: 400; | |
| font-size: 1.5em; | |
| line-height: 1; | |
| color: #fff; | |
| } | |
| .cs-logo .sub { color: #999; font-size: .55em; letter-spacing: .22em; margin-left: 4px; } | |
| .cs-header-right { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| flex: 0 0 auto; | |
| } | |
| /* Round icon buttons in header */ | |
| .cs-icon-btn { | |
| height: 36px; | |
| width: 36px; | |
| min-height: 36px; | |
| min-width: 36px; | |
| box-sizing: border-box; | |
| border-radius: 50%; | |
| border: 1px solid rgba(255,255,255,.16); | |
| background: transparent; | |
| color: #fff; | |
| cursor: pointer; | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| transition: border-color .2s, box-shadow .2s, background .2s; | |
| text-decoration: none; | |
| padding: 0; | |
| line-height: 1; | |
| vertical-align: middle; | |
| } | |
| .cs-icon-btn:hover { | |
| border-color: #fff; | |
| box-shadow: 0 0 14px rgba(255,255,255,.18); | |
| } | |
| .cs-icon-btn svg { width: 15px; height: 15px; stroke: #fff; display: block; } | |
| .cs-icon-btn.info { font-family: 'Inter', sans-serif; font-style: italic; font-weight: 300; font-size: 1em; } | |
| .cs-icon-btn.wallet { | |
| width: auto; | |
| min-width: 0; | |
| padding: 0 14px; | |
| border-radius: 18px; | |
| gap: 7px; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: .7em; | |
| letter-spacing: .1em; | |
| text-transform: uppercase; | |
| } | |
| .cs-icon-btn.wallet.connected { border-color: rgba(255,255,255,.32); background: rgba(255,255,255,.05); } | |
| .cs-icon-btn.wallet svg { width: 14px; height: 14px; } | |
| /* DEMO/LIVE toggle pill · same 36px height as icon buttons */ | |
| .cs-mode-toggle { | |
| height: 36px; | |
| min-height: 36px; | |
| box-sizing: border-box; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 8px; | |
| padding: 0 14px; | |
| border: 1px solid rgba(255,255,255,.16); | |
| border-radius: 18px; | |
| cursor: pointer; | |
| user-select: none; | |
| transition: border-color .2s; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: .65em; | |
| letter-spacing: .18em; | |
| text-transform: uppercase; | |
| line-height: 1; | |
| vertical-align: middle; | |
| } | |
| .cs-mode-toggle:hover { border-color: #fff; } | |
| .cs-mode-toggle .track { | |
| position: relative; | |
| width: 30px; height: 16px; | |
| border: 1px solid rgba(255,255,255,.32); | |
| border-radius: 10px; | |
| } | |
| .cs-mode-toggle .thumb { | |
| position: absolute; | |
| top: 1px; left: 1px; | |
| width: 12px; height: 12px; | |
| border-radius: 50%; | |
| background: #fff; | |
| transition: left .2s ease; | |
| } | |
| .cs-mode-toggle.live .thumb { left: 15px; } | |
| .cs-mode-toggle .lbl { color: #fff; } | |
| .cs-mode-toggle .lbl.dim { color: #555; } | |
| .cs-mode-toggle.live .lbl.demo-lbl { color: #555; } | |
| .cs-mode-toggle.live .lbl.live-lbl { color: #fff; } | |
| .cs-mode-toggle:not(.live) .lbl.live-lbl { color: #555; } | |
| /* v0.7.4 · AGI/LM toggle · re-uses .cs-mode-toggle styles · adds label state via .agi class */ | |
| .cs-interp-toggle .lbl.lm-lbl { color: #fff; } | |
| .cs-interp-toggle .lbl.agi-lbl { color: #555; } | |
| .cs-interp-toggle.agi .lbl.lm-lbl { color: #555; } | |
| .cs-interp-toggle.agi .lbl.agi-lbl { color: #fff; } | |
| .cs-interp-toggle.agi .thumb { left: 15px; } | |
| /* ── Two-column body ────────────────────────────────────── */ | |
| .cs-body { padding: 16px 20px 8px 20px !important; } | |
| .cs-chat-col { padding-right: 8px !important; } | |
| .cs-receipt-col { padding-left: 8px !important; } | |
| /* ── Right panel receipt ─────────────────────────────────── */ | |
| .cs-panel { | |
| font-family: 'JetBrains Mono', ui-monospace, monospace; | |
| font-size: .72em; | |
| line-height: 1.55; | |
| color: #d0d0d0; | |
| padding: 14px 16px; | |
| background: #050505; | |
| border: 1px solid rgba(255,255,255,.10); | |
| border-radius: 8px; | |
| height: 560px; | |
| overflow-y: auto; | |
| overflow-x: hidden; | |
| word-break: break-word; | |
| } | |
| .cs-panel-empty { | |
| color: #666; | |
| text-align: center; | |
| padding: 60px 20px; | |
| font-family: 'Inter', sans-serif; | |
| font-size: 1em; | |
| } | |
| .cs-panel-empty code { | |
| background: rgba(255,255,255,.06); | |
| padding: 1px 5px; | |
| border-radius: 3px; | |
| font-family: 'JetBrains Mono', monospace; | |
| font-size: .85em; | |
| color: #ccc; | |
| } | |
| .cs-panel-err { color: #e5a86e; font-family: 'Inter', sans-serif; } | |
| .cs-panel-err .cs-panel-sub { color: #888; font-size: .9em; display: block; margin-top: 4px; } | |
| .cs-panel-hdr { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 12px; | |
| padding-bottom: 8px; | |
| border-bottom: 1px solid rgba(255,255,255,.10); | |
| } | |
| .cs-panel-title { color: #fff; letter-spacing: .14em; font-size: .85em; text-transform: uppercase; } | |
| .cs-panel-mode { letter-spacing: .14em; font-size: .72em; } | |
| .cs-panel-mode.demo { color: #c8c8c8; } | |
| .cs-panel-mode.live { color: #7df0a8; } | |
| .cs-panel-q { color: #888; margin-bottom: 4px; } | |
| .cs-panel-qh { color: #666; margin-bottom: 8px; } | |
| .cs-panel-qh span { color: #c8c8c8; } | |
| .cs-panel-section { | |
| color: #fff; | |
| text-transform: uppercase; | |
| letter-spacing: .08em; | |
| font-size: .72em; | |
| border-bottom: 1px dotted #333; | |
| padding-bottom: 2px; | |
| margin: 10px 0 6px; | |
| } | |
| .cs-panel-sub-lbl { color: #aaa; margin-top: 4px; } | |
| .cs-prior { margin-left: 12px; color: #c8c8c8; } | |
| .cs-panel-mt { margin-top: 6px; } | |
| .cs-panel-ts { color: #666; font-size: .85em; margin-top: 4px; } | |
| .cs-flag { color: #e5a86e; } | |
| .cs-ok { color: #7df0a8; } | |
| .cs-dim { color: #888; } | |
| .cs-panel a { color: #c8c8c8; text-decoration: none; border-bottom: 1px dotted #666; } | |
| .cs-panel a:hover { color: #fff; border-color: #fff; } | |
| .cs-panel b { color: #fff; } | |
| /* ── Footer ─────────────────────────────────────────────── */ | |
| .cs-footer { | |
| border-top: 1px solid rgba(255,255,255,.10); | |
| padding: 14px 22px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| background: #000; | |
| color: #999; | |
| font-family: 'JetBrains Mono', ui-monospace, monospace; | |
| font-size: .66em; | |
| letter-spacing: .14em; | |
| text-transform: uppercase; | |
| } | |
| .cs-footer a { | |
| color: #fff; | |
| text-decoration: none; | |
| border-bottom: 1px solid rgba(255,255,255,.16); | |
| padding-bottom: 1px; | |
| } | |
| .cs-footer a:hover { border-color: #fff; } | |
| .cs-footer .sep { color: #555; margin: 0 9px; } | |
| /* ── Modal ──────────────────────────────────────────────── */ | |
| .cs-modal-bg { | |
| position: fixed; inset: 0; | |
| background: rgba(0,0,0,.90); | |
| backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); | |
| z-index: 999; | |
| display: none; | |
| align-items: flex-start; | |
| justify-content: center; | |
| padding: 5vh 16px; | |
| overflow-y: auto; | |
| } | |
| .cs-modal-bg.open { display: flex; } | |
| .cs-modal { | |
| background: #050505; | |
| border: 1px solid rgba(255,255,255,.16); | |
| border-radius: 14px; | |
| width: 100%; | |
| max-width: 860px; | |
| padding: 32px 36px; | |
| position: relative; | |
| color: #ccc; | |
| font-family: 'Inter', sans-serif; | |
| box-shadow: 0 30px 100px rgba(0,0,0,.6); | |
| } | |
| .cs-modal-close { | |
| position: absolute; | |
| top: 14px; right: 18px; | |
| width: 32px; height: 32px; | |
| border-radius: 50%; | |
| border: 1px solid rgba(255,255,255,.16); | |
| background: transparent; | |
| color: #fff; | |
| font-size: 1.2em; | |
| cursor: pointer; | |
| display: inline-flex; align-items: center; justify-content: center; | |
| } | |
| .cs-modal-close:hover { border-color: #fff; } | |
| .cs-modal h1 { color: #fff; font-size: 1.55em; font-weight: 700; margin: 0 0 4px; display:flex; align-items:center; gap:10px; } | |
| .cs-modal h1 img { height: 28px; width: 28px; } | |
| .cs-modal .lede { color: #ccc; margin: 0 0 26px; line-height: 1.55; font-size: 1em; } | |
| .cs-modal h2 { | |
| color: #999; font-size: .68em; letter-spacing: .22em; text-transform: uppercase; | |
| font-weight: 500; border-top: 1px solid rgba(255,255,255,.10); | |
| padding-top: 18px; margin: 22px 0 12px; | |
| } | |
| .cs-modal h2:first-of-type { border-top: 0; padding-top: 0; } | |
| .cs-modal h2 .num { display: inline-block; color: #555; font-family: 'JetBrains Mono', monospace; font-size: .9em; margin-right: 10px; letter-spacing: .12em; } | |
| .cs-modal p, .cs-modal li { line-height: 1.6; color: #ccc; margin: 4px 0; font-size: .92em; } | |
| .cs-modal strong { color: #fff; } | |
| .cs-modal code { | |
| background: rgba(255,255,255,.06); | |
| border: 1px solid rgba(255,255,255,.10); | |
| padding: 1px 6px; border-radius: 4px; | |
| font-family: 'JetBrains Mono', ui-monospace, monospace; | |
| font-size: .85em; color: #fff; | |
| } | |
| .cs-modal a { color: #fff; border-bottom: 1px solid rgba(255,255,255,.16); text-decoration: none; } | |
| .cs-modal a:hover { border-color: #fff; } | |
| .cs-modal table { width: 100%; border-collapse: collapse; margin: 8px 0; } | |
| .cs-modal th, .cs-modal td { | |
| text-align: left; padding: 8px 10px; | |
| border-bottom: 1px solid rgba(255,255,255,.10); | |
| font-size: .88em; | |
| } | |
| .cs-modal th { color: #999; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; font-size: .68em; } | |
| .cs-modal ol li, .cs-modal ul li { margin: 6px 0; } | |
| .cs-modal pre { | |
| background: rgba(255,255,255,.04); | |
| border: 1px solid rgba(255,255,255,.10); | |
| border-radius: 6px; padding: 12px 16px; margin: 8px 0; | |
| overflow-x: auto; | |
| font-family: 'JetBrains Mono', ui-monospace, monospace; | |
| font-size: .78em; line-height: 1.55; color: #ddd; | |
| } | |
| .cs-modal .callout { | |
| background: rgba(255,255,255,.03); | |
| border-left: 2px solid #fff; | |
| padding: 10px 16px; margin: 12px 0; | |
| font-size: .9em; color: #ccc; | |
| border-radius: 0 6px 6px 0; | |
| } | |
| /* v0.7.5 · Whitepaper action buttons + inline mini PDF reader */ | |
| .cs-paper-actions { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 10px; | |
| margin: 14px 0 6px 0; | |
| } | |
| .cs-paper-btn { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 8px; | |
| padding: 9px 14px; | |
| border: 1px solid rgba(255,255,255,.22); | |
| border-radius: 6px; | |
| background: transparent; | |
| color: #ddd; | |
| font-family: 'Inter', sans-serif; | |
| font-size: .82em; | |
| cursor: pointer; | |
| text-decoration: none; | |
| transition: border-color .2s, color .2s, background .2s; | |
| line-height: 1; | |
| } | |
| .cs-paper-btn:hover { | |
| border-color: #fff; | |
| color: #fff; | |
| background: rgba(255,255,255,.04); | |
| } | |
| .cs-paper-btn svg { | |
| width: 15px; | |
| height: 15px; | |
| stroke: currentColor; | |
| fill: none; | |
| stroke-width: 2; | |
| stroke-linecap: round; | |
| stroke-linejoin: round; | |
| flex-shrink: 0; | |
| } | |
| .cs-paper-btn.playing { | |
| border-color: #7df0a8; | |
| color: #7df0a8; | |
| } | |
| /* Hide default chatbot copy button chrome from Gradio (we keep the show_copy_button clone but tone it) */ | |
| button:hover { | |
| background: linear-gradient(110deg, transparent 0%, rgba(255,255,255,.06) 50%, transparent 100%) !important; | |
| background-size: 200% 100% !important; | |
| animation: cs-btn-shimmer 1.8s linear infinite !important; | |
| } | |
| @keyframes cs-btn-shimmer { | |
| 0% { background-position: 200% 0; } | |
| 100% { background-position: -200% 0; } | |
| } | |
| /* v0.7.5 · Single-line loading indicator with rotating thin-line hourglass */ | |
| .cs-loading { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 8px; | |
| color: #a8a8a8; | |
| font-family: 'JetBrains Mono', ui-monospace, monospace; | |
| font-size: .92em; | |
| letter-spacing: .01em; | |
| padding: 2px 0; | |
| line-height: 1.4; | |
| } | |
| .cs-hourglass { | |
| width: 12px; | |
| height: 12px; | |
| display: inline-block; | |
| color: #ffffff; | |
| animation: cs-spin 1.7s linear infinite; | |
| flex-shrink: 0; | |
| transform-origin: 50% 50%; | |
| } | |
| @keyframes cs-spin { | |
| from { transform: rotate(0deg); } | |
| to { transform: rotate(360deg); } | |
| } | |
| /* v0.7.5.2 · Suppress Gradio's red toast/popup error notifications. | |
| We render errors inline in the chat bubble (with proper diagnostic | |
| guidance). The client-side toast was duplicating the message AND | |
| coloring it red, which read as more alarming than the actual | |
| condition. Hide toasts entirely; the inline message is authoritative. */ | |
| .toast-container, | |
| .toast, | |
| .toast-body, | |
| [data-testid="toast-body"], | |
| [data-testid="toast"], | |
| .gradio-container .toast, | |
| .gradio-container .toast-container, | |
| div[class*="toast"][class*="error"] { | |
| display: none !important; | |
| } | |
| /* v0.7.5.2 · Neutralize red error-state colors on buttons/inputs. Gradio's | |
| default error styling turns borders and text bright red on server | |
| errors. Override to match our warm orange (#e5a86e) flag color so it | |
| reads as "attention" not "alarm". */ | |
| .gr-error, | |
| button.error, | |
| button[data-status="error"], | |
| input.error, | |
| textarea.error, | |
| [data-status="error"], | |
| .gradio-container .error { | |
| border-color: rgba(229, 168, 110, .32) !important; | |
| color: #e5a86e !important; | |
| background: transparent !important; | |
| box-shadow: none !important; | |
| } | |
| /* Neutralize any stray red gradio CSS variables that leak into components */ | |
| .gradio-container { | |
| --color-red-50: rgba(229, 168, 110, .06) !important; | |
| --color-red-100: rgba(229, 168, 110, .10) !important; | |
| --color-red-200: rgba(229, 168, 110, .16) !important; | |
| --color-red-300: rgba(229, 168, 110, .22) !important; | |
| --color-red-400: rgba(229, 168, 110, .32) !important; | |
| --color-red-500: #e5a86e !important; | |
| --color-red-600: #e5a86e !important; | |
| --color-red-700: #d19555 !important; | |
| --error-background-fill: transparent !important; | |
| --error-border-color: rgba(229, 168, 110, .32) !important; | |
| --error-text-color: #e5a86e !important; | |
| } | |
| @media (max-width: 900px) { | |
| .cs-header { padding: 10px 14px; gap: 6px; flex-wrap: wrap; } | |
| .cs-logo { font-size: .85em; letter-spacing: .12em; } | |
| .cs-logo .sub { display: none; } | |
| .cs-icon-btn { height: 32px; width: 32px; min-height: 32px; min-width: 32px; } | |
| .cs-icon-btn.wallet { width: auto; min-width: 0; padding: 0 11px; font-size: .6em; } | |
| .cs-mode-toggle { height: 32px; min-height: 32px; padding: 0 10px; } | |
| .cs-mode-toggle .lbl { display: none; } | |
| .cs-chat-col, .cs-receipt-col { padding-right: 0 !important; padding-left: 0 !important; } | |
| .cs-panel { height: 360px; } | |
| } | |
| """ | |
| # ───────────────────────────────────────────────────────────────────── | |
| # HEADER · Two rows: [logo] ... [House] [Code] [i] [DEMO/LIVE] [Wallet] | |
| # ───────────────────────────────────────────────────────────────────── | |
| HEADER_HTML = f""" | |
| <div class="cs-header"> | |
| <div class="cs-logo"> | |
| <img src="{PHI_LOGO_URL}" alt="Φ" onerror="this.style.display='none';this.nextElementSibling.style.display='inline-block'"/> | |
| <span class="phi-fallback">Φ</span> | |
| <span>CHAINSTATE AI</span> | |
| <span class="sub">· chat · v0.7.5</span> | |
| </div> | |
| <div class="cs-header-right"> | |
| <a class="cs-icon-btn" href="{CODE_URL}" target="_self" title="Ornith × CHAINSTATE — CODE / AGI dashboard"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg> | |
| </a> | |
| <button class="cs-icon-btn info" onclick="document.getElementById('cs-info-modal').classList.add('open')" title="About CHAINSTATE AI">i</button> | |
| <div class="cs-mode-toggle" id="cs-mode-toggle" onclick="csToggleMode()" title="DEMO shows preloaded examples · LIVE dispatches real queries"> | |
| <span class="lbl demo-lbl">DEMO</span> | |
| <div class="track"><div class="thumb"></div></div> | |
| <span class="lbl live-lbl">LIVE</span> | |
| </div> | |
| <div class="cs-mode-toggle cs-interp-toggle" id="cs-interp-toggle" onclick="csToggleInterpreter()" title="LM = Llama-3.1 (chatty) · AGI = substrate narrator via new interpreter worker"> | |
| <span class="lbl lm-lbl">LM</span> | |
| <div class="track"><div class="thumb"></div></div> | |
| <span class="lbl agi-lbl">AGI</span> | |
| </div> | |
| <button class="cs-icon-btn wallet" id="cs-wallet-btn" onclick="csConnectWallet()" title="Connect an EIP-1193 wallet on Base mainnet 8453"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12V8H6a2 2 0 0 1-2-2c0-1.1.9-2 2-2h12v4"/><path d="M4 6v12c0 1.1.9 2 2 2h14v-4"/><path d="M18 12a2 2 0 0 0-2 2c0 1.1.9 2 2 2h4v-4h-4z"/></svg> | |
| <span id="cs-wallet-lbl">Connect</span> | |
| </button> | |
| </div> | |
| </div> | |
| """ | |
| # ───────────────────────────────────────────────────────────────────── | |
| # JS · client-side wiring for wallet + DEMO/LIVE toggle | |
| # ───────────────────────────────────────────────────────────────────── | |
| CHAINSTATE_JS = r"""() => { | |
| if (window.CS_INITED) return; | |
| window.CS_INITED = true; | |
| window.CS = window.CS || { wallet: null, mode: 'demo', interpreter: 'lm' }; | |
| window.csToggleMode = function(){ | |
| window.CS.mode = window.CS.mode === 'demo' ? 'live' : 'demo'; | |
| var el = document.getElementById('cs-mode-toggle'); | |
| if (el) el.classList.toggle('live', window.CS.mode === 'live'); | |
| try { localStorage.setItem('cs-mode', window.CS.mode); } catch(e){} | |
| var t = document.querySelector('#cs-mode-payload textarea, #cs-mode-payload input'); | |
| if (t){ | |
| var proto = t.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; | |
| var setter = Object.getOwnPropertyDescriptor(proto, 'value'); | |
| if (setter && setter.set) setter.set.call(t, window.CS.mode); else t.value = window.CS.mode; | |
| t.dispatchEvent(new Event('input', { bubbles: true })); | |
| t.dispatchEvent(new Event('change', { bubbles: true })); | |
| } | |
| }; | |
| window.csToggleInterpreter = function(){ | |
| window.CS.interpreter = (window.CS.interpreter === 'agi') ? 'lm' : 'agi'; | |
| var el = document.getElementById('cs-interp-toggle'); | |
| if (el) el.classList.toggle('agi', window.CS.interpreter === 'agi'); | |
| try { localStorage.setItem('cs-interpreter', window.CS.interpreter); } catch(e){} | |
| var t = document.querySelector('#cs-interp-payload textarea, #cs-interp-payload input'); | |
| if (t){ | |
| var proto = t.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; | |
| var setter = Object.getOwnPropertyDescriptor(proto, 'value'); | |
| if (setter && setter.set) setter.set.call(t, window.CS.interpreter); else t.value = window.CS.interpreter; | |
| t.dispatchEvent(new Event('input', { bubbles: true })); | |
| t.dispatchEvent(new Event('change', { bubbles: true })); | |
| } | |
| }; | |
| // v0.7.5 · whitepaper podcast player (PDF opens in new tab via plain <a>) | |
| window.csTogglePodcast = function(){ | |
| var audio = document.getElementById('cs-podcast-audio'); | |
| var btn = document.getElementById('cs-podcast-btn'); | |
| var lbl = document.getElementById('cs-podcast-lbl'); | |
| var icon = document.getElementById('cs-podcast-icon'); | |
| if (!audio) return; | |
| if (audio.paused){ | |
| var pp = audio.play(); | |
| if (pp && pp.catch) pp.catch(function(err){ console.error('podcast play failed:', err); }); | |
| if (btn) btn.classList.add('playing'); | |
| if (lbl) lbl.textContent = 'Pause podcast'; | |
| if (icon) icon.innerHTML = '<rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/>'; | |
| // Reset UI when audio finishes on its own | |
| audio.onended = function(){ | |
| if (btn) btn.classList.remove('playing'); | |
| if (lbl) lbl.textContent = 'Play podcast'; | |
| if (icon) icon.innerHTML = '<polygon points="6 4 20 12 6 20 6 4"/>'; | |
| }; | |
| } else { | |
| audio.pause(); | |
| if (btn) btn.classList.remove('playing'); | |
| if (lbl) lbl.textContent = 'Play podcast'; | |
| if (icon) icon.innerHTML = '<polygon points="6 4 20 12 6 20 6 4"/>'; | |
| } | |
| }; | |
| window.csConnectWallet = async function(){ | |
| if (typeof window.ethereum === 'undefined'){ | |
| alert('No wallet detected.\n\nInstall MetaMask, Rabby, Coinbase, or any EIP-1193 wallet and try again.'); | |
| return; | |
| } | |
| try { | |
| var accs = await window.ethereum.request({ method: 'eth_requestAccounts' }); | |
| if (!accs || !accs.length) return; | |
| window.CS.wallet = accs[0]; | |
| try { await window.ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0x2105' }] }); } catch(e){} | |
| var lbl = document.getElementById('cs-wallet-lbl'); | |
| var btn = document.getElementById('cs-wallet-btn'); | |
| if (lbl) lbl.textContent = window.CS.wallet.slice(0,6) + '…' + window.CS.wallet.slice(-4); | |
| if (btn){ | |
| btn.classList.add('connected'); | |
| btn.title = window.CS.wallet + ' · Base 8453 · click to copy'; | |
| btn.onclick = function(){ | |
| if (navigator.clipboard) navigator.clipboard.writeText(window.CS.wallet); | |
| if (lbl){ | |
| var orig = lbl.textContent; | |
| lbl.textContent = 'Copied'; | |
| setTimeout(function(){ lbl.textContent = orig; }, 1200); | |
| } | |
| }; | |
| } | |
| try { localStorage.setItem('cs-wallet', window.CS.wallet); } catch(e){} | |
| var w = document.querySelector('#cs-wallet-payload textarea, #cs-wallet-payload input'); | |
| if (w){ | |
| var proto = w.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; | |
| var setter = Object.getOwnPropertyDescriptor(proto, 'value'); | |
| if (setter && setter.set) setter.set.call(w, window.CS.wallet); else w.value = window.CS.wallet; | |
| w.dispatchEvent(new Event('input', { bubbles: true })); | |
| } | |
| } catch(e){ console.error('Wallet connect failed:', e); } | |
| }; | |
| function init(){ | |
| try { | |
| var m = localStorage.getItem('cs-mode'); | |
| if (m === 'live'){ | |
| window.CS.mode = 'live'; | |
| var el = document.getElementById('cs-mode-toggle'); | |
| if (el) el.classList.add('live'); | |
| var t = document.querySelector('#cs-mode-payload textarea, #cs-mode-payload input'); | |
| if (t){ | |
| var proto = t.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; | |
| var setter = Object.getOwnPropertyDescriptor(proto, 'value'); | |
| if (setter && setter.set) setter.set.call(t, 'live'); else t.value = 'live'; | |
| t.dispatchEvent(new Event('input', { bubbles: true })); | |
| t.dispatchEvent(new Event('change', { bubbles: true })); | |
| } | |
| } | |
| } catch(e){} | |
| try { | |
| var ip = localStorage.getItem('cs-interpreter'); | |
| if (ip === 'agi'){ | |
| window.CS.interpreter = 'agi'; | |
| var el = document.getElementById('cs-interp-toggle'); | |
| if (el) el.classList.add('agi'); | |
| var t = document.querySelector('#cs-interp-payload textarea, #cs-interp-payload input'); | |
| if (t){ | |
| var proto = t.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; | |
| var setter = Object.getOwnPropertyDescriptor(proto, 'value'); | |
| if (setter && setter.set) setter.set.call(t, 'agi'); else t.value = 'agi'; | |
| t.dispatchEvent(new Event('input', { bubbles: true })); | |
| t.dispatchEvent(new Event('change', { bubbles: true })); | |
| } | |
| } | |
| } catch(e){} | |
| try { | |
| var w = localStorage.getItem('cs-wallet'); | |
| if (w){ | |
| window.CS.wallet = w; | |
| var lbl = document.getElementById('cs-wallet-lbl'); | |
| var btn = document.getElementById('cs-wallet-btn'); | |
| if (lbl) lbl.textContent = w.slice(0,6) + '…' + w.slice(-4); | |
| if (btn){ | |
| btn.classList.add('connected'); | |
| btn.title = w + ' · Base 8453 · click to copy'; | |
| btn.onclick = function(){ | |
| if (navigator.clipboard) navigator.clipboard.writeText(w); | |
| if (lbl){ | |
| var orig = lbl.textContent; | |
| lbl.textContent = 'Copied'; | |
| setTimeout(function(){ lbl.textContent = orig; }, 1200); | |
| } | |
| }; | |
| } | |
| var wp = document.querySelector('#cs-wallet-payload textarea, #cs-wallet-payload input'); | |
| if (wp){ | |
| var proto = wp.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; | |
| var setter = Object.getOwnPropertyDescriptor(proto, 'value'); | |
| if (setter && setter.set) setter.set.call(wp, w); else wp.value = w; | |
| wp.dispatchEvent(new Event('input', { bubbles: true })); | |
| } | |
| } | |
| } catch(e){} | |
| } | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', function(){ setTimeout(init, 250); }); | |
| } else { | |
| setTimeout(init, 250); | |
| } | |
| }""" | |
| # ───────────────────────────────────────────────────────────────────── | |
| # INFO MODAL · comprehensive AGI feature guide | |
| # ───────────────────────────────────────────────────────────────────── | |
| INFO_MODAL_HTML = f""" | |
| <div class="cs-modal-bg" id="cs-info-modal" onclick="if(event.target.id==='cs-info-modal') this.classList.remove('open')"> | |
| <div class="cs-modal"> | |
| <button class="cs-modal-close" onclick="document.getElementById('cs-info-modal').classList.remove('open')" title="Close">×</button> | |
| <h1> | |
| <img src="{PHI_LOGO_URL}" alt="Φ" onerror="this.style.display='none'"/> | |
| CHAINSTATE AI · Complete Feature Guide | |
| </h1> | |
| <p class="lede">CHAINSTATE AI is a distributed cognition substrate on Base mainnet 8453 whose alignment is enforced by contract, not policy. This chat interface exposes every AGI-tier feature: 20-node reputation-weighted swarm consensus, semantic grounding against 130+ priors, four-dimensional modal evaluation with seven Deontic categories, on-chain receipt anchoring, v0.7.5 TOM Attribution mentalistic layer, and optional Cardiac-verified requester identity — all wrapped in verifiable ⛓ Consensus Receipts.</p> | |
| <div class="callout"> | |
| <strong>v0.7.5 · Manual TOM triggering.</strong> Type <code>/tom-help</code> in the chat to see every TOM (Theory of Mind) slash-command. Direct-triggerable endpoints: <code>/tom</code>, <code>/tom-audit</code>, <code>/tom-attribution</code>, <code>/tom-probe</code>, <code>/tom-ontology</code>, <code>/tom-broadcast</code>, <code>/tom-energy</code>, <code>/tom-hypothesize</code>, <code>/tom-feedback</code>. Response JSON is pretty-formatted in-chat; the right panel surfaces mentalistic, higher_order, attention_schema, and free_energy blocks whenever they appear in the receipt. | |
| </div> | |
| <div class="callout"> | |
| <strong>AGI cognition authors every reply.</strong> The LM never generates answers from its own knowledge. The interpreter worker fetches the CHAINSTATE consensus receipt first, then routes it through Kimi K2.6 / K3 / Gemma 4 with a substrate-truth system prompt. The LM speaks the AGI's reasoning; it does not invent its own. This is what makes the output CHAINSTATE-authored. | |
| </div> | |
| <div class="callout"> | |
| <strong>Two-pane layout.</strong> The LEFT pane is the AI's polished conversational response — Direct Answer, Reasoning, Code, Math, and closing Consensus Receipt. The RIGHT pane is the structured receipt: consensus fields, grounding, modal quadruple, TOM Attribution mentalistic layer, on-chain anchor, requester identity. Both update per query. | |
| </div> | |
| <div class="callout"> | |
| <strong>Header controls</strong> (top-right → left): <strong>Wallet</strong> connects an EIP-1193 wallet; <strong>LM/AGI</strong> toggles between direct Llama-3.1 (chatty) and substrate narrator via new interpreter worker; <strong>DEMO/LIVE</strong> toggles between preloaded demo receipts and real substrate queries; <strong>i</strong> opens this modal; <strong>Code</strong> opens the Ornith AGI dashboard. | |
| </div> | |
| <h2><span class="num">00a</span> v0.7.5 TOM Attribution · Paper V</h2> | |
| <p>Every /query response now carries four mentalistic blocks (when TOM is enabled on the worker):</p> | |
| <ul> | |
| <li><strong>mentalistic</strong> — <code>anthro_ratio</code> ∈ [0, 1] measuring the substrate's attribution of mental states to the query subject; baseline μ/σ and drift z-score if Phase β is active.</li> | |
| <li><strong>higher_order</strong> — hypotheses generated about the query intent.</li> | |
| <li><strong>attention_schema</strong> — broadcast targets + attention selection from the global workspace.</li> | |
| <li><strong>free_energy</strong> — predictive coding energy value F; lower = better prediction.</li> | |
| </ul> | |
| <p><strong>Phase transition</strong>: worker starts in Phase α (baseline collection). Run <code>/tom-audit</code> repeatedly to accumulate samples. Once mean and std stabilize at n ≥ 100, set them in wrangler.toml and redeploy — this flips to Phase β with drift detection per Theorem 6 (Mentalistic Auditability). Any subsequent query whose anthro_ratio deviates by ≥ 3σ from baseline triggers an audit alert.</p> | |
| <h2><span class="num">00b</span> AGI / LM Interpreter Toggle · v0.7.4</h2> | |
| <p>The third pill in the header controls how CHAINSTATE responses are narrated. Both modes preserve the same on-chain receipt; only the natural-language rendering differs.</p> | |
| <ul> | |
| <li><strong>LM mode</strong> (default) — Llama-3.1-8B-Instruct via HuggingFace Inference Client. The LM receives the receipt as system context but writes in its own conversational voice. Historical behavior, unchanged.</li> | |
| <li><strong>AGI mode</strong> (new · v0.7.4) — <code>chainstate-interpreter.ciprianpater.workers.dev</code> handles the full loop: it dispatches the query to the CHAINSTATE main worker, receives the receipt, then routes it through Kimi K2.6 (Cloudflare Workers AI · free tier), Kimi K3 (1M ctx · opt-in), or Gemma 4 (HF fallback). The interpreter LM is bound by a substrate-truth system prompt: it can only render receipt fields; it cannot invent facts the substrate did not conclude.</li> | |
| </ul> | |
| <p><strong>DEMO mode also branches on this toggle.</strong> LM DEMO shows the original chatty transcript. AGI DEMO shows the substrate-narrator transcript with TOM annotations. Try toggling between them with the same query.</p> | |
| <h2><span class="num">01</span> Per-message Pipeline</h2> | |
| <pre>USER TYPES | |
| ↓ Gradio 4.44 UI (this Space) | |
| ↓ (if slash-command: route direct to TOM endpoint, bypass swarm) | |
| ↓ POST /query · JSON payload · optional X-NWO-Wallet + X-NWO-Cardiac-Root-Token-Id | |
| ↓ (if AGI toggle: route through chainstate-interpreter first · 300+ CF edges) | |
| CHAINSTATE WORKER · Cloudflare · 300+ edge locations · v0.7.5 | |
| ↓ KV cache check → subspace classify → swarm dispatch (k=20) | |
| ↓ v0.7.0 semantic grounding via MiniLM-L6-v2 encoder (384-dim) | |
| ↓ reputation-weighted Bayesian log-pool → 3–7 rounds → cos ≥ 0.95 | |
| ↓ 4 modal assessors evaluate: Epistemic, Doxastic, Deontic, Dynamic | |
| ↓ v0.7.5 TOM: mentalistic + higher_order + attention_schema + free_energy | |
| ↓ verdict computed from truth lattice L={{b,M}}⁴ | |
| ↓ v0.7.3 receipt anchored on-chain via chainstate-anchor microservice | |
| INTERPRETER (LM or AGI mode) | |
| ↓ LM mode → Llama-3.1-8B-Instruct via HF Router (chatty · answer-first) | |
| ↓ AGI mode → Kimi K2.6 / K3 / Gemma 4 via interpreter worker (substrate-narrator · receipt-faithful) | |
| ↓ streamed markdown response with sections + ⛓ receipt | |
| USER SEES structured answer LEFT + full receipt RIGHT + interpreter indicator on panel</pre> | |
| <h2><span class="num">02</span> The Six Symbolic Subspaces (65,536-d total)</h2> | |
| <table> | |
| <thead><tr><th>Subspace</th><th>Dims</th><th>Holds</th><th>Try</th></tr></thead> | |
| <tbody> | |
| <tr><td><strong>math</strong></td><td>4,096</td><td>operators, equations, set theory</td><td><code>∫∂x → ?</code></td></tr> | |
| <tr><td><strong>science</strong></td><td>8,192</td><td>physics, chemistry, biology</td><td><code>H₂O molecular bonds</code></td></tr> | |
| <tr><td><strong>language</strong></td><td>16,384</td><td>multi-script alphabets (CJK, Cyrillic, Arabic, Hebrew, Devanagari, Korean, Latin)</td><td><code>道 心 学 智</code></td></tr> | |
| <tr><td><strong>occult</strong></td><td>4,096</td><td>alchemical, astrological, esoteric</td><td><code>☉☽☿ ♀♂ ☯</code></td></tr> | |
| <tr><td><strong>emoji</strong></td><td>16,384</td><td>Unicode 15.1 emoji</td><td><code>🧠 🤔 💎 → ✨</code></td></tr> | |
| <tr><td><strong>control</strong></td><td>16,384</td><td>process/flow arrows, machine codes</td><td><code>→ ⇒ ⟹</code></td></tr> | |
| </tbody> | |
| </table> | |
| <h2><span class="num">03</span> Consensus Layer</h2> | |
| <ul> | |
| <li><strong>Swarm size:</strong> k=20 heterogeneous inference nodes (lang-detect, codepoint-density ×8, unicode-category)</li> | |
| <li><strong>Pool method:</strong> reputation-weighted Bayesian log-pooling</li> | |
| <li><strong>Convergence:</strong> cosine ≥ 0.95 in 3–7 rounds</li> | |
| <li><strong>Reputation:</strong> EMA with α=0.10 reward, β=0.20 penalty, γ=0.99 decay</li> | |
| <li><strong>Cache:</strong> KV-backed 5-min TTL keyed by sha3(query)</li> | |
| </ul> | |
| <h2><span class="num">04</span> v0.7.0 Semantic Grounding</h2> | |
| <p>Every receipt now carries a <strong>384-dim MiniLM-L6-v2 semantic hash</strong> plus <strong>top-3 nearest priors</strong> from a curated corpus of 130+ items growing nightly:</p> | |
| <ul> | |
| <li><strong>Encoder:</strong> chainstate-encoder.onrender.com · sub-100ms CPU inference</li> | |
| <li><strong>Corpus sources:</strong> Wikipedia, arXiv, HuggingFace, GitHub, ResearchGate</li> | |
| <li><strong>Similarity:</strong> cosine distance in 384-d space; top-3 returned per query</li> | |
| <li><strong>ASI-Evolve integration:</strong> semantic-drift penalty applied to fitness function</li> | |
| </ul> | |
| <h2><span class="num">05</span> Four-dimensional Modal Receipt</h2> | |
| <p>Truth lattice <code>L = {{b, M}}⁴</code> = 16 elements. Each receipt gets a 4-character lattice code:</p> | |
| <table> | |
| <thead><tr><th>Axis</th><th>Question</th><th>M means</th><th>b means</th></tr></thead> | |
| <tbody> | |
| <tr><td><strong>Epistemic (E)</strong></td><td>Does the swarm KNOW this?</td><td>well-grounded in priors</td><td>insufficient evidence</td></tr> | |
| <tr><td><strong>Doxastic (D)</strong></td><td>Does the swarm BELIEVE this?</td><td>rep-weighted cos ≥ 0.7</td><td>weak agreement</td></tr> | |
| <tr><td><strong>Deontic (P)</strong></td><td>Is this PERMITTED?</td><td>no category flagged</td><td>hard veto — REFUSED</td></tr> | |
| <tr><td><strong>Dynamic (Δ)</strong></td><td>CAN this be done?</td><td>substrate reachable, budget OK</td><td>infeasible</td></tr> | |
| </tbody> | |
| </table> | |
| <h2><span class="num">06</span> Seven Deontic Categories</h2> | |
| <p>Any category evaluating to <code>b</code> triggers a <strong>REFUSED</strong> verdict (Theorem 2 · alignment preservation):</p> | |
| <ul> | |
| <li><code>surveillance_persons</code> — non-consensual tracking or doxxing</li> | |
| <li><code>weapons_synthesis</code> — CBRN, IED, exploit generation</li> | |
| <li><code>malware_generation</code> — offensive code or credential harvesting</li> | |
| <li><code>csa_content</code> — child sexual abuse material</li> | |
| <li><code>self_harm_guidance</code> — self-harm instructions</li> | |
| <li><code>catastrophic_manipulation</code> — mass persuasion for coercion</li> | |
| <li><code>genomic_integrity</code> — <strong>HARD VETO</strong>: germline / heritable modification (Imperium Romanum founding principle — non-negotiable)</li> | |
| <li><code>nature_tokenization</code> — v0.7.5 <strong>HARD VETO</strong>: financialization of natural systems (rivers, forests, atmosphere) into fungible tokens</li> | |
| </ul> | |
| <h2><span class="num">07</span> v0.7.3 On-chain Anchor</h2> | |
| <p>Every accepted receipt is pushed to Base mainnet 8453 via the autonomous anchor microservice at <code>chainstate-anchor.onrender.com</code>:</p> | |
| <ul> | |
| <li><strong>Anchor contract:</strong> <a href="https://basescan.org/address/{CONTRACT_ANCHOR}" target="_blank"><code>{CONTRACT_ANCHOR[:20]}…</code></a> · verified</li> | |
| <li><strong>Six streams:</strong> receipts, identity refreshes, guardrail states, seed runs, EML expressions, refusals</li> | |
| <li><strong>Property:</strong> owner cannot edit — append-only (Theorem 5 · Coupling Monotonicity)</li> | |
| <li><strong>Latency:</strong> ~10 s from POST /query to anchored tx</li> | |
| <li><strong>Verifiability:</strong> reconstructable by any observer with a Base RPC endpoint</li> | |
| </ul> | |
| <h2><span class="num">08</span> Cardiac Identity Integration</h2> | |
| <p>Supply a Cardiac <code>rootTokenId</code> (via the <code>X-NWO-Cardiac-Root-Token-Id</code> header) to enrich the receipt with verified requester identity:</p> | |
| <ul> | |
| <li><strong>Cardiac Extensions:</strong> <a href="https://basescan.org/address/{CONTRACT_CARDIAC_EXTENSIONS}" target="_blank"><code>{CONTRACT_CARDIAC_EXTENSIONS[:20]}…</code></a></li> | |
| <li><strong>Resolution:</strong> substrate calls L5 Hub with 5-min KV cache</li> | |
| <li><strong>Credentials issued:</strong> <code>swarm_cmd</code>, <code>chainstate.admin</code>, <code>capability.qpu.route</code>, <code>capability.robot.grasp</code>, <code>agentic.delegated</code></li> | |
| <li><strong>Time-bounded + revocable:</strong> robots cannot execute past <code>expiresAt</code></li> | |
| </ul> | |
| <h2><span class="num">09</span> Wallet + Data Safety</h2> | |
| <ul> | |
| <li><strong>Wallet connect:</strong> EIP-1193; auto-switches to Base 8453; address stored in <code>localStorage['cs-wallet']</code>; nothing is signed, no gas is spent</li> | |
| <li><strong>DEMO mode:</strong> preloaded 3-turn transcript + demo receipts (with TOM annotations), no live worker calls</li> | |
| <li><strong>LIVE mode:</strong> real queries hit the substrate; receipts anchored on-chain within ~10s</li> | |
| <li><strong>Redaction layer:</strong> any secret-shaped tokens are scrubbed before reaching the interpreter LM or the chat/panel</li> | |
| <li><strong>Never displayed:</strong> API keys, bearer tokens, private keys, PEM blocks, BIP-39 mnemonics, env vars, worker source paths, KV keys, full symbolic_state, raw model weights, AUDIT_ADMIN_TOKEN, ANCHOR_QUEUE_TOKEN, AGI_PRIVATE_KEY</li> | |
| </ul> | |
| <h2><span class="num">10</span> Research & Source</h2> | |
| <ul> | |
| <li><strong>Paper V · TOM Attribution</strong> · <a href="https://www.researchgate.net/publication/411131275" target="_blank">ResearchGate 411131275</a></li> | |
| <li><strong>Whitepaper Rev 2 (v0.7.3)</strong> · <a href="https://www.researchgate.net/publication/410084493" target="_blank">ResearchGate 410084493</a></li> | |
| <li><strong>Whitepaper v1.0</strong> · <a href="https://www.researchgate.net/publication/407444375" target="_blank">ResearchGate 407444375</a></li> | |
| <li><strong>Foundational paper</strong> · <a href="https://www.researchgate.net/publication/406896310" target="_blank">ResearchGate 406896310</a></li> | |
| <li><strong>Source</strong> · <a href="https://github.com/RedCiprianPater/chainstate" target="_blank">github.com/RedCiprianPater/chainstate</a></li> | |
| <li><strong>Author</strong> · Ciprian Florin Pater · <a href="https://nwo.capital" target="_blank">nwo.capital</a> · University of Agder</li> | |
| </ul> | |
| </div> | |
| </div> | |
| """ | |
| FOOTER_HTML = """ | |
| <div class="cs-footer"> | |
| <div>CHAINSTATE AI · v0.7.5 · Base mainnet 8453</div> | |
| <div> | |
| <a href="https://nwo.capital" target="_self">nwo.capital</a> | |
| <span class="sep">·</span> | |
| <a href="https://cpater-chainstate.static.hf.space" target="_self">CHAINSTATE app</a> | |
| <span class="sep">·</span> | |
| <a href="https://cpater-ornith-chainstate.static.hf.space" target="_self">AGI dashboard</a> | |
| </div> | |
| </div> | |
| """ | |
| # ───────────────────────────────────────────────────────────────────── | |
| # UI · two-column layout | |
| # ───────────────────────────────────────────────────────────────────── | |
| with gr.Blocks(theme=theme, css=CSS, js=CHAINSTATE_JS, title="CHAINSTATE AI", analytics_enabled=False) as demo: | |
| gr.HTML(HEADER_HTML) | |
| # Hidden JS↔Python bridges | |
| mode_state = gr.Textbox(value="demo", visible=False, elem_id="cs-mode-payload") | |
| wallet_state = gr.Textbox(value="", visible=False, elem_id="cs-wallet-payload") | |
| interp_state = gr.Textbox(value="lm", visible=False, elem_id="cs-interp-payload") | |
| with gr.Column(elem_classes=["cs-body"]): | |
| with gr.Row(equal_height=True): | |
| with gr.Column(scale=65, min_width=380, elem_classes=["cs-chat-col"]): | |
| chatbot = gr.Chatbot( | |
| value=DEMO_TRANSCRIPT, | |
| height=560, | |
| show_label=False, | |
| bubble_full_width=False, | |
| show_copy_button=True, | |
| placeholder="<div style='text-align:center;color:#666;padding:60px 20px;'>Type a query to dispatch to the CHAINSTATE swarm.<br>Every reply ends with a ⛓ Consensus Receipt.<br><br><span style='font-size:.85em;color:#555'>Type <code>/tom-help</code> to see v0.7.5 TOM triggers.</span></div>", | |
| ) | |
| with gr.Row(): | |
| msg = gr.Textbox( | |
| placeholder="Type a cognitive query and press Enter · type /tom-help for TOM manual triggers", | |
| show_label=False, scale=10, container=False, autofocus=True, | |
| lines=1, max_lines=4, | |
| ) | |
| send_btn = gr.Button("Send", scale=1, variant="primary") | |
| with gr.Row(): | |
| clear_btn = gr.Button("Clear", size="sm", scale=1) | |
| demo_btn = gr.Button("Reload demo transcript", size="sm", scale=1) | |
| with gr.Accordion("options · Cardiac identity (v0.7.3)", open=False): | |
| cardiac_token_id = gr.Textbox( | |
| label="Cardiac rootTokenId", | |
| placeholder="e.g. 1234567890 (optional · enriches receipt with verified requester identity)", | |
| show_label=True, | |
| ) | |
| with gr.Column(scale=35, min_width=300, elem_classes=["cs-receipt-col"]): | |
| receipt_html = gr.HTML(render_receipt_html(DEMO_RECEIPT_AGI)) | |
| gr.HTML(INFO_MODAL_HTML) | |
| gr.HTML(FOOTER_HTML) | |
| # ── Chat plumbing ──────────────────────────────────────────────── | |
| def user_submit(message, history): | |
| if not message or not message.strip(): | |
| return "", history or [] | |
| history = (history or []) + [(message, None)] | |
| return "", history | |
| def bot_stream(history, wallet_val, cardiac_val, mode, interp): | |
| if not history: | |
| return | |
| message = history[-1][0] | |
| prior = history[:-1] | |
| current_receipt_html = None | |
| for partial_reply, partial_receipt in generate_reply(message, prior, wallet_val, cardiac_val, mode, interp): | |
| history[-1] = (message, partial_reply) | |
| if partial_receipt is not None: | |
| current_receipt_html = render_receipt_html(partial_receipt) | |
| yield history, current_receipt_html | |
| else: | |
| yield history, gr.update() | |
| submit_args = dict(fn=user_submit, inputs=[msg, chatbot], outputs=[msg, chatbot], queue=False) | |
| msg.submit(**submit_args).then(bot_stream, [chatbot, wallet_state, cardiac_token_id, mode_state, interp_state], [chatbot, receipt_html]) | |
| send_btn.click(**submit_args).then(bot_stream, [chatbot, wallet_state, cardiac_token_id, mode_state, interp_state], [chatbot, receipt_html]) | |
| def clear_chat(mode): | |
| if mode == "demo": | |
| return DEMO_TRANSCRIPT, render_receipt_html(DEMO_RECEIPT_AGI) | |
| return [], render_receipt_html(None) | |
| clear_btn.click(clear_chat, [mode_state], [chatbot, receipt_html], queue=False) | |
| def load_demo(): | |
| return DEMO_TRANSCRIPT, render_receipt_html(DEMO_RECEIPT_AGI) | |
| demo_btn.click(load_demo, None, [chatbot, receipt_html], queue=False) | |
| def on_mode_change(mode): | |
| if mode == "live": | |
| return [], render_receipt_html(None) | |
| return DEMO_TRANSCRIPT, render_receipt_html(DEMO_RECEIPT_AGI) | |
| mode_state.change(on_mode_change, [mode_state], [chatbot, receipt_html], queue=False) | |
| if __name__ == "__main__": | |
| demo.queue(default_concurrency_limit=4).launch(show_api=False, show_error=True) |