@acorex-platform/extension-ai-entity-client 0.0.21
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-extension-ai-entity-client-contracts.mjs +9 -0
- package/fesm2022/acorex-platform-extension-ai-entity-client-contracts.mjs.map +1 -0
- package/fesm2022/acorex-platform-extension-ai-entity-client.mjs +331 -0
- package/fesm2022/acorex-platform-extension-ai-entity-client.mjs.map +1 -0
- package/package.json +28 -0
- package/types/acorex-platform-extension-ai-entity-client-contracts.d.ts +26 -0
- package/types/acorex-platform-extension-ai-entity-client.d.ts +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acorex-platform-extension-ai-entity-client-contracts.mjs","sources":["../../../../libs/extensions/ai/entity/contracts/src/ai-entity-assist.types.ts","../../../../libs/extensions/ai/entity/contracts/src/index.ts","../../../../libs/extensions/ai/entity/contracts/src/acorex-platform-extension-ai-entity-client-contracts.ts"],"sourcesContent":["import { AXPEntityCommandScope } from '@acorex-platform/framework-shared/entity';\n//#region ---- Command context ----\n\n/** Entity info passed from list / row command execution. */\nexport interface AXEAiEntityAssistEntityInfo {\n name: string;\n module: string;\n title: string;\n parentKey?: string;\n source?: string;\n}\n\n/** Options on the entity action command. */\nexport interface AXEAiEntityAssistCommandOptions {\n scope: AXPEntityCommandScope;\n}\n\n/** Flat entity-action input from list / table command execution. */\nexport interface AXEAiEntityAssistCommandContext {\n entity: string;\n entityInfo: AXEAiEntityAssistEntityInfo;\n data: unknown;\n options?: AXEAiEntityAssistCommandOptions;\n metadata?: unknown;\n}\n\n/** Input to {@link AXEAiEntityAssistCommand}. */\nexport type AXEAiEntityAssistCommandInput = AXEAiEntityAssistCommandContext;\n\n//#endregion\n","//#region ---- Contracts barrel ----\n\nexport * from './ai-entity-assist.types';\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AA6BA;;AC7BA;AAIA;;ACJA;;AAEG"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
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
|
+
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
|
+
import { AXToastService } from '@acorex/components/toast';
|
|
9
|
+
import { AXTranslationService } from '@acorex/core/translation';
|
|
10
|
+
|
|
11
|
+
//#region ---- Command & action keys ----
|
|
12
|
+
/** Runtime command key registered via {@link provideCommandSetups}. */
|
|
13
|
+
const AXE_AI_ENTITY_ASSIST_COMMAND = 'AiEntity:Assist';
|
|
14
|
+
/** Distinct action command names per scope (resolved to {@link AXE_AI_ENTITY_ASSIST_COMMAND}). */
|
|
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
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
|
|
22
|
+
//#region ---- Imports ----
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region ---- Modifier config ----
|
|
25
|
+
const AI_ASSIST_ORDER = 45;
|
|
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
|
+
];
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region ---- Helpers ----
|
|
49
|
+
function buildAssistAction(scope, commandName, titleKey, priority) {
|
|
50
|
+
return {
|
|
51
|
+
name: commandName,
|
|
52
|
+
title: titleKey,
|
|
53
|
+
command: {
|
|
54
|
+
name: AXE_AI_ENTITY_ASSIST_COMMAND,
|
|
55
|
+
options: {
|
|
56
|
+
scope
|
|
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));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region ---- Global modifier ----
|
|
75
|
+
/**
|
|
76
|
+
* Adds AI Assist to entity list (TypeLevel/Selected primary; Individual not a row command via priority `none`)
|
|
77
|
+
* and single view (Individual primary in header).
|
|
78
|
+
*/
|
|
79
|
+
const AXEAiEntityActionsModifier = {
|
|
80
|
+
entityName: '*',
|
|
81
|
+
modifier: (ctx) => {
|
|
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;
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
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;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function buildSystemInstruction(entity, scope, propertySummary) {
|
|
133
|
+
const truncated = (entity.properties?.length ?? 0) > propertySummary.length;
|
|
134
|
+
return [
|
|
135
|
+
'You are assisting a user working with an ACoreX Platform entity (CRUD list / record context).',
|
|
136
|
+
`Entity: ${entity.module}.${entity.name} (${entity.title}).`,
|
|
137
|
+
`Command scope: ${scopeLabel(scope)}.`,
|
|
138
|
+
'',
|
|
139
|
+
'Scope behavior:',
|
|
140
|
+
'- **typeLevel**: Help with list-level tasks (filters, sorting ideas, bulk create outlines, reporting questions) when no row is selected.',
|
|
141
|
+
'- **selected**: Answer using the provided array of selected records; prefer bulk-safe suggestions.',
|
|
142
|
+
'- **individual**: Focus on one record; you may suggest field-level edits the user can apply manually.',
|
|
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');
|
|
157
|
+
}
|
|
158
|
+
function resolveScope(options) {
|
|
159
|
+
const scope = options?.scope;
|
|
160
|
+
if (scope === AXPEntityCommandScope.TypeLevel ||
|
|
161
|
+
scope === AXPEntityCommandScope.Selected ||
|
|
162
|
+
scope === AXPEntityCommandScope.Individual) {
|
|
163
|
+
return scope;
|
|
164
|
+
}
|
|
165
|
+
return AXPEntityCommandScope.TypeLevel;
|
|
166
|
+
}
|
|
167
|
+
//#endregion
|
|
168
|
+
/**
|
|
169
|
+
* Opens AI assist for entity CRUD views with entity schema and selection context.
|
|
170
|
+
*/
|
|
171
|
+
class AXEAiEntityAssistService {
|
|
172
|
+
constructor() {
|
|
173
|
+
//#region ---- Services & Dependencies ----
|
|
174
|
+
this.aiManager = inject(AXPAiManagerService, { optional: true });
|
|
175
|
+
this.translationService = inject(AXTranslationService);
|
|
176
|
+
this.toastService = inject(AXToastService);
|
|
177
|
+
this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region ---- Public API ----
|
|
181
|
+
async runFromCommandContext(context) {
|
|
182
|
+
const ai = this.aiManager;
|
|
183
|
+
if (!ai) {
|
|
184
|
+
const title = await this.translationService.translateAsync('@general:messages.generic.warning.title');
|
|
185
|
+
const content = await this.translationService.translateAsync('@extensions-ai-entity:assist.no-ai-module');
|
|
186
|
+
await this.toastService.show({ color: 'warning', title, content });
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const { entityInfo, data, options } = context;
|
|
190
|
+
const scope = resolveScope(options);
|
|
191
|
+
const entity = await this.entityRegistry.resolve(entityInfo.module, entityInfo.name);
|
|
192
|
+
const propertySummary = summarizeProperties(entity.properties);
|
|
193
|
+
const systemInstruction = buildSystemInstruction(entity, scope, propertySummary);
|
|
194
|
+
const structuredContext = {
|
|
195
|
+
scenario: 'entity-crud-assist',
|
|
196
|
+
scope,
|
|
197
|
+
entity: {
|
|
198
|
+
module: entity.module,
|
|
199
|
+
name: entity.name,
|
|
200
|
+
title: entity.title,
|
|
201
|
+
source: entityInfo.source ?? `${entity.module}.${entity.name}`,
|
|
202
|
+
},
|
|
203
|
+
propertyCount: entity.properties?.length ?? 0,
|
|
204
|
+
properties: propertySummary,
|
|
205
|
+
data,
|
|
206
|
+
};
|
|
207
|
+
const dialogTitleKey = scope === AXPEntityCommandScope.Selected
|
|
208
|
+
? '@extensions-ai-entity:assist.dialog-title.selected'
|
|
209
|
+
: scope === AXPEntityCommandScope.Individual
|
|
210
|
+
? '@extensions-ai-entity:assist.dialog-title.individual'
|
|
211
|
+
: '@extensions-ai-entity:assist.dialog-title.type-level';
|
|
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,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAiEntityAssistService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
243
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAiEntityAssistService }); }
|
|
244
|
+
}
|
|
245
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAiEntityAssistService, decorators: [{
|
|
246
|
+
type: Injectable
|
|
247
|
+
}] });
|
|
248
|
+
|
|
249
|
+
//#region ---- Imports ----
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region ---- Module ----
|
|
252
|
+
/**
|
|
253
|
+
* Optional AI assist on entity CRUD views (TypeLevel, Selected, Individual scopes).
|
|
254
|
+
* Register next to {@link AXMAiManagementModule} in the application.
|
|
255
|
+
*/
|
|
256
|
+
class AXEAIEntityExtensionModule {
|
|
257
|
+
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, imports: [AXMAiManagementModule] }); }
|
|
259
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAIEntityExtensionModule, providers: [
|
|
260
|
+
AXEAiEntityAssistService,
|
|
261
|
+
{
|
|
262
|
+
provide: AXP_ENTITY_MODIFIER,
|
|
263
|
+
useValue: AXEAiEntityActionsModifier,
|
|
264
|
+
multi: true,
|
|
265
|
+
},
|
|
266
|
+
provideCommandSetups([
|
|
267
|
+
{
|
|
268
|
+
key: AXE_AI_ENTITY_ASSIST_COMMAND,
|
|
269
|
+
command: () => Promise.resolve().then(function () { return aiEntityAssist_command; }).then((c) => c.AXEAiEntityAssistCommand),
|
|
270
|
+
},
|
|
271
|
+
]),
|
|
272
|
+
], imports: [AXMAiManagementModule] }); }
|
|
273
|
+
}
|
|
274
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAIEntityExtensionModule, decorators: [{
|
|
275
|
+
type: NgModule,
|
|
276
|
+
args: [{
|
|
277
|
+
imports: [AXMAiManagementModule],
|
|
278
|
+
providers: [
|
|
279
|
+
AXEAiEntityAssistService,
|
|
280
|
+
{
|
|
281
|
+
provide: AXP_ENTITY_MODIFIER,
|
|
282
|
+
useValue: AXEAiEntityActionsModifier,
|
|
283
|
+
multi: true,
|
|
284
|
+
},
|
|
285
|
+
provideCommandSetups([
|
|
286
|
+
{
|
|
287
|
+
key: AXE_AI_ENTITY_ASSIST_COMMAND,
|
|
288
|
+
command: () => Promise.resolve().then(function () { return aiEntityAssist_command; }).then((c) => c.AXEAiEntityAssistCommand),
|
|
289
|
+
},
|
|
290
|
+
]),
|
|
291
|
+
],
|
|
292
|
+
}]
|
|
293
|
+
}] });
|
|
294
|
+
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region ---- Command ----
|
|
297
|
+
/**
|
|
298
|
+
* Entity list / row AI assist — opens {@link AXPAiManagerService} with entity schema and selection context.
|
|
299
|
+
*/
|
|
300
|
+
class AXEAiEntityAssistCommand {
|
|
301
|
+
constructor() {
|
|
302
|
+
//#region ---- Services & Dependencies ----
|
|
303
|
+
this.assist = inject(AXEAiEntityAssistService);
|
|
304
|
+
}
|
|
305
|
+
//#endregion
|
|
306
|
+
//#region ---- Command execution ----
|
|
307
|
+
async execute(input) {
|
|
308
|
+
const result = await this.assist.runFromCommandContext(input);
|
|
309
|
+
if (result == undefined) {
|
|
310
|
+
return { success: false };
|
|
311
|
+
}
|
|
312
|
+
return { success: true, kind: 'object', data: undefined };
|
|
313
|
+
}
|
|
314
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAiEntityAssistCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
315
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAiEntityAssistCommand }); }
|
|
316
|
+
}
|
|
317
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXEAiEntityAssistCommand, decorators: [{
|
|
318
|
+
type: Injectable
|
|
319
|
+
}] });
|
|
320
|
+
|
|
321
|
+
var aiEntityAssist_command = /*#__PURE__*/Object.freeze({
|
|
322
|
+
__proto__: null,
|
|
323
|
+
AXEAiEntityAssistCommand: AXEAiEntityAssistCommand
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Generated bundle index. Do not edit.
|
|
328
|
+
*/
|
|
329
|
+
|
|
330
|
+
export { AXEAIEntityExtensionModule, AXEAiEntityActionsModifier, AXEAiEntityAssistCommand, AXEAiEntityAssistService, AXE_AI_ENTITY_ASSIST_ACTION, AXE_AI_ENTITY_ASSIST_COMMAND };
|
|
331
|
+
//# sourceMappingURL=acorex-platform-extension-ai-entity-client.mjs.map
|
|
@@ -0,0 +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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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@acorex-platform/extension-ai-entity-client",
|
|
3
|
+
"version": "0.0.21",
|
|
4
|
+
"sideEffects": false,
|
|
5
|
+
"peerDependencies": {
|
|
6
|
+
"@angular/common": "^21.0.0",
|
|
7
|
+
"@angular/core": "^21.0.0"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"tslib": "^2.3.0"
|
|
11
|
+
},
|
|
12
|
+
"module": "fesm2022/acorex-platform-extension-ai-entity-client.mjs",
|
|
13
|
+
"typings": "types/acorex-platform-extension-ai-entity-client.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
"./package.json": {
|
|
16
|
+
"default": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./types/acorex-platform-extension-ai-entity-client.d.ts",
|
|
20
|
+
"default": "./fesm2022/acorex-platform-extension-ai-entity-client.mjs"
|
|
21
|
+
},
|
|
22
|
+
"./contracts": {
|
|
23
|
+
"types": "./types/acorex-platform-extension-ai-entity-client-contracts.d.ts",
|
|
24
|
+
"default": "./fesm2022/acorex-platform-extension-ai-entity-client-contracts.mjs"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"type": "module"
|
|
28
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AXPEntityCommandScope } from '@acorex-platform/framework-shared/entity';
|
|
2
|
+
|
|
3
|
+
/** Entity info passed from list / row command execution. */
|
|
4
|
+
interface AXEAiEntityAssistEntityInfo {
|
|
5
|
+
name: string;
|
|
6
|
+
module: string;
|
|
7
|
+
title: string;
|
|
8
|
+
parentKey?: string;
|
|
9
|
+
source?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Options on the entity action command. */
|
|
12
|
+
interface AXEAiEntityAssistCommandOptions {
|
|
13
|
+
scope: AXPEntityCommandScope;
|
|
14
|
+
}
|
|
15
|
+
/** Flat entity-action input from list / table command execution. */
|
|
16
|
+
interface AXEAiEntityAssistCommandContext {
|
|
17
|
+
entity: string;
|
|
18
|
+
entityInfo: AXEAiEntityAssistEntityInfo;
|
|
19
|
+
data: unknown;
|
|
20
|
+
options?: AXEAiEntityAssistCommandOptions;
|
|
21
|
+
metadata?: unknown;
|
|
22
|
+
}
|
|
23
|
+
/** Input to {@link AXEAiEntityAssistCommand}. */
|
|
24
|
+
type AXEAiEntityAssistCommandInput = AXEAiEntityAssistCommandContext;
|
|
25
|
+
|
|
26
|
+
export type { AXEAiEntityAssistCommandContext, AXEAiEntityAssistCommandInput, AXEAiEntityAssistCommandOptions, AXEAiEntityAssistEntityInfo };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import * as i1 from '@acorex-platform/module-ai-management-client';
|
|
3
|
+
import { AXEAiEntityAssistCommandContext, AXEAiEntityAssistCommandInput } from '@acorex-platform/extension-ai-entity-client/contracts';
|
|
4
|
+
import { AXPEntityModifierProvider } from '@acorex-platform/framework-client/layout/entity';
|
|
5
|
+
import { AXPCommand, AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Optional AI assist on entity CRUD views (TypeLevel, Selected, Individual scopes).
|
|
9
|
+
* Register next to {@link AXMAiManagementModule} in the application.
|
|
10
|
+
*/
|
|
11
|
+
declare class AXEAIEntityExtensionModule {
|
|
12
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AXEAIEntityExtensionModule, never>;
|
|
13
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<AXEAIEntityExtensionModule, never, [typeof i1.AXMAiManagementModule], never>;
|
|
14
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<AXEAIEntityExtensionModule>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Opens AI assist for entity CRUD views with entity schema and selection context.
|
|
19
|
+
*/
|
|
20
|
+
declare class AXEAiEntityAssistService {
|
|
21
|
+
private readonly aiManager;
|
|
22
|
+
private readonly translationService;
|
|
23
|
+
private readonly toastService;
|
|
24
|
+
private readonly entityRegistry;
|
|
25
|
+
runFromCommandContext(context: AXEAiEntityAssistCommandContext): Promise<void>;
|
|
26
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AXEAiEntityAssistService, never>;
|
|
27
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AXEAiEntityAssistService>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Runtime command key registered via {@link provideCommandSetups}. */
|
|
31
|
+
declare const AXE_AI_ENTITY_ASSIST_COMMAND = "AiEntity:Assist";
|
|
32
|
+
/** Distinct action command names per scope (resolved to {@link AXE_AI_ENTITY_ASSIST_COMMAND}). */
|
|
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
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Adds AI Assist to entity list (TypeLevel/Selected primary; Individual not a row command via priority `none`)
|
|
41
|
+
* and single view (Individual primary in header).
|
|
42
|
+
*/
|
|
43
|
+
declare const AXEAiEntityActionsModifier: AXPEntityModifierProvider;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Entity list / row AI assist — opens {@link AXPAiManagerService} with entity schema and selection context.
|
|
47
|
+
*/
|
|
48
|
+
declare class AXEAiEntityAssistCommand implements AXPCommand<AXEAiEntityAssistCommandInput, void> {
|
|
49
|
+
private readonly assist;
|
|
50
|
+
execute(input: AXEAiEntityAssistCommandInput): AXPCommandExecuteResultPromise<void>;
|
|
51
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AXEAiEntityAssistCommand, never>;
|
|
52
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AXEAiEntityAssistCommand>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { AXEAIEntityExtensionModule, AXEAiEntityActionsModifier, AXEAiEntityAssistCommand, AXEAiEntityAssistService, AXE_AI_ENTITY_ASSIST_ACTION, AXE_AI_ENTITY_ASSIST_COMMAND };
|