Unfolding Tool
A ProgressiveTool with a fixed set of inner tools that are revealed when invoked, regardless of the agent process context.
This pattern is useful for:
Reducing tool set complexity for the LLM
Grouping related tools under a category facade
Progressive disclosure based on LLM intent
Progressive disclosure: parent description + childToolUsageNotes
Information about an UnfoldingTool reaches the LLM in two stages:
Up front, the parent tool's
descriptionis in the catalog. It advertises the capability so the LLM can decide whether to descend. Keep this short — every loaded UnfoldingTool pays for it on every turn.On invocation, the unfolded message returned by call lists the revealed inner tools and then appends childToolUsageNotes verbatim. Only the LLM that just chose to descend pays for this text. It can therefore be as long as needed: workflow guidance, the body of an agent skill, "use X for Y, Z for W" routing rules between siblings, background context the inner tools need to be used correctly.
The split is deliberate. Putting the same content in description would tax every turn, even ones that have nothing to do with this tool. Putting it in childToolUsageNotes defers the cost until the LLM has committed.
Context Preservation
When an UnfoldingTool is expanded, a context tool can be created that preserves the parent's description and optional usage notes. This solves the problem where child tools would lose context about the parent's purpose.
Example:
val spotifyTool = UnfoldingTool.of(
name = "spotify_search",
description = "Search Spotify for music data including artists, albums, and tracks.",
innerTools = listOf(vectorSearchTool, textSearchTool, regexSearchTool),
childToolUsageNotes = "Try vector search first for semantic queries like 'upbeat jazz'. " +
"Use text search for exact artist or album names. " +
"Use regex search for pattern matching on metadata."
)See also
for context-dependent tool revelation
Inheritors
Properties
Detail that is progressively disclosed: hidden until the LLM invokes this tool, then appended verbatim to the unfolded message returned by call (after the "Tools now available: …" preamble).
Tool definition for LLM
When true, expanding this tool removes ALL other tools from the LLM's tool set — the LLM will only see the inner tools until the interaction ends. Use this for tools where the LLM consistently picks the wrong sibling tool instead of using the inner tools (e.g., personality changes).
The inner tools that will be exposed when this tool is invoked. This is a fixed set that does not vary by context.
Optional metadata
Whether to remove this tool after invocation.
Functions
Execute the tool with JSON input.
Execute the tool with JSON input and out-of-band context.
Returns the fixed innerTools regardless of process context.
Select which inner tools to expose based on invocation input.
Extension function to convert an Embabel Tool to a Spring AI ToolCallback.
Wrap this tool to conditionally await before execution.
Wrap this tool to always require confirmation before execution.
Create a new tool with additional definition metadata entries merged in. Existing keys are overwritten by the new values.
Create a new tool with a single definition metadata entry added.
Create a new tool with a different description. Useful for providing context-specific descriptions while keeping the same functionality.
Extension function to wrap a Tool with event publication.
Create a new UnfoldingTool with tools added from an annotated object.
Create a new UnfoldingTool with additional tools added.