summaryrefslogtreecommitdiff
path: root/internal/executor
diff options
context:
space:
mode:
Diffstat (limited to 'internal/executor')
-rw-r--r--internal/executor/executor.go27
-rw-r--r--internal/executor/summary.go1
2 files changed, 20 insertions, 8 deletions
diff --git a/internal/executor/executor.go b/internal/executor/executor.go
index 8614481..2f01b93 100644
--- a/internal/executor/executor.go
+++ b/internal/executor/executor.go
@@ -505,7 +505,7 @@ func (p *Pool) handleRunResult(ctx context.Context, t *task.Task, exec *storage.
if err := p.store.UpdateTaskState(t.ID, task.StateReady); err != nil {
p.logger.Error("failed to update task state", "taskID", t.ID, "state", task.StateReady, "error", err)
}
- go p.spawnCheckerTask(context.Background(), t)
+ go p.spawnCheckerTask(context.Background(), t, exec)
}
} else {
exec.Status = "COMPLETED"
@@ -629,7 +629,7 @@ func (p *Pool) ShipStory(ctx context.Context, storyID string) error {
// spawnCheckerTask creates and submits a checker task for the given completed task.
// Guards: not called for subtasks, checker tasks, tasks without a repository URL,
// or tasks that already have a checker.
-func (p *Pool) spawnCheckerTask(ctx context.Context, checked *task.Task) {
+func (p *Pool) spawnCheckerTask(ctx context.Context, checked *task.Task, exec *storage.Execution) {
// Never spawn a checker for subtasks, checker tasks, or tasks without a repository.
if checked.ParentTaskID != "" || checked.CheckerForTaskID != "" || checked.RepositoryURL == "" {
return
@@ -649,6 +649,15 @@ func (p *Pool) spawnCheckerTask(ctx context.Context, checked *task.Task) {
criteria = checked.Agent.Instructions
}
+ // Embed the execution log so the checker can verify output without needing
+ // Docker, API access, or repository cloning.
+ logSnippet := ""
+ if exec != nil && exec.StdoutPath != "" {
+ logSnippet = "\n\nExecution log (last 200 lines):\n<execution_log>\n" +
+ tailFile(exec.StdoutPath, 200) +
+ "\n</execution_log>"
+ }
+
instructions := fmt.Sprintf(`You are validating a completed task. Do not make any changes to the code or repository.
Task: %s
@@ -656,15 +665,17 @@ Instructions given to the implementor:
%s
Acceptance criteria:
-%s
+%s%s
Steps:
-1. Clone the repository and review the changes made.
-2. Verify each acceptance criterion is met. Run tests or make HTTP requests as needed.
-3. If all criteria are satisfied, exit normally (success).
-4. If any criterion is not met, use the Bash tool to exit with a non-zero code:
+1. Review the execution log above to determine what the agent did.
+2. If the task involved code changes, use Read/Grep/Glob to inspect the repository at %s.
+3. Verify each acceptance criterion is met. Run tests or make HTTP requests as needed.
+4. If all criteria are satisfied, exit normally (success).
+5. If any criterion is not met, use the Bash tool to exit with a non-zero code:
bash -c "exit 1"
- Before exiting, write a brief summary of what failed.`, checked.Name, checked.Agent.Instructions, criteria)
+ Before exiting, write a brief summary of what failed.`,
+ checked.Name, checked.Agent.Instructions, criteria, logSnippet, checked.RepositoryURL)
now := time.Now().UTC()
checker := &task.Task{
diff --git a/internal/executor/summary.go b/internal/executor/summary.go
index bcf5cfd..e5a1772 100644
--- a/internal/executor/summary.go
+++ b/internal/executor/summary.go
@@ -12,6 +12,7 @@ import (
"github.com/thepeterstone/claudomator/internal/llm"
)
+
// synthesizeSummaryMaxBytes caps how much of the stdout log we send to the
// LLM. Larger values cost more tokens with diminishing returns for a 2-4
// sentence summary.