新增工具
如何向注册表添加新工具
工具是带 JSON-Schema 参数的 TypeScript 函数。它们位于 apps/agent/src/tools/<name>.ts,并导出返回 ToolEntry[] 的工厂函数。
最小示例
创建 apps/agent/src/tools/my-provider.ts:
import { PermissionTier, type ToolEntry } from "../core/tool-registry.js";
import { ok, err, errFromThrow } from "./_shared/result.js";
export function createMyProviderTools(): ToolEntry[] {
const apiKey = process.env.MY_PROVIDER_API_KEY;
if (!apiKey) return []; // feature-gate: registry hides missing tools
return [
{
name: "my_provider_search",
toolSet: "research",
permissionTier: PermissionTier.READ_ONLY,
isAsync: true,
description: "Search My Provider for a query",
schema: {
name: "my_provider_search",
description: "Search My Provider for a query",
parameters: {
type: "object",
properties: {
query: { type: "string", description: "The search query" },
limit: { type: "number", description: "Max results", default: 10 },
},
required: ["query"],
},
},
handler: async ({ query, limit }) => {
try {
const res = await fetch(
`https://api.myprovider.com/search?q=${encodeURIComponent(query)}&limit=${limit ?? 10}`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
if (!res.ok) return err(`HTTP ${res.status}`);
return ok(await res.json());
} catch (e) {
return errFromThrow(e);
}
},
},
];
}在最接近的能力旁注册工厂。属于某个装配领域的工具应放入 apps/agent/src/app/ 下的对应 Builder,例如 messaging.ts、institution.ts 或 artifacts.ts。没有对应 Builder 的能力留在 apps/agent/src/app.ts,并放在相关注册附近。
import { createMyProviderTools } from "./tools/my-provider.js";
// ...
for (const tool of createMyProviderTools()) toolRegistry.register(tool);在 apps/agent/src/core/tool-registry.ts 的 BUILTIN_TOOL_SETS 中添加工具集条目:
research: {
description: "Market and social research tools",
tools: [
// ... existing
"my_provider_search",
],
},如果 Agent 应通过某项技能发现该工具,请将准确的工具名加入该技能的 metadata.minara.tool_names。延迟加载工具通过 tool_search 被发现,因此描述必须具体且不与其他工具冲突。
权限等级
权限等级在 apps/agent/src/core/tool-registry.ts 中定义:
| 等级 | 名称 | 使用场景 |
|---|---|---|
| 1 | READ_ONLY | 价格 / 余额 / 搜索 / read_file |
| 2 | CONFIRM_ONCE | 分析、研究、小额兑换 |
| 3 | ALWAYS_CONFIRM | write_file、patch、涉及资金的操作、文档生成 |
| 4 | MANUAL_ONLY | 提现、外部地址转账、紧急停止开关 |
如有疑问,参考最接近的现有工具。资金操作工具还要声明 isFundMoving: true 和 controlPolicy.confirm。统一权限门会展示预览,并在处理器运行前确认准确请求。
结果包裹
每个处理器都通过 apps/agent/src/tools/_shared/result.ts 中的 ok({...}) / err("...") 返回字符串。永远不要从处理器抛出异常。使用 errFromThrow(e) 转换捕获的错误。Agent 循环解析包裹并向 LLM 呈现结构化错误。
沙盒根目录文件工具
如果工具涉及文件系统,使用 apps/agent/src/tools/_security/sandbox.ts 中的 resolveInSandbox() 解析所有路径。这是强制要求。参见沙盒与权限。
验证并更新文档
在 apps/agent/tests/unit/tools/ 下添加聚焦测试,覆盖成功结果、提供商错误、凭据缺失和声明的安全策略。
pnpm --filter @minara/agent exec vitest run tests/unit/tools/my-provider.test.ts
pnpm --filter @minara/agent typecheck
pnpm --filter @minara/docs generate工具改变公共流程时,需要同步更新四种语言的手写文档。生成的工具参考来自 BUILTIN_TOOL_SETS,不要直接编辑。