Skip to content

Commit d504352

Browse files
fix: use apiKeys[provider] for model loading and API; prefer new format, deprecate apiKey
- Merge global and project apiKeys so keys are not lost when merging configs - Resolve credentials from apiKeys.<provider> first; legacy apiKey fallback kept - Add gemini-2.0-flash for Timeweb; update README and setup hints Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent bc21152 commit d504352

6 files changed

Lines changed: 65 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## [1.0.31] - 2026-02-20
4+
5+
### 🐛 Исправления
6+
- **Загрузка моделей по ключу провайдера** — модели и запросы к API используют ключ из `apiKeys.<provider>` (новый формат); ключи глобального и проектного конфига объединяются, чтобы не теряться при слиянии
7+
- Рекомендуется использовать только `apiKeys.gptunnel`, `apiKeys.timeweb` и т.д.; старый `apiKey` оставлен для обратной совместимости
8+
9+
### ✨ Новые возможности
10+
- Модель **gemini-2.0-flash** для провайдера Timeweb
11+
12+
### 🔧 Улучшения
13+
- В подсказке `smart-commit setup` приоритет у `apiKeys.<provider>`, старый формат помечен как legacy
14+
- README обновлён: примеры с apiKeys.gptunnel, baseUrls.timeweb для Timeweb
15+
316
## [1.0.18] - 2025-12-02
417

518
### 🐛 Исправления

README.md

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@ Global AI-powered tool for generating meaningful commit messages and running sma
1010

1111
## ⚠️ Important Configuration Update
1212

13-
**Version 1.0.13** introduces support for multiple API keys for different providers and project-specific settings.
13+
Use **`apiKeys.<provider>`** for API keys. Each provider has its own key; model loading and API calls use the key for the current `defaultProvider`.
1414

15-
- ⚠️ **`apiKey` is deprecated** — use `apiKeys` to store keys for different providers
16-
-**New feature**: Store keys for all providers simultaneously (`apiKeys.openai`, `apiKeys.timeweb`, etc.)
17-
-**Project settings**: Each project can have its own `apiKey`, `defaultProvider`, and `defaultModel`
18-
-**New provider**: Timeweb AI support added
15+
-**Recommended**: `apiKeys.gptunnel`, `apiKeys.timeweb`, `apiKeys.openai`, etc.
16+
- ⚠️ **Legacy**: `apiKey` (gptunnel only) is still supported but deprecated.
17+
-**Project settings**: Each project can have its own `apiKey`, `defaultProvider`, and `defaultModel`.
1918

2019
```bash
21-
# Old way (still works, but deprecated)
22-
smart-commit config --global --set apiKey=YOUR_KEY
23-
24-
# New way (recommended)
20+
# Recommended (per-provider keys)
21+
smart-commit config --global --set apiKeys.gptunnel=YOUR_GPTUNNEL_KEY
22+
smart-commit config --global --set apiKeys.timeweb=YOUR_TIMEWEB_KEY
2523
smart-commit config --global --set apiKeys.openai=sk-...
26-
smart-commit config --global --set apiKeys.timeweb=tw-...
27-
smart-commit config --global --set apiKeys.anthropic=sk-ant-...
24+
25+
# Set default provider and model
26+
smart-commit config --global --set defaultProvider=timeweb
27+
smart-commit config --global --set defaultModel=gemini-2.0-flash
2828
```
2929

3030
## 🔗 Links
@@ -108,13 +108,19 @@ Continue? [y/N]
108108
All settings can be stored globally (`~/.smart-commit/config.json`) or per-project (`.smart-commit.json`).
109109

110110
```bash
111-
# Set API keys for different providers (recommended)
112-
smart-commit config --global --set apiKeys.openai=sk-...
111+
# Set API keys per provider (recommended)
112+
smart-commit config --global --set apiKeys.gptunnel=shds-...
113113
smart-commit config --global --set apiKeys.timeweb=tw-...
114-
smart-commit config --global --set apiKeys.anthropic=sk-ant-...
114+
smart-commit config --global --set apiKeys.openai=sk-...
115+
116+
# Timeweb: also set base URL for your agent (required to avoid 404)
117+
smart-commit config --global --set baseUrls.timeweb=https://agent.timeweb.cloud/api/v1/cloud-ai/agents/YOUR_AGENT_ID/v1
118+
119+
# Set default provider and model
120+
smart-commit config --global --set defaultProvider=timeweb
121+
smart-commit config --global --set defaultModel=gemini-2.0-flash
115122

116-
# Set project-specific settings (overrides global)
117-
smart-commit config --set apiKey=project-key
123+
# Project-specific overrides
118124
smart-commit config --set defaultProvider=timeweb
119125
smart-commit config --set defaultModel=gpt-4o-mini
120126

@@ -177,5 +183,4 @@ Smart Commit is released under the [MIT License](LICENSE).
177183

178184
---
179185

180-
Made with ❤️ by [Eugene (prod-broke-again)](https://github.com/prod-broke-again)
181-
Version: 1.0.14
186+
Made with ❤️ by [Eugene (prod-broke-again)](https://github.com/prod-broke-again)

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli/SmartCommitCli.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -504,11 +504,11 @@ export class SmartCommitCli {
504504
console.log();
505505

506506
// In a real implementation, you might use readline for interactive input
507-
console.log(chalk.cyan('Run the following command to set your API key:'));
508-
console.log(chalk.green('smart-commit config --global --set apiKey=YOUR_API_KEY'));
509-
console.log(chalk.green(' or for specific provider:'));
510-
console.log(chalk.green('smart-commit config --global --set apiKeys.openai=YOUR_OPENAI_KEY'));
507+
console.log(chalk.cyan('Run the following command to set your API key (prefer apiKeys.<provider>):'));
508+
console.log(chalk.green('smart-commit config --global --set apiKeys.gptunnel=YOUR_GPTUNNEL_KEY'));
511509
console.log(chalk.green('smart-commit config --global --set apiKeys.timeweb=YOUR_TIMEWEB_KEY'));
510+
console.log(chalk.green('smart-commit config --global --set apiKeys.openai=YOUR_OPENAI_KEY'));
511+
console.log(chalk.gray(' (legacy: apiKey=... for gptunnel only)'));
512512
console.log();
513513
} else {
514514
console.log(chalk.green('✓ API key is configured'));

src/domain/entities/AiModel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export class AiModel {
138138
public static readonly TIMEWEB_GPT_4O_MINI = AiModel.create('gpt-4o-mini', 'timeweb', 128000, 0.7, true);
139139
public static readonly TIMEWEB_GPT_3_5_TURBO = AiModel.create('gpt-3.5-turbo', 'timeweb', 16385, 0.7, true);
140140
public static readonly TIMEWEB_GEMINI_2_5_FLASH = AiModel.create('gemini-2.5-flash', 'timeweb', 1000000, 0.7, true);
141+
public static readonly TIMEWEB_GEMINI_2_FLASH = AiModel.create('gemini-2.0-flash', 'timeweb', 1000000, 0.7, true);
141142

142143
private static readonly DEFAULT_MODELS: Record<string, readonly AiModel[]> = Object.freeze({
143144
gptunnel: Object.freeze([
@@ -167,6 +168,7 @@ export class AiModel {
167168
AiModel.TIMEWEB_GPT_4O_MINI,
168169
AiModel.TIMEWEB_GPT_3_5_TURBO,
169170
AiModel.TIMEWEB_GEMINI_2_5_FLASH,
171+
AiModel.TIMEWEB_GEMINI_2_FLASH,
170172
]),
171173
});
172174

src/infrastructure/filesystem/ConfigFileManager.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,20 @@ export class ConfigFileManager implements IConfigurationManager {
7676
// Determine model: project config overrides global
7777
const model = projectConfig.defaultModel ?? globalConfig.defaultModel;
7878

79-
// Find API key with priority: project apiKey > global apiKeys[provider] > global apiKey (backward compatibility)
80-
let apiKey: string | null = null;
81-
82-
if (projectConfig.apiKey) {
83-
// Project-specific key takes highest priority
84-
apiKey = projectConfig.apiKey;
85-
} else if (globalConfig.apiKeys && globalConfig.apiKeys[provider]) {
86-
// Use key from apiKeys map for the specific provider
87-
apiKey = globalConfig.apiKeys[provider];
88-
} else if (globalConfig.apiKey) {
89-
// Fallback to old apiKey field for backward compatibility
79+
// Merged apiKeys: global + project (project overrides), so keys are never lost when merging configs
80+
const projectApiKeys = (projectConfig as unknown as Record<string, unknown>)['apiKeys'];
81+
const mergedApiKeys: Record<string, string> = {
82+
...(globalConfig.apiKeys || {}),
83+
...(projectApiKeys && typeof projectApiKeys === 'object' && !Array.isArray(projectApiKeys)
84+
? (projectApiKeys as Record<string, string>)
85+
: {}),
86+
};
87+
88+
// Resolve API key: project apiKey > apiKeys[provider] > deprecated global apiKey
89+
let apiKey: string | null =
90+
projectConfig.apiKey ?? mergedApiKeys[provider] ?? null;
91+
if (apiKey === null && globalConfig.apiKey) {
92+
// Deprecated: prefer apiKeys.<provider> (e.g. apiKeys.gptunnel)
9093
apiKey = globalConfig.apiKey;
9194
}
9295

@@ -103,14 +106,15 @@ export class ConfigFileManager implements IConfigurationManager {
103106
aiModel = AiModel.create(model, provider, 400000, 0.7);
104107
}
105108

106-
// Merge configs (project overrides global)
109+
// Merge configs (project overrides global); keep merged apiKeys so keys are never lost
107110
const merged: MergedConfig = {
108111
...globalConfig,
109112
...projectConfig,
110113
defaultProvider: provider,
111114
defaultModel: model,
112115
apiCredentials,
113116
aiModel,
117+
apiKeys: mergedApiKeys,
114118
};
115119

116120
return merged;

0 commit comments

Comments
 (0)