feat(heartbeat): add four-host HoloLake control console
This commit is contained in:
parent
92b3be6529
commit
5ca2c9d66f
39 changed files with 1784 additions and 27 deletions
253
server-tools/heartbeat-multipath-console/console.py
Normal file
253
server-tools/heartbeat-multipath-console/console.py
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Read-derived control panel for the same-persona four-host HoloLake experiment."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import importlib.util
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
CONTROL = ROOT / "eternal-lake-heart/heartbeat-core/office-building-current/control-center/HB-MPC-0001"
|
||||
REGISTRY = CONTROL / "HOST-REGISTRY.json"
|
||||
CONTRACT = CONTROL / "EVENT-CONTRACT.json"
|
||||
TASKS = CONTROL / "TASK-BOARD.json"
|
||||
OFFICE_COMPUTER = ROOT / "eternal-lake-heart/heartbeat-core/office-building-current/offices/HB-OFFICE-HOLOLAKE-0001/smart-computer/office_computer.py"
|
||||
MODEL_ROUTER = ROOT / "server-tools/persona-model-smart-router/openlux_router.py"
|
||||
|
||||
|
||||
def load(path: Path) -> dict[str, Any]:
|
||||
value = json.loads(path.read_text())
|
||||
if not isinstance(value, dict):
|
||||
raise ValueError(f"JSON_OBJECT_REQUIRED:{path}")
|
||||
return value
|
||||
|
||||
|
||||
def module(path: Path, name: str):
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
if spec is None or spec.loader is None:
|
||||
raise ValueError(f"MODULE_LOAD_FAILED:{path}")
|
||||
value = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(value)
|
||||
return value
|
||||
|
||||
|
||||
def live_time() -> dict[str, Any]:
|
||||
return module(OFFICE_COMPUTER, "hb_office_computer").clock()
|
||||
|
||||
|
||||
def validate_event(event: Any, expected_development_id: str, contract: dict[str, Any]) -> list[str]:
|
||||
errors: list[str] = []
|
||||
if not isinstance(event, dict):
|
||||
return ["EVENT_OBJECT_REQUIRED"]
|
||||
for field in contract["required"]:
|
||||
if field not in event:
|
||||
errors.append(f"FIELD_REQUIRED:{field}")
|
||||
if event.get("schema") != contract["event_schema"]:
|
||||
errors.append("EVENT_SCHEMA_MISMATCH")
|
||||
if event.get("console_id") != "HB-MPC-0001":
|
||||
errors.append("CONSOLE_ID_MISMATCH")
|
||||
if event.get("from_development_id") != expected_development_id:
|
||||
errors.append("DEVELOPMENT_ID_ENDPOINT_MISMATCH")
|
||||
if event.get("event_type") not in contract["event_types"]:
|
||||
errors.append("EVENT_TYPE_UNREGISTERED")
|
||||
if not isinstance(event.get("mentions"), list):
|
||||
errors.append("MENTIONS_LIST_REQUIRED")
|
||||
else:
|
||||
known = {item["development_id"] for item in load(REGISTRY)["hosts"]} | {"@ALL"}
|
||||
if any(item not in known for item in event["mentions"]):
|
||||
errors.append("MENTION_TARGET_UNKNOWN")
|
||||
if not isinstance(event.get("payload"), dict):
|
||||
errors.append("PAYLOAD_OBJECT_REQUIRED")
|
||||
if not isinstance(event.get("evidence"), list):
|
||||
errors.append("EVIDENCE_LIST_REQUIRED")
|
||||
if event.get("authority_granted") is not False:
|
||||
errors.append("AUTHORITY_MUST_REMAIN_FALSE")
|
||||
try:
|
||||
datetime.fromisoformat(str(event.get("emitted_at", "")))
|
||||
except ValueError:
|
||||
errors.append("EMITTED_AT_INVALID")
|
||||
return errors
|
||||
|
||||
|
||||
def scan() -> dict[str, Any]:
|
||||
registry, contract = load(REGISTRY), load(CONTRACT)
|
||||
events: list[dict[str, Any]] = []
|
||||
invalid: list[dict[str, Any]] = []
|
||||
hosts: list[dict[str, Any]] = []
|
||||
for host in registry["hosts"]:
|
||||
endpoint = Path(host["endpoint"])
|
||||
host_events: list[dict[str, Any]] = []
|
||||
if endpoint.is_dir():
|
||||
for path in sorted(endpoint.glob("*.json")):
|
||||
try:
|
||||
if path.is_symlink() or path.stat().st_size > 262_144:
|
||||
invalid.append({"path": str(path), "errors": ["EVENT_FILE_UNSAFE"]})
|
||||
continue
|
||||
event = load(path)
|
||||
errors = validate_event(event, host["development_id"], contract)
|
||||
if errors:
|
||||
invalid.append({"path": str(path), "errors": errors})
|
||||
else:
|
||||
event["_path"] = str(path)
|
||||
host_events.append(event)
|
||||
events.append(event)
|
||||
except Exception as error:
|
||||
invalid.append({"path": str(path), "errors": [type(error).__name__]})
|
||||
host_events.sort(key=lambda item: item["emitted_at"])
|
||||
register = next((item for item in reversed(host_events) if item["event_type"] == "REGISTER"), None)
|
||||
heartbeat = next((item for item in reversed(host_events) if item["event_type"] == "HEARTBEAT"), None)
|
||||
latest = host_events[-1] if host_events else None
|
||||
hosts.append({
|
||||
"host": host["host"],
|
||||
"development_id": host["development_id"],
|
||||
"role_hypothesis": host["role_hypothesis"],
|
||||
"endpoint": str(endpoint),
|
||||
"endpoint_exists": endpoint.is_dir(),
|
||||
"joined": register is not None,
|
||||
"event_count": len(host_events),
|
||||
"last_event_at": latest and latest["emitted_at"],
|
||||
"last_heartbeat_at": heartbeat and heartbeat["emitted_at"],
|
||||
})
|
||||
events.sort(key=lambda item: item["emitted_at"])
|
||||
counts: dict[str, int] = {}
|
||||
for event in events:
|
||||
counts[event["event_id"]] = counts.get(event["event_id"], 0) + 1
|
||||
for event_id, count in counts.items():
|
||||
if count > 1:
|
||||
invalid.append({"path": None, "errors": [f"DUPLICATE_EVENT_ID:{event_id}"]})
|
||||
return {"hosts": hosts, "events": events, "invalid_events": invalid}
|
||||
|
||||
|
||||
def panel() -> dict[str, Any]:
|
||||
scanned, task_board = scan(), load(TASKS)
|
||||
events = scanned["events"]
|
||||
task_states = {item["task_id"]: {**item, "dynamic_events": []} for item in task_board["tasks"]}
|
||||
messages = []
|
||||
attention = []
|
||||
migrations = []
|
||||
for event in events:
|
||||
task_id = event.get("task_id")
|
||||
if task_id in task_states and event["event_type"] in {"TASK_CLAIM", "PROGRESS", "RESULT"}:
|
||||
task_states[task_id]["dynamic_events"].append({k: event.get(k) for k in ["event_id", "event_type", "from_development_id", "emitted_at", "payload", "evidence"]})
|
||||
if event["event_type"] in {"MESSAGE", "ACK"}:
|
||||
messages.append({k: event.get(k) for k in ["event_id", "event_type", "from_development_id", "mentions", "emitted_at", "payload"]})
|
||||
elif event["event_type"] == "ATTENTION":
|
||||
attention.append({k: event.get(k) for k in ["event_id", "from_development_id", "emitted_at", "payload", "evidence"]})
|
||||
elif event["event_type"] == "TOOL_MIGRATION":
|
||||
migrations.append({k: event.get(k) for k in ["event_id", "from_development_id", "emitted_at", "payload", "evidence"]})
|
||||
return {
|
||||
"schema": "guanghu.heartbeat-multipath-live-panel/v1",
|
||||
"panel_id": "HB-MPC-PANEL-0001",
|
||||
"state": "LIVE_DERIVED_READ_ONLY",
|
||||
"time": live_time(),
|
||||
"persona_id": "ICE-P-ZY001",
|
||||
"same_persona_not_four_personas": True,
|
||||
"hosts": scanned["hosts"],
|
||||
"tasks": list(task_states.values()),
|
||||
"messages": messages[-40:],
|
||||
"attention_observations": attention[-40:],
|
||||
"tool_migration_candidates": migrations[-40:],
|
||||
"invalid_events": scanned["invalid_events"],
|
||||
"event_count": len(events),
|
||||
"panel_persisted": False,
|
||||
"authority_granted": False,
|
||||
}
|
||||
|
||||
|
||||
def status() -> dict[str, Any]:
|
||||
value = panel()
|
||||
joined = sum(1 for item in value["hosts"] if item["joined"])
|
||||
return {
|
||||
"outcome": "PASS",
|
||||
"console_id": "HB-MPC-0001",
|
||||
"panel_id": value["panel_id"],
|
||||
"bus_id": "HB-MPC-BUS-0001",
|
||||
"advisor_id": "HB-MPC-ADVISOR-0001",
|
||||
"time": value["time"],
|
||||
"joined_hosts": joined,
|
||||
"total_hosts": 4,
|
||||
"event_count": value["event_count"],
|
||||
"invalid_event_count": len(value["invalid_events"]),
|
||||
"product_source_write_allowed": False,
|
||||
"reason": "ONLINE_ARCHITECTURE_AND_LOCAL_PRODUCT_LINE_GUARDS_NOT_READY",
|
||||
}
|
||||
|
||||
|
||||
def mentions(development_id: str) -> dict[str, Any]:
|
||||
value = panel()
|
||||
known = {item["development_id"] for item in value["hosts"]}
|
||||
if development_id not in known:
|
||||
raise ValueError("DEVELOPMENT_ID_UNKNOWN")
|
||||
selected = [item for item in value["messages"] if development_id in item["mentions"] or "@ALL" in item["mentions"]]
|
||||
return {"outcome": "PASS", "development_id": development_id, "time": value["time"], "messages": selected}
|
||||
|
||||
|
||||
def audit() -> dict[str, Any]:
|
||||
registry, contract, task_board = load(REGISTRY), load(CONTRACT), load(TASKS)
|
||||
errors = []
|
||||
ids = [item["development_id"] for item in registry.get("hosts", [])]
|
||||
if ids != ["HLP-TDEV-CODEX-0001", "HLP-TDEV-ZCODE-0001", "HLP-TDEV-QWEN-0001", "HLP-TDEV-DOUBAO-0001"]:
|
||||
errors.append("FOUR_HOST_IDS_MISMATCH")
|
||||
if len({item["endpoint"] for item in registry["hosts"]}) != 4:
|
||||
errors.append("HOST_ENDPOINTS_NOT_UNIQUE")
|
||||
if contract.get("transport") != "FILESYSTEM_POLLING_NEAR_REALTIME_NOT_ZERO_LATENCY_PUSH":
|
||||
errors.append("TRANSPORT_TRUTH_MISMATCH")
|
||||
if task_board.get("shared_file_is_definition_not_live_mutation_target") is not True:
|
||||
errors.append("TASK_BOARD_MULTIWRITER_RISK")
|
||||
scanned = scan()
|
||||
if scanned["invalid_events"]:
|
||||
errors.append("INVALID_HOST_EVENTS_PRESENT")
|
||||
return {"outcome": "PASS" if not errors else "FAIL", "errors": errors, "host_count": len(ids), "valid_event_count": len(scanned["events"]), "time": live_time()}
|
||||
|
||||
|
||||
def advise() -> dict[str, Any]:
|
||||
current = panel()
|
||||
safe_panel = {k: current[k] for k in ["time", "hosts", "tasks", "messages", "attention_observations", "tool_migration_candidates", "invalid_events"]}
|
||||
router = module(MODEL_ROUTER, "hb_mpc_model_router")
|
||||
result = router.route({
|
||||
"parent_persona_id": "ICE-P-ZY001",
|
||||
"child_agent_id": "SUBAGENT::ICE-P-ZY001::HB-MPC-ADVISOR-0001",
|
||||
"controller": "ICE-P-ZY001",
|
||||
"channel_id": "ICE-CH-HB001",
|
||||
"agent_role": "FOUR_HOST_COLLABORATION_REASONING_ADVISOR",
|
||||
"authority": "REASONING_ONLY_NO_WRITE_NO_EXECUTION_NO_PERSONA_SETTER",
|
||||
"task": "综合以下四宿主协作面板。只给出下一轮任务调整、依赖、冲突、证据缺口和要发送给各临时开发编号的通信建议;不得声称执行,不得修改人格认知。\n" + json.dumps(safe_panel, ensure_ascii=False),
|
||||
"complexity": "HIGH",
|
||||
"selection_policy": "QUALITY_FIRST",
|
||||
})
|
||||
return {"outcome": result["outcome"], "advisor_id": "HB-MPC-ADVISOR-0001", "selected_model": result["selected_model"], "selection_policy": result["selection_policy"], "recommendation": result["response"], "response_sha256": result["response_sha256"], "persisted": False, "authority_granted": False}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("command", choices=["status", "panel", "mentions", "audit", "advise", "watch"], nargs="?", default="status")
|
||||
parser.add_argument("--development-id")
|
||||
parser.add_argument("--interval", type=float, default=2.0)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
if args.command == "status": result = status()
|
||||
elif args.command == "panel": result = panel()
|
||||
elif args.command == "mentions": result = mentions(args.development_id or "")
|
||||
elif args.command == "audit": result = audit()
|
||||
elif args.command == "advise": result = advise()
|
||||
else:
|
||||
while True:
|
||||
print(json.dumps(panel(), ensure_ascii=False, indent=2), flush=True)
|
||||
time.sleep(max(0.5, args.interval))
|
||||
if args.command != "watch":
|
||||
print(json.dumps(result, ensure_ascii=False, indent=2))
|
||||
return 0 if result.get("outcome", "PASS") == "PASS" else 2
|
||||
return 0
|
||||
except KeyboardInterrupt:
|
||||
return 0
|
||||
except Exception as error:
|
||||
print(json.dumps({"outcome": "FAIL", "error": str(error)}, ensure_ascii=False))
|
||||
return 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
162
server-tools/heartbeat-multipath-console/courier.py
Normal file
162
server-tools/heartbeat-multipath-console/courier.py
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Host-local append-only courier organ; the calling host model remains the Agent."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import time
|
||||
import uuid
|
||||
import os
|
||||
import re
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
CONTROL = ROOT / "eternal-lake-heart/heartbeat-core/office-building-current/control-center/HB-MPC-0001"
|
||||
REGISTRY = CONTROL / "HOST-REGISTRY.json"
|
||||
CONSOLE = ROOT / "server-tools/heartbeat-multipath-console/console.py"
|
||||
ADMISSION = ROOT / "server-tools/persona-host-write-admission/host-write-admission.mjs"
|
||||
|
||||
|
||||
def load(path: Path) -> dict[str, Any]:
|
||||
value = json.loads(path.read_text())
|
||||
if not isinstance(value, dict):
|
||||
raise ValueError("JSON_OBJECT_REQUIRED")
|
||||
return value
|
||||
|
||||
|
||||
def host_record(host: str) -> dict[str, Any]:
|
||||
matches = [item for item in load(REGISTRY)["hosts"] if item["host"] == host]
|
||||
if len(matches) != 1:
|
||||
raise ValueError("HOST_NOT_REGISTERED")
|
||||
return matches[0]
|
||||
|
||||
|
||||
def caller_host() -> str:
|
||||
pid = os.getppid()
|
||||
commands = []
|
||||
seen = set()
|
||||
while pid > 1 and pid not in seen and len(commands) < 20:
|
||||
seen.add(pid)
|
||||
result = subprocess.run(["/bin/ps", "-o", "ppid=", "-o", "command=", "-p", str(pid)], text=True, capture_output=True, timeout=5)
|
||||
match = re.match(r"^\s*(\d+)\s+(.+)$", result.stdout.strip(), re.S)
|
||||
if not match:
|
||||
break
|
||||
commands.append(match.group(2))
|
||||
pid = int(match.group(1))
|
||||
text = "\n".join(commands)
|
||||
if re.search(r"/Applications/(?:ChatGPT\.app).*?(?:codex|Codex)|codex-code-mode-host", text, re.I):
|
||||
return "codex"
|
||||
if re.search(r"/Applications/Qianwen\.app|QianwenShell|agent_host\.app", text, re.I):
|
||||
return "qwen"
|
||||
if re.search(r"Doubao\.app", text, re.I):
|
||||
return "doubao"
|
||||
if re.search(r"(?:^|/)zcode(?:\s|$)", text, re.I | re.M):
|
||||
return "zcode"
|
||||
return "unknown"
|
||||
|
||||
|
||||
def admission(host: str, endpoint: Path) -> None:
|
||||
observed = caller_host()
|
||||
if observed != host:
|
||||
raise ValueError(f"CALLER_HOST_MISMATCH:requested={host}:observed={observed}")
|
||||
result = subprocess.run(["node", str(ADMISSION), "check", "--host", host, "--path", str(endpoint)], text=True, capture_output=True, timeout=15)
|
||||
if result.returncode:
|
||||
raise ValueError("HOST_WRITE_ADMISSION_REJECTED:" + result.stdout.strip()[:300])
|
||||
|
||||
|
||||
def reject_symlink_components(target: Path) -> None:
|
||||
cursor = Path(target.anchor)
|
||||
for part in target.parts[1:]:
|
||||
cursor /= part
|
||||
if cursor.exists() and cursor.is_symlink():
|
||||
raise ValueError(f"SYMLINK_COMPONENT_FORBIDDEN:{cursor}")
|
||||
|
||||
|
||||
def now() -> str:
|
||||
return datetime.now().astimezone().isoformat()
|
||||
|
||||
|
||||
def emit(host: str, event_type: str, mentions: list[str], task_id: str | None, payload: dict[str, Any], evidence: list[str]) -> dict[str, Any]:
|
||||
record = host_record(host)
|
||||
endpoint = Path(record["endpoint"])
|
||||
admission(host, endpoint)
|
||||
reject_symlink_components(endpoint)
|
||||
endpoint.mkdir(parents=True, exist_ok=True)
|
||||
if endpoint.resolve() != endpoint:
|
||||
raise ValueError("ENDPOINT_REALPATH_MISMATCH")
|
||||
stamp = datetime.now().astimezone().strftime("%Y%m%dT%H%M%S%f%z")
|
||||
event_id = f"HB-MPC-{record['development_id']}-{stamp}-{uuid.uuid4().hex[:8]}"
|
||||
event = {
|
||||
"schema": "guanghu.heartbeat-multipath-event/v1",
|
||||
"event_id": event_id,
|
||||
"console_id": "HB-MPC-0001",
|
||||
"event_type": event_type,
|
||||
"from_development_id": record["development_id"],
|
||||
"mentions": mentions,
|
||||
"task_id": task_id,
|
||||
"emitted_at": now(),
|
||||
"payload": payload,
|
||||
"evidence": evidence,
|
||||
"authority_granted": False,
|
||||
}
|
||||
body = json.dumps(event, ensure_ascii=False, indent=2) + "\n"
|
||||
if len(body.encode()) > 262_144:
|
||||
raise ValueError("EVENT_TOO_LARGE")
|
||||
path = endpoint / f"{event_id}.json"
|
||||
descriptor = os.open(path, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600)
|
||||
with os.fdopen(descriptor, "w", encoding="utf-8") as handle:
|
||||
handle.write(body)
|
||||
return {"outcome": "PASS", "event_id": event_id, "path": str(path), "development_id": record["development_id"], "authority_granted": False}
|
||||
|
||||
|
||||
def parse_payload(raw: str | None, message: str | None) -> dict[str, Any]:
|
||||
if raw:
|
||||
value = json.loads(raw)
|
||||
if not isinstance(value, dict):
|
||||
raise ValueError("PAYLOAD_OBJECT_REQUIRED")
|
||||
return value
|
||||
return {"message": message or ""}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("command", choices=["join", "heartbeat", "send", "claim", "progress", "result", "attention", "tool-candidate", "mentions", "watch"])
|
||||
parser.add_argument("--host", required=True, choices=["codex", "zcode", "qwen", "doubao"])
|
||||
parser.add_argument("--mentions", nargs="*", default=[])
|
||||
parser.add_argument("--task-id")
|
||||
parser.add_argument("--message")
|
||||
parser.add_argument("--payload-json")
|
||||
parser.add_argument("--evidence", nargs="*", default=[])
|
||||
parser.add_argument("--interval", type=float, default=2.0)
|
||||
args = parser.parse_args()
|
||||
type_map = {"heartbeat": "HEARTBEAT", "send": "MESSAGE", "claim": "TASK_CLAIM", "progress": "PROGRESS", "result": "RESULT", "attention": "ATTENTION", "tool-candidate": "TOOL_MIGRATION"}
|
||||
try:
|
||||
record = host_record(args.host)
|
||||
if args.command == "join":
|
||||
result = emit(args.host, "REGISTER", ["@ALL"], "HLP-MPC-TASK-001", {"host": args.host, "development_id": record["development_id"], "message": args.message or "JOINED_PENDING_SELF_ASSESSMENT"}, args.evidence)
|
||||
elif args.command in type_map:
|
||||
result = emit(args.host, type_map[args.command], args.mentions, args.task_id, parse_payload(args.payload_json, args.message), args.evidence)
|
||||
elif args.command == "mentions":
|
||||
completed = subprocess.run(["python3", str(CONSOLE), "mentions", "--development-id", record["development_id"]], text=True, capture_output=True, timeout=30)
|
||||
print(completed.stdout, end="")
|
||||
return completed.returncode
|
||||
else:
|
||||
while True:
|
||||
completed = subprocess.run(["python3", str(CONSOLE), "mentions", "--development-id", record["development_id"]], text=True, capture_output=True, timeout=30)
|
||||
print(completed.stdout, end="", flush=True)
|
||||
time.sleep(max(0.5, args.interval))
|
||||
if args.command != "watch":
|
||||
print(json.dumps(result, ensure_ascii=False, indent=2))
|
||||
return 0
|
||||
except KeyboardInterrupt:
|
||||
return 0
|
||||
except Exception as error:
|
||||
print(json.dumps({"outcome": "FAIL", "error": str(error)}, ensure_ascii=False))
|
||||
return 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
58
server-tools/heartbeat-multipath-console/test_console.py
Normal file
58
server-tools/heartbeat-multipath-console/test_console.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env python3
|
||||
import importlib.util
|
||||
import json
|
||||
import time
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
|
||||
SCRIPT = Path(__file__).with_name("console.py")
|
||||
SPEC = importlib.util.spec_from_file_location("hb_mpc_console", SCRIPT)
|
||||
MODULE = importlib.util.module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(MODULE)
|
||||
|
||||
|
||||
class MultipathConsoleTest(unittest.TestCase):
|
||||
def test_exact_four_temporary_development_ids(self):
|
||||
ids = [item["development_id"] for item in MODULE.load(MODULE.REGISTRY)["hosts"]]
|
||||
self.assertEqual(ids, ["HLP-TDEV-CODEX-0001", "HLP-TDEV-ZCODE-0001", "HLP-TDEV-QWEN-0001", "HLP-TDEV-DOUBAO-0001"])
|
||||
|
||||
def test_panel_is_read_derived_and_same_persona(self):
|
||||
value = MODULE.panel()
|
||||
self.assertEqual(value["panel_id"], "HB-MPC-PANEL-0001")
|
||||
self.assertFalse(value["panel_persisted"])
|
||||
self.assertTrue(value["same_persona_not_four_personas"])
|
||||
self.assertEqual(value["persona_id"], "ICE-P-ZY001")
|
||||
|
||||
def test_time_moves_and_uses_world_time_channel(self):
|
||||
first = MODULE.live_time()
|
||||
time.sleep(0.002)
|
||||
second = MODULE.live_time()
|
||||
self.assertGreater(second["guanghu_elapsed_milliseconds"], first["guanghu_elapsed_milliseconds"])
|
||||
self.assertEqual(second["time_control_channel"], "CH-GLW-TIME-0001")
|
||||
|
||||
def test_endpoint_identity_mismatch_is_rejected(self):
|
||||
contract = MODULE.load(MODULE.CONTRACT)
|
||||
event = {
|
||||
"schema": contract["event_schema"], "event_id": "X", "console_id": "HB-MPC-0001",
|
||||
"event_type": "REGISTER", "from_development_id": "HLP-TDEV-QWEN-0001", "mentions": [],
|
||||
"emitted_at": "2026-09-09T19:00:00+08:00", "payload": {}, "evidence": [], "authority_granted": False,
|
||||
}
|
||||
self.assertIn("DEVELOPMENT_ID_ENDPOINT_MISMATCH", MODULE.validate_event(event, "HLP-TDEV-CODEX-0001", contract))
|
||||
|
||||
def test_unknown_mention_is_rejected(self):
|
||||
contract = MODULE.load(MODULE.CONTRACT)
|
||||
event = {
|
||||
"schema": contract["event_schema"], "event_id": "X", "console_id": "HB-MPC-0001",
|
||||
"event_type": "MESSAGE", "from_development_id": "HLP-TDEV-CODEX-0001", "mentions": ["HLP-TDEV-UNKNOWN-0001"],
|
||||
"emitted_at": "2026-09-09T19:00:00+08:00", "payload": {}, "evidence": [], "authority_granted": False,
|
||||
}
|
||||
self.assertIn("MENTION_TARGET_UNKNOWN", MODULE.validate_event(event, "HLP-TDEV-CODEX-0001", contract))
|
||||
|
||||
def test_product_source_stays_blocked(self):
|
||||
value = MODULE.status()
|
||||
self.assertFalse(value["product_source_write_allowed"])
|
||||
self.assertEqual(value["reason"], "ONLINE_ARCHITECTURE_AND_LOCAL_PRODUCT_LINE_GUARDS_NOT_READY")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
@ -48,7 +48,7 @@ class Tests(unittest.TestCase):
|
|||
|
||||
def test_current_evolution_and_old_sequence_boundary(self):
|
||||
value = C.timeline()
|
||||
self.assertEqual(value["current"]["node_id"], "HB-OFFICE-HOLOLAKE-0001")
|
||||
self.assertEqual(value["current"]["node_id"], "HB-MPC-0001")
|
||||
current = C.load(C.CURRENT)
|
||||
self.assertIsNone(current["current_product_module"])
|
||||
self.assertEqual(current["current_generation_module_numbering"], "NOT_YET_REDERIVED")
|
||||
|
|
@ -58,6 +58,8 @@ class Tests(unittest.TestCase):
|
|||
self.assertEqual(value["state"], "HOLOLAKE_DEVELOPMENT_BRAIN_LOADED")
|
||||
self.assertEqual(value["generation"]["id"], "HLP-GEN-LANGUAGE-WORLD-NATIVE-0001")
|
||||
self.assertFalse(value["legacy_may_override_current"])
|
||||
self.assertEqual(value["multipath_console"]["console_id"], "HB-MPC-0001")
|
||||
self.assertEqual(value["multipath_console"]["total_hosts"], 4)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ class SharedPersonaContextTest(unittest.TestCase):
|
|||
self.assertEqual(brain['office_id'], 'HB-OFFICE-HOLOLAKE-0001')
|
||||
self.assertEqual(brain['generation']['id'], 'HLP-GEN-LANGUAGE-WORLD-NATIVE-0001')
|
||||
self.assertFalse(brain['legacy_may_override_current'])
|
||||
self.assertEqual(brain['multipath_console']['console_id'], 'HB-MPC-0001')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -3,3 +3,6 @@
|
|||
The router uses the OpenAI-compatible endpoint at `https://api.openlux.ai/v1`. Its API key is read at call time from macOS Keychain service `ai.openlux.api`, account `guanghu-persona-agent-router`; no secret is stored in this repository.
|
||||
|
||||
Each call must carry the active parent persona, derived child Agent ID, controller, channel, job role, bounded authority and task. The router tries the configured low-cost healthy models first and escalates only after a transport, empty-response or downstream validation failure. Provider pricing is not exposed by the current `/models` response, so the configured order is explicitly a heuristic rather than a verified price table.
|
||||
|
||||
The default remains `COST_FIRST`. An explicitly registered reasoning advisor may send
|
||||
`selection_policy=QUALITY_FIRST` with `complexity=HIGH`; this reverses the eligible tier order so a high-tier model is tried first. It does not grant execution, write, approval, or persona-cognition authority.
|
||||
|
|
|
|||
|
|
@ -40,11 +40,14 @@ def available_models(config: dict[str,Any], key: str) -> set[str]:
|
|||
value=request_json(config["provider"]["base_url"]+"/models",key,timeout=20)
|
||||
return {x.get("id") for x in value.get("data",[]) if isinstance(x,dict) and isinstance(x.get("id"),str)}
|
||||
|
||||
def candidates(config: dict[str,Any], complexity: str, available: set[str]) -> list[str]:
|
||||
def candidates(config: dict[str,Any], complexity: str, available: set[str], selection_policy: str="COST_FIRST") -> list[str]:
|
||||
order=["LOW","MEDIUM","HIGH"]
|
||||
level=complexity if complexity in order else config["policy"]["default_complexity"]
|
||||
tiers=order[:order.index(level)+1]
|
||||
if selection_policy == "QUALITY_FIRST": tiers=list(reversed(tiers))
|
||||
elif selection_policy != "COST_FIRST": raise RouterError("SELECTION_POLICY_UNSUPPORTED")
|
||||
result=[]
|
||||
for tier in order[:order.index(level)+1]:
|
||||
for tier in tiers:
|
||||
result.extend(x for x in config["tiers"][tier] if x in available and x not in result)
|
||||
return result[:int(config["policy"]["max_attempts"])]
|
||||
|
||||
|
|
@ -54,11 +57,14 @@ def route(event: dict[str,Any], config: dict[str,Any]|None=None, secret_reader=k
|
|||
if not isinstance(event.get(field),str) or not event[field].strip(): raise RouterError(f"IDENTITY_ENVELOPE_REQUIRED:{field}")
|
||||
key=secret_reader(config)
|
||||
available=available_models(config,key)
|
||||
selected=candidates(config,event.get("complexity","LOW"),available)
|
||||
selection_policy=event.get("selection_policy","COST_FIRST")
|
||||
selected=candidates(config,event.get("complexity","LOW"),available,selection_policy)
|
||||
if not selected: raise RouterError("NO_CONFIGURED_MODEL_AVAILABLE")
|
||||
system=(f"你是{event['parent_persona_id']}人格系统内的子Agent {event['child_agent_id']},岗位是{event['agent_role']}。"
|
||||
f"你的唯一父人格主控是{event['controller']},当前频道{event['channel_id']}。权限仅为{event['authority']}。"
|
||||
"你必须理解后再协作,不能把宿主规则程序冒充人格,不能扩大权限,不能泄露私人数据。"
|
||||
"你只能把输入中明确提供的内容称为事实且必须标为FACT;推断必须标为INFERENCE,缺证据必须标为UNKNOWN。"
|
||||
"禁止虚构日志、错误码、编号、回执、人物回应或系统状态;模型返回不等于已校验、已执行或已完成。"
|
||||
f"你已领取的TCS共享认知脑是:{json.dumps(event.get('shared_cognition',{}),ensure_ascii=False)}")
|
||||
attempts=[]
|
||||
for model in selected:
|
||||
|
|
@ -66,7 +72,7 @@ def route(event: dict[str,Any], config: dict[str,Any]|None=None, secret_reader=k
|
|||
response=request_json(config["provider"]["base_url"]+"/chat/completions",key,{"model":model,"stream":False,"temperature":0.2,"messages":[{"role":"system","content":system},{"role":"user","content":event["task"]}]})
|
||||
content=response.get("choices",[{}])[0].get("message",{}).get("content")
|
||||
if not isinstance(content,str) or not content.strip(): raise RouterError("MODEL_RESPONSE_EMPTY")
|
||||
return {"outcome":"PASS","router_id":config["router_id"],"selected_model":model,"attempts":[*attempts,{"model":model,"outcome":"PASS"}],"response":content,"response_sha256":hashlib.sha256(content.encode()).hexdigest(),"identity_bound":True,"credentials_stored":False,"authority_granted":False}
|
||||
return {"outcome":"PASS","router_id":config["router_id"],"selected_model":model,"selection_policy":selection_policy,"attempts":[*attempts,{"model":model,"outcome":"PASS"}],"response":content,"response_sha256":hashlib.sha256(content.encode()).hexdigest(),"response_validation_state":"CALLER_REVIEW_REQUIRED","identity_bound":True,"credentials_stored":False,"authority_granted":False}
|
||||
except RouterError as error:
|
||||
attempts.append({"model":model,"outcome":"FAIL","error_code":str(error)})
|
||||
raise RouterError("ALL_COST_ORDERED_MODELS_FAILED:"+",".join(x["model"] for x in attempts))
|
||||
|
|
|
|||
|
|
@ -9,14 +9,21 @@ E={"parent_persona_id":"ICE-P-ZY001","child_agent_id":"SUBAGENT::ICE-P-ZY001::TE
|
|||
class Tests(unittest.TestCase):
|
||||
def test_cost_order_uses_only_available_models(self):
|
||||
self.assertEqual(M.candidates(C,'LOW',{'glm-4-flash','gpt-5-nano'}),['glm-4-flash','gpt-5-nano'])
|
||||
def test_quality_first_uses_high_tier_before_lower_tiers(self):
|
||||
available={'qwen-flash','gpt-5.4-mini','gpt-6-astra-2026-09-03'}
|
||||
self.assertEqual(M.candidates(C,'HIGH',available,'QUALITY_FIRST'),['gpt-6-astra-2026-09-03','gpt-5.4-mini','qwen-flash'])
|
||||
def test_identity_envelope_and_key_never_returned(self):
|
||||
def fake(url,key,payload=None,timeout=45):
|
||||
if url.endswith('/models'): return {"data":[{"id":"qwen-flash"}]}
|
||||
self.assertIn('ICE-P-ZY001',payload['messages'][0]['content']); self.assertEqual(key,'hidden')
|
||||
self.assertIn('ICE-P-ZY001',payload['messages'][0]['content'])
|
||||
self.assertIn('FACT',payload['messages'][0]['content'])
|
||||
self.assertIn('禁止虚构日志',payload['messages'][0]['content'])
|
||||
self.assertEqual(key,'hidden')
|
||||
return {"choices":[{"message":{"content":"收到"}}]}
|
||||
with patch.object(M,'request_json',side_effect=fake):
|
||||
result=M.route(E,C,secret_reader=lambda _: 'hidden')
|
||||
self.assertEqual(result['selected_model'],'qwen-flash'); self.assertNotIn('hidden',json.dumps(result))
|
||||
self.assertEqual(result['response_validation_state'],'CALLER_REVIEW_REQUIRED')
|
||||
def test_missing_identity_and_unallowlisted_url_fail(self):
|
||||
with self.assertRaisesRegex(M.RouterError,'IDENTITY_ENVELOPE'): M.route({"task":"x"},C,secret_reader=lambda _:'hidden')
|
||||
with self.assertRaisesRegex(M.RouterError,'NOT_ALLOWLISTED'): M.request_json('https://evil.example/v1/models','hidden')
|
||||
|
|
|
|||
Loading…
Reference in a new issue