@gooddata/sdk-ui-gen-ai 11.57.0 → 11.58.0-alpha.1
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/NOTICE +2321 -1760
- package/esm/components/GenAIChatDialogConnected.d.ts +1 -2
- package/esm/components/GenAIChatDialogConnected.d.ts.map +1 -1
- package/esm/components/GenAIChatDialogConnected.js +3 -9
- package/esm/components/Input.d.ts.map +1 -1
- package/esm/components/Input.js +8 -18
- package/esm/components/Messages.d.ts.map +1 -1
- package/esm/components/Messages.js +4 -20
- package/esm/components/customized/LandingQuestion.d.ts.map +1 -1
- package/esm/components/customized/LandingQuestion.js +1 -5
- package/esm/components/hooks/useEndpointCheck.d.ts.map +1 -1
- package/esm/components/hooks/useEndpointCheck.js +2 -2
- package/esm/components/messages/MessageScroller.d.ts +2 -2
- package/esm/components/messages/MessageScroller.d.ts.map +1 -1
- package/esm/components/messages/components/SemanticSearchTreeView.d.ts +4 -3
- package/esm/components/messages/components/SemanticSearchTreeView.d.ts.map +1 -1
- package/esm/components/messages/components/SemanticSearchTreeView.js +4 -4
- package/esm/components/messages/contents/drill/DrillSelectDropdownMenu.js +1 -1
- package/esm/components/messages/conversationContents/ConversationMultipartContent.js +1 -1
- package/esm/components/messages/conversationContents/ConversationSearchContent.d.ts.map +1 -1
- package/esm/components/messages/conversationContents/ConversationSearchContent.js +2 -8
- package/esm/components/messages/conversationContents/ConversationVisualisation.d.ts.map +1 -1
- package/esm/components/messages/conversationContents/ConversationVisualisation.js +63 -3
- package/esm/components/messages/conversationContents/ConversationVisualizationContent.js +2 -2
- package/esm/components/messages/conversationContents/SaveVisualizationDialog.js +1 -1
- package/esm/components/messages/useUserFeedback.d.ts +2 -2
- package/esm/components/messages/useUserFeedback.d.ts.map +1 -1
- package/esm/components/messages/useUserFeedback.js +17 -47
- package/esm/components/utils/modelCheckUtility.d.ts +1 -1
- package/esm/components/utils/modelCheckUtility.d.ts.map +1 -1
- package/esm/components/utils/modelCheckUtility.js +2 -2
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/internal.d.ts +1 -2
- package/esm/internal.d.ts.map +1 -1
- package/esm/internal.js +1 -2
- package/esm/localization/bundles/en-US.localization-bundle.d.ts +0 -12
- package/esm/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/localization/bundles/en-US.localization-bundle.js +0 -12
- package/esm/model.d.ts +0 -209
- package/esm/model.d.ts.map +1 -1
- package/esm/model.js +0 -131
- package/esm/sdk-ui-gen-ai.d.ts +1 -159
- package/esm/store/localStorage.d.ts +0 -4
- package/esm/store/localStorage.d.ts.map +1 -1
- package/esm/store/localStorage.js +0 -41
- package/esm/store/messages/messagesSelectors.d.ts +1 -12
- package/esm/store/messages/messagesSelectors.d.ts.map +1 -1
- package/esm/store/messages/messagesSelectors.js +1 -6
- package/esm/store/messages/messagesSlice.d.ts +7 -34
- package/esm/store/messages/messagesSlice.d.ts.map +1 -1
- package/esm/store/messages/messagesSlice.js +159 -408
- package/esm/store/queues/queue.newMessage.js +2 -4
- package/esm/store/sideEffects/conversationSession.js +1 -1
- package/esm/store/sideEffects/onChatOpenSync.d.ts +0 -1
- package/esm/store/sideEffects/onChatOpenSync.d.ts.map +1 -1
- package/esm/store/sideEffects/onChatOpenSync.js +0 -6
- package/esm/store/sideEffects/onDefinitionReceivedTrigger.d.ts +2 -2
- package/esm/store/sideEffects/onDefinitionReceivedTrigger.d.ts.map +1 -1
- package/esm/store/sideEffects/onDefinitionReceivedTrigger.js +2 -8
- package/esm/store/sideEffects/onEvent.d.ts.map +1 -1
- package/esm/store/sideEffects/onEvent.js +26 -71
- package/esm/store/sideEffects/onThreadClear.d.ts +1 -7
- package/esm/store/sideEffects/onThreadClear.d.ts.map +1 -1
- package/esm/store/sideEffects/onThreadClear.js +4 -26
- package/esm/store/sideEffects/onThreadLoad.d.ts +3 -26
- package/esm/store/sideEffects/onThreadLoad.d.ts.map +1 -1
- package/esm/store/sideEffects/onThreadLoad.js +3 -86
- package/esm/store/sideEffects/onUserFeedback.d.ts +4 -4
- package/esm/store/sideEffects/onUserFeedback.d.ts.map +1 -1
- package/esm/store/sideEffects/onUserFeedback.js +21 -44
- package/esm/store/sideEffects/onUserMessage.d.ts +3 -25
- package/esm/store/sideEffects/onUserMessage.d.ts.map +1 -1
- package/esm/store/sideEffects/onUserMessage.js +7 -161
- package/esm/store/sideEffects/onVisualisationRender.d.ts +2 -8
- package/esm/store/sideEffects/onVisualisationRender.d.ts.map +1 -1
- package/esm/store/sideEffects/onVisualisationRender.js +1 -28
- package/esm/store/sideEffects/onVisualizationSave.d.ts +5 -6
- package/esm/store/sideEffects/onVisualizationSave.d.ts.map +1 -1
- package/esm/store/sideEffects/onVisualizationSave.js +32 -240
- package/esm/store/sideEffects/onVisualizationSuccessSave.d.ts +3 -4
- package/esm/store/sideEffects/onVisualizationSuccessSave.d.ts.map +1 -1
- package/esm/store/sideEffects/onVisualizationSuccessSave.js +16 -49
- package/esm/store/sideEffects/utils.d.ts +0 -2
- package/esm/store/sideEffects/utils.d.ts.map +1 -1
- package/esm/store/sideEffects/utils.js +0 -14
- package/package.json +20 -19
- package/styles/css/main.css +12 -496
- package/styles/css/main.css.map +1 -1
- package/styles/css/messages.css +12 -496
- package/styles/css/messages.css.map +1 -1
- package/styles/scss/messages.scss +14 -375
- package/esm/components/messages/AssistantMessage.d.ts +0 -8
- package/esm/components/messages/AssistantMessage.d.ts.map +0 -1
- package/esm/components/messages/AssistantMessage.js +0 -35
- package/esm/components/messages/MessageContents.d.ts +0 -12
- package/esm/components/messages/MessageContents.d.ts.map +0 -1
- package/esm/components/messages/MessageContents.js +0 -49
- package/esm/components/messages/ReasoningDropdown.d.ts +0 -14
- package/esm/components/messages/ReasoningDropdown.d.ts.map +0 -1
- package/esm/components/messages/ReasoningDropdown.js +0 -42
- package/esm/components/messages/ReasoningMessage.d.ts +0 -9
- package/esm/components/messages/ReasoningMessage.d.ts.map +0 -1
- package/esm/components/messages/ReasoningMessage.js +0 -45
- package/esm/components/messages/UserMessage.d.ts +0 -8
- package/esm/components/messages/UserMessage.d.ts.map +0 -1
- package/esm/components/messages/UserMessage.js +0 -10
- package/esm/components/messages/contents/ChangeAnalysisContentsComponent.d.ts +0 -12
- package/esm/components/messages/contents/ChangeAnalysisContentsComponent.d.ts.map +0 -1
- package/esm/components/messages/contents/ChangeAnalysisContentsComponent.js +0 -36
- package/esm/components/messages/contents/ErrorContents.d.ts +0 -7
- package/esm/components/messages/contents/ErrorContents.d.ts.map +0 -1
- package/esm/components/messages/contents/ErrorContents.js +0 -8
- package/esm/components/messages/contents/ReasoningContents.d.ts +0 -6
- package/esm/components/messages/contents/ReasoningContents.d.ts.map +0 -1
- package/esm/components/messages/contents/ReasoningContents.js +0 -43
- package/esm/components/messages/contents/RoutingContents.d.ts +0 -8
- package/esm/components/messages/contents/RoutingContents.d.ts.map +0 -1
- package/esm/components/messages/contents/RoutingContents.js +0 -8
- package/esm/components/messages/contents/SearchContents.d.ts +0 -7
- package/esm/components/messages/contents/SearchContents.d.ts.map +0 -1
- package/esm/components/messages/contents/SearchContents.js +0 -15
- package/esm/components/messages/contents/SemanticSearchContents.d.ts +0 -8
- package/esm/components/messages/contents/SemanticSearchContents.d.ts.map +0 -1
- package/esm/components/messages/contents/SemanticSearchContents.js +0 -27
- package/esm/components/messages/contents/TextContents.d.ts +0 -7
- package/esm/components/messages/contents/TextContents.d.ts.map +0 -1
- package/esm/components/messages/contents/TextContents.js +0 -8
- package/esm/components/messages/contents/VisualizationContents.d.ts +0 -24
- package/esm/components/messages/contents/VisualizationContents.d.ts.map +0 -1
- package/esm/components/messages/contents/VisualizationContents.js +0 -532
- package/esm/components/messages/contents/VisualizationSaveDialog.d.ts +0 -13
- package/esm/components/messages/contents/VisualizationSaveDialog.d.ts.map +0 -1
- package/esm/components/messages/contents/VisualizationSaveDialog.js +0 -33
- package/esm/components/messages/contents/hooks/useVisualisationSaving.d.ts +0 -6
- package/esm/components/messages/contents/hooks/useVisualisationSaving.d.ts.map +0 -1
- package/esm/components/messages/contents/hooks/useVisualisationSaving.js +0 -17
- package/esm/components/messages/contents/useExecution.d.ts +0 -14
- package/esm/components/messages/contents/useExecution.d.ts.map +0 -1
- package/esm/components/messages/contents/useExecution.js +0 -131
- package/esm/components/messages/contents/useKdaDefinition.d.ts +0 -13
- package/esm/components/messages/contents/useKdaDefinition.d.ts.map +0 -1
- package/esm/components/messages/contents/useKdaDefinition.js +0 -140
- package/esm/components/messages/messageState.d.ts +0 -12
- package/esm/components/messages/messageState.d.ts.map +0 -1
- package/esm/components/messages/messageState.js +0 -21
- package/esm/store/sideEffects/converters/interactionsToMessages.d.ts +0 -19
- package/esm/store/sideEffects/converters/interactionsToMessages.d.ts.map +0 -1
- package/esm/store/sideEffects/converters/interactionsToMessages.js +0 -82
|
@@ -44,10 +44,8 @@ export const queueMiddleware = (storeAPI) => {
|
|
|
44
44
|
};
|
|
45
45
|
};
|
|
46
46
|
function loadAsyncProcess(state) {
|
|
47
|
-
// Load async process from right place
|
|
48
|
-
let asyncProcess = state.messages.messageAsyncProcess;
|
|
49
47
|
if (state.messages.currentConversation) {
|
|
50
|
-
|
|
48
|
+
return checkConversationData(state.messages.conversationsData, state.messages.currentConversation.localId)?.asyncProcess;
|
|
51
49
|
}
|
|
52
|
-
return
|
|
50
|
+
return "loading";
|
|
53
51
|
}
|
|
@@ -30,7 +30,7 @@ export function* onConversationActivity() {
|
|
|
30
30
|
/** Read staleness and refresh the timer on open. Only one open path calls this per opening. @internal */
|
|
31
31
|
export function* consumeStaleConversationSession() {
|
|
32
32
|
const settings = yield select(settingsSelector);
|
|
33
|
-
if (!settings?.
|
|
33
|
+
if (!settings?.enableAiAgenticMultiConversations) {
|
|
34
34
|
return false;
|
|
35
35
|
}
|
|
36
36
|
const workspace = yield getContext("workspace");
|
|
@@ -26,7 +26,6 @@ export declare function onChatOpenSync({ payload: { isOpen } }: PayloadAction<{
|
|
|
26
26
|
type: "messages/startNewConversationAction";
|
|
27
27
|
}> | import("redux-saga/effects").PutEffect<{
|
|
28
28
|
payload: {
|
|
29
|
-
messages?: import("../../model.js").Message[];
|
|
30
29
|
items?: IChatConversationLocalItem[];
|
|
31
30
|
};
|
|
32
31
|
type: "messages/setMessagesAction";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onChatOpenSync.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onChatOpenSync.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"onChatOpenSync.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onChatOpenSync.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAStD,OAAO,EACH,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAElC,MAAM,gBAAgB,CAAC;AAkBxB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAiB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;;;;;;;;;;;;;6DA4G1F"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
2
|
import { call, getContext, put, select } from "redux-saga/effects";
|
|
3
3
|
import { makeConversationItem, } from "../../model.js";
|
|
4
|
-
import { settingsSelector } from "../chatWindow/chatWindowSelectors.js";
|
|
5
4
|
import { asyncProcessSelector, conversationMessagesSelector, conversationSelector, loadedSelector, } from "../messages/messagesSelectors.js";
|
|
6
5
|
import { loadConversationsSuccessAction, setCurrentConversationAction, setMessagesAction, startNewConversationAction, } from "../messages/messagesSlice.js";
|
|
7
6
|
import { consumeStaleConversationSession } from "./conversationSession.js";
|
|
@@ -31,11 +30,6 @@ export function* onChatOpenSync({ payload: { isOpen } }) {
|
|
|
31
30
|
if (!isOpen) {
|
|
32
31
|
return;
|
|
33
32
|
}
|
|
34
|
-
const settings = yield select(settingsSelector);
|
|
35
|
-
// Only the agentic conversations flow keeps a list of conversations on the backend.
|
|
36
|
-
if (!settings?.enableAiAgenticConversations) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
33
|
// Initial load is owned by onThreadLoad; skip until it finishes to avoid a double stale check.
|
|
40
34
|
const loaded = yield select(loadedSelector);
|
|
41
35
|
if (!loaded) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type IChatConversationLocalItem
|
|
1
|
+
import { type IChatConversationLocalItem } from "../../model.js";
|
|
2
2
|
/**
|
|
3
3
|
* Notify the store that a definition was received.
|
|
4
4
|
* @internal
|
|
5
5
|
*/
|
|
6
|
-
export declare function notifyDefinitionReceived(items: IChatConversationLocalItem |
|
|
6
|
+
export declare function notifyDefinitionReceived(items: IChatConversationLocalItem | IChatConversationLocalItem[], conversationId: string): Generator<unknown, void, any>;
|
|
7
7
|
//# sourceMappingURL=onDefinitionReceivedTrigger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onDefinitionReceivedTrigger.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onDefinitionReceivedTrigger.ts"],"names":[],"mappings":"AAYA,OAAO,
|
|
1
|
+
{"version":3,"file":"onDefinitionReceivedTrigger.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onDefinitionReceivedTrigger.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAGjE;;;GAGG;AACH,wBAAiB,wBAAwB,CACrC,KAAK,EAAE,0BAA0B,GAAG,0BAA0B,EAAE,EAChE,cAAc,EAAE,MAAM,iCAmDzB"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// (C) 2024-2026 GoodData Corporation
|
|
2
2
|
import { put } from "redux-saga/effects";
|
|
3
3
|
import { isChatConversationDashboardContent, isChatConversationMultipartContent, isChatConversationVisualisationContent, } from "@gooddata/sdk-backend-spi";
|
|
4
|
-
import { isAssistantMessage, isChatConversationLocalItem, } from "../../model.js";
|
|
5
4
|
import { onDefinitionReceivedAction } from "../chatWindow/chatWindowSlice.js";
|
|
6
5
|
/**
|
|
7
6
|
* Notify the store that a definition was received.
|
|
@@ -39,12 +38,7 @@ export function* notifyDefinitionReceived(items, conversationId) {
|
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
for (const item of itemsArray) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
yield* processContent(item, item.content, interactionId);
|
|
45
|
-
}
|
|
46
|
-
else if (isAssistantMessage(item)) {
|
|
47
|
-
//NOTE: This is not supported for old messages api
|
|
48
|
-
}
|
|
41
|
+
const interactionId = item.responseId;
|
|
42
|
+
yield* processContent(item, item.content, interactionId);
|
|
49
43
|
}
|
|
50
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onEvent.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onEvent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"onEvent.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onEvent.ts"],"names":[],"mappings":"AA6CA,wBAAiB,OAAO,6EA2BvB"}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
// (C) 2024-2026 GoodData Corporation
|
|
2
2
|
import { call, getContext, select, takeEvery } from "redux-saga/effects";
|
|
3
|
-
import { isChatConversationLocalItem, isRoutingContents, isTextContents, isUserMessage, } from "../../model.js";
|
|
4
3
|
import { copyToClipboardAction, onDefinitionReceivedAction, setAmbientUserContextAction, setFullscreenAction, setOpenAction, setUserContextAction, } from "../chatWindow/chatWindowSlice.js";
|
|
5
|
-
import {
|
|
6
|
-
import { conversationMessagesSelector,
|
|
7
|
-
import { clearThreadAction, deleteConversationAction, deleteConversationFailureAction, deleteConversationSuccessAction, evaluateMessageCompleteAction, loadConversationSuccessAction,
|
|
4
|
+
import { setIsOpened } from "../localStorage.js";
|
|
5
|
+
import { conversationMessagesSelector, threadIdSelector } from "../messages/messagesSelectors.js";
|
|
6
|
+
import { clearThreadAction, deleteConversationAction, deleteConversationFailureAction, deleteConversationSuccessAction, evaluateMessageCompleteAction, loadConversationSuccessAction, newMessageAction, pinConversationFailureAction, pinConversationSuccessAction, renameConversationAction, renameConversationFailureAction, renameConversationSuccessAction, saveVisualizationErrorAction, saveVisualizationSuccessAction, setCurrentConversationAction, setSelectedAgentAction, setUserFeedback, setUserFeedbackError, visualizationErrorAction, } from "../messages/messagesSlice.js";
|
|
8
7
|
export function* onEvent() {
|
|
9
8
|
yield takeEvery(setOpenAction.type, onSetOpen);
|
|
10
9
|
yield takeEvery(setFullscreenAction.type, onFullscreenChanged);
|
|
11
10
|
yield takeEvery(setSelectedAgentAction.type, onSelectedAgentChanged);
|
|
12
|
-
yield takeEvery(loadThreadSuccessAction.type, onThreadLoaded);
|
|
13
11
|
yield takeEvery(loadConversationSuccessAction.type, onThreadLoaded);
|
|
14
12
|
yield takeEvery(clearThreadAction.type, onClearThread);
|
|
15
13
|
yield takeEvery(newMessageAction.type, onNewMessage);
|
|
@@ -131,11 +129,6 @@ function* onConversationLoaded({ payload: { currentConversation }, }) {
|
|
|
131
129
|
conversation: currentConversation,
|
|
132
130
|
});
|
|
133
131
|
}
|
|
134
|
-
function* persistMessages() {
|
|
135
|
-
const workspace = yield getContext("workspace");
|
|
136
|
-
const messages = yield select(messagesSelector);
|
|
137
|
-
saveMessages(workspace, messages);
|
|
138
|
-
}
|
|
139
132
|
function* onSetOpen({ payload: { isOpen } }) {
|
|
140
133
|
setIsOpened(isOpen);
|
|
141
134
|
if (isOpen) {
|
|
@@ -168,8 +161,7 @@ function* onSelectedAgentChanged({ payload: { previousAgentId, agentId }, }) {
|
|
|
168
161
|
agentId,
|
|
169
162
|
});
|
|
170
163
|
}
|
|
171
|
-
function* onThreadLoaded({ payload: { threadId }
|
|
172
|
-
yield* persistMessages();
|
|
164
|
+
function* onThreadLoaded({ payload: { threadId } }) {
|
|
173
165
|
// Only emit the chatOpened event when we have a real server-side threadId.
|
|
174
166
|
// The cache-restore dispatch uses an empty threadId and should not trigger telemetry.
|
|
175
167
|
if (!threadId) {
|
|
@@ -182,8 +174,6 @@ function* onThreadLoaded({ payload: { threadId }, }) {
|
|
|
182
174
|
});
|
|
183
175
|
}
|
|
184
176
|
function* onClearThread(_action) {
|
|
185
|
-
const workspace = yield getContext("workspace");
|
|
186
|
-
clearCachedMessages(workspace);
|
|
187
177
|
const eventDispatcher = yield getContext("eventDispatcher");
|
|
188
178
|
const threadId = yield select(threadIdSelector);
|
|
189
179
|
eventDispatcher.dispatch({
|
|
@@ -192,43 +182,23 @@ function* onClearThread(_action) {
|
|
|
192
182
|
});
|
|
193
183
|
}
|
|
194
184
|
function* onNewMessage({ payload: message }) {
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
const messageContent = message.content;
|
|
200
|
-
if (messageContent.type !== "text") {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const eventDispatcher = yield getContext("eventDispatcher");
|
|
204
|
-
const threadId = yield select(threadIdSelector);
|
|
205
|
-
eventDispatcher.dispatch({
|
|
206
|
-
type: "chatUserMessage",
|
|
207
|
-
threadId,
|
|
208
|
-
question: messageContent.text,
|
|
209
|
-
objects: messageContent.objects ?? [],
|
|
210
|
-
});
|
|
185
|
+
if (message.role !== "user") {
|
|
186
|
+
return;
|
|
211
187
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
const messageContent = message.content.find((c) => isTextContents(c));
|
|
217
|
-
if (!messageContent?.text) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
const eventDispatcher = yield getContext("eventDispatcher");
|
|
221
|
-
const threadId = yield select(threadIdSelector);
|
|
222
|
-
eventDispatcher.dispatch({
|
|
223
|
-
type: "chatUserMessage",
|
|
224
|
-
threadId,
|
|
225
|
-
question: messageContent.text,
|
|
226
|
-
objects: messageContent.objects,
|
|
227
|
-
});
|
|
188
|
+
const messageContent = message.content;
|
|
189
|
+
if (messageContent.type !== "text") {
|
|
190
|
+
return;
|
|
228
191
|
}
|
|
192
|
+
const eventDispatcher = yield getContext("eventDispatcher");
|
|
193
|
+
const threadId = yield select(threadIdSelector);
|
|
194
|
+
eventDispatcher.dispatch({
|
|
195
|
+
type: "chatUserMessage",
|
|
196
|
+
threadId,
|
|
197
|
+
question: messageContent.text,
|
|
198
|
+
objects: messageContent.objects ?? [],
|
|
199
|
+
});
|
|
229
200
|
}
|
|
230
201
|
function* onEvaluateMessageComplete({ payload: { assistantMessageId }, }) {
|
|
231
|
-
yield* persistMessages();
|
|
232
202
|
const message = yield call(loadMessage, assistantMessageId);
|
|
233
203
|
if (!message?.useCase) {
|
|
234
204
|
return;
|
|
@@ -319,30 +289,15 @@ function* onDefinitionReceived({ payload }) {
|
|
|
319
289
|
});
|
|
320
290
|
}
|
|
321
291
|
function* loadMessage(assistantMessageId) {
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
: null;
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
const allMessages = yield select(messagesSelector);
|
|
336
|
-
const message = allMessages.find((m) => m.localId === assistantMessageId);
|
|
337
|
-
const useCase = message?.content.find((c) => isRoutingContents(c))?.useCase;
|
|
338
|
-
return message
|
|
339
|
-
? {
|
|
340
|
-
id: message.id ?? "",
|
|
341
|
-
localId: message.localId,
|
|
342
|
-
useCase,
|
|
343
|
-
}
|
|
344
|
-
: null;
|
|
345
|
-
}
|
|
292
|
+
const allMessages = yield select(conversationMessagesSelector);
|
|
293
|
+
const message = allMessages.find((m) => m.localId === assistantMessageId);
|
|
294
|
+
return message
|
|
295
|
+
? {
|
|
296
|
+
id: message.id,
|
|
297
|
+
localId: message.localId,
|
|
298
|
+
useCase: convertMessageTypeTo(message?.content),
|
|
299
|
+
}
|
|
300
|
+
: null;
|
|
346
301
|
}
|
|
347
302
|
function convertMessageTypeTo(content) {
|
|
348
303
|
switch (content?.type) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type IChatConversation, type IUserWorkspaceSettings } from "@gooddata/sdk-backend-spi";
|
|
2
2
|
/**
|
|
3
3
|
* Load thread history and put it to the store.
|
|
4
4
|
* @internal
|
|
@@ -7,12 +7,6 @@ export declare function onThreadClear(): Generator<Generator<import("redux-saga/
|
|
|
7
7
|
payload: undefined;
|
|
8
8
|
type: "messages/startNewConversationAction";
|
|
9
9
|
}>, void, unknown> | Generator<import("redux-saga/effects").GetContextEffect | import("redux-saga/effects").PutEffect<{
|
|
10
|
-
payload: undefined;
|
|
11
|
-
type: "messages/clearThreadSuccessAction";
|
|
12
|
-
}> | import("redux-saga/effects").RaceEffect<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").TakeEffect>, void, IAnalyticalBackend & string & [results: void, {
|
|
13
|
-
payload: undefined;
|
|
14
|
-
type: "messages/cancelAsyncAction";
|
|
15
|
-
}]> | Generator<import("redux-saga/effects").GetContextEffect | import("redux-saga/effects").PutEffect<{
|
|
16
10
|
payload: {
|
|
17
11
|
conversation: import("../../model.js").IChatConversationLocal;
|
|
18
12
|
threadId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onThreadClear.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onThreadClear.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"onThreadClear.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onThreadClear.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC9B,MAAM,2BAA2B,CAAC;AAWnC;;;GAGG;AACH,wBAAiB,aAAa;;;;;;;;;;;;;;0FAW7B"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { call, getContext, put, race, select, take } from "redux-saga/effects";
|
|
3
3
|
import { agentSwitchingActiveSelector, settingsSelector } from "../chatWindow/chatWindowSelectors.js";
|
|
4
4
|
import { selectedAgentIdSelector, threadIdSelector } from "../messages/messagesSelectors.js";
|
|
5
|
-
import { cancelAsyncAction, clearConversationSuccessAction, clearThreadErrorAction,
|
|
5
|
+
import { cancelAsyncAction, clearConversationSuccessAction, clearThreadErrorAction, startNewConversationAction, } from "../messages/messagesSlice.js";
|
|
6
6
|
/**
|
|
7
7
|
* Load thread history and put it to the store.
|
|
8
8
|
* @internal
|
|
@@ -10,39 +10,17 @@ import { cancelAsyncAction, clearConversationSuccessAction, clearThreadErrorActi
|
|
|
10
10
|
export function* onThreadClear() {
|
|
11
11
|
try {
|
|
12
12
|
const settings = yield select(settingsSelector);
|
|
13
|
-
if (settings?.
|
|
14
|
-
|
|
15
|
-
yield createConversation();
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
yield resetConversation();
|
|
19
|
-
}
|
|
13
|
+
if (settings?.enableAiAgenticMultiConversations) {
|
|
14
|
+
yield createConversation();
|
|
20
15
|
}
|
|
21
16
|
else {
|
|
22
|
-
yield
|
|
17
|
+
yield resetConversation();
|
|
23
18
|
}
|
|
24
19
|
}
|
|
25
20
|
catch (e) {
|
|
26
21
|
yield put(clearThreadErrorAction({ error: e }));
|
|
27
22
|
}
|
|
28
23
|
}
|
|
29
|
-
//THREAD API
|
|
30
|
-
function* resetThread() {
|
|
31
|
-
// Retrieve backend from context
|
|
32
|
-
const backend = yield getContext("backend");
|
|
33
|
-
const workspace = yield getContext("workspace");
|
|
34
|
-
const chatThread = backend.workspace(workspace).genAI().getChatThread();
|
|
35
|
-
const [_results, cancelAction] = yield race([
|
|
36
|
-
call(chatThread.reset.bind(chatThread)),
|
|
37
|
-
take(cancelAsyncAction.type),
|
|
38
|
-
]);
|
|
39
|
-
if (cancelAction) {
|
|
40
|
-
// Just skip, as the action was cancelled
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
yield put(clearThreadSuccessAction());
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
24
|
//CONVERSATIONS API
|
|
47
25
|
function* resetConversation() {
|
|
48
26
|
// Retrieve backend from context
|
|
@@ -1,24 +1,9 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type IChatConversationLocal, type Message } from "../../model.js";
|
|
1
|
+
import { type IChatConversationLocal } from "../../model.js";
|
|
3
2
|
/**
|
|
4
3
|
* Load thread history and put it to the store.
|
|
5
4
|
* @internal
|
|
6
5
|
*/
|
|
7
|
-
export declare function onThreadLoad(): Generator<import("redux-saga/effects").CancelledEffect | Generator<import("redux-saga/effects").CallEffect<void>, void, unknown> |
|
|
8
|
-
payload: {
|
|
9
|
-
messages: Message[];
|
|
10
|
-
threadId: string;
|
|
11
|
-
};
|
|
12
|
-
type: "messages/loadThreadSuccessAction";
|
|
13
|
-
}> | import("redux-saga/effects").PutEffect<{
|
|
14
|
-
payload: {
|
|
15
|
-
messages: Message[];
|
|
16
|
-
};
|
|
17
|
-
type: "messages/restoreCachedMessagesAction";
|
|
18
|
-
}> | import("redux-saga/effects").RaceEffect<import("redux-saga/effects").CallEffect<IChatThreadHistory> | import("redux-saga/effects").TakeEffect>, void, IAnalyticalBackend & string & [results: IChatThreadHistory, {
|
|
19
|
-
payload: undefined;
|
|
20
|
-
type: "messages/cancelAsyncAction";
|
|
21
|
-
}]> | import("redux-saga/effects").PutEffect<{
|
|
6
|
+
export declare function onThreadLoad(): Generator<import("redux-saga/effects").CancelledEffect | Generator<import("redux-saga/effects").CallEffect<void>, void, unknown> | import("redux-saga/effects").PutEffect<{
|
|
22
7
|
payload: {
|
|
23
8
|
error: Error;
|
|
24
9
|
};
|
|
@@ -28,13 +13,5 @@ export declare function onThreadLoad(): Generator<import("redux-saga/effects").C
|
|
|
28
13
|
conversationLocalId?: string;
|
|
29
14
|
};
|
|
30
15
|
type: "messages/clearConversationLoadingAction";
|
|
31
|
-
}> | import("redux-saga/effects").SelectEffect, void, (IChatConversationLocal | undefined) &
|
|
32
|
-
/**
|
|
33
|
-
* Merge backend-loaded messages with cached messages.
|
|
34
|
-
* For each assistant message from the backend, if its content is missing semanticSearch
|
|
35
|
-
* data but the corresponding cached message has it, the cached content is preserved.
|
|
36
|
-
* Matching is done by the server-side interaction ID (message.id).
|
|
37
|
-
* @internal
|
|
38
|
-
*/
|
|
39
|
-
export declare function mergeWithCache(backendMessages: Message[], cachedMessages: Message[]): Message[];
|
|
16
|
+
}> | import("redux-saga/effects").SelectEffect, void, (IChatConversationLocal | undefined) & boolean>;
|
|
40
17
|
//# sourceMappingURL=onThreadLoad.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onThreadLoad.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onThreadLoad.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"onThreadLoad.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onThreadLoad.ts"],"names":[],"mappings":"AAYA,OAAO,EACH,KAAK,sBAAsB,EAG9B,MAAM,gBAAgB,CAAC;AAoBxB;;;GAGG;AACH,wBAAiB,YAAY;;;;;;;;;;sGA+B5B"}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
// (C) 2024-2026 GoodData Corporation
|
|
2
2
|
import { all, call, cancelled, getContext, put, race, select, spawn, take } from "redux-saga/effects";
|
|
3
|
-
import {
|
|
4
|
-
import { settingsSelector } from "../chatWindow/chatWindowSelectors.js";
|
|
5
|
-
import { loadMessages } from "../localStorage.js";
|
|
3
|
+
import { makeConversationItem, } from "../../model.js";
|
|
6
4
|
import { conversationMessagesByIdSelector, conversationSelector, conversationsLoadedSelector, conversationsSelector, } from "../messages/messagesSelectors.js";
|
|
7
|
-
import { cancelAsyncAction, clearConversationLoadingAction, loadConversationSuccessAction, loadConversationsSuccessAction, loadThreadErrorAction,
|
|
5
|
+
import { cancelAsyncAction, clearConversationLoadingAction, loadConversationSuccessAction, loadConversationsSuccessAction, loadThreadErrorAction, } from "../messages/messagesSlice.js";
|
|
8
6
|
import { createEmptyConversation } from "../utils.js";
|
|
9
7
|
import { consumeStaleConversationSession } from "./conversationSession.js";
|
|
10
|
-
import { interactionsToMessages } from "./converters/interactionsToMessages.js";
|
|
11
8
|
import { convertToLocalContent } from "./converters/toLocalContent.js";
|
|
12
9
|
import { notifyDefinitionReceived } from "./onDefinitionReceivedTrigger.js";
|
|
13
10
|
/**
|
|
@@ -23,13 +20,7 @@ export function* onThreadLoad() {
|
|
|
23
20
|
const loadingConversation = yield select(conversationSelector);
|
|
24
21
|
const loadingConversationLocalId = loadingConversation?.localId;
|
|
25
22
|
try {
|
|
26
|
-
|
|
27
|
-
if (settings?.enableAiAgenticConversations) {
|
|
28
|
-
yield fetchConversations();
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
yield fetchThread(settings);
|
|
32
|
-
}
|
|
23
|
+
yield fetchConversations();
|
|
33
24
|
}
|
|
34
25
|
catch (e) {
|
|
35
26
|
yield put(loadThreadErrorAction({ error: e }));
|
|
@@ -51,80 +42,6 @@ export function* onThreadLoad() {
|
|
|
51
42
|
}
|
|
52
43
|
}
|
|
53
44
|
}
|
|
54
|
-
/**
|
|
55
|
-
* Merge backend-loaded messages with cached messages.
|
|
56
|
-
* For each assistant message from the backend, if its content is missing semanticSearch
|
|
57
|
-
* data but the corresponding cached message has it, the cached content is preserved.
|
|
58
|
-
* Matching is done by the server-side interaction ID (message.id).
|
|
59
|
-
* @internal
|
|
60
|
-
*/
|
|
61
|
-
export function mergeWithCache(backendMessages, cachedMessages) {
|
|
62
|
-
// Build a lookup of cached assistant messages by their server-side interaction ID.
|
|
63
|
-
const cachedById = new Map();
|
|
64
|
-
for (const msg of cachedMessages) {
|
|
65
|
-
if (isAssistantMessage(msg) && msg.id) {
|
|
66
|
-
cachedById.set(msg.id, msg);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return backendMessages.map((msg) => {
|
|
70
|
-
if (!isAssistantMessage(msg) || !msg.id) {
|
|
71
|
-
return msg;
|
|
72
|
-
}
|
|
73
|
-
const cached = cachedById.get(msg.id);
|
|
74
|
-
if (!cached) {
|
|
75
|
-
return msg;
|
|
76
|
-
}
|
|
77
|
-
// Check if the backend message is missing semanticSearch content but the cache has it.
|
|
78
|
-
const backendHasSemanticSearch = msg.content.some(isSemanticSearchContents);
|
|
79
|
-
const cachedSemanticSearchContents = cached.content.filter(isSemanticSearchContents);
|
|
80
|
-
if (!backendHasSemanticSearch && cachedSemanticSearchContents.length > 0) {
|
|
81
|
-
// Inject cached semanticSearch contents into the backend message.
|
|
82
|
-
const mergedContent = [...msg.content, ...cachedSemanticSearchContents];
|
|
83
|
-
return { ...msg, content: mergedContent };
|
|
84
|
-
}
|
|
85
|
-
return msg;
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
//THREAD API
|
|
89
|
-
function* fetchThread(settings) {
|
|
90
|
-
// Retrieve backend from context
|
|
91
|
-
const backend = yield getContext("backend");
|
|
92
|
-
const workspace = yield getContext("workspace");
|
|
93
|
-
const showReasoning = Boolean(settings?.enableGenAIReasoningVisibility);
|
|
94
|
-
// Immediately restore cached messages so the UI doesn't flash empty while backend loads.
|
|
95
|
-
// Uses restoreCachedMessagesAction which shows messages but keeps loaded=false,
|
|
96
|
-
// preventing useThreadLoading from cancelling the in-progress backend fetch.
|
|
97
|
-
const cachedMessages = loadMessages(workspace);
|
|
98
|
-
if (cachedMessages?.length) {
|
|
99
|
-
yield put(restoreCachedMessagesAction({ messages: cachedMessages }));
|
|
100
|
-
}
|
|
101
|
-
const chatThread = backend.workspace(workspace).genAI().getChatThread();
|
|
102
|
-
const [results, wasCancelled] = yield race([call(fetchChatHistory, chatThread), take(cancelAsyncAction.type)]);
|
|
103
|
-
if (!wasCancelled) {
|
|
104
|
-
const backendMessages = interactionsToMessages(results?.interactions ?? [], { showReasoning });
|
|
105
|
-
// Merge: preserve semanticSearch content from cached messages when the backend omits it.
|
|
106
|
-
const mergedMessages = cachedMessages?.length
|
|
107
|
-
? mergeWithCache(backendMessages, cachedMessages)
|
|
108
|
-
: backendMessages;
|
|
109
|
-
yield put(loadThreadSuccessAction({
|
|
110
|
-
messages: mergedMessages,
|
|
111
|
-
threadId: results?.threadId ?? "",
|
|
112
|
-
}));
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
function* fetchChatHistory(preparedChatThread) {
|
|
116
|
-
const controller = new AbortController();
|
|
117
|
-
try {
|
|
118
|
-
const results = yield call(preparedChatThread.loadHistory.bind(preparedChatThread), undefined, { signal: controller.signal });
|
|
119
|
-
return results;
|
|
120
|
-
}
|
|
121
|
-
finally {
|
|
122
|
-
const wasCancelled = yield cancelled();
|
|
123
|
-
if (wasCancelled) {
|
|
124
|
-
controller.abort();
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
45
|
//CONVERSATIONS API
|
|
129
46
|
function* fetchConversations() {
|
|
130
47
|
// Load all conversations
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type PayloadAction } from "@reduxjs/toolkit";
|
|
2
|
-
import { type IAnalyticalBackend
|
|
2
|
+
import { type IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
|
|
3
3
|
import { type GenAIChatInteractionUserFeedback } from "@gooddata/sdk-model";
|
|
4
|
-
import { type IChatConversationLocalItem
|
|
4
|
+
import { type IChatConversationLocalItem } from "../../model.js";
|
|
5
5
|
/**
|
|
6
6
|
* Save user feedback to server.
|
|
7
7
|
* Optimistic update, ignoring the error.
|
|
@@ -18,9 +18,9 @@ export declare function onUserFeedback({ payload, }: PayloadAction<{
|
|
|
18
18
|
error: string;
|
|
19
19
|
};
|
|
20
20
|
type: "messages/setUserFeedbackError";
|
|
21
|
-
}> | import("redux-saga/effects").SelectEffect, void, IAnalyticalBackend & string &
|
|
21
|
+
}> | import("redux-saga/effects").SelectEffect, void, IAnalyticalBackend & string & import("@gooddata/sdk-backend-spi").IChatConversation & {
|
|
22
22
|
localId: string;
|
|
23
23
|
generatingTitle?: boolean;
|
|
24
24
|
inProgress?: boolean;
|
|
25
|
-
} & IChatConversationLocalItem[]
|
|
25
|
+
} & IChatConversationLocalItem[]>;
|
|
26
26
|
//# sourceMappingURL=onUserFeedback.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onUserFeedback.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onUserFeedback.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,KAAK,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"onUserFeedback.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onUserFeedback.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,KAAK,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AAE5E,OAAO,EAA+B,KAAK,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAM9F;;;;GAIG;AACH,wBAAiB,cAAc,CAAC,EAC5B,OAAO,GACV,EAAE,aAAa,CAAC;IACb,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,gCAAgC,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;;;;;;;;;;;kCAiCD"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// (C) 2024-2026 GoodData Corporation
|
|
2
2
|
import { getContext, put, select } from "redux-saga/effects";
|
|
3
|
-
import {
|
|
4
|
-
import { conversationMessagesSelector, conversationSelector, messagesSelector, } from "../messages/messagesSelectors.js";
|
|
3
|
+
import { conversationMessagesSelector, conversationSelector } from "../messages/messagesSelectors.js";
|
|
5
4
|
import { setUserFeedbackError } from "../messages/messagesSlice.js";
|
|
6
5
|
import { extractError } from "./utils.js";
|
|
7
6
|
/**
|
|
@@ -13,49 +12,27 @@ export function* onUserFeedback({ payload, }) {
|
|
|
13
12
|
// Retrieve backend from context
|
|
14
13
|
const backend = yield getContext("backend");
|
|
15
14
|
const workspace = yield getContext("workspace");
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (!message?.id) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
const chatThread = backend
|
|
26
|
-
.workspace(workspace)
|
|
27
|
-
.genAI()
|
|
28
|
-
.getChatConversations()
|
|
29
|
-
.getConversationThread(conversation.id);
|
|
30
|
-
yield chatThread.saveFeedback(message.responseId, payload.feedback, payload.userTextFeedback);
|
|
31
|
-
}
|
|
32
|
-
catch (e) {
|
|
33
|
-
console.warn(`Failed to save user feedback: ${extractError(e)}`);
|
|
34
|
-
// Dispatch error action to notify UI
|
|
35
|
-
yield put(setUserFeedbackError({
|
|
36
|
-
assistantMessageId: payload.assistantMessageId,
|
|
37
|
-
error: extractError(e),
|
|
38
|
-
conversationId: conversation.localId,
|
|
39
|
-
}));
|
|
15
|
+
const conversation = yield select(conversationSelector);
|
|
16
|
+
try {
|
|
17
|
+
const messages = yield select(conversationMessagesSelector);
|
|
18
|
+
const message = messages.find((message) => message.localId === payload.assistantMessageId);
|
|
19
|
+
if (!message?.id) {
|
|
20
|
+
return;
|
|
40
21
|
}
|
|
22
|
+
const chatThread = backend
|
|
23
|
+
.workspace(workspace)
|
|
24
|
+
.genAI()
|
|
25
|
+
.getChatConversations()
|
|
26
|
+
.getConversationThread(conversation.id);
|
|
27
|
+
yield chatThread.saveFeedback(message.responseId, payload.feedback, payload.userTextFeedback);
|
|
41
28
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
yield chatThread.saveUserFeedback(message.id, payload.feedback, payload.userTextFeedback);
|
|
51
|
-
}
|
|
52
|
-
catch (e) {
|
|
53
|
-
console.warn(`Failed to save user feedback: ${extractError(e)}`);
|
|
54
|
-
// Dispatch error action to notify UI
|
|
55
|
-
yield put(setUserFeedbackError({
|
|
56
|
-
assistantMessageId: payload.assistantMessageId,
|
|
57
|
-
error: extractError(e),
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
console.warn(`Failed to save user feedback: ${extractError(e)}`);
|
|
31
|
+
// Dispatch error action to notify UI
|
|
32
|
+
yield put(setUserFeedbackError({
|
|
33
|
+
assistantMessageId: payload.assistantMessageId,
|
|
34
|
+
error: extractError(e),
|
|
35
|
+
conversationId: conversation.localId,
|
|
36
|
+
}));
|
|
60
37
|
}
|
|
61
38
|
}
|
|
@@ -1,37 +1,15 @@
|
|
|
1
1
|
import { type IChatConversation } from "@gooddata/sdk-backend-spi";
|
|
2
|
-
import { type
|
|
2
|
+
import { type IChatConversationLocal, type IChatConversationLocalItem } from "../../model.js";
|
|
3
3
|
import { type newMessageAction } from "../messages/messagesSlice.js";
|
|
4
4
|
/**
|
|
5
5
|
* Load thread history and put it to the store.
|
|
6
6
|
* @internal
|
|
7
7
|
*/
|
|
8
|
-
export declare function onUserMessage({ payload }: ReturnType<typeof newMessageAction>): Generator<Generator<import("redux-saga/effects").CallEffect<{
|
|
9
|
-
lastAssistantMessage: AssistantMessage;
|
|
10
|
-
}> | import("redux-saga/effects").CancelledEffect | import("redux-saga/effects").GetContextEffect | import("redux-saga/effects").PutEffect<{
|
|
11
|
-
payload: {
|
|
12
|
-
message: AssistantMessage | IChatConversationLocalItem;
|
|
13
|
-
conversationId?: string;
|
|
14
|
-
};
|
|
15
|
-
type: "messages/evaluateMessageAction";
|
|
16
|
-
}> | import("redux-saga/effects").PutEffect<{
|
|
17
|
-
payload: {
|
|
18
|
-
error: string;
|
|
19
|
-
assistantMessageId: string;
|
|
20
|
-
conversationId?: string;
|
|
21
|
-
};
|
|
22
|
-
type: "messages/evaluateMessageErrorAction";
|
|
23
|
-
}> | import("redux-saga/effects").PutEffect<{
|
|
24
|
-
payload: {
|
|
25
|
-
assistantMessageId: string;
|
|
26
|
-
conversationId?: string;
|
|
27
|
-
cancelled?: boolean;
|
|
28
|
-
};
|
|
29
|
-
type: "messages/evaluateMessageCompleteAction";
|
|
30
|
-
}> | import("redux-saga/effects").SelectEffect, void, never> | Generator<import("redux-saga/effects").CallEffect<IChatConversation> | import("redux-saga/effects").CallEffect<{
|
|
8
|
+
export declare function onUserMessage({ payload }: ReturnType<typeof newMessageAction>): Generator<Generator<import("redux-saga/effects").CallEffect<IChatConversation> | import("redux-saga/effects").CallEffect<{
|
|
31
9
|
lastAssistantMessage: IChatConversationLocalItem;
|
|
32
10
|
}> | import("redux-saga/effects").CancelledEffect | import("redux-saga/effects").GetContextEffect | import("redux-saga/effects").PutEffect<{
|
|
33
11
|
payload: {
|
|
34
|
-
message:
|
|
12
|
+
message: IChatConversationLocalItem;
|
|
35
13
|
conversationId?: string;
|
|
36
14
|
};
|
|
37
15
|
type: "messages/evaluateMessageAction";
|