@acorex-platform/extension-ai-entity-client 0.0.38 → 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 ---- Command & action keys ----
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
- /** 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
- };
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 ---- Imports ----
19
+ //#region ----- Imports -----
23
20
  //#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
- ];
21
+ //#region ----- Constants -----
22
+ const MAX_COLUMNS = 24;
47
23
  //#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));
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
- //#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;
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
- //#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;
47
+ };
48
+ push('id');
49
+ for (const name of names) {
50
+ push(name);
130
51
  }
52
+ return columns;
131
53
  }
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');
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 resolveScope(options) {
159
- const scope = options?.scope;
160
- if (scope === AXPEntityCommandScope.TypeLevel ||
161
- scope === AXPEntityCommandScope.Selected ||
162
- scope === AXPEntityCommandScope.Individual) {
163
- return scope;
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 AXPEntityCommandScope.TypeLevel;
75
+ return '';
166
76
  }
167
77
  //#endregion
78
+
79
+ //#region ----- Imports -----
80
+ //#endregion
81
+ //#region ----- Service -----
168
82
  /**
169
- * Opens AI assist for entity CRUD views with entity schema and selection context.
83
+ * Opens contextual assist for a single entity list row.
170
84
  */
171
85
  class AXEAiEntityAssistService {
172
86
  constructor() {
173
- //#region ---- Services & Dependencies ----
174
- this.aiManager = inject(AXPAiManagerService, { optional: true });
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 ---- Public API ----
94
+ //#region ----- Public API -----
181
95
  async runFromCommandContext(context) {
182
- const ai = this.aiManager;
183
- if (!ai) {
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-ai-module');
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 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,
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
- 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,
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 ---- Imports ----
138
+ //#region ----- Imports -----
250
139
  //#endregion
251
- //#region ---- Module ----
140
+ //#region ----- Module -----
252
141
  /**
253
- * Optional AI assist on entity CRUD views (TypeLevel, Selected, Individual scopes).
254
- * Register next to {@link AXMAiManagementModule} in the application.
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, imports: [AXMAiManagementModule] }); }
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
- ], imports: [AXMAiManagementModule] }); }
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 ---- Command ----
222
+ //#region ----- Command -----
297
223
  /**
298
- * Entity list / row AI assist — opens {@link AXPAiManagerService} with entity schema and selection context.
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 ---- Services & Dependencies ----
228
+ //#region ----- Services & Dependencies -----
303
229
  this.assist = inject(AXEAiEntityAssistService);
304
230
  }
305
231
  //#endregion
306
- //#region ---- Command execution ----
232
+ //#region ----- Command execution -----
307
233
  async execute(input) {
308
- const result = await this.assist.runFromCommandContext(input);
309
- if (result == undefined) {
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.38",
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
- * Optional AI assist on entity CRUD views (TypeLevel, Selected, Individual scopes).
9
- * Register next to {@link AXMAiManagementModule} in the application.
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, [typeof i1.AXMAiManagementModule], 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 AI assist for entity CRUD views with entity schema and selection context.
17
+ * Opens contextual assist for a single entity list row.
19
18
  */
20
19
  declare class AXEAiEntityAssistService {
21
- private readonly aiManager;
20
+ private readonly launcher;
22
21
  private readonly translationService;
23
22
  private readonly toastService;
24
23
  private readonly entityRegistry;
25
- runFromCommandContext(context: AXEAiEntityAssistCommandContext): Promise<void>;
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
- /** 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
- };
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 (TypeLevel/Selected primary; Individual not a row command via priority `none`)
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 / row AI assist — opens {@link AXPAiManagerService} with entity schema and selection context.
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;