GitHub - bctnry/OpenSyzygy: a LLM chat interface with a new aesthetic.

GitHub

6 min read Original article ↗

an LLM chat interface with a new aesthetic.

A self-hosted chatbot interface with a Go backend and Svelte frontend, talking to a local or remote Ollama server.

Features

  • Terminal interface — the entire app is a single terminal-style window. Type commands (/help) or chat freely.
  • User accounts — register/login via terminal, JWT auth, conversations stored per-user.
  • Admin tier — admin user can configure Ollama URL, models, system prompts, manage users (create, delete, promote, demote, reset passwords) — from the terminal or the config panel.
  • Onboarding — new users get a short LLM-led interview (4 questions, one at a time). Their answers generate a personalized 4-color UI palette.
  • Streaming chat — messages stream token-by-token with a braille throbber while waiting.
  • Conversations — fork, retry (forks + re-sends), revert (removes message + after), graph view (git-style tree).
  • Memory system — automatically extracts memorable facts about the user from conversations. Toggleable, editable, deletable.
  • Scratchpad — save text snippets, ask the LLM about them, edit/delete.
  • Themes — color picker with live preview, LLM theme generator, create/edit/delete.
  • Background image — upload a background image with adjustable opacity.
  • Markdown rendering — headings, tables, code blocks with syntax highlighting + language label, LaTeX math (KaTeX), lists, blockquotes, links.
  • Font scaling — starts large, shrinks as conversation grows. Input font also shrinks.
  • Data export — export all data (conversations, scratchpad, memories, themes, profile, background image) as a zip.
  • Account management — change password (inline form), export data, delete account.
  • Single binary — frontend embedded into the Go binary via embed.FS.
  • Local fonts — EB Garamond, Noto Serif TC, IBM Plex Mono served as woff2.

Quick start

Prerequisites

  • Go 1.22+
  • Node 18+
  • A running Ollama server with at least one model pulled:

Build & run

make build        # builds frontend, embeds it, compiles backend -> backend/syzygy
make run          # runs the server on :7878

Then open http://localhost:7878.

Dev mode (live frontend reload)

make dev-frontend   # terminal 1: Vite dev server on :5173 (proxies /api to :7878)
make dev            # terminal 2: Go server on :7878

Open http://localhost:5173 during development.

Configuration (environment variables)

Variable Default Description
SYZYGY_ADDR :7878 Listen address.
SYZYGY_DATA_DIR ~/.syzygy Where the SQLite DB is stored.
SYZYGY_JWT_SECRET (random ephemeral) JWT signing secret. Set this in production.
OLLAMA_URL http://localhost:11434 Initial Ollama server URL. Can be changed by admin.

First run

On first boot, a default admin is created and the credentials are printed to stderr:

username=admin  password=admin123

Log in via the terminal: type login, fill in the form, submit. Then set a chat model:

Commands

Chat

/new                create a new conversation
/list               list conversations
/switch <n|name>    switch to conversation by index or name
/del <n|name>       delete a conversation
/model [name]       show or set the active model
/models             list available ollama models
/status             toggle status sidebar (token usage, session info)
/map                show conversation graph
/settings           open configuration panel
/clear              clear the terminal
/whoami             show current user
/about              about this system
/help               show all commands
/logout             log out

Scratchpad

/scratchpad list              list items
/scratchpad add <text>        add a new item
/scratchpad del <n>           delete item by index
/scratchpad ask <n>           ask LLM about item in a new session

Memory

/memory list                  list memories
/memory add <text>            add a memory manually
/memory del <n>               delete memory by index
/memory on                    enable automatic memory extraction
/memory off                   disable automatic memory extraction

Account

/account password             change password (opens a form)
/account export               export all data as a zip
/account delete               permanently delete your account
/export                       shorthand for /account export

Theme

/theme list                   list stored themes
/theme use <n|name>           switch to a theme
/theme random                 apply a random stored theme
/theme new <name> <#bg> <#fg>  create a theme
/theme del <n|name>           delete a theme

Admin (admins only)

/settings                     show current settings
/set <key> <value>            update a setting
/users                        list all users
/user new <name> <pass> [role] create a user
/user del <username>          delete a user
/promote <username>           promote user to admin
/demote <username>            demote admin to user
/admin                        show admin commands

Keyboard shortcuts

  • ctrl+up/down — navigate between messages
  • ctrl+click — select a message for actions (copy/retry/revert/fork)
  • esc — deselect message or close overlay/sidebar
  • enter — send message (shift+enter for newline)

Configuration panel

Click the ⚙ button (top-right) or type /settings.

  • appearance — theme picker, color picker with live preview, LLM theme generator, background image + opacity, font sizes, log width/alignment
  • chat — model selection, custom system prompt, self-introduction
  • scratchpad — view, edit, add, ask LLM about items
  • memory — toggle memory, view, edit, add, delete memories
  • account — change password, export data, delete account
  • admin (admins only) — server settings, user management with password reset

How the onboarding palette works

  1. After registering, the new user enters onboarding.
  2. The LLM asks 4 questions, one at a time (3 personal + 1 "anything else to add?").
  3. The answers generate 4 named color palettes via LLM (with hash-based fallback).
  4. The first palette is applied as the active theme.

Memory system

  • After each conversation reply, a background LLM call extracts memorable facts about the user.
  • Memories are injected into the system prompt for future conversations.
  • Explicit requests like "remember that I'm learning guitar" are honored.
  • Toggle on/off in the config panel or with /memory on|off.
  • View, edit, add, delete memories via the config panel or /memory commands.

Project layout

backend/
  main.go                          # router, embedding, server bootstrap
  frontend-dist/                   # embedded built frontend (generated)
  internal/
    auth/                          # JWT auth, middleware, handlers
    admin/                          # admin-only settings & user management
    conversation/                  # conversations + messages (with SSE streaming)
    memory/                        # memory extraction + CRUD endpoints
    onboarding/                    # 4-question interview + palette completion
    ollama/                        # Ollama API client wrapper
    palette/                       # palette generation (LLM + hash fallback)
    profile/                       # profile, scratchpad, background image, export, account
    theme/                         # theme CRUD + LLM theme generation
    db/                            # SQLite store, migrations, models
frontend/
  src/
    App.svelte                     # mounts the terminal
    lib/
      api.js                       # API client + SSE streaming
      stores/user.js               # user store + palette + background theming
      markdown.js                  # markdown renderer with KaTeX + highlight.js
      graph.js                     # git-style conversation graph builder
      commands.js                  # help text, version, about
      selection.js                 # message selection navigation
      treegraph.js                 # TreeGraph SVG library
      components/
        Terminal.svelte            # the whole UI: auth, onboarding, chat, admin
        Sidebars.svelte            # sessions, scratchpad, memory, status sidebars
        ConfigOverlay.svelte       # configuration panel
        GraphOverlay.svelte        # conversation graph overlay
        Throbber.svelte            # braille spinner
  public/
    fonts/                         # woff2 font files + fonts.css

Security notes

  • Passwords hashed with bcrypt.
  • Auth via JWT in Authorization: Bearer <token>, stored in localStorage.
  • Default admin password is admin123 — change it.
  • SQLite used for simplicity; schema in internal/db/db.go.

License

MIT