Skip to content

Stream Google Interactions over POST and surface reasoning, tool calls and sources - #717

Merged
kblok merged 2 commits into
mainfrom
google-interactions-post-stream
Oct 22, 2026
Merged

kblok merged 2 commits into
mainfrom
google-interactions-post-stream

Conversation

@kblok

@kblok kblok commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

GoogleInteractionsModel.DoStreamAsync used to wait for the whole response and emit it as one text delta. It now posts with stream: true and pipes the event stream, like upstream. The stream transform also surfaces reasoning (with its signature), client function calls, built-in tool calls and results, sources, and google.processing_* custom parts. Sources come from text_annotation deltas and built-in tool results, and each URL or file appears once. The service tier falls back to the x-gemini-service-tier header when interaction.completed has none.

No new public types.

.NET-only symbols, all internal or private:

  • GoogleInteractionsSources is a container for upstream's three exported functions annotationToSource, annotationsToSources and builtinToolResultToSources (extract-google-interactions-sources.ts). C# has no free functions, so they need a static class. Its Key method is upstream's local sourceKey in build-google-interactions-stream-transform.ts, moved here so the transform and the extractor share one rule.
  • GoogleInteractionsStreamTransform.NonEmpty and Strip replace the JS || fallback and String.replace(/_call$/, '') in the same transform.
  • Test support: a ResponseHeaders property on the test SequencedHandler and a stream snapshot helper.

Part of #692.

Not ported

  • buildGoogleInteractionsStreamTransform — video deltas: FileStreamPart carries bytes only, so a uri output cannot be streamed. Needs a design call.
  • buildGoogleInteractionsStreamTransform — usage modality: outputTokensByModality is not ported.
  • GoogleInteractionsLanguageModel.doStream > service tier::sends service_tier in the request body when providerOptions.google.serviceTier is set: the request does not send service_tier yet.
  • GoogleInteractionsLanguageModel.doStream::serializes video response format controls and streams inline video data
  • GoogleInteractionsLanguageModel.doStream > stateful chaining (multi-turn fixtures)
  • GoogleInteractionsLanguageModel.doStream > stateless multi-turn (store: false, no previousInteractionId)
  • GoogleInteractionsLanguageModel.doStream > image output
  • GoogleInteractionsLanguageModel.doStream > agent factory branch
  • GoogleInteractionsLanguageModel agent polling: the two file-part tests.

The doStream tool tests pass tools upstream; the port does not send Interactions tools yet, and the stream output does not depend on them.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TQmtUKfZTs497KkiGSfYk9

Summary by CodeRabbit

  • New Features

    • Google Interactions streaming now supports real-time foreground and background responses.
    • Streams reasoning, text, function calls, built-in tool activity, custom processing steps, annotations, sources, file outputs, and response metadata.
    • Supports cancellation, reconnection, terminal replay, and retry limits.
    • Google Search, Maps, URL context, and File Search results are surfaced as deduplicated sources.
    • Service-tier metadata is reported from response data or fallback headers.
  • Documentation

    • Expanded Google Interactions streaming documentation, including supported events and streaming behaviors.

kblok and others added 2 commits October 21, 2026 17:54
…s and sources

Non-background doStream waited for the whole response and emitted it as one text
delta. It now posts with stream: true and pipes the event stream, like upstream.
The transform also emits reasoning, function calls, built-in tool calls and
results, sources, and processing steps as custom parts, and falls back to the
x-gemini-service-tier header for the service tier.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQmtUKfZTs497KkiGSfYk9
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQmtUKfZTs497KkiGSfYk9
@kblok kblok added the ready-to-tag Ready to tag a release label Oct 21, 2026
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: hardkoded/vercel-ai-sdk-dotnet/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d29113b0-6fc3-46b0-a38c-8bff3a52dcd5
📥 Commits

Reviewing files that changed from the base of the PR and between 8378b04 and 8a4d63a.

📒 Files selected for processing: 21
  • docs/articles/providers.md
  • src/Vercel.AI/Google/GoogleInteractions.cs
  • src/Vercel.AI/Google/GoogleInteractionsSources.cs
  • src/Vercel.AI/Google/GoogleInteractionsStreaming.cs
  • tests/Vercel.AI.Tests/Fixtures/google-interactions-basic.chunks.txt
  • tests/Vercel.AI.Tests/Fixtures/google-interactions-google-search.chunks.txt
  • tests/Vercel.AI.Tests/Fixtures/google-interactions-tool-call-step1.chunks.txt
  • tests/Vercel.AI.Tests/Fixtures/google-interactions-tool-call-step2.chunks.txt
  • tests/Vercel.AI.Tests/Upstream/Google/BuildGoogleInteractionsStreamTransform/AgenticVideoTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/BuildGoogleInteractionsStreamTransform/ErrorsTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/BuildGoogleInteractionsStreamTransform/ToolCallIdsTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/ExtractGoogleInteractionsSources/AnnotationToSourceTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/ExtractGoogleInteractionsSources/AnnotationsToSourcesTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/ExtractGoogleInteractionsSources/BuiltinToolResultToSourcesTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/ExtractGoogleInteractionsSources/ExtractGoogleInteractionsSourcesSupport.cs
  • tests/Vercel.AI.Tests/Upstream/Google/GoogleInteractionsLanguageModel/DoStreamBasicTextTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/GoogleInteractionsLanguageModel/DoStreamBuiltInGoogleSearchToolTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/GoogleInteractionsLanguageModel/DoStreamServiceTierTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/GoogleInteractionsLanguageModel/DoStreamToolCallingTests.cs
  • tests/Vercel.AI.Tests/Upstream/Google/GoogleInteractionsStreamSupport.cs
  • tests/Vercel.AI.Tests/Upstream/Google/GoogleUpstreamSupport.cs
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

📝 Walkthrough

Google Interactions foreground streaming now uses live SSE responses. The stream transformer emits text, reasoning, tool, source, custom, and metadata parts. Added source conversion, fixtures, documentation, and tests for streaming events, tool calls, service-tier metadata, raw chunks, and errors.

Changes: Google Interactions streaming

Layer / File(s) Summary
Annotation and tool-result sources
src/Vercel.AI/Google/GoogleInteractionsSources.cs, tests/Vercel.AI.Tests/Upstream/Google/ExtractGoogleInteractionsSources/*
Annotations and supported built-in tool results map to URL or document sources. Conversion handles duplicate sources, file names, and known media types.
Stream event transformation
src/Vercel.AI/Google/GoogleInteractionsStreaming.cs, tests/Vercel.AI.Tests/Upstream/Google/BuildGoogleInteractionsStreamTransform/*
The transformer handles reasoning, text, function and built-in tool events, custom processing steps, sources, errors, and finish metadata.
Live SSE request and integration
src/Vercel.AI/Google/GoogleInteractions.cs, tests/Vercel.AI.Tests/Upstream/Google/GoogleInteractionsLanguageModel/*
Foreground streaming sends a streaming request and transforms SSE events. Background streaming passes the configured ID generator. Tests cover text, tools, service-tier metadata, and raw chunks.
Fixtures and documentation
tests/Vercel.AI.Tests/Fixtures/google-interactions-*.chunks.txt, tests/Vercel.AI.Tests/Upstream/Google/GoogleInteractionsStreamSupport.cs, tests/Vercel.AI.Tests/Upstream/Google/GoogleUpstreamSupport.cs, docs/articles/providers.md
Fixtures, snapshot helpers, response-header handling, and provider documentation cover the expanded streaming behavior.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant LanguageModelConsumer
  participant GoogleInteractionsModel
  participant InteractionsAPI
  participant GoogleInteractionsStreamTransform
  LanguageModelConsumer->>GoogleInteractionsModel: Call DoStreamAsync
  GoogleInteractionsModel->>InteractionsAPI: POST with stream=true
  InteractionsAPI-->>GoogleInteractionsModel: SSE events and response headers
  GoogleInteractionsModel->>GoogleInteractionsStreamTransform: Parse and transform events
  GoogleInteractionsStreamTransform-->>LanguageModelConsumer: Stream parts and finish metadata
Loading

Possibly related issues

  • hardkoded/vercel-ai-sdk-dotnet#692 — The changes implement the issue’s core streaming POST behavior and emit reasoning, tool, source, and service-tier parts.
  • hardkoded/vercel-ai-sdk-dotnet#445 — The changes replace the buffered generation path with streaming POST requests; reconnect, polling, and agent-polling requirements remain outside this change.
Merge Risk: ⚪ Minimal · up to 8a4d6

No actionable issue remains from this review; the change is mergeable after normal checks.

Security architecture risk: 🔵 Low · up to 8a4d6

Live streaming now exposes tool calls and partial input to callers. Configured tool and approval checks remain in place, but interrupted streams can leave tool-input state unfinished.

Retained concerns

  • Low · reliability · observed: If foreground SSE reaches EOF during a function-call block, Flush clears that block without emitting ToolInputEnd, although ToolInputStart and argument deltas may already be visible. Consumers must recover the abandoned per-call state from whole-stream termination rather than a matching terminal transition. This weakens failure containment of the newly exposed tool-input lifecycle; the inspected execution path does not execute those unfinished arguments.
Security review details

Security Blast Radius

  • inferred — The newly reachable effect is not limited to displayed text: provider-generated function calls can reach application-supplied tool callbacks through foreground streaming. Their effective privileges and tenant or data-store reach depend on those callbacks. The inspected path limits execution to configured tools and retains configured approval checks.

Trust Boundaries and Controls

  • observed — Remote tool names and arguments enter the existing generic parser using the active tool registry. The execution stage skips invalid calls, provider-executed calls and tools awaiting approval. When an approval callback is configured, it runs before the registered execution callback and denial prevents execution.

Resilience and Maintainability Implications

  • observed — The SDK does not execute tool-input deltas directly. Complete calls are emitted at step.stop, error parts abort generic stream processing, and client execution is allowed only for Stop or ToolCalls finish reasons. These controls contain unfinished input despite the missing per-call terminal transition.

Hardening Proposals

  • proposed — Establish explicit provider guarantees for call-ID stability and resumed-event redelivery before relying on stream identifiers for approval or audit correlation. If late IDs or replay are permitted, preserve a stable emitted identity and define duplicate-call handling rather than assuming at-most-once delivery.
Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main changes: POST streaming for Google Interactions and exposure of reasoning, tool calls, and sources.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Upstream Parity Passed The upstream-parity check applies because the PR names upstream interaction files and issue #692. The prior unmatched-symbol concern is addressed: the PR description explicitly names `GoogleInteractio…
Full details: Upstream Parity

Explanation

The upstream-parity check applies because the PR names upstream interaction files and issue #692. The prior unmatched-symbol concern is addressed: the PR description explicitly names GoogleInteractionsSources as a .NET-only internal container and explains that C# requires a static class for upstream free functions. Its methods map to annotationToSource, annotationsToSources, and builtinToolResultToSources in vercel/ai@d0063af (packages/google/src/interactions/extract-google-interactions-sources.ts:27-225). NonEmpty and Strip are also identified as .NET-only in the PR text. Added tests use [UpstreamTest], follow the upstream file/describe layout, and cover the corresponding upstream tests. The PR lists the omitted upstream cases and reasons under Not ported. The changed user-visible behavior updates docs/articles/providers.md; the compatibility pin did not move. Prior failure addressed: The PR description now explicitly identifies GoogleInteractionsSources as a .NET-only internal container and states that C# requires a static class because the upstream functions are free functions.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@kblok

kblok commented Oct 21, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@kblok

kblok commented Oct 21, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@kblok
kblok merged commit 0896625 into main Oct 22, 2026
2 checks passed
@kblok
kblok deleted the google-interactions-post-stream branch October 22, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-tag Ready to tag a release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant