@smart-cloud/ai-kit-ui 1.3.7 → 1.3.8
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/dist/index.cjs +9 -9
- package/dist/index.js +9 -9
- package/package.json +1 -1
- package/src/doc-search/DocSearch.tsx +161 -124
package/package.json
CHANGED
|
@@ -140,6 +140,7 @@ const DocSearchBase: FC<Props> = (props) => {
|
|
|
140
140
|
useAiRun<SearchResult>();
|
|
141
141
|
|
|
142
142
|
const autoRunOnceRef = useRef(false);
|
|
143
|
+
const prevSelectedCategoriesRef = useRef<string[]>([]);
|
|
143
144
|
|
|
144
145
|
const sessionId = result?.sessionId;
|
|
145
146
|
const citationDocs = result?.citations?.docs ?? [];
|
|
@@ -188,6 +189,14 @@ const DocSearchBase: FC<Props> = (props) => {
|
|
|
188
189
|
return Boolean((text && text.trim().length > 0) || audioBlob);
|
|
189
190
|
}, [inputText, busy, audioBlob, featureOpen]);
|
|
190
191
|
|
|
192
|
+
const hasValidFilterOptions = useMemo(() => {
|
|
193
|
+
if (!metadataOptions) return false;
|
|
194
|
+
const hasCategories =
|
|
195
|
+
Object.keys(metadataOptions.allowedCategories).length > 0;
|
|
196
|
+
const hasTags = metadataOptions.allowedTags.length > 0;
|
|
197
|
+
return hasCategories || hasTags;
|
|
198
|
+
}, [metadataOptions]);
|
|
199
|
+
|
|
191
200
|
const startRecording = useCallback(async () => {
|
|
192
201
|
try {
|
|
193
202
|
// Clear query input when starting audio recording
|
|
@@ -405,10 +414,11 @@ const DocSearchBase: FC<Props> = (props) => {
|
|
|
405
414
|
...(audioBlob && { audio: audioBlob }), // Pass Blob directly
|
|
406
415
|
topK,
|
|
407
416
|
// Include user-selected filters if enabled
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
417
|
+
// Always send userSelectedCategories array when enableUserFilters is true (even if empty)
|
|
418
|
+
// to prevent backend from applying its own kb-filter
|
|
419
|
+
...(enableUserFilters && {
|
|
420
|
+
userSelectedCategories: selectedCategories,
|
|
421
|
+
}),
|
|
412
422
|
...(enableUserFilters &&
|
|
413
423
|
selectedSubcategories.length > 0 && {
|
|
414
424
|
userSelectedSubcategories: selectedSubcategories,
|
|
@@ -458,6 +468,24 @@ const DocSearchBase: FC<Props> = (props) => {
|
|
|
458
468
|
}
|
|
459
469
|
}, [canSearch]);
|
|
460
470
|
|
|
471
|
+
// Reset session when main categories change
|
|
472
|
+
useEffect(() => {
|
|
473
|
+
const prev = prevSelectedCategoriesRef.current;
|
|
474
|
+
const current = selectedCategories;
|
|
475
|
+
|
|
476
|
+
// Check if categories changed (different length or different items)
|
|
477
|
+
const categoriesChanged =
|
|
478
|
+
prev.length !== current.length ||
|
|
479
|
+
!current.every((cat) => prev.includes(cat));
|
|
480
|
+
|
|
481
|
+
if (categoriesChanged && prev.length > 0) {
|
|
482
|
+
// Reset session only if we had categories before (not on initial mount)
|
|
483
|
+
reset();
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
prevSelectedCategoriesRef.current = [...current];
|
|
487
|
+
}, [selectedCategories, reset]);
|
|
488
|
+
|
|
461
489
|
const grouped = useMemo(() => groupChunksByDoc(result), [result]);
|
|
462
490
|
|
|
463
491
|
const docNumberMap = useMemo(() => {
|
|
@@ -760,110 +788,66 @@ const DocSearchBase: FC<Props> = (props) => {
|
|
|
760
788
|
) : null}
|
|
761
789
|
|
|
762
790
|
{/* User filter collapse */}
|
|
763
|
-
{enableUserFilters &&
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
<Stack gap="md">
|
|
783
|
-
{/* Main categories as checkboxes */}
|
|
784
|
-
{Object.keys(metadataOptions.allowedCategories)
|
|
785
|
-
.length > 0 && (
|
|
786
|
-
<div>
|
|
787
|
-
<Text size="sm" fw={500} mb="xs">
|
|
788
|
-
{I18n.get("Categories")}
|
|
789
|
-
</Text>
|
|
790
|
-
<Group gap="md">
|
|
791
|
-
{Object.keys(
|
|
792
|
-
metadataOptions.allowedCategories,
|
|
793
|
-
).map((category) => (
|
|
794
|
-
<Checkbox
|
|
795
|
-
key={category}
|
|
796
|
-
label={category}
|
|
797
|
-
checked={selectedCategories.includes(
|
|
798
|
-
category,
|
|
799
|
-
)}
|
|
800
|
-
onChange={(e) => {
|
|
801
|
-
if (e.currentTarget.checked) {
|
|
802
|
-
setSelectedCategories([
|
|
803
|
-
...selectedCategories,
|
|
804
|
-
category,
|
|
805
|
-
]);
|
|
806
|
-
} else {
|
|
807
|
-
setSelectedCategories(
|
|
808
|
-
selectedCategories.filter(
|
|
809
|
-
(c) => c !== category,
|
|
810
|
-
),
|
|
811
|
-
);
|
|
812
|
-
// Remove subcategories of unchecked category
|
|
813
|
-
const subcatsToRemove =
|
|
814
|
-
metadataOptions.allowedCategories[
|
|
815
|
-
category
|
|
816
|
-
] || [];
|
|
817
|
-
setSelectedSubcategories(
|
|
818
|
-
selectedSubcategories.filter(
|
|
819
|
-
(sc) =>
|
|
820
|
-
!subcatsToRemove.includes(sc),
|
|
821
|
-
),
|
|
822
|
-
);
|
|
823
|
-
}
|
|
824
|
-
}}
|
|
825
|
-
disabled={busy || loadingMetadata}
|
|
826
|
-
/>
|
|
827
|
-
))}
|
|
828
|
-
</Group>
|
|
829
|
-
</div>
|
|
830
|
-
)}
|
|
791
|
+
{enableUserFilters &&
|
|
792
|
+
metadataOptions &&
|
|
793
|
+
hasValidFilterOptions && (
|
|
794
|
+
<Stack gap="xs">
|
|
795
|
+
<Button
|
|
796
|
+
variant="subtle"
|
|
797
|
+
size="xs"
|
|
798
|
+
onClick={() => setFiltersOpen(!filtersOpen)}
|
|
799
|
+
leftSection={
|
|
800
|
+
filtersOpen ? (
|
|
801
|
+
<IconChevronDown size={14} />
|
|
802
|
+
) : (
|
|
803
|
+
<IconChevronRight size={14} />
|
|
804
|
+
)
|
|
805
|
+
}
|
|
806
|
+
style={{ alignSelf: "flex-start" }}
|
|
807
|
+
>
|
|
808
|
+
{I18n.get("Filters")}
|
|
809
|
+
</Button>
|
|
831
810
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
)
|
|
846
|
-
.filter(
|
|
847
|
-
(subcat, index, self) =>
|
|
848
|
-
self.indexOf(subcat) === index,
|
|
849
|
-
)
|
|
850
|
-
.map((subcat) => (
|
|
811
|
+
<Collapse in={filtersOpen}>
|
|
812
|
+
<Stack gap="md">
|
|
813
|
+
{/* Main categories as checkboxes */}
|
|
814
|
+
{Object.keys(metadataOptions.allowedCategories)
|
|
815
|
+
.length > 0 && (
|
|
816
|
+
<div>
|
|
817
|
+
<Text size="sm" fw={500} mb="xs">
|
|
818
|
+
{I18n.get("Categories")}
|
|
819
|
+
</Text>
|
|
820
|
+
<Group gap="md">
|
|
821
|
+
{Object.keys(
|
|
822
|
+
metadataOptions.allowedCategories,
|
|
823
|
+
).map((category) => (
|
|
851
824
|
<Checkbox
|
|
852
|
-
key={
|
|
853
|
-
label={
|
|
854
|
-
checked={
|
|
855
|
-
|
|
825
|
+
key={category}
|
|
826
|
+
label={I18n.get(category)}
|
|
827
|
+
checked={selectedCategories.includes(
|
|
828
|
+
category,
|
|
856
829
|
)}
|
|
857
830
|
onChange={(e) => {
|
|
858
831
|
if (e.currentTarget.checked) {
|
|
859
|
-
|
|
860
|
-
...
|
|
861
|
-
|
|
832
|
+
setSelectedCategories([
|
|
833
|
+
...selectedCategories,
|
|
834
|
+
category,
|
|
862
835
|
]);
|
|
863
836
|
} else {
|
|
837
|
+
setSelectedCategories(
|
|
838
|
+
selectedCategories.filter(
|
|
839
|
+
(c) => c !== category,
|
|
840
|
+
),
|
|
841
|
+
);
|
|
842
|
+
// Remove subcategories of unchecked category
|
|
843
|
+
const subcatsToRemove =
|
|
844
|
+
metadataOptions.allowedCategories[
|
|
845
|
+
category
|
|
846
|
+
] || [];
|
|
864
847
|
setSelectedSubcategories(
|
|
865
848
|
selectedSubcategories.filter(
|
|
866
|
-
(sc) =>
|
|
849
|
+
(sc) =>
|
|
850
|
+
!subcatsToRemove.includes(sc),
|
|
867
851
|
),
|
|
868
852
|
);
|
|
869
853
|
}
|
|
@@ -871,31 +855,84 @@ const DocSearchBase: FC<Props> = (props) => {
|
|
|
871
855
|
disabled={busy || loadingMetadata}
|
|
872
856
|
/>
|
|
873
857
|
))}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
858
|
+
</Group>
|
|
859
|
+
</div>
|
|
860
|
+
)}
|
|
861
|
+
|
|
862
|
+
{/* Subcategories for selected categories */}
|
|
863
|
+
{selectedCategories.length > 0 && (
|
|
864
|
+
<div>
|
|
865
|
+
<Text size="sm" fw={500} mb="xs">
|
|
866
|
+
{I18n.get("Subcategories")}
|
|
867
|
+
</Text>
|
|
868
|
+
<Group gap="md">
|
|
869
|
+
{selectedCategories
|
|
870
|
+
.flatMap(
|
|
871
|
+
(cat) =>
|
|
872
|
+
metadataOptions.allowedCategories[
|
|
873
|
+
cat
|
|
874
|
+
] || [],
|
|
875
|
+
)
|
|
876
|
+
.filter(
|
|
877
|
+
(subcat, index, self) =>
|
|
878
|
+
self.indexOf(subcat) === index,
|
|
879
|
+
)
|
|
880
|
+
.map((subcat) => (
|
|
881
|
+
<Checkbox
|
|
882
|
+
key={subcat}
|
|
883
|
+
label={I18n.get(subcat)}
|
|
884
|
+
checked={selectedSubcategories.includes(
|
|
885
|
+
subcat,
|
|
886
|
+
)}
|
|
887
|
+
onChange={(e) => {
|
|
888
|
+
if (e.currentTarget.checked) {
|
|
889
|
+
setSelectedSubcategories([
|
|
890
|
+
...selectedSubcategories,
|
|
891
|
+
subcat,
|
|
892
|
+
]);
|
|
893
|
+
} else {
|
|
894
|
+
setSelectedSubcategories(
|
|
895
|
+
selectedSubcategories.filter(
|
|
896
|
+
(sc) => sc !== subcat,
|
|
897
|
+
),
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
}}
|
|
901
|
+
disabled={busy || loadingMetadata}
|
|
902
|
+
/>
|
|
903
|
+
))}
|
|
904
|
+
</Group>
|
|
905
|
+
</div>
|
|
906
|
+
)}
|
|
907
|
+
|
|
908
|
+
{/* Tags input */}
|
|
909
|
+
{metadataOptions.allowedTags.length > 0 && (
|
|
910
|
+
<MultiSelect
|
|
911
|
+
label={I18n.get("Tags")}
|
|
912
|
+
placeholder={I18n.get(
|
|
913
|
+
"Select or type tags...",
|
|
914
|
+
)}
|
|
915
|
+
data={metadataOptions.allowedTags.map(
|
|
916
|
+
(tag) => ({
|
|
917
|
+
value: tag,
|
|
918
|
+
label: I18n.get(tag),
|
|
919
|
+
}),
|
|
920
|
+
)}
|
|
921
|
+
value={selectedTags}
|
|
922
|
+
onChange={setSelectedTags}
|
|
923
|
+
searchValue={tagSearchValue}
|
|
924
|
+
onSearchChange={setTagSearchValue}
|
|
925
|
+
disabled={busy || loadingMetadata}
|
|
926
|
+
searchable
|
|
927
|
+
clearable
|
|
928
|
+
maxDropdownHeight={200}
|
|
929
|
+
limit={20}
|
|
930
|
+
/>
|
|
931
|
+
)}
|
|
932
|
+
</Stack>
|
|
933
|
+
</Collapse>
|
|
934
|
+
</Stack>
|
|
935
|
+
)}
|
|
899
936
|
|
|
900
937
|
{
|
|
901
938
|
/* Audio level indicator when recording */ USE_AUDIO && (
|