From 94ed63638018c211111d6ce3fb1f6b671799af4e Mon Sep 17 00:00:00 2001 From: Turtle Date: Sat, 24 Oct 2026 13:23:53 +0800 Subject: [PATCH] fix(tool-ask-user): tell the model a skipped question is answered The blocking ask_user_question description did not explain that an answer item with empty selected and no custom is a user skip, so models re-asked the same question after the user clicked Skip. Refs #7134 --- docs/tool-catalog.i18n.yaml | 4 ++-- docs/tool-catalog.md | 2 +- docs/tool-catalog.zh.md | 2 +- packages/interaction/tool-ask-user/README.i18n.yaml | 4 ++-- packages/interaction/tool-ask-user/README.md | 2 +- packages/interaction/tool-ask-user/README.zh.md | 2 +- packages/interaction/tool-ask-user/src/index.ts | 3 ++- .../interaction/tool-ask-user/tests/tool-ask-user.spec.ts | 3 ++- .../sdk/background-wait-steer/tool-schemas.expected.json | 2 +- snapshots/sdk/desktop-context/tool-schemas.expected.json | 2 +- snapshots/sdk/desktop-ptc-context/system-prompt.expected.md | 2 +- .../tool-schemas.expected.json | 2 +- .../web/creation-recommendations/tool-schemas.expected.json | 4 ++-- snapshots/web/fresh-round-trip/tool-schemas.expected.json | 2 +- .../web/official-subagent-bundle/system-prompt.expected.md | 2 +- .../web/optional-string-editor/system-prompt.expected.md | 2 +- .../web/plugin-recommendations/tool-schemas.expected.json | 4 ++-- snapshots/web/ptc-round/system-prompt.expected.md | 2 +- 18 files changed, 24 insertions(+), 22 deletions(-) diff --git a/docs/tool-catalog.i18n.yaml b/docs/tool-catalog.i18n.yaml index bd8974669f..6cfa137a71 100644 --- a/docs/tool-catalog.i18n.yaml +++ b/docs/tool-catalog.i18n.yaml @@ -66,8 +66,8 @@ en: e713a4a11a15d13c zh: e713a4a11a15d13c /tool-schema-catalog/deepseek-ai-dsh-tool-ask-user/ask-user-question: - en: 2f86adf8ae823afb - zh: a5dad3d821e75e55 + en: 664dae29d0eae65f + zh: 2efa5d3f2cb31bf9 /tool-schema-catalog/deepseek-ai-dsh-tool-executor-ptc: en: 8c8643ef46fd075f zh: 8c8643ef46fd075f diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index 149cf1a144..9b466762d3 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -547,7 +547,7 @@ Declared only to an Agent that loaded the skill of a registered card kind; the k ### `ask_user_question` -Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. +Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission. ```json { diff --git a/docs/tool-catalog.zh.md b/docs/tool-catalog.zh.md index 6fab7658a0..092c2b2a10 100644 --- a/docs/tool-catalog.zh.md +++ b/docs/tool-catalog.zh.md @@ -551,7 +551,7 @@ ### `ask_user_question` -继续操作前,如果需要确认、选择或缺失的信息,请向用户提出简明问题。 +继续操作前,如果需要确认、选择或缺失的信息,请向用户提出简明问题。如果回答项的 `selected` 为空且没有 `custom`,表示用户跳过了该问题:不带该回答继续执行,不要再次提问,也不要将跳过视为许可。 ```json { diff --git a/packages/interaction/tool-ask-user/README.i18n.yaml b/packages/interaction/tool-ask-user/README.i18n.yaml index a5d61e2fd2..2d36d742ae 100644 --- a/packages/interaction/tool-ask-user/README.i18n.yaml +++ b/packages/interaction/tool-ask-user/README.i18n.yaml @@ -21,8 +21,8 @@ en: 7c70d43d4cd9aa19 zh: 7597e972067ec5fe /deepseek-ai-dsh-tool-ask-user/use-this-package/what-the-model-gets-back: - en: c30ba8cefa64a287 - zh: cc8bc285ff859983 + en: 9834248654e8939d + zh: d19249ed907763fb /deepseek-ai-dsh-tool-ask-user/use-this-package/when-the-call-fails: en: c4ac3c584f900230 zh: bd8d227f0637b8f1 diff --git a/packages/interaction/tool-ask-user/README.md b/packages/interaction/tool-ask-user/README.md index 535da6f975..0feacedf91 100644 --- a/packages/interaction/tool-ask-user/README.md +++ b/packages/interaction/tool-ask-user/README.md @@ -61,7 +61,7 @@ Send one or more questions with ids unique within the call; the answer echoes th ### What the model gets back -An answer returns one item per question. `selected` holds option labels; `custom` supplements a multi-select answer or replaces a single-select choice. A skipped item has empty `selected` and no `custom`. +An answer returns one item per question. `selected` holds option labels; `custom` supplements a multi-select answer or replaces a single-select choice. A skipped item has empty `selected` and no `custom`; the blocking tool description tells the model to continue without it, not to ask it again, and not to treat the skip as permission. For a finite timed call, `{ "pending": true, "callId": "…" }` means the foreground wait ended without an answer. The question remains answerable, and the model may continue independent work. A later answer arrives as a user message identified by `kind`, `tool`, and `callId`. Web chat pairs its questions and answers; other consumers receive compact JSON text. diff --git a/packages/interaction/tool-ask-user/README.zh.md b/packages/interaction/tool-ask-user/README.zh.md index 3ab957df64..065343ed5d 100644 --- a/packages/interaction/tool-ask-user/README.zh.md +++ b/packages/interaction/tool-ask-user/README.zh.md @@ -61,7 +61,7 @@ kind: "package-reference" ### 模型得到什么 -收到回答时,工具为每个问题返回一项。`selected` 保存选项标签;`custom` 可以补充多选答案,或替代单选选项。跳过的回答项具有空 `selected`,且没有 `custom`。 +收到回答时,工具为每个问题返回一项。`selected` 保存选项标签;`custom` 可以补充多选答案,或替代单选选项。跳过的回答项具有空 `selected`,且没有 `custom`;阻塞模式的工具描述要求模型不带这项回答继续,不再追问,也不把跳过当作许可。 对于有限时长的 timed 调用,`{ "pending": true, "callId": "…" }` 表示前台等待结束时仍没有回答。问题仍可回答,模型可以继续独立工作。之后的回答以用户消息送达,由 `kind`、`tool` 和 `callId` 标识。Web 对话会配对展示问题与回答;其他消费方收到紧凑 JSON 文本。 diff --git a/packages/interaction/tool-ask-user/src/index.ts b/packages/interaction/tool-ask-user/src/index.ts index e9ca98d048..36d4afadc7 100644 --- a/packages/interaction/tool-ask-user/src/index.ts +++ b/packages/interaction/tool-ask-user/src/index.ts @@ -28,7 +28,8 @@ export const Config: z = z.object({ export const name = 'tool-ask-user' export const inject = ['tools', 'userQuestions'] -const description = 'Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.' +const description = 'Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. ' + + 'An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.' export function apply(ctx: Context, config: Config = {}): void { if (config.mode === 'timed') { diff --git a/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts b/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts index edf01b31d2..9438a2df5d 100644 --- a/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts +++ b/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts @@ -222,7 +222,8 @@ describe('ask_user_question tool', () => { expect(schemas).toHaveLength(1) expect(schemas[0]).toMatchObject({ - description: 'Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.', + description: 'Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. ' + + 'An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.', parameters: { properties: { questions: { description: 'Questions to ask the user before continuing.' } } }, }) expect(schemas[0]?.parameters.properties).not.toHaveProperty('timeout') diff --git a/snapshots/sdk/background-wait-steer/tool-schemas.expected.json b/snapshots/sdk/background-wait-steer/tool-schemas.expected.json index a28a4eba08..8f1c417e6e 100644 --- a/snapshots/sdk/background-wait-steer/tool-schemas.expected.json +++ b/snapshots/sdk/background-wait-steer/tool-schemas.expected.json @@ -2,7 +2,7 @@ "initial": [ { "name": "ask_user_question", - "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.", + "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.", "parameters": { "type": "object", "properties": { diff --git a/snapshots/sdk/desktop-context/tool-schemas.expected.json b/snapshots/sdk/desktop-context/tool-schemas.expected.json index a28a4eba08..8f1c417e6e 100644 --- a/snapshots/sdk/desktop-context/tool-schemas.expected.json +++ b/snapshots/sdk/desktop-context/tool-schemas.expected.json @@ -2,7 +2,7 @@ "initial": [ { "name": "ask_user_question", - "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.", + "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.", "parameters": { "type": "object", "properties": { diff --git a/snapshots/sdk/desktop-ptc-context/system-prompt.expected.md b/snapshots/sdk/desktop-ptc-context/system-prompt.expected.md index 7a0ca76e3f..69ace6433c 100644 --- a/snapshots/sdk/desktop-ptc-context/system-prompt.expected.md +++ b/snapshots/sdk/desktop-ptc-context/system-prompt.expected.md @@ -49,7 +49,7 @@ Program-only SDK bindings: type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue } interface ToolArgsMap { - /** Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. */ + /** Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission. */ ask_user_question: { /** Questions to ask the user before continuing. */ questions: ({ diff --git a/snapshots/session/subagent-child-question-rejection/tool-schemas.expected.json b/snapshots/session/subagent-child-question-rejection/tool-schemas.expected.json index 2d0622de05..1d2032fd9e 100644 --- a/snapshots/session/subagent-child-question-rejection/tool-schemas.expected.json +++ b/snapshots/session/subagent-child-question-rejection/tool-schemas.expected.json @@ -2,7 +2,7 @@ "initial": [ { "name": "ask_user_question", - "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.", + "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.", "parameters": { "type": "object", "properties": { diff --git a/snapshots/web/creation-recommendations/tool-schemas.expected.json b/snapshots/web/creation-recommendations/tool-schemas.expected.json index e2f8bc2429..0b9816a7f8 100644 --- a/snapshots/web/creation-recommendations/tool-schemas.expected.json +++ b/snapshots/web/creation-recommendations/tool-schemas.expected.json @@ -2,7 +2,7 @@ "initial": [ { "name": "ask_user_question", - "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.", + "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.", "parameters": { "type": "object", "properties": { @@ -1072,7 +1072,7 @@ [ { "name": "ask_user_question", - "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.", + "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.", "parameters": { "type": "object", "properties": { diff --git a/snapshots/web/fresh-round-trip/tool-schemas.expected.json b/snapshots/web/fresh-round-trip/tool-schemas.expected.json index 8aec2885ca..741ff6d27f 100644 --- a/snapshots/web/fresh-round-trip/tool-schemas.expected.json +++ b/snapshots/web/fresh-round-trip/tool-schemas.expected.json @@ -2,7 +2,7 @@ "initial": [ { "name": "ask_user_question", - "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.", + "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.", "parameters": { "type": "object", "properties": { diff --git a/snapshots/web/official-subagent-bundle/system-prompt.expected.md b/snapshots/web/official-subagent-bundle/system-prompt.expected.md index fc56505ca7..c8dd24b7af 100644 --- a/snapshots/web/official-subagent-bundle/system-prompt.expected.md +++ b/snapshots/web/official-subagent-bundle/system-prompt.expected.md @@ -47,7 +47,7 @@ Program-only SDK bindings: type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue } interface ToolArgsMap { - /** Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. */ + /** Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission. */ ask_user_question: { /** Questions to ask the user before continuing. */ questions: ({ diff --git a/snapshots/web/optional-string-editor/system-prompt.expected.md b/snapshots/web/optional-string-editor/system-prompt.expected.md index 78cf95313b..8ecaade15e 100644 --- a/snapshots/web/optional-string-editor/system-prompt.expected.md +++ b/snapshots/web/optional-string-editor/system-prompt.expected.md @@ -47,7 +47,7 @@ Program-only SDK bindings: type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue } interface ToolArgsMap { - /** Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. */ + /** Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission. */ ask_user_question: { /** Questions to ask the user before continuing. */ questions: ({ diff --git a/snapshots/web/plugin-recommendations/tool-schemas.expected.json b/snapshots/web/plugin-recommendations/tool-schemas.expected.json index e2f8bc2429..0b9816a7f8 100644 --- a/snapshots/web/plugin-recommendations/tool-schemas.expected.json +++ b/snapshots/web/plugin-recommendations/tool-schemas.expected.json @@ -2,7 +2,7 @@ "initial": [ { "name": "ask_user_question", - "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.", + "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.", "parameters": { "type": "object", "properties": { @@ -1072,7 +1072,7 @@ [ { "name": "ask_user_question", - "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding.", + "description": "Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission.", "parameters": { "type": "object", "properties": { diff --git a/snapshots/web/ptc-round/system-prompt.expected.md b/snapshots/web/ptc-round/system-prompt.expected.md index ce7df9c013..68df54fc35 100644 --- a/snapshots/web/ptc-round/system-prompt.expected.md +++ b/snapshots/web/ptc-round/system-prompt.expected.md @@ -47,7 +47,7 @@ Program-only SDK bindings: type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue } interface ToolArgsMap { - /** Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. */ + /** Ask the user a concise question when you need confirmation, a choice, or missing information before proceeding. An answer item with empty selected and no custom means the user skipped that question: continue without it, do not ask it again, and do not treat the skip as permission. */ ask_user_question: { /** Questions to ask the user before continuing. */ questions: ({