Spaces:
Runtime error
Runtime error
Commit History
-
feat(ui): align global button thickness with main page
Tan +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>487b5c1 -
feat(i18n): localize system UI and move Ctrl+K to overflow
Tan +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>d106179 -
feat(ui): add visible Command Palette trigger
Tan +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>25c3ee2 -
fix(hotkeys): remove Ctrl+K conflict with sidebar
Tan +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>6108ab2 -
fix(voice): add language picker for speech recognition
Tan +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>6b82d0c -
feat(features): add full functionality index page
Tan +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>2851378 -
fix(i18n): wire locale behavior and restyle language picker
Tan +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>24c7751 -
feat(wave-13): hub w12 update, cmd palette mount, auto-title/memory hooks, PDF-RAG, audio transcribe, calendar scheduler (13 features)
Đào Minh Tú +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>5b2fda8
-
feat(wave-11): command palette, dashboard, code-review, db, slides, contract, story
Đào Minh Tú +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>b92910d -
feat(wave6): voice TTS, share comments, tags+favorites, export+shortcuts
Đào Minh Tú +1: Copilot- /voice: Web Speech API TTS settings (voice/rate/pitch picker) - /export: download sessions as Markdown - /shortcuts: keyboard cheat-sheet - /tags + /favorites: filter views over ChatSession - share comments mounted on /share/[id] via Gist+local fallback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1de385f -
feat(wave5): mind-map, templates, personas marketplace, meeting mode, pinned, notes, link-preview
Đào Minh Tú +1: Copilot- /mind-map: SVG tree view of branch sessions - /templates: 12 built-in Vietnamese prompt templates + CRUD - /personas-mp: persona marketplace via shared Gist + 6 seeds - /meeting + /meeting/[roomId]: multi-user chat polling 5s - /pinned: cross-session pinned messages list - /notes: per-session markdown notes drawer - components/link-preview: Microlink-based URL preview card Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>26c925a -
feat(wave4): 8 features — slash cmds, search, qr-share, /help, image gen, code sandbox, debate, cost tracker
Đào Minh Tú +1: CopilotSolo: - /search page + chat-search-dialog with Ctrl+K UX - /help page with slash command reference - lib/slash-commands.ts: /help /clear /summarize /translate /code /explain /rewrite - lib/auto-title.ts: AI-regen session title via Groq after 4 turns (module ready) - components/qr-share-dialog.tsx: QR code via qrserver.com Agents: - image-gen: /api/image + Pollinations.ai + composer btn + chat.appendImageMessage - code-sandbox: ▶ Chạy button on code blocks (JS/Python via Pyodide CDN, HTML/CSS srcdoc) - debate: /debate page, side-by-side 2 models + synthesizer - cost-tracker: lib/cost-estimator.ts pricing table, /stats card, usage log ring buffer Build ✓ 26 routes, TS clean Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>19a950f -
feat: message branching + team workspace (Gist-based collab)
Đào Minh Tú +1: Copilot- ux-branching: Add GitBranch button on every AI message → fork session with messages[0..=i], parentId set. Sidebar shows 🔱 for branched sessions. - col-team-sync: New /team page with own GH PAT (scope:gist), team Gist ID + nickname. Pull/push/import/remove team sessions. Dedupe by (id, sharedBy), max 100 sessions per gist. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>bad9b69 -
feat: 10+ features — voice/dragdrop/shortcuts, Ollama+RAG citations, workflows+scheduled, share password+TTL, auto-memory, export-md
Đào Minh Tú +1: CopilotUX: - Voice input (vi-VN webkitSpeechRecognition) + drag-drop upload + ?-shortcuts dialog - Composer revamp with mic button and dropzone overlay AI superpowers: - Ollama local provider + /api/ollama/models discovery - RAG with <Citations> render under assistant messages - Auto-memory fact extraction (Groq llama-3.1-8b, debounced 5s) module - /workflows builder with {{prev}} substitution - /scheduled chats page Collaboration: - Share API: SHA-256 password gate (Web Crypto) + custom TTL 1-90d - ShareView client component with password form - Markdown export with YAML frontmatter Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>70e3124 -
feat(header): wire LocaleSwitcher (vi/en/ja)
Đào Minh Tú +1: CopilotCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>8118c30
-
feat: doc editor + offline mode + stats trio + i18n framework
Đào Minh Tú +1: Copilot- Tiptap doc editor at /doc with 4 AI actions (continue/rewrite/summarize/translate) autosave to localStorage, streaming into editor - Offline mode: service worker SWR for static + network-only /api, IndexedDB queue with toast on drain when back online - Stats: TTFT leaderboard per provider (p50/p95), A/B winners win-rate table, usage by day (14d) - A/B picker now records winner with normalized prompt key for future model auto-suggestion - i18n framework (vi/en/ja) + LocaleSwitcher component, not yet wired into header - Deps: @tiptap/react @tiptap/starter-kit @tiptap/pm Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>f102ffd -
feat(chat): persist+restore active session id across reloads
Đào Minh Tú +1: CopilotProblem: reload mid-chat creates a fresh sessionId so the conversation that WAS being persisted in localStorage every 600ms shows up as an orphan in the sidebar but messages array is empty for the new id -> user sees blank chat. Fix: track the active sessionId in localStorage key 'tans-agents:active-session-id'. On mount, hydrate that id; once useChatHistory finishes loading sessions, replay messages of the restored session into useChat (one-shot guard). Skips replay if user already started typing a new message before history hydrated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>99bef26 -
fix(model-picker): pass correct userKey for openrouter/cerebras/mistral
Đào Minh Tú +1: CopilothandleDiscover() was hardcoded to map only google/groq/github and silently fell back to userKeys.github for any other provider, so OpenRouter etc. never received the saved BYOK key from localStorage and Quet live model failed with 'Thieu OPENROUTER_API_KEY' even when the user had configured it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>aadf55b -
fix(ui): make 'Chi tiết kỹ thuật' + AB error pane scrollable on mobile
Đào Minh Tú +1: CopilotReplace Radix ScrollArea with native overflow-y-auto + WebkitOverflowScrolling for reliable touch scroll. Add visible thin destructive-tinted scrollbar. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>f5f72b6 -
feat(providers): add OpenRouter + Cerebras + Mistral free providers
Đào Minh Tú +1: Copilot- 3 new OpenAI-compatible providers wired (createOpenAI + custom baseURL) - OpenRouter: 50+ free models behind one key (:free suffix) - Cerebras: ultra-fast inference (>2000 t/s), 14400 RPD free - Mistral La Plateforme: free tier 1 RPS / 1B tokens/month - New /api/{openrouter,cerebras,mistral}/models discovery routes - Rate-limit table extended; OpenRouter (epoch ms) + Cerebras header parsers - API keys dialog + .env.local.example updated - usage-tracker fingerprint resolution extended for new providers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>3204b1b -
fix: drop generateImage pre-warm + add loading skeleton
Đào Minh Tú +1: Copilot- Pre-warm fetch (12s GET+drain) was blocking the LLM SSE stream idle for 15-30s, causing iOS Safari + Vercel edge to abort with 'Load failed' before the model could output the markdown. - Now: tool returns URL+markdown instantly. Image loads via browser <img> with a 'Đang tạo ảnh 15-30s' skeleton overlay that hides on onLoad, shows error state with tap-through link on onError. - min-height on wrapper so skeleton is visible during render. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>0fad258 -
fix: render generated images + fix tool-call layout overflow on mobile
Đào Minh Tú +1: Copilot- ReactMarkdown: custom <img> renderer with rounded card, max-w-full, lazy/async loading, alt-as-caption generated images now display properly instead of overflowing or staying invisible - ToolCall: collapsible takes full row when open (basis-full) so JSON output doesn't push siblings off-screen on mobile - Tool-call <pre>: whitespace-pre-wrap + [overflow-wrap:anywhere] so long URLs/JSON wrap instead of forcing horizontal page scroll - Parent flex container: w-full min-w-0 max-w-full to constrain width Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>4b75b09 -
feat: real provider rate-limit data via response headers
Đào Minh Tú +1: Copilot- Parse x-ratelimit-* from Groq + GitHub response.headers in onFinish - Cache RateLimitInfo in Upstash keyed by SHA-256(api_key) (cross-device) - /api/usage returns real {remaining, limit, resetSeconds} per model - ModelPicker shows REAL number from provider when available (sky badge + dot) falls back to local estimate for Google Gemini (no headers) - Refresh on dropdown open with in-flight dedupe - Hover tooltip clarifies data source (provider/local) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1f07029 -
fix(model-picker): swap DropdownMenuItem for plain button on scan row
Đào Minh Tú +1: CopilotMobile bug: on touch devices the Radix DropdownMenuItem onSelect path sometimes closes the menu despite e.preventDefault(), so users never saw the loading state appear they tapped, the menu closed, the scan ran in the background, and they re-opened to see the result. Replacing the scan trigger with a plain <button> inside the dropdown: - Bypasses Radix item roving-focus + auto-close logic entirely. - Adds onPointerDown stopPropagation to prevent the dropdown root from treating the press as 'tap-outside' on touch. - Visually identical (same hover bg, padding, gap), but the spinner + Loader2 animate-spin now visibly shows while in-flight. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>6dfcc2c -
fix(model-picker): spinner + locked button while scanning
Đào Minh Tú +1: Copilot- Loader2 with animate-spin shown next to 'Đang quét <provider>...' while in-flight (was just plain text before). - Button is now hard-disabled (disabled prop + pointer-events-none + cursor-not-allowed + opacity) AND the onSelect handler short-circuits if isDiscovering so multiple rapid clicks can't queue extra scans. - Switched the rotation arrow glyph to lucide RefreshCw icon for consistency with the rest of the icon set. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>8fbb974 -
feat(composer): default AI toggles ON + toast feedback on click
Đào Minh Tú +1: Copilot- Self-critique and auto-compact-context now default to ON for new visitors (first-time = no localStorage entry write 'true' so it sticks; existing users keep their previous choice). - Clicking either icon now fires a sonner toast describing what just changed and what the feature does, so users actually know what those little icons under the input do. Adds 'sonner' dep + <Toaster /> in app/layout.tsx (bottom-center, rich colors, theme-aware, dismissible). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>adb9e89 -
fix(model-picker): show used/total with red when exhausted
Đào Minh Tú +1: CopilotPer user feedback: previous format was ambiguous (1400/1400 read as exhausted when it meant 'all 1400 still available'). Switched to: - '<used>/<total>' so the left number always means 'requests consumed' - exhausted (used >= total): red text + red border (no opacity dim, provider may still allow it) - low (within 5% of cap): amber - otherwise: muted gray - unlimited / unknown-but-generous: emerald infinity icon Tooltip clarifies the counter is a local-only estimate. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>ca0e286 -
feat(model-picker): shared store + rate-limit badges
Đào Minh Tú +1: CopilotTwo related fixes: 1. Cross-component sync of live-scanned models. Previously each ModelPicker instance held its own useState for 'discovered' so scanning in the navbar header didn't propagate to the A/B compare pickers. Lifted state into a module-level ModelStore (subscribers + useSyncExternalStore + localStorage persist + cross-tab storage listener). All pickers now share one source of truth and auto-rerender on scan / usage tick. 2. Per-model rate-limit badge next to each id: - Unlimited (or unknown-but-generous): emerald ∞ icon - Limited: '<remaining>/<total>' with amber when ≤5 left, red when 0 - Tooltip explains the source (e.g. 'Free tier: 250 req/day') Backed by lib/rate-limits.ts (regex-keyed table for google/groq/github free tiers as of 2026-05) and a localStorage usage counter keyed by provider:model:YYYY-MM-DD (auto-GC after 7 days). Usage counter is bumped: - onFinish of useChat (single-model path) — uses current provider/model - onDo…70bea94
-
fix(mobile): pin chat shell with position:fixed inset:0
Đào Minh Tú +1: CopilotPrevious attempt (body overflow:hidden + 100dvh) backfired on mobile: input bar still drifted up and navbar got hidden above viewport with no way to scroll back. Switching to a more bulletproof pattern: - Chat root: position:fixed; inset:0; flex column. Pinned to layout viewport header & composer literally cannot scroll out. - Body restored to normal h-full (no overflow:hidden). - viewport meta: add interactiveWidget:'resizes-content' so when the on-screen keyboard opens, the layout viewport shrinks and the composer floats above the keyboard automatically (Chrome Android). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>0a049d8 -
fix(mobile): lock body to dvh + min-h-0 main to stop composer scroll-up
Đào Minh Tú +1: Copilot- html/body height: 100dvh + overflow:hidden so document doesn't scroll (root cause: body was h-full=100vh while chat root was 100dvh; on mobile with URL bar visible, body had ~80px overflow that scrolled the entire page including the sticky composer up off-screen) - main: add min-h-0 (flex-1 needs this to shrink) + overscroll-contain so rubber-band bounce doesn't propagate - composer: shrink-0 (was sticky bottom-0, now anchored as flex sibling) + safe-area-inset-bottom padding for iOS home-indicator devices Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>8da7101 -
fix(auth): gate SessionProvider + CloudSyncButton behind NEXT_PUBLIC_ENABLE_CLOUD_SYNC=1
Đào Minh TúHF Space crashed because NextAuth requires NEXTAUTH_SECRET in production and SessionProvider auto-fetches /api/auth/session on mount. With cloud-sync env vars unset, that 500s and brings down the space. Now: cloud-sync UI + provider only render when explicitly enabled. Set NEXT_PUBLIC_ENABLE_CLOUD_SYNC=1 (plus the 6 backend env vars) to re-enable.3c5ffff -
feat(message): KaTeX math rendering via remark-math + rehype-katex
Đào Minh Tú- Renders LaTeX math (inline \$...\$ and block \$\$...\$\$) properly - Block formulas overflow-x: auto on mobile (no layout break) - Adds katex.min.css import to globals747e7c5 -
feat(cloud-sync): GitHub OAuth + Upstash Redis cross-device sync (LWW)
Đào Minh Tú- /api/auth/[...nextauth] (NextAuth GitHub provider, JWT session) - /api/sync GET/PUT with scope param (sessions/settings/collections) - lib/sync-keys.ts allowlist of localStorage keys per scope - hooks/use-cloud-sync: patch setItem to detect mutations + debounced 3s push + initial pull + pull on focus/visibility - components/cloud-sync-button: sign in/out + status + manual pull/push - Sidebar footer integration - README + .env.local.example updated with setup stepse58a028 -
fix(chat): pause auto-scroll when user scrolls up during streaming (stick-to-bottom only when near bottom)
Đào Minh Túaec1ffd -
fix(message): position quote button at selection focus point (where mouse released) keeps button near cursor when highlighting across list items / multi-line paragraphs
Đào Minh Tú9cc60f8 -
fix(quote): use getBoundingClientRect + non-empty rect fallback so '\u0026 h\u1ecfi' button appears for selections inside list items; also support touchend for mobile
Đào Minh Tú64310b7 -
feat(model-picker): live discovery for Groq + GitHub Models (parallel to Google) — 'Quét live model' button per provider
Đào Minh Tú0ea3919 -
fix(model-picker): use radix --content-available-height + native overflow-y for reliable dropdown scroll
Đào Minh Túeee0dd7 -
fix(tools+models): repair UTF-8 mojibake in tool descriptions; trim model list to verified-working set; filter non-chat models from Google live discovery
Đào Minh Tú671888a -
fix(model-picker): persist selection + scrollable dropdown for live discovery list
Đào Minh Tú9461505 -
fix(google): remove unsupported Gemma static IDs; rely on live discovery
Đào Minh Tú53fa8ad -
refactor(ui): extract ModelPicker; reuse in header + AB toggle; add reuse rule
Đào Minh Túcbdeca1 -
feat(google): expand model list w/ Gemma-3 + live discovery /api/google/models
Đào Minh Tú521a523 -
ui(error-boxes): wrap long text in ScrollArea + break-words; doc rule
Đào Minh Tú52d338e -
ui(input/textarea): use ring-inset to avoid clipping in tight containers
Đào Minh Túea70636 -
ui(header): hide persona section in overflow menu on desktop (dedupe)
Đào Minh Túa42fca4 -
ui(composer): adaptive placeholder shortens based on input width
Đào Minh Túcf9a3af -
ui(composer): AI feature toggles next to context ring; pct inside circle
Đào Minh Túe1ff957 -
ui: replace 3-dot ThinkingDots with shadcn spinner (Loader2)
Đào Minh Tú2f17cdd -
fix(i18n): restore Vietnamese diacritics in tool-call labels; rename edit save button to Gui
Đào Minh Tú587ec20