Skip to content

feat(interactions): add AutomaticContinuation to Interactions.Create in the Go SDK - #140

Open
copybara-service[bot] wants to merge 1 commit into
mainfrom
copybara/995657092
Open

copybara-service[bot] wants to merge 1 commit into
mainfrom
copybara/995657092

Conversation

@copybara-service

Copy link
Copy Markdown

feat(interactions): add AutomaticContinuation to Interactions.Create in the Go SDK

Foreground Interactions.Create() calls are capped per request by the server (32k output tokens unary, 64k streaming) and stop with status="requires_continuation" plus a continuation_token. Interactions.Create now enables automatic continuation by default (configurable per call via operations.WithAutomaticContinuation(bool)) and chains continuation hops client-side so a plain Create() returns the full decode.

Request chaining:

  • Each hop after the first sends the continuation_token from the previous hop. With Store enabled (default) it sets PreviousInteractionID to the hop that issued the token and omits Input; with Store=false it resends the original Input.
  • Unary foreground model calls default GenerationConfig.MaxOutputTokens to 65536 (DefaultAutomaticContinuationMaxOutputTokens) when unset without mutating caller structs (streaming uses the server's 64k default). Explicit values are never overridden.
  • Stops on completed, incomplete (token preserved for manual resumption), requires_action, failed, cancelled, a missing token, or a repeated token. Skipped for agent requests and Background=true; Background=true with operations.WithAutomaticContinuation(false) returns ErrAutomaticContinuationWithBackground.

Unary (Stream=false) merging:

  • Hops are merged into one Interaction: Steps concatenated in hop order (leading user_input steps dropped on later hops), Usage counts and per-modality breakdowns summed across hops with Usage.InitialInputTokens taken from hop 1, ID / Status / ContinuationToken / Updated from the final hop, and PreviousInteractionID / Created / Input from hop 1.
  • ContinuationIDs lists every hop id in order, de-duplicated with any server-provided ids. Derived output properties (OutputText, etc.) are recomputed across hop boundaries.

Streaming (Stream=true):

  • Events from all hops are yielded verbatim on stream.EventStream[InteractionSSEEvent]. Consumers should treat interaction.completed with status="requires_continuation" as intermediate.
  • Mid-hop transport drops or premature EOF resume from the latest interaction.status_update checkpoint token when no content was yielded since that checkpoint (up to MaxStreamReconnectsWithoutProgress = 3 reconnects). SSE error events are terminal; HTTP status retries stay with SDK retry options.

Timeouts and errors:

  • The ctx deadline/cancellation passed to Create(ctx, ...) bounds the whole call across hops, while operations.WithOperationTimeout, WithTimeout, and retry configs apply per hop.
  • A failure or ctx expiry after progress returns *apierrors.ContinuationInterruptedError (Unwrap() returning Cause) carrying PartialInteraction, ContinuationToken, InteractionID, and ContinuationIDs so billed work is preserved for manual resumption. First-hop failures return unchanged.

Opt-out:

  • operations.WithAutomaticContinuation(false) returns the single server response untouched (no budget injection, no merging) and logs a one-time warning if it stops at requires_continuation without a caller-supplied continuation_token.

Tests: interactions/continuation_conformance_test.go (52 conformance cases) and interactions/continuation_test.go (ctx deadline/cancellation, per-hop timeout, stream close, non-mutation, and option validation).

@copybara-service
copybara-service Bot requested a review from a team October 28, 2026 05:17
…in the Go SDK

Foreground `Interactions.Create()` calls are capped per request by the server (32k output tokens unary, 64k streaming) and stop with `status="requires_continuation"` plus a `continuation_token`. `Interactions.Create` now enables automatic continuation by default (configurable per call via `operations.WithAutomaticContinuation(bool)`) and chains continuation hops client-side so a plain `Create()` returns the full decode.

Request chaining:
- Each hop after the first sends the `continuation_token` from the previous hop. With `Store` enabled (default) it sets `PreviousInteractionID` to the hop that issued the token and omits `Input`; with `Store=false` it resends the original `Input`.
- Unary foreground model calls default `GenerationConfig.MaxOutputTokens` to 65536 (`DefaultAutomaticContinuationMaxOutputTokens`) when unset without mutating caller structs (streaming uses the server's 64k default). Explicit values are never overridden.
- Stops on `completed`, `incomplete` (token preserved for manual resumption), `requires_action`, `failed`, `cancelled`, a missing token, or a repeated token. Skipped for agent requests and `Background=true`; `Background=true` with `operations.WithAutomaticContinuation(false)` returns `ErrAutomaticContinuationWithBackground`.

Unary (`Stream=false`) merging:
- Hops are merged into one `Interaction`: `Steps` concatenated in hop order (leading `user_input` steps dropped on later hops), `Usage` counts and per-modality breakdowns summed across hops with `Usage.InitialInputTokens` taken from hop 1, `ID` / `Status` / `ContinuationToken` / `Updated` from the final hop, and `PreviousInteractionID` / `Created` / `Input` from hop 1.
- `ContinuationIDs` lists every hop id in order, de-duplicated with any server-provided ids. Derived output properties (`OutputText`, etc.) are recomputed across hop boundaries.

Streaming (`Stream=true`):
- Events from all hops are yielded verbatim on `stream.EventStream[InteractionSSEEvent]`. Consumers should treat `interaction.completed` with `status="requires_continuation"` as intermediate.
- Mid-hop transport drops or premature EOF resume from the latest `interaction.status_update` checkpoint token when no content was yielded since that checkpoint (up to `MaxStreamReconnectsWithoutProgress = 3` reconnects). SSE `error` events are terminal; HTTP status retries stay with SDK retry options.

Timeouts and errors:
- The `ctx` deadline/cancellation passed to `Create(ctx, ...)` bounds the whole call across hops, while `operations.WithOperationTimeout`, `WithTimeout`, and retry configs apply per hop.
- A failure or `ctx` expiry after progress returns `*apierrors.ContinuationInterruptedError` (`Unwrap()` returning `Cause`) carrying `PartialInteraction`, `ContinuationToken`, `InteractionID`, and `ContinuationIDs` so billed work is preserved for manual resumption. First-hop failures return unchanged.

Opt-out:
- `operations.WithAutomaticContinuation(false)` returns the single server response untouched (no budget injection, no merging) and logs a one-time warning if it stops at `requires_continuation` without a caller-supplied `continuation_token`.

Tests: `interactions/continuation_conformance_test.go` (52 conformance cases) and `interactions/continuation_test.go` (ctx deadline/cancellation, per-hop timeout, stream close, non-mutation, and option validation).
PiperOrigin-RevId: 995657092
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant