""" Graph 骨架自检:编译 + start_thread(Memory)+ 无 sender_id 拒绝。 用法(在 inquiry-agent 目录、已装依赖): set CHECKPOINT_BACKEND=memory python -m agent.graph.selftest 不连企微、不连主账;正式验收仍以真实企微事件为准。 """ from __future__ import annotations import logging import os import sys logger = logging.getLogger(__name__) def main() -> int: logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") # 自检强制内存,避免误连生产 PG os.environ["CHECKPOINT_BACKEND"] = "memory" os.environ.setdefault("YTD_ENV", "test") from agent.config import get_settings from agent.graph.runtime import GraphIdentityError, GraphRuntime, shutdown_graph_runtime from agent.graph.wake import WorkerWakePayload get_settings.cache_clear() rt = GraphRuntime.create(get_settings()) try: try: rt.start_thread(sender_id="") logger.error("预期应拒绝空 sender_id") return 1 except GraphIdentityError: logger.info("OK: 空 sender_id 已拒绝") started = rt.start_thread(sender_id="selftest_user") tid = started["thread_id"] logger.info("OK: start_thread thread_id=%s", tid) # 骨架:wake 需要已有 thread;写入 last_wake 后再 resume 一步 wake = WorkerWakePayload( thread_id=tid, inquiry_no="SELFTEST-001", quote_version=1, wait_version=0, kind="recognition_done", ) woken = rt.wake_from_worker(wake) logger.info("OK: wake_from_worker kind=%s", woken["wake"]["kind"]) resumed = rt.resume_thread(thread_id=tid, sender_id="selftest_user") logger.info("OK: resume_thread thread_id=%s", resumed["thread_id"]) logger.info( "Graph 骨架自检通过 checkpoint_backend=%s", rt.checkpoint.backend, ) return 0 finally: rt.close() shutdown_graph_runtime() if __name__ == "__main__": sys.exit(main())