@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.
- package/admin/Extension.js +16 -2
- package/admin/Extension.js.map +1 -1
- package/admin/features/permissions/abstractions.d.ts +17 -0
- package/admin/features/permissions/abstractions.js +6 -0
- package/admin/features/permissions/abstractions.js.map +1 -0
- package/admin/features/permissions/feature.d.ts +14 -0
- package/admin/features/permissions/feature.js +7 -0
- package/admin/features/permissions/feature.js.map +1 -0
- package/admin/features/permissions/index.d.ts +2 -0
- package/admin/features/permissions/index.js +2 -0
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.d.ts +2 -2
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js +2 -2
- package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js.map +1 -1
- package/admin/presentation/CmsCompareEntryRevisions/feature.js +2 -2
- package/admin/presentation/CmsCompareEntryRevisions/feature.js.map +1 -1
- package/admin/presentation/security/HasPermission.d.ts +10 -0
- package/admin/presentation/security/HasPermission.js +6 -0
- package/admin/presentation/security/HasPermission.js.map +1 -0
- package/api/Extension.js +6 -0
- package/api/Extension.js.map +1 -1
- package/api/features/Capabilities/ListAiCapabilitiesUseCase.d.ts +7 -4
- package/api/features/Capabilities/ListAiCapabilitiesUseCase.js +11 -5
- package/api/features/Capabilities/ListAiCapabilitiesUseCase.js.map +1 -1
- package/api/features/Capabilities/ResolveAiCapabilityUseCase.d.ts +4 -6
- package/api/features/Capabilities/ResolveAiCapabilityUseCase.js +12 -11
- package/api/features/Capabilities/ResolveAiCapabilityUseCase.js.map +1 -1
- package/api/features/Capabilities/abstractions.d.ts +1 -1
- package/api/features/Capabilities/abstractions.js.map +1 -1
- package/api/features/Capabilities/feature.js +4 -4
- package/api/features/Capabilities/feature.js.map +1 -1
- package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.d.ts +5 -3
- package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.js +11 -6
- package/api/features/CmsCompareEntryRevisions/CmsCompareEntryRevisionsUseCase.js.map +1 -1
- package/api/features/CmsCompareEntryRevisions/feature.js +2 -2
- package/api/features/CmsCompareEntryRevisions/feature.js.map +1 -1
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.d.ts +2 -2
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js +3 -3
- package/api/features/CmsGenerateEntryContent/CmsGenerateEntryContentUseCase.js.map +1 -1
- package/api/features/CmsGenerateEntryContent/QueueCmsGenerateEntryContentUseCase.d.ts +19 -0
- package/api/features/CmsGenerateEntryContent/QueueCmsGenerateEntryContentUseCase.js +61 -0
- package/api/features/CmsGenerateEntryContent/QueueCmsGenerateEntryContentUseCase.js.map +1 -0
- package/api/features/CmsGenerateEntryContent/abstractions.d.ts +14 -0
- package/api/features/CmsGenerateEntryContent/abstractions.js +2 -1
- package/api/features/CmsGenerateEntryContent/abstractions.js.map +1 -1
- package/api/features/CmsGenerateEntryContent/feature.js +4 -2
- package/api/features/CmsGenerateEntryContent/feature.js.map +1 -1
- package/api/features/CmsGenerateEntryContent/index.d.ts +1 -1
- package/api/features/CmsGenerateEntryContent/index.js +1 -1
- package/api/features/Connections/ConnectionsGraphQLMapper.js +1 -1
- package/api/features/Connections/ConnectionsGraphQLMapper.js.map +1 -1
- package/api/features/GetDecryptedSettings/GetDecryptedSettingsUseCase.d.ts +17 -0
- package/api/features/GetDecryptedSettings/GetDecryptedSettingsUseCase.js +41 -0
- package/api/features/GetDecryptedSettings/GetDecryptedSettingsUseCase.js.map +1 -0
- package/api/features/GetDecryptedSettings/abstractions.d.ts +13 -0
- package/api/features/GetDecryptedSettings/abstractions.js +5 -0
- package/api/features/GetDecryptedSettings/abstractions.js.map +1 -0
- package/api/features/GetDecryptedSettings/feature.d.ts +4 -0
- package/api/features/GetDecryptedSettings/feature.js +11 -0
- package/api/features/GetDecryptedSettings/feature.js.map +1 -0
- package/api/features/GetDecryptedSettings/index.d.ts +2 -0
- package/api/features/GetDecryptedSettings/index.js +2 -0
- package/api/features/GetSettings/GetSettingsRepository.d.ts +2 -2
- package/api/features/GetSettings/GetSettingsRepository.js +2 -2
- package/api/features/GetSettings/GetSettingsRepository.js.map +1 -1
- package/api/features/GetSettings/GetSettingsUseCase.d.ts +15 -4
- package/api/features/GetSettings/GetSettingsUseCase.js +34 -5
- package/api/features/GetSettings/GetSettingsUseCase.js.map +1 -1
- package/api/features/GetSettings/abstractions.d.ts +1 -1
- package/api/features/GetSettings/abstractions.js.map +1 -1
- package/api/features/GetSettings/feature.js +4 -4
- package/api/features/GetSettings/feature.js.map +1 -1
- package/api/features/ListModels/ListModelsUseCase.d.ts +15 -0
- package/api/features/ListModels/ListModelsUseCase.js +25 -0
- package/api/features/ListModels/ListModelsUseCase.js.map +1 -0
- package/api/features/ListModels/abstractions.d.ts +10 -0
- package/api/features/ListModels/abstractions.js +5 -0
- package/api/features/ListModels/abstractions.js.map +1 -0
- package/api/features/ListModels/feature.d.ts +4 -0
- package/api/features/ListModels/feature.js +11 -0
- package/api/features/ListModels/feature.js.map +1 -0
- package/api/features/ListModels/index.d.ts +1 -0
- package/api/features/ListModels/index.js +1 -0
- package/api/features/Providers/ProvidersGraphQLMapper.js +1 -1
- package/api/features/Providers/ProvidersGraphQLMapper.js.map +1 -1
- package/api/features/UpdateSettings/UpdateSettingsRepository.d.ts +2 -2
- package/api/features/UpdateSettings/UpdateSettingsRepository.js +2 -2
- package/api/features/UpdateSettings/UpdateSettingsRepository.js.map +1 -1
- package/api/features/UpdateSettings/UpdateSettingsUseCase.d.ts +5 -3
- package/api/features/UpdateSettings/UpdateSettingsUseCase.js +10 -3
- package/api/features/UpdateSettings/UpdateSettingsUseCase.js.map +1 -1
- package/api/features/UpdateSettings/feature.js +4 -4
- package/api/features/UpdateSettings/feature.js.map +1 -1
- package/api/features/WbGeneratePageContent/QueueWbGeneratePageContentUseCase.d.ts +13 -0
- package/api/features/WbGeneratePageContent/QueueWbGeneratePageContentUseCase.js +42 -0
- package/api/features/WbGeneratePageContent/QueueWbGeneratePageContentUseCase.js.map +1 -0
- package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.d.ts +2 -2
- package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js +2 -2
- package/api/features/WbGeneratePageContent/WbGeneratePageContentUseCase.js.map +1 -1
- package/api/features/WbGeneratePageContent/abstractions.d.ts +14 -0
- package/api/features/WbGeneratePageContent/abstractions.js +2 -1
- package/api/features/WbGeneratePageContent/abstractions.js.map +1 -1
- package/api/features/WbGeneratePageContent/feature.js +4 -2
- package/api/features/WbGeneratePageContent/feature.js.map +1 -1
- package/api/features/WbGeneratePageContent/index.d.ts +1 -1
- package/api/features/WbGeneratePageContent/index.js +1 -1
- package/api/features/permissions/abstractions.d.ts +15 -0
- package/api/features/permissions/abstractions.js +6 -0
- package/api/features/permissions/abstractions.js.map +1 -0
- package/api/features/permissions/feature.d.ts +4 -0
- package/api/features/permissions/feature.js +7 -0
- package/api/features/permissions/feature.js.map +1 -0
- package/api/features/permissions/index.d.ts +2 -0
- package/api/features/permissions/index.js +2 -0
- package/api/graphql/BaseGraphQLSchema.js +22 -45
- package/api/graphql/BaseGraphQLSchema.js.map +1 -1
- package/domain/LlmJsonResponse.js +2 -1
- package/domain/LlmJsonResponse.js.map +1 -1
- package/package.json +30 -28
- package/shared/permissionsSchema.d.ts +20 -0
- package/shared/permissionsSchema.js +17 -0
- package/shared/permissionsSchema.js.map +1 -0
package/admin/Extension.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import react from "react";
|
|
2
2
|
import { AdminConfig, AdminLayout, RegisterFeature, useRouter } from "@webiny/app-admin";
|
|
3
|
+
import { ReactComponent } from "@webiny/icons/auto_fix_high.svg";
|
|
4
|
+
import { AI_POWERUPS_PERMISSIONS_SCHEMA } from "../shared/permissionsSchema.js";
|
|
5
|
+
import { AiPowerUpsPermissionsFeature } from "./features/permissions/index.js";
|
|
6
|
+
import { HasPermission } from "./presentation/security/HasPermission.js";
|
|
3
7
|
import { AiPowerUpsSettingsFeature } from "./presentation/AiPowerUpsSettings/index.js";
|
|
4
8
|
import { AiPowerUpsSettingsPage } from "./presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.js";
|
|
5
9
|
import { WbContentGeneration } from "./presentation/WbContentGeneration/Extension.js";
|
|
@@ -9,10 +13,12 @@ import { CmsCompareEntryRevisions } from "./presentation/CmsCompareEntryRevision
|
|
|
9
13
|
import { AiPowerUpsHeadlessFeatures } from "./features/feature.js";
|
|
10
14
|
import { AiPromptFormFeature } from "./presentation/AiPromptFormFactory/feature.js";
|
|
11
15
|
import { Routes } from "./routes.js";
|
|
12
|
-
const { Menu: Menu, Route: Route } = AdminConfig;
|
|
16
|
+
const { Menu: Menu, Route: Route, Security: Security } = AdminConfig;
|
|
13
17
|
const AiPowerUpsSettings = ()=>{
|
|
14
18
|
const { getLink } = useRouter();
|
|
15
|
-
return /*#__PURE__*/ react.createElement(AdminConfig, null, /*#__PURE__*/ react.createElement(
|
|
19
|
+
return /*#__PURE__*/ react.createElement(AdminConfig, null, /*#__PURE__*/ react.createElement(HasPermission, {
|
|
20
|
+
entity: "settings"
|
|
21
|
+
}, /*#__PURE__*/ react.createElement(Route, {
|
|
16
22
|
route: Routes.Settings,
|
|
17
23
|
element: /*#__PURE__*/ react.createElement(AdminLayout, {
|
|
18
24
|
title: "AI Power-Ups"
|
|
@@ -28,9 +34,17 @@ const AiPowerUpsSettings = ()=>{
|
|
|
28
34
|
to: getLink(Routes.Settings),
|
|
29
35
|
pinnable: true
|
|
30
36
|
})
|
|
37
|
+
})), /*#__PURE__*/ react.createElement(Security.Permissions, {
|
|
38
|
+
name: "aiPowerups",
|
|
39
|
+
title: "AI Power-Ups",
|
|
40
|
+
description: "Manage AI Power-Ups permissions.",
|
|
41
|
+
icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
|
|
42
|
+
schema: AI_POWERUPS_PERMISSIONS_SCHEMA
|
|
31
43
|
}));
|
|
32
44
|
};
|
|
33
45
|
const Extension = ()=>/*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(RegisterFeature, {
|
|
46
|
+
feature: AiPowerUpsPermissionsFeature
|
|
47
|
+
}), /*#__PURE__*/ react.createElement(RegisterFeature, {
|
|
34
48
|
feature: AiPromptFormFeature
|
|
35
49
|
}), /*#__PURE__*/ react.createElement(RegisterFeature, {
|
|
36
50
|
feature: AiPowerUpsHeadlessFeatures
|
package/admin/Extension.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin/Extension.js","sources":["../../src/admin/Extension.tsx"],"sourcesContent":["import React from \"react\";\nimport { AdminConfig, AdminLayout, useRouter, RegisterFeature } from \"@webiny/app-admin\";\nimport { AiPowerUpsSettingsFeature } from \"./presentation/AiPowerUpsSettings/index.js\";\nimport { AiPowerUpsSettingsPage } from \"./presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.js\";\nimport { WbContentGeneration } from \"~/admin/presentation/WbContentGeneration/Extension.js\";\nimport { CmsContentGeneration } from \"~/admin/presentation/CmsContentGeneration/Extension.js\";\nimport { CmsEntryWizardExtension } from \"~/admin/presentation/CmsEntryWizard/Extension.js\";\nimport { CmsCompareEntryRevisions } from \"~/admin/presentation/CmsCompareEntryRevisions/Extension.js\";\nimport { AiPowerUpsHeadlessFeatures } from \"~/admin/features/feature.js\";\nimport { AiPromptFormFeature } from \"~/admin/presentation/AiPromptFormFactory/feature.js\";\nimport { Routes } from \"./routes.js\";\n\nconst { Menu, Route } = AdminConfig;\n\nconst AiPowerUpsSettings = () => {\n const { getLink } = useRouter();\n\n return (\n <AdminConfig>\n <Route\n
|
|
1
|
+
{"version":3,"file":"admin/Extension.js","sources":["../../src/admin/Extension.tsx"],"sourcesContent":["import React from \"react\";\nimport { AdminConfig, AdminLayout, useRouter, RegisterFeature } from \"@webiny/app-admin\";\nimport { ReactComponent as AiPowerUpsIcon } from \"@webiny/icons/auto_fix_high.svg\";\nimport { AI_POWERUPS_PERMISSIONS_SCHEMA } from \"~/shared/permissionsSchema.js\";\nimport { AiPowerUpsPermissionsFeature } from \"~/admin/features/permissions/index.js\";\nimport { HasPermission } from \"~/admin/presentation/security/HasPermission.js\";\nimport { AiPowerUpsSettingsFeature } from \"./presentation/AiPowerUpsSettings/index.js\";\nimport { AiPowerUpsSettingsPage } from \"./presentation/AiPowerUpsSettings/AiPowerUpsSettingsPage.js\";\nimport { WbContentGeneration } from \"~/admin/presentation/WbContentGeneration/Extension.js\";\nimport { CmsContentGeneration } from \"~/admin/presentation/CmsContentGeneration/Extension.js\";\nimport { CmsEntryWizardExtension } from \"~/admin/presentation/CmsEntryWizard/Extension.js\";\nimport { CmsCompareEntryRevisions } from \"~/admin/presentation/CmsCompareEntryRevisions/Extension.js\";\nimport { AiPowerUpsHeadlessFeatures } from \"~/admin/features/feature.js\";\nimport { AiPromptFormFeature } from \"~/admin/presentation/AiPromptFormFactory/feature.js\";\nimport { Routes } from \"./routes.js\";\n\nconst { Menu, Route, Security } = AdminConfig;\n\nconst AiPowerUpsSettings = () => {\n const { getLink } = useRouter();\n\n return (\n <AdminConfig>\n {/* The settings hold the AI provider API keys. */}\n <HasPermission entity={\"settings\"}>\n <Route\n route={Routes.Settings}\n element={\n <AdminLayout title={\"AI Power-Ups\"}>\n <AiPowerUpsSettingsPage />\n </AdminLayout>\n }\n />\n <Menu\n parent={\"settings.system\"}\n name={\"aiPowerUps\"}\n element={\n <Menu.Link\n text={\"AI Power-Ups\"}\n badge={<Menu.Link.Badge text=\"BETA\" />}\n to={getLink(Routes.Settings)}\n pinnable={true}\n />\n }\n />\n </HasPermission>\n <Security.Permissions\n name=\"aiPowerups\"\n title=\"AI Power-Ups\"\n description=\"Manage AI Power-Ups permissions.\"\n icon={<AiPowerUpsIcon />}\n schema={AI_POWERUPS_PERMISSIONS_SCHEMA}\n />\n </AdminConfig>\n );\n};\n\nexport const Extension = () => {\n return (\n <>\n <RegisterFeature feature={AiPowerUpsPermissionsFeature} />\n <RegisterFeature feature={AiPromptFormFeature} />\n <RegisterFeature feature={AiPowerUpsHeadlessFeatures} />\n <RegisterFeature feature={AiPowerUpsSettingsFeature} />\n <AiPowerUpsSettings />\n {/* Website Builder Extension */}\n <WbContentGeneration />\n {/* Headless CMS Extension */}\n <CmsContentGeneration />\n {/* CMS Revision Comparison */}\n <CmsCompareEntryRevisions />\n {/* AI Entry Wizard (registered first so custom wizards can override) */}\n <CmsEntryWizardExtension />\n </>\n );\n};\n"],"names":["Menu","Route","Security","AdminConfig","AiPowerUpsSettings","getLink","useRouter","HasPermission","Routes","AdminLayout","AiPowerUpsSettingsPage","AiPowerUpsIcon","AI_POWERUPS_PERMISSIONS_SCHEMA","Extension","RegisterFeature","AiPowerUpsPermissionsFeature","AiPromptFormFeature","AiPowerUpsHeadlessFeatures","AiPowerUpsSettingsFeature","WbContentGeneration","CmsContentGeneration","CmsCompareEntryRevisions","CmsEntryWizardExtension"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAM,EAAEA,MAAAA,IAAI,EAAEC,OAAAA,KAAK,EAAEC,UAAAA,QAAQ,EAAE,GAAGC;AAElC,MAAMC,qBAAqB;IACvB,MAAM,EAAEC,OAAO,EAAE,GAAGC;IAEpB,OAAO,WAAP,GACI,oBAACH,aAAWA,MAAAA,WAAAA,GAER,oBAACI,eAAaA;QAAC,QAAQ;qBACnB,oBAACN,OAAKA;QACF,OAAOO,OAAO,QAAQ;QACtB,uBACI,oBAACC,aAAWA;YAAC,OAAO;yBAChB,oBAACC,wBAAsBA;sBAInC,oBAACV,MAAIA;QACD,QAAQ;QACR,MAAM;QACN,uBACI,oBAACA,KAAK,IAAI;YACN,MAAM;YACN,qBAAO,oBAACA,KAAK,IAAI,CAAC,KAAK;gBAAC,MAAK;;YAC7B,IAAIK,QAAQG,OAAO,QAAQ;YAC3B,UAAU;;uBAK1B,oBAACN,SAAS,WAAW;QACjB,MAAK;QACL,OAAM;QACN,aAAY;QACZ,oBAAM,oBAACS,gBAAcA;QACrB,QAAQC;;AAIxB;AAEO,MAAMC,YAAY,IACd,WAAP,GACI,wDACI,oBAACC,iBAAeA;QAAC,SAASC;sBAC1B,oBAACD,iBAAeA;QAAC,SAASE;sBAC1B,oBAACF,iBAAeA;QAAC,SAASG;sBAC1B,oBAACH,iBAAeA;QAAC,SAASI;sBAC1B,oBAACd,oBAAkBA,OAAAA,WAAAA,GAEnB,oBAACe,qBAAmBA,OAAAA,WAAAA,GAEpB,oBAACC,sBAAoBA,OAAAA,WAAAA,GAErB,oBAACC,0BAAwBA,OAAAA,WAAAA,GAEzB,oBAACC,yBAAuBA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Permissions } from "@webiny/app-admin/exports/admin/security.js";
|
|
2
|
+
import { AI_POWERUPS_PERMISSIONS_SCHEMA } from "../../../shared/permissionsSchema.js";
|
|
3
|
+
export declare const AiPowerUpsPermissions: import("@webiny/di").Abstraction<{
|
|
4
|
+
canAccess: (entityId: "settings") => boolean;
|
|
5
|
+
canAction: (action: string, entityId: "settings") => boolean;
|
|
6
|
+
} & {
|
|
7
|
+
canRead: (entityId: string) => boolean;
|
|
8
|
+
canCreate: (entityId: string) => boolean;
|
|
9
|
+
canEdit: (entityId: string, item?: import("@webiny/app-admin/permissions").OwnableItem) => boolean;
|
|
10
|
+
canDelete: (entityId: string, item?: import("@webiny/app-admin/permissions").OwnableItem) => boolean;
|
|
11
|
+
} & {
|
|
12
|
+
canPublish: (entityId: string) => boolean;
|
|
13
|
+
canUnpublish: (entityId: string) => boolean;
|
|
14
|
+
}>;
|
|
15
|
+
export declare namespace AiPowerUpsPermissions {
|
|
16
|
+
type Interface = Permissions<typeof AI_POWERUPS_PERMISSIONS_SCHEMA>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createPermissionsAbstraction } from "@webiny/app-admin/exports/admin/security.js";
|
|
2
|
+
import { AI_POWERUPS_PERMISSIONS_SCHEMA } from "../../../shared/permissionsSchema.js";
|
|
3
|
+
const AiPowerUpsPermissions = createPermissionsAbstraction(AI_POWERUPS_PERMISSIONS_SCHEMA);
|
|
4
|
+
export { AiPowerUpsPermissions };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=abstractions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin/features/permissions/abstractions.js","sources":["../../../../src/admin/features/permissions/abstractions.ts"],"sourcesContent":["import { createPermissionsAbstraction } from \"@webiny/app-admin/exports/admin/security.js\";\nimport type { Permissions } from \"@webiny/app-admin/exports/admin/security.js\";\nimport { AI_POWERUPS_PERMISSIONS_SCHEMA } from \"~/shared/permissionsSchema.js\";\n\nexport const AiPowerUpsPermissions = createPermissionsAbstraction(AI_POWERUPS_PERMISSIONS_SCHEMA);\n\nexport namespace AiPowerUpsPermissions {\n export type Interface = Permissions<typeof AI_POWERUPS_PERMISSIONS_SCHEMA>;\n}\n"],"names":["AiPowerUpsPermissions","createPermissionsAbstraction","AI_POWERUPS_PERMISSIONS_SCHEMA"],"mappings":";;AAIO,MAAMA,wBAAwBC,6BAA6BC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const AiPowerUpsPermissionsFeature: import("@webiny/feature/admin").FeatureDefinition<{
|
|
2
|
+
permissions: {
|
|
3
|
+
canAccess: (entityId: "settings") => boolean;
|
|
4
|
+
canAction: (action: string, entityId: "settings") => boolean;
|
|
5
|
+
} & {
|
|
6
|
+
canRead: (entityId: string) => boolean;
|
|
7
|
+
canCreate: (entityId: string) => boolean;
|
|
8
|
+
canEdit: (entityId: string, item?: import("@webiny/app-admin/index.js").OwnableItem) => boolean;
|
|
9
|
+
canDelete: (entityId: string, item?: import("@webiny/app-admin/index.js").OwnableItem) => boolean;
|
|
10
|
+
} & {
|
|
11
|
+
canPublish: (entityId: string) => boolean;
|
|
12
|
+
canUnpublish: (entityId: string) => boolean;
|
|
13
|
+
};
|
|
14
|
+
}, []>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createPermissionsFeature } from "@webiny/app-admin/exports/admin/security.js";
|
|
2
|
+
import { AI_POWERUPS_PERMISSIONS_SCHEMA } from "../../../shared/permissionsSchema.js";
|
|
3
|
+
import { AiPowerUpsPermissions } from "./abstractions.js";
|
|
4
|
+
const AiPowerUpsPermissionsFeature = createPermissionsFeature(AI_POWERUPS_PERMISSIONS_SCHEMA, AiPowerUpsPermissions);
|
|
5
|
+
export { AiPowerUpsPermissionsFeature };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin/features/permissions/feature.js","sources":["../../../../src/admin/features/permissions/feature.ts"],"sourcesContent":["import { createPermissionsFeature } from \"@webiny/app-admin/exports/admin/security.js\";\nimport { AI_POWERUPS_PERMISSIONS_SCHEMA } from \"~/shared/permissionsSchema.js\";\nimport { AiPowerUpsPermissions } from \"./abstractions.js\";\n\nexport const AiPowerUpsPermissionsFeature = createPermissionsFeature(\n AI_POWERUPS_PERMISSIONS_SCHEMA,\n AiPowerUpsPermissions\n);\n"],"names":["AiPowerUpsPermissionsFeature","createPermissionsFeature","AI_POWERUPS_PERMISSIONS_SCHEMA","AiPowerUpsPermissions"],"mappings":";;;AAIO,MAAMA,+BAA+BC,yBACxCC,gCACAC"}
|
|
@@ -19,7 +19,7 @@ declare class CmsCompareEntryRevisionsPresenterImpl implements CmsCompareEntryRe
|
|
|
19
19
|
compare(modelId: string): Promise<void>;
|
|
20
20
|
hideDialog(): void;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
declare const _default: typeof CmsCompareEntryRevisionsPresenterImpl & {
|
|
23
23
|
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ICmsCompareEntryRevisionsPresenter>;
|
|
24
24
|
};
|
|
25
|
-
export
|
|
25
|
+
export default _default;
|
|
@@ -78,13 +78,13 @@ class CmsCompareEntryRevisionsPresenterImpl {
|
|
|
78
78
|
this.selectedIds = [];
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
const
|
|
81
|
+
const CmsCompareEntryRevisions_CmsCompareEntryRevisionsPresenter = CmsCompareEntryRevisionsPresenter.createImplementation({
|
|
82
82
|
implementation: CmsCompareEntryRevisionsPresenterImpl,
|
|
83
83
|
dependencies: [
|
|
84
84
|
RevisionsListPresenter,
|
|
85
85
|
CompareEntryRevisionsUseCase
|
|
86
86
|
]
|
|
87
87
|
});
|
|
88
|
-
export
|
|
88
|
+
export default CmsCompareEntryRevisions_CmsCompareEntryRevisionsPresenter;
|
|
89
89
|
|
|
90
90
|
//# sourceMappingURL=CmsCompareEntryRevisionsPresenter.js.map
|
package/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js","sources":["../../../../src/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.ts"],"sourcesContent":["import { computed, makeAutoObservable, runInAction } from \"mobx\";\nimport { RevisionsListPresenter } from \"@webiny/app-headless-cms/exports/admin/cms/entry/editor.js\";\nimport { CompareEntryRevisionsUseCase } from \"~/admin/features/compareEntryRevisions/abstractions.js\";\nimport { CmsCompareEntryRevisionsPresenter } from \"./abstractions.js\";\nimport type { ICmsCompareEntryRevisionsViewModel } from \"./abstractions.js\";\n\nclass CmsCompareEntryRevisionsPresenterImpl implements CmsCompareEntryRevisionsPresenter.Interface {\n private drawerVisible = false;\n private selectedIds: string[] = [];\n private dialogVisible = false;\n private comparing = false;\n private error: string | null = null;\n private result: { html: string; summary: string } | null = null;\n\n constructor(\n private revisionsPresenter: RevisionsListPresenter.Interface,\n private useCase: CompareEntryRevisionsUseCase.Interface\n ) {\n makeAutoObservable<CmsCompareEntryRevisionsPresenterImpl, \"revisionsPresenter\" | \"useCase\">(\n this,\n {\n revisionsPresenter: false,\n useCase: false,\n vm: computed\n }\n );\n }\n\n get vm(): ICmsCompareEntryRevisionsViewModel {\n return {\n drawerVisible: this.drawerVisible,\n revisions: this.revisionsPresenter.vm.revisions,\n selectedIds: this.selectedIds,\n canCompare: this.selectedIds.length === 2,\n dialogVisible: this.dialogVisible,\n comparing: this.comparing,\n error: this.error,\n result: this.result\n };\n }\n\n showDrawer(): void {\n this.drawerVisible = true;\n }\n\n hideDrawer(): void {\n this.drawerVisible = false;\n this.selectedIds = [];\n }\n\n toggleRevision(revisionId: string): void {\n const index = this.selectedIds.indexOf(revisionId);\n if (index >= 0) {\n this.selectedIds = this.selectedIds.filter(id => id !== revisionId);\n } else if (this.selectedIds.length < 2) {\n this.selectedIds = [...this.selectedIds, revisionId];\n }\n }\n\n async compare(modelId: string): Promise<void> {\n if (this.selectedIds.length !== 2) {\n return;\n }\n\n this.drawerVisible = false;\n this.dialogVisible = true;\n this.comparing = true;\n this.error = null;\n this.result = null;\n\n try {\n const result = await this.useCase.execute({\n modelId,\n revisionId1: this.selectedIds[0],\n revisionId2: this.selectedIds[1]\n });\n\n runInAction(() => {\n this.result = result;\n });\n } catch (e: unknown) {\n runInAction(() => {\n this.error = e instanceof Error ? e.message : \"Failed to compare revisions\";\n });\n } finally {\n runInAction(() => {\n this.comparing = false;\n });\n }\n }\n\n hideDialog(): void {\n this.dialogVisible = false;\n this.result = null;\n this.error = null;\n this.selectedIds = [];\n }\n}\n\nexport
|
|
1
|
+
{"version":3,"file":"admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.js","sources":["../../../../src/admin/presentation/CmsCompareEntryRevisions/CmsCompareEntryRevisionsPresenter.ts"],"sourcesContent":["import { computed, makeAutoObservable, runInAction } from \"mobx\";\nimport { RevisionsListPresenter } from \"@webiny/app-headless-cms/exports/admin/cms/entry/editor.js\";\nimport { CompareEntryRevisionsUseCase } from \"~/admin/features/compareEntryRevisions/abstractions.js\";\nimport { CmsCompareEntryRevisionsPresenter } from \"./abstractions.js\";\nimport type { ICmsCompareEntryRevisionsViewModel } from \"./abstractions.js\";\n\nclass CmsCompareEntryRevisionsPresenterImpl implements CmsCompareEntryRevisionsPresenter.Interface {\n private drawerVisible = false;\n private selectedIds: string[] = [];\n private dialogVisible = false;\n private comparing = false;\n private error: string | null = null;\n private result: { html: string; summary: string } | null = null;\n\n constructor(\n private revisionsPresenter: RevisionsListPresenter.Interface,\n private useCase: CompareEntryRevisionsUseCase.Interface\n ) {\n makeAutoObservable<CmsCompareEntryRevisionsPresenterImpl, \"revisionsPresenter\" | \"useCase\">(\n this,\n {\n revisionsPresenter: false,\n useCase: false,\n vm: computed\n }\n );\n }\n\n get vm(): ICmsCompareEntryRevisionsViewModel {\n return {\n drawerVisible: this.drawerVisible,\n revisions: this.revisionsPresenter.vm.revisions,\n selectedIds: this.selectedIds,\n canCompare: this.selectedIds.length === 2,\n dialogVisible: this.dialogVisible,\n comparing: this.comparing,\n error: this.error,\n result: this.result\n };\n }\n\n showDrawer(): void {\n this.drawerVisible = true;\n }\n\n hideDrawer(): void {\n this.drawerVisible = false;\n this.selectedIds = [];\n }\n\n toggleRevision(revisionId: string): void {\n const index = this.selectedIds.indexOf(revisionId);\n if (index >= 0) {\n this.selectedIds = this.selectedIds.filter(id => id !== revisionId);\n } else if (this.selectedIds.length < 2) {\n this.selectedIds = [...this.selectedIds, revisionId];\n }\n }\n\n async compare(modelId: string): Promise<void> {\n if (this.selectedIds.length !== 2) {\n return;\n }\n\n this.drawerVisible = false;\n this.dialogVisible = true;\n this.comparing = true;\n this.error = null;\n this.result = null;\n\n try {\n const result = await this.useCase.execute({\n modelId,\n revisionId1: this.selectedIds[0],\n revisionId2: this.selectedIds[1]\n });\n\n runInAction(() => {\n this.result = result;\n });\n } catch (e: unknown) {\n runInAction(() => {\n this.error = e instanceof Error ? e.message : \"Failed to compare revisions\";\n });\n } finally {\n runInAction(() => {\n this.comparing = false;\n });\n }\n }\n\n hideDialog(): void {\n this.dialogVisible = false;\n this.result = null;\n this.error = null;\n this.selectedIds = [];\n }\n}\n\nexport default CmsCompareEntryRevisionsPresenter.createImplementation({\n implementation: CmsCompareEntryRevisionsPresenterImpl,\n dependencies: [RevisionsListPresenter, CompareEntryRevisionsUseCase]\n});\n"],"names":["CmsCompareEntryRevisionsPresenterImpl","revisionsPresenter","useCase","makeAutoObservable","computed","revisionId","index","id","modelId","result","runInAction","e","Error","CmsCompareEntryRevisionsPresenter","RevisionsListPresenter","CompareEntryRevisionsUseCase"],"mappings":";;;;AAMA,MAAMA;IAQF,YACYC,kBAAoD,EACpDC,OAA+C,CACzD;aAFUD,kBAAkB,GAAlBA;aACAC,OAAO,GAAPA;aATJ,aAAa,GAAG;aAChB,WAAW,GAAa,EAAE;aAC1B,aAAa,GAAG;aAChB,SAAS,GAAG;aACZ,KAAK,GAAkB;aACvB,MAAM,GAA6C;QAMvDC,mBACI,IAAI,EACJ;YACI,oBAAoB;YACpB,SAAS;YACT,IAAIC;QACR;IAER;IAEA,IAAI,KAAyC;QACzC,OAAO;YACH,eAAe,IAAI,CAAC,aAAa;YACjC,WAAW,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,SAAS;YAC/C,aAAa,IAAI,CAAC,WAAW;YAC7B,YAAY,AAA4B,MAA5B,IAAI,CAAC,WAAW,CAAC,MAAM;YACnC,eAAe,IAAI,CAAC,aAAa;YACjC,WAAW,IAAI,CAAC,SAAS;YACzB,OAAO,IAAI,CAAC,KAAK;YACjB,QAAQ,IAAI,CAAC,MAAM;QACvB;IACJ;IAEA,aAAmB;QACf,IAAI,CAAC,aAAa,GAAG;IACzB;IAEA,aAAmB;QACf,IAAI,CAAC,aAAa,GAAG;QACrB,IAAI,CAAC,WAAW,GAAG,EAAE;IACzB;IAEA,eAAeC,UAAkB,EAAQ;QACrC,MAAMC,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,CAACD;QACvC,IAAIC,SAAS,GACT,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAACC,CAAAA,KAAMA,OAAOF;aACrD,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,GACjC,IAAI,CAAC,WAAW,GAAG;eAAI,IAAI,CAAC,WAAW;YAAEA;SAAW;IAE5D;IAEA,MAAM,QAAQG,OAAe,EAAiB;QAC1C,IAAI,AAA4B,MAA5B,IAAI,CAAC,WAAW,CAAC,MAAM,EACvB;QAGJ,IAAI,CAAC,aAAa,GAAG;QACrB,IAAI,CAAC,aAAa,GAAG;QACrB,IAAI,CAAC,SAAS,GAAG;QACjB,IAAI,CAAC,KAAK,GAAG;QACb,IAAI,CAAC,MAAM,GAAG;QAEd,IAAI;YACA,MAAMC,SAAS,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;gBACtCD;gBACA,aAAa,IAAI,CAAC,WAAW,CAAC,EAAE;gBAChC,aAAa,IAAI,CAAC,WAAW,CAAC,EAAE;YACpC;YAEAE,YAAY;gBACR,IAAI,CAAC,MAAM,GAAGD;YAClB;QACJ,EAAE,OAAOE,GAAY;YACjBD,YAAY;gBACR,IAAI,CAAC,KAAK,GAAGC,aAAaC,QAAQD,EAAE,OAAO,GAAG;YAClD;QACJ,SAAU;YACND,YAAY;gBACR,IAAI,CAAC,SAAS,GAAG;YACrB;QACJ;IACJ;IAEA,aAAmB;QACf,IAAI,CAAC,aAAa,GAAG;QACrB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,KAAK,GAAG;QACb,IAAI,CAAC,WAAW,GAAG,EAAE;IACzB;AACJ;AAEA,mEAAeG,kCAAkC,oBAAoB,CAAC;IAClE,gBAAgBb;IAChB,cAAc;QAACc;QAAwBC;KAA6B;AACxE"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createFeature } from "@webiny/feature/admin";
|
|
2
2
|
import { CmsCompareEntryRevisionsPresenter } from "./abstractions.js";
|
|
3
|
-
import
|
|
3
|
+
import CmsCompareEntryRevisionsPresenter_0 from "./CmsCompareEntryRevisionsPresenter.js";
|
|
4
4
|
const CmsCompareEntryRevisionsPresentationFeature = createFeature({
|
|
5
5
|
name: "AiPowerUps/CmsCompareEntryRevisionsPresenter",
|
|
6
6
|
register (container) {
|
|
7
|
-
container.register(
|
|
7
|
+
container.register(CmsCompareEntryRevisionsPresenter_0).inSingletonScope();
|
|
8
8
|
},
|
|
9
9
|
resolve (container) {
|
|
10
10
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin/presentation/CmsCompareEntryRevisions/feature.js","sources":["../../../../src/admin/presentation/CmsCompareEntryRevisions/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { CmsCompareEntryRevisionsPresenter as Abstraction } from \"./abstractions.js\";\nimport
|
|
1
|
+
{"version":3,"file":"admin/presentation/CmsCompareEntryRevisions/feature.js","sources":["../../../../src/admin/presentation/CmsCompareEntryRevisions/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { CmsCompareEntryRevisionsPresenter as Abstraction } from \"./abstractions.js\";\nimport CmsCompareEntryRevisionsPresenter from \"./CmsCompareEntryRevisionsPresenter.js\";\n\nexport const CmsCompareEntryRevisionsPresentationFeature = createFeature({\n name: \"AiPowerUps/CmsCompareEntryRevisionsPresenter\",\n register(container) {\n container.register(CmsCompareEntryRevisionsPresenter).inSingletonScope();\n },\n resolve(container) {\n return {\n presenter: container.resolve(Abstraction)\n };\n }\n});\n"],"names":["CmsCompareEntryRevisionsPresentationFeature","createFeature","container","CmsCompareEntryRevisionsPresenter","Abstraction"],"mappings":";;;AAIO,MAAMA,8CAA8CC,cAAc;IACrE,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,qCAAmC,gBAAgB;IAC1E;IACA,SAAQD,SAAS;QACb,OAAO;YACH,WAAWA,UAAU,OAAO,CAACE;QACjC;IACJ;AACJ"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const HasPermission: import("react").FC<import("@webiny/app-admin/permissions").HasPermissionProps<{
|
|
2
|
+
prefix: string;
|
|
3
|
+
fullAccess: boolean;
|
|
4
|
+
entities: {
|
|
5
|
+
id: "settings";
|
|
6
|
+
title: string;
|
|
7
|
+
permission: string;
|
|
8
|
+
scopes: "full"[];
|
|
9
|
+
}[];
|
|
10
|
+
}>>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createHasPermission } from "@webiny/app-admin/exports/admin/security.js";
|
|
2
|
+
import { AiPowerUpsPermissions } from "../../features/permissions/index.js";
|
|
3
|
+
const HasPermission = createHasPermission(AiPowerUpsPermissions);
|
|
4
|
+
export { HasPermission };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=HasPermission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin/presentation/security/HasPermission.js","sources":["../../../../src/admin/presentation/security/HasPermission.tsx"],"sourcesContent":["import { createHasPermission } from \"@webiny/app-admin/exports/admin/security.js\";\nimport { AiPowerUpsPermissions } from \"~/admin/features/permissions/index.js\";\nimport { AI_POWERUPS_PERMISSIONS_SCHEMA } from \"~/shared/permissionsSchema.js\";\n\nexport const HasPermission =\n createHasPermission<typeof AI_POWERUPS_PERMISSIONS_SCHEMA>(AiPowerUpsPermissions);\n"],"names":["HasPermission","createHasPermission","AiPowerUpsPermissions"],"mappings":";;AAIO,MAAMA,gBACTC,oBAA2DC"}
|
package/api/Extension.js
CHANGED
|
@@ -3,7 +3,10 @@ import { WcpContext } from "@webiny/api-core/features/wcp/WcpContext/index.js";
|
|
|
3
3
|
import { BaseGraphQLSchema } from "./graphql/BaseGraphQLSchema.js";
|
|
4
4
|
import AiPowerUpsSettingsGraphQLMapper from "./graphql/AiPowerUpsSettingsGraphQLMapper.js";
|
|
5
5
|
import { AiPowerUpsSettingsCache } from "./features/shared/SettingsCache.js";
|
|
6
|
+
import { AiPowerUpsPermissionsFeature } from "./features/permissions/index.js";
|
|
6
7
|
import { GetSettingsFeature } from "./features/GetSettings/feature.js";
|
|
8
|
+
import { GetDecryptedSettingsFeature } from "./features/GetDecryptedSettings/feature.js";
|
|
9
|
+
import { ListModelsFeature } from "./features/ListModels/feature.js";
|
|
7
10
|
import { UpdateSettingsFeature } from "./features/UpdateSettings/feature.js";
|
|
8
11
|
import { WbGeneratePageContentFeature } from "./features/WbGeneratePageContent/feature.js";
|
|
9
12
|
import { ProvidersFeature } from "./features/Providers/feature.js";
|
|
@@ -25,7 +28,10 @@ const Extension = createFeature({
|
|
|
25
28
|
name: "AiPowerUps",
|
|
26
29
|
register (container) {
|
|
27
30
|
container.register(AiPowerUpsSettingsCache).inSingletonScope();
|
|
31
|
+
AiPowerUpsPermissionsFeature.register(container);
|
|
28
32
|
GetSettingsFeature.register(container);
|
|
33
|
+
GetDecryptedSettingsFeature.register(container);
|
|
34
|
+
ListModelsFeature.register(container);
|
|
29
35
|
UpdateSettingsFeature.register(container);
|
|
30
36
|
ProvidersFeature.register(container);
|
|
31
37
|
ConnectionsFeature.register(container);
|
package/api/Extension.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 { ConnectionsFeature } from \"./features/Connections/feature.js\";\nimport { ModelRolesFeature } from \"./features/ModelRoles/feature.js\";\nimport { CapabilitiesFeature } from \"./features/Capabilities/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\";\nimport { CmsGenerateEntryContentFeature } from \"./features/CmsGenerateEntryContent/feature.js\";\nimport { CmsResolveImageToolFeature } from \"./features/CmsResolveImageTool/feature.js\";\nimport { CmsCompareEntryRevisionsFeature } from \"./features/CmsCompareEntryRevisions/feature.js\";\nimport { WbTranslatePageFeature } from \"./features/WbTranslatePage/feature.js\";\nimport { CmsCompareEntryRevisionsSchema } from \"./graphql/CmsCompareEntryRevisionsSchema.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 /*\n * `ProvidersFeature` is still registered so the legacy `providers` section keeps round-\n * tripping through storage. `Connections` and `ModelRoles` read it once to seed\n * themselves; nothing else does. It goes away with the next breaking release.\n */\n ProvidersFeature.register(container);\n ConnectionsFeature.register(container);\n ModelRolesFeature.register(container);\n CapabilitiesFeature.register(container);\n ReaderPersonasFeature.register(container);\n WriterPersonasFeature.register(container);\n ProjectsFeature.register(container);\n AiPromptContextFeature.register(container);\n WbGeneratePageContentFeature.register(container);\n CmsGenerateEntryContentFeature.register(container);\n CmsResolveImageToolFeature.register(container);\n ExtractFrontmatterFeature.register(container);\n\n const wcp = container.resolve(WcpContext);\n if (wcp.canUseAiImageEnrichment()) {\n AiImageEnrichmentFeature.register(container);\n }\n\n CmsCompareEntryRevisionsFeature.register(container);\n\n // Without it, translating a page still copies it into the target language, untranslated.\n if (wcp.canUseAiPageTranslation()) {\n WbTranslatePageFeature.register(container);\n }\n\n container.register(AiPowerUpsSettingsGraphQLMapperImpl).inSingletonScope();\n container.register(BaseGraphQLSchema);\n container.register(CmsCompareEntryRevisionsSchema);\n }\n});\n"],"names":["Extension","createFeature","container","AiPowerUpsSettingsCache","GetSettingsFeature","UpdateSettingsFeature","ProvidersFeature","ConnectionsFeature","ModelRolesFeature","CapabilitiesFeature","ReaderPersonasFeature","WriterPersonasFeature","ProjectsFeature","AiPromptContextFeature","WbGeneratePageContentFeature","CmsGenerateEntryContentFeature","CmsResolveImageToolFeature","ExtractFrontmatterFeature","wcp","WcpContext","AiImageEnrichmentFeature","CmsCompareEntryRevisionsFeature","WbTranslatePageFeature","AiPowerUpsSettingsGraphQLMapperImpl","BaseGraphQLSchema","CmsCompareEntryRevisionsSchema"],"mappings":"
|
|
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 { AiPowerUpsPermissionsFeature } from \"./features/permissions/index.js\";\nimport { GetSettingsFeature } from \"./features/GetSettings/feature.js\";\nimport { GetDecryptedSettingsFeature } from \"./features/GetDecryptedSettings/feature.js\";\nimport { ListModelsFeature } from \"./features/ListModels/feature.js\";\nimport { UpdateSettingsFeature } from \"./features/UpdateSettings/feature.js\";\nimport { WbGeneratePageContentFeature } from \"./features/WbGeneratePageContent/feature.js\";\nimport { ProvidersFeature } from \"./features/Providers/feature.js\";\nimport { ConnectionsFeature } from \"./features/Connections/feature.js\";\nimport { ModelRolesFeature } from \"./features/ModelRoles/feature.js\";\nimport { CapabilitiesFeature } from \"./features/Capabilities/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\";\nimport { CmsGenerateEntryContentFeature } from \"./features/CmsGenerateEntryContent/feature.js\";\nimport { CmsResolveImageToolFeature } from \"./features/CmsResolveImageTool/feature.js\";\nimport { CmsCompareEntryRevisionsFeature } from \"./features/CmsCompareEntryRevisions/feature.js\";\nimport { WbTranslatePageFeature } from \"./features/WbTranslatePage/feature.js\";\nimport { CmsCompareEntryRevisionsSchema } from \"./graphql/CmsCompareEntryRevisionsSchema.js\";\n\nexport const Extension = createFeature({\n name: \"AiPowerUps\",\n register(container) {\n container.register(AiPowerUpsSettingsCache).inSingletonScope();\n\n AiPowerUpsPermissionsFeature.register(container);\n GetSettingsFeature.register(container);\n GetDecryptedSettingsFeature.register(container);\n ListModelsFeature.register(container);\n UpdateSettingsFeature.register(container);\n /*\n * `ProvidersFeature` is still registered so the legacy `providers` section keeps round-\n * tripping through storage. `Connections` and `ModelRoles` read it once to seed\n * themselves; nothing else does. It goes away with the next breaking release.\n */\n ProvidersFeature.register(container);\n ConnectionsFeature.register(container);\n ModelRolesFeature.register(container);\n CapabilitiesFeature.register(container);\n ReaderPersonasFeature.register(container);\n WriterPersonasFeature.register(container);\n ProjectsFeature.register(container);\n AiPromptContextFeature.register(container);\n WbGeneratePageContentFeature.register(container);\n CmsGenerateEntryContentFeature.register(container);\n CmsResolveImageToolFeature.register(container);\n ExtractFrontmatterFeature.register(container);\n\n const wcp = container.resolve(WcpContext);\n if (wcp.canUseAiImageEnrichment()) {\n AiImageEnrichmentFeature.register(container);\n }\n\n CmsCompareEntryRevisionsFeature.register(container);\n\n // Without it, translating a page still copies it into the target language, untranslated.\n if (wcp.canUseAiPageTranslation()) {\n WbTranslatePageFeature.register(container);\n }\n\n container.register(AiPowerUpsSettingsGraphQLMapperImpl).inSingletonScope();\n container.register(BaseGraphQLSchema);\n container.register(CmsCompareEntryRevisionsSchema);\n }\n});\n"],"names":["Extension","createFeature","container","AiPowerUpsSettingsCache","AiPowerUpsPermissionsFeature","GetSettingsFeature","GetDecryptedSettingsFeature","ListModelsFeature","UpdateSettingsFeature","ProvidersFeature","ConnectionsFeature","ModelRolesFeature","CapabilitiesFeature","ReaderPersonasFeature","WriterPersonasFeature","ProjectsFeature","AiPromptContextFeature","WbGeneratePageContentFeature","CmsGenerateEntryContentFeature","CmsResolveImageToolFeature","ExtractFrontmatterFeature","wcp","WcpContext","AiImageEnrichmentFeature","CmsCompareEntryRevisionsFeature","WbTranslatePageFeature","AiPowerUpsSettingsGraphQLMapperImpl","BaseGraphQLSchema","CmsCompareEntryRevisionsSchema"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA2BO,MAAMA,YAAYC,cAAc;IACnC,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,yBAAyB,gBAAgB;QAE5DC,6BAA6B,QAAQ,CAACF;QACtCG,mBAAmB,QAAQ,CAACH;QAC5BI,4BAA4B,QAAQ,CAACJ;QACrCK,kBAAkB,QAAQ,CAACL;QAC3BM,sBAAsB,QAAQ,CAACN;QAM/BO,iBAAiB,QAAQ,CAACP;QAC1BQ,mBAAmB,QAAQ,CAACR;QAC5BS,kBAAkB,QAAQ,CAACT;QAC3BU,oBAAoB,QAAQ,CAACV;QAC7BW,sBAAsB,QAAQ,CAACX;QAC/BY,sBAAsB,QAAQ,CAACZ;QAC/Ba,gBAAgB,QAAQ,CAACb;QACzBc,uBAAuB,QAAQ,CAACd;QAChCe,6BAA6B,QAAQ,CAACf;QACtCgB,+BAA+B,QAAQ,CAAChB;QACxCiB,2BAA2B,QAAQ,CAACjB;QACpCkB,0BAA0B,QAAQ,CAAClB;QAEnC,MAAMmB,MAAMnB,UAAU,OAAO,CAACoB;QAC9B,IAAID,IAAI,uBAAuB,IAC3BE,yBAAyB,QAAQ,CAACrB;QAGtCsB,gCAAgC,QAAQ,CAACtB;QAGzC,IAAImB,IAAI,uBAAuB,IAC3BI,uBAAuB,QAAQ,CAACvB;QAGpCA,UAAU,QAAQ,CAACwB,iCAAqC,gBAAgB;QACxExB,UAAU,QAAQ,CAACyB;QACnBzB,UAAU,QAAQ,CAAC0B;IACvB;AACJ"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
1
3
|
import { AiCapability, ListAiCapabilitiesUseCase } from "./abstractions.js";
|
|
2
4
|
import type { IAiCapabilitySummary } from "./abstractions.js";
|
|
3
5
|
/**
|
|
@@ -8,11 +10,12 @@ import type { IAiCapabilitySummary } from "./abstractions.js";
|
|
|
8
10
|
* capability's prompt is implementation, and the summary simply has no field for it.
|
|
9
11
|
*/
|
|
10
12
|
declare class ListAiCapabilitiesUseCaseImpl implements ListAiCapabilitiesUseCase.Interface {
|
|
13
|
+
private identityContext;
|
|
11
14
|
private capabilities;
|
|
12
|
-
constructor(capabilities: AiCapability.Interface[]);
|
|
13
|
-
execute(): Promise<IAiCapabilitySummary[]
|
|
15
|
+
constructor(identityContext: IdentityContext.Interface, capabilities: AiCapability.Interface[]);
|
|
16
|
+
execute(): Promise<Result<IAiCapabilitySummary[], Error>>;
|
|
14
17
|
}
|
|
15
|
-
|
|
18
|
+
declare const _default: typeof ListAiCapabilitiesUseCaseImpl & {
|
|
16
19
|
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IListAiCapabilitiesUseCase>;
|
|
17
20
|
};
|
|
18
|
-
export
|
|
21
|
+
export default _default;
|
|
@@ -1,20 +1,26 @@
|
|
|
1
|
+
import { Result } from "@webiny/feature/api";
|
|
2
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
3
|
+
import { NotAuthorizedError } from "@webiny/api-core/features/security/shared/errors.js";
|
|
1
4
|
import { AiCapability, ListAiCapabilitiesUseCase } from "./abstractions.js";
|
|
2
5
|
class ListAiCapabilitiesUseCaseImpl {
|
|
3
|
-
constructor(capabilities){
|
|
6
|
+
constructor(identityContext, capabilities){
|
|
7
|
+
this.identityContext = identityContext;
|
|
4
8
|
this.capabilities = capabilities;
|
|
5
9
|
}
|
|
6
10
|
async execute() {
|
|
7
|
-
|
|
11
|
+
if (this.identityContext.getIdentity().isAnonymous()) return Result.fail(new NotAuthorizedError());
|
|
12
|
+
return Result.ok(this.capabilities.map((capability)=>({
|
|
8
13
|
id: capability.id,
|
|
9
14
|
label: capability.label,
|
|
10
15
|
description: capability.description,
|
|
11
16
|
defaultRole: capability.defaultRole
|
|
12
|
-
}));
|
|
17
|
+
})));
|
|
13
18
|
}
|
|
14
19
|
}
|
|
15
|
-
const
|
|
20
|
+
const Capabilities_ListAiCapabilitiesUseCase = ListAiCapabilitiesUseCase.createImplementation({
|
|
16
21
|
implementation: ListAiCapabilitiesUseCaseImpl,
|
|
17
22
|
dependencies: [
|
|
23
|
+
IdentityContext,
|
|
18
24
|
[
|
|
19
25
|
AiCapability,
|
|
20
26
|
{
|
|
@@ -23,6 +29,6 @@ const ListAiCapabilitiesUseCaseImplementation = ListAiCapabilitiesUseCase.create
|
|
|
23
29
|
]
|
|
24
30
|
]
|
|
25
31
|
});
|
|
26
|
-
export
|
|
32
|
+
export default Capabilities_ListAiCapabilitiesUseCase;
|
|
27
33
|
|
|
28
34
|
//# sourceMappingURL=ListAiCapabilitiesUseCase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/Capabilities/ListAiCapabilitiesUseCase.js","sources":["../../../../src/api/features/Capabilities/ListAiCapabilitiesUseCase.ts"],"sourcesContent":["import { AiCapability, ListAiCapabilitiesUseCase } from \"./abstractions.js\";\nimport type { IAiCapabilitySummary } from \"./abstractions.js\";\n\n/**\n * Lists the registered capabilities for callers outside the api.\n *\n * The mapping lives here rather than in the GraphQL resolver so the shape sent over the wire is\n * decided once, next to the abstraction it describes. It also keeps `guidance` from leaking: a\n * capability's prompt is implementation, and the summary simply has no field for it.\n */\nclass ListAiCapabilitiesUseCaseImpl implements ListAiCapabilitiesUseCase.Interface {\n constructor(private capabilities: AiCapability.Interface[]) {}\n\n async execute(): Promise<IAiCapabilitySummary[]
|
|
1
|
+
{"version":3,"file":"api/features/Capabilities/ListAiCapabilitiesUseCase.js","sources":["../../../../src/api/features/Capabilities/ListAiCapabilitiesUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { NotAuthorizedError } from \"@webiny/api-core/features/security/shared/errors.js\";\nimport { AiCapability, ListAiCapabilitiesUseCase } from \"./abstractions.js\";\nimport type { IAiCapabilitySummary } from \"./abstractions.js\";\n\n/**\n * Lists the registered capabilities for callers outside the api.\n *\n * The mapping lives here rather than in the GraphQL resolver so the shape sent over the wire is\n * decided once, next to the abstraction it describes. It also keeps `guidance` from leaking: a\n * capability's prompt is implementation, and the summary simply has no field for it.\n */\nclass ListAiCapabilitiesUseCaseImpl implements ListAiCapabilitiesUseCase.Interface {\n constructor(\n private identityContext: IdentityContext.Interface,\n private capabilities: AiCapability.Interface[]\n ) {}\n\n async execute(): Promise<Result<IAiCapabilitySummary[], Error>> {\n if (this.identityContext.getIdentity().isAnonymous()) {\n return Result.fail(new NotAuthorizedError());\n }\n\n return Result.ok(\n this.capabilities.map(capability => ({\n id: capability.id,\n label: capability.label,\n description: capability.description,\n defaultRole: capability.defaultRole\n }))\n );\n }\n}\n\nexport default ListAiCapabilitiesUseCase.createImplementation({\n implementation: ListAiCapabilitiesUseCaseImpl,\n dependencies: [IdentityContext, [AiCapability, { multiple: true }]]\n});\n"],"names":["ListAiCapabilitiesUseCaseImpl","identityContext","capabilities","Result","NotAuthorizedError","capability","ListAiCapabilitiesUseCase","IdentityContext","AiCapability"],"mappings":";;;;AAaA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,YAAsC,CAChD;aAFUD,eAAe,GAAfA;aACAC,YAAY,GAAZA;IACT;IAEH,MAAM,UAA0D;QAC5D,IAAI,IAAI,CAAC,eAAe,CAAC,WAAW,GAAG,WAAW,IAC9C,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAG3B,OAAOD,OAAO,EAAE,CACZ,IAAI,CAAC,YAAY,CAAC,GAAG,CAACE,CAAAA,aAAe;gBACjC,IAAIA,WAAW,EAAE;gBACjB,OAAOA,WAAW,KAAK;gBACvB,aAAaA,WAAW,WAAW;gBACnC,aAAaA,WAAW,WAAW;YACvC;IAER;AACJ;AAEA,+CAAeC,0BAA0B,oBAAoB,CAAC;IAC1D,gBAAgBN;IAChB,cAAc;QAACO;QAAiB;YAACC;YAAc;gBAAE,UAAU;YAAK;SAAE;KAAC;AACvE"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Result } from "@webiny/feature/api";
|
|
2
|
-
import {
|
|
3
|
-
import { GetSettingsUseCase } from "../../../api/features/GetSettings/index.js";
|
|
2
|
+
import { GetDecryptedSettingsUseCase } from "../../../api/features/GetDecryptedSettings/index.js";
|
|
4
3
|
import { AiCapability, ResolveAiCapabilityUseCase } from "./abstractions.js";
|
|
5
4
|
import type { IResolvedAiCapability } from "./abstractions.js";
|
|
6
5
|
/**
|
|
@@ -19,13 +18,12 @@ import type { IResolvedAiCapability } from "./abstractions.js";
|
|
|
19
18
|
*/
|
|
20
19
|
declare class ResolveAiCapabilityUseCaseImpl implements ResolveAiCapabilityUseCase.Interface {
|
|
21
20
|
private getSettings;
|
|
22
|
-
private encryption;
|
|
23
21
|
private capabilityLookup;
|
|
24
|
-
constructor(capabilities: AiCapability.Interface[], getSettings:
|
|
22
|
+
constructor(capabilities: AiCapability.Interface[], getSettings: GetDecryptedSettingsUseCase.Interface);
|
|
25
23
|
execute(capabilityId: string): Promise<Result<IResolvedAiCapability, Error>>;
|
|
26
24
|
private selectModel;
|
|
27
25
|
}
|
|
28
|
-
|
|
26
|
+
declare const _default: typeof ResolveAiCapabilityUseCaseImpl & {
|
|
29
27
|
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IResolveAiCapabilityUseCase>;
|
|
30
28
|
};
|
|
31
|
-
export
|
|
29
|
+
export default _default;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { Result } from "@webiny/feature/api";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { NotAuthorizedError } from "@webiny/api-core/features/security/shared/errors.js";
|
|
3
|
+
import { GetDecryptedSettingsUseCase } from "../GetDecryptedSettings/index.js";
|
|
4
4
|
import { sdkNameFromModel } from "../shared/modelId.js";
|
|
5
5
|
import { AiCapability, ResolveAiCapabilityUseCase } from "./abstractions.js";
|
|
6
6
|
import { isCapabilityEnabled } from "./types.js";
|
|
7
7
|
import { AiCapabilityDisabledError } from "./AiCapabilityDisabledError.js";
|
|
8
8
|
const SETTINGS_PATH = "Settings → AI Power-Ups";
|
|
9
9
|
class ResolveAiCapabilityUseCaseImpl {
|
|
10
|
-
constructor(capabilities, getSettings
|
|
10
|
+
constructor(capabilities, getSettings){
|
|
11
11
|
this.getSettings = getSettings;
|
|
12
|
-
this.encryption = encryption;
|
|
13
12
|
this.capabilityLookup = new Map(capabilities.map((c)=>[
|
|
14
13
|
c.id,
|
|
15
14
|
c
|
|
@@ -19,7 +18,10 @@ class ResolveAiCapabilityUseCaseImpl {
|
|
|
19
18
|
const capability = this.capabilityLookup.get(capabilityId);
|
|
20
19
|
if (!capability) return Result.fail(new Error(`Unknown AI capability "${capabilityId}". Register it with the AiCapability abstraction.`));
|
|
21
20
|
const settingsResult = await this.getSettings.execute();
|
|
22
|
-
if (settingsResult.isFail())
|
|
21
|
+
if (settingsResult.isFail()) {
|
|
22
|
+
if (settingsResult.error instanceof NotAuthorizedError) return Result.fail(settingsResult.error);
|
|
23
|
+
return Result.fail(new Error("Failed to load AI Power-Ups settings."));
|
|
24
|
+
}
|
|
23
25
|
const settings = settingsResult.value;
|
|
24
26
|
const entry = settings.capabilities?.items?.[capabilityId];
|
|
25
27
|
if (!isCapabilityEnabled(entry)) return Result.fail(new AiCapabilityDisabledError(capabilityId, capability.label, SETTINGS_PATH));
|
|
@@ -29,7 +31,7 @@ class ResolveAiCapabilityUseCaseImpl {
|
|
|
29
31
|
const { connectionId, model, roleId, fellBackToStandard } = selection.value;
|
|
30
32
|
const connection = settings.connections?.presets?.find((c)=>c.id === connectionId);
|
|
31
33
|
if (!connection) return Result.fail(new Error(`"${capability.label}" points at a connection that no longer exists. Pick one under ${SETTINGS_PATH} → Model roles.`));
|
|
32
|
-
if (!connection.
|
|
34
|
+
if (!connection.apiKey) return Result.fail(new Error(`The connection "${connection.name}" has no API key. Add one under ${SETTINGS_PATH} → Connections.`));
|
|
33
35
|
const modelSdkName = sdkNameFromModel(model);
|
|
34
36
|
if (modelSdkName && connection.sdkName && modelSdkName !== connection.sdkName) return Result.fail(new Error(`The model "${model}" cannot run on the "${connection.name}" connection, which is a ${connection.sdkName} credential. Fix the pairing under ${SETTINGS_PATH} → Model roles.`));
|
|
35
37
|
return Result.ok({
|
|
@@ -37,7 +39,7 @@ class ResolveAiCapabilityUseCaseImpl {
|
|
|
37
39
|
model,
|
|
38
40
|
connection: {
|
|
39
41
|
sdkName: modelSdkName || connection.sdkName,
|
|
40
|
-
apiKey:
|
|
42
|
+
apiKey: connection.apiKey
|
|
41
43
|
},
|
|
42
44
|
roleId,
|
|
43
45
|
fellBackToStandard,
|
|
@@ -72,7 +74,7 @@ class ResolveAiCapabilityUseCaseImpl {
|
|
|
72
74
|
return Result.fail(new Error(`No model is configured for the "${requestedRole}" role. Pick one under ${SETTINGS_PATH} → Model roles.`));
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
|
-
const
|
|
77
|
+
const Capabilities_ResolveAiCapabilityUseCase = ResolveAiCapabilityUseCase.createImplementation({
|
|
76
78
|
implementation: ResolveAiCapabilityUseCaseImpl,
|
|
77
79
|
dependencies: [
|
|
78
80
|
[
|
|
@@ -81,10 +83,9 @@ const ResolveAiCapabilityUseCaseImplementation = ResolveAiCapabilityUseCase.crea
|
|
|
81
83
|
multiple: true
|
|
82
84
|
}
|
|
83
85
|
],
|
|
84
|
-
|
|
85
|
-
Encryption
|
|
86
|
+
GetDecryptedSettingsUseCase
|
|
86
87
|
]
|
|
87
88
|
});
|
|
88
|
-
export
|
|
89
|
+
export default Capabilities_ResolveAiCapabilityUseCase;
|
|
89
90
|
|
|
90
91
|
//# sourceMappingURL=ResolveAiCapabilityUseCase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/Capabilities/ResolveAiCapabilityUseCase.js","sources":["../../../../src/api/features/Capabilities/ResolveAiCapabilityUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { GetSettingsUseCase } from \"~/api/features/GetSettings/index.js\";\nimport { sdkNameFromModel } from \"~/api/features/shared/modelId.js\";\nimport { AiCapability, ResolveAiCapabilityUseCase } from \"./abstractions.js\";\nimport type { IResolvedAiCapability } from \"./abstractions.js\";\nimport { isCapabilityEnabled } from \"./types.js\";\nimport { AiCapabilityDisabledError } from \"./AiCapabilityDisabledError.js\";\nimport type { AiCapabilityOverride } from \"./types.js\";\nimport type { AiModelRoleId } from \"~/api/features/ModelRoles/index.js\";\nimport type { IAiPowerUpsSettings } from \"~/api/types.js\";\n\nconst SETTINGS_PATH = \"Settings → AI Power-Ups\";\n\n/**\n * Turns a capability id into the model, credential and prompt text a use case needs.\n *\n * This is the single place that knows the precedence rules. Before it existed, six use cases each\n * read `providers.presets[0]`, re-derived the SDK name from the model string and decrypted the key\n * themselves, so \"which model runs this feature\" had six answers that only happened to agree.\n *\n * Precedence: a capability's pinned connection+model, else its chosen role, else its declared\n * default role, else the `standard` role. The last step does not apply to `vision`, which fails\n * rather than sending images to a model that may not accept them.\n *\n * There is deliberately no environment-variable fallback. A project whose settings say one thing\n * and whose requests use another is the exact confusion this replaces.\n */\nclass ResolveAiCapabilityUseCaseImpl implements ResolveAiCapabilityUseCase.Interface {\n private capabilityLookup: Map<string, AiCapability.Interface>;\n\n constructor(\n capabilities: AiCapability.Interface[],\n private getSettings: GetSettingsUseCase.Interface,\n private encryption: Encryption.Interface\n ) {\n this.capabilityLookup = new Map(capabilities.map(c => [c.id, c]));\n }\n\n async execute(capabilityId: string): Promise<Result<IResolvedAiCapability, Error>> {\n const capability = this.capabilityLookup.get(capabilityId);\n\n if (!capability) {\n // Nothing a project can do about this one: the caller passed an unregistered id.\n return Result.fail(\n new Error(\n `Unknown AI capability \"${capabilityId}\". Register it with the AiCapability abstraction.`\n )\n );\n }\n\n const settingsResult = await this.getSettings.execute();\n if (settingsResult.isFail()) {\n return Result.fail(new Error(\"Failed to load AI Power-Ups settings.\"));\n }\n\n const settings = settingsResult.value;\n const entry = settings.capabilities?.items?.[capabilityId];\n\n /*\n * Checked here rather than at every call site, so a capability switched off in settings is\n * off for the GraphQL mutation as much as for the button that usually triggers it. The\n * admin hides the affordance too, but that is a courtesy and this is the actual gate.\n */\n if (!isCapabilityEnabled(entry)) {\n return Result.fail(\n new AiCapabilityDisabledError(capabilityId, capability.label, SETTINGS_PATH)\n );\n }\n\n const override: AiCapabilityOverride = entry?.overrides ?? {};\n\n const selection = this.selectModel(settings, capability.defaultRole, override);\n if (selection.isFail()) {\n return Result.fail(selection.error);\n }\n\n const { connectionId, model, roleId, fellBackToStandard } = selection.value;\n\n const connection = settings.connections?.presets?.find(c => c.id === connectionId);\n\n if (!connection) {\n return Result.fail(\n new Error(\n `\"${capability.label}\" points at a connection that no longer exists. Pick one under ${SETTINGS_PATH} → Model roles.`\n )\n );\n }\n\n if (!connection.apiKeyEncrypted) {\n return Result.fail(\n new Error(\n `The connection \"${connection.name}\" has no API key. Add one under ${SETTINGS_PATH} → Connections.`\n )\n );\n }\n\n /*\n * A model is stored fully qualified (\"anthropic/claude-sonnet-4-5\") and a connection stores\n * its vendor separately, so the two can disagree if a connection is re-pointed at another\n * vendor after a role was filled. Catching it here beats a provider-side auth error.\n */\n const modelSdkName = sdkNameFromModel(model);\n if (modelSdkName && connection.sdkName && modelSdkName !== connection.sdkName) {\n return Result.fail(\n new Error(\n `The model \"${model}\" cannot run on the \"${connection.name}\" connection, which is a ${connection.sdkName} credential. Fix the pairing under ${SETTINGS_PATH} → Model roles.`\n )\n );\n }\n\n return Result.ok({\n capabilityId,\n model,\n connection: {\n sdkName: modelSdkName || connection.sdkName,\n apiKey: await this.encryption.decrypt(connection.apiKeyEncrypted)\n },\n roleId,\n fellBackToStandard,\n // Always the capability's own. Projects adjust prompts by appending, never by\n // replacing, because for most capabilities the prompt is the output contract.\n guidance: capability.guidance ?? \"\",\n additionalInstructions: override.additionalInstructions?.trim() ?? \"\"\n });\n }\n\n private selectModel(\n settings: IAiPowerUpsSettings,\n defaultRole: AiModelRoleId,\n override: AiCapabilityOverride\n ): Result<\n {\n connectionId: string;\n model: string;\n roleId: AiModelRoleId | null;\n fellBackToStandard: boolean;\n },\n Error\n > {\n // A pinned connection+model wins outright. Both halves are required; one alone is a\n // half-finished edit, so it is ignored rather than guessed at.\n if (override.connectionId && override.model) {\n return Result.ok({\n connectionId: override.connectionId,\n model: override.model,\n roleId: null,\n fellBackToStandard: false\n });\n }\n\n const roles = settings.modelRoles?.roles;\n const requestedRole = (override.roleId || defaultRole) as AiModelRoleId;\n const requested = roles?.[requestedRole];\n\n if (requested?.connectionId && requested.model) {\n return Result.ok({\n connectionId: requested.connectionId,\n model: requested.model,\n roleId: requestedRole,\n fellBackToStandard: false\n });\n }\n\n /*\n * `vision` never falls back. Work on this role sends images, and nothing guarantees the\n * Standard model accepts them, so falling through would trade a clear \"set a Vision model\"\n * for a provider error about image input, or a text-only model silently guessing.\n *\n * Upgrades are not broken by this: `ModelRolesHandler` seeds `vision` from the legacy\n * preset alongside `standard`, so a project that ran image work on `providers.presets[0]`\n * keeps running it there, with the choice visible on the settings screen. A capability can\n * still be pointed at another role deliberately through its `roleId` override.\n */\n if (requestedRole === \"vision\") {\n return Result.fail(\n new Error(\n `No model is configured for the \"vision\" role, and image work does not fall back to Standard. Pick one under ${SETTINGS_PATH} → Model roles.`\n )\n );\n }\n\n /*\n * Every other role falls back to `standard`. Running cheap work on a stronger model is\n * always correct, only more expensive.\n */\n const standard = roles?.standard;\n\n if (standard?.connectionId && standard.model) {\n return Result.ok({\n connectionId: standard.connectionId,\n model: standard.model,\n roleId: \"standard\",\n fellBackToStandard: requestedRole !== \"standard\"\n });\n }\n\n return Result.fail(\n new Error(\n `No model is configured for the \"${requestedRole}\" role. Pick one under ${SETTINGS_PATH} → Model roles.`\n )\n );\n }\n}\n\nexport const ResolveAiCapabilityUseCaseImplementation =\n ResolveAiCapabilityUseCase.createImplementation({\n implementation: ResolveAiCapabilityUseCaseImpl,\n dependencies: [[AiCapability, { multiple: true }], GetSettingsUseCase, Encryption]\n });\n"],"names":["SETTINGS_PATH","ResolveAiCapabilityUseCaseImpl","capabilities","getSettings","encryption","Map","c","capabilityId","capability","Result","Error","settingsResult","settings","entry","isCapabilityEnabled","AiCapabilityDisabledError","override","selection","connectionId","model","roleId","fellBackToStandard","connection","modelSdkName","sdkNameFromModel","defaultRole","roles","requestedRole","requested","standard","ResolveAiCapabilityUseCaseImplementation","ResolveAiCapabilityUseCase","AiCapability","GetSettingsUseCase","Encryption"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api/features/Capabilities/ResolveAiCapabilityUseCase.js","sources":["../../../../src/api/features/Capabilities/ResolveAiCapabilityUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { NotAuthorizedError } from \"@webiny/api-core/features/security/shared/errors.js\";\nimport { GetDecryptedSettingsUseCase } from \"~/api/features/GetDecryptedSettings/index.js\";\nimport { sdkNameFromModel } from \"~/api/features/shared/modelId.js\";\nimport { AiCapability, ResolveAiCapabilityUseCase } from \"./abstractions.js\";\nimport type { IResolvedAiCapability } from \"./abstractions.js\";\nimport { isCapabilityEnabled } from \"./types.js\";\nimport { AiCapabilityDisabledError } from \"./AiCapabilityDisabledError.js\";\nimport type { AiCapabilityOverride } from \"./types.js\";\nimport type { AiModelRoleId } from \"~/api/features/ModelRoles/index.js\";\nimport type { IAiPowerUpsSettings } from \"~/api/types.js\";\n\nconst SETTINGS_PATH = \"Settings → AI Power-Ups\";\n\n/**\n * Turns a capability id into the model, credential and prompt text a use case needs.\n *\n * This is the single place that knows the precedence rules. Before it existed, six use cases each\n * read `providers.presets[0]`, re-derived the SDK name from the model string and decrypted the key\n * themselves, so \"which model runs this feature\" had six answers that only happened to agree.\n *\n * Precedence: a capability's pinned connection+model, else its chosen role, else its declared\n * default role, else the `standard` role. The last step does not apply to `vision`, which fails\n * rather than sending images to a model that may not accept them.\n *\n * There is deliberately no environment-variable fallback. A project whose settings say one thing\n * and whose requests use another is the exact confusion this replaces.\n */\nclass ResolveAiCapabilityUseCaseImpl implements ResolveAiCapabilityUseCase.Interface {\n private capabilityLookup: Map<string, AiCapability.Interface>;\n\n constructor(\n capabilities: AiCapability.Interface[],\n private getSettings: GetDecryptedSettingsUseCase.Interface\n ) {\n this.capabilityLookup = new Map(capabilities.map(c => [c.id, c]));\n }\n\n async execute(capabilityId: string): Promise<Result<IResolvedAiCapability, Error>> {\n const capability = this.capabilityLookup.get(capabilityId);\n\n if (!capability) {\n // Nothing a project can do about this one: the caller passed an unregistered id.\n return Result.fail(\n new Error(\n `Unknown AI capability \"${capabilityId}\". Register it with the AiCapability abstraction.`\n )\n );\n }\n\n const settingsResult = await this.getSettings.execute();\n if (settingsResult.isFail()) {\n if (settingsResult.error instanceof NotAuthorizedError) {\n return Result.fail(settingsResult.error);\n }\n return Result.fail(new Error(\"Failed to load AI Power-Ups settings.\"));\n }\n\n const settings = settingsResult.value;\n const entry = settings.capabilities?.items?.[capabilityId];\n\n /*\n * Checked here rather than at every call site, so a capability switched off in settings is\n * off for the GraphQL mutation as much as for the button that usually triggers it. The\n * admin hides the affordance too, but that is a courtesy and this is the actual gate.\n */\n if (!isCapabilityEnabled(entry)) {\n return Result.fail(\n new AiCapabilityDisabledError(capabilityId, capability.label, SETTINGS_PATH)\n );\n }\n\n const override: AiCapabilityOverride = entry?.overrides ?? {};\n\n const selection = this.selectModel(settings, capability.defaultRole, override);\n if (selection.isFail()) {\n return Result.fail(selection.error);\n }\n\n const { connectionId, model, roleId, fellBackToStandard } = selection.value;\n\n const connection = settings.connections?.presets?.find(c => c.id === connectionId);\n\n if (!connection) {\n return Result.fail(\n new Error(\n `\"${capability.label}\" points at a connection that no longer exists. Pick one under ${SETTINGS_PATH} → Model roles.`\n )\n );\n }\n\n if (!connection.apiKey) {\n return Result.fail(\n new Error(\n `The connection \"${connection.name}\" has no API key. Add one under ${SETTINGS_PATH} → Connections.`\n )\n );\n }\n\n /*\n * A model is stored fully qualified (\"anthropic/claude-sonnet-4-5\") and a connection stores\n * its vendor separately, so the two can disagree if a connection is re-pointed at another\n * vendor after a role was filled. Catching it here beats a provider-side auth error.\n */\n const modelSdkName = sdkNameFromModel(model);\n if (modelSdkName && connection.sdkName && modelSdkName !== connection.sdkName) {\n return Result.fail(\n new Error(\n `The model \"${model}\" cannot run on the \"${connection.name}\" connection, which is a ${connection.sdkName} credential. Fix the pairing under ${SETTINGS_PATH} → Model roles.`\n )\n );\n }\n\n return Result.ok({\n capabilityId,\n model,\n connection: {\n sdkName: modelSdkName || connection.sdkName,\n apiKey: connection.apiKey\n },\n roleId,\n fellBackToStandard,\n // Always the capability's own. Projects adjust prompts by appending, never by\n // replacing, because for most capabilities the prompt is the output contract.\n guidance: capability.guidance ?? \"\",\n additionalInstructions: override.additionalInstructions?.trim() ?? \"\"\n });\n }\n\n private selectModel(\n settings: IAiPowerUpsSettings,\n defaultRole: AiModelRoleId,\n override: AiCapabilityOverride\n ): Result<\n {\n connectionId: string;\n model: string;\n roleId: AiModelRoleId | null;\n fellBackToStandard: boolean;\n },\n Error\n > {\n // A pinned connection+model wins outright. Both halves are required; one alone is a\n // half-finished edit, so it is ignored rather than guessed at.\n if (override.connectionId && override.model) {\n return Result.ok({\n connectionId: override.connectionId,\n model: override.model,\n roleId: null,\n fellBackToStandard: false\n });\n }\n\n const roles = settings.modelRoles?.roles;\n const requestedRole = (override.roleId || defaultRole) as AiModelRoleId;\n const requested = roles?.[requestedRole];\n\n if (requested?.connectionId && requested.model) {\n return Result.ok({\n connectionId: requested.connectionId,\n model: requested.model,\n roleId: requestedRole,\n fellBackToStandard: false\n });\n }\n\n /*\n * `vision` never falls back. Work on this role sends images, and nothing guarantees the\n * Standard model accepts them, so falling through would trade a clear \"set a Vision model\"\n * for a provider error about image input, or a text-only model silently guessing.\n *\n * Upgrades are not broken by this: `ModelRolesHandler` seeds `vision` from the legacy\n * preset alongside `standard`, so a project that ran image work on `providers.presets[0]`\n * keeps running it there, with the choice visible on the settings screen. A capability can\n * still be pointed at another role deliberately through its `roleId` override.\n */\n if (requestedRole === \"vision\") {\n return Result.fail(\n new Error(\n `No model is configured for the \"vision\" role, and image work does not fall back to Standard. Pick one under ${SETTINGS_PATH} → Model roles.`\n )\n );\n }\n\n /*\n * Every other role falls back to `standard`. Running cheap work on a stronger model is\n * always correct, only more expensive.\n */\n const standard = roles?.standard;\n\n if (standard?.connectionId && standard.model) {\n return Result.ok({\n connectionId: standard.connectionId,\n model: standard.model,\n roleId: \"standard\",\n fellBackToStandard: requestedRole !== \"standard\"\n });\n }\n\n return Result.fail(\n new Error(\n `No model is configured for the \"${requestedRole}\" role. Pick one under ${SETTINGS_PATH} → Model roles.`\n )\n );\n }\n}\n\nexport default ResolveAiCapabilityUseCase.createImplementation({\n implementation: ResolveAiCapabilityUseCaseImpl,\n dependencies: [[AiCapability, { multiple: true }], GetDecryptedSettingsUseCase]\n});\n"],"names":["SETTINGS_PATH","ResolveAiCapabilityUseCaseImpl","capabilities","getSettings","Map","c","capabilityId","capability","Result","Error","settingsResult","NotAuthorizedError","settings","entry","isCapabilityEnabled","AiCapabilityDisabledError","override","selection","connectionId","model","roleId","fellBackToStandard","connection","modelSdkName","sdkNameFromModel","defaultRole","roles","requestedRole","requested","standard","ResolveAiCapabilityUseCase","AiCapability","GetDecryptedSettingsUseCase"],"mappings":"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"}
|
|
@@ -48,7 +48,7 @@ export interface IAiCapabilitySummary {
|
|
|
48
48
|
defaultRole: AiModelRoleId;
|
|
49
49
|
}
|
|
50
50
|
export interface IListAiCapabilitiesUseCase {
|
|
51
|
-
execute(): Promise<IAiCapabilitySummary[]
|
|
51
|
+
execute(): Promise<Result<IAiCapabilitySummary[], Error>>;
|
|
52
52
|
}
|
|
53
53
|
/** Everything registered, for the settings screen to render a row per feature. */
|
|
54
54
|
export declare const ListAiCapabilitiesUseCase: import("@webiny/di").Abstraction<IListAiCapabilitiesUseCase>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api/features/Capabilities/abstractions.js","sources":["../../../../src/api/features/Capabilities/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\nimport type { AiModelRoleId } from \"~/api/features/ModelRoles/index.js\";\n\n/**\n * One AI feature, declared so the settings screen can list it and a project can point it at a\n * different model or adjust its prompt.\n *\n * Features register these; nothing hardcodes the list. An extension that adds an AI feature gets a\n * row in Settings for free by registering a capability alongside it.\n */\nexport interface IAiCapability {\n /**\n * Stable, prefixed with its app (`cmsGenerateEntry`), and persisted as a settings key. Renaming\n * one orphans its overrides.\n *\n * No dots. The id becomes a key under `capabilities.items`, and the settings form names its\n * fields by dotted path, so `cms.generateEntry` reads as two levels of nesting.\n */\n readonly id: string;\n readonly label: string;\n readonly description: string;\n /** Which role supplies the model when the project has not overridden this capability. */\n readonly defaultRole: AiModelRoleId;\n /**\n * The capability's fixed system-prompt block, owned by the code and not configurable.\n *\n * Leave it undefined when the prompt is assembled per request (from a content model schema, a\n * component catalog, a persona) and the use case builds its own system text instead.\n *\n * Either way a project can only append to it, via `additionalInstructions`. These prompts carry\n * the output contract the surrounding code parses, so they are implementation, not settings.\n */\n readonly guidance?: string;\n}\n\nexport const AiCapability = createAbstraction<IAiCapability>(\"AiPowerUpsAiCapability\");\n\nexport namespace AiCapability {\n export type Interface = IAiCapability;\n}\n\n/**\n * What a capability looks like to a caller outside the api.\n *\n * `guidance` is deliberately absent: a prompt is implementation, and there is no reason to ship ours\n * over the wire to anyone who can read settings.\n */\nexport interface IAiCapabilitySummary {\n id: string;\n label: string;\n description: string;\n defaultRole: AiModelRoleId;\n}\n\nexport interface IListAiCapabilitiesUseCase {\n execute(): Promise<IAiCapabilitySummary[]
|
|
1
|
+
{"version":3,"file":"api/features/Capabilities/abstractions.js","sources":["../../../../src/api/features/Capabilities/abstractions.ts"],"sourcesContent":["import { createAbstraction, Result } from \"@webiny/feature/api\";\nimport type { AiModelRoleId } from \"~/api/features/ModelRoles/index.js\";\n\n/**\n * One AI feature, declared so the settings screen can list it and a project can point it at a\n * different model or adjust its prompt.\n *\n * Features register these; nothing hardcodes the list. An extension that adds an AI feature gets a\n * row in Settings for free by registering a capability alongside it.\n */\nexport interface IAiCapability {\n /**\n * Stable, prefixed with its app (`cmsGenerateEntry`), and persisted as a settings key. Renaming\n * one orphans its overrides.\n *\n * No dots. The id becomes a key under `capabilities.items`, and the settings form names its\n * fields by dotted path, so `cms.generateEntry` reads as two levels of nesting.\n */\n readonly id: string;\n readonly label: string;\n readonly description: string;\n /** Which role supplies the model when the project has not overridden this capability. */\n readonly defaultRole: AiModelRoleId;\n /**\n * The capability's fixed system-prompt block, owned by the code and not configurable.\n *\n * Leave it undefined when the prompt is assembled per request (from a content model schema, a\n * component catalog, a persona) and the use case builds its own system text instead.\n *\n * Either way a project can only append to it, via `additionalInstructions`. These prompts carry\n * the output contract the surrounding code parses, so they are implementation, not settings.\n */\n readonly guidance?: string;\n}\n\nexport const AiCapability = createAbstraction<IAiCapability>(\"AiPowerUpsAiCapability\");\n\nexport namespace AiCapability {\n export type Interface = IAiCapability;\n}\n\n/**\n * What a capability looks like to a caller outside the api.\n *\n * `guidance` is deliberately absent: a prompt is implementation, and there is no reason to ship ours\n * over the wire to anyone who can read settings.\n */\nexport interface IAiCapabilitySummary {\n id: string;\n label: string;\n description: string;\n defaultRole: AiModelRoleId;\n}\n\nexport interface IListAiCapabilitiesUseCase {\n execute(): Promise<Result<IAiCapabilitySummary[], Error>>;\n}\n\n/** Everything registered, for the settings screen to render a row per feature. */\nexport const ListAiCapabilitiesUseCase = createAbstraction<IListAiCapabilitiesUseCase>(\n \"AiPowerUpsListAiCapabilitiesUseCase\"\n);\n\nexport namespace ListAiCapabilitiesUseCase {\n export type Interface = IListAiCapabilitiesUseCase;\n export type Summary = IAiCapabilitySummary;\n}\n\nexport interface IResolvedAiCapability {\n capabilityId: string;\n /** Fully qualified, e.g. `\"anthropic/claude-sonnet-4-5\"`. */\n model: string;\n connection: {\n sdkName: string;\n apiKey: string;\n };\n /** Which role supplied the model. `null` when a capability override pinned it directly. */\n roleId: AiModelRoleId | null;\n /** True when the requested role was empty and `standard` filled in for it. */\n fellBackToStandard: boolean;\n /** The capability's own guidance. Empty when it assembles its prompt per request. */\n guidance: string;\n /** Project text to append to the system prompt. Empty when unset. */\n additionalInstructions: string;\n}\n\nexport interface IResolveAiCapabilityUseCase {\n execute(capabilityId: string): Promise<Result<IResolvedAiCapability, Error>>;\n}\n\nexport const ResolveAiCapabilityUseCase = createAbstraction<IResolveAiCapabilityUseCase>(\n \"AiPowerUpsResolveAiCapabilityUseCase\"\n);\n\nexport namespace ResolveAiCapabilityUseCase {\n export type Interface = IResolveAiCapabilityUseCase;\n export type Resolution = IResolvedAiCapability;\n}\n"],"names":["AiCapability","createAbstraction","ListAiCapabilitiesUseCase","ResolveAiCapabilityUseCase"],"mappings":";AAmCO,MAAMA,eAAeC,kBAAiC;AAwBtD,MAAMC,4BAA4BD,kBACrC;AA8BG,MAAME,6BAA6BF,kBACtC"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createFeature } from "@webiny/feature/api";
|
|
2
2
|
import CapabilitiesHandler from "./CapabilitiesHandler.js";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import ResolveAiCapabilityUseCase from "./ResolveAiCapabilityUseCase.js";
|
|
4
|
+
import ListAiCapabilitiesUseCase from "./ListAiCapabilitiesUseCase.js";
|
|
5
5
|
const CapabilitiesFeature = createFeature({
|
|
6
6
|
name: "AiPowerUpsCapabilities",
|
|
7
7
|
register (container) {
|
|
8
8
|
container.register(CapabilitiesHandler);
|
|
9
|
-
container.register(
|
|
10
|
-
container.register(
|
|
9
|
+
container.register(ResolveAiCapabilityUseCase);
|
|
10
|
+
container.register(ListAiCapabilitiesUseCase);
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
13
|
export { CapabilitiesFeature };
|