Tool Calling & Programmatic Prompts
Tools let the LLM call methods in your application during a conversation — query a database, look up an order, send an email, or any other action you want the assistant to be able to perform. Vaadin supports two ways to expose tools: registered tool objects (covered on this page) and framework-agnostic Controllers.
Tool Calling
Register objects with vendor-specific @Tool annotations that the LLM can invoke:
Source code
Java
public class WeatherTools {
@Tool("Get current weather for a city")
public String getWeather(String city) {
return weatherService.getCurrentWeather(city);
}
}
var orchestrator = AIOrchestrator
.builder(provider, systemPrompt)
.withMessageList(messageList)
.withInput(messageInput)
.withTools(new WeatherTools())
.build();For Spring AI, use @org.springframework.ai.tool.annotation.Tool. For LangChain4j, use @dev.langchain4j.agent.tool.Tool.
|
Tip
|
Framework-Agnostic Tools via Controllers
For a reusable set of tools that does not depend on a specific LLM framework’s annotations, or when a lifecycle hook is needed after each LLM request cycle, implement AIController instead. GridAIController and ChartAIController are built-in examples. Controllers and tool objects can be combined on the same orchestrator.
|
Programmatic Prompts
Send prompts without a Message Input component using prompt(). This is useful for triggering AI interaction from button clicks or other events:
|
Note
|
One Request at a Time
The orchestrator processes one prompt at a time. If prompt() is called while a previous request is still streaming, the new call is logged as a warning and silently dropped. Wait for the current response to complete before sending another prompt.
|
|
Important
|
UI Context Required
prompt() requires an active UI context. If called from a background thread or outside a Vaadin request, it throws an IllegalStateException. Always call prompt() from within a UI event handler or wrap the call in ui.access().
|
Prompts with Attachments
The prompt(String, List<AIAttachment>) overload sends a prompt together with caller-supplied attachments. This is useful when attachments are produced server-side — generated files, fetched data, or content from sources other than an upload component:
Source code
Java
byte[] report = generateReport();
orchestrator.prompt("Summarize the attached report.",
List.of(new AIAttachment(
"report.pdf", "application/pdf", report)));The message and its attachments appear in the Message List and are forwarded to the LLM provider, just as if the user had uploaded the files through a configured file receiver. Pass an empty list to send no attachments; passing null throws a NullPointerException.
|
Note
|
This overload uses only the supplied list. If a file receiver is configured via withFileReceiver() (see File Attachments), attachments pending in it are not included — they stay queued for the next prompt(String) call or the user’s next submit through a connected input. To merge uploaded and programmatic attachments, drain the receiver explicitly and pass the combined list.
|