@zeniai/client-epic-state 4.16.81 → 4.16.82
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/lib/entity/aiController/aiControllerPayload.d.ts +1 -1
- package/lib/entity/aiController/aiControllerReducer.d.ts +4 -1
- package/lib/entity/aiController/aiControllerReducer.js +266 -90
- package/lib/entity/aiController/aiControllerState.d.ts +3 -1
- package/lib/view/aiControllerView/aiControllerViewReducer.d.ts +4 -1
- package/lib/view/aiControllerView/aiControllerViewReducer.js +27 -5
- package/lib/view/aiControllerView/aiControllerViewSelector.d.ts +1 -0
- package/lib/view/aiControllerView/aiControllerViewSelector.js +3 -2
- package/lib/view/aiControllerView/aiControllerViewState.d.ts +5 -2
- package/lib/view/aiControllerView/epics/fetchChatHistoryEpic.d.ts +1 -1
- package/lib/view/aiControllerView/epics/fetchChatHistoryEpic.js +15 -3
- package/lib/view/aiControllerView/epics/fetchChatSessionsForUserEpic.d.ts +1 -1
- package/lib/view/aiControllerView/epics/fetchChatSessionsForUserEpic.js +15 -3
- package/lib/view/aiControllerView/epics/submitQuestionEpic.d.ts +2 -2
- package/lib/view/aiControllerView/epics/submitQuestionEpic.js +6 -5
- package/lib/view/companyView/types/cockpitTypes.d.ts +2 -2
- package/package.json +1 -1
|
@@ -19,7 +19,6 @@ export interface AIControllerVisualizationPayload {
|
|
|
19
19
|
}
|
|
20
20
|
export interface AIControllerAnswerPayload {
|
|
21
21
|
text: string;
|
|
22
|
-
follow_up_questions?: string[];
|
|
23
22
|
state: string;
|
|
24
23
|
type: string;
|
|
25
24
|
visualization: AIControllerVisualizationPayload | null;
|
|
@@ -27,6 +26,7 @@ export interface AIControllerAnswerPayload {
|
|
|
27
26
|
assumptions: string | null;
|
|
28
27
|
insights: string | null;
|
|
29
28
|
summarized_title: string | null;
|
|
29
|
+
follow_up_questions?: string[];
|
|
30
30
|
}
|
|
31
31
|
export interface ChatSessionPayload {
|
|
32
32
|
chat_session_id: string;
|
|
@@ -12,6 +12,7 @@ export declare const setNewSession: import("@reduxjs/toolkit").ActionCreatorWith
|
|
|
12
12
|
}, "aiController/setNewSession">, clearSession: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "aiController/clearSession">, setSessions: import("@reduxjs/toolkit").ActionCreatorWithPayload<ChatSessionPayload[], "aiController/setSessions">, setChatHistory: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
13
13
|
chatSessionId: ID;
|
|
14
14
|
history: MessagePayload[];
|
|
15
|
+
isPaginationComplete?: boolean;
|
|
15
16
|
}, "aiController/setChatHistory">, upsertAnswerPayload: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
16
17
|
chatSessionId: ID;
|
|
17
18
|
answerPayload: AIControllerAnswerPayload;
|
|
@@ -40,6 +41,8 @@ export declare const setNewSession: import("@reduxjs/toolkit").ActionCreatorWith
|
|
|
40
41
|
}, "aiController/addQuestionPayload">, clearAIController: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"aiController/clearAIController">, deleteQuestion: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
41
42
|
chatSessionId: ID;
|
|
42
43
|
questionAnswerId: ID;
|
|
43
|
-
}, "aiController/deleteQuestion"
|
|
44
|
+
}, "aiController/deleteQuestion">, updateNewSession: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
45
|
+
chatSessionId: ID;
|
|
46
|
+
}, "aiController/updateNewSession">;
|
|
44
47
|
declare const _default: import("redux").Reducer<AIControllerState>;
|
|
45
48
|
export default _default;
|
|
@@ -1,105 +1,131 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.deleteQuestion = exports.clearAIController = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.setChatHistory = exports.setSessions = exports.clearSession = exports.setNewSession = exports.toAIControllerVisualization = exports.initialAIControllerState = void 0;
|
|
4
|
+
exports.updateNewSession = exports.deleteQuestion = exports.clearAIController = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.setChatHistory = exports.setSessions = exports.clearSession = exports.setNewSession = exports.toAIControllerVisualization = exports.initialAIControllerState = void 0;
|
|
5
5
|
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
6
|
const zeniDayJS_1 = require("../../zeniDayJS");
|
|
7
7
|
const aiControllerState_1 = require("./aiControllerState");
|
|
8
8
|
exports.initialAIControllerState = {
|
|
9
9
|
aiControllerByChatSessionId: {},
|
|
10
|
+
partialQuestionAnswers: {},
|
|
10
11
|
};
|
|
12
|
+
// Utility: Merge two arrays of Q&A pairs, combining responses for the same question
|
|
13
|
+
function mergeQuestionAnswerPairs(existing, newQAs) {
|
|
14
|
+
const merged = new Map();
|
|
15
|
+
// Add existing Q&A pairs
|
|
16
|
+
for (const qa of existing) {
|
|
17
|
+
merged.set(qa.questionAnswerId, Object.assign({}, qa));
|
|
18
|
+
}
|
|
19
|
+
// Merge new Q&A pairs
|
|
20
|
+
for (const newQA of newQAs) {
|
|
21
|
+
const existingQA = merged.get(newQA.questionAnswerId);
|
|
22
|
+
if (existingQA) {
|
|
23
|
+
// Merge responses
|
|
24
|
+
const mergedResponses = Object.assign(Object.assign({}, existingQA.responses), newQA.responses);
|
|
25
|
+
merged.set(newQA.questionAnswerId, Object.assign(Object.assign({}, newQA), { responses: mergedResponses }));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// Add new Q&A pair
|
|
29
|
+
merged.set(newQA.questionAnswerId, newQA);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Convert back to array and sort by question creation time
|
|
33
|
+
return Array.from(merged.values()).sort((a, b) => a.question.createdAt.valueOf() - b.question.createdAt.valueOf());
|
|
34
|
+
}
|
|
11
35
|
// Utility: Convert chat history (array of MessagePayload) to AIControllerQuestionWithAnswer[]
|
|
12
36
|
function chatHistoryToQA(history) {
|
|
37
|
+
var _a, _b, _c;
|
|
38
|
+
const questionGroups = new Map();
|
|
39
|
+
// First pass: collect all messages and group by message_id
|
|
40
|
+
for (const message of history) {
|
|
41
|
+
const messageId = message.message_id;
|
|
42
|
+
if (!questionGroups.has(messageId)) {
|
|
43
|
+
questionGroups.set(messageId, {
|
|
44
|
+
question: null,
|
|
45
|
+
responses: [],
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const group = questionGroups.get(messageId);
|
|
49
|
+
if (!group) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (message.sender === 'user') {
|
|
53
|
+
// User message is the question
|
|
54
|
+
group.question = message;
|
|
55
|
+
}
|
|
56
|
+
else if (message.sender === 'agent') {
|
|
57
|
+
// Agent message is a response block
|
|
58
|
+
group.responses.push(message);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Convert groups to AIControllerQuestionWithAnswer
|
|
13
62
|
const questionAnswerPairs = [];
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
while (lastUserMessageIndex + 1 < history.length &&
|
|
19
|
-
history[lastUserMessageIndex + 1].sender === 'user') {
|
|
20
|
-
lastUserMessageIndex++;
|
|
63
|
+
for (const [messageId, group] of questionGroups.entries()) {
|
|
64
|
+
// Skip groups that don't have a question
|
|
65
|
+
if (!group.question) {
|
|
66
|
+
continue;
|
|
21
67
|
}
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
text: parsedAgentMessage.text,
|
|
70
|
-
visualization: parsedAgentMessage.visualization
|
|
71
|
-
? (0, exports.toAIControllerVisualization)(parsedAgentMessage.visualization)
|
|
72
|
-
: undefined,
|
|
73
|
-
followUpQuestions: Array.isArray(parsedAgentMessage.follow_up_questions)
|
|
74
|
-
? parsedAgentMessage.follow_up_questions
|
|
75
|
-
: [],
|
|
76
|
-
assumptions: '',
|
|
77
|
-
insights: '',
|
|
78
|
-
summarizedTitle: undefined,
|
|
79
|
-
},
|
|
80
|
-
createdAt: (0, zeniDayJS_1.date)(agentMessage.created_at),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
catch (error) {
|
|
85
|
-
console.error('Failed to parse agent message: ', error);
|
|
68
|
+
const question = {
|
|
69
|
+
messageId: group.question.message_id,
|
|
70
|
+
chatSessionId: group.question.chat_session_id,
|
|
71
|
+
userId: group.question.user_id,
|
|
72
|
+
sender: (0, aiControllerState_1.toMessageSender)(group.question.sender),
|
|
73
|
+
state: 'complete',
|
|
74
|
+
questionText: group.question.content,
|
|
75
|
+
createdAt: (0, zeniDayJS_1.date)(group.question.created_at),
|
|
76
|
+
};
|
|
77
|
+
const responses = {};
|
|
78
|
+
// Process each response for this question
|
|
79
|
+
for (const agentMessage of group.responses) {
|
|
80
|
+
try {
|
|
81
|
+
const parsedAgentMessage = (0, aiControllerState_1.toMessageType)(agentMessage.message_type) === 'json'
|
|
82
|
+
? JSON.parse(agentMessage.content)
|
|
83
|
+
: {
|
|
84
|
+
text: agentMessage.content,
|
|
85
|
+
state: 'complete',
|
|
86
|
+
type: 'answer',
|
|
87
|
+
visualization: null,
|
|
88
|
+
follow_up_questions: [],
|
|
89
|
+
};
|
|
90
|
+
const responseType = (0, aiControllerState_1.toAIControllerAnswerResponseType)(parsedAgentMessage.type);
|
|
91
|
+
const responseState = (0, aiControllerState_1.toAIControllerAnswerStateType)(parsedAgentMessage.state);
|
|
92
|
+
if (typeof parsedAgentMessage.text === 'string' &&
|
|
93
|
+
aiControllerState_1.ALL_AI_CONTROLLER_ANSWER_RESPONSE_TYPES.includes(responseType)) {
|
|
94
|
+
responses[responseType] = {
|
|
95
|
+
messageId: agentMessage.message_id,
|
|
96
|
+
chatSessionId: agentMessage.chat_session_id,
|
|
97
|
+
userId: agentMessage.user_id,
|
|
98
|
+
sender: (0, aiControllerState_1.toMessageSender)(agentMessage.sender),
|
|
99
|
+
type: responseType,
|
|
100
|
+
state: responseState,
|
|
101
|
+
content: {
|
|
102
|
+
text: parsedAgentMessage.text,
|
|
103
|
+
visualization: parsedAgentMessage.visualization
|
|
104
|
+
? (0, exports.toAIControllerVisualization)(parsedAgentMessage.visualization)
|
|
105
|
+
: undefined,
|
|
106
|
+
followUpQuestions: Array.isArray(parsedAgentMessage.follow_up_questions)
|
|
107
|
+
? parsedAgentMessage.follow_up_questions
|
|
108
|
+
: [],
|
|
109
|
+
assumptions: (_a = parsedAgentMessage.assumptions) !== null && _a !== void 0 ? _a : '',
|
|
110
|
+
insights: (_b = parsedAgentMessage.insights) !== null && _b !== void 0 ? _b : '',
|
|
111
|
+
summarizedTitle: (_c = parsedAgentMessage.summarized_title) !== null && _c !== void 0 ? _c : undefined,
|
|
112
|
+
},
|
|
113
|
+
createdAt: (0, zeniDayJS_1.date)(agentMessage.created_at),
|
|
114
|
+
};
|
|
86
115
|
}
|
|
87
116
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
responses,
|
|
92
|
-
});
|
|
93
|
-
userMessageIndex =
|
|
94
|
-
agentMessage !== null
|
|
95
|
-
? agentMessageIndex + 1
|
|
96
|
-
: lastUserMessageIndex + 1;
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
userMessageIndex++;
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error('Failed to parse agent message: ', error);
|
|
119
|
+
}
|
|
100
120
|
}
|
|
121
|
+
questionAnswerPairs.push({
|
|
122
|
+
questionAnswerId: `qa_${messageId}`,
|
|
123
|
+
question,
|
|
124
|
+
responses,
|
|
125
|
+
});
|
|
101
126
|
}
|
|
102
|
-
|
|
127
|
+
// Sort by question creation time (oldest first)
|
|
128
|
+
return questionAnswerPairs.sort((a, b) => a.question.createdAt.valueOf() - b.question.createdAt.valueOf());
|
|
103
129
|
}
|
|
104
130
|
const toAIControllerVisualization = (visualization) => {
|
|
105
131
|
var _a;
|
|
@@ -178,10 +204,23 @@ const aiController = (0, toolkit_1.createSlice)({
|
|
|
178
204
|
chatSessionId,
|
|
179
205
|
userId,
|
|
180
206
|
chatSessionSummary: '',
|
|
207
|
+
newSession: true,
|
|
181
208
|
createdAt,
|
|
182
209
|
},
|
|
183
210
|
questionAnswers: [],
|
|
184
211
|
};
|
|
212
|
+
// Clear any existing partial Q&A when creating a new session
|
|
213
|
+
draft.partialQuestionAnswers[chatSessionId] = undefined;
|
|
214
|
+
},
|
|
215
|
+
updateNewSession(draft, action) {
|
|
216
|
+
const { chatSessionId } = action.payload;
|
|
217
|
+
if (draft.aiControllerByChatSessionId[chatSessionId] == null) {
|
|
218
|
+
console.warn(`session with id ${chatSessionId} not found`);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (draft.aiControllerByChatSessionId[chatSessionId].chatSession.newSession) {
|
|
222
|
+
draft.aiControllerByChatSessionId[chatSessionId].chatSession.newSession = false;
|
|
223
|
+
}
|
|
185
224
|
},
|
|
186
225
|
setSessions(draft, action) {
|
|
187
226
|
action.payload.forEach((chatSessionPayload) => {
|
|
@@ -190,16 +229,145 @@ const aiController = (0, toolkit_1.createSlice)({
|
|
|
190
229
|
chatSession: toChatSession(chatSessionPayload),
|
|
191
230
|
questionAnswers: [],
|
|
192
231
|
};
|
|
232
|
+
// Clear any existing partial Q&A for this session
|
|
233
|
+
draft.partialQuestionAnswers[chatSessionPayload.chat_session_id] =
|
|
234
|
+
undefined;
|
|
193
235
|
});
|
|
194
236
|
},
|
|
195
237
|
setChatHistory(draft, action) {
|
|
196
|
-
const { chatSessionId, history } = action.payload;
|
|
238
|
+
const { chatSessionId, history, isPaginationComplete = false, } = action.payload;
|
|
197
239
|
if (draft.aiControllerByChatSessionId[chatSessionId] == null) {
|
|
198
240
|
console.warn(`session with id ${chatSessionId} not found in setChatHistory`);
|
|
199
241
|
return;
|
|
200
242
|
}
|
|
201
|
-
draft.aiControllerByChatSessionId[chatSessionId]
|
|
202
|
-
|
|
243
|
+
const session = draft.aiControllerByChatSessionId[chatSessionId];
|
|
244
|
+
// Check if we have an existing partial Q&A pair for this session
|
|
245
|
+
const existingPartialQA = draft.partialQuestionAnswers[chatSessionId];
|
|
246
|
+
// Process new messages into Q&A pairs
|
|
247
|
+
const newQAs = chatHistoryToQA(history);
|
|
248
|
+
// If we have an existing partial Q&A pair, merge with new Q&A pairs
|
|
249
|
+
let mergedQAs;
|
|
250
|
+
if (existingPartialQA && newQAs.length > 0) {
|
|
251
|
+
// Check if any new QAs have the same message_id as the existing partial QA
|
|
252
|
+
const hasMatchingMessageId = newQAs.some((newQA) => newQA.question.messageId === existingPartialQA.question.messageId);
|
|
253
|
+
if (hasMatchingMessageId) {
|
|
254
|
+
// Merge the existing partial QA with new QAs that have matching message_id
|
|
255
|
+
mergedQAs = mergeQuestionAnswerPairs([existingPartialQA], newQAs);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
// No matching message_id - existing partial QA should be moved to complete
|
|
259
|
+
// and new QAs should be processed separately
|
|
260
|
+
mergedQAs = [existingPartialQA, ...newQAs];
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else if (existingPartialQA && newQAs.length === 0) {
|
|
264
|
+
// Intermediate page scenario: existing partial QA but no new blocks to merge
|
|
265
|
+
// This means the partial QA is complete (no more blocks coming to complete it)
|
|
266
|
+
mergedQAs = [existingPartialQA];
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
mergedQAs = newQAs;
|
|
270
|
+
}
|
|
271
|
+
// Separate complete and incomplete pairs
|
|
272
|
+
const completeQAs = [];
|
|
273
|
+
let incompleteQA;
|
|
274
|
+
for (const qa of mergedQAs) {
|
|
275
|
+
const questionText = qa.question.questionText;
|
|
276
|
+
const hasQuestion = questionText != null && questionText.trim().length > 0;
|
|
277
|
+
if (!hasQuestion) {
|
|
278
|
+
// Skip if no question text
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
// Check if this Q&A pair is complete
|
|
282
|
+
// A Q&A pair is considered complete if it has:
|
|
283
|
+
// 1. A question (already checked above)
|
|
284
|
+
// 2. At least one agent response (any type: thought, reasoning, analysis, answer, etc.)
|
|
285
|
+
// 3. AND EITHER:
|
|
286
|
+
// - At least one response with state: 'complete' (not 'partial')
|
|
287
|
+
// - OR multiple response blocks (thought, reasoning, analysis) even if they're all partial
|
|
288
|
+
const hasAnyResponse = Object.keys(qa.responses).length > 0;
|
|
289
|
+
const hasCompleteResponse = Object.values(qa.responses).some((response) => response.state === 'complete');
|
|
290
|
+
const hasMultipleResponseBlocks = Object.keys(qa.responses).length > 1;
|
|
291
|
+
// Check if this is an existing partial QA that should be moved to complete
|
|
292
|
+
// because no more blocks are coming to complete it
|
|
293
|
+
const isExistingPartialQA = existingPartialQA &&
|
|
294
|
+
qa.question.messageId === existingPartialQA.question.messageId &&
|
|
295
|
+
!hasCompleteResponse;
|
|
296
|
+
if (hasQuestion &&
|
|
297
|
+
hasAnyResponse &&
|
|
298
|
+
(hasCompleteResponse || hasMultipleResponseBlocks)) {
|
|
299
|
+
// This Q&A pair is complete - has question and either:
|
|
300
|
+
// - at least one complete response, OR
|
|
301
|
+
// - multiple response blocks (thought, reasoning, analysis) even if all partial
|
|
302
|
+
completeQAs.push(qa);
|
|
303
|
+
}
|
|
304
|
+
else if (hasQuestion &&
|
|
305
|
+
hasAnyResponse &&
|
|
306
|
+
isExistingPartialQA === true) {
|
|
307
|
+
// This is an existing partial QA that should be moved to complete
|
|
308
|
+
// because no more blocks are coming to complete it (intermediate page scenario)
|
|
309
|
+
completeQAs.push(qa);
|
|
310
|
+
}
|
|
311
|
+
else if (hasQuestion && hasAnyResponse) {
|
|
312
|
+
// This Q&A pair has a question and responses but they're all partial
|
|
313
|
+
// Keep as incomplete for potential merging with future pages
|
|
314
|
+
if (!incompleteQA) {
|
|
315
|
+
incompleteQA = qa;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else if (hasQuestion) {
|
|
319
|
+
// This Q&A pair has only a question, no responses yet
|
|
320
|
+
// Keep as incomplete for potential merging with future pages
|
|
321
|
+
if (!incompleteQA) {
|
|
322
|
+
incompleteQA = qa;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Update partialQuestionAnswers based on completion status
|
|
327
|
+
if (isPaginationComplete) {
|
|
328
|
+
// If pagination is complete, we should have processed all messages
|
|
329
|
+
// Any remaining incomplete Q&A pairs should be moved to complete
|
|
330
|
+
if (incompleteQA) {
|
|
331
|
+
// When pagination is complete, move all incomplete Q&A pairs to complete
|
|
332
|
+
// This handles cases where:
|
|
333
|
+
// 1. Question with no responses (error in generation)
|
|
334
|
+
// 2. Question with only partial responses (error in generation)
|
|
335
|
+
// 3. Question with only answer blocks (no thought/reasoning blocks)
|
|
336
|
+
completeQAs.push(incompleteQA);
|
|
337
|
+
draft.partialQuestionAnswers[chatSessionId] = undefined;
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
// No incomplete Q&A pairs, clear partialQuestionAnswers
|
|
341
|
+
draft.partialQuestionAnswers[chatSessionId] = undefined;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
else if (incompleteQA) {
|
|
345
|
+
// Check if this is an intermediate page scenario
|
|
346
|
+
// If we had an existing partial QA but no new blocks were merged,
|
|
347
|
+
// then the partial QA should be considered complete
|
|
348
|
+
if (existingPartialQA && newQAs.length === 0) {
|
|
349
|
+
// Intermediate page: existing partial QA but no new blocks to merge
|
|
350
|
+
// Move the partial QA to complete since no more blocks are coming
|
|
351
|
+
completeQAs.push(incompleteQA);
|
|
352
|
+
draft.partialQuestionAnswers[chatSessionId] = undefined;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
// Pagination is not complete, keep incomplete Q&A pairs for future merging
|
|
356
|
+
draft.partialQuestionAnswers[chatSessionId] = incompleteQA;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else if (existingPartialQA && newQAs.length === 0) {
|
|
360
|
+
// Special case: existing partial QA but no new blocks and no incomplete QA in mergedQAs
|
|
361
|
+
// This means the existing partial QA should be moved to complete
|
|
362
|
+
completeQAs.push(existingPartialQA);
|
|
363
|
+
draft.partialQuestionAnswers[chatSessionId] = undefined;
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
// No incomplete Q&A pairs, clear partialQuestionAnswers
|
|
367
|
+
draft.partialQuestionAnswers[chatSessionId] = undefined;
|
|
368
|
+
}
|
|
369
|
+
// Update state - append new complete Q&As to existing ones
|
|
370
|
+
session.questionAnswers = mergeQuestionAnswerPairs(session.questionAnswers, completeQAs);
|
|
203
371
|
},
|
|
204
372
|
/**
|
|
205
373
|
* Upsert a Q/A pair: if the questionAnswerId exists, upsert the response block; if not, add a new Q/A entry.
|
|
@@ -281,10 +449,17 @@ const aiController = (0, toolkit_1.createSlice)({
|
|
|
281
449
|
}
|
|
282
450
|
},
|
|
283
451
|
clearSession(draft, action) {
|
|
284
|
-
|
|
452
|
+
var _a;
|
|
453
|
+
const sessionId = action.payload;
|
|
454
|
+
delete draft.aiControllerByChatSessionId[sessionId];
|
|
455
|
+
// Clear partial Q&A if it belongs to the cleared session
|
|
456
|
+
if (((_a = draft.partialQuestionAnswers) === null || _a === void 0 ? void 0 : _a[sessionId]) != null) {
|
|
457
|
+
draft.partialQuestionAnswers[sessionId] = undefined;
|
|
458
|
+
}
|
|
285
459
|
},
|
|
286
460
|
clearAIController(draft) {
|
|
287
461
|
draft.aiControllerByChatSessionId = {};
|
|
462
|
+
draft.partialQuestionAnswers = {};
|
|
288
463
|
},
|
|
289
464
|
deleteQuestion(draft, action) {
|
|
290
465
|
const { chatSessionId, questionAnswerId } = action.payload;
|
|
@@ -305,9 +480,10 @@ const toChatSession = (chatSessionPayload) => {
|
|
|
305
480
|
return {
|
|
306
481
|
chatSessionId: chat_session_id,
|
|
307
482
|
userId: user_id,
|
|
483
|
+
newSession: false,
|
|
308
484
|
chatSessionSummary: chat_session_summary !== null && chat_session_summary !== void 0 ? chat_session_summary : undefined,
|
|
309
485
|
createdAt: (0, zeniDayJS_1.date)(created_at),
|
|
310
486
|
};
|
|
311
487
|
};
|
|
312
|
-
_a = aiController.actions, exports.setNewSession = _a.setNewSession, exports.clearSession = _a.clearSession, exports.setSessions = _a.setSessions, exports.setChatHistory = _a.setChatHistory, exports.upsertAnswerPayload = _a.upsertAnswerPayload, exports.upsertOrAddQuestionAnswerPayload = _a.upsertOrAddQuestionAnswerPayload, exports.addQuestionPayload = _a.addQuestionPayload, exports.clearAIController = _a.clearAIController, exports.deleteQuestion = _a.deleteQuestion;
|
|
488
|
+
_a = aiController.actions, exports.setNewSession = _a.setNewSession, exports.clearSession = _a.clearSession, exports.setSessions = _a.setSessions, exports.setChatHistory = _a.setChatHistory, exports.upsertAnswerPayload = _a.upsertAnswerPayload, exports.upsertOrAddQuestionAnswerPayload = _a.upsertOrAddQuestionAnswerPayload, exports.addQuestionPayload = _a.addQuestionPayload, exports.clearAIController = _a.clearAIController, exports.deleteQuestion = _a.deleteQuestion, exports.updateNewSession = _a.updateNewSession;
|
|
313
489
|
exports.default = aiController.reducer;
|
|
@@ -54,11 +54,11 @@ export interface ResponseBlockBase {
|
|
|
54
54
|
}
|
|
55
55
|
export interface AnswerContentBlockBase {
|
|
56
56
|
text: string;
|
|
57
|
-
visualization?: AIControllerVisualization;
|
|
58
57
|
followUpQuestions: string[];
|
|
59
58
|
assumptions: string;
|
|
60
59
|
insights: string;
|
|
61
60
|
summarizedTitle?: string;
|
|
61
|
+
visualization?: AIControllerVisualization;
|
|
62
62
|
}
|
|
63
63
|
export interface QuestionContentBlockBase extends ResponseBlockBase {
|
|
64
64
|
questionText: string;
|
|
@@ -76,6 +76,7 @@ export interface ChatSession {
|
|
|
76
76
|
chatSessionId: ID;
|
|
77
77
|
userId: ID;
|
|
78
78
|
createdAt: ZeniDate;
|
|
79
|
+
newSession: boolean;
|
|
79
80
|
chatSessionSummary?: string;
|
|
80
81
|
}
|
|
81
82
|
export interface ChatSessionWithMessages {
|
|
@@ -84,4 +85,5 @@ export interface ChatSessionWithMessages {
|
|
|
84
85
|
}
|
|
85
86
|
export interface AIControllerState {
|
|
86
87
|
aiControllerByChatSessionId: Record<ID, ChatSessionWithMessages>;
|
|
88
|
+
partialQuestionAnswers: Record<ID, AIControllerQuestionWithAnswer | undefined>;
|
|
87
89
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FetchStateAndError, ID } from '../../commonStateTypes/common';
|
|
2
2
|
import { PageToken } from '../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
|
+
import { ChatSessionPayload } from '../../entity/aiController/aiControllerPayload';
|
|
3
4
|
import { AIControllerAnswerResponseType } from '../../entity/aiController/aiControllerState';
|
|
4
5
|
import { ZeniAPIStatus } from '../../responsePayload';
|
|
5
6
|
import { AIControllerViewState } from './aiControllerViewState';
|
|
@@ -25,8 +26,10 @@ export declare const submitQuestion: import("@reduxjs/toolkit").ActionCreatorWit
|
|
|
25
26
|
sessionId: ID;
|
|
26
27
|
}, "aiControllerView/createSessionSuccess">, createSessionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "aiControllerView/createSessionFailure">, fetchChatSessionsForUser: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"aiControllerView/fetchChatSessionsForUser">, fetchChatSessionsForUserSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
27
28
|
nextPageToken: PageToken;
|
|
28
|
-
|
|
29
|
+
sessions: ChatSessionPayload[];
|
|
30
|
+
}, "aiControllerView/fetchChatSessionsForUserSuccess">, fetchChatSessionsForUserFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "aiControllerView/fetchChatSessionsForUserFailure">, fetchChatHistory: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[chatSessionId: string, userId: string], {
|
|
29
31
|
chatSessionId: string;
|
|
32
|
+
userId: string;
|
|
30
33
|
}, "aiControllerView/fetchChatHistory", never, never>, fetchChatHistorySuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
31
34
|
chatSessionId: ID;
|
|
32
35
|
nextPageToken: PageToken;
|
|
@@ -11,8 +11,9 @@ exports.initialAIControllerViewState = {
|
|
|
11
11
|
scrollPositionByChatSessionId: {},
|
|
12
12
|
currentChatSessionId: undefined,
|
|
13
13
|
agentId: undefined,
|
|
14
|
-
chatHistoryNextPageToken: {
|
|
14
|
+
chatHistoryNextPageToken: {},
|
|
15
15
|
chatSessionsNextPageToken: { nextPageToken: null, hasMore: false },
|
|
16
|
+
chatSessionsFirstPageFetched: false,
|
|
16
17
|
},
|
|
17
18
|
allChatSessionIds: [],
|
|
18
19
|
createSessionState: {
|
|
@@ -99,6 +100,13 @@ const aiControllerView = (0, toolkit_1.createSlice)({
|
|
|
99
100
|
action.payload.nextPageToken;
|
|
100
101
|
draft.uiState.chatSessionsNextPageToken.hasMore =
|
|
101
102
|
action.payload.nextPageToken != null;
|
|
103
|
+
if (draft.uiState.chatSessionsFirstPageFetched == false) {
|
|
104
|
+
draft.uiState.chatSessionsFirstPageFetched = true;
|
|
105
|
+
}
|
|
106
|
+
draft.allChatSessionIds = Array.from(new Set([
|
|
107
|
+
...draft.allChatSessionIds,
|
|
108
|
+
...action.payload.sessions.map((session) => session.chat_session_id),
|
|
109
|
+
]));
|
|
102
110
|
},
|
|
103
111
|
fetchChatSessionsForUserFailure(draft, action) {
|
|
104
112
|
draft.fetchState = 'Error';
|
|
@@ -112,8 +120,8 @@ const aiControllerView = (0, toolkit_1.createSlice)({
|
|
|
112
120
|
error: undefined,
|
|
113
121
|
};
|
|
114
122
|
},
|
|
115
|
-
prepare(chatSessionId) {
|
|
116
|
-
return { payload: { chatSessionId } };
|
|
123
|
+
prepare(chatSessionId, userId) {
|
|
124
|
+
return { payload: { chatSessionId, userId } };
|
|
117
125
|
},
|
|
118
126
|
},
|
|
119
127
|
fetchChatHistorySuccess(draft, action) {
|
|
@@ -122,8 +130,18 @@ const aiControllerView = (0, toolkit_1.createSlice)({
|
|
|
122
130
|
fetchState: 'Completed',
|
|
123
131
|
error: undefined,
|
|
124
132
|
};
|
|
125
|
-
draft.uiState.chatHistoryNextPageToken
|
|
126
|
-
|
|
133
|
+
draft.uiState.chatHistoryNextPageToken[chatSessionId] = {
|
|
134
|
+
nextPageToken,
|
|
135
|
+
hasMore: nextPageToken != null,
|
|
136
|
+
};
|
|
137
|
+
if (draft.responseStateByChatSessionId[chatSessionId] == null) {
|
|
138
|
+
draft.responseStateByChatSessionId[chatSessionId] = {
|
|
139
|
+
thought: { fetchState: 'Completed', error: undefined },
|
|
140
|
+
analysis: { fetchState: 'Completed', error: undefined },
|
|
141
|
+
reasoning: { fetchState: 'Completed', error: undefined },
|
|
142
|
+
answer: { fetchState: 'Completed', error: undefined },
|
|
143
|
+
};
|
|
144
|
+
}
|
|
127
145
|
},
|
|
128
146
|
fetchChatHistoryFailure(draft, action) {
|
|
129
147
|
const { chatSessionId, error } = action.payload;
|
|
@@ -152,6 +170,10 @@ const aiControllerView = (0, toolkit_1.createSlice)({
|
|
|
152
170
|
draft.createSessionState.fetchState = 'Completed';
|
|
153
171
|
draft.createSessionState.error = undefined;
|
|
154
172
|
draft.uiState.currentChatSessionId = sessionId;
|
|
173
|
+
draft.uiState.chatHistoryNextPageToken[sessionId] = {
|
|
174
|
+
nextPageToken: null,
|
|
175
|
+
hasMore: false,
|
|
176
|
+
};
|
|
155
177
|
},
|
|
156
178
|
createSessionFailure(draft, action) {
|
|
157
179
|
draft.createSessionState.fetchState = 'Error';
|
|
@@ -7,6 +7,7 @@ import { AIControllerViewUIState } from './aiControllerViewState';
|
|
|
7
7
|
export interface AIControllerViewSelector extends SelectorView, AIControllerSelectorView {
|
|
8
8
|
createSessionState: FetchStateAndError;
|
|
9
9
|
stopSubmitStateByChatSessionId: Record<ID, FetchStateAndError>;
|
|
10
|
+
fetchChatSessionHistoryByChatSessionId: Record<ID, FetchStateAndError>;
|
|
10
11
|
responseStateByChatSessionId: Record<ID, {
|
|
11
12
|
thought: FetchStateAndError;
|
|
12
13
|
analysis: FetchStateAndError;
|
|
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getAIControllerView = void 0;
|
|
4
4
|
const aiControllerSelector_1 = require("../../entity/aiController/aiControllerSelector");
|
|
5
5
|
const getAIControllerView = (state) => {
|
|
6
|
-
const { fetchState, error, uiState, createSessionState, stopSubmitStateByChatSessionId, responseStateByChatSessionId, } = state.aiControllerViewState;
|
|
6
|
+
const { fetchState, error, uiState, createSessionState, stopSubmitStateByChatSessionId, responseStateByChatSessionId, fetchChatSessionHistoryByChatSessionId, } = state.aiControllerViewState;
|
|
7
7
|
return Object.assign(Object.assign({ fetchState,
|
|
8
8
|
error,
|
|
9
9
|
createSessionState,
|
|
10
10
|
stopSubmitStateByChatSessionId,
|
|
11
11
|
responseStateByChatSessionId,
|
|
12
|
-
uiState
|
|
12
|
+
uiState,
|
|
13
|
+
fetchChatSessionHistoryByChatSessionId }, (0, aiControllerSelector_1.getAIControllerSelectorView)(state.aiControllerState)), { version: 1 });
|
|
13
14
|
};
|
|
14
15
|
exports.getAIControllerView = getAIControllerView;
|
|
@@ -11,10 +11,13 @@ export interface AIControllerViewUIState {
|
|
|
11
11
|
scrollTop: number;
|
|
12
12
|
};
|
|
13
13
|
};
|
|
14
|
+
chatHistoryNextPageToken: {
|
|
15
|
+
[chatSessionId: ID]: PageTokenState;
|
|
16
|
+
};
|
|
17
|
+
chatSessionsNextPageToken: PageTokenState;
|
|
18
|
+
chatSessionsFirstPageFetched: boolean;
|
|
14
19
|
currentChatSessionId?: ID;
|
|
15
20
|
agentId?: ID;
|
|
16
|
-
chatHistoryNextPageToken: PageTokenState;
|
|
17
|
-
chatSessionsNextPageToken: PageTokenState;
|
|
18
21
|
}
|
|
19
22
|
export interface AIControllerViewState extends FetchStateAndError {
|
|
20
23
|
uiState: AIControllerViewUIState;
|
|
@@ -5,4 +5,4 @@ import { RootState } from '../../../reducer';
|
|
|
5
5
|
import { ZeniAPI } from '../../../zeniAPI';
|
|
6
6
|
import { fetchChatHistory, fetchChatHistoryFailure, fetchChatHistorySuccess } from '../aiControllerViewReducer';
|
|
7
7
|
export type ActionType = ReturnType<typeof fetchChatHistory> | ReturnType<typeof setChatHistory> | ReturnType<typeof fetchChatHistorySuccess> | ReturnType<typeof fetchChatHistoryFailure>;
|
|
8
|
-
export declare const fetchChatHistoryEpic: (actions$: ActionsObservable<ActionType>,
|
|
8
|
+
export declare const fetchChatHistoryEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -6,15 +6,27 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const aiControllerReducer_1 = require("../../../entity/aiController/aiControllerReducer");
|
|
7
7
|
const responsePayload_1 = require("../../../responsePayload");
|
|
8
8
|
const aiControllerViewReducer_1 = require("../aiControllerViewReducer");
|
|
9
|
-
const fetchChatHistoryEpic = (actions$,
|
|
10
|
-
|
|
9
|
+
const fetchChatHistoryEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(aiControllerViewReducer_1.fetchChatHistory.match), (0, operators_1.mergeMap)((action) => {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const { chatSessionId, userId } = action.payload;
|
|
12
|
+
const state = state$.value;
|
|
13
|
+
const pageToken = (_b = (_a = state.aiControllerViewState.uiState.chatHistoryNextPageToken[chatSessionId]) === null || _a === void 0 ? void 0 : _a.nextPageToken) !== null && _b !== void 0 ? _b : null;
|
|
14
|
+
const queryParams = new URLSearchParams();
|
|
15
|
+
queryParams.append('page_size', '20');
|
|
16
|
+
queryParams.append('chat_session_id', chatSessionId);
|
|
17
|
+
queryParams.append('user_id', userId);
|
|
18
|
+
if (pageToken != null) {
|
|
19
|
+
queryParams.append('page_token', pageToken);
|
|
20
|
+
}
|
|
11
21
|
return zeniAPI
|
|
12
|
-
.getJSON(`${zeniAPI.apiEndPoints.aiControllerMicroServiceBaseUrl}/1.0/
|
|
22
|
+
.getJSON(`${zeniAPI.apiEndPoints.aiControllerMicroServiceBaseUrl}/1.0/history?${queryParams.toString()}`)
|
|
13
23
|
.pipe((0, operators_1.mergeMap)((response) => {
|
|
14
24
|
if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
|
|
25
|
+
const isPaginationComplete = response.data.next_page_token == null;
|
|
15
26
|
return (0, rxjs_1.of)((0, aiControllerReducer_1.setChatHistory)({
|
|
16
27
|
chatSessionId,
|
|
17
28
|
history: response.data.messages,
|
|
29
|
+
isPaginationComplete,
|
|
18
30
|
}), (0, aiControllerViewReducer_1.fetchChatHistorySuccess)({
|
|
19
31
|
chatSessionId,
|
|
20
32
|
nextPageToken: response.data.next_page_token,
|
|
@@ -5,4 +5,4 @@ import { RootState } from '../../../reducer';
|
|
|
5
5
|
import { ZeniAPI } from '../../../zeniAPI';
|
|
6
6
|
import { fetchChatSessionsForUser, fetchChatSessionsForUserFailure, fetchChatSessionsForUserSuccess } from '../aiControllerViewReducer';
|
|
7
7
|
export type ActionType = ReturnType<typeof fetchChatSessionsForUser> | ReturnType<typeof setSessions> | ReturnType<typeof fetchChatSessionsForUserSuccess> | ReturnType<typeof fetchChatSessionsForUserFailure>;
|
|
8
|
-
export declare const fetchChatSessionsForUserEpic: (actions$: ActionsObservable<ActionType>,
|
|
8
|
+
export declare const fetchChatSessionsForUserEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -6,12 +6,24 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const aiControllerReducer_1 = require("../../../entity/aiController/aiControllerReducer");
|
|
7
7
|
const responsePayload_1 = require("../../../responsePayload");
|
|
8
8
|
const aiControllerViewReducer_1 = require("../aiControllerViewReducer");
|
|
9
|
-
const fetchChatSessionsForUserEpic = (actions$,
|
|
9
|
+
const fetchChatSessionsForUserEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(aiControllerViewReducer_1.fetchChatSessionsForUser.match), (0, operators_1.switchMap)(() => {
|
|
10
|
+
var _a;
|
|
11
|
+
const state = state$.value;
|
|
12
|
+
const pageToken = (_a = state.aiControllerViewState.uiState.chatSessionsNextPageToken
|
|
13
|
+
.nextPageToken) !== null && _a !== void 0 ? _a : null;
|
|
14
|
+
const queryParams = new URLSearchParams();
|
|
15
|
+
queryParams.append('page_size', '50');
|
|
16
|
+
if (pageToken != null) {
|
|
17
|
+
queryParams.append('page_token', pageToken);
|
|
18
|
+
}
|
|
10
19
|
return zeniAPI
|
|
11
|
-
.getJSON(`${zeniAPI.apiEndPoints.aiControllerMicroServiceBaseUrl}/1.0/sessions`)
|
|
20
|
+
.getJSON(`${zeniAPI.apiEndPoints.aiControllerMicroServiceBaseUrl}/1.0/sessions?${queryParams.toString()}`)
|
|
12
21
|
.pipe((0, operators_1.mergeMap)((response) => {
|
|
13
22
|
if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
|
|
14
|
-
|
|
23
|
+
// Filter out empty sessions that don't have a summary
|
|
24
|
+
const sessions = response.data.sessions.filter((session) => Boolean(session.chat_session_summary) === true);
|
|
25
|
+
return (0, rxjs_1.of)((0, aiControllerReducer_1.setSessions)(sessions), (0, aiControllerViewReducer_1.fetchChatSessionsForUserSuccess)({
|
|
26
|
+
sessions,
|
|
15
27
|
nextPageToken: response.data.next_page_token,
|
|
16
28
|
}));
|
|
17
29
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
|
-
import { upsertOrAddQuestionAnswerPayload } from '../../../entity/aiController/aiControllerReducer';
|
|
3
|
+
import { updateNewSession, upsertOrAddQuestionAnswerPayload } from '../../../entity/aiController/aiControllerReducer';
|
|
4
4
|
import { RootState } from '../../../reducer';
|
|
5
5
|
import { ZeniAPI } from '../../../zeniAPI';
|
|
6
6
|
import { submitQuestion, submitQuestionFailure, submitQuestionSuccess } from '../aiControllerViewReducer';
|
|
7
|
-
export type ActionType = ReturnType<typeof submitQuestion> | ReturnType<typeof submitQuestionSuccess> | ReturnType<typeof submitQuestionFailure> | ReturnType<typeof upsertOrAddQuestionAnswerPayload>;
|
|
7
|
+
export type ActionType = ReturnType<typeof submitQuestion> | ReturnType<typeof updateNewSession> | ReturnType<typeof submitQuestionSuccess> | ReturnType<typeof submitQuestionFailure> | ReturnType<typeof upsertOrAddQuestionAnswerPayload>;
|
|
8
8
|
export declare const submitQuestionEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -6,7 +6,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
6
6
|
const aiControllerReducer_1 = require("../../../entity/aiController/aiControllerReducer");
|
|
7
7
|
const responsePayload_1 = require("../../../responsePayload");
|
|
8
8
|
const aiControllerViewReducer_1 = require("../aiControllerViewReducer");
|
|
9
|
-
const submitQuestionEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(aiControllerViewReducer_1.submitQuestion.match), (0, operators_1.
|
|
9
|
+
const submitQuestionEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(aiControllerViewReducer_1.submitQuestion.match), (0, operators_1.mergeMap)((action) => {
|
|
10
10
|
const { questionAnswerId, userId, questionId, createdAt, question } = action.payload;
|
|
11
11
|
const { aiControllerViewState } = state$.value;
|
|
12
12
|
const { uiState } = aiControllerViewState;
|
|
@@ -16,7 +16,9 @@ const submitQuestionEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, oper
|
|
|
16
16
|
if (agentId == null || sessionId == null || Boolean(question) == false) {
|
|
17
17
|
throw new Error('Invalid State');
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
// First, update the session to mark it as no longer new
|
|
20
|
+
const updateSessionAction = (0, aiControllerReducer_1.updateNewSession)({ chatSessionId: sessionId });
|
|
21
|
+
return (0, rxjs_1.concat)((0, rxjs_1.of)(updateSessionAction), zeniAPI
|
|
20
22
|
.postAndGetJSON(`${zeniAPI.apiEndPoints.aiControllerMicroServiceBaseUrl}/1.0/agents/${agentId}`, payload)
|
|
21
23
|
.pipe((0, operators_1.mergeMap)((response) => {
|
|
22
24
|
if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
|
|
@@ -32,14 +34,13 @@ const submitQuestionEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, oper
|
|
|
32
34
|
answerPayload: response.data,
|
|
33
35
|
userId,
|
|
34
36
|
insertQuestionAnswer: false, // Don't insert the Q/A here after stopSubmitSuccess
|
|
35
|
-
}));
|
|
36
|
-
actions.push((0, aiControllerViewReducer_1.submitQuestionSuccess)());
|
|
37
|
+
}), (0, aiControllerViewReducer_1.submitQuestionSuccess)());
|
|
37
38
|
return (0, rxjs_1.of)(...actions);
|
|
38
39
|
}
|
|
39
40
|
else {
|
|
40
41
|
return (0, rxjs_1.of)((0, aiControllerViewReducer_1.submitQuestionFailure)(response.status));
|
|
41
42
|
}
|
|
42
43
|
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, aiControllerViewReducer_1.submitQuestionFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Submit question REST API call errored out' +
|
|
43
|
-
JSON.stringify(error))))));
|
|
44
|
+
JSON.stringify(error)))))));
|
|
44
45
|
}));
|
|
45
46
|
exports.submitQuestionEpic = submitQuestionEpic;
|
|
@@ -4,9 +4,9 @@ import { SubscriptionViewSortKey } from '../../subscriptionView/types/subscripti
|
|
|
4
4
|
import { FilterCategoryValueType } from '../helpers/cockpitHelpers';
|
|
5
5
|
import { CockpitDownloadTabsID, CockpitTabsFileType } from './cockpitTabsID';
|
|
6
6
|
export declare const toPortfolioSortKeyType: (v: string) => "expenses" | "runway" | "companyName" | "cashBalance" | "revenues" | "netIncome";
|
|
7
|
-
export declare const toManagementSortKeyType: (v: string) => "status" | "bookCloseDate" | "taxStatus" | "controller" | "preparer" | "reviewer" | "annualRecurringRevenue" | "monthlyRecurringRevenue" | "companyName" | "
|
|
7
|
+
export declare const toManagementSortKeyType: (v: string) => "status" | "bookCloseDate" | "group" | "taxStatus" | "controller" | "preparer" | "reviewer" | "annualRecurringRevenue" | "monthlyRecurringRevenue" | "companyName" | "task" | "notes" | "plans" | "customerSuccessManager" | "apAnalyst" | "reportSent" | "taxLead" | "satisfaction";
|
|
8
8
|
export declare const toOnboardingSortKeyType: (v: string) => "companyName" | "identityVerified" | "businessVerified" | "bankAccountLinked" | "qboLinked" | "groupCreated" | "customerCreated" | "notes" | "enroller" | "invite" | "latestCreated";
|
|
9
|
-
export declare const toHealthSortKeyType: (v: string) => "
|
|
9
|
+
export declare const toHealthSortKeyType: (v: string) => "group" | "runway" | "controller" | "monthlyRecurringRevenue" | "companyName" | "companyEngagementMetricsUpdatedAt" | "netPromoterScore" | "customerSatisfactionScore" | "externalProductServiceExposure" | "customerSuccessManager" | "lastReportSent" | "issues" | "productVerticals" | "churnProbability" | "subscriptionDate" | "renewalDate" | "dashboardLastSeen" | "lastEngagement";
|
|
10
10
|
export declare const toTaskManagerSortKeyType: (v: string) => "status" | "name" | "dueDate" | "tags" | "createdBy" | "priority" | "taskName" | "assignee";
|
|
11
11
|
export type PortfolioViewSortKey = ReturnType<typeof toPortfolioSortKeyType>;
|
|
12
12
|
export type ManagementViewSortKey = ReturnType<typeof toManagementSortKeyType>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "4.16.
|
|
3
|
+
"version": "4.16.82",
|
|
4
4
|
"description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|