@envive-ai/react-hooks 0.3.6 → 0.3.7

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 (142) hide show
  1. package/dist/application/commerce-api.cjs +1 -1
  2. package/dist/application/commerce-api.js +1 -1
  3. package/dist/application/models/api/userEvent.d.cts +4 -2
  4. package/dist/application/models/api/userEvent.d.ts +4 -2
  5. package/dist/application/models/graphql/queries/getColorsAndFrontendQuery.cjs +18 -0
  6. package/dist/application/models/graphql/queries/getColorsAndFrontendQuery.js +18 -0
  7. package/dist/application/models/guards/api/isApiFormResponse.cjs +1 -1
  8. package/dist/application/models/guards/api/isApiFormResponse.js +1 -1
  9. package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.cjs +1 -1
  10. package/dist/application/models/guards/api/isApiFormSubmittedResponseAttributes.js +1 -1
  11. package/dist/application/models/guards/api/isApiOrderResponseAttributes.cjs +1 -1
  12. package/dist/application/models/guards/api/isApiOrderResponseAttributes.js +1 -1
  13. package/dist/application/models/guards/api/isApiProductResponseAttributes.cjs +1 -1
  14. package/dist/application/models/guards/api/isApiProductResponseAttributes.js +1 -1
  15. package/dist/application/models/guards/api/isApiQueryTypedEventAttributes.cjs +2 -2
  16. package/dist/application/models/guards/api/isApiQueryTypedEventAttributes.js +2 -2
  17. package/dist/application/models/guards/api/isApiResponse.cjs +1 -1
  18. package/dist/application/models/guards/api/isApiResponse.js +1 -1
  19. package/dist/application/utils/analyticsUtils.cjs +1 -1
  20. package/dist/application/utils/analyticsUtils.js +1 -1
  21. package/dist/application/utils/elementObserver.d.cts +2 -2
  22. package/dist/application/utils/elementObserver.d.ts +2 -2
  23. package/dist/atoms/app/variant.d.cts +6 -6
  24. package/dist/atoms/app/variant.d.ts +6 -6
  25. package/dist/atoms/chat/chatState.d.ts +17 -17
  26. package/dist/atoms/chat/form.d.cts +2 -2
  27. package/dist/atoms/chat/form.d.ts +2 -2
  28. package/dist/atoms/chat/index.cjs +1 -3
  29. package/dist/atoms/chat/index.d.cts +4 -5
  30. package/dist/atoms/chat/index.d.ts +4 -5
  31. package/dist/atoms/chat/index.js +2 -3
  32. package/dist/atoms/chat/lastMessage.d.cts +2 -2
  33. package/dist/atoms/chat/lastMessage.d.ts +2 -2
  34. package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
  35. package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
  36. package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
  37. package/dist/atoms/chat/renderedWidgetRefs.d.ts +2 -2
  38. package/dist/atoms/chat/suggestions.d.cts +2 -2
  39. package/dist/atoms/chat/suggestions.d.ts +2 -2
  40. package/dist/atoms/globalSearch/globalSearch.d.cts +5 -5
  41. package/dist/atoms/globalSearch/globalSearch.d.ts +5 -5
  42. package/dist/atoms/org/customerService.d.cts +6 -6
  43. package/dist/atoms/org/customerService.d.ts +6 -6
  44. package/dist/atoms/org/graphqlConfig.d.cts +4 -4
  45. package/dist/atoms/org/graphqlConfig.d.ts +4 -4
  46. package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
  47. package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
  48. package/dist/atoms/org/orgAnalyticsConfig.d.cts +5 -5
  49. package/dist/atoms/org/orgAnalyticsConfig.d.ts +5 -5
  50. package/dist/atoms/search/chatSearch.d.cts +17 -17
  51. package/dist/atoms/search/chatSearch.d.ts +17 -17
  52. package/dist/atoms/search/searchAPI.d.cts +13 -13
  53. package/dist/atoms/search/searchAPI.d.ts +13 -13
  54. package/dist/atoms/search/types.d.cts +1 -1
  55. package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
  56. package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
  57. package/dist/contexts/featureFlagContext/featureFlagContext.cjs +1 -1
  58. package/dist/contexts/featureFlagContext/featureFlagContext.js +1 -1
  59. package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.cjs +1 -1
  60. package/dist/contexts/featureFlagServiceContext/featureFlagServiceContext.js +1 -1
  61. package/dist/contexts/graphqlContext/graphqlContext.cjs +41 -27
  62. package/dist/contexts/graphqlContext/graphqlContext.js +42 -27
  63. package/dist/contexts/graphqlContext/mockV3Config.cjs +47 -45
  64. package/dist/contexts/graphqlContext/mockV3Config.js +5 -3
  65. package/dist/contexts/newOrgConfigContext/newOrgConfigContext.cjs +1 -2
  66. package/dist/contexts/newOrgConfigContext/newOrgConfigContext.js +1 -2
  67. package/dist/contexts/salesAgentContext/chatAPI.cjs +26 -5
  68. package/dist/contexts/salesAgentContext/chatAPI.d.cts +7 -3
  69. package/dist/contexts/salesAgentContext/chatAPI.d.ts +7 -3
  70. package/dist/contexts/salesAgentContext/chatAPI.js +26 -5
  71. package/dist/contexts/salesAgentContext/salesAgentContext.cjs +4 -7
  72. package/dist/contexts/salesAgentContext/salesAgentContext.js +4 -7
  73. package/dist/contexts/salesAgentContext/salesAgentService.cjs +43 -18
  74. package/dist/contexts/salesAgentContext/salesAgentService.js +43 -18
  75. package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
  76. package/dist/contexts/systemSettingsContext/systemSettingsContext.d.ts +2 -2
  77. package/dist/contexts/types.d.cts +1 -1
  78. package/dist/contexts/types.d.ts +1 -1
  79. package/dist/contexts/typesV3.cjs +1 -1
  80. package/dist/contexts/typesV3.d.cts +4 -4
  81. package/dist/contexts/typesV3.d.ts +4 -4
  82. package/dist/contexts/typesV3.js +1 -1
  83. package/dist/contexts/userIdentityContext/userIdentityContext.cjs +1 -2
  84. package/dist/contexts/userIdentityContext/userIdentityContext.js +1 -2
  85. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.cts +2 -2
  86. package/dist/hooks/GrabAndScroll/useGrabAndScroll.d.ts +2 -2
  87. package/dist/hooks/GraphQLConfig/useGraphQLConfig.cjs +1 -2
  88. package/dist/hooks/GraphQLConfig/useGraphQLConfig.js +1 -2
  89. package/dist/hooks/Search/useSearchInput.cjs +1 -1
  90. package/dist/hooks/Search/useSearchInput.js +1 -1
  91. package/dist/hooks/utils.d.cts +1 -1
  92. package/dist/hooks/utils.d.ts +1 -1
  93. package/dist/packages/components-v3/dist/ChatHeader/hooks/useGetCloseButtonProperties.cjs +1 -1
  94. package/dist/packages/components-v3/dist/ChatHeader/hooks/useGetCloseButtonProperties.js +1 -1
  95. package/dist/packages/components-v3/dist/Container/Container.cjs +1 -1
  96. package/dist/packages/components-v3/dist/Container/Container.js +1 -1
  97. package/dist/packages/components-v3/dist/FloatingButton/FloatingButton.cjs +2 -0
  98. package/dist/packages/components-v3/dist/FloatingButton/FloatingButton.js +4 -0
  99. package/dist/packages/components-v3/dist/FloatingButton/components/Button.cjs +9 -0
  100. package/dist/packages/components-v3/dist/FloatingButton/components/Button.js +10 -0
  101. package/dist/packages/components-v3/dist/FloatingButton/components/Container.cjs +9 -0
  102. package/dist/packages/components-v3/dist/FloatingButton/components/Container.js +10 -0
  103. package/dist/packages/components-v3/dist/FloatingButton/components/Icon.cjs +3 -0
  104. package/dist/packages/components-v3/dist/FloatingButton/components/Icon.js +5 -0
  105. package/dist/packages/components-v3/dist/FloatingButton/components/Wrapper.cjs +9 -0
  106. package/dist/packages/components-v3/dist/FloatingButton/components/Wrapper.js +10 -0
  107. package/dist/packages/components-v3/dist/FloatingButton/components/index.cjs +4 -0
  108. package/dist/packages/components-v3/dist/FloatingButton/components/index.js +6 -0
  109. package/dist/packages/components-v3/dist/FloatingButton/index.cjs +2 -0
  110. package/dist/packages/components-v3/dist/FloatingButton/index.js +4 -0
  111. package/dist/packages/components-v3/dist/FloatingButton/types/types.cjs +17 -0
  112. package/dist/packages/components-v3/dist/FloatingButton/types/types.js +16 -0
  113. package/dist/packages/components-v3/dist/ImageGallery/components/Layout.cjs +1 -1
  114. package/dist/packages/components-v3/dist/ImageGallery/components/Layout.js +1 -1
  115. package/dist/packages/components-v3/dist/WelcomeMessage/components/SparkleIcon.cjs +1 -1
  116. package/dist/packages/components-v3/dist/WelcomeMessage/components/SparkleIcon.js +1 -1
  117. package/dist/packages/components-v3/dist/utils/CustomIcon.cjs +2 -0
  118. package/dist/packages/components-v3/dist/utils/CustomIcon.js +4 -0
  119. package/dist/services/amplitudeService/amplitudeService.cjs +5 -2
  120. package/dist/services/amplitudeService/amplitudeService.js +5 -2
  121. package/package.json +1 -5
  122. package/src/application/models/api/userEvent.ts +3 -1
  123. package/src/application/models/graphql/queries/getColorsAndFrontendQuery.ts +13 -0
  124. package/src/application/models/guards/api/isApiQueryTypedEventAttributes.ts +6 -1
  125. package/src/atoms/chat/index.ts +0 -1
  126. package/src/contexts/graphqlContext/graphqlContext.tsx +32 -41
  127. package/src/contexts/graphqlContext/mockV3Config.ts +3 -2
  128. package/src/contexts/newOrgConfigContext/newOrgConfigContext.tsx +0 -1
  129. package/src/contexts/salesAgentContext/chatAPI.ts +21 -4
  130. package/src/contexts/salesAgentContext/salesAgentContext.tsx +3 -7
  131. package/src/contexts/salesAgentContext/salesAgentService.ts +36 -11
  132. package/src/contexts/typesV3.ts +3 -4
  133. package/src/contexts/uiConfigContext/__tests__/uiConfigContext.test.tsx +3 -2
  134. package/src/contexts/userIdentityContext/userIdentityContext.tsx +0 -1
  135. package/src/hooks/GraphQLConfig/useGraphQLConfig.ts +0 -1
  136. package/src/services/amplitudeService/__tests__/amplitudeService.test.ts +0 -15
  137. package/src/services/amplitudeService/amplitudeService.ts +2 -1
  138. package/dist/atoms/chat/replies.cjs +0 -46
  139. package/dist/atoms/chat/replies.d.cts +0 -14
  140. package/dist/atoms/chat/replies.d.ts +0 -14
  141. package/dist/atoms/chat/replies.js +0 -45
  142. package/src/atoms/chat/replies.ts +0 -56
@@ -1,26 +1,23 @@
1
- import React, { ReactNode, createContext, useCallback, useContext, useMemo } from 'react';
1
+ import { ReactNode, createContext, useCallback, useContext, useMemo } from 'react';
2
2
  import { useAtomValue } from 'jotai';
3
3
  import { baseUrlAtom, orgLevelApiKeyAtom } from 'src/atoms/envive/enviveConfig';
4
4
  import { getMerchantOrgIdQuery } from 'src/application/models/graphql/queries/getMerchantOrgIdQuery';
5
5
  import { validateGraphQLOrgId } from 'src/application/models/validators/validateGraphQLOrgId';
6
- import {
7
- GetMerchantColorsQueryData,
8
- GetMerchantFrontendConfigQueryData,
9
- } from 'src/application/models/graphql';
10
6
  import { ColorMapping } from 'src/application/models/colorsConfig';
11
7
  import { FrontendConfig } from 'src/application/models/frontendConfig';
12
8
  import Logger from 'src/application/logging/logger';
13
- import { configVersion } from 'src/types/config-versions';
14
9
  import {
15
10
  CamelCasedPropertiesDeep,
16
11
  transformSnakeToCamel,
17
12
  validateAndTransformMountingConfig,
18
13
  validateAndTransformPageVariants,
19
14
  } from 'src/application/models';
15
+ import { getColorsAndFrontendQuery } from 'src/application/models/graphql/queries/getColorsAndFrontendQuery';
20
16
  import { FrontendConfigV3 } from 'src/application/models/frontendConfigV3';
21
17
  import { ColorMappingV3 } from 'src/application/models/colorsConfigV3';
18
+ import { FloatingButtonLocation } from '@envive-ai/react-toolkit-v3/FloatingButton';
22
19
  import { mockV3ColorsConfig, mockV3FrontendConfig } from './mockV3Config';
23
- import { ConfigVersionEnum, Position, WidgetConfigV3 } from '../typesV3';
20
+ import { ConfigVersionEnum, WidgetConfigV3 } from '../typesV3';
24
21
  import {
25
22
  OrgPageConfig,
26
23
  PageVariantConfig,
@@ -28,19 +25,6 @@ import {
28
25
  WidgetMountingConfig,
29
26
  } from '../types';
30
27
 
31
- interface BaseMeConfigQueryResponse {
32
- me: {
33
- org?: {
34
- id: string;
35
- };
36
- getProductsConfigByVersion?: {
37
- frontend?: {
38
- values: CamelCasedPropertiesDeep<GetMerchantFrontendConfigQueryData>;
39
- };
40
- colors?: { values: CamelCasedPropertiesDeep<GetMerchantColorsQueryData> };
41
- };
42
- };
43
- }
44
28
  export type ColorsConfigResponse = CamelCasedPropertiesDeep<ColorMapping>;
45
29
  export type FrontendConfigResponse = CamelCasedPropertiesDeep<FrontendConfig>;
46
30
  export type ColorsConfigV3Response = CamelCasedPropertiesDeep<ColorMappingV3>;
@@ -63,18 +47,6 @@ interface GraphQLContextValue {
63
47
 
64
48
  const GraphQLContext = createContext<GraphQLContextValue | null>(null);
65
49
 
66
- const colorsAndFrontendConfigQuery = () => `
67
- query ($version: String = "${configVersion()}") {
68
- me {
69
- getProductsConfigByVersion(version: $version) {
70
- frontend { values }
71
- colors { values }
72
- v_three_config { values }
73
- }
74
- }
75
- }
76
- `;
77
-
78
50
  type GraphQLProviderProps = {
79
51
  children: ReactNode;
80
52
  requestV3Config?: boolean;
@@ -106,18 +78,18 @@ const DEFAULT_PAGE_VARIANTS: PageVariantConfig[] = [
106
78
  },
107
79
  ];
108
80
 
109
- const mapPositionToCamelCase = (position: string): Position => {
81
+ const mapPositionToCamelCase = (position: string): FloatingButtonLocation => {
110
82
  if (position === 'bottom-left') {
111
- return 'bottomLeft';
83
+ return FloatingButtonLocation.BOTTOM_LEFT;
112
84
  }
113
85
  if (position === 'middle-left') {
114
- return 'middleLeft';
86
+ return FloatingButtonLocation.MIDDLE_LEFT;
115
87
  }
116
88
  if (position === 'middle-right') {
117
- return 'middleRight';
89
+ return FloatingButtonLocation.MIDDLE_RIGHT;
118
90
  }
119
91
  if (position === 'bottom-right') {
120
- return 'bottomRight';
92
+ return FloatingButtonLocation.BOTTOM_RIGHT;
121
93
  }
122
94
  throw new Error(`Invalid position: ${position}`);
123
95
  };
@@ -234,7 +206,7 @@ export const GraphQLProvider = ({
234
206
 
235
207
  const getV3Config = useCallback(async (): Promise<GraphQlConfigValues> => {
236
208
  try {
237
- const query = await colorsAndFrontendConfigQuery();
209
+ const query = await getColorsAndFrontendQuery();
238
210
  if (!query) {
239
211
  throw new Error('Colors and frontend config query is not defined');
240
212
  }
@@ -271,10 +243,13 @@ export const GraphQLProvider = ({
271
243
  : DEFAULT_PAGE_VARIANTS;
272
244
 
273
245
  const v3ColorsConfig = transformSnakeToCamel(v3RootConfig?.colors?.values);
274
-
275
246
  // If the v3 root config is not found and we are configured to return the deprecated config, we will return the mocked config
276
247
  if (!v3RootConfig && mockV3ConfigToDeprecatedConfig) {
277
248
  const isSemanticColors = !window.location.href.includes('globals=merchant');
249
+ Logger.logInfo('GraphQLContext | Returning mock v3 config', {
250
+ colorsConfig: mockV3ColorsConfig as ColorsConfigV3Response,
251
+ frontendConfig: mockV3FrontendConfig as FrontendConfigV3Response,
252
+ });
278
253
  const colorsConfig = mockV3ColorsConfig;
279
254
  const frontendConfig = mockV3FrontendConfig;
280
255
  return {
@@ -282,9 +257,24 @@ export const GraphQLProvider = ({
282
257
  ? (colorsConfig as ColorsConfigV3Response)
283
258
  : (v3ColorsConfig as ColorsConfigV3Response),
284
259
  frontendConfig: frontendConfig as FrontendConfigV3Response,
260
+ orgPageConfig: {
261
+ pageVariants: [],
262
+ widgetConfigs: {},
263
+ mountingConfigs: {},
264
+ },
285
265
  };
286
266
  }
287
267
 
268
+ Logger.logInfo('GraphQLContext | Returning v3 config', {
269
+ colorsConfig: v3ColorsConfig as ColorsConfigV3Response,
270
+ frontendConfig: v3FrontendConfig as FrontendConfigV3Response,
271
+ orgPageConfig: {
272
+ pageVariants: v3pageVariants,
273
+ widgetConfigs: v3WidgetConfigs,
274
+ mountingConfigs: v3MountingConfigs,
275
+ },
276
+ });
277
+
288
278
  return {
289
279
  colorsConfig: v3ColorsConfig as ColorsConfigV3Response,
290
280
  frontendConfig: {
@@ -307,7 +297,7 @@ export const GraphQLProvider = ({
307
297
 
308
298
  const getColorsAndFrontendConfig = useCallback(async (): Promise<GraphQlConfigValues> => {
309
299
  try {
310
- const query = await colorsAndFrontendConfigQuery();
300
+ const query = await getColorsAndFrontendQuery();
311
301
  if (!query) {
312
302
  throw new Error('Colors and frontend config query is not defined');
313
303
  }
@@ -347,10 +337,11 @@ export const GraphQLProvider = ({
347
337
  }, [executeQuery]);
348
338
 
349
339
  const getConfig = useCallback(async (): Promise<GraphQlConfigValues> => {
350
- console.log('GraphQLProvider: getConfig: requestV3Config', requestV3Config);
351
340
  if (requestV3Config) {
341
+ Logger.logInfo('GraphQLContext | Getting v3 config', requestV3Config);
352
342
  return getV3Config();
353
343
  }
344
+ Logger.logInfo('GraphQLContext | Getting colors and frontend config', requestV3Config);
354
345
  return getColorsAndFrontendConfig();
355
346
  }, [getColorsAndFrontendConfig, getV3Config, requestV3Config]);
356
347
 
@@ -10,6 +10,7 @@ import { ChatHeaderVariant } from '@envive-ai/react-toolkit-v3/ChatHeader';
10
10
  import { SparkleIconColor } from '@envive-ai/react-toolkit-v3/WelcomeMessage';
11
11
 
12
12
  import { CustomerServiceType } from 'src/types/customerService';
13
+ import { FloatingButtonLocation } from '@envive-ai/react-toolkit-v3/FloatingButton';
13
14
  import { ConfigVersionEnum, SocialProofWidgetKind, WidgetTypeV3 } from '../typesV3';
14
15
 
15
16
  const mockImages = [
@@ -111,7 +112,7 @@ export const mockV3FrontendConfig: FrontendConfigV3 = {
111
112
  },
112
113
  },
113
114
  floatingButton: {
114
- position: 'bottomRight',
115
+ position: FloatingButtonLocation.BOTTOM_RIGHT,
115
116
  backgroundColor: ColorNames.BackgroundPrimary,
116
117
  mode: 'dark',
117
118
  showOption: 'always',
@@ -119,7 +120,7 @@ export const mockV3FrontendConfig: FrontendConfigV3 = {
119
120
  iconSVGSrc: '',
120
121
  },
121
122
  floatingChat: {
122
- headerBackgroundColor: undefined,
123
+ headerBackgroundColor: ColorNames.BackgroundPrimary,
123
124
  headerMode: ChatHeaderVariant.DARK,
124
125
  welcomeMessageIconColor: SparkleIconColor.ACCENT_PRIMARY,
125
126
  showVerifiedBuyer: true,
@@ -25,7 +25,6 @@ export const NewOrgConfigProvider: React.FC<NewOrgConfigProviderProps> = ({
25
25
  const setNewOrgConfig = useSetAtom(newOrgConfigAtom);
26
26
 
27
27
  const { data: fetchedConfig, loading, error } = useUIConfig();
28
- console.log('NewOrgConfigProvider: newConfig', fetchedConfig, loading, error);
29
28
 
30
29
  const contextValue = useMemo(() => {
31
30
  if (!orgShortName || loading) {
@@ -6,12 +6,13 @@ import { useSetAtom } from 'jotai';
6
6
  import { useCallback } from 'react';
7
7
  import { v4 as uuid } from 'uuid';
8
8
  import { queueUserEventAtom } from 'src/atoms/chat/messageQueue';
9
+ import { SpiffyMetricsEventName, useAmplitude } from '../amplitudeContext';
9
10
 
10
11
  export interface SalesAgentChatAPI {
11
12
  logPageVisit: ({ pageVisitCategory }: { pageVisitCategory: PageVisitCategory }) => void;
12
13
  logUserEvent: (event: UserEvent) => void;
13
14
  onSuggestionClicked: (suggestion: Suggestion) => void;
14
- onTypedMessageSubmitted: ({ query }: { query: string }) => void;
15
+ onTypedMessageSubmitted: ({ query, userTyped }: { query: string; userTyped: boolean }) => void;
15
16
  onFormResponseSubmitted: (formResponse: any) => void; // TODO: Figure out the right type
16
17
  }
17
18
 
@@ -19,6 +20,7 @@ export const useSalesAgentChatAPI = () => {
19
20
  // TODO: Each of these functions will trigger both the necessary amplitude events and initiate the
20
21
  // necessary actions to trigger the backend API
21
22
  const queueUserEvent = useSetAtom(queueUserEventAtom);
23
+ const { trackEvent } = useAmplitude();
22
24
 
23
25
  const logPageVisit = useCallback(
24
26
  ({ pageVisitCategory }: { pageVisitCategory: PageVisitCategory }) => {
@@ -44,6 +46,13 @@ export const useSalesAgentChatAPI = () => {
44
46
  );
45
47
  const onSuggestionClicked = useCallback(
46
48
  (suggestion: Suggestion) => {
49
+ trackEvent({
50
+ eventName: SpiffyMetricsEventName.ChatSuggestionClicked,
51
+ eventProps: {
52
+ suggestionId: suggestion.id,
53
+ content: suggestion.content,
54
+ },
55
+ });
47
56
  const event: UserEvent = {
48
57
  eventId: uuid(),
49
58
  category: UserEventCategory.SuggestionClicked,
@@ -55,21 +64,29 @@ export const useSalesAgentChatAPI = () => {
55
64
  };
56
65
  queueUserEvent(event);
57
66
  },
58
- [queueUserEvent],
67
+ [queueUserEvent, trackEvent],
59
68
  );
60
69
  const onTypedMessageSubmitted = useCallback(
61
- ({ query }: { query: string }) => {
70
+ ({ query, userTyped }: { query: string; userTyped: boolean }) => {
71
+ trackEvent({
72
+ eventName: SpiffyMetricsEventName.ChatUserMessageInput,
73
+ eventProps: {
74
+ query,
75
+ userTyped,
76
+ },
77
+ });
62
78
  const event: UserEvent = {
63
79
  eventId: uuid(),
64
80
  category: UserEventCategory.QueryTyped,
65
81
  createdAt: new Date().toISOString(),
66
82
  attributes: {
67
83
  query,
84
+ userTyped,
68
85
  },
69
86
  };
70
87
  queueUserEvent(event);
71
88
  },
72
- [queueUserEvent],
89
+ [queueUserEvent, trackEvent],
73
90
  );
74
91
  const onFormResponseSubmitted = useCallback(() => {
75
92
  // TODO: Implement the form response submitted
@@ -1,6 +1,7 @@
1
1
  import { useAtom, useAtomValue, useSetAtom } from 'jotai';
2
2
  import { ReactNode, createContext, useCallback, useEffect, useMemo } from 'react';
3
3
  import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
4
+ import Logger from 'src/application/logging/logger';
4
5
  import { Message, MessageRole, MessageType } from 'src/application/models/message';
5
6
  import { NextMessageRequest, Suggestion, UserEvent } from 'src/application/models';
6
7
  import {
@@ -55,27 +56,22 @@ export const SalesAgentProvider: React.FC<{ children: ReactNode }> = ({ children
55
56
  const sendMessagesToBackend = useCallback(
56
57
  async (requestPayload: NextMessageRequest) => {
57
58
  try {
58
- const response = await getStreamingResponses(requestPayload);
59
+ await getStreamingResponses(requestPayload);
59
60
  setIsInitialized(true);
60
61
 
61
- console.log('response', response);
62
62
  // Remove the pending message from the user events
63
63
  requestPayload.userEvents?.map(userEvent => markUserEventsProcessed([userEvent.eventId]));
64
64
  } catch (error) {
65
- console.error('error sending message');
65
+ Logger.logError('[envive-ai] error sending message', error);
66
66
  }
67
67
  },
68
68
  [getStreamingResponses, setIsInitialized, markUserEventsProcessed],
69
69
  );
70
70
 
71
- console.log('userQueueEventCount', userQueueEventCount);
72
- console.log('userEvents', userEvents);
73
-
74
71
  // This is the primary event loop for communicating with the backend API
75
72
  // It will be triggered when there are pending messages to be sent to the backend
76
73
  // It will be responsible for sending the messages to the backend and receiving the responses
77
74
  useEffect(() => {
78
- console.log('SalesAgentProvider useEffect', userQueueEventCount, isInitialized, userEvents);
79
75
  if (userQueueEventCount > 0) {
80
76
  const payloadEvents = userEvents.slice(0, userQueueEventCount);
81
77
 
@@ -22,7 +22,10 @@ import {
22
22
  suggestionsAtom,
23
23
  } from 'src/atoms/chat/chatState';
24
24
  import { useMessageInterceptor } from 'src/interceptors/useMessageInterceptor';
25
- import { useFeatureFlagService } from '../featureFlagServiceContext';
25
+ import { SpiffyMetricsEventName, useAmplitude } from 'src/contexts/amplitudeContext';
26
+ import { useFeatureFlagService } from 'src/contexts/featureFlagServiceContext';
27
+ import { UserEventCategory } from '@spiffy-ai/commerce-api-client';
28
+
26
29
  import { StatusCodeError } from './statusCodeError';
27
30
 
28
31
  interface SalesAgentService {
@@ -35,6 +38,25 @@ interface SalesAgentService {
35
38
  hydrateMessages: () => Promise<void>;
36
39
  }
37
40
 
41
+ const inputPropsToTrackingProps = (
42
+ payload: NextMessageRequest,
43
+ ): Record<string, unknown> | undefined => {
44
+ const [userEvent] = payload.userEvents || [];
45
+ if (userEvent.category === UserEventCategory.SuggestionClicked) {
46
+ return {
47
+ user_event_type: 'suggestion_clicked',
48
+ user_query: userEvent.attributes.content,
49
+ };
50
+ }
51
+ if (userEvent.category === UserEventCategory.QueryTyped) {
52
+ return {
53
+ user_event_type: 'query_typed',
54
+ user_query: userEvent.attributes.query,
55
+ };
56
+ }
57
+ return {};
58
+ };
59
+
38
60
  export const getQueryParam = (key: string): string | null => {
39
61
  const urlObj = new URL(window.location.href);
40
62
  return urlObj.searchParams.get(key);
@@ -115,6 +137,7 @@ const processStreamingResponse = async (
115
137
  setResponseStreaming: (responseStreaming: boolean) => void,
116
138
  ): Promise<void> => {
117
139
  let lastMessage: Message | undefined;
140
+ setResponseStreaming(true);
118
141
 
119
142
  for await (const response of stream) {
120
143
  try {
@@ -126,8 +149,6 @@ const processStreamingResponse = async (
126
149
  throw new Error('No response from stream');
127
150
  }
128
151
 
129
- setResponseStreaming(true);
130
-
131
152
  const message = messageFromResponse(response);
132
153
  if (!message) {
133
154
  throw new Error('Failed to transform API response to client message');
@@ -148,6 +169,7 @@ const processStreamingResponse = async (
148
169
  response,
149
170
  });
150
171
  }
172
+ setResponseStreaming(false);
151
173
  }
152
174
  };
153
175
 
@@ -158,6 +180,7 @@ export const useSalesAgentService: () => SalesAgentService = () => {
158
180
  const setPendingResponse = useSetAtom(pendingResponseAtom);
159
181
  const setResponseStreaming = useSetAtom(responseStreamingAtom);
160
182
  const messageInterceptor = useMessageInterceptor();
183
+ const { trackEvent } = useAmplitude();
161
184
 
162
185
  const featureFlagService = useFeatureFlagService();
163
186
  const context = useAtomValue(appDetailsAtom);
@@ -192,10 +215,8 @@ export const useSalesAgentService: () => SalesAgentService = () => {
192
215
 
193
216
  const getStreamingResponses = useCallback(
194
217
  async (payload: NextMessageRequest): Promise<void> => {
195
- // logPerfMetric(PerfMetricsEvents.FirstResponseStarted);
196
- // const startTime = Date.now();
218
+ const startTime = Date.now();
197
219
  setPendingResponse(true);
198
- console.log('getStreamingResponses payload', JSON.stringify(payload, null, 2));
199
220
  const stream = CommerceApiClient.getNextResponseStreaming(payload);
200
221
 
201
222
  try {
@@ -208,9 +229,16 @@ export const useSalesAgentService: () => SalesAgentService = () => {
208
229
  setResponseStreaming,
209
230
  );
210
231
 
211
- // TODO: Add support for the Chrome Extension communication
212
232
  // Log successful next_responses call
213
- // const responseTime = Date.now() - startTime;
233
+ const responseTime = Date.now() - startTime;
234
+ trackEvent({
235
+ eventName: SpiffyMetricsEventName.ChatAssistantResponse,
236
+ eventProps: {
237
+ responseTimeMs: responseTime.toString(),
238
+ ...inputPropsToTrackingProps(payload),
239
+ },
240
+ });
241
+ // TODO: Add support for the Chrome Extension communication
214
242
  // await logBundleEvent({
215
243
  // level: 'info',
216
244
  // event: 'NEXT_RESPONSE_SUCCESS',
@@ -264,14 +292,11 @@ export const useSalesAgentService: () => SalesAgentService = () => {
264
292
 
265
293
  const hydrateMessages = useCallback(async () => {
266
294
  const { orgId, chatId, userId } = context;
267
- console.log('hydrateMessages', orgId, chatId, userId, context);
268
295
  const { messages: existingMessages, userEvents } = await CommerceApiClient.getResponses(
269
296
  orgId,
270
297
  chatId,
271
298
  userId,
272
299
  );
273
- console.log('existingMessages', existingMessages);
274
- console.log('userEvents', userEvents);
275
300
  setMessages([...existingMessages]);
276
301
  }, [context, setMessages]);
277
302
 
@@ -5,6 +5,7 @@ import { WidgetWrapperVariant } from '@envive-ai/react-toolkit-v3/WidgetWrapper'
5
5
  import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
6
6
  import { DynamicLayout } from '@envive-ai/react-toolkit-v3/SocialProof';
7
7
  import { SparkleIconColor } from '@envive-ai/react-toolkit-v3/WelcomeMessage';
8
+ import { FloatingButtonLocation } from '@envive-ai/react-toolkit-v3/FloatingButton';
8
9
  import { ColorNames } from '../application/models/colorsConfigV3';
9
10
  import { CustomerServiceType } from '../types/customerService';
10
11
  import type { MerchantVariantSettings, SearchConfig } from './types';
@@ -170,14 +171,12 @@ type ConfigVersion = ConfigVersionEnum.V3 | ConfigVersionEnum.Deprecated | undef
170
171
 
171
172
  type Mode = 'dark' | 'light';
172
173
 
173
- type Position = 'bottomLeft' | 'middleLeft' | 'middleRight' | 'bottomRight';
174
-
175
174
  type ShowOptions = 'always' | 'postInteraction' | 'none';
176
175
 
177
176
  type Style = 'attached' | 'detached';
178
177
 
179
178
  type FloatingButtonConfig = {
180
- position: Position;
179
+ position: FloatingButtonLocation;
181
180
  backgroundColor?: string;
182
181
  mode: Mode;
183
182
  showOption: ShowOptions;
@@ -341,8 +340,8 @@ export type {
341
340
  PromptButtonCarouselWithImageWidgetV3Config,
342
341
  FloatingChatWidgetV3Config,
343
342
  FloatingChatConfig,
343
+ FloatingButtonConfig,
344
344
  CustomerServiceIntegration,
345
- Position,
346
345
  };
347
346
 
348
347
  export { SocialProofWidgetKind };
@@ -4,9 +4,10 @@ import Logger from 'src/application/logging/logger';
4
4
  import { useNewOrgConfig } from 'src/hooks/NewOrgConfig';
5
5
  import { SparkleIconColor } from '@envive-ai/react-toolkit-v3/WelcomeMessage';
6
6
  import { ChatHeaderVariant } from '@envive-ai/react-toolkit-v3/ChatHeader';
7
+ import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
8
+ import { FloatingButtonLocation } from '@envive-ai/react-toolkit-v3/FloatingButton';
7
9
  import { UiConfigProvider, useUiConfig } from '../uiConfigContext';
8
10
  import { ConfigVersionEnum, OrgUIConfigV3 } from '../../typesV3';
9
- import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
10
11
 
11
12
  // Mock the Logger to avoid console output in tests
12
13
  vi.spyOn(Logger, 'logInfo').mockImplementation(() => {});
@@ -107,7 +108,7 @@ describe('UiConfigProvider', () => {
107
108
  },
108
109
  },
109
110
  floatingButton: {
110
- position: 'bottomRight',
111
+ position: FloatingButtonLocation.BOTTOM_RIGHT,
111
112
  backgroundColor: '#000000',
112
113
  mode: 'light',
113
114
  showOption: 'always',
@@ -156,7 +156,6 @@ export const UserIdentityProvider: React.FC<{ children: React.ReactNode }> = ({
156
156
  useEffect(() => {
157
157
  if (isReady && !localUserId) {
158
158
  const newUserId = getUserIdOrDefault();
159
- console.log('useUserIdentity useEffect - setting localUserId', newUserId);
160
159
  setLocalUserId(newUserId);
161
160
  setUserId(newUserId);
162
161
  }
@@ -54,7 +54,6 @@ export const useUIConfig = () => {
54
54
  }
55
55
  }, [data, getConfig, isReady, loading]);
56
56
 
57
- console.log('====== useUIConfig hook ======', isReady, loading, data, error);
58
57
  useEffect(() => {
59
58
  fetchConfig();
60
59
  }, [fetchConfig]);
@@ -435,21 +435,6 @@ describe('AmplitudeService', () => {
435
435
  const eventProps = callArgs[1];
436
436
  expect(eventProps).toHaveProperty('test', 'value');
437
437
  });
438
-
439
- it('should replace existing supplemental props', async () => {
440
- const service = createService();
441
- service.setSupplementalDefaultProps({ prop1: 'value1' });
442
- service.setSupplementalDefaultProps({ prop2: 'value2' });
443
-
444
- await service.trackEvent({
445
- eventName: SpiffyMetricsEventName.ChatUserMessageInput,
446
- });
447
-
448
- const callArgs = mockTrack.mock.calls[0];
449
- const eventProps = callArgs[1];
450
- expect(eventProps).toHaveProperty('prop2', 'value2');
451
- expect(eventProps).not.toHaveProperty('prop1');
452
- });
453
438
  });
454
439
 
455
440
  describe('Event enrichment', () => {
@@ -318,7 +318,8 @@ export class AmplitudeService {
318
318
  }
319
319
  }
320
320
 
321
+ // Ensure that supplemental default props are merged with the existing props
321
322
  setSupplementalDefaultProps(props: Record<string, unknown>): void {
322
- this.supplementalDefaultProps = props;
323
+ this.supplementalDefaultProps = { ...this.supplementalDefaultProps, ...props };
323
324
  }
324
325
  }
@@ -1,46 +0,0 @@
1
- const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
- const require_message = require('../../application/models/message.cjs');
3
- require('../../application/models/index.cjs');
4
- const require_amplitudeService = require('../../services/amplitudeService/amplitudeService.cjs');
5
- require('../../contexts/amplitudeContext/amplitudeContext.cjs');
6
- const require_atoms_chat_chatState = require('./chatState.cjs');
7
- const require_amplitudeTrackEventAtom = require('../amplitude/amplitudeTrackEventAtom.cjs');
8
- const require_messageQueue = require('./messageQueue.cjs');
9
- require('./index.cjs');
10
- let __spiffy_ai_commerce_api_client = require("@spiffy-ai/commerce-api-client");
11
- let jotai = require("jotai");
12
-
13
- //#region src/atoms/chat/replies.ts
14
- const handleReplyAtom = (0, jotai.atom)(null, (get, set, { message, userTyped }) => {
15
- if (message.type !== require_message.MessageType.QueryTyped) return;
16
- const trackEvent = get(require_amplitudeTrackEventAtom.amplitudeTrackEventAtom);
17
- const queryTyped = message.metadata.content;
18
- set(require_atoms_chat_chatState.replyEventCategoryAtom, __spiffy_ai_commerce_api_client.UserEventCategory.QueryTyped);
19
- set(require_atoms_chat_chatState.userQueryAtom, queryTyped);
20
- set(require_atoms_chat_chatState.messagesAtom, [...get(require_atoms_chat_chatState.messagesAtom), [message]]);
21
- set(require_atoms_chat_chatState.userHasRepliedAtom, true);
22
- set(require_messageQueue.queueUserEventAtom, {
23
- eventId: message.id,
24
- createdAt: message.createdAt,
25
- category: __spiffy_ai_commerce_api_client.UserEventCategory.QueryTyped,
26
- attributes: { query: queryTyped }
27
- });
28
- if (trackEvent) trackEvent({
29
- eventName: require_amplitudeService.SpiffyMetricsEventName.ChatUserMessageInput,
30
- eventProps: {
31
- message_id: message.id,
32
- message_role: message.role,
33
- message_type: message.type,
34
- message_metadata: {
35
- content: message?.metadata?.content,
36
- created_at: message.createdAt,
37
- user_typed: userTyped
38
- }
39
- },
40
- alsoSendToGoogleAnalytics: true
41
- });
42
- });
43
-
44
- //#endregion
45
- exports.handleReplyAtom = handleReplyAtom;
46
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwbGllcy5janMiLCJuYW1lcyI6WyJNZXNzYWdlVHlwZSIsImFtcGxpdHVkZVRyYWNrRXZlbnRBdG9tIiwicmVwbHlFdmVudENhdGVnb3J5QXRvbSIsIlVzZXJFdmVudENhdGVnb3J5IiwidXNlclF1ZXJ5QXRvbSIsIm1lc3NhZ2VzQXRvbSIsInVzZXJIYXNSZXBsaWVkQXRvbSIsInF1ZXVlVXNlckV2ZW50QXRvbSIsIlNwaWZmeU1ldHJpY3NFdmVudE5hbWUiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXRvbXMvY2hhdC9yZXBsaWVzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGF0b20gfSBmcm9tICdqb3RhaSc7XG5pbXBvcnQgeyBNZXNzYWdlLCBNZXNzYWdlVHlwZSB9IGZyb20gJ3NyYy9hcHBsaWNhdGlvbi9tb2RlbHMnO1xuaW1wb3J0IHtcbiAgbWVzc2FnZXNBdG9tLFxuICByZXBseUV2ZW50Q2F0ZWdvcnlBdG9tLFxuICB1c2VySGFzUmVwbGllZEF0b20sXG4gIHVzZXJRdWVyeUF0b20sXG59IGZyb20gJ3NyYy9hdG9tcy9jaGF0JztcbmltcG9ydCB7IFVzZXJFdmVudENhdGVnb3J5IH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmltcG9ydCB7IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUgfSBmcm9tICdzcmMvY29udGV4dHMvYW1wbGl0dWRlQ29udGV4dC9hbXBsaXR1ZGVDb250ZXh0JztcbmltcG9ydCB7IGFtcGxpdHVkZVRyYWNrRXZlbnRBdG9tIH0gZnJvbSAnc3JjL2F0b21zL2FtcGxpdHVkZS9hbXBsaXR1ZGVUcmFja0V2ZW50QXRvbSc7XG5pbXBvcnQgeyBxdWV1ZVVzZXJFdmVudEF0b20gfSBmcm9tICcuL21lc3NhZ2VRdWV1ZSc7XG5cbnR5cGUgSGFuZGxlUmVwbHlQYXJhbXMgPSB7XG4gIG1lc3NhZ2U6IE1lc3NhZ2U7XG4gIHVzZXJUeXBlZDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBjb25zdCBoYW5kbGVSZXBseUF0b20gPSBhdG9tKG51bGwsIChnZXQsIHNldCwgeyBtZXNzYWdlLCB1c2VyVHlwZWQgfTogSGFuZGxlUmVwbHlQYXJhbXMpID0+IHtcbiAgaWYgKG1lc3NhZ2UudHlwZSAhPT0gTWVzc2FnZVR5cGUuUXVlcnlUeXBlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHRyYWNrRXZlbnQgPSBnZXQoYW1wbGl0dWRlVHJhY2tFdmVudEF0b20pO1xuICBjb25zdCBxdWVyeVR5cGVkID0gbWVzc2FnZS5tZXRhZGF0YS5jb250ZW50O1xuXG4gIHNldChyZXBseUV2ZW50Q2F0ZWdvcnlBdG9tLCBVc2VyRXZlbnRDYXRlZ29yeS5RdWVyeVR5cGVkKTtcbiAgc2V0KHVzZXJRdWVyeUF0b20sIHF1ZXJ5VHlwZWQpO1xuICBzZXQobWVzc2FnZXNBdG9tLCBbLi4uZ2V0KG1lc3NhZ2VzQXRvbSksIFttZXNzYWdlXV0pO1xuICBzZXQodXNlckhhc1JlcGxpZWRBdG9tLCB0cnVlKTtcbiAgc2V0KHF1ZXVlVXNlckV2ZW50QXRvbSwge1xuICAgIGV2ZW50SWQ6IG1lc3NhZ2UuaWQsXG4gICAgY3JlYXRlZEF0OiBtZXNzYWdlLmNyZWF0ZWRBdCxcbiAgICBjYXRlZ29yeTogVXNlckV2ZW50Q2F0ZWdvcnkuUXVlcnlUeXBlZCxcbiAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICBxdWVyeTogcXVlcnlUeXBlZCxcbiAgICB9LFxuICB9KTtcblxuICBpZiAodHJhY2tFdmVudCkge1xuICAgIHRyYWNrRXZlbnQoe1xuICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLkNoYXRVc2VyTWVzc2FnZUlucHV0LFxuICAgICAgZXZlbnRQcm9wczoge1xuICAgICAgICBtZXNzYWdlX2lkOiBtZXNzYWdlLmlkLFxuICAgICAgICBtZXNzYWdlX3JvbGU6IG1lc3NhZ2Uucm9sZSxcbiAgICAgICAgbWVzc2FnZV90eXBlOiBtZXNzYWdlLnR5cGUsXG4gICAgICAgIG1lc3NhZ2VfbWV0YWRhdGE6IHtcbiAgICAgICAgICBjb250ZW50OiBtZXNzYWdlPy5tZXRhZGF0YT8uY29udGVudCwgLy8gUmVtb3ZlZCBhbXBsaXR1ZGVTYWZlU3RyaW5nXG4gICAgICAgICAgY3JlYXRlZF9hdDogbWVzc2FnZS5jcmVhdGVkQXQsXG4gICAgICAgICAgdXNlcl90eXBlZDogdXNlclR5cGVkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFsc29TZW5kVG9Hb29nbGVBbmFseXRpY3M6IHRydWUsXG4gICAgfSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBa0JBLE1BQWEsa0NBQXVCLE9BQU8sS0FBSyxLQUFLLEVBQUUsU0FBUyxnQkFBbUM7QUFDakcsS0FBSSxRQUFRLFNBQVNBLDRCQUFZLFdBQy9CO0NBR0YsTUFBTSxhQUFhLElBQUlDLHdEQUF3QjtDQUMvQyxNQUFNLGFBQWEsUUFBUSxTQUFTO0FBRXBDLEtBQUlDLHFEQUF3QkMsa0RBQWtCLFdBQVc7QUFDekQsS0FBSUMsNENBQWUsV0FBVztBQUM5QixLQUFJQywyQ0FBYyxDQUFDLEdBQUcsSUFBSUEsMENBQWEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3BELEtBQUlDLGlEQUFvQixLQUFLO0FBQzdCLEtBQUlDLHlDQUFvQjtFQUN0QixTQUFTLFFBQVE7RUFDakIsV0FBVyxRQUFRO0VBQ25CLFVBQVVKLGtEQUFrQjtFQUM1QixZQUFZLEVBQ1YsT0FBTyxZQUNSO0VBQ0YsQ0FBQztBQUVGLEtBQUksV0FDRixZQUFXO0VBQ1QsV0FBV0ssZ0RBQXVCO0VBQ2xDLFlBQVk7R0FDVixZQUFZLFFBQVE7R0FDcEIsY0FBYyxRQUFRO0dBQ3RCLGNBQWMsUUFBUTtHQUN0QixrQkFBa0I7SUFDaEIsU0FBUyxTQUFTLFVBQVU7SUFDNUIsWUFBWSxRQUFRO0lBQ3BCLFlBQVk7SUFDYjtHQUNGO0VBQ0QsMkJBQTJCO0VBQzVCLENBQUM7RUFFSiJ9
@@ -1,14 +0,0 @@
1
- import { Message } from "../../application/models/message.cjs";
2
- import * as jotai0 from "jotai";
3
-
4
- //#region src/atoms/chat/replies.d.ts
5
- type HandleReplyParams = {
6
- message: Message;
7
- userTyped: boolean;
8
- };
9
- declare const handleReplyAtom: jotai0.WritableAtom<null, [HandleReplyParams], void> & {
10
- init: null;
11
- };
12
- //#endregion
13
- export { handleReplyAtom };
14
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwbGllcy5kLmN0cyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXRvbXMvY2hhdC9yZXBsaWVzLmQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTWVzc2FnZSB9IGZyb20gJ3NyYy9hcHBsaWNhdGlvbi9tb2RlbHMnO1xudHlwZSBIYW5kbGVSZXBseVBhcmFtcyA9IHtcbiAgICBtZXNzYWdlOiBNZXNzYWdlO1xuICAgIHVzZXJUeXBlZDogYm9vbGVhbjtcbn07XG5leHBvcnQgZGVjbGFyZSBjb25zdCBoYW5kbGVSZXBseUF0b206IGltcG9ydChcImpvdGFpXCIpLldyaXRhYmxlQXRvbTxudWxsLCBbSGFuZGxlUmVwbHlQYXJhbXNdLCB2b2lkPiAmIHtcbiAgICBpbml0OiBudWxsO1xufTtcbmV4cG9ydCB7fTtcbiJdLCJtYXBwaW5ncyI6Ijs7OztBQUVBLElBQUksb0JBQWdCLENBQUEsU0FBQSxRQUFBO0FBQ3BCLElBQVcsa0JBQVc7Q0FBQTtPQUFBO09BQUEsT0FBQTtDQUFBIn0=
@@ -1,14 +0,0 @@
1
- import { Message } from "../../application/models/message.js";
2
- import * as jotai21 from "jotai";
3
-
4
- //#region src/atoms/chat/replies.d.ts
5
- type HandleReplyParams = {
6
- message: Message;
7
- userTyped: boolean;
8
- };
9
- declare const handleReplyAtom: jotai21.WritableAtom<null, [HandleReplyParams], void> & {
10
- init: null;
11
- };
12
- //#endregion
13
- export { handleReplyAtom };
14
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwbGllcy5kLnRzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdG9tcy9jaGF0L3JlcGxpZXMuZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNZXNzYWdlIH0gZnJvbSAnc3JjL2FwcGxpY2F0aW9uL21vZGVscyc7XG50eXBlIEhhbmRsZVJlcGx5UGFyYW1zID0ge1xuICAgIG1lc3NhZ2U6IE1lc3NhZ2U7XG4gICAgdXNlclR5cGVkOiBib29sZWFuO1xufTtcbmV4cG9ydCBkZWNsYXJlIGNvbnN0IGhhbmRsZVJlcGx5QXRvbTogaW1wb3J0KFwiam90YWlcIikuV3JpdGFibGVBdG9tPG51bGwsIFtIYW5kbGVSZXBseVBhcmFtc10sIHZvaWQ+ICYge1xuICAgIGluaXQ6IG51bGw7XG59O1xuZXhwb3J0IHt9O1xuIl0sIm1hcHBpbmdzIjoiOzs7O0FBRUEsSUFBSSxvQkFBZ0IsQ0FBQSxXQUFBLFFBQUE7QUFDcEIsSUFBVyxrQkFBVztDQUFBO09BQUE7T0FBQSxRQUFBO0NBQUEifQ==
@@ -1,45 +0,0 @@
1
- import { MessageType } from "../../application/models/message.js";
2
- import "../../application/models/index.js";
3
- import { SpiffyMetricsEventName } from "../../services/amplitudeService/amplitudeService.js";
4
- import "../../contexts/amplitudeContext/amplitudeContext.js";
5
- import { messagesAtom, replyEventCategoryAtom, userHasRepliedAtom, userQueryAtom } from "./chatState.js";
6
- import { amplitudeTrackEventAtom } from "../amplitude/amplitudeTrackEventAtom.js";
7
- import { queueUserEventAtom } from "./messageQueue.js";
8
- import "./index.js";
9
- import { UserEventCategory } from "@spiffy-ai/commerce-api-client";
10
- import { atom } from "jotai";
11
-
12
- //#region src/atoms/chat/replies.ts
13
- const handleReplyAtom = atom(null, (get, set, { message, userTyped }) => {
14
- if (message.type !== MessageType.QueryTyped) return;
15
- const trackEvent = get(amplitudeTrackEventAtom);
16
- const queryTyped = message.metadata.content;
17
- set(replyEventCategoryAtom, UserEventCategory.QueryTyped);
18
- set(userQueryAtom, queryTyped);
19
- set(messagesAtom, [...get(messagesAtom), [message]]);
20
- set(userHasRepliedAtom, true);
21
- set(queueUserEventAtom, {
22
- eventId: message.id,
23
- createdAt: message.createdAt,
24
- category: UserEventCategory.QueryTyped,
25
- attributes: { query: queryTyped }
26
- });
27
- if (trackEvent) trackEvent({
28
- eventName: SpiffyMetricsEventName.ChatUserMessageInput,
29
- eventProps: {
30
- message_id: message.id,
31
- message_role: message.role,
32
- message_type: message.type,
33
- message_metadata: {
34
- content: message?.metadata?.content,
35
- created_at: message.createdAt,
36
- user_typed: userTyped
37
- }
38
- },
39
- alsoSendToGoogleAnalytics: true
40
- });
41
- });
42
-
43
- //#endregion
44
- export { handleReplyAtom };
45
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwbGllcy5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXRvbXMvY2hhdC9yZXBsaWVzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGF0b20gfSBmcm9tICdqb3RhaSc7XG5pbXBvcnQgeyBNZXNzYWdlLCBNZXNzYWdlVHlwZSB9IGZyb20gJ3NyYy9hcHBsaWNhdGlvbi9tb2RlbHMnO1xuaW1wb3J0IHtcbiAgbWVzc2FnZXNBdG9tLFxuICByZXBseUV2ZW50Q2F0ZWdvcnlBdG9tLFxuICB1c2VySGFzUmVwbGllZEF0b20sXG4gIHVzZXJRdWVyeUF0b20sXG59IGZyb20gJ3NyYy9hdG9tcy9jaGF0JztcbmltcG9ydCB7IFVzZXJFdmVudENhdGVnb3J5IH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmltcG9ydCB7IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUgfSBmcm9tICdzcmMvY29udGV4dHMvYW1wbGl0dWRlQ29udGV4dC9hbXBsaXR1ZGVDb250ZXh0JztcbmltcG9ydCB7IGFtcGxpdHVkZVRyYWNrRXZlbnRBdG9tIH0gZnJvbSAnc3JjL2F0b21zL2FtcGxpdHVkZS9hbXBsaXR1ZGVUcmFja0V2ZW50QXRvbSc7XG5pbXBvcnQgeyBxdWV1ZVVzZXJFdmVudEF0b20gfSBmcm9tICcuL21lc3NhZ2VRdWV1ZSc7XG5cbnR5cGUgSGFuZGxlUmVwbHlQYXJhbXMgPSB7XG4gIG1lc3NhZ2U6IE1lc3NhZ2U7XG4gIHVzZXJUeXBlZDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBjb25zdCBoYW5kbGVSZXBseUF0b20gPSBhdG9tKG51bGwsIChnZXQsIHNldCwgeyBtZXNzYWdlLCB1c2VyVHlwZWQgfTogSGFuZGxlUmVwbHlQYXJhbXMpID0+IHtcbiAgaWYgKG1lc3NhZ2UudHlwZSAhPT0gTWVzc2FnZVR5cGUuUXVlcnlUeXBlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHRyYWNrRXZlbnQgPSBnZXQoYW1wbGl0dWRlVHJhY2tFdmVudEF0b20pO1xuICBjb25zdCBxdWVyeVR5cGVkID0gbWVzc2FnZS5tZXRhZGF0YS5jb250ZW50O1xuXG4gIHNldChyZXBseUV2ZW50Q2F0ZWdvcnlBdG9tLCBVc2VyRXZlbnRDYXRlZ29yeS5RdWVyeVR5cGVkKTtcbiAgc2V0KHVzZXJRdWVyeUF0b20sIHF1ZXJ5VHlwZWQpO1xuICBzZXQobWVzc2FnZXNBdG9tLCBbLi4uZ2V0KG1lc3NhZ2VzQXRvbSksIFttZXNzYWdlXV0pO1xuICBzZXQodXNlckhhc1JlcGxpZWRBdG9tLCB0cnVlKTtcbiAgc2V0KHF1ZXVlVXNlckV2ZW50QXRvbSwge1xuICAgIGV2ZW50SWQ6IG1lc3NhZ2UuaWQsXG4gICAgY3JlYXRlZEF0OiBtZXNzYWdlLmNyZWF0ZWRBdCxcbiAgICBjYXRlZ29yeTogVXNlckV2ZW50Q2F0ZWdvcnkuUXVlcnlUeXBlZCxcbiAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICBxdWVyeTogcXVlcnlUeXBlZCxcbiAgICB9LFxuICB9KTtcblxuICBpZiAodHJhY2tFdmVudCkge1xuICAgIHRyYWNrRXZlbnQoe1xuICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLkNoYXRVc2VyTWVzc2FnZUlucHV0LFxuICAgICAgZXZlbnRQcm9wczoge1xuICAgICAgICBtZXNzYWdlX2lkOiBtZXNzYWdlLmlkLFxuICAgICAgICBtZXNzYWdlX3JvbGU6IG1lc3NhZ2Uucm9sZSxcbiAgICAgICAgbWVzc2FnZV90eXBlOiBtZXNzYWdlLnR5cGUsXG4gICAgICAgIG1lc3NhZ2VfbWV0YWRhdGE6IHtcbiAgICAgICAgICBjb250ZW50OiBtZXNzYWdlPy5tZXRhZGF0YT8uY29udGVudCwgLy8gUmVtb3ZlZCBhbXBsaXR1ZGVTYWZlU3RyaW5nXG4gICAgICAgICAgY3JlYXRlZF9hdDogbWVzc2FnZS5jcmVhdGVkQXQsXG4gICAgICAgICAgdXNlcl90eXBlZDogdXNlclR5cGVkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFsc29TZW5kVG9Hb29nbGVBbmFseXRpY3M6IHRydWUsXG4gICAgfSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFrQkEsTUFBYSxrQkFBa0IsS0FBSyxPQUFPLEtBQUssS0FBSyxFQUFFLFNBQVMsZ0JBQW1DO0FBQ2pHLEtBQUksUUFBUSxTQUFTLFlBQVksV0FDL0I7Q0FHRixNQUFNLGFBQWEsSUFBSSx3QkFBd0I7Q0FDL0MsTUFBTSxhQUFhLFFBQVEsU0FBUztBQUVwQyxLQUFJLHdCQUF3QixrQkFBa0IsV0FBVztBQUN6RCxLQUFJLGVBQWUsV0FBVztBQUM5QixLQUFJLGNBQWMsQ0FBQyxHQUFHLElBQUksYUFBYSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDcEQsS0FBSSxvQkFBb0IsS0FBSztBQUM3QixLQUFJLG9CQUFvQjtFQUN0QixTQUFTLFFBQVE7RUFDakIsV0FBVyxRQUFRO0VBQ25CLFVBQVUsa0JBQWtCO0VBQzVCLFlBQVksRUFDVixPQUFPLFlBQ1I7RUFDRixDQUFDO0FBRUYsS0FBSSxXQUNGLFlBQVc7RUFDVCxXQUFXLHVCQUF1QjtFQUNsQyxZQUFZO0dBQ1YsWUFBWSxRQUFRO0dBQ3BCLGNBQWMsUUFBUTtHQUN0QixjQUFjLFFBQVE7R0FDdEIsa0JBQWtCO0lBQ2hCLFNBQVMsU0FBUyxVQUFVO0lBQzVCLFlBQVksUUFBUTtJQUNwQixZQUFZO0lBQ2I7R0FDRjtFQUNELDJCQUEyQjtFQUM1QixDQUFDO0VBRUoifQ==