on main help sign in
feat: allow for using CRUSH_ prefixed env-vars without clobbering default env vars (#391)

* feat: allow for using CRUSH_ prefixed env-vars for bedrock without clobbering AWS env vars * feat: make the CRUSH_ prefix generic

commit65cd249cb4488c1c1c0fe817ccb92b6a3cc8c27c authorTai Groot <tai@taigrr.com> dateFri 8 Aug 2025, 06:04 (1 year ago) parent8899b65
2 files changed+33−1
internal/config/load.go+30−1 internal/llm/provider/provider.go+3
internal/config/load.go+30−1
@@ -93,8 +93,38 @@ func Load(workingDir string, debug bool) (*Config, error) {
9393 return cfg, nil
9494}
9595
96+func PushPopCrushEnv() func() {
97+ found := []string{}
98+ for _, ev := range os.Environ() {
99+ if strings.HasPrefix(ev, "CRUSH_") {
100+ pair := strings.SplitN(ev, "=", 2)
101+ if len(pair) != 2 {
102+ continue
103+ }
104+ found = append(found, strings.TrimPrefix(pair[0], "CRUSH_"))
105+ }
106+ }
107+ backups := make(map[string]string)
108+ for _, ev := range found {
109+ backups[ev] = os.Getenv(ev)
110+ }
111+
112+ for _, ev := range found {
113+ os.Setenv(ev, os.Getenv("CRUSH_"+ev))
114+ }
115+
116+ restore := func() {
117+ for k, v := range backups {
118+ os.Setenv(k, v)
119+ }
120+ }
121+ return restore
122+}
123+
96124func (c *Config) configureProviders(env env.Env, resolver VariableResolver, knownProviders []catwalk.Provider) error {
97125 knownProviderNames := make(map[string]bool)
126+ restore := PushPopCrushEnv()
127+ defer restore()
98128 for _, p := range knownProviders {
99129 knownProviderNames[string(p.ID)] = true
100130 config, configExists := c.Providers.Get(string(p.ID))
@@ -495,7 +525,6 @@ func hasAWSCredentials(env env.Env) bool {
495525 env.Get("AWS_CONTAINER_CREDENTIALS_FULL_URI") != "" {
496526 return true
497527 }
498−
499528 return false
500529}
501530
internal/llm/provider/provider.go+3
@@ -5,6 +5,7 @@ import (
55 "fmt"
66
77 "github.com/charmbracelet/catwalk/pkg/catwalk"
8+
89 "github.com/charmbracelet/crush/internal/config"
910 "github.com/charmbracelet/crush/internal/llm/tools"
1011 "github.com/charmbracelet/crush/internal/message"
@@ -139,6 +140,8 @@ func WithMaxTokens(maxTokens int64) ProviderClientOption {
139140}
140141
141142func NewProvider(cfg config.ProviderConfig, opts ...ProviderClientOption) (Provider, error) {
143+ restore := config.PushPopCrushEnv()
144+ defer restore()
142145 resolvedAPIKey, err := config.Get().Resolve(cfg.APIKey)
143146 if err != nil {
144147 return nil, fmt.Errorf("failed to resolve API key for provider %s: %w", cfg.ID, err)