berget 2.0.6 → 2.1.1
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/AGENTS.md +163 -2
- package/dist/package.json +1 -1
- package/dist/src/commands/chat.js +1 -2
- package/dist/src/commands/code.js +152 -87
- package/dist/src/services/auth-service.js +1 -2
- package/dist/src/services/chat-service.js +77 -5
- package/dist/src/utils/config-loader.js +83 -27
- package/dist/tests/commands/chat.test.js +2 -2
- package/dist/tests/commands/code.test.js +4 -4
- package/dist/tests/utils/config-loader.test.js +248 -163
- package/opencode.json +31 -71
- package/package.json +1 -1
- package/src/commands/chat.ts +68 -61
- package/src/commands/code.ts +304 -213
- package/src/services/auth-service.ts +1 -4
- package/src/services/chat-service.ts +86 -5
- package/src/utils/config-loader.ts +113 -38
- package/tests/commands/chat.test.ts +2 -2
- package/tests/commands/code.test.ts +4 -4
- package/tests/utils/config-loader.test.ts +320 -0
- package/blog-post.md +0 -176
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
ConfigLoader,
|
|
4
|
+
getModelConfig,
|
|
5
|
+
getProviderModels,
|
|
6
|
+
getAllAgentConfigs
|
|
7
|
+
} from '../../src/utils/config-loader'
|
|
8
|
+
|
|
9
|
+
// Mock fs module
|
|
10
|
+
const mockFs = vi.hoisted(() => ({
|
|
11
|
+
existsSync: vi.fn(),
|
|
12
|
+
readFileSync: vi.fn(),
|
|
13
|
+
writeFileSync: vi.fn(),
|
|
14
|
+
mkdirSync: vi.fn(),
|
|
15
|
+
}))
|
|
16
|
+
|
|
17
|
+
vi.mock('fs', () => mockFs)
|
|
18
|
+
|
|
19
|
+
describe('ConfigLoader', () => {
|
|
20
|
+
const testConfigPath = '/tmp/test-opencode.json'
|
|
21
|
+
let configLoader: ConfigLoader
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
// Reset mocks and clear singleton
|
|
25
|
+
vi.clearAllMocks()
|
|
26
|
+
ConfigLoader.clearInstance()
|
|
27
|
+
|
|
28
|
+
// Create new instance for each test using getInstance
|
|
29
|
+
configLoader = ConfigLoader.getInstance(testConfigPath)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
vi.clearAllMocks()
|
|
34
|
+
ConfigLoader.clearInstance()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
describe('when config file does not exist', () => {
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
mockFs.existsSync.mockReturnValue(false)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe('getModelConfig', () => {
|
|
43
|
+
it('should return default values when config file does not exist', () => {
|
|
44
|
+
const modelConfig = configLoader.getModelConfig()
|
|
45
|
+
|
|
46
|
+
expect(modelConfig).toEqual({
|
|
47
|
+
primary: 'berget/glm-4.7',
|
|
48
|
+
small: 'berget/gpt-oss'
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('should return default values when using convenience function', () => {
|
|
53
|
+
const modelConfig = getModelConfig(testConfigPath)
|
|
54
|
+
|
|
55
|
+
expect(modelConfig).toEqual({
|
|
56
|
+
primary: 'berget/glm-4.7',
|
|
57
|
+
small: 'berget/gpt-oss'
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
describe('getProviderModels', () => {
|
|
63
|
+
it('should return default provider models when config file does not exist', () => {
|
|
64
|
+
const models = configLoader.getProviderModels()
|
|
65
|
+
|
|
66
|
+
expect(models).toEqual({
|
|
67
|
+
'glm-4.7': {
|
|
68
|
+
name: 'GLM-4.7',
|
|
69
|
+
limit: { output: 4000, context: 90000 }
|
|
70
|
+
},
|
|
71
|
+
'gpt-oss': {
|
|
72
|
+
name: 'GPT-OSS',
|
|
73
|
+
limit: { output: 4000, context: 128000 },
|
|
74
|
+
modalities: {
|
|
75
|
+
input: ['text', 'image'],
|
|
76
|
+
output: ['text']
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
'llama-8b': {
|
|
80
|
+
name: 'llama-3.1-8b',
|
|
81
|
+
limit: { output: 4000, context: 128000 }
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('should return default provider models when using convenience function', () => {
|
|
87
|
+
const models = getProviderModels(testConfigPath)
|
|
88
|
+
|
|
89
|
+
expect(models).toEqual({
|
|
90
|
+
'glm-4.7': {
|
|
91
|
+
name: 'GLM-4.7',
|
|
92
|
+
limit: { output: 4000, context: 90000 }
|
|
93
|
+
},
|
|
94
|
+
'gpt-oss': {
|
|
95
|
+
name: 'GPT-OSS',
|
|
96
|
+
limit: { output: 4000, context: 128000 },
|
|
97
|
+
modalities: {
|
|
98
|
+
input: ['text', 'image'],
|
|
99
|
+
output: ['text']
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
'llama-8b': {
|
|
103
|
+
name: 'llama-3.1-8b',
|
|
104
|
+
limit: { output: 4000, context: 128000 }
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
describe('getAllAgentConfigs', () => {
|
|
111
|
+
it('should return empty object when config file does not exist', () => {
|
|
112
|
+
const agents = configLoader.getAllAgentConfigs()
|
|
113
|
+
|
|
114
|
+
expect(agents).toEqual({})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('should return empty object when using convenience function', () => {
|
|
118
|
+
const agents = getAllAgentConfigs(testConfigPath)
|
|
119
|
+
|
|
120
|
+
expect(agents).toEqual({})
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
describe('getAgentConfig', () => {
|
|
125
|
+
it('should return null when config file does not exist', () => {
|
|
126
|
+
const agent = configLoader.getAgentConfig('fullstack')
|
|
127
|
+
|
|
128
|
+
expect(agent).toBeNull()
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
describe('when config file exists', () => {
|
|
134
|
+
const mockConfig = {
|
|
135
|
+
model: 'custom-model',
|
|
136
|
+
small_model: 'custom-small-model',
|
|
137
|
+
agent: {
|
|
138
|
+
fullstack: {
|
|
139
|
+
model: 'custom-agent-model',
|
|
140
|
+
temperature: 0.5,
|
|
141
|
+
mode: 'primary' as const,
|
|
142
|
+
permission: {
|
|
143
|
+
edit: 'allow' as const,
|
|
144
|
+
bash: 'allow' as const,
|
|
145
|
+
webfetch: 'allow' as const
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
command: {
|
|
150
|
+
test: {
|
|
151
|
+
description: 'Test command'
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
watcher: {
|
|
155
|
+
ignore: ['custom-ignore']
|
|
156
|
+
},
|
|
157
|
+
provider: {
|
|
158
|
+
berget: {
|
|
159
|
+
models: {
|
|
160
|
+
'custom-model': {
|
|
161
|
+
name: 'Custom Model',
|
|
162
|
+
limit: { output: 8000, context: 160000 }
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
beforeEach(() => {
|
|
170
|
+
mockFs.existsSync.mockReturnValue(true)
|
|
171
|
+
mockFs.readFileSync.mockReturnValue(JSON.stringify(mockConfig))
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
describe('getModelConfig', () => {
|
|
175
|
+
it('should return values from config file', () => {
|
|
176
|
+
const modelConfig = configLoader.getModelConfig()
|
|
177
|
+
|
|
178
|
+
expect(modelConfig).toEqual({
|
|
179
|
+
primary: 'custom-model',
|
|
180
|
+
small: 'custom-small-model'
|
|
181
|
+
})
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
describe('getProviderModels', () => {
|
|
186
|
+
it('should return models from config file', () => {
|
|
187
|
+
const models = configLoader.getProviderModels()
|
|
188
|
+
|
|
189
|
+
expect(models).toEqual({
|
|
190
|
+
'custom-model': {
|
|
191
|
+
name: 'Custom Model',
|
|
192
|
+
limit: { output: 8000, context: 160000 }
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
describe('getAllAgentConfigs', () => {
|
|
199
|
+
it('should return agents from config file', () => {
|
|
200
|
+
const agents = configLoader.getAllAgentConfigs()
|
|
201
|
+
|
|
202
|
+
expect(agents).toEqual(mockConfig.agent)
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
describe('getAgentConfig', () => {
|
|
207
|
+
it('should return specific agent from config file', () => {
|
|
208
|
+
const agent = configLoader.getAgentConfig('fullstack')
|
|
209
|
+
|
|
210
|
+
expect(agent).toEqual(mockConfig.agent.fullstack)
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('should return null for non-existent agent', () => {
|
|
214
|
+
const agent = configLoader.getAgentConfig('nonexistent')
|
|
215
|
+
|
|
216
|
+
expect(agent).toBeNull()
|
|
217
|
+
})
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
describe('when config file is invalid JSON', () => {
|
|
222
|
+
beforeEach(() => {
|
|
223
|
+
mockFs.existsSync.mockReturnValue(true)
|
|
224
|
+
mockFs.readFileSync.mockReturnValue('invalid json {')
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
it('should fall back to defaults for getModelConfig', () => {
|
|
228
|
+
const modelConfig = configLoader.getModelConfig()
|
|
229
|
+
|
|
230
|
+
expect(modelConfig).toEqual({
|
|
231
|
+
primary: 'berget/glm-4.7',
|
|
232
|
+
small: 'berget/gpt-oss'
|
|
233
|
+
})
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
it('should fall back to defaults for getProviderModels', () => {
|
|
237
|
+
const models = configLoader.getProviderModels()
|
|
238
|
+
|
|
239
|
+
expect(models).toEqual({
|
|
240
|
+
'glm-4.7': {
|
|
241
|
+
name: 'GLM-4.7',
|
|
242
|
+
limit: { output: 4000, context: 90000 }
|
|
243
|
+
},
|
|
244
|
+
'gpt-oss': {
|
|
245
|
+
name: 'GPT-OSS',
|
|
246
|
+
limit: { output: 4000, context: 128000 },
|
|
247
|
+
modalities: {
|
|
248
|
+
input: ['text', 'image'],
|
|
249
|
+
output: ['text']
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
'llama-8b': {
|
|
253
|
+
name: 'llama-3.1-8b',
|
|
254
|
+
limit: { output: 4000, context: 128000 }
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
it('should fall back to defaults for getAllAgentConfigs', () => {
|
|
260
|
+
const agents = configLoader.getAllAgentConfigs()
|
|
261
|
+
|
|
262
|
+
expect(agents).toEqual({})
|
|
263
|
+
})
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
describe('singleton pattern', () => {
|
|
267
|
+
it('should return the same instance for same path', () => {
|
|
268
|
+
ConfigLoader.clearInstance()
|
|
269
|
+
const loader1 = ConfigLoader.getInstance(testConfigPath)
|
|
270
|
+
const loader2 = ConfigLoader.getInstance(testConfigPath)
|
|
271
|
+
|
|
272
|
+
expect(loader1).toBe(loader2)
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
it('should return the same instance even for different paths (true singleton)', () => {
|
|
276
|
+
ConfigLoader.clearInstance()
|
|
277
|
+
const loader1 = ConfigLoader.getInstance('/path1/config.json')
|
|
278
|
+
const loader2 = ConfigLoader.getInstance('/path2/config.json')
|
|
279
|
+
|
|
280
|
+
// ConfigLoader is a true singleton - it returns the same instance regardless of path
|
|
281
|
+
expect(loader1).toBe(loader2)
|
|
282
|
+
})
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
describe('init scenario regression tests', () => {
|
|
286
|
+
it('should handle missing config file during init scenario', () => {
|
|
287
|
+
// This test specifically verifies the fix for the init issue
|
|
288
|
+
mockFs.existsSync.mockReturnValue(false)
|
|
289
|
+
|
|
290
|
+
// All these methods should work without throwing errors
|
|
291
|
+
expect(() => configLoader.getModelConfig()).not.toThrow()
|
|
292
|
+
expect(() => configLoader.getProviderModels()).not.toThrow()
|
|
293
|
+
expect(() => configLoader.getAllAgentConfigs()).not.toThrow()
|
|
294
|
+
expect(() => configLoader.getAgentConfig('fullstack')).not.toThrow()
|
|
295
|
+
|
|
296
|
+
// And return sensible defaults
|
|
297
|
+
expect(configLoader.getModelConfig()).toEqual({
|
|
298
|
+
primary: 'berget/glm-4.7',
|
|
299
|
+
small: 'berget/gpt-oss'
|
|
300
|
+
})
|
|
301
|
+
expect(configLoader.getAllAgentConfigs()).toEqual({})
|
|
302
|
+
expect(configLoader.getAgentConfig('fullstack')).toBeNull()
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
it('should work with convenience functions during init scenario', () => {
|
|
306
|
+
// This test verifies that convenience functions also work during init
|
|
307
|
+
mockFs.existsSync.mockReturnValue(false)
|
|
308
|
+
|
|
309
|
+
expect(() => getModelConfig(testConfigPath)).not.toThrow()
|
|
310
|
+
expect(() => getProviderModels(testConfigPath)).not.toThrow()
|
|
311
|
+
expect(() => getAllAgentConfigs(testConfigPath)).not.toThrow()
|
|
312
|
+
|
|
313
|
+
expect(getModelConfig(testConfigPath)).toEqual({
|
|
314
|
+
primary: 'berget/glm-4.7',
|
|
315
|
+
small: 'berget/gpt-oss'
|
|
316
|
+
})
|
|
317
|
+
expect(getAllAgentConfigs(testConfigPath)).toEqual({})
|
|
318
|
+
})
|
|
319
|
+
})
|
|
320
|
+
})
|
package/blog-post.md
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
# OpenCode + Berget AI: Den ultimata AI-kodassistensen för svenska företag
|
|
2
|
-
|
|
3
|
-
I en värld där AI-drivna kodassistenter blir standard, står svenska företag inför ett kritiskt val: hur man balanserar produktivitetsvinster med data-suveränitet och efterlevnad. Med integrationen mellan OpenCode och Berget AI får du nu det bästa av två världar – en kraftfull, open source AI-kodassistent med svensk datainfrastruktur.
|
|
4
|
-
|
|
5
|
-
## Vad är OpenCode?
|
|
6
|
-
|
|
7
|
-
OpenCode är en open source AI-kodassistent byggd för terminalen. Till skillnad från många kommersiella alternativ ger OpenCode dig full kontroll över din kod och dina data. Med över 26 000 GitHub-stjärnor och 200 000+ aktiva utvecklare varje månad har det blivit ett av de mest populära verktygen för AI-assisterad programmering.
|
|
8
|
-
|
|
9
|
-
**Nödvändiga funktioner i OpenCode:**
|
|
10
|
-
|
|
11
|
-
- 🎯 **Native TUI** – Responsivt terminalgränssnitt som fungerar i din befintliga workflow
|
|
12
|
-
- 🔄 **Multi-session** – Köra flera agenter parallellt på samma projekt
|
|
13
|
-
- 🔗 **Share links** – Dela sessioner för kodgranskning och felsökning
|
|
14
|
-
- 🤖 **Any model** – Stöd för 75+ LLM-providers via Models.dev
|
|
15
|
-
- 🛠️ **LSP enabled** – Automatisk laddning av rätt Language Servers för LLM:en
|
|
16
|
-
|
|
17
|
-
## Berget AI: Svensk datainfrastruktur
|
|
18
|
-
|
|
19
|
-
Berget AI är en svensk AI-infrastrukturleverantör som säkerställer att din data aldrig lämnar Sverige. Detta är särskilt viktigt för företag som hanterar känslig information, personuppgifter eller skyddad kod.
|
|
20
|
-
|
|
21
|
-
**Fördelar med Berget AI:**
|
|
22
|
-
|
|
23
|
-
- 🇸🇪 **Data-suveränitet** – All data bearbetas inom Sverige
|
|
24
|
-
- ⚖️ **GDPR-kompatibilitet** – Full efterlevnad med EU:s dataskyddslagar
|
|
25
|
-
- 🔒 **Säkerhet** – Industriell säkerhet med kryptering och isolering
|
|
26
|
-
- 🏛️ **Reglering** – Enklare efterlevnad av svenska och EU-regleringar
|
|
27
|
-
- 🚀 **Prestanda** – Låg latens med svensk infrastruktur
|
|
28
|
-
|
|
29
|
-
## Varför kombinationen är oslagbar
|
|
30
|
-
|
|
31
|
-
### 1. Data som aldrig lämnar Sverige
|
|
32
|
-
|
|
33
|
-
När du använder OpenCode med Berget AI förblir all din kod – inklusive API-nycklar, konfigurationer och känslig affärslogik – inom Sveriges gränser. Detta eliminerar risken för dataexponering som kan uppstå med internationella molntjänster.
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
# Initiera ditt projekt med AI-assistent
|
|
37
|
-
berget code init
|
|
38
|
-
|
|
39
|
-
# Din kod och data förblir alltid i Sverige ✅
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### 2. Förenklad reglering och efterlevnad
|
|
43
|
-
|
|
44
|
-
För svenska företag, särskilt inom finans, vård och offentlig sektor, är efterlevnad avgörande. Med Berget AI får du:
|
|
45
|
-
|
|
46
|
-
- **GDPR-säker hantering** av personuppgifter i koden
|
|
47
|
-
- **Klassificerad information** hanteras säkert
|
|
48
|
-
- **Revisionsbara spår** av all AI-interaktion
|
|
49
|
-
- **Lokal lagring** av konfigurationer och API-nycklar
|
|
50
|
-
|
|
51
|
-
### 3. Säker hantering av känslig kod
|
|
52
|
-
|
|
53
|
-
Många företag arbetar med kod som innehåller:
|
|
54
|
-
|
|
55
|
-
- API-nycklar och hemligheter
|
|
56
|
-
- Affärskritisk algoritmlogik
|
|
57
|
-
- Känslig kunddata
|
|
58
|
-
- Proprietära systemintegrationer
|
|
59
|
-
|
|
60
|
-
Med OpenCode + Berget AI kan du använda AI-assistens för:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
# Refaktorera känslig kod utan att lämna Sverige
|
|
64
|
-
berget code run "Refaktorera denna autentiseringsmodul"
|
|
65
|
-
|
|
66
|
-
# Få hjälp med API-integrationer säkert
|
|
67
|
-
berget code run "Optimera denna databasanslutning"
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### 4. Projektspecifika API-nycklar
|
|
71
|
-
|
|
72
|
-
Varje projekt får sin egen unika API-nyckel som skapas automatiskt:
|
|
73
|
-
|
|
74
|
-
```json
|
|
75
|
-
{
|
|
76
|
-
"model": "berget/deepseek-r1",
|
|
77
|
-
"apiKey": "projekt-specifik-nyckel",
|
|
78
|
-
"projectName": "mitt-svenska-projekt",
|
|
79
|
-
"provider": "berget",
|
|
80
|
-
"created": "2025-01-01T00:00:00.000Z",
|
|
81
|
-
"version": "1.0.0"
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Detta ger:
|
|
86
|
-
|
|
87
|
-
- 🔐 **Isolering** mellan projekt
|
|
88
|
-
- 📊 **Spårbarhet** av användning
|
|
89
|
-
- 🔄 **Enkel rotation** av nycklar
|
|
90
|
-
- 🎯 **Granulär kontroll** av åtkomst
|
|
91
|
-
|
|
92
|
-
## Kom igång på 2 minuter
|
|
93
|
-
|
|
94
|
-
### Steg 1: Installera OpenCode
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
curl -fsSL https://opencode.ai/install | bash
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Steg 2: Initiera ditt projekt
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
cd ditt-projekt
|
|
104
|
-
berget code init
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Steg 3: Starta AI-assistenen
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
berget code run
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Det var allt! Du har nu en fullfjädrad AI-kodassistent med svensk datainfrastruktur.
|
|
114
|
-
|
|
115
|
-
## Användningsfall för svenska företag
|
|
116
|
-
|
|
117
|
-
### Finans & Försäkring
|
|
118
|
-
|
|
119
|
-
- Refaktorera transaktionslogik med full säkerhet
|
|
120
|
-
- Hjälp med compliance-kod (KYC, AML)
|
|
121
|
-
- Optimera riskberäkningsalgoritmer
|
|
122
|
-
|
|
123
|
-
### Vård & Hälsa
|
|
124
|
-
|
|
125
|
-
- Utveckla patientdata-system med GDPR-säkerhet
|
|
126
|
-
- Hjälp med medicinsk kod och integrationer
|
|
127
|
-
- Säker hantering av journalsystem
|
|
128
|
-
|
|
129
|
-
### Offentlig Sektor
|
|
130
|
-
|
|
131
|
-
- Utveckla e-tjänster med svensk data
|
|
132
|
-
- Hjälp med myndighetsintegrationer
|
|
133
|
-
- Säker hantering av medborgardata
|
|
134
|
-
|
|
135
|
-
### Industri & Tillverkning
|
|
136
|
-
|
|
137
|
-
- Optimera PLC-kod och styrsystem
|
|
138
|
-
- Hjälp med IoT-integrationer
|
|
139
|
-
- Säker utveckling av produktionssystem
|
|
140
|
-
|
|
141
|
-
## Teknisk integration
|
|
142
|
-
|
|
143
|
-
OpenCode + Berget AI använder den kraftfulla **GLM-4.6** modellen (för närvarande deepseek-r1) som är optimerad för kodning:
|
|
144
|
-
|
|
145
|
-
```bash
|
|
146
|
-
# Se vilka modeller som finns tillgängliga
|
|
147
|
-
berget models list
|
|
148
|
-
|
|
149
|
-
# Använd specifik modell
|
|
150
|
-
berget code run --model berget/glm-4-6 "Hjälp mig optimera denna funktion"
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## Framtiden för svensk AI-utveckling
|
|
154
|
-
|
|
155
|
-
Kombinationen av OpenCode och Berget AI representerar nästa generations AI-utveckling för svenska företag:
|
|
156
|
-
|
|
157
|
-
1. **Produktivitet** – AI-assisterad kodning utan kompromisser
|
|
158
|
-
2. **Säkerhet** – Full kontroll över din data och kod
|
|
159
|
-
3. **Efterlevnad** – Inbyggt stöd för svenska och EU-regleringar
|
|
160
|
-
4. **Flexibilitet** – Open source med frihet att välja modeller och verktyg
|
|
161
|
-
5. **Skalbarhet** – Från små projekt till enterprise-nivå
|
|
162
|
-
|
|
163
|
-
## Sammanfattning
|
|
164
|
-
|
|
165
|
-
OpenCode + Berget AI är inte bara ett verktyg – det är en strategisk lösning för svenska företag som vill leda inom AI-driven utveckling utan att kompromissa med säkerhet och efterlevnad.
|
|
166
|
-
|
|
167
|
-
Med svensk datainfrastruktur, projektspecifika API-nycklar och en open source AI-assistent får du det bästa av två världar: global AI-kompetens med lokal dataskydd.
|
|
168
|
-
|
|
169
|
-
**Redo att transformera din kodning med svensk AI?**
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
# Börja idag
|
|
173
|
-
berget code init
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
_Din kod, din data, ditt land – nu med AI-superkrafter._
|