""" 智能体唯一 Worker 入口(LLM / 识别 / 报价 PDF / 存档)。 本文件职责:组装分槽、Graph、Redis、LLM 网关;阻塞至进程结束。 禁止:Redis wecom:worker:singleton;禁止在 HTTP 回调里跑本模块逻辑。 """ from __future__ import annotations import logging import signal import threading from agent.config import get_settings from agent.graph import get_graph_runtime, shutdown_graph_runtime from agent.jobs import WorkerRuntime from agent.llm import LlmGateway from agent.redis_coord import get_redis_runtime, shutdown_redis_runtime logger = logging.getLogger(__name__) def main() -> None: """ 启动 Worker:wake Stream + LLM Stream + LibreOffice 槽。 Graph resume/wake 仅走 http_jobs 槽。 """ logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s [%(name)s] %(message)s", ) # Worker 自己下素材,必须关掉 httpx INFO,否则 access_token 会进日志。 logging.getLogger("httpx").setLevel(logging.WARNING) settings = get_settings() graph_runtime = get_graph_runtime(settings) redis_runtime = get_redis_runtime(settings) llm = LlmGateway.from_settings(settings) runtime = WorkerRuntime.from_settings( settings.libreoffice_slots, settings.http_job_slots, graph=graph_runtime, redis=redis_runtime, llm=llm, ) runtime.start() stop_event = threading.Event() def _handle_signal(signum: int, _frame: object) -> None: logger.info("收到停止信号 signum=%s", signum) runtime.stop() shutdown_graph_runtime() shutdown_redis_runtime() stop_event.set() signal.signal(signal.SIGINT, _handle_signal) signal.signal(signal.SIGTERM, _handle_signal) logger.info( "Worker 运行中 ytd_env=%s checkpoint=%s redis=%s(Ctrl+C 退出)", settings.ytd_env, graph_runtime.checkpoint.backend, redis_runtime.client.backend, ) stop_event.wait() logger.info("Worker 已退出") if __name__ == "__main__": main()