berget 2.1.1 → 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/dist/index.js +1 -0
- package/dist/package.json +1 -1
- package/dist/src/client.js +22 -6
- package/dist/src/commands/code.js +33 -4
- package/dist/src/services/api-key-service.js +7 -4
- package/dist/src/services/auth-service.js +280 -110
- package/dist/src/utils/token-manager.js +11 -6
- package/index.ts +1 -0
- package/opencode.json +5 -1
- package/package.json +1 -1
- package/src/client.ts +29 -9
- package/src/commands/code.ts +32 -5
- package/src/services/api-key-service.ts +6 -0
- package/src/services/auth-service.ts +319 -184
- package/src/utils/token-manager.ts +13 -7
- package/dist/src/schemas/opencode-schema.json +0 -1121
package/opencode.json
CHANGED
package/package.json
CHANGED
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' :
|
|
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
|
-
//
|
|
236
|
+
// Refresh directly against Keycloak (berget-code is a public PKCE client)
|
|
223
237
|
try {
|
|
224
|
-
const response = await fetch(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
231
|
-
})
|
|
251
|
+
)
|
|
232
252
|
|
|
233
253
|
// Handle HTTP errors
|
|
234
254
|
if (!response.ok) {
|
package/src/commands/code.ts
CHANGED
|
@@ -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,18 +829,19 @@ export function registerCodeCommands(program: Command): void {
|
|
|
829
829
|
npm: '@ai-sdk/openai-compatible',
|
|
830
830
|
name: 'Berget AI',
|
|
831
831
|
options: {
|
|
832
|
-
baseURL: '
|
|
832
|
+
baseURL: '{env:BERGET_API_URL}',
|
|
833
833
|
apiKey: '{env:BERGET_API_KEY}',
|
|
834
834
|
},
|
|
835
835
|
models: {
|
|
836
836
|
'glm-4.7': {
|
|
837
837
|
name: 'GLM-4.7',
|
|
838
|
-
limit: { output: 4000, context:
|
|
838
|
+
limit: { output: 4000, context: 200000 },
|
|
839
|
+
modalities: { input: ['text'], output: ['text'] },
|
|
839
840
|
},
|
|
840
841
|
'gpt-oss': {
|
|
841
842
|
name: 'GPT-OSS',
|
|
842
843
|
limit: { output: 4000, context: 128000 },
|
|
843
|
-
modalities: ['text', 'image'],
|
|
844
|
+
modalities: { input: ['text', 'image'], output: ['text'] },
|
|
844
845
|
},
|
|
845
846
|
'llama-8b': {
|
|
846
847
|
name: 'llama-3.1-8b',
|
|
@@ -1180,6 +1181,32 @@ All agents follow these principles:
|
|
|
1180
1181
|
// Set environment variables for opencode
|
|
1181
1182
|
const env = { ...process.env }
|
|
1182
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
|
+
|
|
1183
1210
|
// Prepare opencode command
|
|
1184
1211
|
const opencodeArgs: string[] = []
|
|
1185
1212
|
|
|
@@ -1486,7 +1513,7 @@ All agents follow these principles:
|
|
|
1486
1513
|
npm: '@ai-sdk/openai-compatible',
|
|
1487
1514
|
name: 'Berget AI',
|
|
1488
1515
|
options: {
|
|
1489
|
-
baseURL: '
|
|
1516
|
+
baseURL: '{env:BERGET_API_URL}',
|
|
1490
1517
|
apiKey: '{env:BERGET_API_KEY}',
|
|
1491
1518
|
},
|
|
1492
1519
|
models: getProviderModels(),
|
|
@@ -115,6 +115,12 @@ export class ApiKeyService {
|
|
|
115
115
|
throw new Error(detailedMessage)
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
if (errorObj.error?.code === 'USER_NOT_FOUND') {
|
|
119
|
+
throw new Error(
|
|
120
|
+
'Your account is still being set up. Please wait a moment and try again.\n\nIf this issue persists, please contact support at support@berget.ai',
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
118
124
|
if (errorObj.error?.code === 'QUOTA_EXCEEDED') {
|
|
119
125
|
throw new Error(
|
|
120
126
|
'You have reached your API key limit. Please delete existing keys or contact support to increase your quota.',
|