@kapeta/local-cluster-service 0.54.6 → 0.54.8

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,17 @@
1
+ ## [0.54.8](https://github.com/kapetacom/local-cluster-service/compare/v0.54.7...v0.54.8) (2024-06-24)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * update webrouter handling after template change ([#187](https://github.com/kapetacom/local-cluster-service/issues/187)) ([1c3dffa](https://github.com/kapetacom/local-cluster-service/commit/1c3dffa0f8e44680e9dbdee0acd97bde9a3e42b8))
7
+
8
+ ## [0.54.7](https://github.com/kapetacom/local-cluster-service/compare/v0.54.6...v0.54.7) (2024-06-21)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Forward errors to the UI ([#185](https://github.com/kapetacom/local-cluster-service/issues/185)) ([482a767](https://github.com/kapetacom/local-cluster-service/commit/482a76741315916ed696aea668a6061069eb3404))
14
+
1
15
  ## [0.54.6](https://github.com/kapetacom/local-cluster-service/compare/v0.54.5...v0.54.6) (2024-06-21)
2
16
 
3
17
 
@@ -17,6 +17,7 @@ export declare class StormCodegen {
17
17
  isAborted(): boolean;
18
18
  getStream(): StormStream;
19
19
  private handleTemplateFileOutput;
20
+ private handleError;
20
21
  private handleUiOutput;
21
22
  private handleFileEvents;
22
23
  private handleFileDoneOutput;
@@ -118,6 +118,9 @@ class StormCodegen {
118
118
  return this.out;
119
119
  }
120
120
  handleTemplateFileOutput(blockUri, aiName, data) {
121
+ if (this.handleError(data)) {
122
+ return;
123
+ }
121
124
  if (this.handleFileEvents(blockUri, aiName, data)) {
122
125
  return;
123
126
  }
@@ -126,9 +129,19 @@ class StormCodegen {
126
129
  return this.handleFileDoneOutput(blockUri, aiName, data);
127
130
  }
128
131
  }
132
+ handleError(data) {
133
+ if (data.type === 'ERROR_INTERNAL') {
134
+ this.out.emit('data', data);
135
+ return true;
136
+ }
137
+ return false;
138
+ }
129
139
  handleUiOutput(blockUri, blockName, data) {
130
140
  const blockRef = blockUri.toNormalizedString();
131
141
  const instanceId = event_parser_1.StormEventParser.toInstanceIdFromRef(blockRef);
142
+ if (this.handleError(data)) {
143
+ return;
144
+ }
132
145
  if (this.handleFileEvents(blockUri, blockName, data)) {
133
146
  return;
134
147
  }
@@ -149,7 +162,7 @@ class StormCodegen {
149
162
  case 'FILE_DONE':
150
163
  return this.handleFileDoneOutput(blockUri, blockName, data);
151
164
  default:
152
- console.warn('Unknown event type', data);
165
+ console.warn('Unknown UI event type', data);
153
166
  break;
154
167
  }
155
168
  }
@@ -342,23 +355,8 @@ class StormCodegen {
342
355
  };
343
356
  });
344
357
  allFiles.push(...screenFilesConverted);
345
- const webRouters = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.WEB_ROUTER);
346
- await Promise.all(webRouters.map(async (webRouter) => {
347
- const payload = {
348
- filename: webRouter.filename,
349
- template: webRouter,
350
- context: screenFilesConverted.concat([getScreenEventsFile()]),
351
- prompt: this.userPrompt,
352
- };
353
- const stream = await stormClient_1.stormClient.generateCode(payload);
354
- stream.on('data', (evt) => {
355
- this.handleTemplateFileOutput(blockUri, block.aiName, evt);
356
- });
357
- this.out.on('aborted', () => {
358
- stream.abort();
359
- });
360
- await stream.waitForDone();
361
- }));
358
+ let webRouters = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.WEB_ROUTER);
359
+ webRouters = await this.processTemplates(blockUri, block.aiName, stormClient_1.stormClient.generateCode.bind(stormClient_1.stormClient), webRouters, screenFilesConverted.concat([getScreenEventsFile()]));
362
360
  // Gather the context files for implementation. These will be all be passed to the AI
363
361
  const contextFiles = relevantFiles.filter((file) => ![codegen_1.AIFileTypes.SERVICE, codegen_1.AIFileTypes.WEB_SCREEN, codegen_1.AIFileTypes.WEB_ROUTER].includes(file.type));
364
362
  // Send the service and UI templates to the AI. These will be sent one-by-one in addition to the context files
@@ -382,7 +380,6 @@ class StormCodegen {
382
380
  const filePath = (0, path_2.join)(basePath, serviceFile.filename);
383
381
  await (0, promises_1.writeFile)(filePath, serviceFile.content);
384
382
  }
385
- // Write again after modifications
386
383
  for (const webRouterFile of webRouters) {
387
384
  const filePath = (0, path_2.join)(basePath, webRouterFile.filename);
388
385
  await (0, promises_1.writeFile)(filePath, webRouterFile.content);
@@ -712,11 +709,18 @@ class StormCodegen {
712
709
  for (const changedFile of changedFiles.flat()) {
713
710
  const find = allFiles.find((file) => file.filename === changedFile.payload.filename);
714
711
  if (find) {
715
- result.push({ type: find.type, filename: find.filename, mode: find.mode, permissions: find.permissions,
716
- content: changedFile.payload.content });
712
+ result.push({
713
+ type: find.type,
714
+ filename: find.filename,
715
+ mode: find.mode,
716
+ permissions: find.permissions,
717
+ content: changedFile.payload.content,
718
+ });
717
719
  }
718
720
  else {
719
- console.warn("processTemplates: AI changed a file that wasn't in the input [" + changedFile.payload.filename + "]");
721
+ console.warn("processTemplates: AI changed a file that wasn't in the input [" +
722
+ changedFile.payload.filename +
723
+ ']');
720
724
  }
721
725
  }
722
726
  return result;
@@ -13,7 +13,7 @@ declare class StormClient {
13
13
  createErrorClassification(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
14
14
  createCodeFix(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
15
15
  createErrorDetails(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
16
- generateCode(prompt: StormFileImplementationPrompt, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
16
+ generateCode(prompt: StormFileImplementationPrompt, conversationId?: string): Promise<StormStream>;
17
17
  }
18
18
  export declare const stormClient: StormClient;
19
19
  export {};
@@ -116,10 +116,10 @@ class StormClient {
116
116
  prompt,
117
117
  });
118
118
  }
119
- generateCode(prompt, history, conversationId) {
119
+ generateCode(prompt, conversationId) {
120
120
  return this.send('/v2/code/generate', {
121
- conversationId: conversationId,
122
121
  prompt,
122
+ conversationId: conversationId,
123
123
  });
124
124
  }
125
125
  }
@@ -17,6 +17,7 @@ export declare class StormCodegen {
17
17
  isAborted(): boolean;
18
18
  getStream(): StormStream;
19
19
  private handleTemplateFileOutput;
20
+ private handleError;
20
21
  private handleUiOutput;
21
22
  private handleFileEvents;
22
23
  private handleFileDoneOutput;
@@ -118,6 +118,9 @@ class StormCodegen {
118
118
  return this.out;
119
119
  }
120
120
  handleTemplateFileOutput(blockUri, aiName, data) {
121
+ if (this.handleError(data)) {
122
+ return;
123
+ }
121
124
  if (this.handleFileEvents(blockUri, aiName, data)) {
122
125
  return;
123
126
  }
@@ -126,9 +129,19 @@ class StormCodegen {
126
129
  return this.handleFileDoneOutput(blockUri, aiName, data);
127
130
  }
128
131
  }
132
+ handleError(data) {
133
+ if (data.type === 'ERROR_INTERNAL') {
134
+ this.out.emit('data', data);
135
+ return true;
136
+ }
137
+ return false;
138
+ }
129
139
  handleUiOutput(blockUri, blockName, data) {
130
140
  const blockRef = blockUri.toNormalizedString();
131
141
  const instanceId = event_parser_1.StormEventParser.toInstanceIdFromRef(blockRef);
142
+ if (this.handleError(data)) {
143
+ return;
144
+ }
132
145
  if (this.handleFileEvents(blockUri, blockName, data)) {
133
146
  return;
134
147
  }
@@ -149,7 +162,7 @@ class StormCodegen {
149
162
  case 'FILE_DONE':
150
163
  return this.handleFileDoneOutput(blockUri, blockName, data);
151
164
  default:
152
- console.warn('Unknown event type', data);
165
+ console.warn('Unknown UI event type', data);
153
166
  break;
154
167
  }
155
168
  }
@@ -342,23 +355,8 @@ class StormCodegen {
342
355
  };
343
356
  });
344
357
  allFiles.push(...screenFilesConverted);
345
- const webRouters = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.WEB_ROUTER);
346
- await Promise.all(webRouters.map(async (webRouter) => {
347
- const payload = {
348
- filename: webRouter.filename,
349
- template: webRouter,
350
- context: screenFilesConverted.concat([getScreenEventsFile()]),
351
- prompt: this.userPrompt,
352
- };
353
- const stream = await stormClient_1.stormClient.generateCode(payload);
354
- stream.on('data', (evt) => {
355
- this.handleTemplateFileOutput(blockUri, block.aiName, evt);
356
- });
357
- this.out.on('aborted', () => {
358
- stream.abort();
359
- });
360
- await stream.waitForDone();
361
- }));
358
+ let webRouters = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.WEB_ROUTER);
359
+ webRouters = await this.processTemplates(blockUri, block.aiName, stormClient_1.stormClient.generateCode.bind(stormClient_1.stormClient), webRouters, screenFilesConverted.concat([getScreenEventsFile()]));
362
360
  // Gather the context files for implementation. These will be all be passed to the AI
363
361
  const contextFiles = relevantFiles.filter((file) => ![codegen_1.AIFileTypes.SERVICE, codegen_1.AIFileTypes.WEB_SCREEN, codegen_1.AIFileTypes.WEB_ROUTER].includes(file.type));
364
362
  // Send the service and UI templates to the AI. These will be sent one-by-one in addition to the context files
@@ -382,7 +380,6 @@ class StormCodegen {
382
380
  const filePath = (0, path_2.join)(basePath, serviceFile.filename);
383
381
  await (0, promises_1.writeFile)(filePath, serviceFile.content);
384
382
  }
385
- // Write again after modifications
386
383
  for (const webRouterFile of webRouters) {
387
384
  const filePath = (0, path_2.join)(basePath, webRouterFile.filename);
388
385
  await (0, promises_1.writeFile)(filePath, webRouterFile.content);
@@ -712,11 +709,18 @@ class StormCodegen {
712
709
  for (const changedFile of changedFiles.flat()) {
713
710
  const find = allFiles.find((file) => file.filename === changedFile.payload.filename);
714
711
  if (find) {
715
- result.push({ type: find.type, filename: find.filename, mode: find.mode, permissions: find.permissions,
716
- content: changedFile.payload.content });
712
+ result.push({
713
+ type: find.type,
714
+ filename: find.filename,
715
+ mode: find.mode,
716
+ permissions: find.permissions,
717
+ content: changedFile.payload.content,
718
+ });
717
719
  }
718
720
  else {
719
- console.warn("processTemplates: AI changed a file that wasn't in the input [" + changedFile.payload.filename + "]");
721
+ console.warn("processTemplates: AI changed a file that wasn't in the input [" +
722
+ changedFile.payload.filename +
723
+ ']');
720
724
  }
721
725
  }
722
726
  return result;
@@ -13,7 +13,7 @@ declare class StormClient {
13
13
  createErrorClassification(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
14
14
  createCodeFix(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
15
15
  createErrorDetails(prompt: string, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
16
- generateCode(prompt: StormFileImplementationPrompt, history?: ConversationItem[], conversationId?: string): Promise<StormStream>;
16
+ generateCode(prompt: StormFileImplementationPrompt, conversationId?: string): Promise<StormStream>;
17
17
  }
18
18
  export declare const stormClient: StormClient;
19
19
  export {};
@@ -116,10 +116,10 @@ class StormClient {
116
116
  prompt,
117
117
  });
118
118
  }
119
- generateCode(prompt, history, conversationId) {
119
+ generateCode(prompt, conversationId) {
120
120
  return this.send('/v2/code/generate', {
121
- conversationId: conversationId,
122
121
  prompt,
122
+ conversationId: conversationId,
123
123
  });
124
124
  }
125
125
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.54.6",
3
+ "version": "0.54.8",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -135,6 +135,10 @@ export class StormCodegen {
135
135
  aiName: string,
136
136
  data: StormEvent
137
137
  ): StormEventFileDone | undefined {
138
+ if (this.handleError(data)) {
139
+ return;
140
+ }
141
+
138
142
  if (this.handleFileEvents(blockUri, aiName, data)) {
139
143
  return;
140
144
  }
@@ -145,10 +149,23 @@ export class StormCodegen {
145
149
  }
146
150
  }
147
151
 
152
+ private handleError(data: StormEvent): boolean {
153
+ if (data.type === 'ERROR_INTERNAL') {
154
+ this.out.emit('data', data);
155
+ return true;
156
+ }
157
+
158
+ return false;
159
+ }
160
+
148
161
  private handleUiOutput(blockUri: KapetaURI, blockName: string, data: StormEvent): StormEventFileDone | undefined {
149
162
  const blockRef = blockUri.toNormalizedString();
150
163
  const instanceId = StormEventParser.toInstanceIdFromRef(blockRef);
151
164
 
165
+ if (this.handleError(data)) {
166
+ return;
167
+ }
168
+
152
169
  if (this.handleFileEvents(blockUri, blockName, data)) {
153
170
  return;
154
171
  }
@@ -169,8 +186,9 @@ export class StormCodegen {
169
186
  break;
170
187
  case 'FILE_DONE':
171
188
  return this.handleFileDoneOutput(blockUri, blockName, data);
189
+
172
190
  default:
173
- console.warn('Unknown event type', data);
191
+ console.warn('Unknown UI event type', data);
174
192
  break;
175
193
  }
176
194
  }
@@ -233,7 +251,11 @@ export class StormCodegen {
233
251
  return false;
234
252
  }
235
253
 
236
- private handleFileDoneOutput(blockUri: KapetaURI, aiName: string, data: StormEvent): StormEventFileDone | undefined {
254
+ private handleFileDoneOutput(
255
+ blockUri: KapetaURI,
256
+ aiName: string,
257
+ data: StormEvent
258
+ ): StormEventFileDone | undefined {
237
259
  switch (data.type) {
238
260
  case 'FILE_DONE':
239
261
  const ref = blockUri.toNormalizedString();
@@ -397,28 +419,13 @@ export class StormCodegen {
397
419
  });
398
420
  allFiles.push(...screenFilesConverted);
399
421
 
400
- const webRouters = allFiles.filter((file) => file.type === AIFileTypes.WEB_ROUTER);
401
- await Promise.all(
402
- webRouters.map(async (webRouter) => {
403
- const payload = {
404
- filename: webRouter.filename,
405
- template: webRouter,
406
- context: screenFilesConverted.concat([getScreenEventsFile()]),
407
- prompt: this.userPrompt,
408
- };
409
-
410
- const stream = await stormClient.generateCode(payload);
411
-
412
- stream.on('data', (evt) => {
413
- this.handleTemplateFileOutput(blockUri, block.aiName, evt);
414
- });
415
-
416
- this.out.on('aborted', () => {
417
- stream.abort();
418
- });
419
-
420
- await stream.waitForDone();
421
- })
422
+ let webRouters = allFiles.filter((file) => file.type === AIFileTypes.WEB_ROUTER);
423
+ webRouters = await this.processTemplates(
424
+ blockUri,
425
+ block.aiName,
426
+ stormClient.generateCode.bind(stormClient),
427
+ webRouters,
428
+ screenFilesConverted.concat([getScreenEventsFile()])
422
429
  );
423
430
 
424
431
  // Gather the context files for implementation. These will be all be passed to the AI
@@ -458,7 +465,6 @@ export class StormCodegen {
458
465
  await writeFile(filePath, serviceFile.content);
459
466
  }
460
467
 
461
- // Write again after modifications
462
468
  for (const webRouterFile of webRouters) {
463
469
  const filePath = join(basePath, webRouterFile.filename);
464
470
  await writeFile(filePath, webRouterFile.content);
@@ -906,10 +912,19 @@ export class StormCodegen {
906
912
  for (const changedFile of changedFiles.flat()) {
907
913
  const find = allFiles.find((file) => file.filename === changedFile.payload.filename);
908
914
  if (find) {
909
- result.push({ type: find.type, filename: find.filename, mode: find.mode, permissions: find.permissions,
910
- content: changedFile.payload.content });
915
+ result.push({
916
+ type: find.type,
917
+ filename: find.filename,
918
+ mode: find.mode,
919
+ permissions: find.permissions,
920
+ content: changedFile.payload.content,
921
+ });
911
922
  } else {
912
- console.warn("processTemplates: AI changed a file that wasn't in the input [" + changedFile.payload.filename + "]");
923
+ console.warn(
924
+ "processTemplates: AI changed a file that wasn't in the input [" +
925
+ changedFile.payload.filename +
926
+ ']'
927
+ );
913
928
  }
914
929
  }
915
930
  return result;
@@ -155,10 +155,10 @@ class StormClient {
155
155
  });
156
156
  }
157
157
 
158
- public generateCode(prompt: StormFileImplementationPrompt, history?: ConversationItem[], conversationId?: string) {
158
+ public generateCode(prompt: StormFileImplementationPrompt, conversationId?: string) {
159
159
  return this.send('/v2/code/generate', {
160
- conversationId: conversationId,
161
160
  prompt,
161
+ conversationId: conversationId,
162
162
  });
163
163
  }
164
164
  }