diff --git a/pkg/agent/context.go b/pkg/agent/context.go index 5a84c45e2..ba4f10568 100644 --- a/pkg/agent/context.go +++ b/pkg/agent/context.go @@ -225,6 +225,7 @@ func (cb *ContextBuilder) sourcePaths() []string { return []string{ filepath.Join(cb.workspace, "AGENTS.md"), filepath.Join(cb.workspace, "SOUL.md"), + filepath.Join(cb.workspace, "TOOLS.md"), filepath.Join(cb.workspace, "USER.md"), filepath.Join(cb.workspace, "IDENTITY.md"), filepath.Join(cb.workspace, "memory", "MEMORY.md"), @@ -435,6 +436,7 @@ func (cb *ContextBuilder) LoadBootstrapFiles() string { bootstrapFiles := []string{ "AGENTS.md", "SOUL.md", + "TOOLS.md", "USER.md", "IDENTITY.md", } diff --git a/pkg/agent/context_cache_test.go b/pkg/agent/context_cache_test.go index 707510820..c4f67f759 100644 --- a/pkg/agent/context_cache_test.go +++ b/pkg/agent/context_cache_test.go @@ -126,6 +126,23 @@ func TestSingleSystemMessage(t *testing.T) { } } +func TestBuildSystemPrompt_IncludesToolsBootstrapFile(t *testing.T) { + tmpDir := setupWorkspace(t, map[string]string{ + "TOOLS.md": "# Tools\nUse the local helper first.", + }) + defer os.RemoveAll(tmpDir) + + cb := NewContextBuilder(tmpDir) + prompt := cb.BuildSystemPromptWithCache() + + if !strings.Contains(prompt, "## TOOLS.md") { + t.Fatal("expected TOOLS.md heading in system prompt") + } + if !strings.Contains(prompt, "Use the local helper first.") { + t.Fatal("expected TOOLS.md content in system prompt") + } +} + // TestMtimeAutoInvalidation verifies that the cache detects source file changes // via mtime without requiring explicit InvalidateCache(). // Fix: original implementation had no auto-invalidation — edits to bootstrap files, @@ -152,6 +169,13 @@ func TestMtimeAutoInvalidation(t *testing.T) { contentV2: "# Memory\nUser likes Rust.", checkField: "User likes Rust", }, + { + name: "tools bootstrap change", + file: "TOOLS.md", + contentV1: "# Tools\nUse tool A.", + contentV2: "# Tools\nUse tool B.", + checkField: "Use tool B", + }, } for _, tt := range tests {