fix: use passive QQ event replies

This commit is contained in:
zenord
2026-08-18 22:20:55 +08:00
parent 4af5049605
commit ffedf616e3
9 changed files with 560 additions and 48 deletions
+2 -2
View File
@@ -228,7 +228,7 @@ Bot fingerprint 包含 bootstrap schema version、Bot ID、workspace、persona
```
- `/help`:显示自然语言使用说明和兜底命令列表。
- `/status`:显示固定 Bot、agent、workspace、Assistant 会话数、各状态 Proposal 计数、Worker 是否在执行及当前用户是否 owner。
- `/status`:显示固定 Bot、agent、workspace、Assistant 会话数、各状态 Proposal 计数、Worker 是否在执行及当前用户是否 owner;另含当前用户维度(`myQueuedProposals`、`myPendingConfirmations`、`schedulerState`、`blockedReason`、`nextAction`,他人 Proposal 只给脱敏原因,不暴露 title/id)与当前 chat 的事件投递状态(`lastEventDelivery`、`lastEventError`、`lastEventAt`)。
- `/list`:列出当前 chat 中当前用户拥有的 Proposal(id、状态、title)。
- `/confirm`:确认当前用户最近待确认的 Proposal(`proposed` 进入队列,`awaiting_user_confirmation` 落定完成/失败或带着回答继续)。
- `/stop`:停止当前用户正在执行的 Worker 并将其 Proposal 标记为 cancelled;对等待确认的 Proposal 按 pending 类型兜底落定(success→completed、failure→failed、step→cancelled);只有 Proposal 发起人可用。
@@ -236,7 +236,7 @@ Bot fingerprint 包含 bootstrap schema version、Bot ID、workspace、persona
日常操作以自然语言为主,Assistant 会自己生成 confirm/cancel/stop 等 action;这些命令是旁路 Assistant 的兜底入口。未识别的 `/` 命令按普通消息交给 Assistant。
Gateway 不维护普通消息队列或 per-chat task lock,也不再有固定时间(15/60/180/480 秒)的处理中提醒;每条 allowlist 普通消息按 conversation(chat + user)串行交给 AssistantManager。Worker 落定结果(成功、失败或提问)时,AssistantManager 生成事件文案并经 `Gateway.sendEvent` 由平台 adapter 作为**新消息**发出(QQ 也是新消息,不引用原消息);发送失败只记录不含消息正文或 provider 错误详情的安全日志,不影响任务或后续发送。
Gateway 不维护普通消息队列或 per-chat task lock,也不再有固定时间(15/60/180/480 秒)的处理中提醒;每条 allowlist 普通消息按 conversation(chat + user)串行交给 AssistantManager。Worker 落定结果(成功、失败或提问)时,AssistantManager 生成事件文案并经 `Gateway.sendEvent` 发出。QQ 无主动消息权限(HTTP 400 / code 40034105)时事件走被动回复窗口:`sendEvent` 引用该 chat 最近一次入站消息(`msg_id` + 递增 `msg_seq`),群聊窗口 5 分钟(按 4.5 分钟保守判定)、C2C 窗口 60 分钟(按 55 分钟保守判定);超过窗口或没有 messageId 时不发主动消息,记录为 skipped 并在该 chat 下次入站时补发。发送失败只记录不含消息正文或 provider 错误详情的安全日志(仅 HTTP status / QQ code),不影响任务或后续发送。
每条异步入站使用独立、串行的回复流,`replySequence` 从 1 动态递增;同步 webhook 直接返回 JSON 结果。