@webiny/ai-powerups 6.6.0-alpha.0 → 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 +10 -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.js +2 -0
- package/admin/features/generateEntryContent/GenerateEntryContentGateway.js.map +1 -1
- package/admin/features/generateEntryContent/abstractions.d.ts +1 -0
- package/admin/features/generateEntryContent/abstractions.js.map +1 -1
- 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/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 +2 -2
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentDialog.d.ts +2 -2
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.d.ts +4 -12
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.js +12 -94
- package/admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.js.map +1 -1
- package/admin/presentation/CmsContentGeneration/Extension.d.ts +1 -1
- package/admin/presentation/CmsContentGeneration/Extension.js +9 -5
- package/admin/presentation/CmsContentGeneration/Extension.js.map +1 -1
- 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/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 +8 -0
- 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/AiImageEnrichmentAfterCreateHandler.d.ts +1 -3
- package/api/features/AiImageEnrichment/AiImageEnrichmentAfterCreateHandler.js +2 -6
- package/api/features/AiImageEnrichment/AiImageEnrichmentAfterCreateHandler.js.map +1 -1
- 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 -16
- package/api/features/AiImageEnrichment/AiImageEnrichmentTask.js +27 -102
- 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 +1 -0
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentTask.js +20 -10
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentTask.js.map +1 -1
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.d.ts +1 -1
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js +5 -5
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js.map +1 -1
- package/api/features/CmsGenerateEntryContent/abstractions.d.ts +10 -3
- package/api/features/CmsGenerateEntryContent/abstractions.js.map +1 -1
- package/api/features/GetSettings/index.d.ts +1 -0
- package/api/features/GetSettings/index.js +1 -0
- package/api/features/Providers/types.d.ts +2 -2
- package/api/features/WbGeneratePageContent/WbGeneratePageContentTask.d.ts +1 -0
- package/api/features/WbGeneratePageContent/WbGeneratePageContentTask.js +19 -9
- 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.js +11 -4
- 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 +32 -25
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ToolPipelineRunner } from "@webiny/app-admin";
|
|
2
2
|
import { CmsGenerateContentPresenter as Abstraction } from "./abstractions.js";
|
|
3
3
|
import { GenerateEntryContentUseCase } from "../../../admin/features/generateEntryContent/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { AiPromptFormFactory } from "../../../admin/presentation/AiPromptFormFactory/abstractions.js";
|
|
5
5
|
declare class CmsGenerateContentPresenterImpl implements Abstraction.Interface {
|
|
6
6
|
private pipelineRunner;
|
|
7
7
|
private generateEntryContent;
|
|
8
|
-
private
|
|
9
|
-
private getSettings;
|
|
8
|
+
private formFactory;
|
|
10
9
|
private _loading;
|
|
11
10
|
private _submitting;
|
|
12
11
|
private _timedOut;
|
|
13
12
|
private _form;
|
|
14
|
-
private _settings;
|
|
15
13
|
private _timeoutId;
|
|
16
14
|
private _intervalId;
|
|
17
15
|
private _elapsedSeconds;
|
|
18
|
-
constructor(pipelineRunner: ToolPipelineRunner.Interface, generateEntryContent: GenerateEntryContentUseCase.Interface,
|
|
16
|
+
constructor(pipelineRunner: ToolPipelineRunner.Interface, generateEntryContent: GenerateEntryContentUseCase.Interface, formFactory: AiPromptFormFactory.Interface);
|
|
19
17
|
get vm(): Abstraction.ViewModel;
|
|
20
18
|
init(): Promise<void>;
|
|
21
19
|
submit(modelId: string): Promise<void>;
|
|
@@ -24,12 +22,6 @@ declare class CmsGenerateContentPresenterImpl implements Abstraction.Interface {
|
|
|
24
22
|
private startTimeout;
|
|
25
23
|
private clearTimeout;
|
|
26
24
|
private clearInterval;
|
|
27
|
-
private buildForm;
|
|
28
|
-
private getSelectedProject;
|
|
29
|
-
private getProjectFileOptions;
|
|
30
|
-
private computeExcludedFileIds;
|
|
31
|
-
private getProjectOptions;
|
|
32
|
-
private getPersonaOptions;
|
|
33
25
|
}
|
|
34
26
|
export declare const CmsGenerateContentPresenter: typeof CmsGenerateContentPresenterImpl & {
|
|
35
27
|
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICmsGenerateContentPresenter>;
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { computed, makeAutoObservable, runInAction } from "mobx";
|
|
2
|
-
import {
|
|
2
|
+
import { ToolPipelineRunner } from "@webiny/app-admin";
|
|
3
3
|
import { CmsGenerateContentPresenter } from "./abstractions.js";
|
|
4
4
|
import { GenerateEntryContentUseCase } from "../../features/generateEntryContent/index.js";
|
|
5
|
-
import {
|
|
5
|
+
import { AiPromptFormFactory } from "../AiPromptFormFactory/abstractions.js";
|
|
6
6
|
const SUBMIT_TIMEOUT_MS = 300000;
|
|
7
7
|
class CmsGenerateContentPresenterImpl {
|
|
8
|
-
constructor(pipelineRunner, generateEntryContent,
|
|
8
|
+
constructor(pipelineRunner, generateEntryContent, formFactory){
|
|
9
9
|
this.pipelineRunner = pipelineRunner;
|
|
10
10
|
this.generateEntryContent = generateEntryContent;
|
|
11
|
-
this.
|
|
12
|
-
this.getSettings = getSettings;
|
|
11
|
+
this.formFactory = formFactory;
|
|
13
12
|
this._loading = false;
|
|
14
13
|
this._submitting = false;
|
|
15
14
|
this._timedOut = false;
|
|
16
15
|
this._form = null;
|
|
17
|
-
this._settings = null;
|
|
18
16
|
this._timeoutId = null;
|
|
19
17
|
this._intervalId = null;
|
|
20
18
|
this._elapsedSeconds = 0;
|
|
@@ -34,18 +32,9 @@ class CmsGenerateContentPresenterImpl {
|
|
|
34
32
|
};
|
|
35
33
|
}
|
|
36
34
|
async init() {
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
runInAction(()=>{
|
|
41
|
-
this._settings = settings;
|
|
42
|
-
this._form = this.buildForm();
|
|
43
|
-
});
|
|
44
|
-
} finally{
|
|
45
|
-
runInAction(()=>{
|
|
46
|
-
this._loading = false;
|
|
47
|
-
});
|
|
48
|
-
}
|
|
35
|
+
this._form = this.formFactory.createForm({
|
|
36
|
+
promptDescription: "Describe the content you want to generate for this entry."
|
|
37
|
+
});
|
|
49
38
|
}
|
|
50
39
|
async submit(modelId) {
|
|
51
40
|
if (!this._form) return;
|
|
@@ -57,14 +46,16 @@ class CmsGenerateContentPresenterImpl {
|
|
|
57
46
|
});
|
|
58
47
|
this.startTimeout();
|
|
59
48
|
try {
|
|
60
|
-
const excludedFileIds = this.computeExcludedFileIds(
|
|
49
|
+
const excludedFileIds = this.formFactory.computeExcludedFileIds(this._form);
|
|
50
|
+
const additionalFileIds = data.additionalFiles?.map((f)=>f.id) ?? null;
|
|
61
51
|
await this.generateEntryContent.execute({
|
|
62
52
|
prompt: data.prompt,
|
|
63
53
|
modelId,
|
|
64
54
|
projectId: data.project || null,
|
|
65
55
|
excludedFileIds,
|
|
66
56
|
readerPersonaId: data.readerPersona || null,
|
|
67
|
-
writerPersonaId: data.writerPersona || null
|
|
57
|
+
writerPersonaId: data.writerPersona || null,
|
|
58
|
+
additionalFileIds
|
|
68
59
|
});
|
|
69
60
|
} catch {
|
|
70
61
|
this.clearTimeout();
|
|
@@ -115,86 +106,13 @@ class CmsGenerateContentPresenterImpl {
|
|
|
115
106
|
this._intervalId = null;
|
|
116
107
|
}
|
|
117
108
|
}
|
|
118
|
-
buildForm() {
|
|
119
|
-
return this.formModelFactory.create({
|
|
120
|
-
fields: (fields)=>({
|
|
121
|
-
project: fields.text().label("Project").description("Select a predefined context to attach.").options(()=>this.getProjectOptions()).afterChange((value, { form })=>{
|
|
122
|
-
const projectId = value;
|
|
123
|
-
const project = projectId ? this._settings?.projects?.presets?.find((p)=>p.id === projectId) : void 0;
|
|
124
|
-
if (project?.defaultReaderPersonaId) form.field("readerPersona").setValue(project.defaultReaderPersonaId);
|
|
125
|
-
if (project?.defaultWriterPersonaId) form.field("writerPersona").setValue(project.defaultWriterPersonaId);
|
|
126
|
-
const fileIds = (project?.files ?? []).map((f)=>f.id);
|
|
127
|
-
form.field("includedFiles").setValue(fileIds);
|
|
128
|
-
}),
|
|
129
|
-
includedFiles: fields.text().label("Files included").description("Uncheck files to exclude them from this generation only.").options(()=>this.getProjectFileOptions()).renderer("checkboxes").list().hiddenWhen(({ form })=>{
|
|
130
|
-
const projectId = form.field("project").as("text").getValue();
|
|
131
|
-
if (!projectId) return true;
|
|
132
|
-
const project = this._settings?.projects?.presets?.find((p)=>p.id === projectId);
|
|
133
|
-
return !project?.files || 0 === project.files.length;
|
|
134
|
-
}),
|
|
135
|
-
readerPersona: fields.text().label("Reader Persona").description("Select the target audience for the generated content.").options(()=>this.getPersonaOptions("reader")),
|
|
136
|
-
writerPersona: fields.text().label("Writer Persona").description("Select the writing style for the generated content.").options(()=>this.getPersonaOptions("writer")),
|
|
137
|
-
prompt: fields.text().label("Prompt").description("Describe the content you want to generate for this entry.").required("Prompt is required").renderer("textarea", {
|
|
138
|
-
rows: 6
|
|
139
|
-
}).defaultValue("Write an evaluation guide for enterprise, self-hosted CMS platform. Use at least 3 content blocks.")
|
|
140
|
-
}),
|
|
141
|
-
layout: (layout)=>[
|
|
142
|
-
layout.row("project"),
|
|
143
|
-
layout.row("includedFiles"),
|
|
144
|
-
layout.row("readerPersona"),
|
|
145
|
-
layout.row("writerPersona"),
|
|
146
|
-
layout.row("prompt")
|
|
147
|
-
]
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
getSelectedProject() {
|
|
151
|
-
if (!this._form || !this._settings) return;
|
|
152
|
-
const projectId = this._form.field("project").getValue();
|
|
153
|
-
if (!projectId) return;
|
|
154
|
-
return this._settings.projects?.presets?.find((p)=>p.id === projectId);
|
|
155
|
-
}
|
|
156
|
-
getProjectFileOptions() {
|
|
157
|
-
const project = this.getSelectedProject();
|
|
158
|
-
const files = project?.files;
|
|
159
|
-
if (!files || 0 === files.length) return [];
|
|
160
|
-
return files.map((f)=>({
|
|
161
|
-
label: f.name,
|
|
162
|
-
value: f.id
|
|
163
|
-
}));
|
|
164
|
-
}
|
|
165
|
-
computeExcludedFileIds(projectId, includedFiles) {
|
|
166
|
-
if (!projectId) return null;
|
|
167
|
-
const project = this._settings?.projects?.presets?.find((p)=>p.id === projectId);
|
|
168
|
-
const allFileIds = (project?.files ?? []).map((f)=>f.id);
|
|
169
|
-
if (0 === allFileIds.length) return null;
|
|
170
|
-
const included = new Set(includedFiles ?? []);
|
|
171
|
-
const excluded = allFileIds.filter((id)=>!included.has(id));
|
|
172
|
-
return excluded.length > 0 ? excluded : null;
|
|
173
|
-
}
|
|
174
|
-
getProjectOptions() {
|
|
175
|
-
const presets = this._settings?.projects?.presets;
|
|
176
|
-
if (!presets || 0 === presets.length) return [];
|
|
177
|
-
return presets.map((preset)=>({
|
|
178
|
-
label: preset.name,
|
|
179
|
-
value: preset.id
|
|
180
|
-
}));
|
|
181
|
-
}
|
|
182
|
-
getPersonaOptions(type) {
|
|
183
|
-
const presets = "reader" === type ? this._settings?.readerPersonas?.presets : this._settings?.writerPersonas?.presets;
|
|
184
|
-
if (!presets || 0 === presets.length) return [];
|
|
185
|
-
return presets.map((preset)=>({
|
|
186
|
-
label: preset.name,
|
|
187
|
-
value: preset.id
|
|
188
|
-
}));
|
|
189
|
-
}
|
|
190
109
|
}
|
|
191
110
|
const CmsGenerateContentPresenter_CmsGenerateContentPresenter = CmsGenerateContentPresenter.createImplementation({
|
|
192
111
|
implementation: CmsGenerateContentPresenterImpl,
|
|
193
112
|
dependencies: [
|
|
194
113
|
ToolPipelineRunner,
|
|
195
114
|
GenerateEntryContentUseCase,
|
|
196
|
-
|
|
197
|
-
GetSettingsUseCase
|
|
115
|
+
AiPromptFormFactory
|
|
198
116
|
]
|
|
199
117
|
});
|
|
200
118
|
export { CmsGenerateContentPresenter_CmsGenerateContentPresenter as CmsGenerateContentPresenter };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.js","sources":["../../../../src/admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.ts"],"sourcesContent":["import { makeAutoObservable, computed, runInAction } from \"mobx\";\nimport { FormModelFactory, ToolPipelineRunner } from \"@webiny/app-admin\";\nimport type { FormModel } from \"@webiny/app-admin\";\nimport { CmsGenerateContentPresenter as Abstraction } from \"./abstractions.js\";\nimport { GenerateEntryContentUseCase } from \"~/admin/features/generateEntryContent/index.js\";\nimport { GetSettingsUseCase } from \"~/admin/features/settings/getSettings/abstractions.js\";\nimport type { IAiPowerUpsSettings } from \"~/admin/features/settings/shared/abstractions.js\";\n\nconst SUBMIT_TIMEOUT_MS = 300_000;\n\nclass CmsGenerateContentPresenterImpl implements Abstraction.Interface {\n private _loading = false;\n private _submitting = false;\n private _timedOut = false;\n private _form: FormModel.Interface | null = null;\n private _settings: IAiPowerUpsSettings | null = null;\n private _timeoutId: ReturnType<typeof setTimeout> | null = null;\n private _intervalId: ReturnType<typeof setInterval> | null = null;\n private _elapsedSeconds = 0;\n\n constructor(\n private pipelineRunner: ToolPipelineRunner.Interface,\n private generateEntryContent: GenerateEntryContentUseCase.Interface,\n private formModelFactory: FormModelFactory.Interface,\n private getSettings: GetSettingsUseCase.Interface\n ) {\n makeAutoObservable(this, { vm: computed }, { autoBind: true });\n }\n\n get vm(): Abstraction.ViewModel {\n return {\n form: this._form ? this._form.vm : null,\n loading: this._loading,\n submitting: this._submitting,\n timedOut: this._timedOut,\n elapsedSeconds: this._elapsedSeconds\n };\n }\n\n async init(): Promise<void> {\n this._loading = true;\n\n try {\n const settings = await this.getSettings.execute();\n runInAction(() => {\n this._settings = settings;\n this._form = this.buildForm();\n });\n } finally {\n runInAction(() => {\n this._loading = false;\n });\n }\n }\n\n async submit(modelId: string): Promise<void> {\n if (!this._form) {\n return;\n }\n\n const data = await this._form.submit<{\n prompt: string;\n project?: string;\n includedFiles?: string[];\n readerPersona?: string;\n writerPersona?: string;\n }>();\n\n if (!data) {\n return;\n }\n\n runInAction(() => {\n this._submitting = true;\n this._timedOut = false;\n });\n\n this.startTimeout();\n\n try {\n const excludedFileIds = this.computeExcludedFileIds(data.project, data.includedFiles);\n\n await this.generateEntryContent.execute({\n prompt: data.prompt,\n modelId,\n projectId: data.project || null,\n excludedFileIds,\n readerPersonaId: data.readerPersona || null,\n writerPersonaId: data.writerPersona || null\n });\n } catch {\n this.clearTimeout();\n runInAction(() => {\n this._submitting = false;\n });\n }\n }\n\n async processAiResponse(responseText: string): Promise<Record<string, unknown>> {\n this.clearTimeout();\n runInAction(() => {\n this._submitting = false;\n });\n\n const aiResponseJson = JSON.parse(responseText);\n const resolved = await this.pipelineRunner.resolve(aiResponseJson);\n return resolved as Record<string, unknown>;\n }\n\n cancelPrompt(): void {\n this.clearTimeout();\n this._submitting = false;\n }\n\n private startTimeout(): void {\n this.clearTimeout();\n this._elapsedSeconds = 0;\n this._intervalId = setInterval(() => {\n runInAction(() => {\n this._elapsedSeconds++;\n });\n }, 1000);\n this._timeoutId = setTimeout(() => {\n runInAction(() => {\n this._submitting = false;\n this._timedOut = true;\n });\n this.clearInterval();\n }, SUBMIT_TIMEOUT_MS);\n }\n\n private clearTimeout(): void {\n if (this._timeoutId !== null) {\n clearTimeout(this._timeoutId);\n this._timeoutId = null;\n }\n this.clearInterval();\n }\n\n private clearInterval(): void {\n if (this._intervalId !== null) {\n clearInterval(this._intervalId);\n this._intervalId = null;\n }\n }\n\n private buildForm() {\n return this.formModelFactory.create({\n fields: fields => ({\n project: fields\n .text()\n .label(\"Project\")\n .description(\"Select a predefined context to attach.\")\n .options(() => this.getProjectOptions())\n .afterChange((value, { form }) => {\n const projectId = value as string | undefined;\n const project = projectId\n ? this._settings?.projects?.presets?.find(p => p.id === projectId)\n : undefined;\n\n if (project?.defaultReaderPersonaId) {\n form.field(\"readerPersona\").setValue(project.defaultReaderPersonaId);\n }\n if (project?.defaultWriterPersonaId) {\n form.field(\"writerPersona\").setValue(project.defaultWriterPersonaId);\n }\n\n const fileIds = (project?.files ?? []).map((f: { id: string }) => f.id);\n form.field(\"includedFiles\").setValue(fileIds);\n }),\n includedFiles: fields\n .text()\n .label(\"Files included\")\n .description(\"Uncheck files to exclude them from this generation only.\")\n .options(() => this.getProjectFileOptions())\n .renderer(\"checkboxes\")\n .list()\n .hiddenWhen(({ form }) => {\n const projectId = form.field(\"project\").as(\"text\").getValue();\n if (!projectId) {\n return true;\n }\n const project = this._settings?.projects?.presets?.find(\n p => p.id === projectId\n );\n return !project?.files || project.files.length === 0;\n }),\n readerPersona: fields\n .text()\n .label(\"Reader Persona\")\n .description(\"Select the target audience for the generated content.\")\n .options(() => this.getPersonaOptions(\"reader\")),\n writerPersona: fields\n .text()\n .label(\"Writer Persona\")\n .description(\"Select the writing style for the generated content.\")\n .options(() => this.getPersonaOptions(\"writer\")),\n prompt: fields\n .text()\n .label(\"Prompt\")\n .description(\"Describe the content you want to generate for this entry.\")\n .required(\"Prompt is required\")\n .renderer(\"textarea\", { rows: 6 })\n .defaultValue(\n \"Write an evaluation guide for enterprise, self-hosted CMS platform. Use at least 3 content blocks.\"\n )\n }),\n layout: layout => [\n layout.row(\"project\"),\n layout.row(\"includedFiles\"),\n layout.row(\"readerPersona\"),\n layout.row(\"writerPersona\"),\n layout.row(\"prompt\")\n ]\n });\n }\n\n private getSelectedProject() {\n if (!this._form || !this._settings) {\n return undefined;\n }\n const projectId = this._form.field(\"project\").getValue<string>();\n if (!projectId) {\n return undefined;\n }\n return this._settings.projects?.presets?.find(p => p.id === projectId);\n }\n\n private getProjectFileOptions() {\n const project = this.getSelectedProject();\n const files = project?.files;\n if (!files || files.length === 0) {\n return [];\n }\n return files.map((f: { id: string; name: string }) => ({\n label: f.name,\n value: f.id\n }));\n }\n\n private computeExcludedFileIds(projectId?: string, includedFiles?: string[]): string[] | null {\n if (!projectId) {\n return null;\n }\n const project = this._settings?.projects?.presets?.find(p => p.id === projectId);\n const allFileIds = (project?.files ?? []).map((f: { id: string }) => f.id);\n if (allFileIds.length === 0) {\n return null;\n }\n const included = new Set(includedFiles ?? []);\n const excluded = allFileIds.filter((id: string) => !included.has(id));\n return excluded.length > 0 ? excluded : null;\n }\n\n private getProjectOptions() {\n const presets = this._settings?.projects?.presets;\n if (!presets || presets.length === 0) {\n return [];\n }\n return presets.map(preset => ({\n label: preset.name,\n value: preset.id\n }));\n }\n\n private getPersonaOptions(type: \"reader\" | \"writer\") {\n const presets =\n type === \"reader\"\n ? this._settings?.readerPersonas?.presets\n : this._settings?.writerPersonas?.presets;\n\n if (!presets || presets.length === 0) {\n return [];\n }\n\n return presets.map(preset => ({\n label: preset.name,\n value: preset.id\n }));\n }\n}\n\nexport const CmsGenerateContentPresenter = Abstraction.createImplementation({\n implementation: CmsGenerateContentPresenterImpl,\n dependencies: [\n ToolPipelineRunner,\n GenerateEntryContentUseCase,\n FormModelFactory,\n GetSettingsUseCase\n ]\n});\n"],"names":["SUBMIT_TIMEOUT_MS","CmsGenerateContentPresenterImpl","pipelineRunner","generateEntryContent","formModelFactory","getSettings","makeAutoObservable","computed","settings","runInAction","modelId","data","excludedFileIds","responseText","aiResponseJson","JSON","resolved","setInterval","setTimeout","clearTimeout","clearInterval","fields","value","form","projectId","project","p","undefined","fileIds","f","layout","files","includedFiles","allFileIds","included","Set","excluded","id","presets","preset","type","CmsGenerateContentPresenter","Abstraction","ToolPipelineRunner","GenerateEntryContentUseCase","FormModelFactory","GetSettingsUseCase"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.js","sources":["../../../../src/admin/presentation/CmsContentGeneration/CmsGenerateContentPresenter.ts"],"sourcesContent":["import { makeAutoObservable, computed, runInAction } from \"mobx\";\nimport { ToolPipelineRunner } from \"@webiny/app-admin\";\nimport type { FormModel } from \"@webiny/app-admin\";\nimport type { FileValue } from \"@webiny/app-admin/features/formModel/abstractions.js\";\nimport { CmsGenerateContentPresenter as Abstraction } from \"./abstractions.js\";\nimport { GenerateEntryContentUseCase } from \"~/admin/features/generateEntryContent/index.js\";\nimport { AiPromptFormFactory } from \"~/admin/presentation/AiPromptFormFactory/abstractions.js\";\n\nconst SUBMIT_TIMEOUT_MS = 300_000;\n\nclass CmsGenerateContentPresenterImpl implements Abstraction.Interface {\n private _loading = false;\n private _submitting = false;\n private _timedOut = false;\n private _form: FormModel.Interface | null = null;\n private _timeoutId: ReturnType<typeof setTimeout> | null = null;\n private _intervalId: ReturnType<typeof setInterval> | null = null;\n private _elapsedSeconds = 0;\n\n constructor(\n private pipelineRunner: ToolPipelineRunner.Interface,\n private generateEntryContent: GenerateEntryContentUseCase.Interface,\n private formFactory: AiPromptFormFactory.Interface\n ) {\n makeAutoObservable(this, { vm: computed }, { autoBind: true });\n }\n\n get vm(): Abstraction.ViewModel {\n return {\n form: this._form ? this._form.vm : null,\n loading: this._loading,\n submitting: this._submitting,\n timedOut: this._timedOut,\n elapsedSeconds: this._elapsedSeconds\n };\n }\n\n async init(): Promise<void> {\n this._form = this.formFactory.createForm({\n promptDescription: \"Describe the content you want to generate for this entry.\"\n });\n }\n\n async submit(modelId: string): Promise<void> {\n if (!this._form) {\n return;\n }\n\n const data = await this._form.submit<{\n prompt: string;\n project?: string;\n includedFiles?: string[];\n readerPersona?: string;\n writerPersona?: string;\n additionalFiles?: FileValue[];\n }>();\n\n if (!data) {\n return;\n }\n\n runInAction(() => {\n this._submitting = true;\n this._timedOut = false;\n });\n\n this.startTimeout();\n\n try {\n const excludedFileIds = this.formFactory.computeExcludedFileIds(this._form);\n const additionalFileIds = data.additionalFiles?.map(f => f.id) ?? null;\n\n await this.generateEntryContent.execute({\n prompt: data.prompt,\n modelId,\n projectId: data.project || null,\n excludedFileIds,\n readerPersonaId: data.readerPersona || null,\n writerPersonaId: data.writerPersona || null,\n additionalFileIds\n });\n } catch {\n this.clearTimeout();\n runInAction(() => {\n this._submitting = false;\n });\n }\n }\n\n async processAiResponse(responseText: string): Promise<Record<string, unknown>> {\n this.clearTimeout();\n runInAction(() => {\n this._submitting = false;\n });\n\n const aiResponseJson = JSON.parse(responseText);\n const resolved = await this.pipelineRunner.resolve(aiResponseJson);\n return resolved as Record<string, unknown>;\n }\n\n cancelPrompt(): void {\n this.clearTimeout();\n this._submitting = false;\n }\n\n private startTimeout(): void {\n this.clearTimeout();\n this._elapsedSeconds = 0;\n this._intervalId = setInterval(() => {\n runInAction(() => {\n this._elapsedSeconds++;\n });\n }, 1000);\n this._timeoutId = setTimeout(() => {\n runInAction(() => {\n this._submitting = false;\n this._timedOut = true;\n });\n this.clearInterval();\n }, SUBMIT_TIMEOUT_MS);\n }\n\n private clearTimeout(): void {\n if (this._timeoutId !== null) {\n clearTimeout(this._timeoutId);\n this._timeoutId = null;\n }\n this.clearInterval();\n }\n\n private clearInterval(): void {\n if (this._intervalId !== null) {\n clearInterval(this._intervalId);\n this._intervalId = null;\n }\n }\n}\n\nexport const CmsGenerateContentPresenter = Abstraction.createImplementation({\n implementation: CmsGenerateContentPresenterImpl,\n dependencies: [ToolPipelineRunner, GenerateEntryContentUseCase, AiPromptFormFactory]\n});\n"],"names":["SUBMIT_TIMEOUT_MS","CmsGenerateContentPresenterImpl","pipelineRunner","generateEntryContent","formFactory","makeAutoObservable","computed","modelId","data","runInAction","excludedFileIds","additionalFileIds","f","responseText","aiResponseJson","JSON","resolved","setInterval","setTimeout","clearTimeout","clearInterval","CmsGenerateContentPresenter","Abstraction","ToolPipelineRunner","GenerateEntryContentUseCase","AiPromptFormFactory"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
export declare const CmsContentGeneration: () => React.JSX.Element;
|
|
2
|
+
export declare const CmsContentGeneration: () => React.JSX.Element | null;
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import react from "react";
|
|
2
|
-
import { AdminConfig, RegisterFeature } from "@webiny/app-admin";
|
|
3
|
-
import {
|
|
2
|
+
import { AdminConfig, RegisterFeature, useFeatureFlags } from "@webiny/app-admin";
|
|
3
|
+
import { InternalContentEntryEditorConfig } from "@webiny/app-headless-cms/admin/config/contentEntries/index.js";
|
|
4
4
|
import { CmsGenerateContentButton } from "./CmsGenerateContentButton.js";
|
|
5
5
|
import { CMS_GENERATE_CONTENT_DIALOG, CmsGenerateContentDialog } from "./CmsGenerateContentDialog.js";
|
|
6
6
|
import { CmsGenerateContentFeature } from "./feature.js";
|
|
7
7
|
import { GenerateEntryContentFeature } from "../../features/generateEntryContent/index.js";
|
|
8
|
-
const { Actions: Actions } =
|
|
9
|
-
const CmsContentGeneration = ()
|
|
8
|
+
const { Actions: Actions } = InternalContentEntryEditorConfig;
|
|
9
|
+
const CmsContentGeneration = ()=>{
|
|
10
|
+
const featureFlags = useFeatureFlags();
|
|
11
|
+
if (!featureFlags.isEnabled("aiPowerups.cms.entryGeneration")) return null;
|
|
12
|
+
return /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(RegisterFeature, {
|
|
10
13
|
feature: CmsGenerateContentFeature
|
|
11
14
|
}), /*#__PURE__*/ react.createElement(RegisterFeature, {
|
|
12
15
|
feature: GenerateEntryContentFeature
|
|
13
16
|
}), /*#__PURE__*/ react.createElement(AdminConfig, null, /*#__PURE__*/ react.createElement(AdminConfig.Dialog, {
|
|
14
17
|
name: CMS_GENERATE_CONTENT_DIALOG,
|
|
15
18
|
element: /*#__PURE__*/ react.createElement(CmsGenerateContentDialog, null)
|
|
16
|
-
})), /*#__PURE__*/ react.createElement(
|
|
19
|
+
})), /*#__PURE__*/ react.createElement(InternalContentEntryEditorConfig, null, /*#__PURE__*/ react.createElement(Actions.ButtonAction, {
|
|
17
20
|
name: "generateEntryContent",
|
|
18
21
|
before: "save",
|
|
19
22
|
element: /*#__PURE__*/ react.createElement(CmsGenerateContentButton, null)
|
|
20
23
|
})));
|
|
24
|
+
};
|
|
21
25
|
export { CmsContentGeneration };
|
|
22
26
|
|
|
23
27
|
//# sourceMappingURL=Extension.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin/presentation/CmsContentGeneration/Extension.js","sources":["../../../../src/admin/presentation/CmsContentGeneration/Extension.tsx"],"sourcesContent":["import React from \"react\";\nimport { AdminConfig, RegisterFeature } from \"@webiny/app-admin\";\nimport {
|
|
1
|
+
{"version":3,"file":"admin/presentation/CmsContentGeneration/Extension.js","sources":["../../../../src/admin/presentation/CmsContentGeneration/Extension.tsx"],"sourcesContent":["import React from \"react\";\nimport { AdminConfig, RegisterFeature, useFeatureFlags } from \"@webiny/app-admin\";\nimport { InternalContentEntryEditorConfig } from \"@webiny/app-headless-cms/admin/config/contentEntries/index.js\";\nimport { CmsGenerateContentButton } from \"~/admin/presentation/CmsContentGeneration/CmsGenerateContentButton.js\";\nimport {\n CmsGenerateContentDialog,\n CMS_GENERATE_CONTENT_DIALOG\n} from \"~/admin/presentation/CmsContentGeneration/CmsGenerateContentDialog.js\";\nimport { CmsGenerateContentFeature } from \"~/admin/presentation/CmsContentGeneration/feature.js\";\nimport { GenerateEntryContentFeature } from \"~/admin/features/generateEntryContent/index.js\";\n\nconst { Actions } = InternalContentEntryEditorConfig;\n\nexport const CmsContentGeneration = () => {\n const featureFlags = useFeatureFlags();\n\n if (!featureFlags.isEnabled(\"aiPowerups.cms.entryGeneration\")) {\n return null;\n }\n\n return (\n <>\n <RegisterFeature feature={CmsGenerateContentFeature} />\n <RegisterFeature feature={GenerateEntryContentFeature} />\n <AdminConfig>\n <AdminConfig.Dialog\n name={CMS_GENERATE_CONTENT_DIALOG}\n element={<CmsGenerateContentDialog />}\n />\n </AdminConfig>\n <InternalContentEntryEditorConfig>\n <Actions.ButtonAction\n name={\"generateEntryContent\"}\n before={\"save\"}\n element={<CmsGenerateContentButton />}\n />\n </InternalContentEntryEditorConfig>\n </>\n );\n};\n"],"names":["Actions","InternalContentEntryEditorConfig","CmsContentGeneration","featureFlags","useFeatureFlags","RegisterFeature","CmsGenerateContentFeature","GenerateEntryContentFeature","AdminConfig","CMS_GENERATE_CONTENT_DIALOG","CmsGenerateContentDialog","CmsGenerateContentButton"],"mappings":";;;;;;;AAWA,MAAM,EAAEA,SAAAA,OAAO,EAAE,GAAGC;AAEb,MAAMC,uBAAuB;IAChC,MAAMC,eAAeC;IAErB,IAAI,CAACD,aAAa,SAAS,CAAC,mCACxB,OAAO;IAGX,OAAO,WAAP,GACI,wDACI,oBAACE,iBAAeA;QAAC,SAASC;sBAC1B,oBAACD,iBAAeA;QAAC,SAASE;sBAC1B,oBAACC,aAAWA,MAAAA,WAAAA,GACR,oBAACA,YAAY,MAAM;QACf,MAAMC;QACN,uBAAS,oBAACC,0BAAwBA;uBAG1C,oBAACT,kCAAgCA,MAAAA,WAAAA,GAC7B,oBAACD,QAAQ,YAAY;QACjB,MAAM;QACN,QAAQ;QACR,uBAAS,oBAACW,0BAAwBA;;AAKtD"}
|
|
@@ -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"}
|
|
@@ -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,
|