@kapeta/local-cluster-service 0.53.3 → 0.53.5

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,20 @@
1
+ ## [0.53.5](https://github.com/kapetacom/local-cluster-service/compare/v0.53.4...v0.53.5) (2024-06-17)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * actually map to correct api ([dc88af0](https://github.com/kapetacom/local-cluster-service/commit/dc88af0f7a76867ed9f96e5653a1ceb7f9002f6d))
7
+ * pretty ([9efc6ed](https://github.com/kapetacom/local-cluster-service/commit/9efc6edd9bb7717889d37a2d1c0c227b10e57d47))
8
+ * split apis into multiple named resources ([da3b59f](https://github.com/kapetacom/local-cluster-service/commit/da3b59fb238f2035235b452491f3b170768e49d9))
9
+ * use type to determine controller or not ([bb88e9f](https://github.com/kapetacom/local-cluster-service/commit/bb88e9f0d349bc23fc7973e8525578e6dcb1d663))
10
+
11
+ ## [0.53.4](https://github.com/kapetacom/local-cluster-service/compare/v0.53.3...v0.53.4) (2024-06-13)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * handle API_RETRY and MODEL_RETRY events ([e784047](https://github.com/kapetacom/local-cluster-service/commit/e784047fbc7d851e03c5301506ab5d663db9e989))
17
+
1
18
  ## [0.53.3](https://github.com/kapetacom/local-cluster-service/compare/v0.53.2...v0.53.3) (2024-06-13)
2
19
 
3
20
 
@@ -242,9 +242,16 @@ class StormCodegen {
242
242
  const relevantFiles = allFiles.filter((file) => file.type !== codegen_1.AIFileTypes.IGNORE && file.type !== codegen_1.AIFileTypes.WEB_SCREEN);
243
243
  const uiTemplates = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.WEB_SCREEN);
244
244
  const screenFiles = [];
245
+ let filteredEvents = [];
246
+ for (const event of this.events) {
247
+ filteredEvents.push(event);
248
+ if (event.type === 'PLAN_RETRY') {
249
+ filteredEvents = [];
250
+ }
251
+ }
245
252
  if (uiTemplates.length > 0) {
246
253
  const uiStream = await stormClient_1.stormClient.createUIImplementation({
247
- events: this.events,
254
+ events: filteredEvents,
248
255
  templates: uiTemplates,
249
256
  context: relevantFiles,
250
257
  blockName: block.aiName,
@@ -210,6 +210,17 @@ class StormEventParser {
210
210
  evt.payload.toBlockId = StormEventParser.toInstanceId(handle, evt.payload.toComponent);
211
211
  this.connections.push(evt.payload);
212
212
  break;
213
+ case 'API_RETRY':
214
+ Object.values(this.blocks).forEach((block) => {
215
+ block.types = [];
216
+ block.apis = [];
217
+ });
218
+ break;
219
+ case 'MODEL_RETRY':
220
+ Object.values(this.blocks).forEach((block) => {
221
+ block.models = [];
222
+ });
223
+ break;
213
224
  }
214
225
  return this.toResult(handle);
215
226
  }
@@ -373,7 +384,7 @@ class StormEventParser {
373
384
  },
374
385
  };
375
386
  const blockSpec = blockDefinitionInfo.content.spec;
376
- let apiResource = undefined;
387
+ const apiResources = {};
377
388
  let dbResource = undefined;
378
389
  blockInfo.resources.forEach((resource) => {
379
390
  const port = {
@@ -381,10 +392,7 @@ class StormEventParser {
381
392
  };
382
393
  switch (resource.type) {
383
394
  case 'API':
384
- if (apiResource) {
385
- break;
386
- }
387
- apiResource = {
395
+ const apiResource = {
388
396
  kind: this.toResourceKind(resource.type),
389
397
  metadata: {
390
398
  name: resource.name,
@@ -400,6 +408,7 @@ class StormEventParser {
400
408
  },
401
409
  },
402
410
  };
411
+ apiResources[resource.name] = apiResource;
403
412
  blockSpec.providers.push(apiResource);
404
413
  break;
405
414
  case 'CLIENT':
@@ -480,11 +489,28 @@ class StormEventParser {
480
489
  });
481
490
  }
482
491
  });
483
- if (apiResource) {
484
- blockInfo.apis.forEach((api) => {
485
- apiResource.spec.source.value += api + '\n\n';
492
+ blockInfo.apis.forEach((api) => {
493
+ const dslApi = kaplang_core_1.DSLAPIParser.parse(api, {
494
+ ignoreSemantics: true,
486
495
  });
487
- }
496
+ let exactMatch = false;
497
+ if (dslApi[0] && dslApi[0].type == kaplang_core_1.DSLEntityType.CONTROLLER) {
498
+ const name = dslApi[0].name.toLowerCase();
499
+ const apiResourceName = Object.keys(apiResources).find((key) => key.indexOf(name) > -1);
500
+ if (apiResourceName) {
501
+ const exactResource = apiResources[apiResourceName];
502
+ exactResource.spec.source.value += api + '\n\n';
503
+ exactMatch = true;
504
+ }
505
+ }
506
+ if (!exactMatch) {
507
+ // if we couldn't place the given api on the exact resource we just park it on the first
508
+ // available rest resource
509
+ const firstKey = Object.keys(apiResources)[0];
510
+ const firstEntry = apiResources[firstKey];
511
+ firstEntry.spec.source.value += api + '\n\n';
512
+ }
513
+ });
488
514
  blockInfo.types.forEach((type) => {
489
515
  blockSpec.entities.source.value += type + '\n';
490
516
  });
@@ -92,6 +92,14 @@ export interface StormEventCreateDSLResource extends Omit<StormEventCreateDSL, '
92
92
  resourceName?: string;
93
93
  };
94
94
  }
95
+ export interface StormEventCreateDSLRetry {
96
+ type: 'API_RETRY' | 'MODEL_RETRY';
97
+ reason: string;
98
+ created: number;
99
+ payload: {
100
+ error: string[];
101
+ };
102
+ }
95
103
  export interface StormEventError {
96
104
  type: 'INVALID_RESPONSE' | 'ERROR_INTERNAL';
97
105
  reason: string;
@@ -250,4 +258,4 @@ export interface StormEventPhases {
250
258
  phaseType: StormEventPhaseType;
251
259
  };
252
260
  }
253
- export type StormEvent = StormEventCreateBlock | StormEventCreateConnection | StormEventCreatePlanProperties | StormEventInvalidResponse | StormEventPlanRetry | StormEventCreateDSL | StormEventCreateDSLResource | StormEventError | StormEventScreen | StormEventScreenCandidate | StormEventFileLogical | StormEventFileState | StormEventFileDone | StormEventFileChunk | StormEventDone | StormEventDefinitionChange | StormEventErrorClassifier | StormEventCodeFix | StormEventErrorDetails | StormEventBlockReady | StormEventPhases | StormEventBlockStatus;
261
+ export type StormEvent = StormEventCreateBlock | StormEventCreateConnection | StormEventCreatePlanProperties | StormEventInvalidResponse | StormEventPlanRetry | StormEventCreateDSL | StormEventCreateDSLResource | StormEventError | StormEventScreen | StormEventScreenCandidate | StormEventFileLogical | StormEventFileState | StormEventFileDone | StormEventFileChunk | StormEventDone | StormEventDefinitionChange | StormEventErrorClassifier | StormEventCodeFix | StormEventErrorDetails | StormEventBlockReady | StormEventPhases | StormEventBlockStatus | StormEventCreateDSLRetry;
@@ -3,8 +3,12 @@
3
3
  * Copyright 2023 Kapeta Inc.
4
4
  * SPDX-License-Identifier: BUSL-1.1
5
5
  */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
6
9
  Object.defineProperty(exports, "__esModule", { value: true });
7
10
  const event_parser_1 = require("../../src/storm/event-parser");
11
+ const simple_blog_events_json_1 = __importDefault(require("./simple-blog-events.json"));
8
12
  const parserOptions = {
9
13
  serviceKind: 'kapeta/block-service:local',
10
14
  serviceLanguage: 'kapeta/language-target-nodejs-ts:local',
@@ -158,4 +162,18 @@ describe('event-parser', () => {
158
162
  expect(result.plan.spec.connections[0].provider.blockId).toBe(serviceBlockInstance.id);
159
163
  expect(result.plan.spec.connections[0].provider.resourceName).toBe(apiResource?.metadata.name);
160
164
  });
165
+ it('it will split api into correct provider', () => {
166
+ const events = simple_blog_events_json_1.default;
167
+ const parser = new event_parser_1.StormEventParser(parserOptions);
168
+ events.forEach((event) => parser.processEvent('kapeta', event));
169
+ const result = parser.toResult('kapeta');
170
+ const blogService = result.blocks.find((block) => block.aiName === 'blog-service');
171
+ expect(blogService).toBeDefined();
172
+ expect(blogService?.content).toBeDefined();
173
+ const apiProviders = blogService?.content?.spec?.providers?.filter((provider) => provider.kind === 'kapeta/block-type-api:local');
174
+ expect(apiProviders).toBeDefined();
175
+ expect(apiProviders.length).toBe(2);
176
+ expect(apiProviders["0"].spec.source.value).not.toBe('');
177
+ expect(apiProviders["1"].spec.source.value).not.toBe('');
178
+ });
161
179
  });
@@ -0,0 +1,470 @@
1
+ [
2
+ {
3
+ "type": "MODEL_RESPONSE",
4
+ "reason": "",
5
+ "payload": {
6
+ "text": "Certainly! Here's how you can design a simple blog system. It will consist of a backend block for managing posts and users, a frontend block for displaying the blog, and a gateway block for making the blog publicly accessible."
7
+ },
8
+ "created": 1718365003668
9
+ },
10
+ {
11
+ "type": "CREATE_PLAN_PROPERTIES",
12
+ "reason": "Define the properties for the plan itself",
13
+ "payload": {
14
+ "description": "A simple blog system with a backend for managing posts and users, a frontend for displaying the blog, and a gateway for making the blog publicly accessible.",
15
+ "name": "Simple Blog"
16
+ },
17
+ "created": 1718365004184
18
+ },
19
+ {
20
+ "type": "CREATE_BLOCK",
21
+ "reason": "The system needs a backend to handle posts and users",
22
+ "payload": {
23
+ "description": "Handles posts and users",
24
+ "name": "blog-service",
25
+ "resources": [
26
+ {
27
+ "description": "Stores blog posts",
28
+ "name": "posts",
29
+ "type": "DATABASE"
30
+ },
31
+ {
32
+ "description": "Stores user information",
33
+ "name": "users",
34
+ "type": "DATABASE"
35
+ },
36
+ {
37
+ "description": "Handles blog posts",
38
+ "name": "posts",
39
+ "type": "API"
40
+ },
41
+ {
42
+ "description": "Handles user information",
43
+ "name": "users",
44
+ "type": "API"
45
+ },
46
+ {
47
+ "description": "Handles JWT token generation and validation",
48
+ "name": "jwt-provider",
49
+ "type": "JWTPROVIDER"
50
+ },
51
+ {
52
+ "description": "Sends emails for user registration and password reset",
53
+ "name": "smtp-client",
54
+ "type": "SMTPCLIENT"
55
+ }
56
+ ],
57
+ "type": "BACKEND",
58
+ "blockRef": "kapeta://kapeta/blog-service:local",
59
+ "instanceId": "d8d25816-bb83-5797-9881-a6282fe7a20b"
60
+ },
61
+ "created": 1718365005843
62
+ },
63
+ {
64
+ "type": "CREATE_BLOCK",
65
+ "reason": "The system needs a frontend to display the blog",
66
+ "payload": {
67
+ "description": "Displays the blog",
68
+ "name": "blog-ui",
69
+ "resources": [
70
+ {
71
+ "description": "Fetches blog posts from the backend",
72
+ "name": "posts",
73
+ "type": "CLIENT"
74
+ },
75
+ {
76
+ "description": "Handles user authentication and registration",
77
+ "name": "users",
78
+ "type": "CLIENT"
79
+ },
80
+ {
81
+ "description": "Displays the main page of the blog",
82
+ "name": "main",
83
+ "type": "WEBPAGE"
84
+ }
85
+ ],
86
+ "type": "FRONTEND",
87
+ "blockRef": "kapeta://kapeta/blog-ui:local",
88
+ "instanceId": "79761687-1528-5f8f-8036-b8d49e23b49d"
89
+ },
90
+ "created": 1718365006823
91
+ },
92
+ {
93
+ "type": "CREATE_BLOCK",
94
+ "reason": "The system needs a gateway to make the blog publicly accessible",
95
+ "payload": {
96
+ "description": "Makes the blog publicly accessible",
97
+ "name": "gateway",
98
+ "resources": [
99
+ {
100
+ "description": "Makes the posts API public under '/posts' path",
101
+ "name": "posts",
102
+ "path": "/posts",
103
+ "type": "CLIENT"
104
+ },
105
+ {
106
+ "description": "Makes the main page public under '/' path",
107
+ "name": "main",
108
+ "path": "/",
109
+ "type": "WEBFRAGMENT"
110
+ }
111
+ ],
112
+ "type": "GATEWAY",
113
+ "blockRef": "kapeta://kapeta/gateway:local",
114
+ "instanceId": "f7327a25-7fc2-57b6-99e6-1b7e07378790"
115
+ },
116
+ "created": 1718365007689
117
+ },
118
+ {
119
+ "type": "CREATE_CONNECTION",
120
+ "reason": "The frontend needs to fetch blog posts from the backend",
121
+ "payload": {
122
+ "fromComponent": "blog-service",
123
+ "fromResource": "posts",
124
+ "fromResourceType": "API",
125
+ "toComponent": "blog-ui",
126
+ "toResource": "posts",
127
+ "toResourceType": "CLIENT",
128
+ "fromBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
129
+ "toBlockId": "79761687-1528-5f8f-8036-b8d49e23b49d"
130
+ },
131
+ "created": 1718365008108
132
+ },
133
+ {
134
+ "type": "CREATE_CONNECTION",
135
+ "reason": "The frontend needs to handle user authentication and registration",
136
+ "payload": {
137
+ "fromComponent": "blog-service",
138
+ "fromResource": "users",
139
+ "fromResourceType": "API",
140
+ "toComponent": "blog-ui",
141
+ "toResource": "users",
142
+ "toResourceType": "CLIENT",
143
+ "fromBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
144
+ "toBlockId": "79761687-1528-5f8f-8036-b8d49e23b49d"
145
+ },
146
+ "created": 1718365008526
147
+ },
148
+ {
149
+ "type": "CREATE_CONNECTION",
150
+ "reason": "The gateway needs to make the posts API publicly accessible",
151
+ "payload": {
152
+ "fromComponent": "blog-service",
153
+ "fromResource": "posts",
154
+ "fromResourceType": "API",
155
+ "toComponent": "gateway",
156
+ "toResource": "posts",
157
+ "toResourceType": "CLIENT",
158
+ "fromBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
159
+ "toBlockId": "f7327a25-7fc2-57b6-99e6-1b7e07378790"
160
+ },
161
+ "created": 1718365008990
162
+ },
163
+ {
164
+ "type": "CREATE_CONNECTION",
165
+ "reason": "The gateway needs to make the main page publicly accessible",
166
+ "payload": {
167
+ "fromComponent": "blog-ui",
168
+ "fromResource": "main",
169
+ "fromResourceType": "WEBPAGE",
170
+ "toComponent": "gateway",
171
+ "toResource": "main",
172
+ "toResourceType": "WEBFRAGMENT",
173
+ "fromBlockId": "79761687-1528-5f8f-8036-b8d49e23b49d",
174
+ "toBlockId": "f7327a25-7fc2-57b6-99e6-1b7e07378790"
175
+ },
176
+ "created": 1718365009823
177
+ },
178
+ {
179
+ "type": "CREATE_CONNECTION",
180
+ "reason": "The blog service needs to be able to authenticate requests",
181
+ "payload": {
182
+ "fromComponent": "blog-service",
183
+ "fromResource": "jwt-provider",
184
+ "fromResourceType": "JWTPROVIDER",
185
+ "toComponent": "blog-service",
186
+ "toResource": "jwt-consumer",
187
+ "toResourceType": "JWTCONSUMER",
188
+ "fromBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
189
+ "toBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b"
190
+ },
191
+ "created": 1718365009974
192
+ },
193
+ {
194
+ "type": "PLAN_RETRY",
195
+ "reason": "Found issues in the response but will try again",
196
+ "payload": {
197
+ "agent": "plan",
198
+ "errors": [
199
+ "Resource jwt-consumer is not defined for component blog-service in connection: 'blog-service.jwt-provider.JWTPROVIDER' to 'blog-service.jwt-consumer.JWTCONSUMER'"
200
+ ]
201
+ },
202
+ "created": 1718365010012
203
+ },
204
+ {
205
+ "type": "MODEL_RESPONSE",
206
+ "reason": "",
207
+ "payload": {
208
+ "text": "Certainly! Here's how you can design a simple blog system. It will consist of a backend block for managing posts and users, a frontend block for displaying the blog, and a gateway block for making the blog publicly accessible."
209
+ },
210
+ "created": 1718365011059
211
+ },
212
+ {
213
+ "type": "CREATE_PLAN_PROPERTIES",
214
+ "reason": "Define the properties for the plan itself",
215
+ "payload": {
216
+ "description": "A simple blog system with a backend for managing posts and users, a frontend for displaying the blog, and a gateway for making the blog publicly accessible.",
217
+ "name": "Simple Blog"
218
+ },
219
+ "created": 1718365011625
220
+ },
221
+ {
222
+ "type": "CREATE_BLOCK",
223
+ "reason": "The system needs a backend to handle posts and users",
224
+ "payload": {
225
+ "description": "Handles posts and users",
226
+ "name": "blog-service",
227
+ "resources": [
228
+ {
229
+ "description": "Stores blog posts",
230
+ "name": "posts",
231
+ "type": "DATABASE"
232
+ },
233
+ {
234
+ "description": "Stores user information",
235
+ "name": "users",
236
+ "type": "DATABASE"
237
+ },
238
+ {
239
+ "description": "Handles blog posts",
240
+ "name": "posts",
241
+ "type": "API"
242
+ },
243
+ {
244
+ "description": "Handles user information",
245
+ "name": "users",
246
+ "type": "API"
247
+ },
248
+ {
249
+ "description": "Handles JWT token generation and validation",
250
+ "name": "jwt-provider",
251
+ "type": "JWTPROVIDER"
252
+ },
253
+ {
254
+ "description": "Handles JWT token validation",
255
+ "name": "jwt-consumer",
256
+ "type": "JWTCONSUMER"
257
+ },
258
+ {
259
+ "description": "Sends emails for user registration and password reset",
260
+ "name": "smtp-client",
261
+ "type": "SMTPCLIENT"
262
+ }
263
+ ],
264
+ "type": "BACKEND",
265
+ "blockRef": "kapeta://kapeta/blog-service:local",
266
+ "instanceId": "d8d25816-bb83-5797-9881-a6282fe7a20b"
267
+ },
268
+ "created": 1718365013238
269
+ },
270
+ {
271
+ "type": "CREATE_BLOCK",
272
+ "reason": "The system needs a frontend to display the blog",
273
+ "payload": {
274
+ "description": "Displays the blog",
275
+ "name": "blog-ui",
276
+ "resources": [
277
+ {
278
+ "description": "Fetches blog posts from the backend",
279
+ "name": "posts",
280
+ "type": "CLIENT"
281
+ },
282
+ {
283
+ "description": "Handles user authentication and registration",
284
+ "name": "users",
285
+ "type": "CLIENT"
286
+ },
287
+ {
288
+ "description": "Displays the main page of the blog",
289
+ "name": "main",
290
+ "type": "WEBPAGE"
291
+ }
292
+ ],
293
+ "type": "FRONTEND",
294
+ "blockRef": "kapeta://kapeta/blog-ui:local",
295
+ "instanceId": "79761687-1528-5f8f-8036-b8d49e23b49d"
296
+ },
297
+ "created": 1718365014077
298
+ },
299
+ {
300
+ "type": "CREATE_BLOCK",
301
+ "reason": "The system needs a gateway to make the blog publicly accessible",
302
+ "payload": {
303
+ "description": "Makes the blog publicly accessible",
304
+ "name": "gateway",
305
+ "resources": [
306
+ {
307
+ "description": "Makes the posts API public under '/posts' path",
308
+ "name": "posts",
309
+ "path": "/posts",
310
+ "type": "CLIENT"
311
+ },
312
+ {
313
+ "description": "Makes the main page public under '/' path",
314
+ "name": "main",
315
+ "path": "/",
316
+ "type": "WEBFRAGMENT"
317
+ }
318
+ ],
319
+ "type": "GATEWAY",
320
+ "blockRef": "kapeta://kapeta/gateway:local",
321
+ "instanceId": "f7327a25-7fc2-57b6-99e6-1b7e07378790"
322
+ },
323
+ "created": 1718365015029
324
+ },
325
+ {
326
+ "type": "CREATE_CONNECTION",
327
+ "reason": "The frontend needs to fetch blog posts from the backend",
328
+ "payload": {
329
+ "fromComponent": "blog-service",
330
+ "fromResource": "posts",
331
+ "fromResourceType": "API",
332
+ "toComponent": "blog-ui",
333
+ "toResource": "posts",
334
+ "toResourceType": "CLIENT",
335
+ "fromBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
336
+ "toBlockId": "79761687-1528-5f8f-8036-b8d49e23b49d"
337
+ },
338
+ "created": 1718365015463
339
+ },
340
+ {
341
+ "type": "CREATE_CONNECTION",
342
+ "reason": "The frontend needs to handle user authentication and registration",
343
+ "payload": {
344
+ "fromComponent": "blog-service",
345
+ "fromResource": "users",
346
+ "fromResourceType": "API",
347
+ "toComponent": "blog-ui",
348
+ "toResource": "users",
349
+ "toResourceType": "CLIENT",
350
+ "fromBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
351
+ "toBlockId": "79761687-1528-5f8f-8036-b8d49e23b49d"
352
+ },
353
+ "created": 1718365016463
354
+ },
355
+ {
356
+ "type": "CREATE_CONNECTION",
357
+ "reason": "The gateway needs to make the posts API publicly accessible",
358
+ "payload": {
359
+ "fromComponent": "blog-service",
360
+ "fromResource": "posts",
361
+ "fromResourceType": "API",
362
+ "toComponent": "gateway",
363
+ "toResource": "posts",
364
+ "toResourceType": "CLIENT",
365
+ "fromBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
366
+ "toBlockId": "f7327a25-7fc2-57b6-99e6-1b7e07378790"
367
+ },
368
+ "created": 1718365016884
369
+ },
370
+ {
371
+ "type": "CREATE_CONNECTION",
372
+ "reason": "The gateway needs to make the main page publicly accessible",
373
+ "payload": {
374
+ "fromComponent": "blog-ui",
375
+ "fromResource": "main",
376
+ "fromResourceType": "WEBPAGE",
377
+ "toComponent": "gateway",
378
+ "toResource": "main",
379
+ "toResourceType": "WEBFRAGMENT",
380
+ "fromBlockId": "79761687-1528-5f8f-8036-b8d49e23b49d",
381
+ "toBlockId": "f7327a25-7fc2-57b6-99e6-1b7e07378790"
382
+ },
383
+ "created": 1718365017299
384
+ },
385
+ {
386
+ "type": "CREATE_CONNECTION",
387
+ "reason": "The blog service needs to be able to authenticate requests",
388
+ "payload": {
389
+ "fromComponent": "blog-service",
390
+ "fromResource": "jwt-provider",
391
+ "fromResourceType": "JWTPROVIDER",
392
+ "toComponent": "blog-service",
393
+ "toResource": "jwt-consumer",
394
+ "toResourceType": "JWTCONSUMER",
395
+ "fromBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
396
+ "toBlockId": "d8d25816-bb83-5797-9881-a6282fe7a20b"
397
+ },
398
+ "created": 1718365017692
399
+ },
400
+ {
401
+ "type": "CREATE_TYPE",
402
+ "reason": "",
403
+ "payload": {
404
+ "blockName": "blog-service",
405
+ "content": "type Post {\n\tid: string\n\ttitle: string\n\tcontent: string\n\tauthorId: string\n\tcreatedAt: date\n\tupdatedAt: date\n}",
406
+ "blockRef": "kapeta://kapeta/blog-service:local",
407
+ "instanceId": "d8d25816-bb83-5797-9881-a6282fe7a20b"
408
+ },
409
+ "created": 1718365018773
410
+ },
411
+ {
412
+ "type": "CREATE_TYPE",
413
+ "reason": "",
414
+ "payload": {
415
+ "blockName": "blog-service",
416
+ "content": "type User {\n\tid: string\n\tusername: string\n\temail: string\n\tpassword: string\n\tcreatedAt: date\n\tupdatedAt: date\n}",
417
+ "blockRef": "kapeta://kapeta/blog-service:local",
418
+ "instanceId": "d8d25816-bb83-5797-9881-a6282fe7a20b"
419
+ },
420
+ "created": 1718365019329
421
+ },
422
+ {
423
+ "type": "CREATE_API",
424
+ "reason": "",
425
+ "payload": {
426
+ "blockName": "blog-service",
427
+ "content": "controller Post(\"/posts\") {\n\n\t@GET(\"/\")\n\tgetPosts():Post[]\n\t\n\t@GET(\"/{id}\")\n\tgetPost(@Path(\"id\") id:string):Post\n\t\n\t@POST(\"/\")\n\tcreatePost(@Body post:Post):Post\n\t\n\t@PUT(\"/{id}\")\n\tupdatePost(@Path(\"id\") id:string, @Body post:Post):Post\n\t\n\t@DELETE(\"/{id}\")\n\tdeletePost(@Path(\"id\") id:string):void\n}",
428
+ "blockRef": "kapeta://kapeta/blog-service:local",
429
+ "instanceId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
430
+ "resourceName": "posts"
431
+ },
432
+ "created": 1718365020235
433
+ },
434
+ {
435
+ "type": "CREATE_API",
436
+ "reason": "",
437
+ "payload": {
438
+ "blockName": "blog-service",
439
+ "content": "controller User(\"/users\") {\n\n\t@GET(\"/\")\n\tgetUsers():User[]\n\t\n\t@GET(\"/{id}\")\n\tgetUser(@Path(\"id\") id:string):User\n\t\n\t@POST(\"/\")\n\tcreateUser(@Body user:User):User\n\t\n\t@PUT(\"/{id}\")\n\tupdateUser(@Path(\"id\") id:string, @Body user:User):User\n\t\n\t@DELETE(\"/{id}\")\n\tdeleteUser(@Path(\"id\") id:string):void\n}",
440
+ "blockRef": "kapeta://kapeta/blog-service:local",
441
+ "instanceId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
442
+ "resourceName": "posts"
443
+ },
444
+ "created": 1718365020558
445
+ },
446
+ {
447
+ "type": "CREATE_MODEL",
448
+ "reason": "",
449
+ "payload": {
450
+ "blockName": "blog-service",
451
+ "content": "type Post {\n\t@Id\n\tid: string\n\ttitle: string\n\tcontent: string\n\tauthorId: string\n\tcreatedAt: date\n\tupdatedAt: date\n}",
452
+ "blockRef": "kapeta://kapeta/blog-service:local",
453
+ "instanceId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
454
+ "resourceName": "posts"
455
+ },
456
+ "created": 1718365022396
457
+ },
458
+ {
459
+ "type": "CREATE_MODEL",
460
+ "reason": "",
461
+ "payload": {
462
+ "blockName": "blog-service",
463
+ "content": "type User {\n\t@Id\n\tid: string\n\tusername: string\n\temail: string\n\tpassword: string\n\tcreatedAt: date\n\tupdatedAt: date\n}",
464
+ "blockRef": "kapeta://kapeta/blog-service:local",
465
+ "instanceId": "d8d25816-bb83-5797-9881-a6282fe7a20b",
466
+ "resourceName": "posts"
467
+ },
468
+ "created": 1718365022826
469
+ }
470
+ ]
@@ -242,9 +242,16 @@ class StormCodegen {
242
242
  const relevantFiles = allFiles.filter((file) => file.type !== codegen_1.AIFileTypes.IGNORE && file.type !== codegen_1.AIFileTypes.WEB_SCREEN);
243
243
  const uiTemplates = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.WEB_SCREEN);
244
244
  const screenFiles = [];
245
+ let filteredEvents = [];
246
+ for (const event of this.events) {
247
+ filteredEvents.push(event);
248
+ if (event.type === 'PLAN_RETRY') {
249
+ filteredEvents = [];
250
+ }
251
+ }
245
252
  if (uiTemplates.length > 0) {
246
253
  const uiStream = await stormClient_1.stormClient.createUIImplementation({
247
- events: this.events,
254
+ events: filteredEvents,
248
255
  templates: uiTemplates,
249
256
  context: relevantFiles,
250
257
  blockName: block.aiName,