berget 2.1.2 → 2.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.
package/src/client.ts CHANGED
@@ -9,13 +9,20 @@ import { logger } from './utils/logger'
9
9
 
10
10
  // API Base URL
11
11
  // Use --local flag to test against local API
12
+ // Use --stage flag to test against stage API
12
13
  const isLocalMode = process.argv.includes('--local')
14
+ const isStageMode = process.argv.includes('--stage')
15
+
13
16
  export const API_BASE_URL =
14
17
  process.env.BERGET_API_URL ||
15
- (isLocalMode ? 'http://localhost:3000' : 'https://api.berget.ai')
18
+ (isLocalMode ? 'http://localhost:3000' :
19
+ isStageMode ? 'https://api.stage.berget.ai' :
20
+ 'https://api.berget.ai') // production default
16
21
 
17
22
  if (isLocalMode && !process.env.BERGET_API_URL) {
18
23
  logger.debug('Using local API endpoint: http://localhost:3000')
24
+ } else if (isStageMode && !process.env.BERGET_API_URL) {
25
+ logger.debug('Using stage API endpoint: https://api.stage.berget.ai')
19
26
  }
20
27
 
21
28
  // Create a typed client for the Berget API
@@ -209,6 +216,13 @@ export const createAuthenticatedClient = () => {
209
216
  })
210
217
  }
211
218
 
219
+ // Keycloak configuration for token refresh (must match auth-service.ts)
220
+ const KEYCLOAK_URL = (isStageMode || isLocalMode)
221
+ ? 'https://keycloak.stage.berget.ai'
222
+ : 'https://keycloak.berget.ai'
223
+ const KEYCLOAK_REALM = 'berget'
224
+ const KEYCLOAK_CLIENT_ID = 'berget-code'
225
+
212
226
  // Helper function to refresh the access token
213
227
  async function refreshAccessToken(
214
228
  tokenManager: TokenManager,
@@ -219,16 +233,22 @@ async function refreshAccessToken(
219
233
 
220
234
  logger.debug('Attempting to refresh access token')
221
235
 
222
- // Use fetch directly since this endpoint might not be in the OpenAPI spec
236
+ // Refresh directly against Keycloak (berget-code is a public PKCE client)
223
237
  try {
224
- const response = await fetch(`${API_BASE_URL}/v1/auth/refresh`, {
225
- method: 'POST',
226
- headers: {
227
- 'Content-Type': 'application/json',
228
- Accept: 'application/json',
238
+ const response = await fetch(
239
+ `${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`,
240
+ {
241
+ method: 'POST',
242
+ headers: {
243
+ 'Content-Type': 'application/x-www-form-urlencoded',
244
+ },
245
+ body: new URLSearchParams({
246
+ grant_type: 'refresh_token',
247
+ client_id: KEYCLOAK_CLIENT_ID,
248
+ refresh_token: refreshToken,
249
+ }),
229
250
  },
230
- body: JSON.stringify({ refresh_token: refreshToken }),
231
- })
251
+ )
232
252
 
233
253
  // Handle HTTP errors
234
254
  if (!response.ok) {
@@ -10,7 +10,7 @@ import { readFile, writeFile } from 'fs/promises'
10
10
  import path from 'path'
11
11
  import { spawn } from 'child_process'
12
12
  import { updateEnvFile } from '../utils/env-manager'
13
- import { createAuthenticatedClient } from '../client'
13
+ import { createAuthenticatedClient, getAuthToken } from '../client'
14
14
  import {
15
15
  getConfigLoader,
16
16
  getModelConfig,
@@ -829,7 +829,7 @@ export function registerCodeCommands(program: Command): void {
829
829
  npm: '@ai-sdk/openai-compatible',
830
830
  name: 'Berget AI',
831
831
  options: {
832
- baseURL: 'https://api.berget.ai/v1',
832
+ baseURL: '{env:BERGET_API_URL}',
833
833
  apiKey: '{env:BERGET_API_KEY}',
834
834
  },
835
835
  models: {
@@ -1181,6 +1181,32 @@ All agents follow these principles:
1181
1181
  // Set environment variables for opencode
1182
1182
  const env = { ...process.env }
1183
1183
 
1184
+ // Set API base URL based on flags (default to production)
1185
+ const isLocalMode = process.argv.includes('--local')
1186
+ const isStageMode = process.argv.includes('--stage')
1187
+ if (isLocalMode) {
1188
+ env.BERGET_API_URL = 'http://localhost:3000/v1'
1189
+ console.log(chalk.dim('Using local API: http://localhost:3000/v1'))
1190
+ } else if (isStageMode) {
1191
+ env.BERGET_API_URL = 'https://api.stage.berget.ai/v1'
1192
+ console.log(chalk.dim('Using stage API: https://api.stage.berget.ai/v1'))
1193
+ } else {
1194
+ env.BERGET_API_URL = 'https://api.berget.ai/v1'
1195
+ }
1196
+
1197
+ // Auth resolution: JWT first (if valid), then API-key
1198
+ // This ensures seat-based users get proper tracking
1199
+ const jwtToken = getAuthToken()
1200
+ if (jwtToken) {
1201
+ env.BERGET_API_KEY = jwtToken
1202
+ console.log(chalk.dim('Using JWT token for authentication'))
1203
+ } else if (env.BERGET_API_KEY) {
1204
+ console.log(chalk.dim('Using API key for authentication'))
1205
+ } else {
1206
+ console.log(chalk.yellow('Warning: No authentication found'))
1207
+ console.log(chalk.dim(' Run `berget auth login` or set BERGET_API_KEY'))
1208
+ }
1209
+
1184
1210
  // Prepare opencode command
1185
1211
  const opencodeArgs: string[] = []
1186
1212
 
@@ -1487,7 +1513,7 @@ All agents follow these principles:
1487
1513
  npm: '@ai-sdk/openai-compatible',
1488
1514
  name: 'Berget AI',
1489
1515
  options: {
1490
- baseURL: 'https://api.berget.ai/v1',
1516
+ baseURL: '{env:BERGET_API_URL}',
1491
1517
  apiKey: '{env:BERGET_API_KEY}',
1492
1518
  },
1493
1519
  models: getProviderModels(),