@botonic/plugin-flow-builder 0.27.0-alpha.0 → 0.27.0-alpha.2

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 (51) hide show
  1. package/lib/cjs/action/index.js +11 -9
  2. package/lib/cjs/action/index.js.map +1 -1
  3. package/lib/cjs/action/knowledge-bases.js +31 -16
  4. package/lib/cjs/action/knowledge-bases.js.map +1 -1
  5. package/lib/cjs/functions/conditional-queue-status.js +1 -10
  6. package/lib/cjs/functions/conditional-queue-status.js.map +1 -1
  7. package/lib/cjs/index.d.ts +2 -1
  8. package/lib/cjs/index.js +6 -4
  9. package/lib/cjs/index.js.map +1 -1
  10. package/lib/cjs/tracking.d.ts +20 -13
  11. package/lib/cjs/tracking.js +37 -19
  12. package/lib/cjs/tracking.js.map +1 -1
  13. package/lib/cjs/types.d.ts +5 -1
  14. package/lib/cjs/user-input/index.js +1 -1
  15. package/lib/cjs/user-input/index.js.map +1 -1
  16. package/lib/cjs/user-input/intent.js +1 -1
  17. package/lib/cjs/user-input/keyword.js +3 -6
  18. package/lib/cjs/user-input/keyword.js.map +1 -1
  19. package/lib/cjs/user-input/smart-intent.js +2 -2
  20. package/lib/cjs/user-input/smart-intent.js.map +1 -1
  21. package/lib/esm/action/index.js +12 -10
  22. package/lib/esm/action/index.js.map +1 -1
  23. package/lib/esm/action/knowledge-bases.js +32 -17
  24. package/lib/esm/action/knowledge-bases.js.map +1 -1
  25. package/lib/esm/functions/conditional-queue-status.js +1 -10
  26. package/lib/esm/functions/conditional-queue-status.js.map +1 -1
  27. package/lib/esm/index.d.ts +2 -1
  28. package/lib/esm/index.js +5 -4
  29. package/lib/esm/index.js.map +1 -1
  30. package/lib/esm/tracking.d.ts +20 -13
  31. package/lib/esm/tracking.js +34 -17
  32. package/lib/esm/tracking.js.map +1 -1
  33. package/lib/esm/types.d.ts +5 -1
  34. package/lib/esm/user-input/index.js +1 -1
  35. package/lib/esm/user-input/index.js.map +1 -1
  36. package/lib/esm/user-input/intent.js +1 -1
  37. package/lib/esm/user-input/keyword.js +3 -6
  38. package/lib/esm/user-input/keyword.js.map +1 -1
  39. package/lib/esm/user-input/smart-intent.js +2 -2
  40. package/lib/esm/user-input/smart-intent.js.map +1 -1
  41. package/package.json +2 -2
  42. package/src/action/index.tsx +22 -10
  43. package/src/action/knowledge-bases.ts +43 -20
  44. package/src/functions/conditional-queue-status.ts +0 -8
  45. package/src/index.ts +8 -10
  46. package/src/tracking.ts +43 -18
  47. package/src/types.ts +5 -1
  48. package/src/user-input/index.ts +1 -1
  49. package/src/user-input/intent.ts +1 -1
  50. package/src/user-input/keyword.ts +3 -7
  51. package/src/user-input/smart-intent.ts +2 -2
@@ -1,8 +1,6 @@
1
1
  import { ActionRequest } from '@botonic/react'
2
2
  import axios from 'axios'
3
3
 
4
- // import { EventAction, trackEvent } from '../tracking'
5
-
6
4
  const HUBTYPE_API_URL = process.env.HUBTYPE_API_URL || 'https://api.hubtype.com'
7
5
 
8
6
  type ConditionalQueueStatusArgs = {
@@ -19,16 +17,10 @@ enum QueueStatusResult {
19
17
  }
20
18
 
21
19
  export async function conditionalQueueStatus({
22
- // request,
23
20
  queue_id,
24
- // queue_name,
25
21
  check_available_agents,
26
22
  }: ConditionalQueueStatusArgs): Promise<QueueStatusResult> {
27
23
  const data = await getQueueAvailability(queue_id, check_available_agents)
28
- // await trackEvent(request, EventAction.handoffOption, {
29
- // queueId: queue_id,
30
- // queueName: queue_name,
31
- // })
32
24
  if (check_available_agents && data.open && data.available_agents === 0) {
33
25
  return QueueStatusResult.OPEN_WITHOUT_AGENTS
34
26
  }
package/src/index.ts CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  HtNodeWithContentType,
31
31
  } from './content-fields/hubtype-fields'
32
32
  import { DEFAULT_FUNCTIONS } from './functions'
33
- import { EventAction, getNodeEventArgs, trackEvent } from './tracking'
33
+ import { trackFlowContent } from './tracking'
34
34
  import {
35
35
  BotonicPluginFlowBuilderOptions,
36
36
  FlowBuilderJSONVersion,
@@ -118,7 +118,7 @@ export default class BotonicPluginFlowBuilder implements Plugin {
118
118
  return payload.split(SOURCE_INFO_SEPARATOR)[0]
119
119
  }
120
120
 
121
- private replacePayload(payload: string): string {
121
+ public replacePayload(payload: string): string {
122
122
  const botActionId = payload.split(SEPARATOR)[1]
123
123
  const botActionNode = this.cmsApi.getNodeById<HtBotActionNode>(botActionId)
124
124
  return this.cmsApi.createPayloadWithParams(botActionNode)
@@ -151,16 +151,13 @@ export default class BotonicPluginFlowBuilder implements Plugin {
151
151
  const resolvedLocale = this.cmsApi.getResolvedLocale(locale)
152
152
  const startNode = this.cmsApi.getStartNode()
153
153
  this.currentRequest.session.flow_thread_id = uuid()
154
- const eventArgs = getNodeEventArgs(
155
- this.currentRequest as unknown as ActionRequest,
156
- startNode
157
- )
158
- await trackEvent(
154
+ const contents = await this.getContentsByNode(startNode, resolvedLocale)
155
+
156
+ await trackFlowContent(
159
157
  this.currentRequest as unknown as ActionRequest,
160
- EventAction.flowNode,
161
- eventArgs
158
+ contents
162
159
  )
163
- return await this.getContentsByNode(startNode, resolvedLocale)
160
+ return contents
164
161
  }
165
162
 
166
163
  async getContentsByNode(
@@ -283,6 +280,7 @@ export default class BotonicPluginFlowBuilder implements Plugin {
283
280
  }
284
281
 
285
282
  export * from './action'
283
+ export { BOT_ACTION_PAYLOAD_PREFIX } from './constants'
286
284
  export * from './content-fields'
287
285
  export {
288
286
  BotonicPluginFlowBuilderOptions,
package/src/tracking.ts CHANGED
@@ -1,8 +1,23 @@
1
1
  import { ActionRequest } from '@botonic/react'
2
2
 
3
+ import { FlowContent } from './content-fields'
3
4
  import { HtNodeWithContent } from './content-fields/hubtype-fields'
4
5
  import { getFlowBuilderPlugin } from './helpers'
5
6
 
7
+ export enum EventAction {
8
+ FlowNode = 'flow_node',
9
+ Keyword = 'nlu_keyword',
10
+ Intent = 'nlu_intent',
11
+ IntentSmart = 'nlu_intent_smart',
12
+ Knowledgebase = 'knowledgebase',
13
+ Fallback = 'fallback',
14
+ }
15
+
16
+ export enum KnowledgebaseFailReason {
17
+ NoKnowledge = 'no_knowledge',
18
+ Hallucination = 'hallucination',
19
+ }
20
+
6
21
  export async function trackEvent(
7
22
  request: ActionRequest,
8
23
  eventAction: EventAction,
@@ -15,29 +30,39 @@ export async function trackEvent(
15
30
  return
16
31
  }
17
32
 
18
- export function getNodeEventArgs(
33
+ export async function trackFlowContent(
34
+ request: ActionRequest,
35
+ contents: FlowContent[]
36
+ ) {
37
+ const flowBuilderPlugin = getFlowBuilderPlugin(request.plugins)
38
+ const cmsApi = flowBuilderPlugin.cmsApi
39
+ const firstNodeContent = cmsApi.getNodeById<HtNodeWithContent>(contents[0].id)
40
+ const flowName = flowBuilderPlugin.getFlowName(firstNodeContent.flow_id)
41
+ const eventArgs = getContentEventArgs(request, {
42
+ code: firstNodeContent.code,
43
+ flowId: firstNodeContent.flow_id,
44
+ flowName,
45
+ id: firstNodeContent.id,
46
+ })
47
+ await trackEvent(request, EventAction.FlowNode, eventArgs)
48
+ }
49
+
50
+ export function getContentEventArgs(
19
51
  request: ActionRequest,
20
- node: HtNodeWithContent
52
+ contentInfo: {
53
+ code: string
54
+ flowId: string
55
+ flowName: string
56
+ id: string
57
+ }
21
58
  ) {
22
59
  const flowBuilderPlugin = getFlowBuilderPlugin(request.plugins)
23
60
  return {
24
61
  flowThreadId: request.session.flow_thread_id,
25
- flowId: node.flow_id,
26
- flowName: flowBuilderPlugin.getFlowName(node.flow_id),
27
- flowNodeId: node.id,
28
- flowNodeContentId: node.code,
62
+ flowId: contentInfo.flowId,
63
+ flowName: flowBuilderPlugin.getFlowName(contentInfo.flowId),
64
+ flowNodeId: contentInfo.id,
65
+ flowNodeContentId: contentInfo.code,
29
66
  flowNodeIsMeaningful: undefined, //node?.isMeaningful,
30
67
  }
31
68
  }
32
-
33
- export enum EventAction {
34
- flowNode = 'flow_node',
35
- handoffOption = 'handoff_option',
36
- handoffSuccess = 'handoff_success',
37
- handoffFail = 'handoff_fail',
38
- keyword = 'nlu_keyword',
39
- intent = 'nlu_intent',
40
- intentSmart = 'nlu_intent_smart',
41
- knowledgebase = 'knowledgebase',
42
- fallback = 'fallback',
43
- }
package/src/types.ts CHANGED
@@ -39,11 +39,15 @@ export enum FlowBuilderJSONVersion {
39
39
  }
40
40
 
41
41
  export interface KnowledgeBaseResponse {
42
+ inferenceId: string
43
+ question: string
42
44
  answer: string
43
45
  hasKnowledge: boolean
46
+ isFaithuful: boolean
44
47
  sources: {
48
+ knowledgeBaseId: string
45
49
  knowledgeSourceId: string
46
- page?: number
50
+ knowledgeChunkId: string
47
51
  }[]
48
52
  }
49
53
 
@@ -30,7 +30,7 @@ export async function getNodeByUserInput(
30
30
  request,
31
31
  smartIntentsConfig
32
32
  )
33
- const smartIntentNode = smartIntentsApi.getNodeByInput()
33
+ const smartIntentNode = await smartIntentsApi.getNodeByInput()
34
34
  if (smartIntentNode) return smartIntentNode
35
35
 
36
36
  const intentNode = await getIntentNodeByInput(cmsApi, locale, request)
@@ -32,7 +32,7 @@ async function trackIntentEvent(
32
32
  nluIntentThreshold: intentNode?.content.confidence,
33
33
  nluIntentMessageId: request.input.message_id,
34
34
  }
35
- await trackEvent(request, EventAction.intent, eventArgs)
35
+ await trackEvent(request, EventAction.Intent, eventArgs)
36
36
  }
37
37
 
38
38
  function isIntentValid(
@@ -39,15 +39,11 @@ export class KeywordMatcher {
39
39
  userInput: string,
40
40
  keywordNodes: HtKeywordNode[]
41
41
  ): HtKeywordNode | undefined {
42
- const matchedKeywordNodes = keywordNodes.filter(node =>
42
+ const matchedKeywordNode = keywordNodes.find(node =>
43
43
  this.matchKeywords(userInput, node)
44
44
  )
45
45
 
46
- if (matchedKeywordNodes.length > 0 && matchedKeywordNodes[0].target) {
47
- return matchedKeywordNodes[0]
48
- }
49
-
50
- return undefined
46
+ return matchedKeywordNode?.target ? matchedKeywordNode : undefined
51
47
  }
52
48
 
53
49
  private matchKeywords(userInput: string, node: HtKeywordNode): boolean {
@@ -96,6 +92,6 @@ export class KeywordMatcher {
96
92
  nluKeywordIsRegex: this.isRegExp,
97
93
  nluKeywordMessageId: this.request.input.message_id,
98
94
  }
99
- await trackEvent(this.request, EventAction.keyword, eventArgs)
95
+ await trackEvent(this.request, EventAction.Keyword, eventArgs)
100
96
  }
101
97
  }
@@ -44,9 +44,9 @@ export class SmartIntentsApi {
44
44
  smartIntentNode.content.title === response.data.smart_intent_title
45
45
  )
46
46
  if (smartIntentNode) {
47
- trackEvent(this.currentRequest, EventAction.intentSmart, {
47
+ trackEvent(this.currentRequest, EventAction.IntentSmart, {
48
48
  nluIntentSmartTitle: response.data.smart_intent_title,
49
- nluIntentSmartNumUsed: response.data.smart_intents_used,
49
+ nluIntentSmartNumUsed: response.data.smart_intents_used.length,
50
50
  nluIntentSmartMessageId: this.currentRequest.input.message_id,
51
51
  })
52
52
  return smartIntentNode