@paymanai/payman-typescript-ask-sdk 1.2.4 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +186 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +187 -8
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +191 -7
- package/dist/index.native.js.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useRef,
|
|
1
|
+
import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
2
2
|
|
|
3
3
|
// src/hooks/useChat.ts
|
|
4
4
|
|
|
@@ -160,6 +160,8 @@ function getEventMessage(event) {
|
|
|
160
160
|
return event.workerName ? `${event.workerName} thinking...` : "Thinking...";
|
|
161
161
|
case "INTENT_THINKING_CONT":
|
|
162
162
|
return event.message || "";
|
|
163
|
+
case "KEEP_ALIVE":
|
|
164
|
+
return "";
|
|
163
165
|
default:
|
|
164
166
|
return eventType;
|
|
165
167
|
}
|
|
@@ -196,6 +198,9 @@ function completeLastInProgressStep(steps) {
|
|
|
196
198
|
}
|
|
197
199
|
function processStreamEvent(event, state) {
|
|
198
200
|
const eventType = event.eventType;
|
|
201
|
+
if (typeof eventType === "string" && eventType.toUpperCase() === "KEEP_ALIVE") {
|
|
202
|
+
return state;
|
|
203
|
+
}
|
|
199
204
|
const message = getEventMessage(event);
|
|
200
205
|
if (eventType !== "INTENT_THINKING" && eventType !== "INTENT_THINKING_CONT") {
|
|
201
206
|
if (state.currentThinkingStepId) {
|
|
@@ -612,6 +617,84 @@ async function cancelUserAction(config, userActionId) {
|
|
|
612
617
|
async function resendUserAction(config, userActionId) {
|
|
613
618
|
return sendUserActionRequest(config, userActionId, "resend");
|
|
614
619
|
}
|
|
620
|
+
|
|
621
|
+
// src/utils/chatStore.ts
|
|
622
|
+
var memoryStore = /* @__PURE__ */ new Map();
|
|
623
|
+
var chatStore = {
|
|
624
|
+
get(key) {
|
|
625
|
+
return memoryStore.get(key) ?? [];
|
|
626
|
+
},
|
|
627
|
+
set(key, messages) {
|
|
628
|
+
memoryStore.set(key, messages);
|
|
629
|
+
},
|
|
630
|
+
delete(key) {
|
|
631
|
+
memoryStore.delete(key);
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
// src/utils/activeStreamStore.ts
|
|
636
|
+
var streams = /* @__PURE__ */ new Map();
|
|
637
|
+
var activeStreamStore = {
|
|
638
|
+
has(key) {
|
|
639
|
+
return streams.has(key);
|
|
640
|
+
},
|
|
641
|
+
get(key) {
|
|
642
|
+
const entry = streams.get(key);
|
|
643
|
+
if (!entry) return null;
|
|
644
|
+
return { messages: entry.messages, isWaiting: entry.isWaiting };
|
|
645
|
+
},
|
|
646
|
+
// Called before startStream — registers the controller and initial messages
|
|
647
|
+
start(key, abortController, initialMessages) {
|
|
648
|
+
const existing = streams.get(key);
|
|
649
|
+
streams.set(key, {
|
|
650
|
+
messages: initialMessages,
|
|
651
|
+
isWaiting: true,
|
|
652
|
+
abortController,
|
|
653
|
+
listeners: existing?.listeners ?? /* @__PURE__ */ new Set()
|
|
654
|
+
});
|
|
655
|
+
},
|
|
656
|
+
// Called by the stream on every event — applies the same updater pattern React uses
|
|
657
|
+
applyMessages(key, updater) {
|
|
658
|
+
const entry = streams.get(key);
|
|
659
|
+
if (!entry) return;
|
|
660
|
+
const next = typeof updater === "function" ? updater(entry.messages) : updater;
|
|
661
|
+
entry.messages = next;
|
|
662
|
+
entry.listeners.forEach((l) => l(next, entry.isWaiting));
|
|
663
|
+
},
|
|
664
|
+
setWaiting(key, waiting) {
|
|
665
|
+
const entry = streams.get(key);
|
|
666
|
+
if (!entry) return;
|
|
667
|
+
entry.isWaiting = waiting;
|
|
668
|
+
entry.listeners.forEach((l) => l(entry.messages, waiting));
|
|
669
|
+
},
|
|
670
|
+
// Called when stream completes — persists to chatStore and cleans up
|
|
671
|
+
complete(key) {
|
|
672
|
+
const entry = streams.get(key);
|
|
673
|
+
if (!entry) return;
|
|
674
|
+
entry.isWaiting = false;
|
|
675
|
+
entry.listeners.forEach((l) => l(entry.messages, false));
|
|
676
|
+
const toSave = entry.messages.filter((m) => !m.isStreaming);
|
|
677
|
+
if (toSave.length > 0) chatStore.set(key, toSave);
|
|
678
|
+
streams.delete(key);
|
|
679
|
+
},
|
|
680
|
+
// Subscribe — returns unsubscribe fn. Component calls this on mount, cleanup on unmount.
|
|
681
|
+
subscribe(key, listener) {
|
|
682
|
+
const entry = streams.get(key);
|
|
683
|
+
if (!entry) return () => {
|
|
684
|
+
};
|
|
685
|
+
entry.listeners.add(listener);
|
|
686
|
+
return () => {
|
|
687
|
+
streams.get(key)?.listeners.delete(listener);
|
|
688
|
+
};
|
|
689
|
+
},
|
|
690
|
+
// Explicit user cancel — aborts the controller and removes the entry
|
|
691
|
+
abort(key) {
|
|
692
|
+
const entry = streams.get(key);
|
|
693
|
+
if (!entry) return;
|
|
694
|
+
entry.abortController.abort();
|
|
695
|
+
streams.delete(key);
|
|
696
|
+
}
|
|
697
|
+
};
|
|
615
698
|
function useStreamManager(config, callbacks, setMessages, setIsWaitingForResponse) {
|
|
616
699
|
const abortControllerRef = useRef(null);
|
|
617
700
|
const configRef = useRef(config);
|
|
@@ -619,9 +702,9 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
619
702
|
const callbacksRef = useRef(callbacks);
|
|
620
703
|
callbacksRef.current = callbacks;
|
|
621
704
|
const startStream = useCallback(
|
|
622
|
-
async (userMessage, streamingId, sessionId) => {
|
|
705
|
+
async (userMessage, streamingId, sessionId, externalAbortController) => {
|
|
623
706
|
abortControllerRef.current?.abort();
|
|
624
|
-
const abortController = new AbortController();
|
|
707
|
+
const abortController = externalAbortController ?? new AbortController();
|
|
625
708
|
abortControllerRef.current = abortController;
|
|
626
709
|
const state = {
|
|
627
710
|
accumulatedContent: "",
|
|
@@ -700,6 +783,11 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
700
783
|
if (abortController.signal.aborted) {
|
|
701
784
|
return;
|
|
702
785
|
}
|
|
786
|
+
if (typeof event.eventType === "string" && event.eventType.toUpperCase() === "KEEP_ALIVE") {
|
|
787
|
+
if (event.executionId) state.executionId = event.executionId;
|
|
788
|
+
if (event.sessionId) state.currentSessionId = event.sessionId;
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
703
791
|
if (event.executionId) state.executionId = event.executionId;
|
|
704
792
|
if (event.sessionId) state.currentSessionId = event.sessionId;
|
|
705
793
|
const activeThinkingLengthBeforeProcess = state.activeThinkingText?.length ?? 0;
|
|
@@ -825,13 +913,43 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
825
913
|
|
|
826
914
|
// src/hooks/useChat.ts
|
|
827
915
|
function useChat(config, callbacks = {}) {
|
|
828
|
-
const [messages, setMessages] = useState(
|
|
916
|
+
const [messages, setMessages] = useState(() => {
|
|
917
|
+
if (config.userId) return chatStore.get(config.userId);
|
|
918
|
+
return config.initialMessages ?? [];
|
|
919
|
+
});
|
|
829
920
|
const [isWaitingForResponse, setIsWaitingForResponse] = useState(false);
|
|
830
|
-
const sessionIdRef = useRef(
|
|
921
|
+
const sessionIdRef = useRef(
|
|
922
|
+
config.userId ? chatStore.get(config.userId).find((m) => m.sessionId)?.sessionId ?? config.initialSessionId ?? void 0 : config.initialSessionId ?? void 0
|
|
923
|
+
);
|
|
924
|
+
const prevUserIdRef = useRef(config.userId);
|
|
831
925
|
const callbacksRef = useRef(callbacks);
|
|
832
926
|
callbacksRef.current = callbacks;
|
|
833
927
|
const configRef = useRef(config);
|
|
834
928
|
configRef.current = config;
|
|
929
|
+
const messagesRef = useRef(messages);
|
|
930
|
+
messagesRef.current = messages;
|
|
931
|
+
const storeAwareSetMessages = useCallback(
|
|
932
|
+
(updater) => {
|
|
933
|
+
const { userId } = configRef.current;
|
|
934
|
+
if (userId && activeStreamStore.has(userId)) {
|
|
935
|
+
activeStreamStore.applyMessages(userId, updater);
|
|
936
|
+
}
|
|
937
|
+
setMessages(updater);
|
|
938
|
+
},
|
|
939
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
940
|
+
[]
|
|
941
|
+
);
|
|
942
|
+
const storeAwareSetIsWaiting = useCallback(
|
|
943
|
+
(waiting) => {
|
|
944
|
+
const { userId } = configRef.current;
|
|
945
|
+
if (userId && activeStreamStore.has(userId)) {
|
|
946
|
+
activeStreamStore.setWaiting(userId, waiting);
|
|
947
|
+
}
|
|
948
|
+
setIsWaitingForResponse(waiting);
|
|
949
|
+
},
|
|
950
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
951
|
+
[]
|
|
952
|
+
);
|
|
835
953
|
const [userActionState, setUserActionState] = useState({
|
|
836
954
|
request: null,
|
|
837
955
|
result: null,
|
|
@@ -874,8 +992,8 @@ function useChat(config, callbacks = {}) {
|
|
|
874
992
|
const { startStream, cancelStream: cancelStreamManager, abortControllerRef } = useStreamManager(
|
|
875
993
|
config,
|
|
876
994
|
wrappedCallbacks,
|
|
877
|
-
|
|
878
|
-
|
|
995
|
+
storeAwareSetMessages,
|
|
996
|
+
storeAwareSetIsWaiting
|
|
879
997
|
);
|
|
880
998
|
const sendMessage = useCallback(
|
|
881
999
|
async (userMessage) => {
|
|
@@ -912,11 +1030,21 @@ function useChat(config, callbacks = {}) {
|
|
|
912
1030
|
currentMessage: void 0
|
|
913
1031
|
};
|
|
914
1032
|
setMessages((prev) => [...prev, streamingMsg]);
|
|
1033
|
+
const abortController = new AbortController();
|
|
1034
|
+
const { userId } = configRef.current;
|
|
1035
|
+
if (userId) {
|
|
1036
|
+
const initialMessages = [...messagesRef.current, userMsg, streamingMsg];
|
|
1037
|
+
activeStreamStore.start(userId, abortController, initialMessages);
|
|
1038
|
+
}
|
|
915
1039
|
const newSessionId = await startStream(
|
|
916
1040
|
userMessage,
|
|
917
1041
|
streamingId,
|
|
918
|
-
sessionIdRef.current
|
|
1042
|
+
sessionIdRef.current,
|
|
1043
|
+
abortController
|
|
919
1044
|
);
|
|
1045
|
+
if (userId) {
|
|
1046
|
+
activeStreamStore.complete(userId);
|
|
1047
|
+
}
|
|
920
1048
|
if (newSessionId && newSessionId !== sessionIdRef.current) {
|
|
921
1049
|
sessionIdRef.current = newSessionId;
|
|
922
1050
|
}
|
|
@@ -924,9 +1052,18 @@ function useChat(config, callbacks = {}) {
|
|
|
924
1052
|
[startStream]
|
|
925
1053
|
);
|
|
926
1054
|
const clearMessages = useCallback(() => {
|
|
1055
|
+
if (configRef.current.userId) {
|
|
1056
|
+
chatStore.delete(configRef.current.userId);
|
|
1057
|
+
}
|
|
927
1058
|
setMessages([]);
|
|
928
1059
|
}, []);
|
|
1060
|
+
const prependMessages = useCallback((msgs) => {
|
|
1061
|
+
setMessages((prev) => [...msgs, ...prev]);
|
|
1062
|
+
}, []);
|
|
929
1063
|
const cancelStream = useCallback(() => {
|
|
1064
|
+
if (configRef.current.userId) {
|
|
1065
|
+
activeStreamStore.abort(configRef.current.userId);
|
|
1066
|
+
}
|
|
930
1067
|
cancelStreamManager();
|
|
931
1068
|
setIsWaitingForResponse(false);
|
|
932
1069
|
setUserActionState((prev) => ({ ...prev, request: null, result: null }));
|
|
@@ -946,6 +1083,10 @@ function useChat(config, callbacks = {}) {
|
|
|
946
1083
|
);
|
|
947
1084
|
}, [cancelStreamManager]);
|
|
948
1085
|
const resetSession = useCallback(() => {
|
|
1086
|
+
if (configRef.current.userId) {
|
|
1087
|
+
activeStreamStore.abort(configRef.current.userId);
|
|
1088
|
+
chatStore.delete(configRef.current.userId);
|
|
1089
|
+
}
|
|
949
1090
|
setMessages([]);
|
|
950
1091
|
sessionIdRef.current = void 0;
|
|
951
1092
|
abortControllerRef.current?.abort();
|
|
@@ -1008,10 +1149,48 @@ function useChat(config, callbacks = {}) {
|
|
|
1008
1149
|
throw error;
|
|
1009
1150
|
}
|
|
1010
1151
|
}, []);
|
|
1152
|
+
useEffect(() => {
|
|
1153
|
+
const { userId } = config;
|
|
1154
|
+
if (!userId) return;
|
|
1155
|
+
const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting) => {
|
|
1156
|
+
setMessages(msgs);
|
|
1157
|
+
setIsWaitingForResponse(isWaiting);
|
|
1158
|
+
});
|
|
1159
|
+
const active = activeStreamStore.get(userId);
|
|
1160
|
+
if (active) {
|
|
1161
|
+
setMessages(active.messages);
|
|
1162
|
+
setIsWaitingForResponse(active.isWaiting);
|
|
1163
|
+
}
|
|
1164
|
+
return unsubscribe;
|
|
1165
|
+
}, []);
|
|
1166
|
+
useEffect(() => {
|
|
1167
|
+
if (!config.userId) return;
|
|
1168
|
+
const toSave = messages.filter((m) => !m.isStreaming);
|
|
1169
|
+
if (toSave.length > 0) {
|
|
1170
|
+
chatStore.set(config.userId, toSave);
|
|
1171
|
+
}
|
|
1172
|
+
}, [messages, config.userId]);
|
|
1173
|
+
useEffect(() => {
|
|
1174
|
+
const prevUserId = prevUserIdRef.current;
|
|
1175
|
+
prevUserIdRef.current = config.userId;
|
|
1176
|
+
if (prevUserId === config.userId) return;
|
|
1177
|
+
if (prevUserId && !config.userId) {
|
|
1178
|
+
chatStore.delete(prevUserId);
|
|
1179
|
+
setMessages([]);
|
|
1180
|
+
sessionIdRef.current = void 0;
|
|
1181
|
+
setIsWaitingForResponse(false);
|
|
1182
|
+
setUserActionState({ request: null, result: null, clearOtpTrigger: 0 });
|
|
1183
|
+
} else if (config.userId) {
|
|
1184
|
+
const stored = chatStore.get(config.userId);
|
|
1185
|
+
setMessages(stored);
|
|
1186
|
+
sessionIdRef.current = stored.find((m) => m.sessionId)?.sessionId;
|
|
1187
|
+
}
|
|
1188
|
+
}, [config.userId]);
|
|
1011
1189
|
return {
|
|
1012
1190
|
messages,
|
|
1013
1191
|
sendMessage,
|
|
1014
1192
|
clearMessages,
|
|
1193
|
+
prependMessages,
|
|
1015
1194
|
cancelStream,
|
|
1016
1195
|
resetSession,
|
|
1017
1196
|
getSessionId,
|