183 lines
5.8 KiB
Go
183 lines
5.8 KiB
Go
package agent
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"ollie/toolsrv"
|
|
)
|
|
|
|
func TestBuildPreamble(t *testing.T) {
|
|
toolInfos := []toolsrv.ToolInfo{
|
|
{
|
|
Name: "file_read",
|
|
Description: "Read a file with line numbers",
|
|
Prompt: "**file_read**\n\nRead a file with line numbers...",
|
|
InputSchema: []byte(`{"type":"object"}`),
|
|
Server: "",
|
|
},
|
|
{
|
|
Name: "file_write",
|
|
Description: "Create or overwrite a file",
|
|
Prompt: "**file_write**\n\nCreate or overwrite a file...",
|
|
InputSchema: []byte(`{"type":"object"}`),
|
|
Server: "remote",
|
|
},
|
|
{
|
|
Name: "shell",
|
|
Description: "Execute shell command",
|
|
Prompt: "",
|
|
InputSchema: []byte(`{}`),
|
|
Server: "",
|
|
},
|
|
}
|
|
|
|
systemPrompt := "# Core System Prompt\nTest"
|
|
envBlock := "# Environment\n- Test env"
|
|
agentPrompt := "# Agent Prompt\nTest instructions"
|
|
|
|
preamble := BuildPreamble(systemPrompt, envBlock, agentPrompt, toolInfos)
|
|
|
|
// Must contain all sections in order
|
|
expectedSections := []string{
|
|
"# Core System Prompt\nTest\n",
|
|
"# Environment\n- Test env\n",
|
|
"# Agent Prompt\nTest instructions\n",
|
|
"# Tool Sections\n",
|
|
"# Available Tools\n",
|
|
"- **file_read** — Read a file with line numbers\n",
|
|
"# Tool Documentation\n",
|
|
"**file_read**\n\nRead a file with line numbers...\n\n**Schema**:\n```json\n{\"type\":\"object\"}\n```\n\n",
|
|
"## Tool discovery\n",
|
|
}
|
|
|
|
for _, section := range expectedSections {
|
|
if !strings.Contains(preamble, section) {
|
|
t.Errorf("BuildPreamble missing section: %q", section)
|
|
}
|
|
}
|
|
|
|
// Should NOT contain remote server tools
|
|
if strings.Contains(preamble, "file_write") {
|
|
t.Error("BuildPreamble should exclude tools with Server != \"\"")
|
|
}
|
|
|
|
// Should NOT contain tools without prompts in docs section
|
|
if strings.Contains(preamble, "**shell**\n\n") {
|
|
t.Error("BuildPreamble should exclude tools without prompts from docs section")
|
|
}
|
|
|
|
// Verify single instances of key headers
|
|
if strings.Count(preamble, "# Available Tools") != 1 {
|
|
t.Errorf("BuildPreamble should have exactly one '# Available Tools' section, got %d",
|
|
strings.Count(preamble, "# Available Tools"))
|
|
}
|
|
if strings.Count(preamble, "# Tool Documentation") != 1 {
|
|
t.Errorf("BuildPreamble should have exactly one '# Tool Documentation' section, got %d",
|
|
strings.Count(preamble, "# Tool Documentation"))
|
|
}
|
|
|
|
// Verify tool listing includes all non-server tools with descriptions
|
|
if !strings.Contains(preamble, "**file_read** — Read a file with line numbers") {
|
|
t.Error("BuildPreamble should include file_read in tool listing")
|
|
}
|
|
if !strings.Contains(preamble, "**shell** — Execute shell command") {
|
|
t.Error("BuildPreamble should include shell in tool listing (has description)")
|
|
}
|
|
}
|
|
|
|
func TestBuildPreambleEmptyTools(t *testing.T) {
|
|
systemPrompt := "# Core System Prompt\nTest"
|
|
envBlock := "# Environment\n- Test env"
|
|
agentPrompt := "# Agent Prompt\nTest instructions"
|
|
|
|
preamble := BuildPreamble(systemPrompt, envBlock, agentPrompt, nil)
|
|
|
|
// Should not contain tool sections when no tools
|
|
if strings.Contains(preamble, "# Tool Sections") {
|
|
t.Error("BuildPreamble should not include tool sections when no tools")
|
|
}
|
|
if strings.Contains(preamble, "# Available Tools") {
|
|
t.Error("BuildPreamble should not include Available Tools when no tools")
|
|
}
|
|
if strings.Contains(preamble, "# Tool Documentation") {
|
|
t.Error("BuildPreamble should not include Tool Documentation when no tools")
|
|
}
|
|
|
|
// Should still contain core sections
|
|
expectedSections := []string{
|
|
"# Core System Prompt\nTest\n",
|
|
"# Environment\n- Test env\n",
|
|
"# Agent Prompt\nTest instructions\n",
|
|
"## Tool discovery\n",
|
|
}
|
|
|
|
for _, section := range expectedSections {
|
|
if !strings.Contains(preamble, section) {
|
|
t.Errorf("BuildPreamble missing core section: %q", section)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBuildPreambleOnlyListingNoDocs(t *testing.T) {
|
|
toolInfos := []toolsrv.ToolInfo{
|
|
{
|
|
Name: "test_tool",
|
|
Description: "Test description",
|
|
Prompt: "", // No prompt means no docs
|
|
InputSchema: []byte(`{}`),
|
|
Server: "",
|
|
},
|
|
}
|
|
|
|
systemPrompt := "# Core System Prompt\nTest"
|
|
envBlock := "# Environment\n- Test env"
|
|
agentPrompt := "# Agent Prompt\nTest instructions"
|
|
|
|
preamble := BuildPreamble(systemPrompt, envBlock, agentPrompt, toolInfos)
|
|
|
|
// Should have tool sections with listing but no docs
|
|
if !strings.Contains(preamble, "# Tool Sections") {
|
|
t.Error("BuildPreamble should include # Tool Sections")
|
|
}
|
|
if !strings.Contains(preamble, "# Available Tools") {
|
|
t.Error("BuildPreamble should include # Available Tools")
|
|
}
|
|
if !strings.Contains(preamble, "**test_tool** — Test description") {
|
|
t.Error("BuildPreamble should include tool in listing")
|
|
}
|
|
if strings.Contains(preamble, "# Tool Documentation") {
|
|
t.Error("BuildPreamble should NOT include # Tool Documentation when no tool has prompt")
|
|
}
|
|
}
|
|
|
|
func TestBuildPreambleOnlyDocsNoListing(t *testing.T) {
|
|
toolInfos := []toolsrv.ToolInfo{
|
|
{
|
|
Name: "test_tool",
|
|
Description: "", // No description means not in listing
|
|
Prompt: "**test_tool**\n\nTest docs...",
|
|
InputSchema: []byte(`{}`),
|
|
Server: "",
|
|
},
|
|
}
|
|
|
|
systemPrompt := "# Core System Prompt\nTest"
|
|
envBlock := "# Environment\n- Test env"
|
|
agentPrompt := "# Agent Prompt\nTest instructions"
|
|
|
|
preamble := BuildPreamble(systemPrompt, envBlock, agentPrompt, toolInfos)
|
|
|
|
// Should have tool sections with docs but no listing
|
|
if !strings.Contains(preamble, "# Tool Sections") {
|
|
t.Error("BuildPreamble should include # Tool Sections")
|
|
}
|
|
if strings.Contains(preamble, "# Available Tools") {
|
|
t.Error("BuildPreamble should NOT include # Available Tools when no tool has description")
|
|
}
|
|
if !strings.Contains(preamble, "# Tool Documentation") {
|
|
t.Error("BuildPreamble should include # Tool Documentation")
|
|
}
|
|
if !strings.Contains(preamble, "**test_tool**") {
|
|
t.Error("BuildPreamble should include tool in docs")
|
|
}
|
|
} |