**EXPERIMENTAL:** Subject to change, rename, or removal in any future patch release. Do not
- * use in production code.
- */
-@SpringBootApplication
-@Import(A2ARemoteConfiguration.class)
-public class A2ARemoteApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(A2ARemoteApplication.class, args);
- }
-}
diff --git a/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteConfiguration.java b/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteConfiguration.java
deleted file mode 100644
index a3f9b48ac..000000000
--- a/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteConfiguration.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.google.adk.webservice;
-
-import com.google.adk.a2a.A2ASendMessageExecutor;
-import com.google.adk.agents.BaseAgent;
-import java.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Registers the transport-only A2A webservice stack.
- *
- *
Importers must supply a {@link BaseAgent} bean. The agent remains opaque to this module so the
- * transport can be reused across applications.
- *
- *
TODO:
- *
- *
- *
Expose discovery endpoints (agent card / extended card) so clients can fetch metadata
- * directly.
- *
Add optional remote-proxy wiring for cases where no local agent bean is available.
- *
- *
- *
**EXPERIMENTAL:** Subject to change, rename, or removal in any future patch release. Do not
- * use in production code.
- */
-@Configuration
-@ComponentScan(basePackages = "com.google.adk.webservice")
-public class A2ARemoteConfiguration {
-
- private static final Logger logger = LoggerFactory.getLogger(A2ARemoteConfiguration.class);
- private static final String DEFAULT_APP_NAME = "a2a-remote-service";
- private static final long DEFAULT_TIMEOUT_SECONDS = 15L;
-
- @Bean
- public A2ASendMessageExecutor a2aSendMessageExecutor(
- BaseAgent agent,
- @Value("${a2a.remote.appName:" + DEFAULT_APP_NAME + "}") String appName,
- @Value("${a2a.remote.timeoutSeconds:" + DEFAULT_TIMEOUT_SECONDS + "}") long timeoutSeconds) {
- logger.info(
- "Initializing A2A send message executor for appName {} with timeout {}s",
- appName,
- timeoutSeconds);
- return new A2ASendMessageExecutor(agent, appName, Duration.ofSeconds(timeoutSeconds));
- }
-}
diff --git a/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteController.java b/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteController.java
deleted file mode 100644
index a0fe5b0cc..000000000
--- a/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.google.adk.webservice;
-
-import io.a2a.spec.SendMessageRequest;
-import io.a2a.spec.SendMessageResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * REST controller exposing an A2A-compliant JSON-RPC endpoint backed by a local ADK runner.
- *
- *
**EXPERIMENTAL:** Subject to change, rename, or removal in any future patch release. Do not
- * use in production code.
- */
-@RestController
-@RequestMapping("/a2a/remote")
-public class A2ARemoteController {
-
- private static final Logger logger = LoggerFactory.getLogger(A2ARemoteController.class);
-
- private final A2ARemoteService service;
-
- public A2ARemoteController(A2ARemoteService service) {
- this.service = service;
- }
-
- @PostMapping(
- path = "/v1/message:send",
- consumes = "application/json",
- produces = "application/json")
- public SendMessageResponse sendMessage(@RequestBody SendMessageRequest request) {
- logger.debug("Received remote A2A request: {}", request);
- SendMessageResponse response = service.handle(request);
- logger.debug("Responding with remote A2A payload: {}", response);
- return response;
- }
-}
diff --git a/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteService.java b/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteService.java
deleted file mode 100644
index 803774568..000000000
--- a/a2a/webservice/src/main/java/com/google/adk/webservice/A2ARemoteService.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.google.adk.webservice;
-
-import com.google.adk.a2a.A2ASendMessageExecutor;
-import com.google.adk.a2a.converters.ResponseConverter;
-import io.a2a.spec.JSONRPCError;
-import io.a2a.spec.Message;
-import io.a2a.spec.MessageSendParams;
-import io.a2a.spec.SendMessageRequest;
-import io.a2a.spec.SendMessageResponse;
-import java.util.List;
-import java.util.UUID;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-/**
- * Core service that bridges the A2A JSON-RPC sendMessage API to a local ADK runner.
- *
- *
**EXPERIMENTAL:** Subject to change, rename, or removal in any future patch release. Do not
- * use in production code.
- */
-@Service
-public class A2ARemoteService {
-
- private static final Logger logger = LoggerFactory.getLogger(A2ARemoteService.class);
- private static final int ERROR_CODE_INVALID_PARAMS = -32602;
- private static final int ERROR_CODE_INTERNAL_ERROR = -32603;
-
- private final A2ASendMessageExecutor executor;
-
- public A2ARemoteService(A2ASendMessageExecutor executor) {
- this.executor = executor;
- }
-
- public SendMessageResponse handle(SendMessageRequest request) {
- if (request == null) {
- logger.warn("Received null SendMessageRequest");
- return invalidParamsResponse(null, "Request body is missing");
- }
-
- MessageSendParams params = request.getParams();
- if (params == null) {
- logger.warn("SendMessageRequest {} missing params", request.getId());
- return invalidParamsResponse(request, "Request params are missing");
- }
-
- Message inbound = params.message();
- if (inbound == null) {
- logger.warn("SendMessageRequest {} missing message payload", request.getId());
- return invalidParamsResponse(request, "Request message payload is missing");
- }
-
- boolean generatedContext = inbound.getContextId() == null || inbound.getContextId().isEmpty();
- Message normalized = ensureContextId(inbound);
- if (generatedContext) {
- logger.debug("Incoming request lacked contextId; generated {}", normalized.getContextId());
- }
-
- try {
- Message result = executor.execute(normalized).blockingGet();
- if (result == null) {
- result =
- ResponseConverter.eventsToMessage(
- List.of(), normalized.getContextId(), normalized.getTaskId());
- }
-
- logger.debug("Returning A2A response for context {}", normalized.getContextId());
- return new SendMessageResponse(request.getId(), result);
- } catch (RuntimeException e) {
- logger.error("Failed to process remote A2A request", e);
- return errorResponse(request, e);
- }
- }
-
- private static Message ensureContextId(Message message) {
- if (message.getContextId() != null && !message.getContextId().isEmpty()) {
- return message;
- }
- return new Message.Builder(message).contextId(UUID.randomUUID().toString()).build();
- }
-
- private static SendMessageResponse invalidParamsResponse(
- SendMessageRequest request, String reason) {
- JSONRPCError error = new JSONRPCError(ERROR_CODE_INVALID_PARAMS, reason, null);
- return new SendMessageResponse(request != null ? request.getId() : null, error);
- }
-
- private static SendMessageResponse errorResponse(SendMessageRequest request, Throwable error) {
- String message = "Internal error processing sendMessage request";
- JSONRPCError jsonrpcError = new JSONRPCError(ERROR_CODE_INTERNAL_ERROR, message, null);
- return new SendMessageResponse(request != null ? request.getId() : null, jsonrpcError);
- }
-}
diff --git a/contrib/samples/a2a_remote/README.md b/contrib/samples/a2a_remote/README.md
deleted file mode 100644
index d1d2601ca..000000000
--- a/contrib/samples/a2a_remote/README.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# A2A Remote Prime Service Sample
-
-This sample starts a standalone Spring Boot service that exposes the
-`remote_prime_agent` via the shared A2A webservice module
-(`google-adk-a2a-webservice`). It behaves like a third‑party service that
-implements the A2A JSON‑RPC contract and can be used by the ADK client (for
-example, the `a2a_basic` demo) as its remote endpoint.
-
-## Running the service
-
-```bash
-cd google_adk
-mvn -f contrib/samples/a2a_remote/pom.xml package
-
-GOOGLE_GENAI_USE_VERTEXAI=FALSE \
-GOOGLE_API_KEY= \
-mvn -f contrib/samples/a2a_remote/pom.xml exec:java
-```
-
-`RemoteA2AApplication` imports the reusable controller/service from
-`google-adk-a2a-webservice`, so the server listens on
-`http://localhost:8080/a2a/remote/v1/message:send` by default. Override the
-port with `-Dspring-boot.run.arguments=--server.port=` when running via
-`spring-boot:run` if you need to avoid collisions.
-
-```
-POST /a2a/remote/v1/message:send
-Content-Type: application/json
-```
-
-and accepts standard A2A JSON‑RPC payloads (`SendMessageRequest`). The
-response is a `SendMessageResponse` that contains either a `Message` or a
-`Task` in the `result` field. Spring Boot logs the request/response lifecycle
-to the console; add your preferred logging configuration if you need
-persistent logs.
-
-## Agent implementation
-
-- `remote_prime_agent/Agent.java` hosts the LLM agent that checks whether
- numbers are prime (lifted from the Stubby demo). The model name defaults
- to `gemini-2.5-pro`; set `GOOGLE_API_KEY` before running.
-- `RemoteA2AApplication` bootstraps the service by importing
- `A2ARemoteConfiguration` and publishing the prime `BaseAgent` bean. The shared
- configuration consumes that bean to create the `A2ASendMessageExecutor`.
-
-## Sample request
-
-```bash
-curl -X POST http://localhost:8080/a2a/remote/v1/message:send \
- -H 'Content-Type: application/json' \
- -d '{
- "jsonrpc": "2.0",
- "id": "demo-123",
- "method": "message/send",
- "params": {
- "message": {
- "role": "user",
- "messageId": "msg-1",
- "contextId": "ctx-1",
- "parts": [
- {"kind": "text", "text": "Check if 17 is prime"}
- ]
- },
- "metadata": {}
- }
- }'
-```
-
-The response contains the prime check result, and the interaction is logged in
-the application console.
diff --git a/contrib/samples/a2a_remote/pom.xml b/contrib/samples/a2a_remote/pom.xml
deleted file mode 100644
index 59d9cf01e..000000000
--- a/contrib/samples/a2a_remote/pom.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-
-
- 4.0.0
-
-
- com.google.adk
- google-adk-parent
- 0.5.1-SNAPSHOT
- ../../../pom.xml
-
-
- google-adk-sample-a2a-remote
- Google ADK - Sample - A2A Remote Prime Service
- Spring Boot service that exposes the remote prime-check agent over the A2A REST interface.
- jar
-
-
- 3.3.4
- 17
- 0.8
- com.google.adk.samples.a2a_remote.RemoteA2AApplication
-
-
-
-
-
- org.springframework.boot
- spring-boot-dependencies
- ${spring-boot.version}
- pom
- import
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- com.google.adk
- google-adk
- ${project.version}
-
-
-
- com.google.adk
- google-adk-a2a
- ${project.version}
-
-
-
- com.google.adk
- google-adk-a2a-webservice
- ${project.version}
-
-
-
- com.google.flogger
- flogger
- ${flogger.version}
-
-
- com.google.flogger
- google-extensions
- ${flogger.version}
-
-
- com.google.flogger
- flogger-system-backend
- ${flogger.version}
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
- com.google.truth
- truth
- ${truth.version}
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
- ${spring-boot.version}
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
- 3.6.0
-
-
- add-source
- generate-sources
-
- add-source
-
-
-
- .
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
-
-
- **/*.jar
- target/**
-
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
- 3.2.0
-
- ${exec.mainClass}
- runtime
-
-
-
-
-
\ No newline at end of file
diff --git a/contrib/samples/a2a_remote/remote_prime_agent/Agent.java b/contrib/samples/a2a_remote/remote_prime_agent/Agent.java
deleted file mode 100644
index a0072e8e3..000000000
--- a/contrib/samples/a2a_remote/remote_prime_agent/Agent.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package com.google.adk.samples.a2a_remote.remote_prime_agent;
-
-import static java.util.stream.Collectors.joining;
-
-import com.google.adk.agents.LlmAgent;
-import com.google.adk.tools.FunctionTool;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.flogger.GoogleLogger;
-import io.reactivex.rxjava3.core.Maybe;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/** Agent that can check whether numbers are prime. */
-public final class Agent {
-
- private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
-
- public static ImmutableMap checkPrime(List nums) {
- logger.atInfo().log("checkPrime called with nums=%s", nums);
- Set primes = new HashSet<>();
- for (int num : nums) {
- if (num <= 1) {
- continue;
- }
- boolean isPrime = true;
- for (int i = 2; i <= Math.sqrt(num); i++) {
- if (num % i == 0) {
- isPrime = false;
- break;
- }
- }
- if (isPrime) {
- primes.add(num);
- }
- }
- String result;
- if (primes.isEmpty()) {
- result = "No prime numbers found.";
- } else if (primes.size() == 1) {
- int only = primes.iterator().next();
- // Per request: singular phrasing without article
- result = only + " is prime number.";
- } else {
- result = primes.stream().map(String::valueOf).collect(joining(", ")) + " are prime numbers.";
- }
- logger.atInfo().log("checkPrime result=%s", result);
- return ImmutableMap.of("result", result);
- }
-
- public static final LlmAgent ROOT_AGENT =
- LlmAgent.builder()
- .model("gemini-2.5-pro")
- .name("check_prime_agent")
- .description("check prime agent that can check whether numbers are prime.")
- .instruction(
- """
- You check whether numbers are prime.
-
- If the last user message contains numbers, call checkPrime exactly once with exactly
- those integers as a list (e.g., [2]). Never add other numbers. Do not ask for
- clarification. Return only the tool's result.
-
- Always pass a list of integers to the tool (use a single-element list for one
- number). Never pass strings.
- """)
- // Log the exact contents passed to the LLM request for verification
- .beforeModelCallback(
- (callbackContext, llmRequest) -> {
- try {
- logger.atInfo().log(
- "Invocation events (count=%d): %s",
- callbackContext.events().size(), callbackContext.events());
- } catch (Throwable t) {
- logger.atWarning().withCause(t).log("BeforeModel logging error");
- }
- return Maybe.empty();
- })
- .afterModelCallback(
- (callbackContext, llmResponse) -> {
- try {
- String content =
- llmResponse.content().map(Object::toString).orElse("");
- logger.atInfo().log("AfterModel content=%s", content);
- llmResponse
- .errorMessage()
- .ifPresent(
- error ->
- logger.atInfo().log(
- "AfterModel errorMessage=%s", error.replace("\n", "\\n")));
- } catch (Throwable t) {
- logger.atWarning().withCause(t).log("AfterModel logging error");
- }
- return Maybe.empty();
- })
- .tools(ImmutableList.of(FunctionTool.create(Agent.class, "checkPrime")))
- .build();
-
- private Agent() {}
-}
diff --git a/contrib/samples/a2a_remote/remote_prime_agent/agent.json b/contrib/samples/a2a_remote/remote_prime_agent/agent.json
deleted file mode 100644
index 87f2d9ecc..000000000
--- a/contrib/samples/a2a_remote/remote_prime_agent/agent.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "capabilities": {},
- "defaultInputModes": ["text/plain"],
- "defaultOutputModes": ["application/json"],
- "description": "An agent specialized in checking whether numbers are prime. It can efficiently determine the primality of individual numbers or lists of numbers.",
- "name": "check_prime_agent",
- "skills": [
- {
- "id": "prime_checking",
- "name": "Prime Number Checking",
- "description": "Check if numbers in a list are prime using efficient mathematical algorithms",
- "tags": ["mathematical", "computation", "prime", "numbers"]
- }
- ],
- "url": "http://localhost:8080/a2a/prime_agent",
- "version": "1.0.0"
-}
diff --git a/contrib/samples/a2a_remote/src/main/java/com/google/adk/samples/a2a_remote/RemoteA2AApplication.java b/contrib/samples/a2a_remote/src/main/java/com/google/adk/samples/a2a_remote/RemoteA2AApplication.java
deleted file mode 100644
index 53be8d1d0..000000000
--- a/contrib/samples/a2a_remote/src/main/java/com/google/adk/samples/a2a_remote/RemoteA2AApplication.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.google.adk.samples.a2a_remote;
-
-import com.google.adk.agents.BaseAgent;
-import com.google.adk.samples.a2a_remote.remote_prime_agent.Agent;
-import com.google.adk.webservice.A2ARemoteConfiguration;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Import;
-
-/** Spring Boot entry point that wires the shared A2A webservice with the prime demo agent. */
-@SpringBootApplication
-@Import(A2ARemoteConfiguration.class)
-public class RemoteA2AApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(RemoteA2AApplication.class, args);
- }
-
- @Bean
- public BaseAgent primeAgent() {
- return Agent.ROOT_AGENT;
- }
-}
diff --git a/contrib/samples/pom.xml b/contrib/samples/pom.xml
index fa5d6dfae..580b10de9 100644
--- a/contrib/samples/pom.xml
+++ b/contrib/samples/pom.xml
@@ -17,7 +17,6 @@
a2a_basic
- a2a_remoteconfigagenthelloworldmcpfilesystem
diff --git a/pom.xml b/pom.xml
index 6a1aa5af5..89f0d2c0f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,7 +37,6 @@
tutorials/city-time-weathertutorials/live-audio-single-agenta2a
- a2a/webservice