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
This commit is contained in:
Turtle committed 2026-10-24 13:23:53 +08:00
1 parent c262a09fd0
commit 94ed636380
18 files changed
+24 -22

No files matched your search

+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
{
+1 -1
View File
@@ -551,7 +551,7 @@
### `ask_user_question`
继续操作前,如果需要确认、选择或缺失的信息,请向用户提出简明问题。
继续操作前,如果需要确认、选择或缺失的信息,请向用户提出简明问题。如果回答项的 `selected` 为空且没有 `custom`,表示用户跳过了该问题:不带该回答继续执行,不要再次提问,也不要将跳过视为许可。
```json
{
@@ -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
+1 -1
View File
@@ -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.
@@ -61,7 +61,7 @@ kind: "package-reference"
### 模型得到什么
收到回答时,工具为每个问题返回一项。`selected` 保存选项标签;`custom` 可以补充多选答案,或替代单选选项。跳过的回答项具有空 `selected`,且没有 `custom`。
收到回答时,工具为每个问题返回一项。`selected` 保存选项标签;`custom` 可以补充多选答案,或替代单选选项。跳过的回答项具有空 `selected`,且没有 `custom`;阻塞模式的工具描述要求模型不带这项回答继续,不再追问,也不把跳过当作许可。
对于有限时长的 timed 调用,`{ "pending": true, "callId": "…" }` 表示前台等待结束时仍没有回答。问题仍可回答,模型可以继续独立工作。之后的回答以用户消息送达,由 `kind`、`tool` 和 `callId` 标识。Web 对话会配对展示问题与回答;其他消费方收到紧凑 JSON 文本。
@@ -28,7 +28,8 @@ export const Config: z<Config> = 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') {
@@ -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')
@@ -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": {
@@ -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": {
@@ -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: ({
@@ -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": {
@@ -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": {
@@ -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": {
@@ -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: ({
@@ -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: ({
@@ -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": {
@@ -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: ({