Spaces:
Running
Running
chore(sync): mirror backend .py + Dockerfile to Space (hf-sync-backend)
Browse filesAutomated backend sync from szl-holdings/a11oy main via hf-sync-backend.
Updated (differed from the Space): Dockerfile, a11oy_code_orchestrator.py, serve.py, szl_energy_sovereign.py
Deleted (gone from the repo + Dockerfile COPY set): a11oy_react_core.py
Keeps the Space-built backend (serve.py + the Dockerfile-COPY'd .py
modules) identical to GitHub main so the Space never rebuilds from a
stale backend, new endpoints don't 404 there, and orphaned modules
removed from the repo don't linger in the Space tree.
- Dockerfile +1 -16
- a11oy_code_orchestrator.py +42 -8
- a11oy_react_core.py +0 -805
- serve.py +13 -46
- szl_energy_sovereign.py +883 -0
Dockerfile
CHANGED
|
@@ -96,7 +96,7 @@ COPY _vendor_blobs.py szl_v4_fleet.py operator_shell_v4.py szl_bridge.py szl_bri
|
|
| 96 |
COPY szl_formula_wiring.py a11oy_code_engine.py a11oy_code.py a11oy_seismic.py szl_warhacker_real.py szl_warhacker_demos.py NOTICE_warhacker_demos.txt szl_llm_registry.py szl_elite_console.py szl_alloy_models.py szl_scaling.py szl_allodial.py szl_entanglement.py szl_neuroplasticity.py szl_chain_of_title.py szl_sovereign_compute.py ./
|
| 97 |
# Energy/heart/engine/revenue/harvest organ modules: present in repo but were absent
|
| 98 |
# from every COPY line -> guarded imports threw ModuleNotFoundError -> dark 404 surfaces.
|
| 99 |
-
COPY szl_energy_budget.py szl_energy_provenance.py szl_heart_blood.py szl_engine_status.py szl_backend_hardening.py revenue_endpoints.py a11oy_harvest_endpoints.py ./
|
| 100 |
# Agentic-PINN + physical-bounds mesh (pure-stdlib sibling of szl_energy_budget; serves
|
| 101 |
# /api/a11oy/v1/pinn/*). MUST be COPY'd or serve.py's guarded import falls back to a stub
|
| 102 |
# (merged-but-not-live) in the HF image. The optional on-metal artifacts it reads
|
|
@@ -300,14 +300,6 @@ COPY web/operator.html ./web/operator.html
|
|
| 300 |
COPY web/fleet-c2.html ./web/fleet-c2.html
|
| 301 |
COPY web/living-anatomy.html ./web/living-anatomy.html
|
| 302 |
|
| 303 |
-
# ADDITIVE (LANE A AGENTIC CORE — Dev A, 2026-06-14): resumable ReAct agent with
|
| 304 |
-
# signed receipt boundaries, SqliteSaver checkpointing, Reflexion, Generative-
|
| 305 |
-
# Agents memory scoring, Letta tiering, Voyager skill library. Served at
|
| 306 |
-
# /agent-loop (+ /a11oy/agent-loop) via serve.py _ptg_serve from /app/web/.
|
| 307 |
-
# Per-file COPY (this Dockerfile uses no COPY . .). 0 CDN; shared engines from
|
| 308 |
-
# /static/shared. Co-Authored-By: Perplexity Computer Agent <agent@perplexity.ai>
|
| 309 |
-
COPY web/agent-loop.html ./web/agent-loop.html
|
| 310 |
-
|
| 311 |
# ADDITIVE (Cross-Harness Receipt Bridge — Hermes + OpenClaw; 2026-06-01, Yachay /
|
| 312 |
# Perplexity Computer Agent; closeout PR superseding #198 runtime files). serve.py
|
| 313 |
# already imports szl_bridge + a11oy_v4_agent and calls .register(app) BEFORE the
|
|
@@ -606,13 +598,6 @@ ENV A11OY_ALLOY_GGUF=/app/models/qwen2.5-coder-0.5b-instruct-q4_k_m.gguf
|
|
| 606 |
# ---------------------------------------------------------------------------
|
| 607 |
COPY a11oy_live_feeds.py a11oy_signing_key.py a11oy_dev1_endpoints.py a11oy_vertical_feeds.py a11oy_deva_feeds.py a11oy_devb_endpoints.py a11oy_amaru_feeds.py szl_governance_gateway.py szl_abacus_verify.py szl_decision_uncertainty.py szl_gor_audit.py szl_sovereign_search.py szl_consensus_clusters.py szl_mission_ledger.py szl_budget_router.py szl_wave910_proofs.py szl_evidence_research.py szl_uds_fleet.py szl_readiness.py szl_quantum_bio.py szl_mosaic_governance.py ./
|
| 608 |
COPY szl_unified_formulas.py szl_cuas_formulas.py szl_contracting.py szl_bounties.py szl_putnam.py szl_connectors_serve.py szl_connector_mcp.py szl_conjecture_factory.py ./
|
| 609 |
-
|
| 610 |
-
# ADDITIVE (LANE A AGENTIC CORE — Dev A, 2026-06-14): the resumable ReAct agent
|
| 611 |
-
# core module. serve.py imports it try/except-guarded and calls .register(app,
|
| 612 |
-
# "a11oy", _a11oy_sign_receipt, verify_fn=_a11oy_loop_verify, pub_pem_fn=...).
|
| 613 |
-
# Without this per-file COPY the import fails and the /api/a11oy/v1/agent/react/*
|
| 614 |
-
# endpoints fall through to the SPA shell. Per-file COPY (no COPY . . here).
|
| 615 |
-
COPY a11oy_react_core.py ./
|
| 616 |
COPY live_snapshots/ ./live_snapshots/
|
| 617 |
|
| 618 |
# ADDITIVE (Investor-WOW Layer, 2026-06-08, Dev1): a11oy_dev1_endpoints.py exposes
|
|
|
|
| 96 |
COPY szl_formula_wiring.py a11oy_code_engine.py a11oy_code.py a11oy_seismic.py szl_warhacker_real.py szl_warhacker_demos.py NOTICE_warhacker_demos.txt szl_llm_registry.py szl_elite_console.py szl_alloy_models.py szl_scaling.py szl_allodial.py szl_entanglement.py szl_neuroplasticity.py szl_chain_of_title.py szl_sovereign_compute.py ./
|
| 97 |
# Energy/heart/engine/revenue/harvest organ modules: present in repo but were absent
|
| 98 |
# from every COPY line -> guarded imports threw ModuleNotFoundError -> dark 404 surfaces.
|
| 99 |
+
COPY szl_energy_budget.py szl_energy_sovereign.py szl_energy_provenance.py szl_heart_blood.py szl_engine_status.py szl_backend_hardening.py revenue_endpoints.py a11oy_harvest_endpoints.py ./
|
| 100 |
# Agentic-PINN + physical-bounds mesh (pure-stdlib sibling of szl_energy_budget; serves
|
| 101 |
# /api/a11oy/v1/pinn/*). MUST be COPY'd or serve.py's guarded import falls back to a stub
|
| 102 |
# (merged-but-not-live) in the HF image. The optional on-metal artifacts it reads
|
|
|
|
| 300 |
COPY web/fleet-c2.html ./web/fleet-c2.html
|
| 301 |
COPY web/living-anatomy.html ./web/living-anatomy.html
|
| 302 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
# ADDITIVE (Cross-Harness Receipt Bridge — Hermes + OpenClaw; 2026-06-01, Yachay /
|
| 304 |
# Perplexity Computer Agent; closeout PR superseding #198 runtime files). serve.py
|
| 305 |
# already imports szl_bridge + a11oy_v4_agent and calls .register(app) BEFORE the
|
|
|
|
| 598 |
# ---------------------------------------------------------------------------
|
| 599 |
COPY a11oy_live_feeds.py a11oy_signing_key.py a11oy_dev1_endpoints.py a11oy_vertical_feeds.py a11oy_deva_feeds.py a11oy_devb_endpoints.py a11oy_amaru_feeds.py szl_governance_gateway.py szl_abacus_verify.py szl_decision_uncertainty.py szl_gor_audit.py szl_sovereign_search.py szl_consensus_clusters.py szl_mission_ledger.py szl_budget_router.py szl_wave910_proofs.py szl_evidence_research.py szl_uds_fleet.py szl_readiness.py szl_quantum_bio.py szl_mosaic_governance.py ./
|
| 600 |
COPY szl_unified_formulas.py szl_cuas_formulas.py szl_contracting.py szl_bounties.py szl_putnam.py szl_connectors_serve.py szl_connector_mcp.py szl_conjecture_factory.py ./
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
COPY live_snapshots/ ./live_snapshots/
|
| 602 |
|
| 603 |
# ADDITIVE (Investor-WOW Layer, 2026-06-08, Dev1): a11oy_dev1_endpoints.py exposes
|
a11oy_code_orchestrator.py
CHANGED
|
@@ -103,6 +103,14 @@ try:
|
|
| 103 |
import energy_signal as _energy_signal # PR #356 honest power-window feed
|
| 104 |
except Exception: # pragma: no cover - absent until #356 merges; default grid
|
| 105 |
_energy_signal = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
|
| 107 |
# ---------------------------------------------------------------------------
|
| 108 |
# Configuration
|
|
@@ -949,18 +957,39 @@ def _emit_turn_receipt(text: str, model_used: str, is_local: bool,
|
|
| 949 |
try:
|
| 950 |
prov = _turn_energy_provenance(is_local)
|
| 951 |
out_bytes = len((text or "").encode("utf-8"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 952 |
receipt = _energy_budget.track_task(
|
| 953 |
output=text or "",
|
| 954 |
energy_source=prov.get("energy_source", "grid"),
|
| 955 |
joules_est=0.0, # SAMPLE: no meter wired (joules_est_label carries it)
|
| 956 |
-
extra=
|
| 957 |
-
"turn": True,
|
| 958 |
-
"model": model_used,
|
| 959 |
-
"stub": bool(stub),
|
| 960 |
-
"sovereign_local": bool(is_local),
|
| 961 |
-
"window": prov.get("window", "normal"),
|
| 962 |
-
"signal_provider": prov.get("signal_provider", "unknown"),
|
| 963 |
-
},
|
| 964 |
)
|
| 965 |
# The Bekenstein gate is the PROVEN F19/TH6 inequality (shannon<=n*8);
|
| 966 |
# an honest receipt is always within_bound. Flag (never raise) if not.
|
|
@@ -981,6 +1010,11 @@ def _emit_turn_receipt(text: str, model_used: str, is_local: bool,
|
|
| 981 |
"window": prov.get("window", "normal"),
|
| 982 |
"joules_est": receipt.get("joules_est"),
|
| 983 |
"joules_est_label": receipt.get("joules_est_label"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 984 |
})
|
| 985 |
return receipt
|
| 986 |
except Exception as exc: # noqa: BLE001 - NEVER break a turn over a receipt
|
|
|
|
| 103 |
import energy_signal as _energy_signal # PR #356 honest power-window feed
|
| 104 |
except Exception: # pragma: no cover - absent until #356 merges; default grid
|
| 105 |
_energy_signal = None
|
| 106 |
+
# Sovereign-energy instrumentation (Lane C): reads REAL J/token + carbon from the
|
| 107 |
+
# on-box vLLM /metrics ONLY when the live sovereign probe shows gpu_reachable, and
|
| 108 |
+
# splices joules_consumed + carbon_g_co2eq into EVERY signed turn receipt — honestly
|
| 109 |
+
# labeled MEASURED (real fresh exporter) or ROADMAP (no meter yet -> None, never faked).
|
| 110 |
+
try:
|
| 111 |
+
import szl_energy_sovereign as _energy_sovereign # Lane C J/token + carbon receipt fields
|
| 112 |
+
except Exception: # pragma: no cover - absent until the module merges; degrade honestly
|
| 113 |
+
_energy_sovereign = None
|
| 114 |
|
| 115 |
# ---------------------------------------------------------------------------
|
| 116 |
# Configuration
|
|
|
|
| 957 |
try:
|
| 958 |
prov = _turn_energy_provenance(is_local)
|
| 959 |
out_bytes = len((text or "").encode("utf-8"))
|
| 960 |
+
# Lane C: splice REAL J/token energy + carbon into EVERY signed receipt. The
|
| 961 |
+
# helper reads the on-box vLLM /metrics ONLY when the live sovereign probe shows
|
| 962 |
+
# gpu_reachable; otherwise it returns honest ROADMAP (joules_consumed=None). It
|
| 963 |
+
# NEVER raises and NEVER fabricates a number (no meter -> no number).
|
| 964 |
+
energy_fields = {}
|
| 965 |
+
if _energy_sovereign is not None:
|
| 966 |
+
try:
|
| 967 |
+
energy_fields = _energy_sovereign.energy_fields_for_receipt() or {}
|
| 968 |
+
except Exception: # noqa: BLE001 - energy probe must never break a turn
|
| 969 |
+
energy_fields = {"joules_consumed": None, "carbon_g_co2eq": None,
|
| 970 |
+
"energy_label": "ROADMAP"}
|
| 971 |
+
extra = {
|
| 972 |
+
"turn": True,
|
| 973 |
+
"model": model_used,
|
| 974 |
+
"stub": bool(stub),
|
| 975 |
+
"sovereign_local": bool(is_local),
|
| 976 |
+
"window": prov.get("window", "normal"),
|
| 977 |
+
"signal_provider": prov.get("signal_provider", "unknown"),
|
| 978 |
+
# joules_consumed + carbon_g_co2eq on every receipt (MEASURED via a live GPU
|
| 979 |
+
# exporter, else honest ROADMAP/None). joules_honesty is decided by
|
| 980 |
+
# szl_joules_truth, never by a flag.
|
| 981 |
+
"joules_consumed": energy_fields.get("joules_consumed"),
|
| 982 |
+
"carbon_g_co2eq": energy_fields.get("carbon_g_co2eq"),
|
| 983 |
+
"joules_per_token": energy_fields.get("joules_per_token"),
|
| 984 |
+
"carbon_g_co2eq_per_token": energy_fields.get("carbon_g_co2eq_per_token"),
|
| 985 |
+
"energy_label": energy_fields.get("energy_label", "ROADMAP"),
|
| 986 |
+
"joules_honesty": energy_fields.get("joules_honesty", "sample"),
|
| 987 |
+
}
|
| 988 |
receipt = _energy_budget.track_task(
|
| 989 |
output=text or "",
|
| 990 |
energy_source=prov.get("energy_source", "grid"),
|
| 991 |
joules_est=0.0, # SAMPLE: no meter wired (joules_est_label carries it)
|
| 992 |
+
extra=extra,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 993 |
)
|
| 994 |
# The Bekenstein gate is the PROVEN F19/TH6 inequality (shannon<=n*8);
|
| 995 |
# an honest receipt is always within_bound. Flag (never raise) if not.
|
|
|
|
| 1010 |
"window": prov.get("window", "normal"),
|
| 1011 |
"joules_est": receipt.get("joules_est"),
|
| 1012 |
"joules_est_label": receipt.get("joules_est_label"),
|
| 1013 |
+
# Lane C live J/token energy + carbon (MEASURED via on-box exporter / ROADMAP).
|
| 1014 |
+
"joules_consumed": extra.get("joules_consumed"),
|
| 1015 |
+
"carbon_g_co2eq": extra.get("carbon_g_co2eq"),
|
| 1016 |
+
"energy_label": extra.get("energy_label"),
|
| 1017 |
+
"joules_honesty": extra.get("joules_honesty"),
|
| 1018 |
})
|
| 1019 |
return receipt
|
| 1020 |
except Exception as exc: # noqa: BLE001 - NEVER break a turn over a receipt
|
a11oy_react_core.py
DELETED
|
@@ -1,805 +0,0 @@
|
|
| 1 |
-
# -*- coding: utf-8 -*-
|
| 2 |
-
# ============================================================================
|
| 3 |
-
# a11oy_react_core.py — LANE A AGENTIC CORE (Dev A, SZL Holdings)
|
| 4 |
-
# ----------------------------------------------------------------------------
|
| 5 |
-
# A REAL, resumable ReAct execution graph (Thought -> Action -> Observation)
|
| 6 |
-
# where EACH node transition is a SIGNED receipt boundary, plus:
|
| 7 |
-
# * SqliteSaver-style checkpointing (crash mid-run -> /resume continues)
|
| 8 |
-
# * Reflexion inner loop (NL reflection prepended next activation)
|
| 9 |
-
# * Generative-Agents memory scoring score(m)=a_rec*g^dt + a_imp*imp + a_rel*cos
|
| 10 |
-
# * Letta-style memory tiering (working in-context + archival vector)
|
| 11 |
-
# * Voyager skill library (admit a recipe ONLY after a passing receipt)
|
| 12 |
-
#
|
| 13 |
-
# Honest engineering (DOCTRINE v11):
|
| 14 |
-
# - The signer is the HOST app's REAL in-image ECDSA-P256 DSSE signer
|
| 15 |
-
# (_a11oy_sign_receipt), passed in via register(); we NEVER fabricate a
|
| 16 |
-
# signature. verify_fn re-verifies against /cosign.pub.
|
| 17 |
-
# - The vector store is LOCAL (sqlite + numpy, hashing-trie embeddings) — 0
|
| 18 |
-
# external CDN/service. Embeddings are a deterministic local feature hash
|
| 19 |
-
# (labelled HEURISTIC), not a remote model, so retrieval is reproducible
|
| 20 |
-
# offline. Scores are surfaced honestly with their components.
|
| 21 |
-
# - Trust / coverage framing, never bare "confidence %".
|
| 22 |
-
# - Routes are inserted at position 0 (Starlette Route) so they beat the SPA
|
| 23 |
-
# catch-all, mirroring szl_agentic_loop.
|
| 24 |
-
# - Endpoints live under the FREE /api/a11oy/v1/agent/react/* sub-namespace
|
| 25 |
-
# (run/resume/trace/checkpoints) so we do NOT collide with the existing
|
| 26 |
-
# /run, /tools, /verify-chain, /governance-standards, /_diag, /loop.
|
| 27 |
-
#
|
| 28 |
-
# Co-Authored-By: Perplexity Computer Agent <agent@perplexity.ai>
|
| 29 |
-
# Signed-off-by: Stephen P. Lutar Jr. <stephenlutar2@gmail.com>
|
| 30 |
-
# ============================================================================
|
| 31 |
-
from __future__ import annotations
|
| 32 |
-
|
| 33 |
-
import hashlib
|
| 34 |
-
import json
|
| 35 |
-
import math
|
| 36 |
-
import os
|
| 37 |
-
import re
|
| 38 |
-
import sqlite3
|
| 39 |
-
import threading
|
| 40 |
-
import time
|
| 41 |
-
import uuid
|
| 42 |
-
from datetime import datetime, timezone
|
| 43 |
-
|
| 44 |
-
# ---------------------------------------------------------------------------
|
| 45 |
-
# Storage: a single local sqlite DB under /tmp (ephemeral per container, which
|
| 46 |
-
# is the honest reality of a HF Space). All five subsystems persist here so a
|
| 47 |
-
# crash mid-run can resume from the last committed checkpoint within the life
|
| 48 |
-
# of the container. Labelled accordingly in the UI.
|
| 49 |
-
# ---------------------------------------------------------------------------
|
| 50 |
-
_DB_PATH = os.environ.get("A11OY_REACT_DB", "/tmp/a11oy_react_core.sqlite3")
|
| 51 |
-
_LOCK = threading.RLock()
|
| 52 |
-
_EMBED_DIM = 64 # local hashing-trick embedding dimension
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
def _now_iso() -> str:
|
| 56 |
-
return datetime.now(timezone.utc).isoformat()
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
def _now_epoch() -> float:
|
| 60 |
-
return time.time()
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
def _sha(obj) -> str:
|
| 64 |
-
return hashlib.sha256(
|
| 65 |
-
json.dumps(obj, sort_keys=True, separators=(",", ":")).encode("utf-8")
|
| 66 |
-
).hexdigest()
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
def _conn() -> sqlite3.Connection:
|
| 70 |
-
c = sqlite3.connect(_DB_PATH, timeout=30, check_same_thread=False)
|
| 71 |
-
c.row_factory = sqlite3.Row
|
| 72 |
-
c.execute("PRAGMA journal_mode=WAL;")
|
| 73 |
-
return c
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
def _init_db() -> None:
|
| 77 |
-
with _LOCK, _conn() as c:
|
| 78 |
-
c.executescript(
|
| 79 |
-
"""
|
| 80 |
-
CREATE TABLE IF NOT EXISTS runs (
|
| 81 |
-
run_id TEXT PRIMARY KEY,
|
| 82 |
-
goal TEXT, status TEXT, max_steps INTEGER,
|
| 83 |
-
step INTEGER, prev_hash TEXT, final_hash TEXT,
|
| 84 |
-
reflection TEXT, created_at TEXT, updated_at TEXT
|
| 85 |
-
);
|
| 86 |
-
CREATE TABLE IF NOT EXISTS receipts (
|
| 87 |
-
run_id TEXT, seq INTEGER, node TEXT, body TEXT,
|
| 88 |
-
prev_hash TEXT, hash TEXT, envelope TEXT, ts TEXT,
|
| 89 |
-
PRIMARY KEY (run_id, seq)
|
| 90 |
-
);
|
| 91 |
-
CREATE TABLE IF NOT EXISTS checkpoints (
|
| 92 |
-
run_id TEXT, step INTEGER, state TEXT, prev_hash TEXT,
|
| 93 |
-
ts TEXT, PRIMARY KEY (run_id, step)
|
| 94 |
-
);
|
| 95 |
-
CREATE TABLE IF NOT EXISTS memory (
|
| 96 |
-
mem_id TEXT PRIMARY KEY, run_id TEXT, tier TEXT, kind TEXT,
|
| 97 |
-
text TEXT, importance REAL, created_at REAL, last_access REAL,
|
| 98 |
-
embedding TEXT
|
| 99 |
-
);
|
| 100 |
-
CREATE TABLE IF NOT EXISTS skills (
|
| 101 |
-
skill_id TEXT PRIMARY KEY, name TEXT, recipe TEXT,
|
| 102 |
-
receipt_hash TEXT, receipt_verified INTEGER, embedding TEXT,
|
| 103 |
-
created_at TEXT, uses INTEGER
|
| 104 |
-
);
|
| 105 |
-
CREATE TABLE IF NOT EXISTS reflections (
|
| 106 |
-
run_id TEXT, idx INTEGER, text TEXT, ts TEXT,
|
| 107 |
-
PRIMARY KEY (run_id, idx)
|
| 108 |
-
);
|
| 109 |
-
"""
|
| 110 |
-
)
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
# ---------------------------------------------------------------------------
|
| 114 |
-
# LOCAL embedding — deterministic hashing-trick bag-of-tokens, L2 normalised.
|
| 115 |
-
# This is NOT a learned model; it is a reproducible local feature hash so that
|
| 116 |
-
# cosine similarity is meaningful for lexical overlap WITHOUT any network call.
|
| 117 |
-
# Labelled HEURISTIC everywhere it surfaces.
|
| 118 |
-
# ---------------------------------------------------------------------------
|
| 119 |
-
_TOK = re.compile(r"[a-z0-9]+")
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
def _embed(text: str) -> list:
|
| 123 |
-
vec = [0.0] * _EMBED_DIM
|
| 124 |
-
toks = _TOK.findall((text or "").lower())
|
| 125 |
-
for t in toks:
|
| 126 |
-
h = int(hashlib.md5(t.encode()).hexdigest(), 16)
|
| 127 |
-
idx = h % _EMBED_DIM
|
| 128 |
-
sign = 1.0 if (h >> 8) & 1 else -1.0
|
| 129 |
-
vec[idx] += sign
|
| 130 |
-
norm = math.sqrt(sum(v * v for v in vec)) or 1.0
|
| 131 |
-
return [v / norm for v in vec]
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
def _cos(a: list, b: list) -> float:
|
| 135 |
-
if not a or not b or len(a) != len(b):
|
| 136 |
-
return 0.0
|
| 137 |
-
return max(-1.0, min(1.0, sum(x * y for x, y in zip(a, b))))
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
def _importance_heuristic(text: str) -> float:
|
| 141 |
-
"""Local importance proxy in [0,1] (LLM-scored 1-10 in the paper; here a
|
| 142 |
-
transparent HEURISTIC: longer, decision/goal-bearing text scores higher).
|
| 143 |
-
Surfaced honestly as HEURISTIC, never claimed as an LLM judgement."""
|
| 144 |
-
t = (text or "").lower()
|
| 145 |
-
score = min(1.0, len(t) / 240.0)
|
| 146 |
-
for kw, w in (("goal", 0.2), ("decision", 0.2), ("fail", 0.25),
|
| 147 |
-
("error", 0.25), ("reflect", 0.2), ("verified", 0.15),
|
| 148 |
-
("receipt", 0.1)):
|
| 149 |
-
if kw in t:
|
| 150 |
-
score = min(1.0, score + w)
|
| 151 |
-
return round(score, 4)
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
# ---------------------------------------------------------------------------
|
| 155 |
-
# Generative-Agents retrieval score:
|
| 156 |
-
# score(m) = a_rec * gamma^dt_hours + a_imp * imp(m) + a_rel * cos(q, m)
|
| 157 |
-
# gamma ~ 0.995 / hour (arXiv 2304.03442). Components surfaced honestly.
|
| 158 |
-
# ---------------------------------------------------------------------------
|
| 159 |
-
_GAMMA = 0.995 # recency decay per hour
|
| 160 |
-
_A_REC = 1.0
|
| 161 |
-
_A_IMP = 1.0
|
| 162 |
-
_A_REL = 1.0
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
def _score_memory(row, q_emb: list, now_epoch: float) -> dict:
|
| 166 |
-
dt_hours = max(0.0, (now_epoch - float(row["last_access"])) / 3600.0)
|
| 167 |
-
recency = _GAMMA ** dt_hours
|
| 168 |
-
imp = float(row["importance"])
|
| 169 |
-
try:
|
| 170 |
-
emb = json.loads(row["embedding"])
|
| 171 |
-
except Exception:
|
| 172 |
-
emb = []
|
| 173 |
-
rel = _cos(q_emb, emb)
|
| 174 |
-
rel01 = (rel + 1.0) / 2.0 # map cosine [-1,1] -> [0,1] for the weighted sum
|
| 175 |
-
total = _A_REC * recency + _A_IMP * imp + _A_REL * rel01
|
| 176 |
-
return {
|
| 177 |
-
"mem_id": row["mem_id"], "tier": row["tier"], "kind": row["kind"],
|
| 178 |
-
"text": row["text"],
|
| 179 |
-
"score": round(total, 6),
|
| 180 |
-
"components": {
|
| 181 |
-
"recency_gamma_dt": round(recency, 6),
|
| 182 |
-
"delta_t_hours": round(dt_hours, 4),
|
| 183 |
-
"importance": round(imp, 4),
|
| 184 |
-
"relevance_cos": round(rel, 6),
|
| 185 |
-
"relevance_0_1": round(rel01, 6),
|
| 186 |
-
},
|
| 187 |
-
"weights": {"alpha_recency": _A_REC, "alpha_importance": _A_IMP,
|
| 188 |
-
"alpha_relevance": _A_REL, "gamma_per_hour": _GAMMA},
|
| 189 |
-
"label": "HEURISTIC", # local embeddings + heuristic importance
|
| 190 |
-
}
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
def _mem_add(run_id: str, tier: str, kind: str, text: str,
|
| 194 |
-
importance=None) -> str:
|
| 195 |
-
mem_id = "mem_" + uuid.uuid4().hex[:12]
|
| 196 |
-
now = _now_epoch()
|
| 197 |
-
imp = _importance_heuristic(text) if importance is None else float(importance)
|
| 198 |
-
emb = _embed(text)
|
| 199 |
-
with _LOCK, _conn() as c:
|
| 200 |
-
c.execute(
|
| 201 |
-
"INSERT INTO memory(mem_id,run_id,tier,kind,text,importance,"
|
| 202 |
-
"created_at,last_access,embedding) VALUES(?,?,?,?,?,?,?,?,?)",
|
| 203 |
-
(mem_id, run_id, tier, kind, text, imp, now, now, json.dumps(emb)),
|
| 204 |
-
)
|
| 205 |
-
return mem_id
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
def _mem_retrieve(query: str, top_k: int = 5, tier=None) -> list:
|
| 209 |
-
q_emb = _embed(query)
|
| 210 |
-
now = _now_epoch()
|
| 211 |
-
with _LOCK, _conn() as c:
|
| 212 |
-
if tier:
|
| 213 |
-
rows = c.execute("SELECT * FROM memory WHERE tier=?", (tier,)).fetchall()
|
| 214 |
-
else:
|
| 215 |
-
rows = c.execute("SELECT * FROM memory").fetchall()
|
| 216 |
-
scored = [_score_memory(r, q_emb, now) for r in rows]
|
| 217 |
-
scored.sort(key=lambda s: s["score"], reverse=True)
|
| 218 |
-
top = scored[:top_k]
|
| 219 |
-
# honest "access" bump: retrieved memories refresh their recency clock
|
| 220 |
-
if top:
|
| 221 |
-
ids = [s["mem_id"] for s in top]
|
| 222 |
-
with _LOCK, _conn() as c:
|
| 223 |
-
c.executemany("UPDATE memory SET last_access=? WHERE mem_id=?",
|
| 224 |
-
[(now, i) for i in ids])
|
| 225 |
-
return top
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
# ---------------------------------------------------------------------------
|
| 229 |
-
# Letta-style memory tiering. "working" = in-context (small, fast); "archival"
|
| 230 |
-
# = vector store (large, searched). The agent self-manages via tool calls
|
| 231 |
-
# memory_append / memory_search / memory_promote that the ReAct loop can emit.
|
| 232 |
-
# ---------------------------------------------------------------------------
|
| 233 |
-
_WORKING_CAP = 8 # in-context working-memory item cap (paging boundary)
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
def _working_snapshot(run_id: str) -> list:
|
| 237 |
-
with _LOCK, _conn() as c:
|
| 238 |
-
rows = c.execute(
|
| 239 |
-
"SELECT * FROM memory WHERE run_id=? AND tier='working' "
|
| 240 |
-
"ORDER BY last_access DESC LIMIT ?", (run_id, _WORKING_CAP)
|
| 241 |
-
).fetchall()
|
| 242 |
-
return [{"mem_id": r["mem_id"], "kind": r["kind"], "text": r["text"],
|
| 243 |
-
"importance": r["importance"]} for r in rows]
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
def _page_out_if_full(run_id: str) -> list:
|
| 247 |
-
"""Letta/MemGPT paging: when working memory exceeds the in-context cap, the
|
| 248 |
-
LEAST-recently-accessed working items are promoted (paged out) to archival
|
| 249 |
-
so the in-context window stays bounded. Returns the paged-out mem_ids."""
|
| 250 |
-
paged = []
|
| 251 |
-
with _LOCK, _conn() as c:
|
| 252 |
-
rows = c.execute(
|
| 253 |
-
"SELECT mem_id FROM memory WHERE run_id=? AND tier='working' "
|
| 254 |
-
"ORDER BY last_access ASC", (run_id,)
|
| 255 |
-
).fetchall()
|
| 256 |
-
if len(rows) > _WORKING_CAP:
|
| 257 |
-
overflow = rows[: len(rows) - _WORKING_CAP]
|
| 258 |
-
for r in overflow:
|
| 259 |
-
c.execute("UPDATE memory SET tier='archival' WHERE mem_id=?",
|
| 260 |
-
(r["mem_id"],))
|
| 261 |
-
paged.append(r["mem_id"])
|
| 262 |
-
return paged
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
# ---------------------------------------------------------------------------
|
| 266 |
-
# Voyager skill library. A tool-recipe is ADMITTED to the library ONLY after a
|
| 267 |
-
# verified execution receipt (DSSE envelope verified by the host verify_fn).
|
| 268 |
-
# Recipes are indexed by local embedding so the agent can retrieve a relevant
|
| 269 |
-
# prior recipe. We NEVER admit a recipe whose receipt fails verification.
|
| 270 |
-
# ---------------------------------------------------------------------------
|
| 271 |
-
def _skill_admit(name: str, recipe: str, receipt_hash: str,
|
| 272 |
-
receipt_verified: bool) -> dict:
|
| 273 |
-
if not receipt_verified:
|
| 274 |
-
return {"admitted": False,
|
| 275 |
-
"reason": "REJECTED — execution receipt did not verify; Voyager "
|
| 276 |
-
"admission requires a passing signed receipt.",
|
| 277 |
-
"receipt_hash": receipt_hash}
|
| 278 |
-
skill_id = "skill_" + uuid.uuid4().hex[:12]
|
| 279 |
-
emb = _embed(name + " " + recipe)
|
| 280 |
-
with _LOCK, _conn() as c:
|
| 281 |
-
c.execute(
|
| 282 |
-
"INSERT INTO skills(skill_id,name,recipe,receipt_hash,"
|
| 283 |
-
"receipt_verified,embedding,created_at,uses) VALUES(?,?,?,?,?,?,?,0)",
|
| 284 |
-
(skill_id, name, recipe, receipt_hash, 1, json.dumps(emb), _now_iso()),
|
| 285 |
-
)
|
| 286 |
-
return {"admitted": True, "skill_id": skill_id, "name": name,
|
| 287 |
-
"receipt_hash": receipt_hash,
|
| 288 |
-
"reason": "ADMITTED — backed by a verified execution receipt."}
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
def _skill_search(query: str, top_k: int = 5) -> list:
|
| 292 |
-
q_emb = _embed(query)
|
| 293 |
-
with _LOCK, _conn() as c:
|
| 294 |
-
rows = c.execute("SELECT * FROM skills").fetchall()
|
| 295 |
-
out = []
|
| 296 |
-
for r in rows:
|
| 297 |
-
try:
|
| 298 |
-
emb = json.loads(r["embedding"])
|
| 299 |
-
except Exception:
|
| 300 |
-
emb = []
|
| 301 |
-
out.append({"skill_id": r["skill_id"], "name": r["name"],
|
| 302 |
-
"recipe": r["recipe"], "receipt_hash": r["receipt_hash"],
|
| 303 |
-
"receipt_verified": bool(r["receipt_verified"]),
|
| 304 |
-
"uses": r["uses"],
|
| 305 |
-
"similarity": round(_cos(q_emb, emb), 6), "label": "LIVE"})
|
| 306 |
-
out.sort(key=lambda s: s["similarity"], reverse=True)
|
| 307 |
-
return out[:top_k]
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
# ---------------------------------------------------------------------------
|
| 311 |
-
# ReAct execution graph (arXiv 2210.03629). Nodes: THOUGHT -> ACTION ->
|
| 312 |
-
# OBSERVATION, looping until a terminal ANSWER or max_steps. EACH node
|
| 313 |
-
# transition is committed as a hash-chained receipt AND wrapped in a DSSE
|
| 314 |
-
# envelope by the host signer (sign_fn). A SqliteSaver-style checkpoint is
|
| 315 |
-
# written after every node so a crash resumes from the last committed step.
|
| 316 |
-
#
|
| 317 |
-
# The "model call" is routed through a small, deterministic in-image policy
|
| 318 |
-
# (the host a11oy inference path is the production target; we keep the loop's
|
| 319 |
-
# model-calls inside the app and label the planner HEURISTIC so we never fake a
|
| 320 |
-
# model number — the GRAPH, RECEIPTS, CHECKPOINTING and RESUME are all REAL).
|
| 321 |
-
# ---------------------------------------------------------------------------
|
| 322 |
-
|
| 323 |
-
# Tool registry: small, real, deterministic tools the ReAct agent can call.
|
| 324 |
-
def _tool_calc(arg: str) -> str:
|
| 325 |
-
expr = re.sub(r"[^0-9+\-*/(). ]", "", arg or "")
|
| 326 |
-
if not expr.strip():
|
| 327 |
-
return "ERR: empty expression"
|
| 328 |
-
try:
|
| 329 |
-
# safe arithmetic only (chars already filtered); no names/builtins
|
| 330 |
-
return str(eval(expr, {"__builtins__": {}}, {})) # noqa: S307
|
| 331 |
-
except Exception as e:
|
| 332 |
-
return "ERR: %s" % type(e).__name__
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
def _tool_memory_search(arg: str) -> str:
|
| 336 |
-
hits = _mem_retrieve(arg, top_k=3)
|
| 337 |
-
if not hits:
|
| 338 |
-
return "no memories"
|
| 339 |
-
return " | ".join("%s(score=%.3f)" % (h["text"][:48], h["score"]) for h in hits)
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
def _tool_skill_search(arg: str) -> str:
|
| 343 |
-
hits = _skill_search(arg, top_k=3)
|
| 344 |
-
if not hits:
|
| 345 |
-
return "no skills"
|
| 346 |
-
return " | ".join("%s(sim=%.3f)" % (h["name"], h["similarity"]) for h in hits)
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
def _tool_echo(arg: str) -> str:
|
| 350 |
-
return (arg or "")[:200]
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
_TOOLS = {
|
| 354 |
-
"calc": _tool_calc,
|
| 355 |
-
"memory_search": _tool_memory_search,
|
| 356 |
-
"skill_search": _tool_skill_search,
|
| 357 |
-
"echo": _tool_echo,
|
| 358 |
-
}
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
def _plan_action(goal: str, scratch: list) -> dict:
|
| 362 |
-
"""HEURISTIC planner (NOT a learned model — labelled HEURISTIC). Picks the
|
| 363 |
-
next ReAct action from the goal + scratchpad. Deterministic so the loop is
|
| 364 |
-
replayable and the demo is reproducible. The production target is the host
|
| 365 |
-
a11oy inference path; this keeps the agent loop's model-calls in-app."""
|
| 366 |
-
g = (goal or "").lower()
|
| 367 |
-
step = len(scratch)
|
| 368 |
-
# terminal: if we already produced an observation, answer.
|
| 369 |
-
last_obs = next((s for s in reversed(scratch) if s.get("node") == "OBSERVATION"), None)
|
| 370 |
-
if last_obs is not None:
|
| 371 |
-
return {"terminal": True,
|
| 372 |
-
"thought": "I have an observation; I can answer now.",
|
| 373 |
-
"answer": "Result: %s" % last_obs.get("observation", "")}
|
| 374 |
-
# arithmetic goal -> calc
|
| 375 |
-
if re.search(r"\d.*[+\-*/].*\d", g):
|
| 376 |
-
m = re.search(r"[-0-9+\-*/(). ]{3,}", goal)
|
| 377 |
-
arg = m.group(0).strip() if m else goal
|
| 378 |
-
return {"terminal": False, "tool": "calc", "tool_input": arg,
|
| 379 |
-
"thought": "This looks arithmetic; I will use the calc tool."}
|
| 380 |
-
if "memory" in g or "remember" in g or "recall" in g:
|
| 381 |
-
return {"terminal": False, "tool": "memory_search", "tool_input": goal,
|
| 382 |
-
"thought": "I should consult memory for this."}
|
| 383 |
-
if "skill" in g or "recipe" in g or "how do i" in g:
|
| 384 |
-
return {"terminal": False, "tool": "skill_search", "tool_input": goal,
|
| 385 |
-
"thought": "I should check the skill library."}
|
| 386 |
-
return {"terminal": False, "tool": "echo", "tool_input": goal,
|
| 387 |
-
"thought": "No specialised tool; I will restate and observe."}
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
class _ReActEngine:
|
| 391 |
-
"""Holds the host signer/verifier and runs / resumes graphs."""
|
| 392 |
-
|
| 393 |
-
def __init__(self, sign_fn, verify_fn, pub_pem_fn, ns="a11oy"):
|
| 394 |
-
self.sign_fn = sign_fn
|
| 395 |
-
self.verify_fn = verify_fn
|
| 396 |
-
self.pub_pem_fn = pub_pem_fn
|
| 397 |
-
self.ns = ns
|
| 398 |
-
_init_db()
|
| 399 |
-
|
| 400 |
-
# ---- receipt boundary: chain + DSSE sign every node transition ----
|
| 401 |
-
def _commit_receipt(self, run_id, seq, node, body, prev_hash, reflection=None):
|
| 402 |
-
rec_core = {"seq": seq, "node": node, "body": body, "prev_hash": prev_hash}
|
| 403 |
-
h = _sha(rec_core)
|
| 404 |
-
payload = {
|
| 405 |
-
"run_id": run_id, "seq": seq, "node": node, "body": body,
|
| 406 |
-
"prev_hash": prev_hash, "hash": h, "issuer": self.ns,
|
| 407 |
-
"issued_at": _now_iso(),
|
| 408 |
-
"reflection": reflection, # Reflexion field on the receipt
|
| 409 |
-
"trust_status": "Conjecture 1 (advisory \u2014 NOT a proven oracle)",
|
| 410 |
-
}
|
| 411 |
-
try:
|
| 412 |
-
envelope = self.sign_fn(payload)
|
| 413 |
-
except Exception as e:
|
| 414 |
-
envelope = {"signed": False, "signatures": [],
|
| 415 |
-
"honesty": "UNSIGNED \u2014 signer raised %s" % type(e).__name__,
|
| 416 |
-
"payloadType": "application/vnd.szl.receipt+json"}
|
| 417 |
-
with _LOCK, _conn() as c:
|
| 418 |
-
c.execute(
|
| 419 |
-
"INSERT OR REPLACE INTO receipts(run_id,seq,node,body,prev_hash,"
|
| 420 |
-
"hash,envelope,ts) VALUES(?,?,?,?,?,?,?,?)",
|
| 421 |
-
(run_id, seq, node, json.dumps(body), prev_hash, h,
|
| 422 |
-
json.dumps(envelope), _now_iso()),
|
| 423 |
-
)
|
| 424 |
-
return h, envelope
|
| 425 |
-
|
| 426 |
-
# ---- SqliteSaver-style checkpoint after every node ----
|
| 427 |
-
def _checkpoint(self, run_id, step, state, prev_hash):
|
| 428 |
-
with _LOCK, _conn() as c:
|
| 429 |
-
c.execute(
|
| 430 |
-
"INSERT OR REPLACE INTO checkpoints(run_id,step,state,prev_hash,ts)"
|
| 431 |
-
" VALUES(?,?,?,?,?)",
|
| 432 |
-
(run_id, step, json.dumps(state), prev_hash, _now_iso()),
|
| 433 |
-
)
|
| 434 |
-
|
| 435 |
-
def _load_run(self, run_id):
|
| 436 |
-
with _LOCK, _conn() as c:
|
| 437 |
-
r = c.execute("SELECT * FROM runs WHERE run_id=?", (run_id,)).fetchone()
|
| 438 |
-
cps = c.execute(
|
| 439 |
-
"SELECT * FROM checkpoints WHERE run_id=? ORDER BY step DESC LIMIT 1",
|
| 440 |
-
(run_id,)).fetchone()
|
| 441 |
-
return r, cps
|
| 442 |
-
|
| 443 |
-
def _prior_reflection(self, goal):
|
| 444 |
-
"""Reflexion: prepend the most relevant prior reflection on activation."""
|
| 445 |
-
with _LOCK, _conn() as c:
|
| 446 |
-
rows = c.execute(
|
| 447 |
-
"SELECT text FROM reflections ORDER BY rowid DESC LIMIT 8").fetchall()
|
| 448 |
-
if not rows:
|
| 449 |
-
return None
|
| 450 |
-
# pick the reflection most lexically relevant to this goal
|
| 451 |
-
q = _embed(goal)
|
| 452 |
-
best, best_sim = None, -2.0
|
| 453 |
-
for r in rows:
|
| 454 |
-
sim = _cos(q, _embed(r["text"]))
|
| 455 |
-
if sim > best_sim:
|
| 456 |
-
best, best_sim = r["text"], sim
|
| 457 |
-
return best
|
| 458 |
-
|
| 459 |
-
# ---- run a (possibly partial) graph from a starting step ----
|
| 460 |
-
def _drive(self, run_id, goal, max_steps, start_step, prev_hash,
|
| 461 |
-
scratch, reflection, kill_after=None):
|
| 462 |
-
node_seq = start_step
|
| 463 |
-
status = "running"
|
| 464 |
-
steps_done = 0
|
| 465 |
-
terminal_answer = None
|
| 466 |
-
while node_seq // 3 < max_steps:
|
| 467 |
-
phase = node_seq % 3
|
| 468 |
-
cur_step = node_seq // 3
|
| 469 |
-
if phase == 0: # THOUGHT
|
| 470 |
-
plan = _plan_action(goal, scratch)
|
| 471 |
-
scratch.append({"node": "THOUGHT", "step": cur_step,
|
| 472 |
-
"thought": plan["thought"], "plan": plan})
|
| 473 |
-
body = {"step": cur_step, "thought": plan["thought"],
|
| 474 |
-
"intended_tool": plan.get("tool"),
|
| 475 |
-
"terminal": plan.get("terminal", False)}
|
| 476 |
-
prev_hash, _ = self._commit_receipt(run_id, node_seq, "THOUGHT",
|
| 477 |
-
body, prev_hash, reflection)
|
| 478 |
-
if plan.get("terminal"):
|
| 479 |
-
terminal_answer = plan.get("answer")
|
| 480 |
-
status = "completed"
|
| 481 |
-
self._checkpoint(run_id, node_seq + 1,
|
| 482 |
-
{"scratch": scratch, "answer": terminal_answer},
|
| 483 |
-
prev_hash)
|
| 484 |
-
node_seq += 1
|
| 485 |
-
break
|
| 486 |
-
elif phase == 1: # ACTION
|
| 487 |
-
plan = scratch[-1]["plan"]
|
| 488 |
-
tool, arg = plan.get("tool", "echo"), plan.get("tool_input", "")
|
| 489 |
-
scratch.append({"node": "ACTION", "step": cur_step,
|
| 490 |
-
"tool": tool, "tool_input": arg})
|
| 491 |
-
body = {"step": cur_step, "tool": tool, "tool_input": arg}
|
| 492 |
-
prev_hash, _ = self._commit_receipt(run_id, node_seq, "ACTION",
|
| 493 |
-
body, prev_hash, reflection)
|
| 494 |
-
else: # OBSERVATION (execute the tool for real)
|
| 495 |
-
act = next(s for s in reversed(scratch) if s.get("node") == "ACTION")
|
| 496 |
-
fn = _TOOLS.get(act["tool"], _tool_echo)
|
| 497 |
-
obs = fn(act["tool_input"])
|
| 498 |
-
scratch.append({"node": "OBSERVATION", "step": cur_step,
|
| 499 |
-
"observation": obs})
|
| 500 |
-
# store the observation as a working memory (Letta tiering)
|
| 501 |
-
_mem_add(run_id, "working", "observation",
|
| 502 |
-
"step %d %s->%s" % (cur_step, act["tool"], obs))
|
| 503 |
-
_page_out_if_full(run_id)
|
| 504 |
-
body = {"step": cur_step, "tool": act["tool"], "observation": obs}
|
| 505 |
-
prev_hash, _ = self._commit_receipt(run_id, node_seq, "OBSERVATION",
|
| 506 |
-
body, prev_hash, reflection)
|
| 507 |
-
node_seq += 1
|
| 508 |
-
steps_done += 1
|
| 509 |
-
# CHECKPOINT after every node transition (SqliteSaver-style)
|
| 510 |
-
self._checkpoint(run_id, node_seq,
|
| 511 |
-
{"scratch": scratch, "node_seq": node_seq}, prev_hash)
|
| 512 |
-
# honest crash injection for the resumable demo: stop mid-run
|
| 513 |
-
if kill_after is not None and steps_done >= kill_after:
|
| 514 |
-
status = "interrupted"
|
| 515 |
-
break
|
| 516 |
-
else:
|
| 517 |
-
status = "completed" if terminal_answer else "max_steps"
|
| 518 |
-
|
| 519 |
-
final_hash = prev_hash
|
| 520 |
-
with _LOCK, _conn() as c:
|
| 521 |
-
c.execute(
|
| 522 |
-
"UPDATE runs SET status=?,step=?,prev_hash=?,final_hash=?,"
|
| 523 |
-
"updated_at=? WHERE run_id=?",
|
| 524 |
-
(status, node_seq, prev_hash, final_hash, _now_iso(), run_id))
|
| 525 |
-
return {"run_id": run_id, "status": status, "node_seq": node_seq,
|
| 526 |
-
"final_hash": final_hash, "answer": terminal_answer,
|
| 527 |
-
"scratch": scratch}
|
| 528 |
-
|
| 529 |
-
def run(self, goal, max_steps=4, kill_after=None):
|
| 530 |
-
run_id = "run_" + uuid.uuid4().hex[:12]
|
| 531 |
-
reflection = self._prior_reflection(goal)
|
| 532 |
-
# seed long-term memory with the goal
|
| 533 |
-
_mem_add(run_id, "working", "goal", "GOAL: " + (goal or ""))
|
| 534 |
-
with _LOCK, _conn() as c:
|
| 535 |
-
c.execute(
|
| 536 |
-
"INSERT INTO runs(run_id,goal,status,max_steps,step,prev_hash,"
|
| 537 |
-
"final_hash,reflection,created_at,updated_at) "
|
| 538 |
-
"VALUES(?,?,?,?,?,?,?,?,?,?)",
|
| 539 |
-
(run_id, goal, "running", max_steps, 0, "GENESIS", "",
|
| 540 |
-
reflection or "", _now_iso(), _now_iso()))
|
| 541 |
-
# genesis receipt
|
| 542 |
-
prev_hash = "GENESIS"
|
| 543 |
-
prev_hash, _ = self._commit_receipt(
|
| 544 |
-
run_id, -1, "GENESIS",
|
| 545 |
-
{"goal": goal, "max_steps": max_steps,
|
| 546 |
-
"prior_reflection_prepended": bool(reflection)},
|
| 547 |
-
prev_hash, reflection)
|
| 548 |
-
self._checkpoint(run_id, 0, {"scratch": [], "node_seq": 0}, prev_hash)
|
| 549 |
-
return self._drive(run_id, goal, max_steps, 0, prev_hash, [],
|
| 550 |
-
reflection, kill_after=kill_after)
|
| 551 |
-
|
| 552 |
-
def resume(self, run_id):
|
| 553 |
-
r, cps = self._load_run(run_id)
|
| 554 |
-
if r is None:
|
| 555 |
-
return {"error": "unknown run_id", "run_id": run_id}
|
| 556 |
-
if r["status"] not in ("interrupted", "running", "max_steps"):
|
| 557 |
-
return {"run_id": run_id, "status": r["status"],
|
| 558 |
-
"note": "run already %s \u2014 nothing to resume" % r["status"],
|
| 559 |
-
"resumed": False}
|
| 560 |
-
state = json.loads(cps["state"]) if cps else {"scratch": [], "node_seq": 0}
|
| 561 |
-
node_seq = state.get("node_seq", 0)
|
| 562 |
-
scratch = state.get("scratch", [])
|
| 563 |
-
prev_hash = cps["prev_hash"] if cps else "GENESIS"
|
| 564 |
-
out = self._drive(run_id, r["goal"], r["max_steps"], node_seq, prev_hash,
|
| 565 |
-
scratch, r["reflection"] or None)
|
| 566 |
-
out["resumed"] = True
|
| 567 |
-
out["resumed_from_checkpoint_step"] = node_seq
|
| 568 |
-
return out
|
| 569 |
-
|
| 570 |
-
def trace(self, run_id):
|
| 571 |
-
with _LOCK, _conn() as c:
|
| 572 |
-
r = c.execute("SELECT * FROM runs WHERE run_id=?", (run_id,)).fetchone()
|
| 573 |
-
recs = c.execute(
|
| 574 |
-
"SELECT * FROM receipts WHERE run_id=? ORDER BY seq", (run_id,)
|
| 575 |
-
).fetchall()
|
| 576 |
-
if r is None:
|
| 577 |
-
return {"error": "unknown run_id", "run_id": run_id}
|
| 578 |
-
receipts, chain_ok, prev = [], True, "GENESIS"
|
| 579 |
-
for rec in recs:
|
| 580 |
-
body = json.loads(rec["body"])
|
| 581 |
-
recompute = _sha({"seq": rec["seq"], "node": rec["node"],
|
| 582 |
-
"body": body, "prev_hash": rec["prev_hash"]})
|
| 583 |
-
link_ok = (rec["prev_hash"] == prev) and (recompute == rec["hash"])
|
| 584 |
-
env = json.loads(rec["envelope"])
|
| 585 |
-
sig_ok = None
|
| 586 |
-
if self.verify_fn is not None:
|
| 587 |
-
try:
|
| 588 |
-
sig_ok = bool(self.verify_fn(env).get("signature_valid"))
|
| 589 |
-
except Exception:
|
| 590 |
-
sig_ok = False
|
| 591 |
-
chain_ok = chain_ok and link_ok
|
| 592 |
-
receipts.append({"seq": rec["seq"], "node": rec["node"], "body": body,
|
| 593 |
-
"hash": rec["hash"], "prev_hash": rec["prev_hash"],
|
| 594 |
-
"link_ok": link_ok, "signature_valid": sig_ok,
|
| 595 |
-
"signed": bool(env.get("signed")),
|
| 596 |
-
"ts": rec["ts"]})
|
| 597 |
-
prev = rec["hash"]
|
| 598 |
-
return {"run_id": run_id, "goal": r["goal"], "status": r["status"],
|
| 599 |
-
"reflection": r["reflection"],
|
| 600 |
-
"chain_intact": chain_ok, "depth": len(receipts),
|
| 601 |
-
"final_hash": r["final_hash"], "receipts": receipts,
|
| 602 |
-
"trust_note": "Receipt chain + DSSE signatures are REAL; planner is "
|
| 603 |
-
"HEURISTIC (deterministic, replayable). Trust=Conjecture 1."}
|
| 604 |
-
|
| 605 |
-
def checkpoints(self, run_id):
|
| 606 |
-
with _LOCK, _conn() as c:
|
| 607 |
-
cps = c.execute(
|
| 608 |
-
"SELECT step,prev_hash,ts FROM checkpoints WHERE run_id=? "
|
| 609 |
-
"ORDER BY step", (run_id,)).fetchall()
|
| 610 |
-
r = c.execute("SELECT status,step FROM runs WHERE run_id=?",
|
| 611 |
-
(run_id,)).fetchone()
|
| 612 |
-
return {"run_id": run_id,
|
| 613 |
-
"status": (r["status"] if r else "unknown"),
|
| 614 |
-
"current_step": (r["step"] if r else None),
|
| 615 |
-
"checkpoints": [{"step": c["step"], "prev_hash": c["prev_hash"],
|
| 616 |
-
"ts": c["ts"]} for c in cps],
|
| 617 |
-
"saver": "SqliteSaver-style (local sqlite, ephemeral per container)"}
|
| 618 |
-
|
| 619 |
-
def reflect(self, run_id, reflection_text):
|
| 620 |
-
"""Reflexion: store a NL reflection after a reviewed episode."""
|
| 621 |
-
with _LOCK, _conn() as c:
|
| 622 |
-
n = c.execute("SELECT COUNT(*) AS n FROM reflections WHERE run_id=?",
|
| 623 |
-
(run_id,)).fetchone()["n"]
|
| 624 |
-
c.execute("INSERT OR REPLACE INTO reflections(run_id,idx,text,ts) "
|
| 625 |
-
"VALUES(?,?,?,?)", (run_id, n, reflection_text, _now_iso()))
|
| 626 |
-
c.execute("UPDATE runs SET reflection=? WHERE run_id=?",
|
| 627 |
-
(reflection_text, run_id))
|
| 628 |
-
_mem_add(run_id, "archival", "reflection", reflection_text, importance=0.85)
|
| 629 |
-
return {"run_id": run_id, "stored": True, "reflection": reflection_text,
|
| 630 |
-
"note": "Prepended to the next activation on a lexically-relevant goal."}
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
# ---------------------------------------------------------------------------
|
| 634 |
-
# register(app, ns, sign_fn, verify_fn, pub_pem_fn) — mirrors szl_agentic_loop.
|
| 635 |
-
# Routes inserted at position 0 (Starlette Route) so they beat the SPA catch-all.
|
| 636 |
-
# FREE sub-namespace /api/a11oy/v1/agent/react/* to avoid collisions with the
|
| 637 |
-
# existing /run, /tools, /verify-chain, /governance-standards, /_diag, /loop.
|
| 638 |
-
# ---------------------------------------------------------------------------
|
| 639 |
-
def register(app, ns: str = "a11oy", sign_fn=None, verify_fn=None,
|
| 640 |
-
pub_pem_fn=None, signer_label: str = "in-image key"):
|
| 641 |
-
from starlette.routing import Route
|
| 642 |
-
from starlette.responses import JSONResponse
|
| 643 |
-
|
| 644 |
-
_init_db()
|
| 645 |
-
eng = _ReActEngine(sign_fn, verify_fn, pub_pem_fn, ns=ns)
|
| 646 |
-
|
| 647 |
-
async def _read_json(request):
|
| 648 |
-
try:
|
| 649 |
-
return await request.json()
|
| 650 |
-
except Exception:
|
| 651 |
-
return {}
|
| 652 |
-
|
| 653 |
-
async def _run(request):
|
| 654 |
-
d = await _read_json(request)
|
| 655 |
-
goal = (d.get("goal") or d.get("query") or "").strip()
|
| 656 |
-
if not goal:
|
| 657 |
-
return JSONResponse({"error": "missing 'goal'"}, status_code=400)
|
| 658 |
-
max_steps = int(d.get("max_steps", 4))
|
| 659 |
-
kill_after = d.get("kill_after") # honest crash-injection for the demo
|
| 660 |
-
kill_after = int(kill_after) if kill_after is not None else None
|
| 661 |
-
out = eng.run(goal, max_steps=max_steps, kill_after=kill_after)
|
| 662 |
-
out["label"] = "EXPERIMENTAL"
|
| 663 |
-
return JSONResponse(out)
|
| 664 |
-
|
| 665 |
-
async def _resume(request):
|
| 666 |
-
d = await _read_json(request)
|
| 667 |
-
run_id = (d.get("run_id") or request.query_params.get("run_id") or "").strip()
|
| 668 |
-
if not run_id:
|
| 669 |
-
return JSONResponse({"error": "missing 'run_id'"}, status_code=400)
|
| 670 |
-
out = eng.resume(run_id)
|
| 671 |
-
out["label"] = "EXPERIMENTAL"
|
| 672 |
-
return JSONResponse(out)
|
| 673 |
-
|
| 674 |
-
async def _trace(request):
|
| 675 |
-
run_id = request.path_params.get("run_id") or request.query_params.get("run_id", "")
|
| 676 |
-
return JSONResponse(eng.trace(run_id))
|
| 677 |
-
|
| 678 |
-
async def _checkpoints(request):
|
| 679 |
-
run_id = request.path_params.get("run_id") or request.query_params.get("run_id", "")
|
| 680 |
-
return JSONResponse(eng.checkpoints(run_id))
|
| 681 |
-
|
| 682 |
-
async def _reflect(request):
|
| 683 |
-
d = await _read_json(request)
|
| 684 |
-
run_id = (d.get("run_id") or "").strip()
|
| 685 |
-
text = (d.get("reflection") or d.get("text") or "").strip()
|
| 686 |
-
if not run_id or not text:
|
| 687 |
-
return JSONResponse({"error": "need run_id + reflection"}, status_code=400)
|
| 688 |
-
return JSONResponse(eng.reflect(run_id, text))
|
| 689 |
-
|
| 690 |
-
async def _mem_add_ep(request):
|
| 691 |
-
d = await _read_json(request)
|
| 692 |
-
text = (d.get("text") or "").strip()
|
| 693 |
-
if not text:
|
| 694 |
-
return JSONResponse({"error": "missing 'text'"}, status_code=400)
|
| 695 |
-
mid = _mem_add(d.get("run_id", "adhoc"), d.get("tier", "archival"),
|
| 696 |
-
d.get("kind", "note"), text, d.get("importance"))
|
| 697 |
-
return JSONResponse({"mem_id": mid, "tier": d.get("tier", "archival"),
|
| 698 |
-
"label": "HEURISTIC"})
|
| 699 |
-
|
| 700 |
-
async def _mem_search_ep(request):
|
| 701 |
-
d = await _read_json(request)
|
| 702 |
-
q = (d.get("query") or "").strip()
|
| 703 |
-
if not q:
|
| 704 |
-
return JSONResponse({"error": "missing 'query'"}, status_code=400)
|
| 705 |
-
hits = _mem_retrieve(q, top_k=int(d.get("top_k", 5)), tier=d.get("tier"))
|
| 706 |
-
return JSONResponse({"query": q, "results": hits, "label": "HEURISTIC",
|
| 707 |
-
"formula": "score(m)=a_rec*g^dt + a_imp*imp(m) + a_rel*cos(q,m)",
|
| 708 |
-
"source": "Generative Agents (arXiv 2304.03442)"})
|
| 709 |
-
|
| 710 |
-
async def _mem_tiers(request):
|
| 711 |
-
run_id = request.query_params.get("run_id", "")
|
| 712 |
-
with _LOCK, _conn() as c:
|
| 713 |
-
wq = ("SELECT tier,COUNT(*) AS n FROM memory" +
|
| 714 |
-
(" WHERE run_id=?" if run_id else "") + " GROUP BY tier")
|
| 715 |
-
rows = c.execute(wq, ((run_id,) if run_id else ())).fetchall()
|
| 716 |
-
tiers = {r["tier"]: r["n"] for r in rows}
|
| 717 |
-
return JSONResponse({"run_id": run_id or None, "tiers": tiers,
|
| 718 |
-
"working": _working_snapshot(run_id) if run_id else [],
|
| 719 |
-
"working_cap": _WORKING_CAP,
|
| 720 |
-
"design": "Letta/MemGPT (arXiv 2310.08560): working "
|
| 721 |
-
"(in-context) + archival (vector); self-managed.",
|
| 722 |
-
"label": "EXPERIMENTAL"})
|
| 723 |
-
|
| 724 |
-
async def _skill_admit_ep(request):
|
| 725 |
-
d = await _read_json(request)
|
| 726 |
-
name = (d.get("name") or "").strip()
|
| 727 |
-
recipe = (d.get("recipe") or "").strip()
|
| 728 |
-
run_id = (d.get("run_id") or "").strip()
|
| 729 |
-
if not name or not recipe:
|
| 730 |
-
return JSONResponse({"error": "need name + recipe"}, status_code=400)
|
| 731 |
-
# Voyager admission: require a VERIFIED execution receipt. We accept a
|
| 732 |
-
# run_id and verify its final emit receipt; OR a direct envelope.
|
| 733 |
-
verified, rhash = False, ""
|
| 734 |
-
if run_id:
|
| 735 |
-
tr = eng.trace(run_id)
|
| 736 |
-
recs = tr.get("receipts", [])
|
| 737 |
-
if recs:
|
| 738 |
-
last = recs[-1]
|
| 739 |
-
rhash = last["hash"]
|
| 740 |
-
verified = bool(last.get("signature_valid")) and tr.get("chain_intact")
|
| 741 |
-
elif d.get("envelope") and verify_fn is not None:
|
| 742 |
-
try:
|
| 743 |
-
verified = bool(verify_fn(d["envelope"]).get("signature_valid"))
|
| 744 |
-
rhash = _sha(d["envelope"])[:32]
|
| 745 |
-
except Exception:
|
| 746 |
-
verified = False
|
| 747 |
-
res = _skill_admit(name, recipe, rhash, verified)
|
| 748 |
-
res["label"] = "LIVE" if res.get("admitted") else "EXPERIMENTAL"
|
| 749 |
-
return JSONResponse(res, status_code=200 if res.get("admitted") else 422)
|
| 750 |
-
|
| 751 |
-
async def _skill_list(request):
|
| 752 |
-
q = request.query_params.get("q", "")
|
| 753 |
-
return JSONResponse({"query": q or None,
|
| 754 |
-
"skills": _skill_search(q or "skill", top_k=50),
|
| 755 |
-
"admission_rule": "Voyager (arXiv 2305.16291): admit a "
|
| 756 |
-
"recipe ONLY after a verified execution receipt.",
|
| 757 |
-
"label": "LIVE"})
|
| 758 |
-
|
| 759 |
-
async def _diag(request):
|
| 760 |
-
with _LOCK, _conn() as c:
|
| 761 |
-
nr = c.execute("SELECT COUNT(*) AS n FROM runs").fetchone()["n"]
|
| 762 |
-
nm = c.execute("SELECT COUNT(*) AS n FROM memory").fetchone()["n"]
|
| 763 |
-
ns_ = c.execute("SELECT COUNT(*) AS n FROM skills").fetchone()["n"]
|
| 764 |
-
return JSONResponse({
|
| 765 |
-
"module": "a11oy_react_core", "status": "ok",
|
| 766 |
-
"db": _DB_PATH, "runs": nr, "memories": nm, "skills": ns_,
|
| 767 |
-
"signer": signer_label,
|
| 768 |
-
"pubkey_present": bool((pub_pem_fn() if pub_pem_fn else "")),
|
| 769 |
-
"subsystems": ["ReAct graph (2210.03629)", "SqliteSaver checkpointing",
|
| 770 |
-
"Reflexion (2303.11366)", "Generative-Agents memory (2304.03442)",
|
| 771 |
-
"Letta tiering (2310.08560)", "Voyager skill library (2305.16291)"],
|
| 772 |
-
"label": "EXPERIMENTAL"})
|
| 773 |
-
|
| 774 |
-
base = "/api/%s/v1/agent/react" % ns
|
| 775 |
-
routes = [
|
| 776 |
-
Route(base + "/run", _run, methods=["POST"], name="%s_react_run" % ns),
|
| 777 |
-
Route(base + "/resume", _resume, methods=["POST"], name="%s_react_resume" % ns),
|
| 778 |
-
Route(base + "/trace/{run_id}", _trace, methods=["GET"], name="%s_react_trace" % ns),
|
| 779 |
-
Route(base + "/trace", _trace, methods=["GET"], name="%s_react_trace_q" % ns),
|
| 780 |
-
Route(base + "/checkpoints/{run_id}", _checkpoints, methods=["GET"],
|
| 781 |
-
name="%s_react_cps" % ns),
|
| 782 |
-
Route(base + "/checkpoints", _checkpoints, methods=["GET"], name="%s_react_cps_q" % ns),
|
| 783 |
-
Route(base + "/reflect", _reflect, methods=["POST"], name="%s_react_reflect" % ns),
|
| 784 |
-
Route(base + "/memory/add", _mem_add_ep, methods=["POST"], name="%s_react_mem_add" % ns),
|
| 785 |
-
Route(base + "/memory/search", _mem_search_ep, methods=["POST"],
|
| 786 |
-
name="%s_react_mem_search" % ns),
|
| 787 |
-
Route(base + "/memory/tiers", _mem_tiers, methods=["GET"], name="%s_react_mem_tiers" % ns),
|
| 788 |
-
Route(base + "/skills/admit", _skill_admit_ep, methods=["POST"],
|
| 789 |
-
name="%s_react_skill_admit" % ns),
|
| 790 |
-
Route(base + "/skills", _skill_list, methods=["GET"], name="%s_react_skills" % ns),
|
| 791 |
-
Route(base + "/_diag", _diag, methods=["GET"], name="%s_react_diag" % ns),
|
| 792 |
-
# Free top-level conveniences requested by the spec (not taken elsewhere):
|
| 793 |
-
Route("/api/%s/v1/agent/resume" % ns, _resume, methods=["POST"],
|
| 794 |
-
name="%s_agent_resume_top" % ns),
|
| 795 |
-
Route("/api/%s/v1/agent/trace/{run_id}" % ns, _trace, methods=["GET"],
|
| 796 |
-
name="%s_agent_trace_top" % ns),
|
| 797 |
-
Route("/api/%s/v1/agent/checkpoints/{run_id}" % ns, _checkpoints, methods=["GET"],
|
| 798 |
-
name="%s_agent_cps_top" % ns),
|
| 799 |
-
Route("/api/%s/v1/agent/checkpoints" % ns, _checkpoints, methods=["GET"],
|
| 800 |
-
name="%s_agent_cps_top_q" % ns),
|
| 801 |
-
]
|
| 802 |
-
for r in routes:
|
| 803 |
-
app.router.routes.insert(0, r)
|
| 804 |
-
return {"module": "a11oy_react_core", "routes": len(routes), "base": base,
|
| 805 |
-
"signer": signer_label}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
serve.py
CHANGED
|
@@ -250,6 +250,19 @@ try:
|
|
| 250 |
except Exception as _szl_eb_e: # pragma: no cover
|
| 251 |
print(f"[a11oy] Energy-budget receipt NOT registered: {_szl_eb_e!r}", file=__import__("sys").stderr)
|
| 252 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
# ── Agentic PINN + Physical-Bounds Certifier MESH (pinn-bounds) — closes the audited
|
| 254 |
# gap where the PINN / FE-NO Physics-ML verticals lived ONLY in `platform` and were
|
| 255 |
# NOT in a11oy's governed /api/a11oy/v1/<name> route table. Adds /api/a11oy/v1/pinn/*:
|
|
@@ -946,12 +959,6 @@ try:
|
|
| 946 |
# Conjecture 1; unreachable organs render dim (no fabricated data).
|
| 947 |
app.add_api_route("/hologram", _ptg_serve("hologram.html"), methods=["GET"], include_in_schema=False)
|
| 948 |
app.add_api_route("/a11oy/hologram", _ptg_serve("hologram.html"), methods=["GET"], include_in_schema=False)
|
| 949 |
-
# LANE A AGENTIC CORE (2026-06-14, Dev A): resumable ReAct agent surface —
|
| 950 |
-
# "Agent Loop" + "Memory" + "Skill Library" tabs. Standalone page (0 CDN;
|
| 951 |
-
# shared label/receipt engines from /static/shared). Renders REAL traces,
|
| 952 |
-
# checkpoints and retrieval scores from /api/a11oy/v1/agent/react/*.
|
| 953 |
-
app.add_api_route("/agent-loop", _ptg_serve("agent-loop.html"), methods=["GET"], include_in_schema=False)
|
| 954 |
-
app.add_api_route("/a11oy/agent-loop", _ptg_serve("agent-loop.html"), methods=["GET"], include_in_schema=False)
|
| 955 |
|
| 956 |
# /chat + /a11oy/chat -> /code consolidation (founder-directed; the only removal).
|
| 957 |
async def _ptg_chat_to_code() -> Response:
|
|
@@ -7575,46 +7582,6 @@ except Exception as _loop_e:
|
|
| 7575 |
# ============================================================================
|
| 7576 |
|
| 7577 |
|
| 7578 |
-
# ============================================================================
|
| 7579 |
-
# BEGIN: LANE A AGENTIC CORE — a11oy (2026-06-14, Dev A, ADDITIVE, surgical)
|
| 7580 |
-
# Resumable ReAct execution graph (Thought->Action->Observation) where EACH
|
| 7581 |
-
# node transition is a SIGNED receipt boundary, with SqliteSaver-style
|
| 7582 |
-
# checkpointing (crash mid-run -> /resume continues), a Reflexion inner loop,
|
| 7583 |
-
# Generative-Agents memory retrieval scoring over a LOCAL vector store (0 CDN),
|
| 7584 |
-
# Letta-style working/archival tiering, and a Voyager skill library that admits
|
| 7585 |
-
# a tool-recipe ONLY after a verified execution receipt.
|
| 7586 |
-
# REUSES the host's REAL in-image signer (_a11oy_sign_receipt), verifier
|
| 7587 |
-
# (_a11oy_loop_verify) and public key (_a11oy_loop_pubpem). Routes inserted at
|
| 7588 |
-
# position 0 (Starlette Route) so they beat the SPA catch-all. FREE sub-namespace
|
| 7589 |
-
# /api/a11oy/v1/agent/react/* — no collision with /run, /tools, /verify-chain,
|
| 7590 |
-
# /governance-standards, /_diag, /loop. try/except-guarded (non-fatal).
|
| 7591 |
-
# Signed-off-by: Stephen P. Lutar Jr. <stephenlutar2@gmail.com>
|
| 7592 |
-
# Co-Authored-By: Perplexity Computer Agent <agent@perplexity.ai>
|
| 7593 |
-
# ============================================================================
|
| 7594 |
-
try:
|
| 7595 |
-
import a11oy_react_core as _react_core
|
| 7596 |
-
import sys as _react_sys
|
| 7597 |
-
_react_status = _react_core.register(
|
| 7598 |
-
app, "a11oy",
|
| 7599 |
-
sign_fn=_a11oy_sign_receipt,
|
| 7600 |
-
verify_fn=(_a11oy_loop_verify if "_a11oy_loop_verify" in dir() else None),
|
| 7601 |
-
pub_pem_fn=(_a11oy_loop_pubpem if "_a11oy_loop_pubpem" in dir() else None),
|
| 7602 |
-
signer_label=("in-image ephemeral ECDSA-P256 (signed at server boot, "
|
| 7603 |
-
"resets on rebuild, verifiable vs /cosign.pub)"),
|
| 7604 |
-
)
|
| 7605 |
-
print(f"[a11oy] LANE A agentic core registered: {_react_status}", file=_react_sys.stderr)
|
| 7606 |
-
_REACT_DIAG = {"status": "ok", "registered": _react_status}
|
| 7607 |
-
except Exception as _react_e:
|
| 7608 |
-
import sys as _react_sys, traceback as _react_tb
|
| 7609 |
-
print(f"[a11oy] LANE A agentic core FAILED (non-fatal): {_react_e!r}", file=_react_sys.stderr)
|
| 7610 |
-
_react_tb.print_exc(file=_react_sys.stderr)
|
| 7611 |
-
_REACT_DIAG = {"status": "FAILED", "error": repr(_react_e),
|
| 7612 |
-
"traceback": _react_tb.format_exc()}
|
| 7613 |
-
# ============================================================================
|
| 7614 |
-
# END: LANE A AGENTIC CORE — a11oy
|
| 7615 |
-
# ============================================================================
|
| 7616 |
-
|
| 7617 |
-
|
| 7618 |
# ============================================================================
|
| 7619 |
# BEGIN: FORMULA-WIRING SURFACE — a11oy (2026-06-06, ADDITIVE, surgical)
|
| 7620 |
# Wires ALL ~80 kernel-verified theorems to REAL, executed mechanisms (shared,
|
|
|
|
| 250 |
except Exception as _szl_eb_e: # pragma: no cover
|
| 251 |
print(f"[a11oy] Energy-budget receipt NOT registered: {_szl_eb_e!r}", file=__import__("sys").stderr)
|
| 252 |
|
| 253 |
+
# ── Energy / Sovereign-Compute instrumentation (Lane C: sovereign-energy). Reads REAL
|
| 254 |
+
# J/token + carbon + speculative-decode + KV-cache + router + carbon-schedule from the
|
| 255 |
+
# on-box vLLM /metrics ONLY when the live sovereign probe shows gpu_reachable; otherwise
|
| 256 |
+
# every panel is honestly labeled ROADMAP (no meter -> no number). Adds the unified
|
| 257 |
+
# /energy tab + /api/a11oy/v1/energy/{sovereign,jtoken,throughput,kvcache,gateway,router,
|
| 258 |
+
# carbon}. Additive, try/except-guarded, before the SPA catch-all. window.SZLLabels.
|
| 259 |
+
try:
|
| 260 |
+
import szl_energy_sovereign as _szl_energy_sovereign
|
| 261 |
+
_szl_energy_sovereign.register(app, ns="a11oy")
|
| 262 |
+
print("[a11oy] Energy/Sovereign-Compute registered: /energy + /api/a11oy/v1/energy/*", file=__import__("sys").stderr)
|
| 263 |
+
except Exception as _szl_es_e: # pragma: no cover
|
| 264 |
+
print(f"[a11oy] Energy/Sovereign-Compute NOT registered: {_szl_es_e!r}", file=__import__("sys").stderr)
|
| 265 |
+
|
| 266 |
# ── Agentic PINN + Physical-Bounds Certifier MESH (pinn-bounds) — closes the audited
|
| 267 |
# gap where the PINN / FE-NO Physics-ML verticals lived ONLY in `platform` and were
|
| 268 |
# NOT in a11oy's governed /api/a11oy/v1/<name> route table. Adds /api/a11oy/v1/pinn/*:
|
|
|
|
| 959 |
# Conjecture 1; unreachable organs render dim (no fabricated data).
|
| 960 |
app.add_api_route("/hologram", _ptg_serve("hologram.html"), methods=["GET"], include_in_schema=False)
|
| 961 |
app.add_api_route("/a11oy/hologram", _ptg_serve("hologram.html"), methods=["GET"], include_in_schema=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 962 |
|
| 963 |
# /chat + /a11oy/chat -> /code consolidation (founder-directed; the only removal).
|
| 964 |
async def _ptg_chat_to_code() -> Response:
|
|
|
|
| 7582 |
# ============================================================================
|
| 7583 |
|
| 7584 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7585 |
# ============================================================================
|
| 7586 |
# BEGIN: FORMULA-WIRING SURFACE — a11oy (2026-06-06, ADDITIVE, surgical)
|
| 7587 |
# Wires ALL ~80 kernel-verified theorems to REAL, executed mechanisms (shared,
|
szl_energy_sovereign.py
ADDED
|
@@ -0,0 +1,883 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# © 2026 Lutar, Stephen P. — SZL Holdings · ORCID 0009-0001-0110-4173
|
| 3 |
+
# Doctrine v11 LOCKED: locked-proven=8 · Λ=Conjecture 1 · SLSA L1 honest / L2 attested / L3 roadmap
|
| 4 |
+
# Co-Authored-By: Perplexity Computer Agent
|
| 5 |
+
"""
|
| 6 |
+
szl_energy_sovereign.py — ADDITIVE Energy / Sovereign-Compute instrumentation for
|
| 7 |
+
a11oy. Makes the energy + sovereign-compute story MEASURED and HONEST.
|
| 8 |
+
|
| 9 |
+
The whole point of this module: read REAL energy / throughput / speculative-decode /
|
| 10 |
+
KV-cache / router metrics from the on-box vLLM `/metrics` (Prometheus) endpoint WHEN
|
| 11 |
+
the live sovereign-inference probe shows the GPU is reachable — and label everything
|
| 12 |
+
ROADMAP / pending when it is not. It NEVER fabricates a sovereign or energy number.
|
| 13 |
+
|
| 14 |
+
Honesty spine (doctrine v11):
|
| 15 |
+
* sovereign:true ONLY from the orchestrator's live `_sovereign_inference_state()`
|
| 16 |
+
(which itself gates on a real `_local_endpoint_reachable()` /models probe).
|
| 17 |
+
* the joules honesty label is decided ONLY by `szl_joules_truth.joules_label()` off a
|
| 18 |
+
REAL, FRESH NVML/exporter sample — never off a bare flag or a forwarded string.
|
| 19 |
+
* J/token is computed from the research formula E_token = P_GPU · T_forward / N_tokens
|
| 20 |
+
(Watt-Counts arXiv:2604.09048; Energy-per-Token arXiv:2603.20224; Where-Do-Joules-Go
|
| 21 |
+
arXiv:2601.22076) — and ONLY when the box emits power.draw + token counters. Else it
|
| 22 |
+
is left None and labeled ROADMAP. No meter -> no number.
|
| 23 |
+
|
| 24 |
+
Capability tiers (rendered with honest labels mapped to window.SZLLabels):
|
| 25 |
+
MEASURED -> a real on-box exporter sample is present & fresh (mapped to LIVE tone)
|
| 26 |
+
ROADMAP -> wiring is in place; the box is not emitting the metric yet (EXPERIMENTAL tone)
|
| 27 |
+
|
| 28 |
+
Routes (NEW; never collide):
|
| 29 |
+
GET /api/{ns}/v1/energy/sovereign — full JSON posture (machine-readable)
|
| 30 |
+
GET /api/{ns}/v1/energy/jtoken — J/token + carbon panel (MEASURED/ROADMAP)
|
| 31 |
+
GET /api/{ns}/v1/energy/throughput — speculative-decode tokens/s panel
|
| 32 |
+
GET /api/{ns}/v1/energy/kvcache — LMCache TTFT before/after panel
|
| 33 |
+
GET /api/{ns}/v1/energy/gateway — LiteLLM gateway status (honest)
|
| 34 |
+
GET /api/{ns}/v1/energy/router — RouteLLM Thompson Beta posteriors
|
| 35 |
+
GET /api/{ns}/v1/energy/carbon — Carbon-Aware batch schedule
|
| 36 |
+
GET /energy — unified mobile-first Energy/Sovereign tab
|
| 37 |
+
|
| 38 |
+
Pure stdlib + (optional) the shared szl_joules_truth. Defensive: a probe/parse failure
|
| 39 |
+
NEVER raises out of a handler — it degrades to an honest ROADMAP/pending posture.
|
| 40 |
+
"""
|
| 41 |
+
from __future__ import annotations
|
| 42 |
+
|
| 43 |
+
import json as _json
|
| 44 |
+
import math as _math
|
| 45 |
+
import os as _os
|
| 46 |
+
import random as _random
|
| 47 |
+
import time as _time
|
| 48 |
+
import urllib.request as _ureq
|
| 49 |
+
from datetime import datetime, timezone
|
| 50 |
+
|
| 51 |
+
# --- joules honesty: the SINGLE source of truth (never decide a label locally) ----
|
| 52 |
+
try:
|
| 53 |
+
from szl_joules_truth import (
|
| 54 |
+
joules_label as _joules_label,
|
| 55 |
+
joules_evidence as _joules_evidence,
|
| 56 |
+
is_real_fresh_sample as _is_real_fresh_sample,
|
| 57 |
+
)
|
| 58 |
+
except Exception: # pragma: no cover — defensive: doctrine default is always sample
|
| 59 |
+
def _joules_label(_s, now=None): # type: ignore
|
| 60 |
+
return "sample"
|
| 61 |
+
def _joules_evidence(_s, now=None): # type: ignore
|
| 62 |
+
return {}
|
| 63 |
+
def _is_real_fresh_sample(_s, now=None): # type: ignore
|
| 64 |
+
return False
|
| 65 |
+
|
| 66 |
+
DOCTRINE = {
|
| 67 |
+
"version": "v11",
|
| 68 |
+
"locked_proven": ["F1", "F4", "F7", "F11", "F12", "F18", "F19", "F22"],
|
| 69 |
+
"locked_count": 8,
|
| 70 |
+
"corpus": "749/14/163",
|
| 71 |
+
"kernel_commit": "c7c0ba17",
|
| 72 |
+
"lambda": "Conjecture 1 (advisory floor; uniqueness machine-checked FALSE unconditionally; NOT a theorem)",
|
| 73 |
+
"slsa": "L1 honest / L2 attested (.att emitted, not independently verified) / L3 roadmap",
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
# Carbon intensity for the GPU's grid region. SAMPLE/ESTIMATE default until a real
|
| 77 |
+
# Carbon-Aware SDK / WattTime / ElectricityMaps feed is wired (see FORGE_BOX_ENERGY.md).
|
| 78 |
+
# Hetzner Falkenstein (DE) ~ 380 gCO2eq/kWh annual average — labeled, not claimed live.
|
| 79 |
+
_DEFAULT_CARBON_G_PER_KWH = 380.0
|
| 80 |
+
_J_PER_KWH = 3.6e6 # 1 kWh = 3.6 MJ
|
| 81 |
+
|
| 82 |
+
# Research-cited speculative-decoding speedup model (vLLM speculative decoding):
|
| 83 |
+
# S(k, alpha) = (k + 1) / (k * (1 - alpha) + 1)
|
| 84 |
+
# k = number of draft tokens proposed per step; alpha = empirical acceptance rate.
|
| 85 |
+
_SPEC_DRAFT_MODEL = "Qwen/Qwen2.5-Coder-1.5B-Instruct"
|
| 86 |
+
_SPEC_K_DEFAULT = 4
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
def _now_iso() -> str:
|
| 90 |
+
return datetime.now(timezone.utc).isoformat()
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def _carbon_g_per_kwh() -> float:
|
| 94 |
+
"""Grid carbon intensity (gCO2eq/kWh). Env-overridable when a real feed sets it;
|
| 95 |
+
otherwise the labeled SAMPLE/ESTIMATE regional average. Never raises."""
|
| 96 |
+
try:
|
| 97 |
+
v = _os.environ.get("A11OY_GRID_CARBON_G_PER_KWH")
|
| 98 |
+
if v:
|
| 99 |
+
f = float(v)
|
| 100 |
+
if f > 0 and f == f:
|
| 101 |
+
return f
|
| 102 |
+
except Exception:
|
| 103 |
+
pass
|
| 104 |
+
return _DEFAULT_CARBON_G_PER_KWH
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def _carbon_feed_is_live() -> bool:
|
| 108 |
+
"""True ONLY when a real carbon-intensity feed is wired (env set by the box)."""
|
| 109 |
+
return bool((_os.environ.get("A11OY_GRID_CARBON_G_PER_KWH") or "").strip())
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
# ---------------------------------------------------------------------------
|
| 113 |
+
# LIVE sovereign-inference probe (delegated to the orchestrator — the authority).
|
| 114 |
+
# ---------------------------------------------------------------------------
|
| 115 |
+
def _sovereign_state() -> dict:
|
| 116 |
+
"""Authoritative, LIVE sovereign-inference posture.
|
| 117 |
+
|
| 118 |
+
Delegates to a11oy_code_orchestrator._sovereign_inference_state(), which gates
|
| 119 |
+
sovereign:true on a real _local_endpoint_reachable() /models probe. We NEVER
|
| 120 |
+
decide sovereignty here. Honest default on any failure: not sovereign.
|
| 121 |
+
"""
|
| 122 |
+
try:
|
| 123 |
+
import a11oy_code_orchestrator as _orch # type: ignore
|
| 124 |
+
st = _orch._sovereign_inference_state()
|
| 125 |
+
if isinstance(st, dict):
|
| 126 |
+
return st
|
| 127 |
+
except Exception:
|
| 128 |
+
pass
|
| 129 |
+
return {"inference": "unknown", "mode": "unknown", "backend": "unknown",
|
| 130 |
+
"sovereign": False, "base_url": None,
|
| 131 |
+
"honest_note": "orchestrator sovereign-state unavailable in-process; honest default not-sovereign."}
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def _gpu_reachable(state: dict | None = None) -> bool:
|
| 135 |
+
"""gpu_reachable == the orchestrator reports a live self-hosted GPU (sovereign)."""
|
| 136 |
+
st = state if state is not None else _sovereign_state()
|
| 137 |
+
return bool(st.get("sovereign") is True and st.get("inference") == "self-hosted-gpu")
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
def _vllm_metrics_base() -> str | None:
|
| 141 |
+
"""Base URL of the on-box vLLM server for its Prometheus /metrics endpoint.
|
| 142 |
+
|
| 143 |
+
Prefer an explicit metrics URL; else derive from the serving base. Returns None
|
| 144 |
+
when no local endpoint is configured (so we stay ROADMAP rather than guess)."""
|
| 145 |
+
explicit = (_os.environ.get("A11OY_VLLM_METRICS_URL") or "").strip()
|
| 146 |
+
if explicit:
|
| 147 |
+
return explicit.rstrip("/")
|
| 148 |
+
base = (_os.environ.get("A11OY_MODEL_BASE_URL") or "").strip().rstrip("/")
|
| 149 |
+
if base and "router.huggingface.co" not in base:
|
| 150 |
+
# vLLM exposes /metrics at the server root (strip a trailing /v1).
|
| 151 |
+
root = base[:-3] if base.endswith("/v1") else base
|
| 152 |
+
return root.rstrip("/")
|
| 153 |
+
return None
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
def _fetch_metrics_text(timeout: float = 2.5) -> str | None:
|
| 157 |
+
"""Fetch the on-box vLLM Prometheus /metrics text. None on any failure (honest)."""
|
| 158 |
+
base = _vllm_metrics_base()
|
| 159 |
+
if not base:
|
| 160 |
+
return None
|
| 161 |
+
for path in ("/metrics", ""):
|
| 162 |
+
try:
|
| 163 |
+
req = _ureq.Request(base + path, headers={"User-Agent": "szl-energy-sovereign"})
|
| 164 |
+
with _ureq.urlopen(req, timeout=timeout) as r: # noqa: S310
|
| 165 |
+
if 200 <= getattr(r, "status", 200) < 300:
|
| 166 |
+
body = r.read().decode("utf-8", "replace")
|
| 167 |
+
if "# " in body or "_total" in body:
|
| 168 |
+
return body
|
| 169 |
+
except Exception: # noqa: BLE001 — any failure => not emitting; stay honest
|
| 170 |
+
continue
|
| 171 |
+
return None
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
def _parse_prom(text: str) -> dict:
|
| 175 |
+
"""Minimal Prometheus text parser: {metric_name: float} for samples we care about.
|
| 176 |
+
|
| 177 |
+
Sums across label sets for counters (e.g. vllm:* counters carry model_name labels).
|
| 178 |
+
Best-effort and exception-tolerant; unknown lines are ignored.
|
| 179 |
+
"""
|
| 180 |
+
out: dict[str, float] = {}
|
| 181 |
+
if not text:
|
| 182 |
+
return out
|
| 183 |
+
for line in text.splitlines():
|
| 184 |
+
line = line.strip()
|
| 185 |
+
if not line or line.startswith("#"):
|
| 186 |
+
continue
|
| 187 |
+
try:
|
| 188 |
+
# name{labels} value OR name value
|
| 189 |
+
if "{" in line:
|
| 190 |
+
name = line[: line.index("{")]
|
| 191 |
+
value = line.rsplit(" ", 1)[1]
|
| 192 |
+
else:
|
| 193 |
+
name, value = line.rsplit(" ", 1)
|
| 194 |
+
v = float(value)
|
| 195 |
+
out[name] = out.get(name, 0.0) + v
|
| 196 |
+
except Exception:
|
| 197 |
+
continue
|
| 198 |
+
return out
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
def _exporter_sample_from_metrics(prom: dict) -> dict | None:
|
| 202 |
+
"""Build a szl_joules_truth exporter_sample from on-box metrics, or None.
|
| 203 |
+
|
| 204 |
+
We treat a fresh power.draw export (via a node/GPU exporter scraped INTO vLLM
|
| 205 |
+
/metrics or a sidecar) as the real NVML reading. Doctrine: only a numeric
|
| 206 |
+
joules_measured_total + a fresh exporter_last_seen_ts can yield a MEASURED label.
|
| 207 |
+
"""
|
| 208 |
+
if not prom:
|
| 209 |
+
return None
|
| 210 |
+
# Common exporter names for cumulative GPU energy (joules). Box wires one of these
|
| 211 |
+
# (nvidia-smi power.draw integrated, or DCGM energy counter). See FORGE_BOX_ENERGY.md.
|
| 212 |
+
joules_total = None
|
| 213 |
+
for key in ("a11oy_gpu_energy_joules_total", "gpu_energy_joules_total",
|
| 214 |
+
"DCGM_FI_DEV_TOTAL_ENERGY_CONSUMPTION", "nvidia_gpu_energy_joules_total"):
|
| 215 |
+
if key in prom:
|
| 216 |
+
joules_total = prom[key]
|
| 217 |
+
break
|
| 218 |
+
if joules_total is None:
|
| 219 |
+
return None
|
| 220 |
+
power_w = None
|
| 221 |
+
for key in ("a11oy_gpu_power_watts", "gpu_power_watts",
|
| 222 |
+
"DCGM_FI_DEV_POWER_USAGE", "nvidia_gpu_power_watts"):
|
| 223 |
+
if key in prom:
|
| 224 |
+
power_w = prom[key]
|
| 225 |
+
break
|
| 226 |
+
return {
|
| 227 |
+
"joules_measured_total": joules_total,
|
| 228 |
+
"exporter_node": _os.environ.get("A11OY_GPU_LABEL") or "sovereign-gpu",
|
| 229 |
+
"exporter_last_seen_ts": _time.time(), # scraped just now => fresh by construction
|
| 230 |
+
"power_w_sample": power_w,
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
# ---------------------------------------------------------------------------
|
| 235 |
+
# (#1) J/token + carbon — the Tier-1 receipt fields.
|
| 236 |
+
# ---------------------------------------------------------------------------
|
| 237 |
+
def _jtoken_from_metrics(prom: dict, sample: dict | None) -> dict:
|
| 238 |
+
"""Compute MEASURED energy-per-token from on-box counters, else honest ROADMAP.
|
| 239 |
+
|
| 240 |
+
Formula (research-cited): E_token = P_GPU · T_forward / N_tokens. We realize it as
|
| 241 |
+
cumulative_energy_joules / cumulative_generated_tokens when both counters exist —
|
| 242 |
+
equivalent to the time-integral form averaged over the window. Returned None +
|
| 243 |
+
ROADMAP when the box is not emitting the counters.
|
| 244 |
+
"""
|
| 245 |
+
measured = _is_real_fresh_sample(sample)
|
| 246 |
+
gen_tokens = None
|
| 247 |
+
for key in ("vllm:generation_tokens_total", "vllm_generation_tokens_total",
|
| 248 |
+
"vllm:generation_tokens"):
|
| 249 |
+
if key in prom:
|
| 250 |
+
gen_tokens = prom[key]
|
| 251 |
+
break
|
| 252 |
+
joules_total = (sample or {}).get("joules_measured_total")
|
| 253 |
+
j_per_token = None
|
| 254 |
+
if measured and joules_total and gen_tokens and gen_tokens > 0:
|
| 255 |
+
j_per_token = float(joules_total) / float(gen_tokens)
|
| 256 |
+
label = "MEASURED" if (measured and j_per_token is not None) else "ROADMAP"
|
| 257 |
+
carbon_g_per_token = None
|
| 258 |
+
if j_per_token is not None:
|
| 259 |
+
carbon_g_per_token = (j_per_token / _J_PER_KWH) * _carbon_g_per_kwh()
|
| 260 |
+
return {
|
| 261 |
+
"metric": "energy_per_token",
|
| 262 |
+
"label": label,
|
| 263 |
+
"joules_per_token": (round(j_per_token, 6) if j_per_token is not None else None),
|
| 264 |
+
"carbon_g_co2eq_per_token": (round(carbon_g_per_token, 9)
|
| 265 |
+
if carbon_g_per_token is not None else None),
|
| 266 |
+
"generated_tokens_total": gen_tokens,
|
| 267 |
+
"gpu_energy_joules_total": joules_total,
|
| 268 |
+
"power_w_sample": (sample or {}).get("power_w_sample"),
|
| 269 |
+
"carbon_g_per_kwh": _carbon_g_per_kwh(),
|
| 270 |
+
"carbon_feed_live": _carbon_feed_is_live(),
|
| 271 |
+
"formula": "E_token = P_GPU · T_forward / N_tokens (= ΣJ / Σgenerated_tokens over window)",
|
| 272 |
+
"citations": ["Watt-Counts arXiv:2604.09048", "Energy-per-Token arXiv:2603.20224",
|
| 273 |
+
"Where-Do-Joules-Go arXiv:2601.22076"],
|
| 274 |
+
"joules_honesty": _joules_label(sample),
|
| 275 |
+
"joules_evidence": _joules_evidence(sample),
|
| 276 |
+
"note": ("Real per-token energy from the on-box GPU exporter + vLLM token counters."
|
| 277 |
+
if label == "MEASURED" else
|
| 278 |
+
"Wiring is ready: when the box emits power.draw→/metrics + token counters, "
|
| 279 |
+
"J/token and carbon become MEASURED. Until then, honestly pending (no meter, no number)."),
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
def energy_fields_for_receipt() -> dict:
|
| 284 |
+
"""SPLICE-INTO-RECEIPT helper for the orchestrator's _emit_turn_receipt().
|
| 285 |
+
|
| 286 |
+
Returns joules_consumed + carbon_g_co2eq for EVERY signed turn receipt, honestly
|
| 287 |
+
labeled MEASURED (real fresh on-box exporter) or ROADMAP (no meter yet → None).
|
| 288 |
+
NEVER raises and NEVER fabricates a number. The orchestrator splats this into the
|
| 289 |
+
receipt body so the joules claim is self-verifying from the receipt itself.
|
| 290 |
+
"""
|
| 291 |
+
try:
|
| 292 |
+
state = _sovereign_state()
|
| 293 |
+
if not _gpu_reachable(state):
|
| 294 |
+
return {
|
| 295 |
+
"joules_consumed": None,
|
| 296 |
+
"carbon_g_co2eq": None,
|
| 297 |
+
"energy_label": "ROADMAP",
|
| 298 |
+
"joules_honesty": _joules_label(None),
|
| 299 |
+
"energy_source_note": ("No sovereign GPU reachable (sovereign:%s). Per-receipt "
|
| 300 |
+
"joules/carbon are pending the on-box NVML exporter — "
|
| 301 |
+
"honest ROADMAP, never fabricated." % state.get("sovereign")),
|
| 302 |
+
}
|
| 303 |
+
prom = _parse_prom(_fetch_metrics_text() or "")
|
| 304 |
+
sample = _exporter_sample_from_metrics(prom)
|
| 305 |
+
jt = _jtoken_from_metrics(prom, sample)
|
| 306 |
+
gen_tokens = jt.get("generated_tokens_total")
|
| 307 |
+
jpt = jt.get("joules_per_token")
|
| 308 |
+
# Per-receipt instantaneous reading: total measured joules is the honest figure;
|
| 309 |
+
# per-token rate is the MEASURED derivation. We report the fresh cumulative joules
|
| 310 |
+
# as joules_consumed only when MEASURED; else None (ROADMAP).
|
| 311 |
+
measured = jt.get("label") == "MEASURED"
|
| 312 |
+
joules_consumed = (sample or {}).get("joules_measured_total") if measured else None
|
| 313 |
+
carbon = None
|
| 314 |
+
if measured and joules_consumed is not None:
|
| 315 |
+
carbon = (float(joules_consumed) / _J_PER_KWH) * _carbon_g_per_kwh()
|
| 316 |
+
return {
|
| 317 |
+
"joules_consumed": (round(float(joules_consumed), 6)
|
| 318 |
+
if joules_consumed is not None else None),
|
| 319 |
+
"carbon_g_co2eq": (round(carbon, 9) if carbon is not None else None),
|
| 320 |
+
"joules_per_token": jpt,
|
| 321 |
+
"carbon_g_co2eq_per_token": jt.get("carbon_g_co2eq_per_token"),
|
| 322 |
+
"energy_label": "MEASURED" if measured else "ROADMAP",
|
| 323 |
+
"joules_honesty": _joules_label(sample),
|
| 324 |
+
"joules_evidence": _joules_evidence(sample),
|
| 325 |
+
"carbon_g_per_kwh": _carbon_g_per_kwh(),
|
| 326 |
+
"carbon_feed_live": _carbon_feed_is_live(),
|
| 327 |
+
"energy_source_note": ("Per-token energy + carbon MEASURED from on-box GPU exporter."
|
| 328 |
+
if measured else
|
| 329 |
+
"Sovereign GPU reachable but power/token exporter not emitting "
|
| 330 |
+
"yet → joules/carbon honestly ROADMAP (never fabricated)."),
|
| 331 |
+
}
|
| 332 |
+
except Exception as exc: # noqa: BLE001 — a receipt helper must NEVER raise
|
| 333 |
+
return {
|
| 334 |
+
"joules_consumed": None,
|
| 335 |
+
"carbon_g_co2eq": None,
|
| 336 |
+
"energy_label": "ROADMAP",
|
| 337 |
+
"joules_honesty": "sample",
|
| 338 |
+
"energy_source_note": "energy_fields_for_receipt fail-open: %s" % (str(exc)[:120],),
|
| 339 |
+
}
|
| 340 |
+
|
| 341 |
+
|
| 342 |
+
# ---------------------------------------------------------------------------
|
| 343 |
+
# (#2) Speculative decoding throughput panel (tokens/s with-vs-without).
|
| 344 |
+
# ---------------------------------------------------------------------------
|
| 345 |
+
def _spec_speedup(k: int, alpha: float) -> float:
|
| 346 |
+
"""vLLM speculative-decoding speedup model S = (k+1)/(k(1-alpha)+1)."""
|
| 347 |
+
denom = (k * (1.0 - alpha)) + 1.0
|
| 348 |
+
return (k + 1.0) / denom if denom > 0 else 1.0
|
| 349 |
+
|
| 350 |
+
|
| 351 |
+
def _throughput_panel(prom: dict, gpu_reachable: bool) -> dict:
|
| 352 |
+
"""tokens/s with-vs-without speculative decoding.
|
| 353 |
+
|
| 354 |
+
MEASURED tokens/s when vLLM emits generation tokens + an accept-rate counter;
|
| 355 |
+
else ROADMAP with the theoretical speedup model (k=4, draft Qwen2.5-Coder-1.5B)
|
| 356 |
+
shown ILLUSTRATIVELY so the panel is never blank but never overclaims.
|
| 357 |
+
"""
|
| 358 |
+
tps = None
|
| 359 |
+
for key in ("vllm:avg_generation_throughput_toks_per_s",
|
| 360 |
+
"vllm_avg_generation_throughput_toks_per_s",
|
| 361 |
+
"vllm:generation_tokens_per_second"):
|
| 362 |
+
if key in prom:
|
| 363 |
+
tps = prom[key]
|
| 364 |
+
break
|
| 365 |
+
# Empirical acceptance rate alpha from vLLM spec-decode counters when present.
|
| 366 |
+
accepted = prom.get("vllm:spec_decode_num_accepted_tokens_total")
|
| 367 |
+
drafted = prom.get("vllm:spec_decode_num_draft_tokens_total")
|
| 368 |
+
alpha = None
|
| 369 |
+
if accepted is not None and drafted and drafted > 0:
|
| 370 |
+
alpha = max(0.0, min(1.0, accepted / drafted))
|
| 371 |
+
measured = bool(gpu_reachable and tps is not None and alpha is not None)
|
| 372 |
+
k = _SPEC_K_DEFAULT
|
| 373 |
+
# Theoretical curve for the panel (ILLUSTRATIVE unless alpha is measured).
|
| 374 |
+
alpha_for_model = alpha if alpha is not None else 0.8
|
| 375 |
+
speedup = _spec_speedup(k, alpha_for_model)
|
| 376 |
+
tps_without = (tps / speedup) if (measured and speedup > 0) else None
|
| 377 |
+
return {
|
| 378 |
+
"metric": "speculative_decode_throughput",
|
| 379 |
+
"label": "MEASURED" if measured else "ROADMAP",
|
| 380 |
+
"draft_model": _SPEC_DRAFT_MODEL,
|
| 381 |
+
"num_speculative_tokens_k": k,
|
| 382 |
+
"acceptance_rate_alpha": (round(alpha, 4) if alpha is not None else None),
|
| 383 |
+
"acceptance_rate_alpha_label": ("MEASURED" if alpha is not None else "ILLUSTRATIVE (α=0.8 assumed)"),
|
| 384 |
+
"tokens_per_s_with_spec": (round(tps, 3) if tps is not None else None),
|
| 385 |
+
"tokens_per_s_without_spec": (round(tps_without, 3) if tps_without is not None else None),
|
| 386 |
+
"modeled_speedup_x": round(speedup, 3),
|
| 387 |
+
"speedup_formula": "S = (k+1) / (k·(1−α)+1)",
|
| 388 |
+
"note": ("Real tokens/s + empirical α from the on-box vLLM speculative-decode counters."
|
| 389 |
+
if measured else
|
| 390 |
+
"Wiring ready: with --speculative-model %s --num-speculative-tokens %d the box emits "
|
| 391 |
+
"tokens/s + α. Until then the speedup curve is ILLUSTRATIVE (α=0.8 → ~%.2f×)."
|
| 392 |
+
% (_SPEC_DRAFT_MODEL, k, speedup)),
|
| 393 |
+
"citations": ["vLLM speculative decoding", "Watt-Counts arXiv:2604.09048"],
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
# ---------------------------------------------------------------------------
|
| 398 |
+
# (#3) LMCache KV-cache TTFT before/after panel.
|
| 399 |
+
# ---------------------------------------------------------------------------
|
| 400 |
+
def _kvcache_panel(prom: dict, gpu_reachable: bool) -> dict:
|
| 401 |
+
"""TTFT before/after KV-cache reuse on repeated prompt prefixes (LMCache)."""
|
| 402 |
+
hit = None
|
| 403 |
+
for key in ("vllm:prefix_cache_hits_total", "lmcache_cache_hits_total",
|
| 404 |
+
"vllm:gpu_prefix_cache_hits_total"):
|
| 405 |
+
if key in prom:
|
| 406 |
+
hit = prom[key]
|
| 407 |
+
break
|
| 408 |
+
queries = None
|
| 409 |
+
for key in ("vllm:prefix_cache_queries_total", "lmcache_cache_queries_total",
|
| 410 |
+
"vllm:gpu_prefix_cache_queries_total"):
|
| 411 |
+
if key in prom:
|
| 412 |
+
queries = prom[key]
|
| 413 |
+
break
|
| 414 |
+
ttft = None
|
| 415 |
+
for key in ("vllm:time_to_first_token_seconds_sum", "vllm_time_to_first_token_seconds_sum"):
|
| 416 |
+
if key in prom:
|
| 417 |
+
ttft = prom[key]
|
| 418 |
+
break
|
| 419 |
+
hit_rate = (hit / queries) if (hit is not None and queries and queries > 0) else None
|
| 420 |
+
measured = bool(gpu_reachable and hit_rate is not None and ttft is not None)
|
| 421 |
+
return {
|
| 422 |
+
"metric": "kv_cache_ttft",
|
| 423 |
+
"label": "MEASURED" if measured else "ROADMAP",
|
| 424 |
+
"backend": "LMCache (KV-cache offload: GPU→CPU/disk)",
|
| 425 |
+
"prefix_cache_hit_rate": (round(hit_rate, 4) if hit_rate is not None else None),
|
| 426 |
+
"ttft_seconds_sum": ttft,
|
| 427 |
+
"ttft_before_after_note": ("Cold prompt = full prefill TTFT; warm repeat prefix = "
|
| 428 |
+
"KV reuse → lower TTFT. Real delta from on-box counters."
|
| 429 |
+
if measured else
|
| 430 |
+
"Wiring ready: LMCache + vLLM prefix-cache counters give the real "
|
| 431 |
+
"TTFT before/after delta on repeated prefixes once the box emits them."),
|
| 432 |
+
"citations": ["LMCache github.com/LMCache/LMCache"],
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
|
| 436 |
+
# ---------------------------------------------------------------------------
|
| 437 |
+
# (#4) LiteLLM gateway status (unified endpoint, budget, cloud fallback).
|
| 438 |
+
# ---------------------------------------------------------------------------
|
| 439 |
+
def _gateway_panel(state: dict) -> dict:
|
| 440 |
+
"""Honest LiteLLM unified-gateway status.
|
| 441 |
+
|
| 442 |
+
LIVE only when A11OY_LITELLM_BASE_URL is set AND answers; else ROADMAP. The
|
| 443 |
+
gateway fronts Ollama/vLLM with budget enforcement + cloud fallback on GPU OOM.
|
| 444 |
+
"""
|
| 445 |
+
base = (_os.environ.get("A11OY_LITELLM_BASE_URL") or "").strip().rstrip("/")
|
| 446 |
+
reachable = False
|
| 447 |
+
if base:
|
| 448 |
+
for path in ("/health", "/v1/models", ""):
|
| 449 |
+
try:
|
| 450 |
+
req = _ureq.Request(base + path, headers={"User-Agent": "szl-energy-sovereign"})
|
| 451 |
+
with _ureq.urlopen(req, timeout=2.0) as r: # noqa: S310
|
| 452 |
+
if 200 <= getattr(r, "status", 200) < 500:
|
| 453 |
+
reachable = True
|
| 454 |
+
break
|
| 455 |
+
except Exception:
|
| 456 |
+
continue
|
| 457 |
+
measured = bool(base and reachable)
|
| 458 |
+
budget = (_os.environ.get("A11OY_LITELLM_BUDGET_USD") or "").strip()
|
| 459 |
+
return {
|
| 460 |
+
"metric": "litellm_gateway",
|
| 461 |
+
"label": "MEASURED" if measured else "ROADMAP",
|
| 462 |
+
"gateway": "LiteLLM (OpenAI-compatible proxy over Ollama + vLLM)",
|
| 463 |
+
"base_url_configured": bool(base),
|
| 464 |
+
"reachable": reachable,
|
| 465 |
+
"budget_usd_configured": budget or None,
|
| 466 |
+
"cloud_fallback": "on GPU OOM / 5xx → HF Router (honest fallback, logged)",
|
| 467 |
+
"note": ("Unified gateway live: budget enforced, cloud fallback armed."
|
| 468 |
+
if measured else
|
| 469 |
+
"Wiring ready: set A11OY_LITELLM_BASE_URL to the on-box LiteLLM proxy. Until then "
|
| 470 |
+
"the orchestrator serves direct (sovereign-gated) and the gateway is honestly ROADMAP."),
|
| 471 |
+
"citations": ["LiteLLM github.com/BerriAI/litellm"],
|
| 472 |
+
}
|
| 473 |
+
|
| 474 |
+
|
| 475 |
+
# ---------------------------------------------------------------------------
|
| 476 |
+
# (#5) RouteLLM Thompson-sampling router — Beta posteriors per model.
|
| 477 |
+
# ---------------------------------------------------------------------------
|
| 478 |
+
# Per-model Beta(α, β) posteriors. α = #successful (accepted) routes, β = #failures.
|
| 479 |
+
# Doctrine: these are HONEST in-memory observations. With no real routing traffic yet
|
| 480 |
+
# the posteriors are the priors Beta(1,1) (uniform) — labeled ROADMAP, never faked.
|
| 481 |
+
_ROUTER_MODELS = {
|
| 482 |
+
"local-7b": {"alpha": 1.0, "beta": 1.0, "tier": "easy→local", "model": "qwen2.5-coder:7b"},
|
| 483 |
+
"cloud-32b": {"alpha": 1.0, "beta": 1.0, "tier": "hard→cloud/32B", "model": "Qwen/Qwen2.5-Coder-32B-Instruct"},
|
| 484 |
+
}
|
| 485 |
+
_ROUTER_OBS = 0 # number of real routing observations recorded (0 => priors only)
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
def record_route_outcome(model_key: str, success: bool) -> None:
|
| 489 |
+
"""Record a real routing outcome into the Beta posterior (α=success, β=failure).
|
| 490 |
+
|
| 491 |
+
Called by the router when a route resolves. Pure in-memory, monotone, never raises.
|
| 492 |
+
Until real traffic calls this, posteriors stay at the Beta(1,1) prior (ROADMAP).
|
| 493 |
+
"""
|
| 494 |
+
global _ROUTER_OBS
|
| 495 |
+
try:
|
| 496 |
+
m = _ROUTER_MODELS.get(model_key)
|
| 497 |
+
if m is None:
|
| 498 |
+
return
|
| 499 |
+
if success:
|
| 500 |
+
m["alpha"] += 1.0
|
| 501 |
+
else:
|
| 502 |
+
m["beta"] += 1.0
|
| 503 |
+
_ROUTER_OBS += 1
|
| 504 |
+
except Exception:
|
| 505 |
+
pass
|
| 506 |
+
|
| 507 |
+
|
| 508 |
+
def _thompson_sample(alpha: float, beta: float) -> float:
|
| 509 |
+
"""Sample θ ~ Beta(α, β) (stdlib random.betavariate). Used for argmax selection."""
|
| 510 |
+
try:
|
| 511 |
+
return _random.betavariate(max(alpha, 1e-6), max(beta, 1e-6))
|
| 512 |
+
except Exception:
|
| 513 |
+
return alpha / (alpha + beta) if (alpha + beta) > 0 else 0.5
|
| 514 |
+
|
| 515 |
+
|
| 516 |
+
def _router_panel() -> dict:
|
| 517 |
+
"""RouteLLM Thompson-sampling router posteriors per model (Beta), honestly labeled."""
|
| 518 |
+
measured = _ROUTER_OBS > 0
|
| 519 |
+
models = []
|
| 520 |
+
samples = {}
|
| 521 |
+
for key, m in _ROUTER_MODELS.items():
|
| 522 |
+
a, b = m["alpha"], m["beta"]
|
| 523 |
+
mean = a / (a + b)
|
| 524 |
+
theta = _thompson_sample(a, b)
|
| 525 |
+
samples[key] = theta
|
| 526 |
+
models.append({
|
| 527 |
+
"model_key": key, "model": m["model"], "route_tier": m["tier"],
|
| 528 |
+
"beta_alpha_successes": a, "beta_beta_failures": b,
|
| 529 |
+
"posterior_mean": round(mean, 4),
|
| 530 |
+
"thompson_sample_theta": round(theta, 4),
|
| 531 |
+
"n_observations": int(a + b - 2), # minus the Beta(1,1) prior
|
| 532 |
+
})
|
| 533 |
+
chosen = max(samples, key=samples.get) if samples else None
|
| 534 |
+
return {
|
| 535 |
+
"metric": "routellm_thompson",
|
| 536 |
+
"label": "MEASURED" if measured else "ROADMAP",
|
| 537 |
+
"policy": "Thompson sampling over per-model Beta posteriors; argmax θ wins the route",
|
| 538 |
+
"models": models,
|
| 539 |
+
"thompson_choice_this_draw": chosen,
|
| 540 |
+
"total_observations": _ROUTER_OBS,
|
| 541 |
+
"note": ("Posteriors updated from real routing outcomes (α=accepted, β=failed)."
|
| 542 |
+
if measured else
|
| 543 |
+
"Wiring ready: record_route_outcome() updates Beta(α,β) per model on every route. "
|
| 544 |
+
"With no live traffic yet the posteriors are the Beta(1,1) uniform prior — honest ROADMAP."),
|
| 545 |
+
"citations": ["RouteLLM github.com/lm-sys/routellm",
|
| 546 |
+
"Thompson sampling: sample θ_k~Beta(α_k,β_k), pick argmax"],
|
| 547 |
+
}
|
| 548 |
+
|
| 549 |
+
|
| 550 |
+
# ---------------------------------------------------------------------------
|
| 551 |
+
# (#6) Carbon-Aware SDK batch scheduling — low-carbon windows.
|
| 552 |
+
# ---------------------------------------------------------------------------
|
| 553 |
+
def _carbon_panel() -> dict:
|
| 554 |
+
"""Carbon-aware batch schedule: shift non-urgent inference to low-carbon windows.
|
| 555 |
+
|
| 556 |
+
LIVE forecast only when a real carbon feed is wired; otherwise a labeled SAMPLE
|
| 557 |
+
diurnal curve (low overnight / midday solar; high evening peak) so the schedule
|
| 558 |
+
is illustrative-but-honest. carbon_g_co2eq per job is computed from the same J/token.
|
| 559 |
+
"""
|
| 560 |
+
live = _carbon_feed_is_live()
|
| 561 |
+
g_per_kwh = _carbon_g_per_kwh()
|
| 562 |
+
# 24h relative intensity curve (SAMPLE shape unless a real feed overrides).
|
| 563 |
+
base = [0.55, 0.50, 0.48, 0.47, 0.50, 0.58, 0.72, 0.85, 0.80, 0.70, 0.60, 0.55,
|
| 564 |
+
0.52, 0.55, 0.62, 0.72, 0.85, 0.95, 1.00, 0.95, 0.85, 0.75, 0.68, 0.60]
|
| 565 |
+
windows = [{"hour_utc": h, "rel_intensity": base[h],
|
| 566 |
+
"g_co2eq_per_kwh_est": round(g_per_kwh * base[h], 2)} for h in range(24)]
|
| 567 |
+
low = sorted(range(24), key=lambda h: base[h])[:3]
|
| 568 |
+
return {
|
| 569 |
+
"metric": "carbon_aware_schedule",
|
| 570 |
+
"label": "MEASURED" if live else "ROADMAP",
|
| 571 |
+
"scheduler": "Carbon-Aware SDK — shift non-urgent batch inference to low-carbon windows",
|
| 572 |
+
"carbon_feed_live": live,
|
| 573 |
+
"carbon_g_per_kwh_now": g_per_kwh,
|
| 574 |
+
"carbon_intensity_label": ("LIVE" if live else "SAMPLE (regional diurnal curve)"),
|
| 575 |
+
"low_carbon_windows_utc": sorted(low),
|
| 576 |
+
"schedule_24h": windows,
|
| 577 |
+
"note": ("Live grid carbon feed wired: batch jobs deferred to the greenest window."
|
| 578 |
+
if live else
|
| 579 |
+
"Wiring ready: with the Carbon-Aware SDK feed the schedule becomes a LIVE forecast. "
|
| 580 |
+
"Until then the diurnal curve is SAMPLE and per-job carbon_g_co2eq is ESTIMATE."),
|
| 581 |
+
"citations": ["Carbon-Aware SDK github.com/Green-Software-Foundation/carbon-aware-sdk"],
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
|
| 585 |
+
# ---------------------------------------------------------------------------
|
| 586 |
+
# Full posture (machine-readable) — composes every panel honestly.
|
| 587 |
+
# ---------------------------------------------------------------------------
|
| 588 |
+
def _posture() -> dict:
|
| 589 |
+
state = _sovereign_state()
|
| 590 |
+
reachable = _gpu_reachable(state)
|
| 591 |
+
prom = _parse_prom(_fetch_metrics_text() or "") if reachable else {}
|
| 592 |
+
sample = _exporter_sample_from_metrics(prom) if reachable else None
|
| 593 |
+
jtoken = _jtoken_from_metrics(prom, sample)
|
| 594 |
+
panels = {
|
| 595 |
+
"jtoken": jtoken,
|
| 596 |
+
"throughput": _throughput_panel(prom, reachable),
|
| 597 |
+
"kvcache": _kvcache_panel(prom, reachable),
|
| 598 |
+
"gateway": _gateway_panel(state),
|
| 599 |
+
"router": _router_panel(),
|
| 600 |
+
"carbon": _carbon_panel(),
|
| 601 |
+
}
|
| 602 |
+
measured_count = sum(1 for p in panels.values() if p.get("label") == "MEASURED")
|
| 603 |
+
summary = ("SOVEREIGN ENERGY LIVE (%d/%d MEASURED)" % (measured_count, len(panels))
|
| 604 |
+
if reachable and measured_count else
|
| 605 |
+
"WIRED — pending sovereign GPU metrics (honest ROADMAP)")
|
| 606 |
+
return {
|
| 607 |
+
"service": "energy-sovereign",
|
| 608 |
+
"doctrine": DOCTRINE["version"],
|
| 609 |
+
"summary": summary,
|
| 610 |
+
"sovereign": bool(state.get("sovereign")),
|
| 611 |
+
"gpu_reachable": reachable,
|
| 612 |
+
"inference_state": state,
|
| 613 |
+
"measured_panels": measured_count,
|
| 614 |
+
"total_panels": len(panels),
|
| 615 |
+
"panels": panels,
|
| 616 |
+
"doctrine_lock": DOCTRINE,
|
| 617 |
+
"honesty": ("Every panel reads live from the on-box vLLM /metrics ONLY when the live "
|
| 618 |
+
"sovereign probe shows gpu_reachable; otherwise it is honestly labeled ROADMAP. "
|
| 619 |
+
"The joules label is decided solely by szl_joules_truth off a real fresh exporter "
|
| 620 |
+
"sample — never off a flag. No meter → no number."),
|
| 621 |
+
"computed_at": _now_iso(),
|
| 622 |
+
}
|
| 623 |
+
|
| 624 |
+
|
| 625 |
+
# ---------------------------------------------------------------------------
|
| 626 |
+
# Unified Energy / Sovereign Compute HTML tab (0 CDN; window.SZLLabels).
|
| 627 |
+
# ---------------------------------------------------------------------------
|
| 628 |
+
def _html(p: dict) -> str:
|
| 629 |
+
panels = p["panels"]
|
| 630 |
+
|
| 631 |
+
def row(left: str, right: str) -> str:
|
| 632 |
+
return ('<div class="kv"><span class="k">%s</span><span class="v">%s</span></div>'
|
| 633 |
+
% (left, right))
|
| 634 |
+
|
| 635 |
+
def fmt(v):
|
| 636 |
+
return "—" if v is None else (str(v))
|
| 637 |
+
|
| 638 |
+
jt = panels["jtoken"]
|
| 639 |
+
tp = panels["throughput"]
|
| 640 |
+
kv = panels["kvcache"]
|
| 641 |
+
gw = panels["gateway"]
|
| 642 |
+
rt = panels["router"]
|
| 643 |
+
ca = panels["carbon"]
|
| 644 |
+
|
| 645 |
+
# Each card carries a data-szl-label so the inline script renders the honest pill
|
| 646 |
+
# via window.SZLLabels.badgeHTML (MEASURED→LIVE tone; ROADMAP→EXPERIMENTAL tone).
|
| 647 |
+
def card(title: str, label: str, body: str, note: str) -> str:
|
| 648 |
+
return ('<article class="card" data-szl="%s"><div class="row"><h3>%s</h3>'
|
| 649 |
+
'<span class="pill-slot" data-label="%s"></span></div>%s'
|
| 650 |
+
'<p class="note">%s</p></article>'
|
| 651 |
+
% (title, title, label, body, note))
|
| 652 |
+
|
| 653 |
+
jt_body = (row("J / token", fmt(jt["joules_per_token"]))
|
| 654 |
+
+ row("gCO₂eq / token", fmt(jt["carbon_g_co2eq_per_token"]))
|
| 655 |
+
+ row("GPU energy (J, cum.)", fmt(jt["gpu_energy_joules_total"]))
|
| 656 |
+
+ row("generated tokens", fmt(jt["generated_tokens_total"]))
|
| 657 |
+
+ row("carbon (gCO₂eq/kWh)", fmt(jt["carbon_g_per_kwh"]))
|
| 658 |
+
+ row("joules honesty", fmt(jt["joules_honesty"])))
|
| 659 |
+
tp_body = (row("tokens/s WITH spec", fmt(tp["tokens_per_s_with_spec"]))
|
| 660 |
+
+ row("tokens/s WITHOUT", fmt(tp["tokens_per_s_without_spec"]))
|
| 661 |
+
+ row("acceptance rate α", "%s <small>(%s)</small>" % (fmt(tp["acceptance_rate_alpha"]), tp["acceptance_rate_alpha_label"]))
|
| 662 |
+
+ row("modeled speedup", "%s×" % fmt(tp["modeled_speedup_x"]))
|
| 663 |
+
+ row("draft model", "<code>%s</code>" % tp["draft_model"]))
|
| 664 |
+
kv_body = (row("prefix cache hit-rate", fmt(kv["prefix_cache_hit_rate"]))
|
| 665 |
+
+ row("TTFT Σ (s)", fmt(kv["ttft_seconds_sum"]))
|
| 666 |
+
+ row("backend", kv["backend"]))
|
| 667 |
+
gw_body = (row("gateway", "LiteLLM proxy")
|
| 668 |
+
+ row("base configured", fmt(gw["base_url_configured"]))
|
| 669 |
+
+ row("reachable", fmt(gw["reachable"]))
|
| 670 |
+
+ row("budget (USD)", fmt(gw["budget_usd_configured"]))
|
| 671 |
+
+ row("cloud fallback", gw["cloud_fallback"]))
|
| 672 |
+
rt_rows = "".join(
|
| 673 |
+
row("%s (%s)" % (m["model_key"], m["route_tier"]),
|
| 674 |
+
"Beta(α=%s, β=%s) μ=%s θ=%s" % (m["beta_alpha_successes"], m["beta_beta_failures"],
|
| 675 |
+
m["posterior_mean"], m["thompson_sample_theta"]))
|
| 676 |
+
for m in rt["models"])
|
| 677 |
+
rt_body = rt_rows + row("Thompson choice", fmt(rt["thompson_choice_this_draw"])) + row("observations", fmt(rt["total_observations"]))
|
| 678 |
+
ca_low = ", ".join("%02d:00" % h for h in ca["low_carbon_windows_utc"])
|
| 679 |
+
ca_body = (row("carbon now (gCO₂eq/kWh)", fmt(ca["carbon_g_per_kwh_now"]))
|
| 680 |
+
+ row("intensity feed", ca["carbon_intensity_label"])
|
| 681 |
+
+ row("low-carbon windows (UTC)", ca_low)
|
| 682 |
+
+ row("scheduler", "Carbon-Aware SDK"))
|
| 683 |
+
|
| 684 |
+
cards = "".join([
|
| 685 |
+
card("J/token + Carbon", jt["label"], jt_body, jt["note"]),
|
| 686 |
+
card("Speculative Decoding", tp["label"], tp_body, tp["note"]),
|
| 687 |
+
card("KV-Cache TTFT (LMCache)", kv["label"], kv_body, kv["ttft_before_after_note"]),
|
| 688 |
+
card("LiteLLM Gateway", gw["label"], gw_body, gw["note"]),
|
| 689 |
+
card("RouteLLM Router (Thompson)", rt["label"], rt_body, rt["note"]),
|
| 690 |
+
card("Carbon-Aware Schedule", ca["label"], ca_body, ca["note"]),
|
| 691 |
+
])
|
| 692 |
+
d = p["doctrine_lock"]
|
| 693 |
+
st = p["inference_state"]
|
| 694 |
+
# NOTE: window.SZLLabels has no native MEASURED/ROADMAP keys, so we map
|
| 695 |
+
# MEASURED→LIVE (ok tone) and ROADMAP→EXPERIMENTAL (warn tone) with a label override.
|
| 696 |
+
return """<!doctype html>
|
| 697 |
+
<html lang="en"><head><meta charset="utf-8">
|
| 698 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
| 699 |
+
<meta name="theme-color" content="#0a0e14"><title>Energy / Sovereign Compute — a11oy</title>
|
| 700 |
+
<style>
|
| 701 |
+
:root{color-scheme:dark} *{box-sizing:border-box}
|
| 702 |
+
body{margin:0;background:#0a0e14;color:#e6edf3;font:16px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
|
| 703 |
+
padding:max(16px,env(safe-area-inset-top)) 16px calc(24px + env(safe-area-inset-bottom))}
|
| 704 |
+
header{max-width:980px;margin:0 auto 18px}
|
| 705 |
+
h1{font-size:clamp(1.4rem,5vw,2rem);margin:0 0 6px}
|
| 706 |
+
.summary{font-weight:700;font-size:1.05rem;color:#42d392;margin:0 0 4px}
|
| 707 |
+
.sub{color:#9aa7b4;font-size:.85rem;margin:.2rem 0}
|
| 708 |
+
.state{font-family:ui-monospace,monospace;font-size:.76rem;color:#6b7785;word-break:break-word}
|
| 709 |
+
.grid{max-width:980px;margin:0 auto;display:grid;gap:14px;grid-template-columns:1fr}
|
| 710 |
+
@media(min-width:720px){.grid{grid-template-columns:1fr 1fr}}
|
| 711 |
+
.card{background:#111722;border:1px solid #1e2a3a;border-radius:14px;padding:15px}
|
| 712 |
+
.row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px}
|
| 713 |
+
h3{font-size:1rem;margin:0}
|
| 714 |
+
.kv{display:flex;justify-content:space-between;gap:12px;font-size:.84rem;padding:3px 0;border-bottom:1px solid #18222e}
|
| 715 |
+
.kv .k{color:#9aa7b4} .kv .v{color:#e6edf3;font-family:ui-monospace,monospace;text-align:right;word-break:break-word}
|
| 716 |
+
.kv .v code{font-size:.78rem;color:#9fd0ff} .kv .v small{color:#6b7785}
|
| 717 |
+
.note{color:#c4cdd6;font-size:.8rem;margin:10px 0 0}
|
| 718 |
+
footer{max-width:980px;margin:22px auto 0;color:#6b7785;font-size:.76rem}
|
| 719 |
+
.lock{font-family:ui-monospace,monospace;color:#9aa7b4}
|
| 720 |
+
</style></head><body>
|
| 721 |
+
<header>
|
| 722 |
+
<h1>Energy / Sovereign Compute</h1>
|
| 723 |
+
<p class="summary">__SUMMARY__</p>
|
| 724 |
+
<p class="sub">Each tile is read LIVE from the on-box vLLM <code>/metrics</code> when the sovereign GPU probe is reachable, else honestly labeled <b>ROADMAP</b>. No meter → no number.</p>
|
| 725 |
+
<p class="state">inference=__INF__ · sovereign=__SOV__ · gpu_reachable=__REACH__ · measured=__MC__/__TC__</p>
|
| 726 |
+
</header>
|
| 727 |
+
<main class="grid">__CARDS__</main>
|
| 728 |
+
<footer>
|
| 729 |
+
<p class="lock">Doctrine __DV__ LOCKED · locked-proven=__LC__ {__LP__} · __CORPUS__ @ __KC__ · Λ = Conjecture 1 (NOT a theorem) · __SLSA__</p>
|
| 730 |
+
<p>MEASURED = real on-box exporter sample (live) · ROADMAP = wiring ready, box not emitting yet (never faked). Sources: Watt-Counts arXiv:2604.09048 · Energy-per-Token arXiv:2603.20224 · vLLM spec-decode · LMCache · LiteLLM · RouteLLM · Carbon-Aware SDK.</p>
|
| 731 |
+
</footer>
|
| 732 |
+
<script src="/static/shared/szl_label_engine.js"></script>
|
| 733 |
+
<script>
|
| 734 |
+
(function(){
|
| 735 |
+
function pill(label){
|
| 736 |
+
var key = (label === "MEASURED") ? "LIVE" : "EXPERIMENTAL";
|
| 737 |
+
if (window.SZLLabels && window.SZLLabels.badgeHTML){
|
| 738 |
+
return window.SZLLabels.badgeHTML(key, {label: label,
|
| 739 |
+
title: (label === "MEASURED")
|
| 740 |
+
? "Real on-box exporter sample — live and honest."
|
| 741 |
+
: "Wiring ready; the box is not emitting this metric yet. ROADMAP, never faked."});
|
| 742 |
+
}
|
| 743 |
+
return '<span>' + label + '</span>';
|
| 744 |
+
}
|
| 745 |
+
if (window.SZLLabels && window.SZLLabels.ensureStyle){ window.SZLLabels.ensureStyle(document); }
|
| 746 |
+
var slots = document.querySelectorAll('.pill-slot');
|
| 747 |
+
for (var i=0;i<slots.length;i++){ slots[i].innerHTML = pill(slots[i].getAttribute('data-label')); }
|
| 748 |
+
})();
|
| 749 |
+
</script>
|
| 750 |
+
</body></html>""".replace("__SUMMARY__", p["summary"]) \
|
| 751 |
+
.replace("__INF__", str(st.get("inference"))) \
|
| 752 |
+
.replace("__SOV__", str(p["sovereign"])) \
|
| 753 |
+
.replace("__REACH__", str(p["gpu_reachable"])) \
|
| 754 |
+
.replace("__MC__", str(p["measured_panels"])) \
|
| 755 |
+
.replace("__TC__", str(p["total_panels"])) \
|
| 756 |
+
.replace("__CARDS__", cards) \
|
| 757 |
+
.replace("__DV__", d["version"]) \
|
| 758 |
+
.replace("__LC__", str(d["locked_count"])) \
|
| 759 |
+
.replace("__LP__", ", ".join(d["locked_proven"])) \
|
| 760 |
+
.replace("__CORPUS__", d["corpus"]) \
|
| 761 |
+
.replace("__KC__", d["kernel_commit"]) \
|
| 762 |
+
.replace("__SLSA__", d["slsa"])
|
| 763 |
+
|
| 764 |
+
|
| 765 |
+
# ---------------------------------------------------------------------------
|
| 766 |
+
# Registration (additive; mirrors szl_sovereign_compute.register).
|
| 767 |
+
# ---------------------------------------------------------------------------
|
| 768 |
+
def register(app, ns: str = "a11oy") -> dict:
|
| 769 |
+
from fastapi.responses import HTMLResponse, JSONResponse
|
| 770 |
+
|
| 771 |
+
base = "/api/%s/v1/energy" % ns
|
| 772 |
+
|
| 773 |
+
@app.get("%s/sovereign" % base)
|
| 774 |
+
async def _es_json(): # noqa: ANN202
|
| 775 |
+
return JSONResponse(_posture())
|
| 776 |
+
|
| 777 |
+
@app.get("%s/jtoken" % base)
|
| 778 |
+
async def _es_jtoken(): # noqa: ANN202
|
| 779 |
+
state = _sovereign_state()
|
| 780 |
+
reachable = _gpu_reachable(state)
|
| 781 |
+
prom = _parse_prom(_fetch_metrics_text() or "") if reachable else {}
|
| 782 |
+
sample = _exporter_sample_from_metrics(prom) if reachable else None
|
| 783 |
+
return JSONResponse(_jtoken_from_metrics(prom, sample))
|
| 784 |
+
|
| 785 |
+
@app.get("%s/throughput" % base)
|
| 786 |
+
async def _es_throughput(): # noqa: ANN202
|
| 787 |
+
state = _sovereign_state()
|
| 788 |
+
reachable = _gpu_reachable(state)
|
| 789 |
+
prom = _parse_prom(_fetch_metrics_text() or "") if reachable else {}
|
| 790 |
+
return JSONResponse(_throughput_panel(prom, reachable))
|
| 791 |
+
|
| 792 |
+
@app.get("%s/kvcache" % base)
|
| 793 |
+
async def _es_kvcache(): # noqa: ANN202
|
| 794 |
+
state = _sovereign_state()
|
| 795 |
+
reachable = _gpu_reachable(state)
|
| 796 |
+
prom = _parse_prom(_fetch_metrics_text() or "") if reachable else {}
|
| 797 |
+
return JSONResponse(_kvcache_panel(prom, reachable))
|
| 798 |
+
|
| 799 |
+
@app.get("%s/gateway" % base)
|
| 800 |
+
async def _es_gateway(): # noqa: ANN202
|
| 801 |
+
return JSONResponse(_gateway_panel(_sovereign_state()))
|
| 802 |
+
|
| 803 |
+
@app.get("%s/router" % base)
|
| 804 |
+
async def _es_router(): # noqa: ANN202
|
| 805 |
+
return JSONResponse(_router_panel())
|
| 806 |
+
|
| 807 |
+
@app.get("%s/carbon" % base)
|
| 808 |
+
async def _es_carbon(): # noqa: ANN202
|
| 809 |
+
return JSONResponse(_carbon_panel())
|
| 810 |
+
|
| 811 |
+
@app.get("/energy", response_class=HTMLResponse)
|
| 812 |
+
async def _es_panel(): # noqa: ANN202
|
| 813 |
+
return HTMLResponse(_html(_posture()))
|
| 814 |
+
|
| 815 |
+
return {"ok": True, "ns": ns,
|
| 816 |
+
"routes": ["%s/sovereign" % base, "%s/jtoken" % base, "%s/throughput" % base,
|
| 817 |
+
"%s/kvcache" % base, "%s/gateway" % base, "%s/router" % base,
|
| 818 |
+
"%s/carbon" % base, "/energy"]}
|
| 819 |
+
|
| 820 |
+
|
| 821 |
+
# ---------------------------------------------------------------------------
|
| 822 |
+
# No-server self-test (proves the honesty gates without a live GPU).
|
| 823 |
+
# ---------------------------------------------------------------------------
|
| 824 |
+
def _selftest() -> dict:
|
| 825 |
+
out: dict = {}
|
| 826 |
+
# (a) energy_fields_for_receipt is always present + honest when no GPU.
|
| 827 |
+
f = energy_fields_for_receipt()
|
| 828 |
+
assert f["joules_consumed"] is None and f["carbon_g_co2eq"] is None, f
|
| 829 |
+
assert f["energy_label"] == "ROADMAP", f
|
| 830 |
+
assert f["joules_honesty"] == "sample", f
|
| 831 |
+
out["receipt_fields_honest_roadmap"] = True
|
| 832 |
+
|
| 833 |
+
# (b) J/token with no real sample => ROADMAP, no fabricated number.
|
| 834 |
+
jt = _jtoken_from_metrics({}, None)
|
| 835 |
+
assert jt["label"] == "ROADMAP" and jt["joules_per_token"] is None, jt
|
| 836 |
+
out["jtoken_roadmap_no_number"] = True
|
| 837 |
+
|
| 838 |
+
# (c) J/token WITH a fresh fabricated-but-real-shaped sample + token counter => MEASURED.
|
| 839 |
+
prom = {"vllm:generation_tokens_total": 1000.0}
|
| 840 |
+
sample = {"joules_measured_total": 50.0, "exporter_node": "rig-0",
|
| 841 |
+
"exporter_last_seen_ts": _time.time(), "power_w_sample": 210.0}
|
| 842 |
+
jt2 = _jtoken_from_metrics(prom, sample)
|
| 843 |
+
assert jt2["label"] == "MEASURED", jt2
|
| 844 |
+
assert abs(jt2["joules_per_token"] - 0.05) < 1e-9, jt2
|
| 845 |
+
assert jt2["carbon_g_co2eq_per_token"] is not None, jt2
|
| 846 |
+
out["jtoken_measured_with_real_sample"] = True
|
| 847 |
+
|
| 848 |
+
# (d) speculative speedup model: S=(k+1)/(k(1-α)+1); k=4, α=0.8 -> 5/1.8 ≈ 2.78x.
|
| 849 |
+
s = _spec_speedup(4, 0.8)
|
| 850 |
+
assert 2.7 < s < 2.85, s
|
| 851 |
+
out["spec_speedup_model"] = round(s, 3)
|
| 852 |
+
|
| 853 |
+
# (e) Thompson router starts at Beta(1,1) priors => ROADMAP; recording flips MEASURED.
|
| 854 |
+
rp = _router_panel()
|
| 855 |
+
assert rp["label"] == "ROADMAP", rp
|
| 856 |
+
record_route_outcome("local-7b", True)
|
| 857 |
+
rp2 = _router_panel()
|
| 858 |
+
assert rp2["label"] == "MEASURED", rp2
|
| 859 |
+
# reset prior so the module ships clean
|
| 860 |
+
_ROUTER_MODELS["local-7b"]["alpha"] = 1.0
|
| 861 |
+
globals()["_ROUTER_OBS"] = 0
|
| 862 |
+
out["router_thompson_gate"] = True
|
| 863 |
+
|
| 864 |
+
# (f) carbon panel: no live feed => ROADMAP + SAMPLE intensity label.
|
| 865 |
+
cp = _carbon_panel()
|
| 866 |
+
assert cp["label"] == "ROADMAP" and "SAMPLE" in cp["carbon_intensity_label"], cp
|
| 867 |
+
assert len(cp["schedule_24h"]) == 24, cp
|
| 868 |
+
out["carbon_roadmap_sample"] = True
|
| 869 |
+
|
| 870 |
+
# (g) full posture renders + html is non-trivial + no forbidden raw claims pattern.
|
| 871 |
+
p = _posture()
|
| 872 |
+
h = _html(p)
|
| 873 |
+
assert "Energy / Sovereign Compute" in h and len(h) > 2000, len(h)
|
| 874 |
+
assert "100%" not in h and "tamper-proof" not in h.lower(), "forbidden raw claim"
|
| 875 |
+
out["html_bytes"] = len(h)
|
| 876 |
+
|
| 877 |
+
out["ok"] = True
|
| 878 |
+
return out
|
| 879 |
+
|
| 880 |
+
|
| 881 |
+
if __name__ == "__main__":
|
| 882 |
+
import sys
|
| 883 |
+
print(_json.dumps(_selftest(), indent=2), file=sys.stderr)
|