feat: add basic chat interface with MudBlazor and propose responses API integration
Install MudBlazor 9.2.0, replace Bootstrap layout with MudLayout/MudAppBar, create Chat.razor with message list, text input, auto-scroll, and hardcoded responses. Add ChatMessage shared model. Remove template pages (Counter, Weather), move health check to /health. Include OpenSpec change artifacts for the upcoming wire-responses-api work. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-04-03
|
||||
@@ -0,0 +1,48 @@
|
||||
## Context
|
||||
|
||||
The project has a working Blazor WASM client and ASP.NET Core API with health check connectivity proven. The client currently uses Bootstrap for layout and has template pages (Counter, Weather). No UI component library is installed. This change introduces MudBlazor and builds the first real feature — a chat interface with hardcoded responses.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Install and configure MudBlazor as the UI component library
|
||||
- Build a ChatGPT/Gemini-inspired chat interface
|
||||
- Establish the message model and UI patterns that future phases will build on
|
||||
- Keep hardcoded responses so the UI is testable without API wiring
|
||||
|
||||
**Non-Goals:**
|
||||
- OpenAI API integration (future phase)
|
||||
- Markdown rendering of messages (future phase — Markdig)
|
||||
- Conversation persistence or history (future phase)
|
||||
- Multiple conversations / sidebar navigation (future phase)
|
||||
- Responsive mobile layout optimization
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: MudBlazor component choices
|
||||
|
||||
**Chat message list**: Use `MudPaper` cards inside a scrollable `div` (or `MudStack`). Each message gets a `MudPaper` with `Elevation="0"` and a background color to distinguish user vs assistant.
|
||||
|
||||
**Input area**: `MudTextField` with `Variant="Outlined"` and an `Adornment` send button (icon). This gives a single-line input with integrated send — similar to ChatGPT.
|
||||
|
||||
**Layout**: `MudLayout` + `MudAppBar` + `MudMainContent`. No drawer/sidebar yet — that comes when we add conversation management.
|
||||
|
||||
**Alternative considered**: Building with raw HTML/CSS. Rejected because MudBlazor is in the tech stack spec and provides the component patterns needed for later phases (dialogs, drawers, lists).
|
||||
|
||||
### Decision 2: ChatMessage model location
|
||||
|
||||
Place `ChatMessage.cs` in `ChatAgent.Shared` so it's available to both Client and API when API integration comes. Fields: `Role` (string: "user" or "assistant"), `Content` (string), `Timestamp` (DateTime).
|
||||
|
||||
### Decision 3: Chat page structure
|
||||
|
||||
The Chat.razor component owns the message list (`List<ChatMessage>`) and handles input. No separate service layer yet — the hardcoded response is inline in the component. When AI integration comes, a service will be extracted.
|
||||
|
||||
### Decision 4: Template page cleanup
|
||||
|
||||
Remove Counter.razor and Weather.razor. Move Home.razor from `/` to `/health` so the health check is still accessible but the chat page takes the root route.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [MudBlazor WASM bundle size] → Acceptable for a personal tool; AOT is deferred per stack spec
|
||||
- [No service abstraction for responses] → Intentional; extracting too early adds complexity before the pattern is clear. Will refactor when adding API integration.
|
||||
- [Removing template pages] → Low risk; they were scaffolding. Health check preserved at `/health`.
|
||||
@@ -0,0 +1,35 @@
|
||||
## Why
|
||||
|
||||
The project exists to be a working AI chat interface, but there is no chat UI yet — only a health check page. This change builds the foundational chat experience using MudBlazor components, with hardcoded responses so the UI can be developed and tested independently of the OpenAI API integration.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Install and configure MudBlazor in the Client project (NuGet, CSS/JS, providers, imports)
|
||||
- Replace the Bootstrap navbar/layout with a MudBlazor layout (MudLayout, MudAppBar, MudMainContent)
|
||||
- Create a Chat page with a message list and text input, styled after ChatGPT/Gemini
|
||||
- Add a shared `ChatMessage` model (role + content + timestamp)
|
||||
- Wire the input to append user messages and reply with a hardcoded bot response
|
||||
- Remove template pages (Counter, Weather) that are no longer needed
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `chat-ui`: The chat interface — message display, input handling, auto-scroll, and layout
|
||||
- `mudblazor-setup`: MudBlazor installation, theming, and provider configuration
|
||||
|
||||
### Modified Capabilities
|
||||
<!-- None -->
|
||||
|
||||
## Impact
|
||||
|
||||
- `src/ChatAgent.Client/ChatAgent.Client.csproj`: Add MudBlazor package
|
||||
- `src/ChatAgent.Client/wwwroot/index.html`: Add MudBlazor CSS/JS/font links
|
||||
- `src/ChatAgent.Client/_Imports.razor`: Add MudBlazor using
|
||||
- `src/ChatAgent.Client/Program.cs`: Add MudBlazor services
|
||||
- `src/ChatAgent.Client/Layout/MainLayout.razor`: Replace with MudBlazor layout
|
||||
- `src/ChatAgent.Client/Layout/NavMenu.razor`: Replace or remove Bootstrap nav
|
||||
- `src/ChatAgent.Client/Pages/Chat.razor`: New chat page (becomes default route)
|
||||
- `src/ChatAgent.Client/Pages/Home.razor`: Demote from `/` route or keep as `/health`
|
||||
- `src/ChatAgent.Shared/Models/ChatMessage.cs`: New shared message model
|
||||
- `src/ChatAgent.Client/Pages/Counter.razor`: Remove
|
||||
- `src/ChatAgent.Client/Pages/Weather.razor`: Remove
|
||||
@@ -0,0 +1,66 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Message display
|
||||
|
||||
The chat page SHALL display messages in a vertically scrolling list, with each message showing the sender role (user or assistant), the message content, and a visual distinction between user and assistant messages (e.g., alignment, color, or avatar).
|
||||
|
||||
#### Scenario: User message displayed
|
||||
|
||||
- **WHEN** the user sends a message
|
||||
- **THEN** the message appears in the message list aligned or styled to indicate it is from the user
|
||||
|
||||
#### Scenario: Assistant message displayed
|
||||
|
||||
- **WHEN** the assistant responds
|
||||
- **THEN** the response appears in the message list with distinct styling from user messages (different alignment, color, or avatar)
|
||||
|
||||
#### Scenario: Message ordering
|
||||
|
||||
- **WHEN** multiple messages exist in the conversation
|
||||
- **THEN** messages are displayed in chronological order, oldest at top
|
||||
|
||||
### Requirement: Message input
|
||||
|
||||
The chat page SHALL provide a text input area at the bottom of the page where the user can type and submit messages.
|
||||
|
||||
#### Scenario: Submit via button
|
||||
|
||||
- **WHEN** the user types text and clicks the send button
|
||||
- **THEN** the message is added to the conversation and the input is cleared
|
||||
|
||||
#### Scenario: Submit via Enter key
|
||||
|
||||
- **WHEN** the user types text and presses Enter
|
||||
- **THEN** the message is submitted (same as clicking send)
|
||||
|
||||
#### Scenario: Empty input blocked
|
||||
|
||||
- **WHEN** the user attempts to send an empty or whitespace-only message
|
||||
- **THEN** nothing is sent and no message is added
|
||||
|
||||
### Requirement: Hardcoded response
|
||||
|
||||
In this phase, the assistant SHALL reply with a hardcoded message to every user input. This stubs the AI integration point for future phases.
|
||||
|
||||
#### Scenario: Bot replies to any input
|
||||
|
||||
- **WHEN** the user sends any message
|
||||
- **THEN** the assistant replies with a hardcoded response (e.g., "This is a placeholder response. AI integration coming soon!")
|
||||
|
||||
### Requirement: Auto-scroll
|
||||
|
||||
The message list SHALL automatically scroll to the newest message when a new message is added.
|
||||
|
||||
#### Scenario: New message scrolls into view
|
||||
|
||||
- **WHEN** a new message (user or assistant) is added to the conversation
|
||||
- **THEN** the message list scrolls to the bottom so the new message is visible
|
||||
|
||||
### Requirement: Chat page is default route
|
||||
|
||||
The chat page SHALL be the default route (`/`) of the application.
|
||||
|
||||
#### Scenario: App opens to chat
|
||||
|
||||
- **WHEN** the user navigates to the root URL
|
||||
- **THEN** the chat page is displayed
|
||||
@@ -0,0 +1,46 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: MudBlazor package installed
|
||||
|
||||
The Client project SHALL have MudBlazor 9.2.0 installed as a NuGet dependency.
|
||||
|
||||
#### Scenario: Package reference present
|
||||
|
||||
- **WHEN** the Client project is built
|
||||
- **THEN** MudBlazor 9.2.0 is resolved as a dependency
|
||||
|
||||
### Requirement: MudBlazor services registered
|
||||
|
||||
MudBlazor services SHALL be registered in the Client's DI container via `AddMudServices()`.
|
||||
|
||||
#### Scenario: Services available
|
||||
|
||||
- **WHEN** the application starts
|
||||
- **THEN** MudBlazor services (snackbar, dialog, etc.) are available for injection
|
||||
|
||||
### Requirement: MudBlazor assets loaded
|
||||
|
||||
The Client's `index.html` SHALL include MudBlazor CSS, JS, and font references.
|
||||
|
||||
#### Scenario: Styles and scripts present
|
||||
|
||||
- **WHEN** the application loads in the browser
|
||||
- **THEN** MudBlazor CSS (`_content/MudBlazor/MudBlazor.min.css`), JS (`_content/MudBlazor/MudBlazor.min.js`), and Material Design Icons font are loaded
|
||||
|
||||
### Requirement: MudBlazor layout providers
|
||||
|
||||
The app root SHALL include `MudThemeProvider`, `MudPopoverProvider`, and `MudDialogProvider` so MudBlazor components function correctly.
|
||||
|
||||
#### Scenario: Providers present
|
||||
|
||||
- **WHEN** any MudBlazor component is rendered
|
||||
- **THEN** it functions correctly because the required providers are in the component tree
|
||||
|
||||
### Requirement: MudBlazor layout replaces Bootstrap
|
||||
|
||||
The application layout SHALL use MudBlazor layout components (`MudLayout`, `MudAppBar`, `MudMainContent`) instead of the current Bootstrap navbar.
|
||||
|
||||
#### Scenario: Layout renders with MudBlazor
|
||||
|
||||
- **WHEN** any page is displayed
|
||||
- **THEN** the page is wrapped in a MudBlazor layout with an app bar showing the application name
|
||||
@@ -0,0 +1,38 @@
|
||||
## 1. MudBlazor Setup
|
||||
|
||||
- [x] 1.1 Install MudBlazor 9.2.0 NuGet package in ChatAgent.Client
|
||||
- [x] 1.2 Add MudBlazor CSS, JS, and Material Design Icons font to index.html (remove Bootstrap CSS)
|
||||
- [x] 1.3 Add `@using MudBlazor` to _Imports.razor
|
||||
- [x] 1.4 Register MudBlazor services (`AddMudServices()`) in Program.cs
|
||||
- [x] 1.5 Add MudThemeProvider, MudPopoverProvider, MudDialogProvider to MainLayout.razor
|
||||
|
||||
## 2. Layout Migration
|
||||
|
||||
- [x] 2.1 Replace MainLayout.razor with MudBlazor layout (MudLayout, MudAppBar, MudMainContent)
|
||||
- [x] 2.2 Remove NavMenu.razor (Bootstrap navbar no longer needed)
|
||||
- [x] 2.3 Remove MainLayout.razor.css (MudBlazor handles styling)
|
||||
|
||||
## 3. Shared Model
|
||||
|
||||
- [x] 3.1 Create ChatMessage.cs in ChatAgent.Shared/Models with Role, Content, Timestamp
|
||||
|
||||
## 4. Chat Page
|
||||
|
||||
- [x] 4.1 Create Chat.razor at route `/` with message list and input area
|
||||
- [x] 4.2 Implement message display with MudPaper cards (distinct styling for user vs assistant)
|
||||
- [x] 4.3 Implement text input with MudTextField and send button adornment
|
||||
- [x] 4.4 Wire Enter key and send button to submit handler
|
||||
- [x] 4.5 Block empty/whitespace-only submissions
|
||||
- [x] 4.6 Add hardcoded assistant response after each user message
|
||||
- [x] 4.7 Implement auto-scroll to bottom on new messages
|
||||
|
||||
## 5. Cleanup
|
||||
|
||||
- [x] 5.1 Move Home.razor route from `/` to `/health`
|
||||
- [x] 5.2 Remove Counter.razor and Weather.razor
|
||||
- [x] 5.3 Update app.css — remove Bootstrap-specific styles, keep custom styles that still apply
|
||||
|
||||
## 6. Verify
|
||||
|
||||
- [x] 6.1 Run `dotnet build` on the solution to confirm no errors
|
||||
- [ ] 6.2 Manually verify: chat page loads at `/`, messages display correctly, hardcoded response works
|
||||
Reference in New Issue
Block a user