@webiny/ai-powerups 6.6.0-alpha.0 → 6.6.0-alpha.2
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
|
@@ -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"}
|
|
@@ -10,6 +10,7 @@ export interface ICmsGenerateEntryContentTaskInput {
|
|
|
10
10
|
excludedFileIds?: string[] | null;
|
|
11
11
|
readerPersonaId?: string | null;
|
|
12
12
|
writerPersonaId?: string | null;
|
|
13
|
+
additionalFileIds?: string[] | null;
|
|
13
14
|
}
|
|
14
15
|
declare class CmsGenerateEntryContentTaskImpl implements TaskDefinition.Interface<ICmsGenerateEntryContentTaskInput> {
|
|
15
16
|
private identityContext;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
|
|
2
2
|
import { WebsocketsSendToIdentityUseCase } from "@webiny/api-websockets/features/SendToIdentity/abstractions.js";
|
|
3
|
-
import {
|
|
3
|
+
import { compressJson } from "@webiny/utils/features/compression/legacy/gzip.js";
|
|
4
4
|
import { CmsGenerateEntryContentUseCase } from "./index.js";
|
|
5
5
|
import { IdentityContext } from "@webiny/api-core/exports/api/security.js";
|
|
6
6
|
const CMS_GENERATE_ENTRY_CONTENT_TASK_ID = "aiPowerUpsGenerateEntryContent";
|
|
@@ -18,22 +18,32 @@ class CmsGenerateEntryContentTaskImpl {
|
|
|
18
18
|
}
|
|
19
19
|
async run({ input, controller }) {
|
|
20
20
|
if (controller.runtime.isAborted()) return controller.response.aborted();
|
|
21
|
-
const result = await this.generateEntryContent.execute({
|
|
22
|
-
prompt: input.prompt,
|
|
23
|
-
modelId: input.modelId,
|
|
24
|
-
projectId: input.projectId,
|
|
25
|
-
excludedFileIds: input.excludedFileIds,
|
|
26
|
-
readerPersonaId: input.readerPersonaId,
|
|
27
|
-
writerPersonaId: input.writerPersonaId
|
|
28
|
-
});
|
|
29
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
|
+
}
|
|
30
40
|
if (result.isFail()) {
|
|
31
41
|
await this.sendErrorToUser(identity.id, result.error.message);
|
|
32
42
|
return controller.response.error({
|
|
33
43
|
message: result.error.message
|
|
34
44
|
});
|
|
35
45
|
}
|
|
36
|
-
const compressed = await
|
|
46
|
+
const compressed = await compressJson(result.value.values);
|
|
37
47
|
const payload = compressed.toString("base64");
|
|
38
48
|
await this.sendContentToUser(identity.id, payload, result.value.telemetry);
|
|
39
49
|
return controller.response.done("Entry content generated successfully.");
|
|
@@ -1 +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 {
|
|
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"}
|
|
@@ -21,7 +21,7 @@ declare class CmsGenerateEntryContentUseCaseImpl implements CmsGenerateEntryCont
|
|
|
21
21
|
private modelToAst;
|
|
22
22
|
private toolPipelineRunner;
|
|
23
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(params: CmsGenerateEntryContentParams): Promise<Result<GenerateEntryContentResult
|
|
24
|
+
execute<TValues = Record<string, any>>(params: CmsGenerateEntryContentParams): Promise<Result<GenerateEntryContentResult<TValues>, Error>>;
|
|
25
25
|
}
|
|
26
26
|
export declare const CmsGenerateEntryContentUseCaseImplementation: typeof CmsGenerateEntryContentUseCaseImpl & {
|
|
27
27
|
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICmsGenerateEntryContentUseCase>;
|
|
@@ -7,7 +7,7 @@ import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/
|
|
|
7
7
|
import { ModelToAstConverter } from "@webiny/api-headless-cms/features/contentModel/ModelToAstConverter/index.js";
|
|
8
8
|
import { CmsModelToJsonSchemaConverter } from "@webiny/api-headless-cms/utils/contentModelToJsonSchema/index.js";
|
|
9
9
|
import { GetSettingsUseCase } from "../GetSettings/index.js";
|
|
10
|
-
import { AiPromptContextBuilder } from "../AiPromptContext/index.js";
|
|
10
|
+
import { AiPromptContextBuilder, formatAdditionalFilesContext } from "../AiPromptContext/index.js";
|
|
11
11
|
import { createReadProjectFileTool } from "../AiPromptContext/ReadProjectFileTool.js";
|
|
12
12
|
import { CmsGenerateEntryContentUseCase } from "./abstractions.js";
|
|
13
13
|
import { buildEntryPrompt } from "./buildPrompt.js";
|
|
@@ -46,7 +46,8 @@ class CmsGenerateEntryContentUseCaseImpl {
|
|
|
46
46
|
projectId: params.projectId,
|
|
47
47
|
readerPersonaId: params.readerPersonaId,
|
|
48
48
|
writerPersonaId: params.writerPersonaId,
|
|
49
|
-
excludedFileIds: params.excludedFileIds
|
|
49
|
+
excludedFileIds: params.excludedFileIds,
|
|
50
|
+
additionalFileIds: params.additionalFileIds
|
|
50
51
|
});
|
|
51
52
|
if (context.allProjectFiles.length > 0) {
|
|
52
53
|
const projectFileTool = createReadProjectFileTool(context.allProjectFiles, context.excludedFileIds);
|
|
@@ -80,7 +81,7 @@ class CmsGenerateEntryContentUseCaseImpl {
|
|
|
80
81
|
},
|
|
81
82
|
system,
|
|
82
83
|
toolChoice: "auto",
|
|
83
|
-
prompt: params.prompt,
|
|
84
|
+
prompt: params.prompt + formatAdditionalFilesContext(context.additionalFiles),
|
|
84
85
|
...Object.keys(sdkTools).length > 0 ? {
|
|
85
86
|
tools: sdkTools,
|
|
86
87
|
stopWhen: stepCountIs(20)
|
|
@@ -93,7 +94,6 @@ class CmsGenerateEntryContentUseCaseImpl {
|
|
|
93
94
|
resolved = await this.toolPipelineRunner.resolve(entry);
|
|
94
95
|
await injectDynamicZoneTypenames(resolved, modelAst, model.singularApiName);
|
|
95
96
|
}
|
|
96
|
-
const output = JSON.stringify(resolved);
|
|
97
97
|
const filesRead = new Set();
|
|
98
98
|
let toolCallsMade = 0;
|
|
99
99
|
for (const step of aiResult.steps)for (const call of step.toolCalls){
|
|
@@ -114,7 +114,7 @@ class CmsGenerateEntryContentUseCaseImpl {
|
|
|
114
114
|
imageTagsInPrompt: imageTags
|
|
115
115
|
};
|
|
116
116
|
return Result.ok({
|
|
117
|
-
|
|
117
|
+
values: resolved ?? {},
|
|
118
118
|
telemetry
|
|
119
119
|
});
|
|
120
120
|
} catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js","sources":["../../../../src/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.ts"],"sourcesContent":["import { stepCountIs } from \"ai\";\nimport { Result } from \"@webiny/feature/api\";\nimport { Ai } from \"@webiny/api-core/features/ai/index.js\";\nimport { AiSdkTools } from \"@webiny/api-core/features/ai/index.js\";\nimport { AiToolPipelineRunner } from \"@webiny/api-core/features/ai/index.js\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { ListTagsUseCase } from \"@webiny/api-file-manager/features/file/ListTags/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 { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\nimport { AiPromptContextBuilder } from \"~/api/features/AiPromptContext/index.js\";\nimport { createReadProjectFileTool } from \"~/api/features/AiPromptContext/ReadProjectFileTool.js\";\nimport { CmsGenerateEntryContentUseCase } from \"./abstractions.js\";\nimport type {\n CmsGenerateEntryContentParams,\n GenerateEntryContentResult,\n GenerateEntryContentTelemetry\n} from \"./abstractions.js\";\nimport { buildEntryPrompt } from \"./buildPrompt.js\";\nimport { LlmJsonResponse } from \"../WbGeneratePageContent/LlmJsonResponse.js\";\nimport { injectDynamicZoneTypenames } from \"./injectDynamicZoneTypenames.js\";\n\nclass CmsGenerateEntryContentUseCaseImpl implements CmsGenerateEntryContentUseCase.Interface {\n constructor(\n private promptContextBuilder: AiPromptContextBuilder.Interface,\n private getSettings: GetSettingsUseCase.Interface,\n private ai: Ai.Interface,\n private aiSdkTools: AiSdkTools.Interface,\n private encryption: Encryption.Interface,\n private listTags: ListTagsUseCase.Interface,\n private getModel: GetModelUseCase.Interface,\n private modelToAst: ModelToAstConverter.Interface,\n private toolPipelineRunner: AiToolPipelineRunner.Interface\n ) {}\n\n async execute(\n params: CmsGenerateEntryContentParams\n ): Promise<Result<GenerateEntryContentResult, Error>> {\n const settingsResult = await this.getSettings.execute();\n if (settingsResult.isFail()) {\n return Result.fail(new Error(\"Failed to load AI PowerUps settings.\"));\n }\n\n const settings = settingsResult.value;\n const firstProvider = settings.providers.presets[0];\n\n if (!firstProvider) {\n return Result.fail(\n new Error(\"No AI provider configured. Add a provider in AI Power Ups settings.\")\n );\n }\n\n const modelResult = await this.getModel.execute(params.modelId);\n if (modelResult.isFail()) {\n return Result.fail(new Error(`Content model \"${params.modelId}\" not found.`));\n }\n\n const model = modelResult.value;\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 const sdkTools = this.aiSdkTools.getToolSet();\n\n const context = await this.promptContextBuilder.execute({\n projectId: params.projectId,\n readerPersonaId: params.readerPersonaId,\n writerPersonaId: params.writerPersonaId,\n excludedFileIds: params.excludedFileIds\n });\n\n if (context.allProjectFiles.length > 0) {\n const projectFileTool = createReadProjectFileTool(\n context.allProjectFiles,\n context.excludedFileIds\n );\n Object.assign(sdkTools, projectFileTool);\n }\n\n const tagsResult = await this.listTags.execute({\n where: { type_startsWith: \"image/\" },\n limit: 100\n });\n const imageTags = tagsResult.isOk() ? tagsResult.value.map(t => t.tag) : [];\n\n const systemText =\n buildEntryPrompt(model.name, entrySchema, imageTags) + context.toString();\n\n const system = {\n role: \"system\" as const,\n content: systemText,\n providerOptions: {\n anthropic: {\n cacheControl: { type: \"ephemeral\" }\n }\n }\n };\n\n try {\n const aiResult = await this.ai.generateText({\n model: firstProvider.model,\n connection: {\n sdkName: firstProvider.model.split(\"/\")[0],\n apiKey\n },\n system,\n toolChoice: \"auto\",\n prompt: params.prompt,\n ...(Object.keys(sdkTools).length > 0\n ? { tools: sdkTools, stopWhen: stepCountIs(20) }\n : {})\n });\n\n const text =\n aiResult.text ||\n (aiResult.steps.filter(step => step.text.length > 0).pop()?.text ?? \"\");\n\n const entry = LlmJsonResponse.fromRawText(text).toArray().pop();\n\n let resolved: Record<string, any> | undefined;\n\n if (entry) {\n resolved = (await this.toolPipelineRunner.resolve(entry)) as Record<string, any>;\n await injectDynamicZoneTypenames(resolved, modelAst, model.singularApiName);\n }\n\n const output = JSON.stringify(resolved);\n\n const filesRead = new Set<string>();\n let toolCallsMade = 0;\n for (const step of aiResult.steps) {\n for (const call of step.toolCalls) {\n toolCallsMade++;\n if (call.toolName === \"read_project_file\") {\n const input = call.input as { fileId?: string };\n if (input.fileId) {\n filesRead.add(input.fileId);\n }\n }\n }\n }\n\n const telemetry: GenerateEntryContentTelemetry = {\n filesRead: [...filesRead],\n cacheHit: context.cacheHit,\n toolCallsMade,\n totalSteps: aiResult.steps.length,\n toolsAvailable: Object.keys(sdkTools),\n imageTagsInPrompt: imageTags\n };\n\n return Result.ok({ output, telemetry });\n } catch (error) {\n return Result.fail(\n new Error(\n `AI generation failed: ${error instanceof Error ? error.message : String(error)}`\n )\n );\n }\n }\n}\n\nexport const CmsGenerateEntryContentUseCaseImplementation =\n CmsGenerateEntryContentUseCase.createImplementation({\n implementation: CmsGenerateEntryContentUseCaseImpl,\n dependencies: [\n AiPromptContextBuilder,\n GetSettingsUseCase,\n Ai,\n AiSdkTools,\n Encryption,\n ListTagsUseCase,\n GetModelUseCase,\n ModelToAstConverter,\n AiToolPipelineRunner\n ]\n });\n"],"names":["CmsGenerateEntryContentUseCaseImpl","promptContextBuilder","getSettings","ai","aiSdkTools","encryption","listTags","getModel","modelToAst","toolPipelineRunner","params","settingsResult","Result","Error","settings","firstProvider","modelResult","model","modelAst","jsonSchemaConverter","CmsModelToJsonSchemaConverter","entrySchema","apiKey","sdkTools","context","projectFileTool","createReadProjectFileTool","Object","tagsResult","imageTags","t","systemText","buildEntryPrompt","system","aiResult","stepCountIs","text","step","entry","LlmJsonResponse","resolved","injectDynamicZoneTypenames","output","JSON","filesRead","Set","toolCallsMade","call","input","telemetry","error","String","CmsGenerateEntryContentUseCaseImplementation","CmsGenerateEntryContentUseCase","AiPromptContextBuilder","GetSettingsUseCase","Ai","AiSdkTools","Encryption","ListTagsUseCase","GetModelUseCase","ModelToAstConverter","AiToolPipelineRunner"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js","sources":["../../../../src/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.ts"],"sourcesContent":["import { stepCountIs } from \"ai\";\nimport { Result } from \"@webiny/feature/api\";\nimport { Ai } from \"@webiny/api-core/features/ai/index.js\";\nimport { AiSdkTools } from \"@webiny/api-core/features/ai/index.js\";\nimport { AiToolPipelineRunner } from \"@webiny/api-core/features/ai/index.js\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { ListTagsUseCase } from \"@webiny/api-file-manager/features/file/ListTags/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 { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\nimport {\n AiPromptContextBuilder,\n formatAdditionalFilesContext\n} from \"~/api/features/AiPromptContext/index.js\";\nimport { createReadProjectFileTool } from \"~/api/features/AiPromptContext/ReadProjectFileTool.js\";\nimport { CmsGenerateEntryContentUseCase } from \"./abstractions.js\";\nimport type {\n CmsGenerateEntryContentParams,\n GenerateEntryContentResult,\n GenerateEntryContentTelemetry\n} from \"./abstractions.js\";\nimport { buildEntryPrompt } from \"./buildPrompt.js\";\nimport { LlmJsonResponse } from \"../WbGeneratePageContent/LlmJsonResponse.js\";\nimport { injectDynamicZoneTypenames } from \"./injectDynamicZoneTypenames.js\";\n\nclass CmsGenerateEntryContentUseCaseImpl implements CmsGenerateEntryContentUseCase.Interface {\n constructor(\n private promptContextBuilder: AiPromptContextBuilder.Interface,\n private getSettings: GetSettingsUseCase.Interface,\n private ai: Ai.Interface,\n private aiSdkTools: AiSdkTools.Interface,\n private encryption: Encryption.Interface,\n private listTags: ListTagsUseCase.Interface,\n private getModel: GetModelUseCase.Interface,\n private modelToAst: ModelToAstConverter.Interface,\n private toolPipelineRunner: AiToolPipelineRunner.Interface\n ) {}\n\n async execute<TValues = Record<string, any>>(\n params: CmsGenerateEntryContentParams\n ): Promise<Result<GenerateEntryContentResult<TValues>, Error>> {\n const settingsResult = await this.getSettings.execute();\n if (settingsResult.isFail()) {\n return Result.fail(new Error(\"Failed to load AI PowerUps settings.\"));\n }\n\n const settings = settingsResult.value;\n const firstProvider = settings.providers.presets[0];\n\n if (!firstProvider) {\n return Result.fail(\n new Error(\"No AI provider configured. Add a provider in AI Power Ups settings.\")\n );\n }\n\n const modelResult = await this.getModel.execute(params.modelId);\n if (modelResult.isFail()) {\n return Result.fail(new Error(`Content model \"${params.modelId}\" not found.`));\n }\n\n const model = modelResult.value;\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 const sdkTools = this.aiSdkTools.getToolSet();\n\n const context = await this.promptContextBuilder.execute({\n projectId: params.projectId,\n readerPersonaId: params.readerPersonaId,\n writerPersonaId: params.writerPersonaId,\n excludedFileIds: params.excludedFileIds,\n additionalFileIds: params.additionalFileIds\n });\n\n if (context.allProjectFiles.length > 0) {\n const projectFileTool = createReadProjectFileTool(\n context.allProjectFiles,\n context.excludedFileIds\n );\n Object.assign(sdkTools, projectFileTool);\n }\n\n const tagsResult = await this.listTags.execute({\n where: { type_startsWith: \"image/\" },\n limit: 100\n });\n const imageTags = tagsResult.isOk() ? tagsResult.value.map(t => t.tag) : [];\n\n const systemText =\n buildEntryPrompt(model.name, entrySchema, imageTags) + context.toString();\n\n const system = {\n role: \"system\" as const,\n content: systemText,\n providerOptions: {\n anthropic: {\n cacheControl: { type: \"ephemeral\" }\n }\n }\n };\n\n try {\n const aiResult = await this.ai.generateText({\n model: firstProvider.model,\n connection: {\n sdkName: firstProvider.model.split(\"/\")[0],\n apiKey\n },\n system,\n toolChoice: \"auto\",\n prompt: params.prompt + formatAdditionalFilesContext(context.additionalFiles),\n ...(Object.keys(sdkTools).length > 0\n ? { tools: sdkTools, stopWhen: stepCountIs(20) }\n : {})\n });\n\n const text =\n aiResult.text ||\n (aiResult.steps.filter(step => step.text.length > 0).pop()?.text ?? \"\");\n\n const entry = LlmJsonResponse.fromRawText(text).toArray().pop();\n\n let resolved: Record<string, any> | undefined;\n\n if (entry) {\n resolved = (await this.toolPipelineRunner.resolve(entry)) as Record<string, any>;\n await injectDynamicZoneTypenames(resolved, modelAst, model.singularApiName);\n }\n\n const filesRead = new Set<string>();\n let toolCallsMade = 0;\n for (const step of aiResult.steps) {\n for (const call of step.toolCalls) {\n toolCallsMade++;\n if (call.toolName === \"read_project_file\") {\n const input = call.input as { fileId?: string };\n if (input.fileId) {\n filesRead.add(input.fileId);\n }\n }\n }\n }\n\n const telemetry: GenerateEntryContentTelemetry = {\n filesRead: [...filesRead],\n cacheHit: context.cacheHit,\n toolCallsMade,\n totalSteps: aiResult.steps.length,\n toolsAvailable: Object.keys(sdkTools),\n imageTagsInPrompt: imageTags\n };\n\n // Boundary cast: the AI output is dynamic JSON, so this is the one honest point\n // where we hand the resolved values to the caller's chosen `TValues` shape.\n return Result.ok({ values: (resolved ?? {}) as TValues, telemetry });\n } catch (error) {\n return Result.fail(\n new Error(\n `AI generation failed: ${error instanceof Error ? error.message : String(error)}`\n )\n );\n }\n }\n}\n\nexport const CmsGenerateEntryContentUseCaseImplementation =\n CmsGenerateEntryContentUseCase.createImplementation({\n implementation: CmsGenerateEntryContentUseCaseImpl,\n dependencies: [\n AiPromptContextBuilder,\n GetSettingsUseCase,\n Ai,\n AiSdkTools,\n Encryption,\n ListTagsUseCase,\n GetModelUseCase,\n ModelToAstConverter,\n AiToolPipelineRunner\n ]\n });\n"],"names":["CmsGenerateEntryContentUseCaseImpl","promptContextBuilder","getSettings","ai","aiSdkTools","encryption","listTags","getModel","modelToAst","toolPipelineRunner","params","settingsResult","Result","Error","settings","firstProvider","modelResult","model","modelAst","jsonSchemaConverter","CmsModelToJsonSchemaConverter","entrySchema","apiKey","sdkTools","context","projectFileTool","createReadProjectFileTool","Object","tagsResult","imageTags","t","systemText","buildEntryPrompt","system","aiResult","formatAdditionalFilesContext","stepCountIs","text","step","entry","LlmJsonResponse","resolved","injectDynamicZoneTypenames","filesRead","Set","toolCallsMade","call","input","telemetry","error","String","CmsGenerateEntryContentUseCaseImplementation","CmsGenerateEntryContentUseCase","AiPromptContextBuilder","GetSettingsUseCase","Ai","AiSdkTools","Encryption","ListTagsUseCase","GetModelUseCase","ModelToAstConverter","AiToolPipelineRunner"],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ export interface CmsGenerateEntryContentParams {
|
|
|
6
6
|
excludedFileIds?: string[] | null;
|
|
7
7
|
readerPersonaId?: string | null;
|
|
8
8
|
writerPersonaId?: string | null;
|
|
9
|
+
additionalFileIds?: string[] | null;
|
|
9
10
|
}
|
|
10
11
|
export interface GenerateEntryContentTelemetry {
|
|
11
12
|
filesRead: string[];
|
|
@@ -15,12 +16,18 @@ export interface GenerateEntryContentTelemetry {
|
|
|
15
16
|
toolsAvailable: string[];
|
|
16
17
|
imageTagsInPrompt: string[];
|
|
17
18
|
}
|
|
18
|
-
export interface GenerateEntryContentResult {
|
|
19
|
-
|
|
19
|
+
export interface GenerateEntryContentResult<TValues = Record<string, any>> {
|
|
20
|
+
/**
|
|
21
|
+
* The generated entry values, keyed by fieldId. Callers that consume the result
|
|
22
|
+
* directly (e.g. a bulk action) can read fields straight off this object; transport
|
|
23
|
+
* edges (the background task / websocket stream) serialize it themselves. Pass a type
|
|
24
|
+
* argument to `execute` to shape this (e.g. `execute<{ aiSummary?: string }>`).
|
|
25
|
+
*/
|
|
26
|
+
values: TValues;
|
|
20
27
|
telemetry: GenerateEntryContentTelemetry;
|
|
21
28
|
}
|
|
22
29
|
export interface ICmsGenerateEntryContentUseCase {
|
|
23
|
-
execute(params: CmsGenerateEntryContentParams): Promise<Result<GenerateEntryContentResult
|
|
30
|
+
execute<TValues = Record<string, any>>(params: CmsGenerateEntryContentParams): Promise<Result<GenerateEntryContentResult<TValues>, Error>>;
|
|
24
31
|
}
|
|
25
32
|
export declare const CmsGenerateEntryContentUseCase: import("@webiny/di").Abstraction<ICmsGenerateEntryContentUseCase>;
|
|
26
33
|
export declare namespace CmsGenerateEntryContentUseCase {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/CmsGenerateEntryContent/abstractions.js","sources":["../../../../src/api/features/CmsGenerateEntryContent/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\n\nexport interface CmsGenerateEntryContentParams {\n prompt: string;\n modelId: string;\n projectId?: string | null;\n excludedFileIds?: string[] | null;\n readerPersonaId?: string | null;\n writerPersonaId?: string | null;\n}\n\nexport interface GenerateEntryContentTelemetry {\n filesRead: string[];\n cacheHit: boolean;\n toolCallsMade: number;\n totalSteps: number;\n toolsAvailable: string[];\n imageTagsInPrompt: string[];\n}\n\nexport interface GenerateEntryContentResult {\n
|
|
1
|
+
{"version":3,"file":"api/features/CmsGenerateEntryContent/abstractions.js","sources":["../../../../src/api/features/CmsGenerateEntryContent/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\n\nexport interface CmsGenerateEntryContentParams {\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\nexport interface GenerateEntryContentTelemetry {\n filesRead: string[];\n cacheHit: boolean;\n toolCallsMade: number;\n totalSteps: number;\n toolsAvailable: string[];\n imageTagsInPrompt: string[];\n}\n\nexport interface GenerateEntryContentResult<TValues = Record<string, any>> {\n /**\n * The generated entry values, keyed by fieldId. Callers that consume the result\n * directly (e.g. a bulk action) can read fields straight off this object; transport\n * edges (the background task / websocket stream) serialize it themselves. Pass a type\n * argument to `execute` to shape this (e.g. `execute<{ aiSummary?: string }>`).\n */\n values: TValues;\n telemetry: GenerateEntryContentTelemetry;\n}\n\nexport interface ICmsGenerateEntryContentUseCase {\n execute<TValues = Record<string, any>>(\n params: CmsGenerateEntryContentParams\n ): Promise<Result<GenerateEntryContentResult<TValues>, Error>>;\n}\n\nexport const CmsGenerateEntryContentUseCase = createAbstraction<ICmsGenerateEntryContentUseCase>(\n \"AiPowerUpsCmsGenerateEntryContentUseCase\"\n);\n\nexport namespace CmsGenerateEntryContentUseCase {\n export type Interface = ICmsGenerateEntryContentUseCase;\n export type Params = CmsGenerateEntryContentParams;\n}\n"],"names":["CmsGenerateEntryContentUseCase","createAbstraction"],"mappings":";AAsCO,MAAMA,iCAAiCC,kBAC1C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IAiPowerUpsSettings } from "
|
|
1
|
+
import type { IAiPowerUpsSettings } from "../../types.js";
|
|
2
2
|
export interface ProviderPreset {
|
|
3
3
|
id: string;
|
|
4
4
|
name: string;
|
|
@@ -8,7 +8,7 @@ export interface ProviderPreset {
|
|
|
8
8
|
apiKeyMasked: string;
|
|
9
9
|
apiKeyEncrypted: string;
|
|
10
10
|
}
|
|
11
|
-
declare module "
|
|
11
|
+
declare module "../../types.js" {
|
|
12
12
|
interface IAiPowerUpsSettings {
|
|
13
13
|
providers: {
|
|
14
14
|
presets: ProviderPreset[];
|
|
@@ -11,6 +11,7 @@ export interface IWbGeneratePageContentTaskInput {
|
|
|
11
11
|
excludedFileIds?: string[] | null;
|
|
12
12
|
readerPersonaId?: string | null;
|
|
13
13
|
writerPersonaId?: string | null;
|
|
14
|
+
additionalFileIds?: string[] | null;
|
|
14
15
|
}
|
|
15
16
|
declare class WbGeneratePageContentTaskImpl implements TaskDefinition.Interface<IWbGeneratePageContentTaskInput> {
|
|
16
17
|
private identityContext;
|
|
@@ -18,16 +18,26 @@ class WbGeneratePageContentTaskImpl {
|
|
|
18
18
|
}
|
|
19
19
|
async run({ input, controller }) {
|
|
20
20
|
if (controller.runtime.isAborted()) return controller.response.aborted();
|
|
21
|
-
const result = await this.generatePageContent.execute({
|
|
22
|
-
prompt: input.prompt,
|
|
23
|
-
components: input.components,
|
|
24
|
-
tools: input.tools,
|
|
25
|
-
projectId: input.projectId,
|
|
26
|
-
excludedFileIds: input.excludedFileIds,
|
|
27
|
-
readerPersonaId: input.readerPersonaId,
|
|
28
|
-
writerPersonaId: input.writerPersonaId
|
|
29
|
-
});
|
|
30
21
|
const identity = this.identityContext.getIdentity();
|
|
22
|
+
let result;
|
|
23
|
+
try {
|
|
24
|
+
result = await this.generatePageContent.execute({
|
|
25
|
+
prompt: input.prompt,
|
|
26
|
+
components: input.components,
|
|
27
|
+
tools: input.tools,
|
|
28
|
+
projectId: input.projectId,
|
|
29
|
+
excludedFileIds: input.excludedFileIds,
|
|
30
|
+
readerPersonaId: input.readerPersonaId,
|
|
31
|
+
writerPersonaId: input.writerPersonaId,
|
|
32
|
+
additionalFileIds: input.additionalFileIds
|
|
33
|
+
});
|
|
34
|
+
} catch (err) {
|
|
35
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
36
|
+
await this.sendErrorToUser(identity.id, message);
|
|
37
|
+
return controller.response.error({
|
|
38
|
+
message
|
|
39
|
+
});
|
|
40
|
+
}
|
|
31
41
|
if (result.isFail()) {
|
|
32
42
|
await this.sendErrorToUser(identity.id, result.error.message);
|
|
33
43
|
return controller.response.error({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/WbGeneratePageContent/WbGeneratePageContentTask.js","sources":["../../../../src/api/features/WbGeneratePageContent/WbGeneratePageContentTask.ts"],"sourcesContent":["import { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { WebsocketsSendToIdentityUseCase } from \"@webiny/api-websockets/features/SendToIdentity/abstractions.js\";\nimport { compress } from \"@webiny/utils/features/compression/legacy/gzip.js\";\nimport { WbGeneratePageContentUseCase } from \"~/api/features/WbGeneratePageContent/index.js\";\nimport type { GenerationTelemetry } from \"~/api/features/WbGeneratePageContent/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/exports/api/security.js\";\n\nexport const WB_GENERATE_PAGE_CONTENT_TASK_ID = \"aiPowerUpsGeneratePageContent\";\n\nexport interface IWbGeneratePageContentTaskInput {\n prompt: string;\n components: unknown;\n tools: unknown;\n projectId?: string | null;\n excludedFileIds?: string[] | null;\n readerPersonaId?: string | null;\n writerPersonaId?: string | null;\n}\n\nclass WbGeneratePageContentTaskImpl implements TaskDefinition.Interface<IWbGeneratePageContentTaskInput> {\n id = WB_GENERATE_PAGE_CONTENT_TASK_ID;\n title = \"AI Power-Ups - Generate Page Content\";\n description = \"Generates page 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 generatePageContent: WbGeneratePageContentUseCase.Interface,\n private sendToIdentity: WebsocketsSendToIdentityUseCase.Interface\n ) {}\n\n async run({\n input,\n controller\n }: TaskDefinition.RunParams<IWbGeneratePageContentTaskInput>): Promise<\n TaskDefinition.Result<IWbGeneratePageContentTaskInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n const result = await this.generatePageContent.execute({\n
|
|
1
|
+
{"version":3,"file":"api/features/WbGeneratePageContent/WbGeneratePageContentTask.js","sources":["../../../../src/api/features/WbGeneratePageContent/WbGeneratePageContentTask.ts"],"sourcesContent":["import { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { WebsocketsSendToIdentityUseCase } from \"@webiny/api-websockets/features/SendToIdentity/abstractions.js\";\nimport { compress } from \"@webiny/utils/features/compression/legacy/gzip.js\";\nimport { WbGeneratePageContentUseCase } from \"~/api/features/WbGeneratePageContent/index.js\";\nimport type { GenerationTelemetry } from \"~/api/features/WbGeneratePageContent/abstractions.js\";\nimport { IdentityContext } from \"@webiny/api-core/exports/api/security.js\";\n\nexport const WB_GENERATE_PAGE_CONTENT_TASK_ID = \"aiPowerUpsGeneratePageContent\";\n\nexport interface IWbGeneratePageContentTaskInput {\n prompt: string;\n components: unknown;\n tools: unknown;\n projectId?: string | null;\n excludedFileIds?: string[] | null;\n readerPersonaId?: string | null;\n writerPersonaId?: string | null;\n additionalFileIds?: string[] | null;\n}\n\nclass WbGeneratePageContentTaskImpl implements TaskDefinition.Interface<IWbGeneratePageContentTaskInput> {\n id = WB_GENERATE_PAGE_CONTENT_TASK_ID;\n title = \"AI Power-Ups - Generate Page Content\";\n description = \"Generates page 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 generatePageContent: WbGeneratePageContentUseCase.Interface,\n private sendToIdentity: WebsocketsSendToIdentityUseCase.Interface\n ) {}\n\n async run({\n input,\n controller\n }: TaskDefinition.RunParams<IWbGeneratePageContentTaskInput>): Promise<\n TaskDefinition.Result<IWbGeneratePageContentTaskInput>\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.generatePageContent.execute({\n prompt: input.prompt,\n components: input.components,\n tools: input.tools,\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 const compressed = await compress(result.value.output);\n const payload = compressed.toString(\"base64\");\n\n await this.sendContentToUser(identity.id, payload, result.value.telemetry);\n\n return controller.response.done(\"Page content generated successfully.\");\n }\n\n private async sendContentToUser(\n identityId: string,\n payload: string,\n telemetry: GenerationTelemetry\n ) {\n await this.sendToIdentity.execute(\n { id: identityId },\n {\n action: \"aiPowerUps.generatePageContent.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.generatePageContent.error\",\n data: {\n message\n }\n }\n );\n }\n}\n\nexport const WbGeneratePageContentTask = TaskDefinition.createImplementation({\n implementation: WbGeneratePageContentTaskImpl,\n dependencies: [IdentityContext, WbGeneratePageContentUseCase, WebsocketsSendToIdentityUseCase]\n});\n"],"names":["WB_GENERATE_PAGE_CONTENT_TASK_ID","WbGeneratePageContentTaskImpl","identityContext","generatePageContent","sendToIdentity","input","controller","identity","result","err","message","Error","String","compressed","compress","payload","identityId","telemetry","WbGeneratePageContentTask","TaskDefinition","IdentityContext","WbGeneratePageContentUseCase","WebsocketsSendToIdentityUseCase"],"mappings":";;;;;AAOO,MAAMA,mCAAmC;AAahD,MAAMC;IAQF,YACYC,eAA0C,EAC1CC,mBAA2D,EAC3DC,cAAyD,CACnE;aAHUF,eAAe,GAAfA;aACAC,mBAAmB,GAAnBA;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,EAC8C,EAE1D;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,mBAAmB,CAAC,OAAO,CAAC;gBAC5C,QAAQH,MAAM,MAAM;gBACpB,YAAYA,MAAM,UAAU;gBAC5B,OAAOA,MAAM,KAAK;gBAClB,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;QAEA,MAAMK,aAAa,MAAMC,SAASN,OAAO,KAAK,CAAC,MAAM;QACrD,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,SAA8B,EAChC;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,4BAA4BC,eAAe,oBAAoB,CAAC;IACzE,gBAAgBlB;IAChB,cAAc;QAACmB;QAAiBC;QAA8BC;KAAgC;AAClG"}
|
|
@@ -4,7 +4,7 @@ import { Ai, AiSdkTools } from "@webiny/api-core/features/ai/index.js";
|
|
|
4
4
|
import { Encryption } from "@webiny/api-core/features/encryption/index.js";
|
|
5
5
|
import { ListTagsUseCase } from "@webiny/api-file-manager/features/file/ListTags/index.js";
|
|
6
6
|
import { GetSettingsUseCase } from "../GetSettings/index.js";
|
|
7
|
-
import { AiPromptContextBuilder } from "../AiPromptContext/index.js";
|
|
7
|
+
import { AiPromptContextBuilder, formatAdditionalFilesContext } from "../AiPromptContext/index.js";
|
|
8
8
|
import { createReadProjectFileTool } from "../AiPromptContext/ReadProjectFileTool.js";
|
|
9
9
|
import { WbGeneratePageContentUseCase } from "./abstractions.js";
|
|
10
10
|
import { buildDomainPrompt } from "./buildPrompt.js";
|
|
@@ -31,7 +31,8 @@ class WbGeneratePageContentUseCaseImpl {
|
|
|
31
31
|
projectId: params.projectId,
|
|
32
32
|
readerPersonaId: params.readerPersonaId,
|
|
33
33
|
writerPersonaId: params.writerPersonaId,
|
|
34
|
-
excludedFileIds: params.excludedFileIds
|
|
34
|
+
excludedFileIds: params.excludedFileIds,
|
|
35
|
+
additionalFileIds: params.additionalFileIds
|
|
35
36
|
});
|
|
36
37
|
if (context.allProjectFiles.length > 0) {
|
|
37
38
|
const projectFileTool = createReadProjectFileTool(context.allProjectFiles, context.excludedFileIds);
|
|
@@ -66,7 +67,7 @@ class WbGeneratePageContentUseCaseImpl {
|
|
|
66
67
|
},
|
|
67
68
|
system,
|
|
68
69
|
toolChoice: "auto",
|
|
69
|
-
prompt: params.prompt,
|
|
70
|
+
prompt: params.prompt + formatAdditionalFilesContext(context.additionalFiles),
|
|
70
71
|
...Object.keys(sdkTools).length > 0 ? {
|
|
71
72
|
tools: sdkTools,
|
|
72
73
|
stopWhen: stepCountIs(20)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js","sources":["../../../../src/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.ts"],"sourcesContent":["import { stepCountIs } from \"ai\";\nimport { Result } from \"@webiny/feature/api\";\nimport { Ai } from \"@webiny/api-core/features/ai/index.js\";\nimport { AiSdkTools } from \"@webiny/api-core/features/ai/index.js\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { ListTagsUseCase } from \"@webiny/api-file-manager/features/file/ListTags/index.js\";\nimport { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js","sources":["../../../../src/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.ts"],"sourcesContent":["import { stepCountIs } from \"ai\";\nimport { Result } from \"@webiny/feature/api\";\nimport { Ai } from \"@webiny/api-core/features/ai/index.js\";\nimport { AiSdkTools } from \"@webiny/api-core/features/ai/index.js\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { ListTagsUseCase } from \"@webiny/api-file-manager/features/file/ListTags/index.js\";\nimport { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\nimport {\n AiPromptContextBuilder,\n formatAdditionalFilesContext\n} from \"~/api/features/AiPromptContext/index.js\";\nimport { createReadProjectFileTool } from \"~/api/features/AiPromptContext/ReadProjectFileTool.js\";\nimport { WbGeneratePageContentUseCase } from \"./abstractions.js\";\nimport type {\n WbGeneratePageContentParams,\n GeneratePageContentResult,\n GenerationTelemetry\n} from \"./abstractions.js\";\nimport { buildDomainPrompt } from \"./buildPrompt.js\";\nimport { LlmJsonResponse } from \"./LlmJsonResponse.js\";\nimport { ComponentFilter } from \"./ComponentFilter.js\";\n\nclass WbGeneratePageContentUseCaseImpl implements WbGeneratePageContentUseCase.Interface {\n constructor(\n private promptContextBuilder: AiPromptContextBuilder.Interface,\n private getSettings: GetSettingsUseCase.Interface,\n private ai: Ai.Interface,\n private aiSdkTools: AiSdkTools.Interface,\n private encryption: Encryption.Interface,\n private listTags: ListTagsUseCase.Interface\n ) {}\n\n async execute(\n params: WbGeneratePageContentParams\n ): Promise<Result<GeneratePageContentResult, Error>> {\n const settingsResult = await this.getSettings.execute();\n if (settingsResult.isFail()) {\n return Result.fail(new Error(\"Failed to load AI PowerUps settings.\"));\n }\n\n const settings = settingsResult.value;\n const firstProvider = settings.providers.presets[0];\n\n if (!firstProvider) {\n return Result.fail(\n new Error(\"No AI provider configured. Add a provider in AI Power Ups settings.\")\n );\n }\n\n const apiKey = await this.encryption.decrypt(firstProvider.apiKeyEncrypted);\n\n const sdkTools = this.aiSdkTools.getToolSet();\n\n const context = await this.promptContextBuilder.execute({\n projectId: params.projectId,\n readerPersonaId: params.readerPersonaId,\n writerPersonaId: params.writerPersonaId,\n excludedFileIds: params.excludedFileIds,\n additionalFileIds: params.additionalFileIds\n });\n\n if (context.allProjectFiles.length > 0) {\n const projectFileTool = createReadProjectFileTool(\n context.allProjectFiles,\n context.excludedFileIds\n );\n Object.assign(sdkTools, projectFileTool);\n }\n\n // Fetch image tags so the prompt can enumerate what's queryable; without\n // this the model invents tag/IDs instead of calling listImagesByTag.\n const tagsResult = await this.listTags.execute({\n where: { type_startsWith: \"image/\" },\n limit: 100\n });\n const imageTags = tagsResult.isOk() ? tagsResult.value.map(t => t.tag) : [];\n\n const components = params.components as Array<{ name: string }>;\n const systemText =\n buildDomainPrompt(components, params.tools, imageTags) + context.toString();\n\n const system = {\n role: \"system\" as const,\n content: systemText,\n providerOptions: {\n anthropic: {\n cacheControl: { type: \"ephemeral\" }\n }\n }\n };\n\n try {\n const aiResult = await this.ai.generateText({\n model: firstProvider.model,\n connection: {\n sdkName: firstProvider.model.split(\"/\")[0],\n apiKey\n },\n system,\n toolChoice: \"auto\",\n prompt: params.prompt + formatAdditionalFilesContext(context.additionalFiles),\n ...(Object.keys(sdkTools).length > 0\n ? { tools: sdkTools, stopWhen: stepCountIs(20) }\n : {})\n });\n\n const text =\n aiResult.text ||\n (aiResult.steps.filter(step => step.text.length > 0).pop()?.text ?? \"\");\n\n const elements = LlmJsonResponse.fromRawText(text).toArray();\n const componentFilter = new ComponentFilter(components);\n const output = JSON.stringify(componentFilter.filter(elements));\n\n const filesRead = new Set<string>();\n let toolCallsMade = 0;\n for (const step of aiResult.steps) {\n for (const call of step.toolCalls) {\n toolCallsMade++;\n if (call.toolName === \"read_project_file\") {\n const input = call.input as { fileId?: string };\n if (input.fileId) {\n filesRead.add(input.fileId);\n }\n }\n }\n }\n\n const telemetry: GenerationTelemetry = {\n filesRead: [...filesRead],\n cacheHit: context.cacheHit,\n toolCallsMade,\n totalSteps: aiResult.steps.length,\n toolsAvailable: Object.keys(sdkTools),\n imageTagsInPrompt: imageTags\n };\n\n return Result.ok({ output, telemetry });\n } catch (error) {\n return Result.fail(\n new Error(\n `AI generation failed: ${error instanceof Error ? error.message : String(error)}`\n )\n );\n }\n }\n}\n\nexport const WbGeneratePageContentUseCaseImplementation =\n WbGeneratePageContentUseCase.createImplementation({\n implementation: WbGeneratePageContentUseCaseImpl,\n dependencies: [\n AiPromptContextBuilder,\n GetSettingsUseCase,\n Ai,\n AiSdkTools,\n Encryption,\n ListTagsUseCase\n ]\n });\n"],"names":["WbGeneratePageContentUseCaseImpl","promptContextBuilder","getSettings","ai","aiSdkTools","encryption","listTags","params","settingsResult","Result","Error","settings","firstProvider","apiKey","sdkTools","context","projectFileTool","createReadProjectFileTool","Object","tagsResult","imageTags","t","components","systemText","buildDomainPrompt","system","aiResult","formatAdditionalFilesContext","stepCountIs","text","step","elements","LlmJsonResponse","componentFilter","ComponentFilter","output","JSON","filesRead","Set","toolCallsMade","call","input","telemetry","error","String","WbGeneratePageContentUseCaseImplementation","WbGeneratePageContentUseCase","AiPromptContextBuilder","GetSettingsUseCase","Ai","AiSdkTools","Encryption","ListTagsUseCase"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/WbGeneratePageContent/abstractions.js","sources":["../../../../src/api/features/WbGeneratePageContent/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\n\nexport interface WbGeneratePageContentParams {\n prompt: string;\n components: unknown;\n tools: unknown;\n projectId?: string | null;\n excludedFileIds?: string[] | null;\n readerPersonaId?: string | null;\n writerPersonaId?: string | null;\n}\n\nexport interface GenerationTelemetry {\n filesRead: string[];\n cacheHit: boolean;\n toolCallsMade: number;\n totalSteps: number;\n toolsAvailable: string[];\n imageTagsInPrompt: string[];\n}\n\nexport interface GeneratePageContentResult {\n output: string;\n telemetry: GenerationTelemetry;\n}\n\nexport interface IWbGeneratePageContentUseCase {\n execute(params: WbGeneratePageContentParams): Promise<Result<GeneratePageContentResult, Error>>;\n}\n\nexport const WbGeneratePageContentUseCase = createAbstraction<IWbGeneratePageContentUseCase>(\n \"AiPowerUpsWbGeneratePageContentUseCase\"\n);\n\nexport namespace WbGeneratePageContentUseCase {\n export type Interface = IWbGeneratePageContentUseCase;\n export type Params = WbGeneratePageContentParams;\n}\n"],"names":["WbGeneratePageContentUseCase","createAbstraction"],"mappings":";
|
|
1
|
+
{"version":3,"file":"api/features/WbGeneratePageContent/abstractions.js","sources":["../../../../src/api/features/WbGeneratePageContent/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\n\nexport interface WbGeneratePageContentParams {\n prompt: string;\n components: unknown;\n tools: unknown;\n projectId?: string | null;\n excludedFileIds?: string[] | null;\n readerPersonaId?: string | null;\n writerPersonaId?: string | null;\n additionalFileIds?: string[] | null;\n}\n\nexport interface GenerationTelemetry {\n filesRead: string[];\n cacheHit: boolean;\n toolCallsMade: number;\n totalSteps: number;\n toolsAvailable: string[];\n imageTagsInPrompt: string[];\n}\n\nexport interface GeneratePageContentResult {\n output: string;\n telemetry: GenerationTelemetry;\n}\n\nexport interface IWbGeneratePageContentUseCase {\n execute(params: WbGeneratePageContentParams): Promise<Result<GeneratePageContentResult, Error>>;\n}\n\nexport const WbGeneratePageContentUseCase = createAbstraction<IWbGeneratePageContentUseCase>(\n \"AiPowerUpsWbGeneratePageContentUseCase\"\n);\n\nexport namespace WbGeneratePageContentUseCase {\n export type Interface = IWbGeneratePageContentUseCase;\n export type Params = WbGeneratePageContentParams;\n}\n"],"names":["WbGeneratePageContentUseCase","createAbstraction"],"mappings":";AA+BO,MAAMA,+BAA+BC,kBACxC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LexicalParser as Abstraction } from "./abstractions/LexicalParser.js";
|
|
2
|
+
declare class LexicalParserImpl implements Abstraction.Interface {
|
|
3
|
+
private WindowClass;
|
|
4
|
+
parse(html: string): Promise<Record<string, unknown> | null>;
|
|
5
|
+
private loadWindow;
|
|
6
|
+
}
|
|
7
|
+
export declare const LexicalParser: typeof LexicalParserImpl & {
|
|
8
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions/LexicalParser.js").ILexicalParser>;
|
|
9
|
+
};
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createHtmlToLexicalParser } from "@webiny/lexical-converter";
|
|
2
|
+
import { LexicalParser } from "./abstractions/LexicalParser.js";
|
|
3
|
+
const parser = createHtmlToLexicalParser();
|
|
4
|
+
class LexicalParserImpl {
|
|
5
|
+
async parse(html) {
|
|
6
|
+
try {
|
|
7
|
+
const Window = await this.loadWindow();
|
|
8
|
+
const window = new Window();
|
|
9
|
+
const document = window.document;
|
|
10
|
+
document.body.innerHTML = html;
|
|
11
|
+
const result = parser(document);
|
|
12
|
+
await window.happyDOM.close();
|
|
13
|
+
return result;
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error("[LexicalParser] Failed to parse HTML to Lexical state:", error);
|
|
16
|
+
console.error("[LexicalParser] Input HTML:", html);
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async loadWindow() {
|
|
21
|
+
if (!this.WindowClass) {
|
|
22
|
+
const { Window } = await import("happy-dom");
|
|
23
|
+
this.WindowClass = Window;
|
|
24
|
+
}
|
|
25
|
+
return this.WindowClass;
|
|
26
|
+
}
|
|
27
|
+
constructor(){
|
|
28
|
+
this.WindowClass = null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const LexicalParser_LexicalParser = LexicalParser.createImplementation({
|
|
32
|
+
implementation: LexicalParserImpl,
|
|
33
|
+
dependencies: []
|
|
34
|
+
});
|
|
35
|
+
export { LexicalParser_LexicalParser as LexicalParser };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=LexicalParser.js.map
|