@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.
- package/fesm2022/{praxisui-table-praxisui-table-GekTiEGg.mjs → praxisui-table-praxisui-table-AUAbRLeB.mjs} +2 -2
- package/fesm2022/{praxisui-table-table-agentic-authoring-turn-flow-DtoCwCVX.mjs → praxisui-table-table-agentic-authoring-turn-flow-B075RDUj.mjs} +3 -924
- package/fesm2022/{praxisui-table-table-ai.adapter-eGo1zPuy.mjs → praxisui-table-table-ai.adapter-rtjGFq_B.mjs} +1 -1
- package/fesm2022/praxisui-table.mjs +1 -1
- package/package.json +10 -10
|
@@ -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-
|
|
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-
|
|
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
|
|
84
|
-
|
|
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
|
|
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-
|
|
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-
|
|
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.
|
|
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.
|
|
9
|
-
"@praxisui/core": "^8.0.0-beta.
|
|
10
|
-
"@praxisui/dynamic-fields": "^8.0.0-beta.
|
|
11
|
-
"@praxisui/dynamic-form": "^8.0.0-beta.
|
|
12
|
-
"@praxisui/metadata-editor": "^8.0.0-beta.
|
|
13
|
-
"@praxisui/rich-content": "^8.0.0-beta.
|
|
14
|
-
"@praxisui/settings-panel": "^8.0.0-beta.
|
|
15
|
-
"@praxisui/table-rule-builder": "^8.0.0-beta.
|
|
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.
|
|
20
|
+
"@praxisui/dialog": "^8.0.0-beta.53",
|
|
21
21
|
"rxjs": "~7.8.0"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|