AI Chatbot Feature
Add a real AI chat feature with streaming responses, conversation history, and graceful failure handling.
Add this plan to a project to track work and checks.Open workspace
The route
6 steps to Done
- 01
Define the assistant spec
Decide what the assistant does, its boundaries, and its system prompt.
Preview prompt + verify gate ▾Hide ▴
Define the AI assistant spec for this app. Specify: what the assistant helps with (its scope) and what it should refuse; the exact system prompt text; which LLM provider/model is used and where the API key lives (backend env var only); the conversation model (conversation id, messages with role/content/timestamp, owner); and limits (max message length, history window sent to the model). Do not implement yet.
- ✓System prompt text is written out
- ✓Key location is backend env only
- ✓Conversation/message model is defined
- 02
Build the chat UI
A trustworthy chat surface with all interaction states.
Preview prompt + verify gate ▾Hide ▴
Build the chat interface. Requirements: scrollable message list with distinct user/assistant styling; input with send button and Enter-to-send; send disabled while a response is pending; a typing indicator while waiting; auto-scroll to the newest message; an empty state introducing the assistant; timestamps; mobile responsive layout. Wire it to local state for now - the real API comes next.
- ✓Send disables while pending
- ✓Typing indicator renders
- ✓Auto-scroll works on new messages
- 03
Integrate the real LLM API
Replace nothing with something: real model responses through the backend.
Preview prompt + verify gate ▾Hide ▴
Implement the backend chat endpoint with the real LLM. Requirements: the frontend posts the message to our backend; the backend calls the LLM API with the system prompt and recent history window, using the key from environment variables; the response is returned to the UI (stream it if supported, otherwise show the typing indicator until complete); errors from the API map to a visible UI error with a retry button - never an infinite spinner. Prove it is real by asking something no canned array could answer.
- ✓Responses are genuinely from the model
- ✓The key is absent from all frontend code
- ✓API failure shows a retry-able error, not a stuck spinner
- 04
Persist conversation history
Chats must survive refresh and be scoped to their owner.
Preview prompt + verify gate ▾Hide ▴
Implement history persistence. Requirements: store every user and assistant message in the database under a conversation id and owner; on load, restore the active conversation; support starting a new conversation and listing past ones with titles (first message snippet); include the recent history window in each LLM call so the assistant has context; verify context by referencing something said earlier in the chat.
- ✓Refresh restores the conversation
- ✓The assistant remembers earlier messages
- ✓New conversation starts clean
- ✓Users see only their own conversations
- 05
Harden failure and limit handling
AI features fail in production - make every failure visible and recoverable.
Preview prompt + verify gate ▾Hide ▴
Harden the chat. Requirements: handle API timeout, rate limit, and server errors with distinct friendly messages and a retry action that resends the failed message; enforce max message length with an inline counter/error; prevent empty sends; if the model returns nothing, show a fallback message rather than a blank bubble; log failures server-side. Simulate at least one failure (bad key or forced error) to prove the UI path.
- ✓A simulated API failure shows the error UI
- ✓Retry resends the failed message
- ✓Overlong/empty messages are blocked inline
- 06
Chat QA pass
Verify realness, persistence, and resilience end to end.
Preview prompt + verify gate ▾Hide ▴
Run chat QA and report PASS/FAIL with evidence: a novel question gets a real model answer; follow-up shows context memory; refresh restores history; new conversation isolates cleanly; forced API failure shows recoverable error; rapid double-send is blocked; mobile layout works. Fix all failures and re-run.
- ✓Context memory demonstrated
- ✓Forced failure path verified
- ✓History persistence verified via refresh
- ✓All failures fixed