@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.
Files changed (150) hide show
  1. package/NOTICE +2321 -1760
  2. package/esm/components/GenAIChatDialogConnected.d.ts +1 -2
  3. package/esm/components/GenAIChatDialogConnected.d.ts.map +1 -1
  4. package/esm/components/GenAIChatDialogConnected.js +3 -9
  5. package/esm/components/Input.d.ts.map +1 -1
  6. package/esm/components/Input.js +8 -18
  7. package/esm/components/Messages.d.ts.map +1 -1
  8. package/esm/components/Messages.js +4 -20
  9. package/esm/components/customized/LandingQuestion.d.ts.map +1 -1
  10. package/esm/components/customized/LandingQuestion.js +1 -5
  11. package/esm/components/hooks/useEndpointCheck.d.ts.map +1 -1
  12. package/esm/components/hooks/useEndpointCheck.js +2 -2
  13. package/esm/components/messages/MessageScroller.d.ts +2 -2
  14. package/esm/components/messages/MessageScroller.d.ts.map +1 -1
  15. package/esm/components/messages/components/SemanticSearchTreeView.d.ts +4 -3
  16. package/esm/components/messages/components/SemanticSearchTreeView.d.ts.map +1 -1
  17. package/esm/components/messages/components/SemanticSearchTreeView.js +4 -4
  18. package/esm/components/messages/contents/drill/DrillSelectDropdownMenu.js +1 -1
  19. package/esm/components/messages/conversationContents/ConversationMultipartContent.js +1 -1
  20. package/esm/components/messages/conversationContents/ConversationSearchContent.d.ts.map +1 -1
  21. package/esm/components/messages/conversationContents/ConversationSearchContent.js +2 -8
  22. package/esm/components/messages/conversationContents/ConversationVisualisation.d.ts.map +1 -1
  23. package/esm/components/messages/conversationContents/ConversationVisualisation.js +63 -3
  24. package/esm/components/messages/conversationContents/ConversationVisualizationContent.js +2 -2
  25. package/esm/components/messages/conversationContents/SaveVisualizationDialog.js +1 -1
  26. package/esm/components/messages/useUserFeedback.d.ts +2 -2
  27. package/esm/components/messages/useUserFeedback.d.ts.map +1 -1
  28. package/esm/components/messages/useUserFeedback.js +17 -47
  29. package/esm/components/utils/modelCheckUtility.d.ts +1 -1
  30. package/esm/components/utils/modelCheckUtility.d.ts.map +1 -1
  31. package/esm/components/utils/modelCheckUtility.js +2 -2
  32. package/esm/index.d.ts +1 -1
  33. package/esm/index.d.ts.map +1 -1
  34. package/esm/index.js +1 -1
  35. package/esm/internal.d.ts +1 -2
  36. package/esm/internal.d.ts.map +1 -1
  37. package/esm/internal.js +1 -2
  38. package/esm/localization/bundles/en-US.localization-bundle.d.ts +0 -12
  39. package/esm/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
  40. package/esm/localization/bundles/en-US.localization-bundle.js +0 -12
  41. package/esm/model.d.ts +0 -209
  42. package/esm/model.d.ts.map +1 -1
  43. package/esm/model.js +0 -131
  44. package/esm/sdk-ui-gen-ai.d.ts +1 -159
  45. package/esm/store/localStorage.d.ts +0 -4
  46. package/esm/store/localStorage.d.ts.map +1 -1
  47. package/esm/store/localStorage.js +0 -41
  48. package/esm/store/messages/messagesSelectors.d.ts +1 -12
  49. package/esm/store/messages/messagesSelectors.d.ts.map +1 -1
  50. package/esm/store/messages/messagesSelectors.js +1 -6
  51. package/esm/store/messages/messagesSlice.d.ts +7 -34
  52. package/esm/store/messages/messagesSlice.d.ts.map +1 -1
  53. package/esm/store/messages/messagesSlice.js +159 -408
  54. package/esm/store/queues/queue.newMessage.js +2 -4
  55. package/esm/store/sideEffects/conversationSession.js +1 -1
  56. package/esm/store/sideEffects/onChatOpenSync.d.ts +0 -1
  57. package/esm/store/sideEffects/onChatOpenSync.d.ts.map +1 -1
  58. package/esm/store/sideEffects/onChatOpenSync.js +0 -6
  59. package/esm/store/sideEffects/onDefinitionReceivedTrigger.d.ts +2 -2
  60. package/esm/store/sideEffects/onDefinitionReceivedTrigger.d.ts.map +1 -1
  61. package/esm/store/sideEffects/onDefinitionReceivedTrigger.js +2 -8
  62. package/esm/store/sideEffects/onEvent.d.ts.map +1 -1
  63. package/esm/store/sideEffects/onEvent.js +26 -71
  64. package/esm/store/sideEffects/onThreadClear.d.ts +1 -7
  65. package/esm/store/sideEffects/onThreadClear.d.ts.map +1 -1
  66. package/esm/store/sideEffects/onThreadClear.js +4 -26
  67. package/esm/store/sideEffects/onThreadLoad.d.ts +3 -26
  68. package/esm/store/sideEffects/onThreadLoad.d.ts.map +1 -1
  69. package/esm/store/sideEffects/onThreadLoad.js +3 -86
  70. package/esm/store/sideEffects/onUserFeedback.d.ts +4 -4
  71. package/esm/store/sideEffects/onUserFeedback.d.ts.map +1 -1
  72. package/esm/store/sideEffects/onUserFeedback.js +21 -44
  73. package/esm/store/sideEffects/onUserMessage.d.ts +3 -25
  74. package/esm/store/sideEffects/onUserMessage.d.ts.map +1 -1
  75. package/esm/store/sideEffects/onUserMessage.js +7 -161
  76. package/esm/store/sideEffects/onVisualisationRender.d.ts +2 -8
  77. package/esm/store/sideEffects/onVisualisationRender.d.ts.map +1 -1
  78. package/esm/store/sideEffects/onVisualisationRender.js +1 -28
  79. package/esm/store/sideEffects/onVisualizationSave.d.ts +5 -6
  80. package/esm/store/sideEffects/onVisualizationSave.d.ts.map +1 -1
  81. package/esm/store/sideEffects/onVisualizationSave.js +32 -240
  82. package/esm/store/sideEffects/onVisualizationSuccessSave.d.ts +3 -4
  83. package/esm/store/sideEffects/onVisualizationSuccessSave.d.ts.map +1 -1
  84. package/esm/store/sideEffects/onVisualizationSuccessSave.js +16 -49
  85. package/esm/store/sideEffects/utils.d.ts +0 -2
  86. package/esm/store/sideEffects/utils.d.ts.map +1 -1
  87. package/esm/store/sideEffects/utils.js +0 -14
  88. package/package.json +20 -19
  89. package/styles/css/main.css +12 -496
  90. package/styles/css/main.css.map +1 -1
  91. package/styles/css/messages.css +12 -496
  92. package/styles/css/messages.css.map +1 -1
  93. package/styles/scss/messages.scss +14 -375
  94. package/esm/components/messages/AssistantMessage.d.ts +0 -8
  95. package/esm/components/messages/AssistantMessage.d.ts.map +0 -1
  96. package/esm/components/messages/AssistantMessage.js +0 -35
  97. package/esm/components/messages/MessageContents.d.ts +0 -12
  98. package/esm/components/messages/MessageContents.d.ts.map +0 -1
  99. package/esm/components/messages/MessageContents.js +0 -49
  100. package/esm/components/messages/ReasoningDropdown.d.ts +0 -14
  101. package/esm/components/messages/ReasoningDropdown.d.ts.map +0 -1
  102. package/esm/components/messages/ReasoningDropdown.js +0 -42
  103. package/esm/components/messages/ReasoningMessage.d.ts +0 -9
  104. package/esm/components/messages/ReasoningMessage.d.ts.map +0 -1
  105. package/esm/components/messages/ReasoningMessage.js +0 -45
  106. package/esm/components/messages/UserMessage.d.ts +0 -8
  107. package/esm/components/messages/UserMessage.d.ts.map +0 -1
  108. package/esm/components/messages/UserMessage.js +0 -10
  109. package/esm/components/messages/contents/ChangeAnalysisContentsComponent.d.ts +0 -12
  110. package/esm/components/messages/contents/ChangeAnalysisContentsComponent.d.ts.map +0 -1
  111. package/esm/components/messages/contents/ChangeAnalysisContentsComponent.js +0 -36
  112. package/esm/components/messages/contents/ErrorContents.d.ts +0 -7
  113. package/esm/components/messages/contents/ErrorContents.d.ts.map +0 -1
  114. package/esm/components/messages/contents/ErrorContents.js +0 -8
  115. package/esm/components/messages/contents/ReasoningContents.d.ts +0 -6
  116. package/esm/components/messages/contents/ReasoningContents.d.ts.map +0 -1
  117. package/esm/components/messages/contents/ReasoningContents.js +0 -43
  118. package/esm/components/messages/contents/RoutingContents.d.ts +0 -8
  119. package/esm/components/messages/contents/RoutingContents.d.ts.map +0 -1
  120. package/esm/components/messages/contents/RoutingContents.js +0 -8
  121. package/esm/components/messages/contents/SearchContents.d.ts +0 -7
  122. package/esm/components/messages/contents/SearchContents.d.ts.map +0 -1
  123. package/esm/components/messages/contents/SearchContents.js +0 -15
  124. package/esm/components/messages/contents/SemanticSearchContents.d.ts +0 -8
  125. package/esm/components/messages/contents/SemanticSearchContents.d.ts.map +0 -1
  126. package/esm/components/messages/contents/SemanticSearchContents.js +0 -27
  127. package/esm/components/messages/contents/TextContents.d.ts +0 -7
  128. package/esm/components/messages/contents/TextContents.d.ts.map +0 -1
  129. package/esm/components/messages/contents/TextContents.js +0 -8
  130. package/esm/components/messages/contents/VisualizationContents.d.ts +0 -24
  131. package/esm/components/messages/contents/VisualizationContents.d.ts.map +0 -1
  132. package/esm/components/messages/contents/VisualizationContents.js +0 -532
  133. package/esm/components/messages/contents/VisualizationSaveDialog.d.ts +0 -13
  134. package/esm/components/messages/contents/VisualizationSaveDialog.d.ts.map +0 -1
  135. package/esm/components/messages/contents/VisualizationSaveDialog.js +0 -33
  136. package/esm/components/messages/contents/hooks/useVisualisationSaving.d.ts +0 -6
  137. package/esm/components/messages/contents/hooks/useVisualisationSaving.d.ts.map +0 -1
  138. package/esm/components/messages/contents/hooks/useVisualisationSaving.js +0 -17
  139. package/esm/components/messages/contents/useExecution.d.ts +0 -14
  140. package/esm/components/messages/contents/useExecution.d.ts.map +0 -1
  141. package/esm/components/messages/contents/useExecution.js +0 -131
  142. package/esm/components/messages/contents/useKdaDefinition.d.ts +0 -13
  143. package/esm/components/messages/contents/useKdaDefinition.d.ts.map +0 -1
  144. package/esm/components/messages/contents/useKdaDefinition.js +0 -140
  145. package/esm/components/messages/messageState.d.ts +0 -12
  146. package/esm/components/messages/messageState.d.ts.map +0 -1
  147. package/esm/components/messages/messageState.js +0 -21
  148. package/esm/store/sideEffects/converters/interactionsToMessages.d.ts +0 -19
  149. package/esm/store/sideEffects/converters/interactionsToMessages.d.ts.map +0 -1
  150. package/esm/store/sideEffects/converters/interactionsToMessages.js +0 -82
@@ -1 +1 @@
1
- {"version":3,"file":"onUserMessage.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onUserMessage.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,iBAAiB,EAWzB,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAOlC,MAAM,gBAAgB,CAAC;AAkBxB,OAAO,EAUH,KAAK,gBAAgB,EAGxB,MAAM,8BAA8B,CAAC;AAOtC;;;GAGG;AACH,wBAAiB,aAAa,CAAC,EAAE,OAAO,EAAE,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oJAmB9E"}
1
+ {"version":3,"file":"onUserMessage.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onUserMessage.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,iBAAiB,EASzB,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EACH,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAElC,MAAM,gBAAgB,CAAC;AAiBxB,OAAO,EAUH,KAAK,gBAAgB,EAGxB,MAAM,8BAA8B,CAAC;AAMtC;;;GAGG;AACH,wBAAiB,aAAa,CAAC,EAAE,OAAO,EAAE,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oJAS9E"}
@@ -1,179 +1,25 @@
1
1
  // (C) 2024-2026 GoodData Corporation
2
2
  import { call, cancel, cancelled, getContext, put, select } from "redux-saga/effects";
3
3
  import { isChatConversationError, isChatConversationInteractionStep, isChatConversationItem, } from "@gooddata/sdk-backend-spi";
4
- import { isChatConversationLocalItem, isTextContents, isUserMessage, makeAssistantItem, makeAssistantMessage, } from "../../model.js";
4
+ import { makeAssistantItem, } from "../../model.js";
5
5
  import { generateTitleFromQuestion } from "../../utils.js";
6
6
  import { agentSwitchingActiveSelector, allowedRelationshipTypesSelector, objectTypesSelector, settingsSelector, tagsSelector, userContextSelector, } from "../chatWindow/chatWindowSelectors.js";
7
- import { conversationEffortSelector, conversationMessagesByIdSelector, conversationSelector, messagesSelector, pendingAgentSwitchSelector, selectedAgentIdSelector, } from "../messages/messagesSelectors.js";
7
+ import { conversationEffortSelector, conversationMessagesByIdSelector, conversationSelector, pendingAgentSwitchSelector, selectedAgentIdSelector, } from "../messages/messagesSelectors.js";
8
8
  import { appendInteractionStepAction, appendResponseDetailAction, appendTracedActionAction, applyPendingAgentSwitchAction, evaluateMessageAction, evaluateMessageCompleteAction, evaluateMessageErrorAction, evaluateMessageStreamingAction, evaluateMessageUpdateAction, revertAgentSwitchAction, setCurrentConversationAction, } from "../messages/messagesSlice.js";
9
- import { processContents } from "./converters/interactionsToMessages.js";
10
9
  import { convertToLocalContent } from "./converters/toLocalContent.js";
11
10
  import { notifyDefinitionReceived } from "./onDefinitionReceivedTrigger.js";
12
- import { convertMessageToChatConversation, extractError } from "./utils.js";
11
+ import { extractError } from "./utils.js";
13
12
  /**
14
13
  * Load thread history and put it to the store.
15
14
  * @internal
16
15
  */
17
16
  export function* onUserMessage({ payload }) {
18
17
  const conversation = yield select(conversationSelector);
19
- let message = payload;
20
- if (conversation && !isChatConversationLocalItem(message)) {
21
- message = convertMessageToChatConversation(message);
22
- }
23
- if (isChatConversationLocalItem(message)) {
24
- if (!conversation) {
25
- throw new Error("Thread mode is turned on, but conversation message was provided.");
26
- }
27
- yield conversationUserMessage(message);
28
- }
29
- else {
30
- if (conversation) {
31
- throw new Error("Conversation mode is turned on, but thread message was provided.");
32
- }
33
- yield threadUserMessage(message);
34
- }
35
- }
36
- //THREAD API
37
- function* threadUserMessage(message) {
38
- let initialAssistantMessage = undefined;
39
- let lastAssistantMessage = undefined;
40
- try {
41
- // Make sure the message is a user message and it got text contents
42
- if (!isUserMessage(message)) {
43
- return;
44
- }
45
- const textContents = message.content.find(isTextContents)?.text;
46
- if (!textContents) {
47
- return;
48
- }
49
- // Create a new empty assistant message
50
- initialAssistantMessage = makeAssistantMessage([]);
51
- // Set evaluation state in store
52
- yield put(evaluateMessageAction({ message: initialAssistantMessage }));
53
- // Retrieve backend from context
54
- const backend = yield getContext("backend");
55
- const workspace = yield getContext("workspace");
56
- // Make the request to start the evaluation
57
- const chatThreadQuery = backend.workspace(workspace).genAI().getChatThread().query(textContents);
58
- // evaluateUserMessage may create additional assistant messages if the stream contains
59
- // multiple interaction IDs. It returns the last message that needs to be completed.
60
- const result = yield call(evaluateUserMessage, initialAssistantMessage, chatThreadQuery);
61
- lastAssistantMessage = result.lastAssistantMessage;
62
- }
63
- catch (e) {
64
- const wasCanceled = yield cancelled();
65
- // On error, mark the last known message (or initial if no result yet)
66
- const messageToError = lastAssistantMessage ?? initialAssistantMessage;
67
- if (messageToError && !wasCanceled) {
68
- yield put(evaluateMessageErrorAction({
69
- assistantMessageId: messageToError.localId,
70
- error: extractError(e),
71
- }));
72
- }
73
- }
74
- finally {
75
- const wasCanceled = yield cancelled();
76
- // Mark the last assistant message as complete
77
- const messageToComplete = lastAssistantMessage ?? initialAssistantMessage;
78
- if (messageToComplete) {
79
- // Check if the message still exists before marking it complete
80
- // (it may have been removed if the chat was cleared)
81
- const currentMessages = yield select(messagesSelector);
82
- const messageExists = currentMessages.some((m) => m.localId === messageToComplete.localId);
83
- if (messageExists) {
84
- yield put(evaluateMessageCompleteAction({
85
- assistantMessageId: messageToComplete.localId,
86
- cancelled: wasCanceled,
87
- }));
88
- }
89
- }
90
- }
91
- }
92
- function* evaluateUserMessage(message, preparedChatThread) {
93
- let reader = undefined;
94
- const settings = yield select(settingsSelector);
95
- const objectTypes = yield select(objectTypesSelector);
96
- const allowedRelationshipTypes = yield select(allowedRelationshipTypesSelector);
97
- const context = yield select(userContextSelector);
98
- const showReasoning = Boolean(settings?.enableGenAIReasoningVisibility);
99
- // Track interaction ID to assistant message mapping
100
- let currentAssistantMessage = message;
101
- let currentInteractionId = undefined;
102
- let queryBuilder = preparedChatThread
103
- .withSearchLimit(Number(settings?.["aiChatSearchLimit"]) || 10)
104
- .withObjectTypes(objectTypes);
105
- if (allowedRelationshipTypes?.length) {
106
- queryBuilder = queryBuilder.withAllowedRelationshipTypes(allowedRelationshipTypes);
107
- }
108
- if (context) {
109
- queryBuilder = queryBuilder.withUserContext(context);
110
- }
111
- try {
112
- const results = yield call([queryBuilder, queryBuilder.stream]);
113
- reader = results.getReader();
114
- while (true) {
115
- const { value, done } = yield call([
116
- reader,
117
- reader.read,
118
- ]);
119
- if (done) {
120
- break;
121
- }
122
- if (value) {
123
- const chunkInteractionId = value.chatHistoryInteractionId;
124
- // If we see a NEW interaction ID, create a new assistant message
125
- if (chunkInteractionId &&
126
- currentInteractionId &&
127
- chunkInteractionId !== currentInteractionId) {
128
- // Check if the current message still exists before marking it complete
129
- // (it may have been removed if the chat was cleared)
130
- const currentMessages = yield select(messagesSelector);
131
- const messageExists = currentMessages.some((m) => m.localId === currentAssistantMessage.localId);
132
- if (messageExists) {
133
- // Mark current message as complete
134
- yield put(evaluateMessageCompleteAction({
135
- assistantMessageId: currentAssistantMessage.localId,
136
- }));
137
- }
138
- // Create new assistant message for the new interaction
139
- currentAssistantMessage = makeAssistantMessage([]);
140
- yield put(evaluateMessageAction({ message: currentAssistantMessage }));
141
- }
142
- // Track the current interaction ID
143
- if (chunkInteractionId) {
144
- currentInteractionId = chunkInteractionId;
145
- }
146
- // Dispatch streaming content to current message
147
- const contents = processContents(value, true, { showReasoning });
148
- yield put(evaluateMessageStreamingAction({
149
- assistantMessageId: currentAssistantMessage.localId,
150
- interactionId: chunkInteractionId,
151
- contents,
152
- }));
153
- yield call(notifyDefinitionReceived, {
154
- ...currentAssistantMessage,
155
- content: contents,
156
- id: chunkInteractionId,
157
- }, "");
158
- }
159
- }
160
- return { lastAssistantMessage: currentAssistantMessage };
161
- }
162
- finally {
163
- if (reader) {
164
- const wasCancelled = yield cancelled();
165
- if (wasCancelled) {
166
- yield call([reader, reader.cancel]);
167
- }
168
- yield call([reader, reader.releaseLock]);
169
- }
170
- //Cancel saga
171
- const messages = yield select(messagesSelector);
172
- const found = messages.find((m) => m.localId === currentAssistantMessage.localId);
173
- if (!found) {
174
- yield cancel();
175
- }
18
+ const message = payload;
19
+ if (!conversation) {
20
+ throw new Error("Thread mode is turned on, but conversation message was provided.");
176
21
  }
22
+ yield conversationUserMessage(message);
177
23
  }
178
24
  //CONVERSATIONS API
179
25
  function* conversationUserMessage(message) {
@@ -1,6 +1,4 @@
1
1
  import { type PayloadAction } from "@reduxjs/toolkit";
2
- import { type IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
3
- import { type Message } from "../../model.js";
4
2
  /**
5
3
  * Visualisation render status to server.
6
4
  * Optimistic update, ignoring the error.
@@ -10,16 +8,12 @@ export declare function onVisualisationRender({ payload, }: PayloadAction<{
10
8
  visualizationId: string;
11
9
  assistantMessageId: string;
12
10
  status: "SUCCESSFUL" | "UNEXPECTED_ERROR" | "TOO_MANY_DATA_POINTS" | "NO_DATA" | "NO_RESULTS";
13
- }>): Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").GetContextEffect | import("redux-saga/effects").PutEffect<{
11
+ }>): Generator<import("redux-saga/effects").PutEffect<{
14
12
  payload: {
15
13
  visualizationId: string;
16
14
  assistantMessageId: string;
17
15
  status: "SUCCESSFUL" | "UNEXPECTED_ERROR" | "TOO_MANY_DATA_POINTS" | "NO_DATA" | "NO_RESULTS";
18
16
  };
19
17
  type: "messages/saveVisualisationRenderStatusSuccessAction";
20
- }> | import("redux-saga/effects").SelectEffect, void, IAnalyticalBackend & string & import("@gooddata/sdk-backend-spi").IChatConversation & {
21
- localId: string;
22
- generatingTitle?: boolean;
23
- inProgress?: boolean;
24
- } & Message[]>;
18
+ }>, void, unknown>;
25
19
  //# sourceMappingURL=onVisualisationRender.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"onVisualisationRender.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onVisualisationRender.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,EAA+B,KAAK,OAAO,EAA2B,MAAM,gBAAgB,CAAC;AAMpG;;;;GAIG;AACH,wBAAiB,qBAAqB,CAAC,EACnC,OAAO,GACV,EAAE,aAAa,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,YAAY,GAAG,kBAAkB,GAAG,sBAAsB,GAAG,SAAS,GAAG,YAAY,CAAC;CACjG,CAAC;;;;;;;;;;;eAuCD"}
1
+ {"version":3,"file":"onVisualisationRender.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onVisualisationRender.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOtD;;;;GAIG;AACH,wBAAiB,qBAAqB,CAAC,EACnC,OAAO,GACV,EAAE,aAAa,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,YAAY,GAAG,kBAAkB,GAAG,sBAAsB,GAAG,SAAS,GAAG,YAAY,CAAC;CACjG,CAAC;;;;;;;mBAMD"}
@@ -1,7 +1,5 @@
1
1
  // (C) 2024-2026 GoodData Corporation
2
- import { call, getContext, put, select } from "redux-saga/effects";
3
- import { isVisualizationContents } from "../../model.js";
4
- import { conversationSelector, messagesSelector } from "../messages/messagesSelectors.js";
2
+ import { put } from "redux-saga/effects";
5
3
  import { saveVisualisationRenderStatusSuccessAction } from "../messages/messagesSlice.js";
6
4
  import { extractError } from "./utils.js";
7
5
  /**
@@ -10,32 +8,7 @@ import { extractError } from "./utils.js";
10
8
  * @internal
11
9
  */
12
10
  export function* onVisualisationRender({ payload, }) {
13
- // Retrieve backend from context
14
- const backend = yield getContext("backend");
15
- const workspace = yield getContext("workspace");
16
- const conversation = yield select(conversationSelector);
17
11
  try {
18
- if (conversation) {
19
- // NOTE: In new conversations, the render status is now
20
- // not saved to the server, so we can skip this.
21
- yield put(saveVisualisationRenderStatusSuccessAction(payload));
22
- return;
23
- }
24
- const messages = yield select(messagesSelector);
25
- const message = messages.find((message) => message.localId === payload.assistantMessageId);
26
- if (!message?.id) {
27
- return;
28
- }
29
- const visualization = message.content
30
- .filter(isVisualizationContents)
31
- .flatMap((content) => content.createdVisualizations)
32
- .find((content) => content.id === payload.visualizationId);
33
- // Already reported
34
- if (!visualization?.statusReportPending) {
35
- return;
36
- }
37
- const chatThread = backend.workspace(workspace).genAI().getChatThread();
38
- yield call([chatThread, chatThread.saveRenderVisualisationStatus], message.id, payload.status);
39
12
  yield put(saveVisualisationRenderStatusSuccessAction(payload));
40
13
  }
41
14
  catch (e) {
@@ -1,7 +1,7 @@
1
1
  import { type PayloadAction } from "@reduxjs/toolkit";
2
2
  import { type IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
3
- import { type IGenAIVisualization, type IInsight, type IInsightDefinition } from "@gooddata/sdk-model";
4
- import { type IChatConversationLocalItem, type Message } from "../../model.js";
3
+ import { type IInsight } from "@gooddata/sdk-model";
4
+ import { type IChatConversationLocalItem } from "../../model.js";
5
5
  export declare function onVisualizationSave({ payload, }: PayloadAction<{
6
6
  visualizationId: string;
7
7
  visualizationTitle: string;
@@ -31,13 +31,12 @@ export declare function onVisualizationSave({ payload, }: PayloadAction<{
31
31
  localId: string;
32
32
  generatingTitle?: boolean;
33
33
  inProgress?: boolean;
34
- } & IChatConversationLocalItem[] & IInsightDefinition & import("@gooddata/sdk-model").IInsightIdentity & {
34
+ } & IChatConversationLocalItem[] & import("@gooddata/sdk-model").IInsightDefinition & import("@gooddata/sdk-model").IInsightIdentity & {
35
35
  insight: import("@gooddata/sdk-model").IAuditable & {
36
36
  isLocked?: boolean;
37
37
  isDraft?: boolean;
38
+ permissions?: import("@gooddata/sdk-model").AccessGranularPermission[];
38
39
  certification?: import("@gooddata/sdk-model").IObjectCertification;
39
40
  };
40
- } & Message[]>;
41
- export declare const buildLineChart: (visualizationContent: IGenAIVisualization, visualizationTitle: string) => IInsightDefinition;
42
- export declare const buildScatterPlot: (visualizationContent: IGenAIVisualization, visualizationTitle: string) => IInsightDefinition;
41
+ }>;
43
42
  //# sourceMappingURL=onVisualizationSave.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"onVisualizationSave.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onVisualizationSave.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAGH,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,KAAK,kBAAkB,EAG1B,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAEH,KAAK,0BAA0B,EAE/B,KAAK,OAAO,EAEf,MAAM,gBAAgB,CAAC;AASxB,wBAAiB,mBAAmB,CAAC,EACjC,OAAO,GACV,EAAE,aAAa,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAgHD;AAoGD,eAAO,MAAM,cAAc,yBACD,mBAAmB,sBACrB,MAAM,KAC3B,kBAuCF,CAAC;AAEF,eAAO,MAAM,gBAAgB,yBACH,mBAAmB,sBACrB,MAAM,KAC3B,kBAiCF,CAAC"}
1
+ {"version":3,"file":"onVisualizationSave.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onVisualizationSave.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,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAEH,KAAK,0BAA0B,EAElC,MAAM,gBAAgB,CAAC;AAIxB,wBAAiB,mBAAmB,CAAC,EACjC,OAAO,GACV,EAAE,aAAa,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqED"}
@@ -1,14 +1,6 @@
1
1
  // (C) 2024-2026 GoodData Corporation
2
2
  import { call, getContext, put, select } from "redux-saga/effects";
3
- import { applyRatioRule, newBucket, } from "@gooddata/sdk-model";
4
- import { BucketNames } from "@gooddata/sdk-ui";
5
- import { mapVisualizationAnomalyDetectionToChartConfig } from "../../anomalyDetection/anomalyDetectionMapping.js";
6
- import { mapVisualizationClusteringToChartConfig } from "../../clustering/clusteringMapping.js";
7
- import { prepareExecution } from "../../components/messages/contents/useExecution.js";
8
- import { mapVisualizationForecastToChartConfig } from "../../forecast/forecastMapping.js";
9
- import { isVisualizationContents, } from "../../model.js";
10
- import { getHeadlineComparison } from "../../utils.js";
11
- import { conversationMessagesSelector, conversationSelector, messagesSelector, } from "../messages/messagesSelectors.js";
3
+ import { conversationMessagesSelector, conversationSelector } from "../messages/messagesSelectors.js";
12
4
  import { saveVisualizationErrorAction, saveVisualizationSuccessAction } from "../messages/messagesSlice.js";
13
5
  export function* onVisualizationSave({ payload, }) {
14
6
  // Retrieve backend from context
@@ -16,65 +8,39 @@ export function* onVisualizationSave({ payload, }) {
16
8
  const workspace = yield getContext("workspace");
17
9
  const conversation = yield select(conversationSelector);
18
10
  try {
19
- if (conversation) {
20
- const messages = yield select(conversationMessagesSelector);
21
- const assistantMessage = messages.find((message) => message.localId === payload.assistantMessageId);
22
- if (assistantMessage?.content.type !== "multipart") {
23
- return;
24
- }
25
- const visualizationContent = assistantMessage.content.parts
26
- .filter((filter) => filter.type === "visualization")
27
- .find((content) => content.visualization?.insight.identifier === payload.visualizationId);
28
- if (!visualizationContent?.visualization) {
29
- return;
30
- }
31
- const sourceVisualization = visualizationContent.visualization;
32
- const insightsService = backend.workspace(workspace).insights();
33
- const savedVisualization = yield call(insightsService.createInsight.bind(insightsService), {
34
- ...sourceVisualization,
35
- insight: {
36
- ...sourceVisualization.insight,
37
- title: payload.visualizationTitle,
38
- },
39
- });
40
- const resave = backend
41
- .workspace(workspace)
42
- .genAI()
43
- .getChatConversations()
44
- .getConversationThread(conversation.id);
45
- yield call(resave.resaveVisualisation.bind(resave), sourceVisualization.insight.identifier, savedVisualization.insight.identifier);
46
- yield put(saveVisualizationSuccessAction({
47
- visualizationId: payload.visualizationId,
48
- assistantMessageId: payload.assistantMessageId,
49
- savedVisualizationId: savedVisualization.insight.identifier,
50
- explore: payload.explore,
51
- conversationId: conversation.localId,
52
- }));
11
+ const messages = yield select(conversationMessagesSelector);
12
+ const assistantMessage = messages.find((message) => message.localId === payload.assistantMessageId);
13
+ if (assistantMessage?.content.type !== "multipart") {
14
+ return;
53
15
  }
54
- else {
55
- const messages = yield select(messagesSelector);
56
- const assistantMessage = messages.find((message) => message.localId === payload.assistantMessageId);
57
- if (!assistantMessage) {
58
- return;
59
- }
60
- // Find the content with the visualization
61
- const visualizationContent = assistantMessage.content
62
- .filter(isVisualizationContents)
63
- .flatMap((content) => content.createdVisualizations)
64
- .find((visualization) => visualization.id === payload.visualizationId);
65
- if (!visualizationContent) {
66
- return;
67
- }
68
- const visDefinition = buildInsightDefinition(visualizationContent, payload.visualizationTitle);
69
- const insightsService = backend.workspace(workspace).insights();
70
- const savedVisualization = yield call(insightsService.createInsight.bind(insightsService), visDefinition);
71
- yield put(saveVisualizationSuccessAction({
72
- visualizationId: payload.visualizationId,
73
- assistantMessageId: payload.assistantMessageId,
74
- savedVisualizationId: savedVisualization.insight.identifier,
75
- explore: payload.explore,
76
- }));
16
+ const visualizationContent = assistantMessage.content.parts
17
+ .filter((filter) => filter.type === "visualization")
18
+ .find((content) => content.visualization?.insight.identifier === payload.visualizationId);
19
+ if (!visualizationContent?.visualization) {
20
+ return;
77
21
  }
22
+ const sourceVisualization = visualizationContent.visualization;
23
+ const insightsService = backend.workspace(workspace).insights();
24
+ const savedVisualization = yield call(insightsService.createInsight.bind(insightsService), {
25
+ ...sourceVisualization,
26
+ insight: {
27
+ ...sourceVisualization.insight,
28
+ title: payload.visualizationTitle,
29
+ },
30
+ });
31
+ const resave = backend
32
+ .workspace(workspace)
33
+ .genAI()
34
+ .getChatConversations()
35
+ .getConversationThread(conversation.id);
36
+ yield call(resave.resaveVisualisation.bind(resave), sourceVisualization.insight.identifier, savedVisualization.insight.identifier);
37
+ yield put(saveVisualizationSuccessAction({
38
+ visualizationId: payload.visualizationId,
39
+ assistantMessageId: payload.assistantMessageId,
40
+ savedVisualizationId: savedVisualization.insight.identifier,
41
+ explore: payload.explore,
42
+ conversationId: conversation.localId,
43
+ }));
78
44
  }
79
45
  catch (e) {
80
46
  console.error(e);
@@ -90,177 +56,3 @@ export function* onVisualizationSave({ payload, }) {
90
56
  }));
91
57
  }
92
58
  }
93
- const buildInsightDefinition = (visualizationContent, visualizationTitle) => {
94
- switch (visualizationContent.visualizationType) {
95
- case "BAR":
96
- return buildBarChart(visualizationContent, visualizationTitle);
97
- case "COLUMN":
98
- return buildColumnChart(visualizationContent, visualizationTitle);
99
- case "PIE":
100
- return buildPieChart(visualizationContent, visualizationTitle);
101
- case "LINE":
102
- return buildLineChart(visualizationContent, visualizationTitle);
103
- case "SCATTER":
104
- return buildScatterPlot(visualizationContent, visualizationTitle);
105
- case "TABLE":
106
- return buildTableChart(visualizationContent, visualizationTitle);
107
- case "HEADLINE":
108
- return buildHeadlineChart(visualizationContent, visualizationTitle);
109
- default:
110
- return assertNever(visualizationContent.visualizationType);
111
- }
112
- };
113
- const assertNever = (type) => {
114
- throw new Error(`Unknown visualization type ${type}`);
115
- };
116
- const buildBarChart = (visualizationContent, visualizationTitle) => {
117
- const exec = prepareExecution(visualizationContent);
118
- const metrics = applyRatioRule(exec.metrics);
119
- const viewBy = exec.dimensions.slice(0, 2);
120
- const stackBy = exec.dimensions[2];
121
- const buckets = [
122
- newBucket(BucketNames.MEASURES, ...metrics),
123
- newBucket(BucketNames.VIEW, ...viewBy),
124
- ];
125
- if (stackBy) {
126
- newBucket(BucketNames.STACK, stackBy);
127
- }
128
- return {
129
- insight: {
130
- title: visualizationTitle,
131
- visualizationUrl: "local:bar",
132
- buckets: buckets,
133
- filters: exec.filters,
134
- sorts: [],
135
- properties: exec.metrics.length > 1 && exec.dimensions.length === 2
136
- ? {
137
- controls: {
138
- stackMeasures: true,
139
- },
140
- }
141
- : {},
142
- },
143
- };
144
- };
145
- const buildColumnChart = (visualizationContent, visualizationTitle) => {
146
- const definition = buildBarChart(visualizationContent, visualizationTitle);
147
- definition.insight.visualizationUrl = "local:column";
148
- return definition;
149
- };
150
- const buildPieChart = (visualizationContent, visualizationTitle) => {
151
- const exec = prepareExecution(visualizationContent);
152
- const metrics = applyRatioRule(exec.metrics);
153
- const viewBy = metrics.length <= 1 ? exec.dimensions.slice(0, 2) : [];
154
- return {
155
- insight: {
156
- title: visualizationTitle,
157
- visualizationUrl: "local:pie",
158
- buckets: [newBucket(BucketNames.MEASURES, ...metrics), newBucket(BucketNames.VIEW, ...viewBy)],
159
- filters: exec.filters,
160
- sorts: [],
161
- properties: {},
162
- },
163
- };
164
- };
165
- export const buildLineChart = (visualizationContent, visualizationTitle) => {
166
- const exec = prepareExecution(visualizationContent);
167
- const metrics = applyRatioRule(exec.metrics);
168
- const viewBy = exec.dimensions[0];
169
- const segmentBy = exec.dimensions[1];
170
- const buckets = [
171
- newBucket(BucketNames.MEASURES, ...metrics),
172
- newBucket(BucketNames.TREND, viewBy),
173
- ];
174
- if (segmentBy && metrics.length <= 1) {
175
- newBucket(BucketNames.SEGMENT, segmentBy);
176
- }
177
- const forecast = mapVisualizationForecastToChartConfig(visualizationContent.config);
178
- const anomalies = mapVisualizationAnomalyDetectionToChartConfig(visualizationContent.config);
179
- const controls = {
180
- ...(forecast ? { forecast } : {}),
181
- ...(anomalies ? { anomalies } : {}),
182
- };
183
- return {
184
- insight: {
185
- title: visualizationTitle,
186
- visualizationUrl: "local:line",
187
- buckets: buckets,
188
- filters: exec.filters,
189
- sorts: [],
190
- properties: {
191
- legend: {
192
- responsive: "autoPositionWithPopup",
193
- },
194
- ...(Object.keys(controls).length > 0 ? { controls } : {}),
195
- },
196
- },
197
- };
198
- };
199
- export const buildScatterPlot = (visualizationContent, visualizationTitle) => {
200
- const exec = prepareExecution(visualizationContent);
201
- const metrics = applyRatioRule(exec.metrics);
202
- const xAxisMeasure = metrics[0];
203
- const yAxisMeasure = metrics[1];
204
- const attribute = exec.dimensions[0];
205
- const segmentBy = exec.dimensions[1];
206
- const buckets = [
207
- newBucket(BucketNames.MEASURES, xAxisMeasure),
208
- newBucket(BucketNames.SECONDARY_MEASURES, yAxisMeasure),
209
- newBucket(BucketNames.ATTRIBUTE, attribute),
210
- ];
211
- if (segmentBy) {
212
- buckets.push(newBucket(BucketNames.SEGMENT, segmentBy));
213
- }
214
- const clustering = mapVisualizationClusteringToChartConfig(visualizationContent.config);
215
- return {
216
- insight: {
217
- title: visualizationTitle,
218
- visualizationUrl: "local:scatter",
219
- buckets: buckets,
220
- filters: exec.filters,
221
- sorts: [],
222
- properties: {
223
- ...(clustering ? { controls: { clustering } } : {}),
224
- },
225
- },
226
- };
227
- };
228
- const buildTableChart = (visualizationContent, visualizationTitle) => {
229
- const exec = prepareExecution(visualizationContent);
230
- const buckets = [
231
- newBucket(BucketNames.MEASURES, ...applyRatioRule(exec.metrics)),
232
- newBucket(BucketNames.ATTRIBUTE, ...exec.dimensions),
233
- ];
234
- return {
235
- insight: {
236
- title: visualizationTitle,
237
- visualizationUrl: "local:table",
238
- buckets: buckets,
239
- filters: exec.filters,
240
- sorts: [],
241
- properties: {},
242
- },
243
- };
244
- };
245
- const buildHeadlineChart = (visualizationContent, visualizationTitle) => {
246
- const exec = prepareExecution(visualizationContent);
247
- const metrics = applyRatioRule(exec.metrics);
248
- const buckets = [newBucket(BucketNames.MEASURES, metrics[0])];
249
- if (metrics.length > 1) {
250
- buckets.push(newBucket(BucketNames.SECONDARY_MEASURES, ...[metrics[1], metrics[2]].filter(Boolean)));
251
- }
252
- return {
253
- insight: {
254
- title: visualizationTitle,
255
- visualizationUrl: "local:headline",
256
- buckets,
257
- filters: exec.filters,
258
- sorts: [],
259
- properties: {
260
- controls: {
261
- ...getHeadlineComparison(metrics),
262
- },
263
- },
264
- },
265
- };
266
- };
@@ -1,15 +1,14 @@
1
1
  import { type PayloadAction } from "@reduxjs/toolkit";
2
- import { type IAnalyticalBackend, type IUserWorkspaceSettings } from "@gooddata/sdk-backend-spi";
3
- import { type Message } from "../../model.js";
2
+ import { type IUserWorkspaceSettings } from "@gooddata/sdk-backend-spi";
4
3
  import { type OptionsDispatcher } from "../options.js";
5
4
  export declare function onVisualizationSuccessSave({ payload, }: PayloadAction<{
6
5
  visualizationId: string;
7
6
  assistantMessageId: string;
8
7
  savedVisualizationId: string;
9
8
  explore: boolean;
10
- }>): Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").GetContextEffect | import("redux-saga/effects").SelectEffect, void, IAnalyticalBackend & string & OptionsDispatcher & import("@gooddata/sdk-backend-spi").IChatConversation & {
9
+ }>): Generator<import("redux-saga/effects").GetContextEffect | import("redux-saga/effects").SelectEffect, void, string & OptionsDispatcher & import("@gooddata/sdk-backend-spi").IChatConversation & {
11
10
  localId: string;
12
11
  generatingTitle?: boolean;
13
12
  inProgress?: boolean;
14
- } & IUserWorkspaceSettings & Message[]>;
13
+ } & IUserWorkspaceSettings>;
15
14
  //# sourceMappingURL=onVisualizationSuccessSave.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"onVisualizationSuccessSave.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onVisualizationSuccessSave.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGjG,OAAO,EAA+B,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAI3E,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,wBAAiB,0BAA0B,CAAC,EACxC,OAAO,GACV,EAAE,aAAa,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;;;;wCAmFD"}
1
+ {"version":3,"file":"onVisualizationSuccessSave.d.ts","sourceRoot":"","sources":["../../../src/store/sideEffects/onVisualizationSuccessSave.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAMxE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,wBAAiB,0BAA0B,CAAC,EACxC,OAAO,GACV,EAAE,aAAa,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;;;;4BAqCD"}