Skip to main content

工具

工具是 AI 可以调用的具名操作,具有类型化输入——例如 send_email(to, subject, body)。工具在技能的 tools.ts 中声明,对于应用提供的工具,由其中一个组件中的 HTTP 路由支持。本页是工具契约的权威来源;技能涵盖 tools.ts 的位置。

声明工具

tools.ts 中的每个条目都有一个提供商安全的 name、一个友好的 displayName、一个 description、一个 Zod input 模式和一个 target,用于指定 Kazzle 调用的内容。

目标

target 是工具或必需操作按钮的可复用地址。直接 AI 工具调用和按钮点击可以使用同一个目标对象,因此都运行相同的代码。 HTTP 目标使用相同的请求字段:
没有隐式请求默认值。如果你的处理程序应该接收原始工具输入作为 JSON,请写 body: '${input}'

引用

Kazzle 在分发前解析 HTTP 目标 queryheadersbodyurl 字段中的引用:
  • ${input} — 整个工具输入,或整个按钮输入。
  • ${input.path} — 输入中的嵌套值。
  • ${env.NAME} — 来自拥有应用组件声明的 env.collection + env.environment 的具名环境变量。
解析是单遍的。如果引用缺失或未知,工具失败而不是替换为空值。当你需要字面的 ${input.name} 文本时,使用 $${input.name}

处理程序请求

对于 app 目标,在目标组件中添加匹配的路由。使用 body: '${input}',Kazzle 将类型化输入作为 JSON 正文发送:
app 目标还接收: 应用目标无法通过 headers 设置 Authorization;Kazzle 拥有该标头。当处理程序必须区分线程与工具 API 时,从 @kazzle/app/tools 使用 toolContext(req) 读取上下文。 声明的工具如果没有匹配的路由则无用——同时添加两者。不支持 tools.json;如果应用编译器找到它会失败。

处理程序响应

返回纯文本或最多三个通道的 JSON:
  • content — AI 读取的纯结果(馈送到模型)。必需。
  • markdown — 可选。在工具卡中呈现的简短富文本摘要(react-markdown;原始 HTML 被转义)。适合一个句子、一个小列表、一个内联链接。裸相对路径呈现为死预格式化文本——链接必须是绝对的
  • embedUrl — 可选。你的应用提供的绝对 URL;卡在沙箱 iframe 中呈现它。这是你展示真实、全宽 UI 的方式——连接屏幕、仪表板、图表。你的应用托管并拥有该页面,因此它可以完全针对你自己的后端、cookie 和 OAuth 进行交互。没有任何内容写入驱动器。
当两者都设置时,embedUrl 优先于 markdown。始终保持有意义的 content ——那是 AI 读取的内容。

必需操作

应用工具可以在需要用户(或设备)操作时暂停线程。返回 type: 'action_required' 以及卡标题和按钮。仅在 toolContext(req).source === 'thread' 时有效——通过工具 API(source: 'api'),改为返回正常的域错误。
Kazzle 在工具调用时保存卡,并在按钮被按下后通过 /chat/resume 恢复。匹配的客户端看到作者按钮;不匹配的客户端仍然看到跳过/取消加上”在 上继续”。没有 target 的按钮将其 input 作为工具结果提交。有目标的按钮先运行该目标,然后使用目标结果作为工具结果。

富 UI——嵌入应用托管的页面

当工具的结果是视觉或交互式的(连接屏幕、图表、摘要仪表板)时,从你的某个组件提供该页面,并将其绝对 URL 作为 embedUrl 返回。从注入的组件 URL 构建 URL——永远不要使用相对路径。
该页面在跨源 iframe 中运行(其自己的源、cookie 和脚本)。要调整卡的大小,将其高度发布到父级——卡侦听此操作并调整大小(上限为视口的 70%):
优先使用 embedUrl 而不是发出 HTML 字符串:你的应用已经提供页面,UI 保持交互式并与你的代码一起版本化,并且没有按调用工件写入任何地方。