🪲 Bug: ask_user_question usable during autonomous goal rounds #6074
Replies: 7 comments
|
@johnhenry030888 这条把「自治回合里交互式询问」的裂缝定位得很准——两个独立事实叠加(共享 runtime root 无封锁 + 嵌套答案只在 log/return 可见)确实各占一半。我在当前基线(0.1.5-alpha.2 / 0.1.2-rc.1 的 goal-round-driver 已在节选里对齐)核对后,补充两点源级事实,帮你把 fix 落到位。 一、
|
|
Thanks for the source-level confirmation — especially that On your two points:
I'll report back here with the rebased diff and the PR link. 谢谢! |
|
@johnhenry030888 插件形态做出来了—— 仓库 https://github.com/argszero/cordis-plugin-goal-ask-guard,npm 已发布。 它做什么在
goal round 的检测与 与你 in-tree PR 的关系你的 primary fix(goal-round-driver 内部装 guard)是正解, 我完全支持作为 in-tree PR。这个插件是独立的 interim mitigation——它不碰 goal-round-driver 源码, 用同一套既有原语( 用法npm install @argszero/cordis-plugin-goal-ask-guard- insert:
- id: goal-ask-guard
name: '@argszero/cordis-plugin-goal-ask-guard'8/8 测试通过。如果你愿意拿你的复现场景测一下这个插件(你没提到 guard 模板插件时我说过"happy to test the plugin shape against my reproduction once you post it"——现在插件已发, 随时可测), 有任何行为差异或需要调整的地方, 在仓库开 issue 或 @我。等你的 rebase diff + PR link。 |
|
Follow-up: the fix is rebased onto current Branch (pushed, public): What changed ( Verification on current master: package suite 57/57 (new test fails pre-fix with the stub invoked once — true negative control), Full diff (88 insertions, 4 files) is on the branch; key hunk: /** Deny interactive human questions while an admitted goal round owns the turn. */
const denyAskDuringRound: ToolGuard = execution =>
execution.name === 'ask_user_question' ? GOAL_ROUND_ASK_DENIAL : undefinedinstalled on |
|
Tested the plugin shape as promised: cloned Review against the in-tree semantics (from my port work) — three gaps worth closing, all narrow:
Minor copy note: the denial tells the model the goal continues on its own, but doesn't point at None of these block the interim-mitigation role: install/deny/reinstall behavior matches, detection predicate matches the driver exactly, and it touches no driver source. Thanks for building it out so fast. |
|
@johnhenry030888 Thanks for the independent verification (8/8) and for the precise review — applied all of it. Released What changed (v0.1.0 → v0.1.1), aligned against your in-tree
13/13 tests pass ( The standalone plugin remains the interim mitigation while your in-tree PR (author branch |
|
Verified v0.1.1 independently just now (fresh clone, Thanks for turning the review around so fast. The in-tree branch stands ready whenever a maintainer wants to open that PR. |
Uh oh!
There was an error while loading. Please reload this page.
Environment: dsh 0.1.1-rc.2, Code Mode (
run_code), same-session goal (256-round cap).What happened:
During a goal run the agent called
ask_user_questionnested insiderun_code:await tools.ask_user_question({...}); return "asked";. I answered twice (answers visible in the session log as innertool/code-dispatchresults), but the outertool/resultthe model sees was just"asked"both times. The agent then looped 30+ goal rounds running verifier slices ending in "Awaiting your two decisions".Root causes (two independent facts combining):
dsh-user-questionsonly rejects live subagents (DELEGATED_CALLER), so nothing stops interactive asks during autonomous rounds. A pending question declares no timeout budget — my first answer took ~8.5 minutes to arrive while the driver stalled.Suggested fix (implemented + tested locally against 0.1.1-rc.2):
dsh-goal-round-driverregisters an agent-scoped monotonicctx.tools.guard()denyingask_user_questionfor the lifetime of each admitted goal attempt (install on inbox claim + admit; dispose on turn/end, discard, competing input, pre-step rejections, teardown). Denial tells the model to proceed or recordupdate_goal(blocked). A guard denial surfaces in Code Mode as a catchableToolCallError, unlikerestrict()-hiding.tools:sdkusage blocks warning that binding results reach the model ONLY via logs/return.Happy to share the full diff (two files) here if wanted. Thanks for all the work on the harness.
All reactions