@praxisui/table 8.0.0-beta.52 → 8.0.0-beta.53

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.
@@ -39528,7 +39528,7 @@ class PraxisTable {
39528
39528
  if (this.aiAdapter || this.aiAdapterLoadStarted)
39529
39529
  return;
39530
39530
  this.aiAdapterLoadStarted = true;
39531
- import('./praxisui-table-table-ai.adapter-eGo1zPuy.mjs')
39531
+ import('./praxisui-table-table-ai.adapter-rtjGFq_B.mjs')
39532
39532
  .then(({ TableAiAdapter }) => {
39533
39533
  this.aiAdapter = new TableAiAdapter(this);
39534
39534
  this.initializeAiAssistantController();
@@ -39678,7 +39678,7 @@ class PraxisTable {
39678
39678
  initializeAiAssistantController() {
39679
39679
  if (!this.aiAdapter || this.aiAssistantController)
39680
39680
  return;
39681
- import('./praxisui-table-table-agentic-authoring-turn-flow-DtoCwCVX.mjs')
39681
+ import('./praxisui-table-table-agentic-authoring-turn-flow-B075RDUj.mjs')
39682
39682
  .then(({ TableAgenticAuthoringTurnFlow }) => {
39683
39683
  if (this.aiAssistantController || !this.aiAdapter)
39684
39684
  return;
@@ -48,11 +48,9 @@ class TableAgenticAuthoringTurnFlow {
48
48
  this.selectedRecordFieldsForTurn = this.extractSelectedRecordFields(contextHints);
49
49
  this.selectedRecordsCountForTurn = this.extractSelectedRecordsCount(contextHints);
50
50
  this.filterExpressionSupportedForTurn = this.resolveFilterExpressionSupported(contextHints);
51
- const localResponse = this.selectedRecordLocalResponse(request, contextHints);
52
51
  const messages = this.withCapabilitySystemMessages(this.toChatMessages(request.messages, prompt), contextHints);
53
52
  return {
54
53
  contextHints,
55
- ...(localResponse ? { localResponse } : {}),
56
54
  patchRequest: {
57
55
  componentId,
58
56
  componentType,
@@ -80,21 +78,8 @@ class TableAgenticAuthoringTurnFlow {
80
78
  return this.submitViaSnapshot(request, currentState, run);
81
79
  }
82
80
  async submitViaSnapshot(request, currentState, buildRequest) {
83
- const { patchRequest, contextHints, localResponse } = await buildRequest();
84
- if (localResponse) {
85
- return this.toTurnResult(this.compileAdapterResponse(localResponse, request), request);
86
- }
87
- let response;
88
- try {
89
- response = await firstValueFrom(this.aiApi.getPatch(patchRequest));
90
- }
91
- catch (error) {
92
- const recovery = this.selectedRecordBackendFailureClarification(request, contextHints ?? null, error);
93
- if (recovery) {
94
- return this.toTurnResult(recovery, request);
95
- }
96
- throw error;
97
- }
81
+ const { patchRequest } = await buildRequest();
82
+ const response = await firstValueFrom(this.aiApi.getPatch(patchRequest));
98
83
  return this.toTurnResult(this.compileAdapterResponse(this.groundRelativeColumnOrder(response, request, currentState), request), request);
99
84
  }
100
85
  submitViaStream(request, prompt, currentState, componentId, buildRequest) {
@@ -226,15 +211,8 @@ class TableAgenticAuthoringTurnFlow {
226
211
  void (async () => {
227
212
  try {
228
213
  emitProgress(this.buildInitialProgressMessage(prompt, componentId));
229
- const { patchRequest, contextHints, localResponse } = await buildRequest();
214
+ const { patchRequest, contextHints } = await buildRequest();
230
215
  streamContextHints = contextHints ?? null;
231
- if (localResponse) {
232
- subscriber.next(this.toTurnResult(this.compileAdapterResponse(localResponse, request), request));
233
- subscriber.complete();
234
- closed = true;
235
- closeConnection();
236
- return;
237
- }
238
216
  if (this.shouldUseSelectedRecordSurfaceSnapshotFallback(streamContextHints)) {
239
217
  const result = await this.submitViaSnapshot(request, currentState, buildRequest);
240
218
  if (!closed) {
@@ -574,26 +552,6 @@ class TableAgenticAuthoringTurnFlow {
574
552
  isTurnInProgressResponse(response) {
575
553
  return this.normalizeLabel(response.code ?? '') === 'turn in progress';
576
554
  }
577
- selectedRecordLocalResponse(request, contextHints) {
578
- if (this.authoringContractHasResponseModes(contextHints)) {
579
- return this.completeSelectedRecordFilterClarification(request, contextHints);
580
- }
581
- return this.selectedRecordMissingSelectionAnswer(request, contextHints)
582
- ?? this.selectedRecordExportOnlyRequest(request, contextHints)
583
- ?? this.selectedRecordSingleCandidateQuestionAnswer(request, contextHints)
584
- ?? this.selectedRecordFieldQuestionAnswer(request, contextHints)
585
- ?? this.selectedRecordMultiFieldQuestionAnswer(request, contextHints)
586
- ?? this.completeSelectedRecordFilterApplyRequest(request, contextHints)
587
- ?? this.selectedRecordCommonQuestionAnswer(request, contextHints)
588
- ?? this.completeSelectedRecordFilterClarification(request, contextHints)
589
- ?? this.selectedRecordMultipleFilterFieldClarification(request, contextHints)
590
- ?? this.selectedRecordSimilarityClarification(request, contextHints);
591
- }
592
- authoringContractHasResponseModes(contextHints) {
593
- const authoringContract = this.toRecord(contextHints?.['authoringContract']);
594
- return Array.isArray(authoringContract?.['responseModes'])
595
- && authoringContract['responseModes'].length > 0;
596
- }
597
555
  compileAdapterResponse(response, request) {
598
556
  if (response.type === 'clarification' || response.type === 'info' || response.type === 'error') {
599
557
  return response;
@@ -700,851 +658,6 @@ class TableAgenticAuthoringTurnFlow {
700
658
  .map((operation) => this.toRecord(operation))
701
659
  .some((operation) => this.stringValue(operation?.['operationId']) === 'table.filter.apply');
702
660
  }
703
- completeSelectedRecordFilterClarification(request, contextHints) {
704
- if (request.action?.kind !== 'clarify')
705
- return null;
706
- const selectedRecordsFilter = this.toRecord(contextHints?.['selectedRecordsFilter']);
707
- const field = this.stringValue(selectedRecordsFilter?.['field']);
708
- if (!field)
709
- return null;
710
- const candidate = this.selectedRecordFilterCandidate(contextHints, field);
711
- const criteria = this.toRecord(candidate?.['criteria']);
712
- if (!criteria || Object.keys(criteria).length === 0)
713
- return null;
714
- const label = this.stringValue(candidate?.['label'])
715
- || this.stringValue(selectedRecordsFilter?.['label'])
716
- || this.humanizeFilterField(field);
717
- return this.selectedRecordFilterApplyResponse(label, criteria, [
718
- 'selected-record-filter-clarification-materialized',
719
- 'Clarification choice carried canonical filter field context; selectedRecordsContext.filterCandidates supplied runtime criteria.',
720
- ], request, contextHints);
721
- }
722
- completeSelectedRecordFilterApplyRequest(request, contextHints) {
723
- if (this.selectedRecordsCountForTurn <= 0)
724
- return null;
725
- const prompt = this.selectedRecordFilterGroundingPrompt(request, contextHints);
726
- if (!prompt || !this.selectedRecordFilterApplyRequested(prompt))
727
- return null;
728
- const availableCandidates = this.selectedRecordFilterCandidates(contextHints)
729
- .filter((candidate) => {
730
- const field = this.stringValue(candidate['field']);
731
- const criteria = this.toRecord(candidate['criteria']);
732
- return !!field
733
- && !!criteria
734
- && Object.keys(criteria).length > 0;
735
- });
736
- const candidates = availableCandidates
737
- .map((candidate) => ({
738
- candidate,
739
- score: this.selectedRecordFilterPromptGroundingScore(prompt, candidate),
740
- }))
741
- .filter((entry) => entry.score > 0)
742
- .sort((left, right) => right.score - left.score);
743
- if (!candidates.length)
744
- return null;
745
- if (candidates.length > 1 && candidates[0].score === candidates[1].score)
746
- return null;
747
- const candidate = candidates[0].candidate;
748
- const field = this.stringValue(candidate['field']);
749
- const criteria = this.toRecord(candidate['criteria']);
750
- if (!field || !criteria)
751
- return null;
752
- const label = this.stringValue(candidate['label']) || this.humanizeFilterField(field);
753
- return this.selectedRecordFilterApplyResponse(label, criteria, [
754
- 'selected-record-filter-request-materialized',
755
- 'Selected records supplied canonical filterCandidates; user prompt grounded one candidate through the declared filter field catalog.',
756
- ], request, contextHints);
757
- }
758
- selectedRecordFieldQuestionAnswer(request, contextHints) {
759
- if (this.selectedRecordsCountForTurn !== 1)
760
- return null;
761
- const prompt = request.prompt ?? '';
762
- const normalizedPrompt = this.normalizeLabel(prompt);
763
- if (!this.selectedRecordInformationalQuestionRequested(normalizedPrompt))
764
- return null;
765
- if (this.selectedRecordFilterApplyRequested(prompt))
766
- return null;
767
- const row = this.selectedRecordSampleRows(contextHints)[0];
768
- if (!row)
769
- return null;
770
- const candidates = Object.keys(row)
771
- .map((field) => ({
772
- field,
773
- score: this.selectedRecordQuestionFieldScore(normalizedPrompt, field),
774
- }))
775
- .filter((entry) => entry.score > 0)
776
- .sort((left, right) => right.score - left.score);
777
- const field = candidates.length
778
- ? this.singleTopSelectedRecordQuestionField(candidates)
779
- : this.singleTemporalSelectedRecordField(normalizedPrompt, row);
780
- if (!field)
781
- return null;
782
- const value = row[field];
783
- if (value === undefined || value === null || value === '')
784
- return null;
785
- const label = this.selectedRecordFieldLabel(field);
786
- return {
787
- type: 'info',
788
- message: `${label} do registro selecionado: ${this.formatSelectedRecordFilterValue(value)}.`,
789
- warnings: [
790
- 'selected-record-field-question-answered-locally',
791
- 'Single selected record supplied sampleRows; local answer grounded a field-level informational question before remote authoring.',
792
- ],
793
- };
794
- }
795
- selectedRecordSingleCandidateQuestionAnswer(request, contextHints) {
796
- if (this.selectedRecordsCountForTurn !== 1)
797
- return null;
798
- const prompt = request.prompt ?? '';
799
- const normalizedPrompt = this.normalizeLabel(prompt);
800
- if (!this.selectedRecordInformationalQuestionRequested(normalizedPrompt))
801
- return null;
802
- if (this.selectedRecordFilterApplyRequested(prompt))
803
- return null;
804
- const candidates = this.selectedRecordFilterCandidates(contextHints)
805
- .map((candidate) => ({
806
- candidate,
807
- score: this.selectedRecordCandidateQuestionScore(normalizedPrompt, candidate),
808
- }))
809
- .filter((entry) => entry.score > 0)
810
- .sort((left, right) => right.score - left.score);
811
- if (!candidates.length)
812
- return null;
813
- if (candidates.length > 1 && candidates[0].score === candidates[1].score)
814
- return null;
815
- const candidate = candidates[0].candidate;
816
- const values = this.selectedRecordCandidateDisplayValues(candidate);
817
- if (values.length !== 1)
818
- return null;
819
- const label = this.selectedRecordCandidateDisplayLabel(candidate);
820
- return {
821
- type: 'info',
822
- message: `${label} do registro selecionado: ${values[0]}.`,
823
- warnings: [
824
- 'selected-record-candidate-question-answered-locally',
825
- 'Single selected record supplied canonical filterCandidates; local answer used declared filter catalog metadata instead of materializing a table operation.',
826
- ],
827
- };
828
- }
829
- selectedRecordMissingSelectionAnswer(request, contextHints) {
830
- if (this.selectedRecordsCountForTurn > 0)
831
- return null;
832
- const normalizedPrompt = this.normalizeLabel(request.prompt ?? '');
833
- if (!this.selectedRecordReferentialRecordsPrompt(normalizedPrompt)
834
- && !this.selectedRecordExplicitSelectionPrompt(normalizedPrompt)) {
835
- return null;
836
- }
837
- if (!this.selectedRecordsContextExplicitlyEmpty(contextHints)
838
- && !this.selectedRecordMissingSelectionQuestionRequested(normalizedPrompt)) {
839
- return null;
840
- }
841
- return {
842
- type: 'info',
843
- message: 'Não encontrei registros selecionados na tabela. Selecione um ou mais registros para eu responder usando esse contexto.',
844
- warnings: [
845
- 'selected-record-context-missing',
846
- 'Prompt referenced selected/current records, but runtime.selectedRecordsContext reported no selected rows.',
847
- ],
848
- };
849
- }
850
- selectedRecordReferentialRecordsPrompt(normalizedPrompt) {
851
- if (!normalizedPrompt)
852
- return false;
853
- return [
854
- 'esses registros',
855
- 'estes registros',
856
- 'essas linhas',
857
- 'estas linhas',
858
- 'esses aqui',
859
- 'essas aqui',
860
- ].some((token) => this.normalizedTextContainsApproxPhrase(normalizedPrompt, token));
861
- }
862
- selectedRecordExplicitSelectionPrompt(normalizedPrompt) {
863
- if (!normalizedPrompt)
864
- return false;
865
- return [
866
- 'selecionado',
867
- 'selecionados',
868
- 'selecionada',
869
- 'selecionadas',
870
- ].some((token) => this.normalizedTextContainsApproxPhrase(normalizedPrompt, token));
871
- }
872
- selectedRecordMissingSelectionQuestionRequested(normalizedPrompt) {
873
- return this.selectedRecordInformationalQuestionRequested(normalizedPrompt)
874
- && this.selectedRecordPromptGroundsKnownFilterField(normalizedPrompt);
875
- }
876
- selectedRecordPromptGroundsKnownFilterField(normalizedPrompt) {
877
- if (!normalizedPrompt)
878
- return false;
879
- return this.filterFieldCatalogEntries.some((entry) => [
880
- entry.name,
881
- entry.label,
882
- ...entry.aliases,
883
- ...entry.relatedColumnLabels,
884
- ...entry.relatedColumnFields,
885
- ].some((candidate) => this.promptContainsAnyVariant(normalizedPrompt, candidate)));
886
- }
887
- selectedRecordsContextExplicitlyEmpty(contextHints) {
888
- const authoringContract = this.toRecord(contextHints?.['authoringContract']);
889
- const consultativeContext = this.toRecord(authoringContract?.['consultativeContext']);
890
- const selectedRecordsContext = this.toRecord(consultativeContext?.['selectedRecordsContext'])
891
- ?? this.toRecord(contextHints?.['selectedRecordsContext']);
892
- return !!selectedRecordsContext && this.extractSelectedRecordsCount(contextHints) <= 0;
893
- }
894
- singleTopSelectedRecordQuestionField(candidates) {
895
- if (!candidates.length)
896
- return null;
897
- if (candidates.length > 1 && candidates[0].score === candidates[1].score)
898
- return null;
899
- return candidates[0].field;
900
- }
901
- singleTemporalSelectedRecordField(normalizedPrompt, row) {
902
- if (!/(^|\s)quando\s/u.test(normalizedPrompt))
903
- return null;
904
- const temporalFields = Object.keys(row)
905
- .filter((field) => this.isDateOnlyValue(row[field]));
906
- return temporalFields.length === 1 ? temporalFields[0] : null;
907
- }
908
- isDateOnlyValue(value) {
909
- return typeof value === 'string' && /^\d{4}-\d{2}-\d{2}$/u.test(value.trim());
910
- }
911
- selectedRecordCommonQuestionAnswer(request, contextHints) {
912
- if (this.selectedRecordsCountForTurn < 2)
913
- return null;
914
- const prompt = request.prompt ?? '';
915
- const normalizedPrompt = this.normalizeLabel(prompt);
916
- if (!this.selectedRecordCommonQuestionRequested(normalizedPrompt))
917
- return null;
918
- if (this.selectedRecordCommonQuestionAlsoRequestsFilter(normalizedPrompt))
919
- return null;
920
- const rows = this.selectedRecordSampleRows(contextHints);
921
- if (rows.length < 2)
922
- return null;
923
- const requestedField = this.selectedRecordRequestedCommonField(normalizedPrompt, rows[0]);
924
- if (requestedField) {
925
- return this.selectedRecordFieldCommonAnswer(requestedField, rows);
926
- }
927
- const commonEntries = this.selectedRecordCommonEntries(rows).slice(0, 4);
928
- if (!commonEntries.length) {
929
- return {
930
- type: 'info',
931
- message: `Não encontrei um valor comum evidente nos ${rows.length} registros selecionados.`,
932
- warnings: [
933
- 'selected-record-common-question-answered-locally',
934
- 'Selected records supplied sampleRows; local answer summarized common values without materializing table operations.',
935
- ],
936
- };
937
- }
938
- const summary = commonEntries
939
- .map((entry) => `${entry.label}: ${entry.value}`)
940
- .join('; ');
941
- return {
942
- type: 'info',
943
- message: `Em comum nos ${rows.length} registros selecionados: ${summary}.`,
944
- warnings: [
945
- 'selected-record-common-question-answered-locally',
946
- 'Selected records supplied sampleRows; local answer summarized common values without materializing table operations.',
947
- ],
948
- };
949
- }
950
- selectedRecordMultiFieldQuestionAnswer(request, contextHints) {
951
- if (this.selectedRecordsCountForTurn < 2)
952
- return null;
953
- const prompt = request.prompt ?? '';
954
- const normalizedPrompt = this.normalizeLabel(prompt);
955
- if (!this.selectedRecordMultiFieldQuestionRequested(normalizedPrompt))
956
- return null;
957
- if (this.selectedRecordCommonQuestionAlsoRequestsFilter(normalizedPrompt))
958
- return null;
959
- const rows = this.selectedRecordSampleRows(contextHints);
960
- if (rows.length < 2)
961
- return null;
962
- const requestedField = this.selectedRecordRequestedCommonField(normalizedPrompt, rows[0]);
963
- if (requestedField) {
964
- const numericRangeAnswer = this.selectedRecordNumericMinMaxAnswer(normalizedPrompt, requestedField, rows);
965
- if (numericRangeAnswer)
966
- return numericRangeAnswer;
967
- const candidateAnswer = this.selectedRecordCandidateCommonAnswer(normalizedPrompt, contextHints, rows.length);
968
- if (candidateAnswer)
969
- return candidateAnswer;
970
- return this.selectedRecordFieldCommonAnswer(requestedField, rows);
971
- }
972
- const candidateAnswer = this.selectedRecordCandidateCommonAnswer(normalizedPrompt, contextHints, rows.length);
973
- if (candidateAnswer)
974
- return candidateAnswer;
975
- return null;
976
- }
977
- selectedRecordNumericMinMaxAnswer(normalizedPrompt, field, rows) {
978
- const asksMinMax = ['menor', 'minimo', 'mínimo', 'maior', 'maximo', 'máximo'].some((token) => (this.normalizedTextContainsApproxToken(normalizedPrompt, token)));
979
- if (!asksMinMax)
980
- return null;
981
- const values = rows
982
- .map((row) => row[field])
983
- .filter((value) => typeof value === 'number' && Number.isFinite(value));
984
- if (!values.length)
985
- return null;
986
- const min = Math.min(...values);
987
- const max = Math.max(...values);
988
- const label = this.selectedRecordFieldLabel(field);
989
- return {
990
- type: 'info',
991
- message: `${label} nos ${rows.length} registros selecionados: menor ${this.formatSelectedRecordFilterValue(min)} e maior ${this.formatSelectedRecordFilterValue(max)}.`,
992
- warnings: [
993
- 'selected-record-common-question-answered-locally',
994
- 'Selected records supplied sampleRows; local answer summarized numeric min/max without materializing table operations.',
995
- ],
996
- };
997
- }
998
- selectedRecordCandidateCommonAnswer(normalizedPrompt, contextHints, rowCount) {
999
- const candidates = this.selectedRecordFilterCandidates(contextHints)
1000
- .map((candidate) => ({
1001
- candidate,
1002
- score: this.selectedRecordCandidateQuestionScore(normalizedPrompt, candidate),
1003
- }))
1004
- .filter((entry) => entry.score > 0)
1005
- .sort((left, right) => right.score - left.score);
1006
- if (!candidates.length)
1007
- return null;
1008
- if (candidates.length > 1 && candidates[0].score === candidates[1].score)
1009
- return null;
1010
- const candidate = candidates[0].candidate;
1011
- const label = this.stringValue(candidate['label'])
1012
- || this.humanizeFilterField(this.stringValue(candidate['field']))
1013
- || 'Campo';
1014
- const values = this.selectedRecordCandidateDisplayValues(candidate);
1015
- if (!values.length)
1016
- return null;
1017
- const message = values.length === 1
1018
- ? `${label} em comum nos ${rowCount} registros selecionados: ${values[0]}.`
1019
- : `${label} nos ${rowCount} registros selecionados: ${values.slice(0, 5).join(', ')}${values.length > 5 ? ', ...' : ''}.`;
1020
- return {
1021
- type: 'info',
1022
- message,
1023
- warnings: [
1024
- 'selected-record-common-question-answered-locally',
1025
- 'Selected records supplied canonical filterCandidates; local answer summarized candidate values without materializing table operations.',
1026
- ],
1027
- };
1028
- }
1029
- selectedRecordCandidateQuestionScore(normalizedPrompt, candidate) {
1030
- let score = 0;
1031
- const candidateLabel = this.stringValue(candidate['label']);
1032
- const field = this.stringValue(candidate['field']);
1033
- const entry = this.filterFieldCatalogEntries.find((candidateEntry) => candidateEntry.name === field);
1034
- score += candidateLabel && this.promptContainsAnyVariant(normalizedPrompt, candidateLabel) ? 70 : 0;
1035
- score += field && this.promptContainsAnyVariant(normalizedPrompt, this.humanizeFilterField(field)) ? 50 : 0;
1036
- for (const value of [
1037
- ...this.stringArrayValue(candidate['aliases']),
1038
- ...(entry?.aliases ?? []),
1039
- ...this.selectedRecordCandidateDisplayValues(candidate),
1040
- ...this.stringArrayValue(candidate['relatedColumnLabels']),
1041
- ...(entry?.relatedColumnLabels ?? []),
1042
- ...this.stringArrayValue(candidate['relatedColumnFields']),
1043
- ...(entry?.relatedColumnFields ?? []),
1044
- ]) {
1045
- score += this.promptContainsAnyVariant(normalizedPrompt, value) ? 80 : 0;
1046
- }
1047
- return score;
1048
- }
1049
- selectedRecordCandidateDisplayLabel(candidate) {
1050
- const field = this.stringValue(candidate['field']);
1051
- const entry = this.filterFieldCatalogEntries.find((candidateEntry) => candidateEntry.name === field);
1052
- return this.stringArrayValue(candidate['relatedColumnLabels'])[0]
1053
- || entry?.relatedColumnLabels[0]
1054
- || this.stringValue(candidate['label'])
1055
- || entry?.label
1056
- || this.humanizeFilterField(field)
1057
- || 'Campo';
1058
- }
1059
- selectedRecordCandidateDisplayValues(candidate) {
1060
- const displayValues = Array.isArray(candidate['displayValues'])
1061
- ? candidate['displayValues']
1062
- .map((entry) => this.formatSelectedRecordFilterValue(entry))
1063
- .filter((entry) => !!entry)
1064
- : [];
1065
- if (displayValues.length)
1066
- return displayValues;
1067
- const criteria = this.toRecord(candidate['criteria']);
1068
- const field = this.stringValue(candidate['field']);
1069
- const value = field ? criteria?.[field] : undefined;
1070
- if (Array.isArray(value)) {
1071
- return value
1072
- .map((entry) => this.formatSelectedRecordFilterValue(entry))
1073
- .filter((entry, index, values) => !!entry && values.indexOf(entry) === index);
1074
- }
1075
- const record = this.toRecord(value);
1076
- if (record) {
1077
- const start = record['start'] ?? record['startDate'];
1078
- const end = record['end'] ?? record['endDate'];
1079
- if (start !== undefined && end !== undefined) {
1080
- return [`${this.formatSelectedRecordFilterValue(start)} até ${this.formatSelectedRecordFilterValue(end)}`];
1081
- }
1082
- }
1083
- return value === undefined || value === null
1084
- ? []
1085
- : [this.formatSelectedRecordFilterValue(value)];
1086
- }
1087
- selectedRecordMultiFieldQuestionRequested(normalizedPrompt) {
1088
- if (this.selectedRecordInformationalQuestionRequested(normalizedPrompt))
1089
- return true;
1090
- return /(^|\s)(eles|elas|esses|essas|estes|estas)\s+(estao|sao|ficam|ficaram|tem|têm)\s/u.test(normalizedPrompt);
1091
- }
1092
- selectedRecordCommonQuestionRequested(normalizedPrompt) {
1093
- if (!normalizedPrompt)
1094
- return false;
1095
- return ['comum', 'igual', 'padrao', 'mesma', 'mesmo'].some((token) => (this.normalizedTextContainsApproxToken(normalizedPrompt, token)));
1096
- }
1097
- selectedRecordCommonQuestionAlsoRequestsFilter(normalizedPrompt) {
1098
- if (this.selectedRecordOperationalAudienceRequested(normalizedPrompt))
1099
- return true;
1100
- return ['filtro', 'filtrar', 'filtre', 'filtra', 'aplique', 'aplicar', 'buscar', 'busque', 'procure', 'exportar', 'mostra', 'mostre', 'traz', 'traga', 'trazer', 'outro', 'outros', 'pega', 'pegue', 'acha', 'ache', 'encontra', 'encontre'].some((token) => (this.normalizedTextContainsApproxToken(normalizedPrompt, token)));
1101
- }
1102
- selectedRecordOperationalAudienceRequested(normalizedPrompt) {
1103
- if (!normalizedPrompt)
1104
- return false;
1105
- // Post-grounding bridge only: this distinguishes "show people/records like these"
1106
- // from an informational field question. Canonical filterCandidates still decide
1107
- // which field can be materialized.
1108
- return /(^|\s)(gente|pessoas|pessoal)\s+com\s+(os\s+|as\s+)?(mesmos|mesmas|mesmo|mesma)\b/u.test(normalizedPrompt);
1109
- }
1110
- selectedRecordRequestedCommonField(normalizedPrompt, row) {
1111
- const candidates = Object.keys(row)
1112
- .map((field) => ({
1113
- field,
1114
- score: this.selectedRecordQuestionFieldScore(normalizedPrompt, field),
1115
- }))
1116
- .filter((entry) => entry.score > 0)
1117
- .sort((left, right) => right.score - left.score);
1118
- return this.singleTopSelectedRecordQuestionField(candidates)
1119
- ?? this.selectedRecordRequestedFieldByValue(normalizedPrompt, row);
1120
- }
1121
- selectedRecordRequestedFieldByValue(normalizedPrompt, row) {
1122
- const candidates = Object.keys(row)
1123
- .filter((field) => {
1124
- const value = row[field];
1125
- if (value === undefined || value === null || value === '')
1126
- return false;
1127
- const formatted = this.formatSelectedRecordFilterValue(value);
1128
- return this.filterFieldMentionVariants(formatted)
1129
- .some((variant) => !!variant && this.normalizedTextContainsApproxPhrase(normalizedPrompt, variant));
1130
- });
1131
- return candidates.length === 1 ? candidates[0] : null;
1132
- }
1133
- selectedRecordFieldCommonAnswer(field, rows) {
1134
- const label = this.selectedRecordFieldLabel(field);
1135
- const values = this.selectedRecordDistinctFormattedValues(rows, field);
1136
- if (!values.length)
1137
- return null;
1138
- const message = values.length === 1
1139
- ? `${label} em comum nos ${rows.length} registros selecionados: ${values[0]}.`
1140
- : `${label} não é comum nos ${rows.length} registros selecionados. Valores encontrados: ${values.slice(0, 5).join(', ')}${values.length > 5 ? ', ...' : ''}.`;
1141
- return {
1142
- type: 'info',
1143
- message,
1144
- warnings: [
1145
- 'selected-record-common-question-answered-locally',
1146
- 'Selected records supplied sampleRows; local answer summarized a requested field without materializing table operations.',
1147
- ],
1148
- };
1149
- }
1150
- selectedRecordCommonEntries(rows) {
1151
- return Object.keys(rows[0] ?? {})
1152
- .map((field) => ({
1153
- field,
1154
- values: this.selectedRecordDistinctFormattedValues(rows, field),
1155
- }))
1156
- .filter((entry) => entry.values.length === 1)
1157
- .map((entry) => ({
1158
- label: this.selectedRecordFieldLabel(entry.field),
1159
- value: entry.values[0],
1160
- }));
1161
- }
1162
- selectedRecordDistinctFormattedValues(rows, field) {
1163
- return rows
1164
- .map((row) => row[field])
1165
- .filter((value) => value !== undefined && value !== null && value !== '')
1166
- .map((value) => this.formatSelectedRecordFilterValue(value))
1167
- .filter((value, index, values) => value && values.indexOf(value) === index);
1168
- }
1169
- selectedRecordInformationalQuestionRequested(normalizedPrompt) {
1170
- if (!normalizedPrompt)
1171
- return false;
1172
- return /(^|\s)(qual|quais|quando|quanto|quantos|quantas|quem)\s/u.test(normalizedPrompt);
1173
- }
1174
- selectedRecordQuestionFieldScore(normalizedPrompt, field) {
1175
- const rawCandidates = [
1176
- field,
1177
- this.humanizeField(field),
1178
- this.selectedRecordFieldLabel(field),
1179
- ...this.filterFieldCatalogEntries
1180
- .filter((entry) => entry.name === field || entry.relatedColumnFields.includes(field))
1181
- .flatMap((entry) => [
1182
- entry.label,
1183
- ...entry.aliases,
1184
- ...entry.relatedColumnLabels,
1185
- ...entry.relatedColumnFields,
1186
- ]),
1187
- ];
1188
- return rawCandidates
1189
- .flatMap((candidate) => this.filterFieldMentionVariants(candidate ?? ''))
1190
- .reduce((score, candidate) => (candidate && this.normalizedTextContainsApproxPhrase(normalizedPrompt, candidate)
1191
- ? Math.max(score, candidate.split(/\s+/u).length > 1 ? 80 : 50)
1192
- : score), 0);
1193
- }
1194
- selectedRecordFieldLabel(field) {
1195
- const entry = this.filterFieldCatalogEntries
1196
- .find((candidate) => candidate.name === field || candidate.relatedColumnFields.includes(field));
1197
- return entry?.relatedColumnLabels[0] || entry?.label || this.humanizeField(field);
1198
- }
1199
- selectedRecordSimilarityClarification(request, contextHints) {
1200
- if (this.selectedRecordsCountForTurn <= 0)
1201
- return null;
1202
- const prompt = this.selectedRecordFilterGroundingPrompt(request, contextHints);
1203
- if (!prompt || !this.selectedRecordSimilarityRequested(prompt))
1204
- return null;
1205
- const candidateFields = this.selectedRecordFilterCandidates(contextHints)
1206
- .map((candidate) => this.stringValue(candidate['field']))
1207
- .filter((field, index, fields) => !!field && fields.indexOf(field) === index);
1208
- if (candidateFields.length < 2)
1209
- return null;
1210
- const mentionedFields = candidateFields
1211
- .filter((field) => this.promptMentionsFilterField(prompt, field));
1212
- if (mentionedFields.length === 1)
1213
- return null;
1214
- const options = this.selectedRecordFilterClarificationOptionEntries(candidateFields);
1215
- if (options.length < 2)
1216
- return null;
1217
- return {
1218
- type: 'clarification',
1219
- message: [
1220
- `Encontrei ${this.selectedRecordsCountForTurn} registro${this.selectedRecordsCountForTurn === 1 ? '' : 's'} selecionado${this.selectedRecordsCountForTurn === 1 ? '' : 's'}.`,
1221
- `Para buscar registros parecidos, escolha qual propriedade deve guiar o filtro: ${this.joinHumanList(options.map((option) => option.label))}.`,
1222
- ].join(' '),
1223
- questions: ['Como você quer definir registros parecidos?'],
1224
- optionPayloads: options.map((entry) => this.selectedRecordFilterClarificationOptionPayload(entry, contextHints)),
1225
- warnings: [
1226
- 'selected-record-similarity-clarification-materialized',
1227
- 'Selected records supplied multiple canonical filterCandidates; ambiguous similarity was converted into governed clarification without calling the remote LLM.',
1228
- ],
1229
- };
1230
- }
1231
- selectedRecordMultipleFilterFieldClarification(request, contextHints) {
1232
- if (this.selectedRecordsCountForTurn <= 0)
1233
- return null;
1234
- const prompt = this.selectedRecordFilterGroundingPrompt(request, contextHints);
1235
- if (!prompt)
1236
- return null;
1237
- const candidateFields = this.selectedRecordFilterCandidates(contextHints)
1238
- .map((candidate) => this.stringValue(candidate['field']))
1239
- .filter((field, index, fields) => !!field && fields.indexOf(field) === index);
1240
- const mentionedFields = candidateFields
1241
- .filter((field) => this.promptMentionsFilterField(prompt, field));
1242
- if (mentionedFields.length < 2)
1243
- return null;
1244
- const options = this.selectedRecordFilterClarificationOptionEntries(mentionedFields);
1245
- if (options.length < 2)
1246
- return null;
1247
- return this.selectedRecordFilterFieldClarificationResponse(options, contextHints, [
1248
- 'selected-record-multiple-filter-fields-clarification',
1249
- 'Selected-record prompt mentioned multiple canonical filter candidates; local response asked for a governed target instead of routing by prose.',
1250
- ]);
1251
- }
1252
- selectedRecordFilterFieldClarificationResponse(options, contextHints, warnings) {
1253
- return {
1254
- type: 'clarification',
1255
- message: [
1256
- `Encontrei ${this.selectedRecordsCountForTurn} registro${this.selectedRecordsCountForTurn === 1 ? '' : 's'} selecionado${this.selectedRecordsCountForTurn === 1 ? '' : 's'}.`,
1257
- `Para buscar registros parecidos, escolha qual propriedade deve guiar o filtro: ${this.joinHumanList(options.map((option) => option.label))}.`,
1258
- ].join(' '),
1259
- questions: ['Como você quer definir registros parecidos?'],
1260
- optionPayloads: options.map((entry) => this.selectedRecordFilterClarificationOptionPayload(entry, contextHints)),
1261
- warnings,
1262
- };
1263
- }
1264
- joinHumanList(values) {
1265
- const filtered = values
1266
- .map((value) => value.trim())
1267
- .filter((value, index, items) => !!value && items.indexOf(value) === index);
1268
- if (filtered.length <= 1)
1269
- return filtered[0] ?? '';
1270
- if (filtered.length === 2)
1271
- return `${filtered[0]} ou ${filtered[1]}`;
1272
- return `${filtered.slice(0, -1).join(', ')} ou ${filtered[filtered.length - 1]}`;
1273
- }
1274
- selectedRecordFilterApplyResponse(label, criteria, warnings, request, contextHints) {
1275
- const operations = [
1276
- {
1277
- operationId: 'table.filter.apply',
1278
- input: {
1279
- criteria,
1280
- source: 'selected-records',
1281
- },
1282
- },
1283
- ];
1284
- const exportOperation = this.selectedRecordRequestedExportOperation(request, contextHints, 'filtered');
1285
- if (exportOperation) {
1286
- operations.push(exportOperation);
1287
- }
1288
- return {
1289
- type: 'patch',
1290
- tableRuntimeOperations: {
1291
- kind: 'praxis.table.runtime-operation.batch',
1292
- operations,
1293
- },
1294
- explanation: `Vou aplicar filtros por ${label}.`,
1295
- warnings,
1296
- };
1297
- }
1298
- selectedRecordExportOnlyRequest(request, contextHints) {
1299
- if (this.selectedRecordsCountForTurn <= 0)
1300
- return null;
1301
- const prompt = this.selectedRecordFilterGroundingPrompt(request, contextHints);
1302
- if (!this.selectedRecordPureExportRequested(prompt, contextHints))
1303
- return null;
1304
- const exportOperation = this.selectedRecordRequestedExportOperation(request, contextHints, 'selected');
1305
- if (!exportOperation)
1306
- return null;
1307
- const format = this.stringValue(this.toRecord(exportOperation['input'])?.['format']).toUpperCase();
1308
- return {
1309
- type: 'patch',
1310
- tableRuntimeOperations: {
1311
- kind: 'praxis.table.runtime-operation.batch',
1312
- operations: [exportOperation],
1313
- },
1314
- explanation: `Vou exportar as linhas selecionadas${format ? ` em ${format}` : ''}.`,
1315
- warnings: [
1316
- 'selected-record-export-request-materialized',
1317
- 'Selected records supplied runtime context; prompt requested export with an explicit format and no selected-record filter target.',
1318
- ],
1319
- };
1320
- }
1321
- selectedRecordRequestedExportOperation(request, contextHints, scope) {
1322
- if (!request || !this.tableRuntimeOperationAllowed(contextHints, 'table.export.run'))
1323
- return null;
1324
- const prompt = this.selectedRecordFilterGroundingPrompt(request, contextHints ?? null);
1325
- const format = this.resolveRuntimeExportFormat(prompt);
1326
- if (!format)
1327
- return null;
1328
- if (!this.tableRuntimeExportFormatAllowed(contextHints, format))
1329
- return null;
1330
- return {
1331
- operationId: 'table.export.run',
1332
- input: {
1333
- format,
1334
- scope,
1335
- },
1336
- };
1337
- }
1338
- tableRuntimeOperationAllowed(contextHints, operationId) {
1339
- const authoringContract = this.toRecord(contextHints?.['authoringContract']);
1340
- const runtimeOperations = this.toRecord(authoringContract?.['runtimeOperations']);
1341
- const allowedOperationIds = Array.isArray(runtimeOperations?.['allowedOperationIds'])
1342
- ? runtimeOperations['allowedOperationIds'].map((value) => this.stringValue(value))
1343
- : [];
1344
- if (allowedOperationIds.includes(operationId))
1345
- return true;
1346
- const operations = Array.isArray(runtimeOperations?.['operations']) ? runtimeOperations['operations'] : [];
1347
- return operations
1348
- .map((operation) => this.toRecord(operation))
1349
- .some((operation) => this.stringValue(operation?.['operationId']) === operationId);
1350
- }
1351
- tableRuntimeExportFormatAllowed(contextHints, format) {
1352
- const authoringContract = this.toRecord(contextHints?.['authoringContract']);
1353
- const runtimeOperations = this.toRecord(authoringContract?.['runtimeOperations']);
1354
- const operations = Array.isArray(runtimeOperations?.['operations']) ? runtimeOperations['operations'] : [];
1355
- const exportOperation = operations
1356
- .map((operation) => this.toRecord(operation))
1357
- .find((operation) => this.stringValue(operation?.['operationId']) === 'table.export.run');
1358
- const inputSchema = this.toRecord(exportOperation?.['inputSchema']);
1359
- const formats = Array.isArray(inputSchema?.['format'])
1360
- ? inputSchema['format'].map((value) => this.stringValue(value).toLowerCase()).filter(Boolean)
1361
- : [];
1362
- return !formats.length || formats.includes(format.toLowerCase());
1363
- }
1364
- resolveRuntimeExportFormat(prompt) {
1365
- const normalized = this.normalizeLabel(prompt);
1366
- if (!normalized)
1367
- return null;
1368
- if (normalized.includes('excel') || normalized.includes('xlsx'))
1369
- return 'excel';
1370
- if (normalized.includes('csv'))
1371
- return 'csv';
1372
- if (normalized.includes('json'))
1373
- return 'json';
1374
- if (normalized.includes('pdf'))
1375
- return 'pdf';
1376
- if (normalized.includes('print') || normalized.includes('impress') || normalized.includes('imprimir'))
1377
- return 'print';
1378
- return null;
1379
- }
1380
- selectedRecordPureExportRequested(prompt, contextHints) {
1381
- const normalized = this.normalizeLabel(prompt);
1382
- if (!normalized || !this.resolveRuntimeExportFormat(prompt))
1383
- return false;
1384
- if (!this.tableRuntimeOperationAllowed(contextHints, 'table.export.run'))
1385
- return false;
1386
- const hasExportIntent = [
1387
- 'exportar',
1388
- 'exporte',
1389
- 'exporta',
1390
- 'baixar',
1391
- 'baixe',
1392
- 'baixa',
1393
- 'download',
1394
- 'gerar',
1395
- 'gere',
1396
- 'gera',
1397
- 'mandar',
1398
- 'mande',
1399
- 'manda',
1400
- 'enviar',
1401
- 'envie',
1402
- 'envia',
1403
- ].some((token) => this.normalizedTextContainsApproxToken(normalized, token));
1404
- if (!hasExportIntent)
1405
- return false;
1406
- const hasFilterIntent = [
1407
- 'filtrar',
1408
- 'filtre',
1409
- 'filtra',
1410
- 'buscar',
1411
- 'busque',
1412
- 'busca',
1413
- 'procurar',
1414
- 'procure',
1415
- 'procura',
1416
- 'mostrar',
1417
- 'mostre',
1418
- 'mostra',
1419
- 'parecido',
1420
- 'parecidos',
1421
- 'semelhante',
1422
- 'semelhantes',
1423
- ].some((token) => this.normalizedTextContainsApproxToken(normalized, token));
1424
- if (hasFilterIntent)
1425
- return false;
1426
- return !this.selectedRecordFilterCandidates(contextHints)
1427
- .some((candidate) => this.promptMentionsFilterField(prompt, this.stringValue(candidate['field'])));
1428
- }
1429
- selectedRecordFilterGroundingPrompt(request, contextHints) {
1430
- const pendingClarification = this.toRecord(contextHints?.['pendingClarification'])
1431
- ?? this.toRecord(request.pendingClarification);
1432
- return [
1433
- request.prompt,
1434
- this.stringValue(pendingClarification?.['sourcePrompt']),
1435
- this.stringValue(pendingClarification?.['assistantMessage']),
1436
- ].filter((part) => !!part).join(' ');
1437
- }
1438
- selectedRecordFilterApplyRequested(prompt) {
1439
- const normalized = this.normalizeLabel(prompt);
1440
- if (!normalized)
1441
- return false;
1442
- // This is a post-grounding materialization guard: selectedRecordsContext.filterCandidates
1443
- // and filterFieldCatalog decide the canonical target; these verbs only distinguish
1444
- // an operational bridge request from an informational question about the field.
1445
- return [
1446
- 'aplicar',
1447
- 'aplique',
1448
- 'aplica',
1449
- 'filtrar',
1450
- 'filtre',
1451
- 'filtra',
1452
- 'buscar',
1453
- 'busque',
1454
- 'busca',
1455
- 'procurar',
1456
- 'procure',
1457
- 'procura',
1458
- 'mostrar',
1459
- 'mostre',
1460
- 'mostra',
1461
- 'trazer',
1462
- 'traga',
1463
- 'traz',
1464
- 'pegar',
1465
- 'pegue',
1466
- 'pega',
1467
- 'achar',
1468
- 'ache',
1469
- 'acha',
1470
- 'encontrar',
1471
- 'encontre',
1472
- 'encontra',
1473
- 'parecido',
1474
- 'parecidos',
1475
- 'semelhante',
1476
- 'semelhantes',
1477
- 'outro',
1478
- 'outros',
1479
- ].some((token) => this.normalizedTextContainsApproxToken(normalized, token))
1480
- || this.selectedRecordOperationalAudienceRequested(normalized)
1481
- || this.selectedRecordSameFieldFilterRequested(normalized)
1482
- || this.selectedRecordPrepositionalFilterRequested(normalized)
1483
- || this.selectedRecordProximityFilterRequested(normalized);
1484
- }
1485
- selectedRecordSameFieldFilterRequested(normalizedPrompt) {
1486
- if (!normalizedPrompt)
1487
- return false;
1488
- if (this.selectedRecordInformationalQuestionRequested(normalizedPrompt))
1489
- return false;
1490
- if (!this.selectedRecordReferentialRecordsPrompt(normalizedPrompt)
1491
- && !this.selectedRecordExplicitSelectionPrompt(normalizedPrompt)) {
1492
- return false;
1493
- }
1494
- const sameValueIntent = ['mesmo', 'mesma', 'mesmos', 'mesmas', 'igual', 'iguais'].some((token) => (this.normalizedTextContainsApproxToken(normalizedPrompt, token)));
1495
- return sameValueIntent && this.selectedRecordPromptGroundsKnownFilterField(normalizedPrompt);
1496
- }
1497
- selectedRecordPrepositionalFilterRequested(normalizedPrompt) {
1498
- if (/(^|\s)(qual|quais|oque|o que|como|quando|quanto|quantos|quantas)\s/u.test(normalizedPrompt)) {
1499
- return false;
1500
- }
1501
- const hasCriterionPreposition = /(^|\s)(por|pelo|pela|pelos|pelas)\s/u.test(normalizedPrompt);
1502
- if (!hasCriterionPreposition)
1503
- return false;
1504
- return [
1505
- 'faixa',
1506
- 'banda',
1507
- 'periodo',
1508
- 'data',
1509
- 'cargo',
1510
- 'cargos',
1511
- 'departamento',
1512
- 'departamentos',
1513
- 'status',
1514
- ].some((token) => this.normalizedTextContainsApproxToken(normalizedPrompt, token));
1515
- }
1516
- selectedRecordProximityFilterRequested(normalizedPrompt) {
1517
- if (/(^|\s)(qual|quais|oque|o que|como|quando|quanto|quantos|quantas)\s/u.test(normalizedPrompt)) {
1518
- return false;
1519
- }
1520
- const hasProximityIntent = ['perto', 'proximo', 'proximos', 'parecido', 'parecidos'].some((token) => (this.normalizedTextContainsApproxToken(normalizedPrompt, token)));
1521
- if (!hasProximityIntent)
1522
- return false;
1523
- return [
1524
- 'faixa',
1525
- 'banda',
1526
- 'periodo',
1527
- 'data',
1528
- 'cargo',
1529
- 'cargos',
1530
- 'departamento',
1531
- 'departamentos',
1532
- 'status',
1533
- ].some((token) => this.normalizedTextContainsApproxToken(normalizedPrompt, token));
1534
- }
1535
- selectedRecordSimilarityRequested(prompt) {
1536
- const normalized = this.normalizeLabel(prompt);
1537
- if (!normalized)
1538
- return false;
1539
- return [
1540
- 'parecido',
1541
- 'parecidos',
1542
- 'semelhante',
1543
- 'semelhantes',
1544
- 'comparavel',
1545
- 'comparaveis',
1546
- ].some((token) => this.normalizedTextContainsApproxToken(normalized, token));
1547
- }
1548
661
  selectedRecordFilterCandidate(contextHints, field) {
1549
662
  const normalizedField = field.trim();
1550
663
  if (!normalizedField)
@@ -1681,40 +794,6 @@ class TableAgenticAuthoringTurnFlow {
1681
794
  ],
1682
795
  };
1683
796
  }
1684
- selectedRecordBackendFailureClarification(request, contextHints, error) {
1685
- if (this.selectedRecordsCountForTurn <= 0)
1686
- return null;
1687
- const candidateFields = this.selectedRecordFilterCandidates(contextHints)
1688
- .map((candidate) => this.stringValue(candidate['field']))
1689
- .filter((field, index, fields) => !!field && fields.indexOf(field) === index);
1690
- if (!candidateFields.length)
1691
- return null;
1692
- const options = this.selectedRecordFilterClarificationOptionEntries(candidateFields);
1693
- if (!options.length)
1694
- return null;
1695
- return {
1696
- type: 'clarification',
1697
- message: [
1698
- 'Não consegui confirmar automaticamente esse pedido.',
1699
- `Encontrei ${this.selectedRecordsCountForTurn} registro${this.selectedRecordsCountForTurn === 1 ? '' : 's'} selecionado${this.selectedRecordsCountForTurn === 1 ? '' : 's'} e posso continuar usando uma propriedade derivada dessa seleção.`,
1700
- ].join(' '),
1701
- questions: ['Qual propriedade dos registros selecionados deve guiar o filtro?'],
1702
- optionPayloads: options.map((entry) => this.selectedRecordFilterClarificationOptionPayload(entry, contextHints)),
1703
- warnings: [
1704
- 'selected-record-backend-failure-clarification-materialized',
1705
- `Backend failed after selected-record context was prepared; recovered with canonical filterCandidates instead of exposing transport error. ${this.backendErrorSummary(error)}`,
1706
- ],
1707
- };
1708
- }
1709
- backendErrorSummary(error) {
1710
- const record = this.toRecord(error);
1711
- const status = this.stringValue(record?.['status']);
1712
- const statusText = this.stringValue(record?.['statusText']);
1713
- if (status || statusText) {
1714
- return `status=${status || 'unknown'} ${statusText || ''}`.trim();
1715
- }
1716
- return this.stringValue(record?.['message']) || 'status=unknown';
1717
- }
1718
797
  tableFilterApplyOperations(patch) {
1719
798
  const envelope = this.toRecord(this.toRecord(patch)?.['tableRuntimeOperations']);
1720
799
  const operations = Array.isArray(envelope?.['operations']) ? envelope['operations'] : [];
@@ -1,7 +1,7 @@
1
1
  import { firstValueFrom } from 'rxjs';
2
2
  import { BaseAiAdapter, createComponentAuthoringContext } from '@praxisui/ai';
3
3
  import { deepMerge } from '@praxisui/core';
4
- import { z as TABLE_COMPONENT_EDIT_PLAN_OPERATION_IDS, k as PRAXIS_TABLE_AUTHORING_MANIFEST, T as TABLE_AI_CAPABILITIES, R as coerceTableComponentEditPlans, W as compileTableComponentEditPlans, G as TASK_PRESETS, $ as getTableComponentEditPlanCapabilities, w as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, u as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, x as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, E as TABLE_COMPONENT_EDIT_PLAN_VERSION, v as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, y as TABLE_COMPONENT_EDIT_PLAN_KIND } from './praxisui-table-praxisui-table-GekTiEGg.mjs';
4
+ import { z as TABLE_COMPONENT_EDIT_PLAN_OPERATION_IDS, k as PRAXIS_TABLE_AUTHORING_MANIFEST, T as TABLE_AI_CAPABILITIES, R as coerceTableComponentEditPlans, W as compileTableComponentEditPlans, G as TASK_PRESETS, $ as getTableComponentEditPlanCapabilities, w as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, u as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, x as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, E as TABLE_COMPONENT_EDIT_PLAN_VERSION, v as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, y as TABLE_COMPONENT_EDIT_PLAN_KIND } from './praxisui-table-praxisui-table-AUAbRLeB.mjs';
5
5
 
6
6
  const TABLE_COMPONENT_CONTEXT_PACK = {
7
7
  version: 'v1',
@@ -1 +1 @@
1
- export { A as AnalyticsTableConfigAdapterService, a as AnalyticsTableContractService, b as AnalyticsTableStatsApiService, B as BOOLEAN_PRESETS, c as BehaviorConfigEditorComponent, C as CURRENCY_PRESETS, d as ColumnsConfigEditorComponent, D as DATE_PRESETS, e as DataFormatterComponent, f as DataFormattingService, F as FORMULA_TEMPLATES, g as FilterConfigService, h as FilterSettingsComponent, i as FormulaGeneratorService, J as JsonConfigEditorComponent, M as MessagesLocalizationEditorComponent, N as NUMBER_PRESETS, P as PERCENTAGE_PRESETS, j as PRAXIS_FILTER_COMPONENT_METADATA, k as PRAXIS_TABLE_AUTHORING_MANIFEST, l as PRAXIS_TABLE_COMPONENT_METADATA, m as PraxisFilter, n as PraxisFilterWidgetConfigEditor, o as PraxisTable, p as PraxisTableConfigEditor, q as PraxisTableInlineAuthoringEditorComponent, r as PraxisTableToolbar, s as PraxisTableWidgetConfigEditor, S as STRING_PRESETS, T as TABLE_AI_CAPABILITIES, t as TABLE_COMPONENT_AI_CAPABILITIES, u as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, v as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, w as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, x as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, y as TABLE_COMPONENT_EDIT_PLAN_KIND, E as TABLE_COMPONENT_EDIT_PLAN_VERSION, G as TASK_PRESETS, H as TableDefaultsProvider, I as TableRulesEditorComponent, K as ToolbarActionsEditorComponent, V as ValueMappingEditorComponent, L as VisualFormulaBuilderComponent, O as buildTableApplyPlan, Q as coerceTableComponentEditPlan, R as coerceTableComponentEditPlans, U as compileTableComponentEditPlan, W as compileTableComponentEditPlans, X as createTableAuthoringDocument, Y as getActionId, Z as getEnum, _ as getTableCapabilities, $ as getTableComponentEditPlanCapabilities, a0 as isTableRendererSupportedByRichContentP0, a1 as mapTableRendererToRichContentP0, a2 as normalizeTableAuthoringDocument, a3 as parseLegacyOrTableDocument, a4 as providePraxisFilterMetadata, a5 as providePraxisTableMetadata, a6 as serializeTableAuthoringDocument, a7 as toCanonicalTableConfig, a8 as validateTableAuthoringDocument } from './praxisui-table-praxisui-table-GekTiEGg.mjs';
1
+ export { A as AnalyticsTableConfigAdapterService, a as AnalyticsTableContractService, b as AnalyticsTableStatsApiService, B as BOOLEAN_PRESETS, c as BehaviorConfigEditorComponent, C as CURRENCY_PRESETS, d as ColumnsConfigEditorComponent, D as DATE_PRESETS, e as DataFormatterComponent, f as DataFormattingService, F as FORMULA_TEMPLATES, g as FilterConfigService, h as FilterSettingsComponent, i as FormulaGeneratorService, J as JsonConfigEditorComponent, M as MessagesLocalizationEditorComponent, N as NUMBER_PRESETS, P as PERCENTAGE_PRESETS, j as PRAXIS_FILTER_COMPONENT_METADATA, k as PRAXIS_TABLE_AUTHORING_MANIFEST, l as PRAXIS_TABLE_COMPONENT_METADATA, m as PraxisFilter, n as PraxisFilterWidgetConfigEditor, o as PraxisTable, p as PraxisTableConfigEditor, q as PraxisTableInlineAuthoringEditorComponent, r as PraxisTableToolbar, s as PraxisTableWidgetConfigEditor, S as STRING_PRESETS, T as TABLE_AI_CAPABILITIES, t as TABLE_COMPONENT_AI_CAPABILITIES, u as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, v as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, w as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, x as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, y as TABLE_COMPONENT_EDIT_PLAN_KIND, E as TABLE_COMPONENT_EDIT_PLAN_VERSION, G as TASK_PRESETS, H as TableDefaultsProvider, I as TableRulesEditorComponent, K as ToolbarActionsEditorComponent, V as ValueMappingEditorComponent, L as VisualFormulaBuilderComponent, O as buildTableApplyPlan, Q as coerceTableComponentEditPlan, R as coerceTableComponentEditPlans, U as compileTableComponentEditPlan, W as compileTableComponentEditPlans, X as createTableAuthoringDocument, Y as getActionId, Z as getEnum, _ as getTableCapabilities, $ as getTableComponentEditPlanCapabilities, a0 as isTableRendererSupportedByRichContentP0, a1 as mapTableRendererToRichContentP0, a2 as normalizeTableAuthoringDocument, a3 as parseLegacyOrTableDocument, a4 as providePraxisFilterMetadata, a5 as providePraxisTableMetadata, a6 as serializeTableAuthoringDocument, a7 as toCanonicalTableConfig, a8 as validateTableAuthoringDocument } from './praxisui-table-praxisui-table-AUAbRLeB.mjs';
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@praxisui/table",
3
- "version": "8.0.0-beta.52",
3
+ "version": "8.0.0-beta.53",
4
4
  "description": "Advanced data table for Angular (Praxis UI) with editing, filtering, sorting, virtualization, and settings panel integration.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
- "@praxisui/ai": "^8.0.0-beta.52",
9
- "@praxisui/core": "^8.0.0-beta.52",
10
- "@praxisui/dynamic-fields": "^8.0.0-beta.52",
11
- "@praxisui/dynamic-form": "^8.0.0-beta.52",
12
- "@praxisui/metadata-editor": "^8.0.0-beta.52",
13
- "@praxisui/rich-content": "^8.0.0-beta.52",
14
- "@praxisui/settings-panel": "^8.0.0-beta.52",
15
- "@praxisui/table-rule-builder": "^8.0.0-beta.52",
8
+ "@praxisui/ai": "^8.0.0-beta.53",
9
+ "@praxisui/core": "^8.0.0-beta.53",
10
+ "@praxisui/dynamic-fields": "^8.0.0-beta.53",
11
+ "@praxisui/dynamic-form": "^8.0.0-beta.53",
12
+ "@praxisui/metadata-editor": "^8.0.0-beta.53",
13
+ "@praxisui/rich-content": "^8.0.0-beta.53",
14
+ "@praxisui/settings-panel": "^8.0.0-beta.53",
15
+ "@praxisui/table-rule-builder": "^8.0.0-beta.53",
16
16
  "@angular/cdk": "^21.0.0",
17
17
  "@angular/forms": "^21.0.0",
18
18
  "@angular/material": "^21.0.0",
19
19
  "@angular/router": "^21.0.0",
20
- "@praxisui/dialog": "^8.0.0-beta.52",
20
+ "@praxisui/dialog": "^8.0.0-beta.53",
21
21
  "rxjs": "~7.8.0"
22
22
  },
23
23
  "dependencies": {