@dcode-dev/dcode-cli 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/dcode-bin CHANGED
Binary file
package/cmd/agent_v2.go CHANGED
@@ -79,7 +79,7 @@ func runAgentV2(cmd *cobra.Command, args []string) error {
79
79
  // Set default models
80
80
  switch provider {
81
81
  case "gemini":
82
- cfg.Model.Model = "gemini-2.0-flash-exp"
82
+ cfg.Model.Model = "gemini-2.5-flash"
83
83
  case "openai":
84
84
  cfg.Model.Model = "gpt-4"
85
85
  case "copilot":
@@ -365,6 +365,7 @@ func handleCommand(input string, agentManager *agents.AgentManager, toolRegistry
365
365
  fmt.Println("\nAvailable Commands:")
366
366
  fmt.Println(" /help, /h - Show this help")
367
367
  fmt.Println(" /agent - List and switch agents")
368
+ fmt.Println(" /model - Change AI model")
368
369
  fmt.Println(" /tools - List available tools")
369
370
  fmt.Println(" /auth - Show authentication status")
370
371
  fmt.Println(" /clear - Clear conversation history")
@@ -402,6 +403,57 @@ func handleCommand(input string, agentManager *agents.AgentManager, toolRegistry
402
403
  }
403
404
  fmt.Println()
404
405
  return true, true
406
+
407
+ case "/model":
408
+ // Show current model and allow changing
409
+ cfg, err := config.LoadConfig()
410
+ if err != nil {
411
+ fmt.Printf("āŒ Error loading config: %v\n", err)
412
+ return true, true
413
+ }
414
+
415
+ provider := cfg.Model.Provider
416
+ currentModel := cfg.Model.Model
417
+
418
+ fmt.Printf("\nšŸ¤– Current: %s (%s)\n\n", currentModel, provider)
419
+
420
+ // Show available models
421
+ models := map[string][]string{
422
+ "gemini": {"gemini-2.5-flash", "gemini-2.0-flash-exp", "gemini-1.5-pro", "gemini-1.5-flash"},
423
+ "openai": {"gpt-4", "gpt-4-turbo", "gpt-4o", "gpt-4o-mini", "gpt-3.5-turbo", "o1-preview", "o1-mini"},
424
+ "copilot": {"gpt-4", "gpt-4-turbo", "gpt-4o", "gpt-4o-mini", "gpt-3.5-turbo", "o1-preview", "o1-mini", "claude-3.5-sonnet"},
425
+ "claude": {"claude-3-5-sonnet-20241022", "claude-3-5-haiku-20241022", "claude-3-opus-20240229"},
426
+ }
427
+
428
+ if availableModels, ok := models[provider]; ok {
429
+ fmt.Println("Available models:")
430
+ for i, model := range availableModels {
431
+ marker := " "
432
+ if model == currentModel {
433
+ marker = "ā–ø"
434
+ }
435
+ fmt.Printf(" %s %d. %s\n", marker, i+1, model)
436
+ }
437
+ fmt.Print("\nEnter number to switch (or press Enter to keep current): ")
438
+
439
+ var choice string
440
+ fmt.Scanln(&choice)
441
+
442
+ if choice != "" {
443
+ var num int
444
+ if _, err := fmt.Sscanf(choice, "%d", &num); err == nil && num >= 1 && num <= len(availableModels) {
445
+ cfg.Model.Model = availableModels[num-1]
446
+ if err := config.SaveConfig(cfg); err != nil {
447
+ fmt.Printf("āŒ Error saving: %v\n", err)
448
+ } else {
449
+ fmt.Printf("āœ… Switched to: %s\n", cfg.Model.Model)
450
+ fmt.Println("āš ļø Restart dcode for changes to take effect")
451
+ }
452
+ }
453
+ }
454
+ }
455
+ fmt.Println()
456
+ return true, true
405
457
 
406
458
  case "/clear":
407
459
  agent, _ := agentManager.GetCurrentAgent()
package/cmd/model.go ADDED
@@ -0,0 +1,159 @@
1
+ package cmd
2
+
3
+ import (
4
+ "fmt"
5
+ "strconv"
6
+
7
+ "github.com/ddhanush1/dcode/internal/config"
8
+ "github.com/spf13/cobra"
9
+ )
10
+
11
+ var modelCmd = &cobra.Command{
12
+ Use: "model [model-name]",
13
+ Short: "Select AI model for current provider",
14
+ Long: `Select which AI model to use with the current provider.
15
+
16
+ If no model name is provided, shows available models for current provider.
17
+
18
+ Examples:
19
+ dcode model # List available models
20
+ dcode model gpt-4 # Use GPT-4
21
+ dcode model gpt-3.5-turbo # Use GPT-3.5 Turbo`,
22
+ RunE: selectModel,
23
+ }
24
+
25
+ func init() {
26
+ rootCmd.AddCommand(modelCmd)
27
+ }
28
+
29
+ // Available models for each provider
30
+ var providerModels = map[string][]string{
31
+ "gemini": {
32
+ "gemini-2.5-flash",
33
+ "gemini-2.0-flash-exp",
34
+ "gemini-1.5-pro",
35
+ "gemini-1.5-flash",
36
+ "gemini-pro",
37
+ },
38
+ "openai": {
39
+ "gpt-4",
40
+ "gpt-4-turbo",
41
+ "gpt-4o",
42
+ "gpt-4o-mini",
43
+ "gpt-3.5-turbo",
44
+ "o1-preview",
45
+ "o1-mini",
46
+ },
47
+ "copilot": {
48
+ "gpt-4",
49
+ "gpt-4-turbo",
50
+ "gpt-4o",
51
+ "gpt-4o-mini",
52
+ "gpt-3.5-turbo",
53
+ "o1-preview",
54
+ "o1-mini",
55
+ "claude-3.5-sonnet",
56
+ },
57
+ "claude": {
58
+ "claude-3-5-sonnet-20241022",
59
+ "claude-3-5-haiku-20241022",
60
+ "claude-3-opus-20240229",
61
+ "claude-3-sonnet-20240229",
62
+ "claude-3-haiku-20240307",
63
+ },
64
+ }
65
+
66
+ func selectModel(cmd *cobra.Command, args []string) error {
67
+ // Load config
68
+ cfg, err := config.LoadConfig()
69
+ if err != nil {
70
+ return fmt.Errorf("failed to load config: %w", err)
71
+ }
72
+
73
+ provider := cfg.Model.Provider
74
+ if provider == "" {
75
+ return fmt.Errorf("no provider set. Use 'dcode switch <provider>' first")
76
+ }
77
+
78
+ availableModels, ok := providerModels[provider]
79
+ if !ok {
80
+ return fmt.Errorf("unknown provider: %s", provider)
81
+ }
82
+
83
+ // If model name provided, set it directly
84
+ if len(args) > 0 {
85
+ modelName := args[0]
86
+
87
+ // Validate model
88
+ valid := false
89
+ for _, m := range availableModels {
90
+ if m == modelName {
91
+ valid = true
92
+ break
93
+ }
94
+ }
95
+
96
+ if !valid {
97
+ fmt.Printf("āš ļø Warning: '%s' is not in the list of known models\n", modelName)
98
+ fmt.Printf("Setting it anyway... (custom models are supported)\n\n")
99
+ }
100
+
101
+ cfg.Model.Model = modelName
102
+ if err := config.SaveConfig(cfg); err != nil {
103
+ return fmt.Errorf("failed to save config: %w", err)
104
+ }
105
+
106
+ fmt.Printf("āœ… Model set to: %s\n", modelName)
107
+ fmt.Printf(" Provider: %s\n", provider)
108
+ return nil
109
+ }
110
+
111
+ // Interactive selection
112
+ fmt.Printf("\nšŸ¤– Available models for %s:\n\n", provider)
113
+ for i, model := range availableModels {
114
+ current := ""
115
+ if model == cfg.Model.Model {
116
+ current = " (current)"
117
+ }
118
+ fmt.Printf(" %d. %s%s\n", i+1, model, current)
119
+ }
120
+
121
+ fmt.Printf("\n 0. Enter custom model name\n")
122
+ fmt.Print("\nSelect model (0-" + strconv.Itoa(len(availableModels)) + "): ")
123
+
124
+ var choice int
125
+ fmt.Scanf("%d", &choice)
126
+
127
+ if choice == 0 {
128
+ // Custom model
129
+ fmt.Print("Enter custom model name: ")
130
+ var customModel string
131
+ fmt.Scanln(&customModel)
132
+
133
+ if customModel != "" {
134
+ cfg.Model.Model = customModel
135
+ if err := config.SaveConfig(cfg); err != nil {
136
+ return fmt.Errorf("failed to save config: %w", err)
137
+ }
138
+ fmt.Printf("\nāœ… Model set to: %s\n", customModel)
139
+ }
140
+ return nil
141
+ }
142
+
143
+ if choice < 1 || choice > len(availableModels) {
144
+ return fmt.Errorf("invalid choice: %d", choice)
145
+ }
146
+
147
+ selectedModel := availableModels[choice-1]
148
+ cfg.Model.Model = selectedModel
149
+
150
+ if err := config.SaveConfig(cfg); err != nil {
151
+ return fmt.Errorf("failed to save config: %w", err)
152
+ }
153
+
154
+ fmt.Printf("\nāœ… Model set to: %s\n", selectedModel)
155
+ fmt.Printf(" Provider: %s\n", provider)
156
+ fmt.Println("\nYou can now run: dcode")
157
+
158
+ return nil
159
+ }
package/cmd/switch.go CHANGED
@@ -86,24 +86,16 @@ func switchProvider(cmd *cobra.Command, args []string) error {
86
86
  cfg.Auth.Provider = provider
87
87
  }
88
88
 
89
- // Set default models
89
+ // Set default models (ALWAYS update model when switching provider)
90
90
  switch provider {
91
91
  case "gemini":
92
- if cfg.Model.Model == "" {
93
- cfg.Model.Model = "gemini-2.0-flash-exp"
94
- }
92
+ cfg.Model.Model = "gemini-2.5-flash"
95
93
  case "openai":
96
- if cfg.Model.Model == "" {
97
- cfg.Model.Model = "gpt-4"
98
- }
94
+ cfg.Model.Model = "gpt-4"
99
95
  case "claude":
100
- if cfg.Model.Model == "" {
101
- cfg.Model.Model = "claude-3-5-sonnet-20241022"
102
- }
96
+ cfg.Model.Model = "claude-3-5-sonnet-20241022"
103
97
  case "copilot":
104
- if cfg.Model.Model == "" {
105
- cfg.Model.Model = "gpt-4"
106
- }
98
+ cfg.Model.Model = "gpt-4"
107
99
  }
108
100
 
109
101
  // Save config
@@ -209,38 +209,89 @@ func GetConfigDir() (string, error) {
209
209
 
210
210
  // LoadConfig loads configuration from file and environment
211
211
  func LoadConfig() (*Config, error) {
212
- cfg := DefaultConfig()
213
-
214
- // Check environment for provider override first
215
- if provider := os.Getenv("AI_PROVIDER"); provider != "" {
216
- cfg.Model.Provider = provider
217
- cfg.Auth.Provider = provider
218
- }
219
-
220
212
  // Load from settings.toml if it exists
221
213
  configDir, err := GetConfigDir()
222
214
  if err != nil {
223
215
  return nil, err
224
216
  }
225
217
 
218
+ homeDir, _ := os.UserHomeDir()
226
219
  settingsPath := filepath.Join(configDir, "settings.toml")
220
+ var cfg *Config
221
+
227
222
  if _, err := os.Stat(settingsPath); err == nil {
223
+ // File exists - load it WITHOUT defaults to avoid env-based auto-detection
224
+ cfg = &Config{
225
+ // Set ONLY structural defaults, no provider detection
226
+ Agent: AgentConfig{
227
+ DefaultAgent: "generalist",
228
+ EnabledAgents: []string{"generalist"},
229
+ AgentDirectory: filepath.Join(homeDir, ".dcode", "agents"),
230
+ MaxTurns: 50,
231
+ EnableSubAgents: true,
232
+ },
233
+ Tool: ToolConfig{
234
+ ToolDirectory: filepath.Join(homeDir, ".dcode", "tools"),
235
+ ShellTimeout: 300,
236
+ WebSearchEnabled: false,
237
+ ToolSettings: make(map[string]string),
238
+ },
239
+ Server: ServerConfig{
240
+ Host: "localhost",
241
+ Port: 8080,
242
+ A2APort: 41242,
243
+ },
244
+ Telemetry: TelemetryConfig{
245
+ SampleRate: 1.0,
246
+ EnableLogging: true,
247
+ LogLevel: "info",
248
+ },
249
+ }
250
+
228
251
  data, err := os.ReadFile(settingsPath)
229
252
  if err != nil {
230
253
  return nil, fmt.Errorf("failed to read settings file: %w", err)
231
254
  }
232
255
 
256
+ // This will override the structural defaults with saved values
233
257
  if err := toml.Unmarshal(data, cfg); err != nil {
234
258
  return nil, fmt.Errorf("failed to parse settings file: %w", err)
235
259
  }
260
+
261
+ // DEBUG: Print what was loaded
262
+ // fmt.Printf("DEBUG: Loaded provider=%s model=%s\n", cfg.Model.Provider, cfg.Model.Model)
263
+ } else {
264
+ // No file, use full defaults (with env detection)
265
+ cfg = DefaultConfig()
236
266
  }
237
267
 
238
- // Override with environment variables
239
- cfg.ApplyEnvironment()
268
+ // ONLY override if AI_PROVIDER is explicitly set in environment
269
+ if provider := os.Getenv("AI_PROVIDER"); provider != "" {
270
+ cfg.Model.Provider = provider
271
+ cfg.Auth.Provider = provider
272
+ }
273
+
274
+ // Apply other environment overrides
275
+ if val := os.Getenv("AI_MODEL"); val != "" {
276
+ cfg.Model.Model = val
277
+ }
240
278
 
241
- // Auto-detect model if using default OpenAI model with non-OpenAI provider
242
- if cfg.Model.Model == "gpt-4o-mini" && cfg.Model.Provider != "openai" {
243
- cfg.Model.Model = GetDefaultModelForProvider(cfg.Model.Provider)
279
+ // Set API keys for current provider
280
+ switch cfg.Auth.Provider {
281
+ case "openai":
282
+ if val := os.Getenv("OPENAI_API_KEY"); val != "" {
283
+ cfg.Auth.APIKey = val
284
+ }
285
+ case "gemini":
286
+ if val := os.Getenv("GEMINI_API_KEY"); val != "" {
287
+ cfg.Auth.APIKey = val
288
+ } else if val := os.Getenv("GOOGLE_API_KEY"); val != "" {
289
+ cfg.Auth.APIKey = val
290
+ }
291
+ case "claude":
292
+ if val := os.Getenv("ANTHROPIC_API_KEY"); val != "" {
293
+ cfg.Auth.APIKey = val
294
+ }
244
295
  }
245
296
 
246
297
  return cfg, nil
@@ -265,11 +316,13 @@ func (c *Config) ApplyEnvironment() {
265
316
  c.mu.Lock()
266
317
  defer c.mu.Unlock()
267
318
 
268
- // Auth
319
+ // ONLY override provider if AI_PROVIDER env var is explicitly set
269
320
  if val := os.Getenv("AI_PROVIDER"); val != "" {
270
321
  c.Auth.Provider = val
271
322
  c.Model.Provider = val
272
323
  }
324
+
325
+ // Set API keys based on current provider
273
326
  if val := os.Getenv("OPENAI_API_KEY"); val != "" && c.Auth.Provider == "openai" {
274
327
  c.Auth.APIKey = val
275
328
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcode-dev/dcode-cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "DCode - AI-powered coding assistant CLI",
5
5
  "keywords": [
6
6
  "ai",