diff --git a/pkg/agentic/prep.go b/pkg/agentic/prep.go index 1cd2073..0e28c36 100644 --- a/pkg/agentic/prep.go +++ b/pkg/agentic/prep.go @@ -620,11 +620,21 @@ func (s *PrepSubsystem) PrepareWorkspace(ctx context.Context, input PrepInput) ( return s.prepWorkspace(ctx, nil, input) } +// _, out, err := prep.TestPrepWorkspace(ctx, input) +func (s *PrepSubsystem) TestPrepWorkspace(ctx context.Context, input PrepInput) (*mcp.CallToolResult, PrepOutput, error) { + return s.prepWorkspace(ctx, nil, input) +} + // prompt, memories, consumers := prep.BuildPrompt(ctx, input, "dev", repoPath) func (s *PrepSubsystem) BuildPrompt(ctx context.Context, input PrepInput, branch, repoPath string) (string, int, int) { return s.buildPrompt(ctx, input, branch, repoPath) } +// prompt, memories, consumers := prep.TestBuildPrompt(ctx, input, "dev", repoPath) +func (s *PrepSubsystem) TestBuildPrompt(ctx context.Context, input PrepInput, branch, repoPath string) (string, int, int) { + return s.buildPrompt(ctx, input, branch, repoPath) +} + // prompt, memories, consumers := prep.buildPrompt(ctx, input, "dev", "/srv/repos/go-io") func (s *PrepSubsystem) buildPrompt(ctx context.Context, input PrepInput, branch, repoPath string) (string, int, int) { b := core.NewBuilder() diff --git a/pkg/agentic/prep_extra_test.go b/pkg/agentic/prep_extra_test.go index 0e5d7df..53566e4 100644 --- a/pkg/agentic/prep_extra_test.go +++ b/pkg/agentic/prep_extra_test.go @@ -360,6 +360,31 @@ func TestPrep_BuildPrompt_Good_BasicFields(t *testing.T) { assert.Equal(t, 0, consumers) } +func TestPrep_TestBuildPrompt_Good_BasicFields(t *testing.T) { + dir := t.TempDir() + fs.Write(core.JoinPath(dir, "go.mod"), "module test\n\ngo 1.22\n") + + s := &PrepSubsystem{ + ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{}), + codePath: t.TempDir(), + backoff: make(map[string]time.Time), + failCount: make(map[string]int), + } + + prompt, memories, consumers := s.TestBuildPrompt(context.Background(), PrepInput{ + Task: "Fix the tests", + Org: "core", + Repo: "go-io", + }, "dev", dir) + + assert.Contains(t, prompt, "TASK: Fix the tests") + assert.Contains(t, prompt, "REPO: core/go-io on branch dev") + assert.Contains(t, prompt, "LANGUAGE: go") + assert.Contains(t, prompt, "CONSTRAINTS:") + assert.Equal(t, 0, memories) + assert.Equal(t, 0, consumers) +} + func TestPrep_BuildPrompt_Good_WithIssue(t *testing.T) { dir := t.TempDir() @@ -391,6 +416,40 @@ func TestPrep_BuildPrompt_Good_WithIssue(t *testing.T) { assert.Contains(t, prompt, "Steps to reproduce") } +func TestPrep_TestBuildPrompt_Bad_EmptyRepoPath(t *testing.T) { + s := &PrepSubsystem{ + ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{}), + codePath: t.TempDir(), + backoff: make(map[string]time.Time), + failCount: make(map[string]int), + } + + prompt, memories, consumers := s.TestBuildPrompt(context.Background(), PrepInput{ + Task: "Add unit tests", + Org: "core", + Repo: "go-io", + }, "dev", "") + + assert.Contains(t, prompt, "TASK: Add unit tests") + assert.Equal(t, 0, memories) + assert.Equal(t, 0, consumers) +} + +func TestPrep_TestBuildPrompt_Ugly_StillBuildsPrompt(t *testing.T) { + s := &PrepSubsystem{ + ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{}), + codePath: t.TempDir(), + backoff: make(map[string]time.Time), + failCount: make(map[string]int), + } + + prompt, memories, consumers := s.TestBuildPrompt(context.Background(), PrepInput{}, "", "") + + assert.Contains(t, prompt, "TASK:") + assert.Equal(t, 0, memories) + assert.Equal(t, 0, consumers) +} + // --- buildPrompt (naming convention tests) --- func TestPrep_BuildPromptNaming_Good(t *testing.T) { diff --git a/pkg/agentic/prep_test.go b/pkg/agentic/prep_test.go index 7abecb2..ce8b4d2 100644 --- a/pkg/agentic/prep_test.go +++ b/pkg/agentic/prep_test.go @@ -988,3 +988,71 @@ func TestPrep_PrepWorkspace_Good(t *testing.T) { assert.NotEmpty(t, out.Branch) assert.Contains(t, out.Branch, "agent/") } + +func TestPrep_TestPrepWorkspace_Good(t *testing.T) { + root := t.TempDir() + t.Setenv("CORE_WORKSPACE", root) + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(core.JSONMarshalString(map[string]any{ + "number": 1, + "title": "Fix tests", + "body": "Tests are broken", + }))) + })) + t.Cleanup(srv.Close) + + srcRepo := core.JoinPath(root, "src", "core", "test-repo") + gitEnv := []string{"GIT_AUTHOR_NAME=Test", "GIT_AUTHOR_EMAIL=test@test.com", "GIT_COMMITTER_NAME=Test", "GIT_COMMITTER_EMAIL=test@test.com"} + run := func(dir string, args ...string) { + t.Helper() + r := testCore.Process().RunWithEnv(context.Background(), dir, gitEnv, args[0], args[1:]...) + require.True(t, r.OK, "cmd %v failed: %s", args, r.Value) + } + require.True(t, fs.EnsureDir(srcRepo).OK) + run(srcRepo, "git", "init", "-b", "main") + run(srcRepo, "git", "config", "user.name", "Test") + run(srcRepo, "git", "config", "user.email", "test@test.com") + require.True(t, fs.Write(core.JoinPath(srcRepo, "README.md"), "# Test").OK) + run(srcRepo, "git", "add", "README.md") + run(srcRepo, "git", "commit", "-m", "initial commit") + + s := &PrepSubsystem{ + ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{}), + forge: forge.NewForge(srv.URL, "test-token"), + codePath: core.JoinPath(root, "src"), + backoff: make(map[string]time.Time), + failCount: make(map[string]int), + } + + _, out, err := s.TestPrepWorkspace(context.Background(), PrepInput{ + Repo: "test-repo", + Issue: 1, + Task: "Fix tests", + }) + require.NoError(t, err) + assert.True(t, out.Success) + assert.NotEmpty(t, out.WorkspaceDir) +} + +func TestPrep_TestPrepWorkspace_Bad(t *testing.T) { + s := &PrepSubsystem{ + ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{}), + backoff: make(map[string]time.Time), + failCount: make(map[string]int), + } + + _, _, err := s.TestPrepWorkspace(context.Background(), PrepInput{Repo: "."}) + require.Error(t, err) +} + +func TestPrep_TestPrepWorkspace_Ugly(t *testing.T) { + s := &PrepSubsystem{ + ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{}), + backoff: make(map[string]time.Time), + failCount: make(map[string]int), + } + + _, _, err := s.TestPrepWorkspace(context.Background(), PrepInput{Repo: ".."}) + require.Error(t, err) +}