Skip to content

Commit b9c4e45

Browse files
committed
Merge remote-tracking branch 'origin/main' into feature/subagent-escalation
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
2 parents 7ce4914 + cf5be25 commit b9c4e45

File tree

3 files changed

+47
-25
lines changed

3 files changed

+47
-25
lines changed

core/src/main/java/com/google/adk/models/Gemini.java

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,24 @@ public Flowable<LlmResponse> generateContent(LlmRequest llmRequest, boolean stre
223223
effectiveModelName, llmRequest.contents(), config);
224224

225225
return Flowable.defer(
226-
() ->
227-
processRawResponses(
228-
Flowable.fromFuture(streamFuture).flatMapIterable(iterable -> iterable)));
226+
() ->
227+
processRawResponses(
228+
Flowable.fromFuture(streamFuture).flatMapIterable(iterable -> iterable)))
229+
.filter(
230+
llmResponse ->
231+
llmResponse
232+
.content()
233+
.flatMap(Content::parts)
234+
.map(
235+
parts ->
236+
!parts.isEmpty()
237+
&& parts.stream()
238+
.anyMatch(
239+
p ->
240+
p.functionCall().isPresent()
241+
|| p.functionResponse().isPresent()
242+
|| p.text().map(t -> !t.isBlank()).orElse(false)))
243+
.orElse(false));
229244
} else {
230245
logger.debug("Sending generateContent request to model {}", effectiveModelName);
231246
return Flowable.fromFuture(
@@ -253,15 +268,16 @@ static Flowable<LlmResponse> processRawResponses(Flowable<GenerateContentRespons
253268
Optional<Part> part = GeminiUtil.getPart0FromLlmResponse(currentProcessedLlmResponse);
254269
String currentTextChunk = part.flatMap(Part::text).orElse("");
255270

256-
if (!currentTextChunk.isEmpty()) {
271+
if (!currentTextChunk.isBlank()) {
257272
if (part.get().thought().orElse(false)) {
258273
accumulatedThoughtText.append(currentTextChunk);
274+
responsesToEmit.add(
275+
thinkingResponseFromText(currentTextChunk).toBuilder().partial(true).build());
259276
} else {
260277
accumulatedText.append(currentTextChunk);
278+
responsesToEmit.add(
279+
responseFromText(currentTextChunk).toBuilder().partial(true).build());
261280
}
262-
LlmResponse partialResponse =
263-
currentProcessedLlmResponse.toBuilder().partial(true).build();
264-
responsesToEmit.add(partialResponse);
265281
} else {
266282
if (accumulatedThoughtText.length() > 0
267283
&& GeminiUtil.shouldEmitAccumulatedText(currentProcessedLlmResponse)) {
@@ -284,22 +300,28 @@ static Flowable<LlmResponse> processRawResponses(Flowable<GenerateContentRespons
284300
.concatWith(
285301
Flowable.defer(
286302
() -> {
287-
if (accumulatedText.length() > 0 && lastRawResponseHolder[0] != null) {
288-
GenerateContentResponse finalRawResp = lastRawResponseHolder[0];
289-
boolean isStop =
290-
finalRawResp
291-
.candidates()
292-
.flatMap(candidates -> candidates.stream().findFirst())
293-
.flatMap(Candidate::finishReason)
294-
.map(
295-
finishReason -> finishReason.knownEnum() == FinishReason.Known.STOP)
296-
.orElse(false);
297-
298-
if (isStop) {
299-
LlmResponse finalAggregatedTextResponse =
300-
responseFromText(accumulatedText.toString());
301-
return Flowable.just(finalAggregatedTextResponse);
303+
GenerateContentResponse finalRawResp = lastRawResponseHolder[0];
304+
if (finalRawResp == null) {
305+
return Flowable.empty();
306+
}
307+
boolean isStop =
308+
finalRawResp
309+
.candidates()
310+
.flatMap(candidates -> candidates.stream().findFirst())
311+
.flatMap(Candidate::finishReason)
312+
.map(finishReason -> finishReason.knownEnum() == FinishReason.Known.STOP)
313+
.orElse(false);
314+
315+
if (isStop) {
316+
List<LlmResponse> finalResponses = new ArrayList<>();
317+
if (accumulatedThoughtText.length() > 0) {
318+
finalResponses.add(
319+
thinkingResponseFromText(accumulatedThoughtText.toString()));
320+
}
321+
if (accumulatedText.length() > 0) {
322+
finalResponses.add(responseFromText(accumulatedText.toString()));
302323
}
324+
return Flowable.fromIterable(finalResponses);
303325
}
304326
return Flowable.empty();
305327
}));

dev/src/main/java/com/google/adk/web/AgentStaticLoader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* <p>This class is not a Spring component by itself - instances are created programmatically and
3838
* then registered as beans via factory methods.
3939
*/
40-
class AgentStaticLoader implements AgentLoader {
40+
public class AgentStaticLoader implements AgentLoader {
4141

4242
private final ImmutableMap<String, BaseAgent> agents;
4343

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<otel.version>1.49.0</otel.version>
4848
<mcp.version>0.14.0</mcp.version>
4949
<errorprone.version>2.38.0</errorprone.version>
50-
<google.genai.version>1.22.0</google.genai.version>
50+
<google.genai.version>1.24.0</google.genai.version>
5151
<protobuf.version>4.32.0</protobuf.version>
5252
<junit.version>5.11.4</junit.version>
5353
<mockito.version>5.17.0</mockito.version>
@@ -58,7 +58,7 @@
5858
<graphviz.version>0.18.1</graphviz.version>
5959
<ecj.version>3.41.0</ecj.version>
6060
<maven.version>3.9.0</maven.version>
61-
<langchain4j.version>1.4.0</langchain4j.version>
61+
<langchain4j.version>1.8.0</langchain4j.version>
6262
<slf4j.version>2.0.17</slf4j.version>
6363
<truth.version>1.4.4</truth.version>
6464
<jspecify.version>1.0.0</jspecify.version>

0 commit comments

Comments
 (0)