@kapeta/local-cluster-service 0.67.0 → 0.67.1

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,10 @@
1
+ ## [0.67.1](https://github.com/kapetacom/local-cluster-service/compare/v0.67.0...v0.67.1) (2024-08-28)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * edit bulk pages in parallel using the page agent ([#227](https://github.com/kapetacom/local-cluster-service/issues/227)) ([ac0d5d6](https://github.com/kapetacom/local-cluster-service/commit/ac0d5d611d9a3b84119b3ff5a272c2f2293236a1))
7
+
1
8
  # [0.67.0](https://github.com/kapetacom/local-cluster-service/compare/v0.66.0...v0.67.0) (2024-08-27)
2
9
 
3
10
 
@@ -382,58 +382,40 @@ router.post('/:handle/ui', async (req, res) => {
382
382
  });
383
383
  router.post('/ui/edit', async (req, res) => {
384
384
  try {
385
- const conversationId = req.headers[stormClient_1.ConversationIdHeader.toLowerCase()];
385
+ const systemId = (req.headers[page_utils_1.SystemIdHeader.toLowerCase()] ||
386
+ req.headers[stormClient_1.ConversationIdHeader.toLowerCase()]);
386
387
  const aiRequest = JSON.parse(req.stringBody ?? '{}');
387
- const pages = aiRequest.prompt.pages
388
- .map((page) => {
389
- const content = (0, page_utils_1.readPageFromDiskAsString)(conversationId, page.path, page.method);
390
- if (!content) {
391
- console.warn('Page not found', page);
392
- return undefined;
393
- }
394
- return {
395
- filename: page.filename,
396
- path: page.path,
397
- method: page.method,
398
- title: page.title,
399
- conversationId: page.conversationId,
400
- prompt: page.prompt,
401
- name: page.name,
402
- description: page.description,
403
- content,
404
- };
405
- })
406
- .filter((page) => !!page);
407
- const editStream = await stormClient_1.stormClient.editPages({
408
- prompt: aiRequest.prompt.prompt.prompt,
409
- blockDescription: aiRequest.prompt.blockDescription,
410
- planDescription: aiRequest.prompt.planDescription,
411
- pages,
412
- }, conversationId);
388
+ const storagePrefix = systemId ? systemId + '_' : 'mock_';
389
+ const queue = new PageGenerator_1.PageQueue(storagePrefix, 5);
413
390
  onRequestAborted(req, res, () => {
414
- editStream.abort();
391
+ queue.cancel();
415
392
  });
416
- res.set('Content-Type', 'application/x-ndjson');
417
- res.set('Access-Control-Expose-Headers', stormClient_1.ConversationIdHeader);
418
- res.set(stormClient_1.ConversationIdHeader, editStream.getConversationId());
419
393
  const promises = [];
420
- editStream.on('data', (data) => {
421
- try {
422
- if (data.type === 'PAGE') {
423
- promises.push(sendPageEvent(editStream.getConversationId(), data, res));
424
- }
425
- else {
426
- sendEvent(res, data);
427
- }
394
+ queue.on('page', (data) => {
395
+ if (systemId) {
396
+ promises.push(sendPageEvent(systemId, data, res));
428
397
  }
429
- catch (e) {
430
- console.error('Failed to process event', e);
398
+ });
399
+ queue.on('event', (data) => {
400
+ if (data.type === 'FILE_START' || data.type === 'FILE_DONE' || data.type === 'FILE_STATE') {
401
+ sendEvent(res, data);
431
402
  }
432
403
  });
433
- await waitForStormStream(editStream);
434
- if (editStream.isAborted()) {
435
- return;
436
- }
404
+ await Promise.allSettled(aiRequest.prompt.pages.map((page) => {
405
+ if (page.conversationId) {
406
+ return queue.addPrompt({
407
+ title: page.title,
408
+ name: page.name,
409
+ method: page.method,
410
+ path: page.path,
411
+ description: page.description ?? '',
412
+ filename: page.filename,
413
+ prompt: aiRequest.prompt.prompt.prompt,
414
+ storage_prefix: storagePrefix,
415
+ }, page.conversationId, true);
416
+ }
417
+ }));
418
+ await queue.wait();
437
419
  await Promise.all(promises);
438
420
  sendDone(res);
439
421
  }
@@ -24,7 +24,7 @@ export interface UIPagePrompt {
24
24
  description: string;
25
25
  storage_prefix: string;
26
26
  shell_page?: string;
27
- theme: string;
27
+ theme?: string;
28
28
  }
29
29
  export interface UIPageSamplePrompt extends UIPagePrompt {
30
30
  variantId: string;
@@ -382,58 +382,40 @@ router.post('/:handle/ui', async (req, res) => {
382
382
  });
383
383
  router.post('/ui/edit', async (req, res) => {
384
384
  try {
385
- const conversationId = req.headers[stormClient_1.ConversationIdHeader.toLowerCase()];
385
+ const systemId = (req.headers[page_utils_1.SystemIdHeader.toLowerCase()] ||
386
+ req.headers[stormClient_1.ConversationIdHeader.toLowerCase()]);
386
387
  const aiRequest = JSON.parse(req.stringBody ?? '{}');
387
- const pages = aiRequest.prompt.pages
388
- .map((page) => {
389
- const content = (0, page_utils_1.readPageFromDiskAsString)(conversationId, page.path, page.method);
390
- if (!content) {
391
- console.warn('Page not found', page);
392
- return undefined;
393
- }
394
- return {
395
- filename: page.filename,
396
- path: page.path,
397
- method: page.method,
398
- title: page.title,
399
- conversationId: page.conversationId,
400
- prompt: page.prompt,
401
- name: page.name,
402
- description: page.description,
403
- content,
404
- };
405
- })
406
- .filter((page) => !!page);
407
- const editStream = await stormClient_1.stormClient.editPages({
408
- prompt: aiRequest.prompt.prompt.prompt,
409
- blockDescription: aiRequest.prompt.blockDescription,
410
- planDescription: aiRequest.prompt.planDescription,
411
- pages,
412
- }, conversationId);
388
+ const storagePrefix = systemId ? systemId + '_' : 'mock_';
389
+ const queue = new PageGenerator_1.PageQueue(storagePrefix, 5);
413
390
  onRequestAborted(req, res, () => {
414
- editStream.abort();
391
+ queue.cancel();
415
392
  });
416
- res.set('Content-Type', 'application/x-ndjson');
417
- res.set('Access-Control-Expose-Headers', stormClient_1.ConversationIdHeader);
418
- res.set(stormClient_1.ConversationIdHeader, editStream.getConversationId());
419
393
  const promises = [];
420
- editStream.on('data', (data) => {
421
- try {
422
- if (data.type === 'PAGE') {
423
- promises.push(sendPageEvent(editStream.getConversationId(), data, res));
424
- }
425
- else {
426
- sendEvent(res, data);
427
- }
394
+ queue.on('page', (data) => {
395
+ if (systemId) {
396
+ promises.push(sendPageEvent(systemId, data, res));
428
397
  }
429
- catch (e) {
430
- console.error('Failed to process event', e);
398
+ });
399
+ queue.on('event', (data) => {
400
+ if (data.type === 'FILE_START' || data.type === 'FILE_DONE' || data.type === 'FILE_STATE') {
401
+ sendEvent(res, data);
431
402
  }
432
403
  });
433
- await waitForStormStream(editStream);
434
- if (editStream.isAborted()) {
435
- return;
436
- }
404
+ await Promise.allSettled(aiRequest.prompt.pages.map((page) => {
405
+ if (page.conversationId) {
406
+ return queue.addPrompt({
407
+ title: page.title,
408
+ name: page.name,
409
+ method: page.method,
410
+ path: page.path,
411
+ description: page.description ?? '',
412
+ filename: page.filename,
413
+ prompt: aiRequest.prompt.prompt.prompt,
414
+ storage_prefix: storagePrefix,
415
+ }, page.conversationId, true);
416
+ }
417
+ }));
418
+ await queue.wait();
437
419
  await Promise.all(promises);
438
420
  sendDone(res);
439
421
  }
@@ -24,7 +24,7 @@ export interface UIPagePrompt {
24
24
  description: string;
25
25
  storage_prefix: string;
26
26
  shell_page?: string;
27
- theme: string;
27
+ theme?: string;
28
28
  }
29
29
  export interface UIPageSamplePrompt extends UIPagePrompt {
30
30
  variantId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.67.0",
3
+ "version": "0.67.1",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -473,67 +473,53 @@ router.post('/:handle/ui', async (req: KapetaBodyRequest, res: Response) => {
473
473
 
474
474
  router.post('/ui/edit', async (req: KapetaBodyRequest, res: Response) => {
475
475
  try {
476
- const conversationId = req.headers[ConversationIdHeader.toLowerCase()] as string | undefined;
476
+ const systemId = (req.headers[SystemIdHeader.toLowerCase()] ||
477
+ req.headers[ConversationIdHeader.toLowerCase()]) as string | undefined;
477
478
 
478
479
  const aiRequest: StormContextRequest<UIPageEditRequest> = JSON.parse(req.stringBody ?? '{}');
479
-
480
- const pages = aiRequest.prompt.pages
481
- .map((page) => {
482
- const content = readPageFromDiskAsString(conversationId!, page.path, page.method);
483
- if (!content) {
484
- console.warn('Page not found', page);
485
- return undefined;
486
- }
487
-
488
- return {
489
- filename: page.filename,
490
- path: page.path,
491
- method: page.method,
492
- title: page.title,
493
- conversationId: page.conversationId,
494
- prompt: page.prompt,
495
- name: page.name,
496
- description: page.description,
497
- content,
498
- } satisfies Page;
499
- })
500
- .filter((page: Page | undefined) => !!page) as UIPageEditPrompt['pages'];
501
-
502
- const editStream = await stormClient.editPages(
503
- {
504
- prompt: aiRequest.prompt.prompt.prompt,
505
- blockDescription: aiRequest.prompt.blockDescription,
506
- planDescription: aiRequest.prompt.planDescription,
507
- pages,
508
- },
509
- conversationId
510
- );
480
+ const storagePrefix = systemId ? systemId + '_' : 'mock_';
481
+ const queue = new PageQueue(storagePrefix, 5);
511
482
 
512
483
  onRequestAborted(req, res, () => {
513
- editStream.abort();
484
+ queue.cancel();
514
485
  });
515
486
 
516
- res.set('Content-Type', 'application/x-ndjson');
517
- res.set('Access-Control-Expose-Headers', ConversationIdHeader);
518
- res.set(ConversationIdHeader, editStream.getConversationId());
519
-
520
487
  const promises: Promise<void>[] = [];
521
- editStream.on('data', (data: StormEvent) => {
522
- try {
523
- if (data.type === 'PAGE') {
524
- promises.push(sendPageEvent(editStream.getConversationId(), data, res));
525
- } else {
526
- sendEvent(res, data);
527
- }
528
- } catch (e) {
529
- console.error('Failed to process event', e);
488
+
489
+ queue.on('page', (data) => {
490
+ if (systemId) {
491
+ promises.push(sendPageEvent(systemId, data, res));
530
492
  }
531
493
  });
532
494
 
533
- await waitForStormStream(editStream);
534
- if (editStream.isAborted()) {
535
- return;
536
- }
495
+ queue.on('event', (data) => {
496
+ if (data.type === 'FILE_START' || data.type === 'FILE_DONE' || data.type === 'FILE_STATE') {
497
+ sendEvent(res, data);
498
+ }
499
+ });
500
+
501
+ await Promise.allSettled(
502
+ aiRequest.prompt.pages.map((page) => {
503
+ if (page.conversationId) {
504
+ return queue.addPrompt(
505
+ {
506
+ title: page.title,
507
+ name: page.name,
508
+ method: page.method,
509
+ path: page.path,
510
+ description: page.description ?? '',
511
+ filename: page.filename,
512
+ prompt: aiRequest.prompt.prompt.prompt,
513
+ storage_prefix: storagePrefix,
514
+ },
515
+ page.conversationId,
516
+ true
517
+ );
518
+ }
519
+ })
520
+ );
521
+
522
+ await queue.wait();
537
523
  await Promise.all(promises);
538
524
 
539
525
  sendDone(res);
@@ -44,7 +44,7 @@ export interface UIPagePrompt {
44
44
  storage_prefix: string;
45
45
  shell_page?: string;
46
46
  // contents of theme.css
47
- theme: string;
47
+ theme?: string;
48
48
  }
49
49
 
50
50
  export interface UIPageSamplePrompt extends UIPagePrompt {