@absolutejs/absolute 0.19.0-beta.436 → 0.19.0-beta.438

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.
Files changed (42) hide show
  1. package/dist/ai/client/index.js +74 -1
  2. package/dist/ai/client/index.js.map +3 -3
  3. package/dist/ai/index.js +234 -2
  4. package/dist/ai/index.js.map +4 -4
  5. package/dist/ai-client/angular/ai/index.js +73 -0
  6. package/dist/ai-client/react/ai/index.js +369 -126
  7. package/dist/ai-client/vue/ai/index.js +73 -0
  8. package/dist/angular/ai/index.js +74 -1
  9. package/dist/angular/ai/index.js.map +3 -3
  10. package/dist/angular/index.js +4 -3
  11. package/dist/angular/index.js.map +4 -4
  12. package/dist/angular/server.js +2 -2
  13. package/dist/angular/server.js.map +1 -1
  14. package/dist/build.js +2 -2
  15. package/dist/build.js.map +1 -1
  16. package/dist/client/index.js +2 -1
  17. package/dist/client/index.js.map +3 -3
  18. package/dist/index.js +4 -3
  19. package/dist/index.js.map +4 -4
  20. package/dist/react/ai/index.js +623 -294
  21. package/dist/react/ai/index.js.map +12 -8
  22. package/dist/react/index.js +3 -2
  23. package/dist/react/index.js.map +4 -4
  24. package/dist/src/ai/client/ragClient.d.ts +8 -1
  25. package/dist/src/ai/rag/chat.d.ts +134 -2
  26. package/dist/src/react/ai/index.d.ts +3 -0
  27. package/dist/src/react/ai/useRAG.d.ts +45 -0
  28. package/dist/src/react/ai/useRAGChunkPreview.d.ts +11 -0
  29. package/dist/src/react/ai/useRAGDocuments.d.ts +10 -0
  30. package/dist/src/react/ai/useRAGIndexAdmin.d.ts +30 -0
  31. package/dist/svelte/ai/index.js +74 -1
  32. package/dist/svelte/ai/index.js.map +3 -3
  33. package/dist/svelte/index.js +3 -2
  34. package/dist/svelte/index.js.map +4 -4
  35. package/dist/types/ai.d.ts +74 -0
  36. package/dist/vue/ai/index.js +74 -1
  37. package/dist/vue/ai/index.js.map +3 -3
  38. package/dist/vue/components/index.js +11 -2
  39. package/dist/vue/components/index.js.map +3 -3
  40. package/dist/vue/index.js +13 -3
  41. package/dist/vue/index.js.map +5 -5
  42. package/package.json +1 -1
@@ -144,13 +144,67 @@ var isValidAIClientMessage = (data) => {
144
144
  }
145
145
  };
146
146
 
147
- // src/react/ai/AIStreamProvider.tsx
148
- import {
149
- createContext,
150
- useContext,
151
- useEffect,
152
- useRef
153
- } from "react";
147
+ // src/ai/client/actions.ts
148
+ var serverMessageToAction = (msg) => {
149
+ switch (msg.type) {
150
+ case "chunk":
151
+ return {
152
+ content: msg.content,
153
+ conversationId: msg.conversationId,
154
+ messageId: msg.messageId,
155
+ type: "chunk"
156
+ };
157
+ case "thinking":
158
+ return {
159
+ content: msg.content,
160
+ conversationId: msg.conversationId,
161
+ messageId: msg.messageId,
162
+ type: "thinking"
163
+ };
164
+ case "tool_status":
165
+ return {
166
+ conversationId: msg.conversationId,
167
+ input: msg.input,
168
+ messageId: msg.messageId,
169
+ name: msg.name,
170
+ result: msg.result,
171
+ status: msg.status,
172
+ type: "tool_status"
173
+ };
174
+ case "image":
175
+ return {
176
+ conversationId: msg.conversationId,
177
+ data: msg.data,
178
+ format: msg.format,
179
+ imageId: msg.imageId,
180
+ isPartial: msg.isPartial,
181
+ messageId: msg.messageId,
182
+ revisedPrompt: msg.revisedPrompt,
183
+ type: "image"
184
+ };
185
+ case "complete":
186
+ return {
187
+ conversationId: msg.conversationId,
188
+ durationMs: msg.durationMs,
189
+ messageId: msg.messageId,
190
+ model: msg.model,
191
+ sources: msg.sources,
192
+ type: "complete",
193
+ usage: msg.usage
194
+ };
195
+ case "rag_retrieved":
196
+ return {
197
+ conversationId: msg.conversationId,
198
+ messageId: msg.messageId,
199
+ sources: msg.sources,
200
+ type: "rag_retrieved"
201
+ };
202
+ case "error":
203
+ return { message: msg.message, type: "error" };
204
+ default:
205
+ return null;
206
+ }
207
+ };
154
208
 
155
209
  // src/ai/client/connection.ts
156
210
  var WS_OPEN = 1;
@@ -556,107 +610,6 @@ var createAIMessageStore = () => {
556
610
  };
557
611
  };
558
612
 
559
- // src/ai/client/actions.ts
560
- var serverMessageToAction = (msg) => {
561
- switch (msg.type) {
562
- case "chunk":
563
- return {
564
- content: msg.content,
565
- conversationId: msg.conversationId,
566
- messageId: msg.messageId,
567
- type: "chunk"
568
- };
569
- case "thinking":
570
- return {
571
- content: msg.content,
572
- conversationId: msg.conversationId,
573
- messageId: msg.messageId,
574
- type: "thinking"
575
- };
576
- case "tool_status":
577
- return {
578
- conversationId: msg.conversationId,
579
- input: msg.input,
580
- messageId: msg.messageId,
581
- name: msg.name,
582
- result: msg.result,
583
- status: msg.status,
584
- type: "tool_status"
585
- };
586
- case "image":
587
- return {
588
- conversationId: msg.conversationId,
589
- data: msg.data,
590
- format: msg.format,
591
- imageId: msg.imageId,
592
- isPartial: msg.isPartial,
593
- messageId: msg.messageId,
594
- revisedPrompt: msg.revisedPrompt,
595
- type: "image"
596
- };
597
- case "complete":
598
- return {
599
- conversationId: msg.conversationId,
600
- durationMs: msg.durationMs,
601
- messageId: msg.messageId,
602
- model: msg.model,
603
- sources: msg.sources,
604
- type: "complete",
605
- usage: msg.usage
606
- };
607
- case "rag_retrieved":
608
- return {
609
- conversationId: msg.conversationId,
610
- messageId: msg.messageId,
611
- sources: msg.sources,
612
- type: "rag_retrieved"
613
- };
614
- case "error":
615
- return { message: msg.message, type: "error" };
616
- default:
617
- return null;
618
- }
619
- };
620
-
621
- // src/react/ai/AIStreamProvider.tsx
622
- import { jsxDEV } from "react/jsx-dev-runtime";
623
- var AIStreamContext = createContext(null);
624
- var AIStreamProvider = ({
625
- children,
626
- path
627
- }) => {
628
- const ref = useRef(null);
629
- if (!ref.current) {
630
- const connection = createAIConnection(path);
631
- const store = createAIMessageStore();
632
- ref.current = { connection, store };
633
- }
634
- useEffect(() => {
635
- const { current } = ref;
636
- if (!current) {
637
- return;
638
- }
639
- const { connection, store } = current;
640
- const unsubscribe = connection.subscribe((msg) => {
641
- const action = serverMessageToAction(msg);
642
- if (action) {
643
- store.dispatch(action);
644
- }
645
- });
646
- return () => {
647
- unsubscribe();
648
- connection.close();
649
- };
650
- }, []);
651
- return /* @__PURE__ */ jsxDEV(AIStreamContext.Provider, {
652
- value: ref.current,
653
- children
654
- }, undefined, false, undefined, this);
655
- };
656
- var useAIStreamContext = () => useContext(AIStreamContext);
657
- // src/react/ai/useAIStream.ts
658
- import { useCallback, useEffect as useEffect2, useRef as useRef2, useSyncExternalStore } from "react";
659
-
660
613
  // src/ai/protocol.ts
661
614
  var generateId = () => crypto.randomUUID();
662
615
  var parseAIMessage = (raw) => {
@@ -690,42 +643,59 @@ var parseAIMessage = (raw) => {
690
643
  };
691
644
  var serializeAIMessage = (msg) => JSON.stringify(msg);
692
645
 
693
- // src/react/ai/useAIStream.ts
694
- var useAIStream = (path, conversationId) => {
695
- const context = useAIStreamContext();
696
- const standaloneRef = useRef2(null);
697
- const isStandalone = !context;
698
- if (isStandalone && !standaloneRef.current && path) {
699
- const connection2 = createAIConnection(path);
700
- const store2 = createAIMessageStore();
701
- standaloneRef.current = { connection: connection2, store: store2 };
702
- }
703
- const resolved = context ?? standaloneRef.current;
704
- if (!resolved) {
705
- throw new Error("useAIStream requires either an AIStreamProvider or a path argument");
706
- }
707
- const { connection, store } = resolved;
708
- useEffect2(() => {
709
- if (!isStandalone) {
710
- return;
646
+ // src/ai/client/createAIStream.ts
647
+ var createAIStream = (path, conversationId) => {
648
+ const connection = createAIConnection(path);
649
+ const store = createAIMessageStore();
650
+ const listeners = new Set;
651
+ let currentError = null;
652
+ let currentIsStreaming = false;
653
+ let currentMessages = [];
654
+ let activeConversationId = conversationId ?? null;
655
+ const syncState = () => {
656
+ const snapshot = store.getSnapshot();
657
+ const convId = activeConversationId ?? snapshot.activeConversationId;
658
+ const conversation = convId ? snapshot.conversations.get(convId) : undefined;
659
+ activeConversationId = convId ?? snapshot.activeConversationId;
660
+ currentError = snapshot.error;
661
+ currentIsStreaming = snapshot.isStreaming;
662
+ currentMessages = conversation?.messages ?? [];
663
+ listeners.forEach((listener) => listener());
664
+ };
665
+ const unsubscribeStore = store.subscribe(syncState);
666
+ const unsubscribeConnection = connection.subscribe((msg) => {
667
+ const action = serverMessageToAction(msg);
668
+ if (action) {
669
+ store.dispatch(action);
711
670
  }
712
- const unsubscribe = connection.subscribe((msg) => {
713
- const action = serverMessageToAction(msg);
714
- if (action) {
715
- store.dispatch(action);
716
- }
717
- });
718
- return () => {
719
- unsubscribe();
720
- connection.close();
721
- };
722
- }, [connection, isStandalone, store]);
723
- const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);
724
- const activeConvId = conversationId ?? state.activeConversationId;
725
- const conversation = activeConvId ? state.conversations.get(activeConvId) : undefined;
726
- const messages = conversation?.messages ?? [];
727
- const send = useCallback((content, attachments) => {
728
- const convId = activeConvId ?? generateId();
671
+ });
672
+ const branch = (messageId, content) => {
673
+ if (activeConversationId) {
674
+ connection.send({
675
+ content,
676
+ conversationId: activeConversationId,
677
+ messageId,
678
+ type: "branch"
679
+ });
680
+ }
681
+ };
682
+ const cancel = () => {
683
+ if (activeConversationId) {
684
+ store.dispatch({ type: "cancel" });
685
+ connection.send({
686
+ conversationId: activeConversationId,
687
+ type: "cancel"
688
+ });
689
+ }
690
+ };
691
+ const destroy = () => {
692
+ unsubscribeStore();
693
+ unsubscribeConnection();
694
+ connection.close();
695
+ listeners.clear();
696
+ };
697
+ const send = (content, attachments) => {
698
+ const convId = activeConversationId ?? generateId();
729
699
  const msgId = generateId();
730
700
  store.dispatch({
731
701
  attachments,
@@ -740,37 +710,348 @@ var useAIStream = (path, conversationId) => {
740
710
  conversationId: convId,
741
711
  type: "message"
742
712
  });
743
- }, [activeConvId, connection, store]);
744
- const cancel = useCallback(() => {
745
- if (activeConvId) {
746
- store.dispatch({ type: "cancel" });
747
- connection.send({ conversationId: activeConvId, type: "cancel" });
748
- }
749
- }, [activeConvId, connection, store]);
750
- const branch = useCallback((messageId, content) => {
751
- if (activeConvId) {
752
- connection.send({
753
- content,
754
- conversationId: activeConvId,
755
- messageId,
756
- type: "branch"
757
- });
758
- }
759
- }, [activeConvId, connection]);
713
+ };
714
+ const subscribe = (callback) => {
715
+ listeners.add(callback);
716
+ return () => {
717
+ listeners.delete(callback);
718
+ };
719
+ };
760
720
  return {
761
721
  branch,
762
722
  cancel,
763
- error: state.error,
764
- isStreaming: state.isStreaming,
765
- messages,
766
- send
723
+ destroy,
724
+ send,
725
+ subscribe,
726
+ get error() {
727
+ return currentError;
728
+ },
729
+ get isStreaming() {
730
+ return currentIsStreaming;
731
+ },
732
+ get messages() {
733
+ return currentMessages;
734
+ }
767
735
  };
768
736
  };
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";
737
+ // src/ai/client/ragClient.ts
738
+ var jsonHeaders = {
739
+ "Content-Type": "application/json"
740
+ };
741
+ var normalizeBasePath = (path) => path.endsWith("/") ? path.slice(0, -1) : path;
742
+ var parseJson = async (response) => {
743
+ const payload = await response.json();
744
+ return payload;
745
+ };
746
+ var toErrorMessage = async (response) => {
747
+ try {
748
+ const payload = await response.json();
749
+ if (typeof payload.error === "string" && payload.error) {
750
+ return payload.error;
751
+ }
752
+ } catch {}
753
+ return `Request failed with status ${response.status}`;
754
+ };
755
+ var createRAGClient = (options) => {
756
+ const basePath = normalizeBasePath(options.path);
757
+ const fetchImpl = options.fetch ?? fetch;
758
+ return {
759
+ async ingest(chunks) {
760
+ const response = await fetchImpl(`${basePath}/ingest`, {
761
+ body: JSON.stringify({ chunks }),
762
+ headers: jsonHeaders,
763
+ method: "POST"
764
+ });
765
+ if (!response.ok) {
766
+ return {
767
+ ok: false,
768
+ error: await toErrorMessage(response)
769
+ };
770
+ }
771
+ return parseJson(response);
772
+ },
773
+ async ingestDocuments(input) {
774
+ const response = await fetchImpl(`${basePath}/ingest`, {
775
+ body: JSON.stringify(input),
776
+ headers: jsonHeaders,
777
+ method: "POST"
778
+ });
779
+ if (!response.ok) {
780
+ return {
781
+ ok: false,
782
+ error: await toErrorMessage(response)
783
+ };
784
+ }
785
+ return parseJson(response);
786
+ },
787
+ async search(input) {
788
+ const response = await fetchImpl(`${basePath}/search`, {
789
+ body: JSON.stringify(input),
790
+ headers: jsonHeaders,
791
+ method: "POST"
792
+ });
793
+ if (!response.ok) {
794
+ throw new Error(await toErrorMessage(response));
795
+ }
796
+ const payload = await parseJson(response);
797
+ if (!payload.ok) {
798
+ throw new Error(payload.error ?? "RAG search failed");
799
+ }
800
+ return payload.results ?? [];
801
+ },
802
+ async status() {
803
+ const response = await fetchImpl(`${basePath}/status`);
804
+ if (!response.ok) {
805
+ throw new Error(await toErrorMessage(response));
806
+ }
807
+ return parseJson(response);
808
+ },
809
+ async documents(kind) {
810
+ const query = kind ? `?kind=${encodeURIComponent(kind)}` : "";
811
+ const response = await fetchImpl(`${basePath}/documents${query}`);
812
+ if (!response.ok) {
813
+ throw new Error(await toErrorMessage(response));
814
+ }
815
+ return parseJson(response);
816
+ },
817
+ async createDocument(input) {
818
+ const response = await fetchImpl(`${basePath}/documents`, {
819
+ body: JSON.stringify(input),
820
+ headers: jsonHeaders,
821
+ method: "POST"
822
+ });
823
+ if (!response.ok) {
824
+ return {
825
+ ok: false,
826
+ error: await toErrorMessage(response)
827
+ };
828
+ }
829
+ return parseJson(response);
830
+ },
831
+ async documentChunks(id) {
832
+ const response = await fetchImpl(`${basePath}/documents/${encodeURIComponent(id)}/chunks`);
833
+ if (!response.ok) {
834
+ const error = await toErrorMessage(response);
835
+ return { ok: false, error };
836
+ }
837
+ return parseJson(response);
838
+ },
839
+ async deleteDocument(id) {
840
+ const response = await fetchImpl(`${basePath}/documents/${encodeURIComponent(id)}`, {
841
+ method: "DELETE"
842
+ });
843
+ if (!response.ok) {
844
+ return {
845
+ ok: false,
846
+ error: await toErrorMessage(response)
847
+ };
848
+ }
849
+ return parseJson(response);
850
+ },
851
+ async reseed() {
852
+ const response = await fetchImpl(`${basePath}/reseed`, {
853
+ method: "POST"
854
+ });
855
+ if (!response.ok) {
856
+ return {
857
+ ok: false,
858
+ error: await toErrorMessage(response)
859
+ };
860
+ }
861
+ return parseJson(response);
862
+ },
863
+ async reset() {
864
+ const response = await fetchImpl(`${basePath}/reset`, {
865
+ method: "POST"
866
+ });
867
+ if (!response.ok) {
868
+ return {
869
+ ok: false,
870
+ error: await toErrorMessage(response)
871
+ };
872
+ }
873
+ return parseJson(response);
874
+ },
875
+ async backends() {
876
+ const response = await fetchImpl(`${basePath}/backends`);
877
+ if (!response.ok) {
878
+ throw new Error(await toErrorMessage(response));
879
+ }
880
+ return parseJson(response);
881
+ },
882
+ async clearIndex() {
883
+ const response = await fetchImpl(`${basePath}/index`, {
884
+ method: "DELETE"
885
+ });
886
+ if (!response.ok) {
887
+ throw new Error(await toErrorMessage(response));
888
+ }
889
+ return parseJson(response);
890
+ }
891
+ };
892
+ };
893
+ // src/react/ai/AIStreamProvider.tsx
894
+ import {
895
+ createContext,
896
+ useContext,
897
+ useEffect,
898
+ useRef
899
+ } from "react";
900
+ import { jsxDEV } from "react/jsx-dev-runtime";
901
+ var AIStreamContext = createContext(null);
902
+ var AIStreamProvider = ({
903
+ children,
904
+ path
905
+ }) => {
906
+ const ref = useRef(null);
907
+ if (!ref.current) {
908
+ const connection = createAIConnection(path);
909
+ const store = createAIMessageStore();
910
+ ref.current = { connection, store };
911
+ }
912
+ useEffect(() => {
913
+ const { current } = ref;
914
+ if (!current) {
915
+ return;
916
+ }
917
+ const { connection, store } = current;
918
+ const unsubscribe = connection.subscribe((msg) => {
919
+ const action = serverMessageToAction(msg);
920
+ if (action) {
921
+ store.dispatch(action);
922
+ }
923
+ });
924
+ return () => {
925
+ unsubscribe();
926
+ connection.close();
927
+ };
928
+ }, []);
929
+ return /* @__PURE__ */ jsxDEV(AIStreamContext.Provider, {
930
+ value: ref.current,
931
+ children
932
+ }, undefined, false, undefined, this);
933
+ };
934
+ var useAIStreamContext = () => useContext(AIStreamContext);
935
+ // src/react/ai/useAIStream.ts
936
+ import { useCallback, useEffect as useEffect2, useRef as useRef2, useSyncExternalStore } from "react";
937
+ var useAIStream = (path, conversationId) => {
938
+ const context = useAIStreamContext();
939
+ const standaloneRef = useRef2(null);
940
+ const isStandalone = !context;
941
+ if (isStandalone && !standaloneRef.current && path) {
942
+ const connection2 = createAIConnection(path);
943
+ const store2 = createAIMessageStore();
944
+ standaloneRef.current = { connection: connection2, store: store2 };
945
+ }
946
+ const resolved = context ?? standaloneRef.current;
947
+ if (!resolved) {
948
+ throw new Error("useAIStream requires either an AIStreamProvider or a path argument");
949
+ }
950
+ const { connection, store } = resolved;
951
+ useEffect2(() => {
952
+ if (!isStandalone) {
953
+ return;
954
+ }
955
+ const unsubscribe = connection.subscribe((msg) => {
956
+ const action = serverMessageToAction(msg);
957
+ if (action) {
958
+ store.dispatch(action);
959
+ }
960
+ });
961
+ return () => {
962
+ unsubscribe();
963
+ connection.close();
964
+ };
965
+ }, [connection, isStandalone, store]);
966
+ const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);
967
+ const activeConvId = conversationId ?? state.activeConversationId;
968
+ const conversation = activeConvId ? state.conversations.get(activeConvId) : undefined;
969
+ const messages = conversation?.messages ?? [];
970
+ const send = useCallback((content, attachments) => {
971
+ const convId = activeConvId ?? generateId();
972
+ const msgId = generateId();
973
+ store.dispatch({
974
+ attachments,
975
+ content,
976
+ conversationId: convId,
977
+ messageId: msgId,
978
+ type: "send"
979
+ });
980
+ connection.send({
981
+ attachments,
982
+ content,
983
+ conversationId: convId,
984
+ type: "message"
985
+ });
986
+ }, [activeConvId, connection, store]);
987
+ const cancel = useCallback(() => {
988
+ if (activeConvId) {
989
+ store.dispatch({ type: "cancel" });
990
+ connection.send({ conversationId: activeConvId, type: "cancel" });
991
+ }
992
+ }, [activeConvId, connection, store]);
993
+ const branch = useCallback((messageId, content) => {
994
+ if (activeConvId) {
995
+ connection.send({
996
+ content,
997
+ conversationId: activeConvId,
998
+ messageId,
999
+ type: "branch"
1000
+ });
1001
+ }
1002
+ }, [activeConvId, connection]);
1003
+ return {
1004
+ branch,
1005
+ cancel,
1006
+ error: state.error,
1007
+ isStreaming: state.isStreaming,
1008
+ messages,
1009
+ send
1010
+ };
1011
+ };
1012
+ // src/react/ai/useRAGChunkPreview.ts
1013
+ import { useCallback as useCallback2, useMemo, useState } from "react";
1014
+ var useRAGChunkPreview = (path) => {
1015
+ const client = useMemo(() => createRAGClient({ path }), [path]);
1016
+ const [preview, setPreview] = useState(null);
1017
+ const [isLoading, setIsLoading] = useState(false);
1018
+ const [error, setError] = useState(null);
1019
+ const inspect = useCallback2(async (id) => {
1020
+ setIsLoading(true);
1021
+ setError(null);
1022
+ try {
1023
+ const response = await client.documentChunks(id);
1024
+ if (!response.ok) {
1025
+ throw new Error(response.error);
1026
+ }
1027
+ setPreview(response);
1028
+ return response;
1029
+ } catch (err) {
1030
+ const message = err instanceof Error ? err.message : "Failed to load RAG chunk preview";
1031
+ setError(message);
1032
+ throw err;
1033
+ } finally {
1034
+ setIsLoading(false);
1035
+ }
1036
+ }, [client]);
1037
+ const clear = useCallback2(() => {
1038
+ setPreview(null);
1039
+ setError(null);
1040
+ setIsLoading(false);
1041
+ }, []);
1042
+ return {
1043
+ clear,
1044
+ error,
1045
+ inspect,
1046
+ isLoading,
1047
+ preview
1048
+ };
1049
+ };
1050
+ // src/react/ai/useRAG.ts
1051
+ import { useMemo as useMemo10 } from "react";
1052
+
1053
+ // src/react/ai/useRAGCitations.ts
1054
+ import { useMemo as useMemo2 } from "react";
774
1055
 
775
1056
  // src/ai/rag/presentation.ts
776
1057
  var buildSourceGroupKey = (source) => source.source ?? source.title ?? source.chunkId;
@@ -864,8 +1145,8 @@ var resolveRAGStreamStage = ({
864
1145
 
865
1146
  // src/react/ai/useRAGCitations.ts
866
1147
  var useRAGCitations = (sources) => {
867
- const citations = useMemo(() => buildRAGCitations(sources), [sources]);
868
- const sourceGroups = useMemo(() => buildRAGSourceGroups(sources), [sources]);
1148
+ const citations = useMemo2(() => buildRAGCitations(sources), [sources]);
1149
+ const sourceGroups = useMemo2(() => buildRAGSourceGroups(sources), [sources]);
869
1150
  return {
870
1151
  citations,
871
1152
  hasCitations: citations.length > 0,
@@ -873,102 +1154,56 @@ var useRAGCitations = (sources) => {
873
1154
  };
874
1155
  };
875
1156
 
876
- // src/react/ai/useRAGIngest.ts
877
- import { useCallback as useCallback2, useMemo as useMemo2, useState } from "react";
878
-
879
- // src/ai/client/ragClient.ts
880
- var jsonHeaders = {
881
- "Content-Type": "application/json"
882
- };
883
- var normalizeBasePath = (path) => path.endsWith("/") ? path.slice(0, -1) : path;
884
- var parseJson = async (response) => {
885
- const payload = await response.json();
886
- return payload;
887
- };
888
- var toErrorMessage = async (response) => {
889
- try {
890
- const payload = await response.json();
891
- if (typeof payload.error === "string" && payload.error) {
892
- return payload.error;
1157
+ // src/react/ai/useRAGDocuments.ts
1158
+ import { useCallback as useCallback3, useMemo as useMemo3, useState as useState2 } from "react";
1159
+ var useRAGDocuments = (path) => {
1160
+ const client = useMemo3(() => createRAGClient({ path }), [path]);
1161
+ const [documents, setDocuments] = useState2([]);
1162
+ const [isLoading, setIsLoading] = useState2(false);
1163
+ const [error, setError] = useState2(null);
1164
+ const [lastResponse, setLastResponse] = useState2(null);
1165
+ const load = useCallback3(async (kind) => {
1166
+ setIsLoading(true);
1167
+ setError(null);
1168
+ try {
1169
+ const response = await client.documents(kind);
1170
+ setDocuments(response.documents);
1171
+ setLastResponse(response);
1172
+ return response;
1173
+ } catch (err) {
1174
+ const message = err instanceof Error ? err.message : "Failed to load RAG documents";
1175
+ setError(message);
1176
+ throw err;
1177
+ } finally {
1178
+ setIsLoading(false);
893
1179
  }
894
- } catch {}
895
- return `Request failed with status ${response.status}`;
896
- };
897
- var createRAGClient = (options) => {
898
- const basePath = normalizeBasePath(options.path);
899
- const fetchImpl = options.fetch ?? fetch;
1180
+ }, [client]);
1181
+ const reset = useCallback3(() => {
1182
+ setDocuments([]);
1183
+ setError(null);
1184
+ setLastResponse(null);
1185
+ setIsLoading(false);
1186
+ }, []);
900
1187
  return {
901
- async ingest(chunks) {
902
- const response = await fetchImpl(`${basePath}/ingest`, {
903
- body: JSON.stringify({ chunks }),
904
- headers: jsonHeaders,
905
- method: "POST"
906
- });
907
- if (!response.ok) {
908
- return {
909
- ok: false,
910
- error: await toErrorMessage(response)
911
- };
912
- }
913
- return parseJson(response);
914
- },
915
- async ingestDocuments(input) {
916
- const response = await fetchImpl(`${basePath}/ingest`, {
917
- body: JSON.stringify(input),
918
- headers: jsonHeaders,
919
- method: "POST"
920
- });
921
- if (!response.ok) {
922
- return {
923
- ok: false,
924
- error: await toErrorMessage(response)
925
- };
926
- }
927
- return parseJson(response);
928
- },
929
- async search(input) {
930
- const response = await fetchImpl(`${basePath}/search`, {
931
- body: JSON.stringify(input),
932
- headers: jsonHeaders,
933
- method: "POST"
934
- });
935
- if (!response.ok) {
936
- throw new Error(await toErrorMessage(response));
937
- }
938
- const payload = await parseJson(response);
939
- if (!payload.ok) {
940
- throw new Error(payload.error ?? "RAG search failed");
941
- }
942
- return payload.results ?? [];
943
- },
944
- async status() {
945
- const response = await fetchImpl(`${basePath}/status`);
946
- if (!response.ok) {
947
- throw new Error(await toErrorMessage(response));
948
- }
949
- return parseJson(response);
950
- },
951
- async clearIndex() {
952
- const response = await fetchImpl(`${basePath}/index`, {
953
- method: "DELETE"
954
- });
955
- if (!response.ok) {
956
- throw new Error(await toErrorMessage(response));
957
- }
958
- return parseJson(response);
959
- }
1188
+ documents,
1189
+ error,
1190
+ isLoading,
1191
+ lastResponse,
1192
+ load,
1193
+ reset
960
1194
  };
961
1195
  };
962
1196
 
963
1197
  // src/react/ai/useRAGIngest.ts
1198
+ import { useCallback as useCallback4, useMemo as useMemo4, useState as useState3 } from "react";
964
1199
  var useRAGIngest = (path) => {
965
- const client = useMemo2(() => createRAGClient({ path }), [path]);
966
- const [error, setError] = useState(null);
967
- const [isIngesting, setIsIngesting] = useState(false);
968
- const [lastIngestCount, setLastIngestCount] = useState(null);
969
- const [lastDocumentCount, setLastDocumentCount] = useState(null);
970
- const [lastResponse, setLastResponse] = useState(null);
971
- const ingestChunks = useCallback2(async (chunks) => {
1200
+ const client = useMemo4(() => createRAGClient({ path }), [path]);
1201
+ const [error, setError] = useState3(null);
1202
+ const [isIngesting, setIsIngesting] = useState3(false);
1203
+ const [lastIngestCount, setLastIngestCount] = useState3(null);
1204
+ const [lastDocumentCount, setLastDocumentCount] = useState3(null);
1205
+ const [lastResponse, setLastResponse] = useState3(null);
1206
+ const ingestChunks = useCallback4(async (chunks) => {
972
1207
  setIsIngesting(true);
973
1208
  setError(null);
974
1209
  try {
@@ -988,7 +1223,7 @@ var useRAGIngest = (path) => {
988
1223
  setIsIngesting(false);
989
1224
  }
990
1225
  }, [client]);
991
- const ingestDocuments = useCallback2(async (input) => {
1226
+ const ingestDocuments = useCallback4(async (input) => {
992
1227
  setIsIngesting(true);
993
1228
  setError(null);
994
1229
  try {
@@ -1008,7 +1243,7 @@ var useRAGIngest = (path) => {
1008
1243
  setIsIngesting(false);
1009
1244
  }
1010
1245
  }, [client]);
1011
- const clearIndex = useCallback2(async () => {
1246
+ const clearIndex = useCallback4(async () => {
1012
1247
  setIsIngesting(true);
1013
1248
  setError(null);
1014
1249
  try {
@@ -1024,7 +1259,7 @@ var useRAGIngest = (path) => {
1024
1259
  setIsIngesting(false);
1025
1260
  }
1026
1261
  }, [client]);
1027
- const reset = useCallback2(() => {
1262
+ const reset = useCallback4(() => {
1028
1263
  setError(null);
1029
1264
  setLastDocumentCount(null);
1030
1265
  setLastIngestCount(null);
@@ -1044,16 +1279,101 @@ var useRAGIngest = (path) => {
1044
1279
  };
1045
1280
  };
1046
1281
 
1282
+ // src/react/ai/useRAGIndexAdmin.ts
1283
+ import { useCallback as useCallback5, useMemo as useMemo5, useState as useState4 } from "react";
1284
+ var useRAGIndexAdmin = (path) => {
1285
+ const client = useMemo5(() => createRAGClient({ path }), [path]);
1286
+ const [isLoading, setIsLoading] = useState4(false);
1287
+ const [error, setError] = useState4(null);
1288
+ const [lastMutation, setLastMutation] = useState4(null);
1289
+ const [backends, setBackends] = useState4(null);
1290
+ const run = useCallback5(async (operation) => {
1291
+ setIsLoading(true);
1292
+ setError(null);
1293
+ try {
1294
+ return await operation();
1295
+ } catch (err) {
1296
+ const message = err instanceof Error ? err.message : "RAG index administration failed";
1297
+ setError(message);
1298
+ throw err;
1299
+ } finally {
1300
+ setIsLoading(false);
1301
+ }
1302
+ }, []);
1303
+ const deleteDocument = useCallback5(async (id) => run(async () => {
1304
+ const response = await client.deleteDocument(id);
1305
+ setLastMutation(response);
1306
+ if (!response.ok) {
1307
+ throw new Error(response.error ?? "Failed to delete document");
1308
+ }
1309
+ return response;
1310
+ }), [client, run]);
1311
+ const createDocument = useCallback5(async (input) => run(async () => {
1312
+ const response = await client.createDocument(input);
1313
+ setLastMutation(response);
1314
+ if (!response.ok) {
1315
+ throw new Error(response.error ?? "Failed to create document");
1316
+ }
1317
+ return response;
1318
+ }), [client, run]);
1319
+ const reseed = useCallback5(async () => run(async () => {
1320
+ const response = await client.reseed();
1321
+ setLastMutation(response);
1322
+ if (!response.ok) {
1323
+ throw new Error(response.error ?? "Failed to reseed index");
1324
+ }
1325
+ return response;
1326
+ }), [client, run]);
1327
+ const reset = useCallback5(async () => run(async () => {
1328
+ const response = await client.reset();
1329
+ setLastMutation(response);
1330
+ if (!response.ok) {
1331
+ throw new Error(response.error ?? "Failed to reset index");
1332
+ }
1333
+ return response;
1334
+ }), [client, run]);
1335
+ const loadBackends = useCallback5(async () => run(async () => {
1336
+ const response = await client.backends();
1337
+ setBackends(response);
1338
+ return response;
1339
+ }), [client, run]);
1340
+ const clearIndex = useCallback5(async () => run(async () => {
1341
+ const response = await client.clearIndex();
1342
+ const mutation = { ok: response.ok };
1343
+ setLastMutation(mutation);
1344
+ return mutation;
1345
+ }), [client, run]);
1346
+ const resetState = useCallback5(() => {
1347
+ setIsLoading(false);
1348
+ setError(null);
1349
+ setLastMutation(null);
1350
+ setBackends(null);
1351
+ }, []);
1352
+ return {
1353
+ backends,
1354
+ clearIndex,
1355
+ createDocument,
1356
+ deleteDocument,
1357
+ error,
1358
+ isLoading,
1359
+ lastMutation,
1360
+ loadBackends,
1361
+ reseed,
1362
+ reset,
1363
+ resetState
1364
+ };
1365
+ };
1366
+
1047
1367
  // src/react/ai/useRAGSearch.ts
1048
- import { useCallback as useCallback3, useMemo as useMemo3, useState as useState2 } from "react";
1368
+ import { useCallback as useCallback6, useMemo as useMemo6, useState as useState5 } from "react";
1049
1369
  var useRAGSearch = (path) => {
1050
- const client = useMemo3(() => createRAGClient({ path }), [path]);
1051
- const [results, setResults] = useState2([]);
1052
- const [error, setError] = useState2(null);
1053
- const [isSearching, setIsSearching] = useState2(false);
1054
- const [hasSearched, setHasSearched] = useState2(false);
1055
- const [lastRequest, setLastRequest] = useState2(null);
1056
- const search = useCallback3(async (input) => {
1370
+ const client = useMemo6(() => createRAGClient({ path }), [path]);
1371
+ const [results, setResults] = useState5([]);
1372
+ const [error, setError] = useState5(null);
1373
+ const [isSearching, setIsSearching] = useState5(false);
1374
+ const [hasSearched, setHasSearched] = useState5(false);
1375
+ const [lastRequest, setLastRequest] = useState5(null);
1376
+ const search = useCallback6(async (input) => {
1057
1377
  setIsSearching(true);
1058
1378
  setError(null);
1059
1379
  setLastRequest(input);
@@ -1070,7 +1390,7 @@ var useRAGSearch = (path) => {
1070
1390
  setIsSearching(false);
1071
1391
  }
1072
1392
  }, [client]);
1073
- const reset = useCallback3(() => {
1393
+ const reset = useCallback6(() => {
1074
1394
  setError(null);
1075
1395
  setHasSearched(false);
1076
1396
  setLastRequest(null);
@@ -1089,11 +1409,11 @@ var useRAGSearch = (path) => {
1089
1409
  };
1090
1410
 
1091
1411
  // src/react/ai/useRAGSources.ts
1092
- import { useMemo as useMemo4 } from "react";
1412
+ import { useMemo as useMemo7 } from "react";
1093
1413
  var useRAGSources = (messages) => {
1094
- const latestAssistantMessage = useMemo4(() => getLatestAssistantMessage(messages), [messages]);
1095
- const sources = useMemo4(() => getLatestRAGSources(messages), [messages]);
1096
- const sourceGroups = useMemo4(() => buildRAGSourceGroups(sources), [sources]);
1414
+ const latestAssistantMessage = useMemo7(() => getLatestAssistantMessage(messages), [messages]);
1415
+ const sources = useMemo7(() => getLatestRAGSources(messages), [messages]);
1416
+ const sourceGroups = useMemo7(() => buildRAGSourceGroups(sources), [sources]);
1097
1417
  return {
1098
1418
  hasSources: sources.length > 0,
1099
1419
  latestAssistantMessage,
@@ -1103,14 +1423,14 @@ var useRAGSources = (messages) => {
1103
1423
  };
1104
1424
 
1105
1425
  // src/react/ai/useRAGStatus.ts
1106
- import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo5, useState as useState3 } from "react";
1426
+ import { useCallback as useCallback7, useEffect as useEffect3, useMemo as useMemo8, useState as useState6 } from "react";
1107
1427
  var useRAGStatus = (path, autoLoad = true) => {
1108
- const client = useMemo5(() => createRAGClient({ path }), [path]);
1109
- const [status, setStatus] = useState3();
1110
- const [capabilities, setCapabilities] = useState3();
1111
- const [error, setError] = useState3(null);
1112
- const [isLoading, setIsLoading] = useState3(autoLoad);
1113
- const refresh = useCallback4(async () => {
1428
+ const client = useMemo8(() => createRAGClient({ path }), [path]);
1429
+ const [status, setStatus] = useState6();
1430
+ const [capabilities, setCapabilities] = useState6();
1431
+ const [error, setError] = useState6(null);
1432
+ const [isLoading, setIsLoading] = useState6(autoLoad);
1433
+ const refresh = useCallback7(async () => {
1114
1434
  setIsLoading(true);
1115
1435
  setError(null);
1116
1436
  try {
@@ -1126,7 +1446,7 @@ var useRAGStatus = (path, autoLoad = true) => {
1126
1446
  setIsLoading(false);
1127
1447
  }
1128
1448
  }, [client]);
1129
- const reset = useCallback4(() => {
1449
+ const reset = useCallback7(() => {
1130
1450
  setCapabilities(undefined);
1131
1451
  setError(null);
1132
1452
  setIsLoading(false);
@@ -1150,19 +1470,19 @@ var useRAGStatus = (path, autoLoad = true) => {
1150
1470
  };
1151
1471
 
1152
1472
  // src/react/ai/useRAGStream.ts
1153
- import { useCallback as useCallback5, useMemo as useMemo6 } from "react";
1473
+ import { useCallback as useCallback8, useMemo as useMemo9 } from "react";
1154
1474
  var useRAGStream = (path, conversationId) => {
1155
1475
  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({
1476
+ const latestAssistantMessage = useMemo9(() => getLatestAssistantMessage(stream.messages), [stream.messages]);
1477
+ const sources = useMemo9(() => getLatestRAGSources(stream.messages), [stream.messages]);
1478
+ const sourceGroups = useMemo9(() => buildRAGSourceGroups(sources), [sources]);
1479
+ const citations = useMemo9(() => buildRAGCitations(sources), [sources]);
1480
+ const stage = useMemo9(() => resolveRAGStreamStage({
1161
1481
  error: stream.error,
1162
1482
  isStreaming: stream.isStreaming,
1163
1483
  messages: stream.messages
1164
1484
  }), [stream.error, stream.isStreaming, stream.messages]);
1165
- const query = useCallback5((content, attachments) => {
1485
+ const query = useCallback8((content, attachments) => {
1166
1486
  stream.send(content, attachments);
1167
1487
  }, [stream]);
1168
1488
  return {
@@ -1182,17 +1502,23 @@ var useRAG = (path, options = {}) => {
1182
1502
  const search = useRAGSearch(path);
1183
1503
  const ingest = useRAGIngest(path);
1184
1504
  const status = useRAGStatus(path, options.autoLoadStatus ?? true);
1505
+ const documents = useRAGDocuments(path);
1506
+ const chunkPreview = useRAGChunkPreview(path);
1507
+ const index = useRAGIndexAdmin(path);
1185
1508
  const stream = useRAGStream(options.streamPath ?? path, options.conversationId);
1186
1509
  const sources = useRAGSources(stream.messages);
1187
1510
  const citations = useRAGCitations(sources.sources);
1188
- return useMemo7(() => ({
1511
+ return useMemo10(() => ({
1189
1512
  citations,
1513
+ chunkPreview,
1514
+ documents,
1190
1515
  ingest,
1516
+ index,
1191
1517
  search,
1192
1518
  sources,
1193
1519
  status,
1194
1520
  stream
1195
- }), [citations, ingest, search, sources, status, stream]);
1521
+ }), [citations, chunkPreview, documents, ingest, index, search, sources, status, stream]);
1196
1522
  };
1197
1523
  export {
1198
1524
  useRAGStream,
@@ -1200,11 +1526,14 @@ export {
1200
1526
  useRAGSources,
1201
1527
  useRAGSearch,
1202
1528
  useRAGIngest,
1529
+ useRAGIndexAdmin,
1530
+ useRAGDocuments,
1203
1531
  useRAGCitations,
1532
+ useRAGChunkPreview,
1204
1533
  useRAG,
1205
1534
  useAIStream,
1206
1535
  AIStreamProvider
1207
1536
  };
1208
1537
 
1209
- //# debugId=D0ADC407D5CCE73D64756E2164756E21
1538
+ //# debugId=55AD95E07D2CA2EF64756E2164756E21
1210
1539
  //# sourceMappingURL=index.js.map