From 9f35b2663e34b3239adc541bee68e48b13ffbdb7 Mon Sep 17 00:00:00 2001 From: Aska Date: Mon, 7 Sep 2026 19:54:14 +0800 Subject: [PATCH] =?UTF-8?q?fix(wire):=20a.gw=20=E5=9C=A8=E6=8E=A5=E7=BA=BF?= =?UTF-8?q?=20onPersisted=20=E5=89=8D=E8=B5=8B=E5=80=BC=E2=80=94=E2=80=94?= =?UTF-8?q?=E9=98=B2=20nil=20Server=20panic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wire.go 原在 a.channelBridge.SetOnPersisted(a.gw.BroadcastPersisted) / AuditEvent 之后才 a.gw=gw(663),导致网关 Server 字段为 nil;一旦有 IM 主人私聊落主会话→notifyPersisted→ BroadcastPersisted(nil receiver)→panic 崩溃,面板 adminBackthink 请求失败显示'暂无后台思考'。 把 a.gw=gw 提前到 gw.SetVoice 后(接线前),移除冗余复制。go build/test 全绿, 已重建部署. --- cmd/cyrene/wire.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/cyrene/wire.go b/cmd/cyrene/wire.go index 202369e..6878d3c 100644 --- a/cmd/cyrene/wire.go +++ b/cmd/cyrene/wire.go @@ -648,6 +648,7 @@ func (a *app) wireFrontend() error { return fmt.Errorf("gateway: %w", err) } gw.SetVoice(a.voice) + a.gw = gw // assign BEFORE wiring hooks below, which capture a.gw / gw (nil-receiver panic otherwise) if a.channelBridge != nil { // Route the channel bridge's owner-private persisted messages into the same // `message_persisted` broadcast the orchestrator uses, so the Web client mirrors @@ -660,9 +661,9 @@ func (a *app) wireFrontend() error { a.gw.AuditEvent("bridge:"+msg.Platform, "channel.reject", reason) }) } - a.gw = gw a.capacitySink = gw + // Wire the backthink proactive sinks now that the gateway hub (active-client // route) and the channel bridge (IM fallback) both exist. They were absent when // backthink.New ran (the hub needs the loop and the bridge needs the loop and the