@absolutejs/absolute 0.19.0-beta.433 → 0.19.0-beta.434
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/ai/index.js +95 -1
- package/dist/ai/index.js.map +5 -4
- package/dist/ai-client/react/ai/index.js +252 -10
- package/dist/react/ai/index.js +253 -11
- package/dist/react/ai/index.js.map +11 -7
- package/dist/src/ai/client/actions.d.ts +1 -1
- package/dist/src/ai/index.d.ts +2 -2
- package/dist/src/ai/rag/index.d.ts +1 -0
- package/dist/src/ai/rag/presentation.d.ts +10 -0
- package/dist/src/ai/rag/types.d.ts +1 -1
- package/dist/src/react/ai/index.d.ts +3 -0
- package/dist/src/react/ai/useRAG.d.ts +64 -0
- package/dist/src/react/ai/useRAGCitations.d.ts +7 -0
- package/dist/src/react/ai/useRAGIngest.d.ts +8 -2
- package/dist/src/react/ai/useRAGSearch.d.ts +3 -0
- package/dist/src/react/ai/useRAGSources.d.ts +8 -0
- package/dist/src/react/ai/useRAGStatus.d.ts +1 -0
- package/dist/src/react/ai/useRAGStream.d.ts +9 -1
- package/dist/types/ai.d.ts +20 -0
- package/dist/vue/components/index.js +16 -2
- package/dist/vue/components/index.js.map +3 -3
- package/dist/vue/index.js +18 -4
- package/dist/vue/index.js.map +3 -3
- package/package.json +1 -1
|
@@ -629,8 +629,115 @@ var useAIStream = (path, conversationId) => {
|
|
|
629
629
|
send
|
|
630
630
|
};
|
|
631
631
|
};
|
|
632
|
+
// src/react/ai/useRAG.ts
|
|
633
|
+
import { useMemo as useMemo7 } from "react";
|
|
634
|
+
|
|
635
|
+
// src/react/ai/useRAGCitations.ts
|
|
636
|
+
import { useMemo } from "react";
|
|
637
|
+
|
|
638
|
+
// src/ai/rag/presentation.ts
|
|
639
|
+
var buildSourceGroupKey = (source) => source.source ?? source.title ?? source.chunkId;
|
|
640
|
+
var buildSourceLabel = (source) => source.source ?? source.title ?? source.chunkId;
|
|
641
|
+
var getLatestAssistantMessage = (messages) => {
|
|
642
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
643
|
+
const message = messages[index];
|
|
644
|
+
if (message?.role === "assistant") {
|
|
645
|
+
return message;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return;
|
|
649
|
+
};
|
|
650
|
+
var getLatestRAGSources = (messages) => getLatestAssistantMessage(messages)?.sources ?? [];
|
|
651
|
+
var buildRAGSourceGroups = (sources) => {
|
|
652
|
+
const groups = new Map;
|
|
653
|
+
for (const source of sources) {
|
|
654
|
+
const key = buildSourceGroupKey(source);
|
|
655
|
+
const existing = groups.get(key);
|
|
656
|
+
if (existing) {
|
|
657
|
+
existing.bestScore = Math.max(existing.bestScore, source.score);
|
|
658
|
+
existing.count += 1;
|
|
659
|
+
existing.chunks.push(source);
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
groups.set(key, {
|
|
663
|
+
bestScore: source.score,
|
|
664
|
+
chunks: [source],
|
|
665
|
+
count: 1,
|
|
666
|
+
key,
|
|
667
|
+
label: buildSourceLabel(source),
|
|
668
|
+
source: source.source,
|
|
669
|
+
title: source.title
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
return [...groups.values()].sort((left, right) => {
|
|
673
|
+
if (right.bestScore !== left.bestScore) {
|
|
674
|
+
return right.bestScore - left.bestScore;
|
|
675
|
+
}
|
|
676
|
+
return left.label.localeCompare(right.label);
|
|
677
|
+
});
|
|
678
|
+
};
|
|
679
|
+
var buildRAGCitations = (sources) => {
|
|
680
|
+
const unique = new Map;
|
|
681
|
+
for (const source of sources) {
|
|
682
|
+
const key = source.chunkId;
|
|
683
|
+
const existing = unique.get(key);
|
|
684
|
+
if (existing && existing.score >= source.score) {
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
unique.set(key, {
|
|
688
|
+
chunkId: source.chunkId,
|
|
689
|
+
key,
|
|
690
|
+
label: buildSourceLabel(source),
|
|
691
|
+
metadata: source.metadata,
|
|
692
|
+
score: source.score,
|
|
693
|
+
source: source.source,
|
|
694
|
+
text: source.text,
|
|
695
|
+
title: source.title
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
return [...unique.values()].sort((left, right) => {
|
|
699
|
+
if (right.score !== left.score) {
|
|
700
|
+
return right.score - left.score;
|
|
701
|
+
}
|
|
702
|
+
return left.label.localeCompare(right.label);
|
|
703
|
+
});
|
|
704
|
+
};
|
|
705
|
+
var resolveRAGStreamStage = ({
|
|
706
|
+
error,
|
|
707
|
+
isStreaming,
|
|
708
|
+
messages
|
|
709
|
+
}) => {
|
|
710
|
+
if (error) {
|
|
711
|
+
return "error";
|
|
712
|
+
}
|
|
713
|
+
const assistantMessage = getLatestAssistantMessage(messages);
|
|
714
|
+
if (!assistantMessage) {
|
|
715
|
+
return isStreaming ? "submitting" : "idle";
|
|
716
|
+
}
|
|
717
|
+
if (!isStreaming) {
|
|
718
|
+
return "complete";
|
|
719
|
+
}
|
|
720
|
+
const hasSources = (assistantMessage.sources?.length ?? 0) > 0;
|
|
721
|
+
const hasContent = assistantMessage.content.trim().length > 0 || assistantMessage.thinking?.trim().length || (assistantMessage.toolCalls?.length ?? 0) > 0 || (assistantMessage.images?.length ?? 0) > 0;
|
|
722
|
+
if (hasSources && !hasContent) {
|
|
723
|
+
return "retrieved";
|
|
724
|
+
}
|
|
725
|
+
return "streaming";
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
// src/react/ai/useRAGCitations.ts
|
|
729
|
+
var useRAGCitations = (sources) => {
|
|
730
|
+
const citations = useMemo(() => buildRAGCitations(sources), [sources]);
|
|
731
|
+
const sourceGroups = useMemo(() => buildRAGSourceGroups(sources), [sources]);
|
|
732
|
+
return {
|
|
733
|
+
citations,
|
|
734
|
+
hasCitations: citations.length > 0,
|
|
735
|
+
sourceGroups
|
|
736
|
+
};
|
|
737
|
+
};
|
|
738
|
+
|
|
632
739
|
// src/react/ai/useRAGIngest.ts
|
|
633
|
-
import { useCallback as useCallback2, useMemo, useState } from "react";
|
|
740
|
+
import { useCallback as useCallback2, useMemo as useMemo2, useState } from "react";
|
|
634
741
|
|
|
635
742
|
// src/ai/client/ragClient.ts
|
|
636
743
|
var jsonHeaders = {
|
|
@@ -718,11 +825,13 @@ var createRAGClient = (options) => {
|
|
|
718
825
|
|
|
719
826
|
// src/react/ai/useRAGIngest.ts
|
|
720
827
|
var useRAGIngest = (path) => {
|
|
721
|
-
const client =
|
|
828
|
+
const client = useMemo2(() => createRAGClient({ path }), [path]);
|
|
722
829
|
const [error, setError] = useState(null);
|
|
723
830
|
const [isIngesting, setIsIngesting] = useState(false);
|
|
724
831
|
const [lastIngestCount, setLastIngestCount] = useState(null);
|
|
725
|
-
const
|
|
832
|
+
const [lastDocumentCount, setLastDocumentCount] = useState(null);
|
|
833
|
+
const [lastResponse, setLastResponse] = useState(null);
|
|
834
|
+
const ingestChunks = useCallback2(async (chunks) => {
|
|
726
835
|
setIsIngesting(true);
|
|
727
836
|
setError(null);
|
|
728
837
|
try {
|
|
@@ -731,6 +840,8 @@ var useRAGIngest = (path) => {
|
|
|
731
840
|
throw new Error(response.error ?? "RAG ingest failed");
|
|
732
841
|
}
|
|
733
842
|
setLastIngestCount(response.count ?? chunks.length);
|
|
843
|
+
setLastDocumentCount(null);
|
|
844
|
+
setLastResponse(response);
|
|
734
845
|
return response;
|
|
735
846
|
} catch (caught) {
|
|
736
847
|
const message = caught instanceof Error ? caught.message : String(caught);
|
|
@@ -740,26 +851,79 @@ var useRAGIngest = (path) => {
|
|
|
740
851
|
setIsIngesting(false);
|
|
741
852
|
}
|
|
742
853
|
}, [client]);
|
|
854
|
+
const ingestDocuments = useCallback2(async (input) => {
|
|
855
|
+
setIsIngesting(true);
|
|
856
|
+
setError(null);
|
|
857
|
+
try {
|
|
858
|
+
const response = await client.ingestDocuments(input);
|
|
859
|
+
if (!response.ok) {
|
|
860
|
+
throw new Error(response.error ?? "RAG ingest failed");
|
|
861
|
+
}
|
|
862
|
+
setLastIngestCount(response.count ?? null);
|
|
863
|
+
setLastDocumentCount(response.documentCount ?? input.documents.length);
|
|
864
|
+
setLastResponse(response);
|
|
865
|
+
return response;
|
|
866
|
+
} catch (caught) {
|
|
867
|
+
const message = caught instanceof Error ? caught.message : String(caught);
|
|
868
|
+
setError(message);
|
|
869
|
+
throw caught;
|
|
870
|
+
} finally {
|
|
871
|
+
setIsIngesting(false);
|
|
872
|
+
}
|
|
873
|
+
}, [client]);
|
|
874
|
+
const clearIndex = useCallback2(async () => {
|
|
875
|
+
setIsIngesting(true);
|
|
876
|
+
setError(null);
|
|
877
|
+
try {
|
|
878
|
+
await client.clearIndex();
|
|
879
|
+
setLastIngestCount(0);
|
|
880
|
+
setLastDocumentCount(0);
|
|
881
|
+
setLastResponse(null);
|
|
882
|
+
} catch (caught) {
|
|
883
|
+
const message = caught instanceof Error ? caught.message : String(caught);
|
|
884
|
+
setError(message);
|
|
885
|
+
throw caught;
|
|
886
|
+
} finally {
|
|
887
|
+
setIsIngesting(false);
|
|
888
|
+
}
|
|
889
|
+
}, [client]);
|
|
890
|
+
const reset = useCallback2(() => {
|
|
891
|
+
setError(null);
|
|
892
|
+
setLastDocumentCount(null);
|
|
893
|
+
setLastIngestCount(null);
|
|
894
|
+
setLastResponse(null);
|
|
895
|
+
}, []);
|
|
743
896
|
return {
|
|
897
|
+
clearIndex,
|
|
744
898
|
error,
|
|
745
|
-
ingest,
|
|
899
|
+
ingest: ingestChunks,
|
|
900
|
+
ingestChunks,
|
|
901
|
+
ingestDocuments,
|
|
746
902
|
isIngesting,
|
|
747
|
-
|
|
903
|
+
lastDocumentCount,
|
|
904
|
+
lastIngestCount,
|
|
905
|
+
lastResponse,
|
|
906
|
+
reset
|
|
748
907
|
};
|
|
749
908
|
};
|
|
909
|
+
|
|
750
910
|
// src/react/ai/useRAGSearch.ts
|
|
751
|
-
import { useCallback as useCallback3, useMemo as
|
|
911
|
+
import { useCallback as useCallback3, useMemo as useMemo3, useState as useState2 } from "react";
|
|
752
912
|
var useRAGSearch = (path) => {
|
|
753
|
-
const client =
|
|
913
|
+
const client = useMemo3(() => createRAGClient({ path }), [path]);
|
|
754
914
|
const [results, setResults] = useState2([]);
|
|
755
915
|
const [error, setError] = useState2(null);
|
|
756
916
|
const [isSearching, setIsSearching] = useState2(false);
|
|
917
|
+
const [hasSearched, setHasSearched] = useState2(false);
|
|
918
|
+
const [lastRequest, setLastRequest] = useState2(null);
|
|
757
919
|
const search = useCallback3(async (input) => {
|
|
758
920
|
setIsSearching(true);
|
|
759
921
|
setError(null);
|
|
922
|
+
setLastRequest(input);
|
|
760
923
|
try {
|
|
761
924
|
const nextResults = await client.search(input);
|
|
762
925
|
setResults(nextResults);
|
|
926
|
+
setHasSearched(true);
|
|
763
927
|
return nextResults;
|
|
764
928
|
} catch (caught) {
|
|
765
929
|
const message = caught instanceof Error ? caught.message : String(caught);
|
|
@@ -769,18 +933,42 @@ var useRAGSearch = (path) => {
|
|
|
769
933
|
setIsSearching(false);
|
|
770
934
|
}
|
|
771
935
|
}, [client]);
|
|
936
|
+
const reset = useCallback3(() => {
|
|
937
|
+
setError(null);
|
|
938
|
+
setHasSearched(false);
|
|
939
|
+
setLastRequest(null);
|
|
940
|
+
setResults([]);
|
|
941
|
+
}, []);
|
|
772
942
|
return {
|
|
773
943
|
error,
|
|
944
|
+
hasSearched,
|
|
774
945
|
isSearching,
|
|
946
|
+
lastRequest,
|
|
947
|
+
reset,
|
|
775
948
|
results,
|
|
776
949
|
search,
|
|
777
950
|
setResults
|
|
778
951
|
};
|
|
779
952
|
};
|
|
953
|
+
|
|
954
|
+
// src/react/ai/useRAGSources.ts
|
|
955
|
+
import { useMemo as useMemo4 } from "react";
|
|
956
|
+
var useRAGSources = (messages) => {
|
|
957
|
+
const latestAssistantMessage = useMemo4(() => getLatestAssistantMessage(messages), [messages]);
|
|
958
|
+
const sources = useMemo4(() => getLatestRAGSources(messages), [messages]);
|
|
959
|
+
const sourceGroups = useMemo4(() => buildRAGSourceGroups(sources), [sources]);
|
|
960
|
+
return {
|
|
961
|
+
hasSources: sources.length > 0,
|
|
962
|
+
latestAssistantMessage,
|
|
963
|
+
sourceGroups,
|
|
964
|
+
sources
|
|
965
|
+
};
|
|
966
|
+
};
|
|
967
|
+
|
|
780
968
|
// src/react/ai/useRAGStatus.ts
|
|
781
|
-
import { useCallback as useCallback4, useEffect as useEffect3, useMemo as
|
|
969
|
+
import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo5, useState as useState3 } from "react";
|
|
782
970
|
var useRAGStatus = (path, autoLoad = true) => {
|
|
783
|
-
const client =
|
|
971
|
+
const client = useMemo5(() => createRAGClient({ path }), [path]);
|
|
784
972
|
const [status, setStatus] = useState3();
|
|
785
973
|
const [capabilities, setCapabilities] = useState3();
|
|
786
974
|
const [error, setError] = useState3(null);
|
|
@@ -801,6 +989,12 @@ var useRAGStatus = (path, autoLoad = true) => {
|
|
|
801
989
|
setIsLoading(false);
|
|
802
990
|
}
|
|
803
991
|
}, [client]);
|
|
992
|
+
const reset = useCallback4(() => {
|
|
993
|
+
setCapabilities(undefined);
|
|
994
|
+
setError(null);
|
|
995
|
+
setIsLoading(false);
|
|
996
|
+
setStatus(undefined);
|
|
997
|
+
}, []);
|
|
804
998
|
useEffect3(() => {
|
|
805
999
|
if (!autoLoad) {
|
|
806
1000
|
setIsLoading(false);
|
|
@@ -813,16 +1007,64 @@ var useRAGStatus = (path, autoLoad = true) => {
|
|
|
813
1007
|
error,
|
|
814
1008
|
isLoading,
|
|
815
1009
|
refresh,
|
|
1010
|
+
reset,
|
|
816
1011
|
status
|
|
817
1012
|
};
|
|
818
1013
|
};
|
|
1014
|
+
|
|
819
1015
|
// src/react/ai/useRAGStream.ts
|
|
820
|
-
|
|
1016
|
+
import { useCallback as useCallback5, useMemo as useMemo6 } from "react";
|
|
1017
|
+
var useRAGStream = (path, conversationId) => {
|
|
1018
|
+
const stream = useAIStream(path, conversationId);
|
|
1019
|
+
const latestAssistantMessage = useMemo6(() => getLatestAssistantMessage(stream.messages), [stream.messages]);
|
|
1020
|
+
const sources = useMemo6(() => getLatestRAGSources(stream.messages), [stream.messages]);
|
|
1021
|
+
const sourceGroups = useMemo6(() => buildRAGSourceGroups(sources), [sources]);
|
|
1022
|
+
const citations = useMemo6(() => buildRAGCitations(sources), [sources]);
|
|
1023
|
+
const stage = useMemo6(() => resolveRAGStreamStage({
|
|
1024
|
+
error: stream.error,
|
|
1025
|
+
isStreaming: stream.isStreaming,
|
|
1026
|
+
messages: stream.messages
|
|
1027
|
+
}), [stream.error, stream.isStreaming, stream.messages]);
|
|
1028
|
+
const query = useCallback5((content, attachments) => {
|
|
1029
|
+
stream.send(content, attachments);
|
|
1030
|
+
}, [stream]);
|
|
1031
|
+
return {
|
|
1032
|
+
...stream,
|
|
1033
|
+
citations,
|
|
1034
|
+
hasSources: sources.length > 0,
|
|
1035
|
+
latestAssistantMessage,
|
|
1036
|
+
query,
|
|
1037
|
+
sourceGroups,
|
|
1038
|
+
sources,
|
|
1039
|
+
stage
|
|
1040
|
+
};
|
|
1041
|
+
};
|
|
1042
|
+
|
|
1043
|
+
// src/react/ai/useRAG.ts
|
|
1044
|
+
var useRAG = (path, options = {}) => {
|
|
1045
|
+
const search = useRAGSearch(path);
|
|
1046
|
+
const ingest = useRAGIngest(path);
|
|
1047
|
+
const status = useRAGStatus(path, options.autoLoadStatus ?? true);
|
|
1048
|
+
const stream = useRAGStream(options.streamPath ?? path, options.conversationId);
|
|
1049
|
+
const sources = useRAGSources(stream.messages);
|
|
1050
|
+
const citations = useRAGCitations(sources.sources);
|
|
1051
|
+
return useMemo7(() => ({
|
|
1052
|
+
citations,
|
|
1053
|
+
ingest,
|
|
1054
|
+
search,
|
|
1055
|
+
sources,
|
|
1056
|
+
status,
|
|
1057
|
+
stream
|
|
1058
|
+
}), [citations, ingest, search, sources, status, stream]);
|
|
1059
|
+
};
|
|
821
1060
|
export {
|
|
822
1061
|
useRAGStream,
|
|
823
1062
|
useRAGStatus,
|
|
1063
|
+
useRAGSources,
|
|
824
1064
|
useRAGSearch,
|
|
825
1065
|
useRAGIngest,
|
|
1066
|
+
useRAGCitations,
|
|
1067
|
+
useRAG,
|
|
826
1068
|
useAIStream,
|
|
827
1069
|
AIStreamProvider
|
|
828
1070
|
};
|
package/dist/react/ai/index.js
CHANGED
|
@@ -766,8 +766,115 @@ var useAIStream = (path, conversationId) => {
|
|
|
766
766
|
send
|
|
767
767
|
};
|
|
768
768
|
};
|
|
769
|
+
// src/react/ai/useRAG.ts
|
|
770
|
+
import { useMemo as useMemo7 } from "react";
|
|
771
|
+
|
|
772
|
+
// src/react/ai/useRAGCitations.ts
|
|
773
|
+
import { useMemo } from "react";
|
|
774
|
+
|
|
775
|
+
// src/ai/rag/presentation.ts
|
|
776
|
+
var buildSourceGroupKey = (source) => source.source ?? source.title ?? source.chunkId;
|
|
777
|
+
var buildSourceLabel = (source) => source.source ?? source.title ?? source.chunkId;
|
|
778
|
+
var getLatestAssistantMessage = (messages) => {
|
|
779
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
780
|
+
const message = messages[index];
|
|
781
|
+
if (message?.role === "assistant") {
|
|
782
|
+
return message;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
return;
|
|
786
|
+
};
|
|
787
|
+
var getLatestRAGSources = (messages) => getLatestAssistantMessage(messages)?.sources ?? [];
|
|
788
|
+
var buildRAGSourceGroups = (sources) => {
|
|
789
|
+
const groups = new Map;
|
|
790
|
+
for (const source of sources) {
|
|
791
|
+
const key = buildSourceGroupKey(source);
|
|
792
|
+
const existing = groups.get(key);
|
|
793
|
+
if (existing) {
|
|
794
|
+
existing.bestScore = Math.max(existing.bestScore, source.score);
|
|
795
|
+
existing.count += 1;
|
|
796
|
+
existing.chunks.push(source);
|
|
797
|
+
continue;
|
|
798
|
+
}
|
|
799
|
+
groups.set(key, {
|
|
800
|
+
bestScore: source.score,
|
|
801
|
+
chunks: [source],
|
|
802
|
+
count: 1,
|
|
803
|
+
key,
|
|
804
|
+
label: buildSourceLabel(source),
|
|
805
|
+
source: source.source,
|
|
806
|
+
title: source.title
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
return [...groups.values()].sort((left, right) => {
|
|
810
|
+
if (right.bestScore !== left.bestScore) {
|
|
811
|
+
return right.bestScore - left.bestScore;
|
|
812
|
+
}
|
|
813
|
+
return left.label.localeCompare(right.label);
|
|
814
|
+
});
|
|
815
|
+
};
|
|
816
|
+
var buildRAGCitations = (sources) => {
|
|
817
|
+
const unique = new Map;
|
|
818
|
+
for (const source of sources) {
|
|
819
|
+
const key = source.chunkId;
|
|
820
|
+
const existing = unique.get(key);
|
|
821
|
+
if (existing && existing.score >= source.score) {
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
824
|
+
unique.set(key, {
|
|
825
|
+
chunkId: source.chunkId,
|
|
826
|
+
key,
|
|
827
|
+
label: buildSourceLabel(source),
|
|
828
|
+
metadata: source.metadata,
|
|
829
|
+
score: source.score,
|
|
830
|
+
source: source.source,
|
|
831
|
+
text: source.text,
|
|
832
|
+
title: source.title
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
return [...unique.values()].sort((left, right) => {
|
|
836
|
+
if (right.score !== left.score) {
|
|
837
|
+
return right.score - left.score;
|
|
838
|
+
}
|
|
839
|
+
return left.label.localeCompare(right.label);
|
|
840
|
+
});
|
|
841
|
+
};
|
|
842
|
+
var resolveRAGStreamStage = ({
|
|
843
|
+
error,
|
|
844
|
+
isStreaming,
|
|
845
|
+
messages
|
|
846
|
+
}) => {
|
|
847
|
+
if (error) {
|
|
848
|
+
return "error";
|
|
849
|
+
}
|
|
850
|
+
const assistantMessage = getLatestAssistantMessage(messages);
|
|
851
|
+
if (!assistantMessage) {
|
|
852
|
+
return isStreaming ? "submitting" : "idle";
|
|
853
|
+
}
|
|
854
|
+
if (!isStreaming) {
|
|
855
|
+
return "complete";
|
|
856
|
+
}
|
|
857
|
+
const hasSources = (assistantMessage.sources?.length ?? 0) > 0;
|
|
858
|
+
const hasContent = assistantMessage.content.trim().length > 0 || assistantMessage.thinking?.trim().length || (assistantMessage.toolCalls?.length ?? 0) > 0 || (assistantMessage.images?.length ?? 0) > 0;
|
|
859
|
+
if (hasSources && !hasContent) {
|
|
860
|
+
return "retrieved";
|
|
861
|
+
}
|
|
862
|
+
return "streaming";
|
|
863
|
+
};
|
|
864
|
+
|
|
865
|
+
// src/react/ai/useRAGCitations.ts
|
|
866
|
+
var useRAGCitations = (sources) => {
|
|
867
|
+
const citations = useMemo(() => buildRAGCitations(sources), [sources]);
|
|
868
|
+
const sourceGroups = useMemo(() => buildRAGSourceGroups(sources), [sources]);
|
|
869
|
+
return {
|
|
870
|
+
citations,
|
|
871
|
+
hasCitations: citations.length > 0,
|
|
872
|
+
sourceGroups
|
|
873
|
+
};
|
|
874
|
+
};
|
|
875
|
+
|
|
769
876
|
// src/react/ai/useRAGIngest.ts
|
|
770
|
-
import { useCallback as useCallback2, useMemo, useState } from "react";
|
|
877
|
+
import { useCallback as useCallback2, useMemo as useMemo2, useState } from "react";
|
|
771
878
|
|
|
772
879
|
// src/ai/client/ragClient.ts
|
|
773
880
|
var jsonHeaders = {
|
|
@@ -855,11 +962,13 @@ var createRAGClient = (options) => {
|
|
|
855
962
|
|
|
856
963
|
// src/react/ai/useRAGIngest.ts
|
|
857
964
|
var useRAGIngest = (path) => {
|
|
858
|
-
const client =
|
|
965
|
+
const client = useMemo2(() => createRAGClient({ path }), [path]);
|
|
859
966
|
const [error, setError] = useState(null);
|
|
860
967
|
const [isIngesting, setIsIngesting] = useState(false);
|
|
861
968
|
const [lastIngestCount, setLastIngestCount] = useState(null);
|
|
862
|
-
const
|
|
969
|
+
const [lastDocumentCount, setLastDocumentCount] = useState(null);
|
|
970
|
+
const [lastResponse, setLastResponse] = useState(null);
|
|
971
|
+
const ingestChunks = useCallback2(async (chunks) => {
|
|
863
972
|
setIsIngesting(true);
|
|
864
973
|
setError(null);
|
|
865
974
|
try {
|
|
@@ -868,6 +977,8 @@ var useRAGIngest = (path) => {
|
|
|
868
977
|
throw new Error(response.error ?? "RAG ingest failed");
|
|
869
978
|
}
|
|
870
979
|
setLastIngestCount(response.count ?? chunks.length);
|
|
980
|
+
setLastDocumentCount(null);
|
|
981
|
+
setLastResponse(response);
|
|
871
982
|
return response;
|
|
872
983
|
} catch (caught) {
|
|
873
984
|
const message = caught instanceof Error ? caught.message : String(caught);
|
|
@@ -877,26 +988,79 @@ var useRAGIngest = (path) => {
|
|
|
877
988
|
setIsIngesting(false);
|
|
878
989
|
}
|
|
879
990
|
}, [client]);
|
|
991
|
+
const ingestDocuments = useCallback2(async (input) => {
|
|
992
|
+
setIsIngesting(true);
|
|
993
|
+
setError(null);
|
|
994
|
+
try {
|
|
995
|
+
const response = await client.ingestDocuments(input);
|
|
996
|
+
if (!response.ok) {
|
|
997
|
+
throw new Error(response.error ?? "RAG ingest failed");
|
|
998
|
+
}
|
|
999
|
+
setLastIngestCount(response.count ?? null);
|
|
1000
|
+
setLastDocumentCount(response.documentCount ?? input.documents.length);
|
|
1001
|
+
setLastResponse(response);
|
|
1002
|
+
return response;
|
|
1003
|
+
} catch (caught) {
|
|
1004
|
+
const message = caught instanceof Error ? caught.message : String(caught);
|
|
1005
|
+
setError(message);
|
|
1006
|
+
throw caught;
|
|
1007
|
+
} finally {
|
|
1008
|
+
setIsIngesting(false);
|
|
1009
|
+
}
|
|
1010
|
+
}, [client]);
|
|
1011
|
+
const clearIndex = useCallback2(async () => {
|
|
1012
|
+
setIsIngesting(true);
|
|
1013
|
+
setError(null);
|
|
1014
|
+
try {
|
|
1015
|
+
await client.clearIndex();
|
|
1016
|
+
setLastIngestCount(0);
|
|
1017
|
+
setLastDocumentCount(0);
|
|
1018
|
+
setLastResponse(null);
|
|
1019
|
+
} catch (caught) {
|
|
1020
|
+
const message = caught instanceof Error ? caught.message : String(caught);
|
|
1021
|
+
setError(message);
|
|
1022
|
+
throw caught;
|
|
1023
|
+
} finally {
|
|
1024
|
+
setIsIngesting(false);
|
|
1025
|
+
}
|
|
1026
|
+
}, [client]);
|
|
1027
|
+
const reset = useCallback2(() => {
|
|
1028
|
+
setError(null);
|
|
1029
|
+
setLastDocumentCount(null);
|
|
1030
|
+
setLastIngestCount(null);
|
|
1031
|
+
setLastResponse(null);
|
|
1032
|
+
}, []);
|
|
880
1033
|
return {
|
|
1034
|
+
clearIndex,
|
|
881
1035
|
error,
|
|
882
|
-
ingest,
|
|
1036
|
+
ingest: ingestChunks,
|
|
1037
|
+
ingestChunks,
|
|
1038
|
+
ingestDocuments,
|
|
883
1039
|
isIngesting,
|
|
884
|
-
|
|
1040
|
+
lastDocumentCount,
|
|
1041
|
+
lastIngestCount,
|
|
1042
|
+
lastResponse,
|
|
1043
|
+
reset
|
|
885
1044
|
};
|
|
886
1045
|
};
|
|
1046
|
+
|
|
887
1047
|
// src/react/ai/useRAGSearch.ts
|
|
888
|
-
import { useCallback as useCallback3, useMemo as
|
|
1048
|
+
import { useCallback as useCallback3, useMemo as useMemo3, useState as useState2 } from "react";
|
|
889
1049
|
var useRAGSearch = (path) => {
|
|
890
|
-
const client =
|
|
1050
|
+
const client = useMemo3(() => createRAGClient({ path }), [path]);
|
|
891
1051
|
const [results, setResults] = useState2([]);
|
|
892
1052
|
const [error, setError] = useState2(null);
|
|
893
1053
|
const [isSearching, setIsSearching] = useState2(false);
|
|
1054
|
+
const [hasSearched, setHasSearched] = useState2(false);
|
|
1055
|
+
const [lastRequest, setLastRequest] = useState2(null);
|
|
894
1056
|
const search = useCallback3(async (input) => {
|
|
895
1057
|
setIsSearching(true);
|
|
896
1058
|
setError(null);
|
|
1059
|
+
setLastRequest(input);
|
|
897
1060
|
try {
|
|
898
1061
|
const nextResults = await client.search(input);
|
|
899
1062
|
setResults(nextResults);
|
|
1063
|
+
setHasSearched(true);
|
|
900
1064
|
return nextResults;
|
|
901
1065
|
} catch (caught) {
|
|
902
1066
|
const message = caught instanceof Error ? caught.message : String(caught);
|
|
@@ -906,18 +1070,42 @@ var useRAGSearch = (path) => {
|
|
|
906
1070
|
setIsSearching(false);
|
|
907
1071
|
}
|
|
908
1072
|
}, [client]);
|
|
1073
|
+
const reset = useCallback3(() => {
|
|
1074
|
+
setError(null);
|
|
1075
|
+
setHasSearched(false);
|
|
1076
|
+
setLastRequest(null);
|
|
1077
|
+
setResults([]);
|
|
1078
|
+
}, []);
|
|
909
1079
|
return {
|
|
910
1080
|
error,
|
|
1081
|
+
hasSearched,
|
|
911
1082
|
isSearching,
|
|
1083
|
+
lastRequest,
|
|
1084
|
+
reset,
|
|
912
1085
|
results,
|
|
913
1086
|
search,
|
|
914
1087
|
setResults
|
|
915
1088
|
};
|
|
916
1089
|
};
|
|
1090
|
+
|
|
1091
|
+
// src/react/ai/useRAGSources.ts
|
|
1092
|
+
import { useMemo as useMemo4 } from "react";
|
|
1093
|
+
var useRAGSources = (messages) => {
|
|
1094
|
+
const latestAssistantMessage = useMemo4(() => getLatestAssistantMessage(messages), [messages]);
|
|
1095
|
+
const sources = useMemo4(() => getLatestRAGSources(messages), [messages]);
|
|
1096
|
+
const sourceGroups = useMemo4(() => buildRAGSourceGroups(sources), [sources]);
|
|
1097
|
+
return {
|
|
1098
|
+
hasSources: sources.length > 0,
|
|
1099
|
+
latestAssistantMessage,
|
|
1100
|
+
sourceGroups,
|
|
1101
|
+
sources
|
|
1102
|
+
};
|
|
1103
|
+
};
|
|
1104
|
+
|
|
917
1105
|
// src/react/ai/useRAGStatus.ts
|
|
918
|
-
import { useCallback as useCallback4, useEffect as useEffect3, useMemo as
|
|
1106
|
+
import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo5, useState as useState3 } from "react";
|
|
919
1107
|
var useRAGStatus = (path, autoLoad = true) => {
|
|
920
|
-
const client =
|
|
1108
|
+
const client = useMemo5(() => createRAGClient({ path }), [path]);
|
|
921
1109
|
const [status, setStatus] = useState3();
|
|
922
1110
|
const [capabilities, setCapabilities] = useState3();
|
|
923
1111
|
const [error, setError] = useState3(null);
|
|
@@ -938,6 +1126,12 @@ var useRAGStatus = (path, autoLoad = true) => {
|
|
|
938
1126
|
setIsLoading(false);
|
|
939
1127
|
}
|
|
940
1128
|
}, [client]);
|
|
1129
|
+
const reset = useCallback4(() => {
|
|
1130
|
+
setCapabilities(undefined);
|
|
1131
|
+
setError(null);
|
|
1132
|
+
setIsLoading(false);
|
|
1133
|
+
setStatus(undefined);
|
|
1134
|
+
}, []);
|
|
941
1135
|
useEffect3(() => {
|
|
942
1136
|
if (!autoLoad) {
|
|
943
1137
|
setIsLoading(false);
|
|
@@ -950,19 +1144,67 @@ var useRAGStatus = (path, autoLoad = true) => {
|
|
|
950
1144
|
error,
|
|
951
1145
|
isLoading,
|
|
952
1146
|
refresh,
|
|
1147
|
+
reset,
|
|
953
1148
|
status
|
|
954
1149
|
};
|
|
955
1150
|
};
|
|
1151
|
+
|
|
956
1152
|
// src/react/ai/useRAGStream.ts
|
|
957
|
-
|
|
1153
|
+
import { useCallback as useCallback5, useMemo as useMemo6 } from "react";
|
|
1154
|
+
var useRAGStream = (path, conversationId) => {
|
|
1155
|
+
const stream = useAIStream(path, conversationId);
|
|
1156
|
+
const latestAssistantMessage = useMemo6(() => getLatestAssistantMessage(stream.messages), [stream.messages]);
|
|
1157
|
+
const sources = useMemo6(() => getLatestRAGSources(stream.messages), [stream.messages]);
|
|
1158
|
+
const sourceGroups = useMemo6(() => buildRAGSourceGroups(sources), [sources]);
|
|
1159
|
+
const citations = useMemo6(() => buildRAGCitations(sources), [sources]);
|
|
1160
|
+
const stage = useMemo6(() => resolveRAGStreamStage({
|
|
1161
|
+
error: stream.error,
|
|
1162
|
+
isStreaming: stream.isStreaming,
|
|
1163
|
+
messages: stream.messages
|
|
1164
|
+
}), [stream.error, stream.isStreaming, stream.messages]);
|
|
1165
|
+
const query = useCallback5((content, attachments) => {
|
|
1166
|
+
stream.send(content, attachments);
|
|
1167
|
+
}, [stream]);
|
|
1168
|
+
return {
|
|
1169
|
+
...stream,
|
|
1170
|
+
citations,
|
|
1171
|
+
hasSources: sources.length > 0,
|
|
1172
|
+
latestAssistantMessage,
|
|
1173
|
+
query,
|
|
1174
|
+
sourceGroups,
|
|
1175
|
+
sources,
|
|
1176
|
+
stage
|
|
1177
|
+
};
|
|
1178
|
+
};
|
|
1179
|
+
|
|
1180
|
+
// src/react/ai/useRAG.ts
|
|
1181
|
+
var useRAG = (path, options = {}) => {
|
|
1182
|
+
const search = useRAGSearch(path);
|
|
1183
|
+
const ingest = useRAGIngest(path);
|
|
1184
|
+
const status = useRAGStatus(path, options.autoLoadStatus ?? true);
|
|
1185
|
+
const stream = useRAGStream(options.streamPath ?? path, options.conversationId);
|
|
1186
|
+
const sources = useRAGSources(stream.messages);
|
|
1187
|
+
const citations = useRAGCitations(sources.sources);
|
|
1188
|
+
return useMemo7(() => ({
|
|
1189
|
+
citations,
|
|
1190
|
+
ingest,
|
|
1191
|
+
search,
|
|
1192
|
+
sources,
|
|
1193
|
+
status,
|
|
1194
|
+
stream
|
|
1195
|
+
}), [citations, ingest, search, sources, status, stream]);
|
|
1196
|
+
};
|
|
958
1197
|
export {
|
|
959
1198
|
useRAGStream,
|
|
960
1199
|
useRAGStatus,
|
|
1200
|
+
useRAGSources,
|
|
961
1201
|
useRAGSearch,
|
|
962
1202
|
useRAGIngest,
|
|
1203
|
+
useRAGCitations,
|
|
1204
|
+
useRAG,
|
|
963
1205
|
useAIStream,
|
|
964
1206
|
AIStreamProvider
|
|
965
1207
|
};
|
|
966
1208
|
|
|
967
|
-
//# debugId=
|
|
1209
|
+
//# debugId=D0ADC407D5CCE73D64756E2164756E21
|
|
968
1210
|
//# sourceMappingURL=index.js.map
|