@absolutejs/absolute 0.19.0-beta.435 → 0.19.0-beta.437

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 +60 -1
  2. package/dist/ai/client/index.js.map +3 -3
  3. package/dist/ai/index.js +199 -2
  4. package/dist/ai/index.js.map +4 -4
  5. package/dist/ai-client/angular/ai/index.js +59 -0
  6. package/dist/ai-client/react/ai/index.js +346 -126
  7. package/dist/ai-client/vue/ai/index.js +59 -0
  8. package/dist/angular/ai/index.js +60 -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 +600 -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 +7 -1
  25. package/dist/src/ai/rag/chat.d.ts +120 -2
  26. package/dist/src/react/ai/index.d.ts +3 -0
  27. package/dist/src/react/ai/useRAG.d.ts +31 -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 +16 -0
  31. package/dist/svelte/ai/index.js +60 -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 +73 -0
  36. package/dist/vue/ai/index.js +60 -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,334 @@ 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 documentChunks(id) {
818
+ const response = await fetchImpl(`${basePath}/documents/${encodeURIComponent(id)}/chunks`);
819
+ if (!response.ok) {
820
+ const error = await toErrorMessage(response);
821
+ return { ok: false, error };
822
+ }
823
+ return parseJson(response);
824
+ },
825
+ async deleteDocument(id) {
826
+ const response = await fetchImpl(`${basePath}/documents/${encodeURIComponent(id)}`, {
827
+ method: "DELETE"
828
+ });
829
+ if (!response.ok) {
830
+ return {
831
+ ok: false,
832
+ error: await toErrorMessage(response)
833
+ };
834
+ }
835
+ return parseJson(response);
836
+ },
837
+ async reseed() {
838
+ const response = await fetchImpl(`${basePath}/reseed`, {
839
+ method: "POST"
840
+ });
841
+ if (!response.ok) {
842
+ return {
843
+ ok: false,
844
+ error: await toErrorMessage(response)
845
+ };
846
+ }
847
+ return parseJson(response);
848
+ },
849
+ async reset() {
850
+ const response = await fetchImpl(`${basePath}/reset`, {
851
+ method: "POST"
852
+ });
853
+ if (!response.ok) {
854
+ return {
855
+ ok: false,
856
+ error: await toErrorMessage(response)
857
+ };
858
+ }
859
+ return parseJson(response);
860
+ },
861
+ async backends() {
862
+ const response = await fetchImpl(`${basePath}/backends`);
863
+ if (!response.ok) {
864
+ throw new Error(await toErrorMessage(response));
865
+ }
866
+ return parseJson(response);
867
+ },
868
+ async clearIndex() {
869
+ const response = await fetchImpl(`${basePath}/index`, {
870
+ method: "DELETE"
871
+ });
872
+ if (!response.ok) {
873
+ throw new Error(await toErrorMessage(response));
874
+ }
875
+ return parseJson(response);
876
+ }
877
+ };
878
+ };
879
+ // src/react/ai/AIStreamProvider.tsx
880
+ import {
881
+ createContext,
882
+ useContext,
883
+ useEffect,
884
+ useRef
885
+ } from "react";
886
+ import { jsxDEV } from "react/jsx-dev-runtime";
887
+ var AIStreamContext = createContext(null);
888
+ var AIStreamProvider = ({
889
+ children,
890
+ path
891
+ }) => {
892
+ const ref = useRef(null);
893
+ if (!ref.current) {
894
+ const connection = createAIConnection(path);
895
+ const store = createAIMessageStore();
896
+ ref.current = { connection, store };
897
+ }
898
+ useEffect(() => {
899
+ const { current } = ref;
900
+ if (!current) {
901
+ return;
902
+ }
903
+ const { connection, store } = current;
904
+ const unsubscribe = connection.subscribe((msg) => {
905
+ const action = serverMessageToAction(msg);
906
+ if (action) {
907
+ store.dispatch(action);
908
+ }
909
+ });
910
+ return () => {
911
+ unsubscribe();
912
+ connection.close();
913
+ };
914
+ }, []);
915
+ return /* @__PURE__ */ jsxDEV(AIStreamContext.Provider, {
916
+ value: ref.current,
917
+ children
918
+ }, undefined, false, undefined, this);
919
+ };
920
+ var useAIStreamContext = () => useContext(AIStreamContext);
921
+ // src/react/ai/useAIStream.ts
922
+ import { useCallback, useEffect as useEffect2, useRef as useRef2, useSyncExternalStore } from "react";
923
+ var useAIStream = (path, conversationId) => {
924
+ const context = useAIStreamContext();
925
+ const standaloneRef = useRef2(null);
926
+ const isStandalone = !context;
927
+ if (isStandalone && !standaloneRef.current && path) {
928
+ const connection2 = createAIConnection(path);
929
+ const store2 = createAIMessageStore();
930
+ standaloneRef.current = { connection: connection2, store: store2 };
931
+ }
932
+ const resolved = context ?? standaloneRef.current;
933
+ if (!resolved) {
934
+ throw new Error("useAIStream requires either an AIStreamProvider or a path argument");
935
+ }
936
+ const { connection, store } = resolved;
937
+ useEffect2(() => {
938
+ if (!isStandalone) {
939
+ return;
940
+ }
941
+ const unsubscribe = connection.subscribe((msg) => {
942
+ const action = serverMessageToAction(msg);
943
+ if (action) {
944
+ store.dispatch(action);
945
+ }
946
+ });
947
+ return () => {
948
+ unsubscribe();
949
+ connection.close();
950
+ };
951
+ }, [connection, isStandalone, store]);
952
+ const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);
953
+ const activeConvId = conversationId ?? state.activeConversationId;
954
+ const conversation = activeConvId ? state.conversations.get(activeConvId) : undefined;
955
+ const messages = conversation?.messages ?? [];
956
+ const send = useCallback((content, attachments) => {
957
+ const convId = activeConvId ?? generateId();
958
+ const msgId = generateId();
959
+ store.dispatch({
960
+ attachments,
961
+ content,
962
+ conversationId: convId,
963
+ messageId: msgId,
964
+ type: "send"
965
+ });
966
+ connection.send({
967
+ attachments,
968
+ content,
969
+ conversationId: convId,
970
+ type: "message"
971
+ });
972
+ }, [activeConvId, connection, store]);
973
+ const cancel = useCallback(() => {
974
+ if (activeConvId) {
975
+ store.dispatch({ type: "cancel" });
976
+ connection.send({ conversationId: activeConvId, type: "cancel" });
977
+ }
978
+ }, [activeConvId, connection, store]);
979
+ const branch = useCallback((messageId, content) => {
980
+ if (activeConvId) {
981
+ connection.send({
982
+ content,
983
+ conversationId: activeConvId,
984
+ messageId,
985
+ type: "branch"
986
+ });
987
+ }
988
+ }, [activeConvId, connection]);
989
+ return {
990
+ branch,
991
+ cancel,
992
+ error: state.error,
993
+ isStreaming: state.isStreaming,
994
+ messages,
995
+ send
996
+ };
997
+ };
998
+ // src/react/ai/useRAGChunkPreview.ts
999
+ import { useCallback as useCallback2, useMemo, useState } from "react";
1000
+ var useRAGChunkPreview = (path) => {
1001
+ const client = useMemo(() => createRAGClient({ path }), [path]);
1002
+ const [preview, setPreview] = useState(null);
1003
+ const [isLoading, setIsLoading] = useState(false);
1004
+ const [error, setError] = useState(null);
1005
+ const inspect = useCallback2(async (id) => {
1006
+ setIsLoading(true);
1007
+ setError(null);
1008
+ try {
1009
+ const response = await client.documentChunks(id);
1010
+ if (!response.ok) {
1011
+ throw new Error(response.error);
1012
+ }
1013
+ setPreview(response);
1014
+ return response;
1015
+ } catch (err) {
1016
+ const message = err instanceof Error ? err.message : "Failed to load RAG chunk preview";
1017
+ setError(message);
1018
+ throw err;
1019
+ } finally {
1020
+ setIsLoading(false);
1021
+ }
1022
+ }, [client]);
1023
+ const clear = useCallback2(() => {
1024
+ setPreview(null);
1025
+ setError(null);
1026
+ setIsLoading(false);
1027
+ }, []);
1028
+ return {
1029
+ clear,
1030
+ error,
1031
+ inspect,
1032
+ isLoading,
1033
+ preview
1034
+ };
1035
+ };
1036
+ // src/react/ai/useRAG.ts
1037
+ import { useMemo as useMemo10 } from "react";
1038
+
1039
+ // src/react/ai/useRAGCitations.ts
1040
+ import { useMemo as useMemo2 } from "react";
774
1041
 
775
1042
  // src/ai/rag/presentation.ts
776
1043
  var buildSourceGroupKey = (source) => source.source ?? source.title ?? source.chunkId;
@@ -864,8 +1131,8 @@ var resolveRAGStreamStage = ({
864
1131
 
865
1132
  // src/react/ai/useRAGCitations.ts
866
1133
  var useRAGCitations = (sources) => {
867
- const citations = useMemo(() => buildRAGCitations(sources), [sources]);
868
- const sourceGroups = useMemo(() => buildRAGSourceGroups(sources), [sources]);
1134
+ const citations = useMemo2(() => buildRAGCitations(sources), [sources]);
1135
+ const sourceGroups = useMemo2(() => buildRAGSourceGroups(sources), [sources]);
869
1136
  return {
870
1137
  citations,
871
1138
  hasCitations: citations.length > 0,
@@ -873,102 +1140,56 @@ var useRAGCitations = (sources) => {
873
1140
  };
874
1141
  };
875
1142
 
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;
1143
+ // src/react/ai/useRAGDocuments.ts
1144
+ import { useCallback as useCallback3, useMemo as useMemo3, useState as useState2 } from "react";
1145
+ var useRAGDocuments = (path) => {
1146
+ const client = useMemo3(() => createRAGClient({ path }), [path]);
1147
+ const [documents, setDocuments] = useState2([]);
1148
+ const [isLoading, setIsLoading] = useState2(false);
1149
+ const [error, setError] = useState2(null);
1150
+ const [lastResponse, setLastResponse] = useState2(null);
1151
+ const load = useCallback3(async (kind) => {
1152
+ setIsLoading(true);
1153
+ setError(null);
1154
+ try {
1155
+ const response = await client.documents(kind);
1156
+ setDocuments(response.documents);
1157
+ setLastResponse(response);
1158
+ return response;
1159
+ } catch (err) {
1160
+ const message = err instanceof Error ? err.message : "Failed to load RAG documents";
1161
+ setError(message);
1162
+ throw err;
1163
+ } finally {
1164
+ setIsLoading(false);
893
1165
  }
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;
1166
+ }, [client]);
1167
+ const reset = useCallback3(() => {
1168
+ setDocuments([]);
1169
+ setError(null);
1170
+ setLastResponse(null);
1171
+ setIsLoading(false);
1172
+ }, []);
900
1173
  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
- }
1174
+ documents,
1175
+ error,
1176
+ isLoading,
1177
+ lastResponse,
1178
+ load,
1179
+ reset
960
1180
  };
961
1181
  };
962
1182
 
963
1183
  // src/react/ai/useRAGIngest.ts
1184
+ import { useCallback as useCallback4, useMemo as useMemo4, useState as useState3 } from "react";
964
1185
  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) => {
1186
+ const client = useMemo4(() => createRAGClient({ path }), [path]);
1187
+ const [error, setError] = useState3(null);
1188
+ const [isIngesting, setIsIngesting] = useState3(false);
1189
+ const [lastIngestCount, setLastIngestCount] = useState3(null);
1190
+ const [lastDocumentCount, setLastDocumentCount] = useState3(null);
1191
+ const [lastResponse, setLastResponse] = useState3(null);
1192
+ const ingestChunks = useCallback4(async (chunks) => {
972
1193
  setIsIngesting(true);
973
1194
  setError(null);
974
1195
  try {
@@ -988,7 +1209,7 @@ var useRAGIngest = (path) => {
988
1209
  setIsIngesting(false);
989
1210
  }
990
1211
  }, [client]);
991
- const ingestDocuments = useCallback2(async (input) => {
1212
+ const ingestDocuments = useCallback4(async (input) => {
992
1213
  setIsIngesting(true);
993
1214
  setError(null);
994
1215
  try {
@@ -1008,7 +1229,7 @@ var useRAGIngest = (path) => {
1008
1229
  setIsIngesting(false);
1009
1230
  }
1010
1231
  }, [client]);
1011
- const clearIndex = useCallback2(async () => {
1232
+ const clearIndex = useCallback4(async () => {
1012
1233
  setIsIngesting(true);
1013
1234
  setError(null);
1014
1235
  try {
@@ -1024,7 +1245,7 @@ var useRAGIngest = (path) => {
1024
1245
  setIsIngesting(false);
1025
1246
  }
1026
1247
  }, [client]);
1027
- const reset = useCallback2(() => {
1248
+ const reset = useCallback4(() => {
1028
1249
  setError(null);
1029
1250
  setLastDocumentCount(null);
1030
1251
  setLastIngestCount(null);
@@ -1044,16 +1265,92 @@ var useRAGIngest = (path) => {
1044
1265
  };
1045
1266
  };
1046
1267
 
1268
+ // src/react/ai/useRAGIndexAdmin.ts
1269
+ import { useCallback as useCallback5, useMemo as useMemo5, useState as useState4 } from "react";
1270
+ var useRAGIndexAdmin = (path) => {
1271
+ const client = useMemo5(() => createRAGClient({ path }), [path]);
1272
+ const [isLoading, setIsLoading] = useState4(false);
1273
+ const [error, setError] = useState4(null);
1274
+ const [lastMutation, setLastMutation] = useState4(null);
1275
+ const [backends, setBackends] = useState4(null);
1276
+ const run = useCallback5(async (operation) => {
1277
+ setIsLoading(true);
1278
+ setError(null);
1279
+ try {
1280
+ return await operation();
1281
+ } catch (err) {
1282
+ const message = err instanceof Error ? err.message : "RAG index administration failed";
1283
+ setError(message);
1284
+ throw err;
1285
+ } finally {
1286
+ setIsLoading(false);
1287
+ }
1288
+ }, []);
1289
+ const deleteDocument = useCallback5(async (id) => run(async () => {
1290
+ const response = await client.deleteDocument(id);
1291
+ setLastMutation(response);
1292
+ if (!response.ok) {
1293
+ throw new Error(response.error ?? "Failed to delete document");
1294
+ }
1295
+ return response;
1296
+ }), [client, run]);
1297
+ const reseed = useCallback5(async () => run(async () => {
1298
+ const response = await client.reseed();
1299
+ setLastMutation(response);
1300
+ if (!response.ok) {
1301
+ throw new Error(response.error ?? "Failed to reseed index");
1302
+ }
1303
+ return response;
1304
+ }), [client, run]);
1305
+ const reset = useCallback5(async () => run(async () => {
1306
+ const response = await client.reset();
1307
+ setLastMutation(response);
1308
+ if (!response.ok) {
1309
+ throw new Error(response.error ?? "Failed to reset index");
1310
+ }
1311
+ return response;
1312
+ }), [client, run]);
1313
+ const loadBackends = useCallback5(async () => run(async () => {
1314
+ const response = await client.backends();
1315
+ setBackends(response);
1316
+ return response;
1317
+ }), [client, run]);
1318
+ const clearIndex = useCallback5(async () => run(async () => {
1319
+ const response = await client.clearIndex();
1320
+ const mutation = { ok: response.ok };
1321
+ setLastMutation(mutation);
1322
+ return mutation;
1323
+ }), [client, run]);
1324
+ const resetState = useCallback5(() => {
1325
+ setIsLoading(false);
1326
+ setError(null);
1327
+ setLastMutation(null);
1328
+ setBackends(null);
1329
+ }, []);
1330
+ return {
1331
+ backends,
1332
+ clearIndex,
1333
+ deleteDocument,
1334
+ error,
1335
+ isLoading,
1336
+ lastMutation,
1337
+ loadBackends,
1338
+ reseed,
1339
+ reset,
1340
+ resetState
1341
+ };
1342
+ };
1343
+
1047
1344
  // src/react/ai/useRAGSearch.ts
1048
- import { useCallback as useCallback3, useMemo as useMemo3, useState as useState2 } from "react";
1345
+ import { useCallback as useCallback6, useMemo as useMemo6, useState as useState5 } from "react";
1049
1346
  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) => {
1347
+ const client = useMemo6(() => createRAGClient({ path }), [path]);
1348
+ const [results, setResults] = useState5([]);
1349
+ const [error, setError] = useState5(null);
1350
+ const [isSearching, setIsSearching] = useState5(false);
1351
+ const [hasSearched, setHasSearched] = useState5(false);
1352
+ const [lastRequest, setLastRequest] = useState5(null);
1353
+ const search = useCallback6(async (input) => {
1057
1354
  setIsSearching(true);
1058
1355
  setError(null);
1059
1356
  setLastRequest(input);
@@ -1070,7 +1367,7 @@ var useRAGSearch = (path) => {
1070
1367
  setIsSearching(false);
1071
1368
  }
1072
1369
  }, [client]);
1073
- const reset = useCallback3(() => {
1370
+ const reset = useCallback6(() => {
1074
1371
  setError(null);
1075
1372
  setHasSearched(false);
1076
1373
  setLastRequest(null);
@@ -1089,11 +1386,11 @@ var useRAGSearch = (path) => {
1089
1386
  };
1090
1387
 
1091
1388
  // src/react/ai/useRAGSources.ts
1092
- import { useMemo as useMemo4 } from "react";
1389
+ import { useMemo as useMemo7 } from "react";
1093
1390
  var useRAGSources = (messages) => {
1094
- const latestAssistantMessage = useMemo4(() => getLatestAssistantMessage(messages), [messages]);
1095
- const sources = useMemo4(() => getLatestRAGSources(messages), [messages]);
1096
- const sourceGroups = useMemo4(() => buildRAGSourceGroups(sources), [sources]);
1391
+ const latestAssistantMessage = useMemo7(() => getLatestAssistantMessage(messages), [messages]);
1392
+ const sources = useMemo7(() => getLatestRAGSources(messages), [messages]);
1393
+ const sourceGroups = useMemo7(() => buildRAGSourceGroups(sources), [sources]);
1097
1394
  return {
1098
1395
  hasSources: sources.length > 0,
1099
1396
  latestAssistantMessage,
@@ -1103,14 +1400,14 @@ var useRAGSources = (messages) => {
1103
1400
  };
1104
1401
 
1105
1402
  // src/react/ai/useRAGStatus.ts
1106
- import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo5, useState as useState3 } from "react";
1403
+ import { useCallback as useCallback7, useEffect as useEffect3, useMemo as useMemo8, useState as useState6 } from "react";
1107
1404
  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 () => {
1405
+ const client = useMemo8(() => createRAGClient({ path }), [path]);
1406
+ const [status, setStatus] = useState6();
1407
+ const [capabilities, setCapabilities] = useState6();
1408
+ const [error, setError] = useState6(null);
1409
+ const [isLoading, setIsLoading] = useState6(autoLoad);
1410
+ const refresh = useCallback7(async () => {
1114
1411
  setIsLoading(true);
1115
1412
  setError(null);
1116
1413
  try {
@@ -1126,7 +1423,7 @@ var useRAGStatus = (path, autoLoad = true) => {
1126
1423
  setIsLoading(false);
1127
1424
  }
1128
1425
  }, [client]);
1129
- const reset = useCallback4(() => {
1426
+ const reset = useCallback7(() => {
1130
1427
  setCapabilities(undefined);
1131
1428
  setError(null);
1132
1429
  setIsLoading(false);
@@ -1150,19 +1447,19 @@ var useRAGStatus = (path, autoLoad = true) => {
1150
1447
  };
1151
1448
 
1152
1449
  // src/react/ai/useRAGStream.ts
1153
- import { useCallback as useCallback5, useMemo as useMemo6 } from "react";
1450
+ import { useCallback as useCallback8, useMemo as useMemo9 } from "react";
1154
1451
  var useRAGStream = (path, conversationId) => {
1155
1452
  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({
1453
+ const latestAssistantMessage = useMemo9(() => getLatestAssistantMessage(stream.messages), [stream.messages]);
1454
+ const sources = useMemo9(() => getLatestRAGSources(stream.messages), [stream.messages]);
1455
+ const sourceGroups = useMemo9(() => buildRAGSourceGroups(sources), [sources]);
1456
+ const citations = useMemo9(() => buildRAGCitations(sources), [sources]);
1457
+ const stage = useMemo9(() => resolveRAGStreamStage({
1161
1458
  error: stream.error,
1162
1459
  isStreaming: stream.isStreaming,
1163
1460
  messages: stream.messages
1164
1461
  }), [stream.error, stream.isStreaming, stream.messages]);
1165
- const query = useCallback5((content, attachments) => {
1462
+ const query = useCallback8((content, attachments) => {
1166
1463
  stream.send(content, attachments);
1167
1464
  }, [stream]);
1168
1465
  return {
@@ -1182,17 +1479,23 @@ var useRAG = (path, options = {}) => {
1182
1479
  const search = useRAGSearch(path);
1183
1480
  const ingest = useRAGIngest(path);
1184
1481
  const status = useRAGStatus(path, options.autoLoadStatus ?? true);
1482
+ const documents = useRAGDocuments(path);
1483
+ const chunkPreview = useRAGChunkPreview(path);
1484
+ const index = useRAGIndexAdmin(path);
1185
1485
  const stream = useRAGStream(options.streamPath ?? path, options.conversationId);
1186
1486
  const sources = useRAGSources(stream.messages);
1187
1487
  const citations = useRAGCitations(sources.sources);
1188
- return useMemo7(() => ({
1488
+ return useMemo10(() => ({
1189
1489
  citations,
1490
+ chunkPreview,
1491
+ documents,
1190
1492
  ingest,
1493
+ index,
1191
1494
  search,
1192
1495
  sources,
1193
1496
  status,
1194
1497
  stream
1195
- }), [citations, ingest, search, sources, status, stream]);
1498
+ }), [citations, chunkPreview, documents, ingest, index, search, sources, status, stream]);
1196
1499
  };
1197
1500
  export {
1198
1501
  useRAGStream,
@@ -1200,11 +1503,14 @@ export {
1200
1503
  useRAGSources,
1201
1504
  useRAGSearch,
1202
1505
  useRAGIngest,
1506
+ useRAGIndexAdmin,
1507
+ useRAGDocuments,
1203
1508
  useRAGCitations,
1509
+ useRAGChunkPreview,
1204
1510
  useRAG,
1205
1511
  useAIStream,
1206
1512
  AIStreamProvider
1207
1513
  };
1208
1514
 
1209
- //# debugId=D0ADC407D5CCE73D64756E2164756E21
1515
+ //# debugId=1512F3E572D165FB64756E2164756E21
1210
1516
  //# sourceMappingURL=index.js.map