落地并存测服全端:智能体 Graph/路由、后台切 8180、主账与部署脚本齐备,便于线上重发与验收。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
linmianxun
2026-09-13 21:15:58 +08:00
co-authored by Cursor
parent 0eb1adecc8
commit 8103b3b651
143 changed files with 8968 additions and 277 deletions
+12 -10
View File
@@ -1,5 +1,5 @@
"""
通道消费循环:inbox → echo handler;outbox → 企微发送。
通道消费循环:inbox → RouteDecision → dispatch → handler;outbox → 企微发送。
本文件职责:在 HTTP 进程内独立线程跑快路径,不与 LibreOffice 串队。
禁止:在回调请求线程调用本循环的阻塞逻辑;禁止 Redis 全局单例锁。
@@ -12,9 +12,10 @@ import threading
from typing import Optional
from agent.channel.outbox.sender import PERMANENT_SEND_ERRORS, WeComAppClient
from agent.channel.queue import MemoryMessageStore, get_message_store
from agent.channel.queue import get_message_store
from agent.config import Settings
from agent.handlers.echo_text import handle_echo_text
from agent.routing import IntentRouter
from agent.routing.dispatch import dispatch_inbound
logger = logging.getLogger(__name__)
# 避免 httpx 把 access_token / secret 打进 INFO
@@ -26,6 +27,7 @@ class ChannelRuntime:
企微通道运行时:inbox/outbox 各一条守护线程。
启动时机:FastAPI lifespan;停止:进程退出。
inbox:IntentRouter.route(默认 stub)→ dispatch 查表;无业务分支森林。
"""
def __init__(self, settings: Settings) -> None:
@@ -33,6 +35,7 @@ class ChannelRuntime:
self._store = get_message_store()
self._stop = threading.Event()
self._threads: list[threading.Thread] = []
self._router = IntentRouter(allow_network=False)
agent_id = int(settings.wecom_agent_id or "0") or 0
self._client = WeComAppClient(
corp_id=settings.wecom_corp_id,
@@ -41,7 +44,7 @@ class ChannelRuntime:
)
@property
def store(self) -> MemoryMessageStore:
def store(self):
return self._store
def start(self) -> None:
@@ -53,7 +56,7 @@ class ChannelRuntime:
]
for t in self._threads:
t.start()
logger.info("ChannelRuntime 已启动(inbox/outbox 独立线程)")
logger.info("ChannelRuntime 已启动(inbox/outbox 独立线程;dispatch 分发)")
def stop(self) -> None:
self._stop.set()
@@ -65,12 +68,11 @@ class ChannelRuntime:
self._store.wait_inbox(1.0)
continue
try:
handle_echo_text(
item.message,
self._store,
ytd_env=self._settings.ytd_env,
reply_template=self._settings.wecom_callback_reply_text,
decision = self._router.route(
text=item.message.content or "",
sender_id=item.message.sender_id or "",
)
dispatch_inbound(item.message, decision)
self._store.complete_inbound(item.id)
except Exception as exc: # noqa: BLE001
logger.exception("inbox 处理失败 id=%s", item.id)