UNPKG

agents

Version:

A home for your AI agents

94 lines (93 loc) • 3.2 kB
import { i as renderSkillResource } from "../../catalog-BpOejOsE.js"; import { tool } from "ai"; import { z } from "zod"; //#region src/skills/tools/ai-sdk.ts /** * Build AI SDK tools for a catalog: `activate_skill`, `read_skill_resource`, * and, with a script runner, `run_skill_script`. * * Failures (an unknown skill, a missing file) are thrown, so the AI SDK * returns them to the model as tool errors. * * @param catalog - The catalog to expose. Build tools again after reloading it. * @param options - Optional script runner. * @returns The tools, or an empty set when the catalog has no skills. */ function createSkillTools(catalog, options = {}) { const [first, ...rest] = catalog.skills.map((entry) => entry.skill.name); if (first === void 0) return {}; const nameSchema = z.enum([first, ...rest]); const tools = { activate_skill: tool({ description: "Activate a skill by name. Use this when the user's task matches one of the available skills.", inputSchema: z.object({ name: nameSchema }), execute: async ({ name }) => { const activated = catalog.activate(name); if (!activated.ok) throw activated.error; return activated.value; } }), read_skill_resource: tool({ description: "Read a bundled resource from an available skill by relative path. Pass name and path, or use a qualified path like skill-name/references/file.md.", inputSchema: z.object({ name: nameSchema.optional(), path: z.string().min(1) }), execute: async ({ name, path }) => { const read = await catalog.readResource(name === void 0 ? { path } : { name, path }); if (!read.ok) throw read.error; return renderSkillResource(read.value); } }) }; const runner = options.scriptRunner; if (runner) tools.run_skill_script = tool({ description: "Run a bundled script resource from an available skill. Use only when a skill instructs you to run a script.", inputSchema: z.object({ name: nameSchema, path: z.string().min(1), input: z.unknown().default({}) }), execute: async ({ name, path, input }) => { const script = await catalog.readResource({ name, path }); if (!script.ok) throw script.error; const { entry, resource } = script.value; if (resource.kind !== "script") throw new Error(`Resource is not a script: ${name}/${path}`); if (resource.encoding !== "text") throw new Error(`Script resource must be text: ${name}/${path}`); const files = []; for (const info of entry.resources) { const read = await catalog.readResource({ name, path: info.path }); if (read.ok) files.push({ path: read.value.resource.path, content: read.value.resource.content, encoding: read.value.resource.encoding, kind: read.value.resource.kind }); } try { return await runner.run({ skill: entry.skill, path: resource.path, source: resource.content, input, resources: files }); } catch (error) { throw new Error(`Skill script failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error }); } } }); return tools; } //#endregion export { createSkillTools }; //# sourceMappingURL=ai-sdk.js.map