|
|
@@ -3,24 +3,14 @@ import { pathToFileURL } from "url"
|
|
|
import z from "zod"
|
|
|
import { Tool } from "./tool"
|
|
|
import { Skill } from "../skill"
|
|
|
-import { PermissionNext } from "../permission/next"
|
|
|
import { Ripgrep } from "../file/ripgrep"
|
|
|
import { iife } from "@/util/iife"
|
|
|
|
|
|
export const SkillTool = Tool.define("skill", async (ctx) => {
|
|
|
- const skills = await Skill.all()
|
|
|
-
|
|
|
- // Filter skills by agent permissions if agent provided
|
|
|
- const agent = ctx?.agent
|
|
|
- const accessibleSkills = agent
|
|
|
- ? skills.filter((skill) => {
|
|
|
- const rule = PermissionNext.evaluate("skill", skill.name, agent.permission)
|
|
|
- return rule.action !== "deny"
|
|
|
- })
|
|
|
- : skills
|
|
|
+ const list = await Skill.available(ctx?.agent)
|
|
|
|
|
|
const description =
|
|
|
- accessibleSkills.length === 0
|
|
|
+ list.length === 0
|
|
|
? "Load a specialized skill that provides domain-specific instructions and workflows. No skills are currently available."
|
|
|
: [
|
|
|
"Load a specialized skill that provides domain-specific instructions and workflows.",
|
|
|
@@ -34,18 +24,10 @@ export const SkillTool = Tool.define("skill", async (ctx) => {
|
|
|
"The following skills provide specialized sets of instructions for particular tasks",
|
|
|
"Invoke this tool to load a skill when a task matches one of the available skills listed below:",
|
|
|
"",
|
|
|
- "<available_skills>",
|
|
|
- ...accessibleSkills.flatMap((skill) => [
|
|
|
- ` <skill>`,
|
|
|
- ` <name>${skill.name}</name>`,
|
|
|
- ` <description>${skill.description}</description>`,
|
|
|
- ` <location>${pathToFileURL(skill.location).href}</location>`,
|
|
|
- ` </skill>`,
|
|
|
- ]),
|
|
|
- "</available_skills>",
|
|
|
+ Skill.fmt(list),
|
|
|
].join("\n")
|
|
|
|
|
|
- const examples = accessibleSkills
|
|
|
+ const examples = list
|
|
|
.map((skill) => `'${skill.name}'`)
|
|
|
.slice(0, 3)
|
|
|
.join(", ")
|
|
|
@@ -62,7 +44,7 @@ export const SkillTool = Tool.define("skill", async (ctx) => {
|
|
|
const skill = await Skill.get(params.name)
|
|
|
|
|
|
if (!skill) {
|
|
|
- const available = await Skill.all().then((x) => Object.keys(x).join(", "))
|
|
|
+ const available = await Skill.all().then((x) => x.map((skill) => skill.name).join(", "))
|
|
|
throw new Error(`Skill "${params.name}" not found. Available skills: ${available || "none"}`)
|
|
|
}
|
|
|
|