nanochat/services/frontend
Manmohan 1d2a76eec4
feat: deploy d24 SFT + polished UI redesign with dark mode (#39)
* feat(inference): deploy d24 SFT weights to Modal

Repoint Modal inference app from the broken d20 checkpoint to our own
ManmohanSharma/nanochat-d24 SFT step 484. Rewrites the standalone model
as an inference-only port of nanochat/gpt.py so the modern architecture
(smear gate, per-layer value embeddings, ve_gate, backout, sliding
window attention via SDPA, rotary base 100000, padded vocab, logit
softcap) loads cleanly from the checkpoint. Tokenizer loads the pickled
tiktoken encoding directly so special tokens end up at their true IDs
(32759-32767), and the stop check uses that set instead of hardcoded
0-8. GPU bumped to L4 for headroom. HF token sourced from the
'huggingface' Modal secret.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(frontend): polished redesign with serif display + dark mode

Lifts the craft level of the landing and chat UI without changing the
desi identity. Adds Fraunces for display headlines, a floating pill
LandingNav, a saffron-glow hero with a large serif headline and black
pill CTAs, and three gradient-tiled feature cards with inline SVG
glyphs replacing the emoji cards. The chat empty state is now a serif
greeting with pill-chip prompt starters, and ChatInput is a single
rounded pod so the send button sits inside the input (fixes the
misaligned floating button). Adds a class-based dark mode across the
chat surfaces with a sun/moon toggle in the sidebar footer, powered by
a small useTheme hook and a no-flash init script in the root layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(frontend): add ESLint config so CI lint step passes

next lint was failing with an interactive prompt because the repo had
no ESLint config. Adds a minimal next/core-web-vitals extends and
drops the now-unloadable @typescript-eslint/no-explicit-any disable
directive in the stream proxy by narrowing the body type to unknown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:55:16 -04:00
..
app feat: deploy d24 SFT + polished UI redesign with dark mode (#39) 2026-04-16 19:55:16 -04:00
components feat: deploy d24 SFT + polished UI redesign with dark mode (#39) 2026-04-16 19:55:16 -04:00
hooks feat: deploy d24 SFT + polished UI redesign with dark mode (#39) 2026-04-16 19:55:16 -04:00
lib feat(frontend): wire frontend to real backend auth + chat-api services 2026-04-16 13:21:38 -07:00
public feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
store feat(frontend): wire frontend to real backend auth + chat-api services 2026-04-16 13:21:38 -07:00
types feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
.dockerignore feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
.env.example feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
.eslintrc.json feat: deploy d24 SFT + polished UI redesign with dark mode (#39) 2026-04-16 19:55:16 -04:00
.gitignore feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
auth.ts feat(frontend): wire frontend to real backend auth + chat-api services 2026-04-16 13:21:38 -07:00
Dockerfile feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
index.html scaffold monorepo platform layout 2026-04-16 11:06:29 -07:00
middleware.ts feat(frontend): wire frontend to real backend auth + chat-api services 2026-04-16 13:21:38 -07:00
next-env.d.ts feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
next.config.mjs feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
package-lock.json feat(frontend): wire frontend to real backend auth + chat-api services 2026-04-16 13:21:38 -07:00
package.json feat(frontend): wire frontend to real backend auth + chat-api services 2026-04-16 13:21:38 -07:00
postcss.config.mjs feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
README.md feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00
tailwind.config.ts feat: deploy d24 SFT + polished UI redesign with dark mode (#39) 2026-04-16 19:55:16 -04:00
tsconfig.json feat(frontend): Next.js 14 frontend service for samosaChaat (#2) 2026-04-16 11:26:57 -07:00

samosaChaat — Frontend Service

Next.js 14 (App Router) application that replaces the legacy nanochat/ui.html. It blends Sarvam.ai's clean split-screen layout with samosaChaat's warm desi personality — samosa and chai illustrations, lemon-mirchi toran, gold + cream palette.

Pages

  • / Landing — Devanagari + Great Vibes calligraphy, animated samosa (float), chai kettle (wobble + steam), toran (pendulum), ambient doodles, CTA.
  • /login Sign-in — left: architectural/mandala motif with saffron-cream gradient; right: Google + GitHub OAuth, disabled email input.
  • /chat Chat — collapsible 260px sidebar (grouped history, model selector, user avatar, logout), main area with empty state + suggestion chips, markdown rendering with code-copy, auto-expanding textarea, slash commands (/temperature, /topk, /clear, /help), SSE streaming with steam typing indicator.

Tech

  • Next.js 14 (App Router, standalone output)
  • Tailwind CSS (theme tokens carried from ui.html)
  • Zustand (persisted conversations/settings)
  • NextAuth.js v5 (Google + GitHub)
  • Framer Motion (hero transitions)
  • Lucide React (icons)
  • react-markdown + rehype-highlight (assistant rendering)

Environment

Copy .env.example.env.local and fill in:

Var Purpose
NEXT_PUBLIC_APP_URL Public URL (defaults to http://localhost:3000)
AUTH_SERVICE_URL Auth microservice (BFF only; reserved for future)
CHAT_API_URL Upstream chat service. If unset the frontend serves mock echo responses — perfect for local dev.
NEXTAUTH_SECRET openssl rand -base64 32
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET Google OAuth (optional in dev)
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET GitHub OAuth (optional in dev)

Middleware protects /chat/* — unauthenticated users are redirected to /login?callbackUrl=/chat.

Run locally

cd services/frontend
npm install
cp .env.example .env.local    # then edit
npm run dev
# → http://localhost:3000

Without any OAuth keys the /login buttons will show the NextAuth error page; the rest of the UI works via the mocked API routes.

API routes (BFF pattern)

All client calls hit Next.js routes — the frontend never talks to the chat backend directly.

  • GET /api/health — service info + upstream config flags
  • GET /api/conversations — mocked conversation list
  • POST /api/chat/stream — proxies to CHAT_API_URL/chat/completions if set, otherwise streams a mock echo. Emits SSE: data: {"token": "...", "gpu": 0}\n\n and terminates with data: {"done": true}\n\n.

Docker

docker build -t samosachaat-frontend .
docker run --rm -p 3000:3000 \
  -e NEXTAUTH_SECRET=... \
  -e CHAT_API_URL=http://host.docker.internal:8000 \
  samosachaat-frontend

The image is based on node:20-alpine, uses Next.js output: standalone, and runs as a non-root user.

Porting notes

All SVG assets (samosa, chai kettle, toran, steam, doodles, logo) are componentized under components/svg/. CSS keyframes (pendulum, float, wobble, steamFloat, steamType) moved into tailwind.config.ts — reference via the animate-* utilities. The original single-file UI lives at nanochat/ui.html for reference.