docs(website): document ctx.signal abort contract and execute() concurrency

This commit is contained in:
Simon
2026-06-08 22:19:25 +08:00
parent 0ba3bbd67f
commit 4108f67079
3 changed files with 14 additions and 11 deletions

View File

@@ -257,7 +257,8 @@ const root = createRoot(document.getElementById('my-ui')!)
root.render(<MyAgentUI agent={agent} />) root.render(<MyAgentUI agent={agent} />)
// 4. Handle user input (optional) // 4. Handle user input (optional)
agent.onAskUser = async (question) => window.prompt(question) || '' // options.signal aborts when the task is stopped or disposed
agent.onAskUser = async (question, options) => window.prompt(question) || ''
// 5. Execute task // 5. Execute task
await agent.execute('Fill the form with test data') await agent.execute('Fill the form with test data')

View File

@@ -354,10 +354,10 @@ const result = await agent.execute('Fill in the form with test data')`}
}, },
{ {
name: 'onAskUser', name: 'onAskUser',
type: '(question: string) => Promise<string>', type: '(question: string, options?: { signal: AbortSignal }) => Promise<string>',
description: isZh description: isZh
? '当 agent 需要向用户提问时调用。未设置则禁用 `ask_user` 工具。' ? '当 agent 需要向用户提问时调用。未设置则禁用 `ask_user` 工具。实现应在 options.signal 触发 abort 时 reject promise。'
: 'Called when the agent needs to ask the user questions. If unset, the `ask_user` tool will be disabled.', : 'Called when the agent needs to ask the user questions. If unset, the `ask_user` tool will be disabled. Implementations should reject the promise when options.signal aborts.',
}, },
]} ]}
/> />
@@ -373,8 +373,8 @@ const result = await agent.execute('Fill in the form with test data')`}
name: 'execute(task)', name: 'execute(task)',
type: 'Promise<ExecutionResult>', type: 'Promise<ExecutionResult>',
description: isZh description: isZh
? '执行任务并返回结果包含 success、data 和 history 字段。' ? '执行任务并返回结果包含 success、data 和 history 字段)。若已有任务在运行则抛出错误——不支持并发执行。'
: 'Execute a task and return result. Contains success, data, and history fields.', : 'Execute a task and return result (contains success, data, and history fields). Throws if a task is already running — concurrent execution is not supported.',
}, },
{ {
name: 'stop()', name: 'stop()',

View File

@@ -38,8 +38,8 @@ import { z } from 'zod/v4'`}
</Heading> </Heading>
<p className="text-gray-600 dark:text-gray-300 mb-4"> <p className="text-gray-600 dark:text-gray-300 mb-4">
{isZh {isZh
? '使用 tool() 辅助函数定义自定义工具,每个工具包含 description、inputSchema 和 execute 三个属性。' ? '使用 tool() 辅助函数定义自定义工具,每个工具包含 description、inputSchema 和 execute 三个属性。异步工具必须 honor ctx.signal。'
: 'Use the tool() helper to define custom tools with description, inputSchema, and execute.'} : 'Use the tool() helper to define custom tools with description, inputSchema, and execute. Async tools must honor ctx.signal.'}
</p> </p>
<CodeEditor <CodeEditor
@@ -56,10 +56,11 @@ const pageAgent = new PageAgent({
productId: z.string(), productId: z.string(),
quantity: z.number().min(1).default(1), quantity: z.number().min(1).default(1),
}), }),
execute: async function (input) { execute: async function (input, { signal }) {
await fetch('/api/cart', { await fetch('/api/cart', {
method: 'POST', method: 'POST',
body: JSON.stringify(input), body: JSON.stringify(input),
signal, // honor cancellation
}) })
return \`Added \${input.quantity}x \${input.productId} to cart.\` return \`Added \${input.quantity}x \${input.productId} to cart.\`
}, },
@@ -72,9 +73,10 @@ const pageAgent = new PageAgent({
query: z.string(), query: z.string(),
limit: z.number().max(10).default(3), limit: z.number().max(10).default(3),
}), }),
execute: async function (input) { execute: async function (input, { signal }) {
const res = await fetch( const res = await fetch(
\`/api/kb?q=\${encodeURIComponent(input.query)}&limit=\${input.limit}\` \`/api/kb?q=\${encodeURIComponent(input.query)}&limit=\${input.limit}\`,
{ signal }
) )
const articles = await res.json() const articles = await res.json()
return JSON.stringify(articles) return JSON.stringify(articles)