Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)"];
Expand Down Expand Up @@ -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"];
}
}
14 changes: 7 additions & 7 deletions embabel-agent-docs/src/main/asciidoc/reference/rag/page.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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"));
Expand All @@ -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")
Expand Down
26 changes: 10 additions & 16 deletions embabel-agent-docs/src/main/asciidoc/reference/tools/page.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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]
====
Expand All @@ -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."
);
----

Expand All @@ -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.",
)
----
====
Expand Down Expand Up @@ -4737,40 +4733,38 @@ 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]
====
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")
);
----

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:
Expand Down
Loading