diff --git a/pkg/github/instructions.go b/pkg/github/instructions.go index e783c6c08..7a9c7ce4c 100644 --- a/pkg/github/instructions.go +++ b/pkg/github/instructions.go @@ -1,6 +1,7 @@ package github import ( + "fmt" "os" "slices" "strings" @@ -20,6 +21,11 @@ func GenerateInstructions(enabledToolsets []string) string { instructions = append(instructions, "Always call 'get_me' first to understand current user permissions and context.") } + generalInstructions := getGeneralInstructions(enabledToolsets) + if generalInstructions != "" { + instructions = append(instructions, "Here are common scenarios you may encounter followed by name and description of the steps to follow:", generalInstructions) + } + // Individual toolset instructions for _, toolset := range enabledToolsets { if inst := getToolsetInstructions(toolset); inst != "" { @@ -47,6 +53,60 @@ Tool usage guidance: return strings.Join(allInstructions, " ") } +// scenarioDefinition defines a scenario with its instruction text and required toolsets +type scenarioDefinition struct { + instruction string + requiredToolsets []string +} + +// getGeneralInstructions returns scenario-based guidance for common development tasks +func getGeneralInstructions(enabledToolsets []string) string { + enabledSet := make(map[string]bool) + for _, ts := range enabledToolsets { + enabledSet[ts] = true + } + + scenarios := map[string]scenarioDefinition{ + "Triaging Security Alerts": { + instruction: "Use list_dependabot_alerts, list_code_scanning_alerts, or list_secret_scanning_alerts with state='open' to find active security issues. Use get_*_alert for detailed information about specific alerts. For broader context, search list_global_security_advisories or get_global_security_advisory for known CVEs affecting your dependencies.", + requiredToolsets: []string{}, + }, + "Manage Workflow": { + instruction: "Call list_notifications regularly to see what needs attention. Use get_notification_details for full context on important items. Mark items as done with dismiss_notification or mark_all_notifications_read to keep your inbox organized. Use manage_notification_subscription to adjust notification preferences for threads or manage_repository_notification_subscription for entire repositories.", + requiredToolsets: []string{"notifications"}, + }, + "Investigating Bugs": { + instruction: "Use search_code to find relevant code patterns or function definitions across repositories. Use search_issues to check if similar bugs were reported before. Once you find relevant files, use get_file_contents to read them. Review get_commit and list_commits to understand recent changes that might have introduced the issue.", + requiredToolsets: []string{"repos"}, + }, + } + + var parts []string + parts = append(parts, "When helping with development tasks, consider these common scenarios and appropriate tool choices:") + + // Filter scenarios based on enabled toolsets + for scenarioName, scenario := range scenarios { + if len(scenario.requiredToolsets) == 0 { + parts = append(parts, fmt.Sprintf("%s: %s", scenarioName, scenario.instruction)) + continue + } + + hasAllRequiredToolsets := true + for _, required := range scenario.requiredToolsets { + if !enabledSet[required] { + hasAllRequiredToolsets = false + break + } + } + + if hasAllRequiredToolsets { + parts = append(parts, fmt.Sprintf("%s: %s", scenarioName, scenario.instruction)) + } + } + + return strings.Join(parts, " ") +} + // getToolsetInstructions returns specific instructions for individual toolsets func getToolsetInstructions(toolset string) string { switch toolset {