@tellescope/validation 1.256.0 → 1.256.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.
package/src/validation.ts CHANGED
@@ -350,13 +350,18 @@ import {
350
350
  MetriportSyncAutomationAction,
351
351
  AIDecisionAutomationAction,
352
352
  GenerateEnduserSummaryAutomationAction,
353
+ StartAIConversationAutomationAction,
354
+ StartAIConversationActionInfo,
353
355
  AssignInboxItemAutomationAction,
354
356
  CreateScriptSureDraftAutomationAction,
355
357
  BelugaAutoRxAutomationAction,
356
358
  BelugaAutoRxPatientPreferenceItem,
357
359
  BelugaUpdateVisitAutomationAction,
358
360
  BelugaUpdateVisitPatientPreferenceItem,
361
+ BelugaTriggerRefillAutomationAction,
362
+ BelugaTriggerRefillPatientPreferenceItem,
359
363
  OnAIDecisionAutomationEvent,
364
+ OnAIConversationOutcomeAutomationEvent,
360
365
  OnErrorEventInfo,
361
366
  OnErrorAutomationEvent,
362
367
  AIContextSource,
@@ -1453,13 +1458,19 @@ export const journeysValidator: ValidatorDefinition<Indexable> = {
1453
1458
 
1454
1459
  export const escape_phone_number = (p='') => p.replace(/[^\d+]/g, '')
1455
1460
 
1461
+ // SMS short codes are valid message endpoints but not E.164: no country code and no leading '+'.
1462
+ // escape_phone_number preserves '+', so '+1894546' fails this and falls through to the strict
1463
+ // path below — which is what keeps short codes stored in the bare form inbound matching expects.
1464
+ const SHORT_CODE_REGEX = /^\d{5,6}$/
1465
+
1456
1466
  export const phoneValidator: ValidatorDefinition<string> = {
1457
1467
  validate: (options={}) => build_validator(
1458
1468
  phone => {
1459
1469
  if (typeof phone !== "string") throw new Error(`Expecting phone to be string but got ${phone}`)
1460
1470
 
1461
- let escaped = escape_phone_number(phone)
1471
+ let escaped = escape_phone_number(phone)
1462
1472
  if (escaped === '311') return escaped
1473
+ if (SHORT_CODE_REGEX.test(escaped)) return escaped
1463
1474
  if (escaped.length < 10) throw new Error(`Phone number must be at least 10 digits`)
1464
1475
 
1465
1476
  escaped = escaped.startsWith('+') ? escaped
@@ -1487,8 +1498,9 @@ export const phoneValidatorOptional: ValidatorDefinition<string> = {
1487
1498
  phone => {
1488
1499
  if (typeof phone !== "string") throw new Error(`Expecting phone to be string but got ${phone}`)
1489
1500
 
1490
- let escaped = escape_phone_number(phone)
1501
+ let escaped = escape_phone_number(phone)
1491
1502
  if (escaped === '311') return escaped
1503
+ if (SHORT_CODE_REGEX.test(escaped)) return escaped
1492
1504
  if (escaped.length < 10) throw new Error(`Phone number must be at least 10 digits`)
1493
1505
 
1494
1506
  escaped = escaped.startsWith('+') ? escaped
@@ -1505,7 +1517,7 @@ export const phoneValidatorOptional: ValidatorDefinition<string> = {
1505
1517
  }
1506
1518
 
1507
1519
  return escaped
1508
- },
1520
+ },
1509
1521
  { ...options, maxLength: 25, listOf: false, isOptional: true, emptyStringOk: true }
1510
1522
  ),
1511
1523
  getExample: () => "+15555555555",
@@ -2647,6 +2659,7 @@ const _AUTOMATION_EVENTS: { [K in AutomationEventType]: any } = {
2647
2659
  waitForTrigger: '',
2648
2660
  onCallOutcome: '',
2649
2661
  onAIDecision: '',
2662
+ onAIConversationOutcome: '',
2650
2663
  onError: '',
2651
2664
  }
2652
2665
  export const AUTOMATION_EVENTS = Object.keys(_AUTOMATION_EVENTS) as AutomationEventType[]
@@ -2681,6 +2694,7 @@ const _AUTOMATION_ACTIONS: { [K in AutomationActionType]: any } = {
2681
2694
  smartMeterPlaceOrder: '',
2682
2695
  belugaAutoRx: '',
2683
2696
  belugaUpdateVisit: '',
2697
+ belugaTriggerRefill: '',
2684
2698
  healthieSync: '',
2685
2699
  healthieAddToCourse: '',
2686
2700
  healthieSendChat: '',
@@ -2713,6 +2727,7 @@ const _AUTOMATION_ACTIONS: { [K in AutomationActionType]: any } = {
2713
2727
  metriportSync: '',
2714
2728
  aiDecision: '',
2715
2729
  generateEnduserSummary: '',
2730
+ startAIConversation: '',
2716
2731
  assignInboxItem: '',
2717
2732
  createScriptSureDraft: '',
2718
2733
  }
@@ -2921,6 +2936,13 @@ export const automationEventValidator = orValidator<{ [K in AutomationEventType]
2921
2936
  outcomes: listOfStringsValidator,
2922
2937
  }, { emptyOk: false }),
2923
2938
  }),
2939
+ onAIConversationOutcome: objectValidator<OnAIConversationOutcomeAutomationEvent>({
2940
+ type: exactMatchValidator(['onAIConversationOutcome']),
2941
+ info: objectValidator<OnAIConversationOutcomeAutomationEvent['info']>({
2942
+ automationStepId: mongoIdStringRequired,
2943
+ outcome: stringValidator,
2944
+ }, { emptyOk: false }),
2945
+ }),
2924
2946
  onError: objectValidator<OnErrorAutomationEvent>({
2925
2947
  type: exactMatchValidator(['onError']),
2926
2948
  info: objectValidator<OnErrorEventInfo>({
@@ -3101,6 +3123,26 @@ export const AIMessageInputValidator = objectValidator<{ role: 'user' | 'assista
3101
3123
  text: stringValidator100000,
3102
3124
  }, { emptyOk: false })
3103
3125
 
3126
+ // capabilities granted to an AI agent (phone tree 'AI Agent' node or 'startAIConversation' journey
3127
+ // action) — extensible like phoneTreeActionValidator (one branch per tool type). Defined ABOVE
3128
+ // automationActionValidator, which references it (const TDZ — declaration order matters at module load).
3129
+ export const phoneTreeAgentToolValidator = orValidator<{ [K in PhoneTreeAgentToolType]: PhoneTreeAgentTools[K] }>({
3130
+ "Submit Form": objectValidator<PhoneTreeAgentTools["Submit Form"]>({
3131
+ type: exactMatchValidator(['Submit Form']),
3132
+ info: objectValidator<PhoneTreeAgentTools["Submit Form"]['info']>({
3133
+ formId: mongoIdStringRequired,
3134
+ useWhen: stringValidator1000Optional,
3135
+ }),
3136
+ }),
3137
+ "Book Appointment": objectValidator<PhoneTreeAgentTools["Book Appointment"]>({
3138
+ type: exactMatchValidator(['Book Appointment']),
3139
+ info: objectValidator<PhoneTreeAgentTools["Book Appointment"]['info']>({
3140
+ appointmentBookingPageId: mongoIdStringRequired,
3141
+ useWhen: stringValidator1000Optional,
3142
+ }),
3143
+ }),
3144
+ })
3145
+
3104
3146
  export const automationActionValidator = orValidator<{ [K in AutomationActionType]: AutomationAction & { type: K } } | { [K in BrandedWebhookActions]: SendWebhookAutomationAction } >({
3105
3147
  developHealthMedEligibility: objectValidator<DevelopHealthMedicationEligibilityAutomationAction>({
3106
3148
  type: exactMatchValidator(['developHealthMedEligibility']),
@@ -3438,6 +3480,18 @@ export const automationActionValidator = orValidator<{ [K in AutomationActionTyp
3438
3480
  customFieldName: stringValidatorOptional,
3439
3481
  }),
3440
3482
  }),
3483
+ belugaTriggerRefill: objectValidator<BelugaTriggerRefillAutomationAction>({
3484
+ ...sharedAutomationActionValidators,
3485
+ type: exactMatchValidator(['belugaTriggerRefill']),
3486
+ info: objectValidator<BelugaTriggerRefillAutomationAction['info']>({
3487
+ formId: mongoIdStringRequired,
3488
+ patientPreferences: listValidatorOptionalOrEmptyOk(objectValidator<BelugaTriggerRefillPatientPreferenceItem>({
3489
+ medId: stringValidatorOptional,
3490
+ })),
3491
+ useOrganizationMapping: booleanValidatorOptional,
3492
+ customFieldName: stringValidatorOptional,
3493
+ }),
3494
+ }),
3441
3495
  sendChat: objectValidator<SendChatAutomationAction>({
3442
3496
  ...sharedAutomationActionValidators,
3443
3497
  type: exactMatchValidator(['sendChat']),
@@ -3661,6 +3715,27 @@ export const automationActionValidator = orValidator<{ [K in AutomationActionTyp
3661
3715
  aiSummaryConfiguration: aiSummaryConfigurationValidator, // optional shared config
3662
3716
  }, { emptyOk: true }) // config is optional; an empty info is valid
3663
3717
  }),
3718
+ startAIConversation: objectValidator<StartAIConversationAutomationAction>({
3719
+ ...sharedAutomationActionValidators,
3720
+ type: exactMatchValidator(['startAIConversation']),
3721
+ info: objectValidator<StartAIConversationActionInfo>({
3722
+ channel: exactMatchValidator(['SMS']),
3723
+ senderId: mongoIdStringRequired,
3724
+ fromNumber: phoneValidatorOptional,
3725
+ initialMessage: SMSMessageValidator, // required, ≤1200 chars (SMS cap)
3726
+ prompt: stringValidator5000,
3727
+ outcomes: listValidator(objectValidator({
3728
+ value: stringValidator250,
3729
+ description: stringValidator1000,
3730
+ })),
3731
+ tools: listValidatorOptionalOrEmptyOk(phoneTreeAgentToolValidator),
3732
+ model: selectableAIModelValidator,
3733
+ maxTokensPerTurn: numberValidatorOptional,
3734
+ maxTurns: numberValidatorOptional,
3735
+ maxCreditsPerCall: numberValidatorOptional,
3736
+ inactivityTimeoutHours: numberValidatorOptional,
3737
+ }, { emptyOk: false }),
3738
+ }),
3664
3739
  assignInboxItem: objectValidator<AssignInboxItemAutomationAction>({
3665
3740
  ...sharedAutomationActionValidators,
3666
3741
  type: exactMatchValidator(['assignInboxItem']),
@@ -6718,24 +6793,6 @@ export const phonePlaybackValidatorOptional = orValidator<{
6718
6793
  optional: optionalEmptyObjectValidator,
6719
6794
  }, { isOptional: true })
6720
6795
 
6721
- // capabilities granted to an 'AI Agent' node — extensible like phoneTreeActionValidator (one branch per tool type)
6722
- export const phoneTreeAgentToolValidator = orValidator<{ [K in PhoneTreeAgentToolType]: PhoneTreeAgentTools[K] }>({
6723
- "Submit Form": objectValidator<PhoneTreeAgentTools["Submit Form"]>({
6724
- type: exactMatchValidator(['Submit Form']),
6725
- info: objectValidator<PhoneTreeAgentTools["Submit Form"]['info']>({
6726
- formId: mongoIdStringRequired,
6727
- useWhen: stringValidator1000Optional,
6728
- }),
6729
- }),
6730
- "Book Appointment": objectValidator<PhoneTreeAgentTools["Book Appointment"]>({
6731
- type: exactMatchValidator(['Book Appointment']),
6732
- info: objectValidator<PhoneTreeAgentTools["Book Appointment"]['info']>({
6733
- appointmentBookingPageId: mongoIdStringRequired,
6734
- useWhen: stringValidator1000Optional,
6735
- }),
6736
- }),
6737
- })
6738
-
6739
6796
  export const phoneTreeActionValidator = orValidator<{ [K in PhoneTreeActionType]: PhoneTreeActions[K] }>({
6740
6797
  // "Play": objectValidator<PhoneTreeActions["Play"]>({
6741
6798
  // type: exactMatchValidator(['Play']),