Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions internal/runtime/turn_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,25 @@ func collectCompletionState(

// applyToolExecutionCompletion 更新一轮工具执行后的 completion 事实。
func applyToolExecutionCompletion(current controlplane.CompletionState, summary toolExecutionSummary) controlplane.CompletionState {
if summary.HasSuccessfulWorkspaceWrite {
current.HasUnverifiedWrites = true
if len(summary.Results) == 0 {
if summary.HasSuccessfulWorkspaceWrite {
current.HasUnverifiedWrites = true
}
if summary.HasSuccessfulVerification {
current.HasUnverifiedWrites = false
}
return current
}
if summary.HasSuccessfulVerification {
current.HasUnverifiedWrites = false
for _, result := range summary.Results {
if result.IsError {
continue
}
if result.Facts.WorkspaceWrite {
current.HasUnverifiedWrites = true
}
if result.Facts.VerificationPerformed && result.Facts.VerificationPassed {
current.HasUnverifiedWrites = false
}
}
return current
}
Expand Down
36 changes: 34 additions & 2 deletions internal/runtime/turn_control_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,52 @@ func TestApplyToolExecutionCompletionTracksWriteAndVerification(t *testing.T) {
t.Parallel()

written := applyToolExecutionCompletion(controlplane.CompletionState{}, toolExecutionSummary{
HasSuccessfulWorkspaceWrite: true,
Results: []tools.ToolResult{
{Facts: tools.ToolExecutionFacts{WorkspaceWrite: true}},
},
})
if !written.HasUnverifiedWrites {
t.Fatalf("expected successful write to require verification, got %+v", written)
}

verified := applyToolExecutionCompletion(written, toolExecutionSummary{
HasSuccessfulVerification: true,
Results: []tools.ToolResult{
{Facts: tools.ToolExecutionFacts{VerificationPerformed: true, VerificationPassed: true}},
},
})
if verified.HasUnverifiedWrites {
t.Fatalf("expected explicit verification to clear pending write, got %+v", verified)
}
}

func TestApplyToolExecutionCompletionKeepsUnverifiedWhenVerifyBeforeWrite(t *testing.T) {
t.Parallel()

got := applyToolExecutionCompletion(controlplane.CompletionState{}, toolExecutionSummary{
Results: []tools.ToolResult{
{Facts: tools.ToolExecutionFacts{VerificationPerformed: true, VerificationPassed: true}},
{Facts: tools.ToolExecutionFacts{WorkspaceWrite: true}},
},
})
if !got.HasUnverifiedWrites {
t.Fatalf("expected write after verify to remain unverified, got %+v", got)
}
}

func TestApplyToolExecutionCompletionClearsWhenVerifyAfterWrite(t *testing.T) {
t.Parallel()

got := applyToolExecutionCompletion(controlplane.CompletionState{}, toolExecutionSummary{
Results: []tools.ToolResult{
{Facts: tools.ToolExecutionFacts{WorkspaceWrite: true}},
{Facts: tools.ToolExecutionFacts{VerificationPerformed: true, VerificationPassed: true}},
},
})
if got.HasUnverifiedWrites {
t.Fatalf("expected verify after write to clear unverified flag, got %+v", got)
}
}

func TestHasPendingAgentTodosBlocksOnAnyNonTerminalTodo(t *testing.T) {
t.Parallel()

Expand Down
Loading