prompt.go

 1package prompt
 2
 3import (
 4	"fmt"
 5	"os"
 6	"path/filepath"
 7	"strings"
 8
 9	"github.com/opencode-ai/opencode/internal/config"
10	"github.com/opencode-ai/opencode/internal/llm/models"
11)
12
13// contextFiles is a list of potential context files to check for
14var contextFiles = []string{
15	".github/copilot-instructions.md",
16	".cursorrules",
17	".cursor/rules/", // Directory containing multiple rule files
18	"CLAUDE.md",
19	"CLAUDE.local.md",
20	"opencode.md",
21	"opencode.local.md",
22	"OpenCode.md",
23	"OpenCode.local.md",
24	"OPENCODE.md",
25	"OPENCODE.local.md",
26}
27
28func GetAgentPrompt(agentName config.AgentName, provider models.ModelProvider) string {
29	basePrompt := ""
30	switch agentName {
31	case config.AgentCoder:
32		basePrompt = CoderPrompt(provider)
33	case config.AgentTitle:
34		basePrompt = TitlePrompt(provider)
35	case config.AgentTask:
36		basePrompt = TaskPrompt(provider)
37	default:
38		basePrompt = "You are a helpful assistant"
39	}
40
41	if agentName == config.AgentCoder || agentName == config.AgentTask {
42		// Add context from project-specific instruction files if they exist
43		contextContent := getContextFromFiles()
44		if contextContent != "" {
45			return fmt.Sprintf("%s\n\n# Project-Specific Context\n%s", basePrompt, contextContent)
46		}
47	}
48	return basePrompt
49}
50
51// getContextFromFiles checks for the existence of context files and returns their content
52func getContextFromFiles() string {
53	workDir := config.WorkingDirectory()
54	var contextContent string
55
56	for _, path := range contextFiles {
57		// Check if path ends with a slash (indicating a directory)
58		if strings.HasSuffix(path, "/") {
59			// Handle directory - read all files within it
60			dirPath := filepath.Join(workDir, path)
61			files, err := os.ReadDir(dirPath)
62			if err == nil {
63				for _, file := range files {
64					if !file.IsDir() {
65						filePath := filepath.Join(dirPath, file.Name())
66						content, err := os.ReadFile(filePath)
67						if err == nil {
68							contextContent += fmt.Sprintf("\n# From %s\n%s\n", file.Name(), string(content))
69						}
70					}
71				}
72			}
73		} else {
74			// Handle individual file as before
75			filePath := filepath.Join(workDir, path)
76			content, err := os.ReadFile(filePath)
77			if err == nil {
78				contextContent += fmt.Sprintf("\n%s\n", string(content))
79			}
80		}
81	}
82
83	return contextContent
84}