Repository navigation
Serve a Vaadin chat at /ui with a blocking reply - #98
Merged
Merged
Conversation
First step of moving the chat from HTMX to Vaadin. The new view shows the existing "web" conversation, read from the agent's own chat memory, and sends a question through Agent.respondTo, showing the reply once it is complete. Streaming is the next step. The HTMX chat at /chat is unchanged and is still the start page. The UI lives in its own Gradle module, ui, which depends on base. The ui module builds Vaadin in production mode: a development-mode build only runs with Vaadin's dev server on the classpath, so the packaged jar and the Jib image would not start. With no custom frontend this uses Vaadin's pre-compiled bundle and needs no Node. Vaadin 25 applies no theme by default, so the stock Lumo theme is loaded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without a layout the transcript ran edge to edge with nothing telling the speakers apart, which read as broken next to the HTMX chat. The reader's messages now sit on the right and the agent's on the left, in a centred reading column, as in /chat. Only Lumo tokens are used, so colours and light/dark stay with the later theme step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
CI failure here is unrelated to this change: it's |
arefbehboudi
self-requested a review
October 23, 2026 18:14
Collaborator
|
Thanks @JoseWalker, this is exactly the scope I had in mind: small, isolated |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First step of the split we agreed on: the Vaadin dependency, a chat view at
/ui, the existingconversation from the agent's own chat memory, and a composer with a blocking (non-streaming)
reply. Streaming is the next MR.
What it does
ui, depending only onbase;appdepends onui.ChatViewat/uishows thewebconversation — the same one the HTMX chat uses — read withChatMemoryRepository.findByConversationId, user and assistant messages only, the same filteras
ChatChannel.loadHistoryAsHtml. There is no second store: a message sent from/uishows upat
/chatand vice versa.Agent.respondTo(conversationId, question)and appends the question and the replyas plain text. Markup in messages is displayed, never rendered.
to the server log only.
/chatis untouched and/still redirects to it.Worth knowing
lock, so every
/uitab of that session waits until the reply is back, and the question onlyappears together with its answer. The streaming MR moves the call off the request thread.
ui/build.gradle. A development-mode build only starts with Vaadin's devserver on the classpath, so the packaged jar and the Jib image would fail on startup. With no
custom frontend, production mode uses Vaadin's pre-compiled bundle and needs no Node.
bootRunruns in production mode too.AppShellConfigurator. JavaClaw's own look and light/dark are a later MR.the left, like
/chat, instyles/chat.cssusing only Lumo tokens. Without it the transcriptran edge to edge and looked worse than the page it will replace. Happy to drop it if you'd rather
keep this MR even more bare.
/uishows what the chat memory holds — at most the last 20 messages,because of
MessageWindowChatMemory's default window — exactly like/chattoday.Not in this MR
Streaming, Stop, Markdown, copy, edit/regenerate, theme, keyboard shortcuts, mobile layout, code
highlighting, conversation list and settings — each comes as its own MR, in that order.
Verified
./gradlew clean build: all tests pass, includingModularityTestsandModuleBoundaryArchTest;8 new tests in
ChatViewTest.java -jar app/build/libs/app-1.0.0-SNAPSHOT.jar) starts;/ui/returns 200and
/still redirects to/chat./uigets its reply, and the same exchange is visible at/chat.