### Basic Setup with Claude Subagents Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/TaskTools.md Configure the Task tool with Claude subagents and build the main chat client. This example demonstrates how to use the agent for natural language queries that delegate to sub-agents. ```java import org.springaicommunity.agent.tools.task.TaskTool; import org.springaicommunity.agent.tools.task.claude.ClaudeSubagentType; @Configuration public class AgentConfig { @Bean CommandLineRunner demo(ChatClient.Builder chatClientBuilder) { return args -> { // Configure Task tool with Claude subagents var taskTool = TaskTool.builder() .subagentTypes(ClaudeSubagentType.builder() .chatClientBuilder("default", chatClientBuilder) .build()) .build(); // Build main chat client with Task tool ChatClient chatClient = chatClientBuilder .defaultToolCallbacks(taskTool) .build(); // Use naturally - agent will delegate to sub-agents String response = chatClient .prompt("Explore the authentication module and explain how it works") .call() .content(); }; } } ``` -------------------------------- ### Example Workflow with ShellTools Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/ShellTools.md Demonstrates a typical workflow: starting a long-running background task, periodically checking its progress, and finally killing the process. Includes starting a process, getting its output with filtering, and then terminating it. ```java ShellTools shellTools = new ShellTools(); // 1. Start a long-running background task String start = shellTools.bash( "python train_model.py", null, "Train ML model", true ); // Returns: "bash_id: shell_1234567890 ..." // 2. Periodically check progress String output1 = shellTools.bashOutput("shell_1234567890", ".*epoch.*\n"); // Shows only lines containing "epoch" Thread.sleep(5000); String output2 = shellTools.bashOutput("shell_1234567890", null); // Shows all new output since last check // 3. Kill if needed String killResult = shellTools.killShell("shell_1234567890"); // Returns: "Successfully killed shell: shell_1234567890" ``` -------------------------------- ### Manual MemoryTools Setup vs. Advisor Setup Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/AutoMemoryToolsAdvisor.md Compares the manual setup of AutoMemoryTools with the simplified setup using AutoMemoryToolsAdvisor. The advisor reduces boilerplate by handling prompt injection and tool registration automatically. ```java // Manual setup AutoMemoryTools memoryTools = AutoMemoryTools.builder() .memoriesDir("/path/to/memories") .build(); String memoryPrompt = new PromptTemplate(memorySystemPromptResource) .render(Map.of("MEMORIES_ROOT_DIERCTORY", memoriesDir)); ChatClient chatClient = ChatClient.builder(chatModel) .defaultSystem(baseSystemPrompt + "\n\n" + memoryPrompt) .defaultTools(memoryTools) .build(); ``` ```java // Advisor setup — equivalent, less boilerplate ChatClient chatClient = ChatClient.builder(chatModel) .defaultAdvisors( AutoAutoMemoryToolsAdvisor.builder() .memoriesRootDirectory("/path/to/memories") .build()) .build(); ``` -------------------------------- ### Full Shell Workflow Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/ShellTools.md Demonstrates a complete workflow: starting a long-running background task, periodically checking its output, and finally killing the process. Includes simulated progress checks and output retrieval. ```java ShellTools shellTools = new ShellTools(); // 1. Start a long-running background task String start = shellTools.bash( "python train_model.py", null, "Train ML model", true ); // Returns: "bash_id: shell_1234567890 ..." // 2. Periodically check progress String output1 = shellTools.bashOutput("shell_1234567890", ".*epoch.*"); // Shows only lines containing "epoch" Thread.sleep(5000); String output2 = shellTools.bashOutput("shell_1234567890", null); // Shows all new output since last check // 3. Kill if needed String killResult = shellTools.killShell("shell_1234567890"); // Returns: "Successfully killed shell: shell_1234567890" ``` -------------------------------- ### Data Analysis Skill Setup Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md Instructions for setting up the Data Analysis skill by installing its Python dependencies. ```bash cd .claude/skills/data-analysis pip install -r requirements.txt ``` -------------------------------- ### Build and Run Project Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/index.md Commands to build the entire project using Maven and run a specific example application. Ensure you have Java 17+, Spring Boot 3.x/4.x, Spring AI 2.0.0+, and Maven 3.6+ installed. ```bash # Build the entire project mvn clean install # Run an example cd examples/code-agent-demo # or examples/skills-demo mvn spring-boot:run ``` -------------------------------- ### Run the Demo Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/memory/memory-filesystem-tools-demo/README.md Execute the demo using Maven to start the Spring Boot application. ```bash mvn spring-boot:run ``` -------------------------------- ### SmartWebFetchTool Builder with All Options Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SmartWebFetchTool.md Example of configuring the SmartWebFetchTool builder with all available optional parameters for custom behavior. ```java SmartWebFetchTool webFetch = SmartWebFetchTool.builder(chatClient) .maxContentLength(150_000) // Process up to 150KB .domainSafetyCheck(true) // Check domain safety .failOpenOnSafetyCheckError(true) // Allow fetch if safety check errors .maxCacheSize(200) // Cache up to 200 entries .maxRetries(3) // Retry up to 3 times .build(); ``` -------------------------------- ### Install Dependencies with uv Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/subagent-a2a-demo/src/main/resources/skills/ai-tutor/README.md Install the project dependencies using the uv package manager. ```bash uv sync ``` -------------------------------- ### Quick Start with TodoWriteTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/TodoWriteTool.md Initialize a ChatClient with the TodoWriteTool and necessary advisors. Ensure Chat Memory and ToolCallAdvisor are configured for optimal performance. ```java ChatClient chatClient = chatClientBuilder .defaultTools(TodoWriteTool.builder().build()) .defaultAdvisors( ToolCallAdvisor.builder().conversationHistoryEnabled(false).build(), MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().build()).build()) .build(); ``` -------------------------------- ### SKILL.md Format Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md The SKILL.md file includes YAML front-matter with metadata and Markdown content for instructions and examples. ```markdown --- name: my-skill description: Comprehensive description including what the skill does, when to use it, and trigger keywords users might mention. allowed-tools: Read, Grep, Bash model: claude-sonnet-4-5-20250929 --- # Skill Title ## Overview Brief introduction to what this skill does. ## Instructions Step-by-step guidance for the AI agent. ## Examples Concrete examples demonstrating skill usage. ## Additional Resources - For complete details, see [reference.md](reference.md) - For usage examples, see [examples.md](examples.md) ``` -------------------------------- ### Example Prompt for TodoWriteTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/todo-demo/README.md An example prompt demonstrating a complex request that the agent should decompose into trackable todo items using the TodoWrite tool. ```plaintext Find the top 10 Tom Hanks movies, then group them in groups of 2, and finally print the title name inverted (e.g. last char first). Use TodoWrite to organize your tasks. ``` -------------------------------- ### Example Conversation - Session 2 Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/memory/memory-tools-demo/README.md Run the demo again and ask the agent about stored information to see its recall capability. ```bash USER> What do you know about me? ASSISTANT> You're Alice, a backend engineer. You prefer short answers. You're migrating from PostgreSQL to CockroachDB this quarter. ``` -------------------------------- ### Skill File Structure Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md A typical skill directory includes the required SKILL.md file and optional supporting files like reference documents, examples, and scripts. ```text examples/.claude/skills/ └── my-skill/ ├── SKILL.md # Required: Skill definition ├── reference.md # Optional: Detailed documentation ├── examples.md # Optional: Usage examples ├── scripts/ # Optional: Helper scripts │ └── process.py └── pyproject.toml # Optional: Python dependencies ``` -------------------------------- ### Basic AskUserQuestionTool Setup Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/AskUserQuestionTool.md Demonstrates how to build and configure the AskUserQuestionTool with a custom question handler and integrate it with a ChatClient. Ensure your QuestionHandler is thread-safe if it maintains shared state. ```java AskUserQuestionTool askTool = AskUserQuestionTool.builder() .questionHandler(questions -> { // Display questions to user via your UI and collect answers return collectUserAnswers(questions); }) .build(); ChatClient chatClient = chatClientBuilder .defaultTools(askTool) .build(); ``` -------------------------------- ### Start Shell with Description Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/ShellTools.md Starts a shell process and assigns a descriptive name for better logging. This is useful for identifying the purpose of background tasks. ```java shellTools.bash("git status", null, "Check git status", null); ``` -------------------------------- ### Skill Examples (Bash and Python) Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md Illustrative examples of how skills can be invoked using bash scripts or Python code, demonstrating common tasks like text extraction, merging PDFs, and filling forms. ```bash python scripts/extract_text.py input.pdf output.txt ``` ```bash python scripts/merge.py file1.pdf file2.pdf output.pdf ``` ```python from pdf_processor import fill_form fill_form('template.pdf', { 'name': 'John Doe', 'date': '2025-01-04' }, 'filled.pdf') ``` -------------------------------- ### Find All Configuration Files Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Example of finding all '.yml' files within the 'src/main/resources' directory recursively. ```java String configs = globTool.glob("**/*.yml", "./src/main/resources"); ``` -------------------------------- ### Build Project with Maven Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/README.md Use this command to build the project from the root directory. Ensure Java 17+ and Maven 3.6+ are installed. ```bash mvn clean install ``` -------------------------------- ### Agent Configuration for Model Routing (Fast/Cheap) Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/TaskTools.md Example of configuring an agent to use a faster and cheaper model like 'haiku' for simple tasks. ```markdown --- name: quick-search model: haiku --- ``` -------------------------------- ### Example Conversation - Session 1 Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/memory/memory-tools-demo/README.md Interact with the agent in the first session, providing information and preferences. ```bash USER> My name is Alice. I'm a backend engineer and I prefer short answers. USER> Remember that we're migrating from PostgreSQL to CockroachDB this quarter. USER> exit ``` -------------------------------- ### Start Background Task with Description Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/ShellTools.md Starts a shell command to run in the background. Use this for commands expected to take longer than 30 seconds. A descriptive name aids in logging and management. ```java shellTools.bash("git status", null, "Check git status", null); ``` ```java shellTools.bash("npm run test", null, "Run test suite", true); ``` -------------------------------- ### Register SkillsTool with Skill Directories Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/README.md Demonstrates registering SkillsTool with specified skill directories and other necessary tools for AI agent setup. ```java // Register SkillsTool with skill directories ChatClient chatClient = chatClientBuilder .defaultToolCallbacks(SkillsTool.builder() .addSkillsDirectory(".claude/skills") .build()) .defaultTools(FileSystemTools.builder().build()) // For reading reference files .defaultTools(new ShellTools()) // For executing scripts .build(); ``` -------------------------------- ### Quick Start AutoAutoMemoryToolsAdvisor Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/AutoMemoryToolsAdvisor.md Initialize AutoAutoMemoryToolsAdvisor with a memories root directory and integrate it into a ChatClient. ```java AutoAutoMemoryToolsAdvisor memoryAdvisor = AutoAutoMemoryToolsAdvisor.builder() .memoriesRootDirectory("/home/user/.agent/memories") .build(); ChatClient chatClient = ChatClient.builder(chatModel) .defaultAdvisors(memoryAdvisor) .build(); ``` -------------------------------- ### Find All Java Source Files Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Example of finding all '.java' files within the 'src/main' directory recursively. ```java String javaSources = globTool.glob("**/*.java", "./src/main"); ``` -------------------------------- ### Configure Skills Directory Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/skills-demo/README.md Configure the application properties to specify the directory where skills are loaded from. This example uses a classpath resource. ```properties agent.skills.dirs=classpath:/.claude/skills ``` -------------------------------- ### Example QuestionHandler Implementation Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/AskUserQuestionTool.md A sample implementation of the QuestionHandler interface that iterates through questions, prompts the user for an answer to each, and returns a map of questions to answers. ```java QuestionHandler handler = questions -> { Map answers = new HashMap<>(); for (Question q : questions) { String answer = promptUser(q); answers.put(q.question(), answer); } return answers; }; ``` -------------------------------- ### Match Files Starting with 'Test' Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Find all files that begin with the prefix 'Test' and have the '.java' extension within the specified directory. ```java String testFiles = globTool.glob("Test*.java", "./src"); ``` -------------------------------- ### Spring Boot Configuration for SmartWebFetchTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SmartWebFetchTool.md Example of configuring SmartWebFetchTool as a Spring Bean, setting various parameters like maxContentLength, domainSafetyCheck, and maxRetries. ```java @Configuration public class ToolsConfig { @Bean public SmartWebFetchTool smartWebFetchTool(ChatClient.Builder chatClientBuilder) { ChatClient chatClient = chatClientBuilder.build(); return SmartWebFetchTool.builder(chatClient) .maxContentLength(150_000) .domainSafetyCheck(true) .failOpenOnSafetyCheckError(true) .maxCacheSize(100) .maxRetries(2) .build(); } } ``` -------------------------------- ### Skill Execution Examples - Python Script Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/SkillsTool.md Demonstrates calling a Python script to merge multiple PDF files. Ensure the script and its dependencies are accessible. ```bash python scripts/merge.py file1.pdf file2.pdf output.pdf ``` -------------------------------- ### Document a REST Endpoint Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md Example of documenting a GET endpoint with parameters, response format, and error codes in Markdown. ```markdown ## GET /api/users/{id} Retrieve user by ID. **Parameters:** - `id` (path, required): User ID **Response:** `200 OK` ```json { "id": 1, "name": "John Doe", "email": "john@example.com" } ``` **Errors:** - `404`: User not found ``` -------------------------------- ### Custom Sub-Agent File Structure Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/TaskTools.md Illustrates the directory structure for custom sub-agents, showing how Markdown files with YAML front matter are organized within a project. ```markdown project-root/ ├── .claude/ │ └── agents/ │ ├── code-reviewer.md │ ├── test-runner.md │ └── spring-ai-expert.md ``` -------------------------------- ### AgentEnvironment.gitStatus() Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/AgentEnvironment.md Collects and prints the git repository status, including branch, main branch, modified files, and recent commits. Returns an empty string if git is not installed or the directory is not a git repo. ```java String gitStatus = AgentEnvironment.gitStatus(); System.out.println(gitStatus); // gitStatus: This is the git status at the start of the conversation... // Current branch: feature-branch // Main branch (you will usually use this for PRs): main // Status: // M README.md // ... ``` -------------------------------- ### Technology Stack Research with Trusted Sources Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/BraveWebSearchTool.md Find tutorials or guides from a curated list of trusted sources. This ensures the information is relevant and from reputable platforms. ```java // Find tutorials from trusted sources String tutorials = searchTool.webSearch( "Spring AI LangChain4j integration tutorial", List.of("spring.io", "github.com", "medium.com", "dev.to"), null ); ``` -------------------------------- ### Build and Run JAR Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/ask-user-question-demo/README.md Package the application into a JAR file and execute it. ```bash mvn clean package java -jar target/chat-demo2-0.1.0-SNAPSHOT.jar ``` -------------------------------- ### Memory Write Operation Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/memory/memory-filesystem-tools-demo/README.md Illustrates the format of a typed memory file (.md) with YAML frontmatter, including name, description, and type, followed by the memory content. ```markdown --- name: user profile description: Alice — backend engineer, prefers short answers type: user --- Backend engineer named Alice. Prefers concise, direct responses without trailing summaries. ``` -------------------------------- ### Clone Repository and Navigate Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/subagent-a2a-demo/src/main/resources/skills/ai-tutor/README.md Clone the repository containing the AI Tutor Skill and navigate into the project directory. ```bash git clone cd ai-tutor-skill ``` -------------------------------- ### Bad Skill Description Example (YAML) Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md Examples of vague skill descriptions in YAML format that should be avoided. ```yaml # ❌ BAD description: Database helper ``` ```yaml description: Works with files ``` -------------------------------- ### Set API Key and Run Demo Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/todo-demo/README.md Configure your environment with API keys for your chosen model provider and Brave search, then execute the Spring Boot application. ```bash # Set API key for your chosen model provider export GOOGLE_CLOUD_PROJECT=your-project-id # or: export ANTHROPIC_API_KEY=your-key # or: export OPENAI_API_KEY=your-key # Optional: Enable web search export BRAVE_API_KEY=your-brave-key # Run ./mvnw spring-boot:run -pl examples/todo-demo ``` -------------------------------- ### Set Environment Variables and Run Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/code-agent-demo/README.md Set necessary API keys as environment variables and navigate to the demo directory. Then, run the Spring Boot application using Maven. ```bash # 1. Set environment variables export ANTHROPIC_API_KEY=your-key-here export BRAVE_API_KEY=your-brave-key # optional # 2. Run cd examples/code-agent-demo mvn spring-boot:run ``` -------------------------------- ### Skill Execution Examples - Bash Script Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/SkillsTool.md Example of how to invoke a bash script for a specific task. This is useful for automating command-line operations. ```bash python scripts/extract_text.py input.pdf output.txt ``` -------------------------------- ### ChatClient Setup with Tools and Advisors Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/code-agent-demo/README.md Configure the ChatClient in Application.java by setting the system prompt, tool callbacks for MCP and skills, and adding agent tools and advisors for memory and tool execution. ```java ChatClient chatClient = chatClientBuilder .defaultSystem(systemPrompt) // MAIN_AGENT_SYSTEM_PROMPT_V2.md .defaultToolCallbacks(mcpToolCallbackProvider) // MCP tools .defaultToolCallbacks(skillsTool) // Skills .defaultTools(AskUserQuestionTool, TodoWriteTool, // Agent tools ShellTools, FileSystemTools, SmartWebFetchTool, BraveWebSearchTool, GrepTool) .defaultAdvisors(ToolCallAdvisor, // Tool execution MessageChatMemoryAdvisor) // 500-message memory .build(); ``` -------------------------------- ### Automatic Delegation Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/TaskTools.md The main agent automatically delegates tasks to sub-agents based on their descriptions. This example shows a prompt that triggers exploration. ```java String response = chatClient .prompt("How does authentication work in this codebase?") .call() .content(); ``` -------------------------------- ### Find Files Starting with a Pattern using GlobTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Use GlobTool to find files whose names start with a specific pattern, such as 'Test'. ```java // Files starting with pattern globTool.glob("**/Test*.java", "./src"); ``` -------------------------------- ### Build and Use BraveWebSearchTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/README.md Demonstrates how to build a BraveWebSearchTool with an API key and perform web searches, including using search operators. ```java // Build with API key BraveWebSearchTool searchTool = BraveWebSearchTool.builder(apiKey) .resultCount(10) // Optional: default 10 .build(); // Search the web String results = searchTool.webSearch( "Spring AI features 2025", null, // allowedDomains (optional) null // blockedDomains (optional) ); // Or use search operators for efficiency String results2 = searchTool.webSearch("Spring AI site:spring.io", null, null); ``` -------------------------------- ### Complete TaskTool Example with Chat Client Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/TaskTools.md Demonstrates setting up a TaskTool with Claude subagents and integrating it into a main chat client for interactive use. Includes configuration for subagents, tools, and advisors. ```java import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import java.util.List; import java.util.Scanner; import ai.langchain.spring.core.ChatClient; import ai.langchain.spring.core.ToolCallback; import ai.langchain.spring.core.advisors.ToolCallAdvisor; import ai.langchain.spring.core.advisors.MessageChatMemoryAdvisor; import ai.langchain.spring.core.memory.MessageWindowChatMemory; import ai.langchain.agents.task.TaskTool; import ai.langchain.agents.task.ClaudeSubagentType; import ai.langchain.agents.tools.FileSystemTools; import ai.langchain.agents.tools.GrepTool; import ai.langchain.agents.tools.GlobTool; import ai.langchain.agents.tools.ShellTools; import ai.langchain.agents.tools.TodoWriteTool; import ai.langchain.agents.tools.ToolCallAdvisor; import ai.langchain.agents.tools.MyLoggingAdvisor; @SpringBootApplication public class Application { @Bean CommandLineRunner demo( ChatClient.Builder chatClientBuilder, @Value("${agent.skills.paths}") List skillPaths, @Value("${BRAVE_API_KEY:#{null}}") String braveApiKey) { return args -> { // Configure Task tool with Claude subagents var taskTool = TaskTool.builder() .subagentTypes(ClaudeSubagentType.builder() .chatClientBuilder("default", chatClientBuilder.clone().defaultAdvisors(new MyLoggingAdvisor(0, "[TASK]"))) .skillsResources(skillPaths) .braveApiKey(braveApiKey) .build()) .build(); // Build main chat client ChatClient chatClient = chatClientBuilder .defaultToolCallbacks(taskTool) .defaultTools( FileSystemTools.builder().build(), GrepTool.builder().build(), GlobTool.builder().build(), ShellTools.builder().build(), TodoWriteTool.builder().build() ) .defaultAdvisors( ToolCallAdvisor.builder() .conversationHistoryEnabled(false) .build(), MessageChatMemoryAdvisor.builder( MessageWindowChatMemory.builder().maxMessages(500).build() ).build() ) .build(); // Interactive chat loop try (Scanner scanner = new Scanner(System.in)) { while (true) { System.out.print("\nUSER: "); String response = chatClient .prompt(scanner.nextLine()) .call() .content(); System.out.println("\nASSISTANT: " + response); } } }; } } ``` -------------------------------- ### Automatic Delegation Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/TaskTools.md The main agent automatically delegates tasks to sub-agents based on their descriptions. This example shows a prompt that triggers automatic delegation. ```java String response = chatClient .prompt("How does authentication work in this codebase?") .call() .content(); // Main agent recognizes this as exploration task and delegates to Explore sub-agent ``` -------------------------------- ### Single-Select Question Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/AskUserQuestionTool.md An example of a single-select question format that the AI agent can generate. The 'multiSelect' field is set to false, indicating that only one option can be chosen. ```json { "question": "Which library should we use for date formatting?", "header": "Library", "options": [ { "label": "Moment.js", "description": "Popular but large library" }, { "label": "Day.js", "description": "Lightweight Moment.js alternative" }, { "label": "date-fns", "description": "Modular and tree-shakeable" } ], "multiSelect": false } ``` -------------------------------- ### Basic SmartWebFetchTool Usage Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SmartWebFetchTool.md Demonstrates how to build and use the SmartWebFetchTool to fetch and summarize web content. Requires a ChatClient instance. ```java SmartWebFetchTool webFetch = SmartWebFetchTool.builder(chatClient).build(); String result = webFetch.webFetch( "https://docs.spring.io/spring-ai/reference/", "What are the key features of Spring AI?" ); System.out.println(result); ``` -------------------------------- ### Good Skill Description Example (YAML) Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md An example of a well-written skill description in YAML format, including specific capabilities and trigger keywords for better AI matching. ```yaml # ✅ GOOD description: Process Excel files: read sheets, analyze data, create charts, generate reports. Use when working with .xlsx, .xls files, spreadsheets, or when user mentions Excel, data analysis, or pivot tables. ``` ```yaml # ✅ GOOD description: Analyze SQL databases, write optimized queries, explain execution plans. Use when user mentions: databases, SQL, MySQL, PostgreSQL, queries, tables, indexes, or performance tuning. ``` -------------------------------- ### Default GrepTool Configuration and Usage Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GrepTool.md Demonstrates how to create a GrepTool with default settings and perform a basic search for a pattern in the current directory. Uses `files_with_matches` output mode. ```java GrepTool grepTool = GrepTool.builder().build(); String result = grepTool.grep( "TODO", // pattern null, // path (uses current directory) null, // glob OutputMode.files_with_matches, // outputMode null, null, null, // context lines (before, after, surrounding) null, // showLineNumbers null, // caseInsensitive null, // type null, null, null // headLimit, offset, multiline ); ``` -------------------------------- ### Skill Execution Examples - Python Function Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/SkillsTool.md Example of using a Python function to fill a PDF form with provided data. This requires the 'pdf_processor' library and specific template files. ```python from pdf_processor import fill_form fill_form('template.pdf', { 'name': 'John Doe', 'date': '2025-01-04' }, 'filled.pdf') ``` -------------------------------- ### Build and Use TodoWriteTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/README.md Demonstrates building a TodoWriteTool and managing a task list with TodoItem objects. ```java TodoWriteTool todoTool = TodoWriteTool.builder().build(); // Create and manage task list Todos todos = new Todos(List.of( new TodoItem("Read configuration", Status.completed, "Reading configuration"), new TodoItem("Parse settings", Status.in_progress, "Parsing settings"), new TodoItem("Validate config", Status.pending, "Validating config") )); todoTool.todoWrite(todos); ``` -------------------------------- ### Run Spring Boot Demo Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/ask-user-question-demo/README.md Navigate to the demo directory and run the Spring Boot application using Maven. ```bash cd examples/ask-user-question-demo mvn spring-boot:run ``` -------------------------------- ### SmartWebFetchTool Caching Behavior Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SmartWebFetchTool.md Demonstrates how the tool uses URL and prompt to create cache keys. Different prompts for the same URL result in different cache entries, while identical URL and prompt reuse the cache. ```java // These create DIFFERENT cache entries webFetch.webFetch("https://example.com", "What is the main topic?"); webFetch.webFetch("https://example.com", "List all features"); // This reuses the FIRST cache entry (same URL + prompt) webFetch.webFetch("https://example.com", "What is the main topic?"); ``` -------------------------------- ### Initial Conversation Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/memory/memory-filesystem-tools-demo/README.md Start a conversation with the agent, providing initial information about yourself. ```text USER: My name is Alice. I'm a backend engineer and I prefer short answers. USER: We're migrating from PostgreSQL to CockroachDB this quarter. USER: exit ``` -------------------------------- ### Basic SkillsTool Builder Initialization Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md Demonstrates the most basic configuration of the SkillsTool using its builder pattern, specifying a single directory for skill loading. ```java SkillsTool.builder() .addSkillsDirectory(".claude/skills") .build(); ``` -------------------------------- ### AgentEnvironment.info() Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/AgentEnvironment.md Collects and prints current environment information, including working directory, git status, platform, OS version, and date. Ensure AgentEnvironment is imported. ```java String envInfo = AgentEnvironment.info(); System.out.println(envInfo); // Working directory: /Users/username/projects/myapp // Is directory a git repo: Yes // Platform: mac os x // OS Version: Mac OS X 14.5.0 // Today's date: 2026-01-10 ``` -------------------------------- ### Configure AskUserQuestionTool with Custom Handler Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/ask-user-question-demo/README.md Example of configuring the AskUserQuestionTool with a custom question handler in Application.java. ```java tool = AskUserQuestionTool.builder() .questionHandler(new ConsoleQuestionHandler()) .build(); ``` -------------------------------- ### Custom GrepTool Configuration with Limits Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GrepTool.md Shows how to instantiate GrepTool with custom limits for output length, directory depth, and line length. Useful for large codebases or specific processing needs. ```java GrepTool customGrepTool = new GrepTool( 200000, // maxOutputLength - Maximum output before truncation (default: 100000) 50, // maxDepth - Directory traversal depth (default: 100) 5000 // maxLineLength - Max line length to process (default: 10000) ); ``` -------------------------------- ### Find All Test Files Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Example of finding all files ending with 'Test.java' within the 'src/test' directory recursively. ```java String testFiles = globTool.glob("**/*Test.java", "./src/test"); ``` -------------------------------- ### Configure ChatClient with FileSystemTools Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/memory/memory-filesystem-tools-demo/README.md Sets up the ChatClient with default system prompt, memory directory, and includes ShellTools and FileSystemTools. Also configures ToolCallAdvisor and a custom MyLoggingAdvisor. ```java ChatClient chatClient = chatClientBuilder .defaultSystem(p -> p .text(mainPrompt + "\n\n" + memoryToolsPrompt) .param("MEMORIES_ROOT_DIERCTORY", memoryDir)) // tells the agent where to write .defaultTools( ShellTools.builder().build(), // Bash — for ls, mkdir, etc. FileSystemTools.builder().build()) // Read, Write, Edit — memory file operations .defaultAdvisors( ToolCallAdvisor.builder().build(), MyLoggingAdvisor.builder().build()) .build(); ``` -------------------------------- ### Integrate GlobTool with FileSystemTools Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Demonstrates how to use GlobTool to find configuration files and then use FileSystemTools to read their content. ```java GlobTool globTool = GlobTool.builder().build(); FileSystemTools fileTools = FileSystemTools.builder().build(); // Find all config files String configs = globTool.glob("**/*.yml", "./config"); // Read each config for (String configPath : configs.split("\n")) { String content = fileTools.read(configPath, null, null); // Process config content } ``` -------------------------------- ### Configure Agent with Tools and Advisors Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/index.md Configure a Spring Boot application to build a ChatClient with various tools, sub-agents, and advisors. This example sets up task tools, skills, core utilities, and memory advisors. ```java @SpringBootApplication public class Application { @Bean CommandLineRunner demo(ChatClient.Builder chatClientBuilder, @Value("${BRAVE_API_KEY}") String braveApiKey, @Value("${agent.skills.paths}") List skillPaths, @Value("classpath:/prompt/MAIN_AGENT_SYSTEM_PROMPT_V2.md") Resource agentSystemPrompt) { return args -> { // Configure Task tool with Claude sub-agents var taskTool = TaskTool.builder() .subagentTypes(ClaudeSubagentType.builder() .chatClientBuilder("default", chatClientBuilder.clone()) .skillsResources(skillPaths) .braveApiKey(braveApiKey) .build()) .build(); ChatClient chatClient = chatClientBuilder // Main agent prompt .defaultSystem(p -> p.text(agentSystemPrompt) .param(AgentEnvironment.ENVIRONMENT_INFO_KEY, AgentEnvironment.info()) .param(AgentEnvironment.GIT_STATUS_KEY, AgentEnvironment.gitStatus()) .param(AgentEnvironment.AGENT_MODEL_KEY, "claude-sonnet-4-5-20250929") .param(AgentEnvironment.AGENT_MODEL_KNOWLEDGE_CUTOFF_KEY, "2025-01-01")) .defaultTools( // Sub-Agents taskTool, // Skills SkillsTool.builder().addSkillsResources(skillPaths).build(), // Core Tools ShellTools.builder().build(), FileSystemTools.builder().build(), GrepTool.builder().build(), GlobTool.builder().build(), SmartWebFetchTool.builder(chatClientBuilder.clone().build()).build(), BraveWebSearchTool.builder(braveApiKey).build(), // Task orchestration TodoWriteTool.builder().build(), // User feedback tool (use CommandLineQuestionHandler for CLI apps) AskUserQuestionTool.builder() .questionHandler(new CommandLineQuestionHandler()) .build()) // Advisors .defaultAdvisors( MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().maxMessages(500).build()).build()) .build(); String response = chatClient .prompt("Search for Spring AI documentation and summarize it") .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "session-1")) .call() .content(); }; } } ``` -------------------------------- ### Agent Configuration for Provider Routing Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/TaskTools.md Example of configuring an agent to route to a different model provider, such as Ollama with Llama3. ```markdown --- name: local-searcher model: ollama:llama3 --- ``` -------------------------------- ### Use Relative Path with GlobTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Use a relative path to search for files starting from the current working directory. ```java // Relative to current working directory globTool.glob("*.java", "./src"); ``` -------------------------------- ### Agent Configuration with Disallowed Tools Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/docs/TaskTools.md Example of configuring an agent with specific tools and explicitly disallowing dangerous ones for safety. ```markdown --- name: explorer tools: Read, Grep, Glob disallowedTools: Edit, Write, Bash, Shell --- ``` -------------------------------- ### Injecting and Using Environment Parameters Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/AgentEnvironment.md Demonstrates how to configure agent properties, inject them using `@Value`, and provide them as parameters to the system prompt using AgentEnvironment. ```APIDOC ## Basic Usage ### 1. Configure Agent Properties Add agent configuration to your `application.properties`: ```properties # AGENT CONFIGURATION ## Model info (Must match the configured model above) agent.model=claude-sonnet-4-5-20250929 agent.model.knowledge.cutoff=2025-01 # For GPT models # agent.model=gpt-5-mini-2025-08-07 # agent.model.knowledge.cutoff=2025-08-07 # For Gemini models # agent.model=gemini-3.1-pro-preview # agent.model.knowledge.cutoff=Unknown ``` ### 2. Inject Configuration Values Use `@Value` annotations to inject the configuration: ```java @Value("${agent.model:Unknown}") String agentModel; @Value("${agent.model.knowledge.cutoff:Unknown}") String agentModelKnowledgeCutoff; ``` ### 3. Configure System Prompt with Parameters Use the `AgentEnvironment` utility to provide dynamic context to your system prompt: ```java import org.springaicommunity.agent.utils.AgentEnvironment; ChatClient chatClient = chatClientBuilder .defaultSystem(p -> p.text(systemPrompt) // Load system prompt from classpath .param(AgentEnvironment.ENVIRONMENT_INFO_KEY, AgentEnvironment.info()) .param(AgentEnvironment.GIT_STATUS_KEY, AgentEnvironment.gitStatus()) .param(AgentEnvironment.AGENT_MODEL_KEY, agentModel) .param(AgentEnvironment.AGENT_MODEL_KNOWLEDGE_CUTOFF_KEY, agentModelKnowledgeCutoff)) // ... rest of configuration .build(); ``` ### 4. Reference Parameters in System Prompt Create a system prompt template that references the parameters: **File:** `src/main/resources/prompt/MAIN_AGENT_SYSTEM_PROMPT_V2.md` ```markdown Here is useful information about the environment you are running in: {ENVIRONMENT_INFO} You are powered by the model: {AGENT_MODEL} Assistant knowledge cutoff is {AGENT_MODEL_KNOWLEDGE_CUTOFF}. {GIT_STATUS} ``` ``` -------------------------------- ### Multi-Pattern Search for Service and Repository Classes Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GrepTool.md This example demonstrates how to find all service and repository classes using GrepTool by performing separate searches and combining the results. It utilizes `OutputMode.files_with_matches` and filters by Java files. ```java GrepTool grepTool = GrepTool.builder().build(); // Find all service classes String services = grepTool.grep( "@Service|@Component", "./src", null, OutputMode.files_with_matches, null, null, null, null, null, "java", null, null, null ); // Find all repositories String repositories = grepTool.grep( "@Repository", "./src", null, OutputMode.files_with_matches, null, null, null, null, null, "java", null, null, null ); // Combine results for architectural analysis ``` -------------------------------- ### Explicit Subagent Invocation Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/TaskTools.md Users can explicitly request specific sub-agents by mentioning them in the prompt. This example invokes the code-reviewer subagent. ```java String response = chatClient .prompt("Use the code-reviewer subagent to review my recent changes") .call() .content(); ``` -------------------------------- ### Find Dockerfile with GlobTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Use GlobTool to find 'Dockerfile' files, used for Docker containerization, starting from the current directory. ```java // Docker globTool.glob("**/Dockerfile", "."); ``` -------------------------------- ### Set API Key and Run Application Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/subagent-a2a-demo/README.md Set the Google GenAI API key as an environment variable and run the Spring Boot application using Maven. ```bash export GOOGLE_GENAI_API_KEY=your-key mvn spring-boot:run ``` -------------------------------- ### Find All Markdown Files Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Use a simple glob pattern to find all files with the .md extension starting from the current directory. ```java String mdFiles = globTool.glob("*.md", "."); ``` -------------------------------- ### SubagentType Record Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/Subagent.md Defines a subagent with a resolver and executor. It provides a convenience method to get the subagent's kind from its executor. ```java public record SubagentType( SubagentResolver resolver, SubagentExecutor executor ) { public String kind() { return executor.getKind(); } } ``` -------------------------------- ### Initialize AskUserQuestionTool with CommandLineQuestionHandler Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/spring-ai-agent-utils/README.md Shows how to initialize AskUserQuestionTool for CLI applications using CommandLineQuestionHandler. ```java // For CLI applications, use the provided CommandLineQuestionHandler AskUserQuestionTool askTool = AskUserQuestionTool.builder() .questionHandler(new CommandLineQuestionHandler()) .build(); ``` -------------------------------- ### Use Simple Patterns Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GlobTool.md Best practice for GlobTool: use simple patterns like '*.java' when possible. Explicitly using '**/*.java' is often redundant for simple file extensions and less clear. ```java // ✅ GOOD: Simple pattern is faster globTool.glob("*.java", "./src"); // ⚠️ UNNECESSARY: Explicit ** is redundant for simple extensions globTool.glob("**/*.java", "./src"); // Both work the same, but simple pattern is clearer ``` -------------------------------- ### Initialize BraveWebSearchTool Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/BraveWebSearchTool.md Basic initialization of the BraveWebSearchTool with an API key. Use this to create an instance for performing web searches. ```java BraveWebSearchTool searchTool = BraveWebSearchTool.builder("your-api-key") .build(); String results = searchTool.webSearch("Spring AI framework", null, null); System.out.println(results); ``` -------------------------------- ### TodoWrite Tool Result Example Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/examples/todo-demo/README.md Displays the final output after the agent has completed all tasks, including the grouped and inverted movie titles. ```plaintext Group 1 pmuG tserroF (Forrest Gump) nayR etavirP gnivaS (Saving Private Ryan) Group 2 eliM neerG ehT (The Green Mile) yrotS yoT (Toy Story) Group 3 yawA tsaC (Cast Away) 31 ollopA (Apollo 13) ... ``` -------------------------------- ### Valid Skill Name Examples Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/SkillsTool.md Skill names must be lowercase, alphanumeric, and use hyphens. They have a maximum length of 64 characters. ```yaml # ✅ GOOD name: pdf-processor name: data-analysis name: api-documentation # ❌ BAD name: PDF Processor # No spaces or capitals name: data_analysis # Use hyphens, not underscores name: my-super-long-skill-name-that-exceeds-the-limit # Too long ``` -------------------------------- ### GrepTool Basic Usage Source: https://github.com/spring-ai-community/spring-ai-agent-utils/blob/main/docs/tools/GrepTool.md Demonstrates the basic usage of the GrepTool with default configuration to search for a pattern in the current directory. ```APIDOC ## GrepTool Basic Usage This example shows how to initialize the GrepTool with default settings and perform a basic search. ### Method ```java String grep(String pattern, String path, String glob, OutputMode outputMode, Integer linesBefore, Integer linesAfter, Integer linesSurrounding, Boolean showLineNumbers, Boolean caseInsensitive, String type, Integer headLimit, Integer offset, Boolean multiline) ``` ### Parameters - **pattern** (String) - Required: Regex pattern to search. - **path** (String) - Optional: Directory/file to search (default: current dir). - **glob** (String) - Optional: Glob pattern to filter files (e.g., "*.java"). - **outputMode** (OutputMode) - Optional: Output format (default: files_with_matches). - **linesBefore** (Integer) - Optional: Context lines before match (-B). - **linesAfter** (Integer) - Optional: Context lines after match (-A). - **linesSurrounding** (Integer) - Optional: Context lines before+after (-C). - **showLineNumbers** (Boolean) - Optional: Show line numbers in content mode (-n). - **caseInsensitive** (Boolean) - Optional: Case-insensitive search (-i). - **type** (String) - Optional: File type filter (e.g., "java", "js"). - **headLimit** (Integer) - Optional: Limit output lines/entries. - **offset** (Integer) - Optional: Skip first N lines/entries. - **multiline** (Boolean) - Optional: Enable multiline matching. ### Request Example ```java // Default configuration GrepTool grepTool = GrepTool.builder().build(); // Search for pattern in current directory String result = grepTool.grep( "TODO", // pattern null, // path (uses current directory) null, // glob OutputMode.files_with_matches, // outputMode null, null, null, // context lines (before, after, surrounding) null, // showLineNumbers null, // caseInsensitive null, // type null, null, null // headLimit, offset, multiline ); ``` ```