@kapeta/local-cluster-service 0.43.3 → 0.45.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/CHANGELOG.md +20 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/src/codeGeneratorManager.d.ts +1 -0
- package/dist/cjs/src/codeGeneratorManager.js +12 -6
- package/dist/cjs/src/middleware/cors.d.ts +1 -0
- package/dist/cjs/src/middleware/kapeta.d.ts +1 -0
- package/dist/cjs/src/middleware/stringBody.d.ts +1 -0
- package/dist/cjs/src/proxy/routes.js +19 -19
- package/dist/cjs/src/proxy/types/rest.d.ts +2 -4
- package/dist/cjs/src/proxy/types/rest.js +45 -6
- package/dist/cjs/src/proxy/types/web.d.ts +2 -4
- package/dist/cjs/src/proxy/types/web.js +2 -2
- package/dist/cjs/src/storm/codegen.d.ts +36 -0
- package/dist/cjs/src/storm/codegen.js +160 -0
- package/dist/cjs/src/storm/event-parser.d.ts +70 -0
- package/dist/cjs/src/storm/event-parser.js +543 -0
- package/dist/cjs/src/storm/events.d.ts +127 -0
- package/dist/cjs/src/storm/events.js +6 -0
- package/dist/cjs/src/storm/routes.d.ts +7 -0
- package/dist/cjs/src/storm/routes.js +109 -0
- package/dist/cjs/src/storm/stormClient.d.ts +13 -0
- package/dist/cjs/src/storm/stormClient.js +87 -0
- package/dist/cjs/src/storm/stream.d.ts +38 -0
- package/dist/cjs/src/storm/stream.js +57 -0
- package/dist/cjs/src/types.d.ts +5 -2
- package/dist/esm/index.js +2 -0
- package/dist/esm/src/codeGeneratorManager.d.ts +1 -0
- package/dist/esm/src/codeGeneratorManager.js +12 -6
- package/dist/esm/src/middleware/cors.d.ts +1 -0
- package/dist/esm/src/middleware/kapeta.d.ts +1 -0
- package/dist/esm/src/middleware/stringBody.d.ts +1 -0
- package/dist/esm/src/proxy/routes.js +19 -19
- package/dist/esm/src/proxy/types/rest.d.ts +2 -4
- package/dist/esm/src/proxy/types/rest.js +45 -6
- package/dist/esm/src/proxy/types/web.d.ts +2 -4
- package/dist/esm/src/proxy/types/web.js +2 -2
- package/dist/esm/src/storm/codegen.d.ts +36 -0
- package/dist/esm/src/storm/codegen.js +160 -0
- package/dist/esm/src/storm/event-parser.d.ts +70 -0
- package/dist/esm/src/storm/event-parser.js +543 -0
- package/dist/esm/src/storm/events.d.ts +127 -0
- package/dist/esm/src/storm/events.js +6 -0
- package/dist/esm/src/storm/routes.d.ts +7 -0
- package/dist/esm/src/storm/routes.js +109 -0
- package/dist/esm/src/storm/stormClient.d.ts +13 -0
- package/dist/esm/src/storm/stormClient.js +87 -0
- package/dist/esm/src/storm/stream.d.ts +38 -0
- package/dist/esm/src/storm/stream.js +57 -0
- package/dist/esm/src/types.d.ts +5 -2
- package/index.ts +2 -0
- package/package.json +6 -3
- package/src/codeGeneratorManager.ts +17 -8
- package/src/proxy/routes.ts +26 -20
- package/src/proxy/types/rest.ts +73 -11
- package/src/proxy/types/web.ts +3 -5
- package/src/storm/codegen.ts +210 -0
- package/src/storm/event-parser.ts +688 -0
- package/src/storm/events.ts +169 -0
- package/src/storm/routes.ts +143 -0
- package/src/storm/stormClient.ts +114 -0
- package/src/storm/stream.ts +88 -0
- package/src/types.ts +5 -2
- package/src/utils/BlockInstanceRunner.ts +4 -2
@@ -0,0 +1,160 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* Copyright 2023 Kapeta Inc.
|
4
|
+
* SPDX-License-Identifier: BUSL-1.1
|
5
|
+
*/
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
7
|
+
exports.StormCodegen = void 0;
|
8
|
+
const codegen_1 = require("@kapeta/codegen");
|
9
|
+
const codeGeneratorManager_1 = require("../codeGeneratorManager");
|
10
|
+
const stormClient_1 = require("./stormClient");
|
11
|
+
const stream_1 = require("./stream");
|
12
|
+
class StormCodegen {
|
13
|
+
userPrompt;
|
14
|
+
blocks;
|
15
|
+
out = new stream_1.StormStream();
|
16
|
+
constructor(userPrompt, blocks) {
|
17
|
+
this.userPrompt = userPrompt;
|
18
|
+
this.blocks = blocks;
|
19
|
+
}
|
20
|
+
async process() {
|
21
|
+
console.log('Processing blocks', this.blocks.length);
|
22
|
+
for (const block of this.blocks) {
|
23
|
+
await this.processBlockCode(block);
|
24
|
+
}
|
25
|
+
this.out.end();
|
26
|
+
}
|
27
|
+
getStream() {
|
28
|
+
return this.out;
|
29
|
+
}
|
30
|
+
handleFileOutput(blockUri, template, data) {
|
31
|
+
switch (data.type) {
|
32
|
+
case 'FILE':
|
33
|
+
template.filename = data.payload.filename;
|
34
|
+
template.content = data.payload.content;
|
35
|
+
this.emitFile(blockUri, data.payload.filename, data.payload.content, data.reason);
|
36
|
+
break;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
/**
|
40
|
+
* Generates the code for a block and sends it to the AI
|
41
|
+
*/
|
42
|
+
async processBlockCode(block) {
|
43
|
+
// Generate the code for the block using the standard codegen templates
|
44
|
+
const generatedResult = await this.generateBlock(block.content, block.screens);
|
45
|
+
if (!generatedResult) {
|
46
|
+
console.warn('No generated result for block', block.uri);
|
47
|
+
return;
|
48
|
+
}
|
49
|
+
const allFiles = this.toStormFiles(generatedResult);
|
50
|
+
// Send all the non-ai files to the stream
|
51
|
+
this.emitFiles(block.uri, allFiles);
|
52
|
+
const implementFiles = [codegen_1.AIFileTypes.SERVICE, codegen_1.AIFileTypes.WEB_SCREEN];
|
53
|
+
// Gather the context files. These will be all be passed to the AI
|
54
|
+
const contextFiles = allFiles.filter((file) => file.type !== codegen_1.AIFileTypes.IGNORE && !implementFiles.includes(file.type));
|
55
|
+
// Send the service and UI templates to the AI. These will be send one-by-one in addition to the context files
|
56
|
+
const serviceFiles = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.SERVICE);
|
57
|
+
await this.processTemplates(block.uri, stormClient_1.stormClient.createServiceImplementation.bind(stormClient_1.stormClient), serviceFiles, contextFiles);
|
58
|
+
//const uiTemplates: StormFileInfo[] = allFiles.filter((file) => file.type === 'ui');
|
59
|
+
//await this.processTemplates(stormClient.createUIImplementation, uiTemplates, contextFiles);
|
60
|
+
}
|
61
|
+
/**
|
62
|
+
* Emits the text-based files to the stream
|
63
|
+
*/
|
64
|
+
emitFiles(uri, files) {
|
65
|
+
files.forEach((file) => {
|
66
|
+
if (!file.content || typeof file.content !== 'string') {
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
if (file.type === codegen_1.AIFileTypes.SERVICE) {
|
70
|
+
// Don't send the service files to the stream yet
|
71
|
+
// They will need to be implemented by the AI
|
72
|
+
return;
|
73
|
+
}
|
74
|
+
if (file.type === codegen_1.AIFileTypes.WEB_SCREEN) {
|
75
|
+
// Don't send the web screen files to the stream yet
|
76
|
+
// They will need to be implemented by the AI
|
77
|
+
return;
|
78
|
+
}
|
79
|
+
this.emitFile(uri, file.filename, file.content);
|
80
|
+
});
|
81
|
+
}
|
82
|
+
emitFile(uri, filename, content, reason = 'File generated') {
|
83
|
+
this.out.emit('data', {
|
84
|
+
type: 'FILE',
|
85
|
+
reason,
|
86
|
+
created: Date.now(),
|
87
|
+
payload: {
|
88
|
+
filename: filename,
|
89
|
+
content: content,
|
90
|
+
blockRef: uri.toNormalizedString(),
|
91
|
+
},
|
92
|
+
});
|
93
|
+
}
|
94
|
+
/**
|
95
|
+
* Sends the template to the AI and processes the response
|
96
|
+
*/
|
97
|
+
processTemplates(blockUri, generator, templates, contextFiles) {
|
98
|
+
const promises = templates.map(async (templateFile) => {
|
99
|
+
const stream = await generator({
|
100
|
+
context: contextFiles,
|
101
|
+
template: templateFile,
|
102
|
+
prompt: this.userPrompt,
|
103
|
+
});
|
104
|
+
stream.on('data', (evt) => this.handleFileOutput(blockUri, templateFile, evt));
|
105
|
+
return stream.waitForDone();
|
106
|
+
});
|
107
|
+
return Promise.all(promises);
|
108
|
+
}
|
109
|
+
/**
|
110
|
+
* Converts the generated files to a format that can be sent to the AI
|
111
|
+
*/
|
112
|
+
toStormFiles(generatedResult) {
|
113
|
+
const allFiles = generatedResult.files.map((file) => {
|
114
|
+
if (!file.content) {
|
115
|
+
return {
|
116
|
+
...file,
|
117
|
+
type: codegen_1.AIFileTypes.IGNORE,
|
118
|
+
};
|
119
|
+
}
|
120
|
+
if (typeof file.content !== 'string') {
|
121
|
+
return {
|
122
|
+
...file,
|
123
|
+
type: codegen_1.AIFileTypes.IGNORE,
|
124
|
+
};
|
125
|
+
}
|
126
|
+
const rx = /\/\/AI-TYPE:([a-z0-9- _]+)\n/gi;
|
127
|
+
const match = rx.exec(file.content);
|
128
|
+
if (!match) {
|
129
|
+
return {
|
130
|
+
...file,
|
131
|
+
type: codegen_1.AIFileTypes.IGNORE,
|
132
|
+
};
|
133
|
+
}
|
134
|
+
const type = match[1].trim();
|
135
|
+
file.content = file.content.replace(rx, '');
|
136
|
+
return {
|
137
|
+
...file,
|
138
|
+
type,
|
139
|
+
};
|
140
|
+
});
|
141
|
+
return allFiles;
|
142
|
+
}
|
143
|
+
/**
|
144
|
+
* Generates the code using codegen for a given block.
|
145
|
+
*/
|
146
|
+
async generateBlock(yamlContent, screens) {
|
147
|
+
if (!yamlContent.spec.target?.kind) {
|
148
|
+
//Not all block types have targets
|
149
|
+
return;
|
150
|
+
}
|
151
|
+
if (!(await codeGeneratorManager_1.codeGeneratorManager.ensureTarget(yamlContent.spec.target?.kind))) {
|
152
|
+
return;
|
153
|
+
}
|
154
|
+
const codeGenerator = new codegen_1.BlockCodeGenerator(yamlContent);
|
155
|
+
codeGenerator.withOption('AIContext', stormClient_1.STORM_ID);
|
156
|
+
codeGenerator.withOption('AIScreens', screens ?? []);
|
157
|
+
return codeGenerator.generate();
|
158
|
+
}
|
159
|
+
}
|
160
|
+
exports.StormCodegen = StormCodegen;
|
@@ -0,0 +1,70 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2023 Kapeta Inc.
|
3
|
+
* SPDX-License-Identifier: BUSL-1.1
|
4
|
+
*/
|
5
|
+
import { ScreenTemplate, StormEvent } from './events';
|
6
|
+
import { BlockDefinition, Plan } from '@kapeta/schemas';
|
7
|
+
import { KapetaURI } from '@kapeta/nodejs-utils';
|
8
|
+
export interface BlockDefinitionInfo {
|
9
|
+
uri: KapetaURI;
|
10
|
+
content: BlockDefinition;
|
11
|
+
screens: ScreenTemplate[];
|
12
|
+
}
|
13
|
+
export interface ParsedResult {
|
14
|
+
plan: Plan;
|
15
|
+
blocks: BlockDefinitionInfo[];
|
16
|
+
}
|
17
|
+
export interface StormOptions {
|
18
|
+
databaseKind: string;
|
19
|
+
apiKind: string;
|
20
|
+
clientKind: string;
|
21
|
+
webPageKind: string;
|
22
|
+
webFragmentKind: string;
|
23
|
+
mqKind: string;
|
24
|
+
serviceKind: string;
|
25
|
+
serviceLanguage: string;
|
26
|
+
frontendKind: string;
|
27
|
+
frontendLanguage: string;
|
28
|
+
exchangeKind: string;
|
29
|
+
queueKind: string;
|
30
|
+
publisherKind: string;
|
31
|
+
subscriberKind: string;
|
32
|
+
jwtProviderKind: string;
|
33
|
+
jwtConsumerKind: string;
|
34
|
+
smtpKind: string;
|
35
|
+
externalApiKind: string;
|
36
|
+
cliKind: string;
|
37
|
+
cliLanguage: string;
|
38
|
+
desktopKind: string;
|
39
|
+
desktopLanguage: string;
|
40
|
+
gatewayKind: string;
|
41
|
+
}
|
42
|
+
export declare function resolveOptions(): Promise<StormOptions>;
|
43
|
+
export declare class StormEventParser {
|
44
|
+
private events;
|
45
|
+
private planName;
|
46
|
+
private planDescription;
|
47
|
+
private blocks;
|
48
|
+
private connections;
|
49
|
+
private failed;
|
50
|
+
private error;
|
51
|
+
private options;
|
52
|
+
constructor(options: StormOptions);
|
53
|
+
private reset;
|
54
|
+
addEvent(evt: StormEvent): void;
|
55
|
+
getEvents(): StormEvent[];
|
56
|
+
isValid(): boolean;
|
57
|
+
getError(): string;
|
58
|
+
private applyLayoutToBlocks;
|
59
|
+
toResult(handle: string): ParsedResult;
|
60
|
+
private toSafeName;
|
61
|
+
private toRef;
|
62
|
+
toBlockDefinitions(handle: string): {
|
63
|
+
[key: string]: BlockDefinitionInfo;
|
64
|
+
};
|
65
|
+
private toResourceKind;
|
66
|
+
private toBlockKind;
|
67
|
+
private toPortType;
|
68
|
+
private toBlockTarget;
|
69
|
+
private toBlockTargetKind;
|
70
|
+
}
|