@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
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { GetSettingsUseCase } from "../GetSettings/index.js";
|
|
2
|
+
import { GetFileContentsByIdUseCase } from "@webiny/api-file-manager/features/file/GetFileContentsById/index.js";
|
|
3
|
+
import { GetFileUseCase } from "@webiny/api-file-manager/features/file/GetFile/index.js";
|
|
4
|
+
import { TextExtractor } from "@webiny/api-core/features/ai/index.js";
|
|
2
5
|
import { AiPromptContextBuilder, ProjectFileAssembler } from "./abstractions.js";
|
|
3
6
|
import { WriterPersonaSection } from "./WriterPersonaSection.js";
|
|
4
7
|
import { ReaderPersonaSection } from "./ReaderPersonaSection.js";
|
|
@@ -37,6 +40,7 @@ function emptyContext(warnings) {
|
|
|
37
40
|
readerPersona: void 0,
|
|
38
41
|
writerPersona: void 0,
|
|
39
42
|
allProjectFiles: [],
|
|
43
|
+
additionalFiles: [],
|
|
40
44
|
excludedFileIds: new Set(),
|
|
41
45
|
cacheHit: false,
|
|
42
46
|
warnings,
|
|
@@ -46,9 +50,12 @@ function emptyContext(warnings) {
|
|
|
46
50
|
};
|
|
47
51
|
}
|
|
48
52
|
class AiPromptContextBuilderImpl {
|
|
49
|
-
constructor(getSettings, fileAssembler){
|
|
53
|
+
constructor(getSettings, fileAssembler, getFileContents, getFile, textExtractor){
|
|
50
54
|
this.getSettings = getSettings;
|
|
51
55
|
this.fileAssembler = fileAssembler;
|
|
56
|
+
this.getFileContents = getFileContents;
|
|
57
|
+
this.getFile = getFile;
|
|
58
|
+
this.textExtractor = textExtractor;
|
|
52
59
|
}
|
|
53
60
|
async execute(params) {
|
|
54
61
|
const warnings = [];
|
|
@@ -76,11 +83,17 @@ class AiPromptContextBuilderImpl {
|
|
|
76
83
|
totalTokens: visibleFiles.reduce((sum, f)=>sum + f.tokenCount, 0)
|
|
77
84
|
};
|
|
78
85
|
}
|
|
86
|
+
const additionalFiles = await this.fetchAdditionalFiles(params.additionalFileIds, warnings);
|
|
87
|
+
if (additionalFiles.length > 0) allProjectFiles = [
|
|
88
|
+
...allProjectFiles,
|
|
89
|
+
...additionalFiles
|
|
90
|
+
];
|
|
79
91
|
const ctx = {
|
|
80
92
|
project,
|
|
81
93
|
readerPersona: reader,
|
|
82
94
|
writerPersona: writer,
|
|
83
95
|
allProjectFiles,
|
|
96
|
+
additionalFiles,
|
|
84
97
|
excludedFileIds,
|
|
85
98
|
cacheHit,
|
|
86
99
|
warnings,
|
|
@@ -90,12 +103,43 @@ class AiPromptContextBuilderImpl {
|
|
|
90
103
|
};
|
|
91
104
|
return ctx;
|
|
92
105
|
}
|
|
106
|
+
async fetchAdditionalFiles(fileIds, warnings) {
|
|
107
|
+
if (!fileIds || 0 === fileIds.length) return [];
|
|
108
|
+
const results = await Promise.all(fileIds.map(async (fileId)=>{
|
|
109
|
+
const [contentsResult, damResult] = await Promise.all([
|
|
110
|
+
this.getFileContents.execute(fileId),
|
|
111
|
+
this.getFile.execute(fileId)
|
|
112
|
+
]);
|
|
113
|
+
if (contentsResult.isFail()) {
|
|
114
|
+
warnings.push(`Failed to load additional file (${fileId}): ${contentsResult.error.message}`);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const name = damResult.isOk() ? damResult.value.name : fileId;
|
|
118
|
+
const mimeType = damResult.isOk() ? damResult.value.type : "application/octet-stream";
|
|
119
|
+
if (!this.textExtractor.canExtract(mimeType)) {
|
|
120
|
+
warnings.push(`Skipped additional file "${name}" (${fileId}): unsupported type "${mimeType}".`);
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const { text: content } = await this.textExtractor.extract(contentsResult.value.buffer, mimeType);
|
|
124
|
+
return {
|
|
125
|
+
id: fileId,
|
|
126
|
+
name,
|
|
127
|
+
content,
|
|
128
|
+
description: damResult.isOk() ? damResult.value.description : void 0,
|
|
129
|
+
tokenCount: Math.ceil(content.length / 4)
|
|
130
|
+
};
|
|
131
|
+
}));
|
|
132
|
+
return results.filter((r)=>null !== r);
|
|
133
|
+
}
|
|
93
134
|
}
|
|
94
135
|
const AiPromptContextBuilder_AiPromptContextBuilder = AiPromptContextBuilder.createImplementation({
|
|
95
136
|
implementation: AiPromptContextBuilderImpl,
|
|
96
137
|
dependencies: [
|
|
97
138
|
GetSettingsUseCase,
|
|
98
|
-
ProjectFileAssembler
|
|
139
|
+
ProjectFileAssembler,
|
|
140
|
+
GetFileContentsByIdUseCase,
|
|
141
|
+
GetFileUseCase,
|
|
142
|
+
TextExtractor
|
|
99
143
|
]
|
|
100
144
|
});
|
|
101
145
|
export { AiPromptContextBuilder_AiPromptContextBuilder as AiPromptContextBuilder };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/AiPromptContext/AiPromptContextBuilder.js","sources":["../../../../src/api/features/AiPromptContext/AiPromptContextBuilder.ts"],"sourcesContent":["import { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\nimport {\n AiPromptContextBuilder as Abstraction,\n ProjectFileAssembler,\n type AiPromptContext,\n type AiPromptContextParams,\n type ProjectFileContent,\n type ResolvedPersona,\n type ResolvedProject\n} from \"./abstractions.js\";\nimport type { IAiPowerUpsSettings } from \"~/api/types.js\";\nimport type { ProjectPreset } from \"~/api/features/Projects/types.js\";\nimport { WriterPersonaSection } from \"./WriterPersonaSection.js\";\nimport { ReaderPersonaSection } from \"./ReaderPersonaSection.js\";\nimport { ProjectSection } from \"./ProjectSection.js\";\n\nfunction resolvePersonas(\n settings: IAiPowerUpsSettings,\n project: ProjectPreset | undefined,\n params: AiPromptContextParams\n): { reader?: ResolvedPersona; writer?: ResolvedPersona } {\n const readerPersonaId = params.readerPersonaId ?? project?.defaultReaderPersonaId ?? undefined;\n const writerPersonaId = params.writerPersonaId ?? project?.defaultWriterPersonaId ?? undefined;\n\n const readerPreset = readerPersonaId\n ? settings.readerPersonas?.presets?.find(p => p.id === readerPersonaId)\n : undefined;\n\n const writerPreset = writerPersonaId\n ? settings.writerPersonas?.presets?.find(p => p.id === writerPersonaId)\n : undefined;\n\n return {\n reader: readerPreset\n ? {\n name: readerPreset.name,\n description: readerPreset.description,\n style: readerPreset.style\n }\n : undefined,\n writer: writerPreset\n ? {\n name: writerPreset.name,\n description: writerPreset.description,\n style: writerPreset.style\n }\n : undefined\n };\n}\n\nfunction formatContext(ctx: AiPromptContext): string {\n const sections: string[] = [];\n\n if (ctx.writerPersona) {\n sections.push(WriterPersonaSection.format(ctx.writerPersona));\n }\n if (ctx.readerPersona) {\n sections.push(ReaderPersonaSection.format(ctx.readerPersona));\n }\n if (ctx.project) {\n const projectText = ProjectSection.format(ctx.project);\n if (projectText) {\n sections.push(projectText);\n }\n }\n\n return sections.length > 0 ? \"\\n\\n\" + sections.join(\"\\n\\n\") : \"\";\n}\n\nfunction emptyContext(warnings: string[]): AiPromptContext {\n return {\n project: undefined,\n readerPersona: undefined,\n writerPersona: undefined,\n allProjectFiles: [],\n excludedFileIds: new Set(),\n cacheHit: false,\n warnings,\n toString() {\n return \"\";\n }\n };\n}\n\nclass AiPromptContextBuilderImpl implements Abstraction.Interface {\n constructor(\n private getSettings: GetSettingsUseCase.Interface,\n private fileAssembler: ProjectFileAssembler.Interface\n ) {}\n\n async execute(params: AiPromptContextParams): Promise<AiPromptContext> {\n const warnings: string[] = [];\n\n const settingsResult = await this.getSettings.execute();\n if (settingsResult.isFail()) {\n warnings.push(\"Failed to load AI PowerUps settings.\");\n return emptyContext(warnings);\n }\n\n const settings = settingsResult.value;\n const projectPreset = params.projectId\n ? settings.projects?.presets?.find(p => p.id === params.projectId)\n : undefined;\n\n const { reader, writer } = resolvePersonas(settings, projectPreset, params);\n const excludedFileIds = new Set(params.excludedFileIds ?? []);\n\n let project: ResolvedProject | undefined;\n let allProjectFiles: ProjectFileContent[] = [];\n let cacheHit = false;\n\n if (projectPreset) {\n const assembled = await this.fileAssembler.execute(\n projectPreset.id,\n projectPreset.version ?? 0,\n projectPreset.files ?? [],\n warnings\n );\n allProjectFiles = assembled.files;\n cacheHit = assembled.cacheHit;\n\n const visibleFiles =\n excludedFileIds.size > 0\n ? allProjectFiles.filter(f => !excludedFileIds.has(f.id))\n : allProjectFiles;\n\n project = {\n name: projectPreset.name,\n instructions: projectPreset.instructions,\n files: visibleFiles,\n totalTokens: visibleFiles.reduce((sum, f) => sum + f.tokenCount, 0)\n };\n }\n\n const ctx: AiPromptContext = {\n project,\n readerPersona: reader,\n writerPersona: writer,\n allProjectFiles,\n excludedFileIds,\n cacheHit,\n warnings,\n toString() {\n return formatContext(this);\n }\n };\n\n return ctx;\n }\n}\n\nexport const AiPromptContextBuilder = Abstraction.createImplementation({\n implementation: AiPromptContextBuilderImpl,\n dependencies: [GetSettingsUseCase, ProjectFileAssembler]\n});\n"],"names":["resolvePersonas","settings","project","params","readerPersonaId","undefined","writerPersonaId","readerPreset","p","writerPreset","formatContext","ctx","sections","WriterPersonaSection","ReaderPersonaSection","projectText","ProjectSection","emptyContext","warnings","Set","AiPromptContextBuilderImpl","getSettings","fileAssembler","settingsResult","projectPreset","reader","writer","excludedFileIds","allProjectFiles","cacheHit","assembled","visibleFiles","f","sum","AiPromptContextBuilder","Abstraction","GetSettingsUseCase","ProjectFileAssembler"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api/features/AiPromptContext/AiPromptContextBuilder.js","sources":["../../../../src/api/features/AiPromptContext/AiPromptContextBuilder.ts"],"sourcesContent":["import { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\nimport { GetFileContentsByIdUseCase } from \"@webiny/api-file-manager/features/file/GetFileContentsById/index.js\";\nimport { GetFileUseCase } from \"@webiny/api-file-manager/features/file/GetFile/index.js\";\nimport { TextExtractor } from \"@webiny/api-core/features/ai/index.js\";\nimport {\n AiPromptContextBuilder as Abstraction,\n ProjectFileAssembler,\n type AiPromptContext,\n type AiPromptContextParams,\n type ProjectFileContent,\n type ResolvedPersona,\n type ResolvedProject\n} from \"./abstractions.js\";\nimport type { IAiPowerUpsSettings } from \"~/api/types.js\";\nimport type { ProjectPreset } from \"~/api/features/Projects/types.js\";\nimport { WriterPersonaSection } from \"./WriterPersonaSection.js\";\nimport { ReaderPersonaSection } from \"./ReaderPersonaSection.js\";\nimport { ProjectSection } from \"./ProjectSection.js\";\n\nfunction resolvePersonas(\n settings: IAiPowerUpsSettings,\n project: ProjectPreset | undefined,\n params: AiPromptContextParams\n): { reader?: ResolvedPersona; writer?: ResolvedPersona } {\n const readerPersonaId = params.readerPersonaId ?? project?.defaultReaderPersonaId ?? undefined;\n const writerPersonaId = params.writerPersonaId ?? project?.defaultWriterPersonaId ?? undefined;\n\n const readerPreset = readerPersonaId\n ? settings.readerPersonas?.presets?.find(p => p.id === readerPersonaId)\n : undefined;\n\n const writerPreset = writerPersonaId\n ? settings.writerPersonas?.presets?.find(p => p.id === writerPersonaId)\n : undefined;\n\n return {\n reader: readerPreset\n ? {\n name: readerPreset.name,\n description: readerPreset.description,\n style: readerPreset.style\n }\n : undefined,\n writer: writerPreset\n ? {\n name: writerPreset.name,\n description: writerPreset.description,\n style: writerPreset.style\n }\n : undefined\n };\n}\n\nfunction formatContext(ctx: AiPromptContext): string {\n const sections: string[] = [];\n\n if (ctx.writerPersona) {\n sections.push(WriterPersonaSection.format(ctx.writerPersona));\n }\n if (ctx.readerPersona) {\n sections.push(ReaderPersonaSection.format(ctx.readerPersona));\n }\n if (ctx.project) {\n const projectText = ProjectSection.format(ctx.project);\n if (projectText) {\n sections.push(projectText);\n }\n }\n return sections.length > 0 ? \"\\n\\n\" + sections.join(\"\\n\\n\") : \"\";\n}\n\nfunction emptyContext(warnings: string[]): AiPromptContext {\n return {\n project: undefined,\n readerPersona: undefined,\n writerPersona: undefined,\n allProjectFiles: [],\n additionalFiles: [],\n excludedFileIds: new Set(),\n cacheHit: false,\n warnings,\n toString() {\n return \"\";\n }\n };\n}\n\nclass AiPromptContextBuilderImpl implements Abstraction.Interface {\n constructor(\n private getSettings: GetSettingsUseCase.Interface,\n private fileAssembler: ProjectFileAssembler.Interface,\n private getFileContents: GetFileContentsByIdUseCase.Interface,\n private getFile: GetFileUseCase.Interface,\n private textExtractor: TextExtractor.Interface\n ) {}\n\n async execute(params: AiPromptContextParams): Promise<AiPromptContext> {\n const warnings: string[] = [];\n\n const settingsResult = await this.getSettings.execute();\n if (settingsResult.isFail()) {\n warnings.push(\"Failed to load AI PowerUps settings.\");\n return emptyContext(warnings);\n }\n\n const settings = settingsResult.value;\n const projectPreset = params.projectId\n ? settings.projects?.presets?.find(p => p.id === params.projectId)\n : undefined;\n\n const { reader, writer } = resolvePersonas(settings, projectPreset, params);\n const excludedFileIds = new Set(params.excludedFileIds ?? []);\n\n let project: ResolvedProject | undefined;\n let allProjectFiles: ProjectFileContent[] = [];\n let cacheHit = false;\n\n if (projectPreset) {\n const assembled = await this.fileAssembler.execute(\n projectPreset.id,\n projectPreset.version ?? 0,\n projectPreset.files ?? [],\n warnings\n );\n allProjectFiles = assembled.files;\n cacheHit = assembled.cacheHit;\n\n const visibleFiles =\n excludedFileIds.size > 0\n ? allProjectFiles.filter(f => !excludedFileIds.has(f.id))\n : allProjectFiles;\n\n project = {\n name: projectPreset.name,\n instructions: projectPreset.instructions,\n files: visibleFiles,\n totalTokens: visibleFiles.reduce((sum, f) => sum + f.tokenCount, 0)\n };\n }\n\n const additionalFiles = await this.fetchAdditionalFiles(params.additionalFileIds, warnings);\n if (additionalFiles.length > 0) {\n allProjectFiles = [...allProjectFiles, ...additionalFiles];\n }\n\n const ctx: AiPromptContext = {\n project,\n readerPersona: reader,\n writerPersona: writer,\n allProjectFiles,\n additionalFiles,\n excludedFileIds,\n cacheHit,\n warnings,\n toString() {\n return formatContext(this);\n }\n };\n\n return ctx;\n }\n\n private async fetchAdditionalFiles(\n fileIds: string[] | null | undefined,\n warnings: string[]\n ): Promise<ProjectFileContent[]> {\n if (!fileIds || fileIds.length === 0) {\n return [];\n }\n\n const results = await Promise.all(\n fileIds.map(async (fileId): Promise<ProjectFileContent | null> => {\n const [contentsResult, damResult] = await Promise.all([\n this.getFileContents.execute(fileId),\n this.getFile.execute(fileId)\n ]);\n\n if (contentsResult.isFail()) {\n warnings.push(\n `Failed to load additional file (${fileId}): ${contentsResult.error.message}`\n );\n return null;\n }\n\n const name = damResult.isOk() ? damResult.value.name : fileId;\n const mimeType = damResult.isOk()\n ? damResult.value.type\n : \"application/octet-stream\";\n\n if (!this.textExtractor.canExtract(mimeType)) {\n warnings.push(\n `Skipped additional file \"${name}\" (${fileId}): unsupported type \"${mimeType}\".`\n );\n return null;\n }\n\n const { text: content } = await this.textExtractor.extract(\n contentsResult.value.buffer,\n mimeType\n );\n\n return {\n id: fileId,\n name,\n content,\n description: damResult.isOk() ? damResult.value.description : undefined,\n tokenCount: Math.ceil(content.length / 4)\n };\n })\n );\n\n return results.filter((r): r is ProjectFileContent => r !== null);\n }\n}\n\nexport const AiPromptContextBuilder = Abstraction.createImplementation({\n implementation: AiPromptContextBuilderImpl,\n dependencies: [\n GetSettingsUseCase,\n ProjectFileAssembler,\n GetFileContentsByIdUseCase,\n GetFileUseCase,\n TextExtractor\n ]\n});\n"],"names":["resolvePersonas","settings","project","params","readerPersonaId","undefined","writerPersonaId","readerPreset","p","writerPreset","formatContext","ctx","sections","WriterPersonaSection","ReaderPersonaSection","projectText","ProjectSection","emptyContext","warnings","Set","AiPromptContextBuilderImpl","getSettings","fileAssembler","getFileContents","getFile","textExtractor","settingsResult","projectPreset","reader","writer","excludedFileIds","allProjectFiles","cacheHit","assembled","visibleFiles","f","sum","additionalFiles","fileIds","results","Promise","fileId","contentsResult","damResult","name","mimeType","content","Math","r","AiPromptContextBuilder","Abstraction","GetSettingsUseCase","ProjectFileAssembler","GetFileContentsByIdUseCase","GetFileUseCase","TextExtractor"],"mappings":"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"}
|
|
@@ -28,6 +28,7 @@ export interface AiPromptContextParams {
|
|
|
28
28
|
readerPersonaId?: string | null;
|
|
29
29
|
writerPersonaId?: string | null;
|
|
30
30
|
excludedFileIds?: string[] | null;
|
|
31
|
+
additionalFileIds?: string[] | null;
|
|
31
32
|
}
|
|
32
33
|
export interface ProjectFileContent {
|
|
33
34
|
id: string;
|
|
@@ -52,6 +53,7 @@ export interface AiPromptContext {
|
|
|
52
53
|
readerPersona?: ResolvedPersona;
|
|
53
54
|
writerPersona?: ResolvedPersona;
|
|
54
55
|
allProjectFiles: ProjectFileContent[];
|
|
56
|
+
additionalFiles: ProjectFileContent[];
|
|
55
57
|
excludedFileIds: Set<string>;
|
|
56
58
|
cacheHit: boolean;
|
|
57
59
|
warnings: string[];
|
|
@@ -66,3 +68,4 @@ export declare namespace AiPromptContextBuilder {
|
|
|
66
68
|
type Params = AiPromptContextParams;
|
|
67
69
|
type Context = AiPromptContext;
|
|
68
70
|
}
|
|
71
|
+
export declare function formatAdditionalFilesContext(files: ProjectFileContent[]): string;
|
|
@@ -2,6 +2,14 @@ import { createAbstraction } from "@webiny/feature/api";
|
|
|
2
2
|
const ProjectFileCache = createAbstraction("ProjectFileCache");
|
|
3
3
|
const ProjectFileAssembler = createAbstraction("ProjectFileAssembler");
|
|
4
4
|
const AiPromptContextBuilder = createAbstraction("AiPowerUpsPromptContextBuilder");
|
|
5
|
-
|
|
5
|
+
function formatAdditionalFilesContext(files) {
|
|
6
|
+
if (0 === files.length) return "";
|
|
7
|
+
const sections = files.map((f)=>{
|
|
8
|
+
const desc = f.description ? ` description="${f.description}"` : "";
|
|
9
|
+
return `<attached-file name="${f.name}"${desc}>\n${f.content}\n</attached-file>`;
|
|
10
|
+
});
|
|
11
|
+
return `\n\nThe user attached the following files as additional context for this generation:\n\n${sections.join("\n\n")}`;
|
|
12
|
+
}
|
|
13
|
+
export { AiPromptContextBuilder, ProjectFileAssembler, ProjectFileCache, formatAdditionalFilesContext };
|
|
6
14
|
|
|
7
15
|
//# sourceMappingURL=abstractions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/AiPromptContext/abstractions.js","sources":["../../../../src/api/features/AiPromptContext/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\n\n// ============================================================================\n// ProjectFileCache\n// ============================================================================\n\nexport interface IProjectFileCache {\n get(projectId: string, version: number): Promise<{ files: ProjectFileContent[]; hit: boolean }>;\n set(projectId: string, version: number, files: ProjectFileContent[]): Promise<void>;\n}\n\nexport const ProjectFileCache = createAbstraction<IProjectFileCache>(\"ProjectFileCache\");\n\nexport namespace ProjectFileCache {\n export type Interface = IProjectFileCache;\n}\n\n// ============================================================================\n// ProjectFileAssembler\n// ============================================================================\n\nexport interface IProjectFileAssembler {\n execute(\n projectId: string,\n version: number,\n files: Array<{ id: string; name: string; mimeType: string }>,\n warnings: string[]\n ): Promise<{ files: ProjectFileContent[]; cacheHit: boolean }>;\n}\n\nexport const ProjectFileAssembler =\n createAbstraction<IProjectFileAssembler>(\"ProjectFileAssembler\");\n\nexport namespace ProjectFileAssembler {\n export type Interface = IProjectFileAssembler;\n}\n\n// ============================================================================\n// AiPromptContext\n// ============================================================================\n\nexport interface AiPromptContextParams {\n projectId?: string | null;\n readerPersonaId?: string | null;\n writerPersonaId?: string | null;\n excludedFileIds?: string[] | null;\n}\n\nexport interface ProjectFileContent {\n id: string;\n name: string;\n content: string;\n description?: string;\n tokenCount: number;\n}\n\nexport interface ResolvedProject {\n name: string;\n instructions?: string;\n files: ProjectFileContent[];\n totalTokens: number;\n}\n\nexport interface ResolvedPersona {\n name: string;\n description: string;\n style?: string;\n}\n\nexport interface AiPromptContext {\n project?: ResolvedProject;\n readerPersona?: ResolvedPersona;\n writerPersona?: ResolvedPersona;\n allProjectFiles: ProjectFileContent[];\n excludedFileIds: Set<string>;\n cacheHit: boolean;\n warnings: string[];\n toString(): string;\n}\n\nexport interface IAiPromptContextBuilder {\n execute(params: AiPromptContextParams): Promise<AiPromptContext>;\n}\n\nexport const AiPromptContextBuilder = createAbstraction<IAiPromptContextBuilder>(\n \"AiPowerUpsPromptContextBuilder\"\n);\n\nexport namespace AiPromptContextBuilder {\n export type Interface = IAiPromptContextBuilder;\n export type Params = AiPromptContextParams;\n export type Context = AiPromptContext;\n}\n"],"names":["ProjectFileCache","createAbstraction","ProjectFileAssembler","AiPromptContextBuilder"],"mappings":";AAWO,MAAMA,mBAAmBC,kBAAqC;AAmB9D,MAAMC,uBACTD,kBAAyC;
|
|
1
|
+
{"version":3,"file":"api/features/AiPromptContext/abstractions.js","sources":["../../../../src/api/features/AiPromptContext/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\n\n// ============================================================================\n// ProjectFileCache\n// ============================================================================\n\nexport interface IProjectFileCache {\n get(projectId: string, version: number): Promise<{ files: ProjectFileContent[]; hit: boolean }>;\n set(projectId: string, version: number, files: ProjectFileContent[]): Promise<void>;\n}\n\nexport const ProjectFileCache = createAbstraction<IProjectFileCache>(\"ProjectFileCache\");\n\nexport namespace ProjectFileCache {\n export type Interface = IProjectFileCache;\n}\n\n// ============================================================================\n// ProjectFileAssembler\n// ============================================================================\n\nexport interface IProjectFileAssembler {\n execute(\n projectId: string,\n version: number,\n files: Array<{ id: string; name: string; mimeType: string }>,\n warnings: string[]\n ): Promise<{ files: ProjectFileContent[]; cacheHit: boolean }>;\n}\n\nexport const ProjectFileAssembler =\n createAbstraction<IProjectFileAssembler>(\"ProjectFileAssembler\");\n\nexport namespace ProjectFileAssembler {\n export type Interface = IProjectFileAssembler;\n}\n\n// ============================================================================\n// AiPromptContext\n// ============================================================================\n\nexport interface AiPromptContextParams {\n projectId?: string | null;\n readerPersonaId?: string | null;\n writerPersonaId?: string | null;\n excludedFileIds?: string[] | null;\n additionalFileIds?: string[] | null;\n}\n\nexport interface ProjectFileContent {\n id: string;\n name: string;\n content: string;\n description?: string;\n tokenCount: number;\n}\n\nexport interface ResolvedProject {\n name: string;\n instructions?: string;\n files: ProjectFileContent[];\n totalTokens: number;\n}\n\nexport interface ResolvedPersona {\n name: string;\n description: string;\n style?: string;\n}\n\nexport interface AiPromptContext {\n project?: ResolvedProject;\n readerPersona?: ResolvedPersona;\n writerPersona?: ResolvedPersona;\n allProjectFiles: ProjectFileContent[];\n additionalFiles: ProjectFileContent[];\n excludedFileIds: Set<string>;\n cacheHit: boolean;\n warnings: string[];\n toString(): string;\n}\n\nexport interface IAiPromptContextBuilder {\n execute(params: AiPromptContextParams): Promise<AiPromptContext>;\n}\n\nexport const AiPromptContextBuilder = createAbstraction<IAiPromptContextBuilder>(\n \"AiPowerUpsPromptContextBuilder\"\n);\n\nexport namespace AiPromptContextBuilder {\n export type Interface = IAiPromptContextBuilder;\n export type Params = AiPromptContextParams;\n export type Context = AiPromptContext;\n}\n\nexport function formatAdditionalFilesContext(files: ProjectFileContent[]): string {\n if (files.length === 0) {\n return \"\";\n }\n const sections = files.map(f => {\n const desc = f.description ? ` description=\"${f.description}\"` : \"\";\n return `<attached-file name=\"${f.name}\"${desc}>\\n${f.content}\\n</attached-file>`;\n });\n return `\\n\\nThe user attached the following files as additional context for this generation:\\n\\n${sections.join(\"\\n\\n\")}`;\n}\n"],"names":["ProjectFileCache","createAbstraction","ProjectFileAssembler","AiPromptContextBuilder","formatAdditionalFilesContext","files","sections","f","desc"],"mappings":";AAWO,MAAMA,mBAAmBC,kBAAqC;AAmB9D,MAAMC,uBACTD,kBAAyC;AAuDtC,MAAME,yBAAyBF,kBAClC;AASG,SAASG,6BAA6BC,KAA2B;IACpE,IAAIA,AAAiB,MAAjBA,MAAM,MAAM,EACZ,OAAO;IAEX,MAAMC,WAAWD,MAAM,GAAG,CAACE,CAAAA;QACvB,MAAMC,OAAOD,EAAE,WAAW,GAAG,CAAC,cAAc,EAAEA,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG;QACjE,OAAO,CAAC,qBAAqB,EAAEA,EAAE,IAAI,CAAC,CAAC,EAAEC,KAAK,GAAG,EAAED,EAAE,OAAO,CAAC,kBAAkB,CAAC;IACpF;IACA,OAAO,CAAC,wFAAwF,EAAED,SAAS,IAAI,CAAC,SAAS;AAC7H"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { AiPromptContextBuilder, type ResolvedProject, type ResolvedPersona, type ProjectFileContent } from "./abstractions.js";
|
|
1
|
+
export { AiPromptContextBuilder, formatAdditionalFilesContext, type ResolvedProject, type ResolvedPersona, type ProjectFileContent } from "./abstractions.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { AiPromptContextBuilder } from "./abstractions.js";
|
|
1
|
+
export { AiPromptContextBuilder, formatAdditionalFilesContext } from "./abstractions.js";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Ai } from "@webiny/api-core/features/ai/index.js";
|
|
2
|
+
import { Encryption } from "@webiny/api-core/features/encryption/index.js";
|
|
3
|
+
import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
|
|
4
|
+
import { ModelToAstConverter } from "@webiny/api-headless-cms/features/contentModel/ModelToAstConverter/index.js";
|
|
5
|
+
import { GetRevisionByIdUseCase } from "@webiny/api-headless-cms/features/contentEntry/GetRevisionById/index.js";
|
|
6
|
+
import { GetSettingsUseCase } from "../../../api/features/GetSettings/index.js";
|
|
7
|
+
import { CmsCompareEntryRevisionsUseCase } from "./abstractions.js";
|
|
8
|
+
import type { ICmsCompareEntryRevisionsParams, ICmsCompareEntryRevisionsResult } from "./abstractions.js";
|
|
9
|
+
declare class CmsCompareEntryRevisionsUseCaseImpl implements CmsCompareEntryRevisionsUseCase.Interface {
|
|
10
|
+
private getSettings;
|
|
11
|
+
private ai;
|
|
12
|
+
private encryption;
|
|
13
|
+
private getModel;
|
|
14
|
+
private getRevisionById;
|
|
15
|
+
private modelToAst;
|
|
16
|
+
constructor(getSettings: GetSettingsUseCase.Interface, ai: Ai.Interface, encryption: Encryption.Interface, getModel: GetModelUseCase.Interface, getRevisionById: GetRevisionByIdUseCase.Interface, modelToAst: ModelToAstConverter.Interface);
|
|
17
|
+
execute(params: ICmsCompareEntryRevisionsParams): Promise<ICmsCompareEntryRevisionsResult>;
|
|
18
|
+
}
|
|
19
|
+
export declare const CmsCompareEntryRevisionsUseCaseImplementation: typeof CmsCompareEntryRevisionsUseCaseImpl & {
|
|
20
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICmsCompareEntryRevisionsUseCase>;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Ai } from "@webiny/api-core/features/ai/index.js";
|
|
2
|
+
import { Encryption } from "@webiny/api-core/features/encryption/index.js";
|
|
3
|
+
import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
|
|
4
|
+
import { ModelToAstConverter } from "@webiny/api-headless-cms/features/contentModel/ModelToAstConverter/index.js";
|
|
5
|
+
import { CmsModelToJsonSchemaConverter } from "@webiny/api-headless-cms/utils/contentModelToJsonSchema/index.js";
|
|
6
|
+
import { GetRevisionByIdUseCase } from "@webiny/api-headless-cms/features/contentEntry/GetRevisionById/index.js";
|
|
7
|
+
import { GetSettingsUseCase } from "../GetSettings/index.js";
|
|
8
|
+
import { CmsCompareEntryRevisionsUseCase } from "./abstractions.js";
|
|
9
|
+
const SYSTEM_PROMPT = `You are a content intelligence assistant specialized in version comparison for headless CMS platforms.
|
|
10
|
+
|
|
11
|
+
I will provide:
|
|
12
|
+
|
|
13
|
+
1. The content model JSON Schema that defines the structure of the entry.
|
|
14
|
+
2. Two versions of the content entry values in JSON format: Version A and Version B.
|
|
15
|
+
|
|
16
|
+
Your task:
|
|
17
|
+
|
|
18
|
+
- Parse both versions according to the JSON Schema.
|
|
19
|
+
- Identify all differences between Version A and Version B.
|
|
20
|
+
- For each difference, explain:
|
|
21
|
+
- The field name (use the human-readable label from the schema description if available)
|
|
22
|
+
- The value in Version A
|
|
23
|
+
- The value in Version B
|
|
24
|
+
- A brief summary of the change (e.g., "Title changed from 'Old' to 'New'")
|
|
25
|
+
- If nested fields or objects exist, perform a deep comparison.
|
|
26
|
+
- Return the comparison in clean HTML format.
|
|
27
|
+
|
|
28
|
+
Output format:
|
|
29
|
+
|
|
30
|
+
<div class="comparison-report">
|
|
31
|
+
<table class="comparison-table">
|
|
32
|
+
<thead>
|
|
33
|
+
<tr>
|
|
34
|
+
<th>Field</th>
|
|
35
|
+
<th>Version A</th>
|
|
36
|
+
<th>Version B</th>
|
|
37
|
+
<th>Change Summary</th>
|
|
38
|
+
</tr>
|
|
39
|
+
</thead>
|
|
40
|
+
<tbody>
|
|
41
|
+
<tr>
|
|
42
|
+
<td><strong>title</strong></td>
|
|
43
|
+
<td>Launch Plan</td>
|
|
44
|
+
<td>Updated Launch Plan</td>
|
|
45
|
+
<td>Title changed from 'Launch Plan' to 'Updated Launch Plan'</td>
|
|
46
|
+
</tr>
|
|
47
|
+
</tbody>
|
|
48
|
+
</table>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
If no differences are found, return: <div class="no-changes"><h3>No differences detected between Version A and Version B.</h3></div>
|
|
52
|
+
|
|
53
|
+
Use semantic HTML with appropriate CSS classes for styling. Do not include <style> tags or CSS — only return the HTML structure.
|
|
54
|
+
For rich text or complex nested values, show a concise summary rather than raw JSON.`;
|
|
55
|
+
class CmsCompareEntryRevisionsUseCaseImpl {
|
|
56
|
+
constructor(getSettings, ai, encryption, getModel, getRevisionById, modelToAst){
|
|
57
|
+
this.getSettings = getSettings;
|
|
58
|
+
this.ai = ai;
|
|
59
|
+
this.encryption = encryption;
|
|
60
|
+
this.getModel = getModel;
|
|
61
|
+
this.getRevisionById = getRevisionById;
|
|
62
|
+
this.modelToAst = modelToAst;
|
|
63
|
+
}
|
|
64
|
+
async execute(params) {
|
|
65
|
+
const { modelId, revisionId1, revisionId2 } = params;
|
|
66
|
+
const settingsResult = await this.getSettings.execute();
|
|
67
|
+
if (settingsResult.isFail()) throw new Error("Failed to load AI Power Ups settings.");
|
|
68
|
+
const settings = settingsResult.value;
|
|
69
|
+
const firstProvider = settings.providers.presets[0];
|
|
70
|
+
if (!firstProvider) throw new Error("No AI provider configured. Add a provider in AI Power Ups settings.");
|
|
71
|
+
const modelResult = await this.getModel.execute(modelId);
|
|
72
|
+
if (modelResult.isFail()) throw new Error(`Content model "${modelId}" not found.`);
|
|
73
|
+
const model = modelResult.value;
|
|
74
|
+
const [rev1Result, rev2Result] = await Promise.all([
|
|
75
|
+
this.getRevisionById.execute(model, revisionId1),
|
|
76
|
+
this.getRevisionById.execute(model, revisionId2)
|
|
77
|
+
]);
|
|
78
|
+
if (rev1Result.isFail()) throw new Error(`Revision "${revisionId1}" not found.`);
|
|
79
|
+
if (rev2Result.isFail()) throw new Error(`Revision "${revisionId2}" not found.`);
|
|
80
|
+
const revision1 = rev1Result.value;
|
|
81
|
+
const revision2 = rev2Result.value;
|
|
82
|
+
const modelAst = this.modelToAst.toAst(model);
|
|
83
|
+
const jsonSchemaConverter = new CmsModelToJsonSchemaConverter();
|
|
84
|
+
const entrySchema = jsonSchemaConverter.convert(modelAst, {
|
|
85
|
+
name: model.name,
|
|
86
|
+
description: model.description
|
|
87
|
+
});
|
|
88
|
+
const apiKey = await this.encryption.decrypt(firstProvider.apiKeyEncrypted);
|
|
89
|
+
const userPrompt = `CONTENT MODEL JSON SCHEMA:
|
|
90
|
+
${JSON.stringify(entrySchema, null, 2)}
|
|
91
|
+
|
|
92
|
+
VERSION A (Revision #${revision1.version}):
|
|
93
|
+
${JSON.stringify(revision1.values, null, 2)}
|
|
94
|
+
|
|
95
|
+
VERSION B (Revision #${revision2.version}):
|
|
96
|
+
${JSON.stringify(revision2.values, null, 2)}`;
|
|
97
|
+
const result = await this.ai.generateText({
|
|
98
|
+
model: firstProvider.model,
|
|
99
|
+
connection: {
|
|
100
|
+
sdkName: firstProvider.model.split("/")[0],
|
|
101
|
+
apiKey
|
|
102
|
+
},
|
|
103
|
+
system: SYSTEM_PROMPT,
|
|
104
|
+
prompt: userPrompt,
|
|
105
|
+
temperature: 0.3
|
|
106
|
+
});
|
|
107
|
+
const text = result.text;
|
|
108
|
+
const noChangesMatch = text.match(/No differences detected/);
|
|
109
|
+
let summary = "Content comparison completed";
|
|
110
|
+
if (noChangesMatch) summary = "No differences detected between versions";
|
|
111
|
+
else {
|
|
112
|
+
const headingMatch = text.match(/<h[2-3][^>]*>([^<]+)<\/h[2-3]>/);
|
|
113
|
+
const trCount = (text.match(/<tr>/g) || []).length - 1;
|
|
114
|
+
if (headingMatch) summary = headingMatch[1].trim();
|
|
115
|
+
else if (trCount > 0) summary = `${trCount} field${1 === trCount ? "" : "s"} changed`;
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
html: text,
|
|
119
|
+
summary
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const CmsCompareEntryRevisionsUseCaseImplementation = CmsCompareEntryRevisionsUseCase.createImplementation({
|
|
124
|
+
implementation: CmsCompareEntryRevisionsUseCaseImpl,
|
|
125
|
+
dependencies: [
|
|
126
|
+
GetSettingsUseCase,
|
|
127
|
+
Ai,
|
|
128
|
+
Encryption,
|
|
129
|
+
GetModelUseCase,
|
|
130
|
+
GetRevisionByIdUseCase,
|
|
131
|
+
ModelToAstConverter
|
|
132
|
+
]
|
|
133
|
+
});
|
|
134
|
+
export { CmsCompareEntryRevisionsUseCaseImplementation };
|
|
135
|
+
|
|
136
|
+
//# sourceMappingURL=CmsCompareEntryRevisionsUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.js","sources":["../../../../src/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.ts"],"sourcesContent":["import { Ai } from \"@webiny/api-core/features/ai/index.js\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { GetModelUseCase } from \"@webiny/api-headless-cms/features/contentModel/GetModel/index.js\";\nimport { ModelToAstConverter } from \"@webiny/api-headless-cms/features/contentModel/ModelToAstConverter/index.js\";\nimport { CmsModelToJsonSchemaConverter } from \"@webiny/api-headless-cms/utils/contentModelToJsonSchema/index.js\";\nimport { GetRevisionByIdUseCase } from \"@webiny/api-headless-cms/features/contentEntry/GetRevisionById/index.js\";\nimport { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\nimport { CmsCompareEntryRevisionsUseCase } from \"./abstractions.js\";\nimport type {\n ICmsCompareEntryRevisionsParams,\n ICmsCompareEntryRevisionsResult\n} from \"./abstractions.js\";\n\nconst SYSTEM_PROMPT = `You are a content intelligence assistant specialized in version comparison for headless CMS platforms.\n\nI will provide:\n\n1. The content model JSON Schema that defines the structure of the entry.\n2. Two versions of the content entry values in JSON format: Version A and Version B.\n\nYour task:\n\n- Parse both versions according to the JSON Schema.\n- Identify all differences between Version A and Version B.\n- For each difference, explain:\n - The field name (use the human-readable label from the schema description if available)\n - The value in Version A\n - The value in Version B\n - A brief summary of the change (e.g., \"Title changed from 'Old' to 'New'\")\n- If nested fields or objects exist, perform a deep comparison.\n- Return the comparison in clean HTML format.\n\nOutput format:\n\n<div class=\"comparison-report\">\n <table class=\"comparison-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Version A</th>\n <th>Version B</th>\n <th>Change Summary</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td><strong>title</strong></td>\n <td>Launch Plan</td>\n <td>Updated Launch Plan</td>\n <td>Title changed from 'Launch Plan' to 'Updated Launch Plan'</td>\n </tr>\n </tbody>\n </table>\n</div>\n\nIf no differences are found, return: <div class=\"no-changes\"><h3>No differences detected between Version A and Version B.</h3></div>\n\nUse semantic HTML with appropriate CSS classes for styling. Do not include <style> tags or CSS — only return the HTML structure.\nFor rich text or complex nested values, show a concise summary rather than raw JSON.`;\n\nclass CmsCompareEntryRevisionsUseCaseImpl implements CmsCompareEntryRevisionsUseCase.Interface {\n constructor(\n private getSettings: GetSettingsUseCase.Interface,\n private ai: Ai.Interface,\n private encryption: Encryption.Interface,\n private getModel: GetModelUseCase.Interface,\n private getRevisionById: GetRevisionByIdUseCase.Interface,\n private modelToAst: ModelToAstConverter.Interface\n ) {}\n\n async execute(\n params: ICmsCompareEntryRevisionsParams\n ): Promise<ICmsCompareEntryRevisionsResult> {\n const { modelId, revisionId1, revisionId2 } = params;\n\n const settingsResult = await this.getSettings.execute();\n if (settingsResult.isFail()) {\n throw new Error(\"Failed to load AI Power Ups settings.\");\n }\n\n const settings = settingsResult.value;\n const firstProvider = settings.providers.presets[0];\n\n if (!firstProvider) {\n throw new Error(\"No AI provider configured. Add a provider in AI Power Ups settings.\");\n }\n\n const modelResult = await this.getModel.execute(modelId);\n if (modelResult.isFail()) {\n throw new Error(`Content model \"${modelId}\" not found.`);\n }\n const model = modelResult.value;\n\n const [rev1Result, rev2Result] = await Promise.all([\n this.getRevisionById.execute(model, revisionId1),\n this.getRevisionById.execute(model, revisionId2)\n ]);\n\n if (rev1Result.isFail()) {\n throw new Error(`Revision \"${revisionId1}\" not found.`);\n }\n if (rev2Result.isFail()) {\n throw new Error(`Revision \"${revisionId2}\" not found.`);\n }\n\n const revision1 = rev1Result.value;\n const revision2 = rev2Result.value;\n\n const modelAst = this.modelToAst.toAst(model);\n const jsonSchemaConverter = new CmsModelToJsonSchemaConverter();\n const entrySchema = jsonSchemaConverter.convert(modelAst, {\n name: model.name,\n description: model.description\n });\n\n const apiKey = await this.encryption.decrypt(firstProvider.apiKeyEncrypted);\n\n const userPrompt = `CONTENT MODEL JSON SCHEMA:\n${JSON.stringify(entrySchema, null, 2)}\n\nVERSION A (Revision #${revision1.version}):\n${JSON.stringify(revision1.values, null, 2)}\n\nVERSION B (Revision #${revision2.version}):\n${JSON.stringify(revision2.values, null, 2)}`;\n\n const result = await this.ai.generateText({\n model: firstProvider.model,\n connection: {\n sdkName: firstProvider.model.split(\"/\")[0],\n apiKey\n },\n system: SYSTEM_PROMPT,\n prompt: userPrompt,\n temperature: 0.3\n });\n\n const text = result.text;\n\n const noChangesMatch = text.match(/No differences detected/);\n let summary = \"Content comparison completed\";\n if (noChangesMatch) {\n summary = \"No differences detected between versions\";\n } else {\n const headingMatch = text.match(/<h[2-3][^>]*>([^<]+)<\\/h[2-3]>/);\n const trCount = (text.match(/<tr>/g) || []).length - 1;\n if (headingMatch) {\n summary = headingMatch[1].trim();\n } else if (trCount > 0) {\n summary = `${trCount} field${trCount === 1 ? \"\" : \"s\"} changed`;\n }\n }\n\n return { html: text, summary };\n }\n}\n\nexport const CmsCompareEntryRevisionsUseCaseImplementation =\n CmsCompareEntryRevisionsUseCase.createImplementation({\n implementation: CmsCompareEntryRevisionsUseCaseImpl,\n dependencies: [\n GetSettingsUseCase,\n Ai,\n Encryption,\n GetModelUseCase,\n GetRevisionByIdUseCase,\n ModelToAstConverter\n ]\n });\n"],"names":["SYSTEM_PROMPT","CmsCompareEntryRevisionsUseCaseImpl","getSettings","ai","encryption","getModel","getRevisionById","modelToAst","params","modelId","revisionId1","revisionId2","settingsResult","Error","settings","firstProvider","modelResult","model","rev1Result","rev2Result","Promise","revision1","revision2","modelAst","jsonSchemaConverter","CmsModelToJsonSchemaConverter","entrySchema","apiKey","userPrompt","JSON","result","text","noChangesMatch","summary","headingMatch","trCount","CmsCompareEntryRevisionsUseCaseImplementation","CmsCompareEntryRevisionsUseCase","GetSettingsUseCase","Ai","Encryption","GetModelUseCase","GetRevisionByIdUseCase","ModelToAstConverter"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ICmsCompareEntryRevisionsResult {
|
|
2
|
+
html: string;
|
|
3
|
+
summary: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ICmsCompareEntryRevisionsParams {
|
|
6
|
+
modelId: string;
|
|
7
|
+
revisionId1: string;
|
|
8
|
+
revisionId2: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ICmsCompareEntryRevisionsUseCase {
|
|
11
|
+
execute(params: ICmsCompareEntryRevisionsParams): Promise<ICmsCompareEntryRevisionsResult>;
|
|
12
|
+
}
|
|
13
|
+
export declare const CmsCompareEntryRevisionsUseCase: import("@webiny/di").Abstraction<ICmsCompareEntryRevisionsUseCase>;
|
|
14
|
+
export declare namespace CmsCompareEntryRevisionsUseCase {
|
|
15
|
+
type Interface = ICmsCompareEntryRevisionsUseCase;
|
|
16
|
+
type Params = ICmsCompareEntryRevisionsParams;
|
|
17
|
+
type Result = ICmsCompareEntryRevisionsResult;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api/features/CmsCompareEntryRevisions/abstractions.js","sources":["../../../../src/api/features/CmsCompareEntryRevisions/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\n\nexport interface ICmsCompareEntryRevisionsResult {\n html: string;\n summary: string;\n}\n\nexport interface ICmsCompareEntryRevisionsParams {\n modelId: string;\n revisionId1: string;\n revisionId2: string;\n}\n\nexport interface ICmsCompareEntryRevisionsUseCase {\n execute(params: ICmsCompareEntryRevisionsParams): Promise<ICmsCompareEntryRevisionsResult>;\n}\n\nexport const CmsCompareEntryRevisionsUseCase = createAbstraction<ICmsCompareEntryRevisionsUseCase>(\n \"AiPowerUpsCmsCompareEntryRevisionsUseCase\"\n);\n\nexport namespace CmsCompareEntryRevisionsUseCase {\n export type Interface = ICmsCompareEntryRevisionsUseCase;\n export type Params = ICmsCompareEntryRevisionsParams;\n export type Result = ICmsCompareEntryRevisionsResult;\n}\n"],"names":["CmsCompareEntryRevisionsUseCase","createAbstraction"],"mappings":";AAiBO,MAAMA,kCAAkCC,kBAC3C"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/api";
|
|
2
|
+
import { CmsCompareEntryRevisionsUseCaseImplementation } from "./CmsCompareEntryRevisionsUseCase.js";
|
|
3
|
+
const CmsCompareEntryRevisionsFeature = createFeature({
|
|
4
|
+
name: "AiPowerUps/CmsCompareEntryRevisions",
|
|
5
|
+
register (container) {
|
|
6
|
+
container.register(CmsCompareEntryRevisionsUseCaseImplementation);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
export { CmsCompareEntryRevisionsFeature };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api/features/CmsCompareEntryRevisions/feature.js","sources":["../../../../src/api/features/CmsCompareEntryRevisions/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { CmsCompareEntryRevisionsUseCaseImplementation } from \"./CmsCompareEntryRevisionsUseCase.js\";\n\nexport const CmsCompareEntryRevisionsFeature = createFeature({\n name: \"AiPowerUps/CmsCompareEntryRevisions\",\n register(container) {\n container.register(CmsCompareEntryRevisionsUseCaseImplementation);\n }\n});\n"],"names":["CmsCompareEntryRevisionsFeature","createFeature","container","CmsCompareEntryRevisionsUseCaseImplementation"],"mappings":";;AAGO,MAAMA,kCAAkCC,cAAc;IACzD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
|
|
2
|
+
import { WebsocketsSendToIdentityUseCase } from "@webiny/api-websockets/features/SendToIdentity/abstractions.js";
|
|
3
|
+
import { CmsGenerateEntryContentUseCase } from "../../../api/features/CmsGenerateEntryContent/index.js";
|
|
4
|
+
import { IdentityContext } from "@webiny/api-core/exports/api/security.js";
|
|
5
|
+
export declare const CMS_GENERATE_ENTRY_CONTENT_TASK_ID = "aiPowerUpsGenerateEntryContent";
|
|
6
|
+
export interface ICmsGenerateEntryContentTaskInput {
|
|
7
|
+
prompt: string;
|
|
8
|
+
modelId: string;
|
|
9
|
+
projectId?: string | null;
|
|
10
|
+
excludedFileIds?: string[] | null;
|
|
11
|
+
readerPersonaId?: string | null;
|
|
12
|
+
writerPersonaId?: string | null;
|
|
13
|
+
additionalFileIds?: string[] | null;
|
|
14
|
+
}
|
|
15
|
+
declare class CmsGenerateEntryContentTaskImpl implements TaskDefinition.Interface<ICmsGenerateEntryContentTaskInput> {
|
|
16
|
+
private identityContext;
|
|
17
|
+
private generateEntryContent;
|
|
18
|
+
private sendToIdentity;
|
|
19
|
+
id: string;
|
|
20
|
+
title: string;
|
|
21
|
+
description: string;
|
|
22
|
+
maxIterations: number;
|
|
23
|
+
isPrivate: boolean;
|
|
24
|
+
databaseLogs: boolean;
|
|
25
|
+
constructor(identityContext: IdentityContext.Interface, generateEntryContent: CmsGenerateEntryContentUseCase.Interface, sendToIdentity: WebsocketsSendToIdentityUseCase.Interface);
|
|
26
|
+
run({ input, controller }: TaskDefinition.RunParams<ICmsGenerateEntryContentTaskInput>): Promise<TaskDefinition.Result<ICmsGenerateEntryContentTaskInput>>;
|
|
27
|
+
private sendContentToUser;
|
|
28
|
+
private sendErrorToUser;
|
|
29
|
+
}
|
|
30
|
+
export declare const CmsGenerateEntryContentTask: typeof CmsGenerateEntryContentTaskImpl & {
|
|
31
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskDefinition<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>;
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
|
|
2
|
+
import { WebsocketsSendToIdentityUseCase } from "@webiny/api-websockets/features/SendToIdentity/abstractions.js";
|
|
3
|
+
import { compressJson } from "@webiny/utils/features/compression/legacy/gzip.js";
|
|
4
|
+
import { CmsGenerateEntryContentUseCase } from "./index.js";
|
|
5
|
+
import { IdentityContext } from "@webiny/api-core/exports/api/security.js";
|
|
6
|
+
const CMS_GENERATE_ENTRY_CONTENT_TASK_ID = "aiPowerUpsGenerateEntryContent";
|
|
7
|
+
class CmsGenerateEntryContentTaskImpl {
|
|
8
|
+
constructor(identityContext, generateEntryContent, sendToIdentity){
|
|
9
|
+
this.identityContext = identityContext;
|
|
10
|
+
this.generateEntryContent = generateEntryContent;
|
|
11
|
+
this.sendToIdentity = sendToIdentity;
|
|
12
|
+
this.id = CMS_GENERATE_ENTRY_CONTENT_TASK_ID;
|
|
13
|
+
this.title = "AI Power-Ups - Generate Entry Content";
|
|
14
|
+
this.description = "Generates CMS entry content using AI based on a user prompt.";
|
|
15
|
+
this.maxIterations = 1;
|
|
16
|
+
this.isPrivate = true;
|
|
17
|
+
this.databaseLogs = false;
|
|
18
|
+
}
|
|
19
|
+
async run({ input, controller }) {
|
|
20
|
+
if (controller.runtime.isAborted()) return controller.response.aborted();
|
|
21
|
+
const identity = this.identityContext.getIdentity();
|
|
22
|
+
let result;
|
|
23
|
+
try {
|
|
24
|
+
result = await this.generateEntryContent.execute({
|
|
25
|
+
prompt: input.prompt,
|
|
26
|
+
modelId: input.modelId,
|
|
27
|
+
projectId: input.projectId,
|
|
28
|
+
excludedFileIds: input.excludedFileIds,
|
|
29
|
+
readerPersonaId: input.readerPersonaId,
|
|
30
|
+
writerPersonaId: input.writerPersonaId,
|
|
31
|
+
additionalFileIds: input.additionalFileIds
|
|
32
|
+
});
|
|
33
|
+
} catch (err) {
|
|
34
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
35
|
+
await this.sendErrorToUser(identity.id, message);
|
|
36
|
+
return controller.response.error({
|
|
37
|
+
message
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (result.isFail()) {
|
|
41
|
+
await this.sendErrorToUser(identity.id, result.error.message);
|
|
42
|
+
return controller.response.error({
|
|
43
|
+
message: result.error.message
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const compressed = await compressJson(result.value.values);
|
|
47
|
+
const payload = compressed.toString("base64");
|
|
48
|
+
await this.sendContentToUser(identity.id, payload, result.value.telemetry);
|
|
49
|
+
return controller.response.done("Entry content generated successfully.");
|
|
50
|
+
}
|
|
51
|
+
async sendContentToUser(identityId, payload, telemetry) {
|
|
52
|
+
await this.sendToIdentity.execute({
|
|
53
|
+
id: identityId
|
|
54
|
+
}, {
|
|
55
|
+
action: "aiPowerUps.generateEntryContent.content",
|
|
56
|
+
data: {
|
|
57
|
+
compression: "gzip",
|
|
58
|
+
value: payload,
|
|
59
|
+
telemetry
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async sendErrorToUser(identityId, message) {
|
|
64
|
+
await this.sendToIdentity.execute({
|
|
65
|
+
id: identityId
|
|
66
|
+
}, {
|
|
67
|
+
action: "aiPowerUps.generateEntryContent.error",
|
|
68
|
+
data: {
|
|
69
|
+
message
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const CmsGenerateEntryContentTask = TaskDefinition.createImplementation({
|
|
75
|
+
implementation: CmsGenerateEntryContentTaskImpl,
|
|
76
|
+
dependencies: [
|
|
77
|
+
IdentityContext,
|
|
78
|
+
CmsGenerateEntryContentUseCase,
|
|
79
|
+
WebsocketsSendToIdentityUseCase
|
|
80
|
+
]
|
|
81
|
+
});
|
|
82
|
+
export { CMS_GENERATE_ENTRY_CONTENT_TASK_ID, CmsGenerateEntryContentTask };
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=CmsGenerateEntryContentTask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api/features/CmsGenerateEntryContent/CmsGenerateEntryContentTask.js","sources":["../../../../src/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentTask.ts"],"sourcesContent":["import { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { WebsocketsSendToIdentityUseCase } from \"@webiny/api-websockets/features/SendToIdentity/abstractions.js\";\nimport { compressJson } from \"@webiny/utils/features/compression/legacy/gzip.js\";\nimport { CmsGenerateEntryContentUseCase } from \"~/api/features/CmsGenerateEntryContent/index.js\";\nimport type { GenerateEntryContentTelemetry } from \"~/api/features/CmsGenerateEntryContent/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/exports/api/security.js\";\n\nexport const CMS_GENERATE_ENTRY_CONTENT_TASK_ID = \"aiPowerUpsGenerateEntryContent\";\n\nexport interface ICmsGenerateEntryContentTaskInput {\n prompt: string;\n modelId: string;\n projectId?: string | null;\n excludedFileIds?: string[] | null;\n readerPersonaId?: string | null;\n writerPersonaId?: string | null;\n additionalFileIds?: string[] | null;\n}\n\nclass CmsGenerateEntryContentTaskImpl implements TaskDefinition.Interface<ICmsGenerateEntryContentTaskInput> {\n id = CMS_GENERATE_ENTRY_CONTENT_TASK_ID;\n title = \"AI Power-Ups - Generate Entry Content\";\n description = \"Generates CMS entry content using AI based on a user prompt.\";\n maxIterations = 1;\n isPrivate = true;\n databaseLogs = false;\n\n constructor(\n private identityContext: IdentityContext.Interface,\n private generateEntryContent: CmsGenerateEntryContentUseCase.Interface,\n private sendToIdentity: WebsocketsSendToIdentityUseCase.Interface\n ) {}\n\n async run({\n input,\n controller\n }: TaskDefinition.RunParams<ICmsGenerateEntryContentTaskInput>): Promise<\n TaskDefinition.Result<ICmsGenerateEntryContentTaskInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n const identity = this.identityContext.getIdentity();\n\n let result;\n try {\n result = await this.generateEntryContent.execute({\n prompt: input.prompt,\n modelId: input.modelId,\n projectId: input.projectId,\n excludedFileIds: input.excludedFileIds,\n readerPersonaId: input.readerPersonaId,\n writerPersonaId: input.writerPersonaId,\n additionalFileIds: input.additionalFileIds\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await this.sendErrorToUser(identity.id, message);\n return controller.response.error({ message });\n }\n\n if (result.isFail()) {\n await this.sendErrorToUser(identity.id, result.error.message);\n\n return controller.response.error({\n message: result.error.message\n });\n }\n\n // Serialize at the transport edge: the use case returns structured values; the\n // websocket stream carries a gzip+base64 JSON string that the Admin app decodes.\n const compressed = await compressJson(result.value.values);\n const payload = compressed.toString(\"base64\");\n\n await this.sendContentToUser(identity.id, payload, result.value.telemetry);\n\n return controller.response.done(\"Entry content generated successfully.\");\n }\n\n private async sendContentToUser(\n identityId: string,\n payload: string,\n telemetry: GenerateEntryContentTelemetry\n ) {\n await this.sendToIdentity.execute(\n { id: identityId },\n {\n action: \"aiPowerUps.generateEntryContent.content\",\n data: {\n compression: \"gzip\",\n value: payload,\n telemetry\n }\n }\n );\n }\n\n private async sendErrorToUser(identityId: string, message: string) {\n await this.sendToIdentity.execute(\n { id: identityId },\n {\n action: \"aiPowerUps.generateEntryContent.error\",\n data: {\n message\n }\n }\n );\n }\n}\n\nexport const CmsGenerateEntryContentTask = TaskDefinition.createImplementation({\n implementation: CmsGenerateEntryContentTaskImpl,\n dependencies: [IdentityContext, CmsGenerateEntryContentUseCase, WebsocketsSendToIdentityUseCase]\n});\n"],"names":["CMS_GENERATE_ENTRY_CONTENT_TASK_ID","CmsGenerateEntryContentTaskImpl","identityContext","generateEntryContent","sendToIdentity","input","controller","identity","result","err","message","Error","String","compressed","compressJson","payload","identityId","telemetry","CmsGenerateEntryContentTask","TaskDefinition","IdentityContext","CmsGenerateEntryContentUseCase","WebsocketsSendToIdentityUseCase"],"mappings":";;;;;AAOO,MAAMA,qCAAqC;AAYlD,MAAMC;IAQF,YACYC,eAA0C,EAC1CC,oBAA8D,EAC9DC,cAAyD,CACnE;aAHUF,eAAe,GAAfA;aACAC,oBAAoB,GAApBA;aACAC,cAAc,GAAdA;aAVZ,EAAE,GAAGJ;aACL,KAAK,GAAG;aACR,WAAW,GAAG;aACd,aAAa,GAAG;aAChB,SAAS,GAAG;aACZ,YAAY,GAAG;IAMZ;IAEH,MAAM,IAAI,EACNK,KAAK,EACLC,UAAU,EACgD,EAE5D;QACE,IAAIA,WAAW,OAAO,CAAC,SAAS,IAC5B,OAAOA,WAAW,QAAQ,CAAC,OAAO;QAGtC,MAAMC,WAAW,IAAI,CAAC,eAAe,CAAC,WAAW;QAEjD,IAAIC;QACJ,IAAI;YACAA,SAAS,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;gBAC7C,QAAQH,MAAM,MAAM;gBACpB,SAASA,MAAM,OAAO;gBACtB,WAAWA,MAAM,SAAS;gBAC1B,iBAAiBA,MAAM,eAAe;gBACtC,iBAAiBA,MAAM,eAAe;gBACtC,iBAAiBA,MAAM,eAAe;gBACtC,mBAAmBA,MAAM,iBAAiB;YAC9C;QACJ,EAAE,OAAOI,KAAK;YACV,MAAMC,UAAUD,eAAeE,QAAQF,IAAI,OAAO,GAAGG,OAAOH;YAC5D,MAAM,IAAI,CAAC,eAAe,CAACF,SAAS,EAAE,EAAEG;YACxC,OAAOJ,WAAW,QAAQ,CAAC,KAAK,CAAC;gBAAEI;YAAQ;QAC/C;QAEA,IAAIF,OAAO,MAAM,IAAI;YACjB,MAAM,IAAI,CAAC,eAAe,CAACD,SAAS,EAAE,EAAEC,OAAO,KAAK,CAAC,OAAO;YAE5D,OAAOF,WAAW,QAAQ,CAAC,KAAK,CAAC;gBAC7B,SAASE,OAAO,KAAK,CAAC,OAAO;YACjC;QACJ;QAIA,MAAMK,aAAa,MAAMC,aAAaN,OAAO,KAAK,CAAC,MAAM;QACzD,MAAMO,UAAUF,WAAW,QAAQ,CAAC;QAEpC,MAAM,IAAI,CAAC,iBAAiB,CAACN,SAAS,EAAE,EAAEQ,SAASP,OAAO,KAAK,CAAC,SAAS;QAEzE,OAAOF,WAAW,QAAQ,CAAC,IAAI,CAAC;IACpC;IAEA,MAAc,kBACVU,UAAkB,EAClBD,OAAe,EACfE,SAAwC,EAC1C;QACE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B;YAAE,IAAID;QAAW,GACjB;YACI,QAAQ;YACR,MAAM;gBACF,aAAa;gBACb,OAAOD;gBACPE;YACJ;QACJ;IAER;IAEA,MAAc,gBAAgBD,UAAkB,EAAEN,OAAe,EAAE;QAC/D,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAC7B;YAAE,IAAIM;QAAW,GACjB;YACI,QAAQ;YACR,MAAM;gBACFN;YACJ;QACJ;IAER;AACJ;AAEO,MAAMQ,8BAA8BC,eAAe,oBAAoB,CAAC;IAC3E,gBAAgBlB;IAChB,cAAc;QAACmB;QAAiBC;QAAgCC;KAAgC;AACpG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import { Ai } from "@webiny/api-core/features/ai/index.js";
|
|
3
|
+
import { AiSdkTools } from "@webiny/api-core/features/ai/index.js";
|
|
4
|
+
import { AiToolPipelineRunner } from "@webiny/api-core/features/ai/index.js";
|
|
5
|
+
import { Encryption } from "@webiny/api-core/features/encryption/index.js";
|
|
6
|
+
import { ListTagsUseCase } from "@webiny/api-file-manager/features/file/ListTags/index.js";
|
|
7
|
+
import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
|
|
8
|
+
import { ModelToAstConverter } from "@webiny/api-headless-cms/features/contentModel/ModelToAstConverter/index.js";
|
|
9
|
+
import { GetSettingsUseCase } from "../../../api/features/GetSettings/index.js";
|
|
10
|
+
import { AiPromptContextBuilder } from "../../../api/features/AiPromptContext/index.js";
|
|
11
|
+
import { CmsGenerateEntryContentUseCase } from "./abstractions.js";
|
|
12
|
+
import type { CmsGenerateEntryContentParams, GenerateEntryContentResult } from "./abstractions.js";
|
|
13
|
+
declare class CmsGenerateEntryContentUseCaseImpl implements CmsGenerateEntryContentUseCase.Interface {
|
|
14
|
+
private promptContextBuilder;
|
|
15
|
+
private getSettings;
|
|
16
|
+
private ai;
|
|
17
|
+
private aiSdkTools;
|
|
18
|
+
private encryption;
|
|
19
|
+
private listTags;
|
|
20
|
+
private getModel;
|
|
21
|
+
private modelToAst;
|
|
22
|
+
private toolPipelineRunner;
|
|
23
|
+
constructor(promptContextBuilder: AiPromptContextBuilder.Interface, getSettings: GetSettingsUseCase.Interface, ai: Ai.Interface, aiSdkTools: AiSdkTools.Interface, encryption: Encryption.Interface, listTags: ListTagsUseCase.Interface, getModel: GetModelUseCase.Interface, modelToAst: ModelToAstConverter.Interface, toolPipelineRunner: AiToolPipelineRunner.Interface);
|
|
24
|
+
execute<TValues = Record<string, any>>(params: CmsGenerateEntryContentParams): Promise<Result<GenerateEntryContentResult<TValues>, Error>>;
|
|
25
|
+
}
|
|
26
|
+
export declare const CmsGenerateEntryContentUseCaseImplementation: typeof CmsGenerateEntryContentUseCaseImpl & {
|
|
27
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICmsGenerateEntryContentUseCase>;
|
|
28
|
+
};
|
|
29
|
+
export {};
|