Allow sampling in-progress turns with thread/sample (#60620)

## Why

`thread/sample` previously required the source's latest turn to finish before it could be sampled.

## What changed

Add `allowInProgressTurn`, defaulting to `false`, to sample a snapshot of the latest turn while the source continues running. The requested turn must still be the latest, but source history changes during sampling no longer invalidate the result when this option is enabled.

For an in-progress snapshot, include a context note explaining that the source was not stopped and pending tool calls may appear as `aborted` in the copy. Suppress the copy's default interruption message.

## Testing

Add coverage for sampling running turns in legacy and paginated history modes, including pending tool calls and mid-turn compaction. Verify that the source continues independently and that finished-turn samples retain their existing context.

GitOrigin-RevId: 771b979bf677e4ff0686476bfaf21aff92f7e7ac
This commit is contained in:
Keyan Zhang
2026-11-10 16:31:52 +00:00
committed by copyberry
parent 0d37c062de
commit c37fd5665f
5 changed files with 459 additions and 32 deletions
@@ -14,9 +14,11 @@ use std::collections::HashMap;
#[ts(export_to = "v2/")]
pub struct ThreadSampleParams {
pub thread_id: String,
/// The loaded source's latest completed, failed, or interrupted turn.
/// Stale or active sources are rejected.
/// The loaded source's latest turn, which must be finished (completed, failed, or interrupted) unless `allowInProgressTurn` is true.
pub expected_turn_id: String,
/// Allow sampling the latest turn before it finishes.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub allow_in_progress_turn: bool,
pub prompt: String,
/// Applied only when the provider and model support cache-preserving reasoning-effort updates.
#[ts(optional = nullable)]