@praxisui/table 8.0.0-beta.26 → 8.0.0-beta.28
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/{praxisui-table-filter-form-dialog-host.component-CX2ga9Pq.mjs → praxisui-table-filter-form-dialog-host.component-CN9JWFoa.mjs} +47 -14
- package/fesm2022/praxisui-table-praxisui-table-CKnX_qQK.mjs +57015 -0
- package/fesm2022/{praxisui-table-table-agentic-authoring-turn-flow-DRuE55Mi.mjs → praxisui-table-table-agentic-authoring-turn-flow-BvOLCDkU.mjs} +30 -85
- package/fesm2022/{praxisui-table-table-ai.adapter-fS74fZ7o.mjs → praxisui-table-table-ai.adapter-DHNdWFmg.mjs} +30 -5
- package/fesm2022/praxisui-table.mjs +1 -56159
- package/index.d.ts +53 -8
- package/package.json +10 -10
|
@@ -26,9 +26,6 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
26
26
|
?.map((field) => this.toAiJsonObject(field))
|
|
27
27
|
.filter((field) => Object.keys(field).length > 0);
|
|
28
28
|
const contextHints = this.optionalJsonObject(this.adapter.getAuthoringContext?.());
|
|
29
|
-
if (this.shouldRouteToGovernedDecision(prompt, contextHints)) {
|
|
30
|
-
return this.toGovernedDecisionHandoff(prompt, request);
|
|
31
|
-
}
|
|
32
29
|
const response = await firstValueFrom(this.aiApi.getPatch({
|
|
33
30
|
componentId,
|
|
34
31
|
componentType,
|
|
@@ -133,6 +130,7 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
133
130
|
sessionId: response.sessionId ?? request.sessionId,
|
|
134
131
|
assistantMessage: message,
|
|
135
132
|
statusText: message,
|
|
133
|
+
quickReplies: this.toQuickReplies(response),
|
|
136
134
|
canApply: false,
|
|
137
135
|
};
|
|
138
136
|
}
|
|
@@ -149,12 +147,11 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
149
147
|
}
|
|
150
148
|
if (response.patch && Object.keys(response.patch).length > 0) {
|
|
151
149
|
const warnings = response.warnings?.filter(Boolean) ?? [];
|
|
152
|
-
const suffix = warnings.length ? ` Avisos: ${warnings.join('; ')}` : '';
|
|
153
150
|
return {
|
|
154
151
|
state: 'review',
|
|
155
152
|
phase: 'review',
|
|
156
153
|
sessionId: response.sessionId ?? request.sessionId,
|
|
157
|
-
assistantMessage:
|
|
154
|
+
assistantMessage: response.explanation || 'Proposta de alteracao pronta para revisar.',
|
|
158
155
|
statusText: 'Revise a proposta antes de aplicar.',
|
|
159
156
|
canApply: true,
|
|
160
157
|
pendingPatch: response.patch,
|
|
@@ -242,12 +239,17 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
242
239
|
return payloads
|
|
243
240
|
.map((option, index) => {
|
|
244
241
|
const label = option.label?.trim() || option.value?.trim() || `Opcao ${index + 1}`;
|
|
245
|
-
const prompt = option.
|
|
242
|
+
const prompt = option.value?.trim() || option.example?.trim() || label;
|
|
246
243
|
return {
|
|
247
244
|
id: `option-${index + 1}`,
|
|
248
245
|
label,
|
|
249
246
|
prompt,
|
|
250
247
|
kind: 'clarification-option',
|
|
248
|
+
description: this.optionDescription(option),
|
|
249
|
+
icon: this.optionIcon(option),
|
|
250
|
+
tone: this.optionTone(option),
|
|
251
|
+
presentation: this.optionPresentation(option),
|
|
252
|
+
contextHints: this.optionContextHints(option),
|
|
251
253
|
};
|
|
252
254
|
});
|
|
253
255
|
}
|
|
@@ -260,6 +262,28 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
260
262
|
kind: 'clarification-option',
|
|
261
263
|
}));
|
|
262
264
|
}
|
|
265
|
+
optionContextHints(option) {
|
|
266
|
+
return this.toRecord(option.contextHints);
|
|
267
|
+
}
|
|
268
|
+
optionPresentation(option) {
|
|
269
|
+
const hints = this.optionContextHints(option);
|
|
270
|
+
return this.toRecord(hints?.['presentation']);
|
|
271
|
+
}
|
|
272
|
+
optionDescription(option) {
|
|
273
|
+
const presentation = this.optionPresentation(option);
|
|
274
|
+
const value = presentation?.['description'];
|
|
275
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
276
|
+
}
|
|
277
|
+
optionIcon(option) {
|
|
278
|
+
const presentation = this.optionPresentation(option);
|
|
279
|
+
const value = presentation?.['icon'];
|
|
280
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
281
|
+
}
|
|
282
|
+
optionTone(option) {
|
|
283
|
+
const presentation = this.optionPresentation(option);
|
|
284
|
+
const value = presentation?.['tone'];
|
|
285
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
286
|
+
}
|
|
263
287
|
buildCurrentStateDigest(currentState, dataProfile) {
|
|
264
288
|
const columns = Array.isArray(currentState['columns'])
|
|
265
289
|
? currentState['columns']
|
|
@@ -272,85 +296,6 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
272
296
|
...(rowCount !== undefined ? { rowCount } : {}),
|
|
273
297
|
};
|
|
274
298
|
}
|
|
275
|
-
shouldRouteToGovernedDecision(prompt, contextHints) {
|
|
276
|
-
const normalized = prompt.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
|
|
277
|
-
const recommendedFlow = this.toRecord(contextHints?.['domainCatalog'])?.['recommendedAuthoringFlow'];
|
|
278
|
-
if (recommendedFlow === 'shared_rule_authoring')
|
|
279
|
-
return true;
|
|
280
|
-
return [
|
|
281
|
-
'regra',
|
|
282
|
-
'politica',
|
|
283
|
-
'policy',
|
|
284
|
-
'compliance',
|
|
285
|
-
'lgpd',
|
|
286
|
-
'privacidade',
|
|
287
|
-
'aprovacao',
|
|
288
|
-
'aprovar',
|
|
289
|
-
'publicar',
|
|
290
|
-
'materializar',
|
|
291
|
-
'enforcement',
|
|
292
|
-
'validacao de negocio',
|
|
293
|
-
'validar negocio',
|
|
294
|
-
'elegibilidade',
|
|
295
|
-
'permissao',
|
|
296
|
-
'acesso',
|
|
297
|
-
].some((term) => normalized.includes(term));
|
|
298
|
-
}
|
|
299
|
-
toGovernedDecisionHandoff(prompt, request) {
|
|
300
|
-
const message = 'Esse pedido parece alterar uma decisao de negocio compartilhada. A tabela pode ajudar a descrever o alvo, mas a regra deve seguir pelo fluxo governado de domain-rules antes de qualquer materializacao runtime.';
|
|
301
|
-
return {
|
|
302
|
-
state: 'clarification',
|
|
303
|
-
phase: 'clarify',
|
|
304
|
-
sessionId: request.sessionId,
|
|
305
|
-
assistantMessage: message,
|
|
306
|
-
statusText: 'Handoff governado necessario.',
|
|
307
|
-
canApply: false,
|
|
308
|
-
quickReplies: [
|
|
309
|
-
{
|
|
310
|
-
id: 'shared-rule-handoff',
|
|
311
|
-
label: 'Continuar como regra governada',
|
|
312
|
-
prompt,
|
|
313
|
-
kind: 'shared-rule-handoff',
|
|
314
|
-
description: 'Criar intake de domain-rules em vez de aplicar patch local na tabela.',
|
|
315
|
-
icon: 'rule',
|
|
316
|
-
tone: 'warning',
|
|
317
|
-
contextHints: {
|
|
318
|
-
flowId: 'shared_rule_authoring',
|
|
319
|
-
source: 'praxis-table',
|
|
320
|
-
recommendedAction: 'domain-rules/intake',
|
|
321
|
-
},
|
|
322
|
-
},
|
|
323
|
-
],
|
|
324
|
-
clarificationQuestions: [
|
|
325
|
-
{
|
|
326
|
-
id: 'table-governed-rule-confirmation',
|
|
327
|
-
type: 'confirm',
|
|
328
|
-
label: 'Deseja continuar pelo fluxo governado de regras compartilhadas?',
|
|
329
|
-
description: 'Esse caminho permite intake, simulacao, aprovacao/publicacao, materializacao e validacao de enforcement.',
|
|
330
|
-
required: true,
|
|
331
|
-
options: [
|
|
332
|
-
{
|
|
333
|
-
id: 'shared-rule-handoff',
|
|
334
|
-
label: 'Sim, continuar governado',
|
|
335
|
-
value: prompt,
|
|
336
|
-
description: 'Nao aplicar como patch local da tabela.',
|
|
337
|
-
contextHints: {
|
|
338
|
-
flowId: 'shared_rule_authoring',
|
|
339
|
-
source: 'praxis-table',
|
|
340
|
-
},
|
|
341
|
-
},
|
|
342
|
-
],
|
|
343
|
-
},
|
|
344
|
-
],
|
|
345
|
-
diagnostics: {
|
|
346
|
-
governedDecisionHandoff: {
|
|
347
|
-
flowId: 'shared_rule_authoring',
|
|
348
|
-
sourcePrompt: prompt,
|
|
349
|
-
sourceComponent: 'praxis-table',
|
|
350
|
-
},
|
|
351
|
-
},
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
299
|
optionalJsonObject(value) {
|
|
355
300
|
if (value === undefined || value === null) {
|
|
356
301
|
return undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { firstValueFrom } from 'rxjs';
|
|
2
2
|
import { BaseAiAdapter } from '@praxisui/ai';
|
|
3
3
|
import { deepMerge } from '@praxisui/core';
|
|
4
|
-
import { coerceTableComponentEditPlans, compileTableComponentEditPlans, TABLE_AI_CAPABILITIES, TASK_PRESETS, getTableComponentEditPlanCapabilities, TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, TABLE_COMPONENT_EDIT_PLAN_VERSION, TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, TABLE_COMPONENT_EDIT_PLAN_KIND } from './praxisui-table.mjs';
|
|
4
|
+
import { c as coerceTableComponentEditPlans, a as compileTableComponentEditPlans, T as TABLE_AI_CAPABILITIES, b as TASK_PRESETS, g as getTableComponentEditPlanCapabilities, d as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, e as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, f as TABLE_COMPONENT_EDIT_PLAN_OPERATION_IDS, h as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, i as TABLE_COMPONENT_EDIT_PLAN_VERSION, j as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, k as TABLE_COMPONENT_EDIT_PLAN_KIND } from './praxisui-table-praxisui-table-CKnX_qQK.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Analisa uma amostra de dados da tabela para gerar estatísticas
|
|
@@ -179,14 +179,16 @@ class TableAiAdapter extends BaseAiAdapter {
|
|
|
179
179
|
batchKind: TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND,
|
|
180
180
|
version: TABLE_COMPONENT_EDIT_PLAN_VERSION,
|
|
181
181
|
schemaId: TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA.$id,
|
|
182
|
+
allowedOperationIds: [...TABLE_COMPONENT_EDIT_PLAN_OPERATION_IDS],
|
|
182
183
|
allowedChangeKinds: [...TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS],
|
|
183
184
|
expectedPaths: { ...TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS },
|
|
184
185
|
capabilities: getTableComponentEditPlanCapabilities(),
|
|
185
186
|
rules: [
|
|
186
|
-
'Use componentEditPlan instead of free patch when the request fits an allowed table
|
|
187
|
+
'Use componentEditPlan instead of free patch when the request fits an allowed table operationId or changeKind.',
|
|
188
|
+
'Prefer manifest operationId for governed agentic authoring responses.',
|
|
187
189
|
'Use batch kind with operations for multiple table edits in one request.',
|
|
188
190
|
'Use Json Logic objects for computed expressions and conditional rules.',
|
|
189
|
-
'Do not invent fields, changeKinds, capabilityPaths, formats, badge variants, or colors outside the provided contract.',
|
|
191
|
+
'Do not invent fields, operationIds, changeKinds, capabilityPaths, formats, badge variants, or colors outside the provided contract.',
|
|
190
192
|
],
|
|
191
193
|
},
|
|
192
194
|
},
|
|
@@ -773,8 +775,8 @@ Columns Analysis:
|
|
|
773
775
|
});
|
|
774
776
|
}
|
|
775
777
|
/**
|
|
776
|
-
* If a patch adds
|
|
777
|
-
*
|
|
778
|
+
* If a patch adds a typed format, ensure the column type is set so the
|
|
779
|
+
* formatter runs. Avoid overriding an explicit type.
|
|
778
780
|
*/
|
|
779
781
|
normalizePatch(patch) {
|
|
780
782
|
if (!patch.columns || !Array.isArray(patch.columns))
|
|
@@ -792,9 +794,29 @@ Columns Analysis:
|
|
|
792
794
|
if (!format)
|
|
793
795
|
return false;
|
|
794
796
|
const fmt = format.trim();
|
|
797
|
+
if (this.looksLikeMaskFormat(fmt))
|
|
798
|
+
return false;
|
|
795
799
|
// Heuristics: contains date tokens like d/M/y or common date separators
|
|
796
800
|
return /(d|M|y){2,}/i.test(fmt) || fmt.includes('/') || fmt.includes('-');
|
|
797
801
|
}
|
|
802
|
+
looksLikeBooleanFormat(format) {
|
|
803
|
+
if (!format)
|
|
804
|
+
return false;
|
|
805
|
+
const fmt = format.trim();
|
|
806
|
+
return [
|
|
807
|
+
'true-false',
|
|
808
|
+
'yes-no',
|
|
809
|
+
'active-inactive',
|
|
810
|
+
'on-off',
|
|
811
|
+
'enabled-disabled',
|
|
812
|
+
].includes(fmt) || fmt.startsWith('custom|');
|
|
813
|
+
}
|
|
814
|
+
looksLikeMaskFormat(format) {
|
|
815
|
+
if (!format)
|
|
816
|
+
return false;
|
|
817
|
+
const fmt = format.trim();
|
|
818
|
+
return /[0#9X]/i.test(fmt) && /^[0#9X.\-/()\s]+$/i.test(fmt);
|
|
819
|
+
}
|
|
798
820
|
isIconRendererHint(renderer) {
|
|
799
821
|
if (!renderer)
|
|
800
822
|
return false;
|
|
@@ -812,6 +834,9 @@ Columns Analysis:
|
|
|
812
834
|
if (this.looksLikeCurrencyFormat(next.format)) {
|
|
813
835
|
next.type = 'currency';
|
|
814
836
|
}
|
|
837
|
+
else if (this.looksLikeBooleanFormat(next.format)) {
|
|
838
|
+
next.type = 'boolean';
|
|
839
|
+
}
|
|
815
840
|
else if (this.looksLikeDateFormat(next.format)) {
|
|
816
841
|
next.type = 'date';
|
|
817
842
|
}
|