feat: localchat, a Go + Templ + HTMX chat app for local Gemma models

Streams replies over SSE from any OpenAI-compatible server (oMLX,
llama.cpp, Ollama, ...). Single binary that can install itself as an
OS service; docker compose bundles llama.cpp + Gemma 4 E2B.
This commit is contained in:
bdeb1337 committed 2026-10-05 07:25:42 +02:00
commit bb71b49fde
28 files changed
+2459

No files matched your search

+45
View File
@@ -0,0 +1,45 @@
package config
import (
"os"
"path/filepath"
"testing"
)
func TestLoadEnvFile(t *testing.T) {
path := filepath.Join(t.TempDir(), ".env")
os.WriteFile(path, []byte(`
# comment
LLM_MODEL=from-file
export LOCALCHAT_TITLE="My Chat"
SYSTEM_PROMPT='Talk like a pirate = arr'
LLM_BASE_URL=http://file/v1/
`), 0o600)
t.Setenv("LLM_BASE_URL", "http://env/v1") // real env wins over the file
for _, k := range []string{"LLM_MODEL", "LOCALCHAT_TITLE", "SYSTEM_PROMPT"} {
t.Setenv(k, "")
os.Unsetenv(k)
}
if err := LoadEnvFile(path); err != nil {
t.Fatal(err)
}
c, err := Load()
if err != nil {
t.Fatal(err)
}
if c.Model != "from-file" || c.Title != "My Chat" || c.SystemPrompt != "Talk like a pirate = arr" {
t.Fatalf("unexpected config: %+v", c)
}
if c.BaseURL != "http://env/v1" {
t.Fatalf("env should override file, got %q", c.BaseURL)
}
}
func TestLoadValidates(t *testing.T) {
t.Setenv("MAX_HISTORY", "zero")
if _, err := Load(); err == nil {
t.Fatal("want error for bad MAX_HISTORY")
}
}