@praxisui/table 8.0.0-beta.87 → 8.0.0-beta.88
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/README.md +2 -0
- package/fesm2022/{praxisui-table-praxisui-table-DDQAk0TJ.mjs → praxisui-table-praxisui-table-OCU_Au66.mjs} +95 -16
- package/fesm2022/{praxisui-table-table-agentic-authoring-turn-flow-oJhkMALs.mjs → praxisui-table-table-agentic-authoring-turn-flow-4Deh8QJU.mjs} +856 -9
- package/fesm2022/{praxisui-table-table-ai.adapter-yEPQ8xBc.mjs → praxisui-table-table-ai.adapter-C8qa8APT.mjs} +43 -11
- package/fesm2022/praxisui-table.mjs +1 -1
- package/package.json +10 -10
- package/types/praxisui-table.d.ts +5 -0
|
@@ -301,6 +301,9 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
301
301
|
return this.selectedRecordSurfaces(contextHints).length > 0;
|
|
302
302
|
}
|
|
303
303
|
localRecommendedIntentResponse(request, contextHints) {
|
|
304
|
+
const declaredFilterConfirmation = this.localDeclaredFilterConfirmationResponse(request, contextHints);
|
|
305
|
+
if (declaredFilterConfirmation)
|
|
306
|
+
return declaredFilterConfirmation;
|
|
304
307
|
const declaredFilterClarification = this.localDeclaredFilterClarificationCompletionResponse(request, contextHints);
|
|
305
308
|
if (declaredFilterClarification)
|
|
306
309
|
return declaredFilterClarification;
|
|
@@ -559,6 +562,76 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
559
562
|
],
|
|
560
563
|
};
|
|
561
564
|
}
|
|
565
|
+
localDeclaredFilterConfirmationResponse(request, contextHints) {
|
|
566
|
+
const pendingClarification = request.pendingClarification
|
|
567
|
+
?? this.recoverDeclaredFilterConfirmationPendingClarificationFromMessages(request);
|
|
568
|
+
if (!pendingClarification)
|
|
569
|
+
return null;
|
|
570
|
+
if (request.action?.kind && !['clarify', 'submit'].includes(request.action.kind))
|
|
571
|
+
return null;
|
|
572
|
+
if (!this.runtimeOperationAllowed(contextHints, 'table.filter.apply'))
|
|
573
|
+
return null;
|
|
574
|
+
if (!this.pendingClarificationCanContinueDeclaredFilterApply(pendingClarification))
|
|
575
|
+
return null;
|
|
576
|
+
const normalizedPrompt = this.normalizeLabel([
|
|
577
|
+
request.action?.displayPrompt,
|
|
578
|
+
request.action?.value,
|
|
579
|
+
request.prompt,
|
|
580
|
+
].map((value) => this.stringValue(value)).filter(Boolean).join(' '));
|
|
581
|
+
if (!normalizedPrompt)
|
|
582
|
+
return null;
|
|
583
|
+
if (this.isShortNegativeClarificationAnswer(normalizedPrompt)) {
|
|
584
|
+
return {
|
|
585
|
+
type: 'info',
|
|
586
|
+
sessionId: request.sessionId,
|
|
587
|
+
message: 'Tudo bem, não alterei a tabela.',
|
|
588
|
+
warnings: [
|
|
589
|
+
'declared-filter-confirmation-cancelled-by-short-negative',
|
|
590
|
+
],
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
if (!this.isShortAffirmativeClarificationAnswer(normalizedPrompt))
|
|
594
|
+
return null;
|
|
595
|
+
const sourcePrompt = this.declaredFilterClarificationSourcePrompt(pendingClarification);
|
|
596
|
+
const normalizedGroundingPrompt = this.normalizeLabel([
|
|
597
|
+
sourcePrompt,
|
|
598
|
+
pendingClarification.assistantMessage,
|
|
599
|
+
].filter(Boolean).join(' '));
|
|
600
|
+
if (!normalizedGroundingPrompt || !this.promptRequestsRuntimeFilter(normalizedGroundingPrompt))
|
|
601
|
+
return null;
|
|
602
|
+
if (this.promptRequestsVisualOrStructuralEdit(normalizedGroundingPrompt))
|
|
603
|
+
return null;
|
|
604
|
+
const criteria = this.resolveDeclaredFilterConfirmationCriteria(normalizedGroundingPrompt, pendingClarification, contextHints);
|
|
605
|
+
if (!criteria || !Object.keys(criteria).length)
|
|
606
|
+
return null;
|
|
607
|
+
const completedCriteria = this.dedupeRuntimeFilterCriteriaAgainstDiscreteDimensions(this.completeRuntimeFilterCriteriaWithSelectedCandidates(criteria, {
|
|
608
|
+
...request,
|
|
609
|
+
prompt: sourcePrompt || pendingClarification.assistantMessage || request.prompt,
|
|
610
|
+
}));
|
|
611
|
+
return {
|
|
612
|
+
type: 'patch',
|
|
613
|
+
sessionId: request.sessionId,
|
|
614
|
+
patch: {
|
|
615
|
+
tableRuntimeOperations: {
|
|
616
|
+
kind: 'praxis.table.runtime-operation.batch',
|
|
617
|
+
source: 'declared-filter-confirmation-continuation',
|
|
618
|
+
operations: [{
|
|
619
|
+
operationId: 'table.filter.apply',
|
|
620
|
+
input: {
|
|
621
|
+
criteria: completedCriteria,
|
|
622
|
+
criteriaSemantics: 'simple-conjunction',
|
|
623
|
+
source: 'declared-filter-confirmation',
|
|
624
|
+
},
|
|
625
|
+
}],
|
|
626
|
+
},
|
|
627
|
+
},
|
|
628
|
+
explanation: 'Filtro confirmado a partir da clarificação anterior.',
|
|
629
|
+
warnings: [
|
|
630
|
+
'declared-filter-confirmation-continuation-materialized',
|
|
631
|
+
'A resposta curta confirmou uma clarificacao anterior ja ancorada em table.filter.apply e no filterFieldCatalog.',
|
|
632
|
+
],
|
|
633
|
+
};
|
|
634
|
+
}
|
|
562
635
|
localDeclaredFilterClarificationCompletionResponse(request, contextHints) {
|
|
563
636
|
const pendingClarification = request.pendingClarification
|
|
564
637
|
?? this.recoverDeclaredFilterPendingClarificationFromMessages(request);
|
|
@@ -568,7 +641,7 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
568
641
|
return null;
|
|
569
642
|
if (!this.runtimeOperationAllowed(contextHints, 'table.filter.apply'))
|
|
570
643
|
return null;
|
|
571
|
-
const sourcePrompt =
|
|
644
|
+
const sourcePrompt = this.declaredFilterClarificationSourcePrompt(pendingClarification);
|
|
572
645
|
if (!sourcePrompt)
|
|
573
646
|
return null;
|
|
574
647
|
const normalizedSourcePrompt = this.normalizeLabel(sourcePrompt);
|
|
@@ -578,9 +651,15 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
578
651
|
return null;
|
|
579
652
|
if (!this.pendingClarificationAsksForDeclaredFilter(request, pendingClarification))
|
|
580
653
|
return null;
|
|
654
|
+
if (this.declaredFilterClarificationResponseIsNewFilterRequest(request, contextHints))
|
|
655
|
+
return null;
|
|
581
656
|
const selectedEntry = this.filterFieldCatalogEntryForClarificationResponse(request, sourcePrompt);
|
|
582
|
-
if (!selectedEntry)
|
|
657
|
+
if (!selectedEntry) {
|
|
658
|
+
const unresolvedShortResponse = this.unresolvedDeclaredFilterShortConfirmationResponse(request, pendingClarification, sourcePrompt);
|
|
659
|
+
if (unresolvedShortResponse)
|
|
660
|
+
return unresolvedShortResponse;
|
|
583
661
|
return null;
|
|
662
|
+
}
|
|
584
663
|
const criteria = this.resolveDeclaredFilterCriteriaFromPrompt(normalizedSourcePrompt, contextHints) ?? {};
|
|
585
664
|
const clarified = this.resolveClarifiedFilterCriterionFromSourcePrompt(normalizedSourcePrompt, selectedEntry, contextHints, criteria);
|
|
586
665
|
if (!clarified)
|
|
@@ -616,6 +695,119 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
616
695
|
],
|
|
617
696
|
};
|
|
618
697
|
}
|
|
698
|
+
unresolvedDeclaredFilterShortConfirmationResponse(request, pendingClarification, sourcePrompt) {
|
|
699
|
+
const normalizedPrompt = this.normalizeLabel([
|
|
700
|
+
request.action?.displayPrompt,
|
|
701
|
+
request.action?.value,
|
|
702
|
+
request.prompt,
|
|
703
|
+
].map((value) => this.stringValue(value)).filter(Boolean).join(' '));
|
|
704
|
+
if (!normalizedPrompt)
|
|
705
|
+
return null;
|
|
706
|
+
if (this.isShortNegativeClarificationAnswer(normalizedPrompt)) {
|
|
707
|
+
return {
|
|
708
|
+
type: 'info',
|
|
709
|
+
sessionId: request.sessionId,
|
|
710
|
+
message: 'Tudo bem, não alterei a tabela. Você pode escolher um filtro ou fazer um novo pedido.',
|
|
711
|
+
warnings: [
|
|
712
|
+
'declared-filter-clarification-cancelled-by-short-negative',
|
|
713
|
+
],
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
if (!this.isShortAffirmativeClarificationAnswer(normalizedPrompt))
|
|
717
|
+
return null;
|
|
718
|
+
const optionPayloads = this.declaredFilterClarificationReminderOptionPayloads(request, pendingClarification, sourcePrompt);
|
|
719
|
+
if (optionPayloads.length <= 1)
|
|
720
|
+
return null;
|
|
721
|
+
return {
|
|
722
|
+
type: 'clarification',
|
|
723
|
+
sessionId: request.sessionId,
|
|
724
|
+
message: 'Ainda preciso que você escolha qual filtro deve receber esse critério antes de alterar a tabela.',
|
|
725
|
+
questions: ['Escolha uma das opções abaixo para continuar.'],
|
|
726
|
+
optionPayloads,
|
|
727
|
+
diagnostics: {
|
|
728
|
+
tableDeclaredFilterClarification: {
|
|
729
|
+
sourcePrompt,
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
warnings: [
|
|
733
|
+
'declared-filter-short-affirmative-needs-explicit-field-choice',
|
|
734
|
+
],
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
declaredFilterClarificationSourcePrompt(pendingClarification) {
|
|
738
|
+
const diagnostics = this.toRecord(pendingClarification?.diagnostics);
|
|
739
|
+
const declaredFilter = this.toRecord(diagnostics?.['tableDeclaredFilterClarification']);
|
|
740
|
+
const diagnosticSourcePrompt = this.stringValue(declaredFilter?.['sourcePrompt']).trim();
|
|
741
|
+
if (diagnosticSourcePrompt)
|
|
742
|
+
return diagnosticSourcePrompt;
|
|
743
|
+
return pendingClarification?.sourcePrompt?.trim() ?? '';
|
|
744
|
+
}
|
|
745
|
+
isShortAffirmativeClarificationAnswer(normalizedPrompt) {
|
|
746
|
+
return ['sim', 's', 'ok', 'okay', 'isso', 'pode', 'confirmo', 'confirmar']
|
|
747
|
+
.includes(normalizedPrompt);
|
|
748
|
+
}
|
|
749
|
+
isShortNegativeClarificationAnswer(normalizedPrompt) {
|
|
750
|
+
return ['nao', 'não', 'n', 'cancelar', 'cancela', 'deixa', 'deixa pra la', 'deixa pra lá']
|
|
751
|
+
.includes(normalizedPrompt);
|
|
752
|
+
}
|
|
753
|
+
declaredFilterClarificationReminderOptionPayloads(request, pendingClarification, sourcePrompt) {
|
|
754
|
+
const normalizedSourcePrompt = this.normalizeLabel(sourcePrompt);
|
|
755
|
+
const labels = [
|
|
756
|
+
...(pendingClarification?.questions ?? []).flatMap((question) => (question.options ?? []).map((option) => option.label || option.value || option.id)),
|
|
757
|
+
...this.declaredFilterQuickReplyOptions(normalizedSourcePrompt, {
|
|
758
|
+
...request,
|
|
759
|
+
prompt: sourcePrompt,
|
|
760
|
+
}),
|
|
761
|
+
]
|
|
762
|
+
.map((label) => this.stringValue(label).trim())
|
|
763
|
+
.filter((label) => !!label);
|
|
764
|
+
const seen = new Set();
|
|
765
|
+
return labels
|
|
766
|
+
.map((label) => this.filterFieldCatalogEntryForClarificationLabel(label) ?? {
|
|
767
|
+
name: label,
|
|
768
|
+
label: this.humanizeClarificationOptionLabel(label),
|
|
769
|
+
})
|
|
770
|
+
.filter((entry) => {
|
|
771
|
+
const key = this.normalizeLabel(entry.name || entry.label);
|
|
772
|
+
if (!key || seen.has(key))
|
|
773
|
+
return false;
|
|
774
|
+
seen.add(key);
|
|
775
|
+
return true;
|
|
776
|
+
})
|
|
777
|
+
.map((entry) => ({
|
|
778
|
+
label: entry.label,
|
|
779
|
+
value: entry.name,
|
|
780
|
+
contextHints: {
|
|
781
|
+
tableFilterClarification: {
|
|
782
|
+
source: 'declared-filter-field',
|
|
783
|
+
field: entry.name,
|
|
784
|
+
label: entry.label,
|
|
785
|
+
},
|
|
786
|
+
},
|
|
787
|
+
}));
|
|
788
|
+
}
|
|
789
|
+
declaredFilterClarificationResponseIsNewFilterRequest(request, contextHints) {
|
|
790
|
+
if (this.toRecord(request.action?.contextHints?.['tableFilterClarification']))
|
|
791
|
+
return false;
|
|
792
|
+
if (request.action?.kind === 'clarify')
|
|
793
|
+
return false;
|
|
794
|
+
const normalizedPrompt = this.normalizeLabel(request.prompt ?? '');
|
|
795
|
+
if (!normalizedPrompt || !this.promptRequestsRuntimeFilter(normalizedPrompt))
|
|
796
|
+
return false;
|
|
797
|
+
if (this.promptRequestsVisualOrStructuralEdit(normalizedPrompt))
|
|
798
|
+
return false;
|
|
799
|
+
if (this.normalizedTextHasStandaloneToken(normalizedPrompt, 'agora'))
|
|
800
|
+
return true;
|
|
801
|
+
if (this.promptHasCompensationRangeIntent(normalizedPrompt) || this.promptHasDateRangeComparison(normalizedPrompt)) {
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
if (this.promptHasNumericRangeComparison(normalizedPrompt)
|
|
805
|
+
&& this.filterFieldCatalogEntries.filter((entry) => this.isNumericRangeFilterEntry(entry)).length === 1) {
|
|
806
|
+
return true;
|
|
807
|
+
}
|
|
808
|
+
const criteria = this.resolveDeclaredFilterCriteriaFromPrompt(normalizedPrompt, contextHints);
|
|
809
|
+
return !!criteria && Object.keys(criteria).length > 0;
|
|
810
|
+
}
|
|
619
811
|
pendingClarificationAsksForDeclaredFilter(request, pending) {
|
|
620
812
|
const hinted = this.toRecord(request.action?.contextHints?.['tableFilterClarification']);
|
|
621
813
|
if (hinted)
|
|
@@ -661,6 +853,78 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
661
853
|
}
|
|
662
854
|
return null;
|
|
663
855
|
}
|
|
856
|
+
recoverDeclaredFilterConfirmationPendingClarificationFromMessages(request) {
|
|
857
|
+
const messages = [...(request.messages ?? [])];
|
|
858
|
+
if (messages.length < 2)
|
|
859
|
+
return null;
|
|
860
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
861
|
+
const message = messages[index];
|
|
862
|
+
if (message.role !== 'assistant')
|
|
863
|
+
continue;
|
|
864
|
+
if (!this.pendingClarificationCanContinueDeclaredFilterApply({
|
|
865
|
+
assistantMessage: message.text,
|
|
866
|
+
sourcePrompt: '',
|
|
867
|
+
questions: [],
|
|
868
|
+
}))
|
|
869
|
+
continue;
|
|
870
|
+
const sourcePrompt = [...messages.slice(0, index)]
|
|
871
|
+
.reverse()
|
|
872
|
+
.find((candidate) => candidate.role === 'user')
|
|
873
|
+
?.text?.trim();
|
|
874
|
+
if (!sourcePrompt)
|
|
875
|
+
return null;
|
|
876
|
+
return {
|
|
877
|
+
sourcePrompt,
|
|
878
|
+
assistantMessage: message.text,
|
|
879
|
+
questions: [],
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
return null;
|
|
883
|
+
}
|
|
884
|
+
pendingClarificationConfirmsDeclaredFilterApply(pending) {
|
|
885
|
+
const text = this.normalizeLabel([
|
|
886
|
+
pending?.assistantMessage,
|
|
887
|
+
...(pending?.questions ?? []).map((question) => [
|
|
888
|
+
question.label,
|
|
889
|
+
...(question.options ?? []).map((option) => option.label),
|
|
890
|
+
].flat().join(' ')),
|
|
891
|
+
].filter(Boolean).join(' '));
|
|
892
|
+
if (!text)
|
|
893
|
+
return false;
|
|
894
|
+
const asksConfirmation = text.includes('confirma')
|
|
895
|
+
|| text.includes('confirmar')
|
|
896
|
+
|| text.includes('posso filtrar')
|
|
897
|
+
|| text.includes('aplique esse filtro')
|
|
898
|
+
|| text.includes('aplicar esse filtro');
|
|
899
|
+
const mentionsRuntimeFilter = text.includes('filtrar')
|
|
900
|
+
|| text.includes('filtro')
|
|
901
|
+
|| text.includes('apenas funcionarios')
|
|
902
|
+
|| text.includes('apenas funcionários');
|
|
903
|
+
return asksConfirmation && mentionsRuntimeFilter;
|
|
904
|
+
}
|
|
905
|
+
pendingClarificationCanContinueDeclaredFilterApply(pending) {
|
|
906
|
+
return this.pendingClarificationConfirmsDeclaredFilterApply(pending)
|
|
907
|
+
|| this.pendingClarificationDeclaresDeclaredFilterApply(pending);
|
|
908
|
+
}
|
|
909
|
+
pendingClarificationDeclaresDeclaredFilterApply(pending) {
|
|
910
|
+
const text = this.normalizeLabel([
|
|
911
|
+
pending?.assistantMessage,
|
|
912
|
+
...(pending?.questions ?? []).map((question) => [
|
|
913
|
+
question.label,
|
|
914
|
+
...(question.options ?? []).map((option) => option.label),
|
|
915
|
+
].flat().join(' ')),
|
|
916
|
+
].filter(Boolean).join(' '));
|
|
917
|
+
if (!text)
|
|
918
|
+
return false;
|
|
919
|
+
const declaresRuntimeOperation = text.includes('table.filter.apply')
|
|
920
|
+
|| text.includes('operacao table filter apply')
|
|
921
|
+
|| text.includes('operação table filter apply');
|
|
922
|
+
const declaresFiltering = text.includes('vou filtrar')
|
|
923
|
+
|| text.includes('filtrar a tabela')
|
|
924
|
+
|| text.includes('executando operacao')
|
|
925
|
+
|| text.includes('executando operação');
|
|
926
|
+
return declaresRuntimeOperation && declaresFiltering;
|
|
927
|
+
}
|
|
664
928
|
filterFieldCatalogEntryForClarificationResponse(request, sourcePrompt) {
|
|
665
929
|
const hinted = this.toRecord(request.action?.contextHints?.['tableFilterClarification']);
|
|
666
930
|
const hintedField = this.stringValue(hinted?.['field']);
|
|
@@ -746,12 +1010,60 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
746
1010
|
const token = this.ungroundedFilterValueTokens(normalizedSourcePrompt, entry, criteria)[0];
|
|
747
1011
|
return token ? this.restoreFilterValueToken(token, normalizedSourcePrompt) : '';
|
|
748
1012
|
}
|
|
1013
|
+
resolveImplicitTextCriteriaFromValueHints(normalizedPrompt, criteria) {
|
|
1014
|
+
if (!normalizedPrompt)
|
|
1015
|
+
return;
|
|
1016
|
+
const matches = this.filterFieldCatalogEntries
|
|
1017
|
+
.filter((entry) => criteria[entry.name] === undefined)
|
|
1018
|
+
.filter((entry) => this.isTextualFilterCriterion(entry))
|
|
1019
|
+
.map((entry) => ({
|
|
1020
|
+
entry,
|
|
1021
|
+
match: this.bestFilterValueHintMatch(normalizedPrompt, entry),
|
|
1022
|
+
}))
|
|
1023
|
+
.filter((candidate) => !!candidate.match)
|
|
1024
|
+
.sort((left, right) => right.match.score - left.match.score || left.entry.label.localeCompare(right.entry.label));
|
|
1025
|
+
if (!matches.length)
|
|
1026
|
+
return;
|
|
1027
|
+
const topScore = matches[0].match.score;
|
|
1028
|
+
const winners = matches.filter((candidate) => candidate.match.score === topScore);
|
|
1029
|
+
if (winners.length !== 1)
|
|
1030
|
+
return;
|
|
1031
|
+
criteria[winners[0].entry.name] = this.normalizeRuntimeFilterCriterionForCatalogEntry(winners[0].match.value, winners[0].entry);
|
|
1032
|
+
}
|
|
1033
|
+
bestFilterValueHintMatch(normalizedPrompt, entry) {
|
|
1034
|
+
let best = null;
|
|
1035
|
+
for (const hint of entry.valueHints) {
|
|
1036
|
+
for (const candidate of this.filterValueHintCandidates(hint)) {
|
|
1037
|
+
const normalizedCandidate = this.normalizeLabel(candidate);
|
|
1038
|
+
if (!normalizedCandidate || normalizedCandidate.length < 4)
|
|
1039
|
+
continue;
|
|
1040
|
+
if (!this.normalizedTextContainsApproxPhrase(normalizedPrompt, normalizedCandidate))
|
|
1041
|
+
continue;
|
|
1042
|
+
const score = normalizedCandidate.split(/\s+/u).length * 25 + normalizedCandidate.length;
|
|
1043
|
+
if (!best || score > best.score) {
|
|
1044
|
+
best = { value: candidate, score };
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return best;
|
|
1049
|
+
}
|
|
1050
|
+
filterValueHintCandidates(hint) {
|
|
1051
|
+
const trimmed = hint.trim();
|
|
1052
|
+
if (!trimmed)
|
|
1053
|
+
return [];
|
|
1054
|
+
const candidates = new Set([trimmed]);
|
|
1055
|
+
const prefix = trimmed.split(/\s+-\s+/u)[0]?.trim();
|
|
1056
|
+
if (prefix && prefix.length >= 4)
|
|
1057
|
+
candidates.add(prefix);
|
|
1058
|
+
return [...candidates];
|
|
1059
|
+
}
|
|
749
1060
|
ungroundedFilterValueTokens(normalizedPrompt, entry, criteria) {
|
|
750
1061
|
const ignoredTokens = new Set([
|
|
751
1062
|
'filtra',
|
|
752
1063
|
'filtrar',
|
|
753
1064
|
'filtre',
|
|
754
1065
|
'filtro',
|
|
1066
|
+
'agora',
|
|
755
1067
|
'quero',
|
|
756
1068
|
'ver',
|
|
757
1069
|
'mostra',
|
|
@@ -762,6 +1074,26 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
762
1074
|
'busca',
|
|
763
1075
|
'procura',
|
|
764
1076
|
'procurar',
|
|
1077
|
+
'confirma',
|
|
1078
|
+
'confirmar',
|
|
1079
|
+
'aplique',
|
|
1080
|
+
'aplicar',
|
|
1081
|
+
'posso',
|
|
1082
|
+
'para',
|
|
1083
|
+
'eu',
|
|
1084
|
+
'esse',
|
|
1085
|
+
'essa',
|
|
1086
|
+
'tabela',
|
|
1087
|
+
'funcionario',
|
|
1088
|
+
'funcionarios',
|
|
1089
|
+
'funcionário',
|
|
1090
|
+
'funcionários',
|
|
1091
|
+
'qualquer',
|
|
1092
|
+
'qq',
|
|
1093
|
+
'depto',
|
|
1094
|
+
'departamento',
|
|
1095
|
+
'departamentos',
|
|
1096
|
+
'serve',
|
|
765
1097
|
'de',
|
|
766
1098
|
'do',
|
|
767
1099
|
'da',
|
|
@@ -805,6 +1137,18 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
805
1137
|
'admitidas',
|
|
806
1138
|
'admitiu',
|
|
807
1139
|
'admitiram',
|
|
1140
|
+
'ganha',
|
|
1141
|
+
'ganham',
|
|
1142
|
+
'ganhando',
|
|
1143
|
+
'recebe',
|
|
1144
|
+
'recebem',
|
|
1145
|
+
'recebendo',
|
|
1146
|
+
'remuneracao',
|
|
1147
|
+
'remuneração',
|
|
1148
|
+
'pagamento',
|
|
1149
|
+
'folha',
|
|
1150
|
+
'salario',
|
|
1151
|
+
'salário',
|
|
808
1152
|
].map((token) => this.normalizeLabel(token)));
|
|
809
1153
|
const fieldMentionTokens = new Set([
|
|
810
1154
|
entry.name,
|
|
@@ -848,8 +1192,41 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
848
1192
|
}
|
|
849
1193
|
unresolvedFilterCriterionOptions(normalizedPrompt, criteria) {
|
|
850
1194
|
const usedFields = new Set(Object.keys(criteria));
|
|
851
|
-
const
|
|
1195
|
+
const hasSymbolicFilterValue = normalizedPrompt
|
|
1196
|
+
.split(/\s+/u)
|
|
1197
|
+
.some((token) => token.length >= 2
|
|
1198
|
+
&& /[&/+.]/u.test(token)
|
|
1199
|
+
&& !this.tokenIsGroundedByAppliedCriteria(token, criteria));
|
|
1200
|
+
const hasUnresolvedDiscreteFilter = this.promptContainsMentionedUnresolvedDiscreteFilter(normalizedPrompt, criteria);
|
|
1201
|
+
const narrowsByValueShape = !hasSymbolicFilterValue
|
|
1202
|
+
&& !hasUnresolvedDiscreteFilter
|
|
1203
|
+
&& (this.promptHasCompensationRangeIntent(normalizedPrompt)
|
|
1204
|
+
|| this.promptHasNumericRangeComparison(normalizedPrompt)
|
|
1205
|
+
|| this.promptHasDateRangeComparison(normalizedPrompt));
|
|
1206
|
+
const candidateEntries = this.filterFieldCatalogEntries
|
|
1207
|
+
.filter((entry) => !usedFields.has(entry.name))
|
|
1208
|
+
.filter((entry) => !this.promptMentionsFilterFieldAsNonRestrictiveScope(normalizedPrompt, entry))
|
|
1209
|
+
.filter((entry) => {
|
|
1210
|
+
if (!narrowsByValueShape)
|
|
1211
|
+
return true;
|
|
1212
|
+
if (this.promptHasCompensationRangeIntent(normalizedPrompt)) {
|
|
1213
|
+
return this.isCompensationRangeFilterEntry(entry);
|
|
1214
|
+
}
|
|
1215
|
+
if (this.promptHasNumericRangeComparison(normalizedPrompt)) {
|
|
1216
|
+
return this.isNumericRangeFilterEntry(entry);
|
|
1217
|
+
}
|
|
1218
|
+
if (this.promptHasDateRangeComparison(normalizedPrompt)) {
|
|
1219
|
+
return this.isDateRangeFilterEntry(entry);
|
|
1220
|
+
}
|
|
1221
|
+
return true;
|
|
1222
|
+
});
|
|
1223
|
+
if (narrowsByValueShape && !candidateEntries.length) {
|
|
1224
|
+
return [];
|
|
1225
|
+
}
|
|
1226
|
+
const fallbackEntries = this.filterFieldCatalogEntries
|
|
852
1227
|
.filter((entry) => !usedFields.has(entry.name))
|
|
1228
|
+
.filter((entry) => !this.promptMentionsFilterFieldAsNonRestrictiveScope(normalizedPrompt, entry));
|
|
1229
|
+
const ranked = (candidateEntries.length ? candidateEntries : fallbackEntries)
|
|
853
1230
|
.map((entry) => ({
|
|
854
1231
|
entry,
|
|
855
1232
|
score: this.selectedRecordFilterValuePromptScore(entry, normalizedPrompt)
|
|
@@ -920,6 +1297,7 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
920
1297
|
...entry.aliases,
|
|
921
1298
|
...entry.relatedColumnFields,
|
|
922
1299
|
...entry.relatedColumnLabels,
|
|
1300
|
+
...entry.valueHints,
|
|
923
1301
|
...displayValues,
|
|
924
1302
|
];
|
|
925
1303
|
return values.some((value) => value && this.promptContainsAnyVariant(token, value));
|
|
@@ -937,7 +1315,9 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
937
1315
|
'filtrar',
|
|
938
1316
|
'filtre',
|
|
939
1317
|
'filtro',
|
|
1318
|
+
'agora',
|
|
940
1319
|
'quero',
|
|
1320
|
+
'quem',
|
|
941
1321
|
'ver',
|
|
942
1322
|
'mostra',
|
|
943
1323
|
'mostrar',
|
|
@@ -947,6 +1327,26 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
947
1327
|
'busca',
|
|
948
1328
|
'procura',
|
|
949
1329
|
'procurar',
|
|
1330
|
+
'confirma',
|
|
1331
|
+
'confirmar',
|
|
1332
|
+
'aplique',
|
|
1333
|
+
'aplicar',
|
|
1334
|
+
'posso',
|
|
1335
|
+
'para',
|
|
1336
|
+
'eu',
|
|
1337
|
+
'esse',
|
|
1338
|
+
'essa',
|
|
1339
|
+
'tabela',
|
|
1340
|
+
'funcionario',
|
|
1341
|
+
'funcionarios',
|
|
1342
|
+
'funcionário',
|
|
1343
|
+
'funcionários',
|
|
1344
|
+
'qualquer',
|
|
1345
|
+
'qq',
|
|
1346
|
+
'depto',
|
|
1347
|
+
'departamento',
|
|
1348
|
+
'departamentos',
|
|
1349
|
+
'serve',
|
|
950
1350
|
'de',
|
|
951
1351
|
'do',
|
|
952
1352
|
'da',
|
|
@@ -990,6 +1390,18 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
990
1390
|
'admitidas',
|
|
991
1391
|
'admitiu',
|
|
992
1392
|
'admitiram',
|
|
1393
|
+
'ganha',
|
|
1394
|
+
'ganham',
|
|
1395
|
+
'ganhando',
|
|
1396
|
+
'recebe',
|
|
1397
|
+
'recebem',
|
|
1398
|
+
'recebendo',
|
|
1399
|
+
'remuneracao',
|
|
1400
|
+
'remuneração',
|
|
1401
|
+
'pagamento',
|
|
1402
|
+
'folha',
|
|
1403
|
+
'salario',
|
|
1404
|
+
'salário',
|
|
993
1405
|
].map((token) => this.normalizeLabel(token)));
|
|
994
1406
|
const fieldMentionTokens = new Set([
|
|
995
1407
|
entry.name,
|
|
@@ -1023,12 +1435,14 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1023
1435
|
? selectedCandidate['displayValues'].map((value) => this.stringValue(value)).filter((value) => !!value)
|
|
1024
1436
|
: [];
|
|
1025
1437
|
return [
|
|
1438
|
+
this.stringValue(criteria[field]),
|
|
1026
1439
|
entry.name,
|
|
1027
1440
|
entry.label,
|
|
1028
1441
|
this.humanizeFilterField(entry.name),
|
|
1029
1442
|
...entry.aliases,
|
|
1030
1443
|
...entry.relatedColumnFields,
|
|
1031
1444
|
...entry.relatedColumnLabels,
|
|
1445
|
+
...entry.valueHints,
|
|
1032
1446
|
...displayValues,
|
|
1033
1447
|
].some((value) => value && this.promptContainsAnyVariant(token, value));
|
|
1034
1448
|
});
|
|
@@ -1046,6 +1460,7 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1046
1460
|
'buscar',
|
|
1047
1461
|
'procura',
|
|
1048
1462
|
'procurar',
|
|
1463
|
+
'quem',
|
|
1049
1464
|
'mostra',
|
|
1050
1465
|
'mostrar',
|
|
1051
1466
|
'liste',
|
|
@@ -1062,6 +1477,19 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1062
1477
|
'apos',
|
|
1063
1478
|
'após',
|
|
1064
1479
|
'desde',
|
|
1480
|
+
'mais de',
|
|
1481
|
+
'mais que',
|
|
1482
|
+
'menos de',
|
|
1483
|
+
'menos que',
|
|
1484
|
+
'ganha',
|
|
1485
|
+
'ganham',
|
|
1486
|
+
'ganhando',
|
|
1487
|
+
'recebe',
|
|
1488
|
+
'recebem',
|
|
1489
|
+
'remuneracao',
|
|
1490
|
+
'remuneração',
|
|
1491
|
+
'salario',
|
|
1492
|
+
'salário',
|
|
1065
1493
|
].some((token) => normalizedPrompt.includes(this.normalizeLabel(token)));
|
|
1066
1494
|
}
|
|
1067
1495
|
promptRequestsVisualOrStructuralEdit(normalizedPrompt) {
|
|
@@ -1101,8 +1529,31 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1101
1529
|
this.completeImplicitBooleanCriteriaFromPrompt(normalizedPrompt, criteria);
|
|
1102
1530
|
this.completeImplicitDateRangeCriteriaFromPrompt(normalizedPrompt, criteria);
|
|
1103
1531
|
this.completeImplicitNumericRangeCriteriaFromPrompt(normalizedPrompt, criteria);
|
|
1532
|
+
if (!Object.keys(criteria).length) {
|
|
1533
|
+
this.resolveImplicitTextCriteriaFromValueHints(normalizedPrompt, criteria);
|
|
1534
|
+
}
|
|
1104
1535
|
return Object.keys(criteria).length ? criteria : null;
|
|
1105
1536
|
}
|
|
1537
|
+
resolveDeclaredFilterConfirmationCriteria(normalizedGroundingPrompt, pendingClarification, contextHints) {
|
|
1538
|
+
const criteria = this.resolveDeclaredFilterCriteriaFromPrompt(normalizedGroundingPrompt, contextHints);
|
|
1539
|
+
if (criteria && Object.keys(criteria).length)
|
|
1540
|
+
return criteria;
|
|
1541
|
+
const assistantText = this.normalizeLabel(pendingClarification?.assistantMessage ?? '');
|
|
1542
|
+
if (!assistantText)
|
|
1543
|
+
return null;
|
|
1544
|
+
const confirmedCriteria = {};
|
|
1545
|
+
for (const entry of this.filterFieldCatalogEntries) {
|
|
1546
|
+
if (!this.isTextualFilterCriterion(entry))
|
|
1547
|
+
continue;
|
|
1548
|
+
if (!this.promptMentionsFilterField(assistantText, entry.name))
|
|
1549
|
+
continue;
|
|
1550
|
+
const textValue = this.extractClarifiedTextFilterValue(assistantText, entry, confirmedCriteria);
|
|
1551
|
+
if (textValue) {
|
|
1552
|
+
confirmedCriteria[entry.name] = this.normalizeRuntimeFilterCriterionForCatalogEntry(textValue, entry);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
return Object.keys(confirmedCriteria).length ? confirmedCriteria : null;
|
|
1556
|
+
}
|
|
1106
1557
|
completeImplicitBooleanCriteriaFromPrompt(normalizedPrompt, criteria) {
|
|
1107
1558
|
if (!this.promptHasBooleanFilterValue(normalizedPrompt))
|
|
1108
1559
|
return;
|
|
@@ -1202,13 +1653,33 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1202
1653
|
const candidates = this.filterFieldCatalogEntries
|
|
1203
1654
|
.filter((entry) => criteria[entry.name] === undefined)
|
|
1204
1655
|
.filter((entry) => this.isNumericRangeFilterEntry(entry));
|
|
1205
|
-
|
|
1656
|
+
const mentioned = candidates.filter((entry) => this.promptMentionsFilterField(normalizedPrompt, entry.name));
|
|
1657
|
+
const compensation = mentioned.length ? [] : candidates.filter((entry) => this.isCompensationRangeFilterEntry(entry));
|
|
1658
|
+
const eligible = mentioned.length ? mentioned : (this.promptHasCompensationRangeIntent(normalizedPrompt) ? compensation : candidates);
|
|
1659
|
+
if (eligible.length !== 1)
|
|
1206
1660
|
return;
|
|
1207
|
-
const criterion = this.resolveRangeFilterValue(normalizedPrompt,
|
|
1661
|
+
const criterion = this.resolveRangeFilterValue(normalizedPrompt, eligible[0]);
|
|
1208
1662
|
if (criterion !== undefined) {
|
|
1209
|
-
criteria[
|
|
1663
|
+
criteria[eligible[0].name] = criterion;
|
|
1210
1664
|
}
|
|
1211
1665
|
}
|
|
1666
|
+
promptHasCompensationRangeIntent(normalizedPrompt) {
|
|
1667
|
+
return this.promptHasNumericRangeComparison(normalizedPrompt)
|
|
1668
|
+
&& [
|
|
1669
|
+
'ganha',
|
|
1670
|
+
'ganham',
|
|
1671
|
+
'ganhando',
|
|
1672
|
+
'recebe',
|
|
1673
|
+
'recebem',
|
|
1674
|
+
'recebendo',
|
|
1675
|
+
'remuneracao',
|
|
1676
|
+
'remuneração',
|
|
1677
|
+
'pagamento',
|
|
1678
|
+
'folha',
|
|
1679
|
+
'salario',
|
|
1680
|
+
'salário',
|
|
1681
|
+
].some((token) => this.normalizedTextContainsApproxPhrase(normalizedPrompt, this.normalizeLabel(token)));
|
|
1682
|
+
}
|
|
1212
1683
|
promptHasNumericRangeComparison(normalizedPrompt) {
|
|
1213
1684
|
return /\b\d+(?:[,.]\d+)?(?:\s*(?:mil|k))?\b/u.test(normalizedPrompt)
|
|
1214
1685
|
&& this.promptHasAnyToken(normalizedPrompt, [
|
|
@@ -1257,6 +1728,34 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1257
1728
|
|| valueShape.includes('number');
|
|
1258
1729
|
return isRange && isNumericLike && !isDateLike;
|
|
1259
1730
|
}
|
|
1731
|
+
isCompensationRangeFilterEntry(entry) {
|
|
1732
|
+
if (!this.isNumericRangeFilterEntry(entry))
|
|
1733
|
+
return false;
|
|
1734
|
+
const text = this.normalizeLabel([
|
|
1735
|
+
entry.name,
|
|
1736
|
+
entry.label,
|
|
1737
|
+
this.humanizeFilterField(entry.name),
|
|
1738
|
+
entry.controlType,
|
|
1739
|
+
entry.criterionKind,
|
|
1740
|
+
entry.criterionValueShape,
|
|
1741
|
+
...entry.aliases,
|
|
1742
|
+
...entry.relatedColumnFields,
|
|
1743
|
+
...entry.relatedColumnLabels,
|
|
1744
|
+
].join(' '));
|
|
1745
|
+
return [
|
|
1746
|
+
'salario',
|
|
1747
|
+
'salário',
|
|
1748
|
+
'salary',
|
|
1749
|
+
'remuneracao',
|
|
1750
|
+
'remuneração',
|
|
1751
|
+
'compensacao',
|
|
1752
|
+
'compensação',
|
|
1753
|
+
'pagamento',
|
|
1754
|
+
'folha',
|
|
1755
|
+
'wage',
|
|
1756
|
+
'pay',
|
|
1757
|
+
].some((token) => this.normalizedTextContainsApproxPhrase(text, this.normalizeLabel(token)));
|
|
1758
|
+
}
|
|
1260
1759
|
resolveDeclaredFilterCriterionValue(normalizedPrompt, entry, contextHints) {
|
|
1261
1760
|
const type = this.normalizeLabel(entry.type ?? '');
|
|
1262
1761
|
const controlType = this.normalizeLabel(entry.controlType ?? '');
|
|
@@ -1671,16 +2170,24 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1671
2170
|
if (response.type === 'clarification') {
|
|
1672
2171
|
const questions = this.toClarificationQuestions(response, request);
|
|
1673
2172
|
const diagnostics = this.buildClarificationDiagnostics(response);
|
|
2173
|
+
const sourcePrompt = this.pendingClarificationSourcePromptForTurn(request, diagnostics);
|
|
2174
|
+
const assistantMessage = response.message || 'Preciso de mais detalhes para continuar.';
|
|
1674
2175
|
return {
|
|
1675
2176
|
state: 'clarification',
|
|
1676
2177
|
phase: 'clarify',
|
|
1677
2178
|
sessionId: response.sessionId ?? request.sessionId,
|
|
1678
2179
|
observationId: response.observationId ?? request.observationId ?? null,
|
|
1679
|
-
assistantMessage
|
|
2180
|
+
assistantMessage,
|
|
1680
2181
|
clarificationQuestions: questions,
|
|
1681
2182
|
quickReplies: this.toQuickReplies(response, request),
|
|
1682
2183
|
canApply: false,
|
|
1683
2184
|
diagnostics,
|
|
2185
|
+
pendingClarification: {
|
|
2186
|
+
sourcePrompt,
|
|
2187
|
+
assistantMessage,
|
|
2188
|
+
questions,
|
|
2189
|
+
diagnostics,
|
|
2190
|
+
},
|
|
1684
2191
|
};
|
|
1685
2192
|
}
|
|
1686
2193
|
if (response.type === 'info') {
|
|
@@ -1765,6 +2272,10 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1765
2272
|
if (continuedEarlyColumnPlan) {
|
|
1766
2273
|
return this.compileAdapterResponse(continuedEarlyColumnPlan, request);
|
|
1767
2274
|
}
|
|
2275
|
+
const continuedColumnVisibilityPlan = this.columnVisibilityPlanForGroundedClarification(response, request);
|
|
2276
|
+
if (continuedColumnVisibilityPlan) {
|
|
2277
|
+
return this.compileAdapterResponse(continuedColumnVisibilityPlan, request);
|
|
2278
|
+
}
|
|
1768
2279
|
const compiledExecutable = !this.responseCarriesClarificationChoices(response)
|
|
1769
2280
|
&& this.responseMayContainExecutableEnvelope(response)
|
|
1770
2281
|
? this.adapter.compileAiResponse?.(response)
|
|
@@ -1784,6 +2295,10 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1784
2295
|
warnings: warnings.length ? warnings : undefined,
|
|
1785
2296
|
};
|
|
1786
2297
|
delete executableResponse.type;
|
|
2298
|
+
const columnVisibilitySurfaceMismatch = this.columnVisibilityPlanForMisroutedSurfaceRuntime(executableResponse, request);
|
|
2299
|
+
if (columnVisibilitySurfaceMismatch) {
|
|
2300
|
+
return this.compileAdapterResponse(columnVisibilitySurfaceMismatch, request);
|
|
2301
|
+
}
|
|
1787
2302
|
const visualSurfaceMismatch = this.visualPresentationSurfaceRuntimeMismatch(executableResponse, request);
|
|
1788
2303
|
if (visualSurfaceMismatch) {
|
|
1789
2304
|
return visualSurfaceMismatch;
|
|
@@ -1795,6 +2310,10 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1795
2310
|
return executableResponse;
|
|
1796
2311
|
}
|
|
1797
2312
|
if (compiledExecutable?.type === 'error') {
|
|
2313
|
+
const continuedColumnVisibilityError = this.columnVisibilityPlanForMisroutedSurfaceError(response, request, compiledExecutable);
|
|
2314
|
+
if (continuedColumnVisibilityError) {
|
|
2315
|
+
return this.compileAdapterResponse(continuedColumnVisibilityError, request);
|
|
2316
|
+
}
|
|
1798
2317
|
const continuedInvalidExecutable = this.selectedRecordSurfaceRuntimeOperationForInvalidExecutable(response, request, compiledExecutable.warnings);
|
|
1799
2318
|
if (continuedInvalidExecutable) {
|
|
1800
2319
|
return continuedInvalidExecutable;
|
|
@@ -1809,6 +2328,10 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1809
2328
|
warnings: compiledExecutable.warnings,
|
|
1810
2329
|
};
|
|
1811
2330
|
}
|
|
2331
|
+
const continuedColumnVisibilityNarrative = this.columnVisibilityPlanForGroundedNarrative(response, request);
|
|
2332
|
+
if (continuedColumnVisibilityNarrative) {
|
|
2333
|
+
return this.compileAdapterResponse(continuedColumnVisibilityNarrative, request);
|
|
2334
|
+
}
|
|
1812
2335
|
const continuedSurfaceRowActionFromInfo = this.selectedRecordSurfaceRowActionPlanForInfo(response, request);
|
|
1813
2336
|
if (continuedSurfaceRowActionFromInfo) {
|
|
1814
2337
|
return this.compileAdapterResponse(continuedSurfaceRowActionFromInfo, request);
|
|
@@ -1887,6 +2410,10 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1887
2410
|
};
|
|
1888
2411
|
}
|
|
1889
2412
|
if (!compiled) {
|
|
2413
|
+
const continuedColumnVisibilityNarrative = this.columnVisibilityPlanForGroundedNarrative(response, request);
|
|
2414
|
+
if (continuedColumnVisibilityNarrative) {
|
|
2415
|
+
return this.compileAdapterResponse(continuedColumnVisibilityNarrative, request);
|
|
2416
|
+
}
|
|
1890
2417
|
const continuedColumnFormatNarrative = this.columnFormatPlanForNonExecutableNarrative(response, request);
|
|
1891
2418
|
if (continuedColumnFormatNarrative) {
|
|
1892
2419
|
return this.compileAdapterResponse(continuedColumnFormatNarrative, request);
|
|
@@ -1898,6 +2425,10 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1898
2425
|
return response;
|
|
1899
2426
|
}
|
|
1900
2427
|
if (compiled.type === 'error') {
|
|
2428
|
+
const continuedColumnVisibilityError = this.columnVisibilityPlanForMisroutedSurfaceError(response, request, compiled);
|
|
2429
|
+
if (continuedColumnVisibilityError) {
|
|
2430
|
+
return this.compileAdapterResponse(continuedColumnVisibilityError, request);
|
|
2431
|
+
}
|
|
1901
2432
|
const continuedBulkRouteAction = this.bulkRouteActionPlanForInvalidExecutable(response, request, compiled.warnings);
|
|
1902
2433
|
if (continuedBulkRouteAction) {
|
|
1903
2434
|
return this.compileAdapterResponse(continuedBulkRouteAction, request);
|
|
@@ -1953,6 +2484,10 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
1953
2484
|
patch: normalizedCompiled.patch,
|
|
1954
2485
|
warnings: warnings.length ? warnings : undefined,
|
|
1955
2486
|
};
|
|
2487
|
+
const columnVisibilitySurfaceMismatch = this.columnVisibilityPlanForMisroutedSurfaceRuntime(compiledResponse, request);
|
|
2488
|
+
if (columnVisibilitySurfaceMismatch) {
|
|
2489
|
+
return this.compileAdapterResponse(columnVisibilitySurfaceMismatch, request);
|
|
2490
|
+
}
|
|
1956
2491
|
const visualSurfaceMismatch = this.visualPresentationSurfaceRuntimeMismatch(compiledResponse, request);
|
|
1957
2492
|
if (visualSurfaceMismatch) {
|
|
1958
2493
|
return visualSurfaceMismatch;
|
|
@@ -4904,6 +5439,199 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
4904
5439
|
],
|
|
4905
5440
|
};
|
|
4906
5441
|
}
|
|
5442
|
+
columnVisibilityPlanForMisroutedSurfaceRuntime(response, request) {
|
|
5443
|
+
if (!request)
|
|
5444
|
+
return null;
|
|
5445
|
+
const prompt = this.columnVisibilityPromptForTurn(request);
|
|
5446
|
+
if (!this.promptRequestsColumnVisibilityEdit(this.normalizeLabel(prompt)))
|
|
5447
|
+
return null;
|
|
5448
|
+
if (!this.patchContainsRuntimeOperationId(response.patch, 'dynamicPage.surface.open'))
|
|
5449
|
+
return null;
|
|
5450
|
+
const currentConfig = this.adapter.getCurrentConfig?.();
|
|
5451
|
+
const columns = Array.isArray(currentConfig?.['columns'])
|
|
5452
|
+
? currentConfig['columns']
|
|
5453
|
+
.map((column) => this.toRecord(column))
|
|
5454
|
+
.filter((column) => !!column && !!this.stringValue(column['field']))
|
|
5455
|
+
: [];
|
|
5456
|
+
const operations = this.columnVisibilityOperationsFromPrompt(prompt, columns);
|
|
5457
|
+
if (!operations.length) {
|
|
5458
|
+
return {
|
|
5459
|
+
type: 'clarification',
|
|
5460
|
+
sessionId: request.sessionId,
|
|
5461
|
+
message: 'Entendi que o pedido é sobre ocultar ou exibir colunas, não sobre abrir uma superfície do registro.',
|
|
5462
|
+
questions: ['Quais colunas você quer ocultar ou exibir?'],
|
|
5463
|
+
options: columns
|
|
5464
|
+
.slice(0, 8)
|
|
5465
|
+
.map((column) => this.stringValue(column['header']) || this.stringValue(column['field']))
|
|
5466
|
+
.filter((label) => !!label),
|
|
5467
|
+
warnings: [
|
|
5468
|
+
...(response.warnings ?? []),
|
|
5469
|
+
'column-visibility-request-blocked-surface-runtime-operation',
|
|
5470
|
+
],
|
|
5471
|
+
};
|
|
5472
|
+
}
|
|
5473
|
+
return this.componentEditPlanResponse(operations, 'Vou ocultar as colunas indicadas para a visualizacao solicitada.', [
|
|
5474
|
+
...(response.warnings ?? []),
|
|
5475
|
+
'column-visibility-continued-from-surface-runtime-misroute',
|
|
5476
|
+
'Residual continuity guard acted only after the LLM proposed dynamicPage.surface.open for a column visibility/privacy request grounded in declared table columns.',
|
|
5477
|
+
]);
|
|
5478
|
+
}
|
|
5479
|
+
columnVisibilityPlanForGroundedClarification(response, request) {
|
|
5480
|
+
if (!request)
|
|
5481
|
+
return null;
|
|
5482
|
+
if (response.type !== 'clarification')
|
|
5483
|
+
return null;
|
|
5484
|
+
const prompt = this.columnVisibilityPromptForTurn(request);
|
|
5485
|
+
if (!this.promptRequestsColumnVisibilityEdit(this.normalizeLabel(prompt)))
|
|
5486
|
+
return null;
|
|
5487
|
+
const questionText = [
|
|
5488
|
+
response.message,
|
|
5489
|
+
...(response.questions ?? []),
|
|
5490
|
+
...(response.options ?? []),
|
|
5491
|
+
].join(' ');
|
|
5492
|
+
const asksForColumn = this.normalizedTextIncludesAny(this.normalizeLabel(questionText), [
|
|
5493
|
+
'qual coluna',
|
|
5494
|
+
'quais colunas',
|
|
5495
|
+
'coluna devo usar',
|
|
5496
|
+
'colunas devo usar',
|
|
5497
|
+
]);
|
|
5498
|
+
const asksForVisibilityScope = this.normalizedTextIncludesAny(this.normalizeLabel(questionText), [
|
|
5499
|
+
'globalmente',
|
|
5500
|
+
'todos os usuarios',
|
|
5501
|
+
'todos os usuários',
|
|
5502
|
+
'apresentacao publica',
|
|
5503
|
+
'apresentação pública',
|
|
5504
|
+
'visualizacao publica',
|
|
5505
|
+
'visualização pública',
|
|
5506
|
+
'vista padrao',
|
|
5507
|
+
'vista padrão',
|
|
5508
|
+
'confirma qual opcao',
|
|
5509
|
+
'confirma qual opção',
|
|
5510
|
+
]);
|
|
5511
|
+
if (!asksForColumn && !asksForVisibilityScope)
|
|
5512
|
+
return null;
|
|
5513
|
+
const currentConfig = this.adapter.getCurrentConfig?.();
|
|
5514
|
+
const columns = Array.isArray(currentConfig?.['columns'])
|
|
5515
|
+
? currentConfig['columns']
|
|
5516
|
+
.map((column) => this.toRecord(column))
|
|
5517
|
+
.filter((column) => !!column && !!this.stringValue(column['field']))
|
|
5518
|
+
: [];
|
|
5519
|
+
const operations = this.columnVisibilityOperationsFromPrompt(prompt, columns);
|
|
5520
|
+
if (!operations.length)
|
|
5521
|
+
return null;
|
|
5522
|
+
return this.componentEditPlanResponse(operations, 'Vou ocultar as colunas indicadas para a visualizacao solicitada.', [
|
|
5523
|
+
...(response.warnings ?? []),
|
|
5524
|
+
'column-visibility-continued-from-grounded-clarification',
|
|
5525
|
+
'Residual continuity guard acted only after the LLM asked which column to use even though the column visibility request was grounded in declared table columns.',
|
|
5526
|
+
]);
|
|
5527
|
+
}
|
|
5528
|
+
columnVisibilityPlanForGroundedNarrative(response, request) {
|
|
5529
|
+
if (!request)
|
|
5530
|
+
return null;
|
|
5531
|
+
const prompt = this.columnVisibilityPromptForTurn(request);
|
|
5532
|
+
if (!this.promptRequestsColumnVisibilityEdit(this.normalizeLabel(prompt)))
|
|
5533
|
+
return null;
|
|
5534
|
+
const responseText = this.normalizeLabel([
|
|
5535
|
+
response.message,
|
|
5536
|
+
response.explanation,
|
|
5537
|
+
response.code,
|
|
5538
|
+
].join(' '));
|
|
5539
|
+
const narratesVisibilityPlan = this.normalizedTextIncludesAny(responseText, [
|
|
5540
|
+
'componenteditplan',
|
|
5541
|
+
'column.visibility.set',
|
|
5542
|
+
'visible false',
|
|
5543
|
+
'invisivel',
|
|
5544
|
+
'invisível',
|
|
5545
|
+
'ocultar a coluna',
|
|
5546
|
+
'ocultar as colunas',
|
|
5547
|
+
]);
|
|
5548
|
+
if (!narratesVisibilityPlan)
|
|
5549
|
+
return null;
|
|
5550
|
+
const currentConfig = this.adapter.getCurrentConfig?.();
|
|
5551
|
+
const columns = Array.isArray(currentConfig?.['columns'])
|
|
5552
|
+
? currentConfig['columns']
|
|
5553
|
+
.map((column) => this.toRecord(column))
|
|
5554
|
+
.filter((column) => !!column && !!this.stringValue(column['field']))
|
|
5555
|
+
: [];
|
|
5556
|
+
const operations = this.columnVisibilityOperationsFromPrompt(prompt, columns);
|
|
5557
|
+
if (!operations.length)
|
|
5558
|
+
return null;
|
|
5559
|
+
return this.componentEditPlanResponse(operations, 'Vou ocultar as colunas indicadas para a visualizacao solicitada.', [
|
|
5560
|
+
...(response.warnings ?? []),
|
|
5561
|
+
'column-visibility-continued-from-non-executable-narrative',
|
|
5562
|
+
'Residual continuity guard acted only after the LLM narrated a column visibility plan without returning an executable envelope.',
|
|
5563
|
+
]);
|
|
5564
|
+
}
|
|
5565
|
+
columnVisibilityPlanForMisroutedSurfaceError(response, request, compiledError) {
|
|
5566
|
+
if (!request)
|
|
5567
|
+
return null;
|
|
5568
|
+
const prompt = this.columnVisibilityPromptForTurn(request);
|
|
5569
|
+
if (!this.promptRequestsColumnVisibilityEdit(this.normalizeLabel(prompt)))
|
|
5570
|
+
return null;
|
|
5571
|
+
const errorText = this.normalizeLabel([
|
|
5572
|
+
response.message,
|
|
5573
|
+
response.explanation,
|
|
5574
|
+
compiledError.message,
|
|
5575
|
+
compiledError.explanation,
|
|
5576
|
+
...(compiledError.warnings ?? []),
|
|
5577
|
+
].join(' '));
|
|
5578
|
+
if (!this.normalizedTextIncludesAny(errorText, [
|
|
5579
|
+
'dynamicpage.surface.open',
|
|
5580
|
+
'surface.open',
|
|
5581
|
+
'superficie',
|
|
5582
|
+
'superfície',
|
|
5583
|
+
]))
|
|
5584
|
+
return null;
|
|
5585
|
+
const currentConfig = this.adapter.getCurrentConfig?.();
|
|
5586
|
+
const columns = Array.isArray(currentConfig?.['columns'])
|
|
5587
|
+
? currentConfig['columns']
|
|
5588
|
+
.map((column) => this.toRecord(column))
|
|
5589
|
+
.filter((column) => !!column && !!this.stringValue(column['field']))
|
|
5590
|
+
: [];
|
|
5591
|
+
const operations = this.columnVisibilityOperationsFromPrompt(prompt, columns);
|
|
5592
|
+
if (!operations.length)
|
|
5593
|
+
return null;
|
|
5594
|
+
return this.componentEditPlanResponse(operations, 'Vou ocultar as colunas indicadas para a visualizacao solicitada.', [
|
|
5595
|
+
...(response.warnings ?? []),
|
|
5596
|
+
...(compiledError.warnings ?? []),
|
|
5597
|
+
'column-visibility-continued-from-surface-runtime-error',
|
|
5598
|
+
'Residual continuity guard acted only after a misrouted surface runtime operation failed validation for a column visibility request.',
|
|
5599
|
+
]);
|
|
5600
|
+
}
|
|
5601
|
+
columnVisibilityPromptForTurn(request) {
|
|
5602
|
+
const currentPrompt = (request.prompt ?? '').trim();
|
|
5603
|
+
if (this.promptRequestsColumnVisibilityEdit(this.normalizeLabel(currentPrompt))) {
|
|
5604
|
+
return currentPrompt;
|
|
5605
|
+
}
|
|
5606
|
+
const previousVisibilityPrompt = [...(request.messages ?? [])]
|
|
5607
|
+
.reverse()
|
|
5608
|
+
.filter((message) => message.role === 'user')
|
|
5609
|
+
.map((message) => message.text.trim())
|
|
5610
|
+
.find((message) => this.promptRequestsColumnVisibilityEdit(this.normalizeLabel(message)));
|
|
5611
|
+
return [previousVisibilityPrompt, currentPrompt]
|
|
5612
|
+
.filter((part) => !!part)
|
|
5613
|
+
.join(' ');
|
|
5614
|
+
}
|
|
5615
|
+
columnVisibilityOperationsFromPrompt(prompt, columns) {
|
|
5616
|
+
const hide = !this.normalizedTextIncludesAny(this.normalizeLabel(prompt), [
|
|
5617
|
+
'exibir',
|
|
5618
|
+
'mostrar coluna',
|
|
5619
|
+
'mostra coluna',
|
|
5620
|
+
'revelar',
|
|
5621
|
+
]);
|
|
5622
|
+
const operations = [];
|
|
5623
|
+
for (const column of columns) {
|
|
5624
|
+
const field = this.stringValue(column['field']);
|
|
5625
|
+
if (!field || !this.textMentionsColumn(prompt, column))
|
|
5626
|
+
continue;
|
|
5627
|
+
operations.push({
|
|
5628
|
+
operationId: 'column.visibility.set',
|
|
5629
|
+
target: { kind: 'column', field },
|
|
5630
|
+
input: { visible: !hide },
|
|
5631
|
+
});
|
|
5632
|
+
}
|
|
5633
|
+
return operations;
|
|
5634
|
+
}
|
|
4907
5635
|
requestCarriesVisualPresentationContext(request) {
|
|
4908
5636
|
const actionHints = this.toRecord(request.action?.contextHints);
|
|
4909
5637
|
const requestHints = this.toRecord(request.contextHints);
|
|
@@ -4929,6 +5657,8 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
4929
5657
|
if (!normalizedPrompt)
|
|
4930
5658
|
return false;
|
|
4931
5659
|
const entry = this.filterFieldCatalogEntries.find((candidate) => candidate.name === fieldName);
|
|
5660
|
+
if (entry && this.promptMentionsFilterFieldAsNonRestrictiveScope(normalizedPrompt, entry))
|
|
5661
|
+
return false;
|
|
4932
5662
|
const rawCandidates = [
|
|
4933
5663
|
fieldName,
|
|
4934
5664
|
this.humanizeFilterField(fieldName),
|
|
@@ -4941,6 +5671,59 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
4941
5671
|
.flatMap((candidate) => this.filterFieldMentionVariants(candidate ?? ''))
|
|
4942
5672
|
.some((candidate) => candidate && this.normalizedTextContainsApproxPhrase(normalizedPrompt, candidate));
|
|
4943
5673
|
}
|
|
5674
|
+
promptMentionsFilterFieldAsNonRestrictiveScope(normalizedPrompt, entry) {
|
|
5675
|
+
const variants = [
|
|
5676
|
+
entry.name,
|
|
5677
|
+
entry.label,
|
|
5678
|
+
this.humanizeFilterField(entry.name),
|
|
5679
|
+
...entry.aliases,
|
|
5680
|
+
...entry.relatedColumnFields,
|
|
5681
|
+
...entry.relatedColumnLabels,
|
|
5682
|
+
].flatMap((candidate) => this.filterFieldMentionVariants(candidate ?? ''));
|
|
5683
|
+
return variants.some((variant) => {
|
|
5684
|
+
if (!variant)
|
|
5685
|
+
return false;
|
|
5686
|
+
return [
|
|
5687
|
+
`qualquer ${variant}`,
|
|
5688
|
+
`qq ${variant}`,
|
|
5689
|
+
`tanto faz ${variant}`,
|
|
5690
|
+
`${variant} tanto faz`,
|
|
5691
|
+
`${variant} qualquer`,
|
|
5692
|
+
`independente de ${variant}`,
|
|
5693
|
+
`nao importa ${variant}`,
|
|
5694
|
+
`${variant} nao importa`,
|
|
5695
|
+
].some((phrase) => this.normalizedTextContainsExactPhrase(normalizedPrompt, this.normalizeLabel(phrase)));
|
|
5696
|
+
});
|
|
5697
|
+
}
|
|
5698
|
+
removeNonRestrictiveFilterFieldClauses(value) {
|
|
5699
|
+
let normalized = value.trim();
|
|
5700
|
+
if (!normalized)
|
|
5701
|
+
return '';
|
|
5702
|
+
const fieldTerms = this.filterFieldCatalogEntries
|
|
5703
|
+
.flatMap((entry) => [
|
|
5704
|
+
entry.name,
|
|
5705
|
+
entry.label,
|
|
5706
|
+
this.humanizeFilterField(entry.name),
|
|
5707
|
+
...entry.aliases,
|
|
5708
|
+
...entry.relatedColumnFields,
|
|
5709
|
+
...entry.relatedColumnLabels,
|
|
5710
|
+
])
|
|
5711
|
+
.flatMap((term) => this.filterFieldMentionVariants(term ?? ''))
|
|
5712
|
+
.filter((term, index, terms) => !!term && terms.indexOf(term) === index);
|
|
5713
|
+
for (const term of fieldTerms) {
|
|
5714
|
+
const escaped = term.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
5715
|
+
normalized = normalized
|
|
5716
|
+
.replace(new RegExp(`(?:,|;)?\\s*(?:tanto faz|qualquer|qq|independente de|nao importa|não importa)\\s+${escaped}\\b`, 'giu'), '')
|
|
5717
|
+
.replace(new RegExp(`(?:,|;)?\\s*${escaped}\\s+(?:tanto faz|qualquer|nao importa|não importa)\\b`, 'giu'), '');
|
|
5718
|
+
}
|
|
5719
|
+
return normalized.trim();
|
|
5720
|
+
}
|
|
5721
|
+
normalizedTextContainsExactPhrase(normalizedText, normalizedPhrase) {
|
|
5722
|
+
if (!normalizedText || !normalizedPhrase)
|
|
5723
|
+
return false;
|
|
5724
|
+
const escaped = normalizedPhrase.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&').replace(/\s+/gu, '\\s+');
|
|
5725
|
+
return new RegExp(`(^|[^a-z0-9])${escaped}($|[^a-z0-9])`, 'u').test(normalizedText);
|
|
5726
|
+
}
|
|
4944
5727
|
selectedRecordFilterPromptGroundingScore(prompt, candidate) {
|
|
4945
5728
|
const fieldName = this.stringValue(candidate['field']);
|
|
4946
5729
|
if (!fieldName)
|
|
@@ -5493,7 +6276,20 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
5493
6276
|
}
|
|
5494
6277
|
buildClarificationDiagnostics(response) {
|
|
5495
6278
|
const continuation = this.extractPendingComponentEditContinuation(response);
|
|
5496
|
-
|
|
6279
|
+
const responseDiagnostics = this.toRecord(response.diagnostics);
|
|
6280
|
+
if (!continuation && !responseDiagnostics)
|
|
6281
|
+
return undefined;
|
|
6282
|
+
return {
|
|
6283
|
+
...(responseDiagnostics ?? {}),
|
|
6284
|
+
...(continuation ? { tableComponentEditContinuation: continuation } : {}),
|
|
6285
|
+
};
|
|
6286
|
+
}
|
|
6287
|
+
pendingClarificationSourcePromptForTurn(request, diagnostics) {
|
|
6288
|
+
const declaredFilter = this.toRecord(diagnostics?.['tableDeclaredFilterClarification']);
|
|
6289
|
+
return this.stringValue(declaredFilter?.['sourcePrompt']).trim()
|
|
6290
|
+
|| request.pendingClarification?.sourcePrompt?.trim()
|
|
6291
|
+
|| request.prompt?.trim()
|
|
6292
|
+
|| '';
|
|
5497
6293
|
}
|
|
5498
6294
|
buildReviewDiagnostics(response, warnings) {
|
|
5499
6295
|
const memory = this.extractComponentEditDecisionMemory(response);
|
|
@@ -6377,6 +7173,9 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
6377
7173
|
const normalizedOptions = new Set(options
|
|
6378
7174
|
.map((option) => this.normalizeLabel(option))
|
|
6379
7175
|
.filter((option) => !!option));
|
|
7176
|
+
if (this.promptRequestsColumnVisibilityEdit(prompt)) {
|
|
7177
|
+
return null;
|
|
7178
|
+
}
|
|
6380
7179
|
const promptLooksLikeFilter = this.promptRequestsRuntimeFilter(prompt)
|
|
6381
7180
|
|| ['filtro', 'filtrar', 'busca', 'buscar', 'procura', 'procurar', 'mostra', 'mostrar'].some((token) => this.normalizedTextContainsApproxToken(prompt, token));
|
|
6382
7181
|
const responseLooksFilterFieldClarification = responseText.includes('filtro declarado')
|
|
@@ -6538,7 +7337,7 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
6538
7337
|
return quoted;
|
|
6539
7338
|
const match = trimmed.match(/\b(?:de|da|do|dos|das|por|com|contendo|contem|contém)\s+(.{2,})$/iu);
|
|
6540
7339
|
const candidate = (match?.[1] ?? '').trim();
|
|
6541
|
-
return candidate
|
|
7340
|
+
return this.removeNonRestrictiveFilterFieldClauses(candidate)
|
|
6542
7341
|
.replace(/[?.!,;:]+$/u, '')
|
|
6543
7342
|
.trim();
|
|
6544
7343
|
}
|
|
@@ -6576,6 +7375,7 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
6576
7375
|
};
|
|
6577
7376
|
});
|
|
6578
7377
|
}
|
|
7378
|
+
return [];
|
|
6579
7379
|
}
|
|
6580
7380
|
if ((response.type === 'clarification' || response.type === 'info')
|
|
6581
7381
|
&& this.shouldCurateVisibilityClarificationQuickReplies(response, prompt)) {
|
|
@@ -6684,6 +7484,49 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
6684
7484
|
// semantic scope choices the user needs to answer.
|
|
6685
7485
|
return true;
|
|
6686
7486
|
}
|
|
7487
|
+
promptRequestsColumnVisibilityEdit(normalizedPrompt) {
|
|
7488
|
+
if (!normalizedPrompt)
|
|
7489
|
+
return false;
|
|
7490
|
+
const asksVisibilityOrPrivacy = [
|
|
7491
|
+
'ocultacao',
|
|
7492
|
+
'ocultação',
|
|
7493
|
+
'oculta',
|
|
7494
|
+
'ocultar',
|
|
7495
|
+
'esconde',
|
|
7496
|
+
'esconder',
|
|
7497
|
+
'remova a coluna',
|
|
7498
|
+
'remover a coluna',
|
|
7499
|
+
'remova as colunas',
|
|
7500
|
+
'remover as colunas',
|
|
7501
|
+
'tirar da visualizacao',
|
|
7502
|
+
'tirar da visualização',
|
|
7503
|
+
'publico',
|
|
7504
|
+
'público',
|
|
7505
|
+
'privacidade',
|
|
7506
|
+
'sensivel',
|
|
7507
|
+
'sensível',
|
|
7508
|
+
].some((token) => this.normalizedTextContainsApproxPhrase(normalizedPrompt, token));
|
|
7509
|
+
if (!asksVisibilityOrPrivacy)
|
|
7510
|
+
return false;
|
|
7511
|
+
const mentionsColumnScope = [
|
|
7512
|
+
'coluna',
|
|
7513
|
+
'colunas',
|
|
7514
|
+
'visualizacao',
|
|
7515
|
+
'visualização',
|
|
7516
|
+
'tabela',
|
|
7517
|
+
'email',
|
|
7518
|
+
'e-mail',
|
|
7519
|
+
'salario',
|
|
7520
|
+
'salário',
|
|
7521
|
+
'cpf',
|
|
7522
|
+
'documento',
|
|
7523
|
+
'telefone',
|
|
7524
|
+
].some((token) => this.normalizedTextContainsApproxPhrase(normalizedPrompt, token));
|
|
7525
|
+
// Residual guard only: the LLM/authoring contract still decides the primary
|
|
7526
|
+
// intent. Once a turn is already in a column-visibility scope, filter
|
|
7527
|
+
// quick-reply curation must not reinterpret it as row filtering.
|
|
7528
|
+
return mentionsColumnScope;
|
|
7529
|
+
}
|
|
6687
7530
|
visibilityClarificationQuickReplyOptions() {
|
|
6688
7531
|
return [
|
|
6689
7532
|
{
|
|
@@ -6728,6 +7571,10 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
6728
7571
|
const optionCount = response.options?.length ?? 0;
|
|
6729
7572
|
if (payloadCount <= 0 && optionCount <= 0)
|
|
6730
7573
|
return false;
|
|
7574
|
+
if (this.promptRequestsColumnVisibilityEdit(normalizedPrompt))
|
|
7575
|
+
return false;
|
|
7576
|
+
if (payloadCount > 0 && normalizedPrompt && !this.promptRequestsRuntimeFilter(normalizedPrompt))
|
|
7577
|
+
return false;
|
|
6731
7578
|
if (this.responseAsksForDeclaredFilterField(response))
|
|
6732
7579
|
return true;
|
|
6733
7580
|
if (!normalizedPrompt || !this.promptRequestsRuntimeFilter(normalizedPrompt))
|