feat(ai): Add per-resource notes to patrol context
Knowledge store notes are now included in the patrol LLM prompt. When users save notes about resources (e.g., 'This VM intentionally runs hot'), the patrol AI will see these notes and avoid flagging documented behavior as issues. Changes: - Added knowledge store reference to PatrolService - Added SetKnowledgeStore() method to configure the store - Enhanced buildPatrolPrompt() to include knowledge context - Connected knowledge store to patrol in service.go SetStateProvider() This complements the dismissed findings context to give the LLM a complete picture of what the user considers normal/expected behavior.
This commit is contained in:
parent
a3d953172c
commit
fd8cc4a32e
2 changed files with 40 additions and 3 deletions
|
|
@ -10,6 +10,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/rcourtman/pulse-go-rewrite/internal/ai/knowledge"
|
||||
"github.com/rcourtman/pulse-go-rewrite/internal/models"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
|
@ -206,6 +207,7 @@ type PatrolService struct {
|
|||
thresholdProvider ThresholdProvider
|
||||
config PatrolConfig
|
||||
findings *FindingsStore
|
||||
knowledgeStore *knowledge.Store // For per-resource notes in patrol context
|
||||
|
||||
// Cached thresholds (recalculated when thresholdProvider changes)
|
||||
thresholds PatrolThresholds
|
||||
|
|
@ -320,6 +322,13 @@ func (p *PatrolService) SetRunHistoryPersistence(persistence PatrolHistoryPersis
|
|||
return nil
|
||||
}
|
||||
|
||||
// SetKnowledgeStore sets the knowledge store for including per-resource notes in patrol context
|
||||
func (p *PatrolService) SetKnowledgeStore(store *knowledge.Store) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
p.knowledgeStore = store
|
||||
}
|
||||
|
||||
// GetConfig returns the current patrol configuration
|
||||
func (p *PatrolService) GetConfig() PatrolConfig {
|
||||
p.mu.RLock()
|
||||
|
|
@ -1632,6 +1641,15 @@ func (p *PatrolService) buildPatrolPrompt(summary string, deep bool) string {
|
|||
// Get user feedback context (dismissed/snoozed findings)
|
||||
feedbackContext := p.findings.GetDismissedForContext()
|
||||
|
||||
// Get resource notes from knowledge store (per-resource user notes)
|
||||
var knowledgeContext string
|
||||
p.mu.RLock()
|
||||
knowledgeStore := p.knowledgeStore
|
||||
p.mu.RUnlock()
|
||||
if knowledgeStore != nil {
|
||||
knowledgeContext = knowledgeStore.FormatAllForContext()
|
||||
}
|
||||
|
||||
basePrompt := fmt.Sprintf(`Please perform a comprehensive analysis of the following infrastructure and identify any issues, potential problems, or optimization opportunities.
|
||||
|
||||
%s
|
||||
|
|
@ -1645,16 +1663,31 @@ Analyze the above and report any findings using the structured format. Focus on:
|
|||
|
||||
If everything looks healthy, say so briefly.`, summary)
|
||||
|
||||
// If there's user feedback, append instructions
|
||||
var contextAdditions strings.Builder
|
||||
|
||||
// Append knowledge context (user notes about resources)
|
||||
if knowledgeContext != "" {
|
||||
contextAdditions.WriteString("\n\n")
|
||||
contextAdditions.WriteString(knowledgeContext)
|
||||
contextAdditions.WriteString("\nIMPORTANT: Consider the user's saved notes above when analyzing. If a user has noted that a resource behaves a certain way (e.g., 'runs hot for transcoding'), do not flag it as an issue.\n")
|
||||
}
|
||||
|
||||
// Append user feedback context (dismissed/snoozed findings)
|
||||
if feedbackContext != "" {
|
||||
return basePrompt + "\n\n" + feedbackContext + `
|
||||
contextAdditions.WriteString("\n\n")
|
||||
contextAdditions.WriteString(feedbackContext)
|
||||
contextAdditions.WriteString(`
|
||||
|
||||
IMPORTANT: Respect the user's feedback above. Do NOT re-raise findings that are:
|
||||
- Permanently suppressed - the user has explicitly said to never mention these again
|
||||
- Dismissed as "not_an_issue" or "expected_behavior" - the user knows about these
|
||||
- Currently snoozed - only re-raise if the severity has significantly worsened
|
||||
|
||||
Only report NEW issues or issues where the severity has clearly escalated.`
|
||||
Only report NEW issues or issues where the severity has clearly escalated.`)
|
||||
}
|
||||
|
||||
if contextAdditions.Len() > 0 {
|
||||
return basePrompt + contextAdditions.String()
|
||||
}
|
||||
|
||||
return basePrompt
|
||||
|
|
|
|||
|
|
@ -75,6 +75,10 @@ func (s *Service) SetStateProvider(sp StateProvider) {
|
|||
// Initialize patrol service if not already done
|
||||
if s.patrolService == nil && sp != nil {
|
||||
s.patrolService = NewPatrolService(s, sp)
|
||||
// Connect knowledge store to patrol for per-resource notes in context
|
||||
if s.knowledgeStore != nil {
|
||||
s.patrolService.SetKnowledgeStore(s.knowledgeStore)
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize alert-triggered analyzer if not already done
|
||||
|
|
|
|||
Loading…
Reference in a new issue