diff --git a/spring-ai-modules/pom.xml b/spring-ai-modules/pom.xml index 9aac4a8f6797..00de325a278e 100644 --- a/spring-ai-modules/pom.xml +++ b/spring-ai-modules/pom.xml @@ -40,6 +40,7 @@ spring-ai-vector-stores spring-ai-mcp-annotations spring-ai-subagent-orchestrator + spring-ai-ask-user-question spring-ai-anthropic diff --git a/spring-ai-modules/spring-ai-ask-user-question/pom.xml b/spring-ai-modules/spring-ai-ask-user-question/pom.xml new file mode 100644 index 000000000000..46691bab0346 --- /dev/null +++ b/spring-ai-modules/spring-ai-ask-user-question/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + + com.baeldung + spring-ai-modules + 0.0.1 + ../pom.xml + + + spring-ai-cli-agent + spring-ai-ask-user-question + Spring AI AskUserQuestionTool reference implementation + + + + org.springframework.ai + spring-ai-starter-model-ollama + + + org.springaicommunity + spring-ai-agent-utils + 0.10.0 + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + org.springframework.ai + spring-ai-bom + ${spring-ai.version} + pom + import + + + + + + 2.0.0 + 4.1.1 + 1.5.38 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/AgentConfiguration.java b/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/AgentConfiguration.java new file mode 100644 index 000000000000..ff948f3ba400 --- /dev/null +++ b/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/AgentConfiguration.java @@ -0,0 +1,32 @@ +package com.baeldung.agent; + +import org.springaicommunity.agent.tools.AskUserQuestionTool; +import org.springaicommunity.agent.utils.CommandLineQuestionHandler; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; +import org.springframework.ai.chat.memory.ChatMemory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +class AgentConfiguration { + + @Bean + ChatClient chatClient(ChatClient.Builder builder, ChatMemory chatMemory) { + return builder + .defaultSystem("You are an interactive CLI assistant.\n" + + "Be helpful, concise.\n" + + "If you need information, a preference or disambiguation from the user,\n" + + "Always use an available tool to ask - never ask in ordinary assistant text.\n" + + "After receiving the tool result, continue with the response.\n") + .defaultTools( + AskUserQuestionTool.builder() + .questionHandler(new CommandLineQuestionHandler()) + .build() + ) + .defaultAdvisors( + MessageChatMemoryAdvisor.builder(chatMemory).build() + ) + .build(); + } +} \ No newline at end of file diff --git a/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/Application.java b/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/Application.java new file mode 100644 index 000000000000..318de18ae181 --- /dev/null +++ b/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/Application.java @@ -0,0 +1,11 @@ +package com.baeldung.agent; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} \ No newline at end of file diff --git a/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/ChatLoop.java b/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/ChatLoop.java new file mode 100644 index 000000000000..2cc9d40dee8f --- /dev/null +++ b/spring-ai-modules/spring-ai-ask-user-question/src/main/java/com/baeldung/agent/ChatLoop.java @@ -0,0 +1,53 @@ +package com.baeldung.agent; + +import java.util.Scanner; + +import org.springaicommunity.agent.tools.AskUserQuestionTool.InvalidUserAnswerException; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.ai.chat.memory.ChatMemory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; +import org.springframework.web.client.ResourceAccessException; + +@Component +class ChatLoop implements CommandLineRunner { + + private final ChatClient chatClient; + + ChatLoop(ChatClient chatClient) { + this.chatClient = chatClient; + } + + @Override + public void run(String... args) { + System.out.println("AI Agent (type 'exit' to quit)\n"); + try (Scanner scanner = new Scanner(System.in)) { + while (true) { + System.out.print("You: "); + String input = scanner.nextLine(); + if ("exit".equalsIgnoreCase(input.trim())) break; + + try { + String response = chatClient.prompt() + .user(input) + .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "session-1")) + .call() + .content(); + System.out.println("AI: " + response + "\n"); + } + catch (InvalidUserAnswerException e) { + System.out.println("AI: Sorry, I couldn't process your answer: " + e.getMessage() + "\n"); + } + catch (ResourceAccessException e) { + System.out.println("\nError: Unable to connect to the model server."); + System.out.println("Please check that the server is running and accessible.\n"); + System.out.println("Type 'exit' to quit or try again."); + } + catch (Exception e) { + System.out.println("\nError: An unexpected error occurred: " + e.getMessage()); + System.out.println("Type 'exit' to quit or try again."); + } + } + } + } +} \ No newline at end of file diff --git a/spring-ai-modules/spring-ai-ask-user-question/src/main/resources/application.properties b/spring-ai-modules/spring-ai-ask-user-question/src/main/resources/application.properties new file mode 100644 index 000000000000..26fb9796fafd --- /dev/null +++ b/spring-ai-modules/spring-ai-ask-user-question/src/main/resources/application.properties @@ -0,0 +1,4 @@ +spring.ai.ollama.base-url=http://localhost:11434 +spring.ai.ollama.chat.options.model=gemma4:e4b +spring.ai.retry.max-attempts=1 +logging.level.org.springframework.ai.model.tool=DEBUG \ No newline at end of file