67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
package builtin
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"nub/internal/skill"
|
|
"nub/internal/tool"
|
|
)
|
|
|
|
// ReadSkillTool lädt den Body eines im Index (nur Name+Description)
|
|
// angekündigten Skills nach (5.5, Progressive Disclosure).
|
|
type ReadSkillTool struct {
|
|
skills []skill.Skill
|
|
}
|
|
|
|
func NewReadSkillTool(skills []skill.Skill) *ReadSkillTool {
|
|
return &ReadSkillTool{skills: skills}
|
|
}
|
|
|
|
func (*ReadSkillTool) Name() string { return "read_skill" }
|
|
func (*ReadSkillTool) Description() string {
|
|
return "Lädt den vollständigen Inhalt eines Skills nach Name."
|
|
}
|
|
|
|
func (*ReadSkillTool) Schema() json.RawMessage {
|
|
return json.RawMessage(`{
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {"type": "string"}
|
|
},
|
|
"required": ["name"]
|
|
}`)
|
|
}
|
|
|
|
type readSkillInput struct {
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
func (t *ReadSkillTool) Run(ctx context.Context, input json.RawMessage, env tool.Env) (tool.Result, error) {
|
|
var in readSkillInput
|
|
if err := json.Unmarshal(input, &in); err != nil {
|
|
return tool.Result{ForModel: "invalid input: " + err.Error(), IsError: true}, nil
|
|
}
|
|
|
|
for _, s := range t.skills {
|
|
if s.Name == in.Name {
|
|
return tool.Result{ForModel: s.Body, ForUI: SkillResult{Name: s.Name, Dir: s.Dir}}, nil
|
|
}
|
|
}
|
|
|
|
names := make([]string, len(t.skills))
|
|
for i, s := range t.skills {
|
|
names[i] = s.Name
|
|
}
|
|
return tool.Result{
|
|
ForModel: fmt.Sprintf("unknown skill %q. Available: %s", in.Name, strings.Join(names, ", ")),
|
|
IsError: true,
|
|
}, nil
|
|
}
|
|
|
|
type SkillResult struct {
|
|
Name string
|
|
Dir string
|
|
}
|