Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
427 changes: 422 additions & 5 deletions internal/cmd/category.go

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions internal/converter/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,12 @@ func (c *Converter) routeRulesWithLLM(ctx context.Context, userPolicy *schema.Us
}
sem := make(chan struct{}, maxConcurrent)

// Build category name -> description map
categoryMap := make(map[string]string)
for _, cat := range userPolicy.Category {
categoryMap[cat.Name] = cat.Description
}

// Process rules in parallel with concurrency limit
for _, rule := range userPolicy.Rules {
// Get languages for this rule
Expand All @@ -322,7 +328,7 @@ func (c *Converter) routeRulesWithLLM(ctx context.Context, userPolicy *schema.Us
}

wg.Add(1)
go func(r schema.UserRule, linters []string) {
go func(r schema.UserRule, linters []string, catMap map[string]string) {
defer wg.Done()

// Acquire semaphore with context check
Expand All @@ -334,7 +340,7 @@ func (c *Converter) routeRulesWithLLM(ctx context.Context, userPolicy *schema.Us
defer func() { <-sem }()

// Ask LLM which linters are appropriate for this rule
selectedLinters := c.selectLintersForRule(ctx, r, linters)
selectedLinters := c.selectLintersForRule(ctx, r, linters, catMap)

// Send result with context check to prevent deadlock
if len(selectedLinters) == 0 {
Expand All @@ -351,7 +357,7 @@ func (c *Converter) routeRulesWithLLM(ctx context.Context, userPolicy *schema.Us
return
}
}
}(rule, availableLinters)
}(rule, availableLinters, categoryMap)
}

// Close results channel after all goroutines complete
Expand Down Expand Up @@ -398,7 +404,7 @@ func (c *Converter) getAvailableLinters(languages []string) []string {
}

// selectLintersForRule uses LLM to determine which linters are appropriate for a rule
func (c *Converter) selectLintersForRule(ctx context.Context, rule schema.UserRule, availableLinters []string) []string {
func (c *Converter) selectLintersForRule(ctx context.Context, rule schema.UserRule, availableLinters []string, categoryMap map[string]string) []string {
// Build linter descriptions dynamically from registry
linterDescriptions := c.buildLinterDescriptions(availableLinters)

Expand Down Expand Up @@ -465,7 +471,11 @@ Input: "Imports from large packages must be specific"
Output: []
Reason: Requires knowing which packages are "large"`, linterDescriptions, routingHints, availableLinters)

userPrompt := fmt.Sprintf("Rule: %s\nCategory: %s", rule.Say, rule.Category)
categoryInfo := rule.Category
if desc, ok := categoryMap[rule.Category]; ok && desc != "" {
categoryInfo = fmt.Sprintf("%s (%s)", rule.Category, desc)
}
userPrompt := fmt.Sprintf("Rule: %s\nCategory: %s", rule.Say, categoryInfo)

// Call LLM
prompt := systemPrompt + "\n\n" + userPrompt
Expand Down
Loading