diff --git a/README.md b/README.md index 9438805..a547554 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,98 @@ go build -o whiskr ``` 3. Open `http://localhost:3443` in your browser. +Got it 👍 — your README currently mentions “Authentication (optional)” but doesn’t explain how to actually enable it. Since you’ve got the `Environment` struct with `Authentication.Enabled`, `Users`, and the HMAC-based token signing/verification, we can add a **Setup Authentication** section that explains: + +- How to enable it in `config.yml` +- How to generate bcrypt password hashes +- How tokens are issued/verified +- How to use them in requests + +Here’s an updated README with the new section added: + +--- + +# whiskr + +![screenshot](.github/chat.png) + +whiskr is a private, self-hosted web chat interface for interacting with AI models via [OpenRouter](https://openrouter.ai/). + +## Features + +- Private and self-hosted (data stored in localStorage) +- Supports any model available on your OpenRouter account +- Real-time streaming responses +- Edit, delete, or copy any message +- Persistent settings for model, temperature, and other parameters +- Full conversation control including clearing and modifying messages +- Smooth UI updates with [morphdom](https://github.com/patrick-steele-idem/morphdom), selections, images, and other state are preserved during updates +- Easy model selection: + - Tags indicate if a model supports **tools**, **vision**, or **reasoning** + - Search field with fuzzy matching to quickly find models + - Models are listed newest -> oldest +- Reasoning effort control +- Web search tools (set the `EXA_TOKEN` to enable): + - `search_web`: search via Exa in auto mode; returns up to 10 results with short summaries + - `fetch_contents`: fetch page contents for one or more URLs via Exa /contents +- Structured JSON output +- Statistics for messages (provider, ttft, tps and token count) +- Import and export of chats as JSON files +- **Authentication (optional)** + +## TODO + +- Image and file attachments + +## Built With + +**Frontend** +- Vanilla JavaScript and CSS +- [morphdom](https://github.com/patrick-steele-idem/morphdom) for DOM diffing without losing state +- [marked](https://github.com/markedjs/marked) for Markdown rendering +- [highlight.js](https://highlightjs.org/) for syntax highlighting +- Fonts: [Inter](https://rsms.me/inter/) (UI), [Comic Code](https://tosche.net/fonts/comic-code) (code) +- Icons: [SVGRepo](https://www.svgrepo.com/) +- Color palette: [Catppuccin Macchiato](https://catppuccin.com/) + +**Backend** +- Go +- [OpenRouter](https://openrouter.ai/) for model list and completions +- [Exa](https://exa.ai/) for web search and content retrieval (`/search`, `/contents`) + +## Getting Started + +1. Copy `example.config.yml` to `config.yml` and set `tokens.openrouter`: +```bash +cp example.config.yml config.yml +``` +2. Build and run: +```bash +go build -o whiskr +./whiskr +``` +3. Open `http://localhost:3443` in your browser. + +## Authentication (optional) + +whiskr supports simple, stateless authentication. If enabled, users must log in with a username and password before accessing the chat. Passwords are hashed using bcrypt (12 rounds). + +```yaml +authentication: + enabled: true + users: + - username: laura + password: "$2a$12$cIvFwVDqzn18wyk37l4b2OA0UyjLYP1GdRIMYbNqvm1uPlQjC/j6e" + - username: admin + password: "$2a$12$mhImN70h05wnqPxWTci8I.RzomQt9vyLrjWN9ilaV1.GIghcGq.Iy" +``` + +After a successful login, whiskr issues a signed (HMAC-SHA256) token, using the server secret (`tokens.secret` in `config.yml`). This is stored as a cookie and re-used for future authentications. + +### 5. Disabling authentication + +Set `authentication.enabled: false` in `config.yml` to allow open access. + ## Usage - Send a message with `Ctrl+Enter` or the send button