Chat System
Multi-interface chat architecture — public widget, admin chat, Argonaut agent, demo chat, and user workbench with streaming, model selection, and conversation persistence
Chat System
ArgoBox has five chat interfaces sharing common streaming and persistence patterns, each targeting different users and capabilities.
Chat Interfaces
ChatWidget (Public)
| Property | Value |
|---|---|
| File | src/components/chat/ChatWidget.astro |
| Endpoint | POST /api/public/chat |
| Model | google/gemini-2.0-flash-001 (free via OpenRouter) |
| Persistence | sessionStorage — last 20 messages, cleared on tab close |
| Rate limit | 15 requests/hour per IP |
Floating panel in the bottom-right corner on all public pages. Features a welcome state with starter chips, RAG-powered answers using the top 5 matching chunks (min score 0.3), and live infrastructure data injection. Max 8 messages of history sent per request, max 1024 tokens per response.
Private Mode
The ChatWidget includes a private mode toggle (lock icon in header) that unlocks an authenticated tier:
| Property | Public | Private |
|---|---|---|
| Endpoint | /api/public/chat |
/api/public/chat-private |
| Model | Gemini Flash (free) | Claude Sonnet |
| Rate limit | 15/hour | 30/hour |
| RAG scope | Public (blog only) | Private (vaults, sessions, knowledge-base) |
| Biography | Public facts only | Full biographical context (SENSITIVE.md from KV) |
| Max history | 8 messages | 16 messages |
| Max tokens | 1024 | 2048 |
Authentication flow:
- User clicks lock icon → password overlay appears
- Password validated against
PRIVATE_PASSWORDenv var via a probe request - On success, password stored in
sessionStorage(argobox-chat-privatekey) - All subsequent messages route to
/api/public/chat-privatewith password in payload - Green border + "Private" indicator shows active state
- If server returns 401, auto-drops to public mode
Environment variables:
PRIVATE_PASSWORD— Plain text password (CF Pages production env)- KV key
data:sensitive-bio— Contents of DANIEL-LAFORCE-SENSITIVE.md (loaded byassistant-prompt.tsin private scope)
Admin Chat
| Property | Value |
|---|---|
| File | src/pages/admin/chat.astro |
| Endpoint | GET/POST /api/admin/chat |
| Models | Full catalog — Ollama, Anthropic, OpenAI, Google, Groq, NVIDIA NIM, OpenRouter |
| Persistence | localStorage — up to 50 conversations |
Full-featured interface with sidebar conversation list, model selector with categories (pricing tier, route type, context window), custom system prompt editor, and conversation search. Auto-titles conversations from the first message.
Sensitivity routing: Messages containing private topics (health, PII, legal, relationships, credentials) are automatically routed to groq/llama-3.3-70b-versatile for privacy-safe processing.
Argonaut Chat
| Property | Value |
|---|---|
| File | src/pages/admin/argonaut/chat.astro |
| Endpoint | POST /api/argonaut/chat |
| Backends | Argonaut (default) + OpenClaw (toggle) |
| Persistence | localStorage — up to 50 conversations |
Advanced admin interface with two switchable backends:
- Argonaut: Full agent with RAG, tool calling, and user profiles. Three-tier fallback: daemon proxy → local agent → cloud-only.
- OpenClaw: Orchestration agent for automation tasks.
Extras: RAG mode toggle (Full: 85K chunks unsanitized vs Safe: 46K chunks blog-only), voice conversation mode with Whisper STT + ElevenLabs TTS, agentic tool indicators, and sources panel.
Registered tools (when daemon is available): Brave/DuckDuckGo search, Perplexity, file read/write/list, allowlisted shell commands, Resend email, Twilio voice/SMS, Google Calendar.
Demo Chat
| Property | Value |
|---|---|
| File | src/pages/api/demo/chat.ts |
| Endpoint | POST /api/demo/chat |
| Model | google/gemini-2.0-flash-001 (free via OpenRouter) |
| Persistence | None — ephemeral, cleared on session end |
| Rate limit | 30 messages per demo sandbox |
Demo-scoped chat for visitors exploring ArgoBox. Authenticated via demo session cookie (HMAC-signed), not admin auth. Uses the same RAG pipeline as the public chat but with demo-specific system prompt context.
Key restrictions vs. other interfaces:
- RAG scope: Public/knowledge only — never searches private vaults or conversations
- No tools: Pure chat, no agentic tool calling
- No model selection: Fixed to budget model
- Content moderation: Same blocklist as public chat (violence, explicit, prompt injection)
- URL rewriting: The demo iframe's fetch interceptor rewrites
/api/argonaut/chatand/api/public/chatto/api/demo/chatso the admin chat UI works transparently in demo mode
User Workbench Chat
| Property | Value |
|---|---|
| File | src/pages/api/user/chat.ts |
| Endpoint | POST /api/user/chat |
| Models | Free models only |
| Persistence | None (API-only) |
Portal user access with role-based permissions (portal:workbench). Restricted to the free model list. Supports custom system prompts.
Provider Routing
The admin chat endpoint resolves providers by model prefix:
| Prefix | Provider | Requirement |
|---|---|---|
ollama/ |
Ollama (local) | Ollama running on network |
anthropic/ |
Anthropic Direct | ANTHROPIC_API_KEY set |
openai/ |
OpenAI Direct | OPENAI_API_KEY set |
google/ |
Google Gemini Direct | GOOGLE_API_KEY set |
groq/ |
Groq | GROQ_API_KEY set |
nvidia-nim/ |
NVIDIA NIM | NVIDIA_NIM_API_KEY set |
| Everything else | OpenRouter | OPENROUTER_API_KEY set |
Unified Chat Router
POST /api/admin/unified-chat classifies user intent with a two-tier system (regex patterns first, Groq LLM fallback) and routes to the appropriate backend:
| Intent | Backend | Use Case |
|---|---|---|
brain |
RAG + knowledge lookup | Questions about the site or infrastructure |
forge |
Tmux session dispatch | Coding tasks |
terminal |
forge-shell session | Shell commands |
openclaw |
Orchestration agent | Agentic tool use |
content |
Content-specific prompts | Blog/journal writing |
private |
Groq (privacy-safe) | Sensitive topics |
The mode parameter can override intent detection: code→forge, terminal→terminal, agent→openclaw.
Streaming Format
All endpoints use Server-Sent Events (SSE):
data: {"content": "text chunk"}
data: {"content": "more text"}
data: {"sources": [...]}
data: {"suggestions": [...]}
data: [DONE]
Client-side pattern:
- Fetch with
AbortControllerfor cancellation response.body.getReader()+TextDecoderfor streaming- Buffer lines, parse JSON from
data:prefix - Handle special events:
[DONE], error, content, sources - Update DOM incrementally with
markedfor markdown rendering - Sanitize HTML output (strip scripts, iframes, event handlers)
Conversation Persistence
| Interface | Storage | Key | Limit |
|---|---|---|---|
| ChatWidget | sessionStorage | argobox-chat-history |
20 messages |
| Admin Chat | localStorage | argobox-chat-conversations |
50 conversations |
| Argonaut | localStorage | argonaut-conversations |
50 conversations |
| Demo Chat | None (ephemeral) | — | Cleared on session end |
Each stored conversation includes: ID, title (auto-generated from first message), messages array, selected model, optional system prompt, and timestamps.
Key Files
| File | Purpose |
|---|---|
src/components/chat/ChatWidget.astro |
Public floating widget |
src/pages/admin/chat.astro |
Admin chat interface |
src/pages/admin/argonaut/chat.astro |
Argonaut advanced interface |
src/pages/api/public/chat.ts |
Public endpoint (free model + RAG) |
src/pages/api/public/chat-private.ts |
Private endpoint (password auth + Claude Sonnet + full RAG) |
src/pages/api/admin/chat.ts |
Admin endpoint (multi-provider) |
src/pages/api/admin/personal-chat.ts |
Private vault endpoint (Groq-only) |
src/pages/api/admin/unified-chat.ts |
Intent-routing endpoint |
src/pages/api/argonaut/chat.ts |
Argonaut daemon proxy |
src/pages/api/demo/chat.ts |
Demo chat endpoint (knowledge RAG + SSE) |
src/pages/api/user/chat.ts |
Portal user endpoint |