diff --git a/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/annotation/LlmTool.kt b/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/annotation/LlmTool.kt index 67640d811..d438d98c8 100644 --- a/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/annotation/LlmTool.kt +++ b/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/annotation/LlmTool.kt @@ -39,8 +39,8 @@ annotation class LlmTool( val returnDirect: Boolean = false, /** - * Optional category for use with [MatryoshkaTools]. - * When the containing class has `@MatryoshkaTools`, tools with the same category + * Optional category for use with [UnfoldingTools]. + * When the containing class has `@UnfoldingTools`, tools with the same category * are grouped together and exposed when that category is selected. * Leave empty for tools that should always be exposed. */ diff --git a/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/annotation/annotations.kt b/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/annotation/annotations.kt index 6771a07d1..cf068fae9 100644 --- a/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/annotation/annotations.kt +++ b/embabel-agent-api/src/main/kotlin/com/embabel/agent/api/annotation/annotations.kt @@ -47,7 +47,7 @@ annotation class EmbabelComponent( * It doesn't just contribute actions, goals and conditions: * it is an agent in itself. * This is a Spring stereotype annotation, so annotated classes will be picked up on the classpath and injected - * Either @Agent or @AgentCapabilities should be used: not both + * Use either @Agent or @EmbabelComponent, not both. * @param name Name of the agent. If not provided, the name will be the class simple name * @param provider provider of the agent. If not provided, will default to the package this annotation is used in * @param description Description of the agent. Required. This is used for documentation purposes and to choose an agent diff --git a/embabel-agent-api/src/main/kotlin/com/embabel/agent/spi/loop/support/ParallelToolLoop.kt b/embabel-agent-api/src/main/kotlin/com/embabel/agent/spi/loop/support/ParallelToolLoop.kt index 785e0010b..2faf6134e 100644 --- a/embabel-agent-api/src/main/kotlin/com/embabel/agent/spi/loop/support/ParallelToolLoop.kt +++ b/embabel-agent-api/src/main/kotlin/com/embabel/agent/spi/loop/support/ParallelToolLoop.kt @@ -40,11 +40,10 @@ import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit import java.util.concurrent.TimeoutException import javax.annotation.concurrent.ThreadSafe -import org.jetbrains.annotations.ApiStatus import org.slf4j.LoggerFactory /** - * Experimental [com.embabel.agent.spi.loop.ToolLoop] implementation that executes + * [com.embabel.agent.spi.loop.ToolLoop] implementation that executes * multiple tool calls from a single LLM response in parallel. * * Reduces latency for I/O-bound tool operations by running independent tools concurrently. @@ -66,7 +65,6 @@ import org.slf4j.LoggerFactory * @param parallelConfig Configuration for parallel mode (timeouts, etc.) */ @ThreadSafe -@ApiStatus.Experimental internal class ParallelToolLoop( llmMessageSender: LlmMessageSender, objectMapper: ObjectMapper, diff --git a/embabel-agent-docs/src/main/asciidoc/reference/diagrams/architecture/embabel_agent_platform_model.dot b/embabel-agent-docs/src/main/asciidoc/reference/diagrams/architecture/embabel_agent_platform_model.dot index ffa2bdd89..a13f3b75d 100644 --- a/embabel-agent-docs/src/main/asciidoc/reference/diagrams/architecture/embabel_agent_platform_model.dot +++ b/embabel-agent-docs/src/main/asciidoc/reference/diagrams/architecture/embabel_agent_platform_model.dot @@ -13,7 +13,7 @@ digraph AgentPlatformModel { AgentAnnotation [fillcolor=pink, label="@Agent\n(Component annotation)"]; ActionAnnotation [fillcolor=lightgrey, label="@action\n(Method annotation)"]; ConditionAnnotation [fillcolor=lightcyan, label="@condition\n(Method annotation)"]; - CapabilitiesAnnotation [fillcolor=lavender, label="@AgentCapabilities\n(Shared capabilities)"]; + CapabilitiesAnnotation [fillcolor=lavender, label="@EmbabelComponent\n(Shared capabilities)"]; // Configuration ProcessOptions [fillcolor=lightpink, label="ProcessOptions\n(Runtime configuration)"]; @@ -68,4 +68,4 @@ digraph AgentPlatformModel { // Additional platform relationships AgentPlatform -> AgentScope [label="acts as superset", style="dashed"]; ProcessStatus -> AgentProcess [label="reports on", dir="back", style="dashed"]; -} \ No newline at end of file +} diff --git a/embabel-agent-docs/src/main/asciidoc/reference/rag/page.adoc b/embabel-agent-docs/src/main/asciidoc/reference/rag/page.adoc index af6d1e745..1df7909d6 100644 --- a/embabel-agent-docs/src/main/asciidoc/reference/rag/page.adoc +++ b/embabel-agent-docs/src/main/asciidoc/reference/rag/page.adoc @@ -632,7 +632,7 @@ Java:: [source,java] ---- import com.embabel.agent.rag.filter.EntityFilter; -import com.embabel.agent.rag.filter.PropertyFilter; +import com.embabel.agent.filter.PropertyFilter; // Filter by single label EntityFilter personFilter = EntityFilter.hasAnyLabel("Person"); @@ -672,8 +672,8 @@ Kotlin:: [source,kotlin] ---- import com.embabel.agent.rag.filter.EntityFilter -import com.embabel.agent.rag.filter.PropertyFilter.Companion.eq -import com.embabel.agent.rag.filter.PropertyFilter.Companion.gte +import com.embabel.agent.filter.PropertyFilter.Companion.eq +import com.embabel.agent.filter.PropertyFilter.Companion.gte // Filter by single label val personFilter = EntityFilter.hasAnyLabel("Person") @@ -728,7 +728,7 @@ Java:: + [source,java] ---- -import com.embabel.agent.rag.filter.PropertyFilter; +import com.embabel.agent.filter.PropertyFilter; // Simple filter with not operator PropertyFilter notDeleted = PropertyFilter.not(PropertyFilter.eq("status", "deleted")); @@ -753,9 +753,9 @@ Kotlin:: + [source,kotlin] ---- -import com.embabel.agent.rag.filter.PropertyFilter.Companion.eq -import com.embabel.agent.rag.filter.PropertyFilter.Companion.gte -import com.embabel.agent.rag.filter.PropertyFilter.Companion.ne +import com.embabel.agent.filter.PropertyFilter.Companion.eq +import com.embabel.agent.filter.PropertyFilter.Companion.gte +import com.embabel.agent.filter.PropertyFilter.Companion.ne // Simple filter with not operator val notDeleted = !eq("status", "deleted") diff --git a/embabel-agent-docs/src/main/asciidoc/reference/tools/page.adoc b/embabel-agent-docs/src/main/asciidoc/reference/tools/page.adoc index 26667f99d..c71214e75 100644 --- a/embabel-agent-docs/src/main/asciidoc/reference/tools/page.adoc +++ b/embabel-agent-docs/src/main/asciidoc/reference/tools/page.adoc @@ -3632,7 +3632,7 @@ val tool = UnfoldingTool.fromToolObject( ---- ==== -All standard options are available: +Use the same factory when you need to wrap a tool object with an explicit facade name and description: [tabs] ==== @@ -3643,9 +3643,7 @@ Java:: var tool = UnfoldingTool.fromToolObject( fileTools, "file_write_tools", - "Tools for writing and managing files.", - false, // removeOnInvoke - "Use writeFile for new files, appendFile for existing ones." // childToolUsageNotes + "Tools for writing and managing files." ); ---- @@ -3657,8 +3655,6 @@ val tool = UnfoldingTool.fromToolObject( instance = fileTools, name = "file_write_tools", description = "Tools for writing and managing files.", - removeOnInvoke = false, - childToolUsageNotes = "Use writeFile for new files, appendFile for existing ones.", ) ---- ==== @@ -4737,10 +4733,10 @@ val webTool = mcpToolFactory.unfolding( ---- ==== -===== Controlling Facade Removal +===== Facade Replacement -After invocation, `UnfoldingTool` facades created by `McpToolFactory` are replaced by a guide tool and their inner tools. -The `removeOnInvoke` parameter is deprecated and ignored: +After the LLM invokes an MCP-backed `UnfoldingTool`, Embabel always replaces the facade with a guide tool and the matching inner tools. +Use the overloads that do not pass `removeOnInvoke`. [tabs] ==== @@ -4748,12 +4744,10 @@ Java:: + [source,java] ---- -// Keep facade even after invocation -var persistentTool = mcpToolFactory.unfoldingByName( +var wikipediaTool = mcpToolFactory.unfoldingByName( "wikipedia", "Search Wikipedia", - Set.of("search_wikipedia", "get_article"), - false // removeOnInvoke = false + Set.of("search_wikipedia", "get_article") ); ---- @@ -4761,16 +4755,16 @@ Kotlin:: + [source,kotlin] ---- -// Keep facade even after invocation -val persistentTool = mcpToolFactory.unfoldingByName( +val wikipediaTool = mcpToolFactory.unfoldingByName( name = "wikipedia", description = "Search Wikipedia", toolNames = setOf("search_wikipedia", "get_article"), - removeOnInvoke = false ) ---- ==== +Passing the deprecated `removeOnInvoke` parameter has no effect. + ===== Real-World Example: Chatbot with MCP Tools Here's a real-world example from a production chatbot that uses `McpToolFactory` to integrate MCP tools with graceful degradation: