nanochat/services/frontend/lib/slashCommands.ts
Manmohan Sharma 634be4080b
feat(frontend): Next.js 14 frontend service for samosaChaat (#2)
Build services/frontend/ replacing the legacy nanochat/ui.html single-file UI.
Landing, login, and chat pages ported with full design system: Devanagari +
Great Vibes hero, samosa/chai/toran SVG animations, gold/cream palette.

- App Router pages: / (hero + floating illustrations), /login (split-screen
  OAuth with mandala motif), /chat (260px collapsible sidebar, suggestion
  chips, markdown + code-copy, auto-expanding input, slash commands)
- SSE streaming via useSSE hook and /api/chat/stream BFF route (proxies to
  CHAT_API_URL when set, falls back to mock echo for local dev)
- NextAuth.js v5 with Google + GitHub providers; middleware gates /chat/*
- Zustand store with localStorage persistence for conversations/settings
- Tailwind theme carries all ui.html tokens + keyframes (pendulum, float,
  wobble, steamFloat, steamType); SVG assets componentized under components/svg
- Multi-stage node:20-alpine Dockerfile with Next standalone output

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 11:26:57 -07:00

50 lines
1.6 KiB
TypeScript

export interface SlashResult {
handled: boolean;
consoleMessage?: string;
clear?: boolean;
setTemperature?: number;
setTopK?: number;
}
export function parseSlashCommand(
raw: string,
state: { temperature: number; topK: number },
): SlashResult {
const line = raw.trim();
if (!line.startsWith('/')) return { handled: false };
const [cmd, arg] = line.split(/\s+/);
switch (cmd.toLowerCase()) {
case '/temperature': {
if (arg === undefined) {
return { handled: true, consoleMessage: `Current temperature: ${state.temperature}` };
}
const t = parseFloat(arg);
if (isNaN(t) || t < 0 || t > 2) {
return { handled: true, consoleMessage: 'Invalid temperature. Must be between 0.0 and 2.0' };
}
return { handled: true, setTemperature: t, consoleMessage: `Temperature set to ${t}` };
}
case '/topk': {
if (arg === undefined) {
return { handled: true, consoleMessage: `Current top-k: ${state.topK}` };
}
const k = parseInt(arg, 10);
if (isNaN(k) || k < 1 || k > 200) {
return { handled: true, consoleMessage: 'Invalid top-k. Must be between 1 and 200' };
}
return { handled: true, setTopK: k, consoleMessage: `Top-k set to ${k}` };
}
case '/clear':
return { handled: true, clear: true };
case '/help':
return {
handled: true,
consoleMessage:
'Commands:\n/temperature [0-2] — sampling temperature\n/topk [1-200] — top-k sampling\n/clear — clear conversation\n/help — show this help',
};
default:
return { handled: true, consoleMessage: `Unknown command: ${cmd}` };
}
}