Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
bdfb7a7
feat: add multiple LLM responses to LLM recordings for conformance tests
google-genai-bot Mar 12, 2026
3f6504e
feat: update return type for stateDelta() to Map from ConcurrentMap
google-genai-bot Mar 12, 2026
32759f9
refactor: Replacing use of deprecated Runner constructor and Runner.r…
google-genai-bot Mar 12, 2026
be3b3f8
feat: remove executionId method that takes Optional param from CodeEx…
tilgalas Mar 12, 2026
9ce78d7
feat: Update converters for task and artifact events; add long runnin…
google-genai-bot Mar 12, 2026
41f5af0
fix: Removing deprecated InvocationContext methods
google-genai-bot Mar 12, 2026
f9d013b
refactor: update LoggingPlugin.formatContent to accept @Nullable inst…
tilgalas Mar 12, 2026
dc51aec
chore: update deprecation comment for setStateDelta
google-genai-bot Mar 13, 2026
5fd4c53
feat: replace Optional type of version in BaseArtifactService.loadArt…
tilgalas Mar 13, 2026
7cce374
chore: add explicit jackson-annotations dependency in core
tilgalas Mar 13, 2026
910d727
feat!: refactor ApiClient constructors hierarchy to remove Optional p…
tilgalas Mar 13, 2026
a47b651
chore: override new version to 0.9.0
tilgalas Mar 13, 2026
94e6715
chore(main): release 0.9.0
adk-java-releases-bot Mar 13, 2026
0d2c37c
feat: Introducing Tracing.withContext()
google-genai-bot Mar 13, 2026
0a06c77
Merge pull request #979 from google:release-please--branches--main
copybara-github Mar 13, 2026
743ee78
chore(main): release 0.9.1-SNAPSHOT
adk-java-releases-bot Mar 13, 2026
3c702b1
Merge pull request #1031 from google:release-please--branches--main
copybara-github Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
".": "0.8.0"
".": "0.9.0"
}

56 changes: 56 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
# Changelog

## [0.9.0](https://github.com/google/adk-java/compare/v0.8.0...v0.9.0) (2026-03-13)


### ⚠ BREAKING CHANGES

* refactor ApiClient constructors hierarchy to remove Optional parameters
* remove deprecated LlmAgent.canonicalTools method
* remove deprecated LoadArtifactsTool.loadArtifacts method
* update LoopAgent's maxIteration field and methods to be @Nullable instead of Optional
* Remove Optional parameters in EventActions
* remove deprecated url method in ComputerState.Builder
* Remove deprecated create method in ResponseProcessor
* remove McpAsyncToolset constructors
* use @Nullable fields in Event class
* remove methods with Optional params from VertexCredential.Builder

### Features

* add formatting to the RemoteA2A agent so it filters out the previous agent responses and updates the context of the function calls and responses ([0d6dd55](https://github.com/google/adk-java/commit/0d6dd55f4870007e79db23e21bd261879dbfba79))
* add multiple LLM responses to LLM recordings for conformance tests ([bdfb7a7](https://github.com/google/adk-java/commit/bdfb7a72188ce6e72c12c16c0abedb824b846160))
* add support for gemini models in VertexAiRagRetrieval ([924fb71](https://github.com/google/adk-java/commit/924fb7174855b46a58be43373c1a29284c47dfa8))
* Fixing the spans produced by agent calls to have the right parent spans ([3c8f488](https://github.com/google/adk-java/commit/3c8f4886f0e4c76abdbeb64a348bfccd5c16120e))
* Fixing the spans produced by agent calls to have the right parent spans ([973f887](https://github.com/google/adk-java/commit/973f88743cabebcd2e6e7a8d5f141142b596dbbb))
* refactor ApiClient constructors hierarchy to remove Optional parameters ([910d727](https://github.com/google/adk-java/commit/910d727f1981498151dea4cb91b9e5836f91e3ba))
* Remove deprecated create method in ResponseProcessor ([5e1e1d4](https://github.com/google/adk-java/commit/5e1e1d434fa1f3931af30194422800757de96cb6))
* remove deprecated LlmAgent.canonicalTools method ([aabf15a](https://github.com/google/adk-java/commit/aabf15a526ba525cdb47c74c246c178eff1851d5))
* remove deprecated LoadArtifactsTool.loadArtifacts method ([bc38558](https://github.com/google/adk-java/commit/bc385589057a6daf0209a335280bf19d20b2126b))
* remove deprecated url method in ComputerState.Builder ([a86ede0](https://github.com/google/adk-java/commit/a86ede007c3442ed73ee08a5c6ad0e2efa12998a))
* remove executionId method that takes Optional param from CodeExecutionUtils ([be3b3f8](https://github.com/google/adk-java/commit/be3b3f8360888ea1f13796969bb19893c32727e0))
* remove McpAsyncToolset constructors ([82ef5ac](https://github.com/google/adk-java/commit/82ef5ac2689e01676aa95d2616e3b4d8463e573e))
* remove methods with Optional params from VertexCredential.Builder ([0b9057c](https://github.com/google/adk-java/commit/0b9057c9ccab98ea58597ec55b8168e32ac7c9a6))
* Remove Optional parameters in EventActions ([b8316b1](https://github.com/google/adk-java/commit/b8316b1944ce17cc9208963cc09d900c379444c6))
* replace Optional type of version in BaseArtifactService.loadArtifact with Nullable ([5fd4c53](https://github.com/google/adk-java/commit/5fd4c53c88e977d004b9eee8fa3697625ec85f47))
* Trigger traceCallLlm to set call_llm attributes before span ends ([d9d84ee](https://github.com/google/adk-java/commit/d9d84ee67406cce8eeb66abcf1be24fad9c58e29))
* Update converters for task and artifact events; add long running tools ids ([9ce78d7](https://github.com/google/adk-java/commit/9ce78d7c3e1b0fb6d8d4fdce9052a572ffb9e515))
* update LoopAgent's maxIteration field and methods to be @Nullable instead of Optional ([e0d833b](https://github.com/google/adk-java/commit/e0d833b337e958e299d0d11a03f6bfa1468731bc))
* update return type for artifactDelta getter and setter to Map from ConcurrentMap ([d1d5539](https://github.com/google/adk-java/commit/d1d5539ef763b6bfd5057c6ea0f2591225a98535))
* update return type for requestedToolConfirmations getter and setter to Map from ConcurrentMap ([143b656](https://github.com/google/adk-java/commit/143b656949d61363d135e0b74ef5696e78eb270a))
* update return type for stateDelta() to Map from ConcurrentMap ([3f6504e](https://github.com/google/adk-java/commit/3f6504e9416f9f644ef431e612ec983b9a2edd9d))
* update State constructors to accept general Map types ([c6fdb63](https://github.com/google/adk-java/commit/c6fdb63c92e2f3481a01cfeafa946b6dce728c51))
* use @Nullable fields in Event class ([67b602f](https://github.com/google/adk-java/commit/67b602f245f564238ea22298a37bf70049e56a12))


### Bug Fixes

* Explicitly setting the otel parent spans in agents, llm flow and function calls ([20f863f](https://github.com/google/adk-java/commit/20f863f716f653979551c481d85d4e7fa56a35da))
* Make sure that `InvocationContext.callbackContextData` remains the same instance ([14ee28b](https://github.com/google/adk-java/commit/14ee28ba593a9f6f5f7b9bb6003441539fe33a18))
* Removing deprecated InvocationContext methods ([41f5af0](https://github.com/google/adk-java/commit/41f5af0dceb78501ca8b94e434e4d751f608a699))
* Removing deprecated methods in Runner ([0d8e22d](https://github.com/google/adk-java/commit/0d8e22d6e9fe4e8d29c87d485915ba51a22eb350))
* Removing deprecated methods in Runner ([b857f01](https://github.com/google/adk-java/commit/b857f010a0f51df0eb25ecdc364465ffdd9fef65))


### Miscellaneous Chores

* override new version to 0.9.0 ([a47b651](https://github.com/google/adk-java/commit/a47b651b5c4868a603fd79df164b70bc712c3a80))

## [0.8.0](https://github.com/google/adk-java/compare/v0.7.0...v0.8.0) (2026-03-06)


Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ If you're using Maven, add the following to your dependencies:
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk</artifactId>
<version>0.8.0</version>
<version>0.9.0</version>
</dependency>
<!-- Dev UI -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-dev</artifactId>
<version>0.8.0</version>
<version>0.9.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion a2a/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-parent</artifactId>
<version>0.8.1-SNAPSHOT</version><!-- {x-version-update:google-adk:current} -->
<version>0.9.1-SNAPSHOT</version><!-- {x-version-update:google-adk:current} -->
</parent>

<artifactId>google-adk-a2a</artifactId>
Expand Down
113 changes: 44 additions & 69 deletions a2a/src/main/java/com/google/adk/a2a/converters/PartConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ public static Optional<TextPart> toTextPart(io.a2a.spec.Part<?> part) {
}

/** Convert an A2A JSON part into a Google GenAI part representation. */
public static Optional<com.google.genai.types.Part> toGenaiPart(io.a2a.spec.Part<?> a2aPart) {
public static com.google.genai.types.Part toGenaiPart(io.a2a.spec.Part<?> a2aPart) {
if (a2aPart == null) {
return Optional.empty();
throw new IllegalArgumentException("A2A part cannot be null");
}

if (a2aPart instanceof TextPart textPart) {
return Optional.of(com.google.genai.types.Part.builder().text(textPart.getText()).build());
return com.google.genai.types.Part.builder().text(textPart.getText()).build();
}

if (a2aPart instanceof FilePart filePart) {
Expand All @@ -95,56 +95,41 @@ public static Optional<com.google.genai.types.Part> toGenaiPart(io.a2a.spec.Part
return convertDataPartToGenAiPart(dataPart);
}

logger.warn("Unsupported A2A part type: {}", a2aPart.getClass());
return Optional.empty();
throw new IllegalArgumentException("Unsupported A2A part type: " + a2aPart.getClass());
}

public static ImmutableList<com.google.genai.types.Part> toGenaiParts(
List<io.a2a.spec.Part<?>> a2aParts) {
return a2aParts.stream()
.map(PartConverter::toGenaiPart)
.flatMap(Optional::stream)
.collect(toImmutableList());
return a2aParts.stream().map(PartConverter::toGenaiPart).collect(toImmutableList());
}

private static Optional<com.google.genai.types.Part> convertFilePartToGenAiPart(
FilePart filePart) {
private static com.google.genai.types.Part convertFilePartToGenAiPart(FilePart filePart) {
FileContent fileContent = filePart.getFile();
if (fileContent instanceof FileWithUri fileWithUri) {
return Optional.of(
com.google.genai.types.Part.builder()
.fileData(
FileData.builder()
.fileUri(fileWithUri.uri())
.mimeType(fileWithUri.mimeType())
.build())
.build());
return com.google.genai.types.Part.builder()
.fileData(
FileData.builder()
.fileUri(fileWithUri.uri())
.mimeType(fileWithUri.mimeType())
.build())
.build();
}

if (fileContent instanceof FileWithBytes fileWithBytes) {
String bytesString = fileWithBytes.bytes();
if (bytesString == null) {
logger.warn("FileWithBytes missing byte content");
return Optional.empty();
}
try {
byte[] decoded = Base64.getDecoder().decode(bytesString);
return Optional.of(
com.google.genai.types.Part.builder()
.inlineData(Blob.builder().data(decoded).mimeType(fileWithBytes.mimeType()).build())
.build());
} catch (IllegalArgumentException e) {
logger.warn("Failed to decode base64 file content", e);
return Optional.empty();
throw new GenAiFieldMissingException("FileWithBytes missing byte content");
}
byte[] decoded = Base64.getDecoder().decode(bytesString);
return com.google.genai.types.Part.builder()
.inlineData(Blob.builder().data(decoded).mimeType(fileWithBytes.mimeType()).build())
.build();
}

logger.warn("Unsupported FilePart content: {}", fileContent.getClass());
return Optional.empty();
throw new IllegalArgumentException("Unsupported FilePart content: " + fileContent.getClass());
}

private static Optional<com.google.genai.types.Part> convertDataPartToGenAiPart(
DataPart dataPart) {
private static com.google.genai.types.Part convertDataPartToGenAiPart(DataPart dataPart) {
Map<String, Object> data =
Optional.ofNullable(dataPart.getData()).map(HashMap::new).orElseGet(HashMap::new);
Map<String, Object> metadata =
Expand All @@ -154,67 +139,57 @@ private static Optional<com.google.genai.types.Part> convertDataPartToGenAiPart(

if ((data.containsKey(NAME_KEY) && data.containsKey(ARGS_KEY))
|| metadataType.equals(A2ADataPartMetadataType.FUNCTION_CALL.getType())) {
String functionName = String.valueOf(data.getOrDefault(NAME_KEY, null));
String functionId = String.valueOf(data.getOrDefault(ID_KEY, null));
String functionName = String.valueOf(data.getOrDefault(NAME_KEY, ""));
String functionId = String.valueOf(data.getOrDefault(ID_KEY, ""));
Map<String, Object> args = coerceToMap(data.get(ARGS_KEY));
return Optional.of(
com.google.genai.types.Part.builder()
.functionCall(
FunctionCall.builder().name(functionName).id(functionId).args(args).build())
.build());
return com.google.genai.types.Part.builder()
.functionCall(FunctionCall.builder().name(functionName).id(functionId).args(args).build())
.build();
}

if ((data.containsKey(NAME_KEY) && data.containsKey(RESPONSE_KEY))
|| metadataType.equals(A2ADataPartMetadataType.FUNCTION_RESPONSE.getType())) {
String functionName = String.valueOf(data.getOrDefault(NAME_KEY, ""));
String functionId = String.valueOf(data.getOrDefault(ID_KEY, ""));
Map<String, Object> response = coerceToMap(data.get(RESPONSE_KEY));
return Optional.of(
com.google.genai.types.Part.builder()
.functionResponse(
FunctionResponse.builder()
.name(functionName)
.id(functionId)
.response(response)
.build())
.build());
return com.google.genai.types.Part.builder()
.functionResponse(
FunctionResponse.builder()
.name(functionName)
.id(functionId)
.response(response)
.build())
.build();
}

if ((data.containsKey(CODE_KEY) && data.containsKey(LANGUAGE_KEY))
|| metadataType.equals(A2ADataPartMetadataType.EXECUTABLE_CODE.getType())) {
String code = String.valueOf(data.getOrDefault(CODE_KEY, ""));
String language =
String.valueOf(
data.getOrDefault(LANGUAGE_KEY, Language.Known.LANGUAGE_UNSPECIFIED.toString())
.toString());
return Optional.of(
com.google.genai.types.Part.builder()
.executableCode(
ExecutableCode.builder().code(code).language(new Language(language)).build())
.build());
data.getOrDefault(LANGUAGE_KEY, Language.Known.LANGUAGE_UNSPECIFIED.toString()));
return com.google.genai.types.Part.builder()
.executableCode(
ExecutableCode.builder().code(code).language(new Language(language)).build())
.build();
}

if ((data.containsKey(OUTCOME_KEY) && data.containsKey(OUTPUT_KEY))
|| metadataType.equals(A2ADataPartMetadataType.CODE_EXECUTION_RESULT.getType())) {
String outcome =
String.valueOf(data.getOrDefault(OUTCOME_KEY, Outcome.Known.OUTCOME_OK).toString());
String output = String.valueOf(data.getOrDefault(OUTPUT_KEY, ""));
return Optional.of(
com.google.genai.types.Part.builder()
.codeExecutionResult(
CodeExecutionResult.builder()
.outcome(new Outcome(outcome))
.output(output)
.build())
.build());
return com.google.genai.types.Part.builder()
.codeExecutionResult(
CodeExecutionResult.builder().outcome(new Outcome(outcome)).output(output).build())
.build();
}

try {
String json = objectMapper.writeValueAsString(data);
return Optional.of(com.google.genai.types.Part.builder().text(json).build());
return com.google.genai.types.Part.builder().text(json).build();
} catch (JsonProcessingException e) {
logger.warn("Failed to serialize DataPart payload", e);
return Optional.empty();
throw new IllegalArgumentException("Failed to serialize DataPart payload", e);
}
}

Expand Down
Loading
Loading