feat: add FOREMAN_KEEP_ALIVE config for worker model residency
CI / Tidy (push) Successful in 9m42s
CI / Build & Test (push) Successful in 10m28s
CI / Publish Docker Image (push) Successful in 21s

Allow configuring how long the worker model stays resident on the Ollama
target after a request via FOREMAN_KEEP_ALIVE env var. Accepts Ollama
duration strings ("-1" forever, "0" unload, "15m", "1h", etc). Defaults
to "-1" (pin forever). The embedder warm-up is unaffected and always
uses keep_alive=-1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 21:29:37 -04:00
parent c16e1af752
commit 7cd7eaff8b
9 changed files with 133 additions and 6 deletions
+8
View File
@@ -48,6 +48,13 @@ type Config struct {
// JobTTL is how long terminal jobs are retained before the pruner deletes them
// (default 24h).
JobTTL time.Duration
// KeepAlive is the keep_alive value sent in outbound /api/chat requests to the
// Ollama target. It controls how long the worker model stays resident after a
// request. Accepts Ollama duration strings like "15m", "1h", "-1" (forever), or
// "0" (unload immediately). Default is "-1" (pin forever). This does NOT affect
// the embedder, which is always pinned with keep_alive=-1.
KeepAlive string
}
// Load reads configuration from environment variables and returns a validated Config.
@@ -64,6 +71,7 @@ func Load() (Config, error) {
EmbedModel: os.Getenv("FOREMAN_EMBED_MODEL"),
DBPath: envOr("FOREMAN_DB_PATH", "foreman.db"),
WebhookSecret: os.Getenv("FOREMAN_WEBHOOK_SECRET"),
KeepAlive: envOr("FOREMAN_KEEP_ALIVE", "-1"),
}
pollStr := envOr("FOREMAN_POLL_INTERVAL", "30s")
+7
View File
@@ -31,6 +31,9 @@ func TestLoad_Defaults(t *testing.T) {
if cfg.PollInterval != 30*time.Second {
t.Errorf("PollInterval = %v, want %v", cfg.PollInterval, 30*time.Second)
}
if cfg.KeepAlive != "-1" {
t.Errorf("KeepAlive = %q, want %q", cfg.KeepAlive, "-1")
}
}
func TestLoad_AllEnvVars(t *testing.T) {
@@ -42,6 +45,7 @@ func TestLoad_AllEnvVars(t *testing.T) {
t.Setenv("FOREMAN_DB_PATH", "/data/foreman.db")
t.Setenv("FOREMAN_POLL_INTERVAL", "1m")
t.Setenv("FOREMAN_WEBHOOK_SECRET", "hmac-key")
t.Setenv("FOREMAN_KEEP_ALIVE", "15m")
cfg, err := Load()
if err != nil {
@@ -72,6 +76,9 @@ func TestLoad_AllEnvVars(t *testing.T) {
if cfg.WebhookSecret != "hmac-key" {
t.Errorf("WebhookSecret = %q", cfg.WebhookSecret)
}
if cfg.KeepAlive != "15m" {
t.Errorf("KeepAlive = %q, want %q", cfg.KeepAlive, "15m")
}
}
func TestLoad_MissingOllamaURL(t *testing.T) {