Block goals after three empty automatic continuation turns (#44320)

## Why

Automatic goal continuations can repeatedly return empty final answers without
making progress. Stop this loop by marking the goal as `blocked` after three
consecutive empty turns with no other activity.

## What changed

- Observe completed turn items through a new `on_item_completed` lifecycle hook.
- Track empty final answers only for automatically admitted goal turns, resetting
  the streak on activity, user turns, or goal changes.
- Preserve normal turn completion and streamed message deltas when blocking a goal.

## Testing

Add accounting coverage for the three-turn threshold and streak resets, plus
app-server tests for empty continuations and recovery through final-answer text,
commentary, or tool activity.

GitOrigin-RevId: 4b9d2cb2e306b0adc316972429cc35000115b88b
This commit is contained in:
Eric Traut authored and copyberry committed 2026-09-09 22:27:37 +00:00
1 parent eb680c0558
commit 0735c51978
8 files changed
+331 -2

No files matched your search

+9
View File
@@ -2521,6 +2521,15 @@ impl Session {
item: TurnItem,
) {
record_turn_ttfm_metric(turn_context, &item).await;
for contributor in self.services.extensions.turn_lifecycle_contributors() {
contributor
.on_item_completed(
&self.services.thread_extension_data,
turn_context.extension_data.as_ref(),
&item,
)
.await;
}
let completed_at_ms = now_unix_timestamp_ms();
let item_id = item.id();
let started_at_ms = turn_context