@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.
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-agent.mjs +30 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-agent.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-assist.mjs +16 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-assist.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-mcp-server.mjs +30 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-mcp-server.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-model.mjs +52 -15
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-model.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-open-ai-endpoint.mjs +30 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-open-ai-endpoint.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-rule.mjs +30 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-rule.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-run-log.mjs +430 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-run-log.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-skill.mjs +30 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entities-skill.mjs.map +1 -1
- 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
- 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
- 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
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-agent.entity-Dj7dZRjE.mjs.map +1 -0
- 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
- 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
- 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
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-mcp-server.entity-BVI_7IhH.mjs.map +1 -0
- 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
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-model.entity-Xd45s9xE.mjs.map +1 -0
- 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
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-open-ai-endpoint.entity-CWsUMad_.mjs.map +1 -0
- 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
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-rule.entity-Z6wYZrFU.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-run-log.entity-B2PG0QN0.mjs +343 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-run-log.entity-B2PG0QN0.mjs.map +1 -0
- 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
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-skill.entity-sNsPtjnT.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog.mjs +1 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts.mjs +598 -526
- package/fesm2022/acorex-platform-module-ai-management-client-contracts.mjs.map +1 -1
- 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
- package/fesm2022/acorex-platform-module-ai-management-client-list-ai-query-registry-catalog.query-BxL3pxzj.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-ai-management-client-local-entities.mjs +1 -0
- package/fesm2022/acorex-platform-module-ai-management-client-local-entities.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-ai-management-client.mjs +281 -117
- package/fesm2022/acorex-platform-module-ai-management-client.mjs.map +1 -1
- package/package.json +5 -1
- package/types/acorex-platform-module-ai-management-client-contracts-entities-run-log.d.ts +5 -0
- package/types/acorex-platform-module-ai-management-client-contracts.d.ts +149 -85
- package/types/acorex-platform-module-ai-management-client.d.ts +27 -19
- 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
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-agent.entity-C75X-uZh.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-mcp-server.entity-UxFvQ92v.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-model.entity-DEdFUAPx.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-open-ai-endpoint.entity-CygH9dU_.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-rule.entity-Ddul_n4_.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-ai-management-client-contracts-entity-catalog-skill.entity-CeMnKpRg.mjs.map +0 -1
- 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,
|
|
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,
|
|
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 {
|
|
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 {
|
|
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 =
|
|
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.
|
|
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.
|
|
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.
|
|
971
|
+
if (this.runPhase() !== 'idle') {
|
|
898
972
|
return;
|
|
899
973
|
}
|
|
900
974
|
this.onCancel();
|
|
901
975
|
}
|
|
902
976
|
/**
|
|
903
|
-
*
|
|
977
|
+
* Idle: close. Running: Stop (stay open). Stopping: ignore.
|
|
904
978
|
*/
|
|
905
979
|
onDocumentEscape() {
|
|
906
|
-
if (!isPlatformBrowser(this.platformId)
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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:
|
|
1398
|
-
closeOnOutsideClick:
|
|
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.
|
|
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
|
-
|
|
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 =
|
|
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
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
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-
|
|
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-
|
|
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
|
|
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.
|
|
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,
|
|
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
|