-```
-
-### Assistant message direction
-
-Use:
-
-- branded `m-avatar.svg`
-- name label as a small line item
-- cleaner vertical rhythm
-- no faux bot-icon chip
-
-### Assistant avatar helper
-
-```tsx
-function MapleChatAvatar() {
- return (
-
- );
-}
-```
-
-### Messages area padding
-
-- `p-6` -> `p-4 md:p-6` (tighter on mobile)
-
-### Tool and search result shells
-
-Adopt the larger rounded cards from the PR.
-
-Examples:
-
-- web search status: `rounded-2xl`
-- tool result cards: `rounded-3xl`
-- incomplete/canceled indicator: `rounded-2xl`
-
-## 8.4.5 Composer shell
-
-This is one of the most important visual upgrades.
-
-### Canonical shell
-
-```tsx
-className =
- "relative overflow-hidden rounded-3xl border border-[hsl(var(--maple-secondary-container))] bg-background transition-colors focus-within:border-[hsl(var(--maple-primary))]";
-```
-
-### Fullscreen variant
-
-Keep fullscreen behavior, but use the same shell language.
-
-### Layout changes to preserve
-
-- textarea and fullscreen button on the same top row
-- thinner border than current `border-2`
-- much rounder shell
-- no top-right absolute icon floating over the textarea
-- toolbar without a hard separator line
-
-### Empty-state textarea direction
-
-- `rows={1}`
-- `min-h-[52px]`
-- `max-h-[200px]`
-- comfortable `leading-6`
-
-## 8.4.6 Toolbar controls
-
-Adopt the calmer pebble/coral icon treatment.
-
-### Canonical icon-button classes
-
-```tsx
-className =
- "h-8 w-8 p-0 text-[hsl(var(--maple-secondary-700))] hover:text-[hsl(var(--maple-secondary-700))] hover:bg-[hsl(var(--maple-primary-container))]";
-```
-
-### Keep these controls functional
-
-- model selector
-- web search toggle
-- attachment menu
-- mic
-- stop generation
-- send
-- project picker if currently shown in this flow
-
-Important: this is a visual redesign, not a capability reduction.
-
-## 8.4.7 Send button
-
-Keep the PR's custom circular gradient send button.
-
-### Canonical send button
-
-```tsx
-
-```
-
-Use the `h-8 w-8` version for the bottom compact composer.
-
-## 8.4.8 Voice / stop / attachment shells
-
-Preserve the PR's softer geometry:
-
-- mic: `rounded-xl`
-- stop button: `rounded-xl`
-- inner stop square: `rounded-md`
-- image thumbs: `rounded-xl`
-- document chip: `rounded-2xl`
-- recording overlay: `rounded-3xl`
-
-## 8.4.9 Color migrations in UnifiedChat
-
-Throughout the chat interface, apply the semantic color migration:
-
-- Error text: `text-red-500` -> `text-maple-error`
-- Success icons in tool results: `text-green-600 dark:text-green-400` -> `text-maple-success`
-- Warning dot (incomplete/canceled): `bg-yellow-500` -> `bg-maple-warning`
-- Web search enabled icon: `text-blue-500` -> `text-[hsl(var(--maple-primary))]`
-- Web search disabled icon: `text-muted-foreground` -> `text-[hsl(var(--maple-secondary-700))]`
-- Toolbar icon buttons (globe, plus, mic): all use the pebble/coral treatment from Section 9.7
-
-## 8.4.10 Footer copy
-
-Use the stronger privacy microcopy from the PR.
-
-```tsx
-
-```
-
-Bottom disclaimer: `text-sm` -> `text-[10px]`, `text-muted-foreground/60` -> `text-muted-foreground/50`, `mt-2` -> `mt-1 mb-2`.
-
-## 8.4.11 Do not regress current UnifiedChat behavior
-
-The following are visual-only or presentation-oriented changes. Do not use this redesign as an excuse to delete:
-
-- pagination state
-- model gating
-- attachment validation
-- project integration
-- title refresh logic
-- web search education flow
-- TTS logic
-- voice recording lifecycle
-
-## 8.5 Archived chat route
-
-Even though this is a compatibility surface, the PR includes useful polish here.
-
-### Take from the PR
-
-- user messages become the same right-aligned rounded bubble treatment
-- assistant messages use the branded `m-avatar.svg`
-- mobile new-chat button becomes borderless
-
-### Keep
-
-- read-only archived behavior
-- current route semantics
-
-## 8.6 Account menu
-
-## 8.6.1 Visual direction
-
-- centered plan badge
-- compact ring-style credit meter below it
-- small circular account trigger instead of a full-width `Account` button
-- dropdown aligns to the sidebar edge, not to the tiny circular trigger center
-
-## 8.6.2 Canonical trigger
-
-```tsx
-
-```
-
-## 8.6.4 Content and styling details
-
-- Menu label: `Maple Research` instead of `Maple AI`
-- Plan badge styling:
- - **Old:** `bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]` (black/white)
- - **New:** `bg-[hsl(var(--maple-tertiary-container))] text-[hsl(var(--maple-tertiary))] text-[10px]` (earthy tint)
-- Team setup badge: `bg-amber-500 text-white` -> `bg-maple-warning text-maple-onWarning`
-- Privacy/terms links: **ignore the PR's URL swap.** The designer branch came from an older fork. Current `master` privacy/terms pages, routes, and destinations are canonical and must remain exactly as `master` defines them.
-
-## 8.6.5 Keep current account behavior
-
-Do not regress:
-
-- sign-out cache clearing behavior unless consciously reworked everywhere
-- billing portal behavior
-- external-link behavior in Tauri/web
-- team/API modal flows
-
-## 8.7 Account dialog
-
-### Add
-
-A `Theme` section with `Light`, `Dark`, and `System` controls.
-
-### Visual direction
-
-- `Sun`, `Moon`, `Monitor` icons
-- use buttons that clearly show active selection
-
-### Token cleanup
-
-- verified email icon -> `text-maple-success`
-- unverified email icon -> `text-maple-error`
-- destructive action becomes text/ghost-style destructive action instead of a heavy outlined danger button
-
-## 8.8 Credit usage
-
-## 8.8.1 Keep both layouts
-
-- existing bar layout remains useful outside the sidebar
-- new ring layout is used in the redesigned account area
-
-## 8.8.2 Ring layout to preserve
-
-- Compact bordered card: `rounded-xl border border-[hsl(var(--sidebar-chrome))] bg-transparent p-3`
-- Left side: status label ("Plan credits" / "Almost full" / "Limit reached") + reset date + optional extra credits text
-- Right side: 32x32 SVG ring meter with 3.5px stroke
-- Ring track: `stroke-[hsl(var(--sidebar-chrome))]`
-- Ring fill: linear gradient from `hsl(var(--maple-primary))` to `hsl(var(--maple-primary-strong))`
-- Animated: `transition-[stroke-dashoffset] duration-500 ease-out`
-- Rotated -90deg so arc starts from top
-
-Refer to PR #465 `CreditUsage.tsx` diff for the `RingMeter` SVG implementation -- it's ~40 lines of clean SVG component code worth carrying over directly.
-
-## 8.8.3 Usage thresholds
-
-| Threshold | Tone | Color | Text class |
-| --------- | ------ | --------------------------- | -------------------- |
-| `>= 90%` | danger | `hsl(var(--maple-error))` | `text-maple-error` |
-| `>= 75%` | warn | `hsl(var(--maple-warning))` | `text-maple-warning` |
-| `< 75%` | ok | `hsl(var(--maple-success))` | `text-maple-success` |
-
-Old bar variant used hardcoded Tailwind (red-500, amber-500, emerald-500) -- migrate to the same semantic tokens.
-
-Status labels: `>= 100%` "Limit reached", `>= 90%` "Almost full", `< 90%` "Plan credits".
-
-## 8.8.4 Dev-only mock support
-
-The PR's dev-only mock scenarios are useful and can stay behind `import.meta.env.DEV`.
-
-Supported scenarios from the PR:
-
-- `demo`
-- `full`
-- `high`
-- `warn`
-- `ok`
-- `off`
-
-## 8.9 Model selector
-
-### Take from the PR
-
-- Trigger text size: `text-sm` -> `text-xs`
-- Trigger button color: `text-[hsl(var(--maple-secondary-700))] hover:bg-[hsl(var(--maple-primary-container))]`
-- Chevron: remove `opacity-50`
-- Badge border radius: `rounded-sm` -> `rounded-md`
-- Upgrade hover state: `hover:bg-purple-50 dark:hover:bg-purple-950/20` -> `hover:bg-[hsl(var(--maple-primary-container))] dark:hover:bg-[hsl(var(--maple-primary))]/10`
-
-### Preserve
-
-- all current gating logic
-- image restrictions
-- model availability logic
-- current category/model selection behavior
-
-### Badge mapping from the PR
-
-| Badge | Treatment |
-| ------------- | -------------------------------------------- |
-| `Coming Soon` | `bg-muted text-muted-foreground` |
-| `Pro` | coral-to-tertiary soft gradient + coral text |
-| `Starter` | `bg-maple-success/10 text-maple-success` |
-| `New` | `bg-maple-info/10 text-maple-info` |
-| `Reasoning` | `bg-maple-error/10 text-maple-error` |
-| `Beta` | `bg-maple-warning/10 text-maple-warning` |
-
-## 8.10 Markdown rendering
-
-## 8.10.1 Link behavior (chat.css)
-
-Replace the current accent-colored, outline-ring link style with calmer foreground-based treatment:
-
-```css
-.markdown-body a {
- color: hsl(var(--foreground) / 0.72); /* subdued, not accent-colored */
- text-decoration: none;
- -webkit-tap-highlight-color: transparent;
-}
-.markdown-body a:hover {
- text-decoration: underline;
- text-underline-offset: 0.15em;
- color: hsl(var(--foreground)); /* full opacity on hover */
-}
-.markdown-body a:focus {
- outline: none;
- box-shadow: none;
-}
-.markdown-body a:focus-visible {
- outline: none;
- box-shadow: none;
- text-decoration: underline;
- text-underline-offset: 0.15em;
- color: hsl(var(--foreground));
-}
-```
-
-Remove the old `.markdown-body a:focus`, `.markdown-body a:focus:not(:focus-visible)`, and `.markdown-body a:focus-visible` rules that used outline rings.
-
-## 8.10.2 Tables
-
-### Component change (markdown.tsx)
-
-Replace the `ResponsiveTable` scroll-detection approach (removes `useState`, `useEffect`, `useRef` for scroll tracking, gradient fade indicators) with a simpler wrapper:
-
-```tsx
-
-```
-
-### CSS additions (chat.css)
-
-Add a new `.markdown-table-maple` class with these traits:
-
-- `display: table; table-layout: fixed; width: 100%`
-- Transparent backgrounds (no alternating row stripes)
-- Horizontal rules only: `border-bottom: 1px solid hsl(var(--maple-secondary) / 0.2)` for headers, `hsl(var(--maple-secondary-container))` for cells
-- Last row: no bottom border
-- First column flush left (`padding-left: 0`)
-- Responsive first-column widths: 34% on mobile, 22% on desktop
-- `overflow-wrap: break-word; word-break: break-word` on all cells
-
-Remove `display: block; width: max-content; max-width: 100%; overflow: auto` from base `.markdown-body table`.
-
-Refer to the PR diff for the exact CSS rules -- there are ~90 lines of table styling.
-
-## 8.10.3 Typography sizes (chat.css)
-
-Set explicit `font-size: 14px; line-height: 1.5` on:
-
-- `.markdown-body p`
-- `.markdown-body ol`, `.markdown-body ul`
-- `.markdown-body li`, `.markdown-body li > p`
-- `.markdown-body td`
-
-Add mobile reading optimization:
-
-```css
-@media (max-width: 767px) {
- .markdown-body p {
- max-width: min(100%, 48ch);
- }
- .markdown-body td p,
- .markdown-body th p {
- max-width: none;
- }
-}
-```
-
-## 8.10.4 Thinking blocks (markdown.tsx)
-
-Replace the bordered card treatment:
-
-- **Old:** `border border-gray-200 dark:border-gray-700 rounded-lg bg-gray-50 dark:bg-gray-900/50`
-- **New:** No border, no background. Plain button + expandable content.
-- Icon/text colors: `text-gray-500 dark:text-gray-400` -> `text-muted-foreground`
-- Collapse chevron moves from left side to right side of the row
-- Expanded content: no border-top, just `pb-1 pt-2`
-
-## 8.10.5 Code and content radius consistency
-
-All code-related `border-radius` values change from `6px` to `12px`:
-
-- `.markdown-body kbd`
-- `.markdown-body pre`
-- `.markdown-body .mermaid`
-- Footnote checkbox `::before`
-
-## 8.10.6 Dark mode in chat.css
-
-Remove the `@media (prefers-color-scheme: dark) { :root { ... } }` block from `chat.css` (the markdown-specific dark variable overrides). Dark mode is now handled by the `.dark` class in `index.css`.
-
-## 8.11 Product dialogs and secondary surfaces
-
-### Apply token/radius polish to product-reachable dialogs
-
-Use PR #465 mostly as a semantic cleanup guide here.
-
-#### High-priority dialogs
-
-- `UpgradePromptDialog`
-- `PromoDialog`
-- `WebSearchInfoDialog`
-- `DocumentPlatformDialog`
-- `ContextLimitDialog`
-- `DeleteChatDialog`
-- `BulkDeleteDialog`
-- `TTSDownloadDialog`
-- `VerificationModal`
-- `GuestPaymentWarningDialog`
-
-#### Expected treatment
-
-- semantic icon/text color migration (see Section 7.5 for the full mapping table)
-- rounded container polish
-- use `variant="primary"` for the strongest upgrade CTA when appropriate
-- preserve existing logic and copy unless the PR provides a clear product-facing improvement
-
-#### Specific dialog changes from PR #465 worth preserving
-
-- **UpgradePromptDialog:** benefit check icons `text-green-500` -> `text-maple-success`; upgrade button uses `variant="primary"`
-- **PromoDialog:** pink/orange gradients -> `from-[hsl(var(--maple-primary))] to-[hsl(var(--maple-primary-strong))]`; badge, benefit icons, privacy check all migrate to maple semantic colors
-- **WebSearchInfoDialog:** info icon `bg-blue-500/10 text-blue-500` -> `bg-maple-info/10 text-maple-info`; feature checks -> `text-maple-info`
-- **GuestPaymentWarningDialog:** warning colors -> `text-maple-warning`, `bg-maple-warning/10`
-- **AccountDialog:** verified email `text-green-700` -> `text-maple-success`; unverified `text-red-700` -> `text-maple-error`; delete account button `variant="outline" border-destructive` -> `variant="ghost" text-destructive hover:bg-destructive/10`
-
-## 8.12 Team/API/account dashboards
-
-These are in scope only for polish, not for wholesale redesign.
-
-### What to carry over
-
-- semantic token cleanup
-- softer badges/fills
-- progress bars using Maple semantic colors
-- consistent dialog/dropdown/button styling inherited from shared primitives
-
-### What not to do
-
-- do not restructure these dashboards just because product chrome changed elsewhere
-
-## 8.13 Project surfaces
-
-The designer PR does not directly redesign project mode, but the authenticated product still supports it.
-
-### Required rule
-
-The new redesign PR must leave project functionality intact.
-
-### Minimum expectation
-
-- shared theme/tokens should not make project mode look broken
-- shared buttons/dialogs/sidebar chrome should feel consistent
-- project flows remain operational
-
-### Not required in the first redesign PR
-
-- a bespoke new visual language for `ProjectDetailView`
-- redesigning project instructions UX
-- redesigning move/create/delete project dialogs beyond shared primitive polish
-
----
-
-## 9. Exact High-Value Class Specs
-
-These are the visual details most worth preserving verbatim or near-verbatim.
-
-## 9.1 Sidebar history fade
-
-```tsx
-const SIDEBAR_TITLE_FADE =
- "pointer-events-none absolute inset-y-0 right-0 z-[1] bg-gradient-to-l from-muted from-35% via-muted/85 to-transparent dark:from-[hsl(var(--sidebar))] dark:from-35% dark:via-[hsl(var(--sidebar)/0.85)] dark:to-transparent";
-```
-
-## 9.2 Sidebar ellipsis button
-
-```tsx
-const SIDEBAR_ELLIPSIS_BTN =
- "z-20 shrink-0 rounded-full bg-muted/90 p-1.5 text-primary backdrop-blur-sm transition-opacity dark:bg-[hsl(var(--sidebar)/0.9)]";
-```
-
-## 9.3 Empty-state heading
-
-```tsx
-className =
- "overflow-visible pb-1 text-4xl font-normal leading-relaxed brand-gradient-text mb-6";
-```
-
-## 9.4 Composer shell
-
-```tsx
-className =
- "relative overflow-hidden rounded-3xl border border-[hsl(var(--maple-secondary-container))] bg-background transition-colors focus-within:border-[hsl(var(--maple-primary))]";
-```
-
-## 9.5 Composer top row
-
-```tsx
-className = "flex items-start gap-1 pl-4 pr-2 pt-2";
-```
-
-## 9.6 Fullscreen toggle button
-
-```tsx
-className =
- "mt-0.5 shrink-0 rounded-full p-1.5 text-muted-foreground/60 transition-colors hover:bg-muted/50 hover:text-foreground";
-```
-
-## 9.7 Toolbar icon button
-
-```tsx
-className =
- "h-8 w-8 p-0 text-[hsl(var(--maple-secondary-700))] hover:text-[hsl(var(--maple-secondary-700))] hover:bg-[hsl(var(--maple-primary-container))]";
-```
-
-## 9.8 User bubble
-
-```tsx
-className =
- "max-w-[min(100%,42rem)] rounded-2xl border border-border bg-muted px-4 py-3 backdrop-blur-lg dark:bg-card";
-```
-
-## 9.9 Assistant message shell
-
-```tsx
-
-```
-
-## 9.10 Account trigger
-
-```tsx
-className =
- "relative flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--sidebar-chrome))] text-[hsl(var(--on-sidebar-chrome))] shadow-none ring-0 transition-colors hover:bg-[hsl(var(--sidebar-chrome-hover))]";
-```
-
-## 9.11 Ring credit card
-
-```tsx
-
-```
-
----
-
-## 10. What Not To Copy Literally From PR #465
-
-## 10.1 Do not copy any marketing/page work
-
-Ignore those files entirely for the new product redesign PR.
-
-## 10.2 Do not infer feature removals from visual simplifications
-
-If the designer PR visually simplifies a control but the current product still supports that feature, preserve the feature.
-
-Key examples:
-
-- bulk move
-- projects/project mode
-- pinned chats
-- project picker behavior
-- current route/search-param contracts
-
-## 10.3 Do not hand-edit generated files
-
-- `routeTree.gen.ts`
-
-## 10.4 Do not import unused branding assets
-
-Only bring over assets actually needed by the product redesign.
-
-## 10.5 Do not keep marketing-specific token names in shared product primitives if a neutral semantic alias is cleaner
-
-Example: prefer `overlay-scrim` over `marketing-hero-scrim` for dialog overlays if touching shared primitives.
-
-## 10.6 Do not land huge global primitive changes without auditing blast radius
-
-Because marketing/helper pages are out of scope, avoid unintentionally redesigning them through careless primitive changes.
-
-## 10.7 Do not overwrite newer master content with older-fork PR content
-
-PR #465 started from an older fork, so some content/routing changes in that branch are stale by definition.
-
-- keep newer `master` pages, routes, and copy
-- only reapply the visual/product-chrome improvements from the designer branch
-- do not let old-fork link destinations replace current `master` behavior
-- example: privacy/terms on `master` stay exactly as they are
-
----
-
-## 11. Implementation Phase Plan For The Future Product PR
-
-## Phase 1: foundation
-
-- add tokens to `index.css`
-- add Tailwind semantic mappings
-- add `ThemeProvider`
-- add early-theme script
-- self-host `Manrope` assets and wire `@font-face` / preload strategy
-- add `MapleWordmark` + `m-avatar.svg`
-
-## Phase 2: shared primitives
-
-- button improvements
-- dialog/dropdown/alert/sheet/switch polish
-- only land safe global changes
-
-## Phase 3: shell + sidebar
-
-- sidebar shell/header
-- sidebar toggle
-- chat history row chrome
-- account menu shell
-- ring credit meter
-
-## Phase 4: chat surface
-
-- empty state
-- mobile/desktop header behavior
-- message shells
-- composer shell
-- send button
-- tool/web search status cards
-- footer/privacy microcopy
-
-## Phase 5: markdown + secondary dialogs
-
-- markdown link/table/thinking polish
-- upgrade/search/promo/document dialogs
-- account dialog theme picker
-- product-reachable dashboard token cleanup
-
-## Phase 6: compatibility pass
-
-- archived route visual alignment
-- project surfaces sanity pass
-- ensure project mode does not clash with new shared foundation
-
-## Phase 7: validation
-
-For the future implementation PR, run at minimum:
-
-```bash
-just format
-just lint
-just build
-```
-
-If Rust is untouched, Rust validators are not required.
-
----
-
-## 12. Acceptance Checklist For The Future Implementation PR
-
-## 12.1 Theme and shell
-
-- [ ] light mode looks correct
-- [ ] dark mode looks correct
-- [ ] `system` theme follows OS changes
-- [ ] no initial theme flash on reload
-
-## 12.2 Responsive behavior
-
-- [ ] desktop closed-sidebar top-left wordmark row works
-- [ ] mobile two-row chat header works
-- [ ] sidebar open/close behavior still works correctly
-
-## 12.3 Chat behavior
-
-- [ ] empty state redesign is present
-- [ ] active chat layout works
-- [ ] streaming states look correct
-- [ ] canceled/tool/web-search states look correct
-- [ ] image/document attachments still work
-- [ ] voice flow still works
-- [ ] fullscreen composer still works
-
-## 12.4 History behavior
-
-- [ ] projects still work
-- [ ] pinned chats still work
-- [ ] archived chats still work
-- [ ] bulk move still works
-- [ ] bulk delete still works
-- [ ] search still works
-- [ ] pull-to-refresh still works on mobile
-
-## 12.5 Account/billing behavior
-
-- [ ] account menu redesign is present
-- [ ] credit ring is present in sidebar
-- [ ] theme picker works
-- [ ] team/API dialogs still open and work
-- [ ] billing/manage subscription still works
-
-## 12.6 Compatibility surfaces
-
-- [ ] archived route looks aligned with new system
-- [ ] project mode still works and does not look broken
-
----
-
-## 13. PR #465 File Map For The New Product PR
-
-## 13.1 Carry over directly or near-directly
-
-- `frontend/src/components/MapleWordmark.tsx`
-- `frontend/public/m-avatar.svg`
-- theme/token additions in `index.css`
-- Tailwind semantic mappings in `tailwind.config.js`
-- `ThemeProvider` concept in `src/contexts/ThemeContext.tsx` (with fixes)
-- core product chrome direction in:
- - `Sidebar.tsx`
- - `ChatHistoryList.tsx`
- - `UnifiedChat.tsx`
- - `AccountMenu.tsx`
- - `CreditUsage.tsx`
- - `ModelSelector.tsx`
- - `markdown.tsx`
- - `AccountDialog.tsx`
-
-## 13.2 Carry over as token/radius cleanup only
-
-- product-reachable dialogs
-- API dashboard surfaces
-- team dashboard surfaces
-- verification/promo/search/upgrade supporting surfaces
-
-## 13.3 Ignore for the new product-only PR
-
-- all marketing/public routes and components
-- pricing config changes
-- `routeTree.gen.ts`
-- `BillingDebugger.tsx`
-- extra marketing-only asset work
-
----
-
-## 14. Bottom Line
-
-The right implementation is **not** “merge the designer branch.”
-
-The right implementation is:
-
-- take the designer's product visual language,
-- keep Maple's real product behavior,
-- express the redesign through shared tokens, clean primitives, and reusable product chrome,
-- and keep the rewrite tightly scoped to the authenticated product experience.
diff --git a/docs/tool-call-immediate-rendering.md b/docs/tool-call-immediate-rendering.md
deleted file mode 100644
index 61bf1a4e2..000000000
--- a/docs/tool-call-immediate-rendering.md
+++ /dev/null
@@ -1,152 +0,0 @@
-# Tool Call Immediate Rendering Refactor
-
-## Problem Statement
-
-Tool calls don't render immediately during streaming in UnifiedChat. Currently:
-
-1. **Tool call arrives** (`tool_call.created` event) → stored in Map, not displayed
-2. **Tool output arrives** (`tool_output.created` event) → stored in Map, not displayed
-3. **Assistant message created** (`response.output_item.added` type="message") → empty message created
-4. **Text starts streaming** (`response.output_text.delta`) → **NOW** tool calls finally render
-
-**User experience**: 5+ second delay between tool call and seeing any visual feedback.
-
-## Streaming Event Sequence (from logs)
-
-```
-🔵 response.created
-🔵 response.in_progress
-🔵 tool_call.created ← Call created, but not displayed yet
- hasAssistantId: false
- toolCallsCount: 0
-
-🔵 tool_output.created ← Output ready, but not displayed yet
- hasAssistantId: false
- toolCallsCount: 1
-
-🔵 response.output_item.added ← NOW assistant message created
- type: "message"
- hasAssistantId: true
-
-🔵 response.output_text.delta ← NOW tool calls finally display!
-```
-
-## Root Cause
-
-The architecture tightly couples "displayed items" with the API's `output_item` concept:
-
-1. **Current architecture**: Wait for `output_item.added` (type="message") to create container
-2. **Tool calls arrive first**: Before the message container exists
-3. **Buffered in Map**: Waiting to be grouped inside assistant message
-4. **Finally rendered**: Only when text deltas start arriving
-
-## Solution Approach
-
-### Original Architecture
-```
-Message (assistant) {
- content: [tool_call, tool_output, text]
-}
-```
-- Everything nested inside message's content array
-- Tool calls/outputs don't exist as standalone items
-- Must wait for message to exist before rendering
-
-### New Architecture (Flat List)
-```
-messages = [
- { type: "message", role: "user", ... },
- { type: "function_call", call_id: "...", ... },
- { type: "function_call_output", call_id: "...", ... },
- { type: "message", role: "assistant", ... }
-]
-```
-- Each item is independent at top level
-- Render immediately as events arrive
-- Visual pairing handled by renderer (matching `call_id`)
-- Matches how LLMs and the API actually model conversations
-
-## Implementation Progress
-
-### ✅ Completed
-
-1. **Simplified type system**
- - Changed `type Message = ConversationItem` to use OpenAI's native types
- - Removed custom `Message` interface with nested content
- - Removed `timestamp` field (wasn't used for anything)
-
-2. **Simplified data conversion**
- - `convertItemsToMessages` now just casts items as-is
- - No more grouping/buffering logic (126 lines → 5 lines)
-
-### 🚧 In Progress
-
-3. **Update MessageList rendering** (partially complete)
- - Need to handle different item types: `message`, `function_call`, `function_call_output`, `web_search_call`
- - Render each type independently
- - Keep visual pairing logic (tools render together when adjacent)
- - Update to check `item.type` instead of `message.role`
-
-### ❌ TODO
-
-4. **Update streaming logic** (processStreamingResponse)
- - Create items immediately as events arrive (no Map buffering)
- - `tool_call.created` → `setMessages([...prev, toolCallItem])`
- - `tool_output.created` → `setMessages([...prev, toolOutputItem])`
- - `response.output_text.delta` → update assistant message text
- - Remove the `toolCalls` Map entirely
-
-5. **Update user message creation**
- - Change from custom Message type to OpenAI's Message format
- - Match the `type: "message"` structure
-
-6. **Fix TypeScript errors**
- - Update all code that checks `message.role` to check `item.type`
- - Update all code that assumes `message.content` exists on all items
- - Handle different item types in scroll logic, status checks, etc.
-
-## Benefits of Flat Structure
-
-1. **Immediate rendering**: Items render as soon as they arrive
-2. **Matches API model**: No impedance mismatch with OpenAI's data structure
-3. **Simpler streaming logic**: No buffering, no grouping, just add items
-4. **Matches LLM mental model**: Tools are distinct operations, not nested content
-5. **Easier to maintain**: Less custom mapping logic
-
-## Alternative: Minimal Fix
-
-If full refactor is too large, we could do a smaller fix:
-
-1. Keep current grouped structure
-2. Create assistant message **eagerly** (on first tool call, not on output_item.added)
-3. Add items to message immediately (no Map buffering)
-
-This would fix the immediate issue but keep the coupling between display and API structure.
-
-## Testing Plan
-
-1. **Streaming test**: Tool call should appear immediately (< 100ms after event)
-2. **Pairing test**: When output arrives, should render as grouped pair
-3. **Orphan test**: Tool output without call should render standalone
-4. **Loading test**: Old conversations load correctly with tool calls
-5. **Scroll test**: Auto-scroll behavior still works with flat structure
-
-## Files Changed
-
-- `/frontend/src/components/UnifiedChat.tsx` - Main refactor
- - Type definitions (lines 75-102)
- - convertItemsToMessages (lines 114-120)
- - MessageList rendering (lines 492+)
- - processStreamingResponse (lines 1724+)
- - handleSendMessage user message creation (lines 1926+)
-
-## Current State
-
-The code is **partially refactored** but **not working**:
-- Type system simplified ✅
-- Data conversion simplified ✅
-- Rendering needs update for flat items ❌
-- Streaming needs update to create items immediately ❌
-- TypeScript errors need fixing ❌
-
-**Decision needed**: Complete the flat refactor OR revert and do minimal fix?
diff --git a/docs/tts-research.md b/docs/tts-research.md
deleted file mode 100644
index edb81022a..000000000
--- a/docs/tts-research.md
+++ /dev/null
@@ -1,248 +0,0 @@
-# TTS Research
-
-## Gemini
-
-Definitive Comparative Analysis of Local TTS Architectures for Cross-Platform Tauri Integration: Supertonic 2 vs. Chatterbox Turbo1. Executive Strategic Overview: The Local Inference Convergence in 2026The trajectory of computational linguistics and speech synthesis has undergone a profound transformation over the last half-decade, culminating in a distinct bifurcation of technology stacks in early 2026. For systems architects and developers leveraging the Tauri framework to build cross-platform applications—spanning the unrestricted desktop ecosystems of macOS and Linux, as well as the rigorously sandboxed mobile environments of iOS and Android—the selection of a Text-to-Speech (TTS) engine is no longer a mere feature choice. It has elevated to a fundamental architectural decision that dictates the entire build pipeline, runtime efficiency, and distribution strategy of the final application.The user’s query posits a choice between two leading contenders in the open-weight arena: Supertonic 2, released by Supertone Inc. in January 2026, and Chatterbox Turbo, developed by Resemble AI. This report provides an exhaustive technical due diligence of these two models. The core tension explored herein is between Architectural Agility—epitomized by Supertonic’s lightweight, ONNX-native design—and Expressive Density—represented by Chatterbox’s larger, Llama-based backbone.While cloud-based inference dominated the early 2020s, the current paradigm emphasizes "Edge AI" and "Local First" principles. This shift is driven by privacy mandates, the need for zero-latency interaction in conversational interfaces, and the desire to eliminate recurring API costs. However, achieving parity with cloud-grade TTS on consumer hardware requires navigating a labyrinth of constraints: binary size limitations, memory bandwidth bottlenecks on mobile SoCs (System on Chips), and the draconian process management restrictions of mobile operating systems.For a Tauri developer, who enjoys the luxury of Rust’s performance and the web’s ubiquity, the challenge is uniquely complex. Tauri’s promise of a "write once, deploy everywhere" codebase is severely tested when integrating deep learning models that rely on disparate runtimes. Supertonic 2 offers a path of least resistance through native compilation, while Chatterbox Turbo demands a hybrid architecture that may fracture the unified codebase ideal. This report rigorously dissects these trade-offs to provide a definitive integration roadmap.2. Architectural Deconstruction: The Lightweight vs. The Large Language BackboneTo understand the feasibility of these models within a constrained Tauri environment, one must first dismantle their internal architectures. The "black box" of AI often obscures dependency chains that can shatter a cross-platform build pipeline. The difference between 44 million parameters and 350 million parameters is not merely quantitative; it represents two divergent philosophies of engineering.2.1 Supertonic 2: The Principles of Architectural DistillationSupertonic 2, as of its January 2026 release 1, is an anomaly in the contemporary landscape of generative AI. While the broader industry trend has been to scale parameters upwards—moving from millions to billions to achieve nuanced reasoning—Supertone Inc. has focused on distillation and efficiency. The model is engineered explicitly for embedded and on-device usage, prioritizing the reduction of computational overhead to near-negligible levels.The 44 Million Parameter AdvantageThe model operates with approximately 44 million parameters.2 In the context of modern neural networks, where even "Small Language Models" (SLMs) typically range from 0.5B to 3B parameters, 44M is microscopic. This scale confers specific hardware advantages that are critical for mobile performance:Cache Residency: A model of this size (approx. 268 MB in FP32, significantly less if quantized) can often reside entirely within the System Level Cache (SLC) or high-speed RAM partitions of modern mobile processors like the Apple A-series or Qualcomm Snapdragon. This drastically minimizes memory bandwidth saturation, which is the primary source of heat and battery drain during inference.Initialization Speed: The "cold start" time—the duration from loading the model to the first audio sample—is imperceptible, measured in milliseconds. This allows the TTS engine to be instantiated on-demand rather than requiring a persistent background service, optimizing system resource usage.The ONNX-Native RuntimeCrucially for Tauri developers, Supertonic is built natively for the ONNX Runtime.1 This choice is not incidental; it is a strategic enablement of cross-platform portability. ONNX (Open Neural Network Exchange) provides a standardized inference engine that is completely decoupled from the training environment. It does not require a Python interpreter, the heavy PyTorch library, or complex CUDA drivers to execute. Instead, it runs via optimized C++ libraries.Because Tauri's backend is written in Rust, developers can utilize the ort crate to bind directly to these C++ libraries. This means the TTS engine is not an external dependency or a separate process; it becomes an intrinsic function within the application's binary. This "library-level" integration is the gold standard for mobile development, ensuring compliance with App Store policies regarding executable code and utilizing native platform capabilities.The January 2026 Evolution (v2)The user's query specifically highlights "Supertonic 2 (Jan 2026)." This version introduces pivotal upgrades that address previous limitations:Multilingual Unification: Prior versions were often language-specific. Supertonic 2 introduces a unified architecture supporting English, Korean, Spanish, Portuguese, and French.1 This implies that a single ONNX model file can handle dynamic language switching at runtime without the latency penalty of unloading and reloading different model weights.Voice Personas: The update adds distinct voice styles (e.g., Alex, Sarah, James).5 While not offering the infinite flexibility of voice cloning, these preset personas cover the vast majority of use cases for standard reading applications, navigation, and accessibility tools.2.2 Chatterbox Turbo: The Llama-Based HeavyweightChatterbox, developed by Resemble AI, represents the "Quality First" school of thought. It leverages the massive advancements in Large Language Models (LLMs) and generative flow matching to achieve state-of-the-art naturalness.The Llama BackboneChatterbox Turbo is built upon a Llama backbone 6, likely adapting the transformer architecture to process audio tokens alongside text. Even in its "Turbo" configuration, which is optimized for latency, the model retains a 350 million parameter structure. While efficient for a server-grade GPU, this is nearly an order of magnitude larger than Supertonic.Memory Pressure: The model weights alone exceed 4 GB.7 Loading a 4GB model into memory is a non-trivial operation on mobile devices. Most mid-range Android phones ship with 6GB or 8GB of total RAM, shared between the OS, the GPU, and all active apps. Allocating 4GB to a single background TTS process will almost certainly trigger the operating system's Low Memory Killer (LMK), terminating the application or other background services to preserve system stability.Storage Friction: Distributing a mobile application with a 4GB asset payload is highly problematic. It exceeds the initial download size limits of both the Apple App Store (which requires Over-the-Air downloads to be under a certain threshold, often 200MB-4GB depending on OS version) and the Google Play Store (150MB base limit). Developers would be forced to implement complex "On-Demand Resource" downloading or expansive expansion files (OBB), adding significant friction to the user's first-run experience.The Python-PyTorch Dependency ChainChatterbox is a PyTorch-native model.6 Its architecture utilizes complex operations—specifically paralinguistic tag handling and flow matching decoders—that are deeply entwined with the PyTorch runtime and the Python ecosystem (requiring libraries like numpy, scipy, and torchaudio).Lack of ONNX Export: Unlike simpler models, Chatterbox does not offer a first-party, fully functional ONNX export that retains all its features. The dynamic nature of its flow matching steps and custom tokenizers makes "freezing" the model into a static computation graph exceptionally difficult. Consequently, running Chatterbox requires a live Python environment, a requirement that introduces the "Sidecar Problem" on mobile platforms—a critical hurdle for Tauri integration that will be explored in depth in subsequent sections.Feature SuperiorityDespite these architectural weights, Chatterbox offers capabilities Supertonic cannot match:Paralinguistic Control: Developers can inject tags like [laugh], [sigh], or [cough] directly into the text stream.6 The model understands these non-verbal cues and generates appropriate audio artifacts, creating a level of "human" performance that is SOTA.Zero-Shot Cloning: The model can clone a target voice from a mere 5-second reference clip.9 This feature relies on the dense vector representations of the Llama backbone to capture and replicate timbre and prosody instantly.3. The Tauri Framework Context: Integration RealitiesThe user's choice of Tauri as the application framework is the defining constraint of this analysis. Tauri operates on a unique architecture distinct from Electron or Native development. A Tauri app consists of two distinct layers:The Core (Backend): Written in Rust. This layer handles system interactions, file I/O, and heavy computation. It compiles down to a native binary.The Webview (Frontend): Written in web technologies (HTML/JS/CSS). This layer handles the UI and communicates with the Core via an asynchronous IPC bridge.For a TTS engine to be "local," it must reside within or be managed by the Rust Core. The feasibility of this integration varies wildly between Desktop (macOS/Linux) and Mobile (iOS/Android).3.1 The "Sidecar Pattern" and Desktop SuccessOn desktop operating systems, Tauri supports a feature known as the Sidecar Pattern. This allows the Rust Core to bundle and spawn external binaries as subprocesses.Mechanism: The developer compiles a Python script (and its interpreter) into a standalone executable using tools like PyInstaller or Nuitka. The Rust Core then uses the Command::sidecar API to launch this executable. Communication occurs via stdin (sending text) and stdout (receiving audio data).Implication for Chatterbox: This pattern makes running Chatterbox on macOS and Linux entirely feasible. The massive Python dependency chain is encapsulated in the sidecar binary. While the installer size bloats to 4GB+, the application runs successfully.Implication for Supertonic: While Supertonic can be run this way (e.g., using a Python wrapper around ONNX Runtime), it is unnecessary. Supertonic's C++ roots allow it to be linked directly into the Rust Core, avoiding the IPC overhead of a sidecar.3.2 The "Mobile Wall": Why Sidecars Fail on iOS & AndroidThe user's requirement for iOS and Android support reveals the fundamental weakness of the Chatterbox architecture in a Tauri context. The "Sidecar Pattern" described above is functionally non-existent on mobile platforms due to strict OS security models.iOS Sandbox ConstraintsApple's iOS enforces a draconian sandbox. An application bundle cannot contain arbitrary executables that are spawned as independent processes. The fork() and exec() system calls—essential for spawning a sidecar—are restricted or forbidden for App Store applications.Furthermore, iOS prohibits Just-In-Time (JIT) compilation for most applications (exceptions exist for browser engines and debuggers, but not general apps). PyTorch and complex Python runtimes heavily rely on JIT for performance. Running them in "interpreter-only" mode results in a catastrophic performance degradation, rendering a 350M parameter model unusable.Android Sandbox ConstraintsAndroid's security model, while slightly more flexible regarding JIT, imposes similar restrictions on subprocesses. While it is theoretically possible to package a Python binary and execute it via the NDK, managing the lifecycle of that process, ensuring it isn't killed by the stringent Android memory manager, and handling the communication bridge is a task of immense complexity. It fights against the grain of the Android application lifecycle.The Dependency Hell of Embedded PythonThe alternative to a sidecar is embedding the Python interpreter directly into the Rust binary (using crates like pyo3). This allows Python code to run within the main application process, bypassing the subprocess restriction.However, this leads to "Dependency Hell." To run Chatterbox, one must embed not just Python, but numpy, scipy, and torch. These are not pure Python libraries; they are wrappers around massive C/C++ and Fortran codebases. Compiling scipy or torch from source for aarch64-linux-android or aarch64-apple-ios and linking them statically into a Rust binary is one of the most notoriously difficult tasks in cross-platform development. It involves resolving thousands of symbol conflicts, matching libc versions, and dealing with build system incompatibilities. For 99% of development teams, this is a non-starter.4. Platform-Specific Integration Analysis: Mobile Deep DiveGiven that Mobile is the "Great Filter" in this selection process, we must analyze the integration pathway for the surviving candidate—Supertonic—and the theoretical (but painful) path for Chatterbox.4.1 Supertonic 2 on Mobile: The Native RouteSupertonic's reliance on ONNX Runtime (ORT) is its superpower here. ORT is designed with mobile in mind.iOS Integration StrategyStatic Linking: The ORT library is distributed as an .xcframework. In Rust, the ort crate can be configured to link against this framework during the build process (cargo build --target aarch64-apple-ios).CoreML Acceleration: iOS devices feature the Apple Neural Engine (ANE). ONNX Runtime supports the CoreML Execution Provider. By enabling this provider in the Rust ort session options, Supertonic inference is offloaded from the CPU to the NPU. This results in faster generation and, critically, drastically lower battery consumption.Asset Management: The 268MB .onnx file is treated as a standard bundle resource. It is accessible to the Rust Core via the NSBundle API (wrapped by Tauri's resource path helpers).Android Integration StrategyJNI and Shared Libraries: Android requires native libraries to be .so files. The ort crate manages the inclusion of libonnxruntime.so into the jniLibs folder of the Android project structure generated by Tauri.NNAPI Acceleration: Similar to CoreML, Android offers the Neural Networks API (NNAPI). Supertonic can leverage this to run on the DSP or NPU of Qualcomm or MediaTek chips, ensuring performance across the fragmented Android hardware ecosystem.App Bundle Size: While 268MB exceeds the 150MB base APK limit, Tauri developers can utilize "Play Asset Delivery" (install-time delivery) to package the model. Since the model is a static file, this is a solved infrastructure problem.4.2 Chatterbox on Mobile: The Remote FallbackSince running Chatterbox locally on mobile is effectively blocked by the OS constraints discussed in Section 3.2, the only viable architecture for a Tauri app wanting to use Chatterbox is a Hybrid Approach.Desktop Users: Enjoy local inference via the Python Sidecar.Mobile Users: The app detects the platform and routes TTS requests to a remote API (hosted by the developer) running the Chatterbox engine.The Cost: This violates the user's "local" requirement. It introduces latency, server costs (GPU hosting for inference), and privacy concerns (data leaving the device). However, it is the only way to access Chatterbox's features on a phone.5. Performance and Resource Profiling: The Cost of QualityPerformance is the secondary selector after compatibility. The user's query mentions "architecture differences," and nowhere is this more visible than in the computational cost of running the models.5.1 Real-Time Factor (RTF) BenchmarksThe "Real-Time Factor" measures the speed of generation. RTF = Processing Time / Audio Duration. An RTF of 0.1 means generating 10 seconds of audio takes 1 second. Lower is better.Supertonic 2 PerformanceDesktop (M4 Pro): Benchmarks indicate an RTF of 0.006.10 This is ~166x faster than real-time. For the user, this means the audio starts playing instantly, with zero perceived latency.Mobile (A17 Pro / Snapdragon 8 Gen 3): Even on mobile silicon, the 44M parameter model flies. Estimations based on similar SLMs suggest an RTF of 0.01 - 0.05 when using NPU acceleration. This enables "streaming" capabilities where long paragraphs are synthesized faster than the user can read them.Chatterbox Turbo PerformanceDesktop (RTX 4090): The model is fast, achieving sub-0.1 RTF.Mobile CPU (Theoretical): If one could run it on a mobile CPU (bypassing the build issues), the 350M parameters would crush the processor. Without heavy quantization (e.g., 4-bit) and optimization, RTF would likely hover between 0.5 and 1.0. This means a 10-second sentence could take 5-10 seconds to generate, creating awkward pauses in conversation or UI interaction.5.2 Memory Footprint & System StabilitySupertonic: Requires ~300-500 MB of RAM. This is safe for almost all modern mobile devices, even low-end Android phones with 4GB RAM. It leaves plenty of room for the OS and the webview.Chatterbox: Requires ~4-5 GB of RAM/VRAM. On a PC, this is fine. On a mobile device, this is catastrophic. iOS aggressively kills background processes that consume excessive memory. An app attempting to allocate 4GB for TTS would likely be terminated immediately upon initialization on all but the most expensive "Pro" model iPhones and Android flagships.6. Technical Integration Guide: Supertonic 2 (Recommended)Based on the evidence, Supertonic 2 is the only viable candidate for a truly local, cross-platform Tauri application. This section details the integration roadmap.6.1 Rust Core ConfigurationThe integration avoids the sidecar pattern entirely. We utilize the ort crate to bind to ONNX Runtime directly within the Rust process.Step 1: Dependency ManagementIn src-tauri/Cargo.toml:Ini, TOML[dependencies]
-tauri = { version = "2.0", features = }
-# ORT: The interface to ONNX Runtime.
-# 'fetch-models' allows auto-downloading libs (mostly for dev).
-# 'load-dynamic-lib' is crucial for mobile linking.
-ort = { version = "2.0", features = ["fetch-models", "load-dynamic-lib", "ndarray"] }
-# Rodio: For cross-platform audio playback
-rodio = "0.19"
-Step 2: Model Asset BundlingThe 268MB model file must be accessible to the binary at runtime.Place supertonic-v2.onnx and config.json in src-tauri/assets/.Update tauri.conf.json to include these assets:JSON"bundle": {
- "resources": ["assets/*"]
-}
-Step 3: The Inference Engine (Rust)In src-tauri/src/lib.rs, implement a command that the frontend can invoke. This command should:Tokenize: Convert the input string into the specific integer tokens expected by Supertonic. (Note: Check if Supertonic v2 includes a fused tokenizer in the ONNX graph; if not, a small Rust-based tokenizer matching the training data is required).Inference: Pass the tokens to the ort session.Rust// Conceptual Rust Code
-let inputs = ort::inputs!["input_ids" => token_tensor]?;
-let outputs = session.run(inputs)?;
-let audio_data = outputs["audio"].extract_tensor::()?;
-Playback: Feed the audio_data into a rodio Sink for immediate playback.6.2 Mobile-Specific Build FlagsAndroid: You must ensure the correct jniLibs are present. You can often rely on the ort crate's build script, but for production, manually downloading the onnxruntime-android AAR and extracting the .so files to your project's android/app/src/main/jniLibs is the most robust method.iOS: You must link the onnxruntime.xcframework. In your build.rs, you may need to emit linker flags:Rustprintln!("cargo:rustc-link-lib=framework=onnxruntime");
-7. Technical Integration Guide: Chatterbox (The Desktop-Only Hybrid)For completeness, if the project demands Chatterbox's features, here is the implementation strategy. Note that this abandons local mobile inference.7.1 Desktop: The Python SidecarEnvironment Isolation: Create a standalone Python environment using uv or conda. Install chatterbox-tts and its heavy dependencies (torch).Freezing the Binary: Use PyInstaller to compile a server.py script into a single binary. This script should launch a local web server (e.g., FastAPI) to listen for TTS requests.Warning: The resulting binary will be 4GB+.Tauri Orchestration:Add the binary to externalBin in tauri.conf.json.On app launch, spawn it via Command::sidecar.Wait for the "ready" signal (monitor stdout).Send HTTP requests to localhost for generation.7.2 Mobile: The Remote API FallbackSince the sidecar cannot run on iOS/Android:Host a Server: Deploy the Chatterbox model to a cloud GPU provider (e.g., RunPod, Lambda Labs, or AWS).Conditional Logic: In your frontend JavaScript:JavaScriptimport { type } from '@tauri-apps/plugin-os';
-
-async function generateSpeech(text) {
- if (type() === 'android' |
-
-| type() === 'ios') {// Call Remote APIreturn await fetch('https://api.myapp.com/tts', { body: { text } });} else {// Call Local Sidecarreturn await fetch('http://localhost:8000/tts', { body: { text } });}}```8. Quality of Experience (QoE) AnalysisBeyond the binary "can it run" question lies the "how does it sound" question.8.1 Prosody and StabilitySupertonic 2: The model produces highly stable, intelligible speech. The prosody is consistent, making it ideal for reading long-form content (articles, ebooks). It rarely "hallucinates" or creates bizarre artifacts, a common trait of distilled models. However, it can sound "flatter" or less dynamic than larger models.Chatterbox Turbo: The "human" element is significantly higher. The model captures micro-tremors in pitch, breath intake, and varied pacing that signals high production value. It is better suited for narrative content (fiction, gaming) where emotional engagement is key.8.2 The "Uncanny Valley" of LatencySupertonic: The near-instant response (0.006 RTF) creates a seamless user experience. It feels like a native OS feature.Chatterbox: Even on desktop, the 200ms+ latency can create a "turn-taking" delay in conversational apps. On a slow connection (mobile remote fallback), this latency can spike to seconds, breaking the illusion of interactivity.9. Commercial and Operational Considerations9.1 Licensing and WatermarkingSupertonic 2: Released under the OpenRAIL-M license.5 This license permits commercial use but includes usage restrictions to prevent abuse (e.g., generating deepfakes for fraud). It does not mandate watermarking, though developers should be mindful of transparency.Chatterbox: Released under the MIT license 6, the most permissive option. However, Resemble AI includes PerTh Watermarking technology baked into the model.12 Every generated audio file contains an imperceptible watermark. This is a robust safety feature for a commercial app, allowing you to prove the provenance of the audio if challenged, but it incurs a small computational cost during inference.9.2 Update VelocitySupertone Inc.: The release of v2 in Jan 2026 suggests a committed roadmap. The shift to a unified multilingual architecture indicates a maturity in their R&D pipeline.Resemble AI: Chatterbox is an open-source offshoot of their core commercial product. Updates are frequent, but often prioritize their paid API services or newer, larger models that may drift further away from consumer hardware capability.10. Conclusion and Strategic RecommendationThe comparative analysis yields a definitive conclusion based on the user's specific constraint of running locally across iOS, Android, Mac, and Linux.The Recommendation: Supertonic 2 is the superior architectural choice.Mobile Feasibility: Supertonic 2 is the only candidate that offers a viable path to local inference on iOS and Android within a Tauri application. Its ONNX-native architecture allows for static linking and NPU acceleration, bypassing the OS restrictions that block Chatterbox's Python-based stack.Performance Profile: With an inference speed 166x faster than real-time and a memory footprint of under 500MB, Supertonic ensures the application remains responsive and stable on resource-constrained mobile devices. Chatterbox's 4GB requirement is a non-starter for mobile memory budgets.Integration Simplicity: While Rust requires a learning curve, the ort integration is cleaner and more robust than maintaining a fragile Python sidecar build chain.When to Consider Chatterbox:Chatterbox should only be selected if the application is Desktop-exclusive (Mac/Linux/Windows) or if the requirement for Zero-Shot Voice Cloning and Paralinguistic Tags (laughter, emotion) outweighs the requirement for "Local" execution on mobile. In that scenario, a hybrid architecture (Local Desktop + Remote Mobile API) is the only path forward.For the stated goal of a unified, local, cross-platform Tauri build, Supertonic 2 is not just the better option; it is practically the only option.
-
-
-## Claude
-
-# Local TTS for Tauri: Supertonic vs Chatterbox compared
-
-**Supertonic emerges as the clear choice for cross-platform Tauri deployment**, offering native Rust integration, ~264 MB model size, and proven iOS/Android support out of the box. Chatterbox provides superior voice cloning and emotion control but at **10-12× the model size** and significantly higher deployment complexity. For a privacy-focused chat application prioritizing simplicity and bundle size, Supertonic's ONNX-based architecture delivers the most practical path to production.
-
-## Model architecture and runtime requirements
-
-**Supertonic** runs entirely on ONNX Runtime, making it deployment-friendly across all platforms. The architecture splits into four ONNX components: text encoder (28 MB), vector estimator (133 MB), vocoder (101 MB), and duration predictor (1.6 MB). With only **66 million parameters**, it's deliberately optimized for edge devices—proven to run on Raspberry Pi and e-readers at 0.3× real-time factor.
-
-**Chatterbox** was built on PyTorch with a **0.5B Llama backbone**, requiring substantially more resources. Three model variants exist: the original 500M parameter model, Chatterbox-Multilingual (500M, 23 languages), and Chatterbox-Turbo (350M, optimized for speed). While native inference requires PyTorch with CUDA/MPS/ROCm backends, official ONNX exports now exist through `ResembleAI/chatterbox-turbo-ONNX`.
-
-| Specification | Supertonic | Chatterbox |
-|--------------|------------|------------|
-| Parameters | 66M | 350M-500M |
-| Native framework | ONNX Runtime | PyTorch |
-| ONNX available | ✅ Primary | ✅ Exported |
-| MLX support | ❌ | ✅ via mlx-audio |
-
-## Model sizes shape deployment decisions
-
-Supertonic's total ONNX bundle weighs approximately **264 MB** across all components, with OnnxSlim optimizations shaving a few megabytes. This size remains consistent since the architecture doesn't support quantization variants in the official release.
-
-Chatterbox offers more flexibility through quantization but starts much larger. The full-precision Turbo ONNX export totals **~3.3 GB** across its four sessions (speech encoder, language model, conditional decoder, embed tokens). Quantized variants dramatically reduce this:
-
-- **Q4F16** (4-bit with FP16): ~560 MB total
-- **INT8 (Q8)**: ~1.1 GB total
-- **FP16**: ~1.7 GB total
-
-For mobile deployment, the Q4F16 Chatterbox variant at 560 MB remains **roughly twice Supertonic's size**. Memory requirements diverge even more sharply: Supertonic runs comfortably in **250-500 MB RAM**, while Chatterbox ONNX peaks at **~3.2 GB RAM** on iOS based on real-world testing.
-
-## Cross-platform deployment capabilities
-
-Supertonic provides exceptional platform coverage with **official examples for every major platform** in its repository:
-
-- **Desktop**: Windows, macOS, Linux via C++, Rust, Go, Python, Node.js, Java, C#
-- **Mobile**: Native iOS (Swift/Xcode), Android (Java/Kotlin), Flutter
-- **Web**: WebGPU/WASM (Chrome 121+, Edge 121+, Safari macOS 15+)
-- **Embedded**: Proven on Raspberry Pi, Onyx Boox e-readers
-
-Chatterbox's platform support depends heavily on your chosen runtime:
-
-- **PyTorch native**: Linux (primary), macOS (MPS), Windows (CUDA/CPU only)
-- **ONNX Runtime**: All platforms theoretically supported; iOS demonstrated working
-- **MLX**: macOS 14.0+ and iOS 16.0+ only (Apple Silicon exclusive)
-- **Android**: ONNX Runtime supports it, but not officially tested
-
-## Rust integration and Tauri compatibility
-
-**Supertonic offers native Rust support** directly in the repository's `rust/` directory. The implementation uses ONNX Runtime Rust bindings, making Tauri integration straightforward—you can call TTS directly from your Rust backend without spawning external processes.
-
-```rust
-// Supertonic approach: Native Rust in Tauri backend
-// Uses ort crate (ONNX Runtime) directly
-```
-
-**Chatterbox lacks official Rust bindings**, creating three integration paths for Tauri:
-
-1. **ONNX via `ort` crate**: Load quantized ONNX models directly from Rust—no Python required, works cross-platform
-2. **Python sidecar**: Bundle PyInstaller-compiled Python with Tauri's `externalBin` feature
-3. **Local HTTP server**: Run chatterbox-tts-api as subprocess with OpenAI-compatible endpoints
-
-The Python sidecar approach has been documented for Chatterbox with mlx-audio. Configure `tauri.conf.json` with `"externalBin": ["binaries/tts-sidecar"]`, compile Python using PyInstaller with target-specific naming (`tts-sidecar-x86_64-apple-darwin`), and spawn via `app.shell().sidecar()`. Known issues include sidecars not terminating cleanly on app close and **50-200 MB additional bundle size** for the Python runtime.
-
-## Voice quality and feature comparison
-
-Both systems produce high-quality, natural speech—neither sounds robotic in typical usage.
-
-**Supertonic** offers configurable inference steps trading speed for quality:
-- 2-step inference: "Close to ElevenLabs Flash" quality, fastest
-- 5-step inference: "Reaches much of ElevenLabs Prime tier"
-- 10+ steps: Highest quality, slower
-
-It includes **11 preset voices** (5 male, 5 female) and excels at text normalization—handling currencies ($5.2M), dates, phone numbers, and abbreviations without preprocessing. Supertonic 2, released January 6, 2026, added support for English, Korean, Spanish, Portuguese, and French.
-
-**Chatterbox** won **63.75% preference over ElevenLabs** in blind evaluations and offers richer features:
-- **Zero-shot voice cloning** from 5-10 seconds of reference audio
-- **Emotion exaggeration control** (0 = monotone, 1 = normal, 2+ = dramatic)
-- **Paralinguistic tags**: `[laugh]`, `[cough]`, `[sigh]`, `[groan]`
-- **23 languages** in the multilingual model
-- Built-in neural watermarking (PerTh) for provenance tracking
-
-## Performance benchmarks reveal the gap
-
-Supertonic's lightweight architecture delivers exceptional speed-to-quality ratios:
-
-| Hardware | Supertonic RTF | Throughput |
-|----------|---------------|------------|
-| M4 Pro (CPU) | 0.015 | 1,263 chars/sec |
-| M4 Pro (WebGPU) | 0.006 | 2,509 chars/sec |
-| RTX 4090 | 0.001 | 12,164 chars/sec |
-| Raspberry Pi | 0.3 | Real-time capable |
-
-Chatterbox requires more compute but achieves competitive latency:
-- **Streaming RTF**: 0.499 on RTX 4090
-- **Latency**: Sub-200ms optimized, sub-300ms typical
-- **Apple Silicon via MLX**: 2-3× faster than CPU
-- **Mobile (iOS ONNX)**: Functional but ~3.2 GB peak RAM
-
-## Licensing permits commercial use
-
-Both projects use permissive licenses suitable for commercial applications:
-
-| Aspect | Supertonic | Chatterbox |
-|--------|------------|------------|
-| Code license | MIT | MIT |
-| Model license | OpenRAIL-M | MIT |
-| Commercial use | ✅ Allowed | ✅ Allowed |
-| Voice cloning | Not supported | Built-in |
-| Watermarking | None | Optional neural watermark |
-
-## Practical deployment recommendation
-
-For your privacy-focused Tauri chat application, **Supertonic provides the most straightforward path**:
-
-1. **Native Rust integration**: Add ONNX Runtime via `ort` crate, call TTS directly from Tauri backend
-2. **Minimal bundle impact**: ~264 MB models + ~7-15 MB ONNX Runtime per platform
-3. **True cross-platform**: iOS, Android, macOS, Linux work today with official examples
-4. **No Python dependency**: Ships as pure native code
-
-Choose Chatterbox only if you specifically need **voice cloning** or **emotion control**. In that case, use the Q4F16 ONNX variant (~560 MB) with the `ort` crate for maximum portability. Avoid the Python sidecar approach on mobile—it's impractical due to bundle size and process management complexity.
-
-## Conclusion
-
-The two systems serve different use cases despite both being local TTS solutions. Supertonic optimizes for **deployment simplicity and efficiency**—its 66M parameter model runs on constrained devices while maintaining quality competitive with cloud services. Chatterbox optimizes for **feature richness**—voice cloning and emotion control justify its 5-8× larger footprint for applications requiring those capabilities.
-
-For a Tauri app shipping across iOS, Android, macOS, and Linux with privacy as a priority, Supertonic's architecture eliminates the primary pain points: no Python runtime, no platform-specific codepaths for inference, and proven mobile deployment. The January 2026 Supertonic 2 release with multilingual support further strengthens this recommendation for international applications.
-
----
-
-## Grok
-
-### Key Considerations for Choosing Between Supertonic and Chatterbox
-- **Model Size and Resource Efficiency**: Research indicates Supertonic (66 million parameters) is significantly smaller and more lightweight than Chatterbox models (350-500 million parameters), making it better suited for resource-constrained devices across platforms.
-- **Cross-Platform Compatibility**: Evidence leans toward Supertonic being more reliable and easier to deploy on iOS, Android, Mac, and Linux due to its ONNX Runtime integration, with native examples for mobile and desktop; Chatterbox, while feasible on Mac and potentially iOS via optimizations like MLX, lacks straightforward Android support and relies on Python, complicating Tauri integration.
-- **Ease of Integration in Tauri Apps**: Supertonic appears more straightforward for Rust-based Tauri builds with direct Rust examples, while Chatterbox may require a Python sidecar (e.g., with MLX-audio on Apple devices), adding complexity but remaining viable for certain setups.
-- **Reliability and Recent Developments**: Both are actively maintained, but Supertonic 2's January 2026 release introduces multilingual support and optimizations, suggesting it may offer fresher reliability for local runs; user feedback highlights its stability for long-form audio, though Chatterbox excels in voice cloning and expressiveness.
-- **Recommendation**: For local TTS in Tauri across all specified platforms, Supertonic seems likely the better choice due to its smaller size, broader native compatibility, and simpler integration, though Chatterbox could suit scenarios prioritizing advanced features like zero-shot cloning if platform constraints are flexible.
-
-#### Tech Stack Overview
-Supertonic leverages ONNX Runtime for inference, enabling efficient, CPU-optimized execution without heavy dependencies—ideal for embedding in cross-platform apps. It supports batch processing and configurable inference steps (e.g., 2-5), with models hosted on Hugging Face (https://huggingface.co/Supertone/supertonic-2). Chatterbox, built on PyTorch, requires Python environments and supports CUDA, CPU, or MPS (Metal Performance Shaders) for Apple devices, but integration often involves additional tools like MLX-audio for optimization on Mac/iOS.
-
-#### Performance and Features
-Supertonic prioritizes speed, achieving real-time factors (RTF) as low as 0.006 on WebGPU and handling complex text (e.g., dates, currencies) natively. Chatterbox focuses on quality, with features like paralinguistic tags ([laugh], [chuckle]) for expressive speech and zero-shot voice cloning, though it may require more VRAM (around 5-6.5GB on GPUs). For local runs, Supertonic's lightweight design suggests lower latency on diverse hardware, while Chatterbox performs well on supported setups but could be slower on non-optimized platforms.
-
-#### Platform-Specific Insights
-- **iOS/Android**: Supertonic offers native iOS examples and Flutter support for cross-mobile deployment; ONNX Runtime ensures compatibility (https://onnxruntime.ai/docs/build/ios.html). Chatterbox has been adapted for iOS via apps like Chinny, but Android integration is less documented and may need custom work.
-- **Mac/Linux**: Both run well—Supertonic via Swift/Rust on Mac and various examples on Linux; Chatterbox uses MPS on Mac for acceleration and is straightforward on Linux with CUDA/CPU.
-
-If prioritizing minimal footprint and ease, start with Supertonic's Rust example for Tauri: clone the repo, build with Cargo, and integrate ONNX models directly.
-
----
-### In-Depth Analysis of Supertonic and Chatterbox for Cross-Platform Local TTS in Tauri Applications
-
-Text-to-speech (TTS) models like Supertonic and Chatterbox represent significant advancements in open-source AI, enabling privacy-focused, offline audio generation for applications such as voice assistants, accessibility tools, and content creation. As of early 2026, these models cater to developers building cross-platform apps with frameworks like Tauri, which allows Rust-based backends for web-like UIs on iOS, Android, Mac, and Linux. This analysis draws from repository details, user integrations, performance benchmarks, and community feedback to evaluate their suitability for local deployment. We prioritize factors like model size, tech stack, platform compatibility, reliability, and Tauri-specific integration, acknowledging that while both are capable, differences in architecture influence their ease of use across devices.
-
-#### Model Architectures and Core Technologies
-Supertonic, developed by Supertone Inc., is an ONNX-based TTS system optimized for on-device inference with minimal overhead. Its core relies on ONNX Runtime, a cross-platform engine that supports CPU-optimized execution (GPU untested in the repo but feasible). Models are slimmed using OnnxSlim, resulting in efficient, lightweight files. The system generates 16-bit WAV audio, supports batch processing for throughput, and handles natural text variations (e.g., phone numbers, units) without preprocessing. Supertonic 2, released on January 6, 2026 (v2.0.0), expands to multilingual support for English, Korean, Spanish, Portuguese, and French, with six new voice styles (M3-M5, F3-F5). It's licensed under MIT for code and OpenRAIL-M for models, allowing commercial use.
-
-Chatterbox, from Resemble AI, is a PyTorch-based family of models: the original (500M parameters, English-only), Multilingual (500M, 23+ languages), and Turbo (350M, English with paralinguistic tags like [chuckle] or [cough]). It emphasizes high-fidelity, zero-shot voice cloning, and expressive speech via configurable parameters (e.g., CFG for guidance, exaggeration for emotion). All include Perth watermarking for ethical traceability. The Turbo variant distills the decoder to a single generation step, reducing latency and VRAM needs. It's MIT-licensed and installable via pip, with dependencies managed in pyproject.toml for Python 3.11 on Debian-like systems.
-
-Key tech differences: Supertonic's ONNX focus enables broader runtime flexibility without Python, while Chatterbox's PyTorch ties it to Python environments, potentially requiring sidecars in non-Python apps like Tauri.
-
-#### Model Sizes and Resource Requirements
-Model size directly impacts local feasibility, especially on mobile devices with limited RAM/VRAM.
-
-| Model | Variant | Parameters | Approximate Size | VRAM Usage (GPU) | Key Optimizations |
-|-------|---------|------------|------------------|------------------|-------------------|
-| Supertonic | Supertonic 2 | 66M | Ultra-lightweight (optimized ONNX files) | Minimal (CPU-focused; ~low GB if GPU) | OnnxSlim for compression; batch support |
-| Chatterbox | Turbo | 350M | Medium | ~5GB (e.g., RTX 3060) | Distilled decoder; low-latency mode |
-| Chatterbox | Multilingual/Original | 500M | Larger | ~6.5GB | Zero-shot cloning; expressive tuning |
-
-Supertonic's 66M parameters make it the smallest, enabling runs on edge devices like Raspberry Pi or e-readers with RTF as low as 0.012 on CPU. Chatterbox models, at 350-500M, demand more resources but offer efficiencies like 1-step generation in Turbo, using ~5GB VRAM for faster output (e.g., 1.8x speed over original). For Tauri apps, Supertonic's footprint reduces bundling overhead, while Chatterbox may need quantized versions (e.g., 6-bit via MLX) for mobile.
-
-#### Performance Benchmarks and Features
-Performance varies by use case: speed vs. quality.
-
-- **Speed and Latency**: Supertonic excels, processing up to 12,164 characters/second on RTX 4090 and 167x real-time on M4 Pro Mac, with RTF 0.006 on WebGPU. It's faster than Chatterbox on non-NVIDIA hardware. Chatterbox Turbo achieves sub-200ms latency, suitable for real-time agents, and handles long texts stably via chunking.
-- **Audio Quality and Expressiveness**: Chatterbox leads in naturalness, with low word error rates, emotional carry-over, and tags for non-verbal cues; it outperforms paid services like ElevenLabs in cloning (7-11s reference audio). Supertonic provides stable, natural long-form narration but lacks cloning or advanced emotion tuning, focusing on clear, reliable output.
-- **Multilingual Support**: Supertonic 2 adds five languages; Chatterbox Multilingual covers 23+.
-
-In comparisons, Supertonic is praised for efficiency in resource-limited scenarios, while Chatterbox shines in expressive, cloned audio.
-
-#### Cross-Platform Compatibility and Deployment
-ONNX Runtime makes Supertonic highly portable: it supports iOS (native Xcode), Android (via Flutter), Mac (Swift/MPS), Linux (multiple languages), and even browsers (WebGPU/WASM). Installation involves cloning the repo, Git LFS for models, and language-specific builds (e.g., `cargo build` for Rust).
-
-Chatterbox supports Mac (MPS), Linux (CUDA/CPU), and Windows (GPU), with iOS adaptations via apps like Chinny for offline runs. Android integration is not native; it may require embedding Python or API wrappers. MLX-audio optimizes for Apple Silicon, enabling faster inference on Mac/iOS.
-
-For Tauri: Supertonic integrates directly via Rust examples, embedding ONNX in the backend. Chatterbox uses a Python sidecar (e.g., via tauri-plugin-shell), running scripts as external processes—feasible but adds overhead, especially with MLX-audio for Apple platforms.
-
-#### Reliability, Maintenance, and Community Feedback
-Both are reliable for local use, with active repos (Supertonic updated January 2026; Chatterbox last in mid-2025). Supertonic's on-device privacy and stability for long narration earn praise in integrations (e.g., browser extensions, e-book apps). Early Supertonic 2 reviews highlight its speed and natural voices on Windows/Mac. Chatterbox is lauded for beating paid TTS in quality but may face setup issues on non-GPU devices.
-
-Pros/Cons Table:
-
-| Aspect | Supertonic | Chatterbox |
-|--------|------------|------------|
-| **Pros** | Ultra-fast, small size, broad platforms, easy Rust/Tauri integration | Superior quality/cloning, expressive tags, multilingual options |
-| **Cons** | Limited voices/cloning, recent multilingual addition | Larger size, Python-dependent, limited mobile native support |
-| **Best For** | Speed-focused, cross-platform local apps | Quality-focused, voice agents with cloning |
-
-#### Recommendations and Implementation Tips
-For Tauri builds targeting all platforms, Supertonic is preferable: download models from Hugging Face, use Rust bindings for backend inference, and expose via Tauri commands. Test on devices like Raspberry Pi for edge cases. If voice cloning is essential, opt for Chatterbox with a Python sidecar—use MLX-audio for Mac/iOS acceleration and explore quantization for Android. Always verify with hardware benchmarks, as real-world performance varies.
-
-### Key Citations
-- [GitHub - supertone-inc/supertonic](https://github.com/supertone-inc/supertonic)
-- [GitHub - resemble-ai/chatterbox](https://github.com/resemble-ai/chatterbox)
-- [Lightning-Fast Open-Source TTS Model Is Here!](https://medium.com/@bytefer/12-164-characters-per-second-lightning-fast-open-source-tts-model-is-here-96452a3dd66f)
-- [ONNX Runtime | Home](https://onnxruntime.ai/)
-- [ONNX Runtime: Enabling Cross-Platform AI Model Inference](https://medium.com/aimonks/onnx-runtime-enabling-cross-platform-ai-model-inference-80f136ecbb2d)
-- [This Local AI Voice Model Beats Paid TTS (Chatterbox Turbo Tested)](https://www.youtube.com/watch?v=3UN70ea4h9c)
-- [A few insights from running Chatterbox fully offline on iPhone and Mac](https://huggingface.co/ResembleAI/chatterbox/discussions/42)
-- [Blaizzy/mlx-audio](https://github.com/Blaizzy/mlx-audio/actions)
-- [Supertonic TTS is incredible — sharing our integration results](https://huggingface.co/Supertone/supertonic/discussions/13)
-- [Supertonic TTS: Ultra-Fast, Natural Voices on Windows & Mac](https://sonusahani.com/blogs/supertonic-tts)
-- [Supertonic Review: A New, Ultra-Fast and Lightweight AI Model](https://www.youtube.com/watch?v=g2CuKBqCeK0)
-- [The Top Open-Source Text to Speech (TTS) Models](https://modal.com/blog/open-source-tts)
-- [The Best Open-Source Text-to-Speech Models in 2026](https://www.bentoml.com/blog/exploring-the-world-of-open-source-text-to-speech-models)
-- [Embedding External Binaries](https://v2.tauri.app/develop/sidecar/)
-- [How Chatterbox Is Redefining Open-Source AI Voice](https://medium.com/%40vinodpolinati/chatterbox-the-leading-family-of-open-source-ai-voice-models-thats-changing-the-game-150991d5cf8d)
diff --git a/docs/unified-chat-refactor.md b/docs/unified-chat-refactor.md
deleted file mode 100644
index c603e0386..000000000
--- a/docs/unified-chat-refactor.md
+++ /dev/null
@@ -1,335 +0,0 @@
-# Unified Chat Refactor - Phase 1
-
-## Overview
-
-This document describes the initial refactor of Maple's chat interface in preparation for migrating from the current localStorage-based chat system to OpenAI's Conversations/Responses API.
-
-## Motivation
-
-The existing chat architecture had several pain points:
-
-1. **Scattered State Management**: Chat state was distributed across multiple components and routes:
- - `frontend/src/routes/index.tsx` - Home page with ChatBox
- - `frontend/src/routes/_auth.chat.$chatId.tsx` - Individual chat route
- - `frontend/src/components/ChatBox.tsx` - Shared chat input component
- - Complex prop drilling and state synchronization between these components
-
-2. **Complex Routing Logic**: The system required careful coordination between routes, with state being passed through navigation params, leading to:
- - Difficult debugging when state got out of sync
- - Re-rendering and remounting issues on navigation
- - Complex URL management logic
-
-3. **Preparation for API Migration**: The upcoming switch to OpenAI's Conversations/Responses API requires a simpler architecture that can handle:
- - Server-side conversation state
- - Streaming responses
- - No dependency on localStorage for chat history
-
-## Architectural Decisions
-
-### 1. Monolithic Component Design
-
-We created a single `UnifiedChat` component that contains all chat functionality:
-
-```typescript
-// frontend/src/components/UnifiedChat.tsx
-export function UnifiedChat() {
- // ALL chat state lives here
- const [messages, setMessages] = useState([]);
- const [input, setInput] = useState("");
- const [isGenerating, setIsGenerating] = useState(false);
- // ...
-}
-```
-
-**Rationale**:
-- Following the principle "Premature abstraction is the root of all evil"
-- Colocated code is easier to debug and understand
-- No state synchronization bugs between components
-- Similar to how large tech companies (Meta, etc.) handle complex components
-
-### 2. URL Management Without Navigation
-
-Instead of using TanStack Router navigation (which causes remounting), we use browser-native `window.history.replaceState()`:
-
-```javascript
-// Update URL without any navigation/reload
-const usp = new URLSearchParams(window.location.search);
-usp.set("conversation_id", newChatId);
-window.history.replaceState(null, "", `/?${usp.toString()}`);
-```
-
-**Benefits**:
-- No component remounting
-- No state loss
-- URL updates for shareability/bookmarking
-- No "route not found" errors (query params don't need routes)
-
-### 3. Query Parameters Over Route Parameters
-
-We use `?conversation_id=xxx` instead of `/chat/xxx`:
-
-- **Before**: `/chat/123` - Requires route file, causes navigation
-- **After**: `/?conversation_id=123` - No route needed, just URL update
-
-This approach avoids the need for route configuration while maintaining URL-based state.
-
-### 4. Preserved Existing Infrastructure
-
-We maintained backward compatibility:
-- Old `/chat/$chatId` routes still work
-- Existing Sidebar component is reused
-- Auth logic and modals (team setup, API keys) remain functional
-- Search parameters for callbacks (`team_setup`, `credits_success`) preserved
-
-## Implementation Details
-
-### File Structure
-
-**New Files**:
-- `frontend/src/components/UnifiedChat.tsx` - The unified chat component
-- `frontend/src/routes/index.backup.tsx` - Backup of original index
-
-**Modified Files**:
-- `frontend/src/routes/index.tsx` - Simplified to show Marketing or UnifiedChat based on auth
-- `frontend/src/components/Sidebar.tsx` - Updated "New Chat" to clear conversation_id
-
-### State Management
-
-Currently using local React state with mocked responses:
-
-```typescript
-// Mock AI response - will be replaced with OpenAI conversations API
-setTimeout(() => {
- const assistantMessage: Message = {
- id: `msg-${Date.now()}-ai`,
- role: "assistant",
- content: "Hello world! This is a mocked response...",
- timestamp: Date.now()
- };
- setMessages(prev => [...prev, assistantMessage]);
-}, 1000);
-```
-
-This will be replaced with actual API calls in Phase 2.
-
-### New Chat Flow
-
-1. User clicks "New Chat" in sidebar
-2. Sidebar clears `conversation_id` from URL
-3. Dispatches 'newchat' event
-4. UnifiedChat listens and clears messages
-5. Input field gets focus
-
-## Benefits Achieved
-
-1. **Simplified Codebase**: ~250 lines in one file vs ~500+ lines across multiple files
-2. **No State Synchronization Issues**: Single source of truth
-3. **Better Performance**: No unnecessary re-renders or navigation
-4. **Easier Debugging**: All logic in one place
-5. **Ready for API Migration**: Clean foundation for OpenAI integration
-
-## Next Steps (Phase 2)
-
-1. **OpenAI Conversations API Integration**:
- - Replace mock responses with actual API calls
- - Implement streaming responses
- - Handle conversation creation and management
-
-2. **Remove localStorage Dependency**:
- - Migrate chat history to server-side storage
- - Update Sidebar to fetch from API instead of localStorage
-
-3. **Error Handling & Edge Cases**:
- - Handle API failures gracefully
- - Implement retry logic
- - Add loading states for conversation fetching
-
-## Design Philosophy
-
-This refactor follows the principle of **"Make it work, make it right, make it fast"**:
-
-1. **Make it work**: Single component with all functionality (current state)
-2. **Make it right**: Will be achieved with API integration
-3. **Make it fast**: Can optimize/split components later if needed
-
-By avoiding premature optimization and keeping everything in one place, we've created a maintainable foundation that can evolve as requirements become clearer.
-
-## Technical Decisions Explained
-
-### Why Not Cache Conversations?
-
-We explicitly decided against caching for now:
-- Most users work on one conversation at a time
-- API is fast enough that loading isn't painful
-- Adds complexity that may not be needed
-- Can be added later if users report performance issues
-
-### Why Query Parameters?
-
-- No route configuration needed
-- Works immediately without router setup
-- Prevents "route not found" errors
-- Can be migrated to proper routes later if needed
-
-### Why Keep Everything in One Component?
-
-- Based on real-world experience at major tech companies
-- Easier to understand and debug
-- No props drilling or state synchronization
-- Can be split later when natural boundaries emerge
-
-## Current Implementation Status
-
-### ✅ Features Successfully Implemented
-
-The UnifiedChat component now includes these fully working features:
-
-#### Core Chat Functionality
-- **Conversations/Responses API Integration** - Full server-side state management with OpenAI-compatible endpoints
-- **Streaming responses** - Real-time SSE event handling for all response types
-- **Message deduplication** - Smart ID management using server-assigned IDs with smooth local-to-server transitions
-- **URL-based conversation routing** - Query parameter approach (`?conversation_id=xxx`) avoiding route configuration
-- **5-second polling** - Automatic synchronization for cross-device conversations
-- **Conversation lifecycle** - Lazy creation, loading from URL, switching between conversations
-
-#### User Interface
-- **Modern ChatGPT-style UI** - Clean aesthetics with hover states and subtle backgrounds
-- **Auto-scrolling** - Intelligent scroll on new messages (user and assistant)
-- **Copy to clipboard** - One-click copy for assistant messages
-- **React.memo optimization** - MessageList component prevents re-renders during input
-- **Responsive sidebar** - Mobile-friendly with toggle button
-- **Centered input for new chats** - Beautiful welcome screen with logo and prompt
-- **Fixed input for active chats** - Standard chat interface when conversation is active
-- **Mobile new chat button** - Quick access button in mobile header when in a conversation
-- **Consistent mobile UI** - Aligned headers and consistent button styling across sidebar and main chat
-
-#### Multimodal Support
-- **Image attachments** - Support for JPEG, PNG, WebP up to 10MB
-- **Document parsing** - PDF, TXT, MD support (PDF requires Tauri)
- - Fixed Tauri command: Uses `extract_document_content` instead of `parse_document`
- - Simplified JSON format: Documents stored as `{ document: { filename, text_content } }`
- - Removed unnecessary `status` and `errors` fields from document structure
- - Proper markdown rendering with document preview button
-- **Attachment preview** - Visual previews with remove capability
-- **Auto model switching** - Automatically selects vision-capable models when images added
-- **Plus button dropdown** - Clean attachment interface
-- **Proper OpenAI format** - Uses `input_text`, `input_image`, `output_text` content types
-
-#### Billing & Access Control
-- **Tier-based features** - Starter (images), Pro/Team (documents)
-- **Upgrade prompts** - Contextual dialogs when accessing restricted features
-- **Model selector integration** - Shows available models based on user's plan
-
-#### Error Handling
-- **404 recovery** - Gracefully handles non-existent conversations
-- **Network error display** - User-friendly error messages
-- **Silent polling failures** - Doesn't interrupt user experience
-- **Attachment validation** - File type and size checks with clear feedback
-
-### ✅ Recently Implemented Features
-
-#### Voice Recording (Completed December 2024)
-- **Voice recording** - Microphone input with RecordRTC
-- **Whisper transcription** - Convert speech to text via OpenSecret API
-- **Recording overlay** - Visual feedback with waveform animation
-- **Proper overlay positioning** - Covers only input area, not full page
-- **Access control** - Requires Pro/Team tier and Whisper model availability
-- **Error handling** - Clear messages for permission issues
-
-### ❌ Features Not Yet Migrated
-
-These features exist in the old components but haven't been implemented in UnifiedChat:
-
-#### TTS Features (Postponed - API not working)
-- **Text-to-Speech (TTS)** - Kokoro voice synthesis with play/stop controls
-- **Auto-play TTS** - Automatic playback for voice-initiated messages
-- **Audio manager** - Prevents multiple TTS playing simultaneously
-
-#### ✅ Scroll Behavior (Completed December 2024)
-- **Smart auto-scroll logic** - Improved scrolling that matches old behavior:
- - Instant scroll to bottom on initial chat load
- - Auto-scroll when user sends a message
- - Auto-scroll slightly (100px) when assistant starts streaming
- - No auto-scroll while streaming (lets user read at their pace)
- - Auto-scroll when new messages arrive from polling (e.g., after refresh)
- - Maintains scroll position when user has scrolled up
-- **User scroll detection** - Tracks if user is within 100px of bottom
-- **Scroll-to-bottom button** - Could be added but not currently implemented
-
-#### System Prompt (Coming Soon via API)
-- **System prompt support** - Will be handled via new API, not frontend input
-- **Collapsible display** - Will need UI for showing system prompts when implemented
-
-#### UI/UX Features
-- **Draft message persistence** - localStorage backup of unsent messages
-
-#### Advanced Features
-- **Document metadata tracking** - Preserve filename and full content
-- **Multi-file selection** - Batch image uploads
-- **Message-specific actions** - Per-message TTS controls
-
-### 🎯 Feature Prioritization
-
-Based on user value and implementation complexity:
-
-#### High Priority (Essential)
-1. ✅ **Voice Input** - COMPLETED! Recording and transcription working
-2. ✅ **Token Management** - HANDLED BY BACKEND! Intelligent compression on server-side
-3. ✅ **Streaming indicators** - COMPLETED! Different implementation but working well
-4. ✅ **Scroll behavior** - COMPLETED! Smart auto-scrolling with user detection
-5. **TTS** - Postponed until API is fixed
-
-#### Medium Priority (Nice to Have)
-6. **System prompt support** - Coming via new API
-7. **Draft persistence** - Prevents data loss on refresh
-
-#### Low Priority (Already Done or Not Needed)
-9. ✅ **Mobile new chat button** - Already implemented
-10. ✅ **Token warnings** - Not needed, backend handles compression automatically
-11. **Message-specific TTS controls** - Will implement when TTS API is fixed
-
-### 🏗️ Architecture Improvements Achieved
-
-The refactor has delivered significant architectural improvements:
-
-1. **Single Component Architecture** - All logic in UnifiedChat.tsx, no prop drilling
-2. **Server-Driven State** - No localStorage dependencies for chat data
-3. **Clean URL Management** - Query parameters avoid complex routing
-4. **Optimized Rendering** - Strategic use of React.memo prevents unnecessary re-renders
-5. **Proper Error Boundaries** - Graceful handling of API failures
-6. **Event-Based Communication** - Clean integration with sidebar via custom events
-7. **Abort Controllers** - Proper cleanup of in-flight requests
-8. **Resource Management** - Proper cleanup of object URLs and event listeners
-
-### 📊 Comparison with Old Architecture
-
-| Aspect | Old Implementation | New UnifiedChat |
-|--------|-------------------|----------------|
-| **Files** | 3+ components, multiple routes | Single component |
-| **State Management** | Props, localStorage, context | Local React state + API |
-| **Chat Persistence** | localStorage | Server-side via API |
-| **Routing** | `/chat/:chatId` with route files | `?conversation_id=xxx` query params |
-| **Message IDs** | Client-generated only | Server-assigned with local fallback |
-| **Polling** | None | 5-second interval with cursor |
-| **Code Complexity** | ~500+ lines across files | ~1276 lines in one file |
-| **Debugging** | Difficult (scattered logic) | Easy (colocated code) |
-
-### 🚀 Next Steps
-
-1. **Implement Voice Features** - Add recording and TTS for accessibility
-2. **Add Token Management** - Implement counting and compression
-3. **Enhance UX** - Add scroll-to-bottom and streaming indicators
-4. **Performance Optimization** - Consider splitting component if it grows much larger
-5. **Testing** - Add comprehensive tests for the unified component
-
-## Conclusion
-
-The UnifiedChat refactor has successfully achieved its primary goals:
-- ✅ Simplified architecture with single component
-- ✅ Full Conversations/Responses API integration
-- ✅ Removed localStorage dependencies for chat data
-- ✅ Maintained all essential functionality
-- ✅ Improved performance with React.memo
-- ✅ Created foundation for future enhancements
-
-While some features from the old implementation haven't been migrated yet, the core chat experience is fully functional and the architecture is much cleaner. The missing features are primarily UX enhancements that can be added incrementally based on user feedback and priorities.
diff --git a/frontend/src-tauri/apple-sign-in-info.md b/frontend/src-tauri/apple-sign-in-info.md
deleted file mode 100644
index 30fcc26d2..000000000
--- a/frontend/src-tauri/apple-sign-in-info.md
+++ /dev/null
@@ -1,102 +0,0 @@
-# Sign in with Apple Integration
-
-## Overview
-This document provides a comprehensive guide to the Sign in with Apple integration for Maple, supporting both native iOS authentication and web-based OAuth.
-
-## Integration Types
-
-### 1. Native iOS Authentication
-- Uses the iOS native Sign In with Apple dialog
-- Implemented via `tauri-plugin-sign-in-with-apple` (version 1.0.0)
-- Returns user credentials directly to the app
-- Provides access to user identifiers, email, and name (only on first sign-in)
-
-### 2. Web-based OAuth Flow
-- Similar to GitHub and Google OAuth flow
-- Redirects users to Apple's authentication page
-- Supports both web and desktop (non-iOS) platforms
-- Handles callback with auth code and state verification
-
-## Configuration
-
-### iOS Native Auth
-1. Required entitlements have been added in `maple_iOS.entitlements`
-2. The capability is registered in `capabilities/default.json` and `capabilities/mobile-ios.json`
-3. Plugin is configured in Cargo.toml and registered in the app
-
-### OAuth Configuration
-1. Set up these parameters in your OpenSecret project settings:
- - **Client ID**: Your Apple Services ID (e.g., com.example.web)
- - **Client Secret**: The base64-encoded contents of your Apple private key (p8 file)
- - **Redirect URI**: Configure as `https://api.opensecret.cloud/auth/apple/callback`
-
-## Implementation Details
-
-### Frontend Integration
-
-#### iOS Native Flow
-```typescript
-// iOS native authentication
-const result = await invoke("plugin:sign-in-with-apple|get_apple_id_credential", {
- payload: {
- scope: ["email", "fullName"],
- state: "apple-auth-state",
- options: { debug: true }
- }
-});
-
-// Format and send to backend
-const appleUser = {
- user_identifier: result.user,
- identity_token: result.identityToken,
- email: result.email,
- given_name: result.fullName?.givenName,
- family_name: result.fullName?.familyName
-};
-
-// Call OpenSecret SDK
-await os.handleAppleNativeSignIn(appleUser, inviteCode);
-```
-
-#### Web OAuth Flow
-```typescript
-// Web OAuth authentication
-const { auth_url } = await os.initiateAppleAuth(inviteCode);
-window.location.href = auth_url;
-
-// Callback handling (in separate component)
-await handleAppleCallback(code, state, inviteCode);
-```
-
-### Platform Detection
-The app automatically determines the appropriate flow:
-1. Checks if the app is running on iOS and uses native flow
-2. Checks if running in a Tauri environment (desktop) and uses the desktop auth flow
-3. Uses the web OAuth flow for all other cases
-
-## Callback Handling
-For the web OAuth flow, callbacks are handled in `auth.$provider.callback.tsx`:
-1. Extracts code and state from URL parameters
-2. Verifies auth state to prevent CSRF attacks
-3. Processes the authentication with the backend
-4. Redirects to appropriate page after successful authentication
-
-## Debugging
-If you experience issues with Sign in with Apple:
-1. Check debug logs (enabled by default in both flows)
-2. Verify that iOS entitlements are properly configured (for native flow)
-3. For OAuth flow, check if Apple Developer account is properly set up
-4. Verify that the OpenSecret project settings are correctly configured
-
-## Apple Developer Setup
-To use Sign in with Apple, you need:
-1. An Apple Developer account
-2. An App ID with "Sign In with Apple" capability
-3. A Services ID for web authentication
-4. A Bundle ID for iOS apps
-5. A private key for JWT token signing
-
-## Resources
-- [Apple Developer Documentation](https://developer.apple.com/documentation/sign_in_with_apple)
-- [OpenSecret Apple Auth API](https://docs.opensecret.cloud/docs/guides/authentication)
-- [tauri-plugin-sign-in-with-apple](https://crates.io/crates/tauri-plugin-sign-in-with-apple)
\ No newline at end of file