berget 1.0.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.
Files changed (44) hide show
  1. package/README.md +92 -0
  2. package/dist/index.js +49 -467
  3. package/dist/package.json +35 -0
  4. package/dist/src/client.js +210 -102
  5. package/dist/src/commands/api-keys.js +277 -0
  6. package/dist/src/commands/auth.js +65 -0
  7. package/dist/src/commands/autocomplete.js +24 -0
  8. package/dist/src/commands/billing.js +53 -0
  9. package/dist/src/commands/chat.js +342 -0
  10. package/dist/src/commands/clusters.js +69 -0
  11. package/dist/src/commands/index.js +25 -0
  12. package/dist/src/commands/models.js +69 -0
  13. package/dist/src/commands/users.js +43 -0
  14. package/dist/src/constants/command-structure.js +14 -0
  15. package/dist/src/services/api-key-service.js +6 -16
  16. package/dist/src/services/auth-service.js +49 -47
  17. package/dist/src/services/chat-service.js +300 -0
  18. package/dist/src/utils/config-checker.js +50 -0
  19. package/dist/src/utils/default-api-key.js +237 -0
  20. package/dist/src/utils/error-handler.js +4 -4
  21. package/dist/src/utils/token-manager.js +165 -0
  22. package/index.ts +56 -566
  23. package/package.json +8 -2
  24. package/src/client.ts +279 -80
  25. package/src/commands/api-keys.ts +374 -0
  26. package/src/commands/auth.ts +58 -0
  27. package/src/commands/autocomplete.ts +19 -0
  28. package/src/commands/billing.ts +41 -0
  29. package/src/commands/chat.ts +445 -0
  30. package/src/commands/clusters.ts +65 -0
  31. package/src/commands/index.ts +23 -0
  32. package/src/commands/models.ts +63 -0
  33. package/src/commands/users.ts +37 -0
  34. package/src/constants/command-structure.ts +16 -0
  35. package/src/services/api-key-service.ts +12 -20
  36. package/src/services/auth-service.ts +90 -50
  37. package/src/services/chat-service.ts +295 -0
  38. package/src/types/api.d.ts +238 -178
  39. package/src/types/json.d.ts +4 -0
  40. package/src/utils/config-checker.ts +23 -0
  41. package/src/utils/default-api-key.ts +229 -0
  42. package/src/utils/error-handler.ts +4 -4
  43. package/src/utils/token-manager.ts +150 -0
  44. package/tsconfig.json +1 -1
@@ -14,6 +14,20 @@ export interface paths {
14
14
  /**
15
15
  * List all API keys
16
16
  * @description Lists all API keys for the authenticated user's organization.
17
+ *
18
+ * ## Using the CLI
19
+ *
20
+ * You can also manage API keys using our CLI tool:
21
+ * ```
22
+ * # Login first (if you haven't already)
23
+ * npx berget auth login
24
+ *
25
+ * # List all API keys
26
+ * npx berget api-keys list
27
+ *
28
+ * # Create a new API key
29
+ * npx berget api-keys create --name my-api-key
30
+ * ```
17
31
  */
18
32
  get: {
19
33
  responses: {
@@ -36,6 +50,17 @@ export interface paths {
36
50
  /**
37
51
  * Create a new API key
38
52
  * @description Creates a new API key for the authenticated user's organization. The full API key is only returned once at creation time.
53
+ *
54
+ * ## Using the CLI
55
+ *
56
+ * Creating an API key is easier with our CLI tool:
57
+ * ```
58
+ * # Login first (if you haven't already)
59
+ * npx berget auth login
60
+ *
61
+ * # Create a new API key
62
+ * npx berget api-keys create --name my-api-key
63
+ * ```
39
64
  */
40
65
  post: {
41
66
  requestBody: {
@@ -97,6 +122,21 @@ export interface paths {
97
122
  /**
98
123
  * Rotate an API key
99
124
  * @description Rotates an API key by invalidating the old key and generating a new one. The new key is returned in the response and is only shown once.
125
+ *
126
+ * ## Using the CLI
127
+ *
128
+ * You can also rotate API keys using our CLI tool:
129
+ * ```
130
+ * # Login first (if you haven't already)
131
+ * npx berget auth login
132
+ *
133
+ * # Rotate an API key
134
+ * npx berget api-keys rotate --id <key-id>
135
+ * ```
136
+ *
137
+ * ## Security Note
138
+ *
139
+ * When you rotate an API key, the old key becomes invalid immediately. Make sure to update any applications using the key.
100
140
  */
101
141
  put: {
102
142
  parameters: {
@@ -131,6 +171,20 @@ export interface paths {
131
171
  /**
132
172
  * Get API key usage statistics
133
173
  * @description Returns usage statistics for a specific API key including request count, daily breakdown, model-specific usage, and token consumption.
174
+ *
175
+ * ## Using the CLI
176
+ *
177
+ * You can also view API key usage using our CLI tool:
178
+ * ```
179
+ * # Login first (if you haven't already)
180
+ * npx berget auth login
181
+ *
182
+ * # View usage for a specific API key
183
+ * npx berget api-keys usage --id <key-id>
184
+ *
185
+ * # View usage for all API keys
186
+ * npx berget usage
187
+ * ```
134
188
  */
135
189
  get: {
136
190
  parameters: {
@@ -351,16 +405,31 @@ export interface paths {
351
405
  "/v1/auth/login": {
352
406
  /**
353
407
  * OAuth login
354
- * @description Initiates OAuth flow for user authentication.
408
+ * @description Initiates OAuth login flow via Keycloak.
355
409
  *
356
- * If you don't have an account yet, you can create one during the login process
357
- * by clicking on the "Register" link on the login page.
410
+ * ## CLI Authentication
358
411
  *
359
- * This is the recommended way to authenticate with the Berget AI API.
412
+ * For a simpler experience, you can use our CLI tool to authenticate:
413
+ * ```
414
+ * npx berget auth login
415
+ * ```
416
+ *
417
+ * After logging in, you can create an API key with:
418
+ * ```
419
+ * npx berget api-keys create --name my-api-key
420
+ * ```
360
421
  */
361
422
  get: {
423
+ parameters: {
424
+ query?: {
425
+ /** @description URL to redirect to after successful login */
426
+ redirect_uri?: string;
427
+ /** @description How to return the token after successful login (default is redirect) */
428
+ response_type?: "redirect" | "json";
429
+ };
430
+ };
362
431
  responses: {
363
- /** @description Redirects to authentication provider */
432
+ /** @description Redirects to Keycloak for login */
364
433
  302: {
365
434
  content: never;
366
435
  };
@@ -370,181 +439,154 @@ export interface paths {
370
439
  "/v1/auth/callback": {
371
440
  /**
372
441
  * OAuth callback
373
- * @description Handles the callback from OAuth authentication. After successful authentication, you'll receive an access token to use for API requests.
442
+ * @description Handles Keycloak login callback and exchanges token
374
443
  */
375
444
  get: {
376
445
  parameters: {
377
- query?: {
378
- /** @description Authorization code */
379
- code?: string;
380
- /** @description State parameter for CSRF protection */
381
- state?: string;
446
+ query: {
447
+ code: string;
448
+ state: string;
382
449
  };
383
450
  };
384
451
  responses: {
385
- /** @description Redirects to frontend with token */
452
+ /** @description Redirects to frontend */
386
453
  302: {
387
454
  content: never;
388
455
  };
389
- /** @description Invalid request */
390
- 400: {
391
- content: never;
392
- };
393
- /** @description Authentication failed */
394
- 401: {
395
- content: never;
456
+ };
457
+ };
458
+ };
459
+ "/v1/auth/device": {
460
+ /**
461
+ * Initiate device authorization flow
462
+ * @description Initiates the device authorization flow, returning a device code and user verification URL.
463
+ *
464
+ * ## Using the CLI
465
+ *
466
+ * The recommended way to authenticate is through our CLI tool:
467
+ * ```
468
+ * npx berget auth login
469
+ * ```
470
+ *
471
+ * This handles the device flow automatically and provides a better user experience.
472
+ */
473
+ post: {
474
+ responses: {
475
+ /** @description Device authorization initiated */
476
+ 200: {
477
+ content: {
478
+ "application/json": components["schemas"]["DeviceAuthInitResponse"];
479
+ };
396
480
  };
397
481
  };
398
482
  };
399
483
  };
400
- "/v1/auth/keycloak": {
484
+ "/v1/auth/device/token": {
401
485
  /**
402
- * Authenticate with OAuth tokens
403
- * @description Exchange OAuth tokens for our system token
486
+ * Poll for device token
487
+ * @description Polls for the status of a device authorization flow. The client should poll this endpoint
488
+ * until it receives a token or an error.
489
+ *
490
+ * ## Using the CLI
491
+ *
492
+ * The recommended way to authenticate is through our CLI tool:
493
+ * ```
494
+ * npx berget auth login
495
+ * ```
496
+ *
497
+ * This handles the polling automatically and provides a better user experience.
498
+ *
499
+ * ## Troubleshooting
500
+ *
501
+ * - If you receive a 400 error, the device code may be invalid or expired
502
+ * - If you receive a 429 error, you're polling too frequently
503
+ * - If you receive a 500 error, there may be an issue with the authentication service
404
504
  */
405
505
  post: {
406
506
  requestBody: {
407
507
  content: {
408
- "application/json": {
409
- /** @description Subject identifier from authentication provider */
410
- sub: string;
411
- /**
412
- * Format: email
413
- * @description User's email address
414
- */
415
- email: string;
416
- /** @description User's full name */
417
- name?: string;
418
- /** @description User's preferred username */
419
- preferred_username?: string;
420
- /** @description OAuth access token */
421
- access_token: string;
422
- /** @description OAuth refresh token */
423
- refresh_token?: string;
424
- /** @description OAuth ID token */
425
- id_token?: string;
426
- };
508
+ "application/json": components["schemas"]["DeviceAuthRequest"];
427
509
  };
428
510
  };
429
511
  responses: {
430
- /** @description Authentication successful */
512
+ /** @description Token returned or pending status */
431
513
  200: {
432
514
  content: {
433
- "application/json": {
434
- /** @description JWT token for our system */
435
- token?: string;
436
- /** @description User information */
437
- user?: Record<string, never>;
438
- };
515
+ "application/json": components["schemas"]["DeviceAuthPendingResponse"] | components["schemas"]["DeviceAuthTokenResponse"];
439
516
  };
440
517
  };
441
- /** @description Invalid request */
518
+ /** @description Invalid device code or expired token */
442
519
  400: {
443
520
  content: never;
444
521
  };
445
- /** @description Authentication failed */
446
- 401: {
522
+ /** @description Polling too frequently */
523
+ 429: {
447
524
  content: never;
448
525
  };
449
- };
450
- };
451
- };
452
- "/v1/auth/register-url": {
453
- /**
454
- * Get registration URL
455
- * @description Returns the URL where users can register a new account.
456
- * This is the recommended way for new users to create accounts.
457
- */
458
- get: {
459
- responses: {
460
- /** @description Registration URL */
461
- 200: {
462
- content: {
463
- "application/json": {
464
- /** @description URL to registration page */
465
- url?: string;
466
- };
467
- };
526
+ /** @description Server error during authentication */
527
+ 500: {
528
+ content: never;
468
529
  };
469
530
  };
470
531
  };
471
532
  };
472
- "/v1/auth/device": {
533
+ "/v1/auth/refresh": {
473
534
  /**
474
- * Initiate device authorization flow
475
- * @description Initiates a device authorization flow for CLI tools.
476
- * Returns a verification URL and device code for the user to complete authentication.
535
+ * Refresh access token
536
+ * @description Refreshes an access token using a refresh token. This endpoint can be used to obtain a new
537
+ * access token when the current one expires.
538
+ *
539
+ * ## Using the CLI
540
+ *
541
+ * The CLI tool handles token refresh automatically:
542
+ * ```
543
+ * # The CLI will refresh tokens as needed
544
+ * npx berget api-keys list
545
+ * ```
477
546
  */
478
547
  post: {
548
+ requestBody: {
549
+ content: {
550
+ "application/json": components["schemas"]["RefreshTokenRequest"];
551
+ };
552
+ };
479
553
  responses: {
480
- /** @description Device authorization initiated */
554
+ /** @description New access and refresh tokens */
481
555
  200: {
482
556
  content: {
483
- "application/json": {
484
- /** @description URL where the user should go to authenticate */
485
- verification_url?: string;
486
- /** @description Code the user should enter on the verification page */
487
- user_code?: string;
488
- /** @description Code used by the device to poll for authentication status */
489
- device_code?: string;
490
- /** @description Seconds until the device code expires */
491
- expires_in?: number;
492
- /** @description Polling interval in seconds */
493
- interval?: number;
494
- };
557
+ "application/json": components["schemas"]["RefreshTokenResponse"];
495
558
  };
496
559
  };
560
+ /** @description Invalid or expired refresh token */
561
+ 401: {
562
+ content: never;
563
+ };
497
564
  };
498
565
  };
499
566
  };
500
- "/v1/auth/device/token": {
501
- /**
502
- * Poll for device authorization token
503
- * @description Polls for the completion of a device authorization flow.
504
- * The CLI tool should call this endpoint repeatedly until authentication is complete.
505
- */
506
- post: {
507
- requestBody: {
508
- content: {
509
- "application/json": {
510
- /** @description Device code received from the /device endpoint */
511
- device_code: string;
512
- };
513
- };
514
- };
567
+ "/v1/auth/register-url": {
568
+ /** Get Keycloak registration URL */
569
+ get: {
515
570
  responses: {
516
- /** @description Authentication successful */
571
+ /** @description Registration URL returned */
517
572
  200: {
518
573
  content: {
519
574
  "application/json": {
520
- /** @description JWT token for API access */
521
- token?: string;
522
- /** @description User information */
523
- user?: Record<string, never>;
575
+ url?: string;
524
576
  };
525
577
  };
526
578
  };
527
- /** @description Invalid request */
528
- 400: {
529
- content: never;
530
- };
531
- /** @description Authentication pending or failed */
532
- 401: {
533
- content: never;
534
- };
535
579
  };
536
580
  };
537
581
  };
538
582
  "/v1/auth/logout": {
539
583
  /**
540
584
  * Logout
541
- * @description Redirects to logout endpoint to properly terminate the session.
542
- * Optionally accepts a redirect_uri query parameter to specify where to redirect after logout.
585
+ * @description Clears cookies and redirects to Keycloak logout
543
586
  */
544
587
  get: {
545
588
  parameters: {
546
589
  query?: {
547
- /** @description URL to redirect to after logout */
548
590
  redirect_uri?: string;
549
591
  };
550
592
  };
@@ -969,6 +1011,28 @@ export interface paths {
969
1011
  };
970
1012
  };
971
1013
  };
1014
+ "/v1/users/me": {
1015
+ /**
1016
+ * Get current user profile
1017
+ * @description Retrieves the profile of the currently authenticated user
1018
+ */
1019
+ get: {
1020
+ responses: {
1021
+ /** @description User profile */
1022
+ 200: {
1023
+ content: {
1024
+ "application/json": components["schemas"]["UserProfile"];
1025
+ };
1026
+ };
1027
+ /** @description Unauthorized */
1028
+ 401: {
1029
+ content: {
1030
+ "application/json": components["schemas"]["ErrorResponse"];
1031
+ };
1032
+ };
1033
+ };
1034
+ };
1035
+ };
972
1036
  "/v1/users/{id}": {
973
1037
  /**
974
1038
  * Get user details
@@ -1073,28 +1137,6 @@ export interface paths {
1073
1137
  };
1074
1138
  };
1075
1139
  };
1076
- "/v1/users/me": {
1077
- /**
1078
- * Get current user profile
1079
- * @description Retrieves the profile of the currently authenticated user
1080
- */
1081
- get: {
1082
- responses: {
1083
- /** @description User profile */
1084
- 200: {
1085
- content: {
1086
- "application/json": components["schemas"]["UserProfile"];
1087
- };
1088
- };
1089
- /** @description Unauthorized */
1090
- 401: {
1091
- content: {
1092
- "application/json": components["schemas"]["ErrorResponse"];
1093
- };
1094
- };
1095
- };
1096
- };
1097
- };
1098
1140
  "/v1/users/invite": {
1099
1141
  /**
1100
1142
  * Invite team member
@@ -1523,8 +1565,6 @@ export interface components {
1523
1565
  };
1524
1566
  AuthToken: {
1525
1567
  accessToken: string;
1526
- /** @enum {string} */
1527
- tokenType: "Bearer";
1528
1568
  expiresIn: number;
1529
1569
  user?: {
1530
1570
  id: string;
@@ -1542,6 +1582,55 @@ export interface components {
1542
1582
  /** Format: uri */
1543
1583
  avatarUrl: string;
1544
1584
  };
1585
+ RefreshTokenRequest: {
1586
+ /** @description The refresh token to use */
1587
+ refresh_token: string;
1588
+ /** @description Whether this is a device token */
1589
+ is_device_token?: boolean;
1590
+ };
1591
+ RefreshTokenResponse: {
1592
+ /** @description The new access token */
1593
+ token: string;
1594
+ /** @description The new refresh token */
1595
+ refresh_token: string;
1596
+ /** @description Seconds until the access token expires */
1597
+ expires_in: number;
1598
+ /** @description Seconds until the refresh token expires */
1599
+ refresh_expires_in: number;
1600
+ };
1601
+ DeviceAuthRequest: {
1602
+ /** @description The device code obtained from the device authorization request */
1603
+ device_code: string;
1604
+ };
1605
+ DeviceAuthInitResponse: {
1606
+ /** @description Code used by the device to poll for authentication status */
1607
+ device_code: string;
1608
+ /** @description Code displayed to the user for authentication */
1609
+ user_code: string;
1610
+ /** @description URL where the user should enter the user_code */
1611
+ verification_url: string;
1612
+ /** @description Expiration time in seconds */
1613
+ expires_in: number;
1614
+ /** @description Polling interval in seconds */
1615
+ interval: number;
1616
+ };
1617
+ DeviceAuthPendingResponse: {
1618
+ /**
1619
+ * @description Authentication is still pending
1620
+ * @enum {string}
1621
+ */
1622
+ status: "pending";
1623
+ };
1624
+ DeviceAuthTokenResponse: {
1625
+ /** @description Access token */
1626
+ token: string;
1627
+ /** @description Refresh token */
1628
+ refresh_token: string;
1629
+ /** @description Access token expiration time in seconds */
1630
+ expires_in: number;
1631
+ /** @description Refresh token expiration time in seconds */
1632
+ refresh_expires_in: number;
1633
+ };
1545
1634
  Usage: {
1546
1635
  current_period: {
1547
1636
  /** Format: date-time */
@@ -1797,46 +1886,17 @@ export interface components {
1797
1886
  };
1798
1887
  };
1799
1888
  };
1800
- /** @description Pricing information for the model */
1801
- ModelPricing: {
1802
- /** @description Cost per token for input in the specified currency */
1803
- input: number;
1804
- /** @description Cost per token for output in the specified currency */
1805
- output: number;
1806
- /** @description The unit of pricing (e.g., "token") */
1807
- unit: string;
1808
- /** @description The currency of the pricing (e.g., "USD") */
1809
- currency: string;
1810
- };
1811
- /** @description Model capabilities */
1812
- ModelCapabilities: {
1813
- /** @description Whether the model supports vision/image input */
1814
- vision: boolean;
1815
- /** @description Whether the model supports function calling */
1816
- function_calling: boolean;
1817
- /** @description Whether the model supports JSON mode */
1818
- json_mode: boolean;
1819
- };
1820
1889
  Model: {
1821
1890
  /** @description Unique identifier for the model */
1822
1891
  id: string;
1823
- /**
1824
- * @description Object type
1825
- * @enum {string}
1826
- */
1827
- object: "model";
1828
- /** @description Unix timestamp of when the model was created */
1829
- created: number;
1830
- /** @description Organization that owns the model */
1831
- owned_by: string;
1832
- pricing: components["schemas"]["ModelPricing"];
1833
- capabilities: components["schemas"]["ModelCapabilities"];
1834
- };
1835
- ModelList: {
1836
- data: components["schemas"]["Model"][];
1837
- /** @enum {string} */
1838
- object: "list";
1892
+ /** @description Name of the model */
1893
+ name: string;
1894
+ /** @description Description of the model */
1895
+ description: string;
1896
+ /** @description Whether the model is active */
1897
+ active: boolean;
1839
1898
  };
1899
+ ModelList: components["schemas"]["Model"][];
1840
1900
  /** @description Cost information for this usage */
1841
1901
  TokenCost: {
1842
1902
  /** @description Cost amount */
@@ -0,0 +1,4 @@
1
+ declare module "*.json" {
2
+ const value: any;
3
+ export = value;
4
+ }
@@ -0,0 +1,23 @@
1
+ import * as fs from 'fs'
2
+ import * as path from 'path'
3
+
4
+ /**
5
+ * Check for .bergetconfig file and handle cluster switching
6
+ */
7
+ export function checkBergetConfig(): void {
8
+ const configPath = path.join(process.cwd(), '.bergetconfig')
9
+ if (fs.existsSync(configPath)) {
10
+ try {
11
+ const config = fs.readFileSync(configPath, 'utf8')
12
+ const match = config.match(/cluster:\s*(.+)/)
13
+ if (match && match[1]) {
14
+ const clusterName = match[1].trim()
15
+ console.log(`🔄 Berget: Switched to cluster "${clusterName}"`)
16
+ console.log('✓ kubectl config updated')
17
+ console.log('')
18
+ }
19
+ } catch (error) {
20
+ // Silently ignore errors reading config
21
+ }
22
+ }
23
+ }