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:
28 files changed
+2457
No files matched your search
@@ -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")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user