@acorex-platform/extension-ai-entity-client 0.0.37 → 0.0.46
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.
|
@@ -1,243 +1,132 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, Injectable, NgModule } from '@angular/core';
|
|
3
|
-
import { AXPAiManagerService, AXMAiManagementModule } from '@acorex-platform/module-ai-management-client';
|
|
4
|
-
import { actionExists, ensureListActions, AXPEntityDefinitionRegistryService, AXP_ENTITY_MODIFIER } from '@acorex-platform/framework-client/layout/entity';
|
|
5
3
|
import { provideCommandSetups } from '@acorex-platform/framework-client/runtime';
|
|
6
|
-
import { AXPEntityCommandScope } from '@acorex-platform/framework-shared/entity';
|
|
7
|
-
import { AXPSystemActionType } from '@acorex-platform/framework-shared/core';
|
|
8
4
|
import { AXToastService } from '@acorex/components/toast';
|
|
9
5
|
import { AXTranslationService } from '@acorex/core/translation';
|
|
6
|
+
import { AXPEntityDefinitionRegistryService, ensureListActions, actionExists } from '@acorex-platform/framework-client/layout/entity';
|
|
7
|
+
import { AXMContextualAssistLauncherService, AXM_CONTEXTUAL_ASSIST_ACTION_ENTITY_RECORD, AXM_CONTEXTUAL_ASSIST_KIND_ENTITY_RECORD } from '@acorex-platform/extension-ai-conversation-client';
|
|
8
|
+
import { normalizeAXPQueryViewColumns, AXPEntityCommandScope } from '@acorex-platform/framework-shared/entity';
|
|
9
|
+
import { getSmart, AXPSystemActionType } from '@acorex-platform/framework-shared/core';
|
|
10
|
+
import { axmShouldSkipContextualAssistKey, axmSanitizeContextualAssistValue } from '@acorex-platform/module-conversation-client/contracts';
|
|
10
11
|
|
|
11
|
-
//#region
|
|
12
|
+
//#region ----- Command & action keys -----
|
|
12
13
|
/** Runtime command key registered via {@link provideCommandSetups}. */
|
|
13
14
|
const AXE_AI_ENTITY_ASSIST_COMMAND = 'AiEntity:Assist';
|
|
14
|
-
/**
|
|
15
|
-
const AXE_AI_ENTITY_ASSIST_ACTION =
|
|
16
|
-
typeLevel: 'ai-entity-assist-type-level',
|
|
17
|
-
selected: 'ai-entity-assist-selected',
|
|
18
|
-
individual: 'ai-entity-assist-individual',
|
|
19
|
-
};
|
|
15
|
+
/** Individual row action name (resolved to {@link AXE_AI_ENTITY_ASSIST_COMMAND}). */
|
|
16
|
+
const AXE_AI_ENTITY_ASSIST_ACTION = 'ai-entity-assist-individual';
|
|
20
17
|
//#endregion
|
|
21
18
|
|
|
22
|
-
//#region
|
|
19
|
+
//#region ----- Imports -----
|
|
23
20
|
//#endregion
|
|
24
|
-
//#region
|
|
25
|
-
const
|
|
26
|
-
/** Scopes injected on master list actions. */
|
|
27
|
-
const SCOPED_ACTIONS = [
|
|
28
|
-
{
|
|
29
|
-
scope: AXPEntityCommandScope.TypeLevel,
|
|
30
|
-
commandName: AXE_AI_ENTITY_ASSIST_ACTION.typeLevel,
|
|
31
|
-
titleKey: '@extensions-ai-entity:actions.assist.type-level.title',
|
|
32
|
-
priority: 'secondary',
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
scope: AXPEntityCommandScope.Selected,
|
|
36
|
-
commandName: AXE_AI_ENTITY_ASSIST_ACTION.selected,
|
|
37
|
-
titleKey: '@extensions-ai-entity:actions.assist.selected.title',
|
|
38
|
-
priority: 'secondary',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
scope: AXPEntityCommandScope.Individual,
|
|
42
|
-
commandName: AXE_AI_ENTITY_ASSIST_ACTION.individual,
|
|
43
|
-
titleKey: '@extensions-ai-entity:actions.assist.individual.title',
|
|
44
|
-
priority: 'none',
|
|
45
|
-
},
|
|
46
|
-
];
|
|
21
|
+
//#region ----- Constants -----
|
|
22
|
+
const MAX_COLUMNS = 24;
|
|
47
23
|
//#endregion
|
|
48
|
-
//#region
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
},
|
|
59
|
-
priority,
|
|
60
|
-
color: 'accent1',
|
|
61
|
-
type: AXPSystemActionType.Generate,
|
|
62
|
-
scope,
|
|
63
|
-
order: AI_ASSIST_ORDER,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function appendScopedActions(actions) {
|
|
67
|
-
for (const { scope, commandName, titleKey, priority } of SCOPED_ACTIONS) {
|
|
68
|
-
if (!actionExists(actions, AXE_AI_ENTITY_ASSIST_COMMAND, commandName)) {
|
|
69
|
-
actions.push(buildAssistAction(scope, commandName, titleKey, priority));
|
|
24
|
+
//#region ----- Column snapshot -----
|
|
25
|
+
function axmBuildEntityRecordAssistColumns(entity, data, translationService) {
|
|
26
|
+
const names = resolveColumnNames(entity);
|
|
27
|
+
const byName = new Map((entity.properties ?? []).map((property) => [property.name, property]));
|
|
28
|
+
const byColumn = new Map((entity.columns ?? []).map((column) => [column.name, column]));
|
|
29
|
+
const columns = [];
|
|
30
|
+
const seen = new Set();
|
|
31
|
+
const push = (name) => {
|
|
32
|
+
if (!name || seen.has(name) || columns.length >= MAX_COLUMNS || axmShouldSkipContextualAssistKey(name)) {
|
|
33
|
+
return;
|
|
70
34
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
ensureListActions(ctx);
|
|
83
|
-
ctx.interfaces.update((interfaces) => {
|
|
84
|
-
const next = (interfaces ?? {});
|
|
85
|
-
const master = (next['master'] ?? {});
|
|
86
|
-
const list = (master['list'] ?? { actions: [], views: [] });
|
|
87
|
-
const listActions = (list['actions'] ?? []);
|
|
88
|
-
appendScopedActions(listActions);
|
|
89
|
-
list['actions'] = listActions;
|
|
90
|
-
master['list'] = list;
|
|
91
|
-
const single = master['single'];
|
|
92
|
-
if (single) {
|
|
93
|
-
const singleActions = (single['actions'] ?? []);
|
|
94
|
-
if (!actionExists(singleActions, AXE_AI_ENTITY_ASSIST_COMMAND, AXE_AI_ENTITY_ASSIST_ACTION.individual)) {
|
|
95
|
-
singleActions.push(buildAssistAction(AXPEntityCommandScope.Individual, AXE_AI_ENTITY_ASSIST_ACTION.individual, '@extensions-ai-entity:actions.assist.individual.title', 'secondary'));
|
|
96
|
-
}
|
|
97
|
-
single['actions'] = singleActions;
|
|
98
|
-
}
|
|
99
|
-
next['master'] = master;
|
|
100
|
-
return next;
|
|
35
|
+
seen.add(name);
|
|
36
|
+
const property = byName.get(name);
|
|
37
|
+
const column = byColumn.get(name);
|
|
38
|
+
const path = column?.options?.dataPath ?? name;
|
|
39
|
+
const raw = getSmart(data, path);
|
|
40
|
+
const titleRaw = column?.title ?? property?.title ?? name;
|
|
41
|
+
const title = translationService.resolve(titleRaw)?.trim() || name;
|
|
42
|
+
columns.push({
|
|
43
|
+
name,
|
|
44
|
+
title,
|
|
45
|
+
value: axmSanitizeContextualAssistValue(raw),
|
|
101
46
|
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
//#region ---- Imports ----
|
|
107
|
-
//#endregion
|
|
108
|
-
//#region ---- Constants ----
|
|
109
|
-
const ENTITY_AI_LOADING_I18N_PREFIX = '@extensions-ai-entity:assist.loading';
|
|
110
|
-
const MAX_PROPERTIES_IN_SUMMARY = 48;
|
|
111
|
-
function summarizeProperties(properties) {
|
|
112
|
-
const list = properties ?? [];
|
|
113
|
-
return list.slice(0, MAX_PROPERTIES_IN_SUMMARY).map((p) => ({
|
|
114
|
-
name: p.name,
|
|
115
|
-
title: p.title,
|
|
116
|
-
dataType: p.schema?.dataType ?? 'unknown',
|
|
117
|
-
widgetType: p.schema?.interface?.type,
|
|
118
|
-
}));
|
|
119
|
-
}
|
|
120
|
-
function scopeLabel(scope) {
|
|
121
|
-
switch (scope) {
|
|
122
|
-
case AXPEntityCommandScope.TypeLevel:
|
|
123
|
-
return 'type-level (list, no row selection)';
|
|
124
|
-
case AXPEntityCommandScope.Selected:
|
|
125
|
-
return 'selected rows (bulk context)';
|
|
126
|
-
case AXPEntityCommandScope.Individual:
|
|
127
|
-
return 'individual row';
|
|
128
|
-
default:
|
|
129
|
-
return scope;
|
|
47
|
+
};
|
|
48
|
+
push('id');
|
|
49
|
+
for (const name of names) {
|
|
50
|
+
push(name);
|
|
130
51
|
}
|
|
52
|
+
return columns;
|
|
131
53
|
}
|
|
132
|
-
function
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
'Property catalog (name, title, dataType, widgetType):',
|
|
145
|
-
JSON.stringify(propertySummary, null, 2),
|
|
146
|
-
truncated
|
|
147
|
-
? `(Only the first ${MAX_PROPERTIES_IN_SUMMARY} properties are listed; infer patterns for the rest.)`
|
|
148
|
-
: '',
|
|
149
|
-
'',
|
|
150
|
-
'Rules:',
|
|
151
|
-
'- Reply in plain language unless the user asks for JSON.',
|
|
152
|
-
'- Do not invent persisted ids or claim data was saved.',
|
|
153
|
-
'- When suggesting field values, name fields by their `name` from the catalog.',
|
|
154
|
-
]
|
|
155
|
-
.filter(Boolean)
|
|
156
|
-
.join('\n');
|
|
54
|
+
function resolveColumnNames(entity) {
|
|
55
|
+
const views = entity.interfaces?.master?.list?.views ?? [];
|
|
56
|
+
const firstView = views.find((view) => view.visible !== false) ?? views[0];
|
|
57
|
+
const viewColumns = normalizeAXPQueryViewColumns(firstView?.columns ?? []).filter((column) => column.visible);
|
|
58
|
+
if (viewColumns.length > 0) {
|
|
59
|
+
return viewColumns.map((column) => column.name);
|
|
60
|
+
}
|
|
61
|
+
const tableColumns = (entity.columns ?? []).filter((column) => column.options?.visible !== false);
|
|
62
|
+
if (tableColumns.length > 0) {
|
|
63
|
+
return tableColumns.map((column) => column.name);
|
|
64
|
+
}
|
|
65
|
+
return (entity.properties ?? []).map((property) => property.name).slice(0, MAX_COLUMNS);
|
|
157
66
|
}
|
|
158
|
-
function
|
|
159
|
-
const
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
67
|
+
function axmReadEntityRecordId(data) {
|
|
68
|
+
const id = getSmart(data, 'id');
|
|
69
|
+
if (typeof id === 'string' && id.trim()) {
|
|
70
|
+
return id.trim();
|
|
71
|
+
}
|
|
72
|
+
if (typeof id === 'number' && Number.isFinite(id)) {
|
|
73
|
+
return String(id);
|
|
164
74
|
}
|
|
165
|
-
return
|
|
75
|
+
return '';
|
|
166
76
|
}
|
|
167
77
|
//#endregion
|
|
78
|
+
|
|
79
|
+
//#region ----- Imports -----
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region ----- Service -----
|
|
168
82
|
/**
|
|
169
|
-
* Opens
|
|
83
|
+
* Opens contextual assist for a single entity list row.
|
|
170
84
|
*/
|
|
171
85
|
class AXEAiEntityAssistService {
|
|
172
86
|
constructor() {
|
|
173
|
-
//#region
|
|
174
|
-
this.
|
|
87
|
+
//#region ----- Services & Dependencies -----
|
|
88
|
+
this.launcher = inject(AXMContextualAssistLauncherService, { optional: true });
|
|
175
89
|
this.translationService = inject(AXTranslationService);
|
|
176
90
|
this.toastService = inject(AXToastService);
|
|
177
91
|
this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
|
|
178
92
|
}
|
|
179
93
|
//#endregion
|
|
180
|
-
//#region
|
|
94
|
+
//#region ----- Public API -----
|
|
181
95
|
async runFromCommandContext(context) {
|
|
182
|
-
const
|
|
183
|
-
if (!
|
|
96
|
+
const launcher = this.launcher;
|
|
97
|
+
if (!launcher) {
|
|
184
98
|
const title = await this.translationService.translateAsync('@general:messages.generic.warning.title');
|
|
185
|
-
const content = await this.translationService.translateAsync('@extensions-ai-entity:assist.no-
|
|
99
|
+
const content = await this.translationService.translateAsync('@extensions-ai-entity:assist.no-conversation-module');
|
|
186
100
|
await this.toastService.show({ color: 'warning', title, content });
|
|
187
|
-
return;
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
const { entityInfo, data } = context;
|
|
104
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const row = data;
|
|
108
|
+
const recordId = axmReadEntityRecordId(row);
|
|
109
|
+
if (!recordId) {
|
|
110
|
+
return false;
|
|
188
111
|
}
|
|
189
|
-
const { entityInfo, data, options } = context;
|
|
190
|
-
const scope = resolveScope(options);
|
|
191
112
|
const entity = await this.entityRegistry.resolve(entityInfo.module, entityInfo.name);
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
source: entityInfo.source ?? `${entity.module}.${entity.name}`,
|
|
202
|
-
},
|
|
203
|
-
propertyCount: entity.properties?.length ?? 0,
|
|
204
|
-
properties: propertySummary,
|
|
205
|
-
data,
|
|
113
|
+
const entityTitle = this.translationService.resolve(entity.title)?.trim() ||
|
|
114
|
+
this.translationService.resolve(entityInfo.title)?.trim() ||
|
|
115
|
+
entity.name;
|
|
116
|
+
const payload = {
|
|
117
|
+
moduleName: entity.module,
|
|
118
|
+
entityName: entity.name,
|
|
119
|
+
entityTitle,
|
|
120
|
+
recordId,
|
|
121
|
+
columns: axmBuildEntityRecordAssistColumns(entity, row, this.translationService),
|
|
206
122
|
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const [dialogTitle, placeholder, runLoadingTitle, runLoadingText] = await Promise.all([
|
|
213
|
-
this.translationService.translateAsync(dialogTitleKey),
|
|
214
|
-
this.translationService.translateAsync('@extensions-ai-entity:assist.placeholder'),
|
|
215
|
-
this.translationService.translateAsync(`${ENTITY_AI_LOADING_I18N_PREFIX}.run-title`),
|
|
216
|
-
this.translationService.translateAsync(`${ENTITY_AI_LOADING_I18N_PREFIX}.run-initial`),
|
|
217
|
-
]);
|
|
218
|
-
const showResult = await ai.show({
|
|
219
|
-
title: dialogTitle,
|
|
220
|
-
placeholder,
|
|
221
|
-
size: 'lg',
|
|
222
|
-
context: {
|
|
223
|
-
systemInstruction,
|
|
224
|
-
structuredContext,
|
|
225
|
-
},
|
|
226
|
-
runLoadingDialog: {
|
|
227
|
-
title: runLoadingTitle,
|
|
228
|
-
text: runLoadingText,
|
|
229
|
-
},
|
|
230
|
-
});
|
|
231
|
-
if (!showResult?.text?.trim()) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
const doneTitle = await this.translationService.translateAsync('@extensions-ai-entity:assist.result-toast-title');
|
|
235
|
-
const preview = showResult.text.length > 600 ? `${showResult.text.slice(0, 600).trim()}…` : showResult.text.trim();
|
|
236
|
-
await this.toastService.show({
|
|
237
|
-
color: 'success',
|
|
238
|
-
title: doneTitle,
|
|
239
|
-
content: preview,
|
|
123
|
+
await launcher.open({
|
|
124
|
+
kind: AXM_CONTEXTUAL_ASSIST_KIND_ENTITY_RECORD,
|
|
125
|
+
actionName: AXM_CONTEXTUAL_ASSIST_ACTION_ENTITY_RECORD,
|
|
126
|
+
title: entityTitle,
|
|
127
|
+
payload: { ...payload },
|
|
240
128
|
});
|
|
129
|
+
return true;
|
|
241
130
|
}
|
|
242
131
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAiEntityAssistService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
243
132
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAiEntityAssistService }); }
|
|
@@ -246,42 +135,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
246
135
|
type: Injectable
|
|
247
136
|
}] });
|
|
248
137
|
|
|
249
|
-
//#region
|
|
138
|
+
//#region ----- Imports -----
|
|
250
139
|
//#endregion
|
|
251
|
-
//#region
|
|
140
|
+
//#region ----- Module -----
|
|
252
141
|
/**
|
|
253
|
-
*
|
|
254
|
-
*
|
|
142
|
+
* AI assist command for entity records.
|
|
143
|
+
* The list-row menu entry is not registered; context is chosen from the header mini chat.
|
|
255
144
|
*/
|
|
256
145
|
class AXEAIEntityExtensionModule {
|
|
257
146
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAIEntityExtensionModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
258
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXEAIEntityExtensionModule
|
|
147
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXEAIEntityExtensionModule }); }
|
|
259
148
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAIEntityExtensionModule, providers: [
|
|
260
149
|
AXEAiEntityAssistService,
|
|
261
|
-
{
|
|
262
|
-
provide: AXP_ENTITY_MODIFIER,
|
|
263
|
-
useValue: AXEAiEntityActionsModifier,
|
|
264
|
-
multi: true,
|
|
265
|
-
},
|
|
266
150
|
provideCommandSetups([
|
|
267
151
|
{
|
|
268
152
|
key: AXE_AI_ENTITY_ASSIST_COMMAND,
|
|
269
153
|
command: () => Promise.resolve().then(function () { return aiEntityAssist_command; }).then((c) => c.AXEAiEntityAssistCommand),
|
|
270
154
|
},
|
|
271
155
|
]),
|
|
272
|
-
]
|
|
156
|
+
] }); }
|
|
273
157
|
}
|
|
274
158
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAIEntityExtensionModule, decorators: [{
|
|
275
159
|
type: NgModule,
|
|
276
160
|
args: [{
|
|
277
|
-
imports: [AXMAiManagementModule],
|
|
278
161
|
providers: [
|
|
279
162
|
AXEAiEntityAssistService,
|
|
280
|
-
{
|
|
281
|
-
provide: AXP_ENTITY_MODIFIER,
|
|
282
|
-
useValue: AXEAiEntityActionsModifier,
|
|
283
|
-
multi: true,
|
|
284
|
-
},
|
|
285
163
|
provideCommandSetups([
|
|
286
164
|
{
|
|
287
165
|
key: AXE_AI_ENTITY_ASSIST_COMMAND,
|
|
@@ -292,21 +170,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
292
170
|
}]
|
|
293
171
|
}] });
|
|
294
172
|
|
|
173
|
+
//#region ----- Imports -----
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region ----- Modifier config -----
|
|
176
|
+
const AI_ASSIST_ORDER = 45;
|
|
177
|
+
function buildRowAssistAction() {
|
|
178
|
+
return {
|
|
179
|
+
name: AXE_AI_ENTITY_ASSIST_ACTION,
|
|
180
|
+
title: '@extensions-ai-entity:actions.assist.individual.title',
|
|
181
|
+
command: {
|
|
182
|
+
name: AXE_AI_ENTITY_ASSIST_COMMAND,
|
|
183
|
+
options: {
|
|
184
|
+
scope: AXPEntityCommandScope.Individual,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
priority: 'secondary',
|
|
188
|
+
color: 'accent1',
|
|
189
|
+
type: AXPSystemActionType.Generate,
|
|
190
|
+
icon: 'fa-regular fa-sparkles',
|
|
191
|
+
scope: AXPEntityCommandScope.Individual,
|
|
192
|
+
order: AI_ASSIST_ORDER,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region ----- Global modifier -----
|
|
197
|
+
/**
|
|
198
|
+
* Adds AI Assist to the entity list row menu (Individual, secondary).
|
|
199
|
+
*/
|
|
200
|
+
const AXEAiEntityActionsModifier = {
|
|
201
|
+
entityName: '*',
|
|
202
|
+
modifier: (ctx) => {
|
|
203
|
+
ensureListActions(ctx);
|
|
204
|
+
ctx.interfaces.update((interfaces) => {
|
|
205
|
+
const next = (interfaces ?? {});
|
|
206
|
+
const master = (next['master'] ?? {});
|
|
207
|
+
const list = (master['list'] ?? { actions: [], views: [] });
|
|
208
|
+
const listActions = (list['actions'] ?? []);
|
|
209
|
+
if (!actionExists(listActions, AXE_AI_ENTITY_ASSIST_COMMAND, AXE_AI_ENTITY_ASSIST_ACTION)) {
|
|
210
|
+
listActions.push(buildRowAssistAction());
|
|
211
|
+
}
|
|
212
|
+
list['actions'] = listActions;
|
|
213
|
+
master['list'] = list;
|
|
214
|
+
next['master'] = master;
|
|
215
|
+
return next;
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
//#endregion
|
|
220
|
+
|
|
295
221
|
//#endregion
|
|
296
|
-
//#region
|
|
222
|
+
//#region ----- Command -----
|
|
297
223
|
/**
|
|
298
|
-
* Entity list
|
|
224
|
+
* Entity list row AI assist — opens the contextual assist overlay with record context.
|
|
299
225
|
*/
|
|
300
226
|
class AXEAiEntityAssistCommand {
|
|
301
227
|
constructor() {
|
|
302
|
-
//#region
|
|
228
|
+
//#region ----- Services & Dependencies -----
|
|
303
229
|
this.assist = inject(AXEAiEntityAssistService);
|
|
304
230
|
}
|
|
305
231
|
//#endregion
|
|
306
|
-
//#region
|
|
232
|
+
//#region ----- Command execution -----
|
|
307
233
|
async execute(input) {
|
|
308
|
-
const
|
|
309
|
-
if (
|
|
234
|
+
const opened = await this.assist.runFromCommandContext(input);
|
|
235
|
+
if (!opened) {
|
|
310
236
|
return { success: false };
|
|
311
237
|
}
|
|
312
238
|
return { success: true, kind: 'object', data: undefined };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acorex-platform-extension-ai-entity-client.mjs","sources":["../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-assist.constants.ts","../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-actions.modifier.ts","../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-assist.service.ts","../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-extension.module.ts","../../../../libs/extensions/ai/entity/client/src/lib/commands/ai-entity-assist.command.ts","../../../../libs/extensions/ai/entity/client/src/acorex-platform-extension-ai-entity-client.ts"],"sourcesContent":["//#region ---- Command & action keys ----\n\n/** Runtime command key registered via {@link provideCommandSetups}. */\nexport const AXE_AI_ENTITY_ASSIST_COMMAND = 'AiEntity:Assist';\n\n/** Distinct action command names per scope (resolved to {@link AXE_AI_ENTITY_ASSIST_COMMAND}). */\nexport const AXE_AI_ENTITY_ASSIST_ACTION = {\n typeLevel: 'ai-entity-assist-type-level',\n selected: 'ai-entity-assist-selected',\n individual: 'ai-entity-assist-individual',\n} as const;\n\n//#endregion\n","//#region ---- Imports ----\n\nimport { AXPEntityAction, AXPEntityCommandScope } from '@acorex-platform/framework-shared/entity';\nimport { AXStyleColorType } from '@acorex/cdk/common';\n\nimport { AXPSystemActionType } from '@acorex-platform/framework-shared/core';\nimport {\n actionExists,\n AXPEntityModifierProvider,\n ensureListActions,\n} from '@acorex-platform/framework-client/layout/entity';\nimport { AXE_AI_ENTITY_ASSIST_ACTION, AXE_AI_ENTITY_ASSIST_COMMAND } from './ai-entity-assist.constants';\n\n//#endregion\n\n//#region ---- Modifier config ----\n\nconst AI_ASSIST_ORDER = 45;\n\n/** Scopes injected on master list actions. */\nconst SCOPED_ACTIONS: ReadonlyArray<{\n scope: AXPEntityCommandScope;\n commandName: string;\n titleKey: string;\n priority: 'primary' | 'secondary' | 'none';\n}> = [\n {\n scope: AXPEntityCommandScope.TypeLevel,\n commandName: AXE_AI_ENTITY_ASSIST_ACTION.typeLevel,\n titleKey: '@extensions-ai-entity:actions.assist.type-level.title',\n priority: 'secondary',\n },\n {\n scope: AXPEntityCommandScope.Selected,\n commandName: AXE_AI_ENTITY_ASSIST_ACTION.selected,\n titleKey: '@extensions-ai-entity:actions.assist.selected.title',\n priority: 'secondary',\n },\n {\n scope: AXPEntityCommandScope.Individual,\n commandName: AXE_AI_ENTITY_ASSIST_ACTION.individual,\n titleKey: '@extensions-ai-entity:actions.assist.individual.title',\n priority: 'none',\n },\n ];\n\n//#endregion\n\n//#region ---- Helpers ----\n\nfunction buildAssistAction(\n scope: AXPEntityCommandScope,\n commandName: string,\n titleKey: string,\n priority: 'primary' | 'secondary' | 'none',\n): AXPEntityAction {\n return {\n name: commandName,\n title: titleKey,\n command: {\n name: AXE_AI_ENTITY_ASSIST_COMMAND,\n options: {\n scope\n },\n },\n priority,\n color: 'accent1' as AXStyleColorType,\n type: AXPSystemActionType.Generate,\n scope,\n order: AI_ASSIST_ORDER,\n };\n}\n\nfunction appendScopedActions(actions: AXPEntityAction[]): void {\n for (const { scope, commandName, titleKey, priority } of SCOPED_ACTIONS) {\n if (!actionExists(actions, AXE_AI_ENTITY_ASSIST_COMMAND, commandName)) {\n actions.push(buildAssistAction(scope, commandName, titleKey, priority));\n }\n }\n}\n\n//#endregion\n\n//#region ---- Global modifier ----\n\n/**\n * Adds AI Assist to entity list (TypeLevel/Selected primary; Individual not a row command via priority `none`)\n * and single view (Individual primary in header).\n */\nexport const AXEAiEntityActionsModifier: AXPEntityModifierProvider = {\n entityName: '*',\n modifier: (ctx) => {\n ensureListActions(ctx);\n\n ctx.interfaces.update((interfaces) => {\n const next = (interfaces ?? {}) as Record<string, unknown>;\n const master = (next['master'] ?? {}) as Record<string, unknown>;\n const list = (master['list'] ?? { actions: [], views: [] }) as Record<string, unknown>;\n const listActions = (list['actions'] ?? []) as AXPEntityAction[];\n appendScopedActions(listActions);\n list['actions'] = listActions;\n master['list'] = list;\n\n const single = master['single'] as Record<string, unknown> | undefined;\n if (single) {\n const singleActions = (single['actions'] ?? []) as AXPEntityAction[];\n if (!actionExists(singleActions, AXE_AI_ENTITY_ASSIST_COMMAND, AXE_AI_ENTITY_ASSIST_ACTION.individual)) {\n singleActions.push(\n buildAssistAction(\n AXPEntityCommandScope.Individual,\n AXE_AI_ENTITY_ASSIST_ACTION.individual,\n '@extensions-ai-entity:actions.assist.individual.title',\n 'secondary',\n ),\n );\n }\n single['actions'] = singleActions;\n }\n\n next['master'] = master;\n return next as typeof interfaces;\n });\n },\n};\n\n//#endregion\n","//#region ---- Imports ----\n\nimport { AXPEntity, AXPEntityCommandScope, AXPEntityProperty } from '@acorex-platform/framework-shared/entity';\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPAiManagerService } from '@acorex-platform/module-ai-management-client';\n\nimport { AXPEntityDefinitionRegistryService } from '@acorex-platform/framework-client/layout/entity';\nimport { inject, Injectable } from '@angular/core';\nimport type {\n AXEAiEntityAssistCommandContext,\n AXEAiEntityAssistCommandOptions,\n} from '@acorex-platform/extension-ai-entity-client/contracts';\n\n//#endregion\n\n//#region ---- Constants ----\n\nconst ENTITY_AI_LOADING_I18N_PREFIX = '@extensions-ai-entity:assist.loading';\nconst MAX_PROPERTIES_IN_SUMMARY = 48;\n\n//#endregion\n\n//#region ---- Context builders ----\n\ninterface AXEAiEntityPropertySummary {\n name: string;\n title: string;\n dataType: string;\n widgetType?: string;\n}\n\nfunction summarizeProperties(properties: AXPEntityProperty[] | undefined): AXEAiEntityPropertySummary[] {\n const list = properties ?? [];\n return list.slice(0, MAX_PROPERTIES_IN_SUMMARY).map((p) => ({\n name: p.name,\n title: p.title,\n dataType: p.schema?.dataType ?? 'unknown',\n widgetType: p.schema?.interface?.type,\n }));\n}\n\nfunction scopeLabel(scope: AXPEntityCommandScope): string {\n switch (scope) {\n case AXPEntityCommandScope.TypeLevel:\n return 'type-level (list, no row selection)';\n case AXPEntityCommandScope.Selected:\n return 'selected rows (bulk context)';\n case AXPEntityCommandScope.Individual:\n return 'individual row';\n default:\n return scope;\n }\n}\n\nfunction buildSystemInstruction(\n entity: AXPEntity,\n scope: AXPEntityCommandScope,\n propertySummary: AXEAiEntityPropertySummary[],\n): string {\n const truncated = (entity.properties?.length ?? 0) > propertySummary.length;\n return [\n 'You are assisting a user working with an ACoreX Platform entity (CRUD list / record context).',\n `Entity: ${entity.module}.${entity.name} (${entity.title}).`,\n `Command scope: ${scopeLabel(scope)}.`,\n '',\n 'Scope behavior:',\n '- **typeLevel**: Help with list-level tasks (filters, sorting ideas, bulk create outlines, reporting questions) when no row is selected.',\n '- **selected**: Answer using the provided array of selected records; prefer bulk-safe suggestions.',\n '- **individual**: Focus on one record; you may suggest field-level edits the user can apply manually.',\n '',\n 'Property catalog (name, title, dataType, widgetType):',\n JSON.stringify(propertySummary, null, 2),\n truncated\n ? `(Only the first ${MAX_PROPERTIES_IN_SUMMARY} properties are listed; infer patterns for the rest.)`\n : '',\n '',\n 'Rules:',\n '- Reply in plain language unless the user asks for JSON.',\n '- Do not invent persisted ids or claim data was saved.',\n '- When suggesting field values, name fields by their `name` from the catalog.',\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction resolveScope(options: AXEAiEntityAssistCommandOptions | undefined): AXPEntityCommandScope {\n const scope = options?.scope;\n if (\n scope === AXPEntityCommandScope.TypeLevel ||\n scope === AXPEntityCommandScope.Selected ||\n scope === AXPEntityCommandScope.Individual\n ) {\n return scope;\n }\n return AXPEntityCommandScope.TypeLevel;\n}\n\n//#endregion\n\n/**\n * Opens AI assist for entity CRUD views with entity schema and selection context.\n */\n@Injectable()\nexport class AXEAiEntityAssistService {\n //#region ---- Services & Dependencies ----\n\n private readonly aiManager = inject(AXPAiManagerService, { optional: true });\n private readonly translationService = inject(AXTranslationService);\n private readonly toastService = inject(AXToastService);\n private readonly entityRegistry = inject(AXPEntityDefinitionRegistryService);\n\n //#endregion\n\n //#region ---- Public API ----\n\n async runFromCommandContext(context: AXEAiEntityAssistCommandContext): Promise<void> {\n const ai = this.aiManager;\n if (!ai) {\n const title = await this.translationService.translateAsync('@general:messages.generic.warning.title');\n const content = await this.translationService.translateAsync('@extensions-ai-entity:assist.no-ai-module');\n await this.toastService.show({ color: 'warning', title, content });\n return;\n }\n\n const { entityInfo, data, options } = context;\n const scope = resolveScope(options);\n const entity = await this.entityRegistry.resolve(entityInfo.module, entityInfo.name);\n const propertySummary = summarizeProperties(entity.properties);\n const systemInstruction = buildSystemInstruction(entity, scope, propertySummary);\n\n const structuredContext = {\n scenario: 'entity-crud-assist',\n scope,\n entity: {\n module: entity.module,\n name: entity.name,\n title: entity.title,\n source: entityInfo.source ?? `${entity.module}.${entity.name}`,\n },\n propertyCount: entity.properties?.length ?? 0,\n properties: propertySummary,\n data,\n };\n\n const dialogTitleKey =\n scope === AXPEntityCommandScope.Selected\n ? '@extensions-ai-entity:assist.dialog-title.selected'\n : scope === AXPEntityCommandScope.Individual\n ? '@extensions-ai-entity:assist.dialog-title.individual'\n : '@extensions-ai-entity:assist.dialog-title.type-level';\n\n const [dialogTitle, placeholder, runLoadingTitle, runLoadingText] = await Promise.all([\n this.translationService.translateAsync(dialogTitleKey),\n this.translationService.translateAsync('@extensions-ai-entity:assist.placeholder'),\n this.translationService.translateAsync(`${ENTITY_AI_LOADING_I18N_PREFIX}.run-title`),\n this.translationService.translateAsync(`${ENTITY_AI_LOADING_I18N_PREFIX}.run-initial`),\n ]);\n\n const showResult = await ai.show({\n title: dialogTitle,\n placeholder,\n size: 'lg',\n context: {\n systemInstruction,\n structuredContext,\n },\n runLoadingDialog: {\n title: runLoadingTitle,\n text: runLoadingText,\n },\n });\n\n if (!showResult?.text?.trim()) {\n return;\n }\n\n const doneTitle = await this.translationService.translateAsync('@extensions-ai-entity:assist.result-toast-title');\n const preview =\n showResult.text.length > 600 ? `${showResult.text.slice(0, 600).trim()}…` : showResult.text.trim();\n await this.toastService.show({\n color: 'success',\n title: doneTitle,\n content: preview,\n });\n }\n\n //#endregion\n}\n","//#region ---- Imports ----\n\nimport { NgModule } from '@angular/core';\nimport { AXMAiManagementModule } from '@acorex-platform/module-ai-management-client';\nimport { AXP_ENTITY_MODIFIER } from '@acorex-platform/framework-client/layout/entity';\nimport { provideCommandSetups } from '@acorex-platform/framework-client/runtime';\nimport { AXEAiEntityActionsModifier } from './ai-entity-actions.modifier';\nimport { AXE_AI_ENTITY_ASSIST_COMMAND } from './ai-entity-assist.constants';\nimport { AXEAiEntityAssistService } from './ai-entity-assist.service';\n\n//#endregion\n\n//#region ---- Module ----\n\n/**\n * Optional AI assist on entity CRUD views (TypeLevel, Selected, Individual scopes).\n * Register next to {@link AXMAiManagementModule} in the application.\n */\n@NgModule({\n imports: [AXMAiManagementModule],\n providers: [\n AXEAiEntityAssistService,\n {\n provide: AXP_ENTITY_MODIFIER,\n useValue: AXEAiEntityActionsModifier,\n multi: true,\n },\n provideCommandSetups([\n {\n key: AXE_AI_ENTITY_ASSIST_COMMAND,\n command: () =>\n import('./commands/ai-entity-assist.command').then((c) => c.AXEAiEntityAssistCommand),\n },\n ]),\n ],\n})\nexport class AXEAIEntityExtensionModule { }\n\n//#endregion\n","//#region ---- Imports ----\n\nimport { AXPCommand, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\n\nimport { inject, Injectable } from '@angular/core';\nimport { AXEAiEntityAssistService } from '../ai-entity-assist.service';\nimport type { AXEAiEntityAssistCommandInput } from '@acorex-platform/extension-ai-entity-client/contracts';\n\n//#endregion\n\n//#region ---- Command ----\n\n/**\n * Entity list / row AI assist — opens {@link AXPAiManagerService} with entity schema and selection context.\n */\n@Injectable()\nexport class AXEAiEntityAssistCommand implements AXPCommand<AXEAiEntityAssistCommandInput, void> {\n //#region ---- Services & Dependencies ----\n\n private readonly assist = inject(AXEAiEntityAssistService);\n\n //#endregion\n\n //#region ---- Command execution ----\n\n async execute(input: AXEAiEntityAssistCommandInput): AXPCommandExecuteResultPromise<void> {\n const result = await this.assist.runFromCommandContext(input);\n\n if (result == undefined) {\n return { success: false };\n }\n\n return { success: true, kind: 'object', data: undefined };\n }\n\n //#endregion\n}\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"acorex-platform-extension-ai-entity-client.mjs","sources":["../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-assist.constants.ts","../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-assist-context.util.ts","../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-assist.service.ts","../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-extension.module.ts","../../../../libs/extensions/ai/entity/client/src/lib/ai-entity-actions.modifier.ts","../../../../libs/extensions/ai/entity/client/src/lib/commands/ai-entity-assist.command.ts","../../../../libs/extensions/ai/entity/client/src/acorex-platform-extension-ai-entity-client.ts"],"sourcesContent":["//#region ----- Command & action keys -----\n\n/** Runtime command key registered via {@link provideCommandSetups}. */\nexport const AXE_AI_ENTITY_ASSIST_COMMAND = 'AiEntity:Assist';\n\n/** Individual row action name (resolved to {@link AXE_AI_ENTITY_ASSIST_COMMAND}). */\nexport const AXE_AI_ENTITY_ASSIST_ACTION = 'ai-entity-assist-individual';\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXPEntity, normalizeAXPQueryViewColumns } from '@acorex-platform/framework-shared/entity';\nimport { getSmart, type AXPMultiLanguageString } from '@acorex-platform/framework-shared/core';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport {\n axmSanitizeContextualAssistValue,\n axmShouldSkipContextualAssistKey,\n type AXMContextualAssistColumnValue,\n} from '@acorex-platform/module-conversation-client/contracts';\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst MAX_COLUMNS = 24;\n\n//#endregion\n\n//#region ----- Column snapshot -----\n\nexport function axmBuildEntityRecordAssistColumns(\n entity: AXPEntity,\n data: Record<string, unknown>,\n translationService: AXTranslationService,\n): AXMContextualAssistColumnValue[] {\n const names = resolveColumnNames(entity);\n const byName = new Map((entity.properties ?? []).map((property) => [property.name, property]));\n const byColumn = new Map((entity.columns ?? []).map((column) => [column.name, column]));\n const columns: AXMContextualAssistColumnValue[] = [];\n const seen = new Set<string>();\n\n const push = (name: string): void => {\n if (!name || seen.has(name) || columns.length >= MAX_COLUMNS || axmShouldSkipContextualAssistKey(name)) {\n return;\n }\n seen.add(name);\n const property = byName.get(name);\n const column = byColumn.get(name);\n const path = column?.options?.dataPath ?? name;\n const raw = getSmart(data, path);\n const titleRaw = column?.title ?? property?.title ?? name;\n const title = translationService.resolve(titleRaw as AXPMultiLanguageString)?.trim() || name;\n columns.push({\n name,\n title,\n value: axmSanitizeContextualAssistValue(raw),\n });\n };\n\n push('id');\n for (const name of names) {\n push(name);\n }\n\n return columns;\n}\n\nfunction resolveColumnNames(entity: AXPEntity): string[] {\n const views = entity.interfaces?.master?.list?.views ?? [];\n const firstView = views.find((view) => view.visible !== false) ?? views[0];\n const viewColumns = normalizeAXPQueryViewColumns(firstView?.columns ?? []).filter((column) => column.visible);\n if (viewColumns.length > 0) {\n return viewColumns.map((column) => column.name);\n }\n\n const tableColumns = (entity.columns ?? []).filter((column) => column.options?.visible !== false);\n if (tableColumns.length > 0) {\n return tableColumns.map((column) => column.name);\n }\n\n return (entity.properties ?? []).map((property) => property.name).slice(0, MAX_COLUMNS);\n}\n\nexport function axmReadEntityRecordId(data: Record<string, unknown>): string {\n const id = getSmart(data, 'id');\n if (typeof id === 'string' && id.trim()) {\n return id.trim();\n }\n if (typeof id === 'number' && Number.isFinite(id)) {\n return String(id);\n }\n return '';\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPEntityDefinitionRegistryService } from '@acorex-platform/framework-client/layout/entity';\nimport { type AXPMultiLanguageString } from '@acorex-platform/framework-shared/core';\nimport {\n AXMContextualAssistLauncherService,\n AXM_CONTEXTUAL_ASSIST_ACTION_ENTITY_RECORD,\n AXM_CONTEXTUAL_ASSIST_KIND_ENTITY_RECORD,\n type AXMEntityRecordAssistPayload,\n} from '@acorex-platform/extension-ai-conversation-client';\nimport { inject, Injectable } from '@angular/core';\nimport type { AXEAiEntityAssistCommandContext } from '@acorex-platform/extension-ai-entity-client/contracts';\nimport { axmBuildEntityRecordAssistColumns, axmReadEntityRecordId } from './ai-entity-assist-context.util';\n\n//#endregion\n\n//#region ----- Service -----\n\n/**\n * Opens contextual assist for a single entity list row.\n */\n@Injectable()\nexport class AXEAiEntityAssistService {\n //#region ----- Services & Dependencies -----\n\n private readonly launcher = inject(AXMContextualAssistLauncherService, { optional: true });\n private readonly translationService = inject(AXTranslationService);\n private readonly toastService = inject(AXToastService);\n private readonly entityRegistry = inject(AXPEntityDefinitionRegistryService);\n\n //#endregion\n\n //#region ----- Public API -----\n\n async runFromCommandContext(context: AXEAiEntityAssistCommandContext): Promise<boolean> {\n const launcher = this.launcher;\n if (!launcher) {\n const title = await this.translationService.translateAsync('@general:messages.generic.warning.title');\n const content = await this.translationService.translateAsync(\n '@extensions-ai-entity:assist.no-conversation-module',\n );\n await this.toastService.show({ color: 'warning', title, content });\n return false;\n }\n\n const { entityInfo, data } = context;\n if (!data || typeof data !== 'object' || Array.isArray(data)) {\n return false;\n }\n const row = data as Record<string, unknown>;\n const recordId = axmReadEntityRecordId(row);\n if (!recordId) {\n return false;\n }\n\n const entity = await this.entityRegistry.resolve(entityInfo.module, entityInfo.name);\n const entityTitle =\n this.translationService.resolve(entity.title as AXPMultiLanguageString)?.trim() ||\n this.translationService.resolve(entityInfo.title as AXPMultiLanguageString)?.trim() ||\n entity.name;\n const payload: AXMEntityRecordAssistPayload = {\n moduleName: entity.module,\n entityName: entity.name,\n entityTitle,\n recordId,\n columns: axmBuildEntityRecordAssistColumns(entity, row, this.translationService),\n };\n\n await launcher.open({\n kind: AXM_CONTEXTUAL_ASSIST_KIND_ENTITY_RECORD,\n actionName: AXM_CONTEXTUAL_ASSIST_ACTION_ENTITY_RECORD,\n title: entityTitle,\n payload: { ...payload },\n });\n return true;\n }\n\n //#endregion\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { NgModule } from '@angular/core';\nimport { provideCommandSetups } from '@acorex-platform/framework-client/runtime';\nimport { AXE_AI_ENTITY_ASSIST_COMMAND } from './ai-entity-assist.constants';\nimport { AXEAiEntityAssistService } from './ai-entity-assist.service';\n\n//#endregion\n\n//#region ----- Module -----\n\n/**\n * AI assist command for entity records.\n * The list-row menu entry is not registered; context is chosen from the header mini chat.\n */\n@NgModule({\n providers: [\n AXEAiEntityAssistService,\n provideCommandSetups([\n {\n key: AXE_AI_ENTITY_ASSIST_COMMAND,\n command: () =>\n import('./commands/ai-entity-assist.command').then((c) => c.AXEAiEntityAssistCommand),\n },\n ]),\n ],\n})\nexport class AXEAIEntityExtensionModule {}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXPEntityAction, AXPEntityCommandScope } from '@acorex-platform/framework-shared/entity';\nimport { AXStyleColorType } from '@acorex/cdk/common';\nimport { AXPSystemActionType } from '@acorex-platform/framework-shared/core';\nimport {\n actionExists,\n AXPEntityModifierProvider,\n ensureListActions,\n} from '@acorex-platform/framework-client/layout/entity';\nimport { AXE_AI_ENTITY_ASSIST_ACTION, AXE_AI_ENTITY_ASSIST_COMMAND } from './ai-entity-assist.constants';\n\n//#endregion\n\n//#region ----- Modifier config -----\n\nconst AI_ASSIST_ORDER = 45;\n\nfunction buildRowAssistAction(): AXPEntityAction {\n return {\n name: AXE_AI_ENTITY_ASSIST_ACTION,\n title: '@extensions-ai-entity:actions.assist.individual.title',\n command: {\n name: AXE_AI_ENTITY_ASSIST_COMMAND,\n options: {\n scope: AXPEntityCommandScope.Individual,\n },\n },\n priority: 'secondary',\n color: 'accent1' as AXStyleColorType,\n type: AXPSystemActionType.Generate,\n icon: 'fa-regular fa-sparkles',\n scope: AXPEntityCommandScope.Individual,\n order: AI_ASSIST_ORDER,\n };\n}\n\n//#endregion\n\n//#region ----- Global modifier -----\n\n/**\n * Adds AI Assist to the entity list row menu (Individual, secondary).\n */\nexport const AXEAiEntityActionsModifier: AXPEntityModifierProvider = {\n entityName: '*',\n modifier: (ctx) => {\n ensureListActions(ctx);\n\n ctx.interfaces.update((interfaces) => {\n const next = (interfaces ?? {}) as Record<string, unknown>;\n const master = (next['master'] ?? {}) as Record<string, unknown>;\n const list = (master['list'] ?? { actions: [], views: [] }) as Record<string, unknown>;\n const listActions = (list['actions'] ?? []) as AXPEntityAction[];\n if (!actionExists(listActions, AXE_AI_ENTITY_ASSIST_COMMAND, AXE_AI_ENTITY_ASSIST_ACTION)) {\n listActions.push(buildRowAssistAction());\n }\n list['actions'] = listActions;\n master['list'] = list;\n next['master'] = master;\n return next as typeof interfaces;\n });\n },\n};\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXPCommand, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\n\nimport { inject, Injectable } from '@angular/core';\nimport { AXEAiEntityAssistService } from '../ai-entity-assist.service';\nimport type { AXEAiEntityAssistCommandInput } from '@acorex-platform/extension-ai-entity-client/contracts';\n\n//#endregion\n\n//#region ----- Command -----\n\n/**\n * Entity list row AI assist — opens the contextual assist overlay with record context.\n */\n@Injectable()\nexport class AXEAiEntityAssistCommand implements AXPCommand<AXEAiEntityAssistCommandInput, void> {\n //#region ----- Services & Dependencies -----\n\n private readonly assist = inject(AXEAiEntityAssistService);\n\n //#endregion\n\n //#region ----- Command execution -----\n\n async execute(input: AXEAiEntityAssistCommandInput): AXPCommandExecuteResultPromise<void> {\n const opened = await this.assist.runFromCommandContext(input);\n if (!opened) {\n return { success: false };\n }\n\n return { success: true, kind: 'object', data: undefined };\n }\n\n //#endregion\n}\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acorex-platform/extension-ai-entity-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.46",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
+
"@acorex-platform/module-conversation-client": "0.0.46",
|
|
6
7
|
"@angular/common": "^21.0.0 || ^22.0.0",
|
|
7
8
|
"@angular/core": "^21.0.0 || ^22.0.0"
|
|
8
9
|
},
|
|
@@ -1,49 +1,43 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import * as i1 from '@acorex-platform/module-ai-management-client';
|
|
3
2
|
import { AXEAiEntityAssistCommandContext, AXEAiEntityAssistCommandInput } from '@acorex-platform/extension-ai-entity-client/contracts';
|
|
4
3
|
import { AXPEntityModifierProvider } from '@acorex-platform/framework-client/layout/entity';
|
|
5
4
|
import { AXPCommand, AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* AI assist command for entity records.
|
|
8
|
+
* The list-row menu entry is not registered; context is chosen from the header mini chat.
|
|
10
9
|
*/
|
|
11
10
|
declare class AXEAIEntityExtensionModule {
|
|
12
11
|
static ɵfac: i0.ɵɵFactoryDeclaration<AXEAIEntityExtensionModule, never>;
|
|
13
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<AXEAIEntityExtensionModule, never,
|
|
12
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<AXEAIEntityExtensionModule, never, never, never>;
|
|
14
13
|
static ɵinj: i0.ɵɵInjectorDeclaration<AXEAIEntityExtensionModule>;
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
|
-
* Opens
|
|
17
|
+
* Opens contextual assist for a single entity list row.
|
|
19
18
|
*/
|
|
20
19
|
declare class AXEAiEntityAssistService {
|
|
21
|
-
private readonly
|
|
20
|
+
private readonly launcher;
|
|
22
21
|
private readonly translationService;
|
|
23
22
|
private readonly toastService;
|
|
24
23
|
private readonly entityRegistry;
|
|
25
|
-
runFromCommandContext(context: AXEAiEntityAssistCommandContext): Promise<
|
|
24
|
+
runFromCommandContext(context: AXEAiEntityAssistCommandContext): Promise<boolean>;
|
|
26
25
|
static ɵfac: i0.ɵɵFactoryDeclaration<AXEAiEntityAssistService, never>;
|
|
27
26
|
static ɵprov: i0.ɵɵInjectableDeclaration<AXEAiEntityAssistService>;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
/** Runtime command key registered via {@link provideCommandSetups}. */
|
|
31
30
|
declare const AXE_AI_ENTITY_ASSIST_COMMAND = "AiEntity:Assist";
|
|
32
|
-
/**
|
|
33
|
-
declare const AXE_AI_ENTITY_ASSIST_ACTION
|
|
34
|
-
readonly typeLevel: "ai-entity-assist-type-level";
|
|
35
|
-
readonly selected: "ai-entity-assist-selected";
|
|
36
|
-
readonly individual: "ai-entity-assist-individual";
|
|
37
|
-
};
|
|
31
|
+
/** Individual row action name (resolved to {@link AXE_AI_ENTITY_ASSIST_COMMAND}). */
|
|
32
|
+
declare const AXE_AI_ENTITY_ASSIST_ACTION = "ai-entity-assist-individual";
|
|
38
33
|
|
|
39
34
|
/**
|
|
40
|
-
* Adds AI Assist to entity list
|
|
41
|
-
* and single view (Individual primary in header).
|
|
35
|
+
* Adds AI Assist to the entity list row menu (Individual, secondary).
|
|
42
36
|
*/
|
|
43
37
|
declare const AXEAiEntityActionsModifier: AXPEntityModifierProvider;
|
|
44
38
|
|
|
45
39
|
/**
|
|
46
|
-
* Entity list
|
|
40
|
+
* Entity list row AI assist — opens the contextual assist overlay with record context.
|
|
47
41
|
*/
|
|
48
42
|
declare class AXEAiEntityAssistCommand implements AXPCommand<AXEAiEntityAssistCommandInput, void> {
|
|
49
43
|
private readonly assist;
|