Files
MailUI4Agents/deploy/check-shared-libs.sh
JianFeeeee 2996f9af9c fix(plugins): 409 时当场表态 + DSH 补投按会话串行
**409 = 永远不会成功**(没有人类可路由)。原来三个插件都在失败时让位给
平台本地 UI —— 但邮件驱动的会话**没有 TUI**,让位之后 waterfall 跑到尾
依旧无人应答,仍是无声挂死。

HTTP 客户端必须把 err.status 与 err.body 挂到 error 上:只看 message
字符串分不出「暂时失败(502,该重试)」与「永远不会成功(409)」,
两种都会被当成前者,而前者会永久挂住会话。

三平台表态方式不同但语义统一:
- opencode: output.status = "deny" + output.reason 带服务端原文
- dsh: return 'rejected'(ApprovalOutcome 只认 allowed-once/rejected/
  cancelled,写 'denied' 不报错而是被当未知值静默失效)
- pi: return { block: true, reason }

其余失败(502 等)保持原行为,让位本地 UI。

---

**DSH 补投并发**(同一文件,故并入本次提交)

生产日志:`补投 5 封(共 16 封未读)`,9 秒后三封失败
`message "undefined" is already pending`。串行 for...of 并未真正串行 ——
awaitFirstTurn 在**首个 token** 就放行,turn 尚未结束下一封已 followup。

新增 waitForTurnEnd(等 turn/end 而非首 chunk)与 sessionLocks/locked()
按会话串行化。live-agent 路径原来直接 followup 就返回,现在也进锁。
120s 超时兜底,模型完全无响应时不会把后续邮件永久卡住。

权限场景下锁会持有到人类决策完 —— 这是正确行为:两封都需要授权时
第二封排队,比同时弹两个授权请求更合理。

顺带把 rename-proposal 纳入 check-shared-libs.sh 的同源校验。
2026-09-03 21:10:48 +08:00

43 lines
1.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# 共用模块必须逐字节相同 —— 见 docs/PLUGIN-CONTRACT.md 第六节。
#
# 一侧改了另一侧没改,几个平台的行为就会悄悄分叉:同一封邮件在 opencode 那边
# 标了已读、在 DSH 那边没标,而两处代码看起来都"对"。
#
# 三方比对以 opencode 为基准逐个对比,而不是两两对比:后者在三方都不同时
# 会打出三条互相矛盾的差异,读的人无从判断谁是对的。
set -euo pipefail
BASE=plugins/opencode-mail-bridge
PEERS=(plugins/dsh-mail-bridge plugins/pi-mail-bridge)
fail=0
for peer in "${PEERS[@]}"; do
for f in relay-dedup inbox-format session-snapshot workspace model-scope catchup addressing discovery rename-proposal permission-grants; do
if [[ ! -f "$peer/lib/$f.js" ]]; then
echo "共用模块缺失:$peer/lib/$f.js" >&2
fail=1
continue
fi
if ! diff -q "$BASE/lib/$f.js" "$peer/lib/$f.js" >/dev/null 2>&1; then
echo "共用模块已分叉lib/$f.js$BASE vs $peer" >&2
diff "$BASE/lib/$f.js" "$peer/lib/$f.js" | head -20 >&2
fail=1
fi
done
# 测试同样要同源:共用模块的行为约定写在测试里,
# 只同步实现不同步测试,等于允许一侧偷偷放宽约定。
for f in inbox-format session-snapshot workspace model-scope catchup addressing discovery rename-proposal permission-grants; do
if [[ ! -f "$peer/test/$f.test.mjs" ]]; then
echo "共用测试缺失:$peer/test/$f.test.mjs" >&2
fail=1
continue
fi
if ! diff -q "$BASE/test/$f.test.mjs" "$peer/test/$f.test.mjs" >/dev/null 2>&1; then
echo "共用测试已分叉test/$f.test.mjs$BASE vs $peer" >&2
fail=1
fi
done
done
[[ $fail -eq 0 ]] && echo " 共用模块三方同源opencode / dsh / pi" || exit 1