berget 1.1.0 → 1.2.0

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.
@@ -22,6 +22,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
25
34
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
36
  };
@@ -31,6 +40,8 @@ const fs = __importStar(require("fs"));
31
40
  const path = __importStar(require("path"));
32
41
  const os = __importStar(require("os"));
33
42
  const chalk_1 = __importDefault(require("chalk"));
43
+ const api_key_service_1 = require("../services/api-key-service");
44
+ const readline_1 = __importDefault(require("readline"));
34
45
  /**
35
46
  * Manages the default API key for chat commands
36
47
  */
@@ -62,7 +73,9 @@ class DefaultApiKeyManager {
62
73
  }
63
74
  }
64
75
  catch (error) {
65
- console.error(chalk_1.default.dim('Failed to load default API key configuration'));
76
+ if (process.argv.includes('--debug')) {
77
+ console.error(chalk_1.default.dim('Failed to load default API key configuration'));
78
+ }
66
79
  this.defaultApiKey = null;
67
80
  }
68
81
  }
@@ -84,20 +97,29 @@ class DefaultApiKeyManager {
84
97
  }
85
98
  }
86
99
  catch (error) {
87
- console.error(chalk_1.default.dim('Failed to save default API key configuration'));
100
+ if (process.argv.includes('--debug')) {
101
+ console.error(chalk_1.default.dim('Failed to save default API key configuration'));
102
+ }
88
103
  }
89
104
  }
90
105
  /**
91
106
  * Set the default API key
92
107
  */
93
- setDefaultApiKey(id, name, prefix) {
94
- this.defaultApiKey = { id, name, prefix };
108
+ setDefaultApiKey(id, name, prefix, key) {
109
+ this.defaultApiKey = { id, name, prefix, key };
95
110
  this.saveConfig();
96
111
  }
97
112
  /**
98
- * Get the default API key
113
+ * Get the default API key string
99
114
  */
100
115
  getDefaultApiKey() {
116
+ var _a;
117
+ return ((_a = this.defaultApiKey) === null || _a === void 0 ? void 0 : _a.key) || null;
118
+ }
119
+ /**
120
+ * Get the default API key data object
121
+ */
122
+ getDefaultApiKeyData() {
101
123
  return this.defaultApiKey;
102
124
  }
103
125
  /**
@@ -107,5 +129,109 @@ class DefaultApiKeyManager {
107
129
  this.defaultApiKey = null;
108
130
  this.saveConfig();
109
131
  }
132
+ /**
133
+ * Prompts the user to select a default API key if none is set
134
+ * @returns The selected API key or null if none was selected
135
+ */
136
+ promptForDefaultApiKey() {
137
+ return __awaiter(this, void 0, void 0, function* () {
138
+ try {
139
+ const isDebug = process.argv.includes('--debug');
140
+ if (isDebug) {
141
+ console.log(chalk_1.default.yellow('DEBUG: promptForDefaultApiKey called'));
142
+ }
143
+ // If we already have a default API key, return it
144
+ if (this.defaultApiKey) {
145
+ if (isDebug) {
146
+ console.log(chalk_1.default.yellow('DEBUG: Using existing default API key'));
147
+ }
148
+ return this.defaultApiKey.key;
149
+ }
150
+ if (isDebug) {
151
+ console.log(chalk_1.default.yellow('DEBUG: No default API key found, getting ApiKeyService'));
152
+ }
153
+ const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
154
+ // Get all API keys
155
+ let apiKeys;
156
+ try {
157
+ if (isDebug) {
158
+ console.log(chalk_1.default.yellow('DEBUG: Calling apiKeyService.list()'));
159
+ }
160
+ apiKeys = yield apiKeyService.list();
161
+ if (isDebug) {
162
+ console.log(chalk_1.default.yellow(`DEBUG: Got ${apiKeys ? apiKeys.length : 0} API keys`));
163
+ }
164
+ if (!apiKeys || apiKeys.length === 0) {
165
+ console.log(chalk_1.default.yellow('No API keys found. Create one with:'));
166
+ console.log(chalk_1.default.blue(' berget api-keys create --name "My Key"'));
167
+ return null;
168
+ }
169
+ }
170
+ catch (error) {
171
+ // Check if this is an authentication error
172
+ const errorMessage = error instanceof Error ? error.message : String(error);
173
+ const isAuthError = errorMessage.includes('Unauthorized') ||
174
+ errorMessage.includes('Authentication failed') ||
175
+ errorMessage.includes('AUTH_FAILED');
176
+ if (isAuthError) {
177
+ console.log(chalk_1.default.yellow('Authentication required. Please run `berget auth login` first.'));
178
+ }
179
+ else {
180
+ console.log(chalk_1.default.red('Error fetching API keys:'));
181
+ if (error instanceof Error) {
182
+ console.log(chalk_1.default.red(error.message));
183
+ if (isDebug) {
184
+ console.log(chalk_1.default.yellow(`DEBUG: API key list error: ${error.message}`));
185
+ console.log(chalk_1.default.yellow(`DEBUG: Stack: ${error.stack}`));
186
+ }
187
+ }
188
+ }
189
+ return null;
190
+ }
191
+ console.log(chalk_1.default.blue('Select an API key to use as default:'));
192
+ // Display available API keys
193
+ apiKeys.forEach((key, index) => {
194
+ console.log(` ${index + 1}. ${key.name} (${key.prefix}...)`);
195
+ });
196
+ // Create readline interface for user input
197
+ const rl = readline_1.default.createInterface({
198
+ input: process.stdin,
199
+ output: process.stdout
200
+ });
201
+ // Prompt for selection
202
+ const selection = yield new Promise((resolve) => {
203
+ rl.question('Enter number (or press Enter to cancel): ', (answer) => {
204
+ rl.close();
205
+ const num = parseInt(answer.trim(), 10);
206
+ if (isNaN(num) || num < 1 || num > apiKeys.length) {
207
+ resolve(-1); // Invalid selection
208
+ }
209
+ else {
210
+ resolve(num - 1); // Convert to zero-based index
211
+ }
212
+ });
213
+ });
214
+ if (selection === -1) {
215
+ console.log(chalk_1.default.yellow('No API key selected'));
216
+ return null;
217
+ }
218
+ const selectedKey = apiKeys[selection];
219
+ // Create a new API key with the selected name
220
+ const newKey = yield apiKeyService.create({
221
+ name: `CLI Default (copy of ${selectedKey.name})`,
222
+ description: 'Created automatically by the Berget CLI for default use'
223
+ });
224
+ // Save the new key as default
225
+ this.setDefaultApiKey(newKey.id.toString(), newKey.name, newKey.key.substring(0, 8), // Use first 8 chars as prefix
226
+ newKey.key);
227
+ console.log(chalk_1.default.green(`✓ Default API key set to: ${newKey.name}`));
228
+ return newKey.key;
229
+ }
230
+ catch (error) {
231
+ console.error(chalk_1.default.red('Failed to set default API key:'), error);
232
+ return null;
233
+ }
234
+ });
235
+ }
110
236
  }
111
237
  exports.DefaultApiKeyManager = DefaultApiKeyManager;
@@ -35,11 +35,11 @@ function handleError(message, error) {
35
35
  console.error(chalk_1.default.dim(`Details: ${error.message}`));
36
36
  }
37
37
  // Check for authentication errors
38
- if ((typeof error === 'string' && error.includes('Unauthorized')) ||
39
- (error && error.message && error.message.includes('Unauthorized')) ||
40
- (error && error.code && error.code === 401)) {
38
+ if ((typeof error === 'string' && (error.includes('Unauthorized') || error.includes('Authentication failed'))) ||
39
+ (error && error.message && (error.message.includes('Unauthorized') || error.message.includes('Authentication failed'))) ||
40
+ (error && error.code && (error.code === 401 || error.code === 'AUTH_FAILED'))) {
41
41
  console.error(chalk_1.default.yellow('\nYou need to be logged in to use this command.'));
42
- console.error(chalk_1.default.yellow('Run `berget login` to authenticate.'));
42
+ console.error(chalk_1.default.yellow('Run `berget auth login` to authenticate.'));
43
43
  }
44
44
  }
45
45
  exports.handleError = handleError;
package/index.ts CHANGED
@@ -3,6 +3,8 @@
3
3
  import { program } from 'commander'
4
4
  import { registerCommands } from './src/commands'
5
5
  import { checkBergetConfig } from './src/utils/config-checker'
6
+ import chalk from 'chalk'
7
+ import { version } from './package.json'
6
8
 
7
9
  // Set version and description
8
10
  program
@@ -17,7 +19,7 @@ program
17
19
  __/ |
18
20
  |___/ AI on European terms`
19
21
  )
20
- .version(process.env.npm_package_version || '0.0.1', '-v, --version')
22
+ .version(version, '-v, --version')
21
23
  .option('--local', 'Use local API endpoint (hidden)', false)
22
24
  .option('--debug', 'Enable debug output', false)
23
25
 
@@ -27,6 +29,55 @@ registerCommands(program)
27
29
  // Check for .bergetconfig if not running a command
28
30
  if (process.argv.length <= 2) {
29
31
  checkBergetConfig()
32
+
33
+ // Show helpful welcome message
34
+ console.log(chalk.blue('\nWelcome to the Berget CLI!'));
35
+ console.log(chalk.blue('Common commands:'));
36
+ console.log(chalk.blue(` ${chalk.bold('berget auth login')} - Log in to Berget`));
37
+ console.log(chalk.blue(` ${chalk.bold('berget models list')} - List available AI models`));
38
+ console.log(chalk.blue(` ${chalk.bold('berget chat run')} - Start a chat session`));
39
+ console.log(chalk.blue(` ${chalk.bold('berget api-keys list')} - List your API keys`));
40
+ console.log(chalk.blue(`\nRun ${chalk.bold('berget --help')} for a complete list of commands.`));
30
41
  }
31
42
 
43
+ // Add helpful suggestions for common command mistakes
44
+ const commonMistakes: Record<string, string> = {
45
+ 'login': 'auth login',
46
+ 'logout': 'auth logout',
47
+ 'whoami': 'auth whoami',
48
+ 'list-models': 'models list',
49
+ 'list-keys': 'api-keys list',
50
+ 'create-key': 'api-keys create',
51
+ 'list-clusters': 'clusters list',
52
+ 'usage': 'billing usage'
53
+ };
54
+
55
+ // Add error handler for unknown commands
56
+ program.on('command:*', (operands) => {
57
+ const unknownCommand = operands[0] as string;
58
+ console.error(chalk.red(`Error: unknown command '${unknownCommand}'`));
59
+
60
+ // Check if this is a known mistake and suggest the correct command
61
+ if (unknownCommand in commonMistakes) {
62
+ console.log(chalk.yellow(`Did you mean? ${chalk.bold(`berget ${commonMistakes[unknownCommand]}`)}`));
63
+ } else {
64
+ // Try to find similar commands
65
+ const availableCommands = program.commands.map(cmd => cmd.name());
66
+ const similarCommands = availableCommands.filter(cmd =>
67
+ cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
68
+ );
69
+
70
+ if (similarCommands.length > 0) {
71
+ console.log(chalk.yellow('Similar commands:'));
72
+ similarCommands.forEach(cmd => {
73
+ console.log(chalk.yellow(` ${chalk.bold(`berget ${cmd}`)}`));
74
+ });
75
+ }
76
+
77
+ console.log(chalk.blue('\nRun `berget --help` for a list of available commands.'));
78
+ }
79
+
80
+ process.exit(1);
81
+ });
82
+
32
83
  program.parse(process.argv)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "berget",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "berget": "dist/index.js"
@@ -29,6 +29,7 @@
29
29
  "fs-extra": "^11.3.0",
30
30
  "open": "^9.1.0",
31
31
  "openapi-fetch": "^0.9.1",
32
- "openapi-typescript": "^6.7.4"
32
+ "openapi-typescript": "^6.7.4",
33
+ "readline": "^1.3.0"
33
34
  }
34
35
  }
package/src/client.ts CHANGED
@@ -126,21 +126,38 @@ export const createAuthenticatedClient = () => {
126
126
  // If we get an auth error, try to refresh the token and retry
127
127
  if (result.error) {
128
128
  // Detect various forms of authentication errors
129
- const isAuthError =
129
+ let isAuthError = false;
130
+
131
+ try {
130
132
  // Standard 401 Unauthorized
131
- (typeof result.error === 'object' && result.error.status === 401) ||
133
+ if (typeof result.error === 'object' && result.error.status === 401) {
134
+ isAuthError = true;
135
+ }
132
136
  // OAuth specific errors
133
- (result.error.error &&
137
+ else if (result.error.error &&
134
138
  (result.error.error.code === 'invalid_token' ||
135
139
  result.error.error.code === 'token_expired' ||
136
140
  result.error.error.message === 'Invalid API key' ||
137
141
  result.error.error.message?.toLowerCase().includes('token') ||
138
- result.error.error.message?.toLowerCase().includes('unauthorized'))) ||
142
+ result.error.error.message?.toLowerCase().includes('unauthorized'))) {
143
+ isAuthError = true;
144
+ }
139
145
  // Message-based detection as fallback
140
- (typeof result.error === 'string' &&
146
+ else if (typeof result.error === 'string' &&
141
147
  (result.error.toLowerCase().includes('unauthorized') ||
142
148
  result.error.toLowerCase().includes('token') ||
143
- result.error.toLowerCase().includes('auth')))
149
+ result.error.toLowerCase().includes('auth'))) {
150
+ isAuthError = true;
151
+ }
152
+ } catch (parseError) {
153
+ // If we can't parse the error structure, do a simple string check
154
+ const errorStr = String(result.error);
155
+ if (errorStr.toLowerCase().includes('unauthorized') ||
156
+ errorStr.toLowerCase().includes('token') ||
157
+ errorStr.toLowerCase().includes('auth')) {
158
+ isAuthError = true;
159
+ }
160
+ }
144
161
 
145
162
  if (isAuthError && tokenManager.getRefreshToken()) {
146
163
  if (process.argv.includes('--debug')) {
@@ -50,10 +50,15 @@ export function registerApiKeyCommands(program: Command): void {
50
50
  ? chalk.green('● Active')
51
51
  : chalk.red('● Inactive')
52
52
 
53
+ // Format the prefix to ensure it's not too long
54
+ const prefixStr = key.prefix.length > 12
55
+ ? key.prefix.substring(0, 12) + '...'
56
+ : key.prefix
57
+
53
58
  console.log(
54
59
  String(key.id).padEnd(10) +
55
60
  key.name.padEnd(25) +
56
- key.prefix.padEnd(12) +
61
+ prefixStr.padEnd(15) +
57
62
  status.padEnd(12) +
58
63
  key.created.substring(0, 10).padEnd(12) +
59
64
  lastUsed
@@ -318,10 +323,15 @@ export function registerApiKeyCommands(program: Command): void {
318
323
 
319
324
  // Save the default API key
320
325
  const defaultApiKeyManager = DefaultApiKeyManager.getInstance()
326
+
327
+ // We need to rotate the key to get the actual key value
328
+ const rotatedKey = await apiKeyService.rotate(id)
329
+
321
330
  defaultApiKeyManager.setDefaultApiKey(
322
331
  id,
323
332
  selectedKey.name,
324
- selectedKey.prefix
333
+ selectedKey.prefix,
334
+ rotatedKey.key
325
335
  )
326
336
 
327
337
  console.log(chalk.green(`✓ API key "${selectedKey.name}" set as default for chat commands`))
@@ -339,9 +349,9 @@ export function registerApiKeyCommands(program: Command): void {
339
349
  .action(() => {
340
350
  try {
341
351
  const defaultApiKeyManager = DefaultApiKeyManager.getInstance()
342
- const defaultApiKey = defaultApiKeyManager.getDefaultApiKey()
352
+ const defaultApiKeyData = defaultApiKeyManager.getDefaultApiKeyData()
343
353
 
344
- if (!defaultApiKey) {
354
+ if (!defaultApiKeyData) {
345
355
  console.log(chalk.yellow('No default API key set'))
346
356
  console.log('')
347
357
  console.log('To set a default API key, run:')
@@ -351,9 +361,9 @@ export function registerApiKeyCommands(program: Command): void {
351
361
 
352
362
  console.log(chalk.bold('Default API key:'))
353
363
  console.log('')
354
- console.log(`${chalk.dim('ID:')} ${defaultApiKey.id}`)
355
- console.log(`${chalk.dim('Name:')} ${defaultApiKey.name}`)
356
- console.log(`${chalk.dim('Prefix:')} ${defaultApiKey.prefix}`)
364
+ console.log(`${chalk.dim('ID:')} ${defaultApiKeyData.id}`)
365
+ console.log(`${chalk.dim('Name:')} ${defaultApiKeyData.name}`)
366
+ console.log(`${chalk.dim('Prefix:')} ${defaultApiKeyData.prefix}`)
357
367
  console.log('')
358
368
  console.log(chalk.dim('This API key will be used by default when running chat commands'))
359
369
  console.log(chalk.dim('You can override it with --api-key or --api-key-id options'))
@@ -2,7 +2,7 @@ import { Command } from 'commander'
2
2
  import chalk from 'chalk'
3
3
  import readline from 'readline'
4
4
  import { COMMAND_GROUPS, SUBCOMMANDS } from '../constants/command-structure'
5
- import { ChatService, ChatMessage } from '../services/chat-service'
5
+ import { ChatService, ChatMessage, ChatCompletionOptions } from '../services/chat-service'
6
6
  import { ApiKeyService } from '../services/api-key-service'
7
7
  import { AuthService } from '../services/auth-service'
8
8
  import { handleError } from '../utils/error-handler'
@@ -36,7 +36,7 @@ export function registerChatCommands(program: Command): void {
36
36
  chat
37
37
  .command(SUBCOMMANDS.CHAT.RUN)
38
38
  .description('Run a chat session with a specified model')
39
- .argument('[model]', 'Model to use (default: berget-70b-instruct)')
39
+ .argument('[model]', 'Model to use (default: google/gemma-3-27b-it)')
40
40
  .option('-s, --system <message>', 'System message')
41
41
  .option('-t, --temperature <temp>', 'Temperature (0-1)', parseFloat)
42
42
  .option('-m, --max-tokens <tokens>', 'Maximum tokens to generate', parseInt)
@@ -52,17 +52,76 @@ export function registerChatCommands(program: Command): void {
52
52
  // Check if we have an API key or need to get one
53
53
  let apiKey = options.apiKey
54
54
  let apiKeyId = options.apiKeyId
55
+
56
+ // Check for environment variable first
57
+ const envApiKey = process.env.BERGET_API_KEY;
58
+ if (envApiKey) {
59
+ console.log(
60
+ chalk.dim(`Using API key from BERGET_API_KEY environment variable`)
61
+ )
62
+ apiKey = envApiKey;
63
+ }
64
+ // If no API key or API key ID provided and no env var, check for default API key
65
+ else if (!apiKey && !apiKeyId) {
66
+ try {
67
+ const defaultApiKeyManager = DefaultApiKeyManager.getInstance()
68
+ const defaultApiKeyData = defaultApiKeyManager.getDefaultApiKeyData()
69
+
70
+ if (defaultApiKeyData) {
71
+ apiKeyId = defaultApiKeyData.id
72
+ apiKey = defaultApiKeyData.key
73
+
74
+ if (apiKey) {
75
+ console.log(
76
+ chalk.dim(`Using default API key: ${defaultApiKeyData.name}`)
77
+ )
78
+ } else {
79
+ console.log(
80
+ chalk.yellow(`Default API key "${defaultApiKeyData.name}" exists but the key value is missing.`)
81
+ )
82
+ console.log(
83
+ chalk.yellow(`Try rotating the key with: berget api-keys rotate ${defaultApiKeyData.id}`)
84
+ )
85
+ }
86
+ } else {
87
+ // No default API key, prompt the user to create one
88
+ console.log(chalk.yellow('No default API key set.'))
55
89
 
56
- // If no API key or API key ID provided, check for default API key
57
- if (!apiKey && !apiKeyId) {
58
- const defaultApiKeyManager = DefaultApiKeyManager.getInstance()
59
- const defaultApiKey = defaultApiKeyManager.getDefaultApiKey()
90
+ // Try to prompt for a default API key
91
+ apiKey = await defaultApiKeyManager.promptForDefaultApiKey()
60
92
 
61
- if (defaultApiKey) {
62
- apiKeyId = defaultApiKey.id
63
- console.log(
64
- chalk.dim(`Using default API key: ${defaultApiKey.name}`)
65
- )
93
+ if (!apiKey) {
94
+ console.log(
95
+ chalk.red(
96
+ 'Error: An API key is required to use the chat command.'
97
+ )
98
+ )
99
+ console.log(chalk.yellow('You can:'))
100
+ console.log(
101
+ chalk.yellow(
102
+ '1. Create an API key with: berget api-keys create --name "My Key"'
103
+ )
104
+ )
105
+ console.log(
106
+ chalk.yellow(
107
+ '2. Set a default API key with: berget api-keys set-default <id>'
108
+ )
109
+ )
110
+ console.log(
111
+ chalk.yellow(
112
+ '3. Provide an API key with the --api-key option'
113
+ )
114
+ )
115
+ return
116
+ }
117
+ }
118
+ } catch (error) {
119
+ if (process.argv.includes('--debug')) {
120
+ console.log(
121
+ chalk.yellow('DEBUG: Error checking default API key:')
122
+ )
123
+ console.log(chalk.yellow(String(error)))
124
+ }
66
125
  }
67
126
  }
68
127
 
@@ -106,9 +165,19 @@ export function registerChatCommands(program: Command): void {
106
165
  }
107
166
  }
108
167
  } catch (error) {
109
- console.error(chalk.red('Error fetching API key:'))
110
- console.error(error)
111
- console.log(chalk.yellow('Using default authentication instead.'))
168
+ // Check if this is an authentication error
169
+ const errorMessage = error instanceof Error ? error.message : String(error);
170
+ const isAuthError = errorMessage.includes('Unauthorized') ||
171
+ errorMessage.includes('Authentication failed') ||
172
+ errorMessage.includes('AUTH_FAILED');
173
+
174
+ if (isAuthError) {
175
+ console.log(chalk.yellow('Authentication required. Please run `berget auth login` first.'));
176
+ } else {
177
+ console.error(chalk.red('Error fetching API key:'));
178
+ console.error(error);
179
+ }
180
+ console.log(chalk.yellow('Using default authentication instead.'));
112
181
  }
113
182
  }
114
183
 
@@ -171,14 +240,45 @@ export function registerChatCommands(program: Command): void {
171
240
 
172
241
  try {
173
242
  // Call the API
174
- const response = await chatService.createCompletion({
175
- model: options.args?.[0] || 'berget-70b-instruct',
243
+ console.log(chalk.yellow('DEBUG: Preparing completion options'))
244
+
245
+ const completionOptions: ChatCompletionOptions = {
246
+ model: options.args?.[0] || 'google/gemma-3-27b-it',
176
247
  messages: messages,
177
248
  temperature:
178
249
  options.temperature !== undefined ? options.temperature : 0.7,
179
250
  max_tokens: options.maxTokens || 4096,
180
- apiKey: apiKey,
181
- })
251
+ }
252
+
253
+ // Only add apiKey if it actually exists
254
+ if (apiKey) {
255
+ completionOptions.apiKey = apiKey
256
+ console.log(chalk.yellow('DEBUG: Using API key from command options or default'))
257
+ } else {
258
+ console.log(chalk.yellow('DEBUG: No API key available in chat command'))
259
+ // If we got this far with defaultApiKeyData but no apiKey, there's a problem
260
+ const defaultApiKeyManager = DefaultApiKeyManager.getInstance();
261
+ if (defaultApiKeyManager.getDefaultApiKeyData()) {
262
+ console.log(chalk.yellow('DEBUG: Default API key data exists but key is missing'))
263
+ }
264
+ }
265
+
266
+ // Debug output
267
+ console.log(chalk.yellow('DEBUG: Completion options:'))
268
+ console.log(chalk.yellow(JSON.stringify({
269
+ ...completionOptions,
270
+ apiKey: completionOptions.apiKey ? '***' : undefined,
271
+ messages: completionOptions.messages.map((m: any) => ({
272
+ role: m.role,
273
+ content: m.content.length > 50 ? m.content.substring(0, 50) + '...' : m.content
274
+ }))
275
+ }, null, 2)))
276
+
277
+ console.log(chalk.yellow('DEBUG: Calling chatService.createCompletion'))
278
+
279
+ const response = await chatService.createCompletion(
280
+ completionOptions
281
+ )
182
282
 
183
283
  // Debug output
184
284
  if (program.opts().debug) {
@@ -252,12 +352,12 @@ export function registerChatCommands(program: Command): void {
252
352
  // If no API key or API key ID provided, check for default API key
253
353
  if (!apiKey && !apiKeyId) {
254
354
  const defaultApiKeyManager = DefaultApiKeyManager.getInstance()
255
- const defaultApiKey = defaultApiKeyManager.getDefaultApiKey()
355
+ const defaultApiKeyData = defaultApiKeyManager.getDefaultApiKeyData()
256
356
 
257
- if (defaultApiKey) {
258
- apiKeyId = defaultApiKey.id
357
+ if (defaultApiKeyData) {
358
+ apiKeyId = defaultApiKeyData.id
259
359
  console.log(
260
- chalk.dim(`Using default API key: ${defaultApiKey.name}`)
360
+ chalk.dim(`Using default API key: ${defaultApiKeyData.name}`)
261
361
  )
262
362
  }
263
363
  }
@@ -33,10 +33,10 @@ export interface ApiKeyResponse {
33
33
  export class ApiKeyService {
34
34
  private static instance: ApiKeyService
35
35
  private client = createAuthenticatedClient()
36
-
36
+
37
37
  // Command group name for this service
38
38
  public static readonly COMMAND_GROUP = COMMAND_GROUPS.API_KEYS
39
-
39
+
40
40
  // Subcommands for this service
41
41
  public static readonly COMMANDS = SUBCOMMANDS.API_KEYS
42
42
 
@@ -56,18 +56,7 @@ export class ApiKeyService {
56
56
  public async list(): Promise<ApiKey[]> {
57
57
  try {
58
58
  const { data, error } = await this.client.GET('/v1/api-keys')
59
- if (error) {
60
- // Check if this is an authentication error
61
- const errorObj = typeof error === 'string' ? JSON.parse(error) : error;
62
- if (errorObj.status === 401) {
63
- throw new Error(JSON.stringify({
64
- error: "Authentication failed. Your session may have expired.",
65
- code: "AUTH_FAILED",
66
- details: "Please run 'berget login' to authenticate again."
67
- }))
68
- }
69
- throw new Error(JSON.stringify(error))
70
- }
59
+ if (error) throw error
71
60
  return data || []
72
61
  } catch (error) {
73
62
  handleError('Failed to list API keys', error)
@@ -82,7 +71,7 @@ export class ApiKeyService {
82
71
  public async create(options: CreateApiKeyOptions): Promise<ApiKeyResponse> {
83
72
  try {
84
73
  const { data, error } = await this.client.POST('/v1/api-keys', {
85
- body: options
74
+ body: options,
86
75
  })
87
76
  if (error) throw new Error(JSON.stringify(error))
88
77
  return data!
@@ -99,7 +88,7 @@ export class ApiKeyService {
99
88
  public async delete(id: string): Promise<boolean> {
100
89
  try {
101
90
  const { error } = await this.client.DELETE('/v1/api-keys/{id}', {
102
- params: { path: { id } }
91
+ params: { path: { id } },
103
92
  })
104
93
  if (error) throw new Error(JSON.stringify(error))
105
94
  return true
@@ -115,9 +104,12 @@ export class ApiKeyService {
115
104
  */
116
105
  public async rotate(id: string): Promise<ApiKeyResponse> {
117
106
  try {
118
- const { data, error } = await this.client.PUT('/v1/api-keys/{id}/rotate', {
119
- params: { path: { id } }
120
- })
107
+ const { data, error } = await this.client.PUT(
108
+ '/v1/api-keys/{id}/rotate',
109
+ {
110
+ params: { path: { id } },
111
+ }
112
+ )
121
113
  if (error) throw new Error(JSON.stringify(error))
122
114
  return data!
123
115
  } catch (error) {
@@ -133,7 +125,7 @@ export class ApiKeyService {
133
125
  public async describe(id: string): Promise<any> {
134
126
  try {
135
127
  const { data, error } = await this.client.GET('/v1/api-keys/{id}/usage', {
136
- params: { path: { id } }
128
+ params: { path: { id } },
137
129
  })
138
130
  if (error) throw new Error(JSON.stringify(error))
139
131
  return data