Class AIOrchestrator
- All Implemented Interfaces:
Serializable
This class is a non-visual coordination engine that connects UI components
with an LLM provider. It is not a UI component itself and should
not be added to a layout or the UI. Instead, add the individual UI
components (e.g. MessageInput, MessageList) to your layout
and pass them to the orchestrator through its AIOrchestrator.Builder. The
orchestrator then wires the components together and manages the LLM
interaction behind the scenes.
It provides:
- LLM integration
- Component wiring (input, message list, file receiver)
- Tool execution coordination
- Controller-based feature composition via
AIController - Programmatic invocation via
prompt(String)
The orchestrator is configured via a fluent builder:
AIOrchestrator orchestrator = AIOrchestrator
.builder(llmProvider, systemPrompt).withInput(messageInput) // optional
.withMessageList(messageList) // optional
.withFileReceiver(uploadManager) // optional
.withTools(toolObj) // optional, for @Tool annotations
.withUserName(userName) // optional
.withAssistantName(assistantName) // optional
.withResponseListener(e -> save(e.getResponse())) // optional
.withHistory(savedHistory, savedAttachments) // optional, for restore
.build();
The orchestrator tracks conversation history internally and delegates to the
LLMProvider for the LLM's working memory. Use getHistory()
to obtain a snapshot and AIOrchestrator.Builder.withHistory(List, Map) to restore
conversation state (including attachments) across sessions. To persist
history automatically after each exchange, use
AIOrchestrator.Builder.withResponseListener(ResponseListener).
Serialization: The LLM provider and tool objects are not serialized
(they are transient). After deserialization, call
reconnect(LLMProvider) to restore transient dependencies and replay
the conversation history onto the new provider:
orchestrator.reconnect(provider).withTools(toolObj) // optional
.withAttachments(attachmentsByMsgId) // optional
.apply();
The conversation history, UI component bindings, and listeners are preserved
across serialization.
- Author:
- Vaadin Ltd
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classBuilder for configuring and creating anAIOrchestratorinstance.static classFluent API for restoring transient dependencies on anAIOrchestratorafter deserialization. -
Method Summary
Modifier and TypeMethodDescriptionstatic AIOrchestrator.Builderbuilder(LLMProvider provider, String systemPrompt) Creates a new builder for AIOrchestrator with a system prompt.Returns the conversation history.voidSends a prompt to the AI orchestrator programmatically.voidprompt(String userMessage, List<AIAttachment> attachments) Sends a prompt with caller-supplied attachments.reconnect(LLMProvider provider) Returns aAIOrchestrator.Reconnectorto restore transient dependencies after deserialization.
-
Method Details
-
builder
Creates a new builder for AIOrchestrator with a system prompt.A system prompt is strongly recommended — without one, the LLM has no guidance beyond tool descriptions and may behave inconsistently.
- Parameters:
provider- the LLM providersystemPrompt- the system prompt for the LLM, ornullto omit- Returns:
- a new builder
-
prompt
Sends a prompt to the AI orchestrator programmatically. This method allows sending prompts without requiring an input component.This is useful for scenarios where you want to trigger AI interaction from button clicks or other UI events without using a message input component.
Attachments are taken from a configured
AIFileReceiver(if any). To send a prompt with caller-supplied attachments, useprompt(String, List).If a request is already being processed, this method logs a warning and returns without processing the new prompt.
- Parameters:
userMessage- the prompt to send to the AI- Throws:
IllegalStateException- if no UI context is available, or if the orchestrator needs to be reconnected after deserialization (seereconnect(LLMProvider))
-
prompt
Sends a prompt with caller-supplied attachments. Useful for programmatic flows where attachments are produced server-side — generated files, fetched data, content from non-Upload sources — rather than uploaded through a UI component.Behaves like
prompt(String)otherwise: the message and attachments appear in the message list, the request listener fires with themessageIdalso recorded in the conversation history, and the attachments are forwarded to theLLMProvider.LLMRequest.Interaction with a configured
AIFileReceiver: this overload uses only the supplied list and does not drain the receiver. Attachments pending in the receiver stay there for the next call toprompt(String)(or the user's next submit through a connected input). To merge UI-driven and programmatic attachments, the caller must drain the receiver explicitly and pass the combined list.If a request is already being processed, this method logs a warning and returns without processing the new prompt.
- Parameters:
userMessage- the prompt to send to the AIattachments- the attachments to send with the prompt; pass an empty list for none. Copied defensively — subsequent mutations of the caller's list have no effect.- Throws:
NullPointerException- ifattachmentsisnullor containsnullelementsIllegalStateException- if no UI context is available, or if the orchestrator needs to be reconnected after deserialization (seereconnect(LLMProvider))
-
reconnect
Returns aAIOrchestrator.Reconnectorto restore transient dependencies after deserialization. The provider is required; tools and attachments are optional.Example usage:
orchestrator.reconnect(provider).withTools(toolObj) .withAttachments(attachmentsByMsgId).apply();Calling
AIOrchestrator.Reconnector.apply()replays the existing conversation history onto the new provider so it has full context for subsequent prompts. The UI is not modified -- message list, input, and file receiver components retain their state across serialization.This method should only be called on a deserialized instance where the provider is
null.- Parameters:
provider- the LLM provider to use, notnull- Returns:
- a reconnector for restoring additional transient dependencies
- Throws:
NullPointerException- if provider isnullIllegalStateException- if the orchestrator is already connected (provider is notnull)
-
getHistory
Returns the conversation history.The returned list contains all user and assistant messages exchanged through this orchestrator. User messages include a
ChatMessage.messageId()matching the id provided to theRequestListener, which can be used to correlate with externally stored attachment data.Note: This method returns a point-in-time snapshot. If a streaming response is in progress, the snapshot may contain the user message without its corresponding assistant response. For automatic persistence, use
AIOrchestrator.Builder.withResponseListener(ResponseListener)to be notified at the right time, then callgetHistory()from that callback.- Returns:
- an unmodifiable copy of the conversation history, never
null
-