nub/internal/tool/builtin/read_skill.go
Tom a97013d876 initial commit
- v 0.1.0 siehe CHANGELOG.md
2026-07-25 11:08:01 +02:00

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
}