fix(template): for coder so we handle memory files correctly

kujtimiihoxha created

Change summary

internal/agent/prompt/prompt.go       | 46 +++++++++++++++++-----------
internal/agent/templates/coder.md.tpl |  7 +---
internal/app/app.go                   |  1 
3 files changed, 30 insertions(+), 24 deletions(-)

Detailed changes

internal/agent/prompt/prompt.go 🔗

@@ -23,13 +23,14 @@ type Prompt struct {
 }
 
 type PromptDat struct {
-	Provider   string
-	Model      string
-	Config     config.Config
-	WorkingDir string
-	IsGitRepo  bool
-	Platform   string
-	Date       string
+	Provider     string
+	Model        string
+	Config       config.Config
+	WorkingDir   string
+	IsGitRepo    bool
+	Platform     string
+	Date         string
+	ContextFiles []ContextFile
 }
 
 type ContextFile struct {
@@ -70,7 +71,7 @@ func NewPrompt(name, promptTemplate string, opts ...Option) (*Prompt, error) {
 }
 
 func (p *Prompt) Build(provider, model string, cfg config.Config) (string, error) {
-	t, err := template.New(p.name).Funcs(p.funcMap(cfg)).Parse(p.template)
+	t, err := template.New(p.name).Parse(p.template)
 	if err != nil {
 		return "", fmt.Errorf("parsing template: %w", err)
 	}
@@ -82,15 +83,6 @@ func (p *Prompt) Build(provider, model string, cfg config.Config) (string, error
 	return sb.String(), nil
 }
 
-func (p *Prompt) funcMap(cfg config.Config) template.FuncMap {
-	return template.FuncMap{
-		"contextFiles": func(path string) []ContextFile {
-			path = expandPath(path, cfg)
-			return processContextPath(path, cfg)
-		},
-	}
-}
-
 func processFile(filePath string) *ContextFile {
 	content, err := os.ReadFile(filePath)
 	if err != nil {
@@ -155,7 +147,20 @@ func (p *Prompt) promptData(provider, model string, cfg config.Config) PromptDat
 	if p.platform != "" {
 		platform = p.platform
 	}
-	return PromptDat{
+
+	files := map[string][]ContextFile{}
+
+	for _, pth := range cfg.Options.ContextPaths {
+		expanded := expandPath(pth, cfg)
+		pathKey := strings.ToLower(expanded)
+		if _, ok := files[pathKey]; ok {
+			continue
+		}
+		content := processContextPath(expanded, cfg)
+		files[pathKey] = content
+	}
+
+	data := PromptDat{
 		Provider:   provider,
 		Model:      model,
 		Config:     cfg,
@@ -164,6 +169,11 @@ func (p *Prompt) promptData(provider, model string, cfg config.Config) PromptDat
 		Platform:   platform,
 		Date:       p.now().Format("1/2/2006"),
 	}
+
+	for _, contextFiles := range files {
+		data.ContextFiles = append(data.ContextFiles, contextFiles...)
+	}
+	return data
 }
 
 func isGitRepo(dir string) bool {

internal/agent/templates/coder.md.tpl 🔗

@@ -124,14 +124,11 @@ Tools that support it will also include useful diagnostics such as linting and t
 - Take necessary actions to fix the issues.
 - You should ignore diagnostics of files that you did not change or are not related or caused by your changes unless the user explicitly asks you to fix them.
 </lsp>
-{{end}}{{if gt (len .Config.Options.ContextPaths) 0}}
-<memory>
-{{range  .Config.Options.ContextPaths}}
-{{range  contextFiles .}}
+{{end}}{{if .ContextFiles}}
+<memory>{{range  .ContextFiles}}
 <file path="{{.Path}}">
 {{.Content}}
 </file>
 {{end}}
-{{end}}
 </memory>
 {{end}}

internal/app/app.go 🔗

@@ -33,7 +33,6 @@ type App struct {
 	History     history.Service
 	Permissions permission.Service
 
-	// TODO: (kujtim) remove this when fully implemented
 	AgentCoordinator agent.Coordinator
 
 	LSPClients *csync.Map[string, *lsp.Client]