berget 2.2.6 → 2.2.8
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/.github/workflows/publish.yml +2 -2
- package/.github/workflows/test.yml +10 -4
- package/.husky/pre-commit +1 -0
- package/.prettierignore +15 -0
- package/.prettierrc +7 -3
- package/CONTRIBUTING.md +38 -0
- package/README.md +2 -148
- package/dist/index.js +10 -11
- package/dist/package.json +30 -2
- package/dist/src/agents/app.js +28 -0
- package/dist/src/agents/backend.js +25 -0
- package/dist/src/agents/devops.js +34 -0
- package/dist/src/agents/frontend.js +25 -0
- package/dist/src/agents/fullstack.js +25 -0
- package/dist/src/agents/index.js +61 -0
- package/dist/src/agents/quality.js +70 -0
- package/dist/src/agents/security.js +26 -0
- package/dist/src/agents/types.js +2 -0
- package/dist/src/client.js +97 -117
- package/dist/src/commands/api-keys.js +75 -90
- package/dist/src/commands/auth.js +7 -16
- package/dist/src/commands/autocomplete.js +1 -1
- package/dist/src/commands/billing.js +6 -17
- package/dist/src/commands/chat.js +68 -101
- package/dist/src/commands/clusters.js +9 -18
- package/dist/src/commands/code/__tests__/auth-sync.test.js +351 -0
- package/dist/src/commands/code/__tests__/fake-api-key-service.js +13 -0
- package/dist/src/commands/code/__tests__/fake-auth-service.js +47 -0
- package/dist/src/commands/code/__tests__/fake-command-runner.js +21 -34
- package/dist/src/commands/code/__tests__/fake-file-store.js +20 -33
- package/dist/src/commands/code/__tests__/fake-prompter.js +83 -57
- package/dist/src/commands/code/__tests__/setup-flow.test.js +359 -92
- package/dist/src/commands/code/adapters/clack-prompter.js +15 -22
- package/dist/src/commands/code/adapters/fs-file-store.js +26 -40
- package/dist/src/commands/code/adapters/spawn-command-runner.js +27 -37
- package/dist/src/commands/code/auth-sync.js +270 -0
- package/dist/src/commands/code/errors.js +12 -9
- package/dist/src/commands/code/ports/auth-services.js +2 -0
- package/dist/src/commands/code/setup.js +387 -281
- package/dist/src/commands/code.js +205 -332
- package/dist/src/commands/index.js +5 -5
- package/dist/src/commands/models.js +6 -17
- package/dist/src/commands/users.js +5 -16
- package/dist/src/constants/command-structure.js +104 -104
- package/dist/src/services/api-key-service.js +132 -157
- package/dist/src/services/auth-service.js +89 -342
- package/dist/src/services/browser-auth.js +268 -0
- package/dist/src/services/chat-service.js +371 -401
- package/dist/src/services/cluster-service.js +47 -62
- package/dist/src/services/collaborator-service.js +10 -25
- package/dist/src/services/flux-service.js +14 -29
- package/dist/src/services/helm-service.js +10 -25
- package/dist/src/services/kubectl-service.js +16 -33
- package/dist/src/utils/config-checker.js +3 -3
- package/dist/src/utils/config-loader.js +95 -95
- package/dist/src/utils/default-api-key.js +124 -134
- package/dist/src/utils/env-manager.js +55 -66
- package/dist/src/utils/error-handler.js +20 -21
- package/dist/src/utils/logger.js +72 -65
- package/dist/src/utils/markdown-renderer.js +27 -27
- package/dist/src/utils/opencode-validator.js +63 -68
- package/dist/src/utils/token-manager.js +74 -45
- package/dist/tests/commands/chat.test.js +16 -25
- package/dist/tests/commands/code.test.js +95 -104
- package/dist/tests/utils/config-loader.test.js +48 -48
- package/dist/tests/utils/env-manager.test.js +43 -52
- package/dist/tests/utils/opencode-validator.test.js +22 -21
- package/dist/vitest.config.js +1 -1
- package/eslint.config.mjs +67 -0
- package/index.ts +35 -42
- package/package.json +30 -2
- package/src/agents/app.ts +27 -0
- package/src/agents/backend.ts +24 -0
- package/src/agents/devops.ts +33 -0
- package/src/agents/frontend.ts +24 -0
- package/src/agents/fullstack.ts +24 -0
- package/src/agents/index.ts +73 -0
- package/src/agents/quality.ts +69 -0
- package/src/agents/security.ts +26 -0
- package/src/agents/types.ts +17 -0
- package/src/client.ts +118 -152
- package/src/commands/api-keys.ts +241 -333
- package/src/commands/auth.ts +22 -27
- package/src/commands/autocomplete.ts +9 -9
- package/src/commands/billing.ts +20 -24
- package/src/commands/chat.ts +248 -338
- package/src/commands/clusters.ts +27 -26
- package/src/commands/code/__tests__/auth-sync.test.ts +482 -0
- package/src/commands/code/__tests__/fake-api-key-service.ts +13 -0
- package/src/commands/code/__tests__/fake-auth-service.ts +50 -0
- package/src/commands/code/__tests__/fake-command-runner.ts +45 -42
- package/src/commands/code/__tests__/fake-file-store.ts +32 -23
- package/src/commands/code/__tests__/fake-prompter.ts +116 -77
- package/src/commands/code/__tests__/setup-flow.test.ts +624 -268
- package/src/commands/code/adapters/clack-prompter.ts +53 -39
- package/src/commands/code/adapters/fs-file-store.ts +32 -27
- package/src/commands/code/adapters/spawn-command-runner.ts +38 -29
- package/src/commands/code/auth-sync.ts +329 -0
- package/src/commands/code/errors.ts +18 -18
- package/src/commands/code/ports/auth-services.ts +14 -0
- package/src/commands/code/ports/command-runner.ts +8 -4
- package/src/commands/code/ports/file-store.ts +5 -4
- package/src/commands/code/ports/prompter.ts +24 -18
- package/src/commands/code/setup.ts +570 -340
- package/src/commands/code.ts +338 -539
- package/src/commands/index.ts +20 -19
- package/src/commands/models.ts +28 -32
- package/src/commands/users.ts +15 -21
- package/src/constants/command-structure.ts +134 -157
- package/src/services/api-key-service.ts +105 -122
- package/src/services/auth-service.ts +99 -345
- package/src/services/browser-auth.ts +296 -0
- package/src/services/chat-service.ts +265 -299
- package/src/services/cluster-service.ts +42 -45
- package/src/services/collaborator-service.ts +14 -19
- package/src/services/flux-service.ts +23 -25
- package/src/services/helm-service.ts +19 -21
- package/src/services/kubectl-service.ts +17 -19
- package/src/types/api.d.ts +1905 -1907
- package/src/types/json.d.ts +2 -2
- package/src/utils/config-checker.ts +10 -10
- package/src/utils/config-loader.ts +162 -178
- package/src/utils/default-api-key.ts +114 -125
- package/src/utils/env-manager.ts +53 -57
- package/src/utils/error-handler.ts +61 -56
- package/src/utils/logger.ts +79 -73
- package/src/utils/markdown-renderer.ts +31 -31
- package/src/utils/opencode-validator.ts +85 -89
- package/src/utils/token-manager.ts +108 -87
- package/templates/agents/app.md +1 -0
- package/templates/agents/backend.md +1 -0
- package/templates/agents/devops.md +2 -0
- package/templates/agents/frontend.md +1 -0
- package/templates/agents/fullstack.md +1 -0
- package/templates/agents/quality.md +45 -40
- package/templates/agents/security.md +1 -0
- package/tests/commands/chat.test.ts +53 -62
- package/tests/commands/code.test.ts +265 -310
- package/tests/utils/config-loader.test.ts +189 -188
- package/tests/utils/env-manager.test.ts +110 -113
- package/tests/utils/opencode-validator.test.ts +52 -56
- package/tsconfig.json +4 -3
- package/vitest.config.ts +3 -3
- package/AGENTS.md +0 -374
- package/TODO.md +0 -19
|
@@ -1,83 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
12
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
13
|
-
var m = o[Symbol.asyncIterator], i;
|
|
14
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
15
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
16
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
17
|
-
};
|
|
18
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
4
|
};
|
|
21
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
6
|
exports.registerChatCommands = void 0;
|
|
23
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
24
|
-
const
|
|
8
|
+
const node_readline_1 = __importDefault(require("node:readline"));
|
|
25
9
|
const command_structure_1 = require("../constants/command-structure");
|
|
26
|
-
const chat_service_1 = require("../services/chat-service");
|
|
27
10
|
const api_key_service_1 = require("../services/api-key-service");
|
|
28
11
|
const auth_service_1 = require("../services/auth-service");
|
|
29
|
-
const
|
|
12
|
+
const chat_service_1 = require("../services/chat-service");
|
|
30
13
|
const default_api_key_1 = require("../utils/default-api-key");
|
|
14
|
+
const error_handler_1 = require("../utils/error-handler");
|
|
31
15
|
const markdown_renderer_1 = require("../utils/markdown-renderer");
|
|
32
|
-
/**
|
|
33
|
-
* Helper function to get user confirmation
|
|
34
|
-
*/
|
|
35
|
-
function confirm(question) {
|
|
36
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
const rl = readline_1.default.createInterface({
|
|
38
|
-
input: process.stdin,
|
|
39
|
-
output: process.stdout,
|
|
40
|
-
});
|
|
41
|
-
return new Promise((resolve) => {
|
|
42
|
-
rl.question(question, (answer) => {
|
|
43
|
-
rl.close();
|
|
44
|
-
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
16
|
/**
|
|
50
17
|
* Register chat commands
|
|
51
18
|
*/
|
|
52
19
|
function registerChatCommands(program) {
|
|
53
|
-
const chat = program
|
|
54
|
-
.command(command_structure_1.COMMAND_GROUPS.CHAT)
|
|
55
|
-
.description('Interact with AI chat models');
|
|
20
|
+
const chat = program.command(command_structure_1.COMMAND_GROUPS.CHAT).description('Interact with AI chat models');
|
|
56
21
|
chat
|
|
57
22
|
.command(command_structure_1.SUBCOMMANDS.CHAT.RUN)
|
|
58
23
|
.description('Run a chat session with a specified model')
|
|
59
24
|
.argument('[message]', 'Message to send directly (skips interactive mode)')
|
|
60
25
|
.option('-m, --model <model>', 'Model to use (default: glm-4.7)')
|
|
61
|
-
.option('-t, --temperature <temp>', 'Temperature (0-1)', parseFloat)
|
|
62
|
-
.option('--max-tokens <tokens>', 'Maximum tokens to generate', parseInt)
|
|
26
|
+
.option('-t, --temperature <temp>', 'Temperature (0-1)', Number.parseFloat)
|
|
27
|
+
.option('--max-tokens <tokens>', 'Maximum tokens to generate', Number.parseInt)
|
|
63
28
|
.option('-k, --api-key <key>', 'API key to use for this chat session')
|
|
64
29
|
.option('--api-key-id <id>', 'ID of the API key to use from your saved keys')
|
|
65
30
|
.option('--no-stream', 'Disable streaming (streaming is enabled by default)')
|
|
66
|
-
.action((message, options) =>
|
|
67
|
-
var _a, e_1, _b, _c;
|
|
31
|
+
.action(async (message, options) => {
|
|
68
32
|
try {
|
|
69
33
|
const chatService = chat_service_1.ChatService.getInstance();
|
|
70
34
|
// Check if we have an API key or need to get one
|
|
71
35
|
let apiKey = options.apiKey;
|
|
72
36
|
let apiKeyId = options.apiKeyId;
|
|
73
37
|
// Check for environment variable first
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
38
|
+
const environmentApiKey = process.env.BERGET_API_KEY;
|
|
39
|
+
if (environmentApiKey) {
|
|
76
40
|
console.log(chalk_1.default.dim(`Using API key from BERGET_API_KEY environment variable`));
|
|
77
|
-
apiKey =
|
|
41
|
+
apiKey = environmentApiKey;
|
|
78
42
|
// Debug the API key (first few characters only)
|
|
79
43
|
if (process.argv.includes('--debug')) {
|
|
80
|
-
console.log(chalk_1.default.yellow(`DEBUG: API key from env starts with: ${
|
|
44
|
+
console.log(chalk_1.default.yellow(`DEBUG: API key from env starts with: ${environmentApiKey.slice(0, 4)}...`));
|
|
81
45
|
}
|
|
82
46
|
}
|
|
83
47
|
// If API key is already provided via command line, use it
|
|
@@ -105,7 +69,7 @@ function registerChatCommands(program) {
|
|
|
105
69
|
// No default API key, prompt the user to create one
|
|
106
70
|
console.log(chalk_1.default.yellow('No default API key set.'));
|
|
107
71
|
// Try to prompt for a default API key
|
|
108
|
-
apiKey =
|
|
72
|
+
apiKey = await defaultApiKeyManager.promptForDefaultApiKey();
|
|
109
73
|
if (!apiKey) {
|
|
110
74
|
console.log(chalk_1.default.red('Error: An API key is required to use the chat command.'));
|
|
111
75
|
console.log(chalk_1.default.yellow('You can:'));
|
|
@@ -127,16 +91,13 @@ function registerChatCommands(program) {
|
|
|
127
91
|
if (!apiKey && apiKeyId) {
|
|
128
92
|
try {
|
|
129
93
|
const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
|
|
130
|
-
const keys =
|
|
94
|
+
const keys = await apiKeyService.list();
|
|
131
95
|
const selectedKey = keys.find((key) => key.id.toString() === options.apiKeyId);
|
|
132
|
-
if (
|
|
133
|
-
console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
96
|
+
if (selectedKey) {
|
|
136
97
|
console.log(chalk_1.default.dim(`Using API key: ${selectedKey.name}`));
|
|
137
98
|
// We need to rotate the key to get the actual key value
|
|
138
|
-
if (
|
|
139
|
-
const rotatedKey =
|
|
99
|
+
if (await confirm(chalk_1.default.yellow(`To use API key "${selectedKey.name}", it needs to be rotated. This will invalidate the current key. Continue? (y/n)`))) {
|
|
100
|
+
const rotatedKey = await apiKeyService.rotate(options.apiKeyId);
|
|
140
101
|
apiKey = rotatedKey.key;
|
|
141
102
|
console.log(chalk_1.default.green(`API key "${selectedKey.name}" rotated successfully.`));
|
|
142
103
|
}
|
|
@@ -144,6 +105,9 @@ function registerChatCommands(program) {
|
|
|
144
105
|
console.log(chalk_1.default.yellow('Using default authentication instead.'));
|
|
145
106
|
}
|
|
146
107
|
}
|
|
108
|
+
else {
|
|
109
|
+
console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
|
|
110
|
+
}
|
|
147
111
|
}
|
|
148
112
|
catch (error) {
|
|
149
113
|
// Check if this is an authentication error
|
|
@@ -166,7 +130,7 @@ function registerChatCommands(program) {
|
|
|
166
130
|
try {
|
|
167
131
|
auth_service_1.AuthService.getInstance();
|
|
168
132
|
}
|
|
169
|
-
catch
|
|
133
|
+
catch {
|
|
170
134
|
console.log(chalk_1.default.red('Error: Authentication required for chat'));
|
|
171
135
|
console.log(chalk_1.default.yellow('Please either:'));
|
|
172
136
|
console.log(chalk_1.default.yellow('1. Log in with `berget auth login`'));
|
|
@@ -181,8 +145,8 @@ function registerChatCommands(program) {
|
|
|
181
145
|
// Add system message if provided
|
|
182
146
|
if (options.system) {
|
|
183
147
|
messages.push({
|
|
184
|
-
role: 'system',
|
|
185
148
|
content: options.system,
|
|
149
|
+
role: 'system',
|
|
186
150
|
});
|
|
187
151
|
}
|
|
188
152
|
// Check if input is being piped in
|
|
@@ -191,20 +155,8 @@ function registerChatCommands(program) {
|
|
|
191
155
|
if (!process.stdin.isTTY) {
|
|
192
156
|
// Read from stdin (piped input)
|
|
193
157
|
const chunks = [];
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
_c = _f.value;
|
|
197
|
-
_d = false;
|
|
198
|
-
const chunk = _c;
|
|
199
|
-
chunks.push(chunk);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
203
|
-
finally {
|
|
204
|
-
try {
|
|
205
|
-
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
206
|
-
}
|
|
207
|
-
finally { if (e_1) throw e_1.error; }
|
|
158
|
+
for await (const chunk of process.stdin) {
|
|
159
|
+
chunks.push(chunk);
|
|
208
160
|
}
|
|
209
161
|
stdinContent = Buffer.concat(chunks).toString('utf8').trim();
|
|
210
162
|
}
|
|
@@ -219,17 +171,17 @@ function registerChatCommands(program) {
|
|
|
219
171
|
if (inputMessage) {
|
|
220
172
|
// Add user message
|
|
221
173
|
messages.push({
|
|
222
|
-
role: 'user',
|
|
223
174
|
content: inputMessage,
|
|
175
|
+
role: 'user',
|
|
224
176
|
});
|
|
225
177
|
try {
|
|
226
178
|
// Call the API
|
|
227
179
|
const completionOptions = {
|
|
228
|
-
model: options.model || 'openai/gpt-oss',
|
|
229
|
-
messages: messages,
|
|
230
|
-
temperature: options.temperature !== undefined ? options.temperature : 0.7,
|
|
231
180
|
max_tokens: options.maxTokens || 4096,
|
|
181
|
+
messages: messages,
|
|
182
|
+
model: options.model || 'openai/gpt-oss',
|
|
232
183
|
stream: options.stream !== false,
|
|
184
|
+
temperature: options.temperature === undefined ? 0.7 : options.temperature,
|
|
233
185
|
};
|
|
234
186
|
// Only add apiKey if it actually exists
|
|
235
187
|
if (apiKey) {
|
|
@@ -260,7 +212,7 @@ function registerChatCommands(program) {
|
|
|
260
212
|
}
|
|
261
213
|
};
|
|
262
214
|
try {
|
|
263
|
-
|
|
215
|
+
await chatService.createCompletion(completionOptions);
|
|
264
216
|
}
|
|
265
217
|
catch (streamError) {
|
|
266
218
|
console.error(chalk_1.default.red('\nStreaming error:'), streamError);
|
|
@@ -268,7 +220,7 @@ function registerChatCommands(program) {
|
|
|
268
220
|
console.log(chalk_1.default.yellow('Falling back to non-streaming mode...'));
|
|
269
221
|
completionOptions.stream = false;
|
|
270
222
|
delete completionOptions.onChunk;
|
|
271
|
-
const response =
|
|
223
|
+
const response = await chatService.createCompletion(completionOptions);
|
|
272
224
|
if (response &&
|
|
273
225
|
response.choices &&
|
|
274
226
|
response.choices[0] &&
|
|
@@ -280,7 +232,7 @@ function registerChatCommands(program) {
|
|
|
280
232
|
console.log(); // Add newline at the end
|
|
281
233
|
return;
|
|
282
234
|
}
|
|
283
|
-
const response =
|
|
235
|
+
const response = await chatService.createCompletion(completionOptions);
|
|
284
236
|
// Check if response has the expected structure
|
|
285
237
|
if (!response ||
|
|
286
238
|
!response.choices ||
|
|
@@ -310,7 +262,7 @@ function registerChatCommands(program) {
|
|
|
310
262
|
}
|
|
311
263
|
}
|
|
312
264
|
// Set up readline interface for user input (only for interactive mode)
|
|
313
|
-
const rl =
|
|
265
|
+
const rl = node_readline_1.default.createInterface({
|
|
314
266
|
input: process.stdin,
|
|
315
267
|
output: process.stdout,
|
|
316
268
|
});
|
|
@@ -318,7 +270,7 @@ function registerChatCommands(program) {
|
|
|
318
270
|
console.log(chalk_1.default.cyan('----------------------------------------'));
|
|
319
271
|
// Start the conversation loop
|
|
320
272
|
const askQuestion = () => {
|
|
321
|
-
rl.question(chalk_1.default.green('You: '), (input) =>
|
|
273
|
+
rl.question(chalk_1.default.green('You: '), async (input) => {
|
|
322
274
|
// Check if user wants to exit
|
|
323
275
|
if (input.toLowerCase() === 'exit') {
|
|
324
276
|
console.log(chalk_1.default.cyan('Goodbye!'));
|
|
@@ -327,17 +279,17 @@ function registerChatCommands(program) {
|
|
|
327
279
|
}
|
|
328
280
|
// Add user message
|
|
329
281
|
messages.push({
|
|
330
|
-
role: 'user',
|
|
331
282
|
content: input,
|
|
283
|
+
role: 'user',
|
|
332
284
|
});
|
|
333
285
|
try {
|
|
334
286
|
// Call the API
|
|
335
287
|
const completionOptions = {
|
|
336
|
-
model: options.model || 'openai/gpt-oss',
|
|
337
|
-
messages: messages,
|
|
338
|
-
temperature: options.temperature !== undefined ? options.temperature : 0.7,
|
|
339
288
|
max_tokens: options.maxTokens || 4096,
|
|
289
|
+
messages: messages,
|
|
290
|
+
model: options.model || 'openai/gpt-oss',
|
|
340
291
|
stream: options.stream !== false,
|
|
292
|
+
temperature: options.temperature === undefined ? 0.7 : options.temperature,
|
|
341
293
|
};
|
|
342
294
|
// Only add apiKey if it actually exists
|
|
343
295
|
if (apiKey) {
|
|
@@ -369,7 +321,7 @@ function registerChatCommands(program) {
|
|
|
369
321
|
}
|
|
370
322
|
};
|
|
371
323
|
try {
|
|
372
|
-
|
|
324
|
+
await chatService.createCompletion(completionOptions);
|
|
373
325
|
}
|
|
374
326
|
catch (streamError) {
|
|
375
327
|
console.error(chalk_1.default.red('\nStreaming error:'), streamError);
|
|
@@ -377,7 +329,7 @@ function registerChatCommands(program) {
|
|
|
377
329
|
console.log(chalk_1.default.yellow('Falling back to non-streaming mode...'));
|
|
378
330
|
completionOptions.stream = false;
|
|
379
331
|
delete completionOptions.onChunk;
|
|
380
|
-
const response =
|
|
332
|
+
const response = await chatService.createCompletion(completionOptions);
|
|
381
333
|
if (response &&
|
|
382
334
|
response.choices &&
|
|
383
335
|
response.choices[0] &&
|
|
@@ -389,14 +341,14 @@ function registerChatCommands(program) {
|
|
|
389
341
|
console.log('\n');
|
|
390
342
|
// Add assistant response to messages
|
|
391
343
|
messages.push({
|
|
392
|
-
role: 'assistant',
|
|
393
344
|
content: assistantResponse,
|
|
345
|
+
role: 'assistant',
|
|
394
346
|
});
|
|
395
347
|
// Continue the conversation
|
|
396
348
|
askQuestion();
|
|
397
349
|
return;
|
|
398
350
|
}
|
|
399
|
-
const response =
|
|
351
|
+
const response = await chatService.createCompletion(completionOptions);
|
|
400
352
|
// Debug output
|
|
401
353
|
if (program.opts().debug) {
|
|
402
354
|
console.log(chalk_1.default.yellow('DEBUG: Full response:'));
|
|
@@ -415,8 +367,8 @@ function registerChatCommands(program) {
|
|
|
415
367
|
const assistantMessage = response.choices[0].message.content;
|
|
416
368
|
// Add to messages array
|
|
417
369
|
messages.push({
|
|
418
|
-
role: 'assistant',
|
|
419
370
|
content: assistantMessage,
|
|
371
|
+
role: 'assistant',
|
|
420
372
|
});
|
|
421
373
|
// Display the response
|
|
422
374
|
console.log(chalk_1.default.blue('Assistant: '));
|
|
@@ -439,7 +391,7 @@ function registerChatCommands(program) {
|
|
|
439
391
|
// Continue despite error
|
|
440
392
|
askQuestion();
|
|
441
393
|
}
|
|
442
|
-
})
|
|
394
|
+
});
|
|
443
395
|
};
|
|
444
396
|
// Start the conversation
|
|
445
397
|
askQuestion();
|
|
@@ -447,13 +399,13 @@ function registerChatCommands(program) {
|
|
|
447
399
|
catch (error) {
|
|
448
400
|
(0, error_handler_1.handleError)('Failed to create chat completion', error);
|
|
449
401
|
}
|
|
450
|
-
})
|
|
402
|
+
});
|
|
451
403
|
chat
|
|
452
404
|
.command(command_structure_1.SUBCOMMANDS.CHAT.LIST)
|
|
453
405
|
.description('List available chat models')
|
|
454
406
|
.option('-k, --api-key <key>', 'API key to use for this request')
|
|
455
407
|
.option('--api-key-id <id>', 'ID of the API key to use from your saved keys')
|
|
456
|
-
.action((options) =>
|
|
408
|
+
.action(async (options) => {
|
|
457
409
|
try {
|
|
458
410
|
// If API key ID is provided, fetch the actual key
|
|
459
411
|
let apiKey = options.apiKey;
|
|
@@ -470,16 +422,13 @@ function registerChatCommands(program) {
|
|
|
470
422
|
if (apiKeyId && !apiKey) {
|
|
471
423
|
try {
|
|
472
424
|
const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
|
|
473
|
-
const keys =
|
|
425
|
+
const keys = await apiKeyService.list();
|
|
474
426
|
const selectedKey = keys.find((key) => key.id.toString() === options.apiKeyId);
|
|
475
|
-
if (
|
|
476
|
-
console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
427
|
+
if (selectedKey) {
|
|
479
428
|
console.log(chalk_1.default.dim(`Using API key: ${selectedKey.name}`));
|
|
480
429
|
// We need to rotate the key to get the actual key value
|
|
481
|
-
if (
|
|
482
|
-
const rotatedKey =
|
|
430
|
+
if (await confirm(chalk_1.default.yellow(`To use API key "${selectedKey.name}", it needs to be rotated. This will invalidate the current key. Continue? (y/n)`))) {
|
|
431
|
+
const rotatedKey = await apiKeyService.rotate(options.apiKeyId);
|
|
483
432
|
apiKey = rotatedKey.key;
|
|
484
433
|
console.log(chalk_1.default.green(`API key "${selectedKey.name}" rotated successfully.`));
|
|
485
434
|
}
|
|
@@ -487,6 +436,9 @@ function registerChatCommands(program) {
|
|
|
487
436
|
console.log(chalk_1.default.yellow('Using default authentication instead.'));
|
|
488
437
|
}
|
|
489
438
|
}
|
|
439
|
+
else {
|
|
440
|
+
console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
|
|
441
|
+
}
|
|
490
442
|
}
|
|
491
443
|
catch (error) {
|
|
492
444
|
console.error(chalk_1.default.red('Error fetching API key:'));
|
|
@@ -495,7 +447,7 @@ function registerChatCommands(program) {
|
|
|
495
447
|
}
|
|
496
448
|
}
|
|
497
449
|
const chatService = chat_service_1.ChatService.getInstance();
|
|
498
|
-
const models =
|
|
450
|
+
const models = await chatService.listModels(apiKey);
|
|
499
451
|
// Debug output
|
|
500
452
|
if (program.opts().debug) {
|
|
501
453
|
console.log(chalk_1.default.yellow('DEBUG: Models response:'));
|
|
@@ -523,6 +475,21 @@ function registerChatCommands(program) {
|
|
|
523
475
|
catch (error) {
|
|
524
476
|
(0, error_handler_1.handleError)('Failed to list chat models', error);
|
|
525
477
|
}
|
|
526
|
-
})
|
|
478
|
+
});
|
|
527
479
|
}
|
|
528
480
|
exports.registerChatCommands = registerChatCommands;
|
|
481
|
+
/**
|
|
482
|
+
* Helper function to get user confirmation
|
|
483
|
+
*/
|
|
484
|
+
async function confirm(question) {
|
|
485
|
+
const rl = node_readline_1.default.createInterface({
|
|
486
|
+
input: process.stdin,
|
|
487
|
+
output: process.stdout,
|
|
488
|
+
});
|
|
489
|
+
return new Promise((resolve) => {
|
|
490
|
+
rl.question(question, (answer) => {
|
|
491
|
+
rl.close();
|
|
492
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.registerClusterCommands = void 0;
|
|
13
4
|
const cluster_service_1 = require("../services/cluster-service");
|
|
@@ -22,10 +13,10 @@ function registerClusterCommands(program) {
|
|
|
22
13
|
cluster
|
|
23
14
|
.command(cluster_service_1.ClusterService.COMMANDS.LIST)
|
|
24
15
|
.description('List all Berget clusters')
|
|
25
|
-
.action(() =>
|
|
16
|
+
.action(async () => {
|
|
26
17
|
try {
|
|
27
18
|
const clusterService = cluster_service_1.ClusterService.getInstance();
|
|
28
|
-
const clusters =
|
|
19
|
+
const clusters = await clusterService.list();
|
|
29
20
|
console.log('NAME STATUS NODES CREATED');
|
|
30
21
|
clusters.forEach((cluster) => {
|
|
31
22
|
console.log(`${cluster.name.padEnd(22)} ${cluster.status.padEnd(9)} ${String(cluster.nodes).padEnd(8)} ${cluster.created}`);
|
|
@@ -34,36 +25,36 @@ function registerClusterCommands(program) {
|
|
|
34
25
|
catch (error) {
|
|
35
26
|
(0, error_handler_1.handleError)('Failed to list clusters', error);
|
|
36
27
|
}
|
|
37
|
-
})
|
|
28
|
+
});
|
|
38
29
|
cluster
|
|
39
30
|
.command(cluster_service_1.ClusterService.COMMANDS.GET_USAGE)
|
|
40
31
|
.description('Get usage metrics for a specific cluster')
|
|
41
32
|
.argument('<clusterId>', 'Cluster ID')
|
|
42
|
-
.action((clusterId) =>
|
|
33
|
+
.action(async (clusterId) => {
|
|
43
34
|
try {
|
|
44
35
|
const clusterService = cluster_service_1.ClusterService.getInstance();
|
|
45
|
-
const usage =
|
|
36
|
+
const usage = await clusterService.getUsage(clusterId);
|
|
46
37
|
console.log('Cluster Usage:');
|
|
47
38
|
console.log(JSON.stringify(usage, null, 2));
|
|
48
39
|
}
|
|
49
40
|
catch (error) {
|
|
50
41
|
(0, error_handler_1.handleError)('Failed to get cluster usage', error);
|
|
51
42
|
}
|
|
52
|
-
})
|
|
43
|
+
});
|
|
53
44
|
cluster
|
|
54
45
|
.command(cluster_service_1.ClusterService.COMMANDS.DESCRIBE)
|
|
55
46
|
.description('Get detailed information about a cluster')
|
|
56
47
|
.argument('<clusterId>', 'Cluster ID')
|
|
57
|
-
.action((clusterId) =>
|
|
48
|
+
.action(async (clusterId) => {
|
|
58
49
|
try {
|
|
59
50
|
const clusterService = cluster_service_1.ClusterService.getInstance();
|
|
60
|
-
const clusterInfo =
|
|
51
|
+
const clusterInfo = await clusterService.describe(clusterId);
|
|
61
52
|
console.log('Cluster Details:');
|
|
62
53
|
console.log(JSON.stringify(clusterInfo, null, 2));
|
|
63
54
|
}
|
|
64
55
|
catch (error) {
|
|
65
56
|
(0, error_handler_1.handleError)('Failed to describe cluster', error);
|
|
66
57
|
}
|
|
67
|
-
})
|
|
58
|
+
});
|
|
68
59
|
}
|
|
69
60
|
exports.registerClusterCommands = registerClusterCommands;
|