@kapeta/local-cluster-service 0.51.1 → 0.51.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [0.51.2](https://github.com/kapetacom/local-cluster-service/compare/v0.51.1...v0.51.2) (2024-06-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * collect generated screens & write these ([50fa728](https://github.com/kapetacom/local-cluster-service/commit/50fa728fea26c0baad2c37b821602b3ca3c46679))
7
+ * merge errors ([92fae09](https://github.com/kapetacom/local-cluster-service/commit/92fae09bc226e7c6128a0a7ae4123ffe810ebe04))
8
+
1
9
  ## [0.51.1](https://github.com/kapetacom/local-cluster-service/compare/v0.51.0...v0.51.1) (2024-06-05)
2
10
 
3
11
 
@@ -27,7 +27,6 @@ export declare class StormCodegen {
27
27
  private processBlockCode;
28
28
  private verifyAndFixCode;
29
29
  removePrefix(prefix: string, str: string): string;
30
- writeToFile(fileName: string, code: Promise<string>): Promise<void>;
31
30
  /**
32
31
  * Sends the code to the AI for a fix
33
32
  */
@@ -42,6 +42,7 @@ const path_1 = __importStar(require("path"));
42
42
  const node_os_1 = __importDefault(require("node:os"));
43
43
  const fs_1 = require("fs");
44
44
  const path_2 = __importDefault(require("path"));
45
+ const yaml_1 = __importDefault(require("yaml"));
45
46
  const SIMULATED_DELAY = 1000;
46
47
  class SimulatedFileDelay {
47
48
  file;
@@ -181,7 +182,7 @@ class StormCodegen {
181
182
  });
182
183
  break;
183
184
  case 'FILE_DONE':
184
- this.handleFileDoneOutput(blockUri, blockName, data);
185
+ return this.handleFileDoneOutput(blockUri, blockName, data);
185
186
  break;
186
187
  }
187
188
  }
@@ -271,6 +272,7 @@ class StormCodegen {
271
272
  }
272
273
  const relevantFiles = allFiles.filter((file) => file.type !== codegen_1.AIFileTypes.IGNORE && file.type !== codegen_1.AIFileTypes.WEB_SCREEN);
273
274
  const uiTemplates = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.WEB_SCREEN);
275
+ const screenFiles = [];
274
276
  if (uiTemplates.length > 0) {
275
277
  const uiStream = await stormClient_1.stormClient.createUIImplementation({
276
278
  events: this.events,
@@ -280,7 +282,10 @@ class StormCodegen {
280
282
  prompt: this.userPrompt,
281
283
  });
282
284
  uiStream.on('data', (evt) => {
283
- this.handleUiOutput((0, nodejs_utils_1.parseKapetaUri)(block.uri), block.aiName, evt);
285
+ const uiFile = this.handleUiOutput((0, nodejs_utils_1.parseKapetaUri)(block.uri), block.aiName, evt);
286
+ if (uiFile != undefined) {
287
+ screenFiles.push(uiFile);
288
+ }
284
289
  });
285
290
  this.out.on('aborted', () => {
286
291
  uiStream.abort();
@@ -309,11 +314,23 @@ class StormCodegen {
309
314
  const filePath = (0, path_1.join)(basePath, serviceFile.filename);
310
315
  await (0, promises_1.writeFile)(filePath, serviceFile.content);
311
316
  }
312
- for (const uiFile of uiTemplates) {
313
- const filePath = (0, path_1.join)(basePath, uiFile.filename);
314
- await (0, promises_1.writeFile)(filePath, uiFile.content);
317
+ const kapetaYmlPath = (0, path_1.join)(basePath, 'kapeta.yml');
318
+ await (0, promises_1.writeFile)(kapetaYmlPath, yaml_1.default.stringify(block.content));
319
+ for (const screenFile of screenFiles) {
320
+ const filePath = (0, path_1.join)(basePath, screenFile.payload.filename);
321
+ await (0, promises_1.writeFile)(filePath, screenFile.payload.content);
315
322
  }
316
- const filesToBeFixed = serviceFiles.concat(contextFiles);
323
+ const screenFilesConverted = screenFiles.map(screenFile => {
324
+ return {
325
+ filename: screenFile.payload.filename,
326
+ content: screenFile.payload.content,
327
+ mode: codegen_1.MODE_CREATE_ONLY,
328
+ permissions: '0644',
329
+ type: codegen_1.AIFileTypes.WEB_SCREEN,
330
+ };
331
+ });
332
+ const filesToBeFixed = serviceFiles.concat(contextFiles).concat(screenFilesConverted);
333
+ allFiles.push(...screenFilesConverted);
317
334
  const codeGenerator = new codegen_1.BlockCodeGenerator(block.content);
318
335
  await this.verifyAndFixCode(codeGenerator, basePath, filesToBeFixed, allFiles);
319
336
  const blockRef = block.uri;
@@ -392,11 +409,6 @@ class StormCodegen {
392
409
  }
393
410
  return str;
394
411
  }
395
- async writeToFile(fileName, code) {
396
- console.log(`writing the fixed code to ${fileName}`);
397
- const resolvedCode = await code;
398
- (0, fs_1.writeFileSync)(fileName, resolvedCode);
399
- }
400
412
  /**
401
413
  * Sends the code to the AI for a fix
402
414
  */
@@ -20,14 +20,15 @@ class StormClient {
20
20
  constructor() {
21
21
  this._baseUrl = (0, utils_1.getRemoteUrl)('ai-service', 'https://ai.kapeta.com');
22
22
  }
23
- createOptions(path, method, body) {
23
+ async createOptions(path, method, body) {
24
24
  const url = `${this._baseUrl}${path}`;
25
25
  const headers = {
26
26
  'Content-Type': 'application/json',
27
27
  };
28
28
  const api = new nodejs_api_client_1.KapetaAPI();
29
29
  if (api.hasToken()) {
30
- //headers['Authorization'] = `Bearer ${api.getAccessToken()}`; //TODO: Enable authentication
30
+ const token = await api.getAccessToken();
31
+ headers['Authorization'] = `Bearer ${token}`;
31
32
  }
32
33
  if (body.conversationId) {
33
34
  headers[exports.ConversationIdHeader] = body.conversationId;
@@ -42,7 +43,7 @@ class StormClient {
42
43
  }
43
44
  async send(path, body, method = 'POST') {
44
45
  const stringPrompt = typeof body.prompt === 'string' ? body.prompt : JSON.stringify(body.prompt);
45
- const options = this.createOptions(path, method, {
46
+ const options = await this.createOptions(path, method, {
46
47
  prompt: stringPrompt,
47
48
  conversationId: body.conversationId,
48
49
  });
@@ -27,7 +27,6 @@ export declare class StormCodegen {
27
27
  private processBlockCode;
28
28
  private verifyAndFixCode;
29
29
  removePrefix(prefix: string, str: string): string;
30
- writeToFile(fileName: string, code: Promise<string>): Promise<void>;
31
30
  /**
32
31
  * Sends the code to the AI for a fix
33
32
  */
@@ -42,6 +42,7 @@ const path_1 = __importStar(require("path"));
42
42
  const node_os_1 = __importDefault(require("node:os"));
43
43
  const fs_1 = require("fs");
44
44
  const path_2 = __importDefault(require("path"));
45
+ const yaml_1 = __importDefault(require("yaml"));
45
46
  const SIMULATED_DELAY = 1000;
46
47
  class SimulatedFileDelay {
47
48
  file;
@@ -181,7 +182,7 @@ class StormCodegen {
181
182
  });
182
183
  break;
183
184
  case 'FILE_DONE':
184
- this.handleFileDoneOutput(blockUri, blockName, data);
185
+ return this.handleFileDoneOutput(blockUri, blockName, data);
185
186
  break;
186
187
  }
187
188
  }
@@ -271,6 +272,7 @@ class StormCodegen {
271
272
  }
272
273
  const relevantFiles = allFiles.filter((file) => file.type !== codegen_1.AIFileTypes.IGNORE && file.type !== codegen_1.AIFileTypes.WEB_SCREEN);
273
274
  const uiTemplates = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.WEB_SCREEN);
275
+ const screenFiles = [];
274
276
  if (uiTemplates.length > 0) {
275
277
  const uiStream = await stormClient_1.stormClient.createUIImplementation({
276
278
  events: this.events,
@@ -280,7 +282,10 @@ class StormCodegen {
280
282
  prompt: this.userPrompt,
281
283
  });
282
284
  uiStream.on('data', (evt) => {
283
- this.handleUiOutput((0, nodejs_utils_1.parseKapetaUri)(block.uri), block.aiName, evt);
285
+ const uiFile = this.handleUiOutput((0, nodejs_utils_1.parseKapetaUri)(block.uri), block.aiName, evt);
286
+ if (uiFile != undefined) {
287
+ screenFiles.push(uiFile);
288
+ }
284
289
  });
285
290
  this.out.on('aborted', () => {
286
291
  uiStream.abort();
@@ -309,11 +314,23 @@ class StormCodegen {
309
314
  const filePath = (0, path_1.join)(basePath, serviceFile.filename);
310
315
  await (0, promises_1.writeFile)(filePath, serviceFile.content);
311
316
  }
312
- for (const uiFile of uiTemplates) {
313
- const filePath = (0, path_1.join)(basePath, uiFile.filename);
314
- await (0, promises_1.writeFile)(filePath, uiFile.content);
317
+ const kapetaYmlPath = (0, path_1.join)(basePath, 'kapeta.yml');
318
+ await (0, promises_1.writeFile)(kapetaYmlPath, yaml_1.default.stringify(block.content));
319
+ for (const screenFile of screenFiles) {
320
+ const filePath = (0, path_1.join)(basePath, screenFile.payload.filename);
321
+ await (0, promises_1.writeFile)(filePath, screenFile.payload.content);
315
322
  }
316
- const filesToBeFixed = serviceFiles.concat(contextFiles);
323
+ const screenFilesConverted = screenFiles.map(screenFile => {
324
+ return {
325
+ filename: screenFile.payload.filename,
326
+ content: screenFile.payload.content,
327
+ mode: codegen_1.MODE_CREATE_ONLY,
328
+ permissions: '0644',
329
+ type: codegen_1.AIFileTypes.WEB_SCREEN,
330
+ };
331
+ });
332
+ const filesToBeFixed = serviceFiles.concat(contextFiles).concat(screenFilesConverted);
333
+ allFiles.push(...screenFilesConverted);
317
334
  const codeGenerator = new codegen_1.BlockCodeGenerator(block.content);
318
335
  await this.verifyAndFixCode(codeGenerator, basePath, filesToBeFixed, allFiles);
319
336
  const blockRef = block.uri;
@@ -392,11 +409,6 @@ class StormCodegen {
392
409
  }
393
410
  return str;
394
411
  }
395
- async writeToFile(fileName, code) {
396
- console.log(`writing the fixed code to ${fileName}`);
397
- const resolvedCode = await code;
398
- (0, fs_1.writeFileSync)(fileName, resolvedCode);
399
- }
400
412
  /**
401
413
  * Sends the code to the AI for a fix
402
414
  */
@@ -20,14 +20,15 @@ class StormClient {
20
20
  constructor() {
21
21
  this._baseUrl = (0, utils_1.getRemoteUrl)('ai-service', 'https://ai.kapeta.com');
22
22
  }
23
- createOptions(path, method, body) {
23
+ async createOptions(path, method, body) {
24
24
  const url = `${this._baseUrl}${path}`;
25
25
  const headers = {
26
26
  'Content-Type': 'application/json',
27
27
  };
28
28
  const api = new nodejs_api_client_1.KapetaAPI();
29
29
  if (api.hasToken()) {
30
- //headers['Authorization'] = `Bearer ${api.getAccessToken()}`; //TODO: Enable authentication
30
+ const token = await api.getAccessToken();
31
+ headers['Authorization'] = `Bearer ${token}`;
31
32
  }
32
33
  if (body.conversationId) {
33
34
  headers[exports.ConversationIdHeader] = body.conversationId;
@@ -42,7 +43,7 @@ class StormClient {
42
43
  }
43
44
  async send(path, body, method = 'POST') {
44
45
  const stringPrompt = typeof body.prompt === 'string' ? body.prompt : JSON.stringify(body.prompt);
45
- const options = this.createOptions(path, method, {
46
+ const options = await this.createOptions(path, method, {
46
47
  prompt: stringPrompt,
47
48
  conversationId: body.conversationId,
48
49
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.51.1",
3
+ "version": "0.51.2",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -11,6 +11,7 @@ import {
11
11
  CodeWriter,
12
12
  GeneratedFile,
13
13
  GeneratedResult,
14
+ MODE_CREATE_ONLY,
14
15
  } from '@kapeta/codegen';
15
16
  import { BlockDefinition } from '@kapeta/schemas';
16
17
  import { codeGeneratorManager } from '../codeGeneratorManager';
@@ -24,6 +25,7 @@ import path, { join } from 'path';
24
25
  import os from 'node:os';
25
26
  import { readFile, readFileSync, writeFileSync } from 'fs';
26
27
  import Path from 'path';
28
+ import YAML from "yaml";
27
29
 
28
30
  type ImplementationGenerator = (prompt: StormFileImplementationPrompt, conversationId?: string) => Promise<StormStream>;
29
31
 
@@ -128,7 +130,7 @@ export class StormCodegen {
128
130
  }
129
131
  }
130
132
 
131
- private handleUiOutput(blockUri: KapetaURI, blockName: string, data: StormEvent) {
133
+ private handleUiOutput(blockUri: KapetaURI, blockName: string, data: StormEvent): StormEventFileDone | undefined {
132
134
  const blockRef = blockUri.toNormalizedString();
133
135
  const instanceId = StormEventParser.toInstanceIdFromRef(blockRef);
134
136
 
@@ -185,7 +187,7 @@ export class StormCodegen {
185
187
  });
186
188
  break;
187
189
  case 'FILE_DONE':
188
- this.handleFileDoneOutput(blockUri, blockName, data);
190
+ return this.handleFileDoneOutput(blockUri, blockName, data);
189
191
  break;
190
192
  }
191
193
  }
@@ -286,6 +288,7 @@ export class StormCodegen {
286
288
  (file) => file.type !== AIFileTypes.IGNORE && file.type !== AIFileTypes.WEB_SCREEN
287
289
  );
288
290
  const uiTemplates: StormFileInfo[] = allFiles.filter((file) => file.type === AIFileTypes.WEB_SCREEN);
291
+ const screenFiles: StormEventFileDone[] = [];
289
292
  if (uiTemplates.length > 0) {
290
293
  const uiStream = await stormClient.createUIImplementation({
291
294
  events: this.events,
@@ -296,7 +299,10 @@ export class StormCodegen {
296
299
  });
297
300
 
298
301
  uiStream.on('data', (evt) => {
299
- this.handleUiOutput(parseKapetaUri(block.uri), block.aiName, evt);
302
+ const uiFile = this.handleUiOutput(parseKapetaUri(block.uri), block.aiName, evt);
303
+ if (uiFile != undefined) {
304
+ screenFiles.push(uiFile);
305
+ }
300
306
  });
301
307
 
302
308
  this.out.on('aborted', () => {
@@ -343,12 +349,25 @@ export class StormCodegen {
343
349
  await writeFile(filePath, serviceFile.content);
344
350
  }
345
351
 
346
- for (const uiFile of uiTemplates) {
347
- const filePath = join(basePath, uiFile.filename);
348
- await writeFile(filePath, uiFile.content);
352
+ const kapetaYmlPath = join(basePath, 'kapeta.yml');
353
+ await writeFile(kapetaYmlPath, YAML.stringify(block.content as BlockDefinition));
354
+
355
+ for (const screenFile of screenFiles) {
356
+ const filePath = join(basePath, screenFile.payload.filename);
357
+ await writeFile(filePath, screenFile.payload.content);
349
358
  }
350
359
 
351
- const filesToBeFixed = serviceFiles.concat(contextFiles);
360
+ const screenFilesConverted = screenFiles.map(screenFile => {
361
+ return {
362
+ filename: screenFile.payload.filename,
363
+ content: screenFile.payload.content,
364
+ mode: MODE_CREATE_ONLY,
365
+ permissions: '0644',
366
+ type: AIFileTypes.WEB_SCREEN,
367
+ };
368
+ });
369
+ const filesToBeFixed = serviceFiles.concat(contextFiles).concat(screenFilesConverted);
370
+ allFiles.push(...screenFilesConverted);
352
371
  const codeGenerator = new BlockCodeGenerator(block.content as BlockDefinition);
353
372
  await this.verifyAndFixCode(codeGenerator, basePath, filesToBeFixed, allFiles);
354
373
 
@@ -439,11 +458,7 @@ export class StormCodegen {
439
458
  }
440
459
  return str;
441
460
  }
442
- async writeToFile(fileName: string, code: Promise<string>) {
443
- console.log(`writing the fixed code to ${fileName}`);
444
- const resolvedCode = await code;
445
- writeFileSync(fileName, resolvedCode);
446
- }
461
+
447
462
  /**
448
463
  * Sends the code to the AI for a fix
449
464
  */
@@ -26,14 +26,15 @@ class StormClient {
26
26
  this._baseUrl = getRemoteUrl('ai-service', 'https://ai.kapeta.com');
27
27
  }
28
28
 
29
- private createOptions(path: string, method: string, body: StormContextRequest): RequestInit & { url: string } {
29
+ private async createOptions(path: string, method: string, body: StormContextRequest): Promise<RequestInit & { url: string }> {
30
30
  const url = `${this._baseUrl}${path}`;
31
31
  const headers: { [k: string]: string } = {
32
32
  'Content-Type': 'application/json',
33
33
  };
34
34
  const api = new KapetaAPI();
35
35
  if (api.hasToken()) {
36
- //headers['Authorization'] = `Bearer ${api.getAccessToken()}`; //TODO: Enable authentication
36
+ const token = await api.getAccessToken();
37
+ headers['Authorization'] = `Bearer ${token}`;
37
38
  }
38
39
 
39
40
  if (body.conversationId) {
@@ -56,7 +57,7 @@ class StormClient {
56
57
  ): Promise<StormStream> {
57
58
  const stringPrompt = typeof body.prompt === 'string' ? body.prompt : JSON.stringify(body.prompt);
58
59
 
59
- const options = this.createOptions(path, method, {
60
+ const options = await this.createOptions(path, method, {
60
61
  prompt: stringPrompt,
61
62
  conversationId: body.conversationId,
62
63
  });