@zeniai/client-epic-state 4.19.24 → 4.19.26

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.
@@ -1,7 +1,7 @@
1
1
  import { ID } from '../../commonStateTypes/common';
2
2
  import { ZeniDate } from '../../zeniDayJS';
3
3
  import { AiCfoAnswerPayload, AiCfoVisualizationPayload, ChatSessionPayload, MessagePayload } from './aiCfoPayload';
4
- import { AiCfoState, AiCfoVisualization } from './aiCfoState';
4
+ import { AiCfoState, AiCfoVisualization, FileAttachmentMetadata } from './aiCfoState';
5
5
  export declare const initialAiCfoState: AiCfoState;
6
6
  export declare const toAiCfoVisualization: (visualization: AiCfoVisualizationPayload) => AiCfoVisualization | undefined;
7
7
  export declare const setNewSession: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
@@ -37,6 +37,7 @@ export declare const setNewSession: import("@reduxjs/toolkit").ActionCreatorWith
37
37
  };
38
38
  questionAnswerId: ID;
39
39
  userId: ID;
40
+ attachments?: FileAttachmentMetadata[];
40
41
  }, "aiCfo/addQuestionPayload">, clearAiCfo: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"aiCfo/clearAiCfo">, deleteQuestion: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
41
42
  chatSessionId: ID;
42
43
  questionAnswerId: ID;
@@ -424,7 +424,7 @@ const aiCfo = (0, toolkit_1.createSlice)({
424
424
  }
425
425
  },
426
426
  addQuestionPayload(draft, action) {
427
- const { chatSessionId, questionAnswerId, question: { questionId, createdAt, text }, userId, } = action.payload;
427
+ const { chatSessionId, questionAnswerId, question: { questionId, createdAt, text }, userId, attachments, } = action.payload;
428
428
  const session = draft.aiCfoByChatSessionId[chatSessionId];
429
429
  if (session == null) {
430
430
  console.warn(`session with id ${chatSessionId} not found in addQuestionPayload`);
@@ -443,6 +443,7 @@ const aiCfo = (0, toolkit_1.createSlice)({
443
443
  chatSessionId,
444
444
  state: 'complete',
445
445
  userId,
446
+ attachments,
446
447
  },
447
448
  responses: {},
448
449
  };
@@ -80,8 +80,15 @@ export interface AnswerContentBlockBase {
80
80
  summarizedTitle?: string;
81
81
  visualization?: AiCfoVisualization;
82
82
  }
83
+ export interface FileAttachmentMetadata {
84
+ file_size: number;
85
+ filename: string;
86
+ mime_type: string;
87
+ file_id?: string;
88
+ }
83
89
  export interface QuestionContentBlockBase extends ResponseBlockBase {
84
90
  questionText: string;
91
+ attachments?: FileAttachmentMetadata[];
85
92
  }
86
93
  export interface ResponseBlockType extends ResponseBlockBase {
87
94
  content: AnswerContentBlockBase;
package/lib/index.d.ts CHANGED
@@ -845,7 +845,7 @@ export { AiCfoViewSelector, getAiCfoView, } from './view/aiCfoView/aiCfoViewSele
845
845
  export { MessagePayload, ChatSessionPayload, AiCfoAnswerPayload, } from './entity/aiCfo/aiCfoPayload';
846
846
  export { setNewSession, setSessions, upsertAnswerPayload, upsertOrAddQuestionAnswerPayload, addQuestionPayload, clearSession, clearAiCfo, toAiCfoVisualization, } from './entity/aiCfo/aiCfoReducer';
847
847
  export { AiCfoSelectorView, getAllQuestionAnswersForChatSession, getQuestionAnswerByIdForChatSession, getAllQuestionsForChatSession, getAiCfoSelectorView, ChatSessionWithOrderedQuestionAnswers, } from './entity/aiCfo/aiCfoSelector';
848
- export { AiCfoQuestionWithAnswer, AiCfoAnswerParagraph, AiCfoAnswerStateType, AiCfoChartType, AiCfoAnswerResponseType, TableVisualization, ChartVisualization, AiCfoVisualization, AiCfoVisualizationType, AiCfoState, ChatSession, ALL_AI_CFO_CHARTS_TYPES, ALL_AI_CFO_VISUALIZATION_TYPES, ALL_AI_CFO_ANSWER_STATE_TYPES, ALL_AI_CFO_ANSWER_RESPONSE_TYPES, toAiCfoVisualizationType, toAiCfoVisualizationTypeStrict, toAiCfoChartType, toAiCfoChartTypeStrict, toAiCfoAnswerStateType, toAiCfoAnswerStateTypeStrict, toAiCfoAnswerResponseType, toAiCfoAnswerResponseTypeStrict, ChatSessionWithMessages, ResponseBlockBase, AnswerContentBlockBase, QuestionContentBlockBase, ResponseBlockType, toMessageSender, toMessageType, MessageSender, MessageType, } from './entity/aiCfo/aiCfoState';
848
+ export { AiCfoQuestionWithAnswer, AiCfoAnswerParagraph, AiCfoAnswerStateType, AiCfoChartType, AiCfoAnswerResponseType, TableVisualization, ChartVisualization, AiCfoVisualization, AiCfoVisualizationType, AiCfoState, ChatSession, ALL_AI_CFO_CHARTS_TYPES, ALL_AI_CFO_VISUALIZATION_TYPES, ALL_AI_CFO_ANSWER_STATE_TYPES, ALL_AI_CFO_ANSWER_RESPONSE_TYPES, toAiCfoVisualizationType, toAiCfoVisualizationTypeStrict, toAiCfoChartType, toAiCfoChartTypeStrict, toAiCfoAnswerStateType, toAiCfoAnswerStateTypeStrict, toAiCfoAnswerResponseType, toAiCfoAnswerResponseTypeStrict, ChatSessionWithMessages, ResponseBlockBase, AnswerContentBlockBase, FileAttachmentMetadata, QuestionContentBlockBase, ResponseBlockType, toMessageSender, toMessageType, MessageSender, MessageType, } from './entity/aiCfo/aiCfoState';
849
849
  export { fetchTreasuryOverviewDetail, fetchTreasuryTransactionList, updateTreasuryTransactionListUIState, } from './view/spendManagement/treasury/treasuryList/treasuryDetailReducer';
850
850
  export { TreasuryDetailSelectorView, getTreasuryDetail, } from './view/spendManagement/treasury/treasuryList/treasuryDetailSelector';
851
851
  export { TreasuryListUIState, TreasuryViewSortKey, TreasuryTransaction, FundAllocation, } from './view/spendManagement/treasury/treasuryList/treasuryDetailState';
@@ -5,13 +5,14 @@ import { AiCfoAnswerResponseType } from '../../entity/aiCfo/aiCfoState';
5
5
  import { ZeniAPIStatus } from '../../responsePayload';
6
6
  import { AiCfoViewState } from './aiCfoViewState';
7
7
  export declare const initialAiCfoViewState: AiCfoViewState;
8
- export declare const submitQuestion: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[sessionId: string, questionAnswerId: string, userId: string, questionId: string, createdAt: import("dayjs").Dayjs, question: string], {
8
+ export declare const submitQuestion: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[sessionId: string, questionAnswerId: string, userId: string, questionId: string, createdAt: import("dayjs").Dayjs, question: string, files?: File[] | undefined], {
9
9
  sessionId: string;
10
10
  questionAnswerId: string;
11
11
  userId: string;
12
12
  questionId: string;
13
13
  createdAt: import("dayjs").Dayjs;
14
14
  question: string;
15
+ files: File[] | undefined;
15
16
  }, "aiCfoView/submitQuestion", never, never>, submitQuestionSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "aiCfoView/submitQuestionSuccess">, submitQuestionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
16
17
  error: ZeniAPIStatus;
17
18
  sessionId: ID;
@@ -28,13 +29,14 @@ export declare const submitQuestion: import("@reduxjs/toolkit").ActionCreatorWit
28
29
  }, "aiCfoView/createSession", never, never>, createSessionSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
29
30
  agentId: string;
30
31
  sessionId: ID;
31
- }, "aiCfoView/createSessionSuccess">, createSessionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "aiCfoView/createSessionFailure">, createSessionAndSubmit: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[agentId: string, userId: string, questionAnswerId: string, questionId: string, createdAt: import("dayjs").Dayjs, question: string], {
32
+ }, "aiCfoView/createSessionSuccess">, createSessionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "aiCfoView/createSessionFailure">, createSessionAndSubmit: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[agentId: string, userId: string, questionAnswerId: string, questionId: string, createdAt: import("dayjs").Dayjs, question: string, files?: File[] | undefined], {
32
33
  agentId: string;
33
34
  userId: string;
34
35
  questionAnswerId: string;
35
36
  questionId: string;
36
37
  createdAt: import("dayjs").Dayjs;
37
38
  question: string;
39
+ files: File[] | undefined;
38
40
  }, "aiCfoView/createSessionAndSubmit", never, never>, initializeNewSessionState: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
39
41
  agentId: string;
40
42
  sessionId: ID;
@@ -48,7 +48,7 @@ const aiCfoView = (0, toolkit_1.createSlice)({
48
48
  answer: { fetchState: 'In-Progress', error: undefined },
49
49
  };
50
50
  },
51
- prepare(sessionId, questionAnswerId, userId, questionId, createdAt, question) {
51
+ prepare(sessionId, questionAnswerId, userId, questionId, createdAt, question, files) {
52
52
  return {
53
53
  payload: {
54
54
  sessionId,
@@ -57,6 +57,7 @@ const aiCfoView = (0, toolkit_1.createSlice)({
57
57
  questionId,
58
58
  createdAt,
59
59
  question,
60
+ files,
60
61
  },
61
62
  };
62
63
  },
@@ -197,7 +198,7 @@ const aiCfoView = (0, toolkit_1.createSlice)({
197
198
  draft.createSessionAndSubmitState.fetchState = 'In-Progress';
198
199
  draft.createSessionAndSubmitState.error = undefined;
199
200
  },
200
- prepare(agentId, userId, questionAnswerId, questionId, createdAt, question) {
201
+ prepare(agentId, userId, questionAnswerId, questionId, createdAt, question, files) {
201
202
  return {
202
203
  payload: {
203
204
  agentId,
@@ -206,6 +207,7 @@ const aiCfoView = (0, toolkit_1.createSlice)({
206
207
  questionId,
207
208
  createdAt,
208
209
  question,
210
+ files,
209
211
  },
210
212
  };
211
213
  },
@@ -69,7 +69,7 @@ function waitForChannelSubscription(pusherInstance, channelName, timeoutMs = 500
69
69
  }));
70
70
  }
71
71
  const createSessionAndSubmitEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(aiCfoViewReducer_1.createSessionAndSubmit.match), (0, operators_1.switchMap)((action) => {
72
- const { agentId, userId, questionAnswerId, questionId, createdAt, question, } = action.payload;
72
+ const { agentId, userId, questionAnswerId, questionId, createdAt, question, files, } = action.payload;
73
73
  const payload = { agent_id: agentId };
74
74
  return zeniAPI
75
75
  .postAndGetJSON(`${zeniAPI.apiEndPoints.aiCfoMicroServiceBaseUrl}/1.0/sessions`, payload)
@@ -113,7 +113,7 @@ const createSessionAndSubmitEpic = (actions$, _state$, zeniAPI) => actions$.pipe
113
113
  // This allows fetchChatHistory to run after the question is submitted
114
114
  (0, rxjs_1.of)((0, aiCfoViewReducer_1.createSessionAndSubmitSuccess)(),
115
115
  // Submit the question after handlers are bound
116
- (0, aiCfoViewReducer_1.submitQuestion)(sessionId, questionAnswerId, userId, questionId, createdAt, question),
116
+ (0, aiCfoViewReducer_1.submitQuestion)(sessionId, questionAnswerId, userId, questionId, createdAt, question, files),
117
117
  // Add question payload optimistically after submitQuestion (matches original order)
118
118
  // This is idempotent - won't create duplicates if called multiple times
119
119
  // submitQuestionEpic will find the question already exists and only update the response
@@ -126,6 +126,13 @@ const createSessionAndSubmitEpic = (actions$, _state$, zeniAPI) => actions$.pipe
126
126
  createdAt,
127
127
  },
128
128
  userId,
129
+ attachments: files != null && files.length > 0
130
+ ? files.map((file) => ({
131
+ filename: file.name,
132
+ file_size: file.size,
133
+ mime_type: file.type,
134
+ }))
135
+ : undefined,
129
136
  })));
130
137
  }));
131
138
  }
@@ -7,16 +7,31 @@ const aiCfoReducer_1 = require("../../../entity/aiCfo/aiCfoReducer");
7
7
  const responsePayload_1 = require("../../../responsePayload");
8
8
  const aiCfoViewReducer_1 = require("../aiCfoViewReducer");
9
9
  const submitQuestionEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(aiCfoViewReducer_1.submitQuestion.match), (0, operators_1.mergeMap)((action) => {
10
- const { questionAnswerId, userId, sessionId, questionId, createdAt, question, } = action.payload;
10
+ const { questionAnswerId, userId, sessionId, questionId, createdAt, question, files, } = action.payload;
11
11
  const { aiCfoViewState } = state$.value;
12
12
  const { uiState } = aiCfoViewState;
13
13
  const agentId = uiState.agentId;
14
- const payload = { chat_session_id: sessionId, message: question };
15
14
  if (agentId == null || Boolean(question) == false) {
16
15
  throw new Error('Invalid State');
17
16
  }
18
- return zeniAPI
19
- .postAndGetJSON(`${zeniAPI.apiEndPoints.aiCfoMicroServiceBaseUrl}/1.0/agents/${agentId}`, payload)
17
+ const endpoint = `${zeniAPI.apiEndPoints.aiCfoMicroServiceBaseUrl}/1.0/agents/${agentId}`;
18
+ let apiCall;
19
+ if (files != null && files.length > 0) {
20
+ const formData = new FormData();
21
+ formData.append('chat_session_id', sessionId);
22
+ formData.append('message', question);
23
+ for (const file of files) {
24
+ formData.append('files', file, file.name);
25
+ }
26
+ apiCall = zeniAPI.postFormData(endpoint, formData);
27
+ }
28
+ else {
29
+ apiCall = zeniAPI.postAndGetJSON(endpoint, {
30
+ chat_session_id: sessionId,
31
+ message: question,
32
+ });
33
+ }
34
+ return apiCall
20
35
  .pipe((0, operators_1.mergeMap)((response) => {
21
36
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
22
37
  const actions = [];
package/lib/zeniAPI.d.ts CHANGED
@@ -33,6 +33,7 @@ export interface ZeniAPI<ResponseType = FetchResponse> {
33
33
  getJSON<T>(path: string, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
34
34
  patchAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
35
35
  postAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
36
+ postFormData<T>(restEndPoint: string, formData: FormData, signal?: AbortSignal): Observable<T>;
36
37
  postJSON(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<ResponseType>;
37
38
  putAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
38
39
  update(userId?: string, sessionId?: string, tenantId?: string): void;
@@ -59,6 +60,7 @@ export declare class ZeniAPIClient implements ZeniAPI {
59
60
  getJSON<T>(restEndPoint: string, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
60
61
  postJSON(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<FetchResponse>;
61
62
  postAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
63
+ postFormData<T>(restEndPoint: string, formData: FormData, signal?: AbortSignal): Observable<T>;
62
64
  deleteAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
63
65
  putAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
64
66
  patchAndGetJSON<T>(restEndPoint: string, body?: Record<string, unknown>, headers?: Record<string, unknown>, signal?: AbortSignal): Observable<T>;
package/lib/zeniAPI.js CHANGED
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  Object.defineProperty(exports, "__esModule", { value: true });
3
14
  exports.ZeniAPIClient = void 0;
4
15
  const cross_fetch_1 = require("cross-fetch");
@@ -75,6 +86,19 @@ class ZeniAPIClient {
75
86
  }).then((response) => this.processJsonResponse(response));
76
87
  return (0, rxjs_1.from)(promise);
77
88
  }
89
+ postFormData(restEndPoint, formData, signal) {
90
+ // Use apiHeaders for auth headers, then remove Content-Type
91
+ // so the browser sets multipart/form-data with the correct boundary
92
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
93
+ const _a = this.apiHeaders(), { 'Content-Type': _contentType } = _a, headers = __rest(_a, ['Content-Type']);
94
+ const promise = (0, cross_fetch_1.fetch)(restEndPoint, {
95
+ method: 'POST',
96
+ body: formData,
97
+ headers,
98
+ signal,
99
+ }).then((response) => this.processJsonResponse(response));
100
+ return (0, rxjs_1.from)(promise);
101
+ }
78
102
  deleteAndGetJSON(restEndPoint, body, headers, signal) {
79
103
  let apiHeaders = this.apiHeaders(headers);
80
104
  if (body != null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "4.19.24",
3
+ "version": "4.19.26",
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",