feat: AI suggestion (#34)
## Feat * feat(ai): add AI suggestion engine, context gathering, and ghost text overlay (`v0.3.0`) ## Security & Perf * fix(ai): restrict background `--help` execution to a hardcoded command allowlist to prevent RCE * fix(root): defer context cancellation in goroutine to prevent resource leaks * perf(ai): implement LRU eviction and maximum size limit for `ProviderCache` * perf(ai): truncate command context output (`CommandContextProvider.Gather`) to 1000 characters to save tokens ## Bug Fixes * fix(ai): add mutex synchronization and thread-safe snapshotting to `AIEngine.RegisterProvider` and `GatherDynamicContext` * fix(ai): return a copy of fresh `Suggestion` in `AIEngine.Suggest` to prevent cache mutation * fix(ai): use length-prefixed encoding in `EnvSnapshot.Hash` to prevent delimiter collisions * fix(ai): skip variable assignment lines containing `=` when extracting Makefile targets * fix(runner): check `scanner.Err()` and return `nil` on scan errors in justfile generator * test(ci): rename `git commit` to `git checkout` in overlay test to resolve CI `typos` false positive
This commit is contained in:
@@ -57,11 +57,55 @@ type UpdaterConfig struct {
|
||||
CheckInterval Duration `toml:"check-interval"`
|
||||
}
|
||||
|
||||
type SuggestOnEmptyConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
DebounceMS int `toml:"debounce_ms"`
|
||||
MinIntervalMS int `toml:"min_interval_ms"`
|
||||
}
|
||||
|
||||
type ProviderConfig struct {
|
||||
InheritedFrom string `toml:"inherited_from"`
|
||||
Endpoint string `toml:"endpoint"`
|
||||
APIKey string `toml:"api_key"`
|
||||
APIKeyEnv string `toml:"api_key_env"`
|
||||
Model string `toml:"model"`
|
||||
TimeoutMS int `toml:"timeout_ms"`
|
||||
ExtraRequestBody map[string]any `toml:"extra_request_body"`
|
||||
}
|
||||
|
||||
type AIConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
Provider string `toml:"provider"`
|
||||
DebounceMS int `toml:"debounce_ms"`
|
||||
MinIntervalMS int `toml:"min_interval_ms"`
|
||||
Providers map[string]ProviderConfig `toml:"providers"`
|
||||
SuggestOnEmpty SuggestOnEmptyConfig `toml:"suggest_on_empty"`
|
||||
}
|
||||
|
||||
func (c *AIConfig) GetActiveProvider() (ProviderConfig, bool) {
|
||||
if c.Providers == nil {
|
||||
return ProviderConfig{}, false
|
||||
}
|
||||
p, ok := c.Providers[c.Provider]
|
||||
return p, ok
|
||||
}
|
||||
|
||||
func (p *ProviderConfig) GetAPIKey() string {
|
||||
if p.APIKey != "" {
|
||||
return p.APIKey
|
||||
}
|
||||
if p.APIKeyEnv != "" {
|
||||
return os.Getenv(p.APIKeyEnv)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Core CoreConfig `toml:"core"`
|
||||
UI UIConfig `toml:"ui"`
|
||||
Git GitConfig `toml:"git"`
|
||||
Updater UpdaterConfig `toml:"updater"`
|
||||
AI AIConfig `toml:"ai"`
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user