Skip to content

Commit 85c6e0a

Browse files
authored
refactor(config): Generate viper defaults via reflection over DefaultConfig() (#436)
## Summary - The hand-maintained `v.SetDefault` block in `initConfig()` had drifted out of sync with `config.DefaultConfig()`, leaving **50 leaf paths and 28 fields silently returning zero values** instead of their documented defaults. Affected: entire `storage.*`, `client.retry.*`, `image.*`, `mcp.*`, `scm.*` sections, plus `init.prompt`, `chat.keybindings.bindings`, `tools.web_fetch.cache.*`, `tools.sandbox.*`, most of `tools.github.*`, and `conversation.title_generation.*`. - Replace 240 lines of hand-written defaults with `registerConfigDefaults()` in `cmd/defaults.go` — a reflection walker over `mapstructure` tags. `config.DefaultConfig()` is now the single source of truth and additions to `Config` are picked up automatically. - Add two regression tests in `cmd/root_defaults_test.go` that guarantee viper stays in sync with `DefaultConfig()`: - `TestViperDefaultsCoverNonZeroConfigDefaults`: every non-zero leaf in `DefaultConfig()` must appear in `V.AllKeys()` after `initConfig()`. - `TestViperUnmarshalReproducesDefaultConfig`: round-tripping viper through `Unmarshal` must equal `DefaultConfig()` field-for-field. Net diff: `cmd/root.go` shrank from ~440 to 204 lines; `// nolint:funlen` removed.
1 parent 5564697 commit 85c6e0a

3 files changed

Lines changed: 249 additions & 193 deletions

File tree

cmd/defaults.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package cmd
2+
3+
import (
4+
"reflect"
5+
"strings"
6+
7+
viper "github.com/spf13/viper"
8+
)
9+
10+
// registerConfigDefaults walks cfg via mapstructure tags and calls
11+
// v.SetDefault for every leaf field with a non-zero value. cfg must be a
12+
// struct or pointer to struct annotated with `mapstructure` tags.
13+
//
14+
// This replaces the hand-maintained list of v.SetDefault calls and keeps
15+
// viper's default registry automatically in sync with config.DefaultConfig().
16+
func registerConfigDefaults(v *viper.Viper, cfg any) {
17+
walkConfigLeaves(reflect.ValueOf(cfg), "", func(path string, val reflect.Value) {
18+
if isLeafZeroValue(val) {
19+
return
20+
}
21+
v.SetDefault(path, val.Interface())
22+
})
23+
}
24+
25+
// walkConfigLeaves traverses a struct (or pointer to struct) using
26+
// mapstructure tags and invokes visit for every leaf field. Structs and
27+
// non-nil pointers to structs are recursed into; everything else (scalars,
28+
// slices, maps, pointers to scalars, nil pointers to structs) is treated as
29+
// a leaf.
30+
func walkConfigLeaves(v reflect.Value, prefix string, visit func(path string, val reflect.Value)) {
31+
if v.Kind() == reflect.Pointer {
32+
if v.IsNil() {
33+
return
34+
}
35+
v = v.Elem()
36+
}
37+
if v.Kind() != reflect.Struct {
38+
return
39+
}
40+
t := v.Type()
41+
for i := 0; i < t.NumField(); i++ {
42+
f := t.Field(i)
43+
if !f.IsExported() {
44+
continue
45+
}
46+
tag := f.Tag.Get("mapstructure")
47+
if tag == "" || tag == "-" {
48+
continue
49+
}
50+
name := strings.SplitN(tag, ",", 2)[0]
51+
if name == "" {
52+
continue
53+
}
54+
full := name
55+
if prefix != "" {
56+
full = prefix + "." + name
57+
}
58+
fv := v.Field(i)
59+
switch {
60+
case fv.Kind() == reflect.Struct:
61+
walkConfigLeaves(fv, full, visit)
62+
case fv.Kind() == reflect.Pointer && fv.Type().Elem().Kind() == reflect.Struct:
63+
if fv.IsNil() {
64+
visit(full, fv)
65+
} else {
66+
walkConfigLeaves(fv.Elem(), full, visit)
67+
}
68+
default:
69+
visit(full, fv)
70+
}
71+
}
72+
}
73+
74+
// isLeafZeroValue reports whether v carries no useful default. Zero-valued
75+
// leaves don't need to be registered with viper since GetXxx already returns
76+
// the zero value of the requested type.
77+
func isLeafZeroValue(v reflect.Value) bool {
78+
switch v.Kind() {
79+
case reflect.Pointer, reflect.Interface:
80+
return v.IsNil()
81+
case reflect.Slice, reflect.Map:
82+
return v.Len() == 0
83+
case reflect.String:
84+
return v.String() == ""
85+
case reflect.Bool:
86+
return !v.Bool()
87+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
88+
return v.Int() == 0
89+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
90+
return v.Uint() == 0
91+
case reflect.Float32, reflect.Float64:
92+
return v.Float() == 0
93+
default:
94+
return v.IsZero()
95+
}
96+
}

cmd/root.go

Lines changed: 5 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import (
66
"path/filepath"
77
"strings"
88

9-
config "github.com/inference-gateway/cli/config"
10-
logger "github.com/inference-gateway/cli/internal/logger"
119
cobra "github.com/spf13/cobra"
1210
viper "github.com/spf13/viper"
11+
12+
config "github.com/inference-gateway/cli/config"
13+
logger "github.com/inference-gateway/cli/internal/logger"
1314
)
1415

1516
// Global Viper instance for commands to use
@@ -52,200 +53,11 @@ func init() {
5253
cobra.OnInitialize(initConfig)
5354
}
5455

55-
func initConfig() { // nolint:funlen
56+
func initConfig() {
5657
V = viper.New()
5758
v := V
5859

59-
defaults := config.DefaultConfig()
60-
v.SetDefault("container_runtime", defaults.ContainerRuntime)
61-
v.SetDefault("container_runtime.type", defaults.ContainerRuntime.Type)
62-
v.SetDefault("gateway", defaults.Gateway)
63-
v.SetDefault("gateway.url", defaults.Gateway.URL)
64-
v.SetDefault("gateway.api_key", defaults.Gateway.APIKey)
65-
v.SetDefault("gateway.timeout", defaults.Gateway.Timeout)
66-
v.SetDefault("gateway.oci", defaults.Gateway.OCI)
67-
v.SetDefault("gateway.run", defaults.Gateway.Run)
68-
v.SetDefault("gateway.standalone_binary", defaults.Gateway.StandaloneBinary)
69-
v.SetDefault("gateway.debug", defaults.Gateway.Debug)
70-
v.SetDefault("gateway.include_models", defaults.Gateway.IncludeModels)
71-
v.SetDefault("gateway.exclude_models", defaults.Gateway.ExcludeModels)
72-
v.SetDefault("gateway.vision_enabled", defaults.Gateway.VisionEnabled)
73-
v.SetDefault("claude_code", defaults.ClaudeCode)
74-
v.SetDefault("claude_code.enabled", defaults.ClaudeCode.Enabled)
75-
v.SetDefault("claude_code.cli_path", defaults.ClaudeCode.CLIPath)
76-
v.SetDefault("claude_code.timeout", defaults.ClaudeCode.Timeout)
77-
v.SetDefault("claude_code.max_output_tokens", defaults.ClaudeCode.MaxOutputTokens)
78-
v.SetDefault("claude_code.thinking_budget", defaults.ClaudeCode.ThinkingBudget)
79-
v.SetDefault("claude_code.max_turns", defaults.ClaudeCode.MaxTurns)
80-
v.SetDefault("logging", defaults.Logging)
81-
v.SetDefault("logging.debug", defaults.Logging.Debug)
82-
v.SetDefault("logging.dir", defaults.Logging.Dir)
83-
v.SetDefault("client", defaults.Client)
84-
v.SetDefault("tools", defaults.Tools)
85-
v.SetDefault("tools.enabled", defaults.Tools.Enabled)
86-
v.SetDefault("tools.bash.enabled", defaults.Tools.Bash.Enabled)
87-
v.SetDefault("tools.bash.timeout", defaults.Tools.Bash.Timeout)
88-
v.SetDefault("tools.bash.whitelist.commands", defaults.Tools.Bash.Whitelist.Commands)
89-
v.SetDefault("tools.bash.whitelist.patterns", defaults.Tools.Bash.Whitelist.Patterns)
90-
v.SetDefault("tools.bash.background_shells.enabled", defaults.Tools.Bash.BackgroundShells.Enabled)
91-
v.SetDefault("tools.bash.background_shells.max_concurrent", defaults.Tools.Bash.BackgroundShells.MaxConcurrent)
92-
v.SetDefault("tools.bash.background_shells.max_output_buffer_mb", defaults.Tools.Bash.BackgroundShells.MaxOutputBufferMB)
93-
v.SetDefault("tools.bash.background_shells.retention_minutes", defaults.Tools.Bash.BackgroundShells.RetentionMinutes)
94-
v.SetDefault("tools.bash.require_approval", defaults.Tools.Bash.RequireApproval)
95-
v.SetDefault("tools.read.enabled", defaults.Tools.Read.Enabled)
96-
v.SetDefault("tools.read.require_approval", defaults.Tools.Read.RequireApproval)
97-
v.SetDefault("tools.write.enabled", defaults.Tools.Write.Enabled)
98-
v.SetDefault("tools.write.require_approval", defaults.Tools.Write.RequireApproval)
99-
v.SetDefault("tools.edit.enabled", defaults.Tools.Edit.Enabled)
100-
v.SetDefault("tools.edit.require_approval", defaults.Tools.Edit.RequireApproval)
101-
v.SetDefault("tools.delete.enabled", defaults.Tools.Delete.Enabled)
102-
v.SetDefault("tools.delete.require_approval", defaults.Tools.Delete.RequireApproval)
103-
v.SetDefault("tools.grep.enabled", defaults.Tools.Grep.Enabled)
104-
v.SetDefault("tools.grep.backend", defaults.Tools.Grep.Backend)
105-
v.SetDefault("tools.grep.require_approval", defaults.Tools.Grep.RequireApproval)
106-
v.SetDefault("tools.tree.enabled", defaults.Tools.Tree.Enabled)
107-
v.SetDefault("tools.tree.require_approval", defaults.Tools.Tree.RequireApproval)
108-
v.SetDefault("tools.web_fetch.enabled", defaults.Tools.WebFetch.Enabled)
109-
v.SetDefault("tools.web_fetch.whitelisted_domains", defaults.Tools.WebFetch.WhitelistedDomains)
110-
v.SetDefault("tools.web_fetch.safety.max_size", defaults.Tools.WebFetch.Safety.MaxSize)
111-
v.SetDefault("tools.web_fetch.safety.timeout", defaults.Tools.WebFetch.Safety.Timeout)
112-
v.SetDefault("tools.web_fetch.safety.allow_redirect", defaults.Tools.WebFetch.Safety.AllowRedirect)
113-
v.SetDefault("tools.web_search.enabled", defaults.Tools.WebSearch.Enabled)
114-
v.SetDefault("tools.web_search.default_engine", defaults.Tools.WebSearch.DefaultEngine)
115-
v.SetDefault("tools.web_search.max_results", defaults.Tools.WebSearch.MaxResults)
116-
v.SetDefault("tools.web_search.engines", defaults.Tools.WebSearch.Engines)
117-
v.SetDefault("tools.web_search.timeout", defaults.Tools.WebSearch.Timeout)
118-
v.SetDefault("tools.github.enabled", defaults.Tools.Github.Enabled)
119-
v.SetDefault("tools.todo_write.enabled", defaults.Tools.TodoWrite.Enabled)
120-
v.SetDefault("tools.todo_write.require_approval", defaults.Tools.TodoWrite.RequireApproval)
121-
v.SetDefault("tools.schedule.enabled", defaults.Tools.Schedule.Enabled)
122-
v.SetDefault("tools.schedule.require_approval", defaults.Tools.Schedule.RequireApproval)
123-
v.SetDefault("tools.schedule.storage_dir", defaults.Tools.Schedule.StorageDir)
124-
v.SetDefault("tools.schedule.max_jobs", defaults.Tools.Schedule.MaxJobs)
125-
v.SetDefault("tools.safety.require_approval", defaults.Tools.Safety.RequireApproval)
126-
v.SetDefault("agent", defaults.Agent)
127-
v.SetDefault("agent.model", defaults.Agent.Model)
128-
v.SetDefault("agent.system_prompt", defaults.Agent.SystemPrompt)
129-
v.SetDefault("agent.system_prompt_with_defaults", defaults.Agent.SystemPromptWithDefaults)
130-
v.SetDefault("agent.custom_instructions", defaults.Agent.CustomInstructions)
131-
v.SetDefault("agent.system_prompt_plan", defaults.Agent.SystemPromptPlan)
132-
v.SetDefault("agent.system_prompt_remote", defaults.Agent.SystemPromptRemote)
133-
v.SetDefault("agent.verbose_tools", defaults.Agent.VerboseTools)
134-
v.SetDefault("agent.max_turns", defaults.Agent.MaxTurns)
135-
v.SetDefault("agent.max_tokens", defaults.Agent.MaxTokens)
136-
v.SetDefault("agent.max_concurrent_tools", defaults.Agent.MaxConcurrentTools)
137-
v.SetDefault("agent.system_reminders.enabled", defaults.Agent.SystemReminders.Enabled)
138-
v.SetDefault("agent.system_reminders.interval", defaults.Agent.SystemReminders.Interval)
139-
v.SetDefault("agent.context.git_context_enabled", defaults.Agent.Context.GitContextEnabled)
140-
v.SetDefault("agent.context.working_dir_enabled", defaults.Agent.Context.WorkingDirEnabled)
141-
v.SetDefault("agent.context.git_context_refresh_turns", defaults.Agent.Context.GitContextRefreshTurns)
142-
v.SetDefault("export", defaults.Export)
143-
v.SetDefault("compact", defaults.Compact)
144-
v.SetDefault("compact.enabled", defaults.Compact.Enabled)
145-
v.SetDefault("compact.auto_at", defaults.Compact.AutoAt)
146-
v.SetDefault("compact.keep_first_messages", defaults.Compact.KeepFirstMessages)
147-
v.SetDefault("compact.rollover_on_idle_minutes", defaults.Compact.RolloverOnIdleMinutes)
148-
v.SetDefault("web", defaults.Web)
149-
v.SetDefault("web.enabled", defaults.Web.Enabled)
150-
v.SetDefault("web.port", defaults.Web.Port)
151-
v.SetDefault("web.host", defaults.Web.Host)
152-
v.SetDefault("web.session_inactivity_mins", defaults.Web.SessionInactivityMins)
153-
v.SetDefault("web.ssh", defaults.Web.SSH)
154-
v.SetDefault("web.ssh.enabled", defaults.Web.SSH.Enabled)
155-
v.SetDefault("web.ssh.use_ssh_config", defaults.Web.SSH.UseSSHConfig)
156-
v.SetDefault("web.ssh.known_hosts_path", defaults.Web.SSH.KnownHostsPath)
157-
v.SetDefault("web.ssh.auto_install", defaults.Web.SSH.AutoInstall)
158-
v.SetDefault("web.ssh.install_version", defaults.Web.SSH.InstallVersion)
159-
v.SetDefault("web.ssh.install_dir", defaults.Web.SSH.InstallDir)
160-
v.SetDefault("web.servers", defaults.Web.Servers)
161-
v.SetDefault("computer_use", defaults.ComputerUse)
162-
v.SetDefault("computer_use.enabled", defaults.ComputerUse.Enabled)
163-
v.SetDefault("computer_use.floating_window.enabled", defaults.ComputerUse.FloatingWindow.Enabled)
164-
v.SetDefault("computer_use.floating_window.respawn_on_close", defaults.ComputerUse.FloatingWindow.RespawnOnClose)
165-
v.SetDefault("computer_use.floating_window.position", defaults.ComputerUse.FloatingWindow.Position)
166-
v.SetDefault("computer_use.floating_window.always_on_top", defaults.ComputerUse.FloatingWindow.AlwaysOnTop)
167-
v.SetDefault("computer_use.screenshot.enabled", defaults.ComputerUse.Screenshot.Enabled)
168-
v.SetDefault("computer_use.screenshot.max_width", defaults.ComputerUse.Screenshot.MaxWidth)
169-
v.SetDefault("computer_use.screenshot.max_height", defaults.ComputerUse.Screenshot.MaxHeight)
170-
v.SetDefault("computer_use.screenshot.target_width", defaults.ComputerUse.Screenshot.TargetWidth)
171-
v.SetDefault("computer_use.screenshot.target_height", defaults.ComputerUse.Screenshot.TargetHeight)
172-
v.SetDefault("computer_use.screenshot.format", defaults.ComputerUse.Screenshot.Format)
173-
v.SetDefault("computer_use.screenshot.quality", defaults.ComputerUse.Screenshot.Quality)
174-
v.SetDefault("computer_use.screenshot.streaming_enabled", defaults.ComputerUse.Screenshot.StreamingEnabled)
175-
v.SetDefault("computer_use.screenshot.capture_interval", defaults.ComputerUse.Screenshot.CaptureInterval)
176-
v.SetDefault("computer_use.screenshot.buffer_size", defaults.ComputerUse.Screenshot.BufferSize)
177-
v.SetDefault("computer_use.screenshot.temp_dir", defaults.ComputerUse.Screenshot.TempDir)
178-
v.SetDefault("computer_use.screenshot.log_captures", defaults.ComputerUse.Screenshot.LogCaptures)
179-
v.SetDefault("computer_use.rate_limit.enabled", defaults.ComputerUse.RateLimit.Enabled)
180-
v.SetDefault("computer_use.rate_limit.max_actions_per_minute", defaults.ComputerUse.RateLimit.MaxActionsPerMinute)
181-
v.SetDefault("computer_use.rate_limit.window_seconds", defaults.ComputerUse.RateLimit.WindowSeconds)
182-
v.SetDefault("computer_use.tools.mouse_move.enabled", defaults.ComputerUse.Tools.MouseMove.Enabled)
183-
v.SetDefault("computer_use.tools.mouse_click.enabled", defaults.ComputerUse.Tools.MouseClick.Enabled)
184-
v.SetDefault("computer_use.tools.mouse_scroll.enabled", defaults.ComputerUse.Tools.MouseScroll.Enabled)
185-
v.SetDefault("computer_use.tools.keyboard_type.enabled", defaults.ComputerUse.Tools.KeyboardType.Enabled)
186-
v.SetDefault("computer_use.tools.keyboard_type.max_text_length", defaults.ComputerUse.Tools.KeyboardType.MaxTextLength)
187-
v.SetDefault("computer_use.tools.get_focused_app.enabled", defaults.ComputerUse.Tools.GetFocusedApp.Enabled)
188-
v.SetDefault("computer_use.tools.activate_app.enabled", defaults.ComputerUse.Tools.ActivateApp.Enabled)
189-
v.SetDefault("git", defaults.Git)
190-
v.SetDefault("storage", defaults.Storage)
191-
v.SetDefault("conversation", defaults.Conversation)
192-
v.SetDefault("chat", defaults.Chat)
193-
v.SetDefault("chat.theme", defaults.Chat.Theme)
194-
v.SetDefault("chat.keybindings.enabled", defaults.Chat.Keybindings.Enabled)
195-
v.SetDefault("chat.status_bar.enabled", defaults.Chat.StatusBar.Enabled)
196-
v.SetDefault("chat.status_bar.indicators.model", defaults.Chat.StatusBar.Indicators.Model)
197-
v.SetDefault("chat.status_bar.indicators.theme", defaults.Chat.StatusBar.Indicators.Theme)
198-
v.SetDefault("chat.status_bar.indicators.max_output", defaults.Chat.StatusBar.Indicators.MaxOutput)
199-
v.SetDefault("chat.status_bar.indicators.a2a_agents", defaults.Chat.StatusBar.Indicators.A2AAgents)
200-
v.SetDefault("chat.status_bar.indicators.tools", defaults.Chat.StatusBar.Indicators.Tools)
201-
v.SetDefault("chat.status_bar.indicators.background_shells", defaults.Chat.StatusBar.Indicators.BackgroundShells)
202-
v.SetDefault("chat.status_bar.indicators.a2a_tasks", defaults.Chat.StatusBar.Indicators.A2ATasks)
203-
v.SetDefault("chat.status_bar.indicators.mcp", defaults.Chat.StatusBar.Indicators.MCP)
204-
v.SetDefault("chat.status_bar.indicators.context_usage", defaults.Chat.StatusBar.Indicators.ContextUsage)
205-
v.SetDefault("chat.status_bar.indicators.session_tokens", defaults.Chat.StatusBar.Indicators.SessionTokens)
206-
v.SetDefault("chat.status_bar.indicators.cost", defaults.Chat.StatusBar.Indicators.Cost)
207-
v.SetDefault("chat.status_bar.indicators.git_branch", defaults.Chat.StatusBar.Indicators.GitBranch)
208-
v.SetDefault("a2a.enabled", defaults.A2A.Enabled)
209-
v.SetDefault("a2a.cache.enabled", defaults.A2A.Cache.Enabled)
210-
v.SetDefault("a2a.cache.ttl", defaults.A2A.Cache.TTL)
211-
v.SetDefault("a2a.task.status_poll_seconds", defaults.A2A.Task.StatusPollSeconds)
212-
v.SetDefault("a2a.task.polling_strategy", defaults.A2A.Task.PollingStrategy)
213-
v.SetDefault("a2a.task.initial_poll_interval_sec", defaults.A2A.Task.InitialPollIntervalSec)
214-
v.SetDefault("a2a.task.max_poll_interval_sec", defaults.A2A.Task.MaxPollIntervalSec)
215-
v.SetDefault("a2a.task.backoff_multiplier", defaults.A2A.Task.BackoffMultiplier)
216-
v.SetDefault("a2a.task.background_monitoring", defaults.A2A.Task.BackgroundMonitoring)
217-
v.SetDefault("a2a.task.completed_task_retention", defaults.A2A.Task.CompletedTaskRetention)
218-
v.SetDefault("a2a.task.agent_mode_max_wait_seconds", defaults.A2A.Task.AgentModeMaxWaitSeconds)
219-
v.SetDefault("a2a.tools.query_agent.enabled", defaults.A2A.Tools.QueryAgent.Enabled)
220-
v.SetDefault("a2a.tools.query_agent.require_approval", defaults.A2A.Tools.QueryAgent.RequireApproval)
221-
v.SetDefault("a2a.tools.query_task.enabled", defaults.A2A.Tools.QueryTask.Enabled)
222-
v.SetDefault("a2a.tools.query_task.require_approval", defaults.A2A.Tools.QueryTask.RequireApproval)
223-
v.SetDefault("a2a.tools.submit_task.enabled", defaults.A2A.Tools.SubmitTask.Enabled)
224-
v.SetDefault("a2a.tools.submit_task.require_approval", defaults.A2A.Tools.SubmitTask.RequireApproval)
225-
v.SetDefault("tools.web_fetch.enabled", defaults.Tools.WebFetch.Enabled)
226-
v.SetDefault("tools.web_fetch.whitelisted_domains", defaults.Tools.WebFetch.WhitelistedDomains)
227-
v.SetDefault("tools.web_fetch.safety.max_size", defaults.Tools.WebFetch.Safety.MaxSize)
228-
v.SetDefault("tools.web_fetch.safety.timeout", defaults.Tools.WebFetch.Safety.Timeout)
229-
v.SetDefault("tools.web_fetch.safety.allow_redirect", defaults.Tools.WebFetch.Safety.AllowRedirect)
230-
v.SetDefault("tools.web_fetch.require_approval", defaults.Tools.WebFetch.RequireApproval)
231-
v.SetDefault("pricing", defaults.Pricing)
232-
v.SetDefault("pricing.enabled", defaults.Pricing.Enabled)
233-
v.SetDefault("pricing.currency", defaults.Pricing.Currency)
234-
v.SetDefault("channels", defaults.Channels)
235-
v.SetDefault("channels.enabled", defaults.Channels.Enabled)
236-
v.SetDefault("channels.max_workers", defaults.Channels.MaxWorkers)
237-
v.SetDefault("channels.image_retention", defaults.Channels.ImageRetention)
238-
v.SetDefault("channels.require_approval", defaults.Channels.RequireApproval)
239-
v.SetDefault("channels.telegram.enabled", defaults.Channels.Telegram.Enabled)
240-
v.SetDefault("channels.telegram.bot_token", defaults.Channels.Telegram.BotToken)
241-
v.SetDefault("channels.telegram.allowed_users", defaults.Channels.Telegram.AllowedUsers)
242-
v.SetDefault("channels.telegram.poll_timeout", defaults.Channels.Telegram.PollTimeout)
243-
v.SetDefault("channels.whatsapp.enabled", defaults.Channels.WhatsApp.Enabled)
244-
v.SetDefault("channels.whatsapp.phone_number_id", defaults.Channels.WhatsApp.PhoneNumberID)
245-
v.SetDefault("channels.whatsapp.access_token", defaults.Channels.WhatsApp.AccessToken)
246-
v.SetDefault("channels.whatsapp.verify_token", defaults.Channels.WhatsApp.VerifyToken)
247-
v.SetDefault("channels.whatsapp.webhook_port", defaults.Channels.WhatsApp.WebhookPort)
248-
v.SetDefault("channels.whatsapp.allowed_users", defaults.Channels.WhatsApp.AllowedUsers)
60+
registerConfigDefaults(v, config.DefaultConfig())
24961

25062
v.SetConfigName("config")
25163
v.SetConfigType("yaml")

0 commit comments

Comments
 (0)