diff --git a/internal/agent/prompt/prompt.go b/internal/agent/prompt/prompt.go index d10fbcae3c3a37f295ec9f9de637cb130d9b6abc..216e7d32c0aebd4415b75885bb5bc523dae499db 100644 --- a/internal/agent/prompt/prompt.go +++ b/internal/agent/prompt/prompt.go @@ -35,6 +35,7 @@ type PromptDat struct { Date string GitStatus string ContextFiles []ContextFile + MemoryFiles []ContextFile } type ContextFile struct { @@ -150,16 +151,27 @@ func (p *Prompt) promptData(ctx context.Context, provider, model string, cfg con workingDir := cmp.Or(p.workingDir, cfg.WorkingDir()) platform := cmp.Or(p.platform, runtime.GOOS) - files := map[string][]ContextFile{} + contextFiles := map[string][]ContextFile{} + memoryFiles := map[string][]ContextFile{} for _, pth := range cfg.Options.ContextPaths { expanded := expandPath(pth, cfg) pathKey := strings.ToLower(expanded) - if _, ok := files[pathKey]; ok { + if _, ok := contextFiles[pathKey]; ok { continue } content := processContextPath(expanded, cfg) - files[pathKey] = content + contextFiles[pathKey] = content + } + + for _, pth := range cfg.Options.MemoryPaths { + expanded := expandPath(pth, cfg) + pathKey := strings.ToLower(expanded) + if _, ok := memoryFiles[pathKey]; ok { + continue + } + content := processContextPath(expanded, cfg) + memoryFiles[pathKey] = content } isGit := isGitRepo(cfg.WorkingDir()) @@ -180,8 +192,11 @@ func (p *Prompt) promptData(ctx context.Context, provider, model string, cfg con } } - for _, contextFiles := range files { - data.ContextFiles = append(data.ContextFiles, contextFiles...) + for _, files := range contextFiles { + data.ContextFiles = append(data.ContextFiles, files...) + } + for _, files := range memoryFiles { + data.MemoryFiles = append(data.MemoryFiles, files...) } return data, nil } diff --git a/internal/agent/templates/coder.md.tpl b/internal/agent/templates/coder.md.tpl index 363b59da2624405684bab9983204b795fb177471..9ec729d168915a3ab7c90ae9fd5e5db20b7b70e8 100644 --- a/internal/agent/templates/coder.md.tpl +++ b/internal/agent/templates/coder.md.tpl @@ -339,10 +339,26 @@ Diagnostics (lint/typecheck) included in tool output. {{if .ContextFiles}} +# Project-Specific Context +Make sure to follow the instructions in the context below. + {{range .ContextFiles}} {{.Content}} {{end}} - + + +{{if .MemoryFiles}} +# User context +The following is personal content added by the user that they'd like you to follow no matter what project you're working in, though project preferences might conflict with their personal preferences. In cases of conflict, prioritise project context over user context. + +{{range .MemoryFiles}} + +{{.Content}} + +{{end}} + +{{end}} + {{end}} diff --git a/internal/config/load.go b/internal/config/load.go index e93ea49bc3a0b54202b2a3aeab03019e47eb935f..f85f5581ae3ec9546d225ff9eda62d293f149f6b 100644 --- a/internal/config/load.go +++ b/internal/config/load.go @@ -321,7 +321,8 @@ func (c *Config) setDefaults(workingDir, dataDir string) { filepath.Join(filepath.Dir(crushConfigDir), "AGENTS.md"), } } - c.Options.ContextPaths = append(c.Options.ContextPaths, c.Options.MemoryPaths...) + slices.Sort(c.Options.MemoryPaths) + c.Options.MemoryPaths = slices.Compact(c.Options.MemoryPaths) if dataDir != "" { c.Options.DataDirectory = dataDir @@ -350,9 +351,6 @@ func (c *Config) setDefaults(workingDir, dataDir string) { // Add the default context paths if they are not already present c.Options.ContextPaths = append(defaultContextPaths, c.Options.ContextPaths...) - - // The ordering of contexts can be important; maybe the user's stuff should - // go at the bottom? Or top? slices.Sort(c.Options.ContextPaths) c.Options.ContextPaths = slices.Compact(c.Options.ContextPaths)