@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 +8 -0
- package/dist/cjs/src/storm/codegen.d.ts +0 -1
- package/dist/cjs/src/storm/codegen.js +23 -11
- package/dist/cjs/src/storm/stormClient.js +4 -3
- package/dist/esm/src/storm/codegen.d.ts +0 -1
- package/dist/esm/src/storm/codegen.js +23 -11
- package/dist/esm/src/storm/stormClient.js +4 -3
- package/package.json +1 -1
- package/src/storm/codegen.ts +27 -12
- package/src/storm/stormClient.ts +4 -3
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
|
-
|
313
|
-
|
314
|
-
|
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
|
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
|
-
|
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
|
-
|
313
|
-
|
314
|
-
|
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
|
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
|
-
|
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
package/src/storm/codegen.ts
CHANGED
@@ -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
|
-
|
347
|
-
|
348
|
-
|
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
|
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
|
-
|
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
|
*/
|
package/src/storm/stormClient.ts
CHANGED
@@ -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
|
-
|
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
|
});
|