Files
Kristopher Overholt 1f2147bfff Add Kotlin language support to ADK docs (#1768)
* Add Kotlin to hero / front page

* Add quickstart page for Kotlin

* Complete Kotlin quickstart guide and fix hero code sample (#2)

* Replace GitHub repo links with language icons in header (#3)

* Fix header icon FOUC and homepage font weight regression (#4)

* Testing staging pipeline

* Revert test edit (for staging pipeline)

* Update language icon tooltips to indicate GitHub destination (#5)

* Add link to ADK Kotlin release notes (#7)

* Initial commit of ADK Kotlin API reference docs (#6)

* Add script to generate ADK Kotlin API reference docs (#8)

* Update links and link checker ignore list (temporarily) (#9)

* Add ADK Kotlin for Android getting started guide to Advanced setup page (#10)

* Add advanced setup page with steps to "Use ADK Kotlin in Android projects"

* Update temp link checker rules

* Add placeholder folder for adk-samples (#13)

* adding linter/compilation checks for kotlin snippets (#12)

* adding linter/compilation checks for kotlin snippets

* Add Kotlin validation scripts

* Initial commit of Kotlin sample agents for adk-samples (#15)

* Adding kotlin snippet for llm agents (#16)

* Adding kotlin snippets to  Events (#17)

* Pull changes to docs/events/index.md from glaforge-kotlin-snippets

* fixing kotlin event timestamp and longRunningToolIds

* Fix language tags (#19)

* Fix language tags

* Update

* Fix wrapping

* Fix wrapping (again)

* Fix wrapping/format

* Fix language tag on integration page

* Enable check_paths in PyMdown Snippets Extension to make the build fail if a snippet can't be found (#20)

* Update mkdocs config (#21)

* Fix broken links, update URLs to adk.dev, and improve (temp) lychee config (#22)

* Add Kotlin/maven badge to README (#23)

* Adding Kotlin snippets for artifacts  (#18)

* Pull Kotlin snippets for artifacts from glaforge-kotlin-snippets

* Add comprehensive Kotlin snippets for artifacts

* Refactor artifacts documentation to use external Kotlin snippets

* Update Kotlin model to gemini-flash-latest

* Fix GCS initialization in Kotlin artifact snippet

* afixi failing test with capital-agent added to files_to_check

* Fix snippet label syntax for MkDocs build

* Configure proper Gradle project for Kotlin snippets and fix dependencies

* Add KSP support and generated sources to Kotlin snippets build

* fixing capital_agent turnComplete

* Fix syntax error in build.gradle.kts by removing invalid placeholders (#25)

* Adding Kotlin snippets to google-gemini.md (#27)

Pulling kotlin changes to google-gemini.md from glaforge-kotlin-snippets

* Add a warning about not adding an api key to production code. (#28)

* Add a warning about not adding an api key to production code.

* Update note

---------

Co-authored-by: Kristopher Overholt <koverholt@google.com>

* Add ADK Demo App sample showcasing Gemini-powered agents (#29)

This sample demonstrates how to use the Google ADK (Agent Development Kit) in an Android application to create a chat interface powered by a Gemini-based "Fun Facts" agent. The implementation features:
*   Integration with the Kotlin ADK core and processor libraries.
*   A `FunFactsAgent` defined using `LlmAgent` and the Gemini model.
*   A `ChatViewModel` utilizing `InMemoryRunner` for asynchronous message streaming.
*   A modern UI built with Jetpack Compose and Material 3.
*   Build configuration logic for secure API key management via environment variables or `local.properties`.

* Update Kotlin docs and samples to align with adk-kotlin API changes (#30)

Rename GeminiModel to Gemini, @AdkTool/@AdkParam to @Tool/@Param,
adkTools() to generatedTools(), replace DebugRunner with InMemoryRunner,
fix AgentLoader import path, use SingleAgentLoader, bump Kotlin to
2.3.21 and KSP to 2.3.7, and update Android minSdk from 24 to 26.

* adding kotlin info to READMEs (#14)

* Reorganize Android sample agent and add READMEs (#31)

* Move Android sample agent

* Update repo README, add Android README, update sample agent README

* Minor edit to language support tags (#32)

* Remove blog post link (#33)

Will re-add after it's published

* Remove examples link (#34)

* Adding Kotlin snippets for Sessions docs (#26)

* initial kotlins snippets additions to sessions docs

* Updating memory docs with kotlin snippets

* Adding kotlin snippets to session state docs.

* update model to gemini-flash-latest

* sessions examples clean-up

* fixing sessions snippet markers

* adding kotlin session snippets to files to test

* adding callback to memory_example

* Fixing capital agent snippet  (#35)

Fixing file name
Updating adkTool > Tool
Updating GeminiModel > Gemini

* Adding kotlin snippets for tools docs (#36)

* adding function tool kotlin snippets

* adding function_tools snippets to files to test

* Adding kotlin snippets to observability docs (#37)

* initial kotlin observability updates

* adding observability snippets to file check (#38)

* Adding Kotlin snippets to Callbacks docs (#39)

*  kotlin callbacks snippets

* adding callbacks snippets to file check

* Align Kotlin and KSP versions with published 0.1.0 artifacts (#40)

* switch CLI entry points from InMemoryRunner to ReplRunner (#41)

* Switch CLI entry points from InMemoryRunner to ReplRunner

* Fix wording

* Update API reference docs for Kotlin, 2026-05-18 (#42)

* Remove ADK on Android note until published (#43)

* Update Kotlin code samples (#44)

* Rename GeminiModel to Gemini in Kotlin snippets and docs

* Remove broken SessionKey call and use sessionId directly in AgentTool snippet

* Rewrite Go hero snippet to use llmagent API

* Use isFinalResponse with safe access in CapitalAgent snippet

* Use Role.USER constant instead of raw string in SetupExample

* Use full semver v0.1.0 in Kotlin language support tags

* Remove Android setup steps, moving to new property (#45)

* Tutorial Kotlin agent (#46)

* Adding multi-tool-agent snippet and updating tutorial
* Fixing Go language order on tutorial page
* adding multi tool agent example to files to test

* Inline Kotlin get-started code sample

* Kotlin Multi agents snippets (#47)

* Multi-agent kotlin snippets

* Fixing docs tags in multiagent example

* Fix Kotlin language support tags, code samples, and google-gemini.md cleanup (#48)

* Add Kotlin v0.1.0 to language support tags across docs

* Fix MultiToolAgent.kt model string and argument style

* Update MultiAgentExample.kt to use gemini-flash-latest model string

* Fix google-gemini.md: add Kotlin sample, remove unsupported Java tabs

* Remove explicit apiKey from CallbackBasic.kt for consistency

* Standardize Gemini() constructor to use named args in all snippets

* Remove adk-samples directory (moved to google/adk-samples#1969)

* Remove adk-samples directory (moved to google/adk-samples#1969) (#49)

* Update API reference docs for ADK Kotlin 0.1.0 (#50)

* Remove adk-samples directory (moved to google/adk-samples#1969)

* Update API reference docs for ADK Kotlin 0.1.0

* Remove kotlin lycheeignore config (#51)

* Remove adk-samples directory (moved to google/adk-samples#1969)

* Remove Kotlin .lycheeignore config links

---------

Co-authored-by: Toni Klopfenstein <2359976+ToniCorinne@users.noreply.github.com>
Co-authored-by: Jolanda Verhoef <JolandaVerhoef@users.noreply.github.com>
2026-05-19 18:24:40 +00:00

11 KiB

Limitations for ADK tools

Some ADK tools have limitations that can impact how you implement them within an agent workflow. This page lists these tool limitations and workarounds, if available.

One tool per agent limitation

!!! note "ONLY for Search in ADK Python v1.15.0 and lower"

This limitation only applies to the use of Google Search and Agent Search
tools in ADK Python v1.15.0 and lower. ADK Python release v1.16.0 and higher
provides a built-in workaround to remove this limitation.

In general, you can use more than one tool in an agent, but use of specific tools within an agent excludes the use of any other tools in that agent. The following ADK Tools can only be used by themselves, without any other tools, in a single agent object:

  • Code Execution with Gemini API (Note: in TypeScript, this requires Gemini 2.0+ and does not have this limitation)
  • Google Search with Gemini API (Note: limitation only applies to Gemini 1.x models in TypeScript)
  • Agent Search (Note: currently unavailable in TypeScript)

For example, the following approach that uses one of these tools along with other tools, within a single agent, is not supported:

=== "Python"

```py
root_agent = Agent(
    name="RootAgent",
    model="gemini-flash-latest",
    description="Code Agent",
    tools=[custom_function],
    code_executor=BuiltInCodeExecutor() # <-- NOT supported when used with tools
)
```

=== "TypeScript"

```typescript
import {Agent, BuiltInCodeExecutor} from '@google/adk';

const rootAgent = new Agent({
  name: 'RootAgent',
  model: 'gemini-flash-latest',
  description: 'Code Agent',
  tools: [myCustomTool], // Assume myCustomTool is defined
  codeExecutor: new BuiltInCodeExecutor(), // <-- NOT supported when used with tools
});
```

=== "Java"

```java
 LlmAgent searchAgent =
        LlmAgent.builder()
            .model(MODEL_ID)
            .name("SearchAgent")
            .instruction("You're a specialist in Google Search")
            .tools(new GoogleSearchTool(), new YourCustomTool()) // <-- NOT supported
            .build();
```

=== "Kotlin"

```kotlin
val searchAgent = LlmAgent(
    name = "SearchAgent",
    model = Gemini(name = "gemini-flash-latest"),
    instruction = Instruction("You're a specialist in Google Search"),
    tools = listOf(GoogleSearchTool(), YourCustomTool()) // <-- NOT supported
)
```

Workaround #1: AgentTool.create() method

Supported in ADKPythonTypeScript (v0.6.1+)JavaKotlin v0.1.0

The following code sample demonstrates how to use multiple built-in tools or how to use built-in tools with other tools by using multiple agents:

=== "Python"

```py
from google.adk.tools.agent_tool import AgentTool
from google.adk.agents import Agent
from google.adk.tools import google_search
from google.adk.code_executors import BuiltInCodeExecutor

search_agent = Agent(
    model='gemini-flash-latest',
    name='SearchAgent',
    instruction="""
    You're a specialist in Google Search
    """,
    tools=[google_search],
)
coding_agent = Agent(
    model='gemini-flash-latest',
    name='CodeAgent',
    instruction="""
    You're a specialist in Code Execution
    """,
    code_executor=BuiltInCodeExecutor(),
)
root_agent = Agent(
    name="RootAgent",
    model="gemini-flash-latest",
    description="Root Agent",
    tools=[AgentTool(agent=search_agent), AgentTool(agent=coding_agent)],
)
```

=== "TypeScript"

```typescript
import {Agent, AgentTool, BuiltInCodeExecutor, GOOGLE_SEARCH} from '@google/adk';

const searchAgent = new Agent({
  model: 'gemini-flash-latest',
  name: 'SearchAgent',
  instruction: "You're a specialist in Google Search",
  tools: [GOOGLE_SEARCH],
});

const codingAgent = new Agent({
  model: 'gemini-flash-latest', // Built-in code execution requires Gemini 2.0+ in ADK JS
  name: 'CodeAgent',
  instruction: "You're a specialist in Code Execution",
  codeExecutor: new BuiltInCodeExecutor(),
});

const rootAgent = new Agent({
  name: 'RootAgent',
  model: 'gemini-flash-latest',
  description: 'Root Agent',
  tools: [new AgentTool({agent: searchAgent}), new AgentTool({agent: codingAgent})],
});
```

=== "Java"

```java
import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.tools.AgentTool;
import com.google.adk.tools.BuiltInCodeExecutionTool;
import com.google.adk.tools.GoogleSearchTool;
import com.google.common.collect.ImmutableList;

public class NestedAgentApp {

  private static final String MODEL_ID = "gemini-flash-latest";

  public static void main(String[] args) {

    // Define the SearchAgent
    LlmAgent searchAgent =
        LlmAgent.builder()
            .model(MODEL_ID)
            .name("SearchAgent")
            .instruction("You're a specialist in Google Search")
            .tools(new GoogleSearchTool()) // Instantiate GoogleSearchTool
            .build();


    // Define the CodingAgent
    LlmAgent codingAgent =
        LlmAgent.builder()
            .model(MODEL_ID)
            .name("CodeAgent")
            .instruction("You're a specialist in Code Execution")
            .tools(new BuiltInCodeExecutionTool()) // Instantiate BuiltInCodeExecutionTool
            .build();

    // Define the RootAgent, which uses AgentTool.create() to wrap SearchAgent and CodingAgent
    BaseAgent rootAgent =
        LlmAgent.builder()
            .name("RootAgent")
            .model(MODEL_ID)
            .description("Root Agent")
            .tools(
                AgentTool.create(searchAgent), // Use create method
                AgentTool.create(codingAgent)   // Use create method
             )
            .build();

    // Note: This sample only demonstrates the agent definitions.
    // To run these agents, you'd need to integrate them with a Runner and SessionService,
    // similar to the previous examples.
    System.out.println("Agents defined successfully:");
    System.out.println("  Root Agent: " + rootAgent.name());
    System.out.println("  Search Agent (nested): " + searchAgent.name());
    System.out.println("  Code Agent (nested): " + codingAgent.name());
  }
}
```

=== "Kotlin"

```kotlin
--8<-- "examples/kotlin/snippets/tools/LimitationsWorkaround.kt:workaround_1"
```

Workaround #2: bypass_multi_tools_limit

Supported in ADKPythonJavaKotlin v0.1.0

ADK Python has a built-in workaround which bypasses this limitation for GoogleSearchTool and VertexAiSearchTool (use bypass_multi_tools_limit=True to enable it), as shown in the built_in_multi_tools. sample agent.

!!! warning

Built-in tools cannot be used within a sub-agent, with the exception of
`GoogleSearchTool` and `VertexAiSearchTool` in ADK Python because of the
workaround mentioned above.

For example, the following approach that uses built-in tools within sub-agents is not supported:

=== "Python"

```py
url_context_agent = Agent(
    model='gemini-flash-latest',
    name='UrlContextAgent',
    instruction="""
    You're a specialist in URL Context
    """,
    tools=[url_context],
)
coding_agent = Agent(
    model='gemini-flash-latest',
    name='CodeAgent',
    instruction="""
    You're a specialist in Code Execution
    """,
    code_executor=BuiltInCodeExecutor(),
)
root_agent = Agent(
    name="RootAgent",
    model="gemini-flash-latest",
    description="Root Agent",
    sub_agents=[
        url_context_agent,
        coding_agent
    ],
)
```

=== "TypeScript"

```typescript
import {Agent, BuiltInCodeExecutor} from '@google/adk';

const urlContextAgent = new Agent({
  model: 'gemini-flash-latest',
  name: 'UrlContextAgent',
  instruction: "You're a specialist in URL Context",
  tools: [myCustomTool], // Assume myCustomTool is defined
});

const codingAgent = new Agent({
  model: 'gemini-flash-latest',
  name: 'CodeAgent',
  instruction: "You're a specialist in Code Execution",
  codeExecutor: new BuiltInCodeExecutor(),
});

const rootAgent = new Agent({
  name: 'RootAgent',
  model: 'gemini-flash-latest',
  description: 'Root Agent',
  subAgents: [urlContextAgent, codingAgent], // NOT supported when sub-agents use built-in tools
});
```

=== "Java"

```java
LlmAgent searchAgent =
    LlmAgent.builder()
        .model("gemini-flash-latest")
        .name("SearchAgent")
        .instruction("You're a specialist in Google Search")
        .tools(new GoogleSearchTool())
        .build();

LlmAgent codingAgent =
    LlmAgent.builder()
        .model("gemini-flash-latest")
        .name("CodeAgent")
        .instruction("You're a specialist in Code Execution")
        .tools(new BuiltInCodeExecutionTool())
        .build();


LlmAgent rootAgent =
    LlmAgent.builder()
        .name("RootAgent")
        .model("gemini-flash-latest")
        .description("Root Agent")
        .subAgents(searchAgent, codingAgent) // Not supported, as the sub agents use built in tools.
        .build();
```

=== "Kotlin"

```kotlin
val searchAgent = LlmAgent(
    model = Gemini(name = "gemini-flash-latest"),
    name = "SearchAgent",
    instruction = Instruction("You're a specialist in Google Search"),
    tools = listOf(GoogleSearchTool())
)

val codingAgent = LlmAgent(
    model = Gemini(name = "gemini-flash-latest"),
    name = "CodeAgent",
    instruction = Instruction("You're a specialist in Code Execution")
    // Kotlin currently doesn't have a BuiltInCodeExecutionTool in core
)


val rootAgent = LlmAgent(
    name = "RootAgent",
    model = Gemini(name = "gemini-flash-latest"),
    description = "Root Agent",
    subAgents = listOf(searchAgent, codingAgent) // Not supported when sub-agents use built-in tools
)
```