Files
AgenticCode/.planning/research/FEATURES.md
2026-03-27 00:59:24 +00:00

15 KiB

Feature Research

Domain: Personal AI chat web application (single-user, OpenAI GPT backend, Blazor WebAssembly) Researched: 2026-03-27 Confidence: HIGH (core features verified against live ChatGPT/Claude, OpenAI API docs, and Blazor ecosystem)

Feature Landscape

Table Stakes (Users Expect These)

Features users assume exist. Missing these = product feels incomplete.

Feature Why Expected Complexity Notes
Send message and receive response Core function of any AI chat app LOW POST to backend API; backend calls OpenAI chat completions endpoint
Streaming token-by-token responses ChatGPT normalized this; blocking responses feel broken MEDIUM Server-Sent Events (SSE) from backend; HttpClient streaming or SignalR on WASM client; creates "typewriter" effect
Markdown rendering in AI responses GPT always responds with markdown; raw markdown is unreadable MEDIUM Markdig library on backend or client; MarkupString in Blazor to render HTML; Markdown.ColorCode for syntax highlighting
Syntax-highlighted code blocks Code responses are a primary GPT use-case; unformatted code is unusable MEDIUM Markdown.ColorCode NuGet package; note: CsharpToColouredHTML has WASM compatibility issues — use base ColorCode package
Copy-to-clipboard on code blocks Standard expectation from ChatGPT/Claude; users paste code constantly LOW JavaScript interop in Blazor (navigator.clipboard.writeText); small JS interop call
Multiple named conversations Users need to separate topics; single-thread apps feel like a toy MEDIUM Conversation list in sidebar; each conversation has ID, title, message list; JSON file per conversation
Create and switch between conversations Navigation between conversations is core workflow LOW Once multi-conversation storage exists, switching is just loading by ID
Delete conversations Users need to clean up; no delete = clutter accumulates LOW Remove JSON file; update conversation list
Persist conversation history across sessions Without persistence, app is useless after refresh MEDIUM JSON file storage on disk; load on startup; save on every message
Auto-scroll to latest message Standard chat behavior; missing it feels broken LOW JavaScript interop to scroll div; or CSS scroll-behavior
Loading/thinking indicator Users need feedback that a request is in-flight LOW Show spinner or "..." while awaiting first token; hide once streaming starts
Input disabled during response Prevent double-submit while response is streaming LOW Boolean state flag; disable textarea and button while isStreaming = true
Send on Enter key Standard text input convention for chat LOW @onkeydown handler; Shift+Enter for newline
Responsive layout Mobile-friendly is expected even for personal tools LOW CSS flexbox/grid; sidebar collapses on small screens

Differentiators (Competitive Advantage)

Features that set the product apart. Not required, but valuable.

Feature Value Proposition Complexity Notes
Auto-generated conversation titles Reduces naming friction; GPT can summarize first message as title LOW Call GPT with "Summarize this in 5 words" after first exchange; update conversation title
System prompt / persona configuration Power users want to customize GPT behavior per conversation MEDIUM Add systemPrompt field to conversation model; include as first message in API payload
Message edit and regenerate Fix typos without starting over; common in ChatGPT MEDIUM Truncate conversation at edited message; resend; requires re-streaming
Token usage display Helps users understand context window consumption; teaches GPT behavior LOW OpenAI API returns usage in response; display in footer or message metadata
Conversation search Find a past conversation by keyword MEDIUM Client-side search over loaded conversation titles; full-text needs indexing
Export conversation Save as markdown or text file LOW Serialize messages to markdown string; trigger browser download via JS interop
Model selector (GPT-4o vs GPT-4o-mini) Cost vs quality tradeoff is real; power users want control LOW Dropdown stored in app settings or per-conversation; passed as model parameter in API call
Well-commented tutorial-style code The project doubles as a Blazor learning resource LOW (implementation cost) Inline // Blazor: comments on lifecycle hooks, DI, component patterns — this is a core differentiator for this specific project's purpose

Anti-Features (Commonly Requested, Often Problematic)

Features that seem good but create problems.

Feature Why Requested Why Problematic Alternative
Authentication / login "What if someone else uses it?" Single-user personal tool; adds OAuth complexity with zero value Leave open; document that it's intentionally single-user
Database (SQL/SQLite) "JSON doesn't scale" Premature optimization for a personal tool; adds EF Core migration complexity JSON files are fast, human-readable, and zero-setup — perfect for this scope
Real-time sync across tabs "What if I have two windows open?" SignalR state sync complexity; no real use case for single user Reload on focus; acceptable for personal tool
Plugin / tool calling system "GPT can call functions!" That's LangChain/MCP territory; v2 scope — building it now adds architecture complexity before core chat works Defer to v2 milestone with LangChain and MCP servers
Voice input / output ChatGPT has it OpenAI Realtime API is being deprecated May 2026; adds Web Speech API complexity; out of scope Text-only for v1
Image uploads / multimodal GPT-4o supports it WASM file upload + base64 encoding + vision API adds significant complexity Text chat first; defer multimodal to v2
Conversation branching "What if I want to explore different answers?" Complex tree data structure; confusing UX; rare real-world use Regenerate last response is sufficient for 95% of cases
Infinite scroll / lazy loading "What about long conversations?" Adds virtual scrolling complexity; JSON load is fine at personal scale Load full conversation on select; revisit if performance suffers
PWA / offline support "Make it installable" Service worker complexity; AI chat requires internet anyway Responsive web design is sufficient

Feature Dependencies

[JSON File Storage]
    └──required by──> [Multiple Conversations]
                          └──required by──> [Create / Switch / Delete Conversations]
                          └──required by──> [Persist History Across Sessions]

[OpenAI API Call (blocking)]
    └──required by──> [Streaming Responses]
                          └──required by──> [Loading Indicator]
                          └──required by──> [Input Disabled During Streaming]

[Markdown Rendering]
    └──required by──> [Syntax-Highlighted Code Blocks]
                          └──required by──> [Copy-to-Clipboard on Code Blocks]

[Streaming Responses] ──enhances──> [Auto-Scroll to Latest Message]

[Multiple Conversations] ──enables──> [Auto-Generated Titles]
[Multiple Conversations] ──enables──> [Conversation Search]
[Multiple Conversations] ──enables──> [Export Conversation]

[System Prompt Config] ──enhances──> [Multiple Conversations]
    (each conversation can have its own persona)

[Token Usage Display] ──conflicts with [Streaming]
    (usage metadata only available when stream=false or in the final chunk)

Dependency Notes

  • JSON File Storage required by Multiple Conversations: Conversations need somewhere to live before the list/switch UI can be built. Storage phase must precede conversation management phase.
  • Blocking API call required by Streaming: Must implement the non-streaming call first to understand the request/response shape, then layer SSE streaming on top.
  • Markdown Rendering required by Syntax Highlighting: ColorCode is a Markdig pipeline extension — Markdig must be wired in before syntax highlighting can be added.
  • Token Usage Display conflicts with Streaming: OpenAI streams individual content chunks; the usage field only appears in the final chunk (finish_reason: stop). Implementation must capture the last chunk separately.

MVP Definition

Launch With (v1)

Minimum viable product — what's needed to validate the concept.

  • Send message, receive non-streaming GPT response — validates API connectivity and basic loop
  • Streaming responses — core UX differentiator; blocking responses feel unacceptable
  • Markdown rendering with syntax highlighting — GPT responses are markdown; unrendered output is unusable
  • Create / switch / delete multiple conversations — without this, the app is a single disposable thread
  • JSON file persistence — conversations must survive page refresh to be useful
  • Auto-scroll and loading indicator — baseline polish that makes the app feel complete
  • Copy-to-clipboard on code blocks — high-frequency action for developer-focused use
  • Tutorial-style inline code comments — this project's defining purpose as a learning resource

Add After Validation (v1.x)

Features to add once core is working.

  • Auto-generated conversation titles — reduces friction once the core loop is validated
  • System prompt / persona configuration — natural extension once multi-conversation is stable
  • Model selector — easy add once API layer is clean; real value for cost control
  • Export conversation — low complexity, high occasional value

Future Consideration (v2+)

Features to defer until product-market fit is established.

  • Message edit and regenerate — medium complexity; wait until core loop is solid
  • Token usage display — useful but not blocking; needs streaming completion handling
  • Conversation search — only valuable when there are many conversations to search
  • LangChain / agentic workflows — explicitly v2 scope per PROJECT.md
  • RAG document retrieval — v2 scope
  • MCP server integration — v2 scope

Feature Prioritization Matrix

Feature User Value Implementation Cost Priority
Send message / receive response HIGH LOW P1
Streaming responses HIGH MEDIUM P1
Markdown + syntax highlighting HIGH MEDIUM P1
Multiple conversations + persistence HIGH MEDIUM P1
Auto-scroll + loading indicator HIGH LOW P1
Copy code to clipboard HIGH LOW P1
Tutorial-style code comments HIGH (for this project) LOW P1
Auto-generated conversation titles MEDIUM LOW P2
System prompt configuration MEDIUM MEDIUM P2
Model selector MEDIUM LOW P2
Export conversation LOW LOW P2
Token usage display LOW LOW P2
Message edit and regenerate MEDIUM MEDIUM P3
Conversation search LOW MEDIUM P3

Priority key:

  • P1: Must have for launch
  • P2: Should have, add when possible
  • P3: Nice to have, future consideration

Competitor Feature Analysis

Feature ChatGPT (OpenAI) Claude (Anthropic) This Project
Streaming responses Yes, token-by-token Yes, token-by-token Yes — SSE via backend API
Markdown rendering Yes Yes Yes — Markdig + MarkupString
Syntax highlighted code Yes + copy button Yes + copy button Yes — Markdown.ColorCode
Multiple conversations (sidebar) Yes Yes (Projects) Yes — JSON file per conversation
Conversation persistence Yes (cloud) Yes (cloud) Yes — local JSON files
Auto-generated titles Yes Yes v1.x — GPT summarization call
System prompt Via custom instructions Via system prompt v1.x — per-conversation field
Model selector Yes (GPT-5.4 variants) Yes (Opus/Sonnet/Haiku) v1.x — GPT-4o vs GPT-4o-mini
Voice input/output Yes (Advanced Voice Mode) No Deliberately excluded from v1
Image uploads Yes (multimodal) Yes (multimodal) Deliberately excluded from v1
Plugin / tool calling Yes (via GPT Actions) Yes (via tool use) v2 — MCP servers
RAG / document search Yes (file attachments) Yes (Projects + files) v2 — RAG milestone
Auth / multi-user Yes Yes Deliberately excluded (single user)

Blazor-Specific Implementation Notes

These are not features per se, but implementation constraints that affect feature complexity in Blazor WebAssembly:

  • JavaScript Interop is required for: clipboard access, scroll-to-bottom, syntax highlighting via client-side JS libraries (Highlight.js alternative to server-side ColorCode)
  • API key must never reach WASM client: all OpenAI calls must go through the ASP.NET Core backend API — the WASM client calls the backend, the backend calls OpenAI
  • Streaming from backend to WASM client: options are SSE (Server-Sent Events via HttpClient streaming) or SignalR HubConnection; SSE is simpler for one-way server-to-client streaming; SignalR is better if bidirectional messaging is needed later
  • MarkupString in Blazor: required to render HTML from Markdig; must be used intentionally as it bypasses Blazor's XSS protections — only render trusted content (GPT output is untrusted; sanitize or accept risk as single-user personal tool)
  • Markdown.ColorCode WASM note: base Markdown.ColorCode package works in WASM; Markdown.ColorCode.CSharpToColoredHtml does NOT — avoid the latter

Sources


Feature research for: Personal AI Chat WebApp (Blazor WebAssembly + OpenAI GPT) Researched: 2026-03-27