Skip to content
FunCoding

Search

Search docs, Skills and MCP

TypeScript 权限与生命周期

区分工具注册和自动批准,配置超时并正确处理中断与关闭。

This page has not been translated into English yet. The original Chinese version is shown below.

SDK 需要应用自己处理无法自动决定的权限请求。默认 SDK 模式没有交互终端替用户确认,未获批准的请求会被拒绝。

审批顺序

官方给出的主要顺序为 deny、ask、plan 限制、yolo、allow、auto 分类器、canUseTool,最后是 SDK 默认拒绝。canUseTool 不是每个调用必经的审计钩子:已允许的工具会跳过它,读操作通常也不要求确认。

permissionMode 的 default 要求写工具得到 callback 或允许规则批准;plan 阻止非只读工具;auto-edit 自动批准 edit、write_file、notebook_edit;auto 使用分类器,连续拒绝或分类器异常时可回到人工批准;yolo 自动批准但仍不覆盖更高优先级的 deny/ask。

注册、隐藏与允许

coreTools 是旧式核心工具注册白名单,支持 Read/Edit/Bash 别名,但 Bash(git *) 这样的调用限定部分会被剥离;它不表达“仅允许 git 命令”。allowedTools 对应 permissions.allow,只自动批准匹配调用,不缩小工具集合或隐藏 schema。

excludeTools 对应 permissions.deny,完整工具规则可从注册表移除内置工具;带 specifier 的规则只拒绝匹配调用。MCP 工具不按普通 deny 规则移出注册表,应使用每服务 excludeTools 或 tools.disabled 隐藏,deny 仍可在执行时阻止。

tools.eager 控制首轮 schema 暴露,并不移除工具。被降为按需发现的工具仍可能通过 tool_search/tool_call 到达;桥接工具缺失时,隐藏工具不能经该桥发现,但直接名称调用仍按正常权限判断。tools.visible、已有直接调用历史及工具集刷新还会改变声明情况。详细通用机制见工具参考。

自定义 callback

canUseTool 接收工具名称、输入和包含 signal 的上下文;允许返回 behavior: allow 及 updatedInput,拒绝返回 behavior: deny 与 message。应用应在用户实际决定后返回相应结果,不能把超时当同意。

import { query, type CanUseTool } from '@qwen-code/sdk';

const canUseTool: CanUseTool = async (toolName, input, { signal }) => {
  if (signal.aborted) {
    return { behavior: 'deny', message: 'Permission request cancelled.' };
  }
  return { behavior: 'deny', message: `Approval is required for ${toolName}.` };
};

const result = query({
  prompt: 'Inspect the repository.',
  options: { cwd: '/path/to/project', canUseTool },
});

for await (const message of result) console.log(message);

示例明确拒绝进入 callback 的请求,供应用替换为自己的审批界面;不宣称这个 callback 阻止所有未经过它的只读或自动批准行为。

超时单位

TypeScript timeout 值为毫秒,以下四项默认都是 60000:

字段约束
canUseTool权限 callback,超时自动拒绝
mcpRequestSDK MCP 调用
controlRequestinitialize、setModel、setPermissionMode、getContextUsage、interrupt 等
streamClose多轮且含 SDK MCP 时,关闭 stdin 前等待初始化

例如 options.timeout 可设 mcpRequest: 600000。不要把 Python SDK 的秒数直接复制到此处。

中断、关闭和异常

Query.interrupt() 只取消当前轮;以 async iterable 输入的多轮查询和输入流仍开放,后续消息继续处理。Query.close() 或配置的 AbortController.abort() 才结束整个会话并清理资源。

setModel()、setPermissionMode() 可在会话中调整,getContextUsage() 返回分类 token 用量,传 true 可请求详细展示提示。isClosed() 用于检查生命周期,不代替等待任务结果。

捕获取消使用 isAbortError,也可识别 AbortError。取消之外的异常应按真实原因处理,不要全部转换成“用户取消”。需要定时 abort 的应用还应管理自己的 timer,避免查询已完成后仍保留无关定时任务。