@webiny/ai-powerups 6.5.1 → 6.5.2-beta.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.
Files changed (121) hide show
  1. package/admin/Extension.js +16 -2
  2. package/admin/Extension.js.map +1 -1
  3. package/admin/features/permissions/abstractions.d.ts +17 -0
  4. package/admin/features/permissions/abstractions.js +6 -0
  5. package/admin/features/permissions/abstractions.js.map +1 -0
  6. package/admin/features/permissions/feature.d.ts +14 -0
  7. package/admin/features/permissions/feature.js +7 -0
  8. package/admin/features/permissions/feature.js.map +1 -0
  9. package/admin/features/permissions/index.d.ts +2 -0
  10. package/admin/features/permissions/index.js +2 -0
  11. package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.d.ts +2 -2
  12. package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js +2 -2
  13. package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js.map +1 -1
  14. package/admin/presentation/CmsCompareEntryRevisions/feature.js +2 -2
  15. package/admin/presentation/CmsCompareEntryRevisions/feature.js.map +1 -1
  16. package/admin/presentation/security/HasPermission.d.ts +10 -0
  17. package/admin/presentation/security/HasPermission.js +6 -0
  18. package/admin/presentation/security/HasPermission.js.map +1 -0
  19. package/api/Extension.js +6 -0
  20. package/api/Extension.js.map +1 -1
  21. package/api/features/Capabilities/ListAiCapabilitiesUseCase.d.ts +7 -4
  22. package/api/features/Capabilities/ListAiCapabilitiesUseCase.js +11 -5
  23. package/api/features/Capabilities/ListAiCapabilitiesUseCase.js.map +1 -1
  24. package/api/features/Capabilities/ResolveAiCapabilityUseCase.d.ts +4 -6
  25. package/api/features/Capabilities/ResolveAiCapabilityUseCase.js +12 -11
  26. package/api/features/Capabilities/ResolveAiCapabilityUseCase.js.map +1 -1
  27. package/api/features/Capabilities/abstractions.d.ts +1 -1
  28. package/api/features/Capabilities/abstractions.js.map +1 -1
  29. package/api/features/Capabilities/feature.js +4 -4
  30. package/api/features/Capabilities/feature.js.map +1 -1
  31. package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.d.ts +5 -3
  32. package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.js +11 -6
  33. package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.js.map +1 -1
  34. package/api/features/CmsCompareEntryRevisions/feature.js +2 -2
  35. package/api/features/CmsCompareEntryRevisions/feature.js.map +1 -1
  36. package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.d.ts +2 -2
  37. package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js +3 -3
  38. package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js.map +1 -1
  39. package/api/features/CmsGenerateEntryContent/QueueCmsGenerateEntryContentUseCase.d.ts +19 -0
  40. package/api/features/CmsGenerateEntryContent/QueueCmsGenerateEntryContentUseCase.js +61 -0
  41. package/api/features/CmsGenerateEntryContent/QueueCmsGenerateEntryContentUseCase.js.map +1 -0
  42. package/api/features/CmsGenerateEntryContent/abstractions.d.ts +14 -0
  43. package/api/features/CmsGenerateEntryContent/abstractions.js +2 -1
  44. package/api/features/CmsGenerateEntryContent/abstractions.js.map +1 -1
  45. package/api/features/CmsGenerateEntryContent/feature.js +4 -2
  46. package/api/features/CmsGenerateEntryContent/feature.js.map +1 -1
  47. package/api/features/CmsGenerateEntryContent/index.d.ts +1 -1
  48. package/api/features/CmsGenerateEntryContent/index.js +1 -1
  49. package/api/features/Connections/ConnectionsGraphQLMapper.js +1 -1
  50. package/api/features/Connections/ConnectionsGraphQLMapper.js.map +1 -1
  51. package/api/features/GetDecryptedSettings/GetDecryptedSettingsUseCase.d.ts +17 -0
  52. package/api/features/GetDecryptedSettings/GetDecryptedSettingsUseCase.js +41 -0
  53. package/api/features/GetDecryptedSettings/GetDecryptedSettingsUseCase.js.map +1 -0
  54. package/api/features/GetDecryptedSettings/abstractions.d.ts +13 -0
  55. package/api/features/GetDecryptedSettings/abstractions.js +5 -0
  56. package/api/features/GetDecryptedSettings/abstractions.js.map +1 -0
  57. package/api/features/GetDecryptedSettings/feature.d.ts +4 -0
  58. package/api/features/GetDecryptedSettings/feature.js +11 -0
  59. package/api/features/GetDecryptedSettings/feature.js.map +1 -0
  60. package/api/features/GetDecryptedSettings/index.d.ts +2 -0
  61. package/api/features/GetDecryptedSettings/index.js +2 -0
  62. package/api/features/GetSettings/GetSettingsRepository.d.ts +2 -2
  63. package/api/features/GetSettings/GetSettingsRepository.js +2 -2
  64. package/api/features/GetSettings/GetSettingsRepository.js.map +1 -1
  65. package/api/features/GetSettings/GetSettingsUseCase.d.ts +15 -4
  66. package/api/features/GetSettings/GetSettingsUseCase.js +34 -5
  67. package/api/features/GetSettings/GetSettingsUseCase.js.map +1 -1
  68. package/api/features/GetSettings/abstractions.d.ts +1 -1
  69. package/api/features/GetSettings/abstractions.js.map +1 -1
  70. package/api/features/GetSettings/feature.js +4 -4
  71. package/api/features/GetSettings/feature.js.map +1 -1
  72. package/api/features/ListModels/ListModelsUseCase.d.ts +15 -0
  73. package/api/features/ListModels/ListModelsUseCase.js +25 -0
  74. package/api/features/ListModels/ListModelsUseCase.js.map +1 -0
  75. package/api/features/ListModels/abstractions.d.ts +10 -0
  76. package/api/features/ListModels/abstractions.js +5 -0
  77. package/api/features/ListModels/abstractions.js.map +1 -0
  78. package/api/features/ListModels/feature.d.ts +4 -0
  79. package/api/features/ListModels/feature.js +11 -0
  80. package/api/features/ListModels/feature.js.map +1 -0
  81. package/api/features/ListModels/index.d.ts +1 -0
  82. package/api/features/ListModels/index.js +1 -0
  83. package/api/features/Providers/ProvidersGraphQLMapper.js +1 -1
  84. package/api/features/Providers/ProvidersGraphQLMapper.js.map +1 -1
  85. package/api/features/UpdateSettings/UpdateSettingsRepository.d.ts +2 -2
  86. package/api/features/UpdateSettings/UpdateSettingsRepository.js +2 -2
  87. package/api/features/UpdateSettings/UpdateSettingsRepository.js.map +1 -1
  88. package/api/features/UpdateSettings/UpdateSettingsUseCase.d.ts +5 -3
  89. package/api/features/UpdateSettings/UpdateSettingsUseCase.js +10 -3
  90. package/api/features/UpdateSettings/UpdateSettingsUseCase.js.map +1 -1
  91. package/api/features/UpdateSettings/feature.js +4 -4
  92. package/api/features/UpdateSettings/feature.js.map +1 -1
  93. package/api/features/WbGeneratePageContent/QueueWbGeneratePageContentUseCase.d.ts +13 -0
  94. package/api/features/WbGeneratePageContent/QueueWbGeneratePageContentUseCase.js +42 -0
  95. package/api/features/WbGeneratePageContent/QueueWbGeneratePageContentUseCase.js.map +1 -0
  96. package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.d.ts +2 -2
  97. package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js +2 -2
  98. package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js.map +1 -1
  99. package/api/features/WbGeneratePageContent/abstractions.d.ts +14 -0
  100. package/api/features/WbGeneratePageContent/abstractions.js +2 -1
  101. package/api/features/WbGeneratePageContent/abstractions.js.map +1 -1
  102. package/api/features/WbGeneratePageContent/feature.js +4 -2
  103. package/api/features/WbGeneratePageContent/feature.js.map +1 -1
  104. package/api/features/WbGeneratePageContent/index.d.ts +1 -1
  105. package/api/features/WbGeneratePageContent/index.js +1 -1
  106. package/api/features/permissions/abstractions.d.ts +15 -0
  107. package/api/features/permissions/abstractions.js +6 -0
  108. package/api/features/permissions/abstractions.js.map +1 -0
  109. package/api/features/permissions/feature.d.ts +4 -0
  110. package/api/features/permissions/feature.js +7 -0
  111. package/api/features/permissions/feature.js.map +1 -0
  112. package/api/features/permissions/index.d.ts +2 -0
  113. package/api/features/permissions/index.js +2 -0
  114. package/api/graphql/BaseGraphQLSchema.js +22 -45
  115. package/api/graphql/BaseGraphQLSchema.js.map +1 -1
  116. package/domain/LlmJsonResponse.js +2 -1
  117. package/domain/LlmJsonResponse.js.map +1 -1
  118. package/package.json +30 -28
  119. package/shared/permissionsSchema.d.ts +20 -0
  120. package/shared/permissionsSchema.js +17 -0
  121. package/shared/permissionsSchema.js.map +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"api/features/Capabilities/feature.js","sources":["../../../../src/api/features/Capabilities/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport CapabilitiesHandler from \"./CapabilitiesHandler.js\";\nimport { ResolveAiCapabilityUseCaseImplementation } from \"./ResolveAiCapabilityUseCase.js\";\nimport { ListAiCapabilitiesUseCaseImplementation } from \"./ListAiCapabilitiesUseCase.js\";\n\nexport const CapabilitiesFeature = createFeature({\n name: \"AiPowerUpsCapabilities\",\n register(container) {\n container.register(CapabilitiesHandler);\n container.register(ResolveAiCapabilityUseCaseImplementation);\n container.register(ListAiCapabilitiesUseCaseImplementation);\n }\n});\n"],"names":["CapabilitiesFeature","createFeature","container","CapabilitiesHandler","ResolveAiCapabilityUseCaseImplementation","ListAiCapabilitiesUseCaseImplementation"],"mappings":";;;;AAKO,MAAMA,sBAAsBC,cAAc;IAC7C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;QACnBF,UAAU,QAAQ,CAACG;IACvB;AACJ"}
1
+ {"version":3,"file":"api/features/Capabilities/feature.js","sources":["../../../../src/api/features/Capabilities/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport CapabilitiesHandler from \"./CapabilitiesHandler.js\";\nimport ResolveAiCapabilityUseCase from \"./ResolveAiCapabilityUseCase.js\";\nimport ListAiCapabilitiesUseCase from \"./ListAiCapabilitiesUseCase.js\";\n\nexport const CapabilitiesFeature = createFeature({\n name: \"AiPowerUpsCapabilities\",\n register(container) {\n container.register(CapabilitiesHandler);\n container.register(ResolveAiCapabilityUseCase);\n container.register(ListAiCapabilitiesUseCase);\n }\n});\n"],"names":["CapabilitiesFeature","createFeature","container","CapabilitiesHandler","ResolveAiCapabilityUseCase","ListAiCapabilitiesUseCase"],"mappings":";;;;AAKO,MAAMA,sBAAsBC,cAAc;IAC7C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;QACnBF,UAAU,QAAQ,CAACG;IACvB;AACJ"}
@@ -1,4 +1,5 @@
1
1
  import { Ai } from "@webiny/api-core/features/ai/index.js";
2
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
2
3
  import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
3
4
  import { ModelToAstConverter } from "@webiny/api-headless-cms/features/contentModel/ModelToAstConverter/index.js";
4
5
  import { GetRevisionByIdUseCase } from "@webiny/api-headless-cms/features/contentEntry/GetRevisionById/index.js";
@@ -6,15 +7,16 @@ import { ResolveAiCapabilityUseCase } from "../../../api/features/Capabilities/i
6
7
  import { CmsCompareEntryRevisionsUseCase } from "./abstractions.js";
7
8
  import type { ICmsCompareEntryRevisionsParams, ICmsCompareEntryRevisionsResult } from "./abstractions.js";
8
9
  declare class CmsCompareEntryRevisionsUseCaseImpl implements CmsCompareEntryRevisionsUseCase.Interface {
10
+ private identityContext;
9
11
  private resolveCapability;
10
12
  private ai;
11
13
  private getModel;
12
14
  private getRevisionById;
13
15
  private modelToAst;
14
- constructor(resolveCapability: ResolveAiCapabilityUseCase.Interface, ai: Ai.Interface, getModel: GetModelUseCase.Interface, getRevisionById: GetRevisionByIdUseCase.Interface, modelToAst: ModelToAstConverter.Interface);
16
+ constructor(identityContext: IdentityContext.Interface, resolveCapability: ResolveAiCapabilityUseCase.Interface, ai: Ai.Interface, getModel: GetModelUseCase.Interface, getRevisionById: GetRevisionByIdUseCase.Interface, modelToAst: ModelToAstConverter.Interface);
15
17
  execute(params: ICmsCompareEntryRevisionsParams): Promise<ICmsCompareEntryRevisionsResult>;
16
18
  }
17
- export declare const CmsCompareEntryRevisionsUseCaseImplementation: typeof CmsCompareEntryRevisionsUseCaseImpl & {
19
+ declare const _default: typeof CmsCompareEntryRevisionsUseCaseImpl & {
18
20
  __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICmsCompareEntryRevisionsUseCase>;
19
21
  };
20
- export {};
22
+ export default _default;
@@ -1,4 +1,6 @@
1
1
  import { Ai } from "@webiny/api-core/features/ai/index.js";
2
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
3
+ import { NotAuthorizedError } from "@webiny/api-core/features/security/shared/errors.js";
2
4
  import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
3
5
  import { ModelToAstConverter } from "@webiny/api-headless-cms/features/contentModel/ModelToAstConverter/index.js";
4
6
  import { CmsModelToJsonSchemaConverter } from "@webiny/api-headless-cms/utils/contentModelToJsonSchema/index.js";
@@ -7,7 +9,8 @@ import { ResolveAiCapabilityUseCase, withAdditionalInstructions } from "../Capab
7
9
  import { CMS_COMPARE_ENTRY_REVISIONS_CAPABILITY } from "./capability.js";
8
10
  import { CmsCompareEntryRevisionsUseCase } from "./abstractions.js";
9
11
  class CmsCompareEntryRevisionsUseCaseImpl {
10
- constructor(resolveCapability, ai, getModel, getRevisionById, modelToAst){
12
+ constructor(identityContext, resolveCapability, ai, getModel, getRevisionById, modelToAst){
13
+ this.identityContext = identityContext;
11
14
  this.resolveCapability = resolveCapability;
12
15
  this.ai = ai;
13
16
  this.getModel = getModel;
@@ -15,13 +18,14 @@ class CmsCompareEntryRevisionsUseCaseImpl {
15
18
  this.modelToAst = modelToAst;
16
19
  }
17
20
  async execute(params) {
21
+ if (this.identityContext.getIdentity().isAnonymous()) throw new NotAuthorizedError();
18
22
  const { modelId, revisionId1, revisionId2 } = params;
23
+ const modelResult = await this.getModel.execute(modelId);
24
+ if (modelResult.isFail() || modelResult.value.isPrivate) throw new Error(`Content model "${modelId}" not found.`);
25
+ const model = modelResult.value;
19
26
  const resolved = await this.resolveCapability.execute(CMS_COMPARE_ENTRY_REVISIONS_CAPABILITY);
20
27
  if (resolved.isFail()) throw resolved.error;
21
28
  const capability = resolved.value;
22
- const modelResult = await this.getModel.execute(modelId);
23
- if (modelResult.isFail()) throw new Error(`Content model "${modelId}" not found.`);
24
- const model = modelResult.value;
25
29
  const [rev1Result, rev2Result] = await Promise.all([
26
30
  this.getRevisionById.execute(model, revisionId1),
27
31
  this.getRevisionById.execute(model, revisionId2)
@@ -67,9 +71,10 @@ ${JSON.stringify(revision2.values, null, 2)}`;
67
71
  };
68
72
  }
69
73
  }
70
- const CmsCompareEntryRevisionsUseCaseImplementation = CmsCompareEntryRevisionsUseCase.createImplementation({
74
+ const CmsCompareEntryRevisions_CmsCompareEntryRevisionsUseCase = CmsCompareEntryRevisionsUseCase.createImplementation({
71
75
  implementation: CmsCompareEntryRevisionsUseCaseImpl,
72
76
  dependencies: [
77
+ IdentityContext,
73
78
  ResolveAiCapabilityUseCase,
74
79
  Ai,
75
80
  GetModelUseCase,
@@ -77,6 +82,6 @@ const CmsCompareEntryRevisionsUseCaseImplementation = CmsCompareEntryRevisionsUs
77
82
  ModelToAstConverter
78
83
  ]
79
84
  });
80
- export { CmsCompareEntryRevisionsUseCaseImplementation };
85
+ export default CmsCompareEntryRevisions_CmsCompareEntryRevisionsUseCase;
81
86
 
82
87
  //# sourceMappingURL=CmsCompareEntryRevisionsUseCase.js.map
@@ -1 +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 { 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 {\n ResolveAiCapabilityUseCase,\n withAdditionalInstructions\n} from \"~/api/features/Capabilities/index.js\";\nimport { CMS_COMPARE_ENTRY_REVISIONS_CAPABILITY } from \"./capability.js\";\nimport { CmsCompareEntryRevisionsUseCase } from \"./abstractions.js\";\nimport type {\n ICmsCompareEntryRevisionsParams,\n ICmsCompareEntryRevisionsResult\n} from \"./abstractions.js\";\n\nclass CmsCompareEntryRevisionsUseCaseImpl implements CmsCompareEntryRevisionsUseCase.Interface {\n constructor(\n private resolveCapability: ResolveAiCapabilityUseCase.Interface,\n private ai: Ai.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 resolved = await this.resolveCapability.execute(\n CMS_COMPARE_ENTRY_REVISIONS_CAPABILITY\n );\n if (resolved.isFail()) {\n throw resolved.error;\n }\n\n const capability = resolved.value;\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 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: capability.model,\n connection: capability.connection,\n system: withAdditionalInstructions(capability),\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 ResolveAiCapabilityUseCase,\n Ai,\n GetModelUseCase,\n GetRevisionByIdUseCase,\n ModelToAstConverter\n ]\n });\n"],"names":["CmsCompareEntryRevisionsUseCaseImpl","resolveCapability","ai","getModel","getRevisionById","modelToAst","params","modelId","revisionId1","revisionId2","resolved","CMS_COMPARE_ENTRY_REVISIONS_CAPABILITY","capability","modelResult","Error","model","rev1Result","rev2Result","Promise","revision1","revision2","modelAst","jsonSchemaConverter","CmsModelToJsonSchemaConverter","entrySchema","userPrompt","JSON","result","withAdditionalInstructions","text","noChangesMatch","summary","headingMatch","trCount","CmsCompareEntryRevisionsUseCaseImplementation","CmsCompareEntryRevisionsUseCase","ResolveAiCapabilityUseCase","Ai","GetModelUseCase","GetRevisionByIdUseCase","ModelToAstConverter"],"mappings":";;;;;;;;AAgBA,MAAMA;IACF,YACYC,iBAAuD,EACvDC,EAAgB,EAChBC,QAAmC,EACnCC,eAAiD,EACjDC,UAAyC,CACnD;aALUJ,iBAAiB,GAAjBA;aACAC,EAAE,GAAFA;aACAC,QAAQ,GAARA;aACAC,eAAe,GAAfA;aACAC,UAAU,GAAVA;IACT;IAEH,MAAM,QACFC,MAAuC,EACC;QACxC,MAAM,EAAEC,OAAO,EAAEC,WAAW,EAAEC,WAAW,EAAE,GAAGH;QAE9C,MAAMI,WAAW,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CACjDC;QAEJ,IAAID,SAAS,MAAM,IACf,MAAMA,SAAS,KAAK;QAGxB,MAAME,aAAaF,SAAS,KAAK;QAEjC,MAAMG,cAAc,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAACN;QAChD,IAAIM,YAAY,MAAM,IAClB,MAAM,IAAIC,MAAM,CAAC,eAAe,EAAEP,QAAQ,YAAY,CAAC;QAE3D,MAAMQ,QAAQF,YAAY,KAAK;QAE/B,MAAM,CAACG,YAAYC,WAAW,GAAG,MAAMC,QAAQ,GAAG,CAAC;YAC/C,IAAI,CAAC,eAAe,CAAC,OAAO,CAACH,OAAOP;YACpC,IAAI,CAAC,eAAe,CAAC,OAAO,CAACO,OAAON;SACvC;QAED,IAAIO,WAAW,MAAM,IACjB,MAAM,IAAIF,MAAM,CAAC,UAAU,EAAEN,YAAY,YAAY,CAAC;QAE1D,IAAIS,WAAW,MAAM,IACjB,MAAM,IAAIH,MAAM,CAAC,UAAU,EAAEL,YAAY,YAAY,CAAC;QAG1D,MAAMU,YAAYH,WAAW,KAAK;QAClC,MAAMI,YAAYH,WAAW,KAAK;QAElC,MAAMI,WAAW,IAAI,CAAC,UAAU,CAAC,KAAK,CAACN;QACvC,MAAMO,sBAAsB,IAAIC;QAChC,MAAMC,cAAcF,oBAAoB,OAAO,CAACD,UAAU;YACtD,MAAMN,MAAM,IAAI;YAChB,aAAaA,MAAM,WAAW;QAClC;QAEA,MAAMU,aAAa,CAAC;AAC5B,EAAEC,KAAK,SAAS,CAACF,aAAa,MAAM,GAAG;;qBAElB,EAAEL,UAAU,OAAO,CAAC;AACzC,EAAEO,KAAK,SAAS,CAACP,UAAU,MAAM,EAAE,MAAM,GAAG;;qBAEvB,EAAEC,UAAU,OAAO,CAAC;AACzC,EAAEM,KAAK,SAAS,CAACN,UAAU,MAAM,EAAE,MAAM,IAAI;QAErC,MAAMO,SAAS,MAAM,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;YACtC,OAAOf,WAAW,KAAK;YACvB,YAAYA,WAAW,UAAU;YACjC,QAAQgB,2BAA2BhB;YACnC,QAAQa;YACR,aAAa;QACjB;QAEA,MAAMI,OAAOF,OAAO,IAAI;QAExB,MAAMG,iBAAiBD,KAAK,KAAK,CAAC;QAClC,IAAIE,UAAU;QACd,IAAID,gBACAC,UAAU;aACP;YACH,MAAMC,eAAeH,KAAK,KAAK,CAAC;YAChC,MAAMI,UAAWJ,AAAAA,CAAAA,KAAK,KAAK,CAAC,YAAY,EAAC,EAAG,MAAM,GAAG;YACrD,IAAIG,cACAD,UAAUC,YAAY,CAAC,EAAE,CAAC,IAAI;iBAC3B,IAAIC,UAAU,GACjBF,UAAU,GAAGE,QAAQ,MAAM,EAAEA,AAAY,MAAZA,UAAgB,KAAK,IAAI,QAAQ,CAAC;QAEvE;QAEA,OAAO;YAAE,MAAMJ;YAAME;QAAQ;IACjC;AACJ;AAEO,MAAMG,gDACTC,gCAAgC,oBAAoB,CAAC;IACjD,gBAAgBnC;IAChB,cAAc;QACVoC;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
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 { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { NotAuthorizedError } from \"@webiny/api-core/features/security/shared/errors.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 {\n ResolveAiCapabilityUseCase,\n withAdditionalInstructions\n} from \"~/api/features/Capabilities/index.js\";\nimport { CMS_COMPARE_ENTRY_REVISIONS_CAPABILITY } from \"./capability.js\";\nimport { CmsCompareEntryRevisionsUseCase } from \"./abstractions.js\";\nimport type {\n ICmsCompareEntryRevisionsParams,\n ICmsCompareEntryRevisionsResult\n} from \"./abstractions.js\";\n\nclass CmsCompareEntryRevisionsUseCaseImpl implements CmsCompareEntryRevisionsUseCase.Interface {\n constructor(\n private identityContext: IdentityContext.Interface,\n private resolveCapability: ResolveAiCapabilityUseCase.Interface,\n private ai: Ai.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 // Calls the AI providers with the project's keys, so anonymous callers can't use it.\n if (this.identityContext.getIdentity().isAnonymous()) {\n throw new NotAuthorizedError();\n }\n\n const { modelId, revisionId1, revisionId2 } = params;\n\n const modelResult = await this.getModel.execute(modelId);\n // Private models are internal, so they are treated as unknown.\n if (modelResult.isFail() || modelResult.value.isPrivate) {\n throw new Error(`Content model \"${modelId}\" not found.`);\n }\n const model = modelResult.value;\n\n const resolved = await this.resolveCapability.execute(\n CMS_COMPARE_ENTRY_REVISIONS_CAPABILITY\n );\n if (resolved.isFail()) {\n throw resolved.error;\n }\n\n const capability = resolved.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 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: capability.model,\n connection: capability.connection,\n system: withAdditionalInstructions(capability),\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 default CmsCompareEntryRevisionsUseCase.createImplementation({\n implementation: CmsCompareEntryRevisionsUseCaseImpl,\n dependencies: [\n IdentityContext,\n ResolveAiCapabilityUseCase,\n Ai,\n GetModelUseCase,\n GetRevisionByIdUseCase,\n ModelToAstConverter\n ]\n});\n"],"names":["CmsCompareEntryRevisionsUseCaseImpl","identityContext","resolveCapability","ai","getModel","getRevisionById","modelToAst","params","NotAuthorizedError","modelId","revisionId1","revisionId2","modelResult","Error","model","resolved","CMS_COMPARE_ENTRY_REVISIONS_CAPABILITY","capability","rev1Result","rev2Result","Promise","revision1","revision2","modelAst","jsonSchemaConverter","CmsModelToJsonSchemaConverter","entrySchema","userPrompt","JSON","result","withAdditionalInstructions","text","noChangesMatch","summary","headingMatch","trCount","CmsCompareEntryRevisionsUseCase","IdentityContext","ResolveAiCapabilityUseCase","Ai","GetModelUseCase","GetRevisionByIdUseCase","ModelToAstConverter"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  import { createFeature } from "@webiny/feature/api";
2
- import { CmsCompareEntryRevisionsUseCaseImplementation } from "./CmsCompareEntryRevisionsUseCase.js";
2
+ import CmsCompareEntryRevisionsUseCase from "./CmsCompareEntryRevisionsUseCase.js";
3
3
  import { CmsCompareEntryRevisionsCapability } from "./capability.js";
4
4
  const CmsCompareEntryRevisionsFeature = createFeature({
5
5
  name: "AiPowerUps/CmsCompareEntryRevisions",
6
6
  register (container) {
7
7
  container.register(CmsCompareEntryRevisionsCapability);
8
- container.register(CmsCompareEntryRevisionsUseCaseImplementation);
8
+ container.register(CmsCompareEntryRevisionsUseCase);
9
9
  }
10
10
  });
11
11
  export { CmsCompareEntryRevisionsFeature };
@@ -1 +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\";\nimport { CmsCompareEntryRevisionsCapability } from \"./capability.js\";\n\nexport const CmsCompareEntryRevisionsFeature = createFeature({\n name: \"AiPowerUps/CmsCompareEntryRevisions\",\n register(container) {\n container.register(CmsCompareEntryRevisionsCapability);\n container.register(CmsCompareEntryRevisionsUseCaseImplementation);\n }\n});\n"],"names":["CmsCompareEntryRevisionsFeature","createFeature","container","CmsCompareEntryRevisionsCapability","CmsCompareEntryRevisionsUseCaseImplementation"],"mappings":";;;AAIO,MAAMA,kCAAkCC,cAAc;IACzD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;IACvB;AACJ"}
1
+ {"version":3,"file":"api/features/CmsCompareEntryRevisions/feature.js","sources":["../../../../src/api/features/CmsCompareEntryRevisions/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport CmsCompareEntryRevisionsUseCase from \"./CmsCompareEntryRevisionsUseCase.js\";\nimport { CmsCompareEntryRevisionsCapability } from \"./capability.js\";\n\nexport const CmsCompareEntryRevisionsFeature = createFeature({\n name: \"AiPowerUps/CmsCompareEntryRevisions\",\n register(container) {\n container.register(CmsCompareEntryRevisionsCapability);\n container.register(CmsCompareEntryRevisionsUseCase);\n }\n});\n"],"names":["CmsCompareEntryRevisionsFeature","createFeature","container","CmsCompareEntryRevisionsCapability","CmsCompareEntryRevisionsUseCase"],"mappings":";;;AAIO,MAAMA,kCAAkCC,cAAc;IACzD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;IACvB;AACJ"}
@@ -21,7 +21,7 @@ declare class CmsGenerateEntryContentUseCaseImpl implements CmsGenerateEntryCont
21
21
  constructor(promptContextBuilder: AiPromptContextBuilder.Interface, resolveCapability: ResolveAiCapabilityUseCase.Interface, ai: Ai.Interface, aiSdkTools: AiSdkTools.Interface, listTags: ListTagsUseCase.Interface, getModel: GetModelUseCase.Interface, modelToAst: ModelToAstConverter.Interface, toolPipelineRunner: AiToolPipelineRunner.Interface);
22
22
  execute<TValues = Record<string, any>>(params: CmsGenerateEntryContentParams): Promise<Result<GenerateEntryContentResult<TValues>, Error>>;
23
23
  }
24
- export declare const CmsGenerateEntryContentUseCaseImplementation: typeof CmsGenerateEntryContentUseCaseImpl & {
24
+ declare const _default: typeof CmsGenerateEntryContentUseCaseImpl & {
25
25
  __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICmsGenerateEntryContentUseCase>;
26
26
  };
27
- export {};
27
+ export default _default;
@@ -29,7 +29,7 @@ class CmsGenerateEntryContentUseCaseImpl {
29
29
  if (resolved.isFail()) return Result.fail(resolved.error);
30
30
  const capability = resolved.value;
31
31
  const modelResult = await this.getModel.execute(params.modelId);
32
- if (modelResult.isFail()) return Result.fail(new Error(`Content model "${params.modelId}" not found.`));
32
+ if (modelResult.isFail() || modelResult.value.isPrivate) return Result.fail(new Error(`Content model "${params.modelId}" not found.`));
33
33
  const model = modelResult.value;
34
34
  const modelAst = this.modelToAst.toAst(model);
35
35
  const jsonSchemaConverter = new CmsModelToJsonSchemaConverter();
@@ -115,7 +115,7 @@ class CmsGenerateEntryContentUseCaseImpl {
115
115
  }
116
116
  }
117
117
  }
118
- const CmsGenerateEntryContentUseCaseImplementation = CmsGenerateEntryContentUseCase.createImplementation({
118
+ const CmsGenerateEntryContent_CmsGenerateEntryContentUseCase = CmsGenerateEntryContentUseCase.createImplementation({
119
119
  implementation: CmsGenerateEntryContentUseCaseImpl,
120
120
  dependencies: [
121
121
  AiPromptContextBuilder,
@@ -128,6 +128,6 @@ const CmsGenerateEntryContentUseCaseImplementation = CmsGenerateEntryContentUseC
128
128
  AiToolPipelineRunner
129
129
  ]
130
130
  });
131
- export { CmsGenerateEntryContentUseCaseImplementation };
131
+ export default CmsGenerateEntryContent_CmsGenerateEntryContentUseCase;
132
132
 
133
133
  //# sourceMappingURL=CmsGenerateEntryContentUseCase.js.map
@@ -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 { 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 {\n ResolveAiCapabilityUseCase,\n withAdditionalInstructions\n} from \"~/api/features/Capabilities/index.js\";\nimport { CMS_GENERATE_ENTRY_CAPABILITY } from \"./capability.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 \"~/domain/LlmJsonResponse.js\";\nimport { injectDynamicZoneTypenames } from \"./injectDynamicZoneTypenames.js\";\n\nclass CmsGenerateEntryContentUseCaseImpl implements CmsGenerateEntryContentUseCase.Interface {\n constructor(\n private promptContextBuilder: AiPromptContextBuilder.Interface,\n private resolveCapability: ResolveAiCapabilityUseCase.Interface,\n private ai: Ai.Interface,\n private aiSdkTools: AiSdkTools.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 resolved = await this.resolveCapability.execute(CMS_GENERATE_ENTRY_CAPABILITY);\n if (resolved.isFail()) {\n return Result.fail(resolved.error);\n }\n\n const capability = resolved.value;\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 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 = withAdditionalInstructions(\n capability,\n buildEntryPrompt(model.name, entrySchema, imageTags) + context.toString()\n );\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: capability.model,\n connection: capability.connection,\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 ResolveAiCapabilityUseCase,\n Ai,\n AiSdkTools,\n ListTagsUseCase,\n GetModelUseCase,\n ModelToAstConverter,\n AiToolPipelineRunner\n ]\n });\n"],"names":["CmsGenerateEntryContentUseCaseImpl","promptContextBuilder","resolveCapability","ai","aiSdkTools","listTags","getModel","modelToAst","toolPipelineRunner","params","resolved","CMS_GENERATE_ENTRY_CAPABILITY","Result","capability","modelResult","Error","model","modelAst","jsonSchemaConverter","CmsModelToJsonSchemaConverter","entrySchema","sdkTools","context","projectFileTool","createReadProjectFileTool","Object","tagsResult","imageTags","t","systemText","withAdditionalInstructions","buildEntryPrompt","system","aiResult","formatAdditionalFilesContext","stepCountIs","text","step","entry","LlmJsonResponse","injectDynamicZoneTypenames","filesRead","Set","toolCallsMade","call","input","telemetry","error","String","CmsGenerateEntryContentUseCaseImplementation","CmsGenerateEntryContentUseCase","AiPromptContextBuilder","ResolveAiCapabilityUseCase","Ai","AiSdkTools","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 { 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 {\n ResolveAiCapabilityUseCase,\n withAdditionalInstructions\n} from \"~/api/features/Capabilities/index.js\";\nimport { CMS_GENERATE_ENTRY_CAPABILITY } from \"./capability.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 \"~/domain/LlmJsonResponse.js\";\nimport { injectDynamicZoneTypenames } from \"./injectDynamicZoneTypenames.js\";\n\nclass CmsGenerateEntryContentUseCaseImpl implements CmsGenerateEntryContentUseCase.Interface {\n constructor(\n private promptContextBuilder: AiPromptContextBuilder.Interface,\n private resolveCapability: ResolveAiCapabilityUseCase.Interface,\n private ai: Ai.Interface,\n private aiSdkTools: AiSdkTools.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 resolved = await this.resolveCapability.execute(CMS_GENERATE_ENTRY_CAPABILITY);\n if (resolved.isFail()) {\n return Result.fail(resolved.error);\n }\n\n const capability = resolved.value;\n\n const modelResult = await this.getModel.execute(params.modelId);\n // Private models are internal, so they are treated as unknown.\n if (modelResult.isFail() || modelResult.value.isPrivate) {\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 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 = withAdditionalInstructions(\n capability,\n buildEntryPrompt(model.name, entrySchema, imageTags) + context.toString()\n );\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: capability.model,\n connection: capability.connection,\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 default CmsGenerateEntryContentUseCase.createImplementation({\n implementation: CmsGenerateEntryContentUseCaseImpl,\n dependencies: [\n AiPromptContextBuilder,\n ResolveAiCapabilityUseCase,\n Ai,\n AiSdkTools,\n ListTagsUseCase,\n GetModelUseCase,\n ModelToAstConverter,\n AiToolPipelineRunner\n ]\n});\n"],"names":["CmsGenerateEntryContentUseCaseImpl","promptContextBuilder","resolveCapability","ai","aiSdkTools","listTags","getModel","modelToAst","toolPipelineRunner","params","resolved","CMS_GENERATE_ENTRY_CAPABILITY","Result","capability","modelResult","Error","model","modelAst","jsonSchemaConverter","CmsModelToJsonSchemaConverter","entrySchema","sdkTools","context","projectFileTool","createReadProjectFileTool","Object","tagsResult","imageTags","t","systemText","withAdditionalInstructions","buildEntryPrompt","system","aiResult","formatAdditionalFilesContext","stepCountIs","text","step","entry","LlmJsonResponse","injectDynamicZoneTypenames","filesRead","Set","toolCallsMade","call","input","telemetry","error","String","CmsGenerateEntryContentUseCase","AiPromptContextBuilder","ResolveAiCapabilityUseCase","Ai","AiSdkTools","ListTagsUseCase","GetModelUseCase","ModelToAstConverter","AiToolPipelineRunner"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
2
+ import { WcpContext } from "@webiny/api-core/features/wcp/WcpContext/index.js";
3
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
4
+ import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
5
+ import { AccessControl } from "@webiny/api-headless-cms/features/shared/abstractions.js";
6
+ import { QueueCmsGenerateEntryContentUseCase } from "./abstractions.js";
7
+ declare class QueueCmsGenerateEntryContentUseCaseImpl implements QueueCmsGenerateEntryContentUseCase.Interface {
8
+ private identityContext;
9
+ private wcp;
10
+ private getModel;
11
+ private accessControl;
12
+ private taskService;
13
+ constructor(identityContext: IdentityContext.Interface, wcp: WcpContext.Interface, getModel: GetModelUseCase.Interface, accessControl: AccessControl.Interface, taskService: TaskService.Interface);
14
+ execute(params: QueueCmsGenerateEntryContentUseCase.Params): QueueCmsGenerateEntryContentUseCase.Return;
15
+ }
16
+ declare const _default: typeof QueueCmsGenerateEntryContentUseCaseImpl & {
17
+ __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IQueueCmsGenerateEntryContentUseCase>;
18
+ };
19
+ export default _default;
@@ -0,0 +1,61 @@
1
+ import { Result } from "@webiny/feature/api";
2
+ import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
3
+ import { WcpContext } from "@webiny/api-core/features/wcp/WcpContext/index.js";
4
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
5
+ import { NotAuthorizedError } from "@webiny/api-core/features/security/shared/errors.js";
6
+ import { GetModelUseCase } from "@webiny/api-headless-cms/features/contentModel/GetModel/index.js";
7
+ import { AccessControl } from "@webiny/api-headless-cms/features/shared/abstractions.js";
8
+ import { ModelNotFoundError } from "@webiny/api-headless-cms/domain/contentModel/errors.js";
9
+ import { EntryNotAuthorizedError } from "@webiny/api-headless-cms/domain/contentEntry/errors.js";
10
+ import { QueueCmsGenerateEntryContentUseCase } from "./abstractions.js";
11
+ import { CMS_GENERATE_ENTRY_CONTENT_TASK_ID } from "./CmsGenerateEntryContentTask.js";
12
+ class QueueCmsGenerateEntryContentUseCaseImpl {
13
+ constructor(identityContext, wcp, getModel, accessControl, taskService){
14
+ this.identityContext = identityContext;
15
+ this.wcp = wcp;
16
+ this.getModel = getModel;
17
+ this.accessControl = accessControl;
18
+ this.taskService = taskService;
19
+ }
20
+ async execute(params) {
21
+ if (this.identityContext.getIdentity().isAnonymous()) return Result.fail(new NotAuthorizedError());
22
+ if (!this.wcp.canUseAiEntryGeneration()) return Result.fail(new Error("AI entry generation cannot be used because your project license does not permit it."));
23
+ const modelResult = await this.getModel.execute(params.modelId);
24
+ if (modelResult.isFail() || modelResult.value.isPrivate) return Result.fail(new ModelNotFoundError(params.modelId));
25
+ const model = modelResult.value;
26
+ const canWrite = await this.accessControl.canAccessEntry({
27
+ model,
28
+ rwd: "w"
29
+ });
30
+ if (!canWrite) return Result.fail(EntryNotAuthorizedError.fromModel(model));
31
+ const result = await this.taskService.trigger({
32
+ definition: CMS_GENERATE_ENTRY_CONTENT_TASK_ID,
33
+ input: {
34
+ prompt: params.prompt,
35
+ modelId: params.modelId,
36
+ projectId: params.projectId ?? null,
37
+ excludedFileIds: params.excludedFileIds ?? null,
38
+ readerPersonaId: params.readerPersonaId ?? null,
39
+ writerPersonaId: params.writerPersonaId ?? null,
40
+ additionalFileIds: params.additionalFileIds ?? null
41
+ }
42
+ });
43
+ if (result.isFail()) return Result.fail(result.error);
44
+ return Result.ok({
45
+ id: result.value.id
46
+ });
47
+ }
48
+ }
49
+ const CmsGenerateEntryContent_QueueCmsGenerateEntryContentUseCase = QueueCmsGenerateEntryContentUseCase.createImplementation({
50
+ implementation: QueueCmsGenerateEntryContentUseCaseImpl,
51
+ dependencies: [
52
+ IdentityContext,
53
+ WcpContext,
54
+ GetModelUseCase,
55
+ AccessControl,
56
+ TaskService
57
+ ]
58
+ });
59
+ export default CmsGenerateEntryContent_QueueCmsGenerateEntryContentUseCase;
60
+
61
+ //# sourceMappingURL=QueueCmsGenerateEntryContentUseCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/CmsGenerateEntryContent/QueueCmsGenerateEntryContentUseCase.js","sources":["../../../../src/api/features/CmsGenerateEntryContent/QueueCmsGenerateEntryContentUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { TaskService } from \"@webiny/api-core/features/task/TaskService/index.js\";\nimport { WcpContext } from \"@webiny/api-core/features/wcp/WcpContext/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { NotAuthorizedError } from \"@webiny/api-core/features/security/shared/errors.js\";\nimport { GetModelUseCase } from \"@webiny/api-headless-cms/features/contentModel/GetModel/index.js\";\nimport { AccessControl } from \"@webiny/api-headless-cms/features/shared/abstractions.js\";\nimport { ModelNotFoundError } from \"@webiny/api-headless-cms/domain/contentModel/errors.js\";\nimport { EntryNotAuthorizedError } from \"@webiny/api-headless-cms/domain/contentEntry/errors.js\";\nimport { QueueCmsGenerateEntryContentUseCase } from \"./abstractions.js\";\nimport {\n CMS_GENERATE_ENTRY_CONTENT_TASK_ID,\n type ICmsGenerateEntryContentTaskInput\n} from \"./CmsGenerateEntryContentTask.js\";\n\nclass QueueCmsGenerateEntryContentUseCaseImpl\n implements QueueCmsGenerateEntryContentUseCase.Interface\n{\n constructor(\n private identityContext: IdentityContext.Interface,\n private wcp: WcpContext.Interface,\n private getModel: GetModelUseCase.Interface,\n private accessControl: AccessControl.Interface,\n private taskService: TaskService.Interface\n ) {}\n\n async execute(\n params: QueueCmsGenerateEntryContentUseCase.Params\n ): QueueCmsGenerateEntryContentUseCase.Return {\n // The task calls the AI providers with the project's keys, so anonymous callers can't queue one.\n if (this.identityContext.getIdentity().isAnonymous()) {\n return Result.fail(new NotAuthorizedError());\n }\n\n // Checked per request, NOT at feature-registration time: the WCP license is loaded per\n // request, so a register-time check reads the placeholder NullLicense (canUse* → false).\n if (!this.wcp.canUseAiEntryGeneration()) {\n return Result.fail(\n new Error(\n \"AI entry generation cannot be used because your project license does not permit it.\"\n )\n );\n }\n\n // The task runs without authorization, so access to the model is checked here.\n // Private models are internal, so they are treated as unknown.\n const modelResult = await this.getModel.execute(params.modelId);\n if (modelResult.isFail() || modelResult.value.isPrivate) {\n return Result.fail(new ModelNotFoundError(params.modelId));\n }\n\n const model = modelResult.value;\n // Generated content is used to fill in an entry, so it needs write access to the model.\n const canWrite = await this.accessControl.canAccessEntry({ model, rwd: \"w\" });\n if (!canWrite) {\n return Result.fail(EntryNotAuthorizedError.fromModel(model));\n }\n\n const result = await this.taskService.trigger<ICmsGenerateEntryContentTaskInput>({\n definition: CMS_GENERATE_ENTRY_CONTENT_TASK_ID,\n input: {\n prompt: params.prompt,\n modelId: params.modelId,\n projectId: params.projectId ?? null,\n excludedFileIds: params.excludedFileIds ?? null,\n readerPersonaId: params.readerPersonaId ?? null,\n writerPersonaId: params.writerPersonaId ?? null,\n additionalFileIds: params.additionalFileIds ?? null\n }\n });\n\n if (result.isFail()) {\n return Result.fail(result.error);\n }\n\n return Result.ok({ id: result.value.id });\n }\n}\n\nexport default QueueCmsGenerateEntryContentUseCase.createImplementation({\n implementation: QueueCmsGenerateEntryContentUseCaseImpl,\n dependencies: [IdentityContext, WcpContext, GetModelUseCase, AccessControl, TaskService]\n});\n"],"names":["QueueCmsGenerateEntryContentUseCaseImpl","identityContext","wcp","getModel","accessControl","taskService","params","Result","NotAuthorizedError","Error","modelResult","ModelNotFoundError","model","canWrite","EntryNotAuthorizedError","result","CMS_GENERATE_ENTRY_CONTENT_TASK_ID","QueueCmsGenerateEntryContentUseCase","IdentityContext","WcpContext","GetModelUseCase","AccessControl","TaskService"],"mappings":";;;;;;;;;;;AAeA,MAAMA;IAGF,YACYC,eAA0C,EAC1CC,GAAyB,EACzBC,QAAmC,EACnCC,aAAsC,EACtCC,WAAkC,CAC5C;aALUJ,eAAe,GAAfA;aACAC,GAAG,GAAHA;aACAC,QAAQ,GAARA;aACAC,aAAa,GAAbA;aACAC,WAAW,GAAXA;IACT;IAEH,MAAM,QACFC,MAAkD,EACR;QAE1C,IAAI,IAAI,CAAC,eAAe,CAAC,WAAW,GAAG,WAAW,IAC9C,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAK3B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,uBAAuB,IACjC,OAAOD,OAAO,IAAI,CACd,IAAIE,MACA;QAOZ,MAAMC,cAAc,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAACJ,OAAO,OAAO;QAC9D,IAAII,YAAY,MAAM,MAAMA,YAAY,KAAK,CAAC,SAAS,EACnD,OAAOH,OAAO,IAAI,CAAC,IAAII,mBAAmBL,OAAO,OAAO;QAG5D,MAAMM,QAAQF,YAAY,KAAK;QAE/B,MAAMG,WAAW,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC;YAAED;YAAO,KAAK;QAAI;QAC3E,IAAI,CAACC,UACD,OAAON,OAAO,IAAI,CAACO,wBAAwB,SAAS,CAACF;QAGzD,MAAMG,SAAS,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAoC;YAC7E,YAAYC;YACZ,OAAO;gBACH,QAAQV,OAAO,MAAM;gBACrB,SAASA,OAAO,OAAO;gBACvB,WAAWA,OAAO,SAAS,IAAI;gBAC/B,iBAAiBA,OAAO,eAAe,IAAI;gBAC3C,iBAAiBA,OAAO,eAAe,IAAI;gBAC3C,iBAAiBA,OAAO,eAAe,IAAI;gBAC3C,mBAAmBA,OAAO,iBAAiB,IAAI;YACnD;QACJ;QAEA,IAAIS,OAAO,MAAM,IACb,OAAOR,OAAO,IAAI,CAACQ,OAAO,KAAK;QAGnC,OAAOR,OAAO,EAAE,CAAC;YAAE,IAAIQ,OAAO,KAAK,CAAC,EAAE;QAAC;IAC3C;AACJ;AAEA,oEAAeE,oCAAoC,oBAAoB,CAAC;IACpE,gBAAgBjB;IAChB,cAAc;QAACkB;QAAiBC;QAAYC;QAAiBC;QAAeC;KAAY;AAC5F"}
@@ -34,3 +34,17 @@ export declare namespace CmsGenerateEntryContentUseCase {
34
34
  type Interface = ICmsGenerateEntryContentUseCase;
35
35
  type Params = CmsGenerateEntryContentParams;
36
36
  }
37
+ export interface IQueueCmsGenerateEntryContentUseCase {
38
+ execute(params: CmsGenerateEntryContentParams): Promise<Result<{
39
+ id: string;
40
+ }, Error>>;
41
+ }
42
+ /** Queues the background task that generates CMS entry content. */
43
+ export declare const QueueCmsGenerateEntryContentUseCase: import("@webiny/di").Abstraction<IQueueCmsGenerateEntryContentUseCase>;
44
+ export declare namespace QueueCmsGenerateEntryContentUseCase {
45
+ type Interface = IQueueCmsGenerateEntryContentUseCase;
46
+ type Params = CmsGenerateEntryContentParams;
47
+ type Return = Promise<Result<{
48
+ id: string;
49
+ }, Error>>;
50
+ }
@@ -1,5 +1,6 @@
1
1
  import { createAbstraction } from "@webiny/feature/api";
2
2
  const CmsGenerateEntryContentUseCase = createAbstraction("AiPowerUpsCmsGenerateEntryContentUseCase");
3
- export { CmsGenerateEntryContentUseCase };
3
+ const QueueCmsGenerateEntryContentUseCase = createAbstraction("AiPowerUpsQueueCmsGenerateEntryContentUseCase");
4
+ export { CmsGenerateEntryContentUseCase, QueueCmsGenerateEntryContentUseCase };
4
5
 
5
6
  //# sourceMappingURL=abstractions.js.map
@@ -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 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
+ {"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\nexport interface IQueueCmsGenerateEntryContentUseCase {\n execute(params: CmsGenerateEntryContentParams): Promise<Result<{ id: string }, Error>>;\n}\n\n/** Queues the background task that generates CMS entry content. */\nexport const QueueCmsGenerateEntryContentUseCase =\n createAbstraction<IQueueCmsGenerateEntryContentUseCase>(\n \"AiPowerUpsQueueCmsGenerateEntryContentUseCase\"\n );\n\nexport namespace QueueCmsGenerateEntryContentUseCase {\n export type Interface = IQueueCmsGenerateEntryContentUseCase;\n export type Params = CmsGenerateEntryContentParams;\n export type Return = Promise<Result<{ id: string }, Error>>;\n}\n"],"names":["CmsGenerateEntryContentUseCase","createAbstraction","QueueCmsGenerateEntryContentUseCase"],"mappings":";AAsCO,MAAMA,iCAAiCC,kBAC1C;AAaG,MAAMC,sCACTD,kBACI"}
@@ -1,13 +1,15 @@
1
1
  import { createFeature } from "@webiny/feature/api";
2
- import { CmsGenerateEntryContentUseCaseImplementation } from "./CmsGenerateEntryContentUseCase.js";
2
+ import CmsGenerateEntryContentUseCase from "./CmsGenerateEntryContentUseCase.js";
3
3
  import { CmsGenerateEntryContentTask } from "./CmsGenerateEntryContentTask.js";
4
4
  import { CmsGenerateEntryCapability } from "./capability.js";
5
+ import QueueCmsGenerateEntryContentUseCase from "./QueueCmsGenerateEntryContentUseCase.js";
5
6
  const CmsGenerateEntryContentFeature = createFeature({
6
7
  name: "AiPowerUps/CmsGenerateEntryContent",
7
8
  register (container) {
8
9
  container.register(CmsGenerateEntryCapability);
9
- container.register(CmsGenerateEntryContentUseCaseImplementation);
10
+ container.register(CmsGenerateEntryContentUseCase);
10
11
  container.register(CmsGenerateEntryContentTask);
12
+ container.register(QueueCmsGenerateEntryContentUseCase);
11
13
  }
12
14
  });
13
15
  export { CmsGenerateEntryContentFeature };
@@ -1 +1 @@
1
- {"version":3,"file":"api/features/CmsGenerateEntryContent/feature.js","sources":["../../../../src/api/features/CmsGenerateEntryContent/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { CmsGenerateEntryContentUseCaseImplementation } from \"./CmsGenerateEntryContentUseCase.js\";\nimport { CmsGenerateEntryContentTask } from \"./CmsGenerateEntryContentTask.js\";\nimport { CmsGenerateEntryCapability } from \"./capability.js\";\n\nexport const CmsGenerateEntryContentFeature = createFeature({\n name: \"AiPowerUps/CmsGenerateEntryContent\",\n register(container) {\n container.register(CmsGenerateEntryCapability);\n container.register(CmsGenerateEntryContentUseCaseImplementation);\n container.register(CmsGenerateEntryContentTask);\n }\n});\n"],"names":["CmsGenerateEntryContentFeature","createFeature","container","CmsGenerateEntryCapability","CmsGenerateEntryContentUseCaseImplementation","CmsGenerateEntryContentTask"],"mappings":";;;;AAKO,MAAMA,iCAAiCC,cAAc;IACxD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;QACnBF,UAAU,QAAQ,CAACG;IACvB;AACJ"}
1
+ {"version":3,"file":"api/features/CmsGenerateEntryContent/feature.js","sources":["../../../../src/api/features/CmsGenerateEntryContent/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport CmsGenerateEntryContentUseCase from \"./CmsGenerateEntryContentUseCase.js\";\nimport { CmsGenerateEntryContentTask } from \"./CmsGenerateEntryContentTask.js\";\nimport { CmsGenerateEntryCapability } from \"./capability.js\";\nimport QueueCmsGenerateEntryContentUseCase from \"./QueueCmsGenerateEntryContentUseCase.js\";\n\nexport const CmsGenerateEntryContentFeature = createFeature({\n name: \"AiPowerUps/CmsGenerateEntryContent\",\n register(container) {\n container.register(CmsGenerateEntryCapability);\n container.register(CmsGenerateEntryContentUseCase);\n container.register(CmsGenerateEntryContentTask);\n container.register(QueueCmsGenerateEntryContentUseCase);\n }\n});\n"],"names":["CmsGenerateEntryContentFeature","createFeature","container","CmsGenerateEntryCapability","CmsGenerateEntryContentUseCase","CmsGenerateEntryContentTask","QueueCmsGenerateEntryContentUseCase"],"mappings":";;;;;AAMO,MAAMA,iCAAiCC,cAAc;IACxD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;QACnBF,UAAU,QAAQ,CAACG;QACnBH,UAAU,QAAQ,CAACI;IACvB;AACJ"}
@@ -1 +1 @@
1
- export { CmsGenerateEntryContentUseCase } from "./abstractions.js";
1
+ export { CmsGenerateEntryContentUseCase, QueueCmsGenerateEntryContentUseCase } from "./abstractions.js";
@@ -1 +1 @@
1
- export { CmsGenerateEntryContentUseCase } from "./abstractions.js";
1
+ export { CmsGenerateEntryContentUseCase, QueueCmsGenerateEntryContentUseCase } from "./abstractions.js";
@@ -7,7 +7,7 @@ class ConnectionsGraphQLMapperImpl {
7
7
  id: p.id,
8
8
  name: p.name,
9
9
  sdkName: p.sdkName,
10
- apiKey: p.apiKeyMasked ?? null
10
+ apiKey: p.apiKeyMasked || null
11
11
  }))
12
12
  };
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"api/features/Connections/ConnectionsGraphQLMapper.js","sources":["../../../../src/api/features/Connections/ConnectionsGraphQLMapper.ts"],"sourcesContent":["import { AiPowerUpsSettingsGroupGraphQLMapper } from \"~/api/features/shared/index.js\";\nimport type { ConnectionsSettings } from \"./types.js\";\n\ninterface ApiConnectionPreset {\n id: string;\n name: string;\n sdkName: string;\n apiKey: string | null;\n}\n\ninterface ApiConnections {\n presets: ApiConnectionPreset[];\n}\n\ninterface ApiInputConnectionPreset {\n id: string;\n name: string;\n sdkName: string;\n apiKey?: string;\n}\n\nclass ConnectionsGraphQLMapperImpl implements AiPowerUpsSettingsGroupGraphQLMapper.Interface {\n readonly name = \"connections\";\n\n toApi(internal: unknown): ApiConnections {\n const data = internal as ConnectionsSettings;\n return {\n presets: data.presets.map(p => ({\n id: p.id,\n name: p.name,\n sdkName: p.sdkName,\n // The admin form only ever sees the mask. The plaintext key never leaves the api.\n apiKey: p.apiKeyMasked ?? null\n }))\n };\n }\n\n fromApi(api: unknown): ConnectionsSettings {\n const data = api as { presets: ApiInputConnectionPreset[] };\n return {\n presets: data.presets.map(p => ({\n id: p.id,\n name: p.name,\n sdkName: p.sdkName,\n apiKey: p.apiKey,\n apiKeyMasked: \"\",\n apiKeyEncrypted: \"\"\n }))\n };\n }\n}\n\nexport default AiPowerUpsSettingsGroupGraphQLMapper.createImplementation({\n implementation: ConnectionsGraphQLMapperImpl,\n dependencies: []\n});\n"],"names":["ConnectionsGraphQLMapperImpl","internal","data","p","api","AiPowerUpsSettingsGroupGraphQLMapper"],"mappings":";AAqBA,MAAMA;IAGF,MAAMC,QAAiB,EAAkB;QACrC,MAAMC,OAAOD;QACb,OAAO;YACH,SAASC,KAAK,OAAO,CAAC,GAAG,CAACC,CAAAA,IAAM;oBAC5B,IAAIA,EAAE,EAAE;oBACR,MAAMA,EAAE,IAAI;oBACZ,SAASA,EAAE,OAAO;oBAElB,QAAQA,EAAE,YAAY,IAAI;gBAC9B;QACJ;IACJ;IAEA,QAAQC,GAAY,EAAuB;QACvC,MAAMF,OAAOE;QACb,OAAO;YACH,SAASF,KAAK,OAAO,CAAC,GAAG,CAACC,CAAAA,IAAM;oBAC5B,IAAIA,EAAE,EAAE;oBACR,MAAMA,EAAE,IAAI;oBACZ,SAASA,EAAE,OAAO;oBAClB,QAAQA,EAAE,MAAM;oBAChB,cAAc;oBACd,iBAAiB;gBACrB;QACJ;IACJ;;aA3BS,IAAI,GAAG;;AA4BpB;AAEA,iCAAeE,qCAAqC,oBAAoB,CAAC;IACrE,gBAAgBL;IAChB,cAAc,EAAE;AACpB"}
1
+ {"version":3,"file":"api/features/Connections/ConnectionsGraphQLMapper.js","sources":["../../../../src/api/features/Connections/ConnectionsGraphQLMapper.ts"],"sourcesContent":["import { AiPowerUpsSettingsGroupGraphQLMapper } from \"~/api/features/shared/index.js\";\nimport type { ConnectionsSettings } from \"./types.js\";\n\ninterface ApiConnectionPreset {\n id: string;\n name: string;\n sdkName: string;\n apiKey: string | null;\n}\n\ninterface ApiConnections {\n presets: ApiConnectionPreset[];\n}\n\ninterface ApiInputConnectionPreset {\n id: string;\n name: string;\n sdkName: string;\n apiKey?: string;\n}\n\nclass ConnectionsGraphQLMapperImpl implements AiPowerUpsSettingsGroupGraphQLMapper.Interface {\n readonly name = \"connections\";\n\n toApi(internal: unknown): ApiConnections {\n const data = internal as ConnectionsSettings;\n return {\n presets: data.presets.map(p => ({\n id: p.id,\n name: p.name,\n sdkName: p.sdkName,\n // The admin form only ever sees the mask. The plaintext key never leaves the api.\n apiKey: p.apiKeyMasked || null\n }))\n };\n }\n\n fromApi(api: unknown): ConnectionsSettings {\n const data = api as { presets: ApiInputConnectionPreset[] };\n return {\n presets: data.presets.map(p => ({\n id: p.id,\n name: p.name,\n sdkName: p.sdkName,\n apiKey: p.apiKey,\n apiKeyMasked: \"\",\n apiKeyEncrypted: \"\"\n }))\n };\n }\n}\n\nexport default AiPowerUpsSettingsGroupGraphQLMapper.createImplementation({\n implementation: ConnectionsGraphQLMapperImpl,\n dependencies: []\n});\n"],"names":["ConnectionsGraphQLMapperImpl","internal","data","p","api","AiPowerUpsSettingsGroupGraphQLMapper"],"mappings":";AAqBA,MAAMA;IAGF,MAAMC,QAAiB,EAAkB;QACrC,MAAMC,OAAOD;QACb,OAAO;YACH,SAASC,KAAK,OAAO,CAAC,GAAG,CAACC,CAAAA,IAAM;oBAC5B,IAAIA,EAAE,EAAE;oBACR,MAAMA,EAAE,IAAI;oBACZ,SAASA,EAAE,OAAO;oBAElB,QAAQA,EAAE,YAAY,IAAI;gBAC9B;QACJ;IACJ;IAEA,QAAQC,GAAY,EAAuB;QACvC,MAAMF,OAAOE;QACb,OAAO;YACH,SAASF,KAAK,OAAO,CAAC,GAAG,CAACC,CAAAA,IAAM;oBAC5B,IAAIA,EAAE,EAAE;oBACR,MAAMA,EAAE,IAAI;oBACZ,SAASA,EAAE,OAAO;oBAClB,QAAQA,EAAE,MAAM;oBAChB,cAAc;oBACd,iBAAiB;gBACrB;QACJ;IACJ;;aA3BS,IAAI,GAAG;;AA4BpB;AAEA,iCAAeE,qCAAqC,oBAAoB,CAAC;IACrE,gBAAgBL;IAChB,cAAc,EAAE;AACpB"}
@@ -0,0 +1,17 @@
1
+ import { Result } from "@webiny/feature/api";
2
+ import { Encryption } from "@webiny/api-core/features/encryption/index.js";
3
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
4
+ import { GetSettingsRepository } from "../../../api/features/GetSettings/abstractions.js";
5
+ import { GetDecryptedSettingsUseCase } from "./abstractions.js";
6
+ import type { IAiPowerUpsSettings } from "../../../api/types.js";
7
+ declare class GetDecryptedSettingsUseCaseImpl implements GetDecryptedSettingsUseCase.Interface {
8
+ private identityContext;
9
+ private repository;
10
+ private encryption;
11
+ constructor(identityContext: IdentityContext.Interface, repository: GetSettingsRepository.Interface, encryption: Encryption.Interface);
12
+ execute(): Promise<Result<IAiPowerUpsSettings, Error>>;
13
+ }
14
+ declare const _default: typeof GetDecryptedSettingsUseCaseImpl & {
15
+ __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IGetDecryptedSettingsUseCase>;
16
+ };
17
+ export default _default;
@@ -0,0 +1,41 @@
1
+ import { Result } from "@webiny/feature/api";
2
+ import { Encryption } from "@webiny/api-core/features/encryption/index.js";
3
+ import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
4
+ import { NotAuthorizedError } from "@webiny/api-core/features/security/shared/errors.js";
5
+ import { GetSettingsRepository } from "../GetSettings/abstractions.js";
6
+ import { GetDecryptedSettingsUseCase } from "./abstractions.js";
7
+ class GetDecryptedSettingsUseCaseImpl {
8
+ constructor(identityContext, repository, encryption){
9
+ this.identityContext = identityContext;
10
+ this.repository = repository;
11
+ this.encryption = encryption;
12
+ }
13
+ async execute() {
14
+ if (this.identityContext.getIdentity().isAnonymous()) return Result.fail(new NotAuthorizedError());
15
+ const result = await this.repository.get();
16
+ if (result.isFail()) return result;
17
+ const settings = result.value;
18
+ const presets = await Promise.all((settings.connections?.presets ?? []).map(async (preset)=>({
19
+ ...preset,
20
+ apiKey: preset.apiKeyEncrypted ? await this.encryption.decrypt(preset.apiKeyEncrypted) : void 0
21
+ })));
22
+ return Result.ok({
23
+ ...settings,
24
+ connections: {
25
+ ...settings.connections,
26
+ presets
27
+ }
28
+ });
29
+ }
30
+ }
31
+ const GetDecryptedSettings_GetDecryptedSettingsUseCase = GetDecryptedSettingsUseCase.createImplementation({
32
+ implementation: GetDecryptedSettingsUseCaseImpl,
33
+ dependencies: [
34
+ IdentityContext,
35
+ GetSettingsRepository,
36
+ Encryption
37
+ ]
38
+ });
39
+ export default GetDecryptedSettings_GetDecryptedSettingsUseCase;
40
+
41
+ //# sourceMappingURL=GetDecryptedSettingsUseCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/GetDecryptedSettings/GetDecryptedSettingsUseCase.js","sources":["../../../../src/api/features/GetDecryptedSettings/GetDecryptedSettingsUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { NotAuthorizedError } from \"@webiny/api-core/features/security/shared/errors.js\";\nimport { GetSettingsRepository } from \"~/api/features/GetSettings/abstractions.js\";\nimport { GetDecryptedSettingsUseCase } from \"./abstractions.js\";\nimport type { IAiPowerUpsSettings } from \"~/api/types.js\";\n\nclass GetDecryptedSettingsUseCaseImpl implements GetDecryptedSettingsUseCase.Interface {\n constructor(\n private identityContext: IdentityContext.Interface,\n private repository: GetSettingsRepository.Interface,\n private encryption: Encryption.Interface\n ) {}\n\n async execute(): Promise<Result<IAiPowerUpsSettings, Error>> {\n // Background tasks run as the identity that created them, so they are never anonymous.\n if (this.identityContext.getIdentity().isAnonymous()) {\n return Result.fail(new NotAuthorizedError());\n }\n\n const result = await this.repository.get();\n if (result.isFail()) {\n return result;\n }\n\n const settings = result.value;\n\n // The repository returns a cached object, so build new ones instead of mutating it.\n const presets = await Promise.all(\n (settings.connections?.presets ?? []).map(async preset => ({\n ...preset,\n apiKey: preset.apiKeyEncrypted\n ? await this.encryption.decrypt(preset.apiKeyEncrypted)\n : undefined\n }))\n );\n\n return Result.ok({\n ...settings,\n connections: {\n ...settings.connections,\n presets\n }\n });\n }\n}\n\nexport default GetDecryptedSettingsUseCase.createImplementation({\n implementation: GetDecryptedSettingsUseCaseImpl,\n dependencies: [IdentityContext, GetSettingsRepository, Encryption]\n});\n"],"names":["GetDecryptedSettingsUseCaseImpl","identityContext","repository","encryption","Result","NotAuthorizedError","result","settings","presets","Promise","preset","undefined","GetDecryptedSettingsUseCase","IdentityContext","GetSettingsRepository","Encryption"],"mappings":";;;;;;AAQA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,UAA2C,EAC3CC,UAAgC,CAC1C;aAHUF,eAAe,GAAfA;aACAC,UAAU,GAAVA;aACAC,UAAU,GAAVA;IACT;IAEH,MAAM,UAAuD;QAEzD,IAAI,IAAI,CAAC,eAAe,CAAC,WAAW,GAAG,WAAW,IAC9C,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAG3B,MAAMC,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG;QACxC,IAAIA,OAAO,MAAM,IACb,OAAOA;QAGX,MAAMC,WAAWD,OAAO,KAAK;QAG7B,MAAME,UAAU,MAAMC,QAAQ,GAAG,CAC5BF,AAAAA,CAAAA,SAAS,WAAW,EAAE,WAAW,EAAC,EAAG,GAAG,CAAC,OAAMG,SAAW;gBACvD,GAAGA,MAAM;gBACT,QAAQA,OAAO,eAAe,GACxB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACA,OAAO,eAAe,IACpDC;YACV;QAGJ,OAAOP,OAAO,EAAE,CAAC;YACb,GAAGG,QAAQ;YACX,aAAa;gBACT,GAAGA,SAAS,WAAW;gBACvBC;YACJ;QACJ;IACJ;AACJ;AAEA,yDAAeI,4BAA4B,oBAAoB,CAAC;IAC5D,gBAAgBZ;IAChB,cAAc;QAACa;QAAiBC;QAAuBC;KAAW;AACtE"}
@@ -0,0 +1,13 @@
1
+ import { Result } from "@webiny/feature/api";
2
+ import type { IAiPowerUpsSettings } from "../../../api/types.js";
3
+ export interface IGetDecryptedSettingsUseCase {
4
+ execute(): Promise<Result<IAiPowerUpsSettings, Error>>;
5
+ }
6
+ /**
7
+ * Internal: returns the settings with each connection's `apiKey` decrypted.
8
+ * For code that calls the AI providers. Never return its result to a client.
9
+ */
10
+ export declare const GetDecryptedSettingsUseCase: import("@webiny/di").Abstraction<IGetDecryptedSettingsUseCase>;
11
+ export declare namespace GetDecryptedSettingsUseCase {
12
+ type Interface = IGetDecryptedSettingsUseCase;
13
+ }
@@ -0,0 +1,5 @@
1
+ import { createAbstraction } from "@webiny/feature/api";
2
+ const GetDecryptedSettingsUseCase = createAbstraction("AiPowerUpsGetDecryptedSettingsUseCase");
3
+ export { GetDecryptedSettingsUseCase };
4
+
5
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/GetDecryptedSettings/abstractions.js","sources":["../../../../src/api/features/GetDecryptedSettings/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\nimport type { IAiPowerUpsSettings } from \"~/api/types.js\";\n\nexport interface IGetDecryptedSettingsUseCase {\n execute(): Promise<Result<IAiPowerUpsSettings, Error>>;\n}\n\n/**\n * Internal: returns the settings with each connection's `apiKey` decrypted.\n * For code that calls the AI providers. Never return its result to a client.\n */\nexport const GetDecryptedSettingsUseCase = createAbstraction<IGetDecryptedSettingsUseCase>(\n \"AiPowerUpsGetDecryptedSettingsUseCase\"\n);\n\nexport namespace GetDecryptedSettingsUseCase {\n export type Interface = IGetDecryptedSettingsUseCase;\n}\n"],"names":["GetDecryptedSettingsUseCase","createAbstraction"],"mappings":";AAWO,MAAMA,8BAA8BC,kBACvC"}
@@ -0,0 +1,4 @@
1
+ export declare const GetDecryptedSettingsFeature: {
2
+ name: string;
3
+ register(container: import("@webiny/di").Container): void;
4
+ };
@@ -0,0 +1,11 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import GetDecryptedSettingsUseCase from "./GetDecryptedSettingsUseCase.js";
3
+ const GetDecryptedSettingsFeature = createFeature({
4
+ name: "AiPowerUpsGetDecryptedSettings",
5
+ register (container) {
6
+ container.register(GetDecryptedSettingsUseCase);
7
+ }
8
+ });
9
+ export { GetDecryptedSettingsFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/GetDecryptedSettings/feature.js","sources":["../../../../src/api/features/GetDecryptedSettings/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport GetDecryptedSettingsUseCase from \"./GetDecryptedSettingsUseCase.js\";\n\nexport const GetDecryptedSettingsFeature = createFeature({\n name: \"AiPowerUpsGetDecryptedSettings\",\n register(container) {\n container.register(GetDecryptedSettingsUseCase);\n }\n});\n"],"names":["GetDecryptedSettingsFeature","createFeature","container","GetDecryptedSettingsUseCase"],"mappings":";;AAGO,MAAMA,8BAA8BC,cAAc;IACrD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1,2 @@
1
+ import "../Connections/types.js";
2
+ export { GetDecryptedSettingsUseCase } from "./abstractions.js";
@@ -0,0 +1,2 @@
1
+ import "../Connections/types.js";
2
+ export { GetDecryptedSettingsUseCase } from "./abstractions.js";