Skip to content

Commit 9c14df4

Browse files
Fix missing thoughts in GenerativeModelSession.streamResponse (#16075)
Co-authored-by: Andrew Heard <andrewheard@google.com>
1 parent 73be126 commit 9c14df4

3 files changed

Lines changed: 38 additions & 4 deletions

File tree

FirebaseAI/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- [fixed] Fix unfound file warnings from `swift build`. (#16012)
44
- [fixed] Fixed a `no member 'autoFunctionDeclaration'` compilation error on
55
unofficially supported Xcode versions older than 26.2. (#16037)
6+
- [fixed] Fixed missing thought summary output in `GenerativeModelSession.streamResponse`. (#16075)
67

78
# 12.12.0
89
- [feature] Added support for automatic function calling in

FirebaseAI/Sources/GenerativeModelSession.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,8 @@
361361
}
362362

363363
// 2. If we have pending data, we now know it wasn't the last chunk.
364-
if let pending = pendingChunkData, !pending.text.isEmpty {
364+
if let pending = pendingChunkData,
365+
!pending.text.isEmpty || pending.response.thoughtSummary != nil {
365366
let rawContent = try Self.makeRawContent(
366367
from: pending.text,
367368
generationID: pending.id,
@@ -413,7 +414,8 @@
413414

414415
if !functionResponses.isEmpty {
415416
// Yield any pending text if it's not empty, but mark it as NOT complete yet.
416-
if let pending = pendingChunkData, !pending.text.isEmpty {
417+
if let pending = pendingChunkData,
418+
!pending.text.isEmpty || pending.response.thoughtSummary != nil {
417419
let rawContent = try Self.makeRawContent(
418420
from: pending.text,
419421
generationID: pending.id,
@@ -523,6 +525,15 @@
523525
hasSchema: Bool, isComplete: Bool) throws
524526
-> FirebaseAI.GeneratedContent {
525527
if hasSchema {
528+
if text.isEmpty && !isComplete {
529+
return FirebaseAI.GeneratedContent(
530+
// TODO: Set `kind:` to `.array(...)`, `.bool()`, `.number()` based on schema type.
531+
kind: .structure(properties: [:], orderedKeys: []),
532+
id: generationID,
533+
isComplete: isComplete
534+
)
535+
}
536+
526537
return try FirebaseAI.GeneratedContent(json: text, id: generationID, isComplete: isComplete)
527538
}
528539

FirebaseAI/Tests/TestApp/Tests/Integration/GenerativeModelSessionTests.swift

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,15 @@
9292
let firebaseAI = FirebaseAI.componentInstance(config)
9393
let session = firebaseAI.generativeModelSession(model: ModelNames.gemini2_5_FlashLite)
9494
let prompt = "Generate a Ragdoll kitten"
95+
let config = GenerationConfig(
96+
thinkingConfig: ThinkingConfig(thinkingBudget: -1, includeThoughts: true)
97+
)
9598

96-
let response = try await session.respond(to: prompt, generating: CatProfile.self)
99+
let response = try await session.respond(
100+
to: prompt,
101+
generating: CatProfile.self,
102+
options: config
103+
)
97104

98105
let catProfile = response.content
99106
#expect(!catProfile.name.isEmpty)
@@ -102,6 +109,10 @@
102109
#expect(!catProfile.profile.isEmpty)
103110
#expect(response.rawContent.isComplete)
104111
#expect(response.rawContent.generationID != nil)
112+
let thoughtSummary = try #require(
113+
response.rawResponse.thoughtSummary, "No thought summary was generated."
114+
)
115+
#expect(!thoughtSummary.isEmpty)
105116
}
106117

107118
@Generable
@@ -438,15 +449,20 @@
438449
let firebaseAI = FirebaseAI.componentInstance(config)
439450
let session = firebaseAI.generativeModelSession(model: ModelNames.gemini2_5_FlashLite)
440451
let prompt = "Generate a Ragdoll kitten"
452+
let config = GenerationConfig(
453+
thinkingConfig: ThinkingConfig(thinkingBudget: -1, includeThoughts: true)
454+
)
441455

442456
let stream = session.streamResponse(
443457
to: prompt,
444-
generating: CatProfile.self
458+
generating: CatProfile.self,
459+
options: config
445460
)
446461

447462
var generationID: FirebaseAI.GenerationID?
448463
var id: FoundationModels.GenerationID?
449464
var isComplete = false
465+
var thoughtSummary = ""
450466
for try await snapshot in stream {
451467
#expect(!isComplete, "Stream yielded more elements after a snapshot was marked complete.")
452468
let partial = snapshot.content
@@ -477,11 +493,17 @@
477493
} else {
478494
id = snapshot.content.id
479495
}
496+
if let partialThoughtSummary = snapshot.rawResponse.thoughtSummary {
497+
thoughtSummary += partialThoughtSummary
498+
}
480499
isComplete = snapshot.rawContent.isComplete
481500
}
482501
#expect(
483502
isComplete, "The stream finished, but the final snapshot was not marked as complete."
484503
)
504+
#expect(
505+
!thoughtSummary.isEmpty, "The stream finished, but no thought summary was generated."
506+
)
485507

486508
let response = try await stream.collect()
487509
#expect(response.rawContent.isComplete, "The final response was not marked as complete.")

0 commit comments

Comments
 (0)