Merge PR #1389
This commit is contained in:
commit
f5145d34fc
3 changed files with 47 additions and 5 deletions
|
|
@ -25,6 +25,7 @@ type ContextBuilder struct {
|
||||||
memory *MemoryStore
|
memory *MemoryStore
|
||||||
toolDiscoveryBM25 bool
|
toolDiscoveryBM25 bool
|
||||||
toolDiscoveryRegex bool
|
toolDiscoveryRegex bool
|
||||||
|
skillsFilter []string
|
||||||
|
|
||||||
// Cache for system prompt to avoid rebuilding on every call.
|
// Cache for system prompt to avoid rebuilding on every call.
|
||||||
// This fixes issue #607: repeated reprocessing of the entire context.
|
// This fixes issue #607: repeated reprocessing of the entire context.
|
||||||
|
|
@ -51,6 +52,13 @@ func (cb *ContextBuilder) WithToolDiscovery(useBM25, useRegex bool) *ContextBuil
|
||||||
return cb
|
return cb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSkillsFilter restricts which skills appear in the system prompt to the
|
||||||
|
// named list. An empty or nil filter means all available skills are included.
|
||||||
|
func (cb *ContextBuilder) WithSkillsFilter(filter []string) *ContextBuilder {
|
||||||
|
cb.skillsFilter = filter
|
||||||
|
return cb
|
||||||
|
}
|
||||||
|
|
||||||
func getGlobalConfigDir() string {
|
func getGlobalConfigDir() string {
|
||||||
if home := os.Getenv("PICOCLAW_HOME"); home != "" {
|
if home := os.Getenv("PICOCLAW_HOME"); home != "" {
|
||||||
return home
|
return home
|
||||||
|
|
@ -141,7 +149,7 @@ func (cb *ContextBuilder) BuildSystemPrompt() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skills - show summary, AI can read full content with read_file tool
|
// Skills - show summary, AI can read full content with read_file tool
|
||||||
skillsSummary := cb.skillsLoader.BuildSkillsSummary()
|
skillsSummary := cb.skillsLoader.BuildSkillsSummaryFiltered(cb.skillsFilter)
|
||||||
if skillsSummary != "" {
|
if skillsSummary != "" {
|
||||||
parts = append(parts, fmt.Sprintf(`# Skills
|
parts = append(parts, fmt.Sprintf(`# Skills
|
||||||
|
|
||||||
|
|
@ -718,16 +726,27 @@ func (cb *ContextBuilder) AddAssistantMessage(
|
||||||
return messages
|
return messages
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSkillsInfo returns information about loaded skills.
|
// GetSkillsInfo returns information about loaded skills, respecting any active filter.
|
||||||
func (cb *ContextBuilder) GetSkillsInfo() map[string]any {
|
func (cb *ContextBuilder) GetSkillsInfo() map[string]any {
|
||||||
allSkills := cb.skillsLoader.ListSkills()
|
allSkills := cb.skillsLoader.ListSkills()
|
||||||
|
|
||||||
|
var allowed map[string]bool
|
||||||
|
if len(cb.skillsFilter) > 0 {
|
||||||
|
allowed = make(map[string]bool, len(cb.skillsFilter))
|
||||||
|
for _, n := range cb.skillsFilter {
|
||||||
|
allowed[n] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
skillNames := make([]string, 0, len(allSkills))
|
skillNames := make([]string, 0, len(allSkills))
|
||||||
for _, s := range allSkills {
|
for _, s := range allSkills {
|
||||||
skillNames = append(skillNames, s.Name)
|
if allowed == nil || allowed[s.Name] {
|
||||||
|
skillNames = append(skillNames, s.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return map[string]any{
|
return map[string]any{
|
||||||
"total": len(allSkills),
|
"total": len(allSkills),
|
||||||
"available": len(allSkills),
|
"available": len(skillNames),
|
||||||
"names": skillNames,
|
"names": skillNames,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,8 @@ func NewAgentInstance(
|
||||||
skillsFilter = agentCfg.Skills
|
skillsFilter = agentCfg.Skills
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contextBuilder.WithSkillsFilter(skillsFilter)
|
||||||
|
|
||||||
maxIter := defaults.MaxToolIterations
|
maxIter := defaults.MaxToolIterations
|
||||||
if maxIter == 0 {
|
if maxIter == 0 {
|
||||||
maxIter = 20
|
maxIter = 20
|
||||||
|
|
|
||||||
|
|
@ -192,19 +192,36 @@ func (sl *SkillsLoader) LoadSkillsForContext(skillNames []string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sl *SkillsLoader) BuildSkillsSummary() string {
|
func (sl *SkillsLoader) BuildSkillsSummary() string {
|
||||||
|
return sl.BuildSkillsSummaryFiltered(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildSkillsSummaryFiltered builds the XML skills summary, restricted to
|
||||||
|
// allowedNames if non-empty. An empty/nil allowedNames includes all skills.
|
||||||
|
func (sl *SkillsLoader) BuildSkillsSummaryFiltered(allowedNames []string) string {
|
||||||
allSkills := sl.ListSkills()
|
allSkills := sl.ListSkills()
|
||||||
if len(allSkills) == 0 {
|
if len(allSkills) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var allowed map[string]bool
|
||||||
|
if len(allowedNames) > 0 {
|
||||||
|
allowed = make(map[string]bool, len(allowedNames))
|
||||||
|
for _, n := range allowedNames {
|
||||||
|
allowed[n] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var lines []string
|
var lines []string
|
||||||
lines = append(lines, "<skills>")
|
lines = append(lines, "<skills>")
|
||||||
for _, s := range allSkills {
|
for _, s := range allSkills {
|
||||||
|
if allowed != nil && !allowed[s.Name] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
escapedName := escapeXML(s.Name)
|
escapedName := escapeXML(s.Name)
|
||||||
escapedDesc := escapeXML(s.Description)
|
escapedDesc := escapeXML(s.Description)
|
||||||
escapedPath := escapeXML(s.Path)
|
escapedPath := escapeXML(s.Path)
|
||||||
|
|
||||||
lines = append(lines, fmt.Sprintf(" <skill>"))
|
lines = append(lines, " <skill>")
|
||||||
lines = append(lines, fmt.Sprintf(" <name>%s</name>", escapedName))
|
lines = append(lines, fmt.Sprintf(" <name>%s</name>", escapedName))
|
||||||
lines = append(lines, fmt.Sprintf(" <description>%s</description>", escapedDesc))
|
lines = append(lines, fmt.Sprintf(" <description>%s</description>", escapedDesc))
|
||||||
lines = append(lines, fmt.Sprintf(" <location>%s</location>", escapedPath))
|
lines = append(lines, fmt.Sprintf(" <location>%s</location>", escapedPath))
|
||||||
|
|
@ -213,6 +230,10 @@ func (sl *SkillsLoader) BuildSkillsSummary() string {
|
||||||
}
|
}
|
||||||
lines = append(lines, "</skills>")
|
lines = append(lines, "</skills>")
|
||||||
|
|
||||||
|
if len(lines) == 2 {
|
||||||
|
// Only open/close tags — filter excluded everything
|
||||||
|
return ""
|
||||||
|
}
|
||||||
return strings.Join(lines, "\n")
|
return strings.Join(lines, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue