@webiny/ai-powerups 6.3.0 → 6.4.0-beta.0

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 (274) hide show
  1. package/AiPowerups.js +8 -9
  2. package/AiPowerups.js.map +1 -1
  3. package/admin/Extension.js +28 -26
  4. package/admin/Extension.js.map +1 -1
  5. package/admin/domain/errors.d.ts +12 -0
  6. package/admin/domain/errors.js +21 -0
  7. package/admin/domain/errors.js.map +1 -0
  8. package/admin/features/feature.js +13 -12
  9. package/admin/features/feature.js.map +1 -1
  10. package/admin/features/generatePageContent/GeneratePageContentGateway.js +35 -16
  11. package/admin/features/generatePageContent/GeneratePageContentGateway.js.map +1 -1
  12. package/admin/features/generatePageContent/GeneratePageContentUseCase.js +13 -10
  13. package/admin/features/generatePageContent/GeneratePageContentUseCase.js.map +1 -1
  14. package/admin/features/generatePageContent/abstractions.d.ts +4 -0
  15. package/admin/features/generatePageContent/abstractions.js +3 -2
  16. package/admin/features/generatePageContent/abstractions.js.map +1 -1
  17. package/admin/features/generatePageContent/feature.js +7 -6
  18. package/admin/features/generatePageContent/feature.js.map +1 -1
  19. package/admin/features/generatePageContent/index.js +1 -3
  20. package/admin/features/listModels/ListModelsGateway.js +17 -14
  21. package/admin/features/listModels/ListModelsGateway.js.map +1 -1
  22. package/admin/features/listModels/ListModelsRepository.js +21 -18
  23. package/admin/features/listModels/ListModelsRepository.js.map +1 -1
  24. package/admin/features/listModels/ListModelsUseCase.js +13 -10
  25. package/admin/features/listModels/ListModelsUseCase.js.map +1 -1
  26. package/admin/features/listModels/abstractions.js +4 -3
  27. package/admin/features/listModels/abstractions.js.map +1 -1
  28. package/admin/features/listModels/feature.js +15 -14
  29. package/admin/features/listModels/feature.js.map +1 -1
  30. package/admin/features/listModels/index.js +1 -3
  31. package/admin/features/settings/getSettings/GetSettingsGateway.js +17 -14
  32. package/admin/features/settings/getSettings/GetSettingsGateway.js.map +1 -1
  33. package/admin/features/settings/getSettings/GetSettingsRepository.js +23 -23
  34. package/admin/features/settings/getSettings/GetSettingsRepository.js.map +1 -1
  35. package/admin/features/settings/getSettings/GetSettingsUseCase.js +13 -10
  36. package/admin/features/settings/getSettings/GetSettingsUseCase.js.map +1 -1
  37. package/admin/features/settings/getSettings/abstractions.js +4 -3
  38. package/admin/features/settings/getSettings/abstractions.js.map +1 -1
  39. package/admin/features/settings/getSettings/feature.js +15 -14
  40. package/admin/features/settings/getSettings/feature.js.map +1 -1
  41. package/admin/features/settings/getSettings/index.js +1 -3
  42. package/admin/features/settings/shared/SettingsCache.js +14 -13
  43. package/admin/features/settings/shared/SettingsCache.js.map +1 -1
  44. package/admin/features/settings/shared/abstractions.d.ts +32 -0
  45. package/admin/features/settings/shared/abstractions.js +2 -18
  46. package/admin/features/settings/shared/abstractions.js.map +1 -1
  47. package/admin/features/settings/shared/feature.js +11 -10
  48. package/admin/features/settings/shared/feature.js.map +1 -1
  49. package/admin/features/settings/shared/index.js +0 -2
  50. package/admin/features/settings/updateSettings/UpdateSettingsGateway.js +34 -18
  51. package/admin/features/settings/updateSettings/UpdateSettingsGateway.js.map +1 -1
  52. package/admin/features/settings/updateSettings/UpdateSettingsRepository.js +17 -13
  53. package/admin/features/settings/updateSettings/UpdateSettingsRepository.js.map +1 -1
  54. package/admin/features/settings/updateSettings/UpdateSettingsUseCase.js +13 -10
  55. package/admin/features/settings/updateSettings/UpdateSettingsUseCase.js.map +1 -1
  56. package/admin/features/settings/updateSettings/abstractions.js +4 -3
  57. package/admin/features/settings/updateSettings/abstractions.js.map +1 -1
  58. package/admin/features/settings/updateSettings/feature.js +15 -14
  59. package/admin/features/settings/updateSettings/feature.js.map +1 -1
  60. package/admin/features/settings/updateSettings/index.js +1 -3
  61. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.d.ts +4 -0
  62. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.js +50 -0
  63. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.js.map +1 -0
  64. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPresenter.d.ts +2 -1
  65. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPresenter.js +133 -129
  66. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsPresenter.js.map +1 -1
  67. package/admin/presentation/AiPowerUpsSettings/abstractions.d.ts +2 -1
  68. package/admin/presentation/AiPowerUpsSettings/abstractions.js +2 -1
  69. package/admin/presentation/AiPowerUpsSettings/abstractions.js.map +1 -1
  70. package/admin/presentation/AiPowerUpsSettings/feature.js +20 -16
  71. package/admin/presentation/AiPowerUpsSettings/feature.js.map +1 -1
  72. package/admin/presentation/AiPowerUpsSettings/index.d.ts +0 -3
  73. package/admin/presentation/AiPowerUpsSettings/index.js +0 -5
  74. package/admin/presentation/AiPowerUpsSettings/settingsGroup.js +2 -1
  75. package/admin/presentation/AiPowerUpsSettings/settingsGroup.js.map +1 -1
  76. package/admin/presentation/AiPowerUpsSettings/useAiPowerUpsSettings.js +19 -20
  77. package/admin/presentation/AiPowerUpsSettings/useAiPowerUpsSettings.js.map +1 -1
  78. package/admin/presentation/{PersonasSettings.d.ts → ProjectsSettings.d.ts} +2 -2
  79. package/admin/presentation/ProjectsSettings.js +56 -0
  80. package/admin/presentation/ProjectsSettings.js.map +1 -0
  81. package/admin/presentation/ProvidersSettings.js +39 -33
  82. package/admin/presentation/ProvidersSettings.js.map +1 -1
  83. package/admin/presentation/ReaderPersonasSettings.d.ts +11 -0
  84. package/admin/presentation/ReaderPersonasSettings.js +37 -0
  85. package/admin/presentation/ReaderPersonasSettings.js.map +1 -0
  86. package/admin/presentation/WbContentGeneration/Extension.js +15 -16
  87. package/admin/presentation/WbContentGeneration/Extension.js.map +1 -1
  88. package/admin/presentation/WbContentGeneration/GenerateContentButton.js +12 -17
  89. package/admin/presentation/WbContentGeneration/GenerateContentButton.js.map +1 -1
  90. package/admin/presentation/WbContentGeneration/GenerateContentDialog.js +94 -127
  91. package/admin/presentation/WbContentGeneration/GenerateContentDialog.js.map +1 -1
  92. package/admin/presentation/WbContentGeneration/GenerateContentPresenter.d.ts +19 -5
  93. package/admin/presentation/WbContentGeneration/GenerateContentPresenter.js +214 -77
  94. package/admin/presentation/WbContentGeneration/GenerateContentPresenter.js.map +1 -1
  95. package/admin/presentation/WbContentGeneration/abstractions.d.ts +4 -2
  96. package/admin/presentation/WbContentGeneration/abstractions.js +2 -1
  97. package/admin/presentation/WbContentGeneration/abstractions.js.map +1 -1
  98. package/admin/presentation/WbContentGeneration/decompressGzipBase64.js +10 -11
  99. package/admin/presentation/WbContentGeneration/decompressGzipBase64.js.map +1 -1
  100. package/admin/presentation/WbContentGeneration/feature.js +11 -10
  101. package/admin/presentation/WbContentGeneration/feature.js.map +1 -1
  102. package/admin/presentation/WriterPersonasSettings.d.ts +11 -0
  103. package/admin/presentation/WriterPersonasSettings.js +37 -0
  104. package/admin/presentation/WriterPersonasSettings.js.map +1 -0
  105. package/admin/routes.d.ts +4 -0
  106. package/admin/routes.js +10 -0
  107. package/admin/routes.js.map +1 -0
  108. package/api/Extension.js +28 -11
  109. package/api/Extension.js.map +1 -1
  110. package/api/constants.js +2 -1
  111. package/api/constants.js.map +1 -1
  112. package/api/features/AiImageEnrichment/AiImageEnrichmentAfterCreateHandler.d.ts +11 -0
  113. package/api/features/AiImageEnrichment/AiImageEnrichmentAfterCreateHandler.js +27 -0
  114. package/api/features/AiImageEnrichment/AiImageEnrichmentAfterCreateHandler.js.map +1 -0
  115. package/api/features/AiImageEnrichment/AiImageEnrichmentTask.d.ts +34 -0
  116. package/api/features/AiImageEnrichment/AiImageEnrichmentTask.js +140 -0
  117. package/api/features/AiImageEnrichment/AiImageEnrichmentTask.js.map +1 -0
  118. package/api/features/AiImageEnrichment/feature.d.ts +4 -0
  119. package/api/features/AiImageEnrichment/feature.js +13 -0
  120. package/api/features/AiImageEnrichment/feature.js.map +1 -0
  121. package/api/features/AiPromptContext/AiPromptContextBuilder.d.ts +12 -0
  122. package/api/features/AiPromptContext/AiPromptContextBuilder.js +103 -0
  123. package/api/features/AiPromptContext/AiPromptContextBuilder.js.map +1 -0
  124. package/api/features/AiPromptContext/ProjectFileAssembler.d.ts +22 -0
  125. package/api/features/AiPromptContext/ProjectFileAssembler.js +76 -0
  126. package/api/features/AiPromptContext/ProjectFileAssembler.js.map +1 -0
  127. package/api/features/AiPromptContext/ProjectFileCache.d.ts +16 -0
  128. package/api/features/AiPromptContext/ProjectFileCache.js +61 -0
  129. package/api/features/AiPromptContext/ProjectFileCache.js.map +1 -0
  130. package/api/features/AiPromptContext/ProjectSection.d.ts +4 -0
  131. package/api/features/AiPromptContext/ProjectSection.js +35 -0
  132. package/api/features/AiPromptContext/ProjectSection.js.map +1 -0
  133. package/api/features/AiPromptContext/ReadProjectFileTool.d.ts +3 -0
  134. package/api/features/AiPromptContext/ReadProjectFileTool.js +36 -0
  135. package/api/features/AiPromptContext/ReadProjectFileTool.js.map +1 -0
  136. package/api/features/AiPromptContext/ReaderPersonaSection.d.ts +4 -0
  137. package/api/features/AiPromptContext/ReaderPersonaSection.js +10 -0
  138. package/api/features/AiPromptContext/ReaderPersonaSection.js.map +1 -0
  139. package/api/features/AiPromptContext/WriterPersonaSection.d.ts +4 -0
  140. package/api/features/AiPromptContext/WriterPersonaSection.js +10 -0
  141. package/api/features/AiPromptContext/WriterPersonaSection.js.map +1 -0
  142. package/api/features/AiPromptContext/abstractions.d.ts +68 -0
  143. package/api/features/AiPromptContext/abstractions.js +7 -0
  144. package/api/features/AiPromptContext/abstractions.js.map +1 -0
  145. package/api/features/AiPromptContext/feature.d.ts +4 -0
  146. package/api/features/AiPromptContext/feature.js +15 -0
  147. package/api/features/AiPromptContext/feature.js.map +1 -0
  148. package/api/features/AiPromptContext/index.d.ts +1 -0
  149. package/api/features/AiPromptContext/index.js +1 -0
  150. package/api/features/ExtractFrontmatter/ExtractFrontmatterBeforeCreateHandler.d.ts +11 -0
  151. package/api/features/ExtractFrontmatter/ExtractFrontmatterBeforeCreateHandler.js +34 -0
  152. package/api/features/ExtractFrontmatter/ExtractFrontmatterBeforeCreateHandler.js.map +1 -0
  153. package/api/features/ExtractFrontmatter/feature.d.ts +4 -0
  154. package/api/features/ExtractFrontmatter/feature.js +11 -0
  155. package/api/features/ExtractFrontmatter/feature.js.map +1 -0
  156. package/api/features/GetSettings/GetSettingsRepository.d.ts +3 -2
  157. package/api/features/GetSettings/GetSettingsRepository.js +29 -26
  158. package/api/features/GetSettings/GetSettingsRepository.js.map +1 -1
  159. package/api/features/GetSettings/GetSettingsUseCase.js +13 -10
  160. package/api/features/GetSettings/GetSettingsUseCase.js.map +1 -1
  161. package/api/features/GetSettings/abstractions.js +3 -2
  162. package/api/features/GetSettings/abstractions.js.map +1 -1
  163. package/api/features/GetSettings/feature.js +7 -6
  164. package/api/features/GetSettings/feature.js.map +1 -1
  165. package/api/features/GetSettings/index.js +0 -2
  166. package/api/features/Projects/ProjectsHandler.d.ts +31 -0
  167. package/api/features/Projects/ProjectsHandler.js +103 -0
  168. package/api/features/Projects/ProjectsHandler.js.map +1 -0
  169. package/api/features/Projects/feature.d.ts +4 -0
  170. package/api/features/Projects/feature.js +11 -0
  171. package/api/features/Projects/feature.js.map +1 -0
  172. package/api/features/Projects/types.d.ts +50 -0
  173. package/api/features/Projects/types.js +0 -0
  174. package/api/features/Providers/ProvidersGraphQLMapper.js +33 -30
  175. package/api/features/Providers/ProvidersGraphQLMapper.js.map +1 -1
  176. package/api/features/Providers/ProvidersHandler.js +67 -64
  177. package/api/features/Providers/ProvidersHandler.js.map +1 -1
  178. package/api/features/Providers/feature.js +7 -6
  179. package/api/features/Providers/feature.js.map +1 -1
  180. package/api/features/Providers/index.js +0 -3
  181. package/api/features/Providers/types.js +0 -3
  182. package/api/features/ReaderPersonas/ReaderPersonasHandler.d.ts +20 -0
  183. package/api/features/ReaderPersonas/ReaderPersonasHandler.js +43 -0
  184. package/api/features/ReaderPersonas/ReaderPersonasHandler.js.map +1 -0
  185. package/api/features/ReaderPersonas/feature.d.ts +4 -0
  186. package/api/features/ReaderPersonas/feature.js +11 -0
  187. package/api/features/ReaderPersonas/feature.js.map +1 -0
  188. package/api/features/ReaderPersonas/index.d.ts +2 -0
  189. package/api/features/ReaderPersonas/index.js +1 -0
  190. package/api/features/ReaderPersonas/types.d.ts +24 -0
  191. package/api/features/ReaderPersonas/types.js +0 -0
  192. package/api/features/UpdateSettings/UpdateSettingsRepository.d.ts +3 -2
  193. package/api/features/UpdateSettings/UpdateSettingsRepository.js +59 -62
  194. package/api/features/UpdateSettings/UpdateSettingsRepository.js.map +1 -1
  195. package/api/features/UpdateSettings/UpdateSettingsUseCase.js +23 -21
  196. package/api/features/UpdateSettings/UpdateSettingsUseCase.js.map +1 -1
  197. package/api/features/UpdateSettings/abstractions.js +5 -7
  198. package/api/features/UpdateSettings/abstractions.js.map +1 -1
  199. package/api/features/UpdateSettings/errors.d.ts +10 -0
  200. package/api/features/UpdateSettings/errors.js +14 -0
  201. package/api/features/UpdateSettings/errors.js.map +1 -0
  202. package/api/features/UpdateSettings/events.js +16 -11
  203. package/api/features/UpdateSettings/events.js.map +1 -1
  204. package/api/features/UpdateSettings/feature.js +7 -6
  205. package/api/features/UpdateSettings/feature.js.map +1 -1
  206. package/api/features/UpdateSettings/index.js +1 -3
  207. package/api/features/WbGeneratePageContent/WbGeneratePageContentTask.d.ts +4 -0
  208. package/api/features/WbGeneratePageContent/WbGeneratePageContentTask.js +63 -60
  209. package/api/features/WbGeneratePageContent/WbGeneratePageContentTask.js.map +1 -1
  210. package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.d.ts +5 -3
  211. package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js +92 -53
  212. package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js.map +1 -1
  213. package/api/features/WbGeneratePageContent/abstractions.d.ts +15 -1
  214. package/api/features/WbGeneratePageContent/abstractions.js +2 -1
  215. package/api/features/WbGeneratePageContent/abstractions.js.map +1 -1
  216. package/api/features/WbGeneratePageContent/buildPrompt.d.ts +1 -1
  217. package/api/features/WbGeneratePageContent/buildPrompt.js +11 -10
  218. package/api/features/WbGeneratePageContent/buildPrompt.js.map +1 -1
  219. package/api/features/WbGeneratePageContent/feature.js +7 -6
  220. package/api/features/WbGeneratePageContent/feature.js.map +1 -1
  221. package/api/features/WbGeneratePageContent/index.js +0 -2
  222. package/api/features/WriterPersonas/WriterPersonasHandler.d.ts +20 -0
  223. package/api/features/WriterPersonas/WriterPersonasHandler.js +43 -0
  224. package/api/features/WriterPersonas/WriterPersonasHandler.js.map +1 -0
  225. package/api/features/WriterPersonas/feature.d.ts +4 -0
  226. package/api/features/WriterPersonas/feature.js +11 -0
  227. package/api/features/WriterPersonas/feature.js.map +1 -0
  228. package/api/features/WriterPersonas/index.d.ts +2 -0
  229. package/api/features/WriterPersonas/index.js +1 -0
  230. package/api/features/WriterPersonas/types.d.ts +24 -0
  231. package/api/features/WriterPersonas/types.js +0 -0
  232. package/api/features/shared/SettingsCache.d.ts +12 -0
  233. package/api/features/shared/SettingsCache.js +22 -0
  234. package/api/features/shared/SettingsCache.js.map +1 -0
  235. package/api/features/shared/abstractions.d.ts +13 -0
  236. package/api/features/shared/abstractions.js +4 -2
  237. package/api/features/shared/abstractions.js.map +1 -1
  238. package/api/features/shared/index.d.ts +3 -1
  239. package/api/features/shared/index.js +1 -3
  240. package/api/graphql/AiPowerUpsSettingsGraphQLMapper.js +35 -26
  241. package/api/graphql/AiPowerUpsSettingsGraphQLMapper.js.map +1 -1
  242. package/api/graphql/BaseGraphQLSchema.js +98 -81
  243. package/api/graphql/BaseGraphQLSchema.js.map +1 -1
  244. package/api/graphql/abstractions.js +2 -1
  245. package/api/graphql/abstractions.js.map +1 -1
  246. package/api/types.d.ts +1 -0
  247. package/api/types.js +1 -4
  248. package/index.js +0 -2
  249. package/package.json +26 -24
  250. package/admin/features/generatePageContent/index.js.map +0 -1
  251. package/admin/features/listModels/index.js.map +0 -1
  252. package/admin/features/settings/getSettings/index.js.map +0 -1
  253. package/admin/features/settings/shared/index.js.map +0 -1
  254. package/admin/features/settings/updateSettings/index.js.map +0 -1
  255. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsConfig.d.ts +0 -2
  256. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsConfig.js +0 -11
  257. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsConfig.js.map +0 -1
  258. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsDialog.d.ts +0 -5
  259. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsDialog.js +0 -58
  260. package/admin/presentation/AiPowerUpsSettings/AiPowerUpsSettingsDialog.js.map +0 -1
  261. package/admin/presentation/AiPowerUpsSettings/index.js.map +0 -1
  262. package/admin/presentation/AiPowerUpsSettings/useAiPowerUpsSettingsDialog.d.ts +0 -1
  263. package/admin/presentation/AiPowerUpsSettings/useAiPowerUpsSettingsDialog.js +0 -12
  264. package/admin/presentation/AiPowerUpsSettings/useAiPowerUpsSettingsDialog.js.map +0 -1
  265. package/admin/presentation/PersonasSettings.js +0 -29
  266. package/admin/presentation/PersonasSettings.js.map +0 -1
  267. package/api/features/GetSettings/index.js.map +0 -1
  268. package/api/features/Providers/index.js.map +0 -1
  269. package/api/features/Providers/types.js.map +0 -1
  270. package/api/features/UpdateSettings/index.js.map +0 -1
  271. package/api/features/WbGeneratePageContent/index.js.map +0 -1
  272. package/api/features/shared/index.js.map +0 -1
  273. package/api/types.js.map +0 -1
  274. package/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"names":["makeAutoObservable","computed","toJS","z","pick","ToolRegistry","ToolPipelineRunner","GenerateContentPresenter","GeneratePageContentUseCase","runInAction","GenerateContentPresenterImpl","_prompt","_submitting","_processing","_components","_createElements","constructor","toolRegistry","pipelineRunner","generatePageContent","vm","autoBind","prompt","submitting","processing","init","components","createElements","setPrompt","value","submit","tools","getTools","map","tool","name","description","inputSchema","toJSONSchema","outputSchema","execute","processAiResponse","responseText","aiResponseJson","JSON","parse","resolved","resolve","items","Array","isArray","element","componentName","component","parentId","slot","bindings","inputs","e","console","error","cancelPrompt","GenerateContentPresenterRegistration","createImplementation","implementation","dependencies"],"sources":["GenerateContentPresenter.ts"],"sourcesContent":["import { makeAutoObservable, computed, toJS } from \"mobx\";\nimport { z } from \"zod\";\nimport pick from \"lodash/pick.js\";\nimport { ToolRegistry, ToolPipelineRunner } from \"@webiny/app-admin\";\nimport { GenerateContentPresenter, type CreateElementsFn } from \"./abstractions.js\";\nimport { GeneratePageContentUseCase } from \"~/admin/features/generatePageContent/index.js\";\nimport { runInAction } from \"mobx\";\n\nclass GenerateContentPresenterImpl implements GenerateContentPresenter.Interface {\n private _prompt = \"\";\n private _submitting = false;\n private _processing = false;\n private _components: Record<string, any>[] = [];\n private _createElements: CreateElementsFn = () => {};\n\n constructor(\n private toolRegistry: ToolRegistry.Interface,\n private pipelineRunner: ToolPipelineRunner.Interface,\n private generatePageContent: GeneratePageContentUseCase.Interface\n ) {\n makeAutoObservable(this, { vm: computed }, { autoBind: true });\n }\n\n get vm(): GenerateContentPresenter.ViewModel {\n return {\n prompt: this._prompt,\n submitting: this._submitting,\n processing: this._processing\n };\n }\n\n init(components: Record<string, any>[], createElements: CreateElementsFn): void {\n this._components = components;\n this._createElements = createElements;\n }\n\n setPrompt(value: string): void {\n this._prompt = value;\n }\n\n async submit(): Promise<void> {\n this._submitting = true;\n\n try {\n const tools = this.toolRegistry.getTools().map(tool => ({\n name: tool.name,\n description: tool.description,\n inputSchema: pick(z.toJSONSchema(tool.inputSchema), [\"properties\", \"type\"]),\n outputSchema: pick(z.toJSONSchema(tool.outputSchema), [\"properties\", \"type\"])\n }));\n\n await this.generatePageContent.execute({\n prompt: this._prompt,\n components: toJS(this._components),\n tools\n });\n } catch {\n runInAction(() => {\n this._submitting = false;\n });\n }\n }\n\n async processAiResponse(responseText: string): Promise<void> {\n this._processing = true;\n this._submitting = false;\n\n try {\n const aiResponseJson = JSON.parse(responseText);\n const resolved = await this.pipelineRunner.resolve(aiResponseJson);\n const items = Array.isArray(resolved) ? resolved : [resolved];\n\n this._createElements(\n items.map((element: { component: string; inputs: Record<string, unknown> }) => ({\n componentName: element.component,\n parentId: \"root\",\n slot: \"children\",\n bindings: { inputs: element.inputs }\n }))\n );\n } catch (e) {\n console.error(e);\n } finally {\n runInAction(() => {\n this._processing = false;\n });\n }\n }\n\n cancelPrompt(): void {\n this._processing = false;\n this._submitting = false;\n }\n}\n\nexport const GenerateContentPresenterRegistration = GenerateContentPresenter.createImplementation({\n implementation: GenerateContentPresenterImpl,\n dependencies: [ToolRegistry, ToolPipelineRunner, GeneratePageContentUseCase]\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"admin/presentation/WbContentGeneration/GenerateContentPresenter.js","sources":["../../../../src/admin/presentation/WbContentGeneration/GenerateContentPresenter.ts"],"sourcesContent":["import { makeAutoObservable, computed, toJS, runInAction } from \"mobx\";\nimport { z } from \"zod\";\nimport pick from \"lodash/pick.js\";\nimport { FormModelFactory, FormModel, ToolRegistry, ToolPipelineRunner } from \"@webiny/app-admin\";\nimport { GenerateContentPresenter, type CreateElementsFn } from \"./abstractions.js\";\nimport { GeneratePageContentUseCase } from \"~/admin/features/generatePageContent/index.js\";\nimport { GetSettingsUseCase } from \"~/admin/features/settings/getSettings/abstractions.js\";\nimport type { IAiPowerUpsSettings } from \"~/admin/features/settings/shared/abstractions.js\";\n\nconst SUBMIT_TIMEOUT_MS = 300_000;\n\nclass GenerateContentPresenterImpl implements GenerateContentPresenter.Interface {\n private _loading = false;\n private _submitting = false;\n private _processing = false;\n private _timedOut = false;\n private _components: Record<string, any>[] = [];\n private _createElements: CreateElementsFn = () => {};\n private _form: FormModel.Interface | null = null;\n private _settings: IAiPowerUpsSettings | null = null;\n private _timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n private toolRegistry: ToolRegistry.Interface,\n private pipelineRunner: ToolPipelineRunner.Interface,\n private generatePageContent: GeneratePageContentUseCase.Interface,\n private formModelFactory: FormModelFactory.Interface,\n private getSettings: GetSettingsUseCase.Interface\n ) {\n makeAutoObservable(this, { vm: computed }, { autoBind: true });\n }\n\n get vm(): GenerateContentPresenter.ViewModel {\n return {\n form: this._form ? this._form.vm : null,\n loading: this._loading,\n submitting: this._submitting,\n processing: this._processing,\n timedOut: this._timedOut\n };\n }\n\n async init(components: Record<string, any>[], createElements: CreateElementsFn): Promise<void> {\n this._components = components;\n this._createElements = createElements;\n\n this._loading = true;\n\n try {\n const settings = await this.getSettings.execute();\n runInAction(() => {\n this._settings = settings;\n this._form = this.buildForm();\n });\n } finally {\n runInAction(() => {\n this._loading = false;\n });\n }\n }\n\n async submit(): Promise<void> {\n if (!this._form) {\n return;\n }\n\n const data = await this._form.submit<{\n prompt: string;\n project?: string;\n includedFiles?: string[];\n readerPersona?: string;\n writerPersona?: string;\n }>();\n\n if (!data) {\n return;\n }\n\n runInAction(() => {\n this._submitting = true;\n this._timedOut = false;\n });\n\n this.startTimeout();\n\n try {\n const tools = this.toolRegistry.getTools().map(tool => ({\n name: tool.name,\n description: tool.description,\n inputSchema: pick(z.toJSONSchema(tool.inputSchema), [\"properties\", \"type\"]),\n outputSchema: pick(z.toJSONSchema(tool.outputSchema), [\"properties\", \"type\"])\n }));\n\n const excludedFileIds = this.computeExcludedFileIds(data.project, data.includedFiles);\n\n await this.generatePageContent.execute({\n prompt: data.prompt,\n components: toJS(this._components),\n tools,\n projectId: data.project || null,\n excludedFileIds,\n readerPersonaId: data.readerPersona || null,\n writerPersonaId: data.writerPersona || null\n });\n } catch {\n this.clearTimeout();\n runInAction(() => {\n this._submitting = false;\n });\n }\n }\n\n async processAiResponse(responseText: string): Promise<void> {\n this.clearTimeout();\n runInAction(() => {\n this._processing = true;\n this._submitting = false;\n });\n\n try {\n const aiResponseJson = JSON.parse(responseText);\n const resolved = await this.pipelineRunner.resolve(aiResponseJson);\n const items = Array.isArray(resolved) ? resolved : [resolved];\n\n this._createElements(\n items.map((element: { component: string; inputs: Record<string, unknown> }) => ({\n componentName: element.component,\n parentId: \"root\",\n slot: \"children\",\n bindings: { inputs: element.inputs }\n }))\n );\n } catch (e) {\n console.error(e);\n } finally {\n runInAction(() => {\n this._processing = false;\n });\n }\n }\n\n cancelPrompt(): void {\n this.clearTimeout();\n this._processing = false;\n this._submitting = false;\n }\n\n private startTimeout(): void {\n this.clearTimeout();\n this._timeoutId = setTimeout(() => {\n runInAction(() => {\n this._submitting = false;\n this._timedOut = true;\n });\n }, SUBMIT_TIMEOUT_MS);\n }\n\n private clearTimeout(): void {\n if (this._timeoutId !== null) {\n clearTimeout(this._timeoutId);\n this._timeoutId = null;\n }\n }\n\n private buildForm() {\n return this.formModelFactory.create({\n fields: fields => ({\n project: fields\n .text()\n .label(\"Project\")\n .description(\"Select a predefined context to attach.\")\n .options(() => this.getProjectOptions())\n .afterChange((value, form) => {\n const projectId = value as string | undefined;\n const project = projectId\n ? this._settings?.projects?.presets?.find(p => p.id === projectId)\n : undefined;\n\n if (project?.defaultReaderPersonaId) {\n form.field(\"readerPersona\").setValue(project.defaultReaderPersonaId);\n }\n if (project?.defaultWriterPersonaId) {\n form.field(\"writerPersona\").setValue(project.defaultWriterPersonaId);\n }\n\n const fileIds = (project?.files ?? []).map(f => f.id);\n form.field(\"includedFiles\").setValue(fileIds);\n }),\n includedFiles: fields\n .text()\n .label(\"Files included\")\n .description(\"Uncheck files to exclude them from this generation only.\")\n .options(() => this.getProjectFileOptions())\n .renderer(\"checkboxes\")\n .list()\n .hiddenWhen(form => {\n const projectId = form.field(\"project\").as(\"text\").getValue();\n if (!projectId) {\n return true;\n }\n const project = this._settings?.projects?.presets?.find(\n p => p.id === projectId\n );\n return !project?.files || project.files.length === 0;\n }),\n readerPersona: fields\n .text()\n .label(\"Reader Persona\")\n .description(\"Select the target audience for the generated content.\")\n .options(() => this.getPersonaOptions(\"reader\")),\n writerPersona: fields\n .text()\n .label(\"Writer Persona\")\n .description(\"Select the writing style for the generated content.\")\n .options(() => this.getPersonaOptions(\"writer\")),\n prompt: fields\n .text()\n .label(\"Prompt\")\n .description(\"Describe the page content you want to generate.\")\n .required(\"Prompt is required\")\n .renderer(\"textarea\", { rows: 6 })\n }),\n layout: layout => [\n layout.row(\"project\"),\n layout.row(\"includedFiles\"),\n layout.row(\"readerPersona\"),\n layout.row(\"writerPersona\"),\n layout.row(\"prompt\")\n ]\n });\n }\n\n private getSelectedProject() {\n if (!this._form || !this._settings) {\n return undefined;\n }\n const projectId = this._form.field(\"project\").getValue<string>();\n if (!projectId) {\n return undefined;\n }\n return this._settings.projects?.presets?.find(p => p.id === projectId);\n }\n\n private getProjectFileOptions() {\n const project = this.getSelectedProject();\n const files = project?.files;\n if (!files || files.length === 0) {\n return [];\n }\n return files.map(f => ({\n label: f.name,\n value: f.id\n }));\n }\n\n private computeExcludedFileIds(projectId?: string, includedFiles?: string[]): string[] | null {\n if (!projectId) {\n return null;\n }\n const project = this._settings?.projects?.presets?.find(p => p.id === projectId);\n const allFileIds = (project?.files ?? []).map(f => f.id);\n if (allFileIds.length === 0) {\n return null;\n }\n const included = new Set(includedFiles ?? []);\n const excluded = allFileIds.filter(id => !included.has(id));\n return excluded.length > 0 ? excluded : null;\n }\n\n private getProjectOptions() {\n const presets = this._settings?.projects?.presets;\n if (!presets || presets.length === 0) {\n return [];\n }\n return presets.map(preset => ({\n label: preset.name,\n value: preset.id\n }));\n }\n\n private getPersonaOptions(type: \"reader\" | \"writer\") {\n const presets =\n type === \"reader\"\n ? this._settings?.readerPersonas?.presets\n : this._settings?.writerPersonas?.presets;\n\n if (!presets || presets.length === 0) {\n return [];\n }\n\n return presets.map(preset => ({\n label: preset.name,\n value: preset.id\n }));\n }\n}\n\nexport const GenerateContentPresenterRegistration = GenerateContentPresenter.createImplementation({\n implementation: GenerateContentPresenterImpl,\n dependencies: [\n ToolRegistry,\n ToolPipelineRunner,\n GeneratePageContentUseCase,\n FormModelFactory,\n GetSettingsUseCase\n ]\n});\n"],"names":["SUBMIT_TIMEOUT_MS","GenerateContentPresenterImpl","toolRegistry","pipelineRunner","generatePageContent","formModelFactory","getSettings","makeAutoObservable","computed","components","createElements","settings","runInAction","data","tools","tool","pick","z","excludedFileIds","toJS","responseText","aiResponseJson","JSON","resolved","items","Array","element","e","console","setTimeout","clearTimeout","fields","value","form","projectId","project","p","undefined","fileIds","f","layout","files","includedFiles","allFileIds","included","Set","excluded","id","presets","preset","type","GenerateContentPresenterRegistration","GenerateContentPresenter","ToolRegistry","ToolPipelineRunner","GeneratePageContentUseCase","FormModelFactory","GetSettingsUseCase"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { IFormVM } from "@webiny/app-admin/features/formModel/abstractions.js";
1
2
  export type CreateElementParams = {
2
3
  componentName: string;
3
4
  parentId: string;
@@ -9,14 +10,15 @@ export type CreateElementParams = {
9
10
  };
10
11
  export type CreateElementsFn = (elements: CreateElementParams[]) => void;
11
12
  export interface IGenerateContentVm {
12
- prompt: string;
13
+ form: IFormVM | null;
14
+ loading: boolean;
13
15
  submitting: boolean;
14
16
  processing: boolean;
17
+ timedOut: boolean;
15
18
  }
16
19
  export interface IGenerateContentPresenter {
17
20
  readonly vm: IGenerateContentVm;
18
21
  init(components: Record<string, any>[], createElements: CreateElementsFn): void;
19
- setPrompt(value: string): void;
20
22
  submit(): Promise<void>;
21
23
  cancelPrompt(): void;
22
24
  processAiResponse(responseText: string): Promise<void>;
@@ -1,4 +1,5 @@
1
1
  import { createAbstraction } from "@webiny/feature/admin";
2
- export const GenerateContentPresenter = createAbstraction("WbContentGeneration/Presenter");
2
+ const GenerateContentPresenter = createAbstraction("WbContentGeneration/Presenter");
3
+ export { GenerateContentPresenter };
3
4
 
4
5
  //# sourceMappingURL=abstractions.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["createAbstraction","GenerateContentPresenter"],"sources":["abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\n\nexport type CreateElementParams = {\n componentName: string;\n parentId: string;\n slot: string;\n index?: number;\n bindings?: { inputs?: Record<string, unknown> };\n};\n\nexport type CreateElementsFn = (elements: CreateElementParams[]) => void;\n\nexport interface IGenerateContentVm {\n prompt: string;\n submitting: boolean;\n processing: boolean;\n}\n\nexport interface IGenerateContentPresenter {\n readonly vm: IGenerateContentVm;\n init(components: Record<string, any>[], createElements: CreateElementsFn): void;\n setPrompt(value: string): void;\n submit(): Promise<void>;\n cancelPrompt(): void;\n processAiResponse(responseText: string): Promise<void>;\n}\n\nexport const GenerateContentPresenter = createAbstraction<IGenerateContentPresenter>(\n \"WbContentGeneration/Presenter\"\n);\n\nexport namespace GenerateContentPresenter {\n export type Interface = IGenerateContentPresenter;\n export type ViewModel = IGenerateContentVm;\n}\n"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,uBAAuB;AA2BzD,OAAO,MAAMC,wBAAwB,GAAGD,iBAAiB,CACrD,+BACJ,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"admin/presentation/WbContentGeneration/abstractions.js","sources":["../../../../src/admin/presentation/WbContentGeneration/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { IFormVM } from \"@webiny/app-admin/features/formModel/abstractions.js\";\n\nexport type CreateElementParams = {\n componentName: string;\n parentId: string;\n slot: string;\n index?: number;\n bindings?: { inputs?: Record<string, unknown> };\n};\n\nexport type CreateElementsFn = (elements: CreateElementParams[]) => void;\n\nexport interface IGenerateContentVm {\n form: IFormVM | null;\n loading: boolean;\n submitting: boolean;\n processing: boolean;\n timedOut: boolean;\n}\n\nexport interface IGenerateContentPresenter {\n readonly vm: IGenerateContentVm;\n init(components: Record<string, any>[], createElements: CreateElementsFn): void;\n submit(): Promise<void>;\n cancelPrompt(): void;\n processAiResponse(responseText: string): Promise<void>;\n}\n\nexport const GenerateContentPresenter = createAbstraction<IGenerateContentPresenter>(\n \"WbContentGeneration/Presenter\"\n);\n\nexport namespace GenerateContentPresenter {\n export type Interface = IGenerateContentPresenter;\n export type ViewModel = IGenerateContentVm;\n}\n"],"names":["GenerateContentPresenter","createAbstraction"],"mappings":";AA6BO,MAAMA,2BAA2BC,kBACpC"}
@@ -1,14 +1,13 @@
1
- export async function decompressGzipBase64(base64) {
2
- const binary = atob(base64);
3
- const bytes = new Uint8Array(binary.length);
4
- for (let i = 0; i < binary.length; i++) {
5
- bytes[i] = binary.charCodeAt(i);
6
- }
7
- const ds = new DecompressionStream("gzip");
8
- const writer = ds.writable.getWriter();
9
- writer.write(bytes);
10
- writer.close();
11
- return new Response(ds.readable).text();
1
+ async function decompressGzipBase64(base64) {
2
+ const binary = atob(base64);
3
+ const bytes = new Uint8Array(binary.length);
4
+ for(let i = 0; i < binary.length; i++)bytes[i] = binary.charCodeAt(i);
5
+ const ds = new DecompressionStream("gzip");
6
+ const writer = ds.writable.getWriter();
7
+ writer.write(bytes);
8
+ writer.close();
9
+ return new Response(ds.readable).text();
12
10
  }
11
+ export { decompressGzipBase64 };
13
12
 
14
13
  //# sourceMappingURL=decompressGzipBase64.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["decompressGzipBase64","base64","binary","atob","bytes","Uint8Array","length","i","charCodeAt","ds","DecompressionStream","writer","writable","getWriter","write","close","Response","readable","text"],"sources":["decompressGzipBase64.ts"],"sourcesContent":["export async function decompressGzipBase64(base64: string): Promise<string> {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const ds = new DecompressionStream(\"gzip\");\n const writer = ds.writable.getWriter();\n writer.write(bytes);\n writer.close();\n return new Response(ds.readable).text();\n}\n"],"mappings":"AAAA,OAAO,eAAeA,oBAAoBA,CAACC,MAAc,EAAmB;EACxE,MAAMC,MAAM,GAAGC,IAAI,CAACF,MAAM,CAAC;EAC3B,MAAMG,KAAK,GAAG,IAAIC,UAAU,CAACH,MAAM,CAACI,MAAM,CAAC;EAC3C,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGL,MAAM,CAACI,MAAM,EAAEC,CAAC,EAAE,EAAE;IACpCH,KAAK,CAACG,CAAC,CAAC,GAAGL,MAAM,CAACM,UAAU,CAACD,CAAC,CAAC;EACnC;EACA,MAAME,EAAE,GAAG,IAAIC,mBAAmB,CAAC,MAAM,CAAC;EAC1C,MAAMC,MAAM,GAAGF,EAAE,CAACG,QAAQ,CAACC,SAAS,CAAC,CAAC;EACtCF,MAAM,CAACG,KAAK,CAACV,KAAK,CAAC;EACnBO,MAAM,CAACI,KAAK,CAAC,CAAC;EACd,OAAO,IAAIC,QAAQ,CAACP,EAAE,CAACQ,QAAQ,CAAC,CAACC,IAAI,CAAC,CAAC;AAC3C","ignoreList":[]}
1
+ {"version":3,"file":"admin/presentation/WbContentGeneration/decompressGzipBase64.js","sources":["../../../../src/admin/presentation/WbContentGeneration/decompressGzipBase64.ts"],"sourcesContent":["export async function decompressGzipBase64(base64: string): Promise<string> {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const ds = new DecompressionStream(\"gzip\");\n const writer = ds.writable.getWriter();\n writer.write(bytes);\n writer.close();\n return new Response(ds.readable).text();\n}\n"],"names":["decompressGzipBase64","base64","binary","atob","bytes","Uint8Array","i","ds","DecompressionStream","writer","Response"],"mappings":"AAAO,eAAeA,qBAAqBC,MAAc;IACrD,MAAMC,SAASC,KAAKF;IACpB,MAAMG,QAAQ,IAAIC,WAAWH,OAAO,MAAM;IAC1C,IAAK,IAAII,IAAI,GAAGA,IAAIJ,OAAO,MAAM,EAAEI,IAC/BF,KAAK,CAACE,EAAE,GAAGJ,OAAO,UAAU,CAACI;IAEjC,MAAMC,KAAK,IAAIC,oBAAoB;IACnC,MAAMC,SAASF,GAAG,QAAQ,CAAC,SAAS;IACpCE,OAAO,KAAK,CAACL;IACbK,OAAO,KAAK;IACZ,OAAO,IAAIC,SAASH,GAAG,QAAQ,EAAE,IAAI;AACzC"}
@@ -1,16 +1,17 @@
1
1
  import { createFeature } from "@webiny/feature/admin";
2
2
  import { GenerateContentPresenter } from "./abstractions.js";
3
3
  import { GenerateContentPresenterRegistration } from "./GenerateContentPresenter.js";
4
- export const GenerateContentFeature = createFeature({
5
- name: "WbContentGeneration/Presenter",
6
- register(container) {
7
- container.register(GenerateContentPresenterRegistration);
8
- },
9
- resolve(container) {
10
- return {
11
- presenter: container.resolve(GenerateContentPresenter)
12
- };
13
- }
4
+ const GenerateContentFeature = createFeature({
5
+ name: "WbContentGeneration/Presenter",
6
+ register (container) {
7
+ container.register(GenerateContentPresenterRegistration);
8
+ },
9
+ resolve (container) {
10
+ return {
11
+ presenter: container.resolve(GenerateContentPresenter)
12
+ };
13
+ }
14
14
  });
15
+ export { GenerateContentFeature };
15
16
 
16
17
  //# sourceMappingURL=feature.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["createFeature","GenerateContentPresenter","GenerateContentPresenterRegistration","GenerateContentFeature","name","register","container","resolve","presenter"],"sources":["feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { GenerateContentPresenter } from \"./abstractions.js\";\nimport { GenerateContentPresenterRegistration } from \"./GenerateContentPresenter.js\";\n\nexport const GenerateContentFeature = createFeature({\n name: \"WbContentGeneration/Presenter\",\n register(container) {\n container.register(GenerateContentPresenterRegistration);\n },\n resolve(container) {\n return {\n presenter: container.resolve(GenerateContentPresenter)\n };\n }\n});\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,uBAAuB;AACrD,SAASC,wBAAwB;AACjC,SAASC,oCAAoC;AAE7C,OAAO,MAAMC,sBAAsB,GAAGH,aAAa,CAAC;EAChDI,IAAI,EAAE,+BAA+B;EACrCC,QAAQA,CAACC,SAAS,EAAE;IAChBA,SAAS,CAACD,QAAQ,CAACH,oCAAoC,CAAC;EAC5D,CAAC;EACDK,OAAOA,CAACD,SAAS,EAAE;IACf,OAAO;MACHE,SAAS,EAAEF,SAAS,CAACC,OAAO,CAACN,wBAAwB;IACzD,CAAC;EACL;AACJ,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"admin/presentation/WbContentGeneration/feature.js","sources":["../../../../src/admin/presentation/WbContentGeneration/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { GenerateContentPresenter } from \"./abstractions.js\";\nimport { GenerateContentPresenterRegistration } from \"./GenerateContentPresenter.js\";\n\nexport const GenerateContentFeature = createFeature({\n name: \"WbContentGeneration/Presenter\",\n register(container) {\n container.register(GenerateContentPresenterRegistration);\n },\n resolve(container) {\n return {\n presenter: container.resolve(GenerateContentPresenter)\n };\n }\n});\n"],"names":["GenerateContentFeature","createFeature","container","GenerateContentPresenterRegistration","GenerateContentPresenter"],"mappings":";;;AAIO,MAAMA,yBAAyBC,cAAc;IAChD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;IACA,SAAQD,SAAS;QACb,OAAO;YACH,WAAWA,UAAU,OAAO,CAACE;QACjC;IACJ;AACJ"}
@@ -0,0 +1,11 @@
1
+ import { AiPowerUpsSettingsGroup } from "./AiPowerUpsSettings/settingsGroup.js";
2
+ declare class WriterPersonasSettingsImpl implements AiPowerUpsSettingsGroup.Interface {
3
+ name: string;
4
+ label: string;
5
+ description: string;
6
+ buildForm(form: AiPowerUpsSettingsGroup.FormBuilder): void;
7
+ }
8
+ export declare const WriterPersonasSettings: typeof WriterPersonasSettingsImpl & {
9
+ __abstraction: import("@webiny/di").Abstraction<import("./AiPowerUpsSettings/settingsGroup.js").IAiPowerUpsSettingsGroup>;
10
+ };
11
+ export {};
@@ -0,0 +1,37 @@
1
+ import { generateAlphaNumericId } from "@webiny/utils";
2
+ import { AiPowerUpsSettingsGroup } from "./AiPowerUpsSettings/settingsGroup.js";
3
+ class WriterPersonasSettingsImpl {
4
+ buildForm(form) {
5
+ form.fields((fields)=>({
6
+ presets: fields.object().label("Presets").renderer("objectAccordionMultiple", {
7
+ container: false,
8
+ addItemLabel: "Add writer persona",
9
+ itemTitle: (data, index)=>String(data.name || `Writer Persona #${index + 1}`)
10
+ }).fields((f)=>({
11
+ id: f.text().hidden().defaultValue(()=>generateAlphaNumericId(10)),
12
+ name: f.text().label("Name").required("Name is required").description("This name will be used to identify the writer persona in the UI."),
13
+ description: f.text().label("Description").required("Description is required").description("Describe how this persona writes and communicates. This will be used when prompting AI.").renderer("textarea", {
14
+ rows: 8
15
+ }),
16
+ style: f.text().label("Style").description("Optional hints about the tone or style this persona should adopt when writing.").renderer("textarea", {
17
+ rows: 3
18
+ })
19
+ })).list()
20
+ }));
21
+ form.layout((layout)=>[
22
+ layout.row("presets")
23
+ ]);
24
+ }
25
+ constructor(){
26
+ this.name = "writerPersonas";
27
+ this.label = "Writer Personas";
28
+ this.description = "Define how text should be written.";
29
+ }
30
+ }
31
+ const WriterPersonasSettings = AiPowerUpsSettingsGroup.createImplementation({
32
+ implementation: WriterPersonasSettingsImpl,
33
+ dependencies: []
34
+ });
35
+ export { WriterPersonasSettings };
36
+
37
+ //# sourceMappingURL=WriterPersonasSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin/presentation/WriterPersonasSettings.js","sources":["../../../src/admin/presentation/WriterPersonasSettings.ts"],"sourcesContent":["import { generateAlphaNumericId } from \"@webiny/utils\";\nimport { AiPowerUpsSettingsGroup } from \"./AiPowerUpsSettings/settingsGroup.js\";\n\nclass WriterPersonasSettingsImpl implements AiPowerUpsSettingsGroup.Interface {\n name = \"writerPersonas\";\n label = \"Writer Personas\";\n description = \"Define how text should be written.\";\n\n buildForm(form: AiPowerUpsSettingsGroup.FormBuilder): void {\n form.fields(fields => ({\n presets: fields\n .object()\n .label(\"Presets\")\n .renderer(\"objectAccordionMultiple\", {\n container: false,\n addItemLabel: \"Add writer persona\",\n itemTitle: (data, index) => String(data.name || `Writer Persona #${index + 1}`)\n })\n .fields(f => ({\n id: f\n .text()\n .hidden()\n .defaultValue(() => generateAlphaNumericId(10)),\n name: f\n .text()\n .label(\"Name\")\n .required(\"Name is required\")\n .description(\n \"This name will be used to identify the writer persona in the UI.\"\n ),\n description: f\n .text()\n .label(\"Description\")\n .required(\"Description is required\")\n .description(\n \"Describe how this persona writes and communicates. This will be used when prompting AI.\"\n )\n .renderer(\"textarea\", { rows: 8 }),\n style: f\n .text()\n .label(\"Style\")\n .description(\n \"Optional hints about the tone or style this persona should adopt when writing.\"\n )\n .renderer(\"textarea\", { rows: 3 })\n }))\n .list()\n }));\n\n form.layout(layout => [layout.row(\"presets\")]);\n }\n}\n\nexport const WriterPersonasSettings = AiPowerUpsSettingsGroup.createImplementation({\n implementation: WriterPersonasSettingsImpl,\n dependencies: []\n});\n"],"names":["WriterPersonasSettingsImpl","form","fields","data","index","String","f","generateAlphaNumericId","layout","WriterPersonasSettings","AiPowerUpsSettingsGroup"],"mappings":";;AAGA,MAAMA;IAKF,UAAUC,IAAyC,EAAQ;QACvDA,KAAK,MAAM,CAACC,CAAAA,SAAW;gBACnB,SAASA,OACJ,MAAM,GACN,KAAK,CAAC,WACN,QAAQ,CAAC,2BAA2B;oBACjC,WAAW;oBACX,cAAc;oBACd,WAAW,CAACC,MAAMC,QAAUC,OAAOF,KAAK,IAAI,IAAI,CAAC,gBAAgB,EAAEC,QAAQ,GAAG;gBAClF,GACC,MAAM,CAACE,CAAAA,IAAM;wBACV,IAAIA,EACC,IAAI,GACJ,MAAM,GACN,YAAY,CAAC,IAAMC,uBAAuB;wBAC/C,MAAMD,EACD,IAAI,GACJ,KAAK,CAAC,QACN,QAAQ,CAAC,oBACT,WAAW,CACR;wBAER,aAAaA,EACR,IAAI,GACJ,KAAK,CAAC,eACN,QAAQ,CAAC,2BACT,WAAW,CACR,2FAEH,QAAQ,CAAC,YAAY;4BAAE,MAAM;wBAAE;wBACpC,OAAOA,EACF,IAAI,GACJ,KAAK,CAAC,SACN,WAAW,CACR,kFAEH,QAAQ,CAAC,YAAY;4BAAE,MAAM;wBAAE;oBACxC,IACC,IAAI;YACb;QAEAL,KAAK,MAAM,CAACO,CAAAA,SAAU;gBAACA,OAAO,GAAG,CAAC;aAAW;IACjD;;aA9CA,IAAI,GAAG;aACP,KAAK,GAAG;aACR,WAAW,GAAG;;AA6ClB;AAEO,MAAMC,yBAAyBC,wBAAwB,oBAAoB,CAAC;IAC/E,gBAAgBV;IAChB,cAAc,EAAE;AACpB"}
@@ -0,0 +1,4 @@
1
+ import { Route } from "@webiny/app-admin";
2
+ export declare const Routes: {
3
+ Settings: Route<undefined>;
4
+ };
@@ -0,0 +1,10 @@
1
+ import { Route } from "@webiny/app-admin";
2
+ const Routes = {
3
+ Settings: new Route({
4
+ name: "AiPowerUps/Settings",
5
+ path: "/settings/ai-powerups"
6
+ })
7
+ };
8
+ export { Routes };
9
+
10
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin/routes.js","sources":["../../src/admin/routes.ts"],"sourcesContent":["import { Route } from \"@webiny/app-admin\";\n\nexport const Routes = {\n Settings: new Route({\n name: \"AiPowerUps/Settings\",\n path: \"/settings/ai-powerups\"\n })\n};\n"],"names":["Routes","Route"],"mappings":";AAEO,MAAMA,SAAS;IAClB,UAAU,IAAIC,MAAM;QAChB,MAAM;QACN,MAAM;IACV;AACJ"}
package/api/Extension.js CHANGED
@@ -1,20 +1,37 @@
1
1
  import { createFeature } from "@webiny/feature/api";
2
+ import { WcpContext } from "@webiny/api-core/features/wcp/WcpContext/index.js";
2
3
  import { BaseGraphQLSchema } from "./graphql/BaseGraphQLSchema.js";
3
- import AiPowerUpsSettingsGraphQLMapperImpl from "./graphql/AiPowerUpsSettingsGraphQLMapper.js";
4
+ import AiPowerUpsSettingsGraphQLMapper from "./graphql/AiPowerUpsSettingsGraphQLMapper.js";
5
+ import { AiPowerUpsSettingsCache } from "./features/shared/SettingsCache.js";
4
6
  import { GetSettingsFeature } from "./features/GetSettings/feature.js";
5
7
  import { UpdateSettingsFeature } from "./features/UpdateSettings/feature.js";
6
8
  import { WbGeneratePageContentFeature } from "./features/WbGeneratePageContent/feature.js";
7
9
  import { ProvidersFeature } from "./features/Providers/feature.js";
8
- export const Extension = createFeature({
9
- name: "AiPowerUps",
10
- register(container) {
11
- GetSettingsFeature.register(container);
12
- UpdateSettingsFeature.register(container);
13
- WbGeneratePageContentFeature.register(container);
14
- ProvidersFeature.register(container);
15
- container.register(AiPowerUpsSettingsGraphQLMapperImpl).inSingletonScope();
16
- container.register(BaseGraphQLSchema);
17
- }
10
+ import { ReaderPersonasFeature } from "./features/ReaderPersonas/feature.js";
11
+ import { WriterPersonasFeature } from "./features/WriterPersonas/feature.js";
12
+ import { ProjectsFeature } from "./features/Projects/feature.js";
13
+ import { AiPromptContextFeature } from "./features/AiPromptContext/feature.js";
14
+ import { AiImageEnrichmentFeature } from "./features/AiImageEnrichment/feature.js";
15
+ import { ExtractFrontmatterFeature } from "./features/ExtractFrontmatter/feature.js";
16
+ const Extension = createFeature({
17
+ name: "AiPowerUps",
18
+ register (container) {
19
+ container.register(AiPowerUpsSettingsCache).inSingletonScope();
20
+ GetSettingsFeature.register(container);
21
+ UpdateSettingsFeature.register(container);
22
+ ProvidersFeature.register(container);
23
+ ReaderPersonasFeature.register(container);
24
+ WriterPersonasFeature.register(container);
25
+ ProjectsFeature.register(container);
26
+ AiPromptContextFeature.register(container);
27
+ WbGeneratePageContentFeature.register(container);
28
+ ExtractFrontmatterFeature.register(container);
29
+ const wcp = container.resolve(WcpContext);
30
+ if (wcp.canUseAiImageEnrichment()) AiImageEnrichmentFeature.register(container);
31
+ container.register(AiPowerUpsSettingsGraphQLMapper).inSingletonScope();
32
+ container.register(BaseGraphQLSchema);
33
+ }
18
34
  });
35
+ export { Extension };
19
36
 
20
37
  //# sourceMappingURL=Extension.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["createFeature","BaseGraphQLSchema","AiPowerUpsSettingsGraphQLMapperImpl","GetSettingsFeature","UpdateSettingsFeature","WbGeneratePageContentFeature","ProvidersFeature","Extension","name","register","container","inSingletonScope"],"sources":["Extension.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { BaseGraphQLSchema } from \"./graphql/BaseGraphQLSchema.js\";\nimport AiPowerUpsSettingsGraphQLMapperImpl from \"./graphql/AiPowerUpsSettingsGraphQLMapper.js\";\nimport { GetSettingsFeature } from \"./features/GetSettings/feature.js\";\nimport { UpdateSettingsFeature } from \"./features/UpdateSettings/feature.js\";\nimport { WbGeneratePageContentFeature } from \"./features/WbGeneratePageContent/feature.js\";\nimport { ProvidersFeature } from \"./features/Providers/feature.js\";\n\nexport const Extension = createFeature({\n name: \"AiPowerUps\",\n register(container) {\n GetSettingsFeature.register(container);\n UpdateSettingsFeature.register(container);\n WbGeneratePageContentFeature.register(container);\n ProvidersFeature.register(container);\n\n container.register(AiPowerUpsSettingsGraphQLMapperImpl).inSingletonScope();\n container.register(BaseGraphQLSchema);\n }\n});\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,qBAAqB;AACnD,SAASC,iBAAiB;AAC1B,OAAOC,mCAAmC;AAC1C,SAASC,kBAAkB;AAC3B,SAASC,qBAAqB;AAC9B,SAASC,4BAA4B;AACrC,SAASC,gBAAgB;AAEzB,OAAO,MAAMC,SAAS,GAAGP,aAAa,CAAC;EACnCQ,IAAI,EAAE,YAAY;EAClBC,QAAQA,CAACC,SAAS,EAAE;IAChBP,kBAAkB,CAACM,QAAQ,CAACC,SAAS,CAAC;IACtCN,qBAAqB,CAACK,QAAQ,CAACC,SAAS,CAAC;IACzCL,4BAA4B,CAACI,QAAQ,CAACC,SAAS,CAAC;IAChDJ,gBAAgB,CAACG,QAAQ,CAACC,SAAS,CAAC;IAEpCA,SAAS,CAACD,QAAQ,CAACP,mCAAmC,CAAC,CAACS,gBAAgB,CAAC,CAAC;IAC1ED,SAAS,CAACD,QAAQ,CAACR,iBAAiB,CAAC;EACzC;AACJ,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"api/Extension.js","sources":["../../src/api/Extension.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { WcpContext } from \"@webiny/api-core/features/wcp/WcpContext/index.js\";\nimport { BaseGraphQLSchema } from \"./graphql/BaseGraphQLSchema.js\";\nimport AiPowerUpsSettingsGraphQLMapperImpl from \"./graphql/AiPowerUpsSettingsGraphQLMapper.js\";\nimport { AiPowerUpsSettingsCache } from \"./features/shared/SettingsCache.js\";\nimport { GetSettingsFeature } from \"./features/GetSettings/feature.js\";\nimport { UpdateSettingsFeature } from \"./features/UpdateSettings/feature.js\";\nimport { WbGeneratePageContentFeature } from \"./features/WbGeneratePageContent/feature.js\";\nimport { ProvidersFeature } from \"./features/Providers/feature.js\";\nimport { ReaderPersonasFeature } from \"./features/ReaderPersonas/feature.js\";\nimport { WriterPersonasFeature } from \"./features/WriterPersonas/feature.js\";\nimport { ProjectsFeature } from \"./features/Projects/feature.js\";\nimport { AiPromptContextFeature } from \"./features/AiPromptContext/feature.js\";\nimport { AiImageEnrichmentFeature } from \"./features/AiImageEnrichment/feature.js\";\nimport { ExtractFrontmatterFeature } from \"./features/ExtractFrontmatter/feature.js\";\n\nexport const Extension = createFeature({\n name: \"AiPowerUps\",\n register(container) {\n container.register(AiPowerUpsSettingsCache).inSingletonScope();\n\n GetSettingsFeature.register(container);\n UpdateSettingsFeature.register(container);\n ProvidersFeature.register(container);\n ReaderPersonasFeature.register(container);\n WriterPersonasFeature.register(container);\n ProjectsFeature.register(container);\n AiPromptContextFeature.register(container);\n WbGeneratePageContentFeature.register(container);\n ExtractFrontmatterFeature.register(container);\n\n const wcp = container.resolve(WcpContext);\n if (wcp.canUseAiImageEnrichment()) {\n AiImageEnrichmentFeature.register(container);\n }\n\n container.register(AiPowerUpsSettingsGraphQLMapperImpl).inSingletonScope();\n container.register(BaseGraphQLSchema);\n }\n});\n"],"names":["Extension","createFeature","container","AiPowerUpsSettingsCache","GetSettingsFeature","UpdateSettingsFeature","ProvidersFeature","ReaderPersonasFeature","WriterPersonasFeature","ProjectsFeature","AiPromptContextFeature","WbGeneratePageContentFeature","ExtractFrontmatterFeature","wcp","WcpContext","AiImageEnrichmentFeature","AiPowerUpsSettingsGraphQLMapperImpl","BaseGraphQLSchema"],"mappings":";;;;;;;;;;;;;;;AAgBO,MAAMA,YAAYC,cAAc;IACnC,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,yBAAyB,gBAAgB;QAE5DC,mBAAmB,QAAQ,CAACF;QAC5BG,sBAAsB,QAAQ,CAACH;QAC/BI,iBAAiB,QAAQ,CAACJ;QAC1BK,sBAAsB,QAAQ,CAACL;QAC/BM,sBAAsB,QAAQ,CAACN;QAC/BO,gBAAgB,QAAQ,CAACP;QACzBQ,uBAAuB,QAAQ,CAACR;QAChCS,6BAA6B,QAAQ,CAACT;QACtCU,0BAA0B,QAAQ,CAACV;QAEnC,MAAMW,MAAMX,UAAU,OAAO,CAACY;QAC9B,IAAID,IAAI,uBAAuB,IAC3BE,yBAAyB,QAAQ,CAACb;QAGtCA,UAAU,QAAQ,CAACc,iCAAqC,gBAAgB;QACxEd,UAAU,QAAQ,CAACe;IACvB;AACJ"}
package/api/constants.js CHANGED
@@ -1,3 +1,4 @@
1
- export const AI_POWER_UPS_SETTINGS = "AiPowerUps/Settings";
1
+ const AI_POWER_UPS_SETTINGS = "AiPowerUps/Settings";
2
+ export { AI_POWER_UPS_SETTINGS };
2
3
 
3
4
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["AI_POWER_UPS_SETTINGS"],"sources":["constants.ts"],"sourcesContent":["export const AI_POWER_UPS_SETTINGS = \"AiPowerUps/Settings\";\n"],"mappings":"AAAA,OAAO,MAAMA,qBAAqB,GAAG,qBAAqB","ignoreList":[]}
1
+ {"version":3,"file":"api/constants.js","sources":["../../src/api/constants.ts"],"sourcesContent":["export const AI_POWER_UPS_SETTINGS = \"AiPowerUps/Settings\";\n"],"names":["AI_POWER_UPS_SETTINGS"],"mappings":"AAAO,MAAMA,wBAAwB"}
@@ -0,0 +1,11 @@
1
+ import { FileAfterCreateEventHandler } from "@webiny/api-file-manager/features/file/CreateFile/events.js";
2
+ import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
3
+ declare class AiImageEnrichmentAfterCreateHandlerImpl implements FileAfterCreateEventHandler.Interface {
4
+ private taskService;
5
+ constructor(taskService: TaskService.Interface);
6
+ handle(event: FileAfterCreateEventHandler.Event): Promise<void>;
7
+ }
8
+ export declare const AiImageEnrichmentAfterCreateHandler: typeof AiImageEnrichmentAfterCreateHandlerImpl & {
9
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/eventPublisher/abstractions.js").IEventHandler<import("@webiny/api-file-manager/features/file/CreateFile/events.js").FileAfterCreateEvent>>;
10
+ };
11
+ export {};
@@ -0,0 +1,27 @@
1
+ import { FileAfterCreateEventHandler } from "@webiny/api-file-manager/features/file/CreateFile/events.js";
2
+ import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
3
+ import { AI_IMAGE_ENRICHMENT_TASK_ID } from "./AiImageEnrichmentTask.js";
4
+ class AiImageEnrichmentAfterCreateHandlerImpl {
5
+ constructor(taskService){
6
+ this.taskService = taskService;
7
+ }
8
+ async handle(event) {
9
+ const { file } = event.payload;
10
+ if (!file.type.startsWith("image/")) return;
11
+ await this.taskService.trigger({
12
+ definition: AI_IMAGE_ENRICHMENT_TASK_ID,
13
+ input: {
14
+ fileId: file.id
15
+ }
16
+ });
17
+ }
18
+ }
19
+ const AiImageEnrichmentAfterCreateHandler = FileAfterCreateEventHandler.createImplementation({
20
+ implementation: AiImageEnrichmentAfterCreateHandlerImpl,
21
+ dependencies: [
22
+ TaskService
23
+ ]
24
+ });
25
+ export { AiImageEnrichmentAfterCreateHandler };
26
+
27
+ //# sourceMappingURL=AiImageEnrichmentAfterCreateHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/AiImageEnrichment/AiImageEnrichmentAfterCreateHandler.js","sources":["../../../../src/api/features/AiImageEnrichment/AiImageEnrichmentAfterCreateHandler.ts"],"sourcesContent":["import { FileAfterCreateEventHandler } from \"@webiny/api-file-manager/features/file/CreateFile/events.js\";\nimport { TaskService } from \"@webiny/api-core/features/task/TaskService/index.js\";\nimport type { IAiImageEnrichmentTaskInput } from \"./AiImageEnrichmentTask.js\";\nimport { AI_IMAGE_ENRICHMENT_TASK_ID } from \"./AiImageEnrichmentTask.js\";\n\nclass AiImageEnrichmentAfterCreateHandlerImpl implements FileAfterCreateEventHandler.Interface {\n constructor(private taskService: TaskService.Interface) {}\n\n async handle(event: FileAfterCreateEventHandler.Event): Promise<void> {\n const { file } = event.payload;\n\n if (!file.type.startsWith(\"image/\")) {\n return;\n }\n\n await this.taskService.trigger<IAiImageEnrichmentTaskInput>({\n definition: AI_IMAGE_ENRICHMENT_TASK_ID,\n input: {\n fileId: file.id\n }\n });\n }\n}\n\nexport const AiImageEnrichmentAfterCreateHandler = FileAfterCreateEventHandler.createImplementation(\n {\n implementation: AiImageEnrichmentAfterCreateHandlerImpl,\n dependencies: [TaskService]\n }\n);\n"],"names":["AiImageEnrichmentAfterCreateHandlerImpl","taskService","event","file","AI_IMAGE_ENRICHMENT_TASK_ID","AiImageEnrichmentAfterCreateHandler","FileAfterCreateEventHandler","TaskService"],"mappings":";;;AAKA,MAAMA;IACF,YAAoBC,WAAkC,CAAE;aAApCA,WAAW,GAAXA;IAAqC;IAEzD,MAAM,OAAOC,KAAwC,EAAiB;QAClE,MAAM,EAAEC,IAAI,EAAE,GAAGD,MAAM,OAAO;QAE9B,IAAI,CAACC,KAAK,IAAI,CAAC,UAAU,CAAC,WACtB;QAGJ,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAA8B;YACxD,YAAYC;YACZ,OAAO;gBACH,QAAQD,KAAK,EAAE;YACnB;QACJ;IACJ;AACJ;AAEO,MAAME,sCAAsCC,4BAA4B,oBAAoB,CAC/F;IACI,gBAAgBN;IAChB,cAAc;QAACO;KAAY;AAC/B"}
@@ -0,0 +1,34 @@
1
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
2
+ import { Ai } from "@webiny/api-core/features/ai/index.js";
3
+ import { Encryption } from "@webiny/api-core/features/encryption/index.js";
4
+ import { GetFileUseCase } from "@webiny/api-file-manager/features/file/GetFile/index.js";
5
+ import { UpdateFileUseCase } from "@webiny/api-file-manager/features/file/UpdateFile/index.js";
6
+ import { GetSettingsUseCase as FmGetSettingsUseCase } from "@webiny/api-file-manager/features/settings/GetSettings/abstractions.js";
7
+ import { WebsocketService } from "@webiny/api-websockets/features/WebsocketService/index.js";
8
+ import { GetSettingsUseCase } from "../../../api/features/GetSettings/index.js";
9
+ export declare const AI_IMAGE_ENRICHMENT_TASK_ID = "fmAiImageEnrichment";
10
+ export interface IAiImageEnrichmentTaskInput {
11
+ fileId: string;
12
+ }
13
+ declare class AiImageEnrichmentTaskImpl implements TaskDefinition.Interface<IAiImageEnrichmentTaskInput> {
14
+ private getFile;
15
+ private fmSettings;
16
+ private updateFile;
17
+ private ai;
18
+ private getSettings;
19
+ private encryption;
20
+ private websocketService?;
21
+ id: string;
22
+ title: string;
23
+ description: string;
24
+ maxIterations: number;
25
+ isPrivate: boolean;
26
+ databaseLogs: boolean;
27
+ readonly selfCleanup: ("onAbort" | "onSuccess")[];
28
+ constructor(getFile: GetFileUseCase.Interface, fmSettings: FmGetSettingsUseCase.Interface, updateFile: UpdateFileUseCase.Interface, ai: Ai.Interface, getSettings: GetSettingsUseCase.Interface, encryption: Encryption.Interface, websocketService?: WebsocketService.Interface | undefined);
29
+ run({ input, controller }: TaskDefinition.RunParams<IAiImageEnrichmentTaskInput>): Promise<TaskDefinition.Result<IAiImageEnrichmentTaskInput>>;
30
+ }
31
+ export declare const AiImageEnrichmentTask: typeof AiImageEnrichmentTaskImpl & {
32
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskDefinition<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>;
33
+ };
34
+ export {};
@@ -0,0 +1,140 @@
1
+ import { Output } from "ai";
2
+ import { z } from "zod";
3
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
4
+ import { Ai } from "@webiny/api-core/features/ai/index.js";
5
+ import { Encryption } from "@webiny/api-core/features/encryption/index.js";
6
+ import { GetFileUseCase } from "@webiny/api-file-manager/features/file/GetFile/index.js";
7
+ import { UpdateFileUseCase } from "@webiny/api-file-manager/features/file/UpdateFile/index.js";
8
+ import { GetSettingsUseCase } from "@webiny/api-file-manager/features/settings/GetSettings/abstractions.js";
9
+ import { WebsocketService } from "@webiny/api-websockets/features/WebsocketService/index.js";
10
+ import { GetSettingsUseCase as index_js_GetSettingsUseCase } from "../GetSettings/index.js";
11
+ const AI_IMAGE_ENRICHMENT_TASK_ID = "fmAiImageEnrichment";
12
+ const AI_PROMPT = "Analyze this image and return up to 5 lowercase descriptive tags and one short sentence describing the image.";
13
+ const aiOutputSchema = Output.object({
14
+ schema: z.object({
15
+ tags: z.array(z.string()),
16
+ description: z.string()
17
+ })
18
+ });
19
+ class AiImageEnrichmentTaskImpl {
20
+ constructor(getFile, fmSettings, updateFile, ai, getSettings, encryption, websocketService){
21
+ this.getFile = getFile;
22
+ this.fmSettings = fmSettings;
23
+ this.updateFile = updateFile;
24
+ this.ai = ai;
25
+ this.getSettings = getSettings;
26
+ this.encryption = encryption;
27
+ this.websocketService = websocketService;
28
+ this.id = AI_IMAGE_ENRICHMENT_TASK_ID;
29
+ this.title = "File Manager - AI Image Enrichment";
30
+ this.description = "Automatically enriches uploaded images with AI-generated tags and description.";
31
+ this.maxIterations = 1;
32
+ this.isPrivate = true;
33
+ this.databaseLogs = false;
34
+ this.selfCleanup = [
35
+ "onSuccess",
36
+ "onAbort"
37
+ ];
38
+ }
39
+ async run({ input, controller }) {
40
+ if (controller.runtime.isAborted()) return controller.response.aborted();
41
+ const fileResult = await this.getFile.execute(input.fileId);
42
+ if (fileResult.isFail()) return controller.response.error({
43
+ message: `File not found: ${input.fileId}`
44
+ });
45
+ const file = fileResult.value;
46
+ if (!file.type.startsWith("image/")) return controller.response.done("File is not an image; skipping AI enrichment.");
47
+ const settingsResult = await this.fmSettings.execute();
48
+ const srcPrefix = settingsResult.isOk() ? settingsResult.value.srcPrefix ?? "" : "";
49
+ const imageUrl = `${srcPrefix}${file.key}`;
50
+ const aiSettingsResult = await this.getSettings.execute();
51
+ if (aiSettingsResult.isFail()) return controller.response.error({
52
+ message: "No AI provider configured. Add a provider in AI Power Ups settings."
53
+ });
54
+ const aiSettings = aiSettingsResult.value;
55
+ const firstProvider = aiSettings.providers.presets[0];
56
+ if (!firstProvider) return controller.response.done({
57
+ message: "No AI provider configured. Add a provider in AI Power Ups settings."
58
+ });
59
+ let tags = [];
60
+ let description = "";
61
+ try {
62
+ const aiResult = await this.ai.generateText({
63
+ model: firstProvider.model,
64
+ output: aiOutputSchema,
65
+ connection: {
66
+ sdkName: firstProvider.model.split("/")[0],
67
+ apiKey: this.encryption.decrypt(firstProvider.apiKeyEncrypted)
68
+ },
69
+ messages: [
70
+ {
71
+ role: "user",
72
+ content: [
73
+ {
74
+ type: "image",
75
+ image: new URL(imageUrl)
76
+ },
77
+ {
78
+ type: "text",
79
+ text: AI_PROMPT
80
+ }
81
+ ]
82
+ }
83
+ ]
84
+ });
85
+ tags = aiResult.output.tags;
86
+ description = aiResult.output.description;
87
+ } catch (error) {
88
+ console.log("error", error.message);
89
+ return controller.response.error({
90
+ message: `AI enrichment failed: ${error instanceof Error ? error.message : String(error)}`
91
+ });
92
+ }
93
+ const mergedTags = [
94
+ ...new Set([
95
+ ...file.tags,
96
+ ...tags
97
+ ])
98
+ ];
99
+ const updateResult = await this.updateFile.execute({
100
+ id: file.id,
101
+ tags: mergedTags,
102
+ description
103
+ });
104
+ if (updateResult.isFail()) return controller.response.error({
105
+ message: `Failed to update file: ${updateResult.error.message}`
106
+ });
107
+ if (this.websocketService) {
108
+ const connectionsResult = await this.websocketService.listConnections();
109
+ if (connectionsResult.isOk() && connectionsResult.value.length > 0) await this.websocketService.sendToConnections(connectionsResult.value, {
110
+ action: "fm.file.enrichment",
111
+ data: {
112
+ id: file.id,
113
+ tags: mergedTags,
114
+ description
115
+ }
116
+ });
117
+ }
118
+ return controller.response.done("AI image enrichment completed successfully.");
119
+ }
120
+ }
121
+ const AiImageEnrichmentTask = TaskDefinition.createImplementation({
122
+ implementation: AiImageEnrichmentTaskImpl,
123
+ dependencies: [
124
+ GetFileUseCase,
125
+ GetSettingsUseCase,
126
+ UpdateFileUseCase,
127
+ Ai,
128
+ index_js_GetSettingsUseCase,
129
+ Encryption,
130
+ [
131
+ WebsocketService,
132
+ {
133
+ optional: true
134
+ }
135
+ ]
136
+ ]
137
+ });
138
+ export { AI_IMAGE_ENRICHMENT_TASK_ID, AiImageEnrichmentTask };
139
+
140
+ //# sourceMappingURL=AiImageEnrichmentTask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api/features/AiImageEnrichment/AiImageEnrichmentTask.js","sources":["../../../../src/api/features/AiImageEnrichment/AiImageEnrichmentTask.ts"],"sourcesContent":["import { Output } from \"ai\";\nimport { z } from \"zod\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { Ai } from \"@webiny/api-core/features/ai/index.js\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { GetFileUseCase } from \"@webiny/api-file-manager/features/file/GetFile/index.js\";\nimport { UpdateFileUseCase } from \"@webiny/api-file-manager/features/file/UpdateFile/index.js\";\nimport { GetSettingsUseCase as FmGetSettingsUseCase } from \"@webiny/api-file-manager/features/settings/GetSettings/abstractions.js\";\nimport { WebsocketService } from \"@webiny/api-websockets/features/WebsocketService/index.js\";\nimport { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\n\nexport const AI_IMAGE_ENRICHMENT_TASK_ID = \"fmAiImageEnrichment\";\n\nconst AI_PROMPT =\n \"Analyze this image and return up to 5 lowercase descriptive tags and one short sentence describing the image.\";\n\nconst aiOutputSchema = Output.object({\n schema: z.object({\n tags: z.array(z.string()),\n description: z.string()\n })\n});\n\nexport interface IAiImageEnrichmentTaskInput {\n fileId: string;\n}\n\nclass AiImageEnrichmentTaskImpl implements TaskDefinition.Interface<IAiImageEnrichmentTaskInput> {\n id = AI_IMAGE_ENRICHMENT_TASK_ID;\n title = \"File Manager - AI Image Enrichment\";\n description = \"Automatically enriches uploaded images with AI-generated tags and description.\";\n maxIterations = 1;\n isPrivate = true;\n databaseLogs = false;\n\n public readonly selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n constructor(\n private getFile: GetFileUseCase.Interface,\n private fmSettings: FmGetSettingsUseCase.Interface,\n private updateFile: UpdateFileUseCase.Interface,\n private ai: Ai.Interface,\n private getSettings: GetSettingsUseCase.Interface,\n private encryption: Encryption.Interface,\n private websocketService?: WebsocketService.Interface\n ) {}\n\n async run({\n input,\n controller\n }: TaskDefinition.RunParams<IAiImageEnrichmentTaskInput>): Promise<\n TaskDefinition.Result<IAiImageEnrichmentTaskInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n const fileResult = await this.getFile.execute(input.fileId);\n if (fileResult.isFail()) {\n return controller.response.error({\n message: `File not found: ${input.fileId}`\n });\n }\n\n const file = fileResult.value;\n\n if (!file.type.startsWith(\"image/\")) {\n return controller.response.done(\"File is not an image; skipping AI enrichment.\");\n }\n\n const settingsResult = await this.fmSettings.execute();\n const srcPrefix = settingsResult.isOk() ? (settingsResult.value.srcPrefix ?? \"\") : \"\";\n const imageUrl = `${srcPrefix}${file.key}`;\n\n const aiSettingsResult = await this.getSettings.execute();\n\n if (aiSettingsResult.isFail()) {\n return controller.response.error({\n message: \"No AI provider configured. Add a provider in AI Power Ups settings.\"\n });\n }\n\n const aiSettings = aiSettingsResult.value;\n\n const firstProvider = aiSettings.providers.presets[0];\n\n if (!firstProvider) {\n return controller.response.done({\n message: \"No AI provider configured. Add a provider in AI Power Ups settings.\"\n });\n }\n\n let tags: string[] = [];\n let description = \"\";\n try {\n const aiResult = await this.ai.generateText({\n model: firstProvider.model,\n output: aiOutputSchema,\n connection: {\n sdkName: firstProvider.model.split(\"/\")[0],\n apiKey: this.encryption.decrypt(firstProvider.apiKeyEncrypted)\n },\n messages: [\n {\n role: \"user\",\n content: [\n {\n type: \"image\",\n image: new URL(imageUrl)\n },\n {\n type: \"text\",\n text: AI_PROMPT\n }\n ]\n }\n ]\n });\n\n tags = aiResult.output.tags;\n description = aiResult.output.description;\n } catch (error) {\n console.log(\"error\", error.message);\n return controller.response.error({\n message: `AI enrichment failed: ${error instanceof Error ? error.message : String(error)}`\n });\n }\n\n const mergedTags = [...new Set([...file.tags, ...tags])];\n\n const updateResult = await this.updateFile.execute({\n id: file.id,\n tags: mergedTags,\n description\n });\n\n if (updateResult.isFail()) {\n return controller.response.error({\n message: `Failed to update file: ${updateResult.error.message}`\n });\n }\n\n if (this.websocketService) {\n const connectionsResult = await this.websocketService.listConnections();\n if (connectionsResult.isOk() && connectionsResult.value.length > 0) {\n await this.websocketService.sendToConnections(connectionsResult.value, {\n action: \"fm.file.enrichment\",\n data: {\n id: file.id,\n tags: mergedTags,\n description\n }\n });\n }\n }\n\n return controller.response.done(\"AI image enrichment completed successfully.\");\n }\n}\n\nexport const AiImageEnrichmentTask = TaskDefinition.createImplementation({\n implementation: AiImageEnrichmentTaskImpl,\n dependencies: [\n GetFileUseCase,\n FmGetSettingsUseCase,\n UpdateFileUseCase,\n Ai,\n GetSettingsUseCase,\n Encryption,\n [WebsocketService, { optional: true }]\n ]\n});\n"],"names":["AI_IMAGE_ENRICHMENT_TASK_ID","AI_PROMPT","aiOutputSchema","Output","z","AiImageEnrichmentTaskImpl","getFile","fmSettings","updateFile","ai","getSettings","encryption","websocketService","input","controller","fileResult","file","settingsResult","srcPrefix","imageUrl","aiSettingsResult","aiSettings","firstProvider","tags","description","aiResult","URL","error","console","Error","String","mergedTags","Set","updateResult","connectionsResult","AiImageEnrichmentTask","TaskDefinition","GetFileUseCase","FmGetSettingsUseCase","UpdateFileUseCase","Ai","GetSettingsUseCase","Encryption","WebsocketService"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const AiImageEnrichmentFeature: {
2
+ name: string;
3
+ register(container: import("@webiny/di").Container): void;
4
+ };