package prompt import ( "fmt" "os" "path/filepath" "strings" "sync" "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/llm/models" ) func GetAgentPrompt(agentName config.AgentName, provider models.ModelProvider) string { basePrompt := "" switch agentName { case config.AgentCoder: basePrompt = CoderPrompt(provider) case config.AgentTitle: basePrompt = TitlePrompt(provider) case config.AgentTask: basePrompt = TaskPrompt(provider) default: basePrompt = "You are a helpful assistant" } if agentName == config.AgentCoder || agentName == config.AgentTask { // Add context from project-specific instruction files if they exist contextContent := getContextFromPaths() if contextContent != "" { return fmt.Sprintf("%s\n\n# Project-Specific Context\n Make sure to follow the instructions in the context below\n%s", basePrompt, contextContent) } } return basePrompt } var ( onceContext sync.Once contextContent string ) func getContextFromPaths() string { onceContext.Do(func() { var ( cfg = config.Get() workDir = cfg.WorkingDir contextPaths = cfg.ContextPaths ) contextContent = processContextPaths(workDir, contextPaths) }) return contextContent } func processContextPaths(workDir string, paths []string) string { var ( wg sync.WaitGroup resultCh = make(chan string) ) for _, path := range paths { wg.Add(1) go func(p string) { defer wg.Done() if strings.HasSuffix(p, "/") { filepath.WalkDir(filepath.Join(workDir, p), func(path string, d os.DirEntry, err error) error { if err != nil { return err } if !d.IsDir() { if result := processFile(path); result != "" { resultCh <- result } } return nil }) } else { result := processFile(filepath.Join(workDir, p)) if result != "" { resultCh <- result } } }(path) } go func() { wg.Wait() close(resultCh) }() results := make([]string, 0) for result := range resultCh { results = append(results, result) } return strings.Join(results, "\n") } func processFile(filePath string) string { content, err := os.ReadFile(filePath) if err != nil { return "" } return "# From:" + filePath + "\n" + string(content) }