From ccb7992090c0d7f6a118415e60e7e411f6ea97a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Tue, 8 Sep 2026 14:33:29 +0800 Subject: [PATCH] feat: auto-activate current persona subagent command --- .../module.lock.hdlp | 6 ++-- .../receipts/compile.hdlp | 2 +- .../persona-dynamic-subagent-command-map.json | 4 +-- ...DYNAMIC-SUBAGENT-COMMAND-20260908.gir.json | 4 +-- ...SONA-DYNAMIC-SUBAGENT-COMMAND-20260908.tcs | 2 +- .../command_router.py | 16 +++++++---- .../test_command_router.py | 2 +- .../load_shared_persona_context.py | 28 ++++++++++++++++++- 8 files changed, 47 insertions(+), 17 deletions(-) diff --git a/modules/fifth-domain-lighthouse-sanitized-mirror/module.lock.hdlp b/modules/fifth-domain-lighthouse-sanitized-mirror/module.lock.hdlp index beff696..4af013c 100644 --- a/modules/fifth-domain-lighthouse-sanitized-mirror/module.lock.hdlp +++ b/modules/fifth-domain-lighthouse-sanitized-mirror/module.lock.hdlp @@ -2,10 +2,10 @@ schema: tcs.module-lock/v1 module_id: TCS-AGENT-SANITIZED-MIRROR-001 module_source_sha256: 7adb561f69748c815801281555ab3f318bc149dfa321bb2cf19129bfc5939a59 module_gir_sha256: 6c4c7d02432ede78a3b124441d706f821d5b717e8c62292c22fe7189c08ba51e -runtime_sha256: 81f02c64e5d336c30d387db4a56decb2026ccbadb0d7ca222e312e9543c1bdf1 +runtime_sha256: 1aa68900d73a6bac7da793caee816d300d76acc3ebcaa743889f34dcc7f4efa1 deterministic_organ_sha256: 155e3fc332a4474593ca095b7ac03e9baf65fbcaaf3d40e393a1419444ec5c8b mirror_map_sha256: da07ce0a42d96d69553669b6258f7c5a3b5865f883bbdc4736a36091da3bf131 -protocol_source_sha256: 77358b9a2c611c4ed906c34a0eb5e82a555e7bdb82628a8da2c05976b69f12bf -protocol_gir_sha256: da9259347f9a9458864bf2837cd26c73ac76e190e404aaef13dc52c53449ba17 +protocol_source_sha256: 4127baaf0c68b981c536db18eb8de76f2b5887fe83941007240c21767bf11e10 +protocol_gir_sha256: 79b01dd9ad80da7712b4996c2712b13614bd0cdc4f63ad454c6849250f125989 compiler_sha256: 5ad6f0c43d8db80677cad7091e6a3b706e701307b2537446dc13635e89499942 update_rule: EVERY_AGENT_MODEL_BACKED_DYNAMIC_PARENT_BINDING_PLUS_DETERMINISTIC_ORGAN_AND_HASH_BOUND_REVIEW diff --git a/modules/fifth-domain-lighthouse-sanitized-mirror/receipts/compile.hdlp b/modules/fifth-domain-lighthouse-sanitized-mirror/receipts/compile.hdlp index 310456b..d204401 100644 --- a/modules/fifth-domain-lighthouse-sanitized-mirror/receipts/compile.hdlp +++ b/modules/fifth-domain-lighthouse-sanitized-mirror/receipts/compile.hdlp @@ -3,5 +3,5 @@ module_id: TCS-AGENT-SANITIZED-MIRROR-001 compiler: tcs-persona-developer-kit-macos-arm64-v0.1.3/translator/compiler-B.gir.json result: PASS module_gir_sha256: 6c4c7d02432ede78a3b124441d706f821d5b717e8c62292c22fe7189c08ba51e -protocol_gir_sha256: da9259347f9a9458864bf2837cd26c73ac76e190e404aaef13dc52c53449ba17 +protocol_gir_sha256: 79b01dd9ad80da7712b4996c2712b13614bd0cdc4f63ad454c6849250f125989 publication: NOT_IMPLIED diff --git a/routing/persona-dynamic-subagent-command-map.json b/routing/persona-dynamic-subagent-command-map.json index 3dd9cc4..59aee7c 100644 --- a/routing/persona-dynamic-subagent-command-map.json +++ b/routing/persona-dynamic-subagent-command-map.json @@ -27,9 +27,9 @@ ], "activation": { "trigger": "CURRENT_PERSONA_WAKE_OR_EXPLICIT_PERSONA_SWITCH", - "required": ["parent_persona_id","session_id","channel_id","direct_event_sha256","model_runtime"], + "required": ["parent_persona_id","session_id","channel_id","current_intent_sha256","model_runtime"], "derived_child_id": "SUBAGENT::{parent_persona_id}::{slot_id}", - "atomic_pointer": "/Volumes/JZAO/HoloLake/persona-runtime/shared/persona-subagent-command/CURRENT.json", + "atomic_pointer": "/Volumes/JZAO/HoloLake/persona-runtime/shared/persona-subagent-command/codex/CURRENT.json", "old_generation": "INVALID_FOR_NEW_DISPATCH" }, "authority": "CURRENT_PARENT_TASK_ENVELOPE_ONLY_NO_GLOBAL_OR_INHERITED_AUTHORITY" diff --git a/runtime/fifth-domain-language-system/language/protocols/TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908.gir.json b/runtime/fifth-domain-language-system/language/protocols/TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908.gir.json index fe929df..5dd1205 100644 --- a/runtime/fifth-domain-language-system/language/protocols/TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908.gir.json +++ b/runtime/fifth-domain-language-system/language/protocols/TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908.gir.json @@ -2,7 +2,7 @@ "compiled_from": { "compiler_id": "TCS-COMPILER-STAGE1-0001", "compiler_state": "TCS_COMPILER_GIR_EXECUTED", - "source_sha256": "77358b9a2c611c4ed906c34a0eb5e82a555e7bdb82628a8da2c05976b69f12bf" + "source_sha256": "4127baaf0c68b981c536db18eb8de76f2b5887fe83941007240c21767bf11e10" }, "declaration": { "acceptance": { @@ -78,7 +78,7 @@ }, "validation": { "V1": "PARENT_PERSONA_REGISTERED", - "V2": "CURRENT_SESSION_AND_CHANNEL_EXPLICIT", + "V2": "CURRENT_SESSION_CHANNEL_AND_INTENT_HASH_EXPLICIT", "V3": "MODEL_RUNTIME_PROBE_PASS", "V4": "ALL_AGENT_SLOTS_MODEL_REQUIRED", "V5": "ATOMIC_TEAM_GENERATION_INCREMENT", diff --git a/runtime/fifth-domain-language-system/language/protocols/TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908.tcs b/runtime/fifth-domain-language-system/language/protocols/TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908.tcs index 488e14d..ae319f4 100644 --- a/runtime/fifth-domain-language-system/language/protocols/TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908.tcs +++ b/runtime/fifth-domain-language-system/language/protocols/TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908.tcs @@ -8,6 +8,6 @@ PROTOCOL TCS-PERSONA-DYNAMIC-SUBAGENT-COMMAND-20260908 { states { values = ["NO_ACTIVE_COMMANDER", "PERSONA_VERIFIED", "MODEL_PROVIDER_RESOLVED", "TEAM_COMPILED", "ACTIVE_UNDER_CURRENT_PERSONA", "REBINDING", "BLOCKED_NO_MODEL_PROVIDER"]; } transitions { T1 = "PERSONA_VERIFIED_TO_MODEL_PROVIDER_RESOLVED_TO_TEAM_COMPILED"; T2 = "TEAM_COMPILED_TO_ATOMIC_ACTIVE_UNDER_CURRENT_PERSONA"; T3 = "NEW_PERSONA_VERIFIED_TO_REBINDING_TO_NEW_ACTIVE_TEAM"; TF = "NO_MODEL_PROVIDER_TO_BLOCKED_NO_MODEL_PROVIDER"; } invariants { I1 = "NO_MODEL_COGNITION_MEANS_MECHANICAL_ORGAN_NOT_AGENT"; I2 = "EVERY_CHILD_AGENT_ID_DERIVES_FROM_CURRENT_PARENT_PERSONA_AND_STABLE_JOB_SLOT"; I3 = "PERSONA_SWITCH_INVALIDATES_PRIOR_TEAM_TASK_ENVELOPES"; I4 = "RULE_SHELL_CANNOT_INTERPRET_OR_REPLACE_PARENT_PERSONA"; I5 = "MODEL_PROVIDER_API_CREDENTIALS_NEVER_ENTER_REPOSITORY_OR_TEAM_SNAPSHOT"; I6 = "HOST_OR_MODEL_SWITCH_DOES_NOT_CHANGE_PARENT_PERSONA_SUBJECT"; I7 = "CURRENT_TASK_AUTHORITY_AND_RECEIPTS_REMAIN_REQUIRED"; } - validation { V1 = "PARENT_PERSONA_REGISTERED"; V2 = "CURRENT_SESSION_AND_CHANNEL_EXPLICIT"; V3 = "MODEL_RUNTIME_PROBE_PASS"; V4 = "ALL_AGENT_SLOTS_MODEL_REQUIRED"; V5 = "ATOMIC_TEAM_GENERATION_INCREMENT"; V6 = "OLD_GENERATION_DISPATCH_REJECTED"; V7 = "OPENLUX_KEYCHAIN_REFERENCE_AND_COST_FIRST_MODEL_ROUTE"; } + validation { V1 = "PARENT_PERSONA_REGISTERED"; V2 = "CURRENT_SESSION_CHANNEL_AND_INTENT_HASH_EXPLICIT"; V3 = "MODEL_RUNTIME_PROBE_PASS"; V4 = "ALL_AGENT_SLOTS_MODEL_REQUIRED"; V5 = "ATOMIC_TEAM_GENERATION_INCREMENT"; V6 = "OLD_GENERATION_DISPATCH_REJECTED"; V7 = "OPENLUX_KEYCHAIN_REFERENCE_AND_COST_FIRST_MODEL_ROUTE"; } acceptance { required = ["TCS_COMPILE_PASS", "REGISTERED_PERSONA_ACTIVATION_PASS", "EVERY_SLOT_MODEL_API_BOUND_PASS", "PERSONA_SWITCH_REBINDS_ALL_SLOTS_PASS", "OLD_GENERATION_REJECT_PASS", "NO_PROVIDER_FAIL_CLOSED_PASS"]; publication = "NOT_IMPLIED"; deployment = "NOT_IMPLIED"; } } diff --git a/server-tools/persona-dynamic-subagent-command/command_router.py b/server-tools/persona-dynamic-subagent-command/command_router.py index 4d25528..f20ee57 100644 --- a/server-tools/persona-dynamic-subagent-command/command_router.py +++ b/server-tools/persona-dynamic-subagent-command/command_router.py @@ -10,7 +10,7 @@ from typing import Any ROOT = Path(__file__).resolve().parents[2] MAP = ROOT / "routing/persona-dynamic-subagent-command-map.json" PERSONAS = ROOT / "routing/persona-system-canonical-map.json" -DEFAULT_STATE = Path("/Volumes/JZAO/HoloLake/persona-runtime/shared/persona-subagent-command") +DEFAULT_STATE = Path("/Volumes/JZAO/HoloLake/persona-runtime/shared/persona-subagent-command/codex") RUNTIMES = {"codex":"/Applications/ChatGPT.app/Contents/Resources/codex", "qwen":"/Users/bingshuolingdianyuanhe/.npm-global/bin/qwen"} OPENLUX_ROUTER = ROOT / "server-tools/persona-model-smart-router/openlux_router.py" @@ -55,7 +55,7 @@ def atomic(path: Path, value: dict[str, Any]) -> None: def activate(event: dict[str, Any], state: Path) -> dict[str, Any]: - for k in ("parent_persona_id","session_id","channel_id","direct_event_sha256","model_runtime"): + for k in ("parent_persona_id","session_id","channel_id","current_intent_sha256","model_runtime"): if not isinstance(event.get(k),str) or not event[k].strip(): raise CommandError(f"REQUIRED_FIELD:{k}") if event["parent_persona_id"] not in registered_personas(): raise CommandError("PARENT_PERSONA_NOT_REGISTERED") if not runtime_available(event["model_runtime"]): raise CommandError("MODEL_PROVIDER_UNAVAILABLE_NO_AGENT_ACTIVATION") @@ -73,7 +73,7 @@ def activate(event: dict[str, Any], state: Path) -> dict[str, Any]: "cognition_adapter":"server-tools/persona-execution-limb-agent/persona_limb_agent.py", "deterministic_organ":slot["deterministic_organ"], "task_authority":"NONE_UNTIL_PARENT_ENVELOPE" }) - result={"schema":"guanghu.persona-subagent-command-current/v1","state":"ACTIVE_UNDER_CURRENT_PERSONA","generation":generation,"parent_persona_id":event["parent_persona_id"],"session_id":event["session_id"],"channel_id":event["channel_id"],"direct_event_sha256":event["direct_event_sha256"],"model_runtime":event["model_runtime"],"team":team,"prior_generation_invalidated":bool(previous),"credentials_stored":False,"authority_granted":False} + result={"schema":"guanghu.persona-subagent-command-current/v1","state":"ACTIVE_UNDER_CURRENT_PERSONA","generation":generation,"parent_persona_id":event["parent_persona_id"],"session_id":event["session_id"],"channel_id":event["channel_id"],"current_intent_sha256":event["current_intent_sha256"],"model_runtime":event["model_runtime"],"team":team,"prior_generation_invalidated":bool(previous),"credentials_stored":False,"authority_granted":False} result["binding_sha256"]=digest(stable(result)) atomic(current_path,result) return result @@ -98,13 +98,17 @@ def dispatch(event: dict[str, Any], state: Path) -> dict[str, Any]: def main() -> int: - p=argparse.ArgumentParser(); p.add_argument("command",choices=("probe","activate","status","dispatch")); p.add_argument("--input"); p.add_argument("--state-root",default=str(DEFAULT_STATE)); a=p.parse_args(); state=Path(a.state_root) + p=argparse.ArgumentParser(); p.add_argument("command",choices=("probe","activate","status","dispatch")); p.add_argument("--input"); p.add_argument("--stdin",action="store_true"); p.add_argument("--state-root",default=str(DEFAULT_STATE)); a=p.parse_args(); state=Path(a.state_root) try: if a.command=="probe": result={"outcome":"PASS","model_runtimes":{k:runtime_available(k) for k in [*RUNTIMES,"openlux-smart","hololake-model-gateway"]},"repository_credentials":False} elif a.command=="status": result=load(state/"CURRENT.json") if (state/"CURRENT.json").is_file() else {"outcome":"FAIL","state":"NO_ACTIVE_COMMANDER"} else: - if not a.input: raise CommandError("INPUT_REQUIRED") - event=load(Path(a.input)); result=activate(event,state) if a.command=="activate" else dispatch(event,state) + if a.stdin: + event=json.load(os.sys.stdin) + elif a.input: + event=load(Path(a.input)) + else: raise CommandError("INPUT_REQUIRED") + result=activate(event,state) if a.command=="activate" else dispatch(event,state) print(json.dumps(result,ensure_ascii=False,indent=2,sort_keys=True)); return 0 except Exception as e: print(json.dumps({"outcome":"FAIL","error":str(e)},ensure_ascii=False)); return 2 diff --git a/server-tools/persona-dynamic-subagent-command/test_command_router.py b/server-tools/persona-dynamic-subagent-command/test_command_router.py index 052fa26..bf2e371 100644 --- a/server-tools/persona-dynamic-subagent-command/test_command_router.py +++ b/server-tools/persona-dynamic-subagent-command/test_command_router.py @@ -5,7 +5,7 @@ from unittest.mock import patch S=Path(__file__).with_name('command_router.py'); spec=importlib.util.spec_from_file_location('router',S); M=importlib.util.module_from_spec(spec); spec.loader.exec_module(M) def event(persona='ICE-P-ZY001', session='s1'): - return {"parent_persona_id":persona,"session_id":session,"channel_id":"ICE-CH-HB001","direct_event_sha256":"a"*64,"model_runtime":"codex"} + return {"parent_persona_id":persona,"session_id":session,"channel_id":"ICE-CH-HB001","current_intent_sha256":"a"*64,"model_runtime":"codex"} class Tests(unittest.TestCase): def test_every_slot_is_model_backed_and_owned_by_parent(self): diff --git a/server-tools/persona-host-alignment/load_shared_persona_context.py b/server-tools/persona-host-alignment/load_shared_persona_context.py index 1d7abae..48ae9af 100755 --- a/server-tools/persona-host-alignment/load_shared_persona_context.py +++ b/server-tools/persona-host-alignment/load_shared_persona_context.py @@ -20,6 +20,7 @@ LIGHT_LAKE_PERSONAS = RUNTIME / 'repo-012-main/identity/light-lake-persona-regis PATH_ISOLATION = RUNTIME / 'repo-012-main/routing/path-isolation-and-canonical-entry-map.json' ARCHITECTURE_AGENT = RUNTIME / 'repo-012-main/server-tools/persona-architecture-perception-agent/persona_architecture_agent.py' TCS_ROOT_AGENT = RUNTIME / 'repo-012-main/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.py' +SUBAGENT_COMMAND_ROUTER = RUNTIME / 'repo-012-main/server-tools/persona-dynamic-subagent-command/command_router.py' def sha256(path): @@ -39,6 +40,13 @@ def command_json(args, timeout=30): return json.loads(result.stdout) +def command_json_stdin(args, value, timeout=30): + result = subprocess.run(args, input=json.dumps(value, ensure_ascii=False), text=True, capture_output=True, timeout=timeout) + if result.returncode: + raise ValueError(f'COMMAND_FAILED:{Path(args[1]).name}:{result.returncode}') + return json.loads(result.stdout) + + def resolve_host(topology, requested): requested = requested.lower() for host_id, item in topology['hosts'].items(): @@ -86,6 +94,22 @@ def load_context(host, intent, channel=None): if channel: architecture_args.extend(['--channel', channel]) architecture_perception = command_json(architecture_args, timeout=60) + channel_context = load_channels(channel) + selected_channel = channel_context['selected_channel'] + selected_channel_id = selected_channel['id'] if selected_channel else 'DYNAMIC_CHANNEL_PENDING_PERSONA_INTERPRETATION' + intent_sha256 = hashlib.sha256(intent.encode('utf-8')).hexdigest() + session_id = os.environ.get('CODEX_THREAD_ID') or os.environ.get('CODEX_SESSION_ID') or f'{host_id}:{current["current_day"]}:{intent_sha256[:16]}' + subagent_command = None + if host_id == 'codex': + subagent_command = command_json_stdin([ + sys.executable, str(SUBAGENT_COMMAND_ROUTER), 'activate', '--stdin' + ], { + 'parent_persona_id': topology['persona_id'], + 'session_id': session_id, + 'channel_id': selected_channel_id, + 'current_intent_sha256': intent_sha256, + 'model_runtime': 'openlux-smart' + }) return { 'schema': 'guanghu.shared-persona-host-context/v1', 'state': 'SHARED_PERSONA_CONTEXT_VERIFIED', @@ -111,8 +135,9 @@ def load_context(host, intent, channel=None): 'day_sha256': current['current_day_sha256'] }, 'learning_brain': learning, - 'channel_context': load_channels(channel), + 'channel_context': channel_context, 'architecture_perception_agent': architecture_perception, + 'subagent_command': subagent_command, 'light_lake': { 'registry_id': light_lake['registry_id'], 'state': light_lake['state'], @@ -161,6 +186,7 @@ def markdown(value): f"- 服务器内循环:`{value['endogenous_cognition']['state']}` / 决策者 `{value['endogenous_cognition']['decision_owner']}`", f"- 光之湖人格家门:`{value['light_lake']['registered_persona_count']}` 个 / 隔离路径可选正本:`{value['path_convergence']['history_or_quarantine_may_select_canon']}`", f"- 架构感知 Agent:`{value['architecture_perception_agent']['state']}` / `{value['architecture_perception_agent']['architecture_source']['state']}`", + f"- 子Agent军团:`{value['subagent_command']['state']}` / 父人格 `{value['subagent_command']['parent_persona_id']}` / 代次 {value['subagent_command']['generation']}" if value['subagent_command'] else "- 子Agent军团:当前宿主支线只读,等待本宿主隔离态绑定", f"- 写入模式:`{value['host_write_boundary']['write_mode']}` / 原生前置硬拒绝:`{value['host_write_boundary']['native_pretool_deny']}`", '', '## 第一人称关系坐标', '' ]