Repository navigation
Replies: 1 comment
|
We reproduced this boundary in a persistent Bot application with real model calls and browser approval controls. The required behavior is that a protected operation stays pending while the same root Agent remains conversational. We would like to qualify a maintained native contract rather than introduce an application-owned executor or reissue the Tool from a later model response. The results are separate:
Evidence and runnable experiments:
On 2026-10-09 we rechecked official Could maintainers identify the intended native owner and API for this lifecycle?
Our concrete acceptance case is a Group conversation: a private-content request stays pending while the requester and another eligible member receive permitted replies, without protected reads/disclosure or private approval-detail leakage. We have not qualified that Group behavior. Timed question success and independent Assignment capacity are supporting evidence, not completion of this requirement. |
Uh oh!
There was an error while loading. Please reload this page.
Part 1 · 中文
标题
待审批会阻塞整个 step —— 提问 seam 已经解决了同样的问题,请把同一套模式扩展到
approval/request摘要
一个审批提示会让所有进展停下:工具调用调度器在 pre-execute 闸门上
await,导致同一步里后续的兄弟调用根本发不出去、step 无法结束、模型也拿不到下一次思考机会,直到有人应答。提问 seam 已经为同一种等待
落地了解法,审批也该有。
现状
dsh-tools内联等待闸门:const gate = await this.ctx.waterfall(carrier, "tools/pre-execute", exec, …)→serviceAsk→await approval.request({ agent, toolName, callId, reason, signal })。结果只有
allowed-once/rejected/cancelled三种——没有超时。dsh-agent-loop用await startCall(nextToStart)顺序启动调用,而startCall在派发前先await prepare(exec)(也就是等审批)。因此挂起的审批会阻塞:后续兄弟调用、step 的结束、模型的下一次思考;
maxParallelToolCalls救不了,因为阻塞的await就在顺序填充循环里。@deepseek-ai/dsh-user-approval自己写明了约束:请求必须在 turn 内;只有一次性授权(
allowed-once,没有记住的规则);并且 "a durable out-of-turn approval workflow isdeferred"。
policy: never,它是自动拒绝,而不是延期。先例:提问 seam 已经这么做了
@deepseek-ai/dsh-tool-ask-user注册ask_user_question的配置是{ mode: "legacy" | "timed", timeout }(默认legacy)。在timed模式下,ctx.userQuestions.askTimed(…)会在前台窗口关闭时立刻返回:{ "pending": true, "callId": "…", "message": "… Continue useful independent work. … Do not treat this as permission." }问题保持可答(
open/continued投影供客户端渲染),晚到的答复会以answer_to_pending_question回送进会话。也就是说,限时等待 → pending 结果 → 继续干活 → 晚到的答复回送,在本代码库里已经被接受为提问的设计。审批是同一种形状的等待,只是安全要求更严。
期望行为
approval/request增加一个软性截止时间。deferred/pending结果收尾,并带上同风格的指令:未执行、不要重复、去做不依赖它的工作。
allow时恢复或重新发起该调用;给reject时按今天的方式收尾。待解问题
deferred状态,是否就是"被延期的跨 turn 审批工作流"的预期形态?deferred调用能否在有序的tools/pre-execute调度器里释放 slot,让兄弟调用继续?approval/requestanswerer + pending 存储」实现,有多少必须动核心?
更省事的替代方案
(上游同样把它列为缺失项)。
rejected,不动核心;代价是那次调用作废而不是被延期。dsh-plugin-decision-inbox(社区插件)覆盖的是决策/提问,并明确声明不替代安全审批。Part 2 · English
Title
Pending approvals block the entire step — the question seam already solved this; please extend the same pattern to
approval/requestSummary
One approval prompt halts all forward progress: the tool-call scheduler
awaits thepre-execute gate, so later sibling calls in the same step never start, the step cannot
end, and the model gets no further turn until a human answers. The question seam already
ships a fix for the same shape of wait; approvals should get it too.
Current behaviour
dsh-toolsawaits the gate inline:const gate = await this.ctx.waterfall(carrier, "tools/pre-execute", exec, …)→serviceAsk→await approval.request({ agent, toolName, callId, reason, signal }).Outcomes are only
allowed-once/rejected/cancelled— no timeout.dsh-agent-loopstarts calls withawait startCall(nextToStart), andstartCallawaits
prepare(exec)— the approval — before dispatching. A pending approval thereforeblocks later sibling calls, the end of the step, and the next model turn;
maxParallelToolCallscannot help, because the blockingawaitsits inside thesequential fill loop.
@deepseek-ai/dsh-user-approvalstates the constraint itself: requests areturn-enclosed, only one-shot grants exist (
allowed-once, no remembered rule), and"a durable out-of-turn approval workflow is deferred."
policy: never, which auto-rejects rather thandefers.
Prior art: the question seam already does this
@deepseek-ai/dsh-tool-ask-userregistersask_user_questionwith{ mode: "legacy" | "timed", timeout }(defaultlegacy). Intimedmode,ctx.userQuestions.askTimed(…)returns as soon as the foreground window closes:{ "pending": true, "callId": "…", "message": "… Continue useful independent work. … Do not treat this as permission." }The questions stay answerable (an
open/continuedprojection feeds the client), and alate reply is delivered into the session as
answer_to_pending_question. So bounded wait→ pending result → keep working → late answer delivered is already accepted design here
for questions. Approvals are the same shape of wait with a stricter safety requirement.
Proposed behaviour
approval/requestgains a soft deadline.card.
deferred/pendingoutcome carrying the same style ofinstruction: not executed, do not repeat it, continue with independent work.
allowresumes or re-issues the call;rejectresolves as today.approval is pending must still pass their own gate.
Open questions
deferredstate the intended shape of the deferred out-of-turn approvalworkflow?
deferredcall release its slot in the orderedtools/pre-executescheduler sosibling calls proceed?
approval/requestanswerer plus a pendingstore, versus needing core changes?
Cheaper alternatives
source and needs no scheduler change (also listed as missing upstream).
rejectedafter N seconds needs no corechange — the trade-off is that the call is lost rather than deferred.
dsh-plugin-decision-inbox(community) covers decisions/questions and explicitly doesnot replace security approvals.
All reactions