@webiny/ai-powerups 6.4.11 → 6.6.0-alpha.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/AiPowerups.js +2 -2
- package/AiPowerups.js.map +1 -1
- package/admin/Extension.js +11 -2
- package/admin/Extension.js.map +1 -1
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsGateway.d.ts +12 -0
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsGateway.js +46 -0
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsGateway.js.map +1 -0
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsRepository.d.ts +11 -0
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsRepository.js +18 -0
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsRepository.js.map +1 -0
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsUseCase.d.ts +11 -0
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsUseCase.js +18 -0
- package/admin/features/compareEntryRevisions/CompareEntryRevisionsUseCase.js.map +1 -0
- package/admin/features/compareEntryRevisions/abstractions.d.ts +32 -0
- package/admin/features/compareEntryRevisions/abstractions.js +7 -0
- package/admin/features/compareEntryRevisions/abstractions.js.map +1 -0
- package/admin/features/compareEntryRevisions/feature.d.ts +1 -0
- package/admin/features/compareEntryRevisions/feature.js +15 -0
- package/admin/features/compareEntryRevisions/feature.js.map +1 -0
- package/admin/features/compareEntryRevisions/index.d.ts +2 -0
- package/admin/features/compareEntryRevisions/index.js +2 -0
- package/admin/features/feature.js +2 -0
- package/admin/features/feature.js.map +1 -1
- package/admin/features/generateEntryContent/GenerateEntryContentGateway.d.ts +12 -0
- package/admin/features/generateEntryContent/GenerateEntryContentGateway.js +45 -0
- package/admin/features/generateEntryContent/GenerateEntryContentGateway.js.map +1 -0
- package/admin/features/generateEntryContent/GenerateEntryContentUseCase.d.ts +11 -0
- package/admin/features/generateEntryContent/GenerateEntryContentUseCase.js +18 -0
- package/admin/features/generateEntryContent/GenerateEntryContentUseCase.js.map +1 -0
- package/admin/features/generateEntryContent/abstractions.d.ts +24 -0
- package/admin/features/generateEntryContent/abstractions.js +6 -0
- package/admin/features/generateEntryContent/abstractions.js.map +1 -0
- package/admin/features/generateEntryContent/feature.d.ts +1 -0
- package/admin/features/generateEntryContent/feature.js +13 -0
- package/admin/features/generateEntryContent/feature.js.map +1 -0
- package/admin/features/generateEntryContent/index.d.ts +3 -0
- package/admin/features/generateEntryContent/index.js +2 -0
- package/admin/features/generatePageContent/GeneratePageContentGateway.js +2 -0
- package/admin/features/generatePageContent/GeneratePageContentGateway.js.map +1 -1
- package/admin/features/generatePageContent/abstractions.d.ts +1 -0
- package/admin/features/generatePageContent/abstractions.js.map +1 -1
- package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.d.ts +2 -2
- package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.js +3 -4
- package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.js.map +1 -1
- package/admin/presentation/AiPromptFormFactory/AiPromptFormFactory.d.ts +20 -0
- package/admin/presentation/AiPromptFormFactory/AiPromptFormFactory.js +108 -0
- package/admin/presentation/AiPromptFormFactory/AiPromptFormFactory.js.map +1 -0
- package/admin/presentation/AiPromptFormFactory/abstractions.d.ts +14 -0
- package/admin/presentation/AiPromptFormFactory/abstractions.js +5 -0
- package/admin/presentation/AiPromptFormFactory/abstractions.js.map +1 -0
- package/admin/presentation/AiPromptFormFactory/feature.d.ts +1 -0
- package/admin/presentation/AiPromptFormFactory/feature.js +11 -0
- package/admin/presentation/AiPromptFormFactory/feature.js.map +1 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsDialog.d.ts +9 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsDialog.js +118 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsDialog.js.map +1 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsDrawer.d.ts +9 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsDrawer.js +72 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsDrawer.js.map +1 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsMenuItem.d.ts +4 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsMenuItem.js +21 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsMenuItem.js.map +1 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsOverlays.d.ts +2 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsOverlays.js +17 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsOverlays.js.map +1 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.d.ts +25 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js +90 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js.map +1 -0
- package/admin/presentation/CmsCompareEntryRevisions/Extension.d.ts +2 -0
- package/admin/presentation/CmsCompareEntryRevisions/Extension.js +16 -0
- package/admin/presentation/CmsCompareEntryRevisions/Extension.js.map +1 -0
- package/admin/presentation/CmsCompareEntryRevisions/abstractions.d.ts +29 -0
- package/admin/presentation/CmsCompareEntryRevisions/abstractions.js +5 -0
- package/admin/presentation/CmsCompareEntryRevisions/abstractions.js.map +1 -0
- package/admin/presentation/CmsCompareEntryRevisions/feature.d.ts +3 -0
- package/admin/presentation/CmsCompareEntryRevisions/feature.js +17 -0
- package/admin/presentation/CmsCompareEntryRevisions/feature.js.map +1 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentButton.d.ts +4 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentButton.js +27 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentButton.js.map +1 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentDialog.d.ts +5 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentDialog.js +106 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentDialog.js.map +1 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.d.ts +29 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.js +120 -0
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.js.map +1 -0
- package/admin/presentation/CmsContentGeneration/Extension.d.ts +2 -0
- package/admin/presentation/CmsContentGeneration/Extension.js +27 -0
- package/admin/presentation/CmsContentGeneration/Extension.js.map +1 -0
- package/admin/presentation/CmsContentGeneration/abstractions.d.ts +20 -0
- package/admin/presentation/CmsContentGeneration/abstractions.js +5 -0
- package/admin/presentation/CmsContentGeneration/abstractions.js.map +1 -0
- package/admin/presentation/CmsContentGeneration/feature.d.ts +3 -0
- package/admin/presentation/CmsContentGeneration/feature.js +17 -0
- package/admin/presentation/CmsContentGeneration/feature.js.map +1 -0
- package/admin/presentation/CmsEntryWizard/CmsEntryWizard.d.ts +4 -0
- package/admin/presentation/CmsEntryWizard/CmsEntryWizard.js +113 -0
- package/admin/presentation/CmsEntryWizard/CmsEntryWizard.js.map +1 -0
- package/admin/presentation/CmsEntryWizard/CmsEntryWizardGate.d.ts +4 -0
- package/admin/presentation/CmsEntryWizard/CmsEntryWizardGate.js +19 -0
- package/admin/presentation/CmsEntryWizard/CmsEntryWizardGate.js.map +1 -0
- package/admin/presentation/CmsEntryWizard/Extension.d.ts +2 -0
- package/admin/presentation/CmsEntryWizard/Extension.js +10 -0
- package/admin/presentation/CmsEntryWizard/Extension.js.map +1 -0
- package/admin/presentation/ProjectsSettings.js +4 -4
- package/admin/presentation/ProjectsSettings.js.map +1 -1
- package/admin/presentation/ProvidersSettings.js +1 -1
- package/admin/presentation/ProvidersSettings.js.map +1 -1
- package/admin/presentation/WbContentGeneration/GenerateContentDialog.d.ts +2 -2
- package/admin/presentation/WbContentGeneration/GenerateContentDialog.js +2 -2
- package/admin/presentation/WbContentGeneration/GenerateContentDialog.js.map +1 -1
- package/admin/presentation/WbContentGeneration/GenerateContentPresenter.d.ts +4 -12
- package/admin/presentation/WbContentGeneration/GenerateContentPresenter.js +12 -94
- package/admin/presentation/WbContentGeneration/GenerateContentPresenter.js.map +1 -1
- package/api/Extension.js +13 -3
- package/api/Extension.js.map +1 -1
- package/api/features/AiChatProvider/PowerUpsAiChatProvider.d.ts +24 -0
- package/api/features/AiChatProvider/PowerUpsAiChatProvider.js +31 -0
- package/api/features/AiChatProvider/PowerUpsAiChatProvider.js.map +1 -0
- package/api/features/AiChatProvider/feature.d.ts +9 -0
- package/api/features/AiChatProvider/feature.js +11 -0
- package/api/features/AiChatProvider/feature.js.map +1 -0
- package/api/features/AiChatProvider/index.d.ts +2 -0
- package/api/features/AiChatProvider/index.js +2 -0
- package/api/features/AiImageEnrichment/AiImageEnrichmentStreamRoute.d.ts +36 -0
- package/api/features/AiImageEnrichment/AiImageEnrichmentStreamRoute.js +85 -0
- package/api/features/AiImageEnrichment/AiImageEnrichmentStreamRoute.js.map +1 -0
- package/api/features/AiImageEnrichment/AiImageEnrichmentTask.d.ts +10 -14
- package/api/features/AiImageEnrichment/AiImageEnrichmentTask.js +27 -100
- package/api/features/AiImageEnrichment/AiImageEnrichmentTask.js.map +1 -1
- package/api/features/AiImageEnrichment/ApplyImageEnrichmentUseCase.d.ts +18 -0
- package/api/features/AiImageEnrichment/ApplyImageEnrichmentUseCase.js +50 -0
- package/api/features/AiImageEnrichment/ApplyImageEnrichmentUseCase.js.map +1 -0
- package/api/features/AiImageEnrichment/PrepareImageEnrichmentUseCase.d.ts +19 -0
- package/api/features/AiImageEnrichment/PrepareImageEnrichmentUseCase.js +49 -0
- package/api/features/AiImageEnrichment/PrepareImageEnrichmentUseCase.js.map +1 -0
- package/api/features/AiImageEnrichment/abstractions.d.ts +60 -0
- package/api/features/AiImageEnrichment/abstractions.js +12 -0
- package/api/features/AiImageEnrichment/abstractions.js.map +1 -0
- package/api/features/AiImageEnrichment/buildEnrichmentAiRequest.d.ts +12 -0
- package/api/features/AiImageEnrichment/buildEnrichmentAiRequest.js +30 -0
- package/api/features/AiImageEnrichment/buildEnrichmentAiRequest.js.map +1 -0
- package/api/features/AiImageEnrichment/errors.d.ts +26 -0
- package/api/features/AiImageEnrichment/errors.js +28 -0
- package/api/features/AiImageEnrichment/errors.js.map +1 -0
- package/api/features/AiImageEnrichment/feature.js +9 -0
- package/api/features/AiImageEnrichment/feature.js.map +1 -1
- package/api/features/AiImageEnrichment/imageEnrichmentErrorStatusCode.d.ts +6 -0
- package/api/features/AiImageEnrichment/imageEnrichmentErrorStatusCode.js +9 -0
- package/api/features/AiImageEnrichment/imageEnrichmentErrorStatusCode.js.map +1 -0
- package/api/features/AiImageEnrichment/readEnrichmentPartial.d.ts +8 -0
- package/api/features/AiImageEnrichment/readEnrichmentPartial.js +16 -0
- package/api/features/AiImageEnrichment/readEnrichmentPartial.js.map +1 -0
- package/api/features/AiImageEnrichment/streamEvents.d.ts +36 -0
- package/api/features/AiImageEnrichment/streamEvents.js +0 -0
- package/api/features/AiPromptContext/AiPromptContextBuilder.d.ts +8 -1
- package/api/features/AiPromptContext/AiPromptContextBuilder.js +46 -2
- package/api/features/AiPromptContext/AiPromptContextBuilder.js.map +1 -1
- package/api/features/AiPromptContext/abstractions.d.ts +3 -0
- package/api/features/AiPromptContext/abstractions.js +9 -1
- package/api/features/AiPromptContext/abstractions.js.map +1 -1
- package/api/features/AiPromptContext/index.d.ts +1 -1
- package/api/features/AiPromptContext/index.js +1 -1
- package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.d.ts +22 -0
- package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.js +136 -0
- package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.js.map +1 -0
- package/api/features/CmsCompareEntryRevisions/abstractions.d.ts +18 -0
- package/api/features/CmsCompareEntryRevisions/abstractions.js +5 -0
- package/api/features/CmsCompareEntryRevisions/abstractions.js.map +1 -0
- package/api/features/CmsCompareEntryRevisions/feature.d.ts +4 -0
- package/api/features/CmsCompareEntryRevisions/feature.js +11 -0
- package/api/features/CmsCompareEntryRevisions/feature.js.map +1 -0
- package/api/features/CmsCompareEntryRevisions/index.d.ts +2 -0
- package/api/features/CmsCompareEntryRevisions/index.js +2 -0
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentTask.d.ts +33 -0
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentTask.js +84 -0
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentTask.js.map +1 -0
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.d.ts +29 -0
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js +141 -0
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js.map +1 -0
- package/api/features/CmsGenerateEntryContent/abstractions.d.ts +36 -0
- package/api/features/CmsGenerateEntryContent/abstractions.js +5 -0
- package/api/features/CmsGenerateEntryContent/abstractions.js.map +1 -0
- package/api/features/CmsGenerateEntryContent/buildPrompt.d.ts +2 -0
- package/api/features/CmsGenerateEntryContent/buildPrompt.js +61 -0
- package/api/features/CmsGenerateEntryContent/buildPrompt.js.map +1 -0
- package/api/features/CmsGenerateEntryContent/feature.d.ts +4 -0
- package/api/features/CmsGenerateEntryContent/feature.js +13 -0
- package/api/features/CmsGenerateEntryContent/feature.js.map +1 -0
- package/api/features/CmsGenerateEntryContent/index.d.ts +1 -0
- package/api/features/CmsGenerateEntryContent/index.js +1 -0
- package/api/features/CmsGenerateEntryContent/injectDynamicZoneTypenames.d.ts +2 -0
- package/api/features/CmsGenerateEntryContent/injectDynamicZoneTypenames.js +30 -0
- package/api/features/CmsGenerateEntryContent/injectDynamicZoneTypenames.js.map +1 -0
- package/api/features/CmsResolveImageTool/CmsResolveImageTool.d.ts +14 -0
- package/api/features/CmsResolveImageTool/CmsResolveImageTool.js +27 -0
- package/api/features/CmsResolveImageTool/CmsResolveImageTool.js.map +1 -0
- package/api/features/CmsResolveImageTool/feature.d.ts +4 -0
- package/api/features/CmsResolveImageTool/feature.js +11 -0
- package/api/features/CmsResolveImageTool/feature.js.map +1 -0
- package/api/features/GetSettings/GetSettingsUseCase.d.ts +1 -1
- package/api/features/GetSettings/index.d.ts +1 -0
- package/api/features/GetSettings/index.js +1 -0
- package/api/features/Providers/ProvidersHandler.d.ts +1 -3
- package/api/features/Providers/ProvidersHandler.js +2 -15
- package/api/features/Providers/ProvidersHandler.js.map +1 -1
- package/api/features/Providers/types.d.ts +2 -2
- package/api/features/WbGeneratePageContent/WbGeneratePageContentTask.d.ts +4 -3
- package/api/features/WbGeneratePageContent/WbGeneratePageContentTask.js +25 -15
- package/api/features/WbGeneratePageContent/WbGeneratePageContentTask.js.map +1 -1
- package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js +4 -3
- package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js.map +1 -1
- package/api/features/WbGeneratePageContent/abstractions.d.ts +1 -0
- package/api/features/WbGeneratePageContent/abstractions.js.map +1 -1
- package/api/features/WbTranslatePage/LexicalParser.d.ts +10 -0
- package/api/features/WbTranslatePage/LexicalParser.js +37 -0
- package/api/features/WbTranslatePage/LexicalParser.js.map +1 -0
- package/api/features/WbTranslatePage/WbTranslatePageDecorator.d.ts +27 -0
- package/api/features/WbTranslatePage/WbTranslatePageDecorator.js +134 -0
- package/api/features/WbTranslatePage/WbTranslatePageDecorator.js.map +1 -0
- package/api/features/WbTranslatePage/abstractions/LexicalParser.d.ts +7 -0
- package/api/features/WbTranslatePage/abstractions/LexicalParser.js +5 -0
- package/api/features/WbTranslatePage/abstractions/LexicalParser.js.map +1 -0
- package/api/features/WbTranslatePage/feature.d.ts +4 -0
- package/api/features/WbTranslatePage/feature.js +13 -0
- package/api/features/WbTranslatePage/feature.js.map +1 -0
- package/api/features/WbTranslatePage/index.d.ts +2 -0
- package/api/features/WbTranslatePage/index.js +2 -0
- package/api/graphql/BaseGraphQLSchema.d.ts +2 -2
- package/api/graphql/BaseGraphQLSchema.js +45 -6
- package/api/graphql/BaseGraphQLSchema.js.map +1 -1
- package/api/graphql/CmsCompareEntryRevisionsSchema.d.ts +8 -0
- package/api/graphql/CmsCompareEntryRevisionsSchema.js +68 -0
- package/api/graphql/CmsCompareEntryRevisionsSchema.js.map +1 -0
- package/exports/admin/ai-powerups.d.ts +1 -0
- package/exports/admin/ai-powerups.js +1 -0
- package/exports/api/ai-powerups.d.ts +2 -0
- package/exports/api/ai-powerups.js +2 -0
- package/package.json +33 -25
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/admin";
|
|
2
|
+
import { CmsGenerateContentPresenter } from "./abstractions.js";
|
|
3
|
+
import { CmsGenerateContentPresenter as external_CmsGenerateContentPresenter_js_CmsGenerateContentPresenter } from "./CmsGenerateContentPresenter.js";
|
|
4
|
+
const CmsGenerateContentFeature = createFeature({
|
|
5
|
+
name: "CmsContentGeneration/Presenter",
|
|
6
|
+
register (container) {
|
|
7
|
+
container.register(external_CmsGenerateContentPresenter_js_CmsGenerateContentPresenter);
|
|
8
|
+
},
|
|
9
|
+
resolve (container) {
|
|
10
|
+
return {
|
|
11
|
+
presenter: container.resolve(CmsGenerateContentPresenter)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
export { CmsGenerateContentFeature };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin/presentation/CmsContentGeneration/feature.js","sources":["../../../../src/admin/presentation/CmsContentGeneration/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { CmsGenerateContentPresenter as Abstraction } from \"./abstractions.js\";\nimport { CmsGenerateContentPresenter } from \"./CmsGenerateContentPresenter.js\";\n\nexport const CmsGenerateContentFeature = createFeature({\n name: \"CmsContentGeneration/Presenter\",\n register(container) {\n container.register(CmsGenerateContentPresenter);\n },\n resolve(container) {\n return {\n presenter: container.resolve(Abstraction)\n };\n }\n});\n"],"names":["CmsGenerateContentFeature","createFeature","container","CmsGenerateContentPresenter","Abstraction"],"mappings":";;;AAIO,MAAMA,4BAA4BC,cAAc;IACnD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;IACA,SAAQD,SAAS;QACb,OAAO;YACH,WAAWA,UAAU,OAAO,CAACE;QACjC;IACJ;AACJ"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import react, { useEffect, useRef } from "react";
|
|
2
|
+
import { observer } from "mobx-react-lite";
|
|
3
|
+
import { FormView } from "@webiny/app-admin";
|
|
4
|
+
import { BetaBadge, Button, Heading, OverlayLoader, useToast } from "@webiny/admin-ui";
|
|
5
|
+
import { useFeature } from "@webiny/app";
|
|
6
|
+
import { useWebsockets } from "@webiny/app-websockets";
|
|
7
|
+
import { useModel } from "@webiny/app-headless-cms/admin/components/ModelProvider/useModel.js";
|
|
8
|
+
import { useContentEntryFormPresenter } from "@webiny/app-headless-cms/exports/admin/cms/entry/editor.js";
|
|
9
|
+
import { CmsGenerateContentFeature } from "../CmsContentGeneration/feature.js";
|
|
10
|
+
import { decompressGzipBase64 } from "../WbContentGeneration/decompressGzipBase64.js";
|
|
11
|
+
function formatElapsed(totalSeconds) {
|
|
12
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
13
|
+
const seconds = totalSeconds % 60;
|
|
14
|
+
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
|
15
|
+
}
|
|
16
|
+
const WS_ACTION_CONTENT = "aiPowerUps.generateEntryContent.content";
|
|
17
|
+
const WS_ACTION_ERROR = "aiPowerUps.generateEntryContent.error";
|
|
18
|
+
const CmsEntryWizard = observer(()=>{
|
|
19
|
+
const { presenter } = useFeature(CmsGenerateContentFeature);
|
|
20
|
+
const formPresenter = useContentEntryFormPresenter();
|
|
21
|
+
const { model } = useModel();
|
|
22
|
+
const vm = presenter.vm;
|
|
23
|
+
const wasSubmitting = useRef(false);
|
|
24
|
+
const websockets = useWebsockets();
|
|
25
|
+
const toast = useToast();
|
|
26
|
+
useEffect(()=>{
|
|
27
|
+
presenter.init().catch((err)=>{
|
|
28
|
+
console.error("Failed to initialize AI entry wizard", err);
|
|
29
|
+
});
|
|
30
|
+
}, []);
|
|
31
|
+
useEffect(()=>{
|
|
32
|
+
const contentSubscription = websockets.onMessage(WS_ACTION_CONTENT, async (message)=>{
|
|
33
|
+
const responseText = await decompressGzipBase64(message.data.value);
|
|
34
|
+
try {
|
|
35
|
+
const entryValues = await presenter.processAiResponse(responseText);
|
|
36
|
+
formPresenter.newEntry(entryValues);
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.error("Failed to process AI response", e);
|
|
39
|
+
toast.showWarningToast({
|
|
40
|
+
title: "Failed to process AI response",
|
|
41
|
+
description: "Open the console for more details."
|
|
42
|
+
});
|
|
43
|
+
presenter.cancelPrompt();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const errorSubscription = websockets.onMessage(WS_ACTION_ERROR, async (message)=>{
|
|
47
|
+
toast.showWarningToast({
|
|
48
|
+
title: "Failed to generate content",
|
|
49
|
+
description: message.data.message
|
|
50
|
+
});
|
|
51
|
+
presenter.cancelPrompt();
|
|
52
|
+
});
|
|
53
|
+
return ()=>{
|
|
54
|
+
contentSubscription.off();
|
|
55
|
+
errorSubscription.off();
|
|
56
|
+
};
|
|
57
|
+
}, []);
|
|
58
|
+
useEffect(()=>{
|
|
59
|
+
wasSubmitting.current && !vm.submitting && vm.timedOut;
|
|
60
|
+
wasSubmitting.current = vm.submitting;
|
|
61
|
+
}, [
|
|
62
|
+
vm.submitting
|
|
63
|
+
]);
|
|
64
|
+
useEffect(()=>{
|
|
65
|
+
if (vm.timedOut) toast.showWarningToast({
|
|
66
|
+
title: "Request timed out",
|
|
67
|
+
description: "The AI generation took too long. Please try again."
|
|
68
|
+
});
|
|
69
|
+
}, [
|
|
70
|
+
vm.timedOut
|
|
71
|
+
]);
|
|
72
|
+
const handleSubmit = async ()=>{
|
|
73
|
+
await presenter.submit(model.modelId);
|
|
74
|
+
};
|
|
75
|
+
const handleSkip = ()=>{
|
|
76
|
+
formPresenter.newEntry();
|
|
77
|
+
};
|
|
78
|
+
return /*#__PURE__*/ react.createElement("div", {
|
|
79
|
+
className: "flex justify-center pt-xl"
|
|
80
|
+
}, /*#__PURE__*/ react.createElement("div", {
|
|
81
|
+
className: "bg-neutral-base rounded-lg p-lg flex flex-col gap-md",
|
|
82
|
+
style: {
|
|
83
|
+
width: 600
|
|
84
|
+
}
|
|
85
|
+
}, /*#__PURE__*/ react.createElement(Heading, {
|
|
86
|
+
level: 4,
|
|
87
|
+
className: "flex items-center gap-sm"
|
|
88
|
+
}, "Generate Entry Content ", /*#__PURE__*/ react.createElement(BetaBadge, null)), /*#__PURE__*/ react.createElement("p", {
|
|
89
|
+
className: "text-neutral-muted"
|
|
90
|
+
}, "Use AI to generate content for this entry. Configure the prompt and click Generate, or skip to create an empty entry."), vm.loading ? /*#__PURE__*/ react.createElement(OverlayLoader, {
|
|
91
|
+
text: "Loading..."
|
|
92
|
+
}) : null, vm.submitting ? /*#__PURE__*/ react.createElement(OverlayLoader, {
|
|
93
|
+
className: "bg-neutral-base/90",
|
|
94
|
+
text: /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement("div", null, "Generating content... ", formatElapsed(vm.elapsedSeconds)), /*#__PURE__*/ react.createElement("div", {
|
|
95
|
+
className: "text-sm text-neutral-muted pt-xs"
|
|
96
|
+
}, "Content generation can take a few minutes, depending on the model you're using."))
|
|
97
|
+
}) : null, vm.form ? /*#__PURE__*/ react.createElement(FormView, {
|
|
98
|
+
name: "CmsEntryWizard",
|
|
99
|
+
form: vm.form
|
|
100
|
+
}) : null, /*#__PURE__*/ react.createElement("div", {
|
|
101
|
+
className: "flex justify-end gap-sm"
|
|
102
|
+
}, /*#__PURE__*/ react.createElement(Button, {
|
|
103
|
+
variant: "secondary",
|
|
104
|
+
onClick: handleSkip
|
|
105
|
+
}, "Skip"), /*#__PURE__*/ react.createElement(Button, {
|
|
106
|
+
variant: "primary",
|
|
107
|
+
onClick: handleSubmit,
|
|
108
|
+
disabled: vm.loading || vm.submitting
|
|
109
|
+
}, "Generate"))));
|
|
110
|
+
});
|
|
111
|
+
export { CmsEntryWizard };
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=CmsEntryWizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin/presentation/CmsEntryWizard/CmsEntryWizard.js","sources":["../../../../src/admin/presentation/CmsEntryWizard/CmsEntryWizard.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { FormView } from \"@webiny/app-admin\";\nimport { BetaBadge } from \"@webiny/admin-ui\";\nimport { Button, Heading, OverlayLoader, useToast } from \"@webiny/admin-ui\";\nimport { useFeature } from \"@webiny/app\";\nimport type { IncomingGenericData } from \"@webiny/app-websockets\";\nimport { useWebsockets } from \"@webiny/app-websockets\";\nimport { useModel } from \"@webiny/app-headless-cms/admin/components/ModelProvider/useModel.js\";\nimport { useContentEntryFormPresenter } from \"@webiny/app-headless-cms/exports/admin/cms/entry/editor.js\";\nimport { CmsGenerateContentFeature } from \"~/admin/presentation/CmsContentGeneration/feature.js\";\nimport { decompressGzipBase64 } from \"~/admin/presentation/WbContentGeneration/decompressGzipBase64.js\";\n\nfunction formatElapsed(totalSeconds: number): string {\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${seconds.toString().padStart(2, \"0\")}`;\n}\n\nconst WS_ACTION_CONTENT = \"aiPowerUps.generateEntryContent.content\";\nconst WS_ACTION_ERROR = \"aiPowerUps.generateEntryContent.error\";\n\ninterface GenerateEntryContentMessage extends IncomingGenericData {\n action: typeof WS_ACTION_CONTENT;\n data: {\n compression: \"gzip\";\n value: string;\n };\n}\n\ninterface GenerateEntryContentErrorMessage extends IncomingGenericData {\n action: typeof WS_ACTION_ERROR;\n data: {\n message: string;\n };\n}\n\nexport const CmsEntryWizard = observer(() => {\n const { presenter } = useFeature(CmsGenerateContentFeature);\n const formPresenter = useContentEntryFormPresenter();\n const { model } = useModel();\n const vm = presenter.vm;\n const wasSubmitting = useRef(false);\n const websockets = useWebsockets();\n const toast = useToast();\n\n useEffect(() => {\n presenter.init().catch(err => {\n console.error(\"Failed to initialize AI entry wizard\", err);\n });\n }, []);\n\n useEffect(() => {\n const contentSubscription = websockets.onMessage<GenerateEntryContentMessage>(\n WS_ACTION_CONTENT,\n async message => {\n const responseText = await decompressGzipBase64(message.data.value);\n try {\n const entryValues = await presenter.processAiResponse(responseText);\n formPresenter.newEntry(entryValues);\n } catch (e) {\n console.error(\"Failed to process AI response\", e);\n toast.showWarningToast({\n title: \"Failed to process AI response\",\n description: \"Open the console for more details.\"\n });\n presenter.cancelPrompt();\n }\n }\n );\n\n const errorSubscription = websockets.onMessage<GenerateEntryContentErrorMessage>(\n WS_ACTION_ERROR,\n async message => {\n toast.showWarningToast({\n title: \"Failed to generate content\",\n description: message.data.message\n });\n presenter.cancelPrompt();\n }\n );\n\n return () => {\n contentSubscription.off();\n errorSubscription.off();\n };\n }, []);\n\n useEffect(() => {\n if (wasSubmitting.current && !vm.submitting && !vm.timedOut) {\n // Generation completed successfully — form was created via newEntry()\n }\n wasSubmitting.current = vm.submitting;\n }, [vm.submitting]);\n\n useEffect(() => {\n if (vm.timedOut) {\n toast.showWarningToast({\n title: \"Request timed out\",\n description: \"The AI generation took too long. Please try again.\"\n });\n }\n }, [vm.timedOut]);\n\n const handleSubmit = async () => {\n await presenter.submit(model.modelId);\n };\n\n const handleSkip = () => {\n formPresenter.newEntry();\n };\n\n return (\n <div className=\"flex justify-center pt-xl\">\n <div\n className=\"bg-neutral-base rounded-lg p-lg flex flex-col gap-md\"\n style={{ width: 600 }}\n >\n <Heading level={4} className=\"flex items-center gap-sm\">\n Generate Entry Content <BetaBadge />\n </Heading>\n <p className=\"text-neutral-muted\">\n Use AI to generate content for this entry. Configure the prompt and click\n Generate, or skip to create an empty entry.\n </p>\n {vm.loading ? <OverlayLoader text={\"Loading...\"} /> : null}\n {vm.submitting ? (\n <OverlayLoader\n className={\"bg-neutral-base/90\"}\n text={\n <>\n <div>Generating content... {formatElapsed(vm.elapsedSeconds)}</div>\n <div className=\"text-sm text-neutral-muted pt-xs\">\n Content generation can take a few minutes, depending on the\n model you're using.\n </div>\n </>\n }\n />\n ) : null}\n {vm.form ? <FormView name=\"CmsEntryWizard\" form={vm.form} /> : null}\n <div className=\"flex justify-end gap-sm\">\n <Button variant=\"secondary\" onClick={handleSkip}>\n Skip\n </Button>\n <Button\n variant=\"primary\"\n onClick={handleSubmit}\n disabled={vm.loading || vm.submitting}\n >\n Generate\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["formatElapsed","totalSeconds","minutes","Math","seconds","WS_ACTION_CONTENT","WS_ACTION_ERROR","CmsEntryWizard","observer","presenter","useFeature","CmsGenerateContentFeature","formPresenter","useContentEntryFormPresenter","model","useModel","vm","wasSubmitting","useRef","websockets","useWebsockets","toast","useToast","useEffect","err","console","contentSubscription","message","responseText","decompressGzipBase64","entryValues","e","errorSubscription","handleSubmit","handleSkip","Heading","BetaBadge","OverlayLoader","FormView","Button"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import react, { useEffect } from "react";
|
|
2
|
+
import { observer } from "mobx-react-lite";
|
|
3
|
+
import { useModel } from "@webiny/app-headless-cms/admin/components/ModelProvider/useModel.js";
|
|
4
|
+
import { useContentEntryFormPresenter } from "@webiny/app-headless-cms/exports/admin/cms/entry/editor.js";
|
|
5
|
+
import { CmsEntryWizard } from "./CmsEntryWizard.js";
|
|
6
|
+
const CmsEntryWizardGate = observer(()=>{
|
|
7
|
+
const { model } = useModel();
|
|
8
|
+
const formPresenter = useContentEntryFormPresenter();
|
|
9
|
+
const showWizard = model.settings?.aiEntryWizard === true;
|
|
10
|
+
useEffect(()=>{
|
|
11
|
+
if (!showWizard) formPresenter.newEntry();
|
|
12
|
+
}, [
|
|
13
|
+
showWizard
|
|
14
|
+
]);
|
|
15
|
+
return /*#__PURE__*/ react.createElement(CmsEntryWizard, null);
|
|
16
|
+
});
|
|
17
|
+
export { CmsEntryWizardGate };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=CmsEntryWizardGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin/presentation/CmsEntryWizard/CmsEntryWizardGate.js","sources":["../../../../src/admin/presentation/CmsEntryWizard/CmsEntryWizardGate.tsx"],"sourcesContent":["import React, { useEffect } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useModel } from \"@webiny/app-headless-cms/admin/components/ModelProvider/useModel.js\";\nimport { useContentEntryFormPresenter } from \"@webiny/app-headless-cms/exports/admin/cms/entry/editor.js\";\nimport { CmsEntryWizard } from \"./CmsEntryWizard.js\";\n\nexport const CmsEntryWizardGate = observer(() => {\n const { model } = useModel();\n const formPresenter = useContentEntryFormPresenter();\n\n const showWizard = model.settings?.aiEntryWizard === true;\n\n useEffect(() => {\n if (!showWizard) {\n formPresenter.newEntry();\n }\n }, [showWizard]);\n\n return <CmsEntryWizard />;\n});\n"],"names":["CmsEntryWizardGate","observer","model","useModel","formPresenter","useContentEntryFormPresenter","showWizard","useEffect","CmsEntryWizard"],"mappings":";;;;;AAMO,MAAMA,qBAAqBC,SAAS;IACvC,MAAM,EAAEC,KAAK,EAAE,GAAGC;IAClB,MAAMC,gBAAgBC;IAEtB,MAAMC,aAAaJ,MAAM,QAAQ,EAAE,kBAAkB;IAErDK,UAAU;QACN,IAAI,CAACD,YACDF,cAAc,QAAQ;IAE9B,GAAG;QAACE;KAAW;IAEf,OAAO,WAAP,GAAO,oBAACE,gBAAcA;AAC1B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import react from "react";
|
|
2
|
+
import { InternalContentEntryEditorConfig } from "@webiny/app-headless-cms/admin/config/contentEntries/index.js";
|
|
3
|
+
import { CmsEntryWizardGate } from "./CmsEntryWizardGate.js";
|
|
4
|
+
const CmsEntryWizardExtension = ()=>/*#__PURE__*/ react.createElement(InternalContentEntryEditorConfig, null, /*#__PURE__*/ react.createElement(InternalContentEntryEditorConfig.NewEntryWizard, {
|
|
5
|
+
name: "aiEntryWizard",
|
|
6
|
+
element: /*#__PURE__*/ react.createElement(CmsEntryWizardGate, null)
|
|
7
|
+
}));
|
|
8
|
+
export { CmsEntryWizardExtension };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=Extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin/presentation/CmsEntryWizard/Extension.js","sources":["../../../../src/admin/presentation/CmsEntryWizard/Extension.tsx"],"sourcesContent":["import React from \"react\";\nimport { InternalContentEntryEditorConfig } from \"@webiny/app-headless-cms/admin/config/contentEntries/index.js\";\nimport { CmsEntryWizardGate } from \"./CmsEntryWizardGate.js\";\n\nexport const CmsEntryWizardExtension = () => {\n return (\n <InternalContentEntryEditorConfig>\n <InternalContentEntryEditorConfig.NewEntryWizard\n name={\"aiEntryWizard\"}\n element={<CmsEntryWizardGate />}\n />\n </InternalContentEntryEditorConfig>\n );\n};\n"],"names":["CmsEntryWizardExtension","InternalContentEntryEditorConfig","CmsEntryWizardGate"],"mappings":";;;AAIO,MAAMA,0BAA0B,IAC5B,WAAP,GACI,oBAACC,kCAAgCA,MAAAA,WAAAA,GAC7B,oBAACA,iCAAiC,cAAc;QAC5C,MAAM;QACN,uBAAS,oBAACC,oBAAkBA"}
|
|
@@ -16,8 +16,8 @@ class ProjectsSettingsImpl {
|
|
|
16
16
|
instructions: f.text().label("Instructions").description("System-prompt-style guidance that will be sent to the LLM when this project is selected.").renderer("textarea", {
|
|
17
17
|
rows: 6
|
|
18
18
|
}),
|
|
19
|
-
defaultReaderPersonaId: f.text().label("Default Reader Persona").description("Auto-populates the reader persona when this project is selected.").options((
|
|
20
|
-
const data =
|
|
19
|
+
defaultReaderPersonaId: f.text().label("Default Reader Persona").description("Auto-populates the reader persona when this project is selected.").options(({ form })=>{
|
|
20
|
+
const data = form.getData();
|
|
21
21
|
const presets = data?.readerPersonas?.presets;
|
|
22
22
|
if (!presets || 0 === presets.length) return [];
|
|
23
23
|
return presets.map((preset)=>({
|
|
@@ -25,8 +25,8 @@ class ProjectsSettingsImpl {
|
|
|
25
25
|
value: preset.id
|
|
26
26
|
}));
|
|
27
27
|
}),
|
|
28
|
-
defaultWriterPersonaId: f.text().label("Default Writer Persona").description("Auto-populates the writer persona when this project is selected.").options((
|
|
29
|
-
const data =
|
|
28
|
+
defaultWriterPersonaId: f.text().label("Default Writer Persona").description("Auto-populates the writer persona when this project is selected.").options(({ form })=>{
|
|
29
|
+
const data = form.getData();
|
|
30
30
|
const presets = data?.writerPersonas?.presets;
|
|
31
31
|
if (!presets || 0 === presets.length) return [];
|
|
32
32
|
return presets.map((preset)=>({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin/presentation/ProjectsSettings.js","sources":["../../../src/admin/presentation/ProjectsSettings.ts"],"sourcesContent":["import { generateAlphaNumericId } from \"@webiny/utils\";\nimport
|
|
1
|
+
{"version":3,"file":"admin/presentation/ProjectsSettings.js","sources":["../../../src/admin/presentation/ProjectsSettings.ts"],"sourcesContent":["import { generateAlphaNumericId } from \"@webiny/utils\";\nimport { AiPowerUpsSettingsGroup } from \"./AiPowerUpsSettings/settingsGroup.js\";\n\nclass ProjectsSettingsImpl implements AiPowerUpsSettingsGroup.Interface {\n name = \"projects\";\n label = \"Projects\";\n description = \"Predefined prompting contexts.\";\n\n buildForm(form: AiPowerUpsSettingsGroup.FormBuilder): void {\n form.fields(fields => ({\n presets: fields\n .object()\n .label(\"Presets\")\n .renderer(\"objectAccordionMultiple\", {\n container: false,\n addItemLabel: \"Add project\",\n itemTitle: (data, index) => String(data.name || `Project #${index + 1}`)\n })\n .fields(f => ({\n id: f\n .text()\n .hidden()\n .defaultValue(() => generateAlphaNumericId(10)),\n name: f\n .text()\n .label(\"Name\")\n .required(\"Name is required\")\n .description(\"This name will be used to identify the project in the UI.\"),\n description: f\n .text()\n .label(\"Description\")\n .description(\n \"Human-facing description shown in the project picker. Not sent to the LLM.\"\n )\n .renderer(\"textarea\", { rows: 3 }),\n instructions: f\n .text()\n .label(\"Instructions\")\n .description(\n \"System-prompt-style guidance that will be sent to the LLM when this project is selected.\"\n )\n .renderer(\"textarea\", { rows: 6 }),\n defaultReaderPersonaId: f\n .text()\n .label(\"Default Reader Persona\")\n .description(\n \"Auto-populates the reader persona when this project is selected.\"\n )\n .options(({ form }) => {\n const data = form.getData();\n const presets = data?.readerPersonas?.presets;\n if (!presets || presets.length === 0) {\n return [];\n }\n return presets.map((preset: { id: string; name: string }) => ({\n label: preset.name,\n value: preset.id\n }));\n }),\n defaultWriterPersonaId: f\n .text()\n .label(\"Default Writer Persona\")\n .description(\n \"Auto-populates the writer persona when this project is selected.\"\n )\n .options(({ form }) => {\n const data = form.getData();\n const presets = data?.writerPersonas?.presets;\n if (!presets || presets.length === 0) {\n return [];\n }\n return presets.map((preset: { id: string; name: string }) => ({\n label: preset.name,\n value: preset.id\n }));\n }),\n files: f\n .file()\n .label(\"Files\")\n .list()\n .description(\n \"Add files from the library to include as context for the LLM.\"\n )\n .note(\n \"Only files containing text will be sent to the LLM (.mdx, .md, .html, .json, .csv, .txt, etc.)\"\n )\n }))\n .list()\n }));\n\n form.layout(layout => [layout.row(\"presets\")]);\n }\n}\n\nexport const ProjectsSettings = AiPowerUpsSettingsGroup.createImplementation({\n implementation: ProjectsSettingsImpl,\n dependencies: []\n});\n"],"names":["ProjectsSettingsImpl","form","fields","data","index","String","f","generateAlphaNumericId","presets","preset","layout","ProjectsSettings","AiPowerUpsSettingsGroup"],"mappings":";;AAGA,MAAMA;IAKF,UAAUC,IAAyC,EAAQ;QACvDA,KAAK,MAAM,CAACC,CAAAA,SAAW;gBACnB,SAASA,OACJ,MAAM,GACN,KAAK,CAAC,WACN,QAAQ,CAAC,2BAA2B;oBACjC,WAAW;oBACX,cAAc;oBACd,WAAW,CAACC,MAAMC,QAAUC,OAAOF,KAAK,IAAI,IAAI,CAAC,SAAS,EAAEC,QAAQ,GAAG;gBAC3E,GACC,MAAM,CAACE,CAAAA,IAAM;wBACV,IAAIA,EACC,IAAI,GACJ,MAAM,GACN,YAAY,CAAC,IAAMC,uBAAuB;wBAC/C,MAAMD,EACD,IAAI,GACJ,KAAK,CAAC,QACN,QAAQ,CAAC,oBACT,WAAW,CAAC;wBACjB,aAAaA,EACR,IAAI,GACJ,KAAK,CAAC,eACN,WAAW,CACR,8EAEH,QAAQ,CAAC,YAAY;4BAAE,MAAM;wBAAE;wBACpC,cAAcA,EACT,IAAI,GACJ,KAAK,CAAC,gBACN,WAAW,CACR,4FAEH,QAAQ,CAAC,YAAY;4BAAE,MAAM;wBAAE;wBACpC,wBAAwBA,EACnB,IAAI,GACJ,KAAK,CAAC,0BACN,WAAW,CACR,oEAEH,OAAO,CAAC,CAAC,EAAEL,IAAI,EAAE;4BACd,MAAME,OAAOF,KAAK,OAAO;4BACzB,MAAMO,UAAUL,MAAM,gBAAgB;4BACtC,IAAI,CAACK,WAAWA,AAAmB,MAAnBA,QAAQ,MAAM,EAC1B,OAAO,EAAE;4BAEb,OAAOA,QAAQ,GAAG,CAAC,CAACC,SAA0C;oCAC1D,OAAOA,OAAO,IAAI;oCAClB,OAAOA,OAAO,EAAE;gCACpB;wBACJ;wBACJ,wBAAwBH,EACnB,IAAI,GACJ,KAAK,CAAC,0BACN,WAAW,CACR,oEAEH,OAAO,CAAC,CAAC,EAAEL,IAAI,EAAE;4BACd,MAAME,OAAOF,KAAK,OAAO;4BACzB,MAAMO,UAAUL,MAAM,gBAAgB;4BACtC,IAAI,CAACK,WAAWA,AAAmB,MAAnBA,QAAQ,MAAM,EAC1B,OAAO,EAAE;4BAEb,OAAOA,QAAQ,GAAG,CAAC,CAACC,SAA0C;oCAC1D,OAAOA,OAAO,IAAI;oCAClB,OAAOA,OAAO,EAAE;gCACpB;wBACJ;wBACJ,OAAOH,EACF,IAAI,GACJ,KAAK,CAAC,SACN,IAAI,GACJ,WAAW,CACR,iEAEH,IAAI,CACD;oBAEZ,IACC,IAAI;YACb;QAEAL,KAAK,MAAM,CAACS,CAAAA,SAAU;gBAACA,OAAO,GAAG,CAAC;aAAW;IACjD;;aAvFA,IAAI,GAAG;aACP,KAAK,GAAG;aACR,WAAW,GAAG;;AAsFlB;AAEO,MAAMC,mBAAmBC,wBAAwB,oBAAoB,CAAC;IACzE,gBAAgBZ;IAChB,cAAc,EAAE;AACpB"}
|
|
@@ -19,7 +19,7 @@ class ProviderSettingsImpl {
|
|
|
19
19
|
}).fields((f)=>({
|
|
20
20
|
id: f.text().hidden().defaultValue(()=>generateAlphaNumericId(10)),
|
|
21
21
|
name: f.text().label("Name").required("Name is required"),
|
|
22
|
-
model: f.text().label("Model").required("Model is required").options(()=>this.getModelOptions()),
|
|
22
|
+
model: f.text().label("Model").required("Model is required").options(()=>this.getModelOptions()).renderer("autoComplete"),
|
|
23
23
|
apiKey: f.text().label("API Key").required("API Key is required")
|
|
24
24
|
})).list()
|
|
25
25
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin/presentation/ProvidersSettings.js","sources":["../../../src/admin/presentation/ProvidersSettings.ts"],"sourcesContent":["import { generateAlphaNumericId } from \"@webiny/utils\";\nimport { AiPowerUpsSettingsGroup } from \"./AiPowerUpsSettings/settingsGroup.js\";\nimport {\n ListModelsUseCase,\n ListModelsRepository\n} from \"~/admin/features/listModels/abstractions.js\";\n\nclass ProviderSettingsImpl implements AiPowerUpsSettingsGroup.Interface {\n name = \"providers\";\n label = \"Providers\";\n description = \"Configure AI model providers.\";\n\n constructor(\n private useCase: ListModelsUseCase.Interface,\n private repository: ListModelsRepository.Interface\n ) {}\n\n buildForm(form: AiPowerUpsSettingsGroup.FormBuilder): void {\n void this.useCase.execute();\n\n form.fields(fields => ({\n presets: fields\n .object()\n .label(\"Presets\")\n .renderer(\"objectAccordionMultiple\", {\n container: false,\n addItemLabel: \"Add provider\",\n itemTitle: (data, index) => String(data.name || `Provider #${index + 1}`)\n })\n .fields(f => ({\n id: f\n .text()\n .hidden()\n .defaultValue(() => generateAlphaNumericId(10)),\n name: f.text().label(\"Name\").required(\"Name is required\"),\n model: f\n .text()\n .label(\"Model\")\n .required(\"Model is required\")\n .options(() => this.getModelOptions()),\n apiKey: f.text().label(\"API Key\").required(\"API Key is required\")\n }))\n .list()\n }));\n\n form.layout(layout => [layout.row(\"presets\")]);\n }\n\n private getModelOptions() {\n return this.repository.getModels().map(model => ({\n label: `${model.modelName} (${model.modelId})`,\n value: `${model.providerId}/${model.modelId}`\n }));\n }\n}\n\nexport const ProviderSettings = AiPowerUpsSettingsGroup.createImplementation({\n implementation: ProviderSettingsImpl,\n dependencies: [ListModelsUseCase, ListModelsRepository]\n});\n"],"names":["ProviderSettingsImpl","useCase","repository","form","fields","data","index","String","f","generateAlphaNumericId","layout","model","ProviderSettings","AiPowerUpsSettingsGroup","ListModelsUseCase","ListModelsRepository"],"mappings":";;;AAOA,MAAMA;IAKF,YACYC,OAAoC,EACpCC,UAA0C,CACpD;aAFUD,OAAO,GAAPA;aACAC,UAAU,GAAVA;aANZ,IAAI,GAAG;aACP,KAAK,GAAG;aACR,WAAW,GAAG;IAKX;IAEH,UAAUC,IAAyC,EAAQ;QAClD,IAAI,CAAC,OAAO,CAAC,OAAO;QAEzBA,KAAK,MAAM,CAACC,CAAAA,SAAW;gBACnB,SAASA,OACJ,MAAM,GACN,KAAK,CAAC,WACN,QAAQ,CAAC,2BAA2B;oBACjC,WAAW;oBACX,cAAc;oBACd,WAAW,CAACC,MAAMC,QAAUC,OAAOF,KAAK,IAAI,IAAI,CAAC,UAAU,EAAEC,QAAQ,GAAG;gBAC5E,GACC,MAAM,CAACE,CAAAA,IAAM;wBACV,IAAIA,EACC,IAAI,GACJ,MAAM,GACN,YAAY,CAAC,IAAMC,uBAAuB;wBAC/C,MAAMD,EAAE,IAAI,GAAG,KAAK,CAAC,QAAQ,QAAQ,CAAC;wBACtC,OAAOA,EACF,IAAI,GACJ,KAAK,CAAC,SACN,QAAQ,CAAC,qBACT,OAAO,CAAC,IAAM,IAAI,CAAC,eAAe;
|
|
1
|
+
{"version":3,"file":"admin/presentation/ProvidersSettings.js","sources":["../../../src/admin/presentation/ProvidersSettings.ts"],"sourcesContent":["import { generateAlphaNumericId } from \"@webiny/utils\";\nimport { AiPowerUpsSettingsGroup } from \"./AiPowerUpsSettings/settingsGroup.js\";\nimport {\n ListModelsUseCase,\n ListModelsRepository\n} from \"~/admin/features/listModels/abstractions.js\";\n\nclass ProviderSettingsImpl implements AiPowerUpsSettingsGroup.Interface {\n name = \"providers\";\n label = \"Providers\";\n description = \"Configure AI model providers.\";\n\n constructor(\n private useCase: ListModelsUseCase.Interface,\n private repository: ListModelsRepository.Interface\n ) {}\n\n buildForm(form: AiPowerUpsSettingsGroup.FormBuilder): void {\n void this.useCase.execute();\n\n form.fields(fields => ({\n presets: fields\n .object()\n .label(\"Presets\")\n .renderer(\"objectAccordionMultiple\", {\n container: false,\n addItemLabel: \"Add provider\",\n itemTitle: (data, index) => String(data.name || `Provider #${index + 1}`)\n })\n .fields(f => ({\n id: f\n .text()\n .hidden()\n .defaultValue(() => generateAlphaNumericId(10)),\n name: f.text().label(\"Name\").required(\"Name is required\"),\n model: f\n .text()\n .label(\"Model\")\n .required(\"Model is required\")\n .options(() => this.getModelOptions())\n .renderer(\"autoComplete\"),\n apiKey: f.text().label(\"API Key\").required(\"API Key is required\")\n }))\n .list()\n }));\n\n form.layout(layout => [layout.row(\"presets\")]);\n }\n\n private getModelOptions() {\n return this.repository.getModels().map(model => ({\n label: `${model.modelName} (${model.modelId})`,\n value: `${model.providerId}/${model.modelId}`\n }));\n }\n}\n\nexport const ProviderSettings = AiPowerUpsSettingsGroup.createImplementation({\n implementation: ProviderSettingsImpl,\n dependencies: [ListModelsUseCase, ListModelsRepository]\n});\n"],"names":["ProviderSettingsImpl","useCase","repository","form","fields","data","index","String","f","generateAlphaNumericId","layout","model","ProviderSettings","AiPowerUpsSettingsGroup","ListModelsUseCase","ListModelsRepository"],"mappings":";;;AAOA,MAAMA;IAKF,YACYC,OAAoC,EACpCC,UAA0C,CACpD;aAFUD,OAAO,GAAPA;aACAC,UAAU,GAAVA;aANZ,IAAI,GAAG;aACP,KAAK,GAAG;aACR,WAAW,GAAG;IAKX;IAEH,UAAUC,IAAyC,EAAQ;QAClD,IAAI,CAAC,OAAO,CAAC,OAAO;QAEzBA,KAAK,MAAM,CAACC,CAAAA,SAAW;gBACnB,SAASA,OACJ,MAAM,GACN,KAAK,CAAC,WACN,QAAQ,CAAC,2BAA2B;oBACjC,WAAW;oBACX,cAAc;oBACd,WAAW,CAACC,MAAMC,QAAUC,OAAOF,KAAK,IAAI,IAAI,CAAC,UAAU,EAAEC,QAAQ,GAAG;gBAC5E,GACC,MAAM,CAACE,CAAAA,IAAM;wBACV,IAAIA,EACC,IAAI,GACJ,MAAM,GACN,YAAY,CAAC,IAAMC,uBAAuB;wBAC/C,MAAMD,EAAE,IAAI,GAAG,KAAK,CAAC,QAAQ,QAAQ,CAAC;wBACtC,OAAOA,EACF,IAAI,GACJ,KAAK,CAAC,SACN,QAAQ,CAAC,qBACT,OAAO,CAAC,IAAM,IAAI,CAAC,eAAe,IAClC,QAAQ,CAAC;wBACd,QAAQA,EAAE,IAAI,GAAG,KAAK,CAAC,WAAW,QAAQ,CAAC;oBAC/C,IACC,IAAI;YACb;QAEAL,KAAK,MAAM,CAACO,CAAAA,SAAU;gBAACA,OAAO,GAAG,CAAC;aAAW;IACjD;IAEQ,kBAAkB;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,GAAG,CAACC,CAAAA,QAAU;gBAC7C,OAAO,GAAGA,MAAM,SAAS,CAAC,EAAE,EAAEA,MAAM,OAAO,CAAC,CAAC,CAAC;gBAC9C,OAAO,GAAGA,MAAM,UAAU,CAAC,CAAC,EAAEA,MAAM,OAAO,EAAE;YACjD;IACJ;AACJ;AAEO,MAAMC,mBAAmBC,wBAAwB,oBAAoB,CAAC;IACzE,gBAAgBb;IAChB,cAAc;QAACc;QAAmBC;KAAqB;AAC3D"}
|
|
@@ -16,6 +16,6 @@ export interface GeneratePageContentErrorMessage extends IncomingGenericData {
|
|
|
16
16
|
message: string;
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
-
export declare const GenerateContentDialog: (() => React.JSX.Element) & {
|
|
20
|
-
|
|
19
|
+
export declare const GenerateContentDialog: (() => React.JSX.Element) & React.NamedExoticComponent<unknown> & {
|
|
20
|
+
readonly type: () => React.JSX.Element;
|
|
21
21
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import react, { useCallback, useEffect, useRef } from "react";
|
|
2
2
|
import { observer } from "mobx-react-lite";
|
|
3
3
|
import { FormView, useDialog } from "@webiny/app-admin";
|
|
4
|
-
import { Dialog, OverlayLoader, useToast } from "@webiny/admin-ui";
|
|
4
|
+
import { BetaBadge, Dialog, OverlayLoader, useToast } from "@webiny/admin-ui";
|
|
5
5
|
import { useFeature } from "@webiny/app";
|
|
6
6
|
import { useWebsockets } from "@webiny/app-websockets";
|
|
7
7
|
import { useSelectFromEditor } from "@webiny/app-website-builder/BaseEditor/hooks/useSelectFromEditor.js";
|
|
@@ -96,7 +96,7 @@ const GenerateContentDialog = observer(()=>{
|
|
|
96
96
|
return /*#__PURE__*/ react.createElement(Dialog, {
|
|
97
97
|
open: true,
|
|
98
98
|
onClose: closeDialog,
|
|
99
|
-
title: "Generate Content",
|
|
99
|
+
title: /*#__PURE__*/ react.createElement(react.Fragment, null, "Generate Content ", /*#__PURE__*/ react.createElement(BetaBadge, null)),
|
|
100
100
|
size: "lg",
|
|
101
101
|
actions: /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(Dialog.CancelAction, {
|
|
102
102
|
onClick: closeDialog,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin/presentation/WbContentGeneration/GenerateContentDialog.js","sources":["../../../../src/admin/presentation/WbContentGeneration/GenerateContentDialog.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useDialog, FormView } from \"@webiny/app-admin\";\nimport { Dialog, OverlayLoader, useToast } from \"@webiny/admin-ui\";\nimport { useFeature } from \"@webiny/app\";\nimport type { IncomingGenericData } from \"@webiny/app-websockets\";\nimport { useWebsockets } from \"@webiny/app-websockets\";\nimport { useSelectFromEditor } from \"@webiny/app-website-builder/BaseEditor/hooks/useSelectFromEditor.js\";\nimport { useCreateElement } from \"@webiny/app-website-builder/BaseEditor/hooks/useCreateElement.js\";\nimport { GenerateContentFeature } from \"./feature.js\";\nimport { decompressGzipBase64 } from \"./decompressGzipBase64.js\";\nimport type { CreateElementParams } from \"./abstractions.js\";\n\nfunction formatElapsed(totalSeconds: number): string {\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${seconds.toString().padStart(2, \"0\")}`;\n}\n\nexport const GENERATE_CONTENT_DIALOG = \"generate-content\";\n\nexport const WS_ACTION_CONTENT = \"aiPowerUps.generatePageContent.content\";\nexport const WS_ACTION_ERROR = \"aiPowerUps.generatePageContent.error\";\n\nexport interface GeneratePageContentMessage extends IncomingGenericData {\n action: typeof WS_ACTION_CONTENT;\n data: {\n compression: \"gzip\";\n value: string;\n };\n}\n\nexport interface GeneratePageContentErrorMessage extends IncomingGenericData {\n action: typeof WS_ACTION_ERROR;\n data: {\n message: string;\n };\n}\n\nexport const GenerateContentDialog = observer(() => {\n const { closeDialog } = useDialog();\n const { presenter } = useFeature(GenerateContentFeature);\n const vm = presenter.vm;\n const wasSubmitting = useRef(false);\n const websockets = useWebsockets();\n const toast = useToast();\n\n const components = useSelectFromEditor(state => state.components);\n const { createElement } = useCreateElement();\n\n const createElements = useCallback(\n async (elements: CreateElementParams[]) => {\n for (const el of elements) {\n await createElement(el);\n }\n },\n [createElement]\n );\n\n useEffect(() => {\n const aiComponents = Object.values(components)\n .filter(c => c.useInAiContentGeneration !== false)\n .map(c => {\n return {\n name: c.name,\n label: c.label,\n aiContext: c.aiContext,\n inputs: c.inputs.map(input => ({\n type: input.type,\n name: input.name,\n label: input.label,\n description: input.description\n }))\n };\n });\n presenter.init(aiComponents, createElements);\n }, [components, createElements]);\n\n useEffect(() => {\n const contentSubscription = websockets.onMessage<GeneratePageContentMessage>(\n WS_ACTION_CONTENT,\n async message => {\n const responseText = await decompressGzipBase64(message.data.value);\n try {\n await presenter.processAiResponse(responseText);\n } catch (e) {\n console.error(\"Failed to process AI response\", { responseText });\n console.error(e);\n toast.showWarningToast({\n title: \"Failed to process AI response\",\n description: \"Open the console for more details.\"\n });\n presenter.cancelPrompt();\n }\n }\n );\n\n const errorSubscription = websockets.onMessage<GeneratePageContentErrorMessage>(\n WS_ACTION_ERROR,\n async message => {\n toast.showWarningToast({\n title: \"Failed to generate content\",\n description: message.data.message\n });\n presenter.cancelPrompt();\n }\n );\n\n return () => {\n contentSubscription.off();\n errorSubscription.off();\n };\n }, []);\n\n useEffect(() => {\n if (wasSubmitting.current && !vm.submitting && !vm.timedOut) {\n closeDialog();\n }\n wasSubmitting.current = vm.submitting;\n }, [vm.submitting]);\n\n useEffect(() => {\n if (vm.timedOut) {\n toast.showWarningToast({\n title: \"Request timed out\",\n description: \"The AI generation took too long. Please try again.\"\n });\n }\n }, [vm.timedOut]);\n\n const handleSubmit = async () => {\n await presenter.submit();\n };\n\n return (\n <Dialog\n open={true}\n onClose={closeDialog}\n title
|
|
1
|
+
{"version":3,"file":"admin/presentation/WbContentGeneration/GenerateContentDialog.js","sources":["../../../../src/admin/presentation/WbContentGeneration/GenerateContentDialog.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport { useDialog, FormView } from \"@webiny/app-admin\";\nimport { BetaBadge } from \"@webiny/admin-ui\";\nimport { Dialog, OverlayLoader, useToast } from \"@webiny/admin-ui\";\nimport { useFeature } from \"@webiny/app\";\nimport type { IncomingGenericData } from \"@webiny/app-websockets\";\nimport { useWebsockets } from \"@webiny/app-websockets\";\nimport { useSelectFromEditor } from \"@webiny/app-website-builder/BaseEditor/hooks/useSelectFromEditor.js\";\nimport { useCreateElement } from \"@webiny/app-website-builder/BaseEditor/hooks/useCreateElement.js\";\nimport { GenerateContentFeature } from \"./feature.js\";\nimport { decompressGzipBase64 } from \"./decompressGzipBase64.js\";\nimport type { CreateElementParams } from \"./abstractions.js\";\n\nfunction formatElapsed(totalSeconds: number): string {\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${seconds.toString().padStart(2, \"0\")}`;\n}\n\nexport const GENERATE_CONTENT_DIALOG = \"generate-content\";\n\nexport const WS_ACTION_CONTENT = \"aiPowerUps.generatePageContent.content\";\nexport const WS_ACTION_ERROR = \"aiPowerUps.generatePageContent.error\";\n\nexport interface GeneratePageContentMessage extends IncomingGenericData {\n action: typeof WS_ACTION_CONTENT;\n data: {\n compression: \"gzip\";\n value: string;\n };\n}\n\nexport interface GeneratePageContentErrorMessage extends IncomingGenericData {\n action: typeof WS_ACTION_ERROR;\n data: {\n message: string;\n };\n}\n\nexport const GenerateContentDialog = observer(() => {\n const { closeDialog } = useDialog();\n const { presenter } = useFeature(GenerateContentFeature);\n const vm = presenter.vm;\n const wasSubmitting = useRef(false);\n const websockets = useWebsockets();\n const toast = useToast();\n\n const components = useSelectFromEditor(state => state.components);\n const { createElement } = useCreateElement();\n\n const createElements = useCallback(\n async (elements: CreateElementParams[]) => {\n for (const el of elements) {\n await createElement(el);\n }\n },\n [createElement]\n );\n\n useEffect(() => {\n const aiComponents = Object.values(components)\n .filter(c => c.useInAiContentGeneration !== false)\n .map(c => {\n return {\n name: c.name,\n label: c.label,\n aiContext: c.aiContext,\n inputs: c.inputs.map(input => ({\n type: input.type,\n name: input.name,\n label: input.label,\n description: input.description\n }))\n };\n });\n presenter.init(aiComponents, createElements);\n }, [components, createElements]);\n\n useEffect(() => {\n const contentSubscription = websockets.onMessage<GeneratePageContentMessage>(\n WS_ACTION_CONTENT,\n async message => {\n const responseText = await decompressGzipBase64(message.data.value);\n try {\n await presenter.processAiResponse(responseText);\n } catch (e) {\n console.error(\"Failed to process AI response\", { responseText });\n console.error(e);\n toast.showWarningToast({\n title: \"Failed to process AI response\",\n description: \"Open the console for more details.\"\n });\n presenter.cancelPrompt();\n }\n }\n );\n\n const errorSubscription = websockets.onMessage<GeneratePageContentErrorMessage>(\n WS_ACTION_ERROR,\n async message => {\n toast.showWarningToast({\n title: \"Failed to generate content\",\n description: message.data.message\n });\n presenter.cancelPrompt();\n }\n );\n\n return () => {\n contentSubscription.off();\n errorSubscription.off();\n };\n }, []);\n\n useEffect(() => {\n if (wasSubmitting.current && !vm.submitting && !vm.timedOut) {\n closeDialog();\n }\n wasSubmitting.current = vm.submitting;\n }, [vm.submitting]);\n\n useEffect(() => {\n if (vm.timedOut) {\n toast.showWarningToast({\n title: \"Request timed out\",\n description: \"The AI generation took too long. Please try again.\"\n });\n }\n }, [vm.timedOut]);\n\n const handleSubmit = async () => {\n await presenter.submit();\n };\n\n return (\n <Dialog\n open={true}\n onClose={closeDialog}\n title={\n <>\n Generate Content <BetaBadge />\n </>\n }\n size={\"lg\"}\n actions={\n <>\n <Dialog.CancelAction onClick={closeDialog} text=\"Cancel\" />\n <Dialog.ConfirmAction\n onClick={handleSubmit}\n text=\"Generate\"\n disabled={vm.loading || vm.submitting}\n />\n </>\n }\n >\n {vm.loading ? <OverlayLoader text={\"Loading...\"} /> : null}\n {vm.submitting ? (\n <OverlayLoader\n className={\"bg-neutral-base/90\"}\n text={\n <>\n <div>Generating content... {formatElapsed(vm.elapsedSeconds)}</div>\n <div className=\"text-sm text-neutral-muted pt-xs\">\n Content generation can take a few minutes, depending on the model\n you're using.\n </div>\n </>\n }\n />\n ) : null}\n {vm.processing ? <OverlayLoader text={\"Processing content...\"} /> : null}\n {vm.form ? <FormView name=\"GenerateContent\" form={vm.form} /> : null}\n </Dialog>\n );\n});\n"],"names":["formatElapsed","totalSeconds","minutes","Math","seconds","GENERATE_CONTENT_DIALOG","WS_ACTION_CONTENT","WS_ACTION_ERROR","GenerateContentDialog","observer","closeDialog","useDialog","presenter","useFeature","GenerateContentFeature","vm","wasSubmitting","useRef","websockets","useWebsockets","toast","useToast","components","useSelectFromEditor","state","createElement","useCreateElement","createElements","useCallback","elements","el","useEffect","aiComponents","Object","c","input","contentSubscription","message","responseText","decompressGzipBase64","e","console","errorSubscription","handleSubmit","Dialog","BetaBadge","OverlayLoader","FormView"],"mappings":"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"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ToolRegistry, ToolPipelineRunner } from "@webiny/app-admin";
|
|
2
2
|
import { GenerateContentPresenter, type CreateElementsFn } from "./abstractions.js";
|
|
3
3
|
import { GeneratePageContentUseCase } from "../../../admin/features/generatePageContent/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { AiPromptFormFactory } from "../../../admin/presentation/AiPromptFormFactory/abstractions.js";
|
|
5
5
|
declare class GenerateContentPresenterImpl implements GenerateContentPresenter.Interface {
|
|
6
6
|
private toolRegistry;
|
|
7
7
|
private pipelineRunner;
|
|
8
8
|
private generatePageContent;
|
|
9
|
-
private
|
|
10
|
-
private getSettings;
|
|
9
|
+
private formFactory;
|
|
11
10
|
private _loading;
|
|
12
11
|
private _submitting;
|
|
13
12
|
private _processing;
|
|
@@ -15,11 +14,10 @@ declare class GenerateContentPresenterImpl implements GenerateContentPresenter.I
|
|
|
15
14
|
private _components;
|
|
16
15
|
private _createElements;
|
|
17
16
|
private _form;
|
|
18
|
-
private _settings;
|
|
19
17
|
private _timeoutId;
|
|
20
18
|
private _intervalId;
|
|
21
19
|
private _elapsedSeconds;
|
|
22
|
-
constructor(toolRegistry: ToolRegistry.Interface, pipelineRunner: ToolPipelineRunner.Interface, generatePageContent: GeneratePageContentUseCase.Interface,
|
|
20
|
+
constructor(toolRegistry: ToolRegistry.Interface, pipelineRunner: ToolPipelineRunner.Interface, generatePageContent: GeneratePageContentUseCase.Interface, formFactory: AiPromptFormFactory.Interface);
|
|
23
21
|
get vm(): GenerateContentPresenter.ViewModel;
|
|
24
22
|
init(components: Record<string, any>[], createElements: CreateElementsFn): Promise<void>;
|
|
25
23
|
submit(): Promise<void>;
|
|
@@ -28,12 +26,6 @@ declare class GenerateContentPresenterImpl implements GenerateContentPresenter.I
|
|
|
28
26
|
private startTimeout;
|
|
29
27
|
private clearTimeout;
|
|
30
28
|
private clearInterval;
|
|
31
|
-
private buildForm;
|
|
32
|
-
private getSelectedProject;
|
|
33
|
-
private getProjectFileOptions;
|
|
34
|
-
private computeExcludedFileIds;
|
|
35
|
-
private getProjectOptions;
|
|
36
|
-
private getPersonaOptions;
|
|
37
29
|
}
|
|
38
30
|
export declare const GenerateContentPresenterRegistration: typeof GenerateContentPresenterImpl & {
|
|
39
31
|
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IGenerateContentPresenter>;
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { computed, makeAutoObservable, runInAction, toJS } from "mobx";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import pick from "lodash/pick.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ToolPipelineRunner, ToolRegistry } from "@webiny/app-admin";
|
|
5
5
|
import { GenerateContentPresenter } from "./abstractions.js";
|
|
6
6
|
import { GeneratePageContentUseCase } from "../../features/generatePageContent/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { AiPromptFormFactory } from "../AiPromptFormFactory/abstractions.js";
|
|
8
8
|
const SUBMIT_TIMEOUT_MS = 300000;
|
|
9
9
|
class GenerateContentPresenterImpl {
|
|
10
|
-
constructor(toolRegistry, pipelineRunner, generatePageContent,
|
|
10
|
+
constructor(toolRegistry, pipelineRunner, generatePageContent, formFactory){
|
|
11
11
|
this.toolRegistry = toolRegistry;
|
|
12
12
|
this.pipelineRunner = pipelineRunner;
|
|
13
13
|
this.generatePageContent = generatePageContent;
|
|
14
|
-
this.
|
|
15
|
-
this.getSettings = getSettings;
|
|
14
|
+
this.formFactory = formFactory;
|
|
16
15
|
this._loading = false;
|
|
17
16
|
this._submitting = false;
|
|
18
17
|
this._processing = false;
|
|
@@ -20,7 +19,6 @@ class GenerateContentPresenterImpl {
|
|
|
20
19
|
this._components = [];
|
|
21
20
|
this._createElements = ()=>{};
|
|
22
21
|
this._form = null;
|
|
23
|
-
this._settings = null;
|
|
24
22
|
this._timeoutId = null;
|
|
25
23
|
this._intervalId = null;
|
|
26
24
|
this._elapsedSeconds = 0;
|
|
@@ -43,18 +41,9 @@ class GenerateContentPresenterImpl {
|
|
|
43
41
|
async init(components, createElements) {
|
|
44
42
|
this._components = components;
|
|
45
43
|
this._createElements = createElements;
|
|
46
|
-
this.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
runInAction(()=>{
|
|
50
|
-
this._settings = settings;
|
|
51
|
-
this._form = this.buildForm();
|
|
52
|
-
});
|
|
53
|
-
} finally{
|
|
54
|
-
runInAction(()=>{
|
|
55
|
-
this._loading = false;
|
|
56
|
-
});
|
|
57
|
-
}
|
|
44
|
+
this._form = this.formFactory.createForm({
|
|
45
|
+
promptDescription: "Describe the page content you want to generate."
|
|
46
|
+
});
|
|
58
47
|
}
|
|
59
48
|
async submit() {
|
|
60
49
|
if (!this._form) return;
|
|
@@ -78,7 +67,8 @@ class GenerateContentPresenterImpl {
|
|
|
78
67
|
"type"
|
|
79
68
|
])
|
|
80
69
|
}));
|
|
81
|
-
const excludedFileIds = this.computeExcludedFileIds(
|
|
70
|
+
const excludedFileIds = this.formFactory.computeExcludedFileIds(this._form);
|
|
71
|
+
const additionalFileIds = data.additionalFiles?.map((f)=>f.id) ?? null;
|
|
82
72
|
await this.generatePageContent.execute({
|
|
83
73
|
prompt: data.prompt,
|
|
84
74
|
components: toJS(this._components),
|
|
@@ -86,7 +76,8 @@ class GenerateContentPresenterImpl {
|
|
|
86
76
|
projectId: data.project || null,
|
|
87
77
|
excludedFileIds,
|
|
88
78
|
readerPersonaId: data.readerPersona || null,
|
|
89
|
-
writerPersonaId: data.writerPersona || null
|
|
79
|
+
writerPersonaId: data.writerPersona || null,
|
|
80
|
+
additionalFileIds
|
|
90
81
|
});
|
|
91
82
|
} catch {
|
|
92
83
|
this.clearTimeout();
|
|
@@ -155,78 +146,6 @@ class GenerateContentPresenterImpl {
|
|
|
155
146
|
this._intervalId = null;
|
|
156
147
|
}
|
|
157
148
|
}
|
|
158
|
-
buildForm() {
|
|
159
|
-
return this.formModelFactory.create({
|
|
160
|
-
fields: (fields)=>({
|
|
161
|
-
project: fields.text().label("Project").description("Select a predefined context to attach.").options(()=>this.getProjectOptions()).afterChange((value, form)=>{
|
|
162
|
-
const projectId = value;
|
|
163
|
-
const project = projectId ? this._settings?.projects?.presets?.find((p)=>p.id === projectId) : void 0;
|
|
164
|
-
if (project?.defaultReaderPersonaId) form.field("readerPersona").setValue(project.defaultReaderPersonaId);
|
|
165
|
-
if (project?.defaultWriterPersonaId) form.field("writerPersona").setValue(project.defaultWriterPersonaId);
|
|
166
|
-
const fileIds = (project?.files ?? []).map((f)=>f.id);
|
|
167
|
-
form.field("includedFiles").setValue(fileIds);
|
|
168
|
-
}),
|
|
169
|
-
includedFiles: fields.text().label("Files included").description("Uncheck files to exclude them from this generation only.").options(()=>this.getProjectFileOptions()).renderer("checkboxes").list().hiddenWhen((form)=>{
|
|
170
|
-
const projectId = form.field("project").as("text").getValue();
|
|
171
|
-
if (!projectId) return true;
|
|
172
|
-
const project = this._settings?.projects?.presets?.find((p)=>p.id === projectId);
|
|
173
|
-
return !project?.files || 0 === project.files.length;
|
|
174
|
-
}),
|
|
175
|
-
readerPersona: fields.text().label("Reader Persona").description("Select the target audience for the generated content.").options(()=>this.getPersonaOptions("reader")),
|
|
176
|
-
writerPersona: fields.text().label("Writer Persona").description("Select the writing style for the generated content.").options(()=>this.getPersonaOptions("writer")),
|
|
177
|
-
prompt: fields.text().label("Prompt").description("Describe the page content you want to generate.").required("Prompt is required").renderer("textarea", {
|
|
178
|
-
rows: 6
|
|
179
|
-
})
|
|
180
|
-
}),
|
|
181
|
-
layout: (layout)=>[
|
|
182
|
-
layout.row("project"),
|
|
183
|
-
layout.row("includedFiles"),
|
|
184
|
-
layout.row("readerPersona"),
|
|
185
|
-
layout.row("writerPersona"),
|
|
186
|
-
layout.row("prompt")
|
|
187
|
-
]
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
getSelectedProject() {
|
|
191
|
-
if (!this._form || !this._settings) return;
|
|
192
|
-
const projectId = this._form.field("project").getValue();
|
|
193
|
-
if (!projectId) return;
|
|
194
|
-
return this._settings.projects?.presets?.find((p)=>p.id === projectId);
|
|
195
|
-
}
|
|
196
|
-
getProjectFileOptions() {
|
|
197
|
-
const project = this.getSelectedProject();
|
|
198
|
-
const files = project?.files;
|
|
199
|
-
if (!files || 0 === files.length) return [];
|
|
200
|
-
return files.map((f)=>({
|
|
201
|
-
label: f.name,
|
|
202
|
-
value: f.id
|
|
203
|
-
}));
|
|
204
|
-
}
|
|
205
|
-
computeExcludedFileIds(projectId, includedFiles) {
|
|
206
|
-
if (!projectId) return null;
|
|
207
|
-
const project = this._settings?.projects?.presets?.find((p)=>p.id === projectId);
|
|
208
|
-
const allFileIds = (project?.files ?? []).map((f)=>f.id);
|
|
209
|
-
if (0 === allFileIds.length) return null;
|
|
210
|
-
const included = new Set(includedFiles ?? []);
|
|
211
|
-
const excluded = allFileIds.filter((id)=>!included.has(id));
|
|
212
|
-
return excluded.length > 0 ? excluded : null;
|
|
213
|
-
}
|
|
214
|
-
getProjectOptions() {
|
|
215
|
-
const presets = this._settings?.projects?.presets;
|
|
216
|
-
if (!presets || 0 === presets.length) return [];
|
|
217
|
-
return presets.map((preset)=>({
|
|
218
|
-
label: preset.name,
|
|
219
|
-
value: preset.id
|
|
220
|
-
}));
|
|
221
|
-
}
|
|
222
|
-
getPersonaOptions(type) {
|
|
223
|
-
const presets = "reader" === type ? this._settings?.readerPersonas?.presets : this._settings?.writerPersonas?.presets;
|
|
224
|
-
if (!presets || 0 === presets.length) return [];
|
|
225
|
-
return presets.map((preset)=>({
|
|
226
|
-
label: preset.name,
|
|
227
|
-
value: preset.id
|
|
228
|
-
}));
|
|
229
|
-
}
|
|
230
149
|
}
|
|
231
150
|
const GenerateContentPresenterRegistration = GenerateContentPresenter.createImplementation({
|
|
232
151
|
implementation: GenerateContentPresenterImpl,
|
|
@@ -234,8 +153,7 @@ const GenerateContentPresenterRegistration = GenerateContentPresenter.createImpl
|
|
|
234
153
|
ToolRegistry,
|
|
235
154
|
ToolPipelineRunner,
|
|
236
155
|
GeneratePageContentUseCase,
|
|
237
|
-
|
|
238
|
-
GetSettingsUseCase
|
|
156
|
+
AiPromptFormFactory
|
|
239
157
|
]
|
|
240
158
|
});
|
|
241
159
|
export { GenerateContentPresenterRegistration };
|