Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions contrib/samples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@
<module>configagent</module>
<module>helloworld</module>
<module>mcpfilesystem</module>
<module>spring-boot-adk-template</module>
</modules>
</project>
55 changes: 55 additions & 0 deletions contrib/samples/spring-boot-adk-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Spring Boot ADK Template

Sample Spring Boot application demonstrating the **`google-adk-spring-boot-starter`** in its simplest form. The user code consists of:

- One `@Bean LlmAgent rootAgent()` — the agent topology
- One `@Bean App` — wraps the root agent under an app name
- One `@Service AgentService` — illustrates injection of the starter-provided `Runner`

Everything else (`Runner`, `BaseSessionService`, `BaseArtifactService`, `RunConfig`) is wired by the starter.

## Prerequisites

- Java 17
- Maven
- This module is built as part of the ADK aggregator; no separate install of the starter is required.

## Build and run

From the repository root:

```bash
mvn -pl contrib/samples/spring-boot-adk-template -am verify
```

To run interactively:

```bash
mvn -pl contrib/samples/spring-boot-adk-template -am spring-boot:run
```

## Configuration

`src/main/resources/application.yaml` shows the full property surface as comments. The defaults give an all-in-memory configuration with no GCP credentials required — switch backends by uncommenting the relevant blocks (`adk.session.type=VERTEX_AI`, `adk.session.type=FIRESTORE`, `adk.artifacts.gcs-enabled=true`, etc.).

See the [starter README](../../spring-boot-starter/README.md) for the full property reference.

## Use Spring AI as the LLM substrate (optional)

This sample uses a string model name (`"gemini-2.5-flash"`). To swap to Spring AI's `ChatModel` ecosystem (OpenAI, Anthropic, Gemini, Ollama, Vertex AI, Azure OpenAI, Bedrock):

1. Add `com.google.adk:google-adk-spring-ai` and your preferred Spring AI provider artifact to `pom.xml`.
2. Configure the provider via `spring.ai.*` properties (e.g. `spring.ai.openai.api-key`).
3. Inject the auto-configured `SpringAI` bean into `AgentConfig.rootAgent()` and pass it to `.model(...)`.

## Project structure

```
src/main/java/com/example/springbootadktemplate/
├── SpringBootAdkTemplateApplication.java — @SpringBootApplication entry point
├── AgentService.java — sample @Service injecting Runner + LlmAgent
└── config/AgentConfig.java — @Bean LlmAgent + @Bean App
src/main/resources/application.yaml — spring.application.name + (commented) adk.* properties
src/test/java/com/example/springbootadktemplate/
└── SpringBootAdkTemplateApplicationTest.java — context-load test asserting every starter bean is reachable
```
67 changes: 67 additions & 0 deletions contrib/samples/spring-boot-adk-template/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2026 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-samples</artifactId>
<version>1.4.1-SNAPSHOT</version><!-- {x-version-update:google-adk:current} -->
<relativePath>..</relativePath>
</parent>

<groupId>com.google.adk.samples</groupId>
<artifactId>google-adk-sample-spring-boot-template</artifactId>
<name>Google ADK - Sample - Spring Boot Template</name>
<description>Spring Boot template demonstrating the google-adk-spring-boot-starter.</description>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<exec.mainClass>com.example.springbootadktemplate.SpringBootAdkTemplateApplication</exec.mainClass>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-spring-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${exec.mainClass}</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.example.springbootadktemplate;

import com.google.adk.agents.LlmAgent;
import com.google.adk.runner.Runner;
import org.springframework.stereotype.Service;

@Service
public class AgentService {

private final Runner runner;
private final LlmAgent agent;

public AgentService(Runner runner, LlmAgent agent) {
this.runner = runner;
this.agent = agent;
}

public String getAgentInfo() {
return "Agent created: "
+ agent.getClass().getSimpleName()
+ ", Runner: "
+ runner.getClass().getSimpleName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
package com.example.springbootadktemplate;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootAdkTemplateApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootAdkTemplateApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
package com.example.springbootadktemplate.config;

import com.google.adk.agents.LlmAgent;
import com.google.adk.apps.App;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Sample agent topology — defines a root LlmAgent and packages it into an App.
*
* <p>The starter provides {@code Runner}, {@code BaseSessionService}, {@code BaseArtifactService},
* and {@code RunConfig} automatically — this configuration only declares the user-specific agent
* topology.
*/
@Configuration
public class AgentConfig {

@Bean
public LlmAgent rootAgent() {
return LlmAgent.builder()
.name("root_agent")
.description("Sample assistant agent.")
.model("gemini-2.5-flash")
.instruction("Answer user questions to the best of your knowledge.")
.build();
}

@Bean
public App app(LlmAgent rootAgent, @Value("${spring.application.name}") String appName) {
return App.builder().name(appName).rootAgent(rootAgent).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
spring:
application:
name: spring_boot_adk_template # must be a valid identifier (App#validateAppName regex)

# Defaults — services are in-memory unless these are uncommented.
# adk:
# artifacts:
# gcs-enabled: false
# # bucket-name: my-bucket
# session:
# type: IN_MEMORY # IN_MEMORY | VERTEX_AI | FIRESTORE
# # project-id: my-project
# # location: us-central1
# memory:
# type: IN_MEMORY # IN_MEMORY | FIRESTORE
# run-config:
# streaming-mode: NONE # NONE | SSE | BIDI
# max-llm-calls: 500
# tool-execution-mode: NONE # NONE | SEQUENTIAL | PARALLEL | PARALLEL_SUBSCRIBE
# save-input-blobs-as-artifacts: false
# auto-create-session: true
# firestore:
# # project-id: my-gcp-project
# # database-id: "(default)"
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
package com.example.springbootadktemplate;

import static org.assertj.core.api.Assertions.assertThat;

import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.RunConfig;
import com.google.adk.apps.App;
import com.google.adk.artifacts.BaseArtifactService;
import com.google.adk.runner.Runner;
import com.google.adk.sessions.BaseSessionService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;

@SpringBootTest
class SpringBootAdkTemplateApplicationTest {

@Test
void contextLoadsAndStarterBeansArePresent(ApplicationContext ctx) {
assertThat(ctx.getBean(LlmAgent.class)).isNotNull();
assertThat(ctx.getBean(App.class).name()).isEqualTo("spring_boot_adk_template");
assertThat(ctx.getBean(BaseArtifactService.class)).isNotNull();
assertThat(ctx.getBean(BaseSessionService.class)).isNotNull();
assertThat(ctx.getBean(RunConfig.class)).isNotNull();
assertThat(ctx.getBean(Runner.class).appName()).isEqualTo("spring_boot_adk_template");
}
}
Loading