Address Copilot review feedback for Exa search + .env loading
- Remove unused SanitizeForLog function (dead code) - Move .env loading before os.IsNotExist early return so fresh installs still get env-based configuration - Differentiate IsNotExist vs real errors in .env loading log message - Cap Exa results loop to requested count parameter - Add missing providers to loadProviderEnvOverrides (VLLM, Cerebras, VolcEngine, Qwen) - Run go mod tidy to fix godotenv indirect -> direct require Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
479958b250
commit
da9bc0ee98
3 changed files with 33 additions and 28 deletions
6
go.mod
6
go.mod
|
|
@ -8,13 +8,16 @@ require (
|
|||
github.com/bwmarrin/discordgo v0.29.0
|
||||
github.com/caarlos0/env/v11 v11.3.1
|
||||
github.com/chzyer/readline v1.5.1
|
||||
github.com/gdamore/tcell/v2 v2.13.8
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/larksuite/oapi-sdk-go/v3 v3.5.3
|
||||
github.com/mdp/qrterminal/v3 v3.2.1
|
||||
github.com/mymmrac/telego v1.6.0
|
||||
github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.1
|
||||
github.com/openai/openai-go/v3 v3.22.0
|
||||
github.com/rivo/tview v0.42.0
|
||||
github.com/slack-go/slack v0.17.3
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/stretchr/testify v1.11.1
|
||||
|
|
@ -34,9 +37,7 @@ require (
|
|||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/elliotchance/orderedmap/v3 v3.1.0 // indirect
|
||||
github.com/gdamore/encoding v1.0.1 // indirect
|
||||
github.com/gdamore/tcell/v2 v2.13.8 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
|
|
@ -44,7 +45,6 @@ require (
|
|||
github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/tview v0.42.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rs/zerolog v1.34.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/caarlos0/env/v11"
|
||||
|
|
@ -590,9 +589,28 @@ type ClawHubRegistryConfig struct {
|
|||
func LoadConfig(path string) (*Config, error) {
|
||||
cfg := DefaultConfig()
|
||||
|
||||
// Load .env file from config directory (secrets, API keys, etc.)
|
||||
// This runs before reading config.json so .env works even on fresh installs.
|
||||
envFile := filepath.Join(filepath.Dir(path), ".env")
|
||||
if err := godotenv.Load(envFile); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Printf("[INFO] No .env file found at %s; skipping .env loading", envFile)
|
||||
} else {
|
||||
log.Printf("[WARN] Failed to load .env file from %s: %v", envFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// No config file — still apply env vars + overrides to default config
|
||||
if err := env.Parse(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
loadProviderEnvOverrides(cfg)
|
||||
if cfg.HasProvidersConfig() {
|
||||
cfg.ModelList = ConvertProvidersToModelList(cfg)
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
return nil, err
|
||||
|
|
@ -616,12 +634,6 @@ func LoadConfig(path string) (*Config, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Load .env file from config directory (secrets, API keys, etc.)
|
||||
envFile := filepath.Join(filepath.Dir(path), ".env")
|
||||
if err := godotenv.Load(envFile); err != nil {
|
||||
log.Printf("[INFO] No .env file loaded from %s: %v", envFile, err)
|
||||
}
|
||||
|
||||
if err := env.Parse(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -816,6 +828,12 @@ func loadProviderEnvOverrides(cfg *Config) {
|
|||
{"SHENGSUANYUN", &cfg.Providers.ShengSuanYun.APIKey, &cfg.Providers.ShengSuanYun.APIBase},
|
||||
{"DEEPSEEK", &cfg.Providers.DeepSeek.APIKey, &cfg.Providers.DeepSeek.APIBase},
|
||||
{"MISTRAL", &cfg.Providers.Mistral.APIKey, &cfg.Providers.Mistral.APIBase},
|
||||
{"VLLM", &cfg.Providers.VLLM.APIKey, &cfg.Providers.VLLM.APIBase},
|
||||
{"CEREBRAS", &cfg.Providers.Cerebras.APIKey, &cfg.Providers.Cerebras.APIBase},
|
||||
{"VOLCENGINE", &cfg.Providers.VolcEngine.APIKey, &cfg.Providers.VolcEngine.APIBase},
|
||||
{"QWEN", &cfg.Providers.Qwen.APIKey, &cfg.Providers.Qwen.APIBase},
|
||||
// Note: GitHubCopilot and Antigravity use different auth patterns (ConnectMode/AuthMethod),
|
||||
// not standard APIKey/APIBase, so they are not included here.
|
||||
}
|
||||
for _, p := range providers {
|
||||
if v := os.Getenv("PICOCLAW_PROVIDERS_" + p.name + "_API_KEY"); v != "" {
|
||||
|
|
@ -826,20 +844,3 @@ func loadProviderEnvOverrides(cfg *Config) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SanitizeForLog masks sensitive API key values for safe logging.
|
||||
func SanitizeForLog(s string) string {
|
||||
prefixes := []string{"sk-", "xoxb-", "xoxp-", "gsk_", "AIza"}
|
||||
for _, p := range prefixes {
|
||||
if strings.HasPrefix(s, p) {
|
||||
if len(s) > len(p)+4 {
|
||||
return s[:len(p)+4] + "****"
|
||||
}
|
||||
return p + "****"
|
||||
}
|
||||
}
|
||||
if len(s) > 8 {
|
||||
return s[:8] + "****"
|
||||
}
|
||||
return "****"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -748,7 +748,11 @@ func (p *ExaSearchProvider) Search(ctx context.Context, query string, count int)
|
|||
}
|
||||
|
||||
var sb strings.Builder
|
||||
for i, r := range result.Results {
|
||||
maxResults := count
|
||||
if maxResults > len(result.Results) {
|
||||
maxResults = len(result.Results)
|
||||
}
|
||||
for i, r := range result.Results[:maxResults] {
|
||||
sb.WriteString(fmt.Sprintf("%d. %s\n URL: %s\n", i+1, r.Title, r.URL))
|
||||
if r.Text != "" {
|
||||
snippet := r.Text
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue