berget 1.4.0 → 2.0.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.
Files changed (66) hide show
  1. package/.env.example +5 -0
  2. package/AGENTS.md +184 -0
  3. package/TODO.md +2 -0
  4. package/blog-post.md +176 -0
  5. package/dist/index.js +11 -8
  6. package/dist/package.json +7 -2
  7. package/dist/src/commands/api-keys.js +4 -2
  8. package/dist/src/commands/chat.js +21 -11
  9. package/dist/src/commands/code.js +1424 -0
  10. package/dist/src/commands/index.js +2 -0
  11. package/dist/src/constants/command-structure.js +12 -0
  12. package/dist/src/schemas/opencode-schema.json +1121 -0
  13. package/dist/src/services/cluster-service.js +1 -1
  14. package/dist/src/utils/default-api-key.js +2 -2
  15. package/dist/src/utils/env-manager.js +86 -0
  16. package/dist/src/utils/error-handler.js +10 -3
  17. package/dist/src/utils/markdown-renderer.js +4 -4
  18. package/dist/src/utils/opencode-validator.js +122 -0
  19. package/dist/src/utils/token-manager.js +2 -2
  20. package/dist/tests/commands/chat.test.js +20 -18
  21. package/dist/tests/commands/code.test.js +414 -0
  22. package/dist/tests/utils/env-manager.test.js +148 -0
  23. package/dist/tests/utils/opencode-validator.test.js +103 -0
  24. package/index.ts +67 -32
  25. package/opencode.json +182 -0
  26. package/package.json +7 -2
  27. package/src/client.ts +20 -20
  28. package/src/commands/api-keys.ts +93 -60
  29. package/src/commands/auth.ts +4 -2
  30. package/src/commands/billing.ts +6 -3
  31. package/src/commands/chat.ts +149 -107
  32. package/src/commands/clusters.ts +2 -2
  33. package/src/commands/code.ts +1696 -0
  34. package/src/commands/index.ts +2 -0
  35. package/src/commands/models.ts +3 -3
  36. package/src/commands/users.ts +2 -2
  37. package/src/constants/command-structure.ts +112 -58
  38. package/src/schemas/opencode-schema.json +991 -0
  39. package/src/services/api-key-service.ts +1 -1
  40. package/src/services/auth-service.ts +27 -25
  41. package/src/services/chat-service.ts +26 -23
  42. package/src/services/cluster-service.ts +5 -5
  43. package/src/services/collaborator-service.ts +3 -3
  44. package/src/services/flux-service.ts +2 -2
  45. package/src/services/helm-service.ts +2 -2
  46. package/src/services/kubectl-service.ts +3 -6
  47. package/src/types/api.d.ts +1032 -1010
  48. package/src/types/json.d.ts +3 -3
  49. package/src/utils/default-api-key.ts +54 -42
  50. package/src/utils/env-manager.ts +98 -0
  51. package/src/utils/error-handler.ts +24 -15
  52. package/src/utils/logger.ts +12 -12
  53. package/src/utils/markdown-renderer.ts +18 -18
  54. package/src/utils/opencode-validator.ts +134 -0
  55. package/src/utils/token-manager.ts +35 -23
  56. package/tests/commands/chat.test.ts +43 -31
  57. package/tests/commands/code.test.ts +505 -0
  58. package/tests/utils/env-manager.test.ts +199 -0
  59. package/tests/utils/opencode-validator.test.ts +118 -0
  60. package/tsconfig.json +8 -8
  61. package/-27b-it +0 -0
  62. package/examples/README.md +0 -95
  63. package/examples/ai-review.sh +0 -30
  64. package/examples/install-global-security-hook.sh +0 -170
  65. package/examples/security-check.sh +0 -102
  66. package/examples/smart-commit.sh +0 -26
package/.env.example ADDED
@@ -0,0 +1,5 @@
1
+ # OpenCode Configuration
2
+ # Copy this file to .env and adjust values as needed
3
+
4
+ # Berget AI API Key - Required for authentication
5
+ BERGET_API_KEY=your_api_key_here
package/AGENTS.md ADDED
@@ -0,0 +1,184 @@
1
+ # Berget Code Agents
2
+
3
+ This document describes the specialized agents available in this project for use with OpenCode.
4
+
5
+ ## Available Agents
6
+
7
+ ### Primary Agents
8
+
9
+ #### fullstack
10
+
11
+ Router/coordinator agent for full-stack development with schema-driven architecture. Handles routing between different personas based on file paths and task requirements.
12
+
13
+ **Use when:**
14
+
15
+ - Working across multiple parts of a monorepo
16
+ - Need to coordinate between frontend, backend, devops, and app
17
+ - Starting new projects and need to determine tech stack
18
+
19
+ **Key features:**
20
+
21
+ - Schema-driven development (database → OpenAPI → types)
22
+ - Automatic routing to appropriate persona
23
+ - Tech stack discovery and recommendations
24
+
25
+ #### frontend
26
+
27
+ Builds Scandinavian, type-safe UIs with React, Tailwind, and Shadcn.
28
+
29
+ **Use when:**
30
+
31
+ - Working with React components (.tsx files)
32
+ - Frontend development in /apps/frontend
33
+ - UI/UX implementation
34
+
35
+ **Key features:**
36
+
37
+ - Design system integration
38
+ - Semantic tokens and accessibility
39
+ - Props-first component architecture
40
+
41
+ #### backend
42
+
43
+ Functional, modular Koa + TypeScript services with schema-first approach and code quality focus.
44
+
45
+ **Use when:**
46
+
47
+ - Working with Koa routers and services
48
+ - Backend development in /services
49
+ - API development and database work
50
+
51
+ **Key features:**
52
+
53
+ - Zod validation and OpenAPI generation
54
+ - Code quality and refactoring principles
55
+ - PR workflow integration
56
+
57
+ #### devops
58
+
59
+ Declarative GitOps infrastructure with FluxCD, Kustomize, Helm, and operators.
60
+
61
+ **Use when:**
62
+
63
+ - Working with Kubernetes manifests
64
+ - Infrastructure in /infra or /k8s
65
+ - CI/CD and deployment configurations
66
+
67
+ **Key features:**
68
+
69
+ - GitOps workflows
70
+ - Operator-first approach
71
+ - SemVer with release candidates
72
+
73
+ #### app
74
+
75
+ Expo + React Native applications with props-first architecture and offline awareness.
76
+
77
+ **Use when:**
78
+
79
+ - Mobile app development with Expo
80
+ - React Native projects in /apps/app
81
+ - Cross-platform mobile development
82
+
83
+ **Key features:**
84
+
85
+ - Shared design tokens with frontend
86
+ - Offline-first architecture
87
+ - Expo integration
88
+
89
+ ### Subagents
90
+
91
+ #### security
92
+
93
+ Security specialist for penetration testing, OWASP compliance, and vulnerability assessments.
94
+
95
+ **Use when:**
96
+
97
+ - Need security review of code changes
98
+ - OWASP Top 10 compliance checks
99
+ - Vulnerability assessments
100
+
101
+ **Key features:**
102
+
103
+ - OWASP standards compliance
104
+ - Security best practices
105
+ - Actionable remediation strategies
106
+
107
+ #### quality
108
+
109
+ Quality assurance specialist for testing, building, and PR management.
110
+
111
+ **Use when:**
112
+
113
+ - Need to run test suites and build processes
114
+ - Creating or updating pull requests
115
+ - Monitoring GitHub for reviewer comments
116
+ - Ensuring code quality standards
117
+
118
+ **Key features:**
119
+
120
+ - Comprehensive testing and building workflows
121
+ - PR creation and management
122
+ - GitHub integration for reviewer feedback
123
+ - CLI command expertise for quality assurance
124
+
125
+ ## Usage
126
+
127
+ ### Switching Agents
128
+
129
+ Use the `<tab>` key to cycle through primary agents during a session.
130
+
131
+ ### Manual Agent Selection
132
+
133
+ Use commands to switch to specific agents:
134
+
135
+ - `/fullstack` - Switch to Fullstack agent
136
+ - `/frontend` - Switch to Frontend agent
137
+ - `/backend` - Switch to Backend agent
138
+ - `/devops` - Switch to DevOps agent
139
+ - `/app` - Switch to App agent
140
+ - `/quality` - Switch to Quality agent for testing and PR management
141
+
142
+ ### Using Subagents
143
+
144
+ Mention subagents with `@` symbol:
145
+
146
+ ```
147
+ @security review this authentication implementation
148
+ @quality run tests and create PR for these changes
149
+ ```
150
+
151
+ ## Routing Rules
152
+
153
+ The fullstack agent automatically routes tasks based on file patterns:
154
+
155
+ - `/apps/frontend` or `.tsx` files → frontend
156
+ - `/apps/app` or Expo/React Native → app
157
+ - `/infra`, `/k8s`, FluxCD, Helm → devops
158
+ - `/services`, Koa routers → backend
159
+
160
+ ## Configuration
161
+
162
+ All agents are configured in `opencode.json` with:
163
+
164
+ - Specialized prompts and temperature settings
165
+ - Appropriate tool permissions
166
+ - Model optimizations for their specific tasks
167
+
168
+ ## Environment Setup
169
+
170
+ Copy `.env.example` to `.env` and configure:
171
+
172
+ ```
173
+ BERGET_API_KEY=your_api_key_here
174
+ ```
175
+
176
+ ## Workflow
177
+
178
+ All agents follow these principles:
179
+
180
+ - Never work directly in main branch
181
+ - Follow branch strategy and commit conventions
182
+ - Create PRs for new functionality
183
+ - Run tests before committing
184
+ - Address reviewer feedback promptly
package/TODO.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # Berget CLI - TODO
2
2
 
3
3
  ## Implementerade funktioner
4
+
4
5
  - [x] Inloggning med BankID
5
6
  - [x] Skapa och hantera API-nycklar
6
7
 
7
8
  ## Kommande funktioner
9
+
8
10
  - [ ] Implementera riktiga API-anrop för klusterhantering
9
11
  - [ ] Implementera riktiga API-anrop för Flux-integration
10
12
  - [ ] Implementera riktiga API-anrop för Helm-kommandon
package/blog-post.md ADDED
@@ -0,0 +1,176 @@
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._
package/dist/index.js CHANGED
@@ -19,7 +19,8 @@ commander_1.program
19
19
  | |_/ / __/ | | (_| | __/ |_ | | | |_| |_
20
20
  \\____/ \\___|_| \\__, |\\___|\\_\\_ \\_| |_/\\___/
21
21
  __/ |
22
- |___/ AI on European terms`)
22
+ |___/ AI on European terms
23
+ Version: ${package_json_1.version}`)
23
24
  .version(package_json_1.version, '-v, --version')
24
25
  .option('--local', 'Use local API endpoint (hidden)', false)
25
26
  .option('--debug', 'Enable debug output', false);
@@ -34,19 +35,21 @@ if (process.argv.length <= 2) {
34
35
  console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget auth login')} - Log in to Berget`));
35
36
  console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget models list')} - List available AI models`));
36
37
  console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget chat run')} - Start a chat session`));
38
+ console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget code init')} - Initialize AI coding assistant`));
37
39
  console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget api-keys list')} - List your API keys`));
38
40
  console.log(chalk_1.default.blue(`\nRun ${chalk_1.default.bold('berget --help')} for a complete list of commands.`));
39
41
  }
40
42
  // Add helpful suggestions for common command mistakes
41
43
  const commonMistakes = {
42
- 'login': 'auth login',
43
- 'logout': 'auth logout',
44
- 'whoami': 'auth whoami',
44
+ login: 'auth login',
45
+ logout: 'auth logout',
46
+ whoami: 'auth whoami',
45
47
  'list-models': 'models list',
46
48
  'list-keys': 'api-keys list',
47
49
  'create-key': 'api-keys create',
48
50
  'list-clusters': 'clusters list',
49
- 'usage': 'billing usage'
51
+ usage: 'billing usage',
52
+ init: 'code init',
50
53
  };
51
54
  // Add error handler for unknown commands
52
55
  commander_1.program.on('command:*', (operands) => {
@@ -58,11 +61,11 @@ commander_1.program.on('command:*', (operands) => {
58
61
  }
59
62
  else {
60
63
  // Try to find similar commands
61
- const availableCommands = commander_1.program.commands.map(cmd => cmd.name());
62
- const similarCommands = availableCommands.filter(cmd => cmd.includes(unknownCommand) || unknownCommand.includes(cmd));
64
+ const availableCommands = commander_1.program.commands.map((cmd) => cmd.name());
65
+ const similarCommands = availableCommands.filter((cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd));
63
66
  if (similarCommands.length > 0) {
64
67
  console.log(chalk_1.default.yellow('Similar commands:'));
65
- similarCommands.forEach(cmd => {
68
+ similarCommands.forEach((cmd) => {
66
69
  console.log(chalk_1.default.yellow(` ${chalk_1.default.bold(`berget ${cmd}`)}`));
67
70
  });
68
71
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "berget",
3
- "version": "1.4.0",
3
+ "version": "2.0.1",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "berget": "dist/index.js"
@@ -24,6 +24,7 @@
24
24
  "license": "MIT",
25
25
  "description": "This is a cli command for interacting with the AI infrastructure provider Berget",
26
26
  "devDependencies": {
27
+ "@types/dotenv": "^6.1.1",
27
28
  "@types/marked": "^5.0.2",
28
29
  "@types/marked-terminal": "^6.1.1",
29
30
  "@types/node": "^20.11.20",
@@ -32,14 +33,18 @@
32
33
  "vitest": "^1.0.0"
33
34
  },
34
35
  "dependencies": {
36
+ "ajv": "^8.17.1",
37
+ "ajv-formats": "^3.0.1",
35
38
  "chalk": "^4.1.2",
36
39
  "commander": "^12.0.0",
40
+ "dotenv": "^17.2.3",
37
41
  "fs-extra": "^11.3.0",
38
42
  "marked": "^9.1.6",
39
43
  "marked-terminal": "^6.2.0",
40
44
  "open": "^9.1.0",
41
45
  "openapi-fetch": "^0.9.1",
42
46
  "openapi-typescript": "^6.7.4",
43
- "readline": "^1.3.0"
47
+ "readline": "^1.3.0",
48
+ "zod": "^4.1.12"
44
49
  }
45
50
  }
@@ -46,7 +46,9 @@ function registerApiKeyCommands(program) {
46
46
  chalk_1.default.dim('LAST USED'));
47
47
  console.log(chalk_1.default.dim('─'.repeat(85)));
48
48
  keys.forEach((key) => {
49
- const lastUsed = key.lastUsed ? key.lastUsed.substring(0, 10) : 'Never';
49
+ const lastUsed = key.lastUsed
50
+ ? key.lastUsed.substring(0, 10)
51
+ : 'Never';
50
52
  const status = key.active
51
53
  ? chalk_1.default.green('● Active')
52
54
  : chalk_1.default.red('● Inactive');
@@ -227,7 +229,7 @@ function registerApiKeyCommands(program) {
227
229
  try {
228
230
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
229
231
  const keys = yield apiKeyService.list();
230
- const selectedKey = keys.find(key => key.id.toString() === id);
232
+ const selectedKey = keys.find((key) => key.id.toString() === id);
231
233
  if (!selectedKey) {
232
234
  console.error(chalk_1.default.red(`Error: API key with ID ${id} not found`));
233
235
  return;
@@ -230,7 +230,7 @@ function registerChatCommands(program) {
230
230
  messages: messages,
231
231
  temperature: options.temperature !== undefined ? options.temperature : 0.7,
232
232
  max_tokens: options.maxTokens || 4096,
233
- stream: options.stream !== false
233
+ stream: options.stream !== false,
234
234
  };
235
235
  // Only add apiKey if it actually exists
236
236
  if (apiKey) {
@@ -241,7 +241,10 @@ function registerChatCommands(program) {
241
241
  let assistantResponse = '';
242
242
  // Stream the response in real-time
243
243
  completionOptions.onChunk = (chunk) => {
244
- if (chunk.choices && chunk.choices[0] && chunk.choices[0].delta && chunk.choices[0].delta.content) {
244
+ if (chunk.choices &&
245
+ chunk.choices[0] &&
246
+ chunk.choices[0].delta &&
247
+ chunk.choices[0].delta.content) {
245
248
  const content = chunk.choices[0].delta.content;
246
249
  try {
247
250
  process.stdout.write(content);
@@ -267,7 +270,10 @@ function registerChatCommands(program) {
267
270
  completionOptions.stream = false;
268
271
  delete completionOptions.onChunk;
269
272
  const response = yield chatService.createCompletion(completionOptions);
270
- if (response && response.choices && response.choices[0] && response.choices[0].message) {
273
+ if (response &&
274
+ response.choices &&
275
+ response.choices[0] &&
276
+ response.choices[0].message) {
271
277
  assistantResponse = response.choices[0].message.content;
272
278
  console.log(assistantResponse);
273
279
  }
@@ -332,7 +338,7 @@ function registerChatCommands(program) {
332
338
  messages: messages,
333
339
  temperature: options.temperature !== undefined ? options.temperature : 0.7,
334
340
  max_tokens: options.maxTokens || 4096,
335
- stream: options.stream !== false
341
+ stream: options.stream !== false,
336
342
  };
337
343
  // Only add apiKey if it actually exists
338
344
  if (apiKey) {
@@ -344,7 +350,10 @@ function registerChatCommands(program) {
344
350
  console.log(chalk_1.default.blue('Assistant: '));
345
351
  // Stream the response in real-time
346
352
  completionOptions.onChunk = (chunk) => {
347
- if (chunk.choices && chunk.choices[0] && chunk.choices[0].delta && chunk.choices[0].delta.content) {
353
+ if (chunk.choices &&
354
+ chunk.choices[0] &&
355
+ chunk.choices[0].delta &&
356
+ chunk.choices[0].delta.content) {
348
357
  const content = chunk.choices[0].delta.content;
349
358
  try {
350
359
  process.stdout.write(content);
@@ -370,7 +379,10 @@ function registerChatCommands(program) {
370
379
  completionOptions.stream = false;
371
380
  delete completionOptions.onChunk;
372
381
  const response = yield chatService.createCompletion(completionOptions);
373
- if (response && response.choices && response.choices[0] && response.choices[0].message) {
382
+ if (response &&
383
+ response.choices &&
384
+ response.choices[0] &&
385
+ response.choices[0].message) {
374
386
  assistantResponse = response.choices[0].message.content;
375
387
  console.log(assistantResponse);
376
388
  }
@@ -379,7 +391,7 @@ function registerChatCommands(program) {
379
391
  // Add assistant response to messages
380
392
  messages.push({
381
393
  role: 'assistant',
382
- content: assistantResponse
394
+ content: assistantResponse,
383
395
  });
384
396
  // Continue the conversation
385
397
  askQuestion();
@@ -492,8 +504,7 @@ function registerChatCommands(program) {
492
504
  }
493
505
  console.log(chalk_1.default.bold('Available Chat Models:'));
494
506
  console.log(chalk_1.default.dim('─'.repeat(70)));
495
- console.log(chalk_1.default.dim('MODEL ID'.padEnd(40)) +
496
- chalk_1.default.dim('CAPABILITIES'));
507
+ console.log(chalk_1.default.dim('MODEL ID'.padEnd(40)) + chalk_1.default.dim('CAPABILITIES'));
497
508
  console.log(chalk_1.default.dim('─'.repeat(70)));
498
509
  // Filter to only show active models
499
510
  const activeModels = models.data.filter((model) => model.active === true);
@@ -507,8 +518,7 @@ function registerChatCommands(program) {
507
518
  capabilities.push('json_mode');
508
519
  // Format model ID in Huggingface compatible format (owner/model)
509
520
  const modelId = `${model.owned_by.toLowerCase()}/${model.id}`.padEnd(40);
510
- console.log(modelId +
511
- capabilities.join(', '));
521
+ console.log(modelId + capabilities.join(', '));
512
522
  });
513
523
  }
514
524
  catch (error) {