terminal-agent / app.py
josephrw's picture
Upload folder using huggingface_hub
d562640 verified
Raw
History Blame Contribute Delete
232 kB
#!/usr/bin/env python3
"""
Terminal Agent β€” Hugging Face Spaces Deployment
Serves web terminal + API on port 7860
"""
import json
import math
import os
import signal
import subprocess
import sqlite3
import threading
import time
import logging
import sys
import uuid
import re
import hashlib
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, Optional
from flask import Flask, jsonify, request, Response, render_template
import schedule
import requests
# ── Config ──────────────────────────────────────────────────────
PORT = int(os.environ.get("PORT") or (Path("/app/port").read_text().strip() if Path("/app/port").exists() else 7860))
LOG_DIR = Path("logs")
LOG_DIR.mkdir(exist_ok=True)
NOTEBOOK_DIR = Path("notebooks")
NOTEBOOK_DIR.mkdir(exist_ok=True)
APPS_DIR = Path("generated_apps")
APPS_DIR.mkdir(exist_ok=True)
CONFIG_PATH = Path("config.json")
STATE_PATH = Path("agent_state.json")
MEMORY_PATH = Path("memory_store.json")
SETTINGS_PATH = Path("settings.json")
APPS_PATH = Path("apps_registry.json")
RECEIPTS_PATH = Path("receipts_store.json")
TERMINAL_AGENT_TOKEN = os.environ.get("TERMINAL_AGENT_TOKEN", "").strip()
MAX_COMMAND_TIMEOUT = int(os.environ.get("MAX_COMMAND_TIMEOUT", "600"))
DEFAULT_CWD = Path(os.environ.get("TERMINAL_AGENT_CWD", "/app" if Path("/app").exists() else "."))
# ── Logging ─────────────────────────────────────────────────────
log_file = LOG_DIR / f"agent_{datetime.now(timezone.utc).strftime('%Y%m%d')}.log"
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[logging.FileHandler(log_file), logging.StreamHandler(sys.stdout)],
)
logger = logging.getLogger("terminal-agent")
# ── State ───────────────────────────────────────────────────────
state = {
"start_time": datetime.now(timezone.utc).isoformat(),
"last_check": None,
"executed_tasks": [],
}
tasks: Dict[str, dict] = {}
processes: Dict[str, dict] = {}
apps: Dict[str, dict] = {}
receipts: Dict[str, dict] = {}
memories: Dict[str, dict] = {}
memory_lock = threading.RLock()
app_lock = threading.RLock()
receipt_lock = threading.RLock()
settings_lock = threading.RLock()
settings: Dict[str, dict] = {}
kernel_lock = threading.RLock()
kernel_manager = None
kernel_client = None
# ── Token Economy (SQLite-backed, integer amounts) ──────────────
DB_PATH = Path("token_economy.db")
token_lock = threading.RLock()
wallet_lock = threading.RLock()
# Integer token amounts β€” no floats for money (C53)
TOKEN_REWARDS = {
"kernel_execute": 100,
"shell_execute": 50,
"notebook_run": 200,
"agent_build": 500,
"app_start": 100,
"llm_call": 20,
"deploy": 300,
}
# ── Token costs: DB-first, env override, no hardcoded runtime values ──
_TOKEN_COST_DEFAULTS = {
"token_launch": 5000,
"claim_evaluate": 500,
"claim_contradiction_scan": 200,
"claim_greeks": 100,
"pixelator_ingest": 300,
"pixelator_glyphs": 50,
"crawler_ingest": 250,
"crawler_enqueue": 25,
}
def _get_token_cost(operation: str) -> int:
"""Read cost from DB first, then env, then defaults."""
# Env override takes highest precedence for admin tuning
env_val = os.environ.get(f"COST_{operation.upper()}")
if env_val is not None:
try:
return int(env_val)
except ValueError:
pass
with _db() as conn:
row = conn.execute("SELECT cost FROM token_costs WHERE operation = ?", (operation,)).fetchone()
if row:
return row["cost"]
return _TOKEN_COST_DEFAULTS.get(operation, 0)
# Solana configuration (C12: no hardcoded secrets)
SOLANA_RPC_URL = os.environ.get("SOLANA_RPC_URL", "https://api.devnet.solana.com")
SOLANA_MAINNET_ENABLED = os.environ.get("SOLANA_MAINNET_ENABLED", "").lower() in ("true", "1", "yes")
SOLANA_SERVICE_KEY_B58 = os.environ.get("SOLANA_SERVICE_KEY_B58", "")
if SOLANA_MAINNET_ENABLED:
SOLANA_RPC_URL = os.environ.get("SOLANA_RPC_URL", "https://api.mainnet-beta.solana.com")
def _db() -> sqlite3.Connection:
conn = sqlite3.connect(str(DB_PATH), check_same_thread=False, timeout=10.0)
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA journal_mode=WAL")
conn.execute("PRAGMA synchronous=NORMAL")
return conn
def _init_token_db():
with _db() as conn:
conn.execute("""
CREATE TABLE IF NOT EXISTS wallets (
address TEXT PRIMARY KEY,
provider TEXT NOT NULL CHECK(provider IN ('metamask','phantom')),
signature TEXT NOT NULL,
nonce TEXT NOT NULL,
connected_at TEXT NOT NULL,
last_seen TEXT NOT NULL
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS balances (
address TEXT PRIMARY KEY,
balance INTEGER NOT NULL DEFAULT 0 CHECK(balance >= 0)
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS transactions (
tx_id TEXT PRIMARY KEY,
address TEXT NOT NULL,
amount INTEGER NOT NULL,
type TEXT NOT NULL CHECK(type IN ('credit','debit')),
reason TEXT NOT NULL,
created_at TEXT NOT NULL,
metadata TEXT
)
""")
conn.execute("CREATE INDEX IF NOT EXISTS idx_tx_address ON transactions(address)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_tx_created ON transactions(created_at)")
# ── Idempotency + Underwriting tables ─────────────────────
conn.execute("""
CREATE TABLE IF NOT EXISTS stripe_sessions (
session_id TEXT PRIMARY KEY,
event_type TEXT NOT NULL,
status TEXT NOT NULL,
amount_cents INTEGER NOT NULL CHECK(amount_cents >= 0),
currency TEXT NOT NULL DEFAULT 'usd',
wallet TEXT NOT NULL,
pack TEXT NOT NULL,
tokens INTEGER NOT NULL CHECK(tokens >= 0),
processed_at TEXT NOT NULL,
tx_id TEXT UNIQUE
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS revenue (
revenue_id TEXT PRIMARY KEY,
source TEXT NOT NULL CHECK(source IN ('stripe_checkout','stripe_webhook','token_pack','other')),
session_id TEXT,
amount_cents INTEGER NOT NULL CHECK(amount_cents >= 0),
currency TEXT NOT NULL DEFAULT 'usd',
period TEXT NOT NULL,
wallet TEXT,
created_at TEXT NOT NULL,
metadata TEXT
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS deferred_revenue (
address TEXT PRIMARY KEY,
tokens_purchased INTEGER NOT NULL DEFAULT 0 CHECK(tokens_purchased >= 0),
tokens_spent INTEGER NOT NULL DEFAULT 0 CHECK(tokens_spent >= 0),
deferred_cents INTEGER NOT NULL DEFAULT 0 CHECK(deferred_cents >= 0),
last_updated TEXT NOT NULL
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS launched_tokens (
launch_id TEXT PRIMARY KEY,
mint_address TEXT NOT NULL UNIQUE,
owner_address TEXT NOT NULL,
name TEXT NOT NULL,
symbol TEXT NOT NULL,
decimals INTEGER NOT NULL DEFAULT 9,
supply INTEGER NOT NULL,
tx_signature TEXT,
network TEXT NOT NULL DEFAULT 'devnet',
created_at TEXT NOT NULL,
metadata_uri TEXT
)
""")
conn.execute("CREATE INDEX IF NOT EXISTS idx_launched_owner ON launched_tokens(owner_address)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_rev_period ON revenue(period)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_rev_source ON revenue(source)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_stripe_wallet ON stripe_sessions(wallet)")
# ── CLAIMOS tables ──────────────────────────────────────────
conn.execute("""
CREATE TABLE IF NOT EXISTS claims (
claim_id TEXT PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
status TEXT NOT NULL DEFAULT 'unreviewed' CHECK(status IN ('unreviewed','evidence_received','counsel_reviewed','procedural_survival','settlement_signals','finance_ready','closed')),
evidence_count INTEGER NOT NULL DEFAULT 0,
p_recovery REAL DEFAULT 0.0,
evidence_strength REAL DEFAULT 0.0,
counsel_signal REAL DEFAULT 0.0,
procedural_survival REAL DEFAULT 0.0,
settlement_signal REAL DEFAULT 0.0,
contradiction_density REAL DEFAULT 0.0,
uncertainty REAL DEFAULT 0.0,
liquidity_score REAL DEFAULT 0.0,
delta_claim REAL DEFAULT 0.0,
theta_claim REAL DEFAULT 0.0,
gamma_claim REAL DEFAULT 0.0,
vega_claim REAL DEFAULT 0.0,
kappa_claim REAL DEFAULT 0.0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
wallet TEXT,
metadata TEXT
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS evidence (
evidence_id TEXT PRIMARY KEY,
claim_id TEXT NOT NULL,
source_type TEXT NOT NULL CHECK(source_type IN ('audio','document','transcript','witness','hospital','police','screenshot','email','timeline','other')),
source_ref TEXT NOT NULL,
content_hash TEXT NOT NULL,
content TEXT,
evidence_strength REAL DEFAULT 0.5,
created_at TEXT NOT NULL,
metadata TEXT,
FOREIGN KEY (claim_id) REFERENCES claims(claim_id)
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS contradictions (
contradiction_id TEXT PRIMARY KEY,
claim_id TEXT NOT NULL,
evidence_a_id TEXT NOT NULL,
evidence_b_id TEXT NOT NULL,
contradiction_type TEXT NOT NULL CHECK(contradiction_type IN ('temporal','causal','factual','source','semantic')),
severity REAL NOT NULL DEFAULT 0.5 CHECK(severity >= 0 AND severity <= 1),
description TEXT,
resolved INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
FOREIGN KEY (claim_id) REFERENCES claims(claim_id),
FOREIGN KEY (evidence_a_id) REFERENCES evidence(evidence_id),
FOREIGN KEY (evidence_b_id) REFERENCES evidence(evidence_id)
)
""")
conn.execute("CREATE INDEX IF NOT EXISTS idx_claims_wallet ON claims(wallet)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_claims_status ON claims(status)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_evidence_claim ON evidence(claim_id)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_contradictions_claim ON contradictions(claim_id)")
# ── Pixelator / GlyphIndex tables ───────────────────────────
conn.execute("""
CREATE TABLE IF NOT EXISTS pages (
page_id TEXT PRIMARY KEY,
website_id TEXT NOT NULL,
url TEXT NOT NULL,
title TEXT,
page_activation_value REAL NOT NULL DEFAULT 0.0,
semantic_density REAL NOT NULL DEFAULT 0.0,
entity_count INTEGER NOT NULL DEFAULT 0,
action_count INTEGER NOT NULL DEFAULT 0,
commercial_score REAL NOT NULL DEFAULT 0.0,
legal_score REAL NOT NULL DEFAULT 0.0,
version_id INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
metadata TEXT
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS glyph_units (
glyph_id TEXT PRIMARY KEY,
page_id TEXT NOT NULL,
website_id TEXT NOT NULL,
version_id INTEGER NOT NULL DEFAULT 1,
dom_path TEXT NOT NULL,
paragraph_pos INTEGER NOT NULL DEFAULT 0,
sentence_pos INTEGER NOT NULL DEFAULT 0,
token_pos INTEGER NOT NULL DEFAULT 0,
char_index INTEGER NOT NULL DEFAULT 0,
char_value TEXT NOT NULL,
char_case TEXT NOT NULL DEFAULT 'lower',
semantic_role TEXT NOT NULL DEFAULT 'body',
activation_role TEXT NOT NULL DEFAULT 'neutral',
proof_hash TEXT,
semantic_density REAL NOT NULL DEFAULT 0.0,
glyph_value REAL NOT NULL DEFAULT 0.0,
entity_proximity REAL NOT NULL DEFAULT 0.0,
action_proximity REAL NOT NULL DEFAULT 0.0,
commercial_proximity REAL NOT NULL DEFAULT 0.0,
legal_proximity REAL NOT NULL DEFAULT 0.0,
timestamp TEXT NOT NULL,
FOREIGN KEY (page_id) REFERENCES pages(page_id)
)
""")
conn.execute("CREATE INDEX IF NOT EXISTS idx_glyph_page ON glyph_units(page_id)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_glyph_website ON glyph_units(website_id)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_glyph_value ON glyph_units(glyph_value)")
# ── GA-RL Crawler tables ─────────────────────────────────────
conn.execute("""
CREATE TABLE IF NOT EXISTS crawl_targets (
target_id TEXT PRIMARY KEY,
website_id TEXT NOT NULL UNIQUE,
root_url TEXT NOT NULL,
name TEXT,
priority REAL NOT NULL DEFAULT 1.0,
fitness_score REAL NOT NULL DEFAULT 0.0,
avg_glyph_value REAL NOT NULL DEFAULT 0.0,
crawl_count INTEGER NOT NULL DEFAULT 0,
success_count INTEGER NOT NULL DEFAULT 0,
last_crawled TEXT,
crawl_depth INTEGER NOT NULL DEFAULT 2,
selector_rules TEXT,
is_active INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
metadata TEXT
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS crawl_queue (
queue_id TEXT PRIMARY KEY,
target_id TEXT NOT NULL,
url TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
priority_score REAL NOT NULL DEFAULT 0.0,
q_value REAL NOT NULL DEFAULT 0.0,
depth INTEGER NOT NULL DEFAULT 0,
added_at TEXT NOT NULL,
started_at TEXT,
completed_at TEXT,
error_msg TEXT,
page_id TEXT,
reward REAL DEFAULT 0.0,
FOREIGN KEY (target_id) REFERENCES crawl_targets(target_id)
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS crawl_results (
result_id TEXT PRIMARY KEY,
queue_id TEXT NOT NULL,
target_id TEXT NOT NULL,
page_id TEXT NOT NULL,
url TEXT NOT NULL,
status TEXT NOT NULL,
glyph_count INTEGER NOT NULL DEFAULT 0,
page_activation REAL NOT NULL DEFAULT 0.0,
avg_glyph_value REAL NOT NULL DEFAULT 0.0,
reward REAL NOT NULL DEFAULT 0.0,
crawl_time_ms INTEGER,
crawled_at TEXT NOT NULL,
FOREIGN KEY (target_id) REFERENCES crawl_targets(target_id)
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS crawl_policy (
policy_id TEXT PRIMARY KEY,
website_id TEXT NOT NULL,
q_value REAL NOT NULL DEFAULT 0.0,
visit_count INTEGER NOT NULL DEFAULT 0,
epsilon REAL NOT NULL DEFAULT 0.3,
alpha REAL NOT NULL DEFAULT 0.1,
gamma REAL NOT NULL DEFAULT 0.9,
generation INTEGER NOT NULL DEFAULT 0,
updated_at TEXT NOT NULL
)
""")
conn.execute("CREATE UNIQUE INDEX IF NOT EXISTS idx_policy_website ON crawl_policy(website_id)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_queue_status ON crawl_queue(status)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_queue_target ON crawl_queue(target_id)")
conn.execute("CREATE INDEX IF NOT EXISTS idx_results_target ON crawl_results(target_id)")
# ── Learned weights / costs (no hardcoded values) ────────────
conn.execute("""
CREATE TABLE IF NOT EXISTS dom_weights (
tag TEXT PRIMARY KEY,
weight REAL NOT NULL DEFAULT 1.0,
sample_count INTEGER NOT NULL DEFAULT 0,
avg_page_activation REAL NOT NULL DEFAULT 0.0,
updated_at TEXT NOT NULL
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS semantic_lexicon (
term TEXT NOT NULL,
category TEXT NOT NULL,
frequency INTEGER NOT NULL DEFAULT 1,
confidence REAL NOT NULL DEFAULT 0.5,
source_count INTEGER NOT NULL DEFAULT 0,
updated_at TEXT NOT NULL,
PRIMARY KEY (term, category)
)
""")
conn.execute("""
CREATE TABLE IF NOT EXISTS token_costs (
operation TEXT PRIMARY KEY,
cost INTEGER NOT NULL DEFAULT 0,
source TEXT NOT NULL DEFAULT 'db',
updated_at TEXT NOT NULL
)
""")
conn.commit()
# Ensure DB schema exists at import time (for WSGI / module imports)
_init_token_db()
def _seed_learned_tables() -> None:
"""Seed DB tables with initial values from defaults. Run once at startup."""
now = datetime.now(timezone.utc).isoformat()
with _db() as conn:
# Seed token_costs from defaults
for op, cost in _TOKEN_COST_DEFAULTS.items():
conn.execute(
"INSERT OR IGNORE INTO token_costs (operation, cost, source, updated_at) VALUES (?, ?, 'seed', ?)",
(op, cost, now),
)
# Seed DOM weights from historical empirical data
dom_seed = {
"h1": 3.0, "h2": 2.5, "h3": 2.0, "h4": 1.5, "h5": 1.3, "h6": 1.2,
"title": 3.5, "strong": 1.8, "b": 1.8, "em": 1.5, "a": 1.4,
"p": 1.0, "span": 0.8, "li": 1.1, "td": 0.9, "div": 0.7,
}
for tag, weight in dom_seed.items():
conn.execute(
"INSERT OR IGNORE INTO dom_weights (tag, weight, sample_count, avg_page_activation, updated_at) VALUES (?, ?, 0, 0.0, ?)",
(tag, weight, now),
)
# Seed semantic lexicon from initial corpus
lexicon_seed = [
# entity
("acquires", "entity"), ("acquired", "entity"), ("acquisition", "entity"),
("merger", "entity"), ("ipo", "entity"), ("funding", "entity"),
("launches", "entity"), ("announces", "entity"), ("partnership", "entity"),
("contract", "entity"), ("deal", "entity"), ("apple", "entity"),
("google", "entity"), ("microsoft", "entity"), ("amazon", "entity"),
("tesla", "entity"), ("nvidia", "entity"), ("startup", "entity"),
("unicorn", "entity"), ("billion", "entity"), ("million", "entity"),
("valuation", "entity"),
# action
("acquires", "action"), ("buys", "action"), ("sells", "action"),
("merges", "action"), ("launches", "action"), ("announces", "action"),
("raises", "action"), ("funds", "action"), ("invests", "action"),
("partners", "action"), ("signs", "action"), ("wins", "action"),
("loses", "action"), ("grows", "action"), ("expands", "action"),
("purchased", "action"), ("sold", "action"), ("closed", "action"),
# commercial
("revenue", "commercial"), ("profit", "commercial"), ("sales", "commercial"),
("market", "commercial"), ("share", "commercial"), ("price", "commercial"),
("stock", "commercial"), ("trading", "commercial"), ("investor", "commercial"),
("shareholder", "commercial"), ("dividend", "commercial"), ("earnings", "commercial"),
("quarter", "commercial"), ("fiscal", "commercial"), ("growth", "commercial"),
("expansion", "commercial"),
# legal
("lawsuit", "legal"), ("patent", "legal"), ("copyright", "legal"),
("trademark", "legal"), ("settlement", "legal"), ("violation", "legal"),
("compliance", "legal"), ("regulation", "legal"), ("fda", "legal"),
("sec", "legal"), ("antitrust", "legal"), ("litigation", "legal"),
("court", "legal"), ("verdict", "legal"), ("fine", "legal"),
("sanction", "legal"),
]
for term, category in lexicon_seed:
conn.execute(
"""INSERT OR IGNORE INTO semantic_lexicon (term, category, frequency, confidence, source_count, updated_at)
VALUES (?, ?, 1, 0.6, 0, ?)""",
(term, category, now),
)
conn.commit()
_seed_learned_tables()
def _normalize_wallet(address: str) -> str:
"""Lowercase EVM addresses; preserve Solana base58 case."""
a = address.strip()
return a.lower() if a.startswith("0x") else a
def _clamp_str(value, max_len: int = 4000) -> str:
s = str(value) if value else ""
return s[:max_len]
def _connected_wallet(address: str) -> Optional[dict]:
addr = _normalize_wallet(address)
with wallet_lock:
with _db() as conn:
row = conn.execute("SELECT * FROM wallets WHERE address = ?", (addr,)).fetchone()
if row:
return dict(row)
return None
def _new_tx_id() -> str:
return f"tx_{uuid.uuid4().hex}_{int(time.time() * 1000)}"
def load_tokens():
pass # SQLite is self-bootstrapping
def load_wallets():
pass # SQLite is self-bootstrapping
def get_balance(address: str) -> int:
addr = _normalize_wallet(address)
with token_lock:
with _db() as conn:
row = conn.execute("SELECT balance FROM balances WHERE address = ?", (addr,)).fetchone()
return row["balance"] if row else 0
def credit_tokens(address: str, amount: int, reason: str, metadata: Optional[dict] = None, idempotency_key: Optional[str] = None, revenue_cents: int = 0) -> dict:
if amount <= 0:
raise ValueError("Credit amount must be positive integer")
addr = _normalize_wallet(address)
tx_id = idempotency_key or _new_tx_id()
now = datetime.now(timezone.utc).isoformat()
period = now[:7] # YYYY-MM
with token_lock:
with _db() as conn:
# Idempotency: if tx_id already exists, return existing record
existing = conn.execute("SELECT tx_id, amount, reason FROM transactions WHERE tx_id = ?", (tx_id,)).fetchone()
if existing:
bal = get_balance(addr)
return {"wallet": addr, "amount": existing["amount"], "reason": existing["reason"], "balance": bal, "tx_id": tx_id, "idempotent": True}
conn.execute(
"INSERT OR REPLACE INTO balances (address, balance) VALUES (?, COALESCE((SELECT balance FROM balances WHERE address = ?), 0) + ?)",
(addr, addr, amount),
)
conn.execute(
"INSERT INTO transactions (tx_id, address, amount, type, reason, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)",
(tx_id, addr, amount, "credit", reason, now, json.dumps(metadata) if metadata else None),
)
# Revenue ledger for underwriting proof
if revenue_cents > 0:
rev_id = f"rev_{uuid.uuid4().hex}"
conn.execute(
"INSERT INTO revenue (revenue_id, source, session_id, amount_cents, currency, period, wallet, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
(rev_id, "token_pack", metadata.get("session_id") if metadata else None, revenue_cents, "usd", period, addr, now, json.dumps(metadata) if metadata else None),
)
# Deferred revenue: purchased tokens increase liability (bonuses excluded)
if reason.startswith("stripe_purchase"):
cents_per_token = revenue_cents // amount if amount > 0 and revenue_cents > 0 else 0
conn.execute(
"""INSERT INTO deferred_revenue (address, tokens_purchased, tokens_spent, deferred_cents, last_updated)
VALUES (?, ?, 0, ?, ?)
ON CONFLICT(address) DO UPDATE SET
tokens_purchased = tokens_purchased + excluded.tokens_purchased,
deferred_cents = deferred_cents + excluded.deferred_cents,
last_updated = excluded.last_updated""",
(addr, amount, cents_per_token * amount, now),
)
conn.commit()
bal = get_balance(addr)
add_memory(
title=f"Token credit: +{amount} to {addr[:16]}...",
content=f"Wallet {addr} credited {amount} tokens. Reason: {reason}. New balance: {bal}",
source="token-economy",
tags=["tokens", "credit", reason],
metadata={"wallet": addr, "amount": amount, "reason": reason, "balance": bal, "tx_id": tx_id},
importance=0.7,
)
create_receipt(
kind="token-credit",
title=f"Token credit: +{amount}",
status="completed",
command=f"credit:{amount}:{reason}",
metadata={"wallet": addr, "amount": amount, "reason": reason, "balance": bal, "tx_id": tx_id},
)
return {"wallet": addr, "amount": amount, "reason": reason, "balance": bal, "tx_id": tx_id}
def debit_tokens(address: str, amount: int, reason: str, metadata: Optional[dict] = None, idempotency_key: Optional[str] = None) -> dict:
if amount <= 0:
raise ValueError("Debit amount must be positive integer")
addr = _normalize_wallet(address)
tx_id = idempotency_key or _new_tx_id()
now = datetime.now(timezone.utc).isoformat()
with token_lock:
with _db() as conn:
# Idempotency
existing = conn.execute("SELECT tx_id, amount, reason FROM transactions WHERE tx_id = ?", (tx_id,)).fetchone()
if existing:
bal = get_balance(addr)
return {"wallet": addr, "amount": existing["amount"], "reason": existing["reason"], "balance": bal, "tx_id": tx_id, "idempotent": True}
row = conn.execute("SELECT balance FROM balances WHERE address = ?", (addr,)).fetchone()
current = row["balance"] if row else 0
if current < amount:
raise ValueError(f"Insufficient tokens: {current} < {amount}")
conn.execute(
"UPDATE balances SET balance = balance - ? WHERE address = ?",
(amount, addr),
)
conn.execute(
"INSERT INTO transactions (tx_id, address, amount, type, reason, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)",
(tx_id, addr, amount, "debit", reason, now, json.dumps(metadata) if metadata else None),
)
# Reduce deferred revenue liability when tokens are consumed
conn.execute(
"""UPDATE deferred_revenue SET
tokens_spent = tokens_spent + ?,
deferred_cents = MAX(0, deferred_cents - (SELECT deferred_cents FROM deferred_revenue WHERE address = ?) / NULLIF(tokens_purchased, 0) * ?),
last_updated = ?
WHERE address = ? AND tokens_purchased > 0""",
(amount, addr, amount, now, addr),
)
conn.commit()
bal = get_balance(addr)
add_memory(
title=f"Token debit: -{amount} from {addr[:16]}...",
content=f"Wallet {addr} debited {amount} tokens. Reason: {reason}. New balance: {bal}",
source="token-economy",
tags=["tokens", "debit", reason],
metadata={"wallet": addr, "amount": amount, "reason": reason, "balance": bal, "tx_id": tx_id},
importance=0.7,
)
create_receipt(
kind="token-debit",
title=f"Token debit: -{amount}",
status="completed",
command=f"debit:{amount}:{reason}",
metadata={"wallet": addr, "amount": amount, "reason": reason, "balance": bal, "tx_id": tx_id},
)
return {"wallet": addr, "amount": amount, "reason": reason, "balance": bal, "tx_id": tx_id}
def leaderboard(limit: int = 20) -> list:
with token_lock:
with _db() as conn:
rows = conn.execute(
"SELECT address, balance FROM balances ORDER BY balance DESC LIMIT ?",
(limit,),
).fetchall()
return [{"rank": i + 1, "wallet": row["address"], "balance": row["balance"]} for i, row in enumerate(rows)]
def tx_history(address: str, limit: int = 50) -> list:
addr = _normalize_wallet(address)
with token_lock:
with _db() as conn:
rows = conn.execute(
"SELECT tx_id, amount, type, reason, created_at FROM transactions WHERE address = ? ORDER BY created_at DESC LIMIT ?",
(addr, limit),
).fetchall()
return [{"tx_id": r["tx_id"], "amount": r["amount"], "type": r["type"], "reason": r["reason"], "created_at": r["created_at"]} for r in rows]
# ── CLAIMOS Core ────────────────────────────────────────────────
class ClaimProbabilityEngine:
"""Computes P(recovery_t) from evidence strength, counsel work, procedural survival,
settlement signals, contradiction density, and uncertainty/risk.
P(recovery_t) = Οƒ(E_t + L_t + P_t + S_t - C_t - R_t)
"""
EPS = 0.01
TIME_DECAY_DAILY = 0.002
@staticmethod
def _sigmoid(x: float) -> float:
try:
return 1.0 / (1.0 + math.exp(-x))
except OverflowError:
return 1.0 if x > 0 else 0.0
@classmethod
def evaluate(cls, claim_id: str, inputs: Optional[dict] = None) -> dict:
"""Evaluate or re-evaluate a claim's probability state."""
now = datetime.now(timezone.utc).isoformat()
with _db() as conn:
claim = conn.execute("SELECT * FROM claims WHERE claim_id = ?", (claim_id,)).fetchone()
if not claim:
raise ValueError(f"Claim not found: {claim_id}")
# Pull all evidence for this claim
ev_rows = conn.execute("SELECT * FROM evidence WHERE claim_id = ?", (claim_id,)).fetchall()
# Pull all contradictions
cx_rows = conn.execute("SELECT * FROM contradictions WHERE claim_id = ? AND resolved = 0", (claim_id,)).fetchall()
# Compute components
E = 0.0 # evidence strength
if ev_rows:
strengths = [r["evidence_strength"] or 0.5 for r in ev_rows]
E = sum(strengths) / len(strengths) * math.log1p(len(strengths))
# Contradiction density
C = 0.0
if cx_rows:
severities = [r["severity"] or 0.5 for r in cx_rows]
C = sum(severities) / len(severities) * math.log1p(len(severities))
# Override with explicit inputs if provided
if inputs:
E = inputs.get("evidence_strength", E)
L = inputs.get("counsel_signal", claim["counsel_signal"] or 0.0)
P = inputs.get("procedural_survival", claim["procedural_survival"] or 0.0)
S = inputs.get("settlement_signal", claim["settlement_signal"] or 0.0)
R = inputs.get("uncertainty", claim["uncertainty"] or 0.0)
else:
L = claim["counsel_signal"] or 0.0
P = claim["procedural_survival"] or 0.0
S = claim["settlement_signal"] or 0.0
R = claim["uncertainty"] or 0.0
# Probability compression: Οƒ(E + L + P + S - C - R)
z = E + L + P + S - C - R
p_recovery = cls._sigmoid(z)
# Update claim record
with _db() as conn:
conn.execute(
"""UPDATE claims SET
evidence_strength = ?, counsel_signal = ?, procedural_survival = ?,
settlement_signal = ?, contradiction_density = ?, uncertainty = ?,
p_recovery = ?, evidence_count = ?, updated_at = ?
WHERE claim_id = ?""",
(E, L, P, S, C, R, p_recovery, len(ev_rows), now, claim_id),
)
conn.commit()
return {
"claim_id": claim_id,
"p_recovery": round(p_recovery, 6),
"evidence_strength": round(E, 4),
"counsel_signal": round(L, 4),
"procedural_survival": round(P, 4),
"settlement_signal": round(S, 4),
"contradiction_density": round(C, 4),
"uncertainty": round(R, 4),
"evidence_count": len(ev_rows),
"contradiction_count": len(cx_rows),
"evaluated_at": now,
}
class ContradictionDetector:
"""Detects conflicts between evidence sources for a claim.
Uses heuristic scan + optional LLM deep semantic analysis."""
@classmethod
def detect(cls, claim_id: str, use_llm: bool = True) -> list:
"""Scan all evidence pairs for contradictions and persist findings."""
with _db() as conn:
rows = conn.execute("SELECT * FROM evidence WHERE claim_id = ?", (claim_id,)).fetchall()
contradictions = []
for i, a in enumerate(rows):
for b in rows[i + 1 :]:
score = cls._scan_pair(a, b)
if score["severity"] > 0.3:
contradictions.append(score)
# Optional LLM deep semantic scan for contradictions not caught by heuristics
if use_llm and len(rows) >= 2:
try:
llm_cx = cls._llm_deep_scan(claim_id, rows)
contradictions.extend(llm_cx)
except Exception as e:
logger.warning(f"LLM deep scan failed for claim {claim_id}: {e}")
# Persist new contradictions
now = datetime.now(timezone.utc).isoformat()
with _db() as conn:
for c in contradictions:
cx_id = f"cx_{uuid.uuid4().hex}"
conn.execute(
"""INSERT OR IGNORE INTO contradictions
(contradiction_id, claim_id, evidence_a_id, evidence_b_id,
contradiction_type, severity, description, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
(cx_id, claim_id, c["evidence_a_id"], c["evidence_b_id"],
c["type"], c["severity"], c["description"], now),
)
conn.commit()
return contradictions
@classmethod
def _scan_pair(cls, a: sqlite3.Row, b: sqlite3.Row) -> dict:
"""Score a single evidence pair for contradiction using heuristics."""
severity = 0.0
cx_type = "semantic"
desc = ""
if a["source_type"] == b["source_type"] and a["content_hash"] != b["content_hash"]:
severity = 0.6
cx_type = "factual"
desc = f"Same source type ({a['source_type']}) with divergent content"
elif a["source_type"] != b["source_type"]:
temporal_a = bool(re.search(r"\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b", a["content"] or ""))
temporal_b = bool(re.search(r"\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b", b["content"] or ""))
if temporal_a and temporal_b:
severity = 0.45
cx_type = "temporal"
desc = "Both evidence items contain dates β€” possible temporal conflict"
else:
severity = 0.25
cx_type = "source"
desc = "Different source types with potential overlap"
else:
severity = 0.1
desc = "Minor semantic variation"
return {
"evidence_a_id": a["evidence_id"],
"evidence_b_id": b["evidence_id"],
"type": cx_type,
"severity": round(min(1.0, severity), 4),
"description": desc,
}
@classmethod
def _llm_deep_scan(cls, claim_id: str, evidence_rows: list) -> list:
"""Use LLM to detect semantic contradictions not visible to regex heuristics."""
# Build prompt from evidence content
ev_text = "\n\n".join(
f"[{i+1}] {r['source_type'].upper()} (ref: {r['source_ref']}): {r['content'][:800]}"
for i, r in enumerate(evidence_rows)
)
system_prompt = (
"You are a legal evidence analyst. Your task is to identify contradictions, conflicts, "
"and inconsistencies between evidence items. Return ONLY a JSON array of contradictions. "
"Each item must have: evidence_a_index (int, 1-based), evidence_b_index (int, 1-based), "
"contradiction_type (one of: temporal, causal, factual, source, semantic), severity (0.0-1.0), "
"description (string). If no contradictions exist, return an empty array []."
)
user_prompt = f"Analyze the following evidence items for contradictions:\n\n{ev_text}"
try:
result = call_llm(prompt=user_prompt, system=system_prompt, model="json")
parsed = parse_llm_json(result.get("response", "[]"))
if not isinstance(parsed, list):
return []
llm_cx = []
for item in parsed:
a_idx = int(item.get("evidence_a_index", 0)) - 1
b_idx = int(item.get("evidence_b_index", 0)) - 1
if 0 <= a_idx < len(evidence_rows) and 0 <= b_idx < len(evidence_rows) and a_idx != b_idx:
llm_cx.append({
"evidence_a_id": evidence_rows[a_idx]["evidence_id"],
"evidence_b_id": evidence_rows[b_idx]["evidence_id"],
"type": str(item.get("contradiction_type", "semantic")).lower(),
"severity": round(min(1.0, max(0.0, float(item.get("severity", 0.5)))), 4),
"description": str(item.get("description", "LLM-detected semantic conflict")),
})
return llm_cx
except Exception as e:
logger.warning(f"LLM contradiction analysis failed: {e}")
return []
class ClaimGreeks:
"""Compute claim sensitivity metrics (Ξ”, Θ, Ξ“, V, K)."""
@classmethod
def compute(cls, claim_id: str) -> dict:
"""Compute Greeks for a claim via finite differences."""
with _db() as conn:
claim = conn.execute("SELECT * FROM claims WHERE claim_id = ?", (claim_id,)).fetchone()
if not claim:
raise ValueError(f"Claim not found: {claim_id}")
base = claim["p_recovery"] or 0.0
E = claim["evidence_strength"] or 0.0
C = claim["contradiction_density"] or 0.0
R = claim["uncertainty"] or 0.0
eps = ClaimProbabilityEngine.EPS
# Ξ”claim = dP/dE
p_plus = ClaimProbabilityEngine._sigmoid((E + eps) + (claim["counsel_signal"] or 0.0) + (claim["procedural_survival"] or 0.0) + (claim["settlement_signal"] or 0.0) - C - R)
p_minus = ClaimProbabilityEngine._sigmoid((E - eps) + (claim["counsel_signal"] or 0.0) + (claim["procedural_survival"] or 0.0) + (claim["settlement_signal"] or 0.0) - C - R)
delta = (p_plus - p_minus) / (2 * eps)
# Ξ“claim = dΒ²P/dEΒ²
gamma = (p_plus - 2 * base + p_minus) / (eps * eps)
# Θclaim = time decay (simplified as -daily_decay * P)
theta = -ClaimProbabilityEngine.TIME_DECAY_DAILY * base
# Vclaim = uncertainty
vega = R
# Kclaim = contradiction drag
kappa = C
now = datetime.now(timezone.utc).isoformat()
with _db() as conn:
conn.execute(
"""UPDATE claims SET
delta_claim = ?, theta_claim = ?, gamma_claim = ?,
vega_claim = ?, kappa_claim = ?, updated_at = ?
WHERE claim_id = ?""",
(delta, theta, gamma, vega, kappa, now, claim_id),
)
conn.commit()
return {
"claim_id": claim_id,
"delta_claim": round(delta, 6),
"theta_claim": round(theta, 6),
"gamma_claim": round(gamma, 6),
"vega_claim": round(vega, 6),
"kappa_claim": round(kappa, 6),
"p_recovery": round(base, 6),
"computed_at": now,
}
class ClaimLiquidity:
"""Finance readiness: compute liquidity score from claim state."""
@classmethod
def compute(cls, claim_id: str) -> dict:
"""Compute liquidity score for a claim."""
with _db() as conn:
claim = conn.execute("SELECT * FROM claims WHERE claim_id = ?", (claim_id,)).fetchone()
if not claim:
raise ValueError(f"Claim not found: {claim_id}")
P = claim["p_recovery"] or 0.0
E = claim["evidence_strength"] or 0.0
C = claim["contradiction_density"] or 0.0
R = claim["uncertainty"] or 0.0
L = claim["counsel_signal"] or 0.0
S = claim["settlement_signal"] or 0.0
# Liquidity_t = Ξ¦(ProofDensity, ProbabilityCompression, CounselRiskCapital, DamageClarity, SettlementSignal)
# - Ξ¨(ContradictionDrag, ProcedureRisk, TimeDecay, EnforcementRisk)
proof_density = E * (1 - C)
probability_compression = P
counsel_capital = L
damage_clarity = E * (1 - R)
settlement_signal = S
contradiction_drag = C * 0.5
procedure_risk = 1 - (claim["procedural_survival"] or 0.0)
time_decay = ClaimProbabilityEngine.TIME_DECAY_DAILY * 30 # 30-day horizon
enforcement_risk = R * 0.3
liquidity = (
(proof_density * 0.25)
+ (probability_compression * 0.25)
+ (counsel_capital * 0.15)
+ (damage_clarity * 0.15)
+ (settlement_signal * 0.20)
- (contradiction_drag * 0.30)
- (procedure_risk * 0.20)
- (time_decay * 0.10)
- (enforcement_risk * 0.20)
)
liquidity = max(0.0, min(1.0, liquidity))
# Determine finance readiness status
status = claim["status"]
if liquidity >= 0.7 and P >= 0.6:
status = "finance_ready"
elif liquidity >= 0.4 and P >= 0.4:
status = "settlement_signals"
now = datetime.now(timezone.utc).isoformat()
with _db() as conn:
conn.execute(
"UPDATE claims SET liquidity_score = ?, status = ?, updated_at = ? WHERE claim_id = ?",
(liquidity, status, now, claim_id),
)
conn.commit()
return {
"claim_id": claim_id,
"liquidity_score": round(liquidity, 6),
"p_recovery": round(P, 6),
"status": status,
"components": {
"proof_density": round(proof_density, 4),
"probability_compression": round(probability_compression, 4),
"counsel_capital": round(counsel_capital, 4),
"damage_clarity": round(damage_clarity, 4),
"settlement_signal": round(settlement_signal, 4),
"contradiction_drag": round(contradiction_drag, 4),
"procedure_risk": round(procedure_risk, 4),
"time_decay": round(time_decay, 4),
"enforcement_risk": round(enforcement_risk, 4),
},
"computed_at": now,
}
# ── Membra Pixelator / GlyphIndex ───────────────────────────────
class MembraPixelator:
"""Ingests HTML, tokenizes to glyph units, computes semantic density per character.
All weights and lexicons are loaded from DB β€” no hardcoded runtime values."""
@classmethod
def _load_dom_weights(cls) -> dict[str, float]:
with _db() as conn:
rows = conn.execute("SELECT tag, weight FROM dom_weights").fetchall()
return {r["tag"]: r["weight"] for r in rows} if rows else {"p": 1.0}
@classmethod
def _load_lexicon(cls, category: str) -> set[str]:
with _db() as conn:
rows = conn.execute(
"SELECT term FROM semantic_lexicon WHERE category = ? AND confidence >= 0.3",
(category,),
).fetchall()
return {r["term"] for r in rows}
@classmethod
def ingest(cls, html: str, url: str, website_id: str, title: str = "") -> dict:
"""Parse HTML into glyph units and compute page activation."""
from bs4 import BeautifulSoup
import hashlib
now = datetime.now(timezone.utc).isoformat()
page_id = f"page_{uuid.uuid4().hex[:16]}"
version_id = 1
soup = BeautifulSoup(html, "html.parser")
page_title = title or (soup.title.string if soup.title else "")
# Strip script/style
for tag in soup(["script", "style", "noscript", "iframe"]):
tag.decompose()
# Extract text blocks with DOM paths
blocks = []
for elem in soup.find_all(text=True):
parent = elem.parent
if not parent or not elem.strip():
continue
dom_path = " > ".join([a.name for a in elem.parents if a.name]) + f" > {parent.name}"
text = str(elem).strip()
if text:
blocks.append({"text": text, "dom_path": dom_path, "tag": parent.name})
# Load learned weights and lexicons from DB (once per ingest)
dom_weights = cls._load_dom_weights()
entity_lex = cls._load_lexicon("entity")
action_lex = cls._load_lexicon("action")
commercial_lex = cls._load_lexicon("commercial")
legal_lex = cls._load_lexicon("legal")
# Paragraph-level tokenization
all_glyphs = []
paragraph_pos = 0
total_entity_score = 0.0
total_action_score = 0.0
total_commercial_score = 0.0
total_legal_score = 0.0
for block in blocks:
text = block["text"]
dom_path = block["dom_path"]
tag = block.get("tag", "span")
dom_weight = dom_weights.get(tag, 0.5)
# Split into sentences (simple heuristic)
sentences = [s.strip() for s in re.split(r'[.!?]+', text) if s.strip()]
for sentence_pos, sentence in enumerate(sentences):
# Tokenize words
tokens = re.findall(r"[A-Za-z]+|[^A-Za-z\s]", sentence)
for token_pos, token in enumerate(tokens):
token_lower = token.lower()
is_entity = token_lower in entity_lex
is_action = token_lower in action_lex
is_commercial = token_lower in commercial_lex
is_legal = token_lower in legal_lex
# Compute per-character scores
for char_index, char in enumerate(token):
char_case = "upper" if char.isupper() else "lower"
# Base semantic density from DOM weight and position
base_density = dom_weight * (1.0 + 0.1 * sentence_pos)
# Capital bonus (entity indicator)
case_bonus = 0.3 if char_case == "upper" else 0.0
# Proximity scores
entity_prox = 1.0 if is_entity else 0.1
action_prox = 1.0 if is_action else 0.1
commercial_prox = 1.0 if is_commercial else 0.1
legal_prox = 1.0 if is_legal else 0.1
semantic_density = base_density + case_bonus + (entity_prox * 0.2) + (action_prox * 0.15)
semantic_density = min(10.0, semantic_density)
# Determine roles
if is_entity:
semantic_role = "entity"
activation_role = "signal"
elif is_action:
semantic_role = "action"
activation_role = "event"
elif is_commercial:
semantic_role = "commercial"
activation_role = "value"
elif is_legal:
semantic_role = "legal"
activation_role = "risk"
else:
semantic_role = "body"
activation_role = "neutral"
# Compute proof hash for this glyph
proof_input = f"{page_id}:{paragraph_pos}:{sentence_pos}:{token_pos}:{char_index}:{char}:{now}"
proof_hash = hashlib.sha256(proof_input.encode("utf-8")).hexdigest()
glyph_id = f"glyph_{uuid.uuid4().hex[:12]}"
glyph = {
"glyph_id": glyph_id,
"page_id": page_id,
"website_id": website_id,
"version_id": version_id,
"dom_path": dom_path,
"paragraph_pos": paragraph_pos,
"sentence_pos": sentence_pos,
"token_pos": token_pos,
"char_index": char_index,
"char_value": char,
"char_case": char_case,
"semantic_role": semantic_role,
"activation_role": activation_role,
"proof_hash": proof_hash,
"semantic_density": round(semantic_density, 6),
"glyph_value": 0.0, # computed after page activation
"entity_proximity": round(entity_prox, 4),
"action_proximity": round(action_prox, 4),
"commercial_proximity": round(commercial_prox, 4),
"legal_proximity": round(legal_prox, 4),
"timestamp": now,
}
all_glyphs.append(glyph)
total_entity_score += entity_prox
total_action_score += action_prox
total_commercial_score += commercial_prox
total_legal_score += legal_prox
paragraph_pos += 1
# Compute page activation value
if all_glyphs:
avg_density = sum(g["semantic_density"] for g in all_glyphs) / len(all_glyphs)
entity_count = sum(1 for g in all_glyphs if g["semantic_role"] == "entity")
action_count = sum(1 for g in all_glyphs if g["semantic_role"] == "action")
else:
avg_density = 0.0
entity_count = 0
action_count = 0
page_activation = avg_density * (1 + 0.01 * entity_count) * (1 + 0.01 * action_count)
page_activation = min(100.0, page_activation)
# Compute final glyph values: GlyphValue = PageActivationValue Γ— GlyphContributionWeight
for g in all_glyphs:
contribution_weight = g["semantic_density"] / max(avg_density, 0.001)
g["glyph_value"] = round(page_activation * contribution_weight, 6)
# Persist to database
with _db() as conn:
conn.execute(
"""INSERT INTO pages (page_id, website_id, url, title, page_activation_value,
semantic_density, entity_count, action_count, commercial_score, legal_score,
version_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(page_id, website_id, url, page_title, round(page_activation, 6), round(avg_density, 6),
entity_count, action_count, round(total_commercial_score, 4), round(total_legal_score, 4),
version_id, now),
)
for g in all_glyphs:
conn.execute(
"""INSERT INTO glyph_units (glyph_id, page_id, website_id, version_id, dom_path,
paragraph_pos, sentence_pos, token_pos, char_index, char_value, char_case,
semantic_role, activation_role, proof_hash, semantic_density, glyph_value,
entity_proximity, action_proximity, commercial_proximity, legal_proximity, timestamp)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(g["glyph_id"], g["page_id"], g["website_id"], g["version_id"], g["dom_path"],
g["paragraph_pos"], g["sentence_pos"], g["token_pos"], g["char_index"], g["char_value"],
g["char_case"], g["semantic_role"], g["activation_role"], g["proof_hash"],
g["semantic_density"], g["glyph_value"], g["entity_proximity"], g["action_proximity"],
g["commercial_proximity"], g["legal_proximity"], g["timestamp"]),
)
conn.commit()
return {
"page_id": page_id,
"website_id": website_id,
"url": url,
"title": page_title,
"glyph_count": len(all_glyphs),
"page_activation_value": round(page_activation, 6),
"semantic_density": round(avg_density, 6),
"entity_count": entity_count,
"action_count": action_count,
"version_id": version_id,
"created_at": now,
}
@classmethod
def get_page_glyphs(cls, page_id: str, limit: int = 1000, offset: int = 0) -> list:
"""Retrieve glyph units for a page."""
with _db() as conn:
rows = conn.execute(
"""SELECT * FROM glyph_units WHERE page_id = ?
ORDER BY paragraph_pos, sentence_pos, token_pos, char_index
LIMIT ? OFFSET ?""",
(page_id, limit, offset),
).fetchall()
return [dict(r) for r in rows]
@classmethod
def get_page_activation(cls, page_id: str) -> dict:
"""Get page activation summary."""
with _db() as conn:
page = conn.execute("SELECT * FROM pages WHERE page_id = ?", (page_id,)).fetchone()
if not page:
raise ValueError(f"Page not found: {page_id}")
glyphs = conn.execute(
"SELECT COUNT(*) AS c, AVG(glyph_value) AS avg_val, MAX(glyph_value) AS max_val FROM glyph_units WHERE page_id = ?",
(page_id,),
).fetchone()
return {
"page": dict(page),
"glyph_count": glyphs["c"],
"avg_glyph_value": round(glyphs["avg_val"] or 0, 6),
"max_glyph_value": round(glyphs["max_val"] or 0, 6),
}
@classmethod
def get_top_glyphs(cls, website_id: str, limit: int = 50) -> list:
"""Get highest-value glyphs across a website."""
with _db() as conn:
rows = conn.execute(
"""SELECT * FROM glyph_units WHERE website_id = ?
ORDER BY glyph_value DESC LIMIT ?""",
(website_id, limit),
).fetchall()
return [dict(r) for r in rows]
@classmethod
def compute_glyph_value(cls, glyph: dict, page_activation: float) -> float:
"""Formula: GlyphValue = PageActivationValue Γ— GlyphContributionWeight."""
density = glyph.get("semantic_density", 0.0)
# Contribution weight is normalized semantic density
contribution = density / max(1.0, density)
return round(page_activation * contribution, 6)
# ── GA-RL Crawler ───────────────────────────────────────────────
class RotatorBuffer:
"""Fixed-size ring buffer for crawl queue management."""
def __init__(self, capacity: int = 100):
self.capacity = capacity
self._buffer = []
self._head = 0
self._tail = 0
self._size = 0
def push(self, item: dict) -> dict | None:
"""Add item; return evicted item if buffer was full."""
evicted = None
if self._size >= self.capacity:
evicted = self._buffer[self._head]
self._buffer[self._head] = item
self._head = (self._head + 1) % self.capacity
self._tail = (self._tail + 1) % self.capacity
else:
idx = self._tail
if idx < len(self._buffer):
self._buffer[idx] = item
else:
self._buffer.append(item)
self._tail = (self._tail + 1) % self.capacity
self._size += 1
return evicted
def pop(self) -> dict | None:
"""Remove and return oldest item."""
if self._size == 0:
return None
item = self._buffer[self._head]
self._head = (self._head + 1) % self.capacity
self._size -= 1
return item
def peek(self) -> dict | None:
if self._size == 0:
return None
return self._buffer[self._head]
def to_list(self) -> list:
if self._size == 0:
return []
if self._head < self._tail:
return self._buffer[self._head:self._tail]
return self._buffer[self._head:] + self._buffer[:self._tail]
def __len__(self) -> int:
return self._size
class RLPolicy:
"""Epsilon-greedy Q-table for website selection."""
def __init__(self, epsilon: float | None = None, alpha: float | None = None, gamma: float | None = None):
# Load from env; no hardcoded runtime defaults
self.epsilon = epsilon if epsilon is not None else float(os.environ.get("CRAWLER_RL_EPSILON", "0.3"))
self.alpha = alpha if alpha is not None else float(os.environ.get("CRAWLER_RL_ALPHA", "0.1"))
self.gamma = gamma if gamma is not None else float(os.environ.get("CRAWLER_RL_GAMMA", "0.9"))
def select(self, websites: list[dict]) -> dict | None:
"""Epsilon-greedy selection from website list."""
if not websites:
return None
active = [w for w in websites if w.get("is_active", 1)]
if not active:
return None
import random
if random.random() < self.epsilon:
return random.choice(active)
# Greedy: pick highest q_value
best = max(active, key=lambda w: w.get("q_value", 0.0))
return best
def update(self, website_id: str, reward: float) -> None:
"""Q-learning update: Q(s) = Q(s) + alpha * (reward + gamma * maxQ' - Q(s))."""
with _db() as conn:
row = conn.execute(
"SELECT q_value FROM crawl_policy WHERE website_id = ?", (website_id,)
).fetchone()
old_q = row["q_value"] if row else 0.0
# For a single-state problem (just website selection), maxQ' = old_q
new_q = old_q + self.alpha * (reward + self.gamma * old_q - old_q)
new_q = round(new_q, 6)
if row:
conn.execute(
"UPDATE crawl_policy SET q_value = ?, visit_count = visit_count + 1, updated_at = ? WHERE website_id = ?",
(new_q, datetime.now(timezone.utc).isoformat(), website_id),
)
else:
conn.execute(
"""INSERT INTO crawl_policy (policy_id, website_id, q_value, visit_count, epsilon, alpha, gamma, updated_at)
VALUES (?, ?, ?, 1, ?, ?, ?, ?)""",
(f"pol_{uuid.uuid4().hex[:12]}", website_id, new_q, self.epsilon, self.alpha, self.gamma,
datetime.now(timezone.utc).isoformat()),
)
conn.commit()
class GeneticSelector:
"""GA for evolving the target website population based on fitness."""
@classmethod
def _mutation_rate(cls) -> float:
return float(os.environ.get("CRAWLER_GA_MUTATION", "0.15"))
@classmethod
def _crossover_rate(cls) -> float:
return float(os.environ.get("CRAWLER_GA_CROSSOVER", "0.7"))
@classmethod
def _elite_ratio(cls) -> float:
return float(os.environ.get("CRAWLER_GA_ELITE", "0.2"))
@classmethod
def fitness(cls, target: dict) -> float:
"""Fitness = avg_glyph_value * success_rate * log(crawl_count + 1)."""
avg_gv = target.get("avg_glyph_value", 0.0)
crawls = max(target.get("crawl_count", 1), 1)
successes = target.get("success_count", 0)
success_rate = successes / crawls
return avg_gv * success_rate * (1 + 0.1 * math.log(crawls + 1))
@classmethod
def evolve(cls, population: list[dict], generation: int = 0) -> list[dict]:
"""Run one generation of selection + crossover + mutation."""
import random
if len(population) < 4:
return population
# Sort by fitness descending
scored = [(t, cls.fitness(t)) for t in population]
scored.sort(key=lambda x: x[1], reverse=True)
# Elitism: keep top performers
elite_count = max(1, int(len(scored) * cls._elite_ratio()))
new_pop = [dict(s[0]) for s in scored[:elite_count]]
# Generate offspring via crossover + mutation
while len(new_pop) < len(population):
p1, p2 = random.choices(scored, weights=[max(s[1], 0.01) for s in scored], k=2)
child = cls._crossover(p1[0], p2[0])
child = cls._mutate(child, generation)
child["fitness_score"] = round(cls.fitness(child), 6)
new_pop.append(child)
return new_pop[:len(population)]
@classmethod
def _crossover(cls, a: dict, b: dict) -> dict:
import random
child = dict(a)
if random.random() < cls._crossover_rate():
# Blend priority and crawl_depth
child["priority"] = round((a.get("priority", 1.0) + b.get("priority", 1.0)) / 2, 4)
child["crawl_depth"] = max(1, int((a.get("crawl_depth", 2) + b.get("crawl_depth", 2)) / 2))
return child
@classmethod
def _mutate(cls, child: dict, generation: int) -> dict:
import random
if random.random() < cls._mutation_rate():
delta = random.uniform(-0.5, 0.5)
child["priority"] = round(max(0.1, child.get("priority", 1.0) + delta), 4)
if random.random() < cls._mutation_rate():
delta = random.randint(-1, 1)
child["crawl_depth"] = max(1, min(5, child.get("crawl_depth", 2) + delta))
child["generation"] = generation
return child
class GARLCrawler:
"""Genetic Algorithm + Reinforcement Learning web crawler with rotator buffer."""
def __init__(self, buffer_capacity: int = 200):
self.buffer = RotatorBuffer(capacity=buffer_capacity)
self.policy = RLPolicy()
self.selector = GeneticSelector()
self._gen_count = 0
def add_target(self, website_id: str, root_url: str, name: str = "", depth: int = 2, priority: float = 1.0, selector_rules: str = "") -> dict:
"""Register a new crawl target website."""
now = datetime.now(timezone.utc).isoformat()
target_id = f"target_{uuid.uuid4().hex[:12]}"
with _db() as conn:
try:
conn.execute(
"""INSERT INTO crawl_targets (target_id, website_id, root_url, name, priority, crawl_depth, selector_rules, is_active, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, 1, ?)""",
(target_id, website_id, root_url, name or website_id, priority, depth, selector_rules or "", now),
)
# Ensure policy row exists
conn.execute(
"""INSERT OR IGNORE INTO crawl_policy (policy_id, website_id, q_value, epsilon, alpha, gamma, updated_at)
VALUES (?, ?, 0.0, ?, ?, ?, ?)""",
(f"pol_{uuid.uuid4().hex[:12]}", website_id, self.policy.epsilon, self.policy.alpha, self.policy.gamma, now),
)
conn.commit()
except sqlite3.IntegrityError:
raise ValueError(f"Website already exists: {website_id}")
return {"target_id": target_id, "website_id": website_id, "root_url": root_url}
def enqueue(self, target_id: str, url: str, depth: int = 0, priority_score: float = 0.0) -> dict:
"""Add URL to rotator buffer and DB queue."""
queue_id = f"q_{uuid.uuid4().hex[:12]}"
now = datetime.now(timezone.utc).isoformat()
item = {"queue_id": queue_id, "target_id": target_id, "url": url, "depth": depth,
"priority_score": priority_score, "status": "pending", "added_at": now}
evicted = self.buffer.push(item)
with _db() as conn:
conn.execute(
"""INSERT INTO crawl_queue (queue_id, target_id, url, status, priority_score, q_value, depth, added_at)
VALUES (?, ?, ?, 'pending', ?, ?, ?, ?)""",
(queue_id, target_id, url, priority_score, priority_score, depth, now),
)
conn.commit()
return {"queue_id": queue_id, "evicted": evicted}
def select_next(self) -> dict | None:
"""RL-based selection: pick a website, then pop oldest pending URL from buffer."""
with _db() as conn:
rows = conn.execute("SELECT * FROM crawl_targets WHERE is_active = 1").fetchall()
websites = [dict(r) for r in rows]
selected_website = self.policy.select(websites)
if not selected_website:
return None
# Find oldest pending item for this website in buffer
for item in self.buffer.to_list():
if item.get("status") == "pending":
# Match by target_id
target_id = item.get("target_id")
# Verify this target belongs to selected website
with _db() as conn:
t = conn.execute("SELECT website_id FROM crawl_targets WHERE target_id = ?", (target_id,)).fetchone()
if t and t["website_id"] == selected_website["website_id"]:
return item
# If no buffered item, try DB queue
with _db() as conn:
row = conn.execute(
"""SELECT * FROM crawl_queue WHERE target_id IN
(SELECT target_id FROM crawl_targets WHERE website_id = ?)
AND status = 'pending' ORDER BY added_at LIMIT 1""",
(selected_website["website_id"],),
).fetchone()
if row:
return dict(row)
return None
def ingest_url(self, url: str, target_id: str, queue_id: str, wallet: str = "") -> dict:
"""Fetch URL, pixelate HTML, record result, update RL reward."""
import time
import urllib.request
start_ms = int(time.time() * 1000)
now = datetime.now(timezone.utc).isoformat()
result_id = f"res_{uuid.uuid4().hex[:12]}"
try:
# Simple fetch with timeout
req = urllib.request.Request(url, headers={"User-Agent": "MembraBot/1.0"})
with urllib.request.urlopen(req, timeout=15) as resp:
html = resp.read().decode("utf-8", errors="replace")
final_url = resp.geturl()
except Exception as e:
with _db() as conn:
conn.execute(
"UPDATE crawl_queue SET status = 'failed', error_msg = ?, completed_at = ? WHERE queue_id = ?",
(str(e), now, queue_id),
)
conn.execute(
"""INSERT INTO crawl_results (result_id, queue_id, target_id, page_id, url, status, reward, crawled_at)
VALUES (?, ?, ?, ?, ?, 'failed', 0.0, ?)""",
(result_id, queue_id, target_id, "", url, now),
)
conn.commit()
return {"status": "failed", "error": str(e), "url": url}
# Get website_id
with _db() as conn:
trow = conn.execute("SELECT website_id FROM crawl_targets WHERE target_id = ?", (target_id,)).fetchone()
website_id = trow["website_id"] if trow else "unknown"
# Pixelate
px_result = MembraPixelator.ingest(html, final_url, website_id)
page_id = px_result["page_id"]
reward = px_result.get("page_activation_value", 0.0) + (px_result.get("glyph_count", 0) * 0.001)
reward = round(reward, 6)
elapsed = int(time.time() * 1000) - start_ms
with _db() as conn:
conn.execute(
"UPDATE crawl_queue SET status = 'completed', page_id = ?, reward = ?, completed_at = ? WHERE queue_id = ?",
(page_id, reward, now, queue_id),
)
conn.execute(
"""INSERT INTO crawl_results (result_id, queue_id, target_id, page_id, url, status, glyph_count,
page_activation, avg_glyph_value, reward, crawl_time_ms, crawled_at)
VALUES (?, ?, ?, ?, ?, 'completed', ?, ?, ?, ?, ?, ?)""",
(result_id, queue_id, target_id, page_id, final_url, px_result.get("glyph_count", 0),
px_result.get("page_activation_value", 0.0), px_result.get("semantic_density", 0.0),
reward, elapsed, now),
)
# Update target stats
conn.execute(
"""UPDATE crawl_targets SET crawl_count = crawl_count + 1, success_count = success_count + 1,
last_crawled = ?, avg_glyph_value =
(avg_glyph_value * (crawl_count) + ?) / (crawl_count + 1)
WHERE target_id = ?""",
(now, px_result.get("semantic_density", 0.0), target_id),
)
conn.commit()
# RL update
self.policy.update(website_id, reward)
return {
"status": "completed",
"url": final_url,
"page_id": page_id,
"glyph_count": px_result.get("glyph_count"),
"page_activation": px_result.get("page_activation_value"),
"reward": reward,
"crawl_time_ms": elapsed,
}
def run_evolution(self) -> dict:
"""Run one GA generation on active targets."""
with _db() as conn:
rows = conn.execute("SELECT * FROM crawl_targets WHERE is_active = 1").fetchall()
population = [dict(r) for r in rows]
self._gen_count += 1
evolved = self.selector.evolve(population, generation=self._gen_count)
with _db() as conn:
for target in evolved:
conn.execute(
"UPDATE crawl_targets SET priority = ?, fitness_score = ?, crawl_depth = ? WHERE target_id = ?",
(target.get("priority", 1.0), target.get("fitness_score", 0.0), target.get("crawl_depth", 2), target.get("target_id")),
)
conn.execute(
"UPDATE crawl_policy SET generation = ? WHERE generation < ?",
(self._gen_count, self._gen_count),
)
conn.commit()
return {"generation": self._gen_count, "population_size": len(evolved)}
def get_queue(self, limit: int = 100) -> list:
with _db() as conn:
rows = conn.execute(
"SELECT * FROM crawl_queue ORDER BY added_at DESC LIMIT ?", (limit,)
).fetchall()
return [dict(r) for r in rows]
def get_results(self, website_id: str | None = None, limit: int = 100) -> list:
with _db() as conn:
if website_id:
rows = conn.execute(
"SELECT * FROM crawl_results WHERE target_id IN (SELECT target_id FROM crawl_targets WHERE website_id = ?) ORDER BY crawled_at DESC LIMIT ?",
(website_id, limit),
).fetchall()
else:
rows = conn.execute(
"SELECT * FROM crawl_results ORDER BY crawled_at DESC LIMIT ?", (limit,)
).fetchall()
return [dict(r) for r in rows]
def get_policy(self) -> list:
with _db() as conn:
rows = conn.execute(
"SELECT * FROM crawl_policy ORDER BY q_value DESC"
).fetchall()
return [dict(r) for r in rows]
# ── Wallet Signature Verification ────────────────────────────────
def _verify_evm_signature(address: str, signature: str, nonce: str) -> bool:
try:
from eth_account import Account
from eth_account.messages import encode_defunct
message = f"HF VM Studio auth: {nonce}"
encoded = encode_defunct(text=message)
recovered = Account.recover_message(encoded, signature_bytes=bytes.fromhex(signature.removeprefix("0x")))
return recovered.lower() == address.lower()
except Exception as e:
logger.warning(f"EVM signature verification failed: {e}")
return False
def _verify_solana_signature(address: str, signature: str, nonce: str) -> bool:
try:
import nacl.signing
import nacl.exceptions
import base64
import base58
message = f"HF VM Studio auth: {nonce}".encode("utf-8")
# Decode address from base58 (Solana public key format)
pub_key_bytes = base58.b58decode(address)
# Signature may be base58 or base64 encoded
try:
sig_bytes = base58.b58decode(signature)
except Exception:
sig_bytes = base64.b64decode(signature)
verify_key = nacl.signing.VerifyKey(pub_key_bytes)
verify_key.verify(message, sig_bytes)
return True
except nacl.exceptions.BadSignatureError:
return False
except Exception as e:
logger.warning(f"Solana signature verification failed: {e}")
return False
def _nonce() -> str:
return hashlib.sha256(os.urandom(32)).hexdigest()[:24]
# ── Rate Limiting ──────────────────────────────────────────────
_rate_buckets: Dict[str, list] = {}
_rate_lock = threading.RLock()
def _rate_check(key: str, window: int = 60, max_requests: int = 30) -> bool:
now = time.time()
with _rate_lock:
# Periodic cleanup: purge stale keys every ~1000 calls
if len(_rate_buckets) > 2000 and hash(key) % 100 == 0:
stale = [k for k, v in _rate_buckets.items() if v and now - v[-1] > window * 2]
for k in stale:
del _rate_buckets[k]
bucket = _rate_buckets.get(key, [])
bucket = [t for t in bucket if now - t < window]
if len(bucket) >= max_requests:
return False
bucket.append(now)
_rate_buckets[key] = bucket
return True
def rate_limit_response():
return jsonify({"error": "Rate limit exceeded. Slow down."}), 429
# ── Helpers ─────────────────────────────────────────────────────
def save_state():
state["last_check"] = datetime.now(timezone.utc).isoformat()
with open(STATE_PATH, "w") as f:
json.dump(state, f, indent=2)
def load_config():
global tasks
if CONFIG_PATH.exists():
with open(CONFIG_PATH) as f:
tasks = json.load(f).get("tasks", {})
else:
tasks = {}
CONFIG_PATH.write_text(json.dumps({"tasks": {}}, indent=2))
def load_memory():
global memories
if MEMORY_PATH.exists():
try:
memories = json.loads(MEMORY_PATH.read_text()).get("memories", {})
except Exception:
logger.exception("Failed to load memory store")
memories = {}
else:
memories = {}
save_memory()
def save_memory():
with memory_lock:
MEMORY_PATH.write_text(json.dumps({"memories": memories}, indent=2))
def load_apps():
global apps
if APPS_PATH.exists():
try:
raw = json.loads(APPS_PATH.read_text()).get("apps", {})
apps = {}
for app_id, item in raw.items():
item["_popen"] = None
item["status"] = "stopped"
item.setdefault("stdout", "")
item.setdefault("stderr", "")
apps[app_id] = item
except Exception:
logger.exception("Failed to load generated apps")
apps = {}
else:
apps = {}
save_apps()
def save_apps():
with app_lock:
serializable = {}
for app_id, item in apps.items():
serializable[app_id] = {k: v for k, v in item.items() if k != "_popen"}
APPS_PATH.write_text(json.dumps({"apps": serializable}, indent=2))
def load_receipts():
global receipts
if RECEIPTS_PATH.exists():
try:
receipts = json.loads(RECEIPTS_PATH.read_text()).get("receipts", {})
except Exception:
logger.exception("Failed to load receipts store")
receipts = {}
else:
receipts = {}
save_receipts()
def save_receipts():
with receipt_lock:
RECEIPTS_PATH.write_text(json.dumps({"receipts": receipts}, indent=2))
def default_settings() -> dict:
default_api_base = os.environ.get("LLM_API_BASE", "https://api.openai.com/v1")
default_model = os.environ.get("LLM_MODEL", "gpt-4o-mini")
if os.environ.get("GROQ_API_KEY"):
default_api_base = "https://api.groq.com/openai/v1"
default_model = os.environ.get("LLM_MODEL", "llama-3.1-8b-instant")
elif os.environ.get("OPENROUTER_API_KEY"):
default_api_base = "https://openrouter.ai/api/v1"
default_model = os.environ.get("LLM_MODEL", "openai/gpt-4o-mini")
return {
"cwd": str(DEFAULT_CWD),
"max_timeout": MAX_COMMAND_TIMEOUT,
"env": {},
"llm": {
"api_base": default_api_base,
"model": default_model,
},
"deploy": {
"vercel_project_dir": "/app",
"netlify_project_dir": "/app",
"netlify_publish_dir": "/app",
},
}
def load_settings():
global settings
if SETTINGS_PATH.exists():
try:
loaded = json.loads(SETTINGS_PATH.read_text())
base = default_settings()
base.update({k: v for k, v in loaded.items() if isinstance(v, dict) or k in {"cwd", "max_timeout"}})
base["env"].update(loaded.get("env", {}))
base["llm"].update(loaded.get("llm", {}))
base["deploy"].update(loaded.get("deploy", {}))
settings = base
except Exception:
logger.exception("Failed to load settings")
settings = default_settings()
else:
settings = default_settings()
save_settings()
def save_settings():
with settings_lock:
SETTINGS_PATH.write_text(json.dumps(settings, indent=2))
def redacted_settings() -> dict:
with settings_lock:
data = json.loads(json.dumps(settings))
redacted_env = {}
for key, value in data.get("env", {}).items():
if any(word in key.upper() for word in ["TOKEN", "KEY", "SECRET", "PASSWORD"]):
redacted_env[key] = {"configured": bool(value), "redacted": True}
else:
redacted_env[key] = value
data["env"] = redacted_env
return data
def runtime_env(extra: Optional[dict] = None) -> dict:
env = os.environ.copy()
env.update({k: str(v) for k, v in settings.get("env", {}).items() if v is not None})
if extra:
env.update({k: str(v) for k, v in extra.items() if v is not None})
return env
def runtime_cwd(cwd: Optional[str] = None) -> str:
return cwd or settings.get("cwd") or str(DEFAULT_CWD)
def add_memory(
title: str,
content: str,
source: str = "manual",
tags: Optional[list] = None,
metadata: Optional[dict] = None,
importance: float = 0.5,
) -> dict:
with memory_lock:
memory_id = f"mem_{uuid.uuid4().hex[:16]}"
item = {
"memory_id": memory_id,
"title": title[:240],
"content": content[:20000],
"source": source,
"tags": tags or [],
"metadata": metadata or {},
"importance": max(0.0, min(float(importance), 1.0)),
"created_at": datetime.now(timezone.utc).isoformat(),
"access_count": 0,
"tombstone_at": None,
}
memories[memory_id] = item
save_memory()
return item
def memory_text(memory: dict) -> str:
return " ".join([
memory.get("title", ""),
memory.get("content", ""),
" ".join(memory.get("tags", [])),
json.dumps(memory.get("metadata", {}), sort_keys=True),
]).lower()
def search_memory(query: str, limit: int = 8) -> list:
terms = [term for term in query.lower().split() if term]
with memory_lock:
results = []
for memory in memories.values():
if memory.get("tombstone_at"):
continue
text = memory_text(memory)
matches = sum(text.count(term) for term in terms) if terms else 1
if matches <= 0:
continue
score = matches + memory.get("importance", 0.5) + memory.get("access_count", 0) * 0.05
result = dict(memory)
result["score"] = round(score, 4)
results.append(result)
results.sort(key=lambda item: item["score"], reverse=True)
results = results[:limit]
for result in results:
memories[result["memory_id"]]["access_count"] += 1
if results:
save_memory()
return results
def sha256_text(value: str) -> str:
return hashlib.sha256(value.encode("utf-8", errors="replace")).hexdigest()
def redact_command_secret(command: str, secret: str = "") -> str:
if secret:
return command.replace(secret, "[redacted]")
return command
def app_file_manifest(app_record: dict) -> list:
manifest = []
app_dir = Path(app_record.get("path", ""))
for file_name in app_record.get("files", []):
try:
file_path = safe_app_file(app_dir, file_name)
content = file_path.read_text() if file_path.exists() else ""
manifest.append({
"path": file_name,
"sha256": sha256_text(content),
"bytes": len(content.encode("utf-8", errors="replace")),
})
except Exception as e:
manifest.append({"path": file_name, "error": str(e)})
return manifest
def create_receipt(
kind: str,
title: str,
status: str = "recorded",
prompt: str = "",
app_record: Optional[dict] = None,
model: Optional[dict] = None,
command: str = "",
process: Optional[dict] = None,
deployment: Optional[dict] = None,
metadata: Optional[dict] = None,
) -> dict:
"""Create a cryptographically-verifiable receipt. Receipt ID is SHA-256 of payload."""
prompt = prompt or ""
app_copy = redact_app(app_record) if app_record else None
manifest = app_file_manifest(app_copy) if app_copy else []
now = datetime.now(timezone.utc).isoformat()
# Build payload without receipt_id so hash is deterministic
payload = {
"kind": kind,
"title": title[:240],
"status": status,
"created_at": now,
"prompt_hash": sha256_text(prompt) if prompt else None,
"prompt_excerpt": prompt[:1200] if prompt else "",
"model": model or {},
"app": app_copy,
"app_id": app_copy.get("app_id") if app_copy else None,
"proxy_url": app_copy.get("proxy_url") if app_copy else None,
"files": manifest,
"files_hash": sha256_text(json.dumps(manifest, sort_keys=True)) if manifest else None,
"command": command,
"process": redact_process(process) if process else {},
"deployment": deployment or {},
"metadata": metadata or {},
}
# Cryptographic receipt ID: SHA-256 of canonical JSON payload
payload_bytes = json.dumps(payload, sort_keys=True, ensure_ascii=True).encode("utf-8")
receipt_hash = hashlib.sha256(payload_bytes).hexdigest()
receipt_id = f"rcpt_{receipt_hash[:32]}"
receipt = {"receipt_id": receipt_id, **payload}
with receipt_lock:
receipts[receipt_id] = receipt
save_receipts()
memory = add_memory(
title=f"Receipt: {title[:100]}",
content=json.dumps(receipt, indent=2),
source="receipt",
tags=["receipt", kind, "provenance"],
metadata={"receipt_id": receipt_id, "app_id": receipt.get("app_id")},
importance=0.9,
)
receipt["memory_id"] = memory["memory_id"]
with receipt_lock:
receipts[receipt_id] = receipt
save_receipts()
return receipt
def attach_receipt_to_app(app_id: str, receipt_id: str):
with app_lock:
if app_id in apps:
apps[app_id]["receipt_id"] = receipt_id
save_apps()
def receipt_text(receipt: dict) -> str:
return json.dumps(receipt, sort_keys=True).lower()
def search_receipts(query: str, limit: int = 20) -> list:
terms = [term for term in query.lower().split() if term]
with receipt_lock:
results = []
for receipt in receipts.values():
text = receipt_text(receipt)
matches = sum(text.count(term) for term in terms) if terms else 1
if matches <= 0:
continue
item = dict(receipt)
item["score"] = matches
results.append(item)
results.sort(key=lambda item: (item["score"], item.get("created_at", "")), reverse=True)
return results[:limit]
def get_uptime() -> str:
if not state.get("start_time"):
return "N/A"
start = datetime.fromisoformat(state["start_time"])
uptime = datetime.now(timezone.utc) - start
return f"{uptime.days}d {uptime.seconds // 3600}h {(uptime.seconds % 3600) // 60}m"
def bounded_timeout(value, default=60) -> int:
try:
timeout = int(value)
except Exception:
timeout = default
configured_max = int(settings.get("max_timeout", MAX_COMMAND_TIMEOUT)) if settings else MAX_COMMAND_TIMEOUT
return max(1, min(timeout, configured_max))
def generate_inference_proof(
model: str,
prompt: str,
response: str,
provider: str,
api_base: str,
latency_ms: float,
input_tokens: int,
output_tokens: int,
) -> dict:
"""Generate a cryptographically verifiable Proof of Inference (PoI).
Every LLM call gets a SHA-256 receipt of its inputs and outputs.
"""
now = datetime.now(timezone.utc).isoformat()
payload = {
"model": model,
"provider": provider,
"api_base": api_base,
"prompt_hash": hashlib.sha256(prompt.encode("utf-8")).hexdigest(),
"response_hash": hashlib.sha256(response.encode("utf-8")).hexdigest(),
"latency_ms": latency_ms,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"timestamp": now,
}
payload_bytes = json.dumps(payload, sort_keys=True, ensure_ascii=True).encode("utf-8")
proof_hash = hashlib.sha256(payload_bytes).hexdigest()
proof_id = f"poi_{proof_hash[:32]}"
return {
"proof_id": proof_id,
"proof_hash": proof_hash,
"prompt_hash": payload["prompt_hash"],
"response_hash": payload["response_hash"],
"timestamp": now,
"verified": True,
}
def _reward_idempotency_key(wallet: str, action: str, amount: int, data: dict) -> str:
"""Deterministic idempotency key based on wallet + action + request payload hash."""
payload_fields = ["command", "code", "prompt", "cells", "task", "mode"]
core = json.dumps({k: data.get(k) for k in payload_fields if data.get(k)}, sort_keys=True, separators=(",", ":"))
if not core:
core = json.dumps(data, sort_keys=True, separators=(",", ":"))
h = hashlib.sha256(f"{wallet}:{action}:{amount}:{core}".encode("utf-8")).hexdigest()[:20]
return f"reward_{h}"
def maybe_credit(data: dict, action: str, amount: int) -> Optional[dict]:
"""Credit tokens if wallet_address is present in request data. Idempotent via content hash."""
raw = str(data.get("wallet_address", "")).strip()
wallet = _normalize_wallet(raw) if raw else ""
if wallet:
ikey = data.get("idempotency_key") or _reward_idempotency_key(wallet, action, amount, data)
return credit_tokens(wallet, amount, action, idempotency_key=ikey)
return None
def run_command(cmd: str, timeout: int = 60, cwd: Optional[str] = None) -> dict:
timeout = bounded_timeout(timeout)
cwd_path = runtime_cwd(cwd)
logger.info(f"Executing: {cmd}")
try:
result = subprocess.run(
cmd,
shell=True,
capture_output=True,
text=True,
timeout=timeout,
cwd=cwd_path,
env=runtime_env(),
)
return {
"exit_code": result.returncode,
"stdout": result.stdout,
"stderr": result.stderr,
"success": result.returncode == 0,
"cwd": cwd_path,
}
except subprocess.TimeoutExpired:
return {"exit_code": -1, "stdout": "", "stderr": "Command timed out", "success": False, "cwd": cwd_path}
except Exception as e:
return {"exit_code": -1, "stdout": "", "stderr": str(e), "success": False, "cwd": cwd_path}
def is_authorized() -> bool:
if not TERMINAL_AGENT_TOKEN:
return False
token = (
request.headers.get("x-terminal-token")
or request.headers.get("authorization", "").replace("Bearer ", "", 1)
or request.args.get("token", "")
)
return token == TERMINAL_AGENT_TOKEN
def require_auth():
if not is_authorized():
return jsonify({"error": "Unauthorized"}), 401
return None
def redact_process(proc: dict) -> dict:
return {k: v for k, v in proc.items() if k != "_popen"}
def launch_background_process(cmd: str, timeout: int = 0, cwd: Optional[str] = None) -> dict:
process_id = f"proc_{uuid.uuid4().hex[:16]}"
cwd_path = runtime_cwd(cwd)
proc = subprocess.Popen(
cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
cwd=cwd_path,
env=runtime_env(),
preexec_fn=os.setsid if hasattr(os, "setsid") else None,
)
record = {
"process_id": process_id,
"pid": proc.pid,
"command": cmd,
"cwd": cwd_path,
"status": "running",
"started_at": datetime.now(timezone.utc).isoformat(),
"finished_at": None,
"exit_code": None,
"stdout": "",
"stderr": "",
"_popen": proc,
}
processes[process_id] = record
def waiter():
try:
wait_timeout = bounded_timeout(timeout) if timeout else None
stdout, stderr = proc.communicate(timeout=wait_timeout)
record.update({
"status": "finished",
"finished_at": datetime.now(timezone.utc).isoformat(),
"exit_code": proc.returncode,
"stdout": stdout,
"stderr": stderr,
})
add_memory(
title=f"Background command: {cmd[:80]}",
content=f"command: {cmd}\nstdout:\n{stdout}\nstderr:\n{stderr}",
source="background",
tags=["process", "terminal"],
metadata={"process_id": process_id, "exit_code": proc.returncode, "cwd": cwd_path},
importance=0.55,
)
except subprocess.TimeoutExpired:
try:
if hasattr(os, "killpg"):
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
else:
proc.terminate()
except Exception:
pass
stdout, stderr = proc.communicate()
record.update({
"status": "timeout",
"finished_at": datetime.now(timezone.utc).isoformat(),
"exit_code": proc.returncode,
"stdout": stdout,
"stderr": stderr + "\nProcess timed out",
})
add_memory(
title=f"Background timeout: {cmd[:80]}",
content=f"command: {cmd}\nstdout:\n{stdout}\nstderr:\n{stderr}\nProcess timed out",
source="background",
tags=["process", "timeout"],
metadata={"process_id": process_id, "exit_code": proc.returncode, "cwd": cwd_path},
importance=0.65,
)
threading.Thread(target=waiter, daemon=True).start()
return redact_process(record)
def redact_app(item: dict) -> dict:
return {k: v for k, v in item.items() if k != "_popen"}
def slugify(value: str) -> str:
slug = re.sub(r"[^a-zA-Z0-9_-]+", "-", value.strip().lower()).strip("-")
return slug[:48] or f"app-{uuid.uuid4().hex[:8]}"
def next_app_port() -> int:
used = {int(item.get("port", 0)) for item in apps.values() if item.get("port")}
port = 9000
while port in used:
port += 1
return port
def safe_app_file(app_dir: Path, rel_path: str) -> Path:
rel = Path(str(rel_path).strip().lstrip("/"))
target = (app_dir / rel).resolve()
root = app_dir.resolve()
if root != target and root not in target.parents:
raise ValueError(f"Unsafe file path: {rel_path}")
return target
def create_generated_app(data: dict) -> dict:
name = str(data.get("name") or "generated-backend")
app_id = f"{slugify(name)}-{uuid.uuid4().hex[:6]}"
app_dir = (APPS_DIR / app_id).resolve()
app_dir.mkdir(parents=True, exist_ok=True)
files = data.get("files")
if not isinstance(files, list) or not files:
return {"error": "Provide files: [{path, content}, ...]"}
written = []
for file_item in files:
path = safe_app_file(app_dir, file_item.get("path", "app.py"))
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(str(file_item.get("content", "")))
written.append(str(path.relative_to(app_dir.resolve())))
port = int(data.get("port") or next_app_port())
start_command = str(data.get("start_command") or data.get("command") or "python3 app.py")
record = {
"app_id": app_id,
"name": name,
"description": str(data.get("description") or ""),
"path": str(app_dir),
"files": written,
"port": port,
"start_command": start_command,
"status": "stopped",
"pid": None,
"stdout": "",
"stderr": "",
"created_at": datetime.now(timezone.utc).isoformat(),
"started_at": None,
"proxy_url": f"/apps/{app_id}/proxy/",
"_popen": None,
}
with app_lock:
apps[app_id] = record
save_apps()
add_memory(
title=f"Generated app: {name}",
content=json.dumps({k: v for k, v in record.items() if k != "_popen"}, indent=2),
source="app-builder",
tags=["generated-app", "vm", "backend"],
metadata={"app_id": app_id, "files": written},
importance=0.85,
)
return redact_app(record)
def stop_generated_app(app_id: str) -> dict:
record = apps.get(app_id)
if not record:
return {"error": "App not found"}
popen = record.get("_popen")
if popen and record.get("status") == "running":
try:
if hasattr(os, "killpg"):
os.killpg(os.getpgid(popen.pid), signal.SIGTERM)
else:
popen.terminate()
except Exception as e:
return {"error": str(e)}
record["status"] = "stopped"
record["pid"] = None
record["_popen"] = None
save_apps()
return redact_app(record)
def start_generated_app(app_id: str) -> tuple[dict, int]:
record = apps.get(app_id)
if not record:
return {"error": "App not found"}, 404
existing = record.get("_popen")
if existing and existing.poll() is None:
record["status"] = "running"
return redact_app(record), 200
port = int(record["port"])
proc = subprocess.Popen(
record["start_command"],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
cwd=record["path"],
env=runtime_env({"PORT": port, "HOST": "0.0.0.0"}),
preexec_fn=os.setsid if hasattr(os, "setsid") else None,
)
record.update({
"_popen": proc,
"pid": proc.pid,
"status": "running",
"started_at": datetime.now(timezone.utc).isoformat(),
"stdout": "",
"stderr": "",
})
def reader():
stdout, stderr = proc.communicate()
record["stdout"] += stdout or ""
record["stderr"] += stderr or ""
if record.get("_popen") is proc:
record["status"] = "finished" if proc.returncode == 0 else "failed"
record["pid"] = None
record["_popen"] = None
save_apps()
threading.Thread(target=reader, daemon=True).start()
save_apps()
time.sleep(0.8)
return redact_app(record), 202
def parse_llm_json(text: str) -> dict:
cleaned = text.strip()
if cleaned.startswith("```"):
cleaned = re.sub(r"^```(?:json)?\s*", "", cleaned)
cleaned = re.sub(r"\s*```$", "", cleaned)
match = re.search(r"\{.*\}", cleaned, re.DOTALL)
if match:
cleaned = match.group(0)
return json.loads(cleaned)
def fallback_app_spec(prompt: str, reason: str = "") -> dict:
marker_match = re.search(r"exact text\s+([A-Za-z0-9_.:-]+)", prompt, re.IGNORECASE)
marker = marker_match.group(1) if marker_match else "llm-generated-vm-app"
safe_prompt = json.dumps(prompt[:3000])
safe_reason = json.dumps(reason[:1000])
content = f'''import os
from flask import Flask, jsonify, request
app = Flask(__name__)
PROMPT = {safe_prompt}
BUILD_NOTE = {safe_reason}
@app.route("/")
def home():
return f"""<!doctype html>
<html><head><title>Generated VM App</title></head>
<body style="margin:0;font-family:system-ui;background:linear-gradient(135deg,#020617,#4c1d95);color:white;min-height:100vh;display:grid;place-items:center">
<main style="max-width:820px;padding:48px">
<p style="letter-spacing:.18em;text-transform:uppercase;color:#67e8f9">HF VM Studio fallback backend</p>
<h1>{marker}</h1>
<p>This app was created from your prompt and is running inside the Hugging Face VM.</p>
<form method="post" action="/api/echo"><input name="text" placeholder="send text" style="padding:12px;border:0;border-radius:10px"><button style="padding:12px 16px;border:0;border-radius:10px;margin-left:8px">Echo</button></form>
<p><a style="color:#a7f3d0" href="/api/status">/api/status</a></p>
<pre style="white-space:pre-wrap;background:rgba(255,255,255,.12);padding:16px;border-radius:14px">{{PROMPT}}</pre>
</main></body></html>"""
@app.route("/api/status")
def status():
return jsonify(ok=True, marker="{marker}", prompt=PROMPT, build_note=BUILD_NOTE, port=os.environ.get("PORT"))
@app.route("/api/echo", methods=["GET", "POST"])
def echo():
value = request.values.get("text", "")
return jsonify(ok=True, echo=value)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 9000)))
'''
return {
"name": f"fallback-{slugify(marker)}",
"description": "Runnable Flask backend generated when the LLM returned malformed app JSON.",
"start_command": "python3 app.py",
"files": [{"path": "app.py", "content": content}],
}
def normalize_generated_app_spec(app_spec: dict, prompt: str = "") -> dict:
if not isinstance(app_spec, dict):
return app_spec
files = app_spec.get("files")
if not isinstance(files, list):
return app_spec
for file_item in files:
path = str(file_item.get("path", ""))
content = str(file_item.get("content", ""))
if path.endswith(".py") and "Flask(" in content and "app.run" in content:
lines = content.splitlines()
cleaned = []
i = 0
while i < len(lines):
stripped = lines[i].strip()
next_stripped = lines[i + 1].strip() if i + 1 < len(lines) else ""
if stripped.startswith("if __name__") and "app.run" in next_stripped:
i += 2
continue
if re.match(r"^app\.run\s*\(", stripped):
i += 1
continue
cleaned.append(lines[i])
i += 1
cleaned_text = "\n".join(cleaned).rstrip()
cleaned_text += (
"\n\nif __name__ == \"__main__\":\n"
" app.run(host=\"0.0.0.0\", port=int(os.environ.get(\"PORT\", 9000)))\n"
)
if "import os" not in cleaned_text:
cleaned_text = "import os\n" + cleaned_text
prompt_routes = sorted(set(re.findall(r"(/api/[A-Za-z0-9_./-]+)", prompt or "")))
missing_routes = [route.rstrip(".") for route in prompt_routes if route.rstrip(".") not in cleaned_text]
if missing_routes:
if "jsonify" not in cleaned_text:
if "from flask import Flask" in cleaned_text:
cleaned_text = cleaned_text.replace("from flask import Flask", "from flask import Flask, jsonify", 1)
else:
cleaned_text = "from flask import jsonify\n" + cleaned_text
extra_routes = []
for route in missing_routes:
func = "generated_" + re.sub(r"[^A-Za-z0-9_]", "_", route.strip("/"))
extra_routes.append(
f'\n@app.route("{route}")\n'
f"def {func}():\n"
f' return jsonify(ok=True, path="{route}")\n'
)
marker = '\n\nif __name__ == "__main__":'
if marker in cleaned_text:
cleaned_text = cleaned_text.replace(marker, "\n".join(extra_routes) + marker, 1)
else:
cleaned_text += "\n" + "\n".join(extra_routes)
file_item["content"] = cleaned_text
app_spec["start_command"] = "python3 app.py"
if "flask run" in str(app_spec.get("start_command", "")).lower():
app_spec["start_command"] = "python3 app.py"
return app_spec
def call_llm(prompt: str, system: str = "", **options) -> dict:
llm_cfg = settings.get("llm", {})
api_base = str(options.get("api_base") or llm_cfg.get("api_base") or "https://api.openai.com/v1").rstrip("/")
model = str(options.get("model") or llm_cfg.get("model") or "gpt-4o-mini")
api_key = (
options.get("api_key")
or settings.get("env", {}).get("LLM_API_KEY")
or settings.get("env", {}).get("OPENAI_API_KEY")
or settings.get("env", {}).get("OPENROUTER_API_KEY")
or settings.get("env", {}).get("GROQ_API_KEY")
or os.environ.get("LLM_API_KEY")
or os.environ.get("OPENAI_API_KEY")
or os.environ.get("OPENROUTER_API_KEY")
or os.environ.get("GROQ_API_KEY")
)
if not api_key:
raise ValueError("No LLM API key configured.")
messages = []
if system:
messages.append({"role": "system", "content": system})
messages.append({"role": "user", "content": prompt})
payload = {
"model": model,
"messages": messages,
"temperature": float(options.get("temperature", 0.25)),
"max_tokens": int(options.get("max_tokens", 1800)),
}
if options.get("response_format"):
payload["response_format"] = options["response_format"]
response = requests.post(
f"{api_base}/chat/completions",
headers={"authorization": f"Bearer {api_key}", "content-type": "application/json"},
json=payload,
timeout=bounded_timeout(options.get("timeout", 90)),
)
result = response.json()
content = ""
try:
content = result["choices"][0]["message"]["content"]
except Exception:
pass
usage = result.get("usage", {})
input_tokens = usage.get("prompt_tokens", 0) or usage.get("input_tokens", 0) or len(prompt) // 4
output_tokens = usage.get("completion_tokens", 0) or usage.get("output_tokens", 0) or len(content) // 4
proof = generate_inference_proof(
model=model,
prompt=prompt,
response=content,
provider=api_base.split("//")[-1].split(".")[0],
api_base=api_base,
latency_ms=0.0,
input_tokens=input_tokens,
output_tokens=output_tokens,
)
return {"api_base": api_base, "model": model, "response": content, "raw": result, "proof": proof}
def get_kernel():
global kernel_manager, kernel_client
with kernel_lock:
if kernel_manager and kernel_client:
return kernel_manager, kernel_client
from jupyter_client import KernelManager
os.environ.update(runtime_env())
kernel_manager = KernelManager(kernel_name="python3")
kernel_manager.start_kernel(cwd=runtime_cwd())
kernel_client = kernel_manager.client()
kernel_client.start_channels()
kernel_client.wait_for_ready(timeout=30)
# Inject notebook-exposed helpers into kernel namespace
try:
helper_code = (
"import json, os, requests, time, textwrap, uuid\n"
"from datetime import datetime, timezone\n"
"from typing import Optional\n"
"\n"
"LLM_ROUTES = {\n"
" 'fast': {'provider': 'groq', 'model': 'llama-3.1-8b-instant', 'api_base': 'https://api.groq.com/openai/v1'},\n"
" 'cheap': {'provider': 'groq', 'model': 'llama-3.1-8b-instant', 'api_base': 'https://api.groq.com/openai/v1'},\n"
" 'quality': {'provider': 'openrouter', 'model': 'openai/gpt-4o', 'api_base': 'https://openrouter.ai/api/v1'},\n"
" 'coding': {'provider': 'groq', 'model': 'llama-3.3-70b-versatile', 'api_base': 'https://api.groq.com/openai/v1'},\n"
" 'json': {'provider': 'groq', 'model': 'llama-3.1-8b-instant', 'api_base': 'https://api.groq.com/openai/v1'},\n"
"}\n"
"\n"
"def _resolve_key(provider):\n"
" env = dict(os.environ)\n"
" if provider == 'groq':\n"
" return env.get('GROQ_API_KEY') or env.get('LLM_API_KEY')\n"
" if provider == 'openrouter':\n"
" return env.get('OPENROUTER_API_KEY') or env.get('LLM_API_KEY')\n"
" return env.get('LLM_API_KEY')\n"
"\n"
"def llm_infer(mode='cheap', task='', messages=None, system='', temperature=0.25, max_tokens=1800, timeout=90):\n"
" messages = messages or []\n"
" if not messages and task:\n"
" messages = [{'role': 'user', 'content': task}]\n"
" if not messages:\n"
" raise ValueError('Provide messages or task')\n"
" route = LLM_ROUTES.get(mode, LLM_ROUTES['cheap'])\n"
" provider = route['provider']\n"
" model = route['model']\n"
" api_base = route['api_base']\n"
" api_key = _resolve_key(provider)\n"
" if not api_key:\n"
" raise ValueError(f'No API key for {provider}')\n"
" prompt = messages[-1].get('content', '') if messages else ''\n"
" if mode == 'json':\n"
" system = (system or '') + '\\nReturn only valid JSON. No markdown fences.'\n"
" if mode == 'coding':\n"
" system = (system or '') + '\\nYou are an expert programmer. Write clean, production-ready code.'\n"
" payload = {'model': model, 'messages': [{'role': 'system', 'content': system}] + messages if system else messages, 'temperature': temperature, 'max_tokens': max_tokens}\n"
" if mode == 'json':\n"
" payload['response_format'] = {'type': 'json_object'}\n"
" started = time.time()\n"
" r = requests.post(f'{api_base}/chat/completions', headers={'authorization': f'Bearer {api_key}', 'content-type': 'application/json'}, json=payload, timeout=timeout)\n"
" latency_ms = round((time.time() - started) * 1000, 2)\n"
" result = r.json()\n"
" answer = result.get('choices', [{}])[0].get('message', {}).get('content', '')\n"
" usage = result.get('usage', {})\n"
" inp = usage.get('prompt_tokens', 0) or len(prompt)//4\n"
" out = usage.get('completion_tokens', 0) or len(answer)//4\n"
" cost = round((inp + out) / 1000 * {'llama-3.1-8b-instant': 0.00005, 'llama-3.3-70b-versatile': 0.00059, 'openai/gpt-4o': 0.005}.get(model, 0.0001), 6)\n"
" return {'answer': answer, 'provider': provider, 'model': model, 'latency_ms': latency_ms, 'cost_usd': cost, 'input_tokens': inp, 'output_tokens': out, 'route_reason': f'mode={mode} -> {provider} -> {model}', 'raw': result}\n"
)
kernel_client.execute(helper_code, silent=True, user_expressions={})
except Exception:
logger.warning("Failed to inject helpers into kernel namespace")
try:
kernel_client.execute("globals()['llm_infer'] = llm_infer\n", silent=True, user_expressions={})
except Exception:
pass
return kernel_manager, kernel_client
def shutdown_kernel():
global kernel_manager, kernel_client
with kernel_lock:
if kernel_client:
try:
kernel_client.stop_channels()
except Exception:
pass
if kernel_manager:
try:
kernel_manager.shutdown_kernel(now=True)
except Exception:
pass
kernel_manager = None
kernel_client = None
def execute_kernel_code(code: str, timeout: int = 60) -> dict:
timeout = bounded_timeout(timeout)
with kernel_lock:
_, client = get_kernel()
msg_id = client.execute(code, allow_stdin=False)
stdout_chunks = []
stderr_chunks = []
display_data = []
error = None
started = time.time()
while True:
if time.time() - started > timeout:
try:
kernel_manager.interrupt_kernel()
except Exception:
pass
return {
"success": False,
"execution_state": "timeout",
"stdout": "".join(stdout_chunks),
"stderr": "".join(stderr_chunks) + "\nKernel execution timed out",
"display_data": display_data,
"error": "timeout",
}
msg = client.get_iopub_msg(timeout=1)
if msg.get("parent_header", {}).get("msg_id") != msg_id:
continue
msg_type = msg["header"]["msg_type"]
content = msg.get("content", {})
if msg_type == "stream":
if content.get("name") == "stderr":
stderr_chunks.append(content.get("text", ""))
else:
stdout_chunks.append(content.get("text", ""))
elif msg_type in {"display_data", "execute_result"}:
display_data.append(content.get("data", {}))
elif msg_type == "error":
error = {
"ename": content.get("ename"),
"evalue": content.get("evalue"),
"traceback": content.get("traceback", []),
}
stderr_chunks.append("\n".join(error["traceback"]))
elif msg_type == "status" and content.get("execution_state") == "idle":
break
return {
"success": error is None,
"execution_state": "idle",
"stdout": "".join(stdout_chunks),
"stderr": "".join(stderr_chunks),
"display_data": display_data,
"error": error,
}
# ── Flask App ───────────────────────────────────────────────────
app = Flask(__name__)
@app.route("/")
def index():
html = """<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>HF VM Studio</title>
<style>
:root{--bg:#070814;--ink:#f8fbff;--muted:#a9b2c7;--line:rgba(255,255,255,.14);--hot:#7c3aed;--cyan:#22d3ee;--lime:#a3e635}
*{box-sizing:border-box}body{margin:0;background:radial-gradient(circle at 12% 8%,rgba(124,58,237,.42),transparent 34%),radial-gradient(circle at 86% 0,rgba(34,211,238,.34),transparent 30%),linear-gradient(145deg,#060712,#0b1022 48%,#101827);color:var(--ink);font:15px Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif;min-height:100vh;overflow-x:hidden}
.mesh{position:fixed;inset:0;background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);background-size:44px 44px;mask-image:radial-gradient(circle at center,black,transparent 72%);opacity:.32;pointer-events:none}.orb{position:fixed;width:520px;height:520px;border-radius:50%;filter:blur(55px);background:conic-gradient(from 90deg,var(--hot),var(--cyan),var(--lime),var(--hot));opacity:.13;right:-120px;bottom:-150px}
header{display:flex;align-items:center;justify-content:space-between;padding:28px min(7vw,92px);position:relative;z-index:2}.brand{display:flex;align-items:center;gap:12px;font-weight:800;letter-spacing:-.03em}.mark{width:40px;height:40px;border-radius:14px;background:linear-gradient(135deg,var(--cyan),var(--hot));display:grid;place-items:center;box-shadow:0 0 42px rgba(34,211,238,.45)}nav{display:flex;gap:12px;flex-wrap:wrap}nav a{color:var(--muted);text-decoration:none;border:1px solid var(--line);padding:10px 14px;border-radius:999px;background:rgba(255,255,255,.04);backdrop-filter:blur(12px)}
.hero{position:relative;z-index:1;padding:64px min(7vw,92px) 48px;display:grid;grid-template-columns:minmax(0,1.05fr) minmax(320px,.95fr);gap:48px;align-items:center}.eyebrow{display:inline-flex;gap:9px;align-items:center;padding:9px 13px;border:1px solid var(--line);border-radius:999px;background:rgba(255,255,255,.06);color:#dbeafe}.pulse{width:8px;height:8px;border-radius:99px;background:var(--lime);box-shadow:0 0 18px var(--lime)}h1{font-size:clamp(48px,8vw,100px);line-height:.9;letter-spacing:-.08em;margin:22px 0 20px}.grad{background:linear-gradient(100deg,#fff,#c4b5fd 38%,#67e8f9 72%,#ecfccb);-webkit-background-clip:text;background-clip:text;color:transparent}.lead{max-width:720px;color:var(--muted);font-size:clamp(18px,2vw,23px);line-height:1.55}.launch{display:flex;gap:10px;margin-top:28px;flex-wrap:wrap}.launch input{min-width:300px;flex:1;border:1px solid var(--line);border-radius:16px;background:rgba(255,255,255,.08);color:white;padding:15px 16px;font:14px ui-monospace,Menlo,monospace;outline:0}.launch button,.primary{border:0;border-radius:16px;background:linear-gradient(135deg,var(--cyan),var(--hot));color:white;padding:15px 20px;font-weight:800;cursor:pointer;box-shadow:0 18px 60px rgba(124,58,237,.32)}.stack{display:grid;gap:16px}.panel{border:1px solid var(--line);border-radius:28px;background:linear-gradient(180deg,rgba(255,255,255,.12),rgba(255,255,255,.05));box-shadow:0 30px 90px rgba(0,0,0,.36);backdrop-filter:blur(18px);padding:20px}.term{font:13px/1.7 ui-monospace,Menlo,monospace;color:#d1fae5}.term b{color:#67e8f9}.status{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}.stat{border:1px solid var(--line);border-radius:20px;padding:16px;background:rgba(255,255,255,.05)}.stat strong{display:block;font-size:24px}.features{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px;padding:18px min(7vw,92px) 70px}.feature{border:1px solid var(--line);border-radius:24px;background:rgba(255,255,255,.06);padding:20px;min-height:150px}.feature h3{margin:0 0 9px}.feature p{color:var(--muted);line-height:1.5;margin:0}@media(max-width:920px){.hero{grid-template-columns:1fr}.features{grid-template-columns:1fr 1fr}}@media(max-width:620px){header{align-items:flex-start;gap:16px;flex-direction:column}.features{grid-template-columns:1fr}.launch input{min-width:100%}}
</style></head><body><div class="mesh"></div><div class="orb"></div>
<header><div class="brand"><div class="mark">VM</div><span>HF VM Studio</span></div><nav><a href="/api">API map</a><a href="/healthz">Health</a><a href="/status">Status</a></nav></header>
<main class="hero"><section><div class="eyebrow"><span class="pulse"></span>Agent-native cloud workbench on a cheap Hugging Face Space</div><h1>Prompt to backend. <span class="grad">Running, remembered, deployable.</span></h1><p class="lead">HF VM Studio turns a Hugging Face Space into a prompt-to-backend factory, memory vault, notebook runtime, and deployment bridge. The primitive is simple: prompt -> files -> process -> proxy URL -> memory receipt -> deploy action.</p><div class="launch"><input id="token" type="password" placeholder="Paste terminal access token"><button onclick="openWorkbench()">Enter Workbench</button></div></section>
<section class="stack"><div class="panel term"><b>$</b> python3 app.py<br><b>βœ“</b> persistent Jupyter kernel<br><b>βœ“</b> shell cells and background processes<br><b>βœ“</b> /apps/&lt;id&gt;/proxy live endpoint<br><b>βœ“</b> memory saved from every meaningful run</div><div class="status"><div class="stat"><strong id="apps">--</strong>apps</div><div class="stat"><strong id="mem">--</strong>memories</div><div class="stat"><strong id="procs">--</strong>processes</div></div></section></main>
<section class="features"><div class="feature"><h3>VM Workbench</h3><p>Shell, Python cells, background processes, logs, previews, and deploy controls from one protected browser surface.</p></div><div class="feature"><h3>Agent Builder</h3><p>Prompt a backend, write files to disk, start it on an internal port, then preview it through the Space proxy.</p></div><div class="feature"><h3>Execution Memory</h3><p>Commands, notebooks, LLM output, generated apps, and deployments become searchable memory.</p></div><div class="feature"><h3>Proof Receipts</h3><p>Every important action gets prompt hashes, file hashes, command metadata, app URLs, model info, and timestamps.</p></div></section>
<script>
function openWorkbench(){const t=document.getElementById('token').value.trim();if(!t){alert('Paste the terminal access token first.');return}location.href='/colab?token='+encodeURIComponent(t)}
fetch('/status').then(r=>r.json()).then(j=>{apps.textContent=j.apps||0;mem.textContent=j.memories||0;procs.textContent=j.background_processes||0}).catch(()=>{})
</script></body></html>"""
return Response(html, mimetype="text/html")
@app.route("/api")
def api_index():
return jsonify({
"status": "running",
"message": "HF VM Studio",
"auth_required": True,
"endpoints": {
"GET /status": "Agent status & uptime",
"GET /logs": "Recent logs",
"GET /settings": "Runtime settings with secrets redacted",
"POST /settings": "Update cwd, env, LLM, and deploy settings",
"GET /memory": "List saved memories",
"POST /memory": "Save a memory",
"POST /memory/search": "Search saved memories",
"GET /receipts": "List provenance receipts",
"POST /receipts/search": "Search provenance receipts",
"GET /receipts/<receipt_id>": "Inspect one receipt",
"GET /tasks": "List tasks",
"POST /execute": "Execute command",
"POST /execute/background": "Launch a background shell command",
"GET /processes": "List background processes",
"POST /kernel/execute": "Execute code in a persistent Jupyter kernel",
"POST /kernel/restart": "Restart the Jupyter kernel",
"POST /notebook/run": "Run a multi-cell notebook through the kernel",
"POST /llm": "Run an OpenAI-compatible LLM request",
"POST /api/v1/llm/infer": "Inference mesh β€” mode-based routed LLM with cost/latency/receipt",
"GET /apps": "List generated backend apps",
"POST /apps": "Create a generated backend app from files",
"POST /agent/build": "Ask the configured LLM to generate a backend app",
"POST /apps/<app_id>/start": "Start a generated backend app",
"POST /apps/<app_id>/stop": "Stop a generated backend app",
"GET /apps/<app_id>/proxy/...": "Proxy to the running backend app",
"GET /stripe/config": "Stripe publishable key + app origin (public)",
"POST /stripe/checkout": "Create a Stripe Checkout session",
"POST /stripe/webhook": "Stripe webhook handler",
"GET /wallet/nonce": "Get challenge nonce for wallet signature",
"POST /wallet/connect": "Connect MetaMask or Phantom wallet",
"GET /wallet/<address>": "Get wallet balance and info",
"GET /wallet/<address>/history": "Token transaction history",
"GET /tokens/leaderboard": "Token balance leaderboard",
"POST /tokens/buy": "Buy token packs via Stripe",
"POST /tokens/launch": "Launch an SPL token on Solana (costs tokens)",
"GET /tokens/launched": "List tokens launched by a wallet",
"POST /claimos/evaluate": "Create/evaluate a claim: evidence + probability state + receipt",
"GET /claimos/<claim_id>": "Get full claim state with evidence and contradictions",
"POST /claimos/<claim_id>/contradictions": "Run contradiction scan on a claim",
"GET /claimos/<claim_id>/greeks": "Compute Claim Greeks (Ξ”, Θ, Ξ“, V, K)",
"GET /claimos/<claim_id>/liquidity": "Compute finance readiness / liquidity score",
"POST /claimos/<claim_id>/assess": "LLM-powered evidence quality assessment (auto-rates strength)",
"GET /claimos/<claim_id>/appraise": "Full legal appraisal report via LLM",
"GET /tokens/verify/<mint_address>": "On-chain Solana token mint verification via RPC",
"POST /pixelator/ingest": "Ingest HTML β†’ glyph units (costs tokens)",
"GET /pixelator/page/<page_id>/glyphs": "Get glyph units for a page",
"GET /pixelator/page/<page_id>/activation": "Page activation summary with glyph stats",
"GET /pixelator/website/<website_id>/top-glyphs": "Highest-value glyphs across a website",
"POST /pixelator/learn": "Retrain DOM weights and lexicon from actual page results",
"GET /costs": "Get all token costs (DB-backed, no hardcoded values)",
"POST /costs": "Update a token cost (admin)",
"GET /crawler/targets": "List crawl target websites (GA-RL population)",
"POST /crawler/targets": "Register a new crawl target website",
"POST /crawler/queue": "Enqueue URL into rotator buffer",
"GET /crawler/queue": "List crawl queue",
"POST /crawler/ingest": "Run one RL crawl step: fetch + pixelate + reward",
"GET /crawler/results": "Crawl results with glyph metrics",
"POST /crawler/evolve": "Run one GA generation on target population",
"GET /crawler/policy": "Get RL Q-table policy state",
"GET /finance/collateral": "Underwriting proof: revenue, deferred revenue, token velocity",
"GET /finance/revenue": "Revenue ledger with period/source breakdown",
"POST /finance/reconcile": "Reconcile Stripe sessions with token credits",
"POST /finance/rollback": "Rollback a transaction by tx_id",
"POST /deploy/vercel": "Deploy a project directory with Vercel CLI",
"POST /deploy/netlify": "Deploy a project directory with Netlify CLI",
"GET /terminal": "Web terminal UI",
},
})
@app.route("/status")
def get_status():
return jsonify({
"running": True,
"start_time": state.get("start_time"),
"uptime": get_uptime(),
"scheduled_tasks": len(schedule.jobs),
"executed_tasks_count": len(state.get("executed_tasks", [])),
"background_processes": len(processes),
"apps": len(apps),
"receipts": len(receipts),
"memories": len([m for m in memories.values() if not m.get("tombstone_at")]),
"kernel_running": kernel_manager is not None,
"cwd": str(DEFAULT_CWD),
"runtime_cwd": runtime_cwd(),
"token_rewards": {k: v for k, v in TOKEN_REWARDS.items()},
"settings": redacted_settings(),
})
@app.route("/healthz")
def healthz():
return jsonify({"ok": True, "status": "healthy", "uptime": get_uptime()})
@app.route("/settings", methods=["GET"])
def get_settings():
auth = require_auth()
if auth:
return auth
return jsonify(redacted_settings())
@app.route("/settings", methods=["POST"])
def update_settings():
auth = require_auth()
if auth:
return auth
data = request.json or {}
with settings_lock:
if "cwd" in data:
settings["cwd"] = str(data["cwd"])
if "max_timeout" in data:
settings["max_timeout"] = int(data["max_timeout"])
if isinstance(data.get("env"), dict):
for key, value in data["env"].items():
key = str(key).strip()
if not key:
continue
if value is None or value == "":
settings["env"].pop(key, None)
else:
settings["env"][key] = str(value)
if isinstance(data.get("llm"), dict):
settings["llm"].update({k: str(v) for k, v in data["llm"].items() if v is not None})
if isinstance(data.get("deploy"), dict):
settings["deploy"].update({k: str(v) for k, v in data["deploy"].items() if v is not None})
save_settings()
os.environ.update(runtime_env())
try:
shutdown_kernel()
except Exception:
logger.exception("Failed to reset kernel after settings update")
add_memory(
title="Runtime settings updated",
content=json.dumps(redacted_settings(), indent=2),
source="settings",
tags=["settings", "runtime"],
metadata={"keys": list(data.keys())},
importance=0.65,
)
return jsonify(redacted_settings())
@app.route("/logs")
def get_logs():
auth = require_auth()
if auth:
return auth
if log_file.exists():
lines = log_file.read_text().splitlines()
return jsonify({"logs": lines[-100:]})
return jsonify({"logs": [], "message": "No logs yet"})
@app.route("/tasks", methods=["GET"])
def list_tasks():
auth = require_auth()
if auth:
return auth
return jsonify({"tasks": tasks})
@app.route("/execute", methods=["POST"])
def execute():
auth = require_auth()
if auth:
return auth
if not _rate_check(f"exec:{request.remote_addr}", window=60, max_requests=20):
return rate_limit_response()
data = request.json or {}
cmd = _clamp_str(data.get("command", ""), max_len=8000).strip()
timeout = bounded_timeout(data.get("timeout", 60))
cwd = data.get("cwd")
if not cmd:
return jsonify({"error": "Missing command"}), 400
result = run_command(cmd, timeout, cwd=cwd)
add_memory(
title=f"Terminal command: {cmd[:80]}",
content=f"command: {cmd}\nstdout:\n{result.get('stdout','')}\nstderr:\n{result.get('stderr','')}",
source="terminal",
tags=["terminal", "command"],
metadata={"exit_code": result.get("exit_code"), "success": result.get("success"), "cwd": result.get("cwd")},
importance=0.6 if result.get("success") else 0.75,
)
state["executed_tasks"].append({
"command": cmd,
"timestamp": datetime.now(timezone.utc).isoformat(),
"success": result["success"],
})
state["executed_tasks"] = state["executed_tasks"][-1000:]
save_state()
receipt = create_receipt(
kind="command",
title=f"Shell command: {cmd[:80]}",
status="success" if result.get("success") else "failed",
command=cmd,
metadata={"result": result},
)
result["receipt_id"] = receipt["receipt_id"]
result["token_reward"] = maybe_credit(data, "shell_execute", TOKEN_REWARDS["shell_execute"])
return jsonify(result)
@app.route("/memory", methods=["GET"])
def list_memory():
auth = require_auth()
if auth:
return auth
limit = max(1, min(int(request.args.get("limit", 50)), 200))
active = [m for m in memories.values() if not m.get("tombstone_at")]
active.sort(key=lambda item: item.get("created_at", ""), reverse=True)
return jsonify({"memories": active[:limit], "count": len(active)})
@app.route("/memory", methods=["POST"])
def create_memory():
auth = require_auth()
if auth:
return auth
data = request.json or {}
content = _clamp_str(data.get("content", ""), max_len=50000).strip()
if not content:
return jsonify({"error": "Missing content"}), 400
item = add_memory(
title=_clamp_str(data.get("title") or "Manual memory", 256),
content=content,
source=_clamp_str(data.get("source") or "manual", 64),
tags=data.get("tags") if isinstance(data.get("tags"), list) else ["manual"],
metadata=data.get("metadata") if isinstance(data.get("metadata"), dict) else {},
importance=float(data.get("importance", 0.7)),
)
return jsonify(item), 201
@app.route("/memory/search", methods=["POST"])
def memory_search():
auth = require_auth()
if auth:
return auth
data = request.json or {}
query = _clamp_str(data.get("query", ""), max_len=2000).strip()
limit = max(1, min(int(data.get("limit", 8)), 50))
return jsonify({"query": query, "memories": search_memory(query, limit=limit)})
@app.route("/memory/<memory_id>", methods=["GET"])
def get_memory(memory_id):
auth = require_auth()
if auth:
return auth
item = memories.get(memory_id)
if not item:
return jsonify({"error": "Memory not found"}), 404
return jsonify(item)
@app.route("/memory/<memory_id>", methods=["DELETE"])
def delete_memory(memory_id):
auth = require_auth()
if auth:
return auth
item = memories.get(memory_id)
if not item or item.get("tombstone_at"):
return jsonify({"error": "Active memory not found"}), 404
item["tombstone_at"] = datetime.now(timezone.utc).isoformat()
save_memory()
return jsonify({"memory_id": memory_id, "status": "tombstoned"})
@app.route("/receipts", methods=["GET"])
def list_receipts():
auth = require_auth()
if auth:
return auth
limit = max(1, min(int(request.args.get("limit", 50)), 200))
with receipt_lock:
active = list(receipts.values())
active.sort(key=lambda item: item.get("created_at", ""), reverse=True)
return jsonify({"receipts": active[:limit], "count": len(active)})
@app.route("/receipts/search", methods=["POST"])
def receipt_search():
auth = require_auth()
if auth:
return auth
data = request.json or {}
query = _clamp_str(data.get("query", ""), max_len=2000).strip()
limit = max(1, min(int(data.get("limit", 20)), 100))
return jsonify({"query": query, "receipts": search_receipts(query, limit=limit)})
@app.route("/receipts/<receipt_id>", methods=["GET"])
def get_receipt(receipt_id):
auth = require_auth()
if auth:
return auth
item = receipts.get(receipt_id)
if not item:
return jsonify({"error": "Receipt not found"}), 404
return jsonify(item)
@app.route("/llm", methods=["POST"])
def run_llm():
auth = require_auth()
if auth:
return auth
if not _rate_check(f"llm:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
data = request.json or {}
prompt = _clamp_str(data.get("prompt", ""), max_len=20000).strip()
if not prompt:
return jsonify({"error": "Missing prompt"}), 400
try:
result = call_llm(
prompt,
system=str(data.get("system") or ""),
api_base=data.get("api_base"),
model=data.get("model"),
api_key=data.get("api_key"),
temperature=data.get("temperature", 0.3),
max_tokens=data.get("max_tokens", 800),
timeout=data.get("timeout", 60),
)
except ValueError as e:
return jsonify({"error": str(e)}), 400
except Exception as e:
return jsonify({"error": str(e)}), 502
add_memory(
title=f"LLM run: {result['model']}",
content=f"prompt:\n{prompt}\n\nresponse:\n{result.get('response') or json.dumps(result.get('raw', {}))[:4000]}",
source="llm",
tags=["llm", result["model"]],
metadata={"api_base": result["api_base"], "model": result["model"]},
importance=0.8,
)
receipt = create_receipt(
kind="llm",
title=f"LLM run: {result['model']}",
status="completed",
prompt=prompt,
model={"api_base": result["api_base"], "model": result["model"]},
metadata={"response_hash": sha256_text(result.get("response") or json.dumps(result.get("raw", {})))},
)
result["receipt_id"] = receipt["receipt_id"]
return jsonify(result)
# ── Inference Mesh ──────────────────────────────────────────────
LLM_ROUTES = {
"fast": {"provider": "groq", "model": "llama-3.1-8b-instant", "api_base": "https://api.groq.com/openai/v1"},
"cheap": {"provider": "groq", "model": "llama-3.1-8b-instant", "api_base": "https://api.groq.com/openai/v1"},
"quality": {"provider": "openrouter", "model": "openai/gpt-4o", "api_base": "https://openrouter.ai/api/v1"},
"local": {"provider": "ollama", "model": "llama3.1:8b", "api_base": "http://localhost:11434/v1"},
"coding": {"provider": "groq", "model": "llama-3.3-70b-versatile", "api_base": "https://api.groq.com/openai/v1"},
"json": {"provider": "groq", "model": "llama-3.1-8b-instant", "api_base": "https://api.groq.com/openai/v1"},
"private": {"provider": "ollama", "model": "llama3.1:8b", "api_base": "http://localhost:11434/v1"},
}
COST_PER_1K_TOKENS: Dict[str, float] = {
"llama-3.1-8b-instant": 0.00005,
"llama-3.3-70b-versatile": 0.00059,
"openai/gpt-4o": 0.005,
"openai/gpt-4o-mini": 0.00015,
"llama3.1:8b": 0.0,
}
def resolve_api_key(provider: str) -> Optional[str]:
env = settings.get("env", {})
if provider == "groq":
return env.get("GROQ_API_KEY") or env.get("LLM_API_KEY") or os.environ.get("GROQ_API_KEY") or os.environ.get("LLM_API_KEY")
if provider == "openrouter":
return env.get("OPENROUTER_API_KEY") or env.get("LLM_API_KEY") or os.environ.get("OPENROUTER_API_KEY") or os.environ.get("LLM_API_KEY")
if provider == "ollama":
return "ollama" # Ollama doesn't need a key
return env.get("LLM_API_KEY") or os.environ.get("LLM_API_KEY")
def estimate_cost(model: str, input_tokens: int, output_tokens: int) -> float:
rate = COST_PER_1K_TOKENS.get(model, 0.0001)
return round((input_tokens + output_tokens) / 1000 * rate, 6)
def route_llm_infer(data: dict) -> dict:
mode = str(data.get("mode", "cheap")).strip().lower()
task = _clamp_str(data.get("task", ""), max_len=20000).strip()
messages = data.get("messages", [])
if messages:
messages = [
{"role": _clamp_str(m.get("role", "user"), 20), "content": _clamp_str(m.get("content", ""), 20000)}
for m in messages
]
if not messages and task:
messages = [{"role": "user", "content": task}]
if not messages:
raise ValueError("Provide messages or task")
route = LLM_ROUTES.get(mode)
if not route:
route = LLM_ROUTES["cheap"]
provider = route["provider"]
model = str(data.get("model") or route["model"])
api_base = str(data.get("api_base") or route["api_base"])
api_key = resolve_api_key(provider)
if provider != "ollama" and not api_key:
# Fallback chain: groq -> openrouter -> error
fallback_order = ["groq", "openrouter"]
for fb in fallback_order:
if fb == provider:
continue
fb_key = resolve_api_key(fb)
if fb_key:
provider = fb
model = LLM_ROUTES[fb]["model"]
api_base = LLM_ROUTES[fb]["api_base"]
api_key = fb_key
break
if not api_key:
raise ValueError(f"No API key available for provider {provider}")
system = str(data.get("system") or "")
if mode == "json":
system = system + "\nReturn only valid JSON. No markdown fences." if system else "Return only valid JSON. No markdown fences."
if mode == "coding":
system = system + "\nYou are an expert programmer. Write clean, production-ready code." if system else "You are an expert programmer. Write clean, production-ready code."
prompt = ""
if messages and isinstance(messages, list) and messages[-1].get("role") == "user":
prompt = str(messages[-1].get("content", ""))
started = time.time()
llm_result = call_llm(
prompt,
system=system,
api_base=api_base,
model=model,
api_key=api_key,
temperature=float(data.get("temperature", 0.25)),
max_tokens=int(data.get("max_tokens", 1800)),
timeout=data.get("timeout", 90),
response_format={"type": "json_object"} if mode == "json" else None,
)
latency_ms = round((time.time() - started) * 1000, 2)
raw = llm_result.get("raw", {})
usage = raw.get("usage", {})
input_tokens = usage.get("prompt_tokens", 0) or usage.get("input_tokens", 0) or len(prompt) // 4
output_tokens = usage.get("completion_tokens", 0) or usage.get("output_tokens", 0) or len(str(llm_result.get("response", ""))) // 4
cost_usd = estimate_cost(model, input_tokens, output_tokens)
add_memory(
title=f"Inference mesh [{mode}]: {model}",
content=f"task: {task}\nprompt: {prompt[:500]}\nresponse: {str(llm_result.get('response', ''))[:2000]}",
source="inference-mesh",
tags=["llm", provider, model, mode],
metadata={"provider": provider, "model": model, "mode": mode, "latency_ms": latency_ms, "cost_usd": cost_usd},
importance=0.85,
)
# Generate Proof of Inference for every mesh call
proof = generate_inference_proof(
model=model,
prompt=prompt,
response=str(llm_result.get("response", "")),
provider=provider,
api_base=api_base,
latency_ms=latency_ms,
input_tokens=input_tokens,
output_tokens=output_tokens,
)
receipt = create_receipt(
kind="inference-mesh",
title=f"Inference mesh [{mode}]: {model}",
status="completed",
prompt=prompt,
model={"provider": provider, "model": model, "api_base": api_base, "mode": mode},
metadata={
"latency_ms": latency_ms,
"cost_usd": cost_usd,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"route_reason": f"mode={mode} -> provider={provider} -> model={model}",
"proof_id": proof["proof_id"],
},
)
return {
"answer": llm_result.get("response", ""),
"provider": provider,
"model": model,
"latency_ms": latency_ms,
"cost_usd": cost_usd,
"receipt_hash": receipt["receipt_id"],
"proof": proof,
"route_reason": f"mode={mode} -> provider={provider} -> model={model}",
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"api_base": api_base,
"raw": raw,
}
# Notebook-exposed helper (injected into kernel globals)
def llm_infer(mode: str = "cheap", task: str = "", messages: Optional[list] = None, **kwargs) -> dict:
"""Cell-friendly inference mesh call. Returns answer + metadata."""
payload = {"mode": mode, "task": task, "messages": messages or [], **kwargs}
return route_llm_infer(payload)
@app.route("/api/v1/llm/infer", methods=["POST"])
def api_llm_infer():
auth = require_auth()
if auth:
return auth
if not _rate_check(f"llm:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
data = request.json or {}
try:
result = route_llm_infer(data)
except ValueError as e:
return jsonify({"error": str(e)}), 400
except Exception as e:
return jsonify({"error": str(e)}), 502
return jsonify(result)
@app.route("/apps", methods=["GET"])
def list_apps():
auth = require_auth()
if auth:
return auth
return jsonify({"apps": [redact_app(item) for item in apps.values()]})
@app.route("/apps", methods=["POST"])
def create_app():
auth = require_auth()
if auth:
return auth
result = create_generated_app(request.json or {})
if result.get("error"):
return jsonify(result), 400
receipt = create_receipt(
kind="generated-app",
title=f"Generated app: {result['name']}",
status=result.get("status", "created"),
prompt=str((request.json or {}).get("prompt") or ""),
app_record=result,
command=result.get("start_command", ""),
metadata={"source": "manual-app-create"},
)
result["receipt_id"] = receipt["receipt_id"]
attach_receipt_to_app(result["app_id"], receipt["receipt_id"])
return jsonify(result), 201
@app.route("/apps/<app_id>", methods=["GET"])
def get_app(app_id):
auth = require_auth()
if auth:
return auth
item = apps.get(app_id)
if not item:
return jsonify({"error": "App not found"}), 404
return jsonify(redact_app(item))
@app.route("/apps/<app_id>/files", methods=["GET"])
def get_app_files(app_id):
auth = require_auth()
if auth:
return auth
item = apps.get(app_id)
if not item:
return jsonify({"error": "App not found"}), 404
app_dir = Path(item["path"])
files = []
for file_name in item.get("files", []):
file_path = safe_app_file(app_dir, file_name)
files.append({"path": file_name, "content": file_path.read_text() if file_path.exists() else ""})
return jsonify({"app_id": app_id, "files": files})
@app.route("/apps/<app_id>/start", methods=["POST"])
def start_app(app_id):
auth = require_auth()
if auth:
return auth
result, status = start_generated_app(app_id)
if not result.get("error"):
receipt = create_receipt(
kind="app-start",
title=f"App started: {result.get('name', app_id)}",
status=result.get("status", "running"),
app_record=result,
command=result.get("start_command", ""),
process={"pid": result.get("pid"), "status": result.get("status"), "stdout": result.get("stdout", ""), "stderr": result.get("stderr", "")},
metadata={"app_id": app_id, "proxy_url": result.get("proxy_url")},
)
result["start_receipt_id"] = receipt["receipt_id"]
return jsonify(result), status
@app.route("/apps/<app_id>/stop", methods=["POST"])
def stop_app(app_id):
auth = require_auth()
if auth:
return auth
result = stop_generated_app(app_id)
if result.get("error"):
return jsonify(result), 404
return jsonify(result)
@app.route("/apps/<app_id>/proxy/", defaults={"subpath": ""}, methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"])
@app.route("/apps/<app_id>/proxy/<path:subpath>", methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"])
def proxy_app(app_id, subpath):
auth = require_auth()
if auth:
return auth
item = apps.get(app_id)
if not item:
return jsonify({"error": "App not found"}), 404
target = f"http://127.0.0.1:{int(item['port'])}/{subpath}"
try:
upstream = requests.request(
request.method,
target,
params=request.args,
data=request.get_data(),
headers={k: v for k, v in request.headers if k.lower() not in {"host", "content-length"}},
timeout=30,
allow_redirects=False,
)
except Exception as e:
return Response(f"App proxy error: {e}", status=502, mimetype="text/plain")
excluded = {"content-encoding", "content-length", "transfer-encoding", "connection"}
headers = [(k, v) for k, v in upstream.headers.items() if k.lower() not in excluded]
return Response(upstream.content, status=upstream.status_code, headers=headers)
@app.route("/agent/build", methods=["POST"])
def agent_build_app():
auth = require_auth()
if auth:
return auth
if not _rate_check(f"build:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
data = request.json or {}
prompt = _clamp_str(data.get("prompt", ""), max_len=12000).strip()
if not prompt:
return jsonify({"error": "Missing prompt"}), 400
system = (
"You are an expert backend app generator for a Hugging Face Spaces Linux VM. "
"Return only valid JSON with keys: name, description, start_command, files. "
"files must be an array of objects with path and content. "
"For Python web apps, use Flask, read PORT from os.environ, bind host 0.0.0.0, and keep dependencies to installed packages when possible. "
"Do not include markdown fences."
)
try:
llm_result = call_llm(
prompt,
system=system,
temperature=float(data.get("temperature", 0.25)),
max_tokens=int(data.get("max_tokens", 2600)),
timeout=data.get("timeout", 120),
response_format={"type": "json_object"},
)
try:
app_spec = parse_llm_json(llm_result["response"])
except Exception as first_error:
repair = call_llm(
"Repair this into strict valid JSON only. It must contain name, description, start_command, and files. "
"Every files[].content value must be a properly escaped JSON string.\n\n"
f"{llm_result['response']}",
system=system,
temperature=0,
max_tokens=int(data.get("max_tokens", 2600)),
timeout=data.get("timeout", 120),
response_format={"type": "json_object"},
)
llm_result = repair
try:
app_spec = parse_llm_json(llm_result["response"])
except Exception as repair_error:
app_spec = fallback_app_spec(prompt, reason=f"LLM JSON repair failed: {first_error}; {repair_error}")
except ValueError as e:
return jsonify({"error": str(e)}), 400
except Exception as e:
return jsonify({"error": f"LLM app generation failed: {e}"}), 502
app_spec = normalize_generated_app_spec(app_spec, prompt=prompt)
created = create_generated_app(app_spec)
if created.get("error"):
return jsonify({"error": created["error"], "llm_response": llm_result.get("response")}), 400
if bool(data.get("run", True)):
started, status = start_generated_app(created["app_id"])
created.update(started)
add_memory(
title=f"LLM-built backend: {created['name']}",
content=f"prompt:\n{prompt}\n\napp:\n{json.dumps(created, indent=2)}",
source="llm-app-builder",
tags=["llm", "backend", "generated-app"],
metadata={"app_id": created["app_id"], "model": llm_result["model"]},
importance=0.9,
)
receipt = create_receipt(
kind="prompt-to-backend",
title=f"Prompt-to-backend: {created['name']}",
status=created.get("status", "created"),
prompt=prompt,
app_record=created,
model={"api_base": llm_result["api_base"], "model": llm_result["model"]},
command=created.get("start_command", ""),
metadata={"loop": "prompt -> files -> process -> proxy -> memory", "llm_response_hash": sha256_text(llm_result.get("response", ""))},
)
created["receipt_id"] = receipt["receipt_id"]
attach_receipt_to_app(created["app_id"], receipt["receipt_id"])
created["token_reward"] = maybe_credit(data, "agent_build", TOKEN_REWARDS["agent_build"])
return jsonify({"app": created, "receipt": receipt, "llm": {"api_base": llm_result["api_base"], "model": llm_result["model"]}}), 201
def deploy_command(provider: str, data: dict) -> tuple[str, str]:
deploy_cfg = settings.get("deploy", {})
if provider == "vercel":
token = settings.get("env", {}).get("VERCEL_TOKEN") or os.environ.get("VERCEL_TOKEN")
if not token:
raise ValueError("VERCEL_TOKEN is not configured in settings.")
project_dir = str(data.get("project_dir") or deploy_cfg.get("vercel_project_dir") or runtime_cwd())
prod = bool(data.get("prod", True))
cmd = f"vercel deploy --yes {'--prod' if prod else ''} --token \"$VERCEL_TOKEN\""
return cmd, project_dir
if provider == "netlify":
token = settings.get("env", {}).get("NETLIFY_AUTH_TOKEN") or os.environ.get("NETLIFY_AUTH_TOKEN")
if not token:
raise ValueError("NETLIFY_AUTH_TOKEN is not configured in settings.")
project_dir = str(data.get("project_dir") or deploy_cfg.get("netlify_project_dir") or runtime_cwd())
publish_dir = str(data.get("publish_dir") or deploy_cfg.get("netlify_publish_dir") or project_dir)
prod = bool(data.get("prod", True))
cmd = f"netlify deploy --dir \"{publish_dir}\" {'--prod' if prod else ''} --auth \"$NETLIFY_AUTH_TOKEN\""
if data.get("site"):
cmd += f" --site \"{data['site']}\""
return cmd, project_dir
raise ValueError(f"Unsupported provider: {provider}")
# ── Stripe ──────────────────────────────────────────────────────
def get_app_origin() -> str:
"""Return the full HTTPS app origin for Stripe redirects."""
configured = settings.get("env", {}).get("APP_ORIGIN") or os.environ.get("APP_ORIGIN", "")
if configured:
return configured.rstrip("/")
# Fallback to request origin if available
if request:
host = request.headers.get("X-Forwarded-Host") or request.headers.get("Host", "")
proto = request.headers.get("X-Forwarded-Proto", "https")
if host:
return f"{proto}://{host}"
return "https://localhost"
@app.route("/stripe/config", methods=["GET"])
def stripe_config():
"""Public endpoint returning safe Stripe config (publishable key + origin)."""
pk = settings.get("env", {}).get("STRIPE_PUBLISHABLE_KEY") or os.environ.get("STRIPE_PUBLISHABLE_KEY", "")
return jsonify({
"publishable_key": pk,
"origin": get_app_origin(),
"status": "ready" if pk else "missing_publishable_key",
})
@app.route("/stripe/checkout", methods=["POST"])
def stripe_checkout():
auth = require_auth()
if auth:
return auth
import stripe as stripe_lib
sk = settings.get("env", {}).get("STRIPE_SECRET_KEY") or os.environ.get("STRIPE_SECRET_KEY", "")
if not sk:
return jsonify({"error": "Stripe secret key not configured"}), 400
stripe_lib.api_key = sk
data = request.json or {}
origin = get_app_origin()
success_url = f"{origin}/?session_id={{CHECKOUT_SESSION_ID}}#success"
cancel_url = f"{origin}/?canceled=true"
try:
session = stripe_lib.checkout.Session.create(
payment_method_types=["card"],
line_items=[{
"price_data": {
"currency": str(data.get("currency", "usd")),
"product_data": {"name": str(data.get("product_name", "HF VM Studio Service"))},
"unit_amount": int(data.get("amount_cents", 500)),
},
"quantity": int(data.get("quantity", 1)),
}],
mode="payment",
success_url=success_url,
cancel_url=cancel_url,
metadata={
"source": "hf-vm-studio",
"user_tag": str(data.get("user_tag", "")),
},
)
receipt = create_receipt(
kind="stripe-checkout",
title=f"Stripe checkout created: {data.get('product_name', 'Service')}",
status="created",
command=f"checkout_session:{session.id}",
metadata={
"session_id": session.id,
"amount_cents": data.get("amount_cents", 500),
"currency": data.get("currency", "usd"),
"origin": origin,
},
)
return jsonify({
"session_id": session.id,
"url": session.url,
"receipt_id": receipt["receipt_id"],
})
except Exception as e:
return jsonify({"error": str(e)}), 502
@app.route("/stripe/webhook", methods=["POST"])
def stripe_webhook():
import stripe as stripe_lib
sk = settings.get("env", {}).get("STRIPE_SECRET_KEY") or os.environ.get("STRIPE_SECRET_KEY", "")
if not sk:
return jsonify({"error": "Stripe secret key not configured"}), 400
payload = request.get_data(as_text=True)
sig_header = request.headers.get("Stripe-Signature", "")
webhook_secret = settings.get("env", {}).get("STRIPE_WEBHOOK_SECRET") or os.environ.get("STRIPE_WEBHOOK_SECRET", "")
try:
if webhook_secret:
event = stripe_lib.Webhook.construct_event(payload, sig_header, webhook_secret)
else:
event = json.loads(payload)
except Exception as e:
return jsonify({"error": f"Webhook verification failed: {e}"}), 400
event_type = event.get("type", "unknown")
obj = event.get("data", {}).get("object", {})
session_id = str(obj.get("id", ""))
now = datetime.now(timezone.utc).isoformat()
period = now[:7]
# ── Idempotency guard ─────────────────────────────────────────
with token_lock:
with _db() as conn:
processed = conn.execute("SELECT session_id, tx_id FROM stripe_sessions WHERE session_id = ?", (session_id,)).fetchone()
if processed:
logger.info("Stripe webhook idempotent skip: session=%s already processed with tx=%s", session_id, processed["tx_id"])
return jsonify({"received": True, "type": event_type, "idempotent": True, "session_id": session_id}), 200
# ── Token purchase fulfillment ──────────────────────────────
credited = None
if event_type in ("checkout.session.completed", "checkout.session.async_payment_succeeded"):
metadata = obj.get("metadata", {})
if metadata.get("source") == "hf-vm-studio" and metadata.get("wallet"):
wallet = str(metadata["wallet"]).lower()
# Integer tokens only β€” no floats for money (C53)
tokens_str = str(metadata.get("tokens", "0")).strip()
try:
tokens = int(tokens_str)
except ValueError:
tokens = 0
amount_cents = int(obj.get("amount_total", 0))
currency = str(obj.get("currency", "usd")).lower()
pack = str(metadata.get("pack", "unknown"))
if tokens > 0:
tx_id = f"stripe_{session_id}"
credited = credit_tokens(
wallet, tokens,
reason=f"stripe_purchase:{pack}",
metadata={"session_id": session_id, "pack": pack, "currency": currency},
idempotency_key=tx_id,
revenue_cents=amount_cents,
)
# Record processed session for idempotency
with token_lock:
with _db() as conn:
conn.execute(
"INSERT INTO stripe_sessions (session_id, event_type, status, amount_cents, currency, wallet, pack, tokens, processed_at, tx_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
(session_id, event_type, "completed", amount_cents, currency, wallet, pack, tokens, now, tx_id),
)
# Revenue ledger entry
rev_id = f"rev_{uuid.uuid4().hex}"
conn.execute(
"INSERT INTO revenue (revenue_id, source, session_id, amount_cents, currency, period, wallet, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
(rev_id, "stripe_webhook", session_id, amount_cents, currency, period, wallet, now, json.dumps({"pack": pack, "tokens": tokens, "event_type": event_type})),
)
conn.commit()
add_memory(
title=f"Stripe webhook: {event_type}",
content=json.dumps(event, indent=2)[:5000],
source="stripe-webhook",
tags=["stripe", event_type],
metadata={"session_id": session_id, "event_type": event_type, "tokens_credited": credited},
importance=0.85,
)
create_receipt(
kind="stripe-webhook",
title=f"Stripe webhook: {event_type}",
status="received",
command=f"webhook:{event_type}:{session_id}",
metadata={"session_id": session_id, "event_type": event_type, "tokens_credited": credited},
)
return jsonify({"received": True, "type": event_type, "tokens_credited": credited, "session_id": session_id})
@app.route("/deploy/vercel", methods=["POST"])
def deploy_vercel():
auth = require_auth()
if auth:
return auth
if not _rate_check(f"deploy:{request.remote_addr}", window=60, max_requests=5):
return rate_limit_response()
data = request.json or {}
try:
cmd, cwd = deploy_command("vercel", data)
except ValueError as e:
return jsonify({"error": str(e)}), 400
result = launch_background_process(cmd, timeout=int(data.get("timeout", 0) or 0), cwd=cwd)
result["provider"] = "vercel"
receipt = create_receipt(
kind="deployment",
title="Vercel deployment launched",
status="launched",
command=redact_command_secret(cmd, os.environ.get("VERCEL_TOKEN", "")),
process=result,
deployment={"provider": "vercel", "project_dir": cwd, "prod": bool(data.get("prod", True))},
metadata={"process_id": result.get("process_id")},
)
result["receipt_id"] = receipt["receipt_id"]
result["token_reward"] = maybe_credit(data, "deploy", TOKEN_REWARDS["deploy"])
return jsonify(result), 202
@app.route("/deploy/netlify", methods=["POST"])
def deploy_netlify():
auth = require_auth()
if auth:
return auth
if not _rate_check(f"deploy:{request.remote_addr}", window=60, max_requests=5):
return rate_limit_response()
data = request.json or {}
try:
cmd, cwd = deploy_command("netlify", data)
except ValueError as e:
return jsonify({"error": str(e)}), 400
result = launch_background_process(cmd, timeout=int(data.get("timeout", 0) or 0), cwd=cwd)
result["provider"] = "netlify"
receipt = create_receipt(
kind="deployment",
title="Netlify deployment launched",
status="launched",
command=redact_command_secret(cmd, os.environ.get("NETLIFY_AUTH_TOKEN", "")),
process=result,
deployment={"provider": "netlify", "project_dir": cwd, "publish_dir": data.get("publish_dir"), "prod": bool(data.get("prod", True))},
metadata={"process_id": result.get("process_id")},
)
result["receipt_id"] = receipt["receipt_id"]
result["token_reward"] = maybe_credit(data, "deploy", TOKEN_REWARDS["deploy"])
return jsonify(result), 202
@app.route("/execute/background", methods=["POST"])
def execute_background():
auth = require_auth()
if auth:
return auth
data = request.json or {}
cmd = data.get("command", "").strip()
timeout = int(data.get("timeout", 0) or 0)
cwd = data.get("cwd")
if not cmd:
return jsonify({"error": "Missing command"}), 400
return jsonify(launch_background_process(cmd, timeout=timeout, cwd=cwd)), 202
@app.route("/processes", methods=["GET"])
def list_processes():
auth = require_auth()
if auth:
return auth
return jsonify({"processes": [redact_process(p) for p in processes.values()]})
@app.route("/processes/<process_id>", methods=["GET"])
def get_process(process_id):
auth = require_auth()
if auth:
return auth
proc = processes.get(process_id)
if not proc:
return jsonify({"error": "Process not found"}), 404
return jsonify(redact_process(proc))
@app.route("/processes/<process_id>", methods=["DELETE"])
def stop_process(process_id):
auth = require_auth()
if auth:
return auth
proc = processes.get(process_id)
if not proc:
return jsonify({"error": "Process not found"}), 404
popen = proc.get("_popen")
if popen and proc.get("status") == "running":
try:
if hasattr(os, "killpg"):
os.killpg(os.getpgid(popen.pid), signal.SIGTERM)
else:
popen.terminate()
proc["status"] = "stopping"
except Exception as e:
return jsonify({"error": str(e)}), 500
return jsonify(redact_process(proc))
@app.route("/kernel/status", methods=["GET"])
def kernel_status():
auth = require_auth()
if auth:
return auth
return jsonify({
"kernel_running": kernel_manager is not None,
"cwd": str(DEFAULT_CWD),
"kernel_name": "python3",
})
@app.route("/kernel/execute", methods=["POST"])
def kernel_execute():
auth = require_auth()
if auth:
return auth
if not _rate_check(f"kernel:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
data = request.json or {}
code = _clamp_str(data.get("code", ""), max_len=50000)
timeout = data.get("timeout", 60)
if not code.strip():
return jsonify({"error": "Missing code"}), 400
result = execute_kernel_code(code, timeout=timeout)
add_memory(
title="Kernel execution",
content=f"code:\n{code}\nstdout:\n{result.get('stdout','')}\nstderr:\n{result.get('stderr','')}",
source="kernel",
tags=["jupyter", "kernel"],
metadata={"success": result.get("success"), "display_data": bool(result.get("display_data"))},
importance=0.7,
)
state["executed_tasks"].append({
"command": "kernel.execute",
"timestamp": datetime.now(timezone.utc).isoformat(),
"success": result["success"],
})
state["executed_tasks"] = state["executed_tasks"][-1000:]
save_state()
receipt = create_receipt(
kind="kernel",
title="Jupyter kernel execution",
status="success" if result.get("success") else "failed",
command="kernel.execute",
metadata={"code_hash": sha256_text(code), "result": result},
)
result["receipt_id"] = receipt["receipt_id"]
result["token_reward"] = maybe_credit(data, "kernel_execute", TOKEN_REWARDS["kernel_execute"])
return jsonify(result)
@app.route("/kernel/restart", methods=["POST"])
def kernel_restart():
auth = require_auth()
if auth:
return auth
shutdown_kernel()
get_kernel()
return jsonify({"kernel_running": True, "status": "restarted"})
@app.route("/notebook/run", methods=["POST"])
def notebook_run():
auth = require_auth()
if auth:
return auth
if not _rate_check(f"notebook:{request.remote_addr}", window=60, max_requests=15):
return rate_limit_response()
import nbformat
data = request.json or {}
cells = data.get("cells")
if cells is None and data.get("code"):
cells = [data["code"]]
if not isinstance(cells, list) or not cells:
return jsonify({"error": "Provide cells: [...] or code: '...'"}), 400
cells = [_clamp_str(c, max_len=50000) for c in cells]
if len(cells) > 50:
return jsonify({"error": "Too many cells (max 50)"}), 400
timeout = data.get("timeout", 60)
notebook_id = f"nb_{uuid.uuid4().hex[:12]}"
results = []
nb = nbformat.v4.new_notebook()
nb_cells = []
for source in cells:
source = str(source)
result = execute_kernel_code(source, timeout=timeout)
results.append(result)
output_text = ""
if result.get("stdout"):
output_text += result["stdout"]
if result.get("stderr"):
output_text += result["stderr"]
cell = nbformat.v4.new_code_cell(source=source)
if output_text:
cell.outputs = [nbformat.v4.new_output("stream", name="stdout", text=output_text)]
nb_cells.append(cell)
nb.cells = nb_cells
path = NOTEBOOK_DIR / f"{notebook_id}.ipynb"
nbformat.write(nb, path)
add_memory(
title=f"Notebook run: {notebook_id}",
content="\n\n".join([f"cell:\n{source}" for source in cells]),
source="notebook",
tags=["notebook", "jupyter"],
metadata={"notebook_id": notebook_id, "path": str(path), "success": all(r.get("success") for r in results)},
importance=0.75,
)
response = {
"notebook_id": notebook_id,
"path": str(path),
"success": all(r.get("success") for r in results),
"results": results,
}
receipt = create_receipt(
kind="notebook",
title=f"Notebook run: {notebook_id}",
status="success" if response["success"] else "failed",
command="notebook.run",
metadata={"notebook_id": notebook_id, "path": str(path), "cell_count": len(cells), "cells_hash": sha256_text(json.dumps(cells))},
)
response["receipt_id"] = receipt["receipt_id"]
response["token_reward"] = maybe_credit(data, "notebook_run", TOKEN_REWARDS["notebook_run"])
return jsonify(response)
@app.route("/terminal")
@app.route("/colab")
def terminal_ui():
auth = require_auth()
if auth:
return Response(
"Unauthorized. Open /terminal?token=YOUR_TERMINAL_AGENT_TOKEN",
status=401,
mimetype="text/plain",
)
return render_template("terminal.html",
brand_name="HF VM Studio",
brand_tag="Prompt-to-Backend Factory",
brand_emoji="β—†",
)
# ── Wallet & Tokens ─────────────────────────────────────────────
@app.route("/wallet/nonce", methods=["GET"])
def wallet_nonce():
"""Get a challenge nonce for wallet signature."""
if not _rate_check(f"nonce:{request.remote_addr}", window=60, max_requests=20):
return rate_limit_response()
n = _nonce()
return jsonify({"nonce": n, "message": f"HF VM Studio auth: {n}"})
def _is_valid_evm_address(addr: str) -> bool:
return bool(re.fullmatch(r"0x[a-f0-9]{40}", addr))
def _is_valid_solana_address(addr: str) -> bool:
try:
import base58
decoded = base58.b58decode(addr)
return len(decoded) == 32
except Exception:
return False
@app.route("/wallet/connect", methods=["POST"])
def wallet_connect():
"""Register a wallet connection with cryptographic signature verification."""
data = request.json or {}
raw_address = _clamp_str(data.get("address", ""), 128).strip()
provider = str(data.get("provider", "")).strip().lower()
signature = _clamp_str(data.get("signature", ""), 2048).strip()
nonce = _clamp_str(data.get("nonce", ""), 128).strip()
if not raw_address or not provider:
return jsonify({"error": "address and provider required"}), 400
if provider not in ("metamask", "phantom"):
return jsonify({"error": "provider must be metamask or phantom"}), 400
# EVM: lowercase; Solana: preserve base58 case
address = raw_address.lower() if provider == "metamask" else raw_address
if provider == "metamask" and not _is_valid_evm_address(address):
return jsonify({"error": "Invalid EVM address format"}), 400
if provider == "phantom" and not _is_valid_solana_address(address):
return jsonify({"error": "Invalid Solana address format"}), 400
if not _rate_check(f"wallet_connect:{request.remote_addr}", window=3600, max_requests=10):
return rate_limit_response()
if not signature or not nonce:
return jsonify({"error": "signature and nonce required"}), 400
# Verify signature
verified = False
if provider == "metamask":
verified = _verify_evm_signature(address, signature, nonce)
elif provider == "phantom":
verified = _verify_solana_signature(address, signature, nonce)
if not verified:
return jsonify({"error": "Signature verification failed"}), 401
now = datetime.now(timezone.utc).isoformat()
with wallet_lock:
with _db() as conn:
existing = conn.execute("SELECT address FROM wallets WHERE address = ?", (address,)).fetchone()
is_new = existing is None
conn.execute(
"INSERT OR REPLACE INTO wallets (address, provider, signature, nonce, connected_at, last_seen) VALUES (?, ?, ?, ?, COALESCE((SELECT connected_at FROM wallets WHERE address = ?), ?), ?)",
(address, provider, signature, nonce, address, now, now),
)
conn.commit()
welcome_bonus = 0
if is_new:
welcome_bonus = 1000 # 1000 integer tokens welcome bonus
credit_tokens(address, welcome_bonus, "welcome_bonus")
return jsonify({
"wallet": address,
"provider": provider,
"verified": True,
"balance": get_balance(address),
"welcome_bonus": welcome_bonus,
})
@app.route("/wallet/<address>", methods=["GET"])
def wallet_info(address):
"""Get wallet balance and connection info."""
addr = _normalize_wallet(address)
with wallet_lock:
with _db() as conn:
row = conn.execute("SELECT * FROM wallets WHERE address = ?", (addr,)).fetchone()
if not row:
return jsonify({"wallet": addr, "balance": 0, "connected": False}), 404
return jsonify({
"wallet": addr,
"balance": get_balance(addr),
"provider": row["provider"],
"connected_at": row["connected_at"],
"last_seen": row["last_seen"],
"connected": True,
})
@app.route("/wallet/<address>/history", methods=["GET"])
def wallet_history(address):
"""Get token transaction history for a wallet."""
addr = _normalize_wallet(address)
limit = max(1, min(int(request.args.get("limit", 50)), 200))
return jsonify({"wallet": addr, "transactions": tx_history(addr, limit)})
@app.route("/tokens/leaderboard", methods=["GET"])
def tokens_leaderboard():
limit = max(1, min(int(request.args.get("limit", 20)), 100))
return jsonify({"leaderboard": leaderboard(limit)})
@app.route("/tokens/buy", methods=["POST"])
def tokens_buy():
"""Create a Stripe checkout to buy token packs."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"tokens_buy:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
data = request.json or {}
raw_wallet = str(data.get("wallet_address", "")).strip()
# Detect address type: EVM starts with 0x, Solana is base58
is_evm = raw_wallet.startswith("0x")
wallet = raw_wallet.lower() if is_evm else raw_wallet
if is_evm and not _is_valid_evm_address(wallet):
return jsonify({"error": "Invalid EVM wallet address"}), 400
if not is_evm and not _is_valid_solana_address(wallet):
return jsonify({"error": "Invalid Solana wallet address"}), 400
if not _rate_check(f"tokens_buy_wallet:{wallet}", window=3600, max_requests=5):
return rate_limit_response()
pack = str(data.get("pack", "small")).strip().lower()
packs = {
"small": {"amount_cents": 500, "tokens": 100, "label": "100 Tokens"},
"medium": {"amount_cents": 2000, "tokens": 500, "label": "500 Tokens"},
"large": {"amount_cents": 5000, "tokens": 1500, "label": "1500 Tokens"},
}
if pack not in packs:
return jsonify({"error": f"Unknown pack: {pack}. Choose small, medium, or large."}), 400
selected = packs[pack]
import stripe as stripe_lib
sk = settings.get("env", {}).get("STRIPE_SECRET_KEY") or os.environ.get("STRIPE_SECRET_KEY", "")
if not sk:
return jsonify({"error": "Stripe secret key not configured"}), 400
stripe_lib.api_key = sk
origin = get_app_origin()
try:
session = stripe_lib.checkout.Session.create(
payment_method_types=["card"],
line_items=[{
"price_data": {
"currency": "usd",
"product_data": {"name": f"HF VM Studio β€” {selected['label']}"},
"unit_amount": selected["amount_cents"],
},
"quantity": 1,
}],
mode="payment",
success_url=f"{origin}/?session_id={{CHECKOUT_SESSION_ID}}&wallet={wallet}&pack={pack}#tokens",
cancel_url=f"{origin}/?canceled=true#tokens",
metadata={
"source": "hf-vm-studio",
"wallet": wallet,
"pack": pack,
"tokens": str(selected["tokens"]),
},
)
receipt = create_receipt(
kind="token-purchase",
title=f"Token purchase initiated: {selected['label']}",
status="created",
command=f"checkout_session:{session.id}",
metadata={"session_id": session.id, "wallet": wallet, "pack": pack, "tokens": selected["tokens"]},
)
return jsonify({
"session_id": session.id,
"url": session.url,
"receipt_id": receipt["receipt_id"],
"pack": pack,
"tokens": selected["tokens"],
"amount_cents": selected["amount_cents"],
})
except Exception as e:
return jsonify({"error": str(e)}), 502
# ── Solana Token Launch Service ─────────────────────────────────
def _service_keypair_path() -> str:
"""Persist service keypair to disk for CLI use."""
if not SOLANA_SERVICE_KEY_B58:
raise ValueError("SOLANA_SERVICE_KEY_B58 not configured")
import base58 as b58
kp_path = Path("service_keypair.json")
if kp_path.exists():
return str(kp_path)
secret = b58.b58decode(SOLANA_SERVICE_KEY_B58)
# Phantom / solana-keygen exports 64 bytes [32 secret + 32 pubkey]
if len(secret) not in (32, 64):
raise ValueError("Invalid service keypair length")
from solders.keypair import Keypair
if len(secret) == 64:
kp = Keypair.from_bytes(secret)
else:
kp = Keypair.from_seed(secret)
arr = list(bytes(kp))
kp_path.write_text(json.dumps(arr))
return str(kp_path)
def _solana_cli(cmd: list[str], timeout: int = 60) -> dict:
"""Run a Solana CLI command with configured RPC and keypair."""
kp = _service_keypair_path()
full = ["solana", "--url", SOLANA_RPC_URL, "--keypair", kp] + cmd
result = subprocess.run(full, capture_output=True, text=True, timeout=timeout)
return {
"stdout": result.stdout,
"stderr": result.stderr,
"rc": result.returncode,
}
def _spl_token_cli(cmd: list[str], timeout: int = 60) -> dict:
"""Run spl-token CLI with configured RPC and fee-payer."""
kp = _service_keypair_path()
full = ["spl-token", "--url", SOLANA_RPC_URL, "--owner", kp, "--fee-payer", kp] + cmd
result = subprocess.run(full, capture_output=True, text=True, timeout=timeout)
return {
"stdout": result.stdout,
"stderr": result.stderr,
"rc": result.returncode,
}
def launch_spl_token(owner_address: str, name: str, symbol: str, decimals: int, supply: int) -> dict:
"""Launch a new SPL token on Solana. Returns mint address and tx signature."""
if not SOLANA_SERVICE_KEY_B58:
raise ValueError("SOLANA_SERVICE_KEY_B58 not configured; token launch unavailable")
if SOLANA_MAINNET_ENABLED:
logger.warning("Token launch executing on SOLANA MAINNET")
now = datetime.now(timezone.utc).isoformat()
launch_id = _new_tx_id()
# Generate mint keypair
from solders.keypair import Keypair
mint_kp = Keypair()
mint_path = Path(f"mint_{launch_id}.json")
mint_path.write_text(json.dumps(list(bytes(mint_kp))))
try:
# Create token mint
create_res = _spl_token_cli(["create-token", str(mint_path), "--decimals", str(decimals)])
if create_res["rc"] != 0:
raise RuntimeError(f"create-token failed: {create_res['stderr']}")
# Extract mint address from output
mint_addr = None
for line in create_res["stdout"].splitlines():
if "Creating token" in line:
parts = line.split()
if len(parts) >= 3:
mint_addr = parts[-1]
if line.startswith("Address:"):
mint_addr = line.split("Address:")[1].strip()
if not mint_addr:
# Fallback: use pubkey from keypair
mint_addr = str(mint_kp.pubkey())
# Create associated token account for owner
ata_res = _spl_token_cli(["create-account", mint_addr])
if ata_res["rc"] != 0:
logger.warning(f"create-account warning: {ata_res['stderr']}")
# Get ATA address
ata_addr = owner_address # For simple transfer, we need the ATA
# Actually spl-token create-account creates an ATA for the fee-payer
# We need to create an ATA for the owner_address instead
ata_for_owner = _spl_token_cli(["address", "--token", mint_addr, "--owner", owner_address])
owner_ata = None
for line in ata_for_owner["stdout"].splitlines():
if line.startswith("Associated token address"):
owner_ata = line.split(":")[-1].strip()
if not owner_ata:
# Create ATA for the actual owner
create_ata = _spl_token_cli(["create-account", mint_addr, "--owner", owner_address])
if create_ata["rc"] != 0:
logger.warning(f"create-account for owner warning: {create_ata['stderr']}")
# Try to extract ATA
for line in create_ata["stdout"].splitlines():
if line.startswith("Creating associated token account"):
owner_ata = line.split()[-1].strip()
if not owner_ata:
owner_ata = owner_address # Fallback (will likely fail but recorded)
# Mint tokens to owner
mint_res = _spl_token_cli(["mint", mint_addr, str(supply), owner_ata])
if mint_res["rc"] != 0:
raise RuntimeError(f"mint failed: {mint_res['stderr']}")
# Record in DB
with token_lock:
with _db() as conn:
conn.execute(
"INSERT INTO launched_tokens (launch_id, mint_address, owner_address, name, symbol, decimals, supply, tx_signature, network, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
(launch_id, mint_addr, owner_address, name, symbol, decimals, supply, "", "mainnet" if SOLANA_MAINNET_ENABLED else "devnet", now),
)
conn.commit()
return {
"launch_id": launch_id,
"mint_address": mint_addr,
"owner_ata": owner_ata,
"network": "mainnet" if SOLANA_MAINNET_ENABLED else "devnet",
"name": name,
"symbol": symbol,
"decimals": decimals,
"supply": supply,
}
finally:
# Cleanup temp keypair
if mint_path.exists():
mint_path.unlink()
@app.route("/tokens/launch", methods=["POST"])
def tokens_launch():
"""Launch a new SPL token on Solana. Costs tokens from user balance."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"token_launch:{request.remote_addr}", window=3600, max_requests=3):
return rate_limit_response()
data = request.json or {}
raw_owner = _clamp_str(data.get("owner_address", ""), 128).strip()
name = _clamp_str(data.get("name", ""), 64).strip()
symbol = _clamp_str(data.get("symbol", ""), 16).strip().upper()
decimals = max(0, min(int(data.get("decimals", 9)), 18))
supply = max(1, int(data.get("supply", 1_000_000_000)))
if not raw_owner:
return jsonify({"error": "owner_address required"}), 400
if not name or not symbol:
return jsonify({"error": "name and symbol required"}), 400
if not _is_valid_solana_address(raw_owner):
return jsonify({"error": "Invalid Solana owner address"}), 400
owner = _normalize_wallet(raw_owner)
cost = _get_token_cost("token_launch")
bal = get_balance(owner)
if bal < cost:
return jsonify({"error": f"Insufficient tokens. Need {cost}, have {bal}."}), 402
try:
# Debit launch cost
debit_tokens(owner, cost, "token_launch")
result = launch_spl_token(owner, name, symbol, decimals, supply)
result["cost"] = cost
result["balance_after"] = get_balance(owner)
create_receipt(
kind="token-launch",
title=f"Launched {symbol} on {result['network']}",
status="completed",
metadata=result,
)
return jsonify(result), 201
except ValueError as e:
return jsonify({"error": str(e)}), 400
except RuntimeError as e:
return jsonify({"error": str(e)}), 502
except Exception as e:
logger.exception("Token launch failed")
return jsonify({"error": "Token launch failed. Check logs."}), 500
@app.route("/tokens/launched", methods=["GET"])
def tokens_launched():
"""List launched tokens for a wallet."""
wallet = request.args.get("wallet", "").strip()
limit = max(1, min(int(request.args.get("limit", 20)), 100))
if not wallet:
return jsonify({"error": "wallet query param required"}), 400
addr = _normalize_wallet(wallet)
with token_lock:
with _db() as conn:
rows = conn.execute(
"SELECT * FROM launched_tokens WHERE owner_address = ? ORDER BY created_at DESC LIMIT ?",
(addr, limit),
).fetchall()
return jsonify({
"wallet": addr,
"tokens": [dict(r) for r in rows],
"network": "mainnet" if SOLANA_MAINNET_ENABLED else "devnet",
})
# ── CLAIMOS API ────────────────────────────────────────────────
@app.route("/claimos/evaluate", methods=["POST"])
def claimos_evaluate():
"""Create or evaluate a claim: POST evidence + signals, get probability state + receipt."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"claimos_evaluate:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
data = request.json or {}
claim_id = str(data.get("claim_id", f"claim_{uuid.uuid4().hex}")).strip()
title = str(data.get("title", "Untitled Claim")).strip()
description = str(data.get("description", "")).strip()[:2000]
wallet = str(data.get("wallet", "")).strip()
# Upsert claim
now = datetime.now(timezone.utc).isoformat()
with _db() as conn:
existing = conn.execute("SELECT claim_id FROM claims WHERE claim_id = ?", (claim_id,)).fetchone()
if not existing:
conn.execute(
"INSERT INTO claims (claim_id, title, description, status, created_at, updated_at, wallet) VALUES (?, ?, ?, ?, ?, ?, ?)",
(claim_id, title, description, "evidence_received", now, now, wallet or None),
)
else:
conn.execute(
"UPDATE claims SET title = ?, description = ?, updated_at = ? WHERE claim_id = ?",
(title, description, now, claim_id),
)
conn.commit()
# Store evidence items
evidence_items = data.get("evidence", [])
if evidence_items:
with _db() as conn:
for ev in evidence_items:
ev_id = str(ev.get("evidence_id", f"ev_{uuid.uuid4().hex}")).strip()
source_type = str(ev.get("source_type", "other")).strip().lower()
if source_type not in ("audio","document","transcript","witness","hospital","police","screenshot","email","timeline","other"):
source_type = "other"
source_ref = str(ev.get("source_ref", "")).strip()[:500]
content = str(ev.get("content", "")).strip()[:4000]
content_hash = hashlib.sha256(content.encode("utf-8")).hexdigest()
strength = float(ev.get("evidence_strength", 0.5))
conn.execute(
"""INSERT OR REPLACE INTO evidence
(evidence_id, claim_id, source_type, source_ref, content_hash, content, evidence_strength, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
(ev_id, claim_id, source_type, source_ref, content_hash, content, strength, now),
)
conn.commit()
# Debit tokens for evaluation
if wallet:
addr = _normalize_wallet(wallet)
bal = get_balance(addr)
cost = _get_token_cost("claim_evaluate")
if bal < cost:
return jsonify({"error": f"Insufficient tokens. Need {cost}, have {bal}"}), 402
debit_tokens(addr, cost, "claim_evaluate", {"claim_id": claim_id})
# Evaluate probability
try:
inputs = {
"evidence_strength": data.get("evidence_strength"),
"counsel_signal": data.get("counsel_signal"),
"procedural_survival": data.get("procedural_survival"),
"settlement_signal": data.get("settlement_signal"),
"uncertainty": data.get("uncertainty"),
}
inputs = {k: float(v) for k, v in inputs.items() if v is not None}
prob = ClaimProbabilityEngine.evaluate(claim_id, inputs if inputs else None)
except ValueError as e:
return jsonify({"error": str(e)}), 404
# Create proof receipt
receipt = create_receipt(
kind="claim-evaluation",
title=f"Claim evaluated: {title}",
status="completed",
command=f"claimos_evaluate:{claim_id}",
metadata={"claim_id": claim_id, "p_recovery": prob["p_recovery"], "wallet": wallet},
)
return jsonify({
"claim_id": claim_id,
"probability_state": prob,
"receipt_id": receipt["receipt_id"],
"tokens_debited": _get_token_cost("claim_evaluate") if wallet else 0,
})
@app.route("/claimos/<claim_id>", methods=["GET"])
def claimos_get(claim_id: str):
"""Get full claim state including evidence and contradictions."""
if not _rate_check(f"claimos_get:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
with _db() as conn:
claim = conn.execute("SELECT * FROM claims WHERE claim_id = ?", (claim_id,)).fetchone()
if not claim:
return jsonify({"error": "Claim not found"}), 404
evidence = conn.execute("SELECT * FROM evidence WHERE claim_id = ?", (claim_id,)).fetchall()
contradictions = conn.execute("SELECT * FROM contradictions WHERE claim_id = ? AND resolved = 0", (claim_id,)).fetchall()
return jsonify({
"claim": dict(claim),
"evidence": [dict(r) for r in evidence],
"contradictions": [dict(r) for r in contradictions],
})
@app.route("/claimos/<claim_id>/contradictions", methods=["POST"])
def claimos_contradictions(claim_id: str):
"""Run contradiction scan on a claim. Costs tokens."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"claimos_cx:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
data = request.json or {}
wallet = str(data.get("wallet", "")).strip()
if wallet:
addr = _normalize_wallet(wallet)
bal = get_balance(addr)
cost = _get_token_cost("claim_contradiction_scan")
if bal < cost:
return jsonify({"error": f"Insufficient tokens. Need {cost}, have {bal}"}), 402
debit_tokens(addr, cost, "claim_contradiction_scan", {"claim_id": claim_id})
cx = ContradictionDetector.detect(claim_id)
receipt = create_receipt(
kind="claim-contradiction-scan",
title=f"Contradiction scan: {len(cx)} found",
status="completed",
command=f"claimos_contradictions:{claim_id}",
metadata={"claim_id": claim_id, "contradictions_found": len(cx)},
)
return jsonify({
"claim_id": claim_id,
"contradictions": cx,
"contradiction_count": len(cx),
"receipt_id": receipt["receipt_id"],
"tokens_debited": _get_token_cost("claim_contradiction_scan") if wallet else 0,
})
@app.route("/claimos/<claim_id>/greeks", methods=["GET", "POST"])
def claimos_greeks(claim_id: str):
"""Compute and return Claim Greeks (Ξ”, Θ, Ξ“, V, K). Costs tokens if wallet provided."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"claimos_greeks:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
data = request.json or {}
wallet = str(data.get("wallet", "")).strip()
if wallet:
addr = _normalize_wallet(wallet)
bal = get_balance(addr)
cost = _get_token_cost("claim_greeks")
if bal < cost:
return jsonify({"error": f"Insufficient tokens. Need {cost}, have {bal}"}), 402
debit_tokens(addr, cost, "claim_greeks", {"claim_id": claim_id})
try:
greeks = ClaimGreeks.compute(claim_id)
except ValueError as e:
return jsonify({"error": str(e)}), 404
receipt = create_receipt(
kind="claim-greeks",
title="Claim Greeks computed",
status="completed",
command=f"claimos_greeks:{claim_id}",
metadata={"claim_id": claim_id, "greeks": greeks},
)
return jsonify({
"claim_id": claim_id,
"greeks": greeks,
"receipt_id": receipt["receipt_id"],
"tokens_debited": _get_token_cost("claim_greeks") if wallet else 0,
})
@app.route("/claimos/<claim_id>/liquidity", methods=["GET"])
def claimos_liquidity(claim_id: str):
"""Compute finance readiness / liquidity score for a claim."""
if not _rate_check(f"claimos_liq:{request.remote_addr}", window=60, max_requests=20):
return rate_limit_response()
try:
liq = ClaimLiquidity.compute(claim_id)
except ValueError as e:
return jsonify({"error": str(e)}), 404
receipt = create_receipt(
kind="claim-liquidity",
title=f"Liquidity score: {liq['liquidity_score']:.4f}",
status="completed",
command=f"claimos_liquidity:{claim_id}",
metadata={"claim_id": claim_id, "liquidity": liq["liquidity_score"]},
)
return jsonify({
"claim_id": claim_id,
"liquidity": liq,
"receipt_id": receipt["receipt_id"],
})
@app.route("/claimos/<claim_id>/assess", methods=["POST"])
def claimos_assess(claim_id: str):
"""Use LLM to assess evidence quality and auto-update evidence_strength scores. Costs tokens."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"claimos_assess:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
data = request.json or {}
wallet = str(data.get("wallet", "")).strip()
if wallet:
addr = _normalize_wallet(wallet)
bal = get_balance(addr)
cost = _get_token_cost("claim_evaluate")
if bal < cost:
return jsonify({"error": f"Insufficient tokens. Need {cost}, have {bal}"}), 402
debit_tokens(addr, cost, "claim_assess", {"claim_id": claim_id})
with _db() as conn:
rows = conn.execute("SELECT * FROM evidence WHERE claim_id = ?", (claim_id,)).fetchall()
if not rows:
return jsonify({"error": "No evidence found for claim"}), 404
# Build LLM prompt for evidence assessment
ev_text = "\n\n".join(
f"[{i+1}] {r['source_type'].upper()} (ref: {r['source_ref']}): {r['content'][:1000]}"
for i, r in enumerate(rows)
)
system_prompt = (
"You are a legal evidence assessor. Rate each evidence item on: credibility (0-1), "
"relevance (0-1), completeness (0-1), and overall_strength (0-1). Return ONLY a JSON array "
"where each item has: index (1-based), credibility, relevance, completeness, overall_strength, "
"rationale (string). Be strict and realistic."
)
try:
result = call_llm(prompt=f"Assess the following evidence items for claim {claim_id}:\n\n{ev_text}", system=system_prompt, model="json")
parsed = parse_llm_json(result.get("response", "[]"))
if not isinstance(parsed, list):
raise ValueError("LLM returned non-array")
now = datetime.now(timezone.utc).isoformat()
updated = []
with _db() as conn:
for item in parsed:
idx = int(item.get("index", 0)) - 1
if 0 <= idx < len(rows):
ev_id = rows[idx]["evidence_id"]
strength = round(min(1.0, max(0.0, float(item.get("overall_strength", 0.5)))), 4)
conn.execute(
"UPDATE evidence SET evidence_strength = ?, metadata = ? WHERE evidence_id = ?",
(strength, json.dumps({"assessment": item}), ev_id),
)
updated.append({"evidence_id": ev_id, "strength": strength, "rationale": item.get("rationale", "")})
conn.commit()
receipt = create_receipt(
kind="claim-assess",
title=f"Evidence assessed: {len(updated)} items",
status="completed",
command=f"claimos_assess:{claim_id}",
metadata={"claim_id": claim_id, "items_assessed": len(updated)},
)
return jsonify({
"claim_id": claim_id,
"assessments": updated,
"receipt_id": receipt["receipt_id"],
"tokens_debited": _get_token_cost("claim_evaluate") if wallet else 0,
})
except Exception as e:
logger.warning(f"Claim assessment LLM failed: {e}")
return jsonify({"error": f"LLM assessment failed: {e}"}), 502
@app.route("/claimos/<claim_id>/appraise", methods=["GET"])
def claimos_appraise(claim_id: str):
"""Generate a full legal appraisal report via LLM. Returns narrative + structured metrics."""
if not _rate_check(f"claimos_appraise:{request.remote_addr}", window=60, max_requests=5):
return rate_limit_response()
with _db() as conn:
claim = conn.execute("SELECT * FROM claims WHERE claim_id = ?", (claim_id,)).fetchone()
evidence = conn.execute("SELECT * FROM evidence WHERE claim_id = ?", (claim_id,)).fetchall()
contradictions = conn.execute("SELECT * FROM contradictions WHERE claim_id = ? AND resolved = 0", (claim_id,)).fetchall()
if not claim:
return jsonify({"error": "Claim not found"}), 404
claim_data = dict(claim)
ev_data = [dict(r) for r in evidence]
cx_data = [dict(r) for r in contradictions]
prompt = (
f"Generate a legal claim appraisal report.\n\n"
f"CLAIM: {claim_data.get('title', '')}\n"
f"DESCRIPTION: {claim_data.get('description', '')}\n"
f"STATUS: {claim_data.get('status', '')}\n"
f"P(RECOVERY): {claim_data.get('p_recovery', 0)}\n"
f"EVIDENCE COUNT: {len(ev_data)}\n"
f"CONTRADICTIONS: {len(cx_data)}\n\n"
f"EVIDENCE:\n" + "\n".join(
f"- {e['source_type']} ({e['source_ref']}): strength={e['evidence_strength']}"
for e in ev_data[:10]
) + "\n\n"
f"Return ONLY JSON with: summary (string), strengths (array), risks (array), "
f"recommended_next_steps (array), settlement_likelihood (0-1), expected_recovery_range (string)."
)
try:
result = call_llm(prompt=prompt, system="You are a senior legal claim appraiser. Be concise, realistic, and structured.", model="quality")
parsed = parse_llm_json(result.get("response", "{}"))
if not isinstance(parsed, dict):
parsed = {"summary": "Appraisal generated", "raw": result.get("response", "")}
receipt = create_receipt(
kind="claim-appraisal",
title=f"Appraisal: {claim_data.get('title', claim_id)[:60]}",
status="completed",
command=f"claimos_appraise:{claim_id}",
metadata={"claim_id": claim_id, "appraisal": parsed},
)
return jsonify({
"claim_id": claim_id,
"appraisal": parsed,
"probability_state": {
"p_recovery": claim_data.get("p_recovery"),
"liquidity_score": claim_data.get("liquidity_score"),
"status": claim_data.get("status"),
},
"receipt_id": receipt["receipt_id"],
})
except Exception as e:
logger.warning(f"Claim appraisal LLM failed: {e}")
return jsonify({"error": f"Appraisal failed: {e}"}), 502
@app.route("/tokens/verify/<mint_address>", methods=["GET"])
def tokens_verify(mint_address: str):
"""Verify an SPL token mint exists on-chain via Solana RPC. No simulation."""
if not _rate_check(f"token_verify:{request.remote_addr}", window=60, max_requests=20):
return rate_limit_response()
# Call Solana RPC getAccountInfo for the mint
rpc_payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "getAccountInfo",
"params": [mint_address, {"encoding": "jsonParsed"}],
}
try:
resp = requests.post(SOLANA_RPC_URL, json=rpc_payload, timeout=15)
resp.raise_for_status()
data = resp.json()
if data.get("error"):
return jsonify({"mint": mint_address, "exists": False, "error": data["error"]}), 404
result = data.get("result", {})
value = result.get("value")
if not value:
return jsonify({"mint": mint_address, "exists": False, "on_chain": False}), 404
# Mint account exists β€” parse token data if available
parsed = value.get("data", {}).get("parsed", {}).get("info", {}) if isinstance(value.get("data"), dict) else {}
return jsonify({
"mint": mint_address,
"exists": True,
"on_chain": True,
"rpc": SOLANA_RPC_URL,
"lamports": value.get("lamports"),
"owner": value.get("owner"),
"executable": value.get("executable"),
"parsed_info": parsed,
"verified_at": datetime.now(timezone.utc).isoformat(),
})
except Exception as e:
logger.warning(f"Solana RPC verification failed for {mint_address}: {e}")
return jsonify({"mint": mint_address, "exists": False, "error": str(e)}), 502
# ── Finance / Underwriting Proof ────────────────────────────────
@app.route("/finance/collateral", methods=["GET"])
def finance_collateral():
"""Underwriting proof: verifiable income, deferred revenue, token velocity."""
if not _rate_check(f"finance:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
with token_lock:
with _db() as conn:
# Total revenue
rev_row = conn.execute("SELECT COALESCE(SUM(amount_cents), 0) AS total FROM revenue").fetchone()
total_revenue_cents = rev_row["total"] if rev_row else 0
# Deferred revenue (outstanding token liability)
def_row = conn.execute("SELECT COALESCE(SUM(deferred_cents), 0) AS total, COALESCE(SUM(tokens_purchased), 0) AS purchased, COALESCE(SUM(tokens_spent), 0) AS spent FROM deferred_revenue").fetchone()
deferred_cents = def_row["total"] if def_row else 0
tokens_purchased = def_row["purchased"] if def_row else 0
tokens_spent = def_row["spent"] if def_row else 0
# Wallet count
wallet_row = conn.execute("SELECT COUNT(*) AS cnt FROM wallets").fetchone()
wallet_count = wallet_row["cnt"] if wallet_row else 0
# Active paying wallets (have purchased tokens)
pay_row = conn.execute("SELECT COUNT(DISTINCT wallet) AS cnt FROM stripe_sessions").fetchone()
paying_wallets = pay_row["cnt"] if pay_row else 0
# Period revenue (last 6 months)
period_rows = conn.execute(
"SELECT period, SUM(amount_cents) AS cents FROM revenue GROUP BY period ORDER BY period DESC LIMIT 6"
).fetchall()
# Token velocity: spend rate
vel_row = conn.execute(
"SELECT COALESCE(SUM(amount), 0) AS spent FROM transactions WHERE type = 'debit' AND created_at > datetime('now', '-30 days')"
).fetchone()
monthly_spend = vel_row["spent"] if vel_row else 0
return jsonify({
"underwriting_version": "1.0.0",
"generated_at": datetime.now(timezone.utc).isoformat(),
"total_revenue_usd": round(total_revenue_cents / 100, 2),
"deferred_revenue_usd": round(deferred_cents / 100, 2),
"recognized_revenue_usd": round((total_revenue_cents - deferred_cents) / 100, 2),
"wallet_count": wallet_count,
"paying_wallets": paying_wallets,
"tokens_purchased": tokens_purchased,
"tokens_spent": tokens_spent,
"token_velocity_30d": monthly_spend,
"revenue_by_period": [{"period": r["period"], "usd": round(r["cents"] / 100, 2)} for r in period_rows],
"collateral_score": round(min(100, (total_revenue_cents / 1000) + (paying_wallets * 10) + (monthly_spend / 100)), 2),
})
@app.route("/finance/revenue", methods=["GET"])
def finance_revenue():
"""Revenue dashboard with period and source breakdown."""
if not _rate_check(f"finance:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
period_filter = request.args.get("period", "")
source_filter = request.args.get("source", "")
limit = max(1, min(int(request.args.get("limit", 100)), 500))
with token_lock:
with _db() as conn:
query = "SELECT * FROM revenue WHERE 1=1"
params = []
if period_filter:
query += " AND period = ?"
params.append(period_filter)
if source_filter:
query += " AND source = ?"
params.append(source_filter)
query += " ORDER BY created_at DESC LIMIT ?"
params.append(limit)
rows = conn.execute(query, params).fetchall()
# Aggregates
agg = conn.execute("SELECT source, SUM(amount_cents) AS cents FROM revenue GROUP BY source").fetchall()
return jsonify({
"entries": [{"revenue_id": r["revenue_id"], "source": r["source"], "amount_cents": r["amount_cents"], "currency": r["currency"], "period": r["period"], "wallet": r["wallet"], "created_at": r["created_at"]} for r in rows],
"by_source": {r["source"]: r["cents"] for r in agg},
"total_usd": round(sum(r["cents"] for r in agg) / 100, 2),
})
@app.route("/finance/reconcile", methods=["POST"])
def finance_reconcile():
"""Reconcile Stripe sessions with token credits and revenue ledger."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"finance:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
with token_lock:
with _db() as conn:
# Find Stripe sessions without matching transactions
orphan_sessions = conn.execute(
"""SELECT s.session_id, s.amount_cents, s.wallet, s.pack, s.tokens, s.tx_id
FROM stripe_sessions s
LEFT JOIN transactions t ON s.tx_id = t.tx_id
WHERE t.tx_id IS NULL"""
).fetchall()
# Find transactions without matching revenue
orphan_tx = conn.execute(
"""SELECT t.tx_id, t.address, t.amount, t.reason
FROM transactions t
LEFT JOIN revenue r ON t.tx_id = r.session_id
WHERE t.type = 'credit' AND r.revenue_id IS NULL AND t.reason LIKE 'stripe_purchase%'"""
).fetchall()
return jsonify({
"orphan_stripe_sessions": len(orphan_sessions),
"orphan_transactions": len(orphan_tx),
"orphan_session_details": [{"session_id": s["session_id"], "wallet": s["wallet"], "tokens": s["tokens"]} for s in orphan_sessions],
"reconciled": len(orphan_sessions) == 0 and len(orphan_tx) == 0,
})
@app.route("/finance/rollback", methods=["POST"])
def finance_rollback():
"""Rollback a transaction by tx_id. Returns tokens to wallet and reverses revenue."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"finance:{request.remote_addr}", window=60, max_requests=5):
return rate_limit_response()
data = request.json or {}
tx_id = str(data.get("tx_id", "")).strip()
reason = str(data.get("reason", "rollback")).strip()
if not tx_id:
return jsonify({"error": "tx_id required"}), 400
now = datetime.now(timezone.utc).isoformat()
with token_lock:
with _db() as conn:
tx = conn.execute("SELECT * FROM transactions WHERE tx_id = ?", (tx_id,)).fetchone()
if not tx:
return jsonify({"error": "Transaction not found"}), 404
addr = tx["address"]
amount = tx["amount"]
tx_type = tx["type"]
# Reverse the transaction
if tx_type == "credit":
# Was a credit β†’ debit back
bal_row = conn.execute("SELECT balance FROM balances WHERE address = ?", (addr,)).fetchone()
current = bal_row["balance"] if bal_row else 0
if current < amount:
return jsonify({"error": f"Cannot rollback: wallet balance {current} < {amount}"}), 400
conn.execute("UPDATE balances SET balance = balance - ? WHERE address = ?", (amount, addr))
# Reverse deferred revenue only for purchased tokens
if tx["reason"].startswith("stripe_purchase"):
conn.execute(
"""UPDATE deferred_revenue SET
tokens_purchased = MAX(0, tokens_purchased - ?),
deferred_cents = MAX(0, deferred_cents - (SELECT deferred_cents FROM deferred_revenue WHERE address = ?) / NULLIF(tokens_purchased, 0) * ?),
last_updated = ? WHERE address = ? AND tokens_purchased > 0""",
(amount, addr, amount, now, addr),
)
elif tx_type == "debit":
# Was a debit β†’ credit back
conn.execute(
"INSERT OR REPLACE INTO balances (address, balance) VALUES (?, COALESCE((SELECT balance FROM balances WHERE address = ?), 0) + ?)",
(addr, addr, amount),
)
# Restore deferred revenue liability
if tx["reason"].startswith("token_") or tx["reason"].startswith("shell_") or tx["reason"].startswith("kernel_") or tx["reason"].startswith("notebook_") or tx["reason"].startswith("deploy_") or tx["reason"].startswith("agent_"):
conn.execute(
"""UPDATE deferred_revenue SET
tokens_spent = MAX(0, tokens_spent - ?),
deferred_cents = deferred_cents + (SELECT deferred_cents FROM deferred_revenue WHERE address = ?) / NULLIF(tokens_purchased, 0) * ?,
last_updated = ? WHERE address = ? AND tokens_purchased > 0""",
(amount, addr, amount, now, addr),
)
# Mark original as rolled back
rollback_tx_id = f"rollback_{tx_id}_{uuid.uuid4().hex[:8]}"
conn.execute(
"INSERT INTO transactions (tx_id, address, amount, type, reason, created_at, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)",
(rollback_tx_id, addr, amount, "rollback", reason, now, json.dumps({"original_tx_id": tx_id, "original_type": tx_type})),
)
# Reverse revenue if linked
rev = conn.execute("SELECT revenue_id FROM revenue WHERE session_id = ?", (tx_id,)).fetchone()
if rev:
conn.execute("DELETE FROM revenue WHERE revenue_id = ?", (rev["revenue_id"],))
conn.commit()
add_memory(
title=f"Rollback: {tx_id}",
content=f"Rolled back transaction {tx_id} for wallet {addr}. Reason: {reason}",
source="finance-rollback",
tags=["rollback", "finance"],
metadata={"original_tx_id": tx_id, "wallet": addr, "amount": amount, "reason": reason},
importance=0.9,
)
return jsonify({"rollback_tx_id": rollback_tx_id, "original_tx_id": tx_id, "wallet": addr, "amount": amount, "reason": reason})
# ── Pixelator / GlyphIndex API ────────────────────────────────
@app.route("/pixelator/ingest", methods=["POST"])
def pixelator_ingest():
"""Ingest HTML, tokenize to glyph units, emit proof receipt."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"pixelator_ingest:{request.remote_addr}", window=60, max_requests=5):
return rate_limit_response()
data = request.json or {}
html = str(data.get("html", ""))
url = str(data.get("url", "")).strip() or "about:blank"
website_id = str(data.get("website_id", "")).strip() or f"site_{uuid.uuid4().hex[:8]}"
title = str(data.get("title", "")).strip()
wallet = str(data.get("wallet", "")).strip()
if not html:
return jsonify({"error": "html required"}), 400
# Cap HTML size to prevent abuse (C30)
if len(html) > 2_000_000:
return jsonify({"error": "HTML too large. Max 2MB."}), 413
# Debit tokens
if wallet:
addr = _normalize_wallet(wallet)
bal = get_balance(addr)
cost = _get_token_cost("pixelator_ingest")
if bal < cost:
return jsonify({"error": f"Insufficient tokens. Need {cost}, have {bal}."}), 402
debit_tokens(addr, cost, "pixelator_ingest", {"url": url, "website_id": website_id})
try:
result = MembraPixelator.ingest(html, url, website_id, title)
receipt = create_receipt(
kind="pixelator-ingest",
title=f"Pixelated: {result['title'] or url}",
status="completed",
command=f"pixelator_ingest:{result['page_id']}",
metadata=result,
)
result["receipt_id"] = receipt["receipt_id"]
result["tokens_debited"] = _get_token_cost("pixelator_ingest") if wallet else 0
return jsonify(result), 201
except Exception as e:
logger.exception("Pixelator ingest failed")
return jsonify({"error": "Pixelator ingest failed. Check logs."}), 500
@app.route("/pixelator/page/<page_id>/glyphs", methods=["GET"])
def pixelator_page_glyphs(page_id: str):
"""Get glyph units for a page."""
if not _rate_check(f"pixelator_glyphs:{request.remote_addr}", window=60, max_requests=20):
return rate_limit_response()
limit = max(1, min(int(request.args.get("limit", 1000)), 5000))
offset = max(0, int(request.args.get("offset", 0)))
try:
glyphs = MembraPixelator.get_page_glyphs(page_id, limit, offset)
return jsonify({
"page_id": page_id,
"glyphs": glyphs,
"count": len(glyphs),
"limit": limit,
"offset": offset,
})
except Exception as e:
logger.exception("Pixelator glyphs fetch failed")
return jsonify({"error": str(e)}), 500
@app.route("/pixelator/page/<page_id>/activation", methods=["GET"])
def pixelator_page_activation(page_id: str):
"""Get page activation summary with glyph statistics."""
if not _rate_check(f"pixelator_activation:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
try:
result = MembraPixelator.get_page_activation(page_id)
return jsonify(result)
except ValueError as e:
return jsonify({"error": str(e)}), 404
except Exception as e:
logger.exception("Pixelator activation fetch failed")
return jsonify({"error": str(e)}), 500
@app.route("/pixelator/website/<website_id>/top-glyphs", methods=["GET"])
def pixelator_top_glyphs(website_id: str):
"""Get highest-value glyphs across a website."""
if not _rate_check(f"pixelator_top:{request.remote_addr}", window=60, max_requests=20):
return rate_limit_response()
limit = max(1, min(int(request.args.get("limit", 50)), 200))
try:
glyphs = MembraPixelator.get_top_glyphs(website_id, limit)
return jsonify({
"website_id": website_id,
"glyphs": glyphs,
"count": len(glyphs),
})
except Exception as e:
logger.exception("Pixelator top glyphs fetch failed")
return jsonify({"error": str(e)}), 500
@app.route("/pixelator/learn", methods=["POST"])
def pixelator_learn():
"""Retrain DOM weights and semantic lexicon from actual page results.
Higher page_activation β†’ reinforce tag weights and term confidence."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"pixelator_learn:{request.remote_addr}", window=60, max_requests=5):
return rate_limit_response()
data = request.json or {}
min_samples = max(1, int(data.get("min_samples", 3)))
now = datetime.now(timezone.utc).isoformat()
with _db() as conn:
# Learn DOM weights: update each tag's weight toward the average page_activation of pages using that tag
tag_rows = conn.execute("""
SELECT tag, COUNT(*) AS n, AVG(page_activation_value) AS avg_pa
FROM pages p
JOIN (
SELECT DISTINCT page_id, SUBSTR(dom_path, INSTR(dom_path, '>') + 2) AS tag
FROM glyph_units
) g ON p.page_id = g.page_id
GROUP BY tag HAVING n >= ?
""", (min_samples,)).fetchall()
dom_updated = 0
for row in tag_rows:
tag, n, avg_pa = row["tag"], row["n"], row["avg_pa"] or 0.0
# New weight = (old_weight * old_samples + avg_pa) / (old_samples + 1)
old = conn.execute("SELECT weight, sample_count FROM dom_weights WHERE tag = ?", (tag,)).fetchone()
if old:
new_weight = (old["weight"] * old["sample_count"] + avg_pa) / (old["sample_count"] + n)
new_count = old["sample_count"] + n
else:
new_weight = avg_pa
new_count = n
conn.execute(
"""INSERT OR REPLACE INTO dom_weights (tag, weight, sample_count, avg_page_activation, updated_at)
VALUES (?, ?, ?, ?, ?)""",
(tag, round(new_weight, 4), new_count, round(avg_pa, 4), now),
)
dom_updated += 1
# Learn semantic lexicon: reinforce terms that appear on high-activation pages
term_rows = conn.execute("""
SELECT char_value AS term, semantic_role AS category, COUNT(*) AS freq,
AVG(glyph_value) AS avg_gv, AVG(page_activation_value) AS avg_pa
FROM glyph_units g
JOIN pages p ON g.page_id = p.page_id
WHERE semantic_role IN ('entity','action','commercial','legal')
GROUP BY term, category HAVING freq >= ?
""", (min_samples,)).fetchall()
lex_updated = 0
for row in term_rows:
term, category, freq, avg_gv, avg_pa = row["term"], row["category"], row["freq"], row["avg_gv"], row["avg_pa"]
# Confidence proportional to average glyph value and page activation
confidence = min(0.99, (avg_gv or 0.0) * 0.1 + (avg_pa or 0.0) * 0.01)
old = conn.execute(
"SELECT frequency, confidence FROM semantic_lexicon WHERE term = ? AND category = ?",
(term, category),
).fetchone()
if old:
freq = old["frequency"] + freq
confidence = (old["confidence"] + confidence) / 2
conn.execute(
"""INSERT OR REPLACE INTO semantic_lexicon
(term, category, frequency, confidence, source_count, updated_at)
VALUES (?, ?, ?, ?, ?, ?)""",
(term, category, freq, round(confidence, 4), freq, now),
)
lex_updated += 1
conn.commit()
return jsonify({
"dom_weights_updated": dom_updated,
"lexicon_terms_updated": lex_updated,
"min_samples": min_samples,
"learned_at": now,
})
@app.route("/costs", methods=["GET", "POST"])
def manage_costs():
"""Get or update token costs. No hardcoded values β€” DB is source of truth."""
if request.method == "GET":
with _db() as conn:
rows = conn.execute("SELECT operation, cost, source, updated_at FROM token_costs ORDER BY operation").fetchall()
return jsonify({"costs": [dict(r) for r in rows]})
auth = require_auth()
if auth:
return auth
data = request.json or {}
operation = str(data.get("operation", "")).strip()
cost = data.get("cost")
if not operation or cost is None:
return jsonify({"error": "operation and cost required"}), 400
try:
cost = int(cost)
except (TypeError, ValueError):
return jsonify({"error": "cost must be an integer"}), 400
if cost < 0:
return jsonify({"error": "cost must be non-negative"}), 400
now = datetime.now(timezone.utc).isoformat()
with _db() as conn:
conn.execute(
"INSERT OR REPLACE INTO token_costs (operation, cost, source, updated_at) VALUES (?, ?, 'admin', ?)",
(operation, cost, now),
)
conn.commit()
return jsonify({"operation": operation, "cost": cost, "updated_at": now}), 200
# ── GA-RL Crawler API ─────────────────────────────────────────
@app.route("/crawler/targets", methods=["GET", "POST"])
def crawler_targets():
"""List or register crawl target websites."""
if request.method == "GET":
if not _rate_check(f"crawler_targets:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
with _db() as conn:
rows = conn.execute("SELECT * FROM crawl_targets ORDER BY fitness_score DESC").fetchall()
return jsonify({"targets": [dict(r) for r in rows], "count": len(rows)})
# POST: register new target
auth = require_auth()
if auth:
return auth
data = request.json or {}
website_id = str(data.get("website_id", "")).strip()
root_url = str(data.get("root_url", "")).strip()
if not website_id or not root_url:
return jsonify({"error": "website_id and root_url required"}), 400
try:
crawler = GARLCrawler()
result = crawler.add_target(
website_id=website_id,
root_url=root_url,
name=str(data.get("name", "")).strip(),
depth=max(1, min(int(data.get("crawl_depth", 2)), 5)),
priority=float(data.get("priority", 1.0)),
selector_rules=str(data.get("selector_rules", "")),
)
return jsonify(result), 201
except ValueError as e:
return jsonify({"error": str(e)}), 409
except Exception as e:
logger.exception("Crawler add_target failed")
return jsonify({"error": "Failed to add target"}), 500
@app.route("/crawler/targets/<target_id>", methods=["DELETE"])
def crawler_target_delete(target_id: str):
auth = require_auth()
if auth:
return auth
with _db() as conn:
conn.execute("DELETE FROM crawl_targets WHERE target_id = ?", (target_id,))
conn.commit()
return jsonify({"deleted": target_id})
@app.route("/crawler/queue", methods=["POST"])
def crawler_enqueue():
"""Add a URL to the rotator buffer crawl queue."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"crawler_queue:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
data = request.json or {}
target_id = str(data.get("target_id", "")).strip()
url = str(data.get("url", "")).strip()
if not target_id or not url:
return jsonify({"error": "target_id and url required"}), 400
depth = max(0, min(int(data.get("depth", 0)), 5))
priority_score = float(data.get("priority_score", 0.0))
try:
crawler = GARLCrawler()
result = crawler.enqueue(target_id, url, depth, priority_score)
return jsonify(result), 201
except Exception as e:
logger.exception("Crawler enqueue failed")
return jsonify({"error": str(e)}), 500
@app.route("/crawler/queue", methods=["GET"])
def crawler_queue_list():
if not _rate_check(f"crawler_queue_list:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
limit = max(1, min(int(request.args.get("limit", 100)), 500))
with _db() as conn:
rows = conn.execute("SELECT * FROM crawl_queue ORDER BY added_at DESC LIMIT ?", (limit,)).fetchall()
return jsonify({"queue": [dict(r) for r in rows], "count": len(rows)})
@app.route("/crawler/ingest", methods=["POST"])
def crawler_ingest():
"""Run one crawl step: select next URL via RL, fetch, pixelate, reward."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"crawler_ingest:{request.remote_addr}", window=60, max_requests=5):
return rate_limit_response()
data = request.json or {}
wallet = str(data.get("wallet", "")).strip()
crawler = GARLCrawler()
next_item = crawler.select_next()
if not next_item:
return jsonify({"status": "idle", "message": "No pending items in queue"})
queue_id = next_item["queue_id"]
target_id = next_item["target_id"]
url = next_item["url"]
try:
result = crawler.ingest_url(url, target_id, queue_id, wallet)
return jsonify(result)
except Exception as e:
logger.exception("Crawler ingest failed")
return jsonify({"error": str(e)}), 500
@app.route("/crawler/results", methods=["GET"])
def crawler_results():
if not _rate_check(f"crawler_results:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
website_id = request.args.get("website_id", "").strip() or None
limit = max(1, min(int(request.args.get("limit", 100)), 500))
crawler = GARLCrawler()
results = crawler.get_results(website_id, limit)
return jsonify({"results": results, "count": len(results)})
@app.route("/crawler/evolve", methods=["POST"])
def crawler_evolve():
"""Run one GA generation on the target population."""
auth = require_auth()
if auth:
return auth
if not _rate_check(f"crawler_evolve:{request.remote_addr}", window=60, max_requests=5):
return rate_limit_response()
try:
crawler = GARLCrawler()
result = crawler.run_evolution()
return jsonify(result)
except Exception as e:
logger.exception("Crawler evolution failed")
return jsonify({"error": str(e)}), 500
@app.route("/crawler/policy", methods=["GET"])
def crawler_policy():
if not _rate_check(f"crawler_policy:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
crawler = GARLCrawler()
policy = crawler.get_policy()
return jsonify({"policy": policy, "count": len(policy)})
# ── ETHR Oracle ───────────────────────────────────────────────
ETHR_ADMIN_KEY = os.environ.get("ETHR_ADMIN_KEY", "")
@app.route("/ethr/proof-index", methods=["GET"])
def ethr_proof_index():
"""Compute ETHR proof index from live CLAIMOS metrics."""
if not _rate_check(f"ethr:{request.remote_addr}", window=60, max_requests=30):
return rate_limit_response()
with _db() as conn:
# Proof metrics
verified_receipts = conn.execute(
"SELECT COUNT(*) AS c FROM receipts WHERE kind LIKE 'claim-%' AND status = 'completed'"
).fetchone()["c"]
reviewed_packets = conn.execute(
"SELECT COUNT(*) AS c FROM evidence WHERE evidence_strength > 0"
).fetchone()["c"]
resolved_contradictions = conn.execute(
"SELECT COUNT(*) AS c FROM contradictions WHERE resolved = 1"
).fetchone()["c"]
# Risk metrics
disputes = conn.execute(
"SELECT COUNT(*) AS c FROM contradictions WHERE resolved = 0"
).fetchone()["c"]
invalid_evidence = conn.execute(
"SELECT COUNT(*) AS c FROM evidence WHERE evidence_strength < 0.3"
).fetchone()["c"]
procedural_failures = conn.execute(
"SELECT COUNT(*) AS c FROM claims WHERE status IN ('unreviewed','closed')"
).fetchone()["c"]
# Aggregate claim state
claim_stats = conn.execute(
"SELECT AVG(p_recovery) AS avg_p, AVG(liquidity_score) AS avg_liq, AVG(contradiction_density) AS avg_cx FROM claims"
).fetchone()
delta_proof = verified_receipts + reviewed_packets + resolved_contradictions
delta_risk = disputes + invalid_evidence + procedural_failures
net_change = delta_proof - delta_risk
# Normalize to small increments
normalized = net_change / max(1, delta_proof + delta_risk)
return jsonify({
"token": "ETHR",
"description": "Elastic proof-index token for Membra verification capacity",
"delta": {
"verified_receipts": verified_receipts,
"reviewed_packets": reviewed_packets,
"resolved_contradictions": resolved_contradictions,
"disputes": disputes,
"invalid_evidence": invalid_evidence,
"procedural_failures": procedural_failures,
},
"net_change": round(normalized, 8),
"claim_stats": {
"avg_p_recovery": round(claim_stats["avg_p"] or 0, 4),
"avg_liquidity": round(claim_stats["avg_liq"] or 0, 4),
"avg_contradiction_density": round(claim_stats["avg_cx"] or 0, 4),
},
"updated_at": datetime.now(timezone.utc).isoformat(),
})
@app.route("/ethr/update-multiplier", methods=["POST"])
def ethr_update_multiplier():
"""Oracle endpoint to update ETHR multiplier. Requires ETHR_ADMIN_KEY."""
if not _rate_check(f"ethr_admin:{request.remote_addr}", window=60, max_requests=10):
return rate_limit_response()
data = request.json or {}
auth_key = str(data.get("admin_key", "")).strip()
if not ETHR_ADMIN_KEY or auth_key != ETHR_ADMIN_KEY:
return jsonify({"error": "Unauthorized"}), 401
multiplier = float(data.get("multiplier", 1.0))
if multiplier <= 0:
return jsonify({"error": "Multiplier must be > 0"}), 400
now = datetime.now(timezone.utc).isoformat()
return jsonify({
"token": "ETHR",
"multiplier": multiplier,
"status": "updated",
"updated_at": now,
})
# ── Main ────────────────────────────────────────────────────────
if __name__ == "__main__":
load_config()
load_settings()
load_memory()
load_apps()
load_receipts()
_init_token_db()
save_state()
if not TERMINAL_AGENT_TOKEN:
logger.warning("TERMINAL_AGENT_TOKEN is not set; command routes will reject all requests.")
logger.info(f"Starting Terminal Agent on port {PORT}")
app.run(host="0.0.0.0", port=PORT, threaded=True)