getTracking(
+ @ToolParam(description = "The order number, for example 1001.") String orderId,
+ ToolContext toolContext) {
+ String trackingNumber = TRACKING_NUMBERS.get(orderId);
+ if (trackingNumber == null) {
+ return ImmutableMap.of("error", "This order has no tracking number yet.");
+ }
+ if (toolContext.getContext().get(ToolConverter.ADK_TOOL_CONTEXT_KEY)
+ instanceof com.google.adk.tools.ToolContext adkToolContext) {
+ adkToolContext.state().put(LAST_TRACKED_ORDER, orderId);
+ }
+ return ImmutableMap.of("orderId", orderId, "tracking", trackingNumber);
+ }
+
+ /** With {@code returnDirect}, ADK shows this result to the user without another model call. */
+ @Tool(
+ description = "Hands the conversation to a human support agent when the user asks for one.",
+ returnDirect = true)
+ String talkToHuman() {
+ return "A human support agent will join this chat within 5 minutes.";
+ }
+}
diff --git a/examples/spring_chat_advanced/src/main/java/com/example/springchat/advanced/SpringChatAdvancedApplication.java b/examples/spring_chat_advanced/src/main/java/com/example/springchat/advanced/SpringChatAdvancedApplication.java
new file mode 100644
index 000000000..d469dfc8f
--- /dev/null
+++ b/examples/spring_chat_advanced/src/main/java/com/example/springchat/advanced/SpringChatAdvancedApplication.java
@@ -0,0 +1,29 @@
+/*
+ * 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
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.springchat.advanced;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/** Spring Boot entry point for the advanced chat sample. */
+@SpringBootApplication
+public class SpringChatAdvancedApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringChatAdvancedApplication.class, args);
+ }
+}
diff --git a/examples/spring_chat_advanced/src/main/resources/application.properties b/examples/spring_chat_advanced/src/main/resources/application.properties
new file mode 100644
index 000000000..5136a5856
--- /dev/null
+++ b/examples/spring_chat_advanced/src/main/resources/application.properties
@@ -0,0 +1,11 @@
+# Spring AI Google GenAI chat model. Vertex AI with Application Default Credentials is the default:
+# set GOOGLE_CLOUD_PROJECT (and optionally GOOGLE_CLOUD_LOCATION). To use the Gemini Developer API
+# instead, set GOOGLE_GENAI_USE_VERTEXAI=false and GOOGLE_API_KEY.
+spring.ai.google.genai.vertex-ai=${GOOGLE_GENAI_USE_VERTEXAI:true}
+spring.ai.google.genai.project-id=${GOOGLE_CLOUD_PROJECT:}
+spring.ai.google.genai.location=${GOOGLE_CLOUD_LOCATION:global}
+spring.ai.google.genai.api-key=${GOOGLE_API_KEY:}
+spring.ai.google.genai.chat.model=${GEMINI_MODEL:gemini-3.8-flash}
+
+# The chat endpoint has no authentication, so listen on loopback only unless told otherwise.
+server.address=${SERVER_ADDRESS:localhost}
diff --git a/examples/spring_chat_advanced/src/main/resources/static/index.html b/examples/spring_chat_advanced/src/main/resources/static/index.html
new file mode 100644
index 000000000..8df433c70
--- /dev/null
+++ b/examples/spring_chat_advanced/src/main/resources/static/index.html
@@ -0,0 +1,139 @@
+
+
+
+
+
+ ADK Spring Chat: Order Support
+
+
+
+ Order Support
+ Ask about orders 1001, 1002 or 1003, track a shipped order, or ask for a human.
+
+
+
+
+
+