编写扩展工具与命令
用 joinSession 注册工具、斜杠命令与事件监听,理解权限和内存状态。
This page has not been translated into English yet. The original Chinese version is shown below.
joinSession 把运行中的 JavaScript 进程连接到 CLI 会话,并注册扩展提供的能力。工具由模型选择调用,斜杠命令由用户主动执行;事件监听则让进程在两次调用之间保留累计状态。
一个累计工具次数的命令
在项目 .github/extensions/tool-counter/extension.mjs 写入以下示例。它根据官方的 joinSession、commands、session.log 和工具事件接口组合,只统计扩展运行期间收到的完成事件:
import { joinSession } from "@github/copilot-sdk/extension";
let completedCalls = 0;
const session = await joinSession({
commands: [
{
name: "toolcount",
description: "Show completed tool calls observed by this extension.",
handler: async () => {
await session.log(`Observed ${completedCalls} completed tool calls.`, {
level: "info",
});
},
},
],
});
session.on("tool.execution_complete", () => {
completedCalls += 1;
});启用 experimental 并从项目启动会话,确认扩展 running,让 Copilot 执行一些工具后运行 /toolcount。这个计数不是历史账单,也不会恢复重启前的值。
注册斜杠命令
commands 条目包含 name、description 和异步 handler。name 不带斜杠;handler 的 ctx.args 是命令名后面的原始文本,例如 /tokencount start 的参数为 start。
用 session.log(message, { level: "info" }) 把结果写到会话时间线。模块级变量在扩展进程存活期间保留,重载或 /clear 后重置。
注册模型工具
tools 条目使用 name、description、parameters 和 handler。parameters 是描述输入的 JSON Schema;handler 返回的字符串成为工具结果,供模型读取。
| 可选字段 | 效果 |
|---|---|
defer: "never" | 即使工具搜索启用,也始终展示工具描述 |
skipPermission: true | 请求扩展级批准后,工具不再每次单独确认 |
defer 不会强迫模型调用工具。描述应说明能力和何时有用,尤其是模型无法从其他来源获得的信息。
skipPermission 不是安装后无条件跳过权限。官方 tool-time 示例首次请求允许 user:tool-time 跳过逐次批准;对应精确预批准模式为 extension-permission-access(user:tool-time)。只应为已审阅且适合此权限范围的扩展采用它。
对齐事件
tool.execution_start 包含 toolName,完成事件包含 success,两者通过 toolCallId 关联。计时扩展应按 ID 保存开始时间,完成时计算差值;计算时可能包含等待用户批准的时间,因此是扩展观察到的墙钟时间。
assistant.usage 提供 inputTokens 和 outputTokens,可用来累计会话 token 用量。它不是价格计算公式;若要统计某段时间,从当前累计值建立基线,再显示差值。
验证结果
先确认 /extensions manage 中状态,再分别测试命令入口、工具调用和事件更新。模型回答正确不必然说明调用了新工具,应检查回复前显示的工具名称。重载后重新检查内存计数,避免把重置误判为事件丢失。