Skip to content

feat: Generate methods that use server-side streaming#2474

Merged
brianquinlan merged 2 commits intogoogleapis:mainfrom
brianquinlan:generate_stream
Oct 6, 2025
Merged

feat: Generate methods that use server-side streaming#2474
brianquinlan merged 2 commits intogoogleapis:mainfrom
brianquinlan:generate_stream

Conversation

@brianquinlan
Copy link
Copy Markdown
Contributor

The generated methods look like this:

  /// Generates a [streamed response](https://ai.google.dev/gemini-api/docs/text-generation?lang=python#generate-a-text-stream)
  /// from the model given an input `GenerateContentRequest`.
  Stream<GenerateContentResponse> streamGenerateContent(
    GenerateContentRequest request,
  ) {
    final url = Uri.https(_host, '/v1/${request.model}:streamGenerateContent');
    return _client
        .postStreaming(url, body: request)
        .map(GenerateContentResponse.fromJson);
  }

@brianquinlan brianquinlan requested a review from a team October 2, 2025 20:09
@codecov
Copy link
Copy Markdown

codecov bot commented Oct 2, 2025

Codecov Report

❌ Patch coverage is 91.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 85.12%. Comparing base (5e22b80) to head (619b41a).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
internal/sidekick/internal/dart/dart.go 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2474      +/-   ##
==========================================
+ Coverage   84.75%   85.12%   +0.36%     
==========================================
  Files         101      101              
  Lines       10224    10276      +52     
==========================================
+ Hits         8665     8747      +82     
+ Misses       1216     1196      -20     
+ Partials      343      333      -10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@brianquinlan
Copy link
Copy Markdown
Contributor Author

@natebosch

@devoncarew
Copy link
Copy Markdown
Contributor

final url = Uri.https(_host, '/v1/${request.model}:streamGenerateContent');

Can you confirm that this isn't instead:

final url = Uri.https(_host, '/v1/${request.model}:generateContent');

I.e., the same end-point as non-streaming, but expecting an SSE streaming response, or using a different endpoint in order to get the streaming response.

Copy link
Copy Markdown
Contributor

@devoncarew devoncarew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions. Also - if we do need to include code to pull config out of the toml files in this PR - it would be worth thinking about how to test that.

@brianquinlan
Copy link
Copy Markdown
Contributor Author

final url = Uri.https(_host, '/v1/${request.model}:streamGenerateContent');

Can you confirm that this isn't instead:

final url = Uri.https(_host, '/v1/${request.model}:generateContent');

I.e., the same end-point as non-streaming, but expecting an SSE streaming response, or using a different endpoint in order to get the streaming response.

I've tested the generated code with:

  final service = GenerativeService(client: client);
  final request = GenerateContentRequest(
    model: 'models/gemini-2.5-flash',
    contents: [
      Content(parts: [Part(text: prompt)]),
    ],
  );

  await for (final s in service.streamGenerateContent(request)) {
    print('output: ${s.candidates?[0].content?.parts?[0].text}');
  }

Copy link
Copy Markdown
Contributor

@devoncarew devoncarew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested the generated code with:

OK, re: the naming of the streaming method and how it gets marked as streaming, looking at the gemini api it has both a GenerateContent (non-streaming) and a StreamGenerateContent (streaming) method.

https://github.com/googleapis/googleapis/blob/master/google/ai/generativelanguage/v1/generative_service.proto#L44

We may still want a way to mark streaming methods as supported - methods we should generate code for - as I believe only some of them will support streaming via SSE.

@brianquinlan
Copy link
Copy Markdown
Contributor Author

I filed #2490 to track adding whitelist support.

@brianquinlan brianquinlan merged commit 31a496d into googleapis:main Oct 6, 2025
6 checks passed
suztomo pushed a commit that referenced this pull request Oct 13, 2025
Librarian Version: v0.0.0-20251009012716-e267b1dfc9b9
Language Image:
us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/librarian-release-container:latest
<details><summary>librarian: 0.4.0</summary>

##
[0.4.0](v0.3.0...v0.4.0)
(2025-10-09)

### Features

* add `git log` functionality (#2510)
([e267b1d](e267b1d))

* Modify README.md to match our agreed-upon wording (#2503)
([2dc6fc6](2dc6fc6))

* Show actual enum values on setter samples. (#2491)
([13fd5a1](13fd5a1))

* sort library state when writing to `state.yaml` (#2504)
([35e4495](35e4495))

* Generate methods that use server-side streaming (#2474)
([31a496d](31a496d))

* allow configuring tag_format in config.yaml (#2236)
([e0eeddb](e0eeddb))

* `update` supports different roots (#2473)
([65fa7ed](65fa7ed))

* Support git push via SSH (#2397)
([7259194](7259194))

* mount output dir in configure docker command (#2439)
([365019e](365019e))

* Update templates for otel (#2443)
([ea54ba6](ea54ba6))

* support aggregated pagination (#2432)
([5b010b9](5b010b9))

* override pagination items field (#2441)
([4a3664a](4a3664a))

* include source root in configure request (#2431)
([475a62d](475a62d))

* rust&#43;disco bytes (de)serialization (#2428)
([b2a186c](b2a186c))

* enum serialization for non-proto sources (#2410)
([516f29e](516f29e))

* optional singular fields in discovery (#2408)
([c86c2db](c86c2db))

* deprecated elements in discovery docs (#2399)
([1d83853](1d83853))

* allow &#34;.&#34; as valid `source_roots` entry (#2396)
([2f52aa7](2f52aa7))

* inline messages in discovery docs (#2394)
([043cf65](043cf65))

* write pr-body.txt to the work root when not pushing (#2395)
([862c7d7](862c7d7))

* define LIBRARIAN_GITHUB_TOKEN as a constant (#2367)
([5979bfd](5979bfd))

### Bug Fixes

* clarify doc and comment with commit and push flag (#2507)
([645e42a](645e42a))

* keep first value for repeated footer keys (#2440)
([e51490d](e51490d))

* group commit msg if they have the same piper id and subject (#2496)
([60b7d38](60b7d38))

* real runs for `rust-publish` (#2484)
([15d63c2](15d63c2))

* Remove unnecessary dereference in transport template (#2481)
([610cec9](610cec9))

* shorten SHAs in generate commit msgs (#2472)
([de336b1](de336b1))

* handle slashes in library IDs (#2463)
([91c0189](91c0189))

* nil check for github.NewClient (#2465)
([71db17e](71db17e))

* Conventional Commit parser filters files based on Librarian flow
(#2433)
([6cb55d2](6cb55d2))

* Ensure detailed-tracing-attributes flag is fully propagated (#2438)
([a184f0d](a184f0d))

* relax footer regex to allow line broke footers to be properly
recognized (#2388)
([dcbe063](dcbe063))

* release init provides read-only full repository (#2370)
([2e11004](2e11004))

* write the PR body on &#34;commit but no push&#34; (#2430)
([88698b4](88698b4))

* should not push to github when no push flag specified (#2405)
([2a49ae6](2a49ae6))

* only mount global files in configure command (#2377)
([1a2aaa0](1a2aaa0))

* `Map` field attribute in discovery (#2414)
([00c645f](00c645f))

* missing IDs in discovery doc fields (#2386)
([d579dd7](d579dd7))

</details>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants