diff --git a/pkg/agent/context.go b/pkg/agent/context.go index 592990607..dd6b38e74 100644 --- a/pkg/agent/context.go +++ b/pkg/agent/context.go @@ -123,7 +123,11 @@ Your workspace is at: %s 3. **Memory** - Use the memory tool to store important facts, preferences, and decisions. -4. **Context Management** - You MUST consolidate your context to stay effective during long tasks. Use start_focus at the beginning of any investigation or multi-step task. After 10-15 tool calls, call complete_focus with a summary of what you learned and accomplished. This compresses your working context and persists knowledge for future reference. Failing to consolidate will degrade your performance as context grows.`, +4. **No fabricated data** - If access is denied, a tool fails, or a request is outside workspace/sandbox, explicitly say so. Do NOT invent file contents, command output, credentials, or sample sensitive data. + +5. **Completion discipline** - For actionable requests, execute the required tools before your final answer. Do NOT end with only intent statements like "I'll do that" or "let me do that." + +6. **Context Management** - You MUST consolidate your context to stay effective during long tasks. Use start_focus at the beginning of any investigation or multi-step task. After 10-15 tool calls, call complete_focus with a summary of what you learned and accomplished. This compresses your working context and persists knowledge for future reference. Failing to consolidate will degrade your performance as context grows.`, now, runtime, workspacePath, workspacePath, toolsSection) } diff --git a/pkg/agent/loop_test.go b/pkg/agent/loop_test.go index c22a12338..93a2b4074 100644 --- a/pkg/agent/loop_test.go +++ b/pkg/agent/loop_test.go @@ -541,3 +541,75 @@ func TestToolResult_UserFacingToolDoesSendMessage(t *testing.T) { t.Errorf("Expected 'Command output: hello world', got: %s", response) } } + +func TestResolveFinalContent_RecoversFromPriorStepText(t *testing.T) { + al := &AgentLoop{} + steps := []fantasy.StepResult{ + { + Response: fantasy.Response{ + Content: fantasy.ResponseContent{ + fantasy.TextContent{Text: "Recovered final response"}, + }, + }, + }, + { + Response: fantasy.Response{ + Content: fantasy.ResponseContent{ + fantasy.ToolCallContent{ToolName: "read_file"}, + }, + }, + }, + } + + got, err := al.resolveFinalContent("", steps) + if err != nil { + t.Fatalf("resolveFinalContent returned error: %v", err) + } + if got != "Recovered final response" { + t.Fatalf("expected recovered text, got %q", got) + } +} + +func TestResolveFinalContent_ErrorsWhenNoTextExists(t *testing.T) { + al := &AgentLoop{} + steps := []fantasy.StepResult{ + { + Response: fantasy.Response{ + Content: fantasy.ResponseContent{ + fantasy.ToolCallContent{ToolName: "write_file"}, + }, + }, + }, + } + + _, err := al.resolveFinalContent("", steps) + if err == nil { + t.Fatal("expected error when no final text exists") + } +} + +func TestResolveFinalContent_RecoversFromToolResultText(t *testing.T) { + al := &AgentLoop{} + steps := []fantasy.StepResult{ + { + Response: fantasy.Response{ + Content: fantasy.ResponseContent{ + fantasy.ToolResultContent{ + ToolName: "exec", + Result: fantasy.ToolResultOutputContentText{ + Text: "progressive-test-marker", + }, + }, + }, + }, + }, + } + + got, err := al.resolveFinalContent("", steps) + if err != nil { + t.Fatalf("resolveFinalContent returned error: %v", err) + } + if got != "progressive-test-marker" { + t.Fatalf("expected tool result text, got %q", got) + } +}