feat(roadblock): surface reported roadblocks in the review result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -335,15 +335,16 @@ public sealed class TaskRunner
|
||||
// so the sequential chain (which advances on terminal states) is unaffected.
|
||||
// Planning parents (PlanningPhase != None) are containers, not reviewable work.
|
||||
var finishedAt = DateTime.UtcNow;
|
||||
var reviewResult = ComposeReviewResult(result.ResultMarkdown, result.Blocks);
|
||||
if (task.ParentTaskId is null && task.PlanningPhase == PlanningPhase.None)
|
||||
{
|
||||
await _state.SubmitForReviewAsync(task.Id, finishedAt, result.ResultMarkdown, CancellationToken.None);
|
||||
await _state.SubmitForReviewAsync(task.Id, finishedAt, reviewResult, CancellationToken.None);
|
||||
await _broadcaster.WorkerLog($"Finished \"{task.Title}\" (waiting for review)", WorkerLogLevel.Success, DateTime.UtcNow);
|
||||
await _broadcaster.TaskFinished(slot, task.Id, "waiting_for_review", finishedAt);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _state.CompleteAsync(task.Id, finishedAt, result.ResultMarkdown, CancellationToken.None);
|
||||
await _state.CompleteAsync(task.Id, finishedAt, reviewResult, CancellationToken.None);
|
||||
await _broadcaster.WorkerLog($"Finished \"{task.Title}\" (done)", WorkerLogLevel.Success, DateTime.UtcNow);
|
||||
await _broadcaster.TaskFinished(slot, task.Id, "done", finishedAt);
|
||||
}
|
||||
@@ -413,4 +414,12 @@ public sealed class TaskRunner
|
||||
? $"{basePrompt}\n\nCaptured error from the failed run:\n\n{capturedError!.Trim()}"
|
||||
: basePrompt;
|
||||
}
|
||||
|
||||
public static string? ComposeReviewResult(string? result, IReadOnlyList<string> blocks)
|
||||
{
|
||||
if (blocks.Count == 0) return result;
|
||||
var section = "⚠ Roadblocks reported during the run:\n"
|
||||
+ string.Join('\n', blocks.Select(b => $"- {b}"));
|
||||
return string.IsNullOrWhiteSpace(result) ? section : $"{result}\n\n{section}";
|
||||
}
|
||||
}
|
||||
|
||||
30
tests/ClaudeDo.Worker.Tests/Runner/ReviewResultTests.cs
Normal file
30
tests/ClaudeDo.Worker.Tests/Runner/ReviewResultTests.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using ClaudeDo.Worker.Runner;
|
||||
|
||||
namespace ClaudeDo.Worker.Tests.Runner;
|
||||
|
||||
public class ReviewResultTests
|
||||
{
|
||||
[Fact]
|
||||
public void No_blocks_returns_result_unchanged()
|
||||
{
|
||||
Assert.Equal("done", TaskRunner.ComposeReviewResult("done", Array.Empty<string>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Blocks_are_appended_as_a_section()
|
||||
{
|
||||
var outp = TaskRunner.ComposeReviewResult("done", new[] { "no creds", "db down" });
|
||||
Assert.Contains("⚠ Roadblocks", outp);
|
||||
Assert.Contains("- no creds", outp);
|
||||
Assert.Contains("- db down", outp);
|
||||
Assert.Contains("done", outp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Null_result_with_blocks_still_lists_them()
|
||||
{
|
||||
var outp = TaskRunner.ComposeReviewResult(null, new[] { "x" });
|
||||
Assert.Contains("⚠ Roadblocks", outp);
|
||||
Assert.Contains("- x", outp);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user