**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 的同源校验。
43 lines
1.8 KiB
Bash
Executable File
43 lines
1.8 KiB
Bash
Executable File
#!/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
|