@acorex-platform/module-ai-management-client 0.0.38 → 0.0.48

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 (55) hide show
  1. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-agent.mjs +30 -0
  2. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-agent.mjs.map +1 -1
  3. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-assist.mjs +16 -0
  4. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-assist.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-mcp-server.mjs +30 -0
  6. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-mcp-server.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-model.mjs +52 -15
  8. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-model.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-open-ai-endpoint.mjs +30 -0
  10. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-open-ai-endpoint.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-rule.mjs +30 -0
  12. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-rule.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-run-log.mjs +430 -0
  14. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-run-log.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-skill.mjs +30 -0
  16. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-skill.mjs.map +1 -1
  17. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-acorex-platform-module-ai-management-client-contracts-entity-catalog-oTY4z5q8.mjs → acorex-platform-module-ai-management-client-contracts-entity-catalog-acorex-platform-module-ai-management-client-contracts-entity-catalog-D8jl5iFT.mjs} +25 -8
  18. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-acorex-platform-module-ai-management-client-contracts-entity-catalog-D8jl5iFT.mjs.map +1 -0
  19. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-agent.entity-C75X-uZh.mjs → acorex-platform-module-ai-management-client-contracts-entity-catalog-agent.entity-Dj7dZRjE.mjs} +16 -2
  20. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-agent.entity-Dj7dZRjE.mjs.map +1 -0
  21. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-assist.entity-DrlJo7CZ.mjs → acorex-platform-module-ai-management-client-contracts-entity-catalog-assist.entity-DUlikO9I.mjs} +2 -2
  22. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-assist.entity-DrlJo7CZ.mjs.map → acorex-platform-module-ai-management-client-contracts-entity-catalog-assist.entity-DUlikO9I.mjs.map} +1 -1
  23. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-mcp-server.entity-UxFvQ92v.mjs → acorex-platform-module-ai-management-client-contracts-entity-catalog-mcp-server.entity-BVI_7IhH.mjs} +16 -2
  24. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-mcp-server.entity-BVI_7IhH.mjs.map +1 -0
  25. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-model.entity-DEdFUAPx.mjs → acorex-platform-module-ai-management-client-contracts-entity-catalog-model.entity-Xd45s9xE.mjs} +38 -17
  26. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-model.entity-Xd45s9xE.mjs.map +1 -0
  27. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-open-ai-endpoint.entity-CygH9dU_.mjs → acorex-platform-module-ai-management-client-contracts-entity-catalog-open-ai-endpoint.entity-CWsUMad_.mjs} +16 -2
  28. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-open-ai-endpoint.entity-CWsUMad_.mjs.map +1 -0
  29. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-rule.entity-Ddul_n4_.mjs → acorex-platform-module-ai-management-client-contracts-entity-catalog-rule.entity-Z6wYZrFU.mjs} +16 -2
  30. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-rule.entity-Z6wYZrFU.mjs.map +1 -0
  31. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-run-log.entity-B2PG0QN0.mjs +343 -0
  32. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-run-log.entity-B2PG0QN0.mjs.map +1 -0
  33. package/fesm2022/{acorex-platform-module-ai-management-client-contracts-entity-catalog-skill.entity-CeMnKpRg.mjs → acorex-platform-module-ai-management-client-contracts-entity-catalog-skill.entity-sNsPtjnT.mjs} +16 -2
  34. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-skill.entity-sNsPtjnT.mjs.map +1 -0
  35. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog.mjs +1 -1
  36. package/fesm2022/acorex-platform-module-ai-management-client-contracts.mjs +598 -526
  37. package/fesm2022/acorex-platform-module-ai-management-client-contracts.mjs.map +1 -1
  38. package/fesm2022/{acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BX0uU1YX.mjs → acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BxL3pxzj.mjs} +3 -3
  39. package/fesm2022/acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BxL3pxzj.mjs.map +1 -0
  40. package/fesm2022/acorex-platform-module-ai-management-client-local-entities.mjs +1 -0
  41. package/fesm2022/acorex-platform-module-ai-management-client-local-entities.mjs.map +1 -1
  42. package/fesm2022/acorex-platform-module-ai-management-client.mjs +281 -117
  43. package/fesm2022/acorex-platform-module-ai-management-client.mjs.map +1 -1
  44. package/package.json +5 -1
  45. package/types/acorex-platform-module-ai-management-client-contracts-entities-run-log.d.ts +5 -0
  46. package/types/acorex-platform-module-ai-management-client-contracts.d.ts +149 -85
  47. package/types/acorex-platform-module-ai-management-client.d.ts +27 -19
  48. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-acorex-platform-module-ai-management-client-contracts-entity-catalog-oTY4z5q8.mjs.map +0 -1
  49. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-agent.entity-C75X-uZh.mjs.map +0 -1
  50. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-mcp-server.entity-UxFvQ92v.mjs.map +0 -1
  51. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-model.entity-DEdFUAPx.mjs.map +0 -1
  52. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-open-ai-endpoint.entity-CygH9dU_.mjs.map +0 -1
  53. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-rule.entity-Ddul_n4_.mjs.map +0 -1
  54. package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-skill.entity-CeMnKpRg.mjs.map +0 -1
  55. package/fesm2022/acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BX0uU1YX.mjs.map +0 -1
@@ -1,21 +1,21 @@
1
1
  import { AXPSessionService, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
2
- import { AXPSettingsService, AXPFileStorageService, AXPOutputContractTranscriptSegmentService, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_OUTPUT_CONTRACT_TRANSCRIPT_SEGMENT_PROVIDER } from '@acorex-platform/framework-client/common';
2
+ import { AXP_SETTING_DEFINITION_PROVIDER, AXPSettingsService, AXPFileStorageService, AXPOutputContractTranscriptSegmentService, AXP_MENU_PROVIDER, AXP_OUTPUT_CONTRACT_TRANSCRIPT_SEGMENT_PROVIDER } from '@acorex-platform/framework-client/common';
3
3
  import * as i1$1 from '@acorex-platform/framework-client/core';
4
- import { objectKeyValueTransforms, AXPTagProvider, AXPComponentSlotModule, AXP_MODULE_MANIFEST_PROVIDER, AXP_FEATURE_DEFINITION_PROVIDER, AXP_TAG_PROVIDER, AXP_CONTEXT_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/core';
4
+ import { objectKeyValueTransforms, AXPTagProvider, AXPComponentSlotModule, AXP_FEATURE_DEFINITION_PROVIDER, AXP_TAG_PROVIDER, AXP_CONTEXT_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/core';
5
5
  import { AXP_WIDGETS_EDITOR_CATEGORY, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/layout/widget-core';
6
6
  import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXPWidgetsModule } from '@acorex-platform/framework-client/layout/widgets';
7
7
  import { AXPRuntimeModule, provideQuerySetups } from '@acorex-platform/framework-client/runtime';
8
8
  import * as i0 from '@angular/core';
9
9
  import { inject, Injectable, LOCALE_ID, PLATFORM_ID, input, signal, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
10
10
  import { ROUTES } from '@angular/router';
11
- import { RootConfig, AXPAiManagementFeatureKeys, AXPAdministrationPermissionKeys, AXPAiManagementMenuKeys, AXMAiAssistPermissionKeys, AXPAiManagementSettings, isChatPurposeModelRow, readModelPurposes } from '@acorex-platform/module-ai-management-client/contracts';
11
+ import { AXPAiManagementFeatureKeys, RootConfig, AXPAdministrationPermissionKeys, AXPAiManagementMenuKeys, AXMAiAssistPermissionKeys, AXPAiManagementSettings, isChatPurposeModelRow, readModelPurposes } from '@acorex-platform/module-ai-management-client/contracts';
12
+ export { AiManagementManifest } from '@acorex-platform/module-ai-management-client/contracts';
12
13
  import { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
13
14
  import { AXPCommonPermissionGroupKeys } from '@acorex-platform/module-common-client/contracts';
14
15
  import * as i7 from '@acorex/core/translation';
15
16
  import { resolveMultiLanguageString, AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
16
17
  import { AXPWidgetsList, AXPPlatformScope, AXPRegionalSetting, AXPFileStorageStatus, createRandomUuid } from '@acorex-platform/framework-shared/core';
17
- import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
18
- import { assembleAxpAiPlatformRuntimeContext, parseAgentOutputContract, axpAiChatMessageGetText, axpAiAgentOutputContractUsesStructuredFinalize, axpAiAgentOutputContractStructuredRetryCap, axpAiChatTextMessage, resolveAgentOutputContract, AXM_AI_PLATFORM_RUNTIME_CONTEXT_DEFINITIONS, AIMANAGEMENT_CHAT_SYNTHESIZE_SPEECH_COMMAND_KEY, AIMANAGEMENT_CHAT_TRANSCRIBE_SPEECH_COMMAND_KEY, AIMANAGEMENT_CHAT_GENERATE_IMAGE_COMMAND_KEY } from '@acorex-platform/module-ai-management-client/contracts';
18
+ import { assembleAxpAiPlatformRuntimeContext, parseAgentOutputContract, axpAiChatMessageGetText, axpAiAgentOutputContractUsesStructuredFinalize, axpAiAgentOutputContractStructuredRetryCap, axpAiChatTextMessage, resolveAgentOutputContract, AXM_AI_PLATFORM_RUNTIME_CONTEXT_DEFINITIONS, AIMANAGEMENT_RENDER_CHAT_CHART_COMMAND_KEY, AIMANAGEMENT_CHAT_SYNTHESIZE_SPEECH_COMMAND_KEY, AIMANAGEMENT_CHAT_TRANSCRIBE_SPEECH_COMMAND_KEY, AIMANAGEMENT_CHAT_GENERATE_IMAGE_COMMAND_KEY } from '@acorex-platform/module-ai-management-client/contracts';
19
19
  export * from '@acorex-platform/module-ai-management-client/contracts';
20
20
  import * as i2 from '@acorex/components/button';
21
21
  import { AXButtonModule } from '@acorex/components/button';
@@ -35,25 +35,6 @@ import { FormsModule } from '@angular/forms';
35
35
  import { AXOverlayService } from '@acorex/cdk/overlay';
36
36
  import { AXPWidgetGroupEnum } from '@acorex-platform/framework-shared/widget-core';
37
37
 
38
- //#region ---- Imports ----
39
- //#endregion
40
- //#region ---- Manifest Definition ----
41
- /**
42
- * AI Management Module Manifest.
43
- * Defines module metadata for AI provider and API key management.
44
- */
45
- const AiManagementManifest = {
46
- name: RootConfig.module.name,
47
- version: '1.0.0',
48
- title: RootConfig.module.title,
49
- icon: RootConfig.module.icon,
50
- i18n: RootConfig.config.i18n,
51
- type: 'domain',
52
- domain: 'ai',
53
- dependencies: [],
54
- };
55
- //#endregion
56
-
57
38
  //#region ---- Imports ----
58
39
  //#endregion
59
40
  //#region ---- Feature Definition Provider ----
@@ -235,6 +216,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
235
216
  const I18N = '@ai-management:settings';
236
217
  class AXMAiManagementSettingProvider {
237
218
  async provide(context) {
219
+ // Extensions attach their own AI sections on this group (for example document reading and form designer).
238
220
  context
239
221
  .addGroup('ai-settings', `${I18N}.group.nav-title`, `${I18N}.group.description`, 'fa-light fa-robot', `${I18N}.group.title`, 60)
240
222
  .addSection('global-ai', `${I18N}.section.global-ai.title`, `${I18N}.section.global-ai.description`)
@@ -279,6 +261,22 @@ class AXMAiManagementSettingProvider {
279
261
  description: `${I18N}.global-system-prompt.prefix.description`,
280
262
  })
281
263
  .endSection()
264
+ .endGroup();
265
+ }
266
+ }
267
+ /**
268
+ * Registered after other Intelligence sections so Google Gemini stays last in that category.
269
+ */
270
+ class AXMAiManagementGeminiSettingProvider {
271
+ async provide(context) {
272
+ if (!context.hasGroup('ai-settings')) {
273
+ return;
274
+ }
275
+ const intelligence = context.group('ai-settings');
276
+ if (!intelligence) {
277
+ return;
278
+ }
279
+ intelligence
282
280
  .addSection('gemini', `${I18N}.section.gemini.title`, `${I18N}.section.gemini.description`)
283
281
  .addSetting({
284
282
  key: AXPAiManagementSettings.Providers.Gemini.ApiKey,
@@ -297,10 +295,16 @@ class AXMAiManagementSettingProvider {
297
295
  },
298
296
  description: `${I18N}.gemini.api-key.description`,
299
297
  })
300
- .endSection()
301
- .endGroup();
298
+ .endSection();
302
299
  }
303
300
  }
301
+ function provideAiManagementGeminiSettings() {
302
+ return {
303
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
304
+ useClass: AXMAiManagementGeminiSettingProvider,
305
+ multi: true,
306
+ };
307
+ }
304
308
  //#endregion
305
309
 
306
310
  //#region ---- Imports ----
@@ -352,6 +356,13 @@ const AI_MODEL_PURPOSE_TAGS = [
352
356
  description: 'Video generation',
353
357
  scope: 'system',
354
358
  },
359
+ {
360
+ id: 'ai-model-purpose-live-voice',
361
+ title: 'live-voice',
362
+ color: '#c026d3',
363
+ description: 'Realtime live voice (OpenAI Realtime / Gemini Live)',
364
+ scope: 'system',
365
+ },
355
366
  ];
356
367
  //#region ---- Provider ----
357
368
  class AXMAiModelPurposeTagProvider extends AXPTagProvider {
@@ -388,7 +399,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
388
399
  //#endregion
389
400
  //#region ---- Structured output ----
390
401
  /** Default max completion tokens when the AiModel row has no `maxOutputTokens` and the caller omits `maxTokens`. */
391
- const AXPAiAssistDefaultStructuredMaxTokens = 128_000;
402
+ const AXPAiAssistDefaultStructuredMaxTokens = 32_000;
392
403
  /** Default maximum follow-up turns after the first model response when validating structured JSON (implementation may use this). */
393
404
  const AXPAiAssistDefaultMaxStructuredRetries = 3;
394
405
  /**
@@ -526,6 +537,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
526
537
  args: [{ providedIn: 'root' }]
527
538
  }] });
528
539
 
540
+ //#region ---- Abort detection (client-only) ----
541
+ function errorName(value) {
542
+ if (!value || typeof value !== 'object') {
543
+ return undefined;
544
+ }
545
+ const name = value.name;
546
+ return typeof name === 'string' ? name : undefined;
547
+ }
548
+ function isAbortNamed(value) {
549
+ return errorName(value) === 'AbortError';
550
+ }
551
+ function isAiAssistAbortError(error, signal) {
552
+ if (signal?.aborted) {
553
+ return true;
554
+ }
555
+ if (isAbortNamed(error)) {
556
+ return true;
557
+ }
558
+ if (error && typeof error === 'object') {
559
+ const cause = error.cause;
560
+ if (isAbortNamed(cause)) {
561
+ return true;
562
+ }
563
+ }
564
+ if (isAbortNamed(signal?.reason)) {
565
+ return true;
566
+ }
567
+ return false;
568
+ }
569
+ function createAiAssistAbortError(message = 'AI assist run cancelled', options) {
570
+ const error = options && 'cause' in options ? new Error(message, { cause: options.cause }) : new Error(message);
571
+ error.name = 'AbortError';
572
+ return error;
573
+ }
574
+ function assertAiAssistNotAborted(signal) {
575
+ if (!signal?.aborted) {
576
+ return;
577
+ }
578
+ const reason = signal.reason;
579
+ if (reason instanceof Error && isAbortNamed(reason)) {
580
+ throw reason;
581
+ }
582
+ throw createAiAssistAbortError('AI assist run cancelled', reason !== undefined ? { cause: reason } : undefined);
583
+ }
584
+ //#endregion
585
+
529
586
  //#region ---- Imports ----
530
587
  //#endregion
531
588
  //#region ---- Constants ----
@@ -820,7 +877,9 @@ class AXMAiAssistPromptBoxComponent {
820
877
  //#region ---- State ----
821
878
  this.promptDraft = signal('', /* @ts-ignore */
822
879
  ...(ngDevMode ? [{ debugName: "promptDraft" }] : /* istanbul ignore next */ []));
823
- this.busy = signal(false, /* @ts-ignore */
880
+ this.runPhase = signal('idle', /* @ts-ignore */
881
+ ...(ngDevMode ? [{ debugName: "runPhase" }] : /* istanbul ignore next */ []));
882
+ this.busy = computed(() => this.runPhase() !== 'idle', /* @ts-ignore */
824
883
  ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []));
825
884
  this.isComposerSaving = signal(false, /* @ts-ignore */
826
885
  ...(ngDevMode ? [{ debugName: "isComposerSaving" }] : /* istanbul ignore next */ []));
@@ -834,10 +893,11 @@ class AXMAiAssistPromptBoxComponent {
834
893
  ...(ngDevMode ? [{ debugName: "draftComposerFiles" }] : /* istanbul ignore next */ []));
835
894
  this.assistTargetKey = signal('', /* @ts-ignore */
836
895
  ...(ngDevMode ? [{ debugName: "assistTargetKey" }] : /* istanbul ignore next */ []));
896
+ this.runAbortController = null;
837
897
  //#endregion
838
898
  //#region ---- Computed ----
839
899
  this.canSend = computed(() => {
840
- if (this.busy() || this.isComposerSaving()) {
900
+ if (this.runPhase() !== 'idle' || this.isComposerSaving()) {
841
901
  return false;
842
902
  }
843
903
  const textOk = this.promptDraft().trim().length > 0;
@@ -870,6 +930,7 @@ class AXMAiAssistPromptBoxComponent {
870
930
  }
871
931
  }
872
932
  ngOnDestroy() {
933
+ this.abortActiveRun();
873
934
  for (const s of this.draftComposerImages()) {
874
935
  URL.revokeObjectURL(s.previewUrl);
875
936
  }
@@ -890,20 +951,40 @@ class AXMAiAssistPromptBoxComponent {
890
951
  void this.onSend();
891
952
  }
892
953
  onCancel() {
954
+ if (this.runPhase() !== 'idle') {
955
+ return;
956
+ }
893
957
  this.requestClose()(null);
894
958
  }
959
+ abortActiveRun() {
960
+ this.runAbortController?.abort();
961
+ }
962
+ onStop() {
963
+ if (this.runPhase() !== 'running') {
964
+ return;
965
+ }
966
+ this.runPhase.set('stopping');
967
+ this.runAbortController?.abort();
968
+ }
895
969
  onMenuCancel(panel) {
896
970
  panel.close();
897
- if (this.busy()) {
971
+ if (this.runPhase() !== 'idle') {
898
972
  return;
899
973
  }
900
974
  this.onCancel();
901
975
  }
902
976
  /**
903
- * Dismisses the prompt box like Cancel (disabled while a run is in flight, same as footer Cancel).
977
+ * Idle: close. Running: Stop (stay open). Stopping: ignore.
904
978
  */
905
979
  onDocumentEscape() {
906
- if (!isPlatformBrowser(this.platformId) || this.busy()) {
980
+ if (!isPlatformBrowser(this.platformId)) {
981
+ return;
982
+ }
983
+ if (this.runPhase() === 'stopping') {
984
+ return;
985
+ }
986
+ if (this.runPhase() === 'running') {
987
+ this.onStop();
907
988
  return;
908
989
  }
909
990
  this.onCancel();
@@ -918,6 +999,10 @@ class AXMAiAssistPromptBoxComponent {
918
999
  void this.pickComposerDocuments();
919
1000
  }
920
1001
  async onSend() {
1002
+ if (this.runPhase() === 'running') {
1003
+ this.onStop();
1004
+ return;
1005
+ }
921
1006
  if (!this.canSend()) {
922
1007
  return;
923
1008
  }
@@ -979,19 +1064,27 @@ class AXMAiAssistPromptBoxComponent {
979
1064
  assistId,
980
1065
  userMediaAttachments,
981
1066
  };
982
- this.busy.set(true);
1067
+ const controller = new AbortController();
1068
+ this.runAbortController = controller;
1069
+ this.runPhase.set('running');
983
1070
  try {
984
- const result = await this.runPrompt()(payload);
1071
+ const result = await this.runPrompt()(payload, { abortSignal: controller.signal });
985
1072
  this.requestClose()(result);
986
1073
  }
987
1074
  catch (err) {
1075
+ if (isAiAssistAbortError(err, controller.signal)) {
1076
+ return;
1077
+ }
988
1078
  const errTitle = await this.translation.translateAsync('@general:messages.error.title');
989
1079
  const fallback = await this.translation.translateAsync('@ai-management:assist-popup.run-error');
990
1080
  const content = err instanceof Error ? err.message : fallback;
991
1081
  await this.toastService.show({ color: 'danger', title: errTitle, content });
992
1082
  }
993
1083
  finally {
994
- this.busy.set(false);
1084
+ if (this.runAbortController === controller) {
1085
+ this.runAbortController = null;
1086
+ }
1087
+ this.runPhase.set('idle');
995
1088
  }
996
1089
  }
997
1090
  removeDraftImage(clientId) {
@@ -1331,7 +1424,7 @@ class AXMAiAssistPromptBoxComponent {
1331
1424
  await this.toastService.show({ color: 'warning', title: errTitle, content });
1332
1425
  }
1333
1426
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAiAssistPromptBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1334
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMAiAssistPromptBoxComponent, isStandalone: true, selector: "axm-ai-assist-prompt-box", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, initialPrompt: { classPropertyName: "initialPrompt", publicName: "initialPrompt", isSignal: true, isRequired: false, transformFunction: null }, contentMaxWidthPx: { classPropertyName: "contentMaxWidthPx", publicName: "contentMaxWidthPx", isSignal: true, isRequired: false, transformFunction: null }, initialAssistId: { classPropertyName: "initialAssistId", publicName: "initialAssistId", isSignal: true, isRequired: false, transformFunction: null }, runPrompt: { classPropertyName: "runPrompt", publicName: "runPrompt", isSignal: true, isRequired: true, transformFunction: null }, requestClose: { classPropertyName: "requestClose", publicName: "requestClose", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onDocumentEscape()" } }, ngImport: i0, template: "<div\n class=\"axm-ai-assist-prompt-box flex flex-col gap-2.5 min-h-0 w-full\"\n [style.max-width.px]=\"contentMaxWidthPx()\"\n>\n <div\n class=\"axm-ai-assist-prompt-box__eyebrow flex items-center justify-between gap-3 shrink-0 px-0.5\"\n >\n <div\n class=\"axm-ai-assist-prompt-box__brand inline-flex min-w-0 items-center gap-2\"\n >\n <span class=\"axm-ai-assist-prompt-box__brand-mark\" aria-hidden=\"true\">\n <i class=\"fa-light fa-sparkles\" aria-hidden=\"true\"></i>\n </span>\n <span class=\"axm-ai-assist-prompt-box__brand-title truncate\">{{\n title()\n }}</span>\n </div>\n <ax-button\n class=\"shrink-0 ax-sm\"\n look=\"blank\"\n color=\"default\"\n type=\"button\"\n [iconOnly]=\"true\"\n [disabled]=\"busy()\"\n [attr.aria-label]=\"\n ('@general:actions.close.title' | translate | async) ?? ''\n \"\n (onClick)=\"onCancel()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button>\n </div>\n\n <div class=\"axm-ai-assist-prompt-box__sheet flex min-h-0 flex-col gap-2\">\n @if (\n draftComposerImages().length > 0 ||\n draftComposerAudios().length > 0 ||\n draftComposerFiles().length > 0 ||\n isComposerSaving()\n ) {\n <div\n class=\"shrink-0 rounded-xl border border-default/45 dark:border-darker bg-lightest/90 p-1.5 flex flex-col gap-1.5\"\n [attr.aria-label]=\"\n ('@ai-management:chat.composer-attachments-region'\n | translate\n | async) ?? ''\n \"\n >\n <div\n class=\"flex flex-wrap items-center justify-between gap-1.5 text-[0.65rem] text-muted\"\n >\n <span>\n @if (isComposerSaving()) {\n {{ '@ai-management:chat.composer-uploading' | translate | async }}\n } @else {\n @if (draftComposerImages().length > 0) {\n <span\n >{{ draftComposerImages().length }}\n {{\n '@ai-management:chat.composer-images-count'\n | translate\n | async\n }}</span\n >\n }\n @if (\n draftComposerImages().length > 0 &&\n draftComposerAudios().length > 0\n ) {\n <span class=\"mx-1\">\u00B7</span>\n }\n @if (draftComposerAudios().length > 0) {\n <span\n >{{ draftComposerAudios().length }}\n {{\n '@ai-management:chat.composer-audio-count'\n | translate\n | async\n }}</span\n >\n }\n @if (draftComposerFiles().length > 0) {\n @if (\n draftComposerImages().length > 0 ||\n draftComposerAudios().length > 0\n ) {\n <span class=\"mx-1\">\u00B7</span>\n }\n <span\n >{{ draftComposerFiles().length }}\n {{\n '@ai-management:chat.composer-documents-count'\n | translate\n | async\n }}</span\n >\n }\n }\n </span>\n </div>\n @if (draftComposerImages().length > 0) {\n <div class=\"flex flex-wrap gap-1.5\">\n @for (slot of draftComposerImages(); track slot.clientId) {\n <div\n class=\"relative h-12 w-12 shrink-0 overflow-hidden rounded-md border border-default/60 dark:border-darker bg-lightest\"\n >\n <img\n [src]=\"slot.previewUrl\"\n [alt]=\"slot.name ?? ''\"\n class=\"h-full w-full object-cover\"\n />\n @if (!slot.fileId) {\n <span\n class=\"absolute inset-0 flex items-center justify-center bg-default/40 text-[0.6rem] font-medium text-on-lightest\"\n >\u2026</span\n >\n }\n <button\n type=\"button\"\n class=\"absolute end-0.5 top-0.5 flex h-4 w-4 items-center justify-center rounded bg-default/80 text-[0.65rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"\n ('@ai-management:chat.remove-draft-image'\n | translate\n | async) ?? ''\n \"\n (click)=\"removeDraftImage(slot.clientId)\"\n >\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n @if (draftComposerAudios().length > 0) {\n <div class=\"flex flex-col gap-1\">\n @for (slot of draftComposerAudios(); track slot.clientId) {\n <div\n class=\"flex items-center justify-between gap-1.5 rounded border border-default/60 dark:border-darker bg-lightest px-1.5 py-1 text-[0.65rem] min-w-0\"\n >\n <span\n class=\"truncate text-on-lightest\"\n [attr.title]=\"slot.name ?? ''\"\n >\n {{\n '@ai-management:chat.attached-audio-label'\n | translate\n | async\n }}:\n {{\n slot.name?.trim() ||\n ('@ai-management:chat.audio-untitled' | translate | async)\n }}\n </span>\n @if (!slot.fileId) {\n <span class=\"text-muted shrink-0\">\u2026</span>\n }\n <button\n type=\"button\"\n class=\"shrink-0 flex h-5 w-5 items-center justify-center rounded bg-default/80 text-[0.75rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"\n ('@ai-management:chat.remove-draft-audio'\n | translate\n | async) ?? ''\n \"\n (click)=\"removeDraftAudio(slot.clientId)\"\n >\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n @if (draftComposerFiles().length > 0) {\n <div class=\"flex flex-col gap-1\">\n @for (slot of draftComposerFiles(); track slot.clientId) {\n <div\n class=\"flex items-center justify-between gap-1.5 rounded border border-default/60 dark:border-darker bg-lightest px-1.5 py-1 text-[0.65rem] min-w-0\"\n >\n <span\n class=\"truncate text-on-lightest\"\n [attr.title]=\"slot.name ?? ''\"\n >\n {{\n '@ai-management:chat.attached-document-label'\n | translate\n | async\n }}:\n {{\n slot.name?.trim() ||\n ('@ai-management:chat.document-untitled'\n | translate\n | async)\n }}\n </span>\n @if (!slot.fileId) {\n <span class=\"text-muted shrink-0\">\u2026</span>\n }\n <button\n type=\"button\"\n class=\"shrink-0 flex h-5 w-5 items-center justify-center rounded bg-default/80 text-[0.75rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"\n ('@ai-management:chat.remove-draft-document'\n | translate\n | async) ?? ''\n \"\n (click)=\"removeDraftFile(slot.clientId)\"\n >\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"axm-ai-assist-prompt-box__body flex min-h-0 flex-col\">\n <ax-text-area\n class=\"axm-ai-assist-prompt-box__prompt-input w-full min-h-0\"\n [rows]=\"3\"\n [disabled]=\"busy()\"\n [ngModel]=\"promptDraft()\"\n (ngModelChange)=\"onPromptDraftChange($event)\"\n (keydown)=\"onPromptKeydown($event)\"\n [placeholder]=\"\n placeholder().trim().length > 0\n ? placeholder()\n : (('@ai-management:assist-popup.placeholder'\n | translate\n | async) ?? '')\n \"\n ></ax-text-area>\n </div>\n\n <div\n class=\"axm-ai-assist-prompt-box__footer flex shrink-0 items-center justify-between gap-2\"\n >\n <ax-button\n class=\"axm-ai-assist-prompt-box__menu-trigger\"\n look=\"solid\"\n color=\"primary\"\n type=\"button\"\n [iconOnly]=\"true\"\n [disabled]=\"busy()\"\n [attr.aria-label]=\"\n ('@ai-management:assist-popup.composer-menu-aria'\n | translate\n | async) ?? ''\n \"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus text-sm\" aria-hidden=\"true\"></i>\n </ax-prefix>\n <ax-dropdown-panel #composerMenu>\n <ax-button-item-list class=\"min-w-56\">\n <ax-button-item\n [text]=\"\n ('@ai-management:chat.upload-images' | translate | async) ?? ''\n \"\n [attr.aria-label]=\"\n ('@ai-management:chat.upload-images-aria'\n | translate\n | async) ?? ''\n \"\n (onClick)=\"openImagePicker(); composerMenu.close()\"\n >\n <ax-prefix>\n <i\n class=\"fa-light fa-image size-4 text-center\"\n aria-hidden=\"true\"\n ></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"\n ('@ai-management:chat.upload-audio' | translate | async) ?? ''\n \"\n [attr.aria-label]=\"\n ('@ai-management:chat.upload-audio-aria' | translate | async) ??\n ''\n \"\n (onClick)=\"openAudioPicker(); composerMenu.close()\"\n >\n <ax-prefix>\n <i\n class=\"fa-light fa-microphone size-4 text-center\"\n aria-hidden=\"true\"\n ></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"\n ('@ai-management:chat.upload-documents' | translate | async) ??\n ''\n \"\n [attr.aria-label]=\"\n ('@ai-management:chat.upload-documents-aria'\n | translate\n | async) ?? ''\n \"\n (onClick)=\"openDocumentPicker(); composerMenu.close()\"\n >\n <ax-prefix>\n <i\n class=\"fa-light fa-paperclip size-4 text-center\"\n aria-hidden=\"true\"\n ></i>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n\n <ax-button\n class=\"axm-ai-assist-prompt-box__send axm-ai-assist-prompt-box__send-gradient\"\n color=\"primary\"\n type=\"button\"\n [disabled]=\"busy() || !canSend()\"\n [text]=\"\n busy()\n ? (('@ai-management:assist-popup.generating' | translate | async) ??\n '')\n : (('@ai-management:assist-popup.generate' | translate | async) ??\n '')\n \"\n (onClick)=\"onSend()\"\n ></ax-button>\n </div>\n </div>\n</div>\n", styles: ["@layer properties;.axm-ai-assist-prompt-box-shell{pointer-events:none;box-sizing:border-box;inset:0;display:flex;max-height:100%;width:100%;flex-direction:column;align-items:center;justify-content:flex-end;padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-right:max(.75rem,env(safe-area-inset-right,0px));padding-bottom:max(.75rem,env(safe-area-inset-bottom,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-ai-assist-prompt-box-shell .overlay-pane{pointer-events:auto;--tw-border-style: none;border-style:none;background-color:transparent;flex:0 0 auto;width:auto!important;max-width:calc(100vw - 1.5rem);min-width:min(480px,100vw - 1.5rem)}.axm-ai-assist-prompt-box{--axm-axm-ai-assist-prompt-chrome-gradient: linear-gradient( 125deg, rgb(var(--ax-sys-color-primary-200)) 0%, rgb(var(--ax-sys-color-primary-400)) 48%, rgb(var(--ax-sys-color-primary-300)) 100% );--axm-axm-ai-assist-prompt-send-gradient: linear-gradient( 90deg, rgb(var(--ax-sys-color-primary-500)), rgb(var(--ax-sys-color-primary-700)) );margin:0;box-sizing:border-box;overflow:hidden;padding:0;max-height:min(78vh,620px);padding:.65rem .7rem .7rem;border-radius:1.35rem;background:var(--axm-axm-ai-assist-prompt-chrome-gradient);box-shadow:0 18px 50px -12px rgba(var(--ax-sys-color-on-surface),.12),0 8px 20px -8px rgba(var(--ax-sys-color-primary-400),.2)}.dark .axm-ai-assist-prompt-box{--axm-axm-ai-assist-prompt-chrome-gradient: linear-gradient( 125deg, rgb(var(--ax-sys-color-primary-600)) 0%, rgb(var(--ax-sys-color-primary-500)) 48%, rgb(var(--ax-sys-color-primary-400)) 100% );box-shadow:0 20px 55px -14px rgba(var(--ax-sys-color-dark),.48),0 8px 24px -8px rgba(var(--ax-sys-color-primary-400),.26)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-title{--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);font-size:.72rem;line-height:1.25;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-surface))}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-title){color:rgb(var(--ax-sys-color-on-lightest-surface))}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-mark{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);width:1.65rem;height:1.65rem;font-size:.75rem;line-height:1;color:rgb(var(--ax-sys-color-on-primary-surface));background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)));box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__sheet{min-height:0px;flex:auto;padding:.65rem .65rem .55rem;border-radius:1rem;background:rgb(var(--ax-sys-color-lightest-surface));border:1px solid rgba(var(--ax-sys-color-neutral-300),.35);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.95)}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__sheet){background:rgb(var(--ax-sys-color-neutral-800));border-color:rgba(var(--ax-sys-color-neutral-500),.4);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.06)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__body{min-height:0px;flex:auto;overflow-y:auto}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input{display:block;min-height:0px;width:100%;--tw-border-style: none !important;border-style:none!important;background-color:transparent!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input:focus-within{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input:focus-within>*{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea{min-height:4.5rem;max-height:min(30vh,240px);font-size:.8125rem;line-height:1.45;padding-block:.55rem;padding-inline:.65rem;border-radius:.65rem;--tw-border-style: none !important;border-style:none!important;background-color:transparent!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:focus,.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:focus-visible,.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:active{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important;outline-offset:0!important}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea){color:rgb(var(--ax-sys-color-on-lightest-surface));background:rgb(var(--ax-sys-color-neutral-900))!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__footer{min-height:0}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;overflow:hidden;border-radius:calc(infinity * 1px)!important;border-color:transparent!important;background-color:transparent!important;background:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.state-disabled,.state-loading,.state-selected),.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.state-disabled,.state-loading,.state-selected){border-color:transparent!important;background-color:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger>button{border-radius:calc(infinity * 1px)!important;--tw-border-style: none !important;border-style:none!important;padding:0!important;width:2.25rem;height:2.25rem;min-width:2.25rem;min-height:2.25rem;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)))!important;box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-disabled>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-loading>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger>button:disabled{opacity:.55;box-shadow:none}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.94)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.88)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;overflow:hidden;border-radius:calc(infinity * 1px)!important;border-color:transparent!important;background-color:transparent!important;background:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.state-disabled,.state-loading,.state-selected),.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.state-disabled,.state-loading,.state-selected){border-color:transparent!important;background-color:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient>button{border-radius:calc(infinity * 1px)!important;--tw-border-style: none !important;border-style:none!important;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);min-height:2.25rem;padding-inline:1rem!important;font-size:.8rem;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:var(--axm-axm-ai-assist-prompt-send-gradient)!important;box-shadow:0 3px 12px rgba(var(--ax-sys-color-secondary-400),.35)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-disabled>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-loading>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient>button:disabled{opacity:.55;box-shadow:none}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.96)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.9)}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i4.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXTextAreaModule }, { kind: "component", type: i5.AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1427
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMAiAssistPromptBoxComponent, isStandalone: true, selector: "axm-ai-assist-prompt-box", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, initialPrompt: { classPropertyName: "initialPrompt", publicName: "initialPrompt", isSignal: true, isRequired: false, transformFunction: null }, contentMaxWidthPx: { classPropertyName: "contentMaxWidthPx", publicName: "contentMaxWidthPx", isSignal: true, isRequired: false, transformFunction: null }, initialAssistId: { classPropertyName: "initialAssistId", publicName: "initialAssistId", isSignal: true, isRequired: false, transformFunction: null }, runPrompt: { classPropertyName: "runPrompt", publicName: "runPrompt", isSignal: true, isRequired: true, transformFunction: null }, requestClose: { classPropertyName: "requestClose", publicName: "requestClose", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onDocumentEscape()" } }, ngImport: i0, template: "<div\r\n class=\"axm-ai-assist-prompt-box flex flex-col gap-2.5 min-h-0 w-full\"\r\n [style.max-width.px]=\"contentMaxWidthPx()\"\r\n>\r\n <div\r\n class=\"axm-ai-assist-prompt-box__eyebrow flex items-center justify-between gap-3 shrink-0 px-0.5\"\r\n >\r\n <div\r\n class=\"axm-ai-assist-prompt-box__brand inline-flex min-w-0 items-center gap-2\"\r\n >\r\n <span class=\"axm-ai-assist-prompt-box__brand-mark\" aria-hidden=\"true\">\r\n <i class=\"fa-light fa-sparkles\" aria-hidden=\"true\"></i>\r\n </span>\r\n <span class=\"axm-ai-assist-prompt-box__brand-title truncate\">{{\r\n title()\r\n }}</span>\r\n </div>\r\n <ax-button\r\n class=\"shrink-0 ax-sm\"\r\n look=\"blank\"\r\n color=\"default\"\r\n type=\"button\"\r\n [iconOnly]=\"true\"\r\n [disabled]=\"busy()\"\r\n [attr.aria-label]=\"\r\n ('@general:actions.close.title' | translate | async) ?? ''\r\n \"\r\n (onClick)=\"onCancel()\"\r\n >\r\n <ax-prefix>\r\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\r\n </ax-prefix>\r\n </ax-button>\r\n </div>\r\n\r\n <div class=\"axm-ai-assist-prompt-box__sheet flex min-h-0 flex-col gap-2\">\r\n @if (\r\n draftComposerImages().length > 0 ||\r\n draftComposerAudios().length > 0 ||\r\n draftComposerFiles().length > 0 ||\r\n isComposerSaving()\r\n ) {\r\n <div\r\n class=\"shrink-0 rounded-xl border border-default/45 dark:border-darker bg-lightest/90 p-1.5 flex flex-col gap-1.5\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.composer-attachments-region'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n >\r\n <div\r\n class=\"flex flex-wrap items-center justify-between gap-1.5 text-[0.65rem] text-muted\"\r\n >\r\n <span>\r\n @if (isComposerSaving()) {\r\n {{ '@ai-management:chat.composer-uploading' | translate | async }}\r\n } @else {\r\n @if (draftComposerImages().length > 0) {\r\n <span\r\n >{{ draftComposerImages().length }}\r\n {{\r\n '@ai-management:chat.composer-images-count'\r\n | translate\r\n | async\r\n }}</span\r\n >\r\n }\r\n @if (\r\n draftComposerImages().length > 0 &&\r\n draftComposerAudios().length > 0\r\n ) {\r\n <span class=\"mx-1\">\u00B7</span>\r\n }\r\n @if (draftComposerAudios().length > 0) {\r\n <span\r\n >{{ draftComposerAudios().length }}\r\n {{\r\n '@ai-management:chat.composer-audio-count'\r\n | translate\r\n | async\r\n }}</span\r\n >\r\n }\r\n @if (draftComposerFiles().length > 0) {\r\n @if (\r\n draftComposerImages().length > 0 ||\r\n draftComposerAudios().length > 0\r\n ) {\r\n <span class=\"mx-1\">\u00B7</span>\r\n }\r\n <span\r\n >{{ draftComposerFiles().length }}\r\n {{\r\n '@ai-management:chat.composer-documents-count'\r\n | translate\r\n | async\r\n }}</span\r\n >\r\n }\r\n }\r\n </span>\r\n </div>\r\n @if (draftComposerImages().length > 0) {\r\n <div class=\"flex flex-wrap gap-1.5\">\r\n @for (slot of draftComposerImages(); track slot.clientId) {\r\n <div\r\n class=\"relative h-12 w-12 shrink-0 overflow-hidden rounded-md border border-default/60 dark:border-darker bg-lightest\"\r\n >\r\n <img\r\n [src]=\"slot.previewUrl\"\r\n [alt]=\"slot.name ?? ''\"\r\n class=\"h-full w-full object-cover\"\r\n />\r\n @if (!slot.fileId) {\r\n <span\r\n class=\"absolute inset-0 flex items-center justify-center bg-default/40 text-[0.6rem] font-medium text-on-lightest\"\r\n >\u2026</span\r\n >\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"absolute end-0.5 top-0.5 flex h-4 w-4 items-center justify-center rounded bg-default/80 text-[0.65rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\r\n [disabled]=\"busy() || isComposerSaving()\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.remove-draft-image'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (click)=\"removeDraftImage(slot.clientId)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n @if (draftComposerAudios().length > 0) {\r\n <div class=\"flex flex-col gap-1\">\r\n @for (slot of draftComposerAudios(); track slot.clientId) {\r\n <div\r\n class=\"flex items-center justify-between gap-1.5 rounded border border-default/60 dark:border-darker bg-lightest px-1.5 py-1 text-[0.65rem] min-w-0\"\r\n >\r\n <span\r\n class=\"truncate text-on-lightest\"\r\n [attr.title]=\"slot.name ?? ''\"\r\n >\r\n {{\r\n '@ai-management:chat.attached-audio-label'\r\n | translate\r\n | async\r\n }}:\r\n {{\r\n slot.name?.trim() ||\r\n ('@ai-management:chat.audio-untitled' | translate | async)\r\n }}\r\n </span>\r\n @if (!slot.fileId) {\r\n <span class=\"text-muted shrink-0\">\u2026</span>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"shrink-0 flex h-5 w-5 items-center justify-center rounded bg-default/80 text-[0.75rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\r\n [disabled]=\"busy() || isComposerSaving()\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.remove-draft-audio'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (click)=\"removeDraftAudio(slot.clientId)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n @if (draftComposerFiles().length > 0) {\r\n <div class=\"flex flex-col gap-1\">\r\n @for (slot of draftComposerFiles(); track slot.clientId) {\r\n <div\r\n class=\"flex items-center justify-between gap-1.5 rounded border border-default/60 dark:border-darker bg-lightest px-1.5 py-1 text-[0.65rem] min-w-0\"\r\n >\r\n <span\r\n class=\"truncate text-on-lightest\"\r\n [attr.title]=\"slot.name ?? ''\"\r\n >\r\n {{\r\n '@ai-management:chat.attached-document-label'\r\n | translate\r\n | async\r\n }}:\r\n {{\r\n slot.name?.trim() ||\r\n ('@ai-management:chat.document-untitled'\r\n | translate\r\n | async)\r\n }}\r\n </span>\r\n @if (!slot.fileId) {\r\n <span class=\"text-muted shrink-0\">\u2026</span>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"shrink-0 flex h-5 w-5 items-center justify-center rounded bg-default/80 text-[0.75rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\r\n [disabled]=\"busy() || isComposerSaving()\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.remove-draft-document'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (click)=\"removeDraftFile(slot.clientId)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"axm-ai-assist-prompt-box__body flex min-h-0 flex-col\">\r\n <ax-text-area\r\n class=\"axm-ai-assist-prompt-box__prompt-input w-full min-h-0\"\r\n [rows]=\"3\"\r\n [disabled]=\"busy()\"\r\n [ngModel]=\"promptDraft()\"\r\n (ngModelChange)=\"onPromptDraftChange($event)\"\r\n (keydown)=\"onPromptKeydown($event)\"\r\n [placeholder]=\"\r\n placeholder().trim().length > 0\r\n ? placeholder()\r\n : (('@ai-management:assist-popup.placeholder'\r\n | translate\r\n | async) ?? '')\r\n \"\r\n ></ax-text-area>\r\n </div>\r\n\r\n <div\r\n class=\"axm-ai-assist-prompt-box__footer flex shrink-0 items-center justify-between gap-2\"\r\n >\r\n <ax-button\r\n class=\"axm-ai-assist-prompt-box__menu-trigger\"\r\n look=\"solid\"\r\n color=\"primary\"\r\n type=\"button\"\r\n [iconOnly]=\"true\"\r\n [disabled]=\"busy()\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:assist-popup.composer-menu-aria'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n >\r\n <ax-prefix>\r\n <i class=\"fa-light fa-plus text-sm\" aria-hidden=\"true\"></i>\r\n </ax-prefix>\r\n <ax-dropdown-panel #composerMenu>\r\n <ax-button-item-list class=\"min-w-56\">\r\n <ax-button-item\r\n [text]=\"\r\n ('@ai-management:chat.upload-images' | translate | async) ?? ''\r\n \"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.upload-images-aria'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (onClick)=\"openImagePicker(); composerMenu.close()\"\r\n >\r\n <ax-prefix>\r\n <i\r\n class=\"fa-light fa-image size-4 text-center\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </ax-prefix>\r\n </ax-button-item>\r\n <ax-button-item\r\n [text]=\"\r\n ('@ai-management:chat.upload-audio' | translate | async) ?? ''\r\n \"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.upload-audio-aria' | translate | async) ??\r\n ''\r\n \"\r\n (onClick)=\"openAudioPicker(); composerMenu.close()\"\r\n >\r\n <ax-prefix>\r\n <i\r\n class=\"fa-light fa-microphone size-4 text-center\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </ax-prefix>\r\n </ax-button-item>\r\n <ax-button-item\r\n [text]=\"\r\n ('@ai-management:chat.upload-documents' | translate | async) ??\r\n ''\r\n \"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.upload-documents-aria'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (onClick)=\"openDocumentPicker(); composerMenu.close()\"\r\n >\r\n <ax-prefix>\r\n <i\r\n class=\"fa-light fa-paperclip size-4 text-center\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </ax-prefix>\r\n </ax-button-item>\r\n </ax-button-item-list>\r\n </ax-dropdown-panel>\r\n </ax-button>\r\n\r\n <ax-button\r\n class=\"axm-ai-assist-prompt-box__send axm-ai-assist-prompt-box__send-gradient\"\r\n color=\"primary\"\r\n type=\"button\"\r\n [disabled]=\"runPhase() === 'stopping' || (runPhase() === 'idle' && !canSend())\"\r\n [text]=\"\r\n runPhase() === 'stopping'\r\n ? (('@ai-management:assist-popup.stopping' | translate | async) ??\r\n '')\r\n : runPhase() === 'running'\r\n ? (('@ai-management:assist-popup.stop' | translate | async) ?? '')\r\n : (('@ai-management:assist-popup.generate' | translate | async) ??\r\n '')\r\n \"\r\n (onClick)=\"onSend()\"\r\n ></ax-button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["@layer properties;.axm-ai-assist-prompt-box-shell{pointer-events:none;box-sizing:border-box;inset:0;display:flex;max-height:100%;width:100%;flex-direction:column;align-items:center;justify-content:flex-end;padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-right:max(.75rem,env(safe-area-inset-right,0px));padding-bottom:max(.75rem,env(safe-area-inset-bottom,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-ai-assist-prompt-box-shell .overlay-pane{pointer-events:auto;--tw-border-style: none;border-style:none;background-color:transparent;flex:0 0 auto;width:auto!important;max-width:calc(100vw - 1.5rem);min-width:min(480px,100vw - 1.5rem)}.axm-ai-assist-prompt-box{--axm-axm-ai-assist-prompt-chrome-gradient: linear-gradient( 125deg, rgb(var(--ax-sys-color-primary-200)) 0%, rgb(var(--ax-sys-color-primary-400)) 48%, rgb(var(--ax-sys-color-primary-300)) 100% );--axm-axm-ai-assist-prompt-send-gradient: linear-gradient( 90deg, rgb(var(--ax-sys-color-primary-500)), rgb(var(--ax-sys-color-primary-700)) );margin:0;box-sizing:border-box;overflow:hidden;padding:0;max-height:min(78vh,620px);padding:.65rem .7rem .7rem;border-radius:1.35rem;background:var(--axm-axm-ai-assist-prompt-chrome-gradient);box-shadow:0 18px 50px -12px rgba(var(--ax-sys-color-on-surface),.12),0 8px 20px -8px rgba(var(--ax-sys-color-primary-400),.2)}.dark .axm-ai-assist-prompt-box{--axm-axm-ai-assist-prompt-chrome-gradient: linear-gradient( 125deg, rgb(var(--ax-sys-color-primary-600)) 0%, rgb(var(--ax-sys-color-primary-500)) 48%, rgb(var(--ax-sys-color-primary-400)) 100% );box-shadow:0 20px 55px -14px rgba(var(--ax-sys-color-dark),.48),0 8px 24px -8px rgba(var(--ax-sys-color-primary-400),.26)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-title{--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);font-size:.72rem;line-height:1.25;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-surface))}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-title){color:rgb(var(--ax-sys-color-on-lightest-surface))}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-mark{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);width:1.65rem;height:1.65rem;font-size:.75rem;line-height:1;color:rgb(var(--ax-sys-color-on-primary-surface));background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)));box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__sheet{min-height:0px;flex:auto;padding:.65rem .65rem .55rem;border-radius:1rem;background:rgb(var(--ax-sys-color-lightest-surface));border:1px solid rgba(var(--ax-sys-color-neutral-300),.35);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.95)}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__sheet){background:rgb(var(--ax-sys-color-neutral-800));border-color:rgba(var(--ax-sys-color-neutral-500),.4);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.06)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__body{min-height:0px;flex:auto;overflow-y:auto}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input{display:block;min-height:0px;width:100%;--tw-border-style: none !important;border-style:none!important;background-color:transparent!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input:focus-within{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input:focus-within>*{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea{min-height:4.5rem;max-height:min(30vh,240px);font-size:.8125rem;line-height:1.45;padding-block:.55rem;padding-inline:.65rem;border-radius:.65rem;--tw-border-style: none !important;border-style:none!important;background-color:transparent!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:focus,.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:focus-visible,.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:active{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important;outline-offset:0!important}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea){color:rgb(var(--ax-sys-color-on-lightest-surface));background:rgb(var(--ax-sys-color-neutral-900))!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__footer{min-height:0}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;overflow:hidden;border-radius:calc(infinity * 1px)!important;border-color:transparent!important;background-color:transparent!important;background:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.state-disabled,.state-loading,.state-selected),.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.state-disabled,.state-loading,.state-selected){border-color:transparent!important;background-color:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger>button{border-radius:calc(infinity * 1px)!important;--tw-border-style: none !important;border-style:none!important;padding:0!important;width:2.25rem;height:2.25rem;min-width:2.25rem;min-height:2.25rem;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)))!important;box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-disabled>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-loading>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger>button:disabled{opacity:.55;box-shadow:none}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.94)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.88)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;overflow:hidden;border-radius:calc(infinity * 1px)!important;border-color:transparent!important;background-color:transparent!important;background:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.state-disabled,.state-loading,.state-selected),.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.state-disabled,.state-loading,.state-selected){border-color:transparent!important;background-color:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient>button{border-radius:calc(infinity * 1px)!important;--tw-border-style: none !important;border-style:none!important;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);min-height:2.25rem;padding-inline:1rem!important;font-size:.8rem;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:var(--axm-axm-ai-assist-prompt-send-gradient)!important;box-shadow:0 3px 12px rgba(var(--ax-sys-color-secondary-400),.35)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-disabled>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-loading>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient>button:disabled{opacity:.55;box-shadow:none}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.96)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.9)}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i4.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXTextAreaModule }, { kind: "component", type: i5.AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1335
1428
  }
1336
1429
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMAiAssistPromptBoxComponent, decorators: [{
1337
1430
  type: Component,
@@ -1346,7 +1439,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
1346
1439
  AXDropdownButtonModule,
1347
1440
  AXTextAreaModule,
1348
1441
  AXTranslationModule,
1349
- ], template: "<div\n class=\"axm-ai-assist-prompt-box flex flex-col gap-2.5 min-h-0 w-full\"\n [style.max-width.px]=\"contentMaxWidthPx()\"\n>\n <div\n class=\"axm-ai-assist-prompt-box__eyebrow flex items-center justify-between gap-3 shrink-0 px-0.5\"\n >\n <div\n class=\"axm-ai-assist-prompt-box__brand inline-flex min-w-0 items-center gap-2\"\n >\n <span class=\"axm-ai-assist-prompt-box__brand-mark\" aria-hidden=\"true\">\n <i class=\"fa-light fa-sparkles\" aria-hidden=\"true\"></i>\n </span>\n <span class=\"axm-ai-assist-prompt-box__brand-title truncate\">{{\n title()\n }}</span>\n </div>\n <ax-button\n class=\"shrink-0 ax-sm\"\n look=\"blank\"\n color=\"default\"\n type=\"button\"\n [iconOnly]=\"true\"\n [disabled]=\"busy()\"\n [attr.aria-label]=\"\n ('@general:actions.close.title' | translate | async) ?? ''\n \"\n (onClick)=\"onCancel()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\n </ax-prefix>\n </ax-button>\n </div>\n\n <div class=\"axm-ai-assist-prompt-box__sheet flex min-h-0 flex-col gap-2\">\n @if (\n draftComposerImages().length > 0 ||\n draftComposerAudios().length > 0 ||\n draftComposerFiles().length > 0 ||\n isComposerSaving()\n ) {\n <div\n class=\"shrink-0 rounded-xl border border-default/45 dark:border-darker bg-lightest/90 p-1.5 flex flex-col gap-1.5\"\n [attr.aria-label]=\"\n ('@ai-management:chat.composer-attachments-region'\n | translate\n | async) ?? ''\n \"\n >\n <div\n class=\"flex flex-wrap items-center justify-between gap-1.5 text-[0.65rem] text-muted\"\n >\n <span>\n @if (isComposerSaving()) {\n {{ '@ai-management:chat.composer-uploading' | translate | async }}\n } @else {\n @if (draftComposerImages().length > 0) {\n <span\n >{{ draftComposerImages().length }}\n {{\n '@ai-management:chat.composer-images-count'\n | translate\n | async\n }}</span\n >\n }\n @if (\n draftComposerImages().length > 0 &&\n draftComposerAudios().length > 0\n ) {\n <span class=\"mx-1\">\u00B7</span>\n }\n @if (draftComposerAudios().length > 0) {\n <span\n >{{ draftComposerAudios().length }}\n {{\n '@ai-management:chat.composer-audio-count'\n | translate\n | async\n }}</span\n >\n }\n @if (draftComposerFiles().length > 0) {\n @if (\n draftComposerImages().length > 0 ||\n draftComposerAudios().length > 0\n ) {\n <span class=\"mx-1\">\u00B7</span>\n }\n <span\n >{{ draftComposerFiles().length }}\n {{\n '@ai-management:chat.composer-documents-count'\n | translate\n | async\n }}</span\n >\n }\n }\n </span>\n </div>\n @if (draftComposerImages().length > 0) {\n <div class=\"flex flex-wrap gap-1.5\">\n @for (slot of draftComposerImages(); track slot.clientId) {\n <div\n class=\"relative h-12 w-12 shrink-0 overflow-hidden rounded-md border border-default/60 dark:border-darker bg-lightest\"\n >\n <img\n [src]=\"slot.previewUrl\"\n [alt]=\"slot.name ?? ''\"\n class=\"h-full w-full object-cover\"\n />\n @if (!slot.fileId) {\n <span\n class=\"absolute inset-0 flex items-center justify-center bg-default/40 text-[0.6rem] font-medium text-on-lightest\"\n >\u2026</span\n >\n }\n <button\n type=\"button\"\n class=\"absolute end-0.5 top-0.5 flex h-4 w-4 items-center justify-center rounded bg-default/80 text-[0.65rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"\n ('@ai-management:chat.remove-draft-image'\n | translate\n | async) ?? ''\n \"\n (click)=\"removeDraftImage(slot.clientId)\"\n >\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n @if (draftComposerAudios().length > 0) {\n <div class=\"flex flex-col gap-1\">\n @for (slot of draftComposerAudios(); track slot.clientId) {\n <div\n class=\"flex items-center justify-between gap-1.5 rounded border border-default/60 dark:border-darker bg-lightest px-1.5 py-1 text-[0.65rem] min-w-0\"\n >\n <span\n class=\"truncate text-on-lightest\"\n [attr.title]=\"slot.name ?? ''\"\n >\n {{\n '@ai-management:chat.attached-audio-label'\n | translate\n | async\n }}:\n {{\n slot.name?.trim() ||\n ('@ai-management:chat.audio-untitled' | translate | async)\n }}\n </span>\n @if (!slot.fileId) {\n <span class=\"text-muted shrink-0\">\u2026</span>\n }\n <button\n type=\"button\"\n class=\"shrink-0 flex h-5 w-5 items-center justify-center rounded bg-default/80 text-[0.75rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"\n ('@ai-management:chat.remove-draft-audio'\n | translate\n | async) ?? ''\n \"\n (click)=\"removeDraftAudio(slot.clientId)\"\n >\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n @if (draftComposerFiles().length > 0) {\n <div class=\"flex flex-col gap-1\">\n @for (slot of draftComposerFiles(); track slot.clientId) {\n <div\n class=\"flex items-center justify-between gap-1.5 rounded border border-default/60 dark:border-darker bg-lightest px-1.5 py-1 text-[0.65rem] min-w-0\"\n >\n <span\n class=\"truncate text-on-lightest\"\n [attr.title]=\"slot.name ?? ''\"\n >\n {{\n '@ai-management:chat.attached-document-label'\n | translate\n | async\n }}:\n {{\n slot.name?.trim() ||\n ('@ai-management:chat.document-untitled'\n | translate\n | async)\n }}\n </span>\n @if (!slot.fileId) {\n <span class=\"text-muted shrink-0\">\u2026</span>\n }\n <button\n type=\"button\"\n class=\"shrink-0 flex h-5 w-5 items-center justify-center rounded bg-default/80 text-[0.75rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\n [disabled]=\"busy() || isComposerSaving()\"\n [attr.aria-label]=\"\n ('@ai-management:chat.remove-draft-document'\n | translate\n | async) ?? ''\n \"\n (click)=\"removeDraftFile(slot.clientId)\"\n >\n \u00D7\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"axm-ai-assist-prompt-box__body flex min-h-0 flex-col\">\n <ax-text-area\n class=\"axm-ai-assist-prompt-box__prompt-input w-full min-h-0\"\n [rows]=\"3\"\n [disabled]=\"busy()\"\n [ngModel]=\"promptDraft()\"\n (ngModelChange)=\"onPromptDraftChange($event)\"\n (keydown)=\"onPromptKeydown($event)\"\n [placeholder]=\"\n placeholder().trim().length > 0\n ? placeholder()\n : (('@ai-management:assist-popup.placeholder'\n | translate\n | async) ?? '')\n \"\n ></ax-text-area>\n </div>\n\n <div\n class=\"axm-ai-assist-prompt-box__footer flex shrink-0 items-center justify-between gap-2\"\n >\n <ax-button\n class=\"axm-ai-assist-prompt-box__menu-trigger\"\n look=\"solid\"\n color=\"primary\"\n type=\"button\"\n [iconOnly]=\"true\"\n [disabled]=\"busy()\"\n [attr.aria-label]=\"\n ('@ai-management:assist-popup.composer-menu-aria'\n | translate\n | async) ?? ''\n \"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus text-sm\" aria-hidden=\"true\"></i>\n </ax-prefix>\n <ax-dropdown-panel #composerMenu>\n <ax-button-item-list class=\"min-w-56\">\n <ax-button-item\n [text]=\"\n ('@ai-management:chat.upload-images' | translate | async) ?? ''\n \"\n [attr.aria-label]=\"\n ('@ai-management:chat.upload-images-aria'\n | translate\n | async) ?? ''\n \"\n (onClick)=\"openImagePicker(); composerMenu.close()\"\n >\n <ax-prefix>\n <i\n class=\"fa-light fa-image size-4 text-center\"\n aria-hidden=\"true\"\n ></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"\n ('@ai-management:chat.upload-audio' | translate | async) ?? ''\n \"\n [attr.aria-label]=\"\n ('@ai-management:chat.upload-audio-aria' | translate | async) ??\n ''\n \"\n (onClick)=\"openAudioPicker(); composerMenu.close()\"\n >\n <ax-prefix>\n <i\n class=\"fa-light fa-microphone size-4 text-center\"\n aria-hidden=\"true\"\n ></i>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item\n [text]=\"\n ('@ai-management:chat.upload-documents' | translate | async) ??\n ''\n \"\n [attr.aria-label]=\"\n ('@ai-management:chat.upload-documents-aria'\n | translate\n | async) ?? ''\n \"\n (onClick)=\"openDocumentPicker(); composerMenu.close()\"\n >\n <ax-prefix>\n <i\n class=\"fa-light fa-paperclip size-4 text-center\"\n aria-hidden=\"true\"\n ></i>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n\n <ax-button\n class=\"axm-ai-assist-prompt-box__send axm-ai-assist-prompt-box__send-gradient\"\n color=\"primary\"\n type=\"button\"\n [disabled]=\"busy() || !canSend()\"\n [text]=\"\n busy()\n ? (('@ai-management:assist-popup.generating' | translate | async) ??\n '')\n : (('@ai-management:assist-popup.generate' | translate | async) ??\n '')\n \"\n (onClick)=\"onSend()\"\n ></ax-button>\n </div>\n </div>\n</div>\n", styles: ["@layer properties;.axm-ai-assist-prompt-box-shell{pointer-events:none;box-sizing:border-box;inset:0;display:flex;max-height:100%;width:100%;flex-direction:column;align-items:center;justify-content:flex-end;padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-right:max(.75rem,env(safe-area-inset-right,0px));padding-bottom:max(.75rem,env(safe-area-inset-bottom,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-ai-assist-prompt-box-shell .overlay-pane{pointer-events:auto;--tw-border-style: none;border-style:none;background-color:transparent;flex:0 0 auto;width:auto!important;max-width:calc(100vw - 1.5rem);min-width:min(480px,100vw - 1.5rem)}.axm-ai-assist-prompt-box{--axm-axm-ai-assist-prompt-chrome-gradient: linear-gradient( 125deg, rgb(var(--ax-sys-color-primary-200)) 0%, rgb(var(--ax-sys-color-primary-400)) 48%, rgb(var(--ax-sys-color-primary-300)) 100% );--axm-axm-ai-assist-prompt-send-gradient: linear-gradient( 90deg, rgb(var(--ax-sys-color-primary-500)), rgb(var(--ax-sys-color-primary-700)) );margin:0;box-sizing:border-box;overflow:hidden;padding:0;max-height:min(78vh,620px);padding:.65rem .7rem .7rem;border-radius:1.35rem;background:var(--axm-axm-ai-assist-prompt-chrome-gradient);box-shadow:0 18px 50px -12px rgba(var(--ax-sys-color-on-surface),.12),0 8px 20px -8px rgba(var(--ax-sys-color-primary-400),.2)}.dark .axm-ai-assist-prompt-box{--axm-axm-ai-assist-prompt-chrome-gradient: linear-gradient( 125deg, rgb(var(--ax-sys-color-primary-600)) 0%, rgb(var(--ax-sys-color-primary-500)) 48%, rgb(var(--ax-sys-color-primary-400)) 100% );box-shadow:0 20px 55px -14px rgba(var(--ax-sys-color-dark),.48),0 8px 24px -8px rgba(var(--ax-sys-color-primary-400),.26)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-title{--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);font-size:.72rem;line-height:1.25;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-surface))}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-title){color:rgb(var(--ax-sys-color-on-lightest-surface))}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-mark{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);width:1.65rem;height:1.65rem;font-size:.75rem;line-height:1;color:rgb(var(--ax-sys-color-on-primary-surface));background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)));box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__sheet{min-height:0px;flex:auto;padding:.65rem .65rem .55rem;border-radius:1rem;background:rgb(var(--ax-sys-color-lightest-surface));border:1px solid rgba(var(--ax-sys-color-neutral-300),.35);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.95)}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__sheet){background:rgb(var(--ax-sys-color-neutral-800));border-color:rgba(var(--ax-sys-color-neutral-500),.4);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.06)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__body{min-height:0px;flex:auto;overflow-y:auto}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input{display:block;min-height:0px;width:100%;--tw-border-style: none !important;border-style:none!important;background-color:transparent!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input:focus-within{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input:focus-within>*{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea{min-height:4.5rem;max-height:min(30vh,240px);font-size:.8125rem;line-height:1.45;padding-block:.55rem;padding-inline:.65rem;border-radius:.65rem;--tw-border-style: none !important;border-style:none!important;background-color:transparent!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:focus,.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:focus-visible,.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:active{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important;outline-offset:0!important}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea){color:rgb(var(--ax-sys-color-on-lightest-surface));background:rgb(var(--ax-sys-color-neutral-900))!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__footer{min-height:0}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;overflow:hidden;border-radius:calc(infinity * 1px)!important;border-color:transparent!important;background-color:transparent!important;background:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.state-disabled,.state-loading,.state-selected),.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.state-disabled,.state-loading,.state-selected){border-color:transparent!important;background-color:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger>button{border-radius:calc(infinity * 1px)!important;--tw-border-style: none !important;border-style:none!important;padding:0!important;width:2.25rem;height:2.25rem;min-width:2.25rem;min-height:2.25rem;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)))!important;box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-disabled>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-loading>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger>button:disabled{opacity:.55;box-shadow:none}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.94)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.88)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;overflow:hidden;border-radius:calc(infinity * 1px)!important;border-color:transparent!important;background-color:transparent!important;background:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.state-disabled,.state-loading,.state-selected),.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.state-disabled,.state-loading,.state-selected){border-color:transparent!important;background-color:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient>button{border-radius:calc(infinity * 1px)!important;--tw-border-style: none !important;border-style:none!important;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);min-height:2.25rem;padding-inline:1rem!important;font-size:.8rem;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:var(--axm-axm-ai-assist-prompt-send-gradient)!important;box-shadow:0 3px 12px rgba(var(--ax-sys-color-secondary-400),.35)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-disabled>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-loading>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient>button:disabled{opacity:.55;box-shadow:none}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.96)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.9)}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
1442
+ ], template: "<div\r\n class=\"axm-ai-assist-prompt-box flex flex-col gap-2.5 min-h-0 w-full\"\r\n [style.max-width.px]=\"contentMaxWidthPx()\"\r\n>\r\n <div\r\n class=\"axm-ai-assist-prompt-box__eyebrow flex items-center justify-between gap-3 shrink-0 px-0.5\"\r\n >\r\n <div\r\n class=\"axm-ai-assist-prompt-box__brand inline-flex min-w-0 items-center gap-2\"\r\n >\r\n <span class=\"axm-ai-assist-prompt-box__brand-mark\" aria-hidden=\"true\">\r\n <i class=\"fa-light fa-sparkles\" aria-hidden=\"true\"></i>\r\n </span>\r\n <span class=\"axm-ai-assist-prompt-box__brand-title truncate\">{{\r\n title()\r\n }}</span>\r\n </div>\r\n <ax-button\r\n class=\"shrink-0 ax-sm\"\r\n look=\"blank\"\r\n color=\"default\"\r\n type=\"button\"\r\n [iconOnly]=\"true\"\r\n [disabled]=\"busy()\"\r\n [attr.aria-label]=\"\r\n ('@general:actions.close.title' | translate | async) ?? ''\r\n \"\r\n (onClick)=\"onCancel()\"\r\n >\r\n <ax-prefix>\r\n <i class=\"fa-light fa-xmark\" aria-hidden=\"true\"></i>\r\n </ax-prefix>\r\n </ax-button>\r\n </div>\r\n\r\n <div class=\"axm-ai-assist-prompt-box__sheet flex min-h-0 flex-col gap-2\">\r\n @if (\r\n draftComposerImages().length > 0 ||\r\n draftComposerAudios().length > 0 ||\r\n draftComposerFiles().length > 0 ||\r\n isComposerSaving()\r\n ) {\r\n <div\r\n class=\"shrink-0 rounded-xl border border-default/45 dark:border-darker bg-lightest/90 p-1.5 flex flex-col gap-1.5\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.composer-attachments-region'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n >\r\n <div\r\n class=\"flex flex-wrap items-center justify-between gap-1.5 text-[0.65rem] text-muted\"\r\n >\r\n <span>\r\n @if (isComposerSaving()) {\r\n {{ '@ai-management:chat.composer-uploading' | translate | async }}\r\n } @else {\r\n @if (draftComposerImages().length > 0) {\r\n <span\r\n >{{ draftComposerImages().length }}\r\n {{\r\n '@ai-management:chat.composer-images-count'\r\n | translate\r\n | async\r\n }}</span\r\n >\r\n }\r\n @if (\r\n draftComposerImages().length > 0 &&\r\n draftComposerAudios().length > 0\r\n ) {\r\n <span class=\"mx-1\">\u00B7</span>\r\n }\r\n @if (draftComposerAudios().length > 0) {\r\n <span\r\n >{{ draftComposerAudios().length }}\r\n {{\r\n '@ai-management:chat.composer-audio-count'\r\n | translate\r\n | async\r\n }}</span\r\n >\r\n }\r\n @if (draftComposerFiles().length > 0) {\r\n @if (\r\n draftComposerImages().length > 0 ||\r\n draftComposerAudios().length > 0\r\n ) {\r\n <span class=\"mx-1\">\u00B7</span>\r\n }\r\n <span\r\n >{{ draftComposerFiles().length }}\r\n {{\r\n '@ai-management:chat.composer-documents-count'\r\n | translate\r\n | async\r\n }}</span\r\n >\r\n }\r\n }\r\n </span>\r\n </div>\r\n @if (draftComposerImages().length > 0) {\r\n <div class=\"flex flex-wrap gap-1.5\">\r\n @for (slot of draftComposerImages(); track slot.clientId) {\r\n <div\r\n class=\"relative h-12 w-12 shrink-0 overflow-hidden rounded-md border border-default/60 dark:border-darker bg-lightest\"\r\n >\r\n <img\r\n [src]=\"slot.previewUrl\"\r\n [alt]=\"slot.name ?? ''\"\r\n class=\"h-full w-full object-cover\"\r\n />\r\n @if (!slot.fileId) {\r\n <span\r\n class=\"absolute inset-0 flex items-center justify-center bg-default/40 text-[0.6rem] font-medium text-on-lightest\"\r\n >\u2026</span\r\n >\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"absolute end-0.5 top-0.5 flex h-4 w-4 items-center justify-center rounded bg-default/80 text-[0.65rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\r\n [disabled]=\"busy() || isComposerSaving()\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.remove-draft-image'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (click)=\"removeDraftImage(slot.clientId)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n @if (draftComposerAudios().length > 0) {\r\n <div class=\"flex flex-col gap-1\">\r\n @for (slot of draftComposerAudios(); track slot.clientId) {\r\n <div\r\n class=\"flex items-center justify-between gap-1.5 rounded border border-default/60 dark:border-darker bg-lightest px-1.5 py-1 text-[0.65rem] min-w-0\"\r\n >\r\n <span\r\n class=\"truncate text-on-lightest\"\r\n [attr.title]=\"slot.name ?? ''\"\r\n >\r\n {{\r\n '@ai-management:chat.attached-audio-label'\r\n | translate\r\n | async\r\n }}:\r\n {{\r\n slot.name?.trim() ||\r\n ('@ai-management:chat.audio-untitled' | translate | async)\r\n }}\r\n </span>\r\n @if (!slot.fileId) {\r\n <span class=\"text-muted shrink-0\">\u2026</span>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"shrink-0 flex h-5 w-5 items-center justify-center rounded bg-default/80 text-[0.75rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\r\n [disabled]=\"busy() || isComposerSaving()\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.remove-draft-audio'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (click)=\"removeDraftAudio(slot.clientId)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n @if (draftComposerFiles().length > 0) {\r\n <div class=\"flex flex-col gap-1\">\r\n @for (slot of draftComposerFiles(); track slot.clientId) {\r\n <div\r\n class=\"flex items-center justify-between gap-1.5 rounded border border-default/60 dark:border-darker bg-lightest px-1.5 py-1 text-[0.65rem] min-w-0\"\r\n >\r\n <span\r\n class=\"truncate text-on-lightest\"\r\n [attr.title]=\"slot.name ?? ''\"\r\n >\r\n {{\r\n '@ai-management:chat.attached-document-label'\r\n | translate\r\n | async\r\n }}:\r\n {{\r\n slot.name?.trim() ||\r\n ('@ai-management:chat.document-untitled'\r\n | translate\r\n | async)\r\n }}\r\n </span>\r\n @if (!slot.fileId) {\r\n <span class=\"text-muted shrink-0\">\u2026</span>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"shrink-0 flex h-5 w-5 items-center justify-center rounded bg-default/80 text-[0.75rem] leading-none text-on-lightest hover:bg-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400\"\r\n [disabled]=\"busy() || isComposerSaving()\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.remove-draft-document'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (click)=\"removeDraftFile(slot.clientId)\"\r\n >\r\n \u00D7\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"axm-ai-assist-prompt-box__body flex min-h-0 flex-col\">\r\n <ax-text-area\r\n class=\"axm-ai-assist-prompt-box__prompt-input w-full min-h-0\"\r\n [rows]=\"3\"\r\n [disabled]=\"busy()\"\r\n [ngModel]=\"promptDraft()\"\r\n (ngModelChange)=\"onPromptDraftChange($event)\"\r\n (keydown)=\"onPromptKeydown($event)\"\r\n [placeholder]=\"\r\n placeholder().trim().length > 0\r\n ? placeholder()\r\n : (('@ai-management:assist-popup.placeholder'\r\n | translate\r\n | async) ?? '')\r\n \"\r\n ></ax-text-area>\r\n </div>\r\n\r\n <div\r\n class=\"axm-ai-assist-prompt-box__footer flex shrink-0 items-center justify-between gap-2\"\r\n >\r\n <ax-button\r\n class=\"axm-ai-assist-prompt-box__menu-trigger\"\r\n look=\"solid\"\r\n color=\"primary\"\r\n type=\"button\"\r\n [iconOnly]=\"true\"\r\n [disabled]=\"busy()\"\r\n [attr.aria-label]=\"\r\n ('@ai-management:assist-popup.composer-menu-aria'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n >\r\n <ax-prefix>\r\n <i class=\"fa-light fa-plus text-sm\" aria-hidden=\"true\"></i>\r\n </ax-prefix>\r\n <ax-dropdown-panel #composerMenu>\r\n <ax-button-item-list class=\"min-w-56\">\r\n <ax-button-item\r\n [text]=\"\r\n ('@ai-management:chat.upload-images' | translate | async) ?? ''\r\n \"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.upload-images-aria'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (onClick)=\"openImagePicker(); composerMenu.close()\"\r\n >\r\n <ax-prefix>\r\n <i\r\n class=\"fa-light fa-image size-4 text-center\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </ax-prefix>\r\n </ax-button-item>\r\n <ax-button-item\r\n [text]=\"\r\n ('@ai-management:chat.upload-audio' | translate | async) ?? ''\r\n \"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.upload-audio-aria' | translate | async) ??\r\n ''\r\n \"\r\n (onClick)=\"openAudioPicker(); composerMenu.close()\"\r\n >\r\n <ax-prefix>\r\n <i\r\n class=\"fa-light fa-microphone size-4 text-center\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </ax-prefix>\r\n </ax-button-item>\r\n <ax-button-item\r\n [text]=\"\r\n ('@ai-management:chat.upload-documents' | translate | async) ??\r\n ''\r\n \"\r\n [attr.aria-label]=\"\r\n ('@ai-management:chat.upload-documents-aria'\r\n | translate\r\n | async) ?? ''\r\n \"\r\n (onClick)=\"openDocumentPicker(); composerMenu.close()\"\r\n >\r\n <ax-prefix>\r\n <i\r\n class=\"fa-light fa-paperclip size-4 text-center\"\r\n aria-hidden=\"true\"\r\n ></i>\r\n </ax-prefix>\r\n </ax-button-item>\r\n </ax-button-item-list>\r\n </ax-dropdown-panel>\r\n </ax-button>\r\n\r\n <ax-button\r\n class=\"axm-ai-assist-prompt-box__send axm-ai-assist-prompt-box__send-gradient\"\r\n color=\"primary\"\r\n type=\"button\"\r\n [disabled]=\"runPhase() === 'stopping' || (runPhase() === 'idle' && !canSend())\"\r\n [text]=\"\r\n runPhase() === 'stopping'\r\n ? (('@ai-management:assist-popup.stopping' | translate | async) ??\r\n '')\r\n : runPhase() === 'running'\r\n ? (('@ai-management:assist-popup.stop' | translate | async) ?? '')\r\n : (('@ai-management:assist-popup.generate' | translate | async) ??\r\n '')\r\n \"\r\n (onClick)=\"onSend()\"\r\n ></ax-button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["@layer properties;.axm-ai-assist-prompt-box-shell{pointer-events:none;box-sizing:border-box;inset:0;display:flex;max-height:100%;width:100%;flex-direction:column;align-items:center;justify-content:flex-end;padding-left:max(.75rem,env(safe-area-inset-left,0px));padding-right:max(.75rem,env(safe-area-inset-right,0px));padding-bottom:max(.75rem,env(safe-area-inset-bottom,0px));padding-top:max(.5rem,env(safe-area-inset-top,0px))}.axm-ai-assist-prompt-box-shell .overlay-pane{pointer-events:auto;--tw-border-style: none;border-style:none;background-color:transparent;flex:0 0 auto;width:auto!important;max-width:calc(100vw - 1.5rem);min-width:min(480px,100vw - 1.5rem)}.axm-ai-assist-prompt-box{--axm-axm-ai-assist-prompt-chrome-gradient: linear-gradient( 125deg, rgb(var(--ax-sys-color-primary-200)) 0%, rgb(var(--ax-sys-color-primary-400)) 48%, rgb(var(--ax-sys-color-primary-300)) 100% );--axm-axm-ai-assist-prompt-send-gradient: linear-gradient( 90deg, rgb(var(--ax-sys-color-primary-500)), rgb(var(--ax-sys-color-primary-700)) );margin:0;box-sizing:border-box;overflow:hidden;padding:0;max-height:min(78vh,620px);padding:.65rem .7rem .7rem;border-radius:1.35rem;background:var(--axm-axm-ai-assist-prompt-chrome-gradient);box-shadow:0 18px 50px -12px rgba(var(--ax-sys-color-on-surface),.12),0 8px 20px -8px rgba(var(--ax-sys-color-primary-400),.2)}.dark .axm-ai-assist-prompt-box{--axm-axm-ai-assist-prompt-chrome-gradient: linear-gradient( 125deg, rgb(var(--ax-sys-color-primary-600)) 0%, rgb(var(--ax-sys-color-primary-500)) 48%, rgb(var(--ax-sys-color-primary-400)) 100% );box-shadow:0 20px 55px -14px rgba(var(--ax-sys-color-dark),.48),0 8px 24px -8px rgba(var(--ax-sys-color-primary-400),.26)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-title{--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);font-size:.72rem;line-height:1.25;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-surface))}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-title){color:rgb(var(--ax-sys-color-on-lightest-surface))}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__brand-mark{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);width:1.65rem;height:1.65rem;font-size:.75rem;line-height:1;color:rgb(var(--ax-sys-color-on-primary-surface));background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)));box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__sheet{min-height:0px;flex:auto;padding:.65rem .65rem .55rem;border-radius:1rem;background:rgb(var(--ax-sys-color-lightest-surface));border:1px solid rgba(var(--ax-sys-color-neutral-300),.35);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.95)}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__sheet){background:rgb(var(--ax-sys-color-neutral-800));border-color:rgba(var(--ax-sys-color-neutral-500),.4);box-shadow:inset 0 1px rgba(var(--ax-sys-color-lightest-surface),.06)}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__body{min-height:0px;flex:auto;overflow-y:auto}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input{display:block;min-height:0px;width:100%;--tw-border-style: none !important;border-style:none!important;background-color:transparent!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input:focus-within{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input:focus-within>*{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea{min-height:4.5rem;max-height:min(30vh,240px);font-size:.8125rem;line-height:1.45;padding-block:.55rem;padding-inline:.65rem;border-radius:.65rem;--tw-border-style: none !important;border-style:none!important;background-color:transparent!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:focus,.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:focus-visible,.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea:active{--tw-border-style: none !important;border-style:none!important;--tw-shadow: 0 0 #0000 !important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important;--tw-outline-style: none !important;outline-style:none!important;outline-offset:0!important}.dark :is(.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__prompt-input textarea){color:rgb(var(--ax-sys-color-on-lightest-surface));background:rgb(var(--ax-sys-color-neutral-900))!important}.axm-ai-assist-prompt-box .axm-ai-assist-prompt-box__footer{min-height:0}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;overflow:hidden;border-radius:calc(infinity * 1px)!important;border-color:transparent!important;background-color:transparent!important;background:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.state-disabled,.state-loading,.state-selected),.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.state-disabled,.state-loading,.state-selected){border-color:transparent!important;background-color:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger>button{border-radius:calc(infinity * 1px)!important;--tw-border-style: none !important;border-style:none!important;padding:0!important;width:2.25rem;height:2.25rem;min-width:2.25rem;min-height:2.25rem;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:linear-gradient(145deg,rgb(var(--ax-sys-color-primary-500)),rgb(var(--ax-sys-color-primary-700)))!important;box-shadow:0 2px 8px rgba(var(--ax-sys-color-primary-500),.35)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-disabled>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger.ax-state-loading>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger>button:disabled{opacity:.55;box-shadow:none}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:hover:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.94)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__menu-trigger:active:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.88)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient{--ax-comp-button-normal-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-hover-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-pressed-bg-color: 0, 0, 0, 0 !important;--ax-comp-button-border-width: 0 !important;overflow:hidden;border-radius:calc(infinity * 1px)!important;border-color:transparent!important;background-color:transparent!important;background:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.state-disabled,.state-loading,.state-selected),.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.state-disabled,.state-loading,.state-selected){border-color:transparent!important;background-color:transparent!important}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient>button{border-radius:calc(infinity * 1px)!important;--tw-border-style: none !important;border-style:none!important;--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);min-height:2.25rem;padding-inline:1rem!important;font-size:.8rem;letter-spacing:.01em;color:rgb(var(--ax-sys-color-on-primary-surface))!important;background:var(--axm-axm-ai-assist-prompt-send-gradient)!important;box-shadow:0 3px 12px rgba(var(--ax-sys-color-secondary-400),.35)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-disabled>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient.ax-state-loading>button,.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient>button:disabled{opacity:.55;box-shadow:none}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:hover:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.96)}.axm-ai-assist-prompt-box ax-button.axm-ai-assist-prompt-box__send-gradient:active:not(.state-disabled,.state-loading,.state-selected)>button{filter:brightness(.9)}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
1350
1443
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], initialPrompt: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialPrompt", required: false }] }], contentMaxWidthPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentMaxWidthPx", required: false }] }], initialAssistId: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialAssistId", required: false }] }], runPrompt: [{ type: i0.Input, args: [{ isSignal: true, alias: "runPrompt", required: true }] }], requestClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestClose", required: true }] }] } });
1351
1444
 
1352
1445
  //#endregion
@@ -1363,6 +1456,7 @@ class AXMAiAssistPromptBoxService {
1363
1456
  this.overlayRef = null;
1364
1457
  this.pendingResolve = null;
1365
1458
  this.settled = false;
1459
+ this.overlaySessionId = 0;
1366
1460
  }
1367
1461
  //#endregion
1368
1462
  //#region ---- Public Methods ----
@@ -1376,11 +1470,15 @@ class AXMAiAssistPromptBoxService {
1376
1470
  superseded(null);
1377
1471
  }
1378
1472
  this.disposeOverlayOnly();
1473
+ const sessionId = ++this.overlaySessionId;
1379
1474
  return new Promise((resolve) => {
1380
1475
  this.pendingResolve = resolve;
1381
1476
  this.settled = false;
1382
1477
  const requestClose = (result) => {
1383
- this.settle(result);
1478
+ if (this.overlaySessionId !== sessionId) {
1479
+ return;
1480
+ }
1481
+ this.settle(result, sessionId);
1384
1482
  this.overlayRef?.dispose();
1385
1483
  };
1386
1484
  void this.overlayService
@@ -1394,8 +1492,8 @@ class AXMAiAssistPromptBoxService {
1394
1492
  background: false,
1395
1493
  closeOnClick: false,
1396
1494
  },
1397
- closeOnEscape: true,
1398
- closeOnOutsideClick: true,
1495
+ closeOnEscape: false,
1496
+ closeOnOutsideClick: false,
1399
1497
  inputs: {
1400
1498
  title: options.title,
1401
1499
  placeholder: options.placeholder ?? '',
@@ -1405,23 +1503,36 @@ class AXMAiAssistPromptBoxService {
1405
1503
  requestClose,
1406
1504
  },
1407
1505
  onDispose: () => {
1506
+ if (this.overlaySessionId !== sessionId) {
1507
+ return;
1508
+ }
1408
1509
  this.overlayRef = null;
1409
1510
  if (!this.settled && this.pendingResolve) {
1410
- this.settle(null);
1511
+ this.settle(null, sessionId);
1411
1512
  }
1412
1513
  },
1413
1514
  })
1414
1515
  .then((ref) => {
1516
+ if (this.overlaySessionId !== sessionId) {
1517
+ ref.dispose();
1518
+ return;
1519
+ }
1415
1520
  this.overlayRef = ref;
1416
1521
  })
1417
1522
  .catch(() => {
1418
- this.settle(null);
1523
+ if (this.overlaySessionId !== sessionId) {
1524
+ return;
1525
+ }
1526
+ this.settle(null, sessionId);
1419
1527
  });
1420
1528
  });
1421
1529
  }
1422
1530
  //#endregion
1423
1531
  //#region ---- Utility Methods ----
1424
- settle(result) {
1532
+ settle(result, sessionId) {
1533
+ if (sessionId != null && this.overlaySessionId !== sessionId) {
1534
+ return;
1535
+ }
1425
1536
  if (this.settled) {
1426
1537
  return;
1427
1538
  }
@@ -2141,7 +2252,16 @@ async function runStructuredOutputPipeline(params) {
2141
2252
  let prevFailurePhase;
2142
2253
  const perAttemptUsage = [];
2143
2254
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
2144
- const result = await params.executeRun(messages);
2255
+ assertAiAssistNotAborted(params.abortSignal);
2256
+ let result;
2257
+ try {
2258
+ result = await params.executeRun(messages);
2259
+ }
2260
+ catch (err) {
2261
+ assertAiAssistNotAborted(params.abortSignal);
2262
+ throw err;
2263
+ }
2264
+ assertAiAssistNotAborted(params.abortSignal);
2145
2265
  mergedUsage = mergeEngineUsageTotals(mergedUsage, result.usageTotals);
2146
2266
  if (result.lastProviderResult !== undefined) {
2147
2267
  lastProvider = result.lastProviderResult;
@@ -2168,6 +2288,7 @@ async function runStructuredOutputPipeline(params) {
2168
2288
  code: 'duplicate_assistant_output',
2169
2289
  });
2170
2290
  }
2291
+ assertAiAssistNotAborted(params.abortSignal);
2171
2292
  const validation = await validateAgainstContract({
2172
2293
  contract: params.contract,
2173
2294
  assistantPlainText: structuredParts.combined,
@@ -2175,6 +2296,7 @@ async function runStructuredOutputPipeline(params) {
2175
2296
  structuredValidator: params.structuredValidator,
2176
2297
  commandExecutor: params.commandExecutor,
2177
2298
  });
2299
+ assertAiAssistNotAborted(params.abortSignal);
2178
2300
  if (validation.ok) {
2179
2301
  const structuredRunRaw = {
2180
2302
  kind: 'structured-output',
@@ -2205,10 +2327,12 @@ async function runStructuredOutputPipeline(params) {
2205
2327
  code: 'validation_exhausted',
2206
2328
  });
2207
2329
  }
2330
+ assertAiAssistNotAborted(params.abortSignal);
2208
2331
  messages = [
2209
2332
  ...result.messages,
2210
2333
  axpAiChatTextMessage('user', buildStructuredOutputRetryUserText(firstError?.message ?? 'Validation failed.', schemaSummary, firstError?.phase ?? 'parse')),
2211
2334
  ];
2335
+ assertAiAssistNotAborted(params.abortSignal);
2212
2336
  }
2213
2337
  throw new AXPAiStructuredOutputError({
2214
2338
  message: 'Structured output validation failed (unexpected end of retry loop).',
@@ -2292,9 +2416,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2292
2416
 
2293
2417
  //#region ---- Imports ----
2294
2418
  //#endregion
2295
- //#region ---- Assist prompt run loading dialog ----
2296
- const AI_ASSIST_RUN_LOADING_DIALOG_CLOSE_DELAY_MS = 200;
2297
- //#endregion
2298
2419
  //#region ---- Assist run helpers ----
2299
2420
  function mergePlatformRuntimeContext(base, notes) {
2300
2421
  if (!notes || Object.keys(notes).length === 0) {
@@ -2374,7 +2495,6 @@ class AXPAiManagerService extends AXPAiAssistService {
2374
2495
  this.runtimeContextBuilder = inject(AXPAiPlatformRuntimeContextBuilder);
2375
2496
  this.assistPromptBox = inject(AXMAiAssistPromptBoxService);
2376
2497
  this.localeId = inject(LOCALE_ID);
2377
- this.loadingDialog = inject(AXLoadingDialogService);
2378
2498
  this.assistData = this.entityService
2379
2499
  .withEntity(RootConfig.module.name, RootConfig.entities.assist.name)
2380
2500
  .data();
@@ -2389,11 +2509,7 @@ class AXPAiManagerService extends AXPAiAssistService {
2389
2509
  */
2390
2510
  async getEffectiveAssist() {
2391
2511
  const raw = await this.settings.get(AXPAiManagementSettings.DefaultAssistId);
2392
- const assistId = typeof raw === 'string'
2393
- ? raw.trim()
2394
- : raw?.value != null
2395
- ? String(raw.value).trim()
2396
- : '';
2512
+ const assistId = readStoredAssistSettingId(raw);
2397
2513
  if (assistId) {
2398
2514
  const byId = await this.assistData.byKey(assistId);
2399
2515
  if (byId) {
@@ -2495,10 +2611,12 @@ class AXPAiManagerService extends AXPAiAssistService {
2495
2611
  }
2496
2612
  /** @inheritdoc */
2497
2613
  async run(input) {
2614
+ assertAiAssistNotAborted(input.abortSignal);
2498
2615
  const baseCtx = await this.runtimeContextBuilder.build();
2499
2616
  const platformRuntimeContext = mergePlatformRuntimeContext(baseCtx, input.platformRuntimeNotes ?? null);
2500
2617
  const assistId = input.assistId?.trim();
2501
2618
  const assistRow = await this.getAssistForChat(assistId);
2619
+ assertAiAssistNotAborted(input.abortSignal);
2502
2620
  const inputContract = outputContractFromAssistRunInput(input);
2503
2621
  const effectiveOutputContract = await this.outputContractResolve.resolveEffective({
2504
2622
  input: inputContract,
@@ -2516,9 +2634,11 @@ class AXPAiManagerService extends AXPAiAssistService {
2516
2634
  ...(input.maxSteps !== undefined ? { maxSteps: input.maxSteps } : {}),
2517
2635
  ...(input.temperature !== undefined ? { temperature: input.temperature } : {}),
2518
2636
  maxTokens: effectiveMaxTokens,
2637
+ ...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),
2519
2638
  };
2520
2639
  if (!usesStructuredPipeline) {
2521
2640
  const result = await this.runEngine({ ...runOptions, messages });
2641
+ assertAiAssistNotAborted(input.abortSignal);
2522
2642
  const text = extractLastAssistantPlainText(result.messages);
2523
2643
  return { success: true, outputKind: effectiveOutputContract.kind,
2524
2644
  text,
@@ -2537,6 +2657,7 @@ class AXPAiManagerService extends AXPAiAssistService {
2537
2657
  retryOnInvalidStructure,
2538
2658
  structuredValidator: input.structuredValidator,
2539
2659
  structuredOutputSchemaSummary: input.structuredOutputSchemaSummary,
2660
+ abortSignal: input.abortSignal,
2540
2661
  });
2541
2662
  return {
2542
2663
  success: pipelineResult.success,
@@ -2551,55 +2672,26 @@ class AXPAiManagerService extends AXPAiAssistService {
2551
2672
  }
2552
2673
  /** @inheritdoc */
2553
2674
  async show(options) {
2554
- const runLoadingSpec = options.runLoadingDialog;
2555
- const data = await this.assistPromptBox.open(options, async (payload) => {
2556
- let progressDialog;
2557
- if (runLoadingSpec) {
2558
- progressDialog = this.loadingDialog.show({
2559
- title: runLoadingSpec.title,
2560
- mode: 'indeterminate',
2561
- progressColor: 'primary',
2562
- text: runLoadingSpec.text,
2563
- });
2564
- }
2565
- try {
2566
- return await this.run({
2567
- prompt: payload.prompt,
2568
- userMediaAttachments: payload.userMediaAttachments.length > 0 ? payload.userMediaAttachments : undefined,
2569
- context: options.context,
2570
- assistId: payload.assistId,
2571
- maxSteps: options.maxSteps,
2572
- temperature: options.temperature,
2573
- maxTokens: options.maxTokens,
2574
- outputContract: options.outputContract,
2575
- expectStructuredOutput: options.expectStructuredOutput,
2576
- structuredOutputInstruction: options.structuredOutputInstruction,
2577
- platformRuntimeNotes: options.platformRuntimeNotes,
2578
- maxStructuredRetries: options.maxStructuredRetries,
2579
- structuredValidator: options.structuredValidator,
2580
- retryOnInvalidStructure: options.retryOnInvalidStructure,
2581
- structuredOutputSchemaSummary: options.structuredOutputSchemaSummary,
2582
- structuredOutputMaxTokens: options.structuredOutputMaxTokens,
2583
- });
2584
- }
2585
- catch (err) {
2586
- if (progressDialog !== undefined) {
2587
- try {
2588
- progressDialog.setProgressColor('danger');
2589
- progressDialog.setProgressText(err instanceof Error ? err.message : String(err));
2590
- }
2591
- catch {
2592
- // Ignore dialog update failures.
2593
- }
2594
- }
2595
- throw err;
2596
- }
2597
- finally {
2598
- if (progressDialog !== undefined) {
2599
- const dlg = progressDialog;
2600
- setTimeout(() => dlg.close(), AI_ASSIST_RUN_LOADING_DIALOG_CLOSE_DELAY_MS);
2601
- }
2602
- }
2675
+ const data = await this.assistPromptBox.open(options, async (payload, execution) => {
2676
+ return await this.run({
2677
+ prompt: payload.prompt,
2678
+ userMediaAttachments: payload.userMediaAttachments.length > 0 ? payload.userMediaAttachments : undefined,
2679
+ context: options.context,
2680
+ assistId: payload.assistId,
2681
+ maxSteps: options.maxSteps,
2682
+ temperature: options.temperature,
2683
+ maxTokens: options.maxTokens,
2684
+ outputContract: options.outputContract,
2685
+ expectStructuredOutput: options.expectStructuredOutput,
2686
+ structuredOutputInstruction: options.structuredOutputInstruction,
2687
+ platformRuntimeNotes: options.platformRuntimeNotes,
2688
+ maxStructuredRetries: options.maxStructuredRetries,
2689
+ structuredValidator: options.structuredValidator,
2690
+ retryOnInvalidStructure: options.retryOnInvalidStructure,
2691
+ structuredOutputSchemaSummary: options.structuredOutputSchemaSummary,
2692
+ structuredOutputMaxTokens: options.structuredOutputMaxTokens,
2693
+ abortSignal: execution.abortSignal,
2694
+ });
2603
2695
  });
2604
2696
  return data ?? null;
2605
2697
  }
@@ -2610,6 +2702,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2610
2702
  type: Injectable,
2611
2703
  args: [{ providedIn: 'root' }]
2612
2704
  }] });
2705
+ /** Lookup settings persist an id string, or `{ id }` / `{ value }` before the widget transform. */
2706
+ function readStoredAssistSettingId(raw) {
2707
+ if (typeof raw === 'string') {
2708
+ return raw.trim();
2709
+ }
2710
+ if (raw != null && typeof raw === 'object') {
2711
+ const record = raw;
2712
+ const value = record['id'] ?? record['value'];
2713
+ if (typeof value === 'string') {
2714
+ return value.trim();
2715
+ }
2716
+ }
2717
+ return '';
2718
+ }
2613
2719
 
2614
2720
  //#region ---- Imports ----
2615
2721
  //#endregion
@@ -2876,11 +2982,6 @@ class AXMAiManagementModule {
2876
2982
  multi: true,
2877
2983
  useFactory: routesFactory,
2878
2984
  },
2879
- {
2880
- provide: AXP_MODULE_MANIFEST_PROVIDER,
2881
- useValue: AiManagementManifest,
2882
- multi: true,
2883
- },
2884
2985
  {
2885
2986
  provide: AXP_PERMISSION_DEFINITION_PROVIDER,
2886
2987
  useClass: AXMPermissionDefinitionProvider,
@@ -2917,7 +3018,7 @@ class AXMAiManagementModule {
2917
3018
  },
2918
3019
  {
2919
3020
  key: 'AiManagement:ListAiQueryRegistryCatalog',
2920
- loader: () => import('./acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BX0uU1YX.mjs').then((c) => c.AXMListAiQueryRegistryCatalogQuery),
3021
+ loader: () => import('./acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BxL3pxzj.mjs').then((c) => c.AXMListAiQueryRegistryCatalogQuery),
2921
3022
  },
2922
3023
  ]),
2923
3024
  {
@@ -2957,11 +3058,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2957
3058
  multi: true,
2958
3059
  useFactory: routesFactory,
2959
3060
  },
2960
- {
2961
- provide: AXP_MODULE_MANIFEST_PROVIDER,
2962
- useValue: AiManagementManifest,
2963
- multi: true,
2964
- },
2965
3061
  {
2966
3062
  provide: AXP_PERMISSION_DEFINITION_PROVIDER,
2967
3063
  useClass: AXMPermissionDefinitionProvider,
@@ -2998,7 +3094,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2998
3094
  },
2999
3095
  {
3000
3096
  key: 'AiManagement:ListAiQueryRegistryCatalog',
3001
- loader: () => import('./acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BX0uU1YX.mjs').then((c) => c.AXMListAiQueryRegistryCatalogQuery),
3097
+ loader: () => import('./acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BxL3pxzj.mjs').then((c) => c.AXMListAiQueryRegistryCatalogQuery),
3002
3098
  },
3003
3099
  ]),
3004
3100
  {
@@ -3267,7 +3363,7 @@ function getAiChatCommandLlmParametersOverride(commandName) {
3267
3363
  properties: {
3268
3364
  model: {
3269
3365
  type: 'string',
3270
- description: 'Catalog AiModel row id for text-to-speech (purpose tts). Pass on the command or rely on agent commandIds options.model; mock default is OpenRouter google/gemini-3.1-flash-tts-preview.',
3366
+ description: 'Catalog AiModel row id for text-to-speech (purpose tts). Pass on the command or rely on agent commandIds options.model; mock default is OpenRouter x-ai/grok-voice-tts-1.0.',
3271
3367
  },
3272
3368
  text: {
3273
3369
  type: 'string',
@@ -3275,7 +3371,7 @@ function getAiChatCommandLlmParametersOverride(commandName) {
3275
3371
  },
3276
3372
  voice: {
3277
3373
  type: 'string',
3278
- description: 'Optional voice. Gemini default row: Zephyr, Puck, Charon, Kore, Fenrir, Leda, Orus, Aoede. Omit to use options.voice or Zephyr.',
3374
+ description: 'Optional voice. Grok Voice default row: ara, eve, rex, sal, leo (alloy maps to ara). Gemini TTS: Zephyr, Puck, Charon, Kore, Fenrir, Leda, Orus, Aoede.',
3279
3375
  },
3280
3376
  responseFormat: {
3281
3377
  type: 'string',
@@ -3284,6 +3380,74 @@ function getAiChatCommandLlmParametersOverride(commandName) {
3284
3380
  },
3285
3381
  required: ['text'],
3286
3382
  };
3383
+ case AIMANAGEMENT_RENDER_CHAT_CHART_COMMAND_KEY:
3384
+ return {
3385
+ type: 'object',
3386
+ properties: {
3387
+ kind: {
3388
+ type: 'string',
3389
+ enum: ['bar', 'line', 'donut', 'gauge', 'funnel', 'heatmap'],
3390
+ description: 'Chart kind. Bar for categorical counts, line for trends, donut for part-to-whole, gauge for one KPI, funnel for stages, heatmap for a matrix.',
3391
+ },
3392
+ title: { type: 'string', description: 'Optional chart title.' },
3393
+ xAxisLabel: { type: 'string', description: 'Optional X-axis caption.' },
3394
+ yAxisLabel: { type: 'string', description: 'Optional Y-axis caption.' },
3395
+ entity: {
3396
+ type: 'string',
3397
+ description: 'Module.Entity for stored rows. When set, this command runs one storage aggregate and ignores items. Do not call Entity:Query:Default first.',
3398
+ },
3399
+ filter: {
3400
+ description: 'Optional AXPQueryRequest.filter JSON applied to the aggregate.',
3401
+ },
3402
+ groupBy: {
3403
+ type: 'array',
3404
+ items: { type: 'string' },
3405
+ description: 'Field paths from the entity schema (source of x / series). Empty array is allowed for gauge.',
3406
+ },
3407
+ measures: {
3408
+ type: 'array',
3409
+ description: 'Aggregate measures. Always set alias. Each item: { reducer, field?, alias? }. First alias is y unless yField is set.',
3410
+ items: {
3411
+ type: 'object',
3412
+ properties: {
3413
+ reducer: { type: 'string', enum: ['count', 'sum', 'min', 'max', 'avg'] },
3414
+ field: { type: 'string' },
3415
+ alias: { type: 'string' },
3416
+ },
3417
+ },
3418
+ },
3419
+ xField: {
3420
+ type: 'string',
3421
+ description: 'Aggregate result column for x. Defaults to the first groupBy path.',
3422
+ },
3423
+ yField: {
3424
+ type: 'string',
3425
+ description: 'Aggregate result column for y. Defaults to the first measure alias.',
3426
+ },
3427
+ seriesField: {
3428
+ type: 'string',
3429
+ description: 'Optional line-series column. Defaults to the second groupBy path when kind is line.',
3430
+ },
3431
+ valueField: {
3432
+ type: 'string',
3433
+ description: 'Heatmap numeric column. Defaults to the first measure alias.',
3434
+ },
3435
+ items: {
3436
+ type: 'array',
3437
+ description: 'Escape hatch when numbers are already in chat (no entity). Ignored when entity is set. Bar/donut/funnel: { x, y }. Line: { x, y, series? }. Heatmap: { x, y, value }. Gauge: one { y } or { value }.',
3438
+ items: {
3439
+ type: 'object',
3440
+ properties: {
3441
+ x: { description: 'Category or X value.' },
3442
+ y: { description: 'Numeric Y for bar/line/donut/funnel/gauge; category for heatmap.' },
3443
+ value: { description: 'Numeric intensity for heatmap, or gauge fallback.' },
3444
+ series: { type: 'string', description: 'Optional line-series name.' },
3445
+ },
3446
+ },
3447
+ },
3448
+ },
3449
+ required: ['kind'],
3450
+ };
3287
3451
  default:
3288
3452
  return null;
3289
3453
  }
@@ -3613,5 +3777,5 @@ function modelItemSupportsChatCatalogPurpose(m, purpose) {
3613
3777
  * Generated bundle index. Do not edit.
3614
3778
  */
3615
3779
 
3616
- export { AI_CHAT_ATTACHMENT_CATEGORY, AI_CHAT_ATTACHMENT_REF_TYPE, AI_CHAT_GENERATED_IMAGE_REF_TYPE, AI_CHAT_GENERATED_SPEECH_REF_TYPE, AI_CHAT_TTS_PCM_SAMPLE_RATE, AI_GENERATED_IMAGE_MAX_REMOTE_URL_IN_TOOL, AXMAiAssistPromptBoxComponent, AXMAiAssistPromptBoxService, AXMAiManagementMenuProvider, AXMAiManagementModule, AXMPermissionDefinitionProvider, AXPAiAssistChatModelCatalogService, AXPAiAssistDefaultMaxStructuredRetries, AXPAiAssistDefaultStructuredMaxTokens, AXPAiAssistService, AXPAiChatToolRunContextService, AXPAiDefaultModelPickerService, AXPAiEngine, AXPAiManagerService, AXPAiOutputContractResolveService, AXPAiPlatformRuntimeContextBuilder, AXPAiStructuredOutputError, AiManagementManifest, axpAiAssistInitialMessagesToTranscript, axpAiAssistStarterPromptLabels, axpAiAssistStarterPromptTexts, axpAiChatMessageIsDelegatedReflectionExcluded, axpAiChatToolOrAgentResultBodyJson, axpAiChatToolResultBodyJson, axpAiChatUserMessage, axpAiDelegatedAgentOutcomeResponsesPlainText, axpAiDelegatedAgentPromptPreview, axpAiDelegatedAgentResultSegments, axpAiStripAssistInitialHtmlToPlain, axpBuildDelegatedAgentRunInputSnapshot, axpSanitizeLastProviderPayloadForPersistence, axpStripEphemeralStreamChunksFromProviderRaw, blobOrFileFromImageResult, buildStructuredOutputRetryUserText, createBrowserPlayableTtsBlobUrl, extractLastAssistantStructuredParts, getAiChatCommandLlmParametersOverride, isRawPcmMimeType, loadAssistPermissionRows, persistAiChatAttachmentImage, persistAiGeneratedImage, persistAiGeneratedSpeech, prepareTtsBytesForBrowserPlayback, validateAgainstContract, validateJsonSchemaMini, validateStructuredAssistantResponse, wrapPcm16LeInWav };
3780
+ export { AI_CHAT_ATTACHMENT_CATEGORY, AI_CHAT_ATTACHMENT_REF_TYPE, AI_CHAT_GENERATED_IMAGE_REF_TYPE, AI_CHAT_GENERATED_SPEECH_REF_TYPE, AI_CHAT_TTS_PCM_SAMPLE_RATE, AI_GENERATED_IMAGE_MAX_REMOTE_URL_IN_TOOL, AXMAiAssistPromptBoxComponent, AXMAiAssistPromptBoxService, AXMAiManagementMenuProvider, AXMAiManagementModule, AXMPermissionDefinitionProvider, AXPAiAssistChatModelCatalogService, AXPAiAssistDefaultMaxStructuredRetries, AXPAiAssistDefaultStructuredMaxTokens, AXPAiAssistService, AXPAiChatToolRunContextService, AXPAiDefaultModelPickerService, AXPAiEngine, AXPAiManagerService, AXPAiOutputContractResolveService, AXPAiPlatformRuntimeContextBuilder, AXPAiStructuredOutputError, axpAiAssistInitialMessagesToTranscript, axpAiAssistStarterPromptLabels, axpAiAssistStarterPromptTexts, axpAiChatMessageIsDelegatedReflectionExcluded, axpAiChatToolOrAgentResultBodyJson, axpAiChatToolResultBodyJson, axpAiChatUserMessage, axpAiDelegatedAgentOutcomeResponsesPlainText, axpAiDelegatedAgentPromptPreview, axpAiDelegatedAgentResultSegments, axpAiStripAssistInitialHtmlToPlain, axpBuildDelegatedAgentRunInputSnapshot, axpSanitizeLastProviderPayloadForPersistence, axpStripEphemeralStreamChunksFromProviderRaw, blobOrFileFromImageResult, buildStructuredOutputRetryUserText, createBrowserPlayableTtsBlobUrl, extractLastAssistantStructuredParts, getAiChatCommandLlmParametersOverride, isRawPcmMimeType, loadAssistPermissionRows, persistAiChatAttachmentImage, persistAiGeneratedImage, persistAiGeneratedSpeech, prepareTtsBytesForBrowserPlayback, provideAiManagementGeminiSettings, validateAgainstContract, validateJsonSchemaMini, validateStructuredAssistantResponse, wrapPcm16LeInWav };
3617
3781
  //# sourceMappingURL=acorex-platform-module-ai-management-client.mjs.map