@@ -210,18 +210,7 @@ public Stream<GeneratedContent> generateContentStream(GenerativeModel model) {
210210 );
211211 return response .body ()
212212 .filter (l -> l .length () > STREAM_LINE_PREFIX_LENGTH )
213- .map (line -> {
214- try {
215- var gcr = jsonParser .fromJson (line .substring (STREAM_LINE_PREFIX_LENGTH ), GenerateContentResponse .class );
216- // each element can just replace the previous one
217- this .responseById .put (uuid , gcr );
218- // todo catch safety error
219- //if ("SAFETY".equals(gcr.candidates().get(0).finishReason())) {
220- return new GeneratedContent (uuid , gcr .candidates ().get (0 ).content ().parts ().get (0 ).text ());
221- } catch (Exception e ) {
222- throw new RuntimeException ("Unexpected line:\n " + line , e );
223- }
224- });
213+ .map (line -> parse (line .substring (STREAM_LINE_PREFIX_LENGTH ), uuid ));
225214 });
226215 }
227216
@@ -249,15 +238,7 @@ public CompletableFuture<GeneratedContent> generateContent(GenerativeModel model
249238 );
250239 return response
251240 .thenApply (HttpResponse ::body )
252- .thenApply (body -> {
253- try {
254- var gcr = jsonParser .fromJson (body , GenerateContentResponse .class );
255- responseById .put (uuid , gcr );
256- return new GeneratedContent (uuid , gcr .candidates ().get (0 ).content ().parts ().get (0 ).text ());
257- } catch (Exception e ) {
258- throw new RuntimeException ("Unexpected body:\n " + body , e );
259- }
260- });
241+ .thenApply (body -> parse (body , uuid ));
261242 });
262243 }
263244
@@ -418,12 +399,14 @@ public void close() {
418399 /**
419400 * Content generated by Gemini API.
420401 *
421- * @param id the id of the request, for subsequent queries regarding metadata of the query
422- * @param text of the generated content
402+ * @param id the id of the request, for subsequent queries regarding metadata of the query
403+ * @param text of the generated content
404+ * @param finishReason the reason generation was finished, according to <a href="https://ai.google.dev/api/generate-content#FinishReason">FinishReason</a>
423405 */
424406 public record GeneratedContent (
425407 UUID id ,
426- String text
408+ String text ,
409+ String finishReason
427410 ) {
428411 }
429412
@@ -542,6 +525,22 @@ public record Model(
542525 ) {
543526 }
544527
528+ private GeneratedContent parse (String body , UUID uuid ) {
529+ try {
530+ var gcr = jsonParser .fromJson (body , GenerateContentResponse .class );
531+ // each element can just replace the previous one
532+ this .responseById .put (uuid , gcr );
533+ // we assume we always get a candidate. Otherwise, there is probably something wrong with the input
534+ var candidate = gcr .candidates ().get (0 );
535+ if (candidate .content () == null ) {
536+ return new GeneratedContent (uuid , "" , candidate .finishReason ());
537+ }
538+ return new GeneratedContent (uuid , candidate .content ().parts ().get (0 ).text (), candidate .finishReason ());
539+ } catch (Exception e ) {
540+ throw new RuntimeException ("Unexpected body:\n " + body , e );
541+ }
542+ }
543+
545544 private record BatchEmbedContentRequest (
546545 List <EmbedContentRequest > requests
547546 ) {
0 commit comments