Skip to content

BaseToolset caches prefixed tools by a single invocation ID, breaking multi-agent concurrency #5721

@chriskinzel

Description

@chriskinzel

Description

In google.adk.tools.base_toolset.BaseToolset, prefixed tool wrappers are cached using a single instance variable self._cached_invocation_id.

When orchestrating multiple agents concurrently (e.g., via ParallelAgent or custom asyncio.TaskGroup harnesses), concurrent worker coroutines call get_tools(invocation_id="worker_N"). Because self._cached_invocation_id only stores the last caller's ID, concurrent workers constantly overwrite each other's cached ID. This results in a cache miss on every single turn, forcing redundant tool wrapper re-instantiations and causing severe lock contention.

Proposed Solution

Refactor self._cached_prefixed_tools to be a dictionary keyed by invocation_id:

self._cached_prefixed_tools: dict[Optional[str], list[BaseTool]] = {}

When get_tools is called, check if invocation_id in self._cached_prefixed_tools and return the cached list for that specific agent thread. Ensure close() clears the dictionary (self._cached_prefixed_tools.clear()).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions