/ internal / memory / config.go
config.go
 1  package memory
 2  
 3  import (
 4  	"os"
 5  	"strings"
 6  	"time"
 7  
 8  	"github.com/spf13/viper"
 9  )
10  
11  type Config struct {
12  	Provider               string
13  	Endpoint               string
14  	APIKey                 string
15  	SocketPath             string
16  	BundleRoot             string
17  	TLMPath                string
18  	BundlePullInterval     time.Duration
19  	BundlePullStartupDelay time.Duration
20  	SidecarReadyTimeout    time.Duration
21  	SidecarShutdownGrace   time.Duration
22  	SidecarRestartMax      int
23  	ClientRequestTimeout   time.Duration
24  }
25  
26  // LoadConfig produces a typed view of memory.* viper keys. Defaults are
27  // registered in internal/config/config.go (single source of truth); this
28  // package's accessors must not register defaults.
29  func LoadConfig(v *viper.Viper) Config {
30  	return Config{
31  		Provider:               v.GetString("memory.provider"),
32  		Endpoint:               v.GetString("memory.endpoint"),
33  		APIKey:                 v.GetString("memory.api_key"),
34  		SocketPath:             expandHome(v.GetString("memory.socket_path")),
35  		BundleRoot:             expandHome(v.GetString("memory.bundle_root")),
36  		TLMPath:                expandHome(v.GetString("memory.tlm_path")),
37  		BundlePullInterval:     v.GetDuration("memory.bundle_pull_interval"),
38  		BundlePullStartupDelay: v.GetDuration("memory.bundle_pull_startup_delay"),
39  		SidecarReadyTimeout:    v.GetDuration("memory.sidecar_ready_timeout"),
40  		SidecarShutdownGrace:   v.GetDuration("memory.sidecar_shutdown_grace"),
41  		SidecarRestartMax:      v.GetInt("memory.sidecar_restart_max"),
42  		ClientRequestTimeout:   v.GetDuration("memory.client_request_timeout"),
43  	}
44  }
45  
46  // ResolveAPIKey is the ONLY call site that reads memory.api_key / cloud.api_key.
47  // memory.api_key wins as override; falls back to cloud.api_key.
48  func ResolveAPIKey(v *viper.Viper) string {
49  	if k := strings.TrimSpace(v.GetString("memory.api_key")); k != "" {
50  		return k
51  	}
52  	return strings.TrimSpace(v.GetString("cloud.api_key"))
53  }
54  
55  // ResolveEndpoint mirrors ResolveAPIKey for the endpoint pair.
56  func ResolveEndpoint(v *viper.Viper) string {
57  	if e := strings.TrimSpace(v.GetString("memory.endpoint")); e != "" {
58  		return e
59  	}
60  	return strings.TrimSpace(v.GetString("cloud.endpoint"))
61  }
62  
63  func expandHome(p string) string {
64  	if p == "" {
65  		return ""
66  	}
67  	if strings.HasPrefix(p, "$HOME") {
68  		return os.Getenv("HOME") + p[len("$HOME"):]
69  	}
70  	if strings.HasPrefix(p, "~") {
71  		return os.Getenv("HOME") + p[1:]
72  	}
73  	return p
74  }