### Running Embabel Example from Shell Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Instructions to run the rag-demo project. This involves starting the shell, ingesting a document, and initiating a chat. ```bash ./scripts/shell.sh # In the shell: ingest ./data/document.md chat > What does the document say about... ``` -------------------------------- ### Clone and Run Embabel Examples Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Clone the Embabel agent examples repository and run the provided shell scripts to quickly get started. ```bash # Clone and run examples git clone https://github.com/embabel/embabel-agent-examples cd embabel-agent-examples/scripts/java ./shell.sh ``` -------------------------------- ### Create Story with Example Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Use `withExample` to provide a sample JSON object to guide the LLM in creating a story. This helps the LLM understand the desired output format and content. ```kotlin val story = context.ai() .withDefaultLlm() .withToolGroup(CoreToolGroups.WEB) .creating(Story::class.java) .withExample("A children's story", Story("Once upon a time...")) .fromPrompt("Create a story about: ${input.content}") ``` -------------------------------- ### Create Story with Few-Shot Example (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates adding a strongly typed example for few-shot prompting when creating a Story object in Java. This helps guide the LLM's response generation. ```java var story = context.ai() .withDefaultLlm() .withToolGroup(CoreToolGroups.WEB) .creating(Story.class) .withExample("A children's story", new Story("Once upon a time...")) __**(1)** .fromPrompt("Create a story about: " + input.getContent()); ``` -------------------------------- ### Create and Start Agent Process Programmatically (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates how to create an agent process with bindings, start it, and retrieve the result synchronously or asynchronously in Kotlin. Requires an AgentPlatform instance and a defined agent. ```kotlin // Create an agent process with bindings val agentProcess = agentPlatform.createAgentProcess( agent = myAgent, processOptions = ProcessOptions(), bindings = mapOf("input" to userRequest) ) // Start the process and wait for completion val result = agentPlatform.start(agentProcess).get() // Or run synchronously val completedProcess = agentProcess.run() val result = completedProcess.last() ``` -------------------------------- ### Create and Start Agent Process Programmatically (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates how to create an agent process with bindings, start it, and retrieve the result synchronously or asynchronously in Java. Requires an AgentPlatform instance and a defined agent. ```java // Create an agent process with bindings AgentProcess agentProcess = agentPlatform.createAgentProcess( myAgent, new ProcessOptions(), Map.of("input", userRequest) ); // Start the process and wait for completion Object result = agentPlatform.start(agentProcess).get(); // Or run synchronously AgentProcess completedProcess = agentProcess.run(); MyResultType result = completedProcess.last(MyResultType.class); ``` -------------------------------- ### Creating and Running an AgentProcess Programmatically Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates how to create an agent process with specific options and bindings, then start it synchronously or asynchronously. ```APIDOC ## Create and Run AgentProcess ### Description This section shows how to programmatically create an agent process using the `AgentPlatform`. You can configure the process with `ProcessOptions` and provide input bindings. The process can then be started and its result retrieved. ### Method `AgentPlatform.createAgentProcess` followed by `AgentPlatform.start` or `AgentProcess.run`. ### Endpoint N/A (Programmatic API) ### Parameters #### AgentPlatform.createAgentProcess - **agent** (Agent) - Required - The agent to create a process for. - **processOptions** (ProcessOptions) - Required - Options to configure the agent process. - **bindings** (Map) - Required - A map of input bindings for the agent. #### AgentPlatform.start - **agentProcess** (AgentProcess) - Required - The agent process to start. #### AgentProcess.run (No parameters) ### Request Example ```java // Java Example AgentProcess agentProcess = agentPlatform.createAgentProcess( myAgent, new ProcessOptions(), Map.of("input", userRequest) ); // Asynchronous execution Object result = agentPlatform.start(agentProcess).get(); // Synchronous execution AgentProcess completedProcess = agentProcess.run(); MyResultType result = completedProcess.last(MyResultType.class); ``` ```kotlin // Kotlin Example val agentProcess = agentPlatform.createAgentProcess( agent = myAgent, processOptions = ProcessOptions(), bindings = mapOf("input" to userRequest) ) // Asynchronous execution val result = agentPlatform.start(agentProcess).get() // Synchronous execution val completedProcess = agentProcess.run() val result = completedProcess.last() ``` ### Response #### Success Response - **result** (Object or specific type) - The result of the agent process execution. #### Response Example ```json { "example": "result of agent execution" } ``` ``` ```APIDOC ## Create AgentProcess from Varargs ### Description This method allows creating an agent process by passing input objects directly as varargs, simplifying the input binding process, especially in web controller scenarios. ### Method `AgentPlatform.createAgentProcessFrom`. ### Endpoint N/A (Programmatic API) ### Parameters #### AgentPlatform.createAgentProcessFrom - **agent** (Agent) - Required - The agent to create a process for. - **processOptions** (ProcessOptions) - Required - Options to configure the agent process. - **varargs** (Object...) - Required - Input objects to be used as bindings for the agent. ### Request Example ```java // Java Example AgentProcess agentProcess = agentPlatform.createAgentProcessFrom( travelAgent, new ProcessOptions(), travelRequest, userPreferences ); ``` ```kotlin // Kotlin Example val agentProcess = agentPlatform.createAgentProcessFrom( agent = travelAgent, processOptions = ProcessOptions(), travelRequest, userPreferences ) ``` ### Response (No specific response details provided for this creation method, the `AgentProcess` object is returned.) ``` ```APIDOC ## Type-Safe Agent Invocation with AgentInvocation ### Description `AgentInvocation` offers a higher-level, type-safe API for invoking agents. It intelligently selects the appropriate agent based on the expected return type, simplifying the invocation process. ### Method `AgentInvocation.create` followed by `AgentInvocation.invoke`. ### Endpoint N/A (Programmatic API) ### Parameters #### AgentInvocation.create - **agentPlatform** (AgentPlatform) - Required - The agent platform instance. - **resultType** (Class) - Required - The expected class type of the invocation result. #### AgentInvocation.invoke - **input** (Object) - Required - The input for the agent invocation. ### Request Example ```java // Java Example var invocation = AgentInvocation.create(agentPlatform, TravelPlan.class); TravelPlan plan = invocation.invoke(travelRequest); ``` ```kotlin // Kotlin Example val invocation: AgentInvocation = AgentInvocation.create(agentPlatform) val plan = invocation.invoke(travelRequest) ``` ### Response #### Success Response - **plan** (TravelPlan or specified type) - The result of the agent invocation. #### Response Example ```json { "example": "Travel plan details" } ``` ``` -------------------------------- ### Capturing All Artifacts with publishToBlackboard in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of capturing all artifacts from a tool and publishing them to the blackboard using Java. ```Java // Capture all artifacts and publish to blackboard Tool wrapped = Tool.publishToBlackboard(myTool); ``` -------------------------------- ### Capturing All Artifacts with publishToBlackboard in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of capturing all artifacts from a tool and publishing them to the blackboard using Kotlin. ```Kotlin // Capture all artifacts and publish to blackboard val wrapped = Tool.publishToBlackboard(myTool) ``` -------------------------------- ### Dynamic System Prompt Creation (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of creating a dynamic system prompt using a lambda expression in Kotlin, incorporating context and input. ```kotlin tool.withSystemPrompt { ctx, input -> "Context: ${ctx.processContext.processOptions.contextId}" + ". Task: $input" } ``` -------------------------------- ### Java Example: Binding Customer to AgentProcess in a Tool Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Shows how a tool method in Java can access the current `AgentProcess` using `AgentProcess.get()` to bind objects, such as a customer, to the blackboard. ```java @LlmTool(description = "My Tool") public String bindCustomer(Long id) { var customer = customerRepository.findById(id); var agentProcess = AgentProcess.get(); if (agentProcess != null) { agentProcess.addObject(customer); return "Customer bound to blackboard"; } return "No agent process: Unable to bind customer"; } ``` -------------------------------- ### Dynamic System Prompt Creation (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of creating a dynamic system prompt using a lambda expression in Java, incorporating context and input. ```java tool.withSystemPrompt((ctx, input) -> "Context: " + ctx.getProcessContext().getProcessOptions().getContextId() + ". Task: " + input ); ``` -------------------------------- ### Kotlin Example: Binding Customer to AgentProcess in a Tool Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Shows how a tool method in Kotlin can access the current `AgentProcess` using `AgentProcess.get()` to bind objects, such as a customer, to the blackboard. ```kotlin @LlmTool(description = "My Tool") fun bindCustomer(id: Long): String { val customer = customerRepository.findById(id) val agentProcess = AgentProcess.get() return if (agentProcess != null) { agentProcess.addObject(customer) "Customer bound to blackboard" } else { "No agent process: Unable to bind customer" } } ``` -------------------------------- ### WriteAndReviewAgent in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Illustrates agent creation in Kotlin, mirroring the Java example with actions for writing and reviewing stories, leveraging different LLM configurations and personas. ```kotlin @Agent(description = "Agent that writes and reviews stories") class WriteAndReviewAgent { @Action fun writeStory(userInput: UserInput, context: OperationContext): Story { return context.ai() .withAutoLlm() .createObject(""" You are a creative writer who aims to delight and surprise. Write a story about ${userInput.content} """, Story::class.java) } @AchievesGoal(description = "Review a story") @Action fun reviewStory(story: Story, context: OperationContext): ReviewedStory { return context.ai() .withLlmByRole("reviewer") .createObject(""" You are a meticulous editor. Carefully review this story: ${story.text} """, ReviewedStory::class.java) } } ``` -------------------------------- ### Java Example: Math Tools with @LlmTool Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates implementing a simple math tool in Java with an `add` method annotated with `@LlmTool`. This tool can be exposed to an LLM for performing addition. ```java public class MathTools { @LlmTool(description = "add two numbers") public double add(double a, double b) { return a + b; } // Other tools } ``` -------------------------------- ### ActionContext.asSubProcess Example Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Use ActionContext.asSubProcess when you need access to ActionContext for other operations while running a subagent. ```java context.asSubProcess(Result.class, agent) ``` -------------------------------- ### Interacting with the Agent in Shell Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates how to invoke the agent's functionality from the shell. This example shows how to prompt the agent to write a story. ```bash x "Tell me a story about a robot learning to paint" ``` -------------------------------- ### Run Agent Explicit Instance in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT This Java example demonstrates running an agent via an explicit agent instance, similar to the general instance method. ```java @Agent(description = "Outer agent via explicit agent instance") public class OuterAgentExplicitInstance { @Action public TaskOutput start(UserInput input) { Agent agent = (Agent) new AgentMetadataReader() .createAgentMetadata(new InnerSubAgent()); return RunSubagent.instance(agent, TaskOutput.class); } @Action @AchievesGoal(description = "Processing complete") public TaskOutput done(TaskOutput output) { return output; } } ``` -------------------------------- ### Capturing Specific Artifact Types with publishToBlackboard in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of capturing only specific types of artifacts (e.g., SearchResult) and publishing them to the blackboard using Java. ```Java // Capture specific types Tool wrapped = Tool.publishToBlackboard(myTool, SearchResult.class); ``` -------------------------------- ### Kotlin Example: Math Tools with @LlmTool Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates implementing a simple math tool in Kotlin with an `add` function annotated with `@LlmTool`. This tool can be exposed to an LLM for performing addition. ```kotlin class MathTools { @LlmTool(description = "add two numbers") fun add(a: Double, b: Double) = a + b // Other tools } ``` -------------------------------- ### Environment Variables for LLM API Keys Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example .env file for setting up API keys for various LLM providers. Ensure you replace placeholder values with your actual keys. ```dotenv OPENAI_API_KEY=your_openai_api_key_here ANTHROPIC_API_KEY=your_anthropic_api_key_here GEMINI_API_KEY=your_gemini_api_key_here MISTRAL_API_KEY=your_mistral_api_key_here ``` -------------------------------- ### Kotlin: Outer and Inner Agents with Constructor Injection Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Illustrates the Kotlin equivalent of the Java example, showing constructor injection for the subagent and its use with `RunSubagent.fromAnnotatedInstance()`. ```kotlin @Agent(description = "Outer agent that delegates to an injected subagent") class OuterAgent( private val innerSubAgent: InnerSubAgent ) { @Action fun start(input: UserInput): TaskOutput { return RunSubagent.fromAnnotatedInstance( innerSubAgent, TaskOutput::class.java ) } @Action @AchievesGoal(description = "Processing complete") fun done(output: TaskOutput): TaskOutput = output } @Agent(description = "Inner subagent that processes input") class InnerSubAgent { @Action fun stepOne(input: UserInput): Intermediate { return Intermediate(input.content) } @Action @AchievesGoal(description = "Subagent complete") fun stepTwo(data: Intermediate): TaskOutput { return TaskOutput(data.value.uppercase()) } } ``` -------------------------------- ### Create Embabel Project with uvx Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Use the `uvx` command to create a custom Embabel project from a GitHub template repository. Ensure the `astral-uv` package is installed to use `uvx`. ```bash uvx --from git+https://github.com/embabel/project-creator.git project-creator ``` -------------------------------- ### Get PromptRunner with Default LLM (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Obtain a PromptRunner using the default LLM configuration from an OperationContext in Kotlin. This is the simplest way to get started with prompt execution. ```kotlin val runner = context.ai().withDefaultLlm() ``` -------------------------------- ### Get PromptRunner with Default LLM (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Obtain a PromptRunner using the default LLM configuration from an OperationContext in Java. This is the simplest way to get started with prompt execution. ```java var runner = context.ai().withDefaultLlm(); ``` -------------------------------- ### Create LlmOptions with Model and Temperature (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates creating LlmOptions with a specified model and temperature in Java. Use this for basic LLM configuration. ```java var options = LlmOptions .withModel(OpenAiModels.GPT_4O_MINI) .withTemperature(0.8); ``` -------------------------------- ### Filter Assets with addAnyReturnedAssets in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Apply a filter to multiple tools simultaneously using addAnyReturnedAssets. This example tracks assets whose IDs start with 'important-'. ```java List wrappedTools = assetTracker.addAnyReturnedAssets( List.of(tool1, tool2, tool3), asset -> asset.getId().startsWith("important-") ); ``` -------------------------------- ### Filter Assets with addAnyReturnedAssets in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Apply a filter to multiple tools simultaneously using addAnyReturnedAssets in Kotlin. This example tracks assets whose IDs start with 'important-'. ```kotlin val wrappedTools = assetTracker.addAnyReturnedAssets( listOf(tool1, tool2, tool3) ) { asset -> asset.id.startsWith("important-") } ``` -------------------------------- ### Implement StuckHandler Interface in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Implement the StuckHandler interface to define custom logic for when an agent action gets stuck. This example adds a 'Duke' dog to the blackboard to resolve the stuck state. ```java @Agent(description = "self unsticking agent") public class SelfUnstickingAgent implements StuckHandler { private boolean called = false; // The agent will get stuck as there's no dog to convert to a frog @Action @AchievesGoal(description = "the big goal in the sky") public Frog toFrog(Dog dog) { return new Frog(dog.name()); } // This method will be called when the agent is stuck @Override public StuckHandlerResult handleStuck(AgentProcess agentProcess) { called = true; agentProcess.addObject(new Dog("Duke")); return new StuckHandlerResult( "Unsticking myself", this, StuckHandlingResultCode.REPLAN, agentProcess ); } } ``` -------------------------------- ### Jinja Guardrails Example Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Defines safety and content guardrails for a chatbot. This example specifies that the bot should not discuss politics or controversial topics. ```Jinja {# Safety and content guardrails for the ragbot. #} DO NOT DISCUSS POLITICS OR CONTROVERSIAL TOPICS. ``` -------------------------------- ### Persona Template Example Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Defines a specific persona for the chatbot. This example sets the chatbot's name to 'Clause' and describes its expertise as a legal chatbot. ```Jinja Your name is Clause. You are a brilliant legal chatbot who excels at interpreting legislation and legal documents. ``` -------------------------------- ### Market Research Agent with Supervisor Planner (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of a Java agent using the Supervisor planner. Annotate the agent with `planner = PlannerType.SUPERVISOR` and mark the goal action with `@AchievesGoal`. Tool actions have descriptions visible to the supervisor LLM. ```java @Agent( planner = PlannerType.SUPERVISOR, description = "Market research report generator" ) public class MarketResearchAgent { public record MarketDataRequest(String topic) {} public record MarketData(Map revenues, Map marketShare) {} public record CompetitorAnalysisRequest(List companies) {} public record CompetitorAnalysis(Map> strengths) {} public record ReportRequest(String topic, List companies) {} public record FinalReport(String title, List sections) {} @Action(description = "Gather market data including revenues and market share") public MarketData gatherMarketData(MarketDataRequest request, Ai ai) { return ai.withDefaultLlm().createObject( "Generate market data for: " + request.topic(), MarketData.class ); } @Action(description = "Analyze competitors: strengths and positioning") public CompetitorAnalysis analyzeCompetitors(CompetitorAnalysisRequest request, Ai ai) { return ai.withDefaultLlm().createObject( "Analyze competitors: " + String.join(", ", request.companies()), CompetitorAnalysis.class ); } @AchievesGoal(description = "Compile all information into a final report") @Action(description = "Compile the final report") public FinalReport compileReport(ReportRequest request, Ai ai) { return ai.withDefaultLlm().createObject( "Create a market research report for " + request.topic(), FinalReport.class ); } } ``` -------------------------------- ### Embabel Supervisor Agent with Typed Tools (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Illustrates a market research agent in Embabel using the supervisor planner. Tools in this example return typed objects with schemas, and the state is managed as a typed blackboard. Tools are filtered based on available inputs. ```java @Agent(planner = PlannerType.SUPERVISOR) public class MarketResearchAgent { // Tools return typed objects with schemas @Action(description = "Gather market data for a topic") public MarketData gatherMarketData(MarketDataRequest request, Ai ai) { return ai.withDefaultLlm().createObject( "Generate market data for " + request.topic(), MarketData.class); } @Action(description = "Analyze competitors") public CompetitorAnalysis analyzeCompetitors(CompetitorAnalysisRequest request, Ai ai) { return ai.withDefaultLlm().createObject( "Analyze " + request.companies(), CompetitorAnalysis.class); } @AchievesGoal @Action public FinalReport compileReport(ReportRequest request, Ai ai) { ... } } // State is a typed blackboard // Tools are filtered based on available inputs ``` -------------------------------- ### RunSubagent.fromAnnotatedInstance Example Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Use RunSubagent.fromAnnotatedInstance when you have an @Agent-annotated instance and do not require ActionContext. ```java RunSubagent.fromAnnotatedInstance(new SubAgent(), Result.class) ``` -------------------------------- ### Original Chunk Text Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of a chunk's original text before transformation. ```plaintext This approach improves performance by 40% compared to the baseline. ``` -------------------------------- ### SimpleAgenticTool for Math Orchestration (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates creating and using a SimpleAgenticTool in Kotlin to orchestrate multiple math tools for evaluating expressions. ```kotlin import com.embabel.agent.api.tool.agentic.simple.SimpleAgenticTool val mathOrchestrator = SimpleAgenticTool("math-orchestrator", "Orchestrates math operations") .withTools(addTool, multiplyTool, divideTool) .withParameter(Tool.Parameter.string("expression", "Math expression to evaluate")) .withLlm(LlmOptions(model = "gpt-4")) context.ai() .withDefaultLlm() .withTool(mathOrchestrator) .generateText("What is 5 + 3 * 2?") ``` -------------------------------- ### ToolishRag Configuration (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of creating a `ToolishRag` by wrapping `SearchOperations` for LLM-controlled RAG searches. ```java public ChatActions(SearchOperations searchOperations) { this.toolishRag = new ToolishRag( "sources", "Sources for answering user questions", searchOperations ); } ``` -------------------------------- ### Create LlmOptions with Model and Temperature (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates creating LlmOptions with a specified model and temperature in Kotlin. Use this for basic LLM configuration. ```kotlin val options = LlmOptions .withModel(OpenAiModels.GPT_4O_MINI) .withTemperature(0.8) ``` -------------------------------- ### Transformed Chunk Text with Context Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of a chunk after being transformed by AddTitlesChunkTransformer, including titles and URI for context. ```plaintext # Title: Performance Optimization Guide # URI: https://docs.example.com/performance # Section: Caching Strategies This approach improves performance by 40% compared to the baseline. ``` -------------------------------- ### ToolishRag Configuration (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of creating a `ToolishRag` by wrapping `SearchOperations` in Kotlin for LLM-controlled RAG searches. ```kotlin class ChatActions(searchOperations: SearchOperations) { private val toolishRag = ToolishRag( "sources", "Sources for answering user questions", searchOperations ) } ``` -------------------------------- ### SimpleAgenticTool for Math Orchestration (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates creating and using a SimpleAgenticTool in Java to orchestrate multiple math tools for evaluating expressions. ```java import com.embabel.agent.api.tool.agentic.simple.SimpleAgenticTool; // Create the agentic tool SimpleAgenticTool mathOrchestrator = new SimpleAgenticTool("math-orchestrator", "Orchestrates math operations") .withTools(addTool, multiplyTool, divideTool) .withParameter(Tool.Parameter.string("expression", "Math expression to evaluate")) .withLlm(LlmOptions.withModel("gpt-4")); // Use it like any other tool context.ai() .withDefaultLlm() .withTool(mathOrchestrator) .generateText("What is 5 + 3 * 2?"); ``` -------------------------------- ### Market Research Agent with Supervisor Planner (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of a Kotlin agent using the Supervisor planner. Annotate the agent with `planner = PlannerType.SUPERVISOR` and mark the goal action with `@AchievesGoal`. Tool actions have descriptions visible to the supervisor LLM. ```kotlin @Agent( planner = PlannerType.SUPERVISOR, description = "Market research report generator" ) class MarketResearchAgent { data class MarketDataRequest(val topic: String) data class MarketData(val revenues: Map, val marketShare: Map) data class CompetitorAnalysisRequest(val companies: List) data class CompetitorAnalysis(val strengths: Map>) data class ReportRequest(val topic: String, val companies: List) data class FinalReport(val title: String, val sections: List) @Action(description = "Gather market data including revenues and market share") fun gatherMarketData(request: MarketDataRequest, ai: Ai): MarketData { return ai.withDefaultLlm().createObject( "Generate market data for: ${request.topic}" ) } @Action(description = "Analyze competitors: strengths and positioning") fun analyzeCompetitors(request: CompetitorAnalysisRequest, ai: Ai): CompetitorAnalysis { return ai.withDefaultLlm().createObject( "Analyze competitors: ${request.companies.joinToString()}" ) } @AchievesGoal(description = "Compile all information into a final report") @Action(description = "Compile the final report") fun compileReport(request: ReportRequest, ai: Ai): FinalReport { return ai.withDefaultLlm().createObject( "Create a market research report for ${request.topic}" ) } } ``` -------------------------------- ### Add LM Studio Starter (Gradle Groovy DSL) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Include the embabel-agent-starter-lmstudio dependency in your Gradle Groovy DSL build.gradle file. ```groovy dependencies { implementation 'com.embabel.agent:embabel-agent-starter-lmstudio:${embabel-agent.version}' } ``` -------------------------------- ### Configure Mistral AI in application.yml Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example configuration for Mistral AI API key and base URL. ```yaml embabel: agent: platform: models: mistralai: api-key: ${MISTRAL_API_KEY:your-dev-key} base-url: ${MISTRAL_BASE_URL:} ``` -------------------------------- ### Add LM Studio Starter (Gradle Kotlin DSL) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Add the embabel-agent-starter-lmstudio dependency to your Gradle Kotlin DSL build.gradle.kts file. ```kotlin dependencies { implementation("com.embabel.agent:embabel-agent-starter-lmstudio:${embabel-agent.version}") } ``` -------------------------------- ### Filter Metadata and Entities in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Kotlin example demonstrating filtering on metadata and entity properties/labels using `PropertyFilter` and `EntityFilter`. ```kotlin val metadataFilter = PropertyFilter.eq("ownerId", currentUserId) val entityFilter = EntityFilter.hasAnyLabel("Person") and PropertyFilter.eq("status", "active") val scopedRag = toolishRag .withMetadataFilter(metadataFilter) .withEntityFilter(entityFilter) ``` -------------------------------- ### DelegatingTool Interface in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT The DelegatingTool interface in Java, which extends the Tool interface. It provides a method to get the delegate tool. ```Java public interface DelegatingTool extends Tool { Tool getDelegate(); } ``` -------------------------------- ### Create BlackboardTools with Default Formatting (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Instantiates BlackboardTools with default entry formatting and adds it to a SimpleAgenticTool. Requires an active AgentProcess context. ```kotlin import com.embabel.agent.tools.blackboard.BlackboardTools import com.embabel.agent.api.tool.progressive.UnfoldingTool // Create with default formatting val blackboardTools: UnfoldingTool= BlackboardTools().create() // Add to SimpleAgenticTool val assistant = SimpleAgenticTool("assistant", "...") .withTools(blackboardTools) ``` -------------------------------- ### Capturing Artifacts to a Custom Sink in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of capturing artifacts of a specific type and sending them to a custom sink using Kotlin. ```Kotlin // Capture to a custom sink val wrapped = Tool.sinkArtifacts(myTool, SearchResult::class.java, mySink) ``` -------------------------------- ### Resuming StateMachineTool from a Specific State (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Shows how to use the `startingIn` method with a StateMachineTool in Java to resume processing from a state other than the initial one, such as continuing an order that is already confirmed. ```Java // Resume an order that's already confirmed Tool resumedProcessor = orderProcessor.startingIn(OrderState.CONFIRMED); ``` -------------------------------- ### Create Simple UnfoldingTool in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates creating an UnfoldingTool in Java by defining inner tools (query, insert, delete) and then combining them into a facade tool. ```java import com.embabel.agent.api.tool.progressive.UnfoldingTool; import com.embabel.agent.api.tool.Tool; // Create inner tools Tool queryTool = Tool.create("query_table", "Execute a SQL query", Tool.InputSchema.of(Tool.Parameter.string("sql", "The SQL query to execute")), input -> Tool.Result.text("{\"rows\": 5}") ); Tool insertTool = Tool.create("insert_record", "Insert a new record", Tool.InputSchema.of(Tool.Parameter.string("table", "Table name")), input -> Tool.Result.text("{\"id\": 123}") ); Tool deleteTool = Tool.create("delete_record", "Delete a record", Tool.InputSchema.of(Tool.Parameter.integer("id", "Record ID to delete")), input -> Tool.Result.text("{\"deleted\": true}") ); // Create the UnfoldingTool facade var databaseTool = UnfoldingTool.of( "database_operations", "Use this tool to work with the database. Invoke to see specific operations.", List.of(queryTool, insertTool, deleteTool) ); ``` -------------------------------- ### Capturing Artifacts to a Custom Sink in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of capturing artifacts of a specific type and sending them to a custom sink using Java. ```Java // Capture to a custom sink Tool wrapped = Tool.sinkArtifacts(myTool, SearchResult.class, mySink); ``` -------------------------------- ### WriteAndReviewAgent in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates agent creation in Java, including defining actions for writing and reviewing stories using different LLM configurations and personas. ```java @Agent(description = "Agent that writes and reviews stories") public class WriteAndReviewAgent { @Action public Story writeStory(UserInput userInput, OperationContext context) { return context.ai() .withAutoLlm() .createObject(""" You are a creative writer who aims to delight and surprise. Write a story about %s """.formatted(userInput.getContent()), Story.class); } @AchievesGoal(description = "Review a story") @Action public ReviewedStory reviewStory(Story story, OperationContext context) { return context.ai() .withLlmByRole("reviewer") .createObject(""" You are a meticulous editor. Carefully review this story: %s """.formatted(story.text), ReviewedStory.class); } } ``` -------------------------------- ### Neo4j Cypher Filtering with Property Filters in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Kotlin example showing automatic conversion of metadata filters to Cypher WHERE clauses for Neo4j. ```kotlin val filter = eq("owner", "alice") and gte("confidenceScore", 0.7) val results = repository.vectorSearch(request, metadataFilter = filter) // Generates: WHERE (e.owner = $_filter_0) AND (e.confidenceScore >= $_filter_1) AND ... ``` -------------------------------- ### Custom Selection Logic in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Use `selectable` for more complex selection logic. This Kotlin example uses an `accessLevel` parameter to determine which tools to expose. ```kotlin import com.embabel.agent.api.tool.progressive.UnfoldingTool import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper val allTools = listOf(basicTool, advancedTool, adminTool) val permissionBasedTool = UnfoldingTool.selectable( name = "api_operations", description = "API operations. Pass 'accessLevel': 'basic', 'advanced', or 'admin'.", innerTools = allTools, inputSchema = Tool.InputSchema.of( Tool.Parameter.string("accessLevel", "Access level for operations", required = true, enumValues = listOf("basic", "advanced", "admin")) ), ) { input -> // Custom selection logic val mapper = jacksonObjectMapper() val params = mapper.readValue(input, Map::class.java) when (params["accessLevel"]) { "basic" -> listOf(basicTool) "advanced" -> listOf(basicTool, advancedTool) "admin" -> allTools else -> listOf(basicTool) } } ``` -------------------------------- ### Tool Availability Before and After Parameter Currying Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Illustrates how tool availability changes based on whether their required parameters are present on the blackboard. Initially, all tools require parameters; after a parameter is satisfied, the tool appears 'ready' with fewer required parameters. ```text # Initial state: empty blackboard Available tools: - gatherMarketData(request: MarketDataRequest) -> MarketData - analyzeCompetitors(request: CompetitorAnalysisRequest) -> CompetitorAnalysis # After MarketData is gathered: Available tools: - gatherMarketData(request: MarketDataRequest) -> MarketData [READY - 0 params needed] - analyzeCompetitors(request: CompetitorAnalysisRequest) -> CompetitorAnalysis ``` -------------------------------- ### Custom Selection Logic in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Use `selectable` for more complex selection logic. This Java example uses an `accessLevel` parameter to determine which tools to expose. ```java import com.embabel.agent.api.tool.progressive.UnfoldingTool; import com.fasterxml.jackson.databind.ObjectMapper; List allTools = List.of(basicTool, advancedTool, adminTool); var permissionBasedTool = UnfoldingTool.selectable( "api_operations", "API operations. Pass 'accessLevel': 'basic', 'advanced', or 'admin'.", allTools, Tool.InputSchema.of( Tool.Parameter.string("accessLevel", "Access level for operations", true, List.of("basic", "advanced", "admin")) ), true, // removeOnInvoke input -> { // Custom selection logic try { ObjectMapper mapper = new ObjectMapper(); Map params = mapper.readValue(input, Map.class); String level = (String) params.get("accessLevel"); return switch (level) { case "basic" -> List.of(basicTool); case "advanced" -> List.of(basicTool, advancedTool); case "admin" -> allTools; default -> List.of(basicTool); }; } catch (Exception e) { return List.of(basicTool); } } ); ``` -------------------------------- ### Create Agent Process from Varargs (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Shows how to create an agent process by passing input objects directly as varargs, useful in web controller scenarios in Java. Requires an AgentPlatform instance and a defined agent. ```java // Create process from objects (like in web controllers) AgentProcess agentProcess = agentPlatform.createAgentProcessFrom( travelAgent, new ProcessOptions(), travelRequest, userPreferences ); ``` -------------------------------- ### Create and Start a Travel Agent Process (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT This Java snippet demonstrates creating a travel agent process. It converts form data to domain objects, finds a suitable agent, and initiates the process with specific options and inputs. ```java @Controller @RequestMapping("/journey") public class JourneyController { private final AgentPlatform agentPlatform; public JourneyController(AgentPlatform agentPlatform) { this.agentPlatform = agentPlatform; } @PostMapping("/plan") public String planJourney(@ModelAttribute JourneyPlanForm form, Model model) { // Convert form to domain objects TravelBrief travelBrief = new TravelBrief( form.getFrom(), form.getTo(), form.getDepartureDate(), form.getReturnDate(), form.getBrief() ); // Find the appropriate agent Agent agent = agentPlatform.agents().stream() .filter(a -> a.getName().toLowerCase().contains("travel")) .findFirst() .orElseThrow(() -> new IllegalStateException("No travel agent found")); // Create the agent process with input bindings AgentProcess agentProcess = agentPlatform.createAgentProcessFrom( agent, new ProcessOptions( new Verbosity().withShowPrompts(true), Budget.DEFAULT // or custom budget ), travelBrief // Vararg inputs bound to blackboard ); // Start the process asynchronously agentPlatform.start(agentProcess); // Add process ID to model for status polling model.addAttribute("processId", agentProcess.getId()); model.addAttribute("travelBrief", travelBrief); // Return a view that polls /api/v1/process/{processId} for status return "processing"; } } ``` -------------------------------- ### Capturing Specific Artifact Types with publishToBlackboard in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of capturing only specific types of artifacts (e.g., SearchResult) and publishing them to the blackboard using Kotlin. ```Kotlin // Capture specific types val wrapped = Tool.publishToBlackboard(myTool, SearchResult::class.java) ``` -------------------------------- ### Enable Tool Chaining for User Management in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Shows how to use `withToolChainingFrom()` in Java to make methods of a retrieved object available as tools. This enables dynamic tool discovery. ```java public class User { private final String id; private String email; @LlmTool("Update the user's email address") public String updateEmail(String newEmail) { this.email = newEmail; return "Email updated to " + newEmail; } } SimpleAgenticTool userManager = new SimpleAgenticTool("userManager", "Manage user accounts") .withTools(searchUserTool, getUserTool) // Tools to find/retrieve users .withToolChainingFrom(User.class); // User methods become tools when retrieved // Flow: // 1. LLM calls searchUserTool to find users // 2. LLM calls getUserTool which returns a User artifact // 3. updateEmail() becomes available as a tool bound to that User // 4. LLM calls updateEmail("new@example.com") ``` -------------------------------- ### Resuming StateMachineTool from a Specific State (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates resuming a StateMachineTool in Kotlin from a specified state using the `startingIn` method. This allows for continuing a process from an intermediate state, like a confirmed order. ```Kotlin // Resume an order that's already confirmed val resumedProcessor = orderProcessor.startingIn(OrderState.CONFIRMED) ``` -------------------------------- ### Create BlackboardTools with Default Formatting (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Instantiates BlackboardTools with default entry formatting and adds it to a SimpleAgenticTool. Requires an active AgentProcess context. ```java import com.embabel.agent.tools.blackboard.BlackboardTools; import com.embabel.agent.api.tool.progressive.UnfoldingTool; // Create with default formatting var blackboardTools = new BlackboardTools().create(); // Add to SimpleAgenticTool var assistant = new SimpleAgenticTool("assistant", "...") .withTools(blackboardTools); ``` -------------------------------- ### Preserve Tool Properties with Customization (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Demonstrates creating a tool and then customizing its description and note using `withDescription()` and `withNote()`, while verifying that the name and functionality remain unchanged. ```java Tool original = Tool.create("calculator", "Performs calculations", Tool.InputSchema.of(Tool.Parameter.integer("x", "Number")), input -> Tool.Result.text("42")); // Create a customized version Tool customized = original .withDescription("Specialized math tool") .withNote("Optimized for financial calculations"); // Name and functionality unchanged assert customized.getDefinition().getName().equals("calculator"); assert customized.call("{}").text().equals("42"); ``` -------------------------------- ### Configure Google GenAI Models in application.yml Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example configuration for setting default LLM and embedding models, and specific Google GenAI model configurations. ```yaml embabel: models: default-llm: gemini-2.5-flash __**(1)** default-embedding-model: gemini-embedding-001 __**(2)** llms: fast: gemini-2.5-flash best: gemini-2.5-pro reasoning: gemini-3-pro-preview embedding-services: default: gemini-embedding-001 agent: platform: models: googlegenai: __**(3)** api-key: ${GOOGLE_API_KEY} __**(4)** # Or use Vertex AI authentication: # project-id: ${GOOGLE_PROJECT_ID} # location: ${GOOGLE_LOCATION} max-attempts: 10 backoff-millis: 5000 ``` -------------------------------- ### Filter Assets with addReturnedAssets in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Use the addReturnedAssets method with a lambda expression to filter which assets are tracked. This example tracks concerts with at least 3 works. ```java Tool wrapped = assetTracker.addReturnedAssets(concertTool, asset -> { // Only track concerts with at least 3 works return asset instanceof Concert concert && concert.getWorks().size() >= 3; }); ``` -------------------------------- ### State-Based Tool Availability with StateMachineTool (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Provides a Kotlin example for StateMachineTool, using an enum to define states and registering tools for specific states. This includes defining transitions and global tools available across all states. ```Kotlin import com.embabel.agent.api.tool.agentic.state.StateMachineTool enum class OrderState { DRAFT, CONFIRMED, SHIPPED, DELIVERED } val orderProcessor = StateMachineTool("orderProcessor", "Process orders", OrderState::class.java) .withInitialState(OrderState.DRAFT) .inState(OrderState.DRAFT) .withTool(addItemTool) .withTool(confirmTool).transitionsTo(OrderState.CONFIRMED) .inState(OrderState.CONFIRMED) .withTool(shipTool).transitionsTo(OrderState.SHIPPED) .inState(OrderState.SHIPPED) .withTool(deliverTool).transitionsTo(OrderState.DELIVERED) .inState(OrderState.DELIVERED) .withTool(reviewTool).build() .withGlobalTools(statusTool, helpTool) // Available in all states .withParameter(Tool.Parameter.string("orderId", "Order to process")) ``` -------------------------------- ### Creating a Custom ArtifactSink for Event Publishing in Kotlin Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of creating a custom ArtifactSink in Kotlin to publish artifacts to an event stream. This sink can then be used with any tool. ```Kotlin // Publish to an event stream val eventSink = ArtifactSink { artifact -> eventPublisher.publish(ToolArtifactEvent(artifact)) } // Use with any tool val wrapped = Tool.sinkArtifacts(myTool, MyType::class.java, eventSink) ``` -------------------------------- ### Add LM Studio Starter (Maven) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Include the embabel-agent-starter-lmstudio dependency in your Maven project's pom.xml. ```xml com.embabel.agent embabel-agent-starter-lmstudio ${embabel-agent.version} ``` -------------------------------- ### Creating a Custom ArtifactSink for Event Publishing in Java Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of creating a custom ArtifactSink in Java to publish artifacts to an event stream. This sink can then be used with any tool. ```Java // Publish to an event stream ArtifactSink eventSink = artifact -> { eventPublisher.publish(new ToolArtifactEvent(artifact)); }; // Use with any tool Tool wrapped = Tool.sinkArtifacts(myTool, MyType.class, eventSink); ``` -------------------------------- ### Configure Tool Groups in application.yml Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Example of configuring tool groups by including specific tools by name in the application.yml file. This method is straightforward for basic configurations. ```yaml embabel: agent: platform: tools: includes: weather: description: Get weather for location provider: Docker tools: - weather ``` -------------------------------- ### Create BlackboardTools with Custom Formatting (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Instantiates BlackboardTools with a custom entry formatter and adds it to a SimpleAgenticTool. Requires an active AgentProcess context. ```kotlin import com.embabel.agent.tools.blackboard.BlackboardTools import com.embabel.agent.api.tool.progressive.UnfoldingTool // Or with custom formatting for blackboard entries val blackboardTools = BlackboardTools().create(myCustomFormatter) // Add to SimpleAgenticTool val assistant = SimpleAgenticTool("assistant", "...") .withTools(blackboardTools) ``` -------------------------------- ### Create LlmOptions with Different Hyperparameters (Java) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Shows how to configure LlmOptions with different hyperparameters like temperature and topP for analytical tasks in Java. Useful for fine-tuning LLM behavior for specific use cases. ```java var analyticalOptions = LlmOptions .withModel(OpenAiModels.GPT_4O_MINI) .withTemperature(0.2) .withTopP(0.9); ``` -------------------------------- ### Create UnfoldingTool Facade by Regex Patterns (Kotlin) Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Kotlin example for creating an UnfoldingTool facade using regex patterns to match MCP tools. This facilitates grouping tools based on patterns like 'db_*' or containing 'query'. ```kotlin // Match tools by regex patterns val dbTool = mcpToolFactory.unfoldingMatching( name = "database_operations", description = "Database operations. Invoke to access database tools.", patterns = listOf("^db_".toRegex(), "query.*".toRegex()) ) ``` -------------------------------- ### Embel Shell Usage Examples Source: https://docs.embabel.com/embabel-agent/guide/0.3.4-SNAPSHOT Illustrates common commands for the Embabel Shell, including executing tasks in closed or open mode, and ranking goals without execution. ```bash # Closed mode (default) - select best agent x "Find a horoscope for Alice who is a Scorpio" # Open mode - select best goal, use any actions x "Find a horoscope for Alice who is a Scorpio" -o # Show goal rankings without executing choose-goal "Find a horoscope for Alice" ```