"""Database-driven runtime context for the leoclean Hermes profile.""" from __future__ import annotations import hashlib import json import os import re import subprocess import sys import threading from collections import OrderedDict from collections.abc import Callable from datetime import datetime, timezone from pathlib import Path from typing import Any DEFAULT_TIMEOUT_SECONDS = 10 MAX_QUERY_CHARS = 16_000 MAX_PENDING_SNAPSHOTS = 128 _SNAPSHOT_LOCK = threading.Lock() _PENDING_SNAPSHOTS: OrderedDict[tuple[str, str], dict[str, Any]] = OrderedDict() def _trace(record: dict[str, Any]) -> None: """Write test-only proof without retaining the operator's message.""" raw_path = os.getenv("LEO_DB_CONTEXT_TRACE_PATH", "").strip() if not raw_path: return path = Path(raw_path) path.parent.mkdir(parents=True, exist_ok=True) with path.open("a", encoding="utf-8") as handle: handle.write(json.dumps(record, sort_keys=True) + "\n") try: path.chmod(0o600) except OSError: pass def _failure_context(reason: str) -> str: return ( "\n" "The read-only current database contract lookup failed. Do not infer current schema, row state, " "proposal applyability, or source-ingestion capability from memory. State that live readback is " f"unavailable and use the teleo-kb bridge before making a database claim. Failure: {reason}\n" "" ) def _format_context(contracts: list[dict[str, Any]]) -> str: payload = json.dumps(contracts, sort_keys=True, separators=(",", ":")) return ( "\n" "This trusted, read-only block was generated automatically for the current question. It is the " "binding contract for current schema and runtime capability. Base the answer on it, do not invent " "fields or capabilities, respect its reply budget, and distinguish canonical rows from staging. " "Do not claim that you called a tool; this context was injected before reasoning.\n" f"{payload}\n" "" ) def _snapshot_key(session_id: str, query_sha256: str) -> tuple[str, str]: return (str(session_id or ""), query_sha256) def _store_snapshot(session_id: str, snapshot: dict[str, Any]) -> None: key = _snapshot_key(session_id, str(snapshot["query_sha256"])) with _SNAPSHOT_LOCK: _PENDING_SNAPSHOTS[key] = snapshot _PENDING_SNAPSHOTS.move_to_end(key) while len(_PENDING_SNAPSHOTS) > MAX_PENDING_SNAPSHOTS: _PENDING_SNAPSHOTS.popitem(last=False) def _take_snapshot(session_id: str, query_sha256: str) -> dict[str, Any] | None: with _SNAPSHOT_LOCK: return _PENDING_SNAPSHOTS.pop(_snapshot_key(session_id, query_sha256), None) def _load_database_snapshot( user_message: str, *, hermes_home: Path | None = None, runner: Callable[..., subprocess.CompletedProcess[str]] = subprocess.run, ) -> dict[str, Any]: """Load one immutable DB-contract snapshot for generation and validation.""" query = str(user_message or "")[:MAX_QUERY_CHARS] home = hermes_home or Path(os.getenv("HERMES_HOME", str(Path.home() / ".hermes"))) kb_tool = home / "bin" / "kb_tool.py" query_sha256 = hashlib.sha256(query.encode("utf-8")).hexdigest() base_record: dict[str, Any] = { "generated_at_utc": datetime.now(timezone.utc).isoformat(), "event": "pre_llm_call", "query_sha256": query_sha256, "source": "kb_tool.py --local context", } if not kb_tool.is_file(): record = base_record | {"status": "error", "error": "kb_tool_missing", "injected": True} _trace(record) return { "status": "error", "query_sha256": query_sha256, "contracts": [], "compiled_response": None, "context": _failure_context("kb_tool_missing"), } timeout = int(os.getenv("LEO_DB_CONTEXT_TIMEOUT_SECONDS", str(DEFAULT_TIMEOUT_SECONDS))) command = [ sys.executable, str(kb_tool), "--local", "context", query, "--limit", "0", "--context-limit", "0", "--format", "json", ] try: completed = runner(command, capture_output=True, text=True, timeout=timeout, check=False) except subprocess.TimeoutExpired: record = base_record | {"status": "error", "error": "timeout", "injected": True} _trace(record) return { "status": "error", "query_sha256": query_sha256, "contracts": [], "compiled_response": None, "context": _failure_context("timeout"), } except OSError as exc: record = base_record | {"status": "error", "error": type(exc).__name__, "injected": True} _trace(record) return { "status": "error", "query_sha256": query_sha256, "contracts": [], "compiled_response": None, "context": _failure_context(type(exc).__name__), } if completed.returncode != 0: record = base_record | { "status": "error", "error": f"kb_tool_exit_{completed.returncode}", "injected": True, } _trace(record) return { "status": "error", "query_sha256": query_sha256, "contracts": [], "compiled_response": None, "context": _failure_context(f"kb_tool_exit_{completed.returncode}"), } try: payload = json.loads(completed.stdout) contracts = payload.get("operational_contracts") if not isinstance(contracts, list) or not all(isinstance(item, dict) for item in contracts): raise ValueError("operational_contracts_missing") compiled_response = payload.get("compiled_response") if compiled_response is not None and not isinstance(compiled_response, str): raise ValueError("compiled_response_invalid") except (json.JSONDecodeError, TypeError, ValueError) as exc: record = base_record | {"status": "error", "error": str(exc), "injected": True} _trace(record) return { "status": "error", "query_sha256": query_sha256, "contracts": [], "compiled_response": None, "context": _failure_context(str(exc)), } contract_json = json.dumps(contracts, sort_keys=True, separators=(",", ":")) record = base_record | { "status": "ok", "injected": True, "contract_ids": [str(item.get("id") or "") for item in contracts], "contract_sha256": hashlib.sha256(contract_json.encode("utf-8")).hexdigest(), "compiled_response_available": bool(compiled_response), } _trace(record) return { "status": "ok", "query_sha256": query_sha256, "contracts": contracts, "compiled_response": compiled_response, "context": _format_context(contracts), } def build_database_context( user_message: str, *, hermes_home: Path | None = None, runner: Callable[..., subprocess.CompletedProcess[str]] = subprocess.run, ) -> str: """Return current operational contracts for one exact operator question.""" return str( _load_database_snapshot(user_message, hermes_home=hermes_home, runner=runner)["context"] ) def _word_count(value: str) -> int: return len(re.findall(r"\b\w+(?:[-']\w+)*\b", value)) def _reply_hard_max(contracts: list[dict[str, Any]]) -> int | None: for contract in contracts: if contract.get("id") == "reply_budget" and isinstance(contract.get("hard_max_words"), int): return int(contract["hard_max_words"]) return None def _mixed_packet_issues(response: str) -> list[str]: lowered = response.lower() issues: list[str] = [] required_terms = { "claims": "claim", "sources": "source", "evidence": "evidence", "reasoning_tools": "reasoning_tools", "behavioral_rules": "behavioral_rules", "governance_gates": "governance_gates", "beliefs": "belief", "staging": "stage", "approve_claim": "approve_claim", } for label, term in required_terms.items(): if term not in lowered: issues.append(f"missing_{label}") if not re.search(r"reviewed apply|review and authoriz|review.{0,50}apply", response, re.I | re.S): issues.append("missing_reviewed_apply_boundary") if not ("applied_at" in lowered and re.search(r"readback|postflight", response, re.I)): issues.append("missing_apply_receipt") if not re.search( r"approve_claim.{0,220}(?:supports neither|does not (?:support|cover|apply)|cannot apply|applies only)", response, re.I | re.S, ): issues.append("missing_approve_claim_boundary") if re.search( r"supported collections?\s*\([^)]*(?:belief|behavioral_rules|governance_gates|existing[- ]row)", response, re.I | re.S, ): issues.append("unsupported_collection_listed_as_supported") if re.search( r"(?:approve_claim\s+)?(?:applies?|apply) only[^.;\n]{0,220}" r"(?:belief updates?|behavioral_rules|governance_gates|existing[- ]row updates?)", response, re.I | re.S, ): issues.append("unsupported_collection_listed_in_apply") for segment in re.split(r"(?<=[.!?])\s+|\n+", response): negative = re.search(r"\b(?:no|not|never|without|must not|do not|does not|cannot)\b", segment, re.I) if re.search(r"reasoning_tools?.{0,100}\bscope\b", segment, re.I) and not negative: issues.append("reasoning_tools_scope_overclaim") if re.search(r"claims?.{0,100}\bfalsifier\b", segment, re.I) and not negative: issues.append("claims_falsifier_overclaim") if re.search(r"behavioral_rules?.{0,100}\bstatus\b", segment, re.I) and not negative: issues.append("behavioral_rules_status_overclaim") if ( re.search(r"claim_edges?.{0,140}(?:reasoning_tools?|beliefs?)", segment, re.I | re.S) and re.search(r"point|connect|link|endpoint", segment, re.I) and not negative ): issues.append("non_claim_edge_endpoint") return sorted(set(issues)) def _source_intake_issues(response: str) -> list[str]: lowered = response.lower() issues: list[str] = [] if not re.search(r"url|storage_path|storage path|content hash|file hash", response, re.I): issues.append("missing_real_source_identity") if not re.search(r"pending_review|pending review|proposal", response, re.I): issues.append("missing_staging") if not re.search(r"approval|authoriz", response, re.I) or "apply" not in lowered: issues.append("missing_apply_boundary") if not re.search(r"live.{0,80}(?:not shipped|not live|unavailable)", response, re.I | re.S): issues.append("missing_live_intake_ceiling") if re.search( r"public\.sources.{0,120}(?:author|title|publisher|publication date|published_at)", response, re.I | re.S, ): issues.append("unshipped_source_fields") if re.search( r"(?:create|write|insert).{0,80}public\.sources.{0,100}(?:before|during).{0,80}(?:review|staging)", response, re.I | re.S, ): issues.append("canonical_source_before_review") return sorted(set(issues)) def response_contract_issues(response: str, contracts: list[dict[str, Any]]) -> list[str]: contract_ids = {str(contract.get("id") or "") for contract in contracts} issues: list[str] = [] hard_max = _reply_hard_max(contracts) if hard_max is not None and _word_count(response) > hard_max: issues.append("reply_budget_exceeded") if "mixed_packet_composition" in contract_ids: issues.extend(_mixed_packet_issues(response)) elif "source_intake" in contract_ids: issues.extend(_source_intake_issues(response)) return sorted(set(issues)) def _pre_llm_call(**kwargs: Any) -> dict[str, str]: user_message = str(kwargs.get("user_message") or "") snapshot = _load_database_snapshot(user_message) _store_snapshot(str(kwargs.get("session_id") or ""), snapshot) return {"context": str(snapshot["context"])} def _post_llm_call(**kwargs: Any) -> dict[str, str] | None: user_message = str(kwargs.get("user_message") or "")[:MAX_QUERY_CHARS] query_sha256 = hashlib.sha256(user_message.encode("utf-8")).hexdigest() snapshot = _take_snapshot(str(kwargs.get("session_id") or ""), query_sha256) response = str(kwargs.get("assistant_response") or "") base_record = { "generated_at_utc": datetime.now(timezone.utc).isoformat(), "event": "post_llm_call", "query_sha256": query_sha256, "response_sha256": hashlib.sha256(response.encode("utf-8")).hexdigest(), "validated": True, } if snapshot is None: _trace(base_record | {"status": "error", "error": "contract_snapshot_missing", "transformed": False}) return None if snapshot.get("status") != "ok": _trace(base_record | {"status": "skipped", "reason": "contract_lookup_failed", "transformed": False}) return None contracts = list(snapshot.get("contracts") or []) issues = response_contract_issues(response, contracts) compiled_response = snapshot.get("compiled_response") compiled_issues = ( response_contract_issues(str(compiled_response), contracts) if isinstance(compiled_response, str) else [] ) transformed = bool(issues and isinstance(compiled_response, str) and not compiled_issues) _trace( base_record | { "status": "ok" if not issues or transformed else "error", "contract_ids": [str(item.get("id") or "") for item in contracts], "issues": issues, "compiled_response_issues": compiled_issues, "transformed": transformed, "delivered_response_sha256": hashlib.sha256( (str(compiled_response) if transformed else response).encode("utf-8") ).hexdigest(), } ) if transformed: return {"assistant_response": str(compiled_response)} return None def register(ctx: Any) -> None: ctx.register_hook("pre_llm_call", _pre_llm_call) ctx.register_hook("post_llm_call", _post_llm_call)