@@ -93,9 +93,7 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
9393 const result = await this . client . models . generateContentStream ( params )
9494
9595 let lastUsageMetadata : GenerateContentResponseUsageMetadata | undefined
96- let accumulatedText = ""
9796 let pendingGroundingMetadata : GroundingMetadata | undefined
98- let hasGroundingEnabled = this . options . enableGrounding
9997
10098 for await ( const chunk of result ) {
10199 // Process candidates and their parts to separate thoughts from content
@@ -116,11 +114,7 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
116114 } else {
117115 // This is regular content
118116 if ( part . text ) {
119- accumulatedText += part . text
120-
121- if ( ! hasGroundingEnabled ) {
122- yield { type : "text" , text : part . text }
123- }
117+ yield { type : "text" , text : part . text }
124118 }
125119 }
126120 }
@@ -129,26 +123,19 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
129123
130124 // Fallback to the original text property if no candidates structure
131125 else if ( chunk . text ) {
132- accumulatedText += chunk . text
133-
134- if ( ! hasGroundingEnabled ) {
135- yield { type : "text" , text : chunk . text }
136- }
126+ yield { type : "text" , text : chunk . text }
137127 }
138128
139129 if ( chunk . usageMetadata ) {
140130 lastUsageMetadata = chunk . usageMetadata
141131 }
142132 }
143133
144- if ( hasGroundingEnabled && accumulatedText ) {
145- let finalText = accumulatedText
146-
147- if ( pendingGroundingMetadata ) {
148- finalText = this . processGroundingCitations ( accumulatedText , pendingGroundingMetadata )
134+ if ( pendingGroundingMetadata ) {
135+ const citations = this . extractCitationsOnly ( pendingGroundingMetadata )
136+ if ( citations ) {
137+ yield { type : "text" , text : `\n\nSources: ${ citations } ` }
149138 }
150-
151- yield { type : "text" , text : finalText }
152139 }
153140
154141 if ( lastUsageMetadata ) {
@@ -188,39 +175,28 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
188175 return { id : id . endsWith ( ":thinking" ) ? id . replace ( ":thinking" , "" ) : id , info, ...params }
189176 }
190177
191- private processGroundingCitations ( text : string , groundingMetadata ?: GroundingMetadata ) : string {
192- const supports = groundingMetadata ?. groundingSupports
178+ private extractCitationsOnly ( groundingMetadata ?: GroundingMetadata ) : string | null {
193179 const chunks = groundingMetadata ?. groundingChunks
194180
195- if ( ! supports || ! chunks ) {
196- return text
181+ if ( ! chunks ) {
182+ return null
197183 }
198184
199- const sortedSupports = [ ...supports ] . sort ( ( a , b ) => ( b . segment ?. endIndex ?? 0 ) - ( a . segment ?. endIndex ?? 0 ) )
200-
201- for ( const support of sortedSupports ) {
202- const endIndex = support . segment ?. endIndex
203- if ( endIndex === undefined || ! support . groundingChunkIndices ?. length ) {
204- continue
205- }
206-
207- const citationLinks = support . groundingChunkIndices
208- . map ( ( i ) => {
209- const uri = chunks [ i ] ?. web ?. uri
210- if ( uri ) {
211- return `[${ i + 1 } ](${ uri } )`
212- }
213- return null
214- } )
215- . filter ( Boolean )
185+ const citationLinks = chunks
186+ . map ( ( chunk , i ) => {
187+ const uri = chunk . web ?. uri
188+ if ( uri ) {
189+ return `[${ i + 1 } ](${ uri } )`
190+ }
191+ return null
192+ } )
193+ . filter ( ( link ) : link is string => link !== null )
216194
217- if ( citationLinks . length > 0 ) {
218- const citationString = citationLinks . join ( ", " )
219- text = text . slice ( 0 , endIndex ) + citationString + text . slice ( endIndex )
220- }
195+ if ( citationLinks . length > 0 ) {
196+ return citationLinks . join ( ", " )
221197 }
222198
223- return text
199+ return null
224200 }
225201
226202 async completePrompt ( prompt : string ) : Promise < string > {
@@ -256,7 +232,10 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
256232
257233 const candidate = result . candidates ?. [ 0 ]
258234 if ( candidate ?. groundingMetadata ) {
259- text = this . processGroundingCitations ( text , candidate . groundingMetadata )
235+ const citations = this . extractCitationsOnly ( candidate . groundingMetadata )
236+ if ( citations ) {
237+ text += `\n\nSources: ${ citations } `
238+ }
260239 }
261240
262241 return text
0 commit comments