76ecf0e49e
Phase 6: skill.New constructor satisfying the agent.Skill contract; instruction-only skills; ordered additive composition; skill/clock (injectable-clock time tools) and skill/calc (recursive-descent arithmetic evaluator) as ready-made examples with full test suites incl. an agent-loop round trip. ADR-0013; README skills section + matrix synced. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
67 lines
2.1 KiB
Go
67 lines
2.1 KiB
Go
// Package skill provides reusable capability bundles for agents: a named
|
|
// set of instructions (appended to the agent's system prompt) plus optional
|
|
// tools (joined into the agent's toolset). Skills attach to ANY agent, at
|
|
// construction (agent.WithSkill) or on demand (Agent.AddSkill), and compose
|
|
// additively in attachment order.
|
|
//
|
|
// The contract a skill satisfies is the agent.Skill interface; this package
|
|
// is the standard way to build one without writing a type:
|
|
//
|
|
// research := skill.New("research",
|
|
// skill.WithInstructions("Cite sources for every claim."),
|
|
// skill.WithTools(searchTool, fetchTool),
|
|
// )
|
|
// a.AddSkill(research)
|
|
//
|
|
// Two ready-made example skills ship as subpackages: clock (time awareness)
|
|
// and calc (exact arithmetic).
|
|
package skill
|
|
|
|
import "gitea.stevedudenhoeffer.com/steve/majordomo/llm"
|
|
|
|
// Skill is a buildable instruction+tool bundle. The zero value is unusable;
|
|
// construct with New.
|
|
type Skill struct {
|
|
name string
|
|
instructions string
|
|
toolbox *llm.Toolbox
|
|
}
|
|
|
|
// Option configures a Skill under construction.
|
|
type Option func(*Skill)
|
|
|
|
// WithInstructions sets the text appended to the agent's system prompt.
|
|
func WithInstructions(s string) Option {
|
|
return func(sk *Skill) { sk.instructions = s }
|
|
}
|
|
|
|
// WithToolbox attaches the skill's tools as an existing toolbox.
|
|
func WithToolbox(b *llm.Toolbox) Option {
|
|
return func(sk *Skill) { sk.toolbox = b }
|
|
}
|
|
|
|
// WithTools attaches loose tools (wrapped in a toolbox named after the
|
|
// skill).
|
|
func WithTools(tools ...llm.Tool) Option {
|
|
return func(sk *Skill) { sk.toolbox = llm.NewToolbox(sk.name, tools...) }
|
|
}
|
|
|
|
// New builds a skill.
|
|
func New(name string, opts ...Option) *Skill {
|
|
sk := &Skill{name: name}
|
|
for _, opt := range opts {
|
|
opt(sk)
|
|
}
|
|
return sk
|
|
}
|
|
|
|
// Name identifies the skill (used in duplicate-tool diagnostics).
|
|
func (s *Skill) Name() string { return s.name }
|
|
|
|
// Instructions returns the system-prompt extension; may be empty.
|
|
func (s *Skill) Instructions() string { return s.instructions }
|
|
|
|
// Tools returns the skill's toolbox; may be nil for instruction-only
|
|
// skills.
|
|
func (s *Skill) Tools() *llm.Toolbox { return s.toolbox }
|