@webiny/app-admin 6.6.0-alpha.4 → 6.6.0-alpha.6

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 (46) hide show
  1. package/base/Admin.js +2 -2
  2. package/base/Admin.js.map +1 -1
  3. package/features/{aiChat/AiChatGateway.d.ts → adminAssistant/AdminAssistantGateway.d.ts} +7 -7
  4. package/features/{aiChat/AiChatGateway.js → adminAssistant/AdminAssistantGateway.js} +8 -8
  5. package/features/adminAssistant/AdminAssistantGateway.js.map +1 -0
  6. package/features/{aiChat/AiChatPresenter.d.ts → adminAssistant/AdminAssistantPresenter.d.ts} +7 -7
  7. package/features/{aiChat/AiChatPresenter.js → adminAssistant/AdminAssistantPresenter.js} +7 -7
  8. package/features/adminAssistant/AdminAssistantPresenter.js.map +1 -0
  9. package/features/{aiChat → adminAssistant}/abstractions.d.ts +30 -30
  10. package/features/adminAssistant/abstractions.js +6 -0
  11. package/features/adminAssistant/abstractions.js.map +1 -0
  12. package/features/adminAssistant/feature.d.ts +3 -0
  13. package/features/adminAssistant/feature.js +19 -0
  14. package/features/adminAssistant/feature.js.map +1 -0
  15. package/features/adminAssistant/index.d.ts +6 -0
  16. package/features/adminAssistant/index.js +3 -0
  17. package/features/formModel/Field.d.ts +6 -0
  18. package/features/formModel/Field.js +11 -0
  19. package/features/formModel/Field.js.map +1 -1
  20. package/features/formModel/Rules.test.js +55 -0
  21. package/features/formModel/Rules.test.js.map +1 -1
  22. package/features/wcp/ReactLicense.d.ts +5 -0
  23. package/features/wcp/ReactLicense.js +15 -0
  24. package/features/wcp/ReactLicense.js.map +1 -1
  25. package/features/wcp/WcpGateway.js +4 -0
  26. package/features/wcp/WcpGateway.js.map +1 -1
  27. package/hooks/useHotkeys.js +2 -2
  28. package/hooks/useHotkeys.js.map +1 -1
  29. package/index.d.ts +2 -2
  30. package/index.js +1 -1
  31. package/package.json +20 -20
  32. package/presentation/commandPalette/CommandPalettePresenter.js +2 -1
  33. package/presentation/commandPalette/CommandPalettePresenter.js.map +1 -1
  34. package/presentation/commandPalette/abstractions.d.ts +2 -0
  35. package/presentation/commandPalette/abstractions.js.map +1 -1
  36. package/presentation/commandPalette/commands/AskAiCommand.js +1 -1
  37. package/presentation/commandPalette/commands/AskAiCommand.js.map +1 -1
  38. package/features/aiChat/AiChatGateway.js.map +0 -1
  39. package/features/aiChat/AiChatPresenter.js.map +0 -1
  40. package/features/aiChat/abstractions.js +0 -6
  41. package/features/aiChat/abstractions.js.map +0 -1
  42. package/features/aiChat/feature.d.ts +0 -3
  43. package/features/aiChat/feature.js +0 -19
  44. package/features/aiChat/feature.js.map +0 -1
  45. package/features/aiChat/index.d.ts +0 -6
  46. package/features/aiChat/index.js +0 -3
package/base/Admin.js CHANGED
@@ -24,7 +24,7 @@ import { NotificationsRenderer } from "../features/notifications/NotificationsRe
24
24
  import { ListCustomIconsFeature } from "../features/iconPicker/listCustomIcons/feature.js";
25
25
  import { CustomIconsPresenterFeature } from "../presentation/iconPicker/customIcons/feature.js";
26
26
  import { CommandPaletteFeature } from "../presentation/commandPalette/index.js";
27
- import { AiChatFeature } from "../features/aiChat/index.js";
27
+ import { AdminAssistantFeature } from "../features/adminAssistant/index.js";
28
28
  import { AdminCommandsFeature } from "../presentation/commandPalette/commands/feature.js";
29
29
  const container = createRootContainer();
30
30
  const Admin = ({ children, createLegacyPlugins })=>{
@@ -37,7 +37,7 @@ const Admin = ({ children, createLegacyPlugins })=>{
37
37
  ListPresenterFeature.register(container);
38
38
  ListCustomIconsFeature.register(container);
39
39
  CustomIconsPresenterFeature.register(container);
40
- AiChatFeature.register(container);
40
+ AdminAssistantFeature.register(container);
41
41
  CommandPaletteFeature.register(container);
42
42
  AdminCommandsFeature.register(container);
43
43
  SortableFeature.register(container);
package/base/Admin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"base/Admin.js","sources":["../../src/base/Admin.tsx"],"sourcesContent":["import React from \"react\";\nimport type { Container } from \"@webiny/di\";\nimport { plugins } from \"@webiny/plugins\";\nimport { App, DiContainerProvider } from \"@webiny/app\";\nimport { Base } from \"./Base.js\";\nimport { createUiStateProvider } from \"./providers/UiStateProvider.js\";\nimport { createAdminUiStateProvider } from \"./providers/AdminUiStateProvider.js\";\nimport { createUiProviders } from \"./providers/UiProviders.js\";\nimport { createDialogsProvider } from \"~/components/Dialogs/DialogsContext.js\";\nimport { createDrawersProvider } from \"~/components/Drawers/DrawersContext.js\";\nimport { DefaultIcons, IconPickerConfigProvider } from \"~/components/IconPicker/config/index.js\";\nimport { createRootContainer } from \"~/base/createRootContainer.js\";\nimport { FeatureFlagsProvider } from \"~/presentation/featureFlags/FeatureFlagsProvider.js\";\nimport { createTenancyProvider } from \"~/presentation/tenancy/createTenancyProvider.js\";\nimport { TelemetryAdminAppStart } from \"./TelemetryAdminAppStart.js\";\nimport { SecurityFeature } from \"~/features/security/SecurityFeature.js\";\nimport { FormModelFeature } from \"~/features/formModel/feature.js\";\nimport type { PluginCollection } from \"@webiny/plugins/types.js\";\nimport { AdminConfigPlugin, AdminConfigProvider } from \"~/config/AdminConfig.js\";\nimport { WebinySdkFeature } from \"~/features/webinySdk/feature.js\";\nimport { DateFormatterFeature } from \"~/features/dateFormatter/feature.js\";\nimport { StringFormatterFeature } from \"~/features/stringFormatter/feature.js\";\nimport { ListPresenterFeature } from \"~/presentation/listPresenter/index.js\";\nimport { SortableFeature } from \"~/presentation/sortable/index.js\";\nimport { NotificationsRenderer } from \"~/features/notifications/NotificationsRenderer.js\";\nimport { ListCustomIconsFeature } from \"~/features/iconPicker/listCustomIcons/feature.js\";\nimport { CustomIconsPresenterFeature } from \"~/presentation/iconPicker/customIcons/feature.js\";\nimport { CommandPaletteFeature } from \"~/presentation/commandPalette/index.js\";\nimport { AiChatFeature } from \"~/features/aiChat/index.js\";\nimport { AdminCommandsFeature } from \"~/presentation/commandPalette/commands/feature.js\";\n\nexport interface AdminProps {\n createLegacyPlugins?: (container: Container) => PluginCollection;\n children?: React.ReactNode;\n}\n\nconst container = createRootContainer();\n\nexport const Admin = ({ children, createLegacyPlugins }: AdminProps) => {\n if (createLegacyPlugins) {\n plugins.register(...createLegacyPlugins(container));\n }\n\n SecurityFeature.register(container);\n DateFormatterFeature.register(container);\n StringFormatterFeature.register(container);\n FormModelFeature.register(container);\n WebinySdkFeature.register(container);\n ListPresenterFeature.register(container);\n ListCustomIconsFeature.register(container);\n CustomIconsPresenterFeature.register(container);\n AiChatFeature.register(container);\n CommandPaletteFeature.register(container);\n AdminCommandsFeature.register(container);\n SortableFeature.register(container);\n\n const UIProviders = createUiProviders();\n const UiStateProvider = createUiStateProvider();\n const AdminUiStateProvider = createAdminUiStateProvider();\n const DialogsProvider = createDialogsProvider();\n const DrawersProvider = createDrawersProvider();\n const TenancyProvider = createTenancyProvider();\n\n return (\n <DiContainerProvider container={container}>\n <TelemetryAdminAppStart />\n <FeatureFlagsProvider>\n <App\n plugins={[AdminConfigPlugin]}\n routes={[]}\n providers={[\n AdminConfigProvider,\n UIProviders,\n UiStateProvider,\n DialogsProvider,\n DrawersProvider,\n IconPickerConfigProvider,\n AdminUiStateProvider,\n TenancyProvider\n ]}\n >\n <Base />\n <DefaultIcons />\n <NotificationsRenderer />\n {children}\n </App>\n </FeatureFlagsProvider>\n </DiContainerProvider>\n );\n};\n"],"names":["container","createRootContainer","Admin","children","createLegacyPlugins","plugins","SecurityFeature","DateFormatterFeature","StringFormatterFeature","FormModelFeature","WebinySdkFeature","ListPresenterFeature","ListCustomIconsFeature","CustomIconsPresenterFeature","AiChatFeature","CommandPaletteFeature","AdminCommandsFeature","SortableFeature","UIProviders","createUiProviders","UiStateProvider","createUiStateProvider","AdminUiStateProvider","createAdminUiStateProvider","DialogsProvider","createDialogsProvider","DrawersProvider","createDrawersProvider","TenancyProvider","createTenancyProvider","DiContainerProvider","TelemetryAdminAppStart","FeatureFlagsProvider","App","AdminConfigPlugin","AdminConfigProvider","IconPickerConfigProvider","Base","DefaultIcons","NotificationsRenderer"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,MAAMA,YAAYC;AAEX,MAAMC,QAAQ,CAAC,EAAEC,QAAQ,EAAEC,mBAAmB,EAAc;IAC/D,IAAIA,qBACAC,QAAQ,QAAQ,IAAID,oBAAoBJ;IAG5CM,gBAAgB,QAAQ,CAACN;IACzBO,qBAAqB,QAAQ,CAACP;IAC9BQ,uBAAuB,QAAQ,CAACR;IAChCS,iBAAiB,QAAQ,CAACT;IAC1BU,iBAAiB,QAAQ,CAACV;IAC1BW,qBAAqB,QAAQ,CAACX;IAC9BY,uBAAuB,QAAQ,CAACZ;IAChCa,4BAA4B,QAAQ,CAACb;IACrCc,cAAc,QAAQ,CAACd;IACvBe,sBAAsB,QAAQ,CAACf;IAC/BgB,qBAAqB,QAAQ,CAAChB;IAC9BiB,gBAAgB,QAAQ,CAACjB;IAEzB,MAAMkB,cAAcC;IACpB,MAAMC,kBAAkBC;IACxB,MAAMC,uBAAuBC;IAC7B,MAAMC,kBAAkBC;IACxB,MAAMC,kBAAkBC;IACxB,MAAMC,kBAAkBC;IAExB,OAAO,WAAP,GACI,oBAACC,qBAAmBA;QAAC,WAAW9B;qBAC5B,oBAAC+B,wBAAsBA,OAAAA,WAAAA,GACvB,oBAACC,sBAAoBA,MAAAA,WAAAA,GACjB,oBAACC,KAAGA;QACA,SAAS;YAACC;SAAkB;QAC5B,QAAQ,EAAE;QACV,WAAW;YACPC;YACAjB;YACAE;YACAI;YACAE;YACAU;YACAd;YACAM;SACH;qBAED,oBAACS,MAAIA,OAAAA,WAAAA,GACL,oBAACC,cAAYA,OAAAA,WAAAA,GACb,oBAACC,uBAAqBA,OACrBpC;AAKrB"}
1
+ {"version":3,"file":"base/Admin.js","sources":["../../src/base/Admin.tsx"],"sourcesContent":["import React from \"react\";\nimport type { Container } from \"@webiny/di\";\nimport { plugins } from \"@webiny/plugins\";\nimport { App, DiContainerProvider } from \"@webiny/app\";\nimport { Base } from \"./Base.js\";\nimport { createUiStateProvider } from \"./providers/UiStateProvider.js\";\nimport { createAdminUiStateProvider } from \"./providers/AdminUiStateProvider.js\";\nimport { createUiProviders } from \"./providers/UiProviders.js\";\nimport { createDialogsProvider } from \"~/components/Dialogs/DialogsContext.js\";\nimport { createDrawersProvider } from \"~/components/Drawers/DrawersContext.js\";\nimport { DefaultIcons, IconPickerConfigProvider } from \"~/components/IconPicker/config/index.js\";\nimport { createRootContainer } from \"~/base/createRootContainer.js\";\nimport { FeatureFlagsProvider } from \"~/presentation/featureFlags/FeatureFlagsProvider.js\";\nimport { createTenancyProvider } from \"~/presentation/tenancy/createTenancyProvider.js\";\nimport { TelemetryAdminAppStart } from \"./TelemetryAdminAppStart.js\";\nimport { SecurityFeature } from \"~/features/security/SecurityFeature.js\";\nimport { FormModelFeature } from \"~/features/formModel/feature.js\";\nimport type { PluginCollection } from \"@webiny/plugins/types.js\";\nimport { AdminConfigPlugin, AdminConfigProvider } from \"~/config/AdminConfig.js\";\nimport { WebinySdkFeature } from \"~/features/webinySdk/feature.js\";\nimport { DateFormatterFeature } from \"~/features/dateFormatter/feature.js\";\nimport { StringFormatterFeature } from \"~/features/stringFormatter/feature.js\";\nimport { ListPresenterFeature } from \"~/presentation/listPresenter/index.js\";\nimport { SortableFeature } from \"~/presentation/sortable/index.js\";\nimport { NotificationsRenderer } from \"~/features/notifications/NotificationsRenderer.js\";\nimport { ListCustomIconsFeature } from \"~/features/iconPicker/listCustomIcons/feature.js\";\nimport { CustomIconsPresenterFeature } from \"~/presentation/iconPicker/customIcons/feature.js\";\nimport { CommandPaletteFeature } from \"~/presentation/commandPalette/index.js\";\nimport { AdminAssistantFeature } from \"~/features/adminAssistant/index.js\";\nimport { AdminCommandsFeature } from \"~/presentation/commandPalette/commands/feature.js\";\n\nexport interface AdminProps {\n createLegacyPlugins?: (container: Container) => PluginCollection;\n children?: React.ReactNode;\n}\n\nconst container = createRootContainer();\n\nexport const Admin = ({ children, createLegacyPlugins }: AdminProps) => {\n if (createLegacyPlugins) {\n plugins.register(...createLegacyPlugins(container));\n }\n\n SecurityFeature.register(container);\n DateFormatterFeature.register(container);\n StringFormatterFeature.register(container);\n FormModelFeature.register(container);\n WebinySdkFeature.register(container);\n ListPresenterFeature.register(container);\n ListCustomIconsFeature.register(container);\n CustomIconsPresenterFeature.register(container);\n AdminAssistantFeature.register(container);\n CommandPaletteFeature.register(container);\n AdminCommandsFeature.register(container);\n SortableFeature.register(container);\n\n const UIProviders = createUiProviders();\n const UiStateProvider = createUiStateProvider();\n const AdminUiStateProvider = createAdminUiStateProvider();\n const DialogsProvider = createDialogsProvider();\n const DrawersProvider = createDrawersProvider();\n const TenancyProvider = createTenancyProvider();\n\n return (\n <DiContainerProvider container={container}>\n <TelemetryAdminAppStart />\n <FeatureFlagsProvider>\n <App\n plugins={[AdminConfigPlugin]}\n routes={[]}\n providers={[\n AdminConfigProvider,\n UIProviders,\n UiStateProvider,\n DialogsProvider,\n DrawersProvider,\n IconPickerConfigProvider,\n AdminUiStateProvider,\n TenancyProvider\n ]}\n >\n <Base />\n <DefaultIcons />\n <NotificationsRenderer />\n {children}\n </App>\n </FeatureFlagsProvider>\n </DiContainerProvider>\n );\n};\n"],"names":["container","createRootContainer","Admin","children","createLegacyPlugins","plugins","SecurityFeature","DateFormatterFeature","StringFormatterFeature","FormModelFeature","WebinySdkFeature","ListPresenterFeature","ListCustomIconsFeature","CustomIconsPresenterFeature","AdminAssistantFeature","CommandPaletteFeature","AdminCommandsFeature","SortableFeature","UIProviders","createUiProviders","UiStateProvider","createUiStateProvider","AdminUiStateProvider","createAdminUiStateProvider","DialogsProvider","createDialogsProvider","DrawersProvider","createDrawersProvider","TenancyProvider","createTenancyProvider","DiContainerProvider","TelemetryAdminAppStart","FeatureFlagsProvider","App","AdminConfigPlugin","AdminConfigProvider","IconPickerConfigProvider","Base","DefaultIcons","NotificationsRenderer"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,MAAMA,YAAYC;AAEX,MAAMC,QAAQ,CAAC,EAAEC,QAAQ,EAAEC,mBAAmB,EAAc;IAC/D,IAAIA,qBACAC,QAAQ,QAAQ,IAAID,oBAAoBJ;IAG5CM,gBAAgB,QAAQ,CAACN;IACzBO,qBAAqB,QAAQ,CAACP;IAC9BQ,uBAAuB,QAAQ,CAACR;IAChCS,iBAAiB,QAAQ,CAACT;IAC1BU,iBAAiB,QAAQ,CAACV;IAC1BW,qBAAqB,QAAQ,CAACX;IAC9BY,uBAAuB,QAAQ,CAACZ;IAChCa,4BAA4B,QAAQ,CAACb;IACrCc,sBAAsB,QAAQ,CAACd;IAC/Be,sBAAsB,QAAQ,CAACf;IAC/BgB,qBAAqB,QAAQ,CAAChB;IAC9BiB,gBAAgB,QAAQ,CAACjB;IAEzB,MAAMkB,cAAcC;IACpB,MAAMC,kBAAkBC;IACxB,MAAMC,uBAAuBC;IAC7B,MAAMC,kBAAkBC;IACxB,MAAMC,kBAAkBC;IACxB,MAAMC,kBAAkBC;IAExB,OAAO,WAAP,GACI,oBAACC,qBAAmBA;QAAC,WAAW9B;qBAC5B,oBAAC+B,wBAAsBA,OAAAA,WAAAA,GACvB,oBAACC,sBAAoBA,MAAAA,WAAAA,GACjB,oBAACC,KAAGA;QACA,SAAS;YAACC;SAAkB;QAC5B,QAAQ,EAAE;QACV,WAAW;YACPC;YACAjB;YACAE;YACAI;YACAE;YACAU;YACAd;YACAM;SACH;qBAED,oBAACS,MAAIA,OAAAA,WAAAA,GACL,oBAACC,cAAYA,OAAAA,WAAAA,GACb,oBAACC,uBAAqBA,OACrBpC;AAKrB"}
@@ -1,8 +1,8 @@
1
1
  import { ApiStreamClient } from "@webiny/app/features/apiStreamClient";
2
2
  import { EnvConfig } from "@webiny/app/features/envConfig";
3
- import { AiChatGateway as Abstraction } from "./abstractions.js";
4
- import type { AiChatRequest } from "./abstractions.js";
5
- import type { AiChatStreamEvent } from "./abstractions.js";
3
+ import { AdminAssistantGateway as Abstraction } from "./abstractions.js";
4
+ import type { AdminAssistantRequest } from "./abstractions.js";
5
+ import type { AdminAssistantStreamEvent } from "./abstractions.js";
6
6
  import { AuthenticationContext } from "../../features/security/AuthenticationContext/index.js";
7
7
  import { TenantContext } from "../../features/tenancy/abstractions.js";
8
8
  /**
@@ -16,15 +16,15 @@ import { TenantContext } from "../../features/tenancy/abstractions.js";
16
16
  * The buffered call still uses `fetch`: `ApiStreamClient` hands back an unread `Response` for a caller
17
17
  * that owns a read loop, which is the wrong shape for a single JSON answer.
18
18
  */
19
- declare class AiChatGatewayImpl implements Abstraction.Interface {
19
+ declare class AdminAssistantGatewayImpl implements Abstraction.Interface {
20
20
  private authContext;
21
21
  private envConfig;
22
22
  private tenantContext;
23
23
  private streamClient;
24
24
  constructor(authContext: AuthenticationContext.Interface, envConfig: EnvConfig.Interface, tenantContext: TenantContext.Interface, streamClient: ApiStreamClient.Interface);
25
- stream(request: AiChatRequest, signal?: AbortSignal): AsyncIterable<AiChatStreamEvent>;
25
+ stream(request: AdminAssistantRequest, signal?: AbortSignal): AsyncIterable<AdminAssistantStreamEvent>;
26
26
  }
27
- export declare const AiChatGateway: typeof AiChatGatewayImpl & {
28
- __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IAiChatGateway>;
27
+ export declare const AdminAssistantGateway: typeof AdminAssistantGatewayImpl & {
28
+ __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IAdminAssistantGateway>;
29
29
  };
30
30
  export {};
@@ -1,9 +1,9 @@
1
1
  import { ApiStreamClient, readServerSentEvents } from "@webiny/app/features/apiStreamClient";
2
2
  import { EnvConfig } from "@webiny/app/features/envConfig";
3
- import { AiChatGateway } from "./abstractions.js";
3
+ import { AdminAssistantGateway } from "./abstractions.js";
4
4
  import { AuthenticationContext } from "../security/AuthenticationContext/index.js";
5
5
  import { TenantContext } from "../tenancy/abstractions.js";
6
- const CHAT_STREAM_PATH = "/stream/ai/chat";
6
+ const STREAM_PATH = "/stream/ai/admin-assistant";
7
7
  const toBody = (request)=>{
8
8
  const body = {
9
9
  messages: request.messages
@@ -11,7 +11,7 @@ const toBody = (request)=>{
11
11
  if (request.approvals?.length) body["approvals"] = request.approvals;
12
12
  return body;
13
13
  };
14
- class AiChatGatewayImpl {
14
+ class AdminAssistantGatewayImpl {
15
15
  constructor(authContext, envConfig, tenantContext, streamClient){
16
16
  this.authContext = authContext;
17
17
  this.envConfig = envConfig;
@@ -20,15 +20,15 @@ class AiChatGatewayImpl {
20
20
  }
21
21
  async *stream(request, signal) {
22
22
  const response = await this.streamClient.execute({
23
- path: CHAT_STREAM_PATH,
23
+ path: STREAM_PATH,
24
24
  body: toBody(request),
25
25
  signal
26
26
  });
27
27
  yield* readServerSentEvents(response);
28
28
  }
29
29
  }
30
- const AiChatGateway_AiChatGateway = AiChatGateway.createImplementation({
31
- implementation: AiChatGatewayImpl,
30
+ const AdminAssistantGateway_AdminAssistantGateway = AdminAssistantGateway.createImplementation({
31
+ implementation: AdminAssistantGatewayImpl,
32
32
  dependencies: [
33
33
  AuthenticationContext,
34
34
  EnvConfig,
@@ -36,6 +36,6 @@ const AiChatGateway_AiChatGateway = AiChatGateway.createImplementation({
36
36
  ApiStreamClient
37
37
  ]
38
38
  });
39
- export { AiChatGateway_AiChatGateway as AiChatGateway };
39
+ export { AdminAssistantGateway_AdminAssistantGateway as AdminAssistantGateway };
40
40
 
41
- //# sourceMappingURL=AiChatGateway.js.map
41
+ //# sourceMappingURL=AdminAssistantGateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/adminAssistant/AdminAssistantGateway.js","sources":["../../../src/features/adminAssistant/AdminAssistantGateway.ts"],"sourcesContent":["import { ApiStreamClient } from \"@webiny/app/features/apiStreamClient\";\nimport { readServerSentEvents } from \"@webiny/app/features/apiStreamClient\";\nimport { EnvConfig } from \"@webiny/app/features/envConfig\";\nimport { AdminAssistantGateway as Abstraction } from \"./abstractions.js\";\nimport type { AdminAssistantRequest } from \"./abstractions.js\";\nimport type { AdminAssistantStreamEvent } from \"./abstractions.js\";\nimport { AuthenticationContext } from \"~/features/security/AuthenticationContext/index.js\";\nimport { TenantContext } from \"~/features/tenancy/abstractions.js\";\n\n/*\n * The `/stream/` prefix is required, not cosmetic: it is the CloudFront behavior that targets the\n * Lambda Function URL. Any other path lands on API Gateway and gets buffered.\n */\nconst STREAM_PATH = \"/stream/ai/admin-assistant\";\n\nconst toBody = (request: AdminAssistantRequest): Record<string, unknown> => {\n const body: Record<string, unknown> = { messages: request.messages };\n\n if (request.approvals?.length) {\n body[\"approvals\"] = request.approvals;\n }\n\n return body;\n};\n\n/**\n * Talks to the API app's chat routes.\n *\n * Streaming goes through `ApiStreamClient`, so auth and tenant headers come from the platform's own\n * decorators — including `x-webiny-authorization`, which the streaming path needs because on AWS\n * SigV4 occupies `Authorization`. Getting that wrong would silently make every streamed request\n * anonymous.\n *\n * The buffered call still uses `fetch`: `ApiStreamClient` hands back an unread `Response` for a caller\n * that owns a read loop, which is the wrong shape for a single JSON answer.\n */\nclass AdminAssistantGatewayImpl implements Abstraction.Interface {\n constructor(\n private authContext: AuthenticationContext.Interface,\n private envConfig: EnvConfig.Interface,\n private tenantContext: TenantContext.Interface,\n private streamClient: ApiStreamClient.Interface\n ) {}\n\n async *stream(\n request: AdminAssistantRequest,\n signal?: AbortSignal\n ): AsyncIterable<AdminAssistantStreamEvent> {\n const response = await this.streamClient.execute({\n path: STREAM_PATH,\n body: toBody(request),\n signal\n });\n\n yield* readServerSentEvents<AdminAssistantStreamEvent>(response);\n }\n}\n\nexport const AdminAssistantGateway = Abstraction.createImplementation({\n implementation: AdminAssistantGatewayImpl,\n dependencies: [AuthenticationContext, EnvConfig, TenantContext, ApiStreamClient]\n});\n"],"names":["STREAM_PATH","toBody","request","body","AdminAssistantGatewayImpl","authContext","envConfig","tenantContext","streamClient","signal","response","readServerSentEvents","AdminAssistantGateway","Abstraction","AuthenticationContext","EnvConfig","TenantContext","ApiStreamClient"],"mappings":";;;;;AAaA,MAAMA,cAAc;AAEpB,MAAMC,SAAS,CAACC;IACZ,MAAMC,OAAgC;QAAE,UAAUD,QAAQ,QAAQ;IAAC;IAEnE,IAAIA,QAAQ,SAAS,EAAE,QACnBC,IAAI,CAAC,YAAY,GAAGD,QAAQ,SAAS;IAGzC,OAAOC;AACX;AAaA,MAAMC;IACF,YACYC,WAA4C,EAC5CC,SAA8B,EAC9BC,aAAsC,EACtCC,YAAuC,CACjD;aAJUH,WAAW,GAAXA;aACAC,SAAS,GAATA;aACAC,aAAa,GAAbA;aACAC,YAAY,GAAZA;IACT;IAEH,OAAO,OACHN,OAA8B,EAC9BO,MAAoB,EACoB;QACxC,MAAMC,WAAW,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;YAC7C,MAAMV;YACN,MAAMC,OAAOC;YACbO;QACJ;QAEA,OAAOE,qBAAgDD;IAC3D;AACJ;AAEO,MAAME,8CAAwBC,sBAAAA,oBAAgC,CAAC;IAClE,gBAAgBT;IAChB,cAAc;QAACU;QAAuBC;QAAWC;QAAeC;KAAgB;AACpF"}
@@ -1,5 +1,5 @@
1
- import { AiChatGateway } from "./abstractions.js";
2
- import { AiChatPresenter as Abstraction, type IAiChatViewModel } from "./abstractions.js";
1
+ import { AdminAssistantGateway } from "./abstractions.js";
2
+ import { AdminAssistantPresenter as Abstraction, type IAdminAssistantViewModel } from "./abstractions.js";
3
3
  /**
4
4
  * Owns the palette's AI conversation.
5
5
  *
@@ -8,13 +8,13 @@ import { AiChatPresenter as Abstraction, type IAiChatViewModel } from "./abstrac
8
8
  *
9
9
  * Registered as a singleton, so `reset` genuinely clears rather than relying on unmount.
10
10
  */
11
- declare class AiChatPresenterImpl implements Abstraction.Interface {
11
+ declare class AdminAssistantPresenterImpl implements Abstraction.Interface {
12
12
  private gateway;
13
13
  private turns;
14
14
  private busy;
15
15
  private controller;
16
- constructor(gateway: AiChatGateway.Interface);
17
- get vm(): IAiChatViewModel;
16
+ constructor(gateway: AdminAssistantGateway.Interface);
17
+ get vm(): IAdminAssistantViewModel;
18
18
  ask(question: string): void;
19
19
  decide(turnIndex: number, approved: boolean): void;
20
20
  reset(): void;
@@ -26,7 +26,7 @@ declare class AiChatPresenterImpl implements Abstraction.Interface {
26
26
  private setBusy;
27
27
  private clear;
28
28
  }
29
- export declare const AiChatPresenter: typeof AiChatPresenterImpl & {
30
- __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IAiChatPresenter>;
29
+ export declare const AdminAssistantPresenter: typeof AdminAssistantPresenterImpl & {
30
+ __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IAdminAssistantPresenter>;
31
31
  };
32
32
  export {};
@@ -1,5 +1,5 @@
1
1
  import { makeAutoObservable } from "mobx";
2
- import { AiChatGateway, AiChatPresenter } from "./abstractions.js";
2
+ import { AdminAssistantGateway, AdminAssistantPresenter } from "./abstractions.js";
3
3
  const emptyTurn = (question)=>({
4
4
  question,
5
5
  text: "",
@@ -11,7 +11,7 @@ const emptyTurn = (question)=>({
11
11
  messages: [],
12
12
  settled: false
13
13
  });
14
- class AiChatPresenterImpl {
14
+ class AdminAssistantPresenterImpl {
15
15
  constructor(gateway){
16
16
  this.gateway = gateway;
17
17
  this.turns = [];
@@ -209,12 +209,12 @@ class AiChatPresenterImpl {
209
209
  this.busy = false;
210
210
  }
211
211
  }
212
- const AiChatPresenter_AiChatPresenter = AiChatPresenter.createImplementation({
213
- implementation: AiChatPresenterImpl,
212
+ const AdminAssistantPresenter_AdminAssistantPresenter = AdminAssistantPresenter.createImplementation({
213
+ implementation: AdminAssistantPresenterImpl,
214
214
  dependencies: [
215
- AiChatGateway
215
+ AdminAssistantGateway
216
216
  ]
217
217
  });
218
- export { AiChatPresenter_AiChatPresenter as AiChatPresenter };
218
+ export { AdminAssistantPresenter_AdminAssistantPresenter as AdminAssistantPresenter };
219
219
 
220
- //# sourceMappingURL=AiChatPresenter.js.map
220
+ //# sourceMappingURL=AdminAssistantPresenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/adminAssistant/AdminAssistantPresenter.js","sources":["../../../src/features/adminAssistant/AdminAssistantPresenter.ts"],"sourcesContent":["import { makeAutoObservable } from \"mobx\";\nimport { AdminAssistantGateway } from \"./abstractions.js\";\nimport type { AdminAssistantMessage, AdminAssistantRequest } from \"./abstractions.js\";\nimport {\n AdminAssistantPresenter as Abstraction,\n type AiTurnViewModel,\n type IAdminAssistantViewModel\n} from \"./abstractions.js\";\n\n/** A turn plus the conversation state the view never sees. */\ninterface Turn extends AiTurnViewModel {\n /** Server messages replayed to continue this conversation or resume its approval. */\n messages: AdminAssistantMessage[];\n}\n\nconst emptyTurn = (question: string): Turn => ({\n question,\n text: \"\",\n tools: [],\n completed: [],\n failed: [],\n running: false,\n pendingApprovals: [],\n messages: [],\n settled: false\n});\n\n/**\n * Owns the palette's AI conversation.\n *\n * A presenter rather than component state: several pieces change together, a network stream drives\n * them, and an abort has to outlive any one render.\n *\n * Registered as a singleton, so `reset` genuinely clears rather than relying on unmount.\n */\nclass AdminAssistantPresenterImpl implements Abstraction.Interface {\n private turns: Turn[] = [];\n private busy = false;\n private controller: AbortController | null = null;\n\n constructor(private gateway: AdminAssistantGateway.Interface) {\n // The controller is machinery, not state anything renders, so keep it out of the map.\n makeAutoObservable<AdminAssistantPresenterImpl, \"controller\">(this, { controller: false });\n }\n\n get vm(): IAdminAssistantViewModel {\n return {\n busy: this.busy,\n turns: this.turns.map(turn => ({\n question: turn.question,\n text: turn.text,\n tools: turn.tools,\n completed: turn.completed,\n failed: turn.failed,\n running: turn.running,\n pendingApprovals: turn.pendingApprovals,\n settled: turn.settled,\n ...(turn.error === undefined ? {} : { error: turn.error })\n }))\n };\n }\n\n ask(question: string): void {\n const trimmed = question.trim();\n\n if (!trimmed || this.busy) {\n return;\n }\n\n const index = this.turns.length;\n this.addTurn(trimmed);\n\n void this.run(index, {\n messages: [...this.historyBefore(index), { role: \"user\", content: trimmed }]\n });\n }\n\n decide(turnIndex: number, approved: boolean): void {\n const turn = this.turns[turnIndex];\n\n if (!turn?.pendingApprovals.length || this.busy) {\n return;\n }\n\n const approvals = turn.pendingApprovals.map(approval => ({\n approvalId: approval.approvalId,\n approved\n }));\n\n /*\n * The paused assistant message must be replayed unchanged: the approval request lives only in\n * the server's messages, so resuming means sending the same history back plus the decision.\n */\n const messages: AdminAssistantMessage[] = [\n ...this.historyBefore(turnIndex),\n { role: \"user\", content: turn.question },\n ...turn.messages\n ];\n\n // Clear the block immediately so the plan cannot be submitted twice.\n this.patch(turnIndex, { pendingApprovals: [], settled: false, running: true });\n\n void this.run(turnIndex, { messages, approvals }, true);\n }\n\n reset(): void {\n this.controller?.abort();\n this.controller = null;\n this.clear();\n }\n\n /** Replays settled turns so a follow-up (\"and which of those is cheapest?\") has context. */\n private historyBefore(upTo: number): AdminAssistantMessage[] {\n const history: AdminAssistantMessage[] = [];\n\n for (const turn of this.turns.slice(0, upTo)) {\n if (!turn.settled || turn.error) {\n continue;\n }\n history.push({ role: \"user\", content: turn.question });\n history.push(...turn.messages);\n }\n\n return history;\n }\n\n private async run(\n index: number,\n request: AdminAssistantRequest,\n resuming = false\n ): Promise<void> {\n this.controller?.abort();\n const controller = new AbortController();\n this.controller = controller;\n\n this.setBusy(true);\n\n try {\n /*\n * Resuming continues the same turn: the tools already called, the text already shown and\n * the messages already collected all still belong to it. Starting from empty would strand\n * earlier chips as running and, worse, drop the assistant message carrying the `tool_use`\n * that the replayed `tool_result` refers to.\n */\n const existing = resuming ? this.turns[index] : undefined;\n let text = existing?.text ?? \"\";\n const tools: string[] = existing ? [...existing.tools] : [];\n const completed: string[] = existing ? [...existing.completed] : [];\n const failed: string[] = existing ? [...existing.failed] : [];\n const priorMessages: AdminAssistantMessage[] = existing ? [...existing.messages] : [];\n\n for await (const event of this.gateway.stream(request, controller.signal)) {\n if (event.type === \"text\") {\n text += event.text;\n this.patch(index, { text, running: false });\n continue;\n }\n\n if (event.type === \"tool-call\") {\n tools.push(event.name);\n this.patch(index, { tools: [...tools], running: true });\n continue;\n }\n\n if (event.type === \"tool-result\") {\n completed.push(event.name);\n this.patch(index, { completed: [...completed] });\n continue;\n }\n\n if (event.type === \"tool-error\") {\n failed.push(event.name);\n this.patch(index, { failed: [...failed] });\n continue;\n }\n\n if (event.type === \"approval\") {\n this.patch(index, { pendingApprovals: event.approvals, running: false });\n continue;\n }\n\n if (event.type === \"done\") {\n this.patch(index, {\n messages: [...priorMessages, ...event.messages],\n settled: true,\n running: false\n });\n continue;\n }\n\n if (event.type === \"error\") {\n this.patch(index, { error: event.message, settled: true, running: false });\n return;\n }\n }\n } catch (error) {\n // An abort is the palette closing, not a failure worth showing.\n if (!controller.signal.aborted) {\n this.patch(index, {\n error: error instanceof Error ? error.message : String(error),\n settled: true,\n running: false\n });\n }\n } finally {\n this.setBusy(false);\n }\n }\n\n /*\n * Every mutation below is its own method on purpose. `run` awaits, and a mutation after an await\n * has escaped the action it started in; `makeAutoObservable` makes these methods actions, so\n * calling them from there is correct.\n */\n private addTurn(question: string): void {\n this.turns = [...this.turns, { ...emptyTurn(question), running: true }];\n }\n\n private patch(index: number, change: Partial<Turn>): void {\n this.turns = this.turns.map((turn, i) => (i === index ? { ...turn, ...change } : turn));\n }\n\n private setBusy(busy: boolean): void {\n this.busy = busy;\n }\n\n private clear(): void {\n this.turns = [];\n this.busy = false;\n }\n}\n\nexport const AdminAssistantPresenter = Abstraction.createImplementation({\n implementation: AdminAssistantPresenterImpl,\n dependencies: [AdminAssistantGateway]\n});\n"],"names":["emptyTurn","question","AdminAssistantPresenterImpl","gateway","makeAutoObservable","turn","undefined","trimmed","index","turnIndex","approved","approvals","approval","messages","upTo","history","request","resuming","controller","AbortController","existing","text","tools","completed","failed","priorMessages","event","error","Error","String","change","i","busy","AdminAssistantPresenter","Abstraction","AdminAssistantGateway"],"mappings":"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"}
@@ -3,17 +3,17 @@
3
3
  * assistant and tool messages carrying approval requests, which must be replayed VERBATIM for the
4
4
  * agent loop to resume — the request exists nowhere else, since the server keeps no session.
5
5
  */
6
- export type AiChatMessage = {
6
+ export type AdminAssistantMessage = {
7
7
  role: string;
8
8
  content: unknown;
9
9
  };
10
10
  /** A tool the assistant invoked, so the UI can show its work rather than just an answer. */
11
- export interface AiChatToolCall {
11
+ export interface AdminAssistantToolCall {
12
12
  name: string;
13
13
  input: unknown;
14
14
  }
15
15
  /** A tool call the assistant wants to make but has not made, because it changes something. */
16
- export interface AiChatPendingApproval {
16
+ export interface AdminAssistantPendingApproval {
17
17
  approvalId: string;
18
18
  toolName: string;
19
19
  title?: string;
@@ -21,21 +21,21 @@ export interface AiChatPendingApproval {
21
21
  /** The tool declared itself destructive — the UI should say so more loudly. */
22
22
  destructive: boolean;
23
23
  }
24
- export interface AiChatDecision {
24
+ export interface AdminAssistantDecision {
25
25
  approvalId: string;
26
26
  approved: boolean;
27
27
  reason?: string;
28
28
  }
29
- export interface AiChatRequest {
30
- messages: AiChatMessage[];
29
+ export interface AdminAssistantRequest {
30
+ messages: AdminAssistantMessage[];
31
31
  /** Approve or reject calls the server paused on. */
32
- approvals?: AiChatDecision[];
32
+ approvals?: AdminAssistantDecision[];
33
33
  }
34
34
  /**
35
- * What the assistant emits while it works. Mirrors the server's `AiChatEvent`; declared here so the
35
+ * What the assistant emits while it works. Mirrors the server's `AdminAssistantEvent`; declared here so the
36
36
  * admin bundle carries no server or AI SDK code.
37
37
  */
38
- export type AiChatStreamEvent = {
38
+ export type AdminAssistantStreamEvent = {
39
39
  type: "text";
40
40
  text: string;
41
41
  } | {
@@ -50,32 +50,32 @@ export type AiChatStreamEvent = {
50
50
  message: string;
51
51
  } | {
52
52
  type: "approval";
53
- approvals: AiChatPendingApproval[];
53
+ approvals: AdminAssistantPendingApproval[];
54
54
  } | {
55
55
  type: "done";
56
- messages: AiChatMessage[];
56
+ messages: AdminAssistantMessage[];
57
57
  steps: number;
58
58
  } | {
59
59
  type: "error";
60
60
  message: string;
61
61
  };
62
- export interface IAiChatGateway {
62
+ export interface IAdminAssistantGateway {
63
63
  /**
64
64
  * Run and yield progress as it arrives. Preferred in the UI: a multi-tool question takes tens of
65
65
  * seconds, and an approval request is worth showing the moment it appears.
66
66
  */
67
- stream(request: AiChatRequest, signal?: AbortSignal): AsyncIterable<AiChatStreamEvent>;
67
+ stream(request: AdminAssistantRequest, signal?: AbortSignal): AsyncIterable<AdminAssistantStreamEvent>;
68
68
  }
69
69
  /** Sends a question to the server-side AI assistant (`POST /ai/chat`). */
70
- export declare const AiChatGateway: import("@webiny/di").Abstraction<IAiChatGateway>;
71
- export declare namespace AiChatGateway {
72
- type Interface = IAiChatGateway;
73
- type Message = AiChatMessage;
74
- type ToolCall = AiChatToolCall;
75
- type PendingApproval = AiChatPendingApproval;
76
- type Decision = AiChatDecision;
77
- type Request = AiChatRequest;
78
- type StreamEvent = AiChatStreamEvent;
70
+ export declare const AdminAssistantGateway: import("@webiny/di").Abstraction<IAdminAssistantGateway>;
71
+ export declare namespace AdminAssistantGateway {
72
+ type Interface = IAdminAssistantGateway;
73
+ type Message = AdminAssistantMessage;
74
+ type ToolCall = AdminAssistantToolCall;
75
+ type PendingApproval = AdminAssistantPendingApproval;
76
+ type Decision = AdminAssistantDecision;
77
+ type Request = AdminAssistantRequest;
78
+ type StreamEvent = AdminAssistantStreamEvent;
79
79
  }
80
80
  /**
81
81
  * One question and the answer to it, as the view needs it.
@@ -98,17 +98,17 @@ export interface AiTurnViewModel {
98
98
  failed: string[];
99
99
  /** Set while a tool is running and no answer text has arrived yet. */
100
100
  running: boolean;
101
- pendingApprovals: AiChatPendingApproval[];
101
+ pendingApprovals: AdminAssistantPendingApproval[];
102
102
  settled: boolean;
103
103
  error?: string;
104
104
  }
105
- export interface IAiChatViewModel {
105
+ export interface IAdminAssistantViewModel {
106
106
  turns: AiTurnViewModel[];
107
107
  /** A run is in flight. Asking again or deciding again is refused while true. */
108
108
  busy: boolean;
109
109
  }
110
- export interface IAiChatPresenter {
111
- readonly vm: IAiChatViewModel;
110
+ export interface IAdminAssistantPresenter {
111
+ readonly vm: IAdminAssistantViewModel;
112
112
  /** Ask a question, carrying the settled turns before it as context. */
113
113
  ask(question: string): void;
114
114
  /** Approve or reject the calls a turn paused on, then resume it. */
@@ -116,9 +116,9 @@ export interface IAiChatPresenter {
116
116
  /** Drop the conversation and stop anything in flight. */
117
117
  reset(): void;
118
118
  }
119
- export declare const AiChatPresenter: import("@webiny/di").Abstraction<IAiChatPresenter>;
120
- export declare namespace AiChatPresenter {
121
- type Interface = IAiChatPresenter;
122
- type ViewModel = IAiChatViewModel;
119
+ export declare const AdminAssistantPresenter: import("@webiny/di").Abstraction<IAdminAssistantPresenter>;
120
+ export declare namespace AdminAssistantPresenter {
121
+ type Interface = IAdminAssistantPresenter;
122
+ type ViewModel = IAdminAssistantViewModel;
123
123
  type Turn = AiTurnViewModel;
124
124
  }
@@ -0,0 +1,6 @@
1
+ import { createAbstraction } from "@webiny/feature/admin";
2
+ const AdminAssistantGateway = createAbstraction("AdminAssistantGateway");
3
+ const AdminAssistantPresenter = createAbstraction("AdminAssistantPresenter");
4
+ export { AdminAssistantGateway, AdminAssistantPresenter };
5
+
6
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/adminAssistant/abstractions.js","sources":["../../../src/features/adminAssistant/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\n\n/**\n * Messages are opaque here on purpose. Beyond plain user/assistant turns the server also returns\n * assistant and tool messages carrying approval requests, which must be replayed VERBATIM for the\n * agent loop to resume — the request exists nowhere else, since the server keeps no session.\n */\nexport type AdminAssistantMessage = { role: string; content: unknown };\n\n/** A tool the assistant invoked, so the UI can show its work rather than just an answer. */\nexport interface AdminAssistantToolCall {\n name: string;\n input: unknown;\n}\n\n/** A tool call the assistant wants to make but has not made, because it changes something. */\nexport interface AdminAssistantPendingApproval {\n approvalId: string;\n toolName: string;\n title?: string;\n input: unknown;\n /** The tool declared itself destructive — the UI should say so more loudly. */\n destructive: boolean;\n}\n\nexport interface AdminAssistantDecision {\n approvalId: string;\n approved: boolean;\n reason?: string;\n}\n\nexport interface AdminAssistantRequest {\n messages: AdminAssistantMessage[];\n /** Approve or reject calls the server paused on. */\n approvals?: AdminAssistantDecision[];\n}\n\n/**\n * What the assistant emits while it works. Mirrors the server's `AdminAssistantEvent`; declared here so the\n * admin bundle carries no server or AI SDK code.\n */\nexport type AdminAssistantStreamEvent =\n | { type: \"text\"; text: string }\n | { type: \"tool-call\"; name: string }\n | { type: \"tool-result\"; name: string }\n // A tool threw. Pairs with `tool-call` by name, and does not end the run.\n | { type: \"tool-error\"; name: string; message: string }\n | { type: \"approval\"; approvals: AdminAssistantPendingApproval[] }\n | { type: \"done\"; messages: AdminAssistantMessage[]; steps: number }\n | { type: \"error\"; message: string };\n\nexport interface IAdminAssistantGateway {\n /**\n * Run and yield progress as it arrives. Preferred in the UI: a multi-tool question takes tens of\n * seconds, and an approval request is worth showing the moment it appears.\n */\n stream(\n request: AdminAssistantRequest,\n signal?: AbortSignal\n ): AsyncIterable<AdminAssistantStreamEvent>;\n}\n\n/** Sends a question to the server-side AI assistant (`POST /ai/chat`). */\nexport const AdminAssistantGateway =\n createAbstraction<IAdminAssistantGateway>(\"AdminAssistantGateway\");\n\nexport namespace AdminAssistantGateway {\n export type Interface = IAdminAssistantGateway;\n export type Message = AdminAssistantMessage;\n export type ToolCall = AdminAssistantToolCall;\n export type PendingApproval = AdminAssistantPendingApproval;\n export type Decision = AdminAssistantDecision;\n export type Request = AdminAssistantRequest;\n export type StreamEvent = AdminAssistantStreamEvent;\n}\n\n/**\n * One question and the answer to it, as the view needs it.\n *\n * The server messages that make a follow-up or a resumed approval work are deliberately absent: they\n * are conversation state, not something rendered, so they stay inside the presenter.\n */\nexport interface AiTurnViewModel {\n question: string;\n /** Answer text so far. Grows as the stream arrives. */\n text: string;\n /** Tools called this turn, in call order. */\n tools: string[];\n /**\n * Tools that returned. A call pending approval still emits `tool-call`, so this is the only way\n * to tell a completed tool from one merely proposed.\n */\n completed: string[];\n /** Tools that threw. Settles the chip as a failure; the run continues. */\n failed: string[];\n /** Set while a tool is running and no answer text has arrived yet. */\n running: boolean;\n pendingApprovals: AdminAssistantPendingApproval[];\n settled: boolean;\n error?: string;\n}\n\nexport interface IAdminAssistantViewModel {\n turns: AiTurnViewModel[];\n /** A run is in flight. Asking again or deciding again is refused while true. */\n busy: boolean;\n}\n\nexport interface IAdminAssistantPresenter {\n readonly vm: IAdminAssistantViewModel;\n /** Ask a question, carrying the settled turns before it as context. */\n ask(question: string): void;\n /** Approve or reject the calls a turn paused on, then resume it. */\n decide(turnIndex: number, approved: boolean): void;\n /** Drop the conversation and stop anything in flight. */\n reset(): void;\n}\n\nexport const AdminAssistantPresenter =\n createAbstraction<IAdminAssistantPresenter>(\"AdminAssistantPresenter\");\n\nexport namespace AdminAssistantPresenter {\n export type Interface = IAdminAssistantPresenter;\n export type ViewModel = IAdminAssistantViewModel;\n export type Turn = AiTurnViewModel;\n}\n"],"names":["AdminAssistantGateway","createAbstraction","AdminAssistantPresenter"],"mappings":";AA+DO,MAAMA,wBACTC,kBAA0C;AAsDvC,MAAMC,0BACTD,kBAA4C"}
@@ -0,0 +1,3 @@
1
+ export declare const AdminAssistantFeature: import("@webiny/feature/admin").FeatureDefinition<{
2
+ presenter: import("./abstractions.js").IAdminAssistantPresenter;
3
+ }, []>;
@@ -0,0 +1,19 @@
1
+ import { createFeature } from "@webiny/feature/admin";
2
+ import { AdminAssistantGateway } from "./AdminAssistantGateway.js";
3
+ import { AdminAssistantPresenter } from "./AdminAssistantPresenter.js";
4
+ import { AdminAssistantPresenter as external_abstractions_js_AdminAssistantPresenter } from "./abstractions.js";
5
+ const AdminAssistantFeature = createFeature({
6
+ name: "AdminAssistant",
7
+ register (container) {
8
+ container.register(AdminAssistantGateway);
9
+ container.register(AdminAssistantPresenter).inSingletonScope();
10
+ },
11
+ resolve (container) {
12
+ return {
13
+ presenter: container.resolve(external_abstractions_js_AdminAssistantPresenter)
14
+ };
15
+ }
16
+ });
17
+ export { AdminAssistantFeature };
18
+
19
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/adminAssistant/feature.js","sources":["../../../src/features/adminAssistant/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { AdminAssistantGateway } from \"./AdminAssistantGateway.js\";\nimport { AdminAssistantPresenter } from \"./AdminAssistantPresenter.js\";\nimport { AdminAssistantPresenter as Abstraction } from \"./abstractions.js\";\n\nexport const AdminAssistantFeature = createFeature({\n name: \"AdminAssistant\",\n register(container) {\n container.register(AdminAssistantGateway);\n // Singleton so the conversation survives re-renders of the palette that reads it.\n container.register(AdminAssistantPresenter).inSingletonScope();\n },\n resolve(container) {\n return { presenter: container.resolve(Abstraction) };\n }\n});\n"],"names":["AdminAssistantFeature","createFeature","container","AdminAssistantGateway","AdminAssistantPresenter","Abstraction"],"mappings":";;;;AAKO,MAAMA,wBAAwBC,cAAc;IAC/C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QAEnBD,UAAU,QAAQ,CAACE,yBAAyB,gBAAgB;IAChE;IACA,SAAQF,SAAS;QACb,OAAO;YAAE,WAAWA,UAAU,OAAO,CAACG;QAAa;IACvD;AACJ"}
@@ -0,0 +1,6 @@
1
+ export { AdminAssistantGateway } from "./abstractions.js";
2
+ export type { IAdminAssistantGateway, AdminAssistantMessage, AdminAssistantToolCall, AdminAssistantPendingApproval, AdminAssistantDecision, AdminAssistantRequest, AdminAssistantStreamEvent } from "./abstractions.js";
3
+ export { AdminAssistantGateway as AdminAssistantGatewayImplementation } from "./AdminAssistantGateway.js";
4
+ export { AdminAssistantFeature } from "./feature.js";
5
+ export { AdminAssistantPresenter } from "./abstractions.js";
6
+ export type { AiTurnViewModel, IAdminAssistantPresenter, IAdminAssistantViewModel } from "./abstractions.js";
@@ -0,0 +1,3 @@
1
+ export { AdminAssistantGateway, AdminAssistantPresenter } from "./abstractions.js";
2
+ export { AdminAssistantGateway as AdminAssistantGatewayImplementation } from "./AdminAssistantGateway.js";
3
+ export { AdminAssistantFeature } from "./feature.js";
@@ -40,6 +40,12 @@ export declare class Field implements IField {
40
40
  */
41
41
  setValueSilent(value: unknown): void;
42
42
  setDisabled(value: boolean): void;
43
+ /**
44
+ * `form.field()` throws for a path it can't resolve, which happens while a form is
45
+ * still being assembled. Ancestor lookups treat that as "no parent" rather than
46
+ * failing the render.
47
+ */
48
+ private _safeGetField;
43
49
  private _evaluateRules;
44
50
  get visible(): boolean;
45
51
  get disabled(): boolean;
@@ -120,6 +120,13 @@ class Field {
120
120
  setDisabled(value) {
121
121
  this._disabled = value;
122
122
  }
123
+ _safeGetField(name) {
124
+ try {
125
+ return this._form?.field(name);
126
+ } catch {
127
+ return;
128
+ }
129
+ }
123
130
  _evaluateRules() {
124
131
  if (!this._form) return {
125
132
  visible: true,
@@ -156,6 +163,10 @@ class Field {
156
163
  }
157
164
  get disabled() {
158
165
  if (this._disabled) return true;
166
+ if (this._parentPath && this._form) {
167
+ const parent = this._safeGetField(this._parentPath);
168
+ if (parent?.disabled) return true;
169
+ }
159
170
  if (this._form && this._disabledWhenCallbacks.length > 0) {
160
171
  const scoped = this._callbackParams();
161
172
  for (const cb of this._disabledWhenCallbacks)if (cb(scoped)) return true;