revox 0.3.0 → 0.4.0

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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +38 -38
  4. data/lib/revox/models/assistant_clone_response.rb +87 -65
  5. data/lib/revox/models/assistant_create_params.rb +90 -66
  6. data/lib/revox/models/assistant_create_response.rb +87 -65
  7. data/lib/revox/models/assistant_list_response.rb +87 -65
  8. data/lib/revox/models/assistant_retrieve_response.rb +86 -65
  9. data/lib/revox/models/assistant_update_params.rb +90 -66
  10. data/lib/revox/models/assistant_update_response.rb +87 -65
  11. data/lib/revox/models/call_create_params.rb +117 -90
  12. data/lib/revox/models/call_create_response.rb +670 -90
  13. data/lib/revox/models/call_export_params.rb +1 -3
  14. data/lib/revox/models/call_phone_history_response.rb +0 -3
  15. data/lib/revox/models/call_retrieve_response.rb +671 -90
  16. data/lib/revox/models/call_search_params.rb +1 -3
  17. data/lib/revox/models/call_search_response.rb +670 -90
  18. data/lib/revox/models/campaign_create_params.rb +7 -57
  19. data/lib/revox/models/campaign_create_response.rb +108 -119
  20. data/lib/revox/models/campaign_get_rows_response.rb +672 -90
  21. data/lib/revox/models/campaign_list_response.rb +108 -119
  22. data/lib/revox/models/campaign_retrieve_response.rb +108 -119
  23. data/lib/revox/models/campaign_statistics_response.rb +51 -23
  24. data/lib/revox/models/campaign_update_params.rb +9 -78
  25. data/lib/revox/models/campaign_update_response.rb +108 -119
  26. data/lib/revox/models/phone_number_list_response.rb +87 -65
  27. data/lib/revox/models/phone_number_update_response.rb +87 -65
  28. data/lib/revox/models/voice_list_response.rb +1 -0
  29. data/lib/revox/models/voice_preview_params.rb +1 -0
  30. data/lib/revox/models/voice_retrieve_params.rb +1 -0
  31. data/lib/revox/models.rb +0 -2
  32. data/lib/revox/resources/assistants.rb +10 -10
  33. data/lib/revox/resources/call.rb +4 -4
  34. data/lib/revox/resources/campaigns.rb +13 -45
  35. data/lib/revox/version.rb +1 -1
  36. data/lib/revox.rb +0 -2
  37. data/rbi/revox/models/assistant_clone_response.rbi +157 -147
  38. data/rbi/revox/models/assistant_create_params.rbi +148 -162
  39. data/rbi/revox/models/assistant_create_response.rbi +157 -147
  40. data/rbi/revox/models/assistant_list_response.rbi +157 -147
  41. data/rbi/revox/models/assistant_retrieve_response.rbi +153 -147
  42. data/rbi/revox/models/assistant_update_params.rbi +148 -162
  43. data/rbi/revox/models/assistant_update_response.rbi +157 -147
  44. data/rbi/revox/models/call_create_params.rbi +190 -187
  45. data/rbi/revox/models/call_create_response.rbi +1138 -227
  46. data/rbi/revox/models/call_export_params.rbi +5 -15
  47. data/rbi/revox/models/call_phone_history_response.rbi +0 -15
  48. data/rbi/revox/models/call_retrieve_response.rbi +1138 -227
  49. data/rbi/revox/models/call_search_params.rbi +2 -9
  50. data/rbi/revox/models/call_search_response.rbi +1138 -227
  51. data/rbi/revox/models/campaign_create_params.rbi +9 -87
  52. data/rbi/revox/models/campaign_create_response.rbi +188 -266
  53. data/rbi/revox/models/campaign_get_rows_response.rbi +1138 -225
  54. data/rbi/revox/models/campaign_list_response.rbi +188 -262
  55. data/rbi/revox/models/campaign_retrieve_response.rbi +188 -266
  56. data/rbi/revox/models/campaign_statistics_response.rbi +94 -36
  57. data/rbi/revox/models/campaign_update_params.rbi +10 -128
  58. data/rbi/revox/models/campaign_update_response.rbi +188 -266
  59. data/rbi/revox/models/phone_number_list_response.rbi +157 -147
  60. data/rbi/revox/models/phone_number_update_response.rbi +157 -147
  61. data/rbi/revox/models/voice_list_response.rbi +5 -0
  62. data/rbi/revox/models/voice_preview_params.rbi +2 -0
  63. data/rbi/revox/models/voice_retrieve_params.rbi +2 -0
  64. data/rbi/revox/models.rbi +0 -2
  65. data/rbi/revox/resources/assistants.rbi +40 -22
  66. data/rbi/revox/resources/call.rbi +7 -4
  67. data/rbi/revox/resources/campaigns.rbi +12 -44
  68. data/sig/revox/models/assistant_clone_response.rbs +46 -54
  69. data/sig/revox/models/assistant_create_params.rbs +39 -58
  70. data/sig/revox/models/assistant_create_response.rbs +46 -54
  71. data/sig/revox/models/assistant_list_response.rbs +46 -54
  72. data/sig/revox/models/assistant_retrieve_response.rbs +46 -54
  73. data/sig/revox/models/assistant_update_params.rbs +39 -58
  74. data/sig/revox/models/assistant_update_response.rbs +46 -54
  75. data/sig/revox/models/call_create_params.rbs +50 -71
  76. data/sig/revox/models/call_create_response.rbs +468 -77
  77. data/sig/revox/models/call_export_params.rbs +2 -6
  78. data/sig/revox/models/call_phone_history_response.rbs +1 -10
  79. data/sig/revox/models/call_retrieve_response.rbs +468 -77
  80. data/sig/revox/models/call_search_params.rbs +2 -6
  81. data/sig/revox/models/call_search_response.rbs +468 -77
  82. data/sig/revox/models/campaign_create_params.rbs +5 -50
  83. data/sig/revox/models/campaign_create_response.rbs +62 -98
  84. data/sig/revox/models/campaign_get_rows_response.rbs +467 -73
  85. data/sig/revox/models/campaign_list_response.rbs +62 -98
  86. data/sig/revox/models/campaign_retrieve_response.rbs +62 -98
  87. data/sig/revox/models/campaign_statistics_response.rbs +55 -24
  88. data/sig/revox/models/campaign_update_params.rbs +1 -69
  89. data/sig/revox/models/campaign_update_response.rbs +62 -98
  90. data/sig/revox/models/phone_number_list_response.rbs +46 -54
  91. data/sig/revox/models/phone_number_update_response.rbs +46 -54
  92. data/sig/revox/models/voice_list_response.rbs +2 -1
  93. data/sig/revox/models/voice_preview_params.rbs +2 -1
  94. data/sig/revox/models/voice_retrieve_params.rbs +2 -1
  95. data/sig/revox/models.rbs +0 -2
  96. data/sig/revox/resources/assistants.rbs +4 -4
  97. data/sig/revox/resources/call.rbs +1 -1
  98. data/sig/revox/resources/campaigns.rbs +0 -12
  99. metadata +2 -8
  100. data/lib/revox/models/campaign_launch_params.rb +0 -20
  101. data/lib/revox/models/campaign_launch_response.rb +0 -2030
  102. data/rbi/revox/models/campaign_launch_params.rbi +0 -33
  103. data/rbi/revox/models/campaign_launch_response.rbi +0 -4170
  104. data/sig/revox/models/campaign_launch_params.rbs +0 -20
  105. data/sig/revox/models/campaign_launch_response.rbs +0 -1694
@@ -333,6 +333,13 @@ module Revox
333
333
  sig { returns(T.nilable(String)) }
334
334
  attr_accessor :outcome_summary
335
335
 
336
+ # Slack channels resolved from the agent prompt's own routing rules, when it
337
+ # defines any. Always a subset of the channels configured on the assistant. Null
338
+ # when the prompt defines no routing rules, in which case every configured channel
339
+ # is notified.
340
+ sig { returns(T.nilable(T::Array[String])) }
341
+ attr_accessor :slack_channel_ids
342
+
336
343
  # This represent a call "order" that was requested by the user. A call order can
337
344
  # be resolved over multiple call attempts spanning up to a few days.
338
345
  sig do
@@ -392,7 +399,8 @@ module Revox
392
399
  T.nilable(
393
400
  Revox::Models::CampaignGetRowsResponse::Row::Call::Outcome::OrSymbol
394
401
  ),
395
- outcome_summary: T.nilable(String)
402
+ outcome_summary: T.nilable(String),
403
+ slack_channel_ids: T.nilable(T::Array[String])
396
404
  ).returns(T.attached_class)
397
405
  end
398
406
  def self.new(
@@ -454,7 +462,12 @@ module Revox
454
462
  # Business outcome of the call. Null if not computed or no transcript.
455
463
  outcome: nil,
456
464
  # LLM explanation for the outcome, when outcome was computed from the transcript.
457
- outcome_summary: nil
465
+ outcome_summary: nil,
466
+ # Slack channels resolved from the agent prompt's own routing rules, when it
467
+ # defines any. Always a subset of the channels configured on the assistant. Null
468
+ # when the prompt defines no routing rules, in which case every configured channel
469
+ # is notified.
470
+ slack_channel_ids: nil
458
471
  )
459
472
  end
460
473
 
@@ -511,7 +524,8 @@ module Revox
511
524
  T.nilable(
512
525
  Revox::Models::CampaignGetRowsResponse::Row::Call::Outcome::TaggedSymbol
513
526
  ),
514
- outcome_summary: T.nilable(String)
527
+ outcome_summary: T.nilable(String),
528
+ slack_channel_ids: T.nilable(T::Array[String])
515
529
  }
516
530
  )
517
531
  end
@@ -680,14 +694,6 @@ module Revox
680
694
  sig { returns(T.nilable(String)) }
681
695
  attr_accessor :email_notification_address
682
696
 
683
- # The language used for the notification email content. One of "en" or "fr".
684
- sig do
685
- returns(
686
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationLanguage::TaggedSymbol
687
- )
688
- end
689
- attr_accessor :email_notification_language
690
-
691
697
  # Which call outcomes trigger an email notification. E.g. ["interested",
692
698
  # "completed", "none"]. Use "none" when outcome is null.
693
699
  sig do
@@ -723,8 +729,8 @@ module Revox
723
729
  sig { returns(T.nilable(String)) }
724
730
  attr_accessor :from_phone_number
725
731
 
726
- # Warm or cold transfer when transfer_phone_number is set; null when transfer is
727
- # not configured.
732
+ # Warm or cold transfer when transfer_destinations is non-empty; null when
733
+ # transfer is not configured.
728
734
  sig do
729
735
  returns(
730
736
  T.nilable(
@@ -787,6 +793,11 @@ module Revox
787
793
  end
788
794
  attr_writer :position
789
795
 
796
+ # URL fetched before an inbound call is answered to resolve the assistant's prompt
797
+ # variables. Null when no lookup is configured.
798
+ sig { returns(T.nilable(String)) }
799
+ attr_accessor :precall_lookup_url
800
+
790
801
  sig { returns(String) }
791
802
  attr_accessor :prompt
792
803
 
@@ -908,9 +919,18 @@ module Revox
908
919
  sig { returns(Float) }
909
920
  attr_accessor :thinking_sound_volume
910
921
 
911
- # Phone number to transfer calls to when users request to speak to a human agent.
912
- sig { returns(T.nilable(String)) }
913
- attr_accessor :transfer_phone_number
922
+ # Where calls can be transferred to when users ask to speak to a human. Null or
923
+ # empty when transfer is not configured.
924
+ sig do
925
+ returns(
926
+ T.nilable(
927
+ T::Array[
928
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::TransferDestination
929
+ ]
930
+ )
931
+ )
932
+ end
933
+ attr_accessor :transfer_destinations
914
934
 
915
935
  sig do
916
936
  returns(
@@ -1020,6 +1040,12 @@ module Revox
1020
1040
  end
1021
1041
  attr_writer :faq_items
1022
1042
 
1043
+ sig { returns(T.nilable(T::Boolean)) }
1044
+ attr_reader :is_inbound_receptionist
1045
+
1046
+ sig { params(is_inbound_receptionist: T::Boolean).void }
1047
+ attr_writer :is_inbound_receptionist
1048
+
1023
1049
  sig { returns(T.nilable(T::Boolean)) }
1024
1050
  attr_reader :is_realestate_assistant
1025
1051
 
@@ -1064,8 +1090,6 @@ module Revox
1064
1090
  ]
1065
1091
  ),
1066
1092
  email_notification_address: T.nilable(String),
1067
- email_notification_language:
1068
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationLanguage::OrSymbol,
1069
1093
  email_notification_outcomes:
1070
1094
  T.nilable(
1071
1095
  T::Array[
@@ -1099,6 +1123,7 @@ module Revox
1099
1123
  T.nilable(
1100
1124
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Position::OrHash
1101
1125
  ),
1126
+ precall_lookup_url: T.nilable(String),
1102
1127
  prompt: String,
1103
1128
  prompt_flow:
1104
1129
  T.nilable(
@@ -1129,7 +1154,12 @@ module Revox
1129
1154
  ),
1130
1155
  thinking_sound_probability: Float,
1131
1156
  thinking_sound_volume: Float,
1132
- transfer_phone_number: T.nilable(String),
1157
+ transfer_destinations:
1158
+ T.nilable(
1159
+ T::Array[
1160
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::TransferDestination::OrHash
1161
+ ]
1162
+ ),
1133
1163
  type:
1134
1164
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Type::OrSymbol,
1135
1165
  updated_at: T.anything,
@@ -1153,6 +1183,7 @@ module Revox
1153
1183
  T::Array[
1154
1184
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::FaqItem::OrHash
1155
1185
  ],
1186
+ is_inbound_receptionist: T::Boolean,
1156
1187
  is_realestate_assistant: T::Boolean,
1157
1188
  pending_faq_count: Float
1158
1189
  ).returns(T.attached_class)
@@ -1181,8 +1212,6 @@ module Revox
1181
1212
  # outcome. Accepts a single email or a comma-separated list (e.g. "alice@x.com,
1182
1213
  # bob@y.com").
1183
1214
  email_notification_address:,
1184
- # The language used for the notification email content. One of "en" or "fr".
1185
- email_notification_language:,
1186
1215
  # Which call outcomes trigger an email notification. E.g. ["interested",
1187
1216
  # "completed", "none"]. Use "none" when outcome is null.
1188
1217
  email_notification_outcomes:,
@@ -1194,8 +1223,8 @@ module Revox
1194
1223
  # Override the default outbound phone number for calls placed with this assistant.
1195
1224
  # When null, the organization's default phone number is used.
1196
1225
  from_phone_number:,
1197
- # Warm or cold transfer when transfer_phone_number is set; null when transfer is
1198
- # not configured.
1226
+ # Warm or cold transfer when transfer_destinations is non-empty; null when
1227
+ # transfer is not configured.
1199
1228
  human_transfer_mode:,
1200
1229
  # Enable IVR navigation tools. When enabled, the assistant can send DTMF tones and
1201
1230
  # skip turns to navigate phone menus.
@@ -1214,6 +1243,9 @@ module Revox
1214
1243
  name:,
1215
1244
  organization_id:,
1216
1245
  position:,
1246
+ # URL fetched before an inbound call is answered to resolve the assistant's prompt
1247
+ # variables. Null when no lookup is configured.
1248
+ precall_lookup_url:,
1217
1249
  prompt:,
1218
1250
  prompt_flow:,
1219
1251
  slack:,
@@ -1245,8 +1277,9 @@ module Revox
1245
1277
  thinking_sound_probability:,
1246
1278
  # Volume of the thinking sound (0 = silent, 1 = max).
1247
1279
  thinking_sound_volume:,
1248
- # Phone number to transfer calls to when users request to speak to a human agent.
1249
- transfer_phone_number:,
1280
+ # Where calls can be transferred to when users ask to speak to a human. Null or
1281
+ # empty when transfer is not configured.
1282
+ transfer_destinations:,
1250
1283
  type:,
1251
1284
  updated_at:,
1252
1285
  voice:,
@@ -1265,6 +1298,7 @@ module Revox
1265
1298
  # The user who created the assistant.
1266
1299
  created_by: nil,
1267
1300
  faq_items: nil,
1301
+ is_inbound_receptionist: nil,
1268
1302
  is_realestate_assistant: nil,
1269
1303
  pending_faq_count: nil
1270
1304
  )
@@ -1303,8 +1337,6 @@ module Revox
1303
1337
  ]
1304
1338
  ),
1305
1339
  email_notification_address: T.nilable(String),
1306
- email_notification_language:
1307
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationLanguage::TaggedSymbol,
1308
1340
  email_notification_outcomes:
1309
1341
  T.nilable(
1310
1342
  T::Array[
@@ -1333,6 +1365,7 @@ module Revox
1333
1365
  T.nilable(
1334
1366
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Position
1335
1367
  ),
1368
+ precall_lookup_url: T.nilable(String),
1336
1369
  prompt: String,
1337
1370
  prompt_flow:
1338
1371
  T.nilable(
@@ -1363,7 +1396,12 @@ module Revox
1363
1396
  ),
1364
1397
  thinking_sound_probability: Float,
1365
1398
  thinking_sound_volume: Float,
1366
- transfer_phone_number: T.nilable(String),
1399
+ transfer_destinations:
1400
+ T.nilable(
1401
+ T::Array[
1402
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::TransferDestination
1403
+ ]
1404
+ ),
1367
1405
  type:
1368
1406
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Type::TaggedSymbol,
1369
1407
  updated_at: T.anything,
@@ -1387,6 +1425,7 @@ module Revox
1387
1425
  T::Array[
1388
1426
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::FaqItem
1389
1427
  ],
1428
+ is_inbound_receptionist: T::Boolean,
1390
1429
  is_realestate_assistant: T::Boolean,
1391
1430
  pending_faq_count: Float
1392
1431
  }
@@ -1427,21 +1466,6 @@ module Revox
1427
1466
  :requested_callback_later,
1428
1467
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::AfterCallSMSOutcome::TaggedSymbol
1429
1468
  )
1430
- REQUESTED_CALLBACK_NEW_NUMBER =
1431
- T.let(
1432
- :requested_callback_new_number,
1433
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::AfterCallSMSOutcome::TaggedSymbol
1434
- )
1435
- DO_NOT_CONTACT =
1436
- T.let(
1437
- :do_not_contact,
1438
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::AfterCallSMSOutcome::TaggedSymbol
1439
- )
1440
- AI_AVERSE =
1441
- T.let(
1442
- :ai_averse,
1443
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::AfterCallSMSOutcome::TaggedSymbol
1444
- )
1445
1469
  NONE =
1446
1470
  T.let(
1447
1471
  :none,
@@ -1712,7 +1736,8 @@ module Revox
1712
1736
  sig { returns(String) }
1713
1737
  attr_accessor :calling_window_start_time
1714
1738
 
1715
- # Delay between retry attempts in seconds. Default: 7200 (2 hours).
1739
+ # Delay between retry attempts in seconds. 0 retries as soon as the calling window
1740
+ # allows. Default: 7200 (2 hours).
1716
1741
  sig { returns(Integer) }
1717
1742
  attr_accessor :retry_delay_seconds
1718
1743
 
@@ -1732,7 +1757,8 @@ module Revox
1732
1757
  # timezone_override if provided). Format: 'HH:mm' (24-hour) or 'H:mma' (12-hour).
1733
1758
  # Examples: '09:00', '10am'. Default: '10:00'.
1734
1759
  calling_window_start_time:,
1735
- # Delay between retry attempts in seconds. Default: 7200 (2 hours).
1760
+ # Delay between retry attempts in seconds. 0 retries as soon as the calling window
1761
+ # allows. Default: 7200 (2 hours).
1736
1762
  retry_delay_seconds:
1737
1763
  )
1738
1764
  end
@@ -2119,41 +2145,6 @@ module Revox
2119
2145
  end
2120
2146
  end
2121
2147
 
2122
- # The language used for the notification email content. One of "en" or "fr".
2123
- module EmailNotificationLanguage
2124
- extend Revox::Internal::Type::Enum
2125
-
2126
- TaggedSymbol =
2127
- T.type_alias do
2128
- T.all(
2129
- Symbol,
2130
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationLanguage
2131
- )
2132
- end
2133
- OrSymbol = T.type_alias { T.any(Symbol, String) }
2134
-
2135
- EN =
2136
- T.let(
2137
- :en,
2138
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationLanguage::TaggedSymbol
2139
- )
2140
- FR =
2141
- T.let(
2142
- :fr,
2143
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationLanguage::TaggedSymbol
2144
- )
2145
-
2146
- sig do
2147
- override.returns(
2148
- T::Array[
2149
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationLanguage::TaggedSymbol
2150
- ]
2151
- )
2152
- end
2153
- def self.values
2154
- end
2155
- end
2156
-
2157
2148
  module EmailNotificationOutcome
2158
2149
  extend Revox::Internal::Type::Enum
2159
2150
 
@@ -2186,21 +2177,6 @@ module Revox
2186
2177
  :requested_callback_later,
2187
2178
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationOutcome::TaggedSymbol
2188
2179
  )
2189
- REQUESTED_CALLBACK_NEW_NUMBER =
2190
- T.let(
2191
- :requested_callback_new_number,
2192
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationOutcome::TaggedSymbol
2193
- )
2194
- DO_NOT_CONTACT =
2195
- T.let(
2196
- :do_not_contact,
2197
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationOutcome::TaggedSymbol
2198
- )
2199
- AI_AVERSE =
2200
- T.let(
2201
- :ai_averse,
2202
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::EmailNotificationOutcome::TaggedSymbol
2203
- )
2204
2180
  NONE =
2205
2181
  T.let(
2206
2182
  :none,
@@ -2257,8 +2233,8 @@ module Revox
2257
2233
  end
2258
2234
  end
2259
2235
 
2260
- # Warm or cold transfer when transfer_phone_number is set; null when transfer is
2261
- # not configured.
2236
+ # Warm or cold transfer when transfer_destinations is non-empty; null when
2237
+ # transfer is not configured.
2262
2238
  module HumanTransferMode
2263
2239
  extend Revox::Internal::Type::Enum
2264
2240
 
@@ -2860,9 +2836,17 @@ module Revox
2860
2836
  )
2861
2837
  end
2862
2838
 
2863
- # The Slack channel ID where the notification will be posted.
2864
- sig { returns(String) }
2865
- attr_accessor :channel_id
2839
+ # The Slack channels eligible to receive the notification. When more than one is
2840
+ # configured, the agent prompt may define routing rules to narrow it down per
2841
+ # call; with no such rules every channel here is notified.
2842
+ sig do
2843
+ returns(
2844
+ T::Array[
2845
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Channel
2846
+ ]
2847
+ )
2848
+ end
2849
+ attr_accessor :channels
2866
2850
 
2867
2851
  # The Nango connection ID linking the org's Slack workspace to Revox.
2868
2852
  sig { returns(String) }
@@ -2879,45 +2863,43 @@ module Revox
2879
2863
  end
2880
2864
  attr_accessor :outcomes
2881
2865
 
2882
- # Human-readable Slack channel name, cached for display in the UI.
2883
- sig { returns(T.nilable(String)) }
2884
- attr_accessor :channel_name
2885
-
2886
2866
  # Optional message template. Supports {{summary}}, {{outcome}}, {{phone}},
2887
2867
  # {{call_url}}, {{assistant_name}}, {{campaign_name}}, {{first_name}},
2888
- # {{last_name}}, {{email}}, {{company}}, {{contact_name}}, {{contact_line}}, plus
2889
- # prompt_variables and structured_output keys. When null/empty a default template
2890
- # is used.
2868
+ # {{last_name}}, {{email}}, {{company}}, {{job_title}}, {{contact_name}},
2869
+ # {{contact_line}}, plus prompt_variables and structured_output keys. When
2870
+ # null/empty a default template is used.
2891
2871
  sig { returns(T.nilable(String)) }
2892
2872
  attr_accessor :template
2893
2873
 
2894
2874
  sig do
2895
2875
  params(
2896
- channel_id: String,
2876
+ channels:
2877
+ T::Array[
2878
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Channel::OrHash
2879
+ ],
2897
2880
  connection_id: String,
2898
2881
  outcomes:
2899
2882
  T::Array[
2900
2883
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Outcome::OrSymbol
2901
2884
  ],
2902
- channel_name: T.nilable(String),
2903
2885
  template: T.nilable(String)
2904
2886
  ).returns(T.attached_class)
2905
2887
  end
2906
2888
  def self.new(
2907
- # The Slack channel ID where the notification will be posted.
2908
- channel_id:,
2889
+ # The Slack channels eligible to receive the notification. When more than one is
2890
+ # configured, the agent prompt may define routing rules to narrow it down per
2891
+ # call; with no such rules every channel here is notified.
2892
+ channels:,
2909
2893
  # The Nango connection ID linking the org's Slack workspace to Revox.
2910
2894
  connection_id:,
2911
2895
  # Which call outcomes trigger a Slack notification (e.g. ['interested', 'none']).
2912
2896
  # Use 'none' to notify when outcome is null.
2913
2897
  outcomes:,
2914
- # Human-readable Slack channel name, cached for display in the UI.
2915
- channel_name: nil,
2916
2898
  # Optional message template. Supports {{summary}}, {{outcome}}, {{phone}},
2917
2899
  # {{call_url}}, {{assistant_name}}, {{campaign_name}}, {{first_name}},
2918
- # {{last_name}}, {{email}}, {{company}}, {{contact_name}}, {{contact_line}}, plus
2919
- # prompt_variables and structured_output keys. When null/empty a default template
2920
- # is used.
2900
+ # {{last_name}}, {{email}}, {{company}}, {{job_title}}, {{contact_name}},
2901
+ # {{contact_line}}, plus prompt_variables and structured_output keys. When
2902
+ # null/empty a default template is used.
2921
2903
  template: nil
2922
2904
  )
2923
2905
  end
@@ -2925,13 +2907,15 @@ module Revox
2925
2907
  sig do
2926
2908
  override.returns(
2927
2909
  {
2928
- channel_id: String,
2910
+ channels:
2911
+ T::Array[
2912
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Channel
2913
+ ],
2929
2914
  connection_id: String,
2930
2915
  outcomes:
2931
2916
  T::Array[
2932
2917
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Outcome::TaggedSymbol
2933
2918
  ],
2934
- channel_name: T.nilable(String),
2935
2919
  template: T.nilable(String)
2936
2920
  }
2937
2921
  )
@@ -2939,6 +2923,45 @@ module Revox
2939
2923
  def to_hash
2940
2924
  end
2941
2925
 
2926
+ class Channel < Revox::Internal::Type::BaseModel
2927
+ OrHash =
2928
+ T.type_alias do
2929
+ T.any(
2930
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Channel,
2931
+ Revox::Internal::AnyHash
2932
+ )
2933
+ end
2934
+
2935
+ # The Slack channel ID (e.g. 'C01234567').
2936
+ sig { returns(String) }
2937
+ attr_accessor :id
2938
+
2939
+ # Human-readable Slack channel name, cached for display in the UI and given to the
2940
+ # LLM when the agent prompt routes by channel name.
2941
+ sig { returns(T.nilable(String)) }
2942
+ attr_accessor :name
2943
+
2944
+ sig do
2945
+ params(id: String, name: T.nilable(String)).returns(
2946
+ T.attached_class
2947
+ )
2948
+ end
2949
+ def self.new(
2950
+ # The Slack channel ID (e.g. 'C01234567').
2951
+ id:,
2952
+ # Human-readable Slack channel name, cached for display in the UI and given to the
2953
+ # LLM when the agent prompt routes by channel name.
2954
+ name: nil
2955
+ )
2956
+ end
2957
+
2958
+ sig do
2959
+ override.returns({ id: String, name: T.nilable(String) })
2960
+ end
2961
+ def to_hash
2962
+ end
2963
+ end
2964
+
2942
2965
  module Outcome
2943
2966
  extend Revox::Internal::Type::Enum
2944
2967
 
@@ -2971,21 +2994,6 @@ module Revox
2971
2994
  :requested_callback_later,
2972
2995
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Outcome::TaggedSymbol
2973
2996
  )
2974
- REQUESTED_CALLBACK_NEW_NUMBER =
2975
- T.let(
2976
- :requested_callback_new_number,
2977
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Outcome::TaggedSymbol
2978
- )
2979
- DO_NOT_CONTACT =
2980
- T.let(
2981
- :do_not_contact,
2982
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Outcome::TaggedSymbol
2983
- )
2984
- AI_AVERSE =
2985
- T.let(
2986
- :ai_averse,
2987
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Slack::Outcome::TaggedSymbol
2988
- )
2989
2997
  NONE =
2990
2998
  T.let(
2991
2999
  :none,
@@ -3300,6 +3308,34 @@ module Revox
3300
3308
  end
3301
3309
  end
3302
3310
 
3311
+ class TransferDestination < Revox::Internal::Type::BaseModel
3312
+ OrHash =
3313
+ T.type_alias do
3314
+ T.any(
3315
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::TransferDestination,
3316
+ Revox::Internal::AnyHash
3317
+ )
3318
+ end
3319
+
3320
+ sig { returns(String) }
3321
+ attr_accessor :label
3322
+
3323
+ sig { returns(String) }
3324
+ attr_accessor :phone_number
3325
+
3326
+ sig do
3327
+ params(label: String, phone_number: String).returns(
3328
+ T.attached_class
3329
+ )
3330
+ end
3331
+ def self.new(label:, phone_number:)
3332
+ end
3333
+
3334
+ sig { override.returns({ label: String, phone_number: String }) }
3335
+ def to_hash
3336
+ end
3337
+ end
3338
+
3303
3339
  module Type
3304
3340
  extend Revox::Internal::Type::Enum
3305
3341
 
@@ -3380,7 +3416,7 @@ module Revox
3380
3416
  attr_writer :model
3381
3417
 
3382
3418
  # The speed of the voice. Range depends on provider: Cartesia 0.6–1.5, ElevenLabs
3383
- # 0.7–1.2. Default is 1.0.
3419
+ # 0.7–1.2, Gradium 0.6–1.5. Default is 1.0.
3384
3420
  sig { returns(T.nilable(Float)) }
3385
3421
  attr_reader :speed
3386
3422
 
@@ -3415,7 +3451,7 @@ module Revox
3415
3451
  # for other providers.
3416
3452
  model: nil,
3417
3453
  # The speed of the voice. Range depends on provider: Cartesia 0.6–1.5, ElevenLabs
3418
- # 0.7–1.2. Default is 1.0.
3454
+ # 0.7–1.2, Gradium 0.6–1.5. Default is 1.0.
3419
3455
  speed: nil,
3420
3456
  # Volume of the voice (Cartesia only). 0.5–2.0, default 1.0. Ignored for other
3421
3457
  # providers.
@@ -3462,6 +3498,11 @@ module Revox
3462
3498
  :elevenlabs,
3463
3499
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Voice::Provider::TaggedSymbol
3464
3500
  )
3501
+ GRADIUM =
3502
+ T.let(
3503
+ :gradium,
3504
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Voice::Provider::TaggedSymbol
3505
+ )
3465
3506
 
3466
3507
  sig do
3467
3508
  override.returns(
@@ -3692,21 +3733,6 @@ module Revox
3692
3733
  :requested_callback_later,
3693
3734
  Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Zoho::Outcome::TaggedSymbol
3694
3735
  )
3695
- REQUESTED_CALLBACK_NEW_NUMBER =
3696
- T.let(
3697
- :requested_callback_new_number,
3698
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Zoho::Outcome::TaggedSymbol
3699
- )
3700
- DO_NOT_CONTACT =
3701
- T.let(
3702
- :do_not_contact,
3703
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Zoho::Outcome::TaggedSymbol
3704
- )
3705
- AI_AVERSE =
3706
- T.let(
3707
- :ai_averse,
3708
- Revox::Models::CampaignGetRowsResponse::Row::Call::Assistant::Zoho::Outcome::TaggedSymbol
3709
- )
3710
3736
  NONE =
3711
3737
  T.let(
3712
3738
  :none,
@@ -3924,6 +3950,37 @@ module Revox
3924
3950
  sig { returns(T.anything) }
3925
3951
  attr_accessor :ended_at
3926
3952
 
3953
+ # Whether the AI agent conducted the conversation on this attempt. False for a
3954
+ # silent speed-dial probe (whose agent only detects a human) and for attempts that
3955
+ # were never answered.
3956
+ sig { returns(T::Boolean) }
3957
+ attr_accessor :handled_by_ai
3958
+
3959
+ # Whether a human operator conducted (part of) this attempt — a jump-in takeover
3960
+ # or a speed-dial operator connection (both stamp human_takeover_at).
3961
+ sig { returns(T::Boolean) }
3962
+ attr_accessor :handled_by_human
3963
+
3964
+ # The team member responsible for following up on this call.
3965
+ sig do
3966
+ returns(
3967
+ T.nilable(
3968
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::HandledByUser
3969
+ )
3970
+ )
3971
+ end
3972
+ attr_reader :handled_by_user
3973
+
3974
+ sig do
3975
+ params(
3976
+ handled_by_user:
3977
+ T.nilable(
3978
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::HandledByUser::OrHash
3979
+ )
3980
+ ).void
3981
+ end
3982
+ attr_writer :handled_by_user
3983
+
3927
3984
  # The phone number that was called. Formatted in E.164 format. Example:
3928
3985
  # +1234567890
3929
3986
  sig { returns(String) }
@@ -3958,6 +4015,19 @@ module Revox
3958
4015
  sig { returns(T.nilable(T::Array[String])) }
3959
4016
  attr_accessor :assistants_used
3960
4017
 
4018
+ # Notification emails sent in connection with the call, ordered oldest first
4019
+ # (from/to addresses, subject, sent time).
4020
+ sig do
4021
+ returns(
4022
+ T.nilable(
4023
+ T::Array[
4024
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::EmailLog
4025
+ ]
4026
+ )
4027
+ )
4028
+ end
4029
+ attr_accessor :email_log
4030
+
3961
4031
  # Reason for ending the call when ended_by is 'agent'. E.g. 'tool_end_call',
3962
4032
  # 'voicemail', 'transfer', 'ivr_no_navigate'.
3963
4033
  sig do
@@ -4007,6 +4077,20 @@ module Revox
4007
4077
  end
4008
4078
  attr_accessor :sms_log
4009
4079
 
4080
+ # Per-turn speech segments (VAD-derived) with timing and pipeline latencies,
4081
+ # ordered by started_speaking_at_ms. Empty for calls recorded before this was
4082
+ # tracked or for realtime sessions that don't emit them.
4083
+ sig do
4084
+ returns(
4085
+ T.nilable(
4086
+ T::Array[
4087
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent
4088
+ ]
4089
+ )
4090
+ )
4091
+ end
4092
+ attr_accessor :speech_events
4093
+
4010
4094
  # The data extracted from the call, using the structured output config from the
4011
4095
  # parent call object.
4012
4096
  sig { returns(T.nilable(T::Hash[Symbol, T.anything])) }
@@ -4035,6 +4119,12 @@ module Revox
4035
4119
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::DialError::OrSymbol
4036
4120
  ),
4037
4121
  ended_at: T.anything,
4122
+ handled_by_ai: T::Boolean,
4123
+ handled_by_human: T::Boolean,
4124
+ handled_by_user:
4125
+ T.nilable(
4126
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::HandledByUser::OrHash
4127
+ ),
4038
4128
  phone_number: String,
4039
4129
  recording_url: T.nilable(String),
4040
4130
  result:
@@ -4045,6 +4135,12 @@ module Revox
4045
4135
  status:
4046
4136
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Status::OrSymbol,
4047
4137
  assistants_used: T.nilable(T::Array[String]),
4138
+ email_log:
4139
+ T.nilable(
4140
+ T::Array[
4141
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::EmailLog::OrHash
4142
+ ]
4143
+ ),
4048
4144
  end_reason:
4049
4145
  T.nilable(
4050
4146
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::EndReason::OrSymbol
@@ -4065,6 +4161,12 @@ module Revox
4065
4161
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::OrHash
4066
4162
  ]
4067
4163
  ),
4164
+ speech_events:
4165
+ T.nilable(
4166
+ T::Array[
4167
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent::OrHash
4168
+ ]
4169
+ ),
4068
4170
  structured_output: T.nilable(T::Hash[Symbol, T.anything]),
4069
4171
  transcript:
4070
4172
  T.nilable(
@@ -4083,6 +4185,15 @@ module Revox
4083
4185
  dial_error:,
4084
4186
  # The time the call ended.
4085
4187
  ended_at:,
4188
+ # Whether the AI agent conducted the conversation on this attempt. False for a
4189
+ # silent speed-dial probe (whose agent only detects a human) and for attempts that
4190
+ # were never answered.
4191
+ handled_by_ai:,
4192
+ # Whether a human operator conducted (part of) this attempt — a jump-in takeover
4193
+ # or a speed-dial operator connection (both stamp human_takeover_at).
4194
+ handled_by_human:,
4195
+ # The team member responsible for following up on this call.
4196
+ handled_by_user:,
4086
4197
  # The phone number that was called. Formatted in E.164 format. Example:
4087
4198
  # +1234567890
4088
4199
  phone_number:,
@@ -4095,6 +4206,9 @@ module Revox
4095
4206
  status:,
4096
4207
  # Assistant node ids entered during this attempt, in traversal order.
4097
4208
  assistants_used: nil,
4209
+ # Notification emails sent in connection with the call, ordered oldest first
4210
+ # (from/to addresses, subject, sent time).
4211
+ email_log: nil,
4098
4212
  # Reason for ending the call when ended_by is 'agent'. E.g. 'tool_end_call',
4099
4213
  # 'voicemail', 'transfer', 'ivr_no_navigate'.
4100
4214
  end_reason: nil,
@@ -4108,6 +4222,10 @@ module Revox
4108
4222
  # first. The in-call `send_sms` is excluded — it already appears in the transcript
4109
4223
  # as a tool call.
4110
4224
  sms_log: nil,
4225
+ # Per-turn speech segments (VAD-derived) with timing and pipeline latencies,
4226
+ # ordered by started_speaking_at_ms. Empty for calls recorded before this was
4227
+ # tracked or for realtime sessions that don't emit them.
4228
+ speech_events: nil,
4111
4229
  # The data extracted from the call, using the structured output config from the
4112
4230
  # parent call object.
4113
4231
  structured_output: nil,
@@ -4126,6 +4244,12 @@ module Revox
4126
4244
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::DialError::TaggedSymbol
4127
4245
  ),
4128
4246
  ended_at: T.anything,
4247
+ handled_by_ai: T::Boolean,
4248
+ handled_by_human: T::Boolean,
4249
+ handled_by_user:
4250
+ T.nilable(
4251
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::HandledByUser
4252
+ ),
4129
4253
  phone_number: String,
4130
4254
  recording_url: T.nilable(String),
4131
4255
  result:
@@ -4136,6 +4260,12 @@ module Revox
4136
4260
  status:
4137
4261
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Status::TaggedSymbol,
4138
4262
  assistants_used: T.nilable(T::Array[String]),
4263
+ email_log:
4264
+ T.nilable(
4265
+ T::Array[
4266
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::EmailLog
4267
+ ]
4268
+ ),
4139
4269
  end_reason:
4140
4270
  T.nilable(
4141
4271
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::EndReason::TaggedSymbol
@@ -4156,6 +4286,12 @@ module Revox
4156
4286
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog
4157
4287
  ]
4158
4288
  ),
4289
+ speech_events:
4290
+ T.nilable(
4291
+ T::Array[
4292
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent
4293
+ ]
4294
+ ),
4159
4295
  structured_output: T.nilable(T::Hash[Symbol, T.anything]),
4160
4296
  transcript:
4161
4297
  T.nilable(
@@ -4234,50 +4370,104 @@ module Revox
4234
4370
  end
4235
4371
  end
4236
4372
 
4237
- module Result
4238
- extend Revox::Internal::Type::Enum
4239
-
4240
- TaggedSymbol =
4373
+ class HandledByUser < Revox::Internal::Type::BaseModel
4374
+ OrHash =
4241
4375
  T.type_alias do
4242
- T.all(
4243
- Symbol,
4244
- Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result
4376
+ T.any(
4377
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::HandledByUser,
4378
+ Revox::Internal::AnyHash
4245
4379
  )
4246
4380
  end
4247
- OrSymbol = T.type_alias { T.any(Symbol, String) }
4248
4381
 
4249
- IVR =
4250
- T.let(
4251
- :IVR,
4252
- Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4253
- )
4254
- VOICEMAIL =
4255
- T.let(
4256
- :voicemail,
4257
- Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4258
- )
4259
- HUMAN =
4260
- T.let(
4261
- :human,
4262
- Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4263
- )
4264
- UNKNOWN =
4265
- T.let(
4266
- :unknown,
4267
- Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4268
- )
4269
- IOS_SCREENING_FILTER =
4270
- T.let(
4271
- :"ios-screening-filter",
4272
- Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4273
- )
4382
+ # The database user id of the assignee.
4383
+ sig { returns(String) }
4384
+ attr_accessor :id
4274
4385
 
4275
- sig do
4276
- override.returns(
4277
- T::Array[
4278
- Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4279
- ]
4280
- )
4386
+ sig { returns(String) }
4387
+ attr_accessor :email
4388
+
4389
+ sig { returns(T.nilable(String)) }
4390
+ attr_accessor :first_name
4391
+
4392
+ sig { returns(T.nilable(String)) }
4393
+ attr_accessor :last_name
4394
+
4395
+ # The team member responsible for following up on this call.
4396
+ sig do
4397
+ params(
4398
+ id: String,
4399
+ email: String,
4400
+ first_name: T.nilable(String),
4401
+ last_name: T.nilable(String)
4402
+ ).returns(T.attached_class)
4403
+ end
4404
+ def self.new(
4405
+ # The database user id of the assignee.
4406
+ id:,
4407
+ email:,
4408
+ first_name:,
4409
+ last_name:
4410
+ )
4411
+ end
4412
+
4413
+ sig do
4414
+ override.returns(
4415
+ {
4416
+ id: String,
4417
+ email: String,
4418
+ first_name: T.nilable(String),
4419
+ last_name: T.nilable(String)
4420
+ }
4421
+ )
4422
+ end
4423
+ def to_hash
4424
+ end
4425
+ end
4426
+
4427
+ module Result
4428
+ extend Revox::Internal::Type::Enum
4429
+
4430
+ TaggedSymbol =
4431
+ T.type_alias do
4432
+ T.all(
4433
+ Symbol,
4434
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result
4435
+ )
4436
+ end
4437
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
4438
+
4439
+ IVR =
4440
+ T.let(
4441
+ :IVR,
4442
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4443
+ )
4444
+ VOICEMAIL =
4445
+ T.let(
4446
+ :voicemail,
4447
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4448
+ )
4449
+ HUMAN =
4450
+ T.let(
4451
+ :human,
4452
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4453
+ )
4454
+ UNKNOWN =
4455
+ T.let(
4456
+ :unknown,
4457
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4458
+ )
4459
+ IOS_SCREENING_FILTER =
4460
+ T.let(
4461
+ :"ios-screening-filter",
4462
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4463
+ )
4464
+
4465
+ sig do
4466
+ override.returns(
4467
+ T::Array[
4468
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::Result::TaggedSymbol
4469
+ ]
4470
+ )
4281
4471
  end
4282
4472
  def self.values
4283
4473
  end
@@ -4333,6 +4523,71 @@ module Revox
4333
4523
  end
4334
4524
  end
4335
4525
 
4526
+ class EmailLog < Revox::Internal::Type::BaseModel
4527
+ OrHash =
4528
+ T.type_alias do
4529
+ T.any(
4530
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::EmailLog,
4531
+ Revox::Internal::AnyHash
4532
+ )
4533
+ end
4534
+
4535
+ sig { returns(String) }
4536
+ attr_accessor :id
4537
+
4538
+ # When the email was sent.
4539
+ sig { returns(T.anything) }
4540
+ attr_accessor :created_at
4541
+
4542
+ sig { returns(String) }
4543
+ attr_accessor :from_address
4544
+
4545
+ sig { returns(T.nilable(String)) }
4546
+ attr_accessor :resend_message_id
4547
+
4548
+ sig { returns(String) }
4549
+ attr_accessor :subject
4550
+
4551
+ sig { returns(T::Array[String]) }
4552
+ attr_accessor :to_emails
4553
+
4554
+ sig do
4555
+ params(
4556
+ id: String,
4557
+ created_at: T.anything,
4558
+ from_address: String,
4559
+ resend_message_id: T.nilable(String),
4560
+ subject: String,
4561
+ to_emails: T::Array[String]
4562
+ ).returns(T.attached_class)
4563
+ end
4564
+ def self.new(
4565
+ id:,
4566
+ # When the email was sent.
4567
+ created_at:,
4568
+ from_address:,
4569
+ resend_message_id:,
4570
+ subject:,
4571
+ to_emails:
4572
+ )
4573
+ end
4574
+
4575
+ sig do
4576
+ override.returns(
4577
+ {
4578
+ id: String,
4579
+ created_at: T.anything,
4580
+ from_address: String,
4581
+ resend_message_id: T.nilable(String),
4582
+ subject: String,
4583
+ to_emails: T::Array[String]
4584
+ }
4585
+ )
4586
+ end
4587
+ def to_hash
4588
+ end
4589
+ end
4590
+
4336
4591
  # Reason for ending the call when ended_by is 'agent'. E.g. 'tool_end_call',
4337
4592
  # 'voicemail', 'transfer', 'ivr_no_navigate'.
4338
4593
  module EndReason
@@ -4662,11 +4917,18 @@ module Revox
4662
4917
  sig { returns(String) }
4663
4918
  attr_accessor :message_body
4664
4919
 
4665
- sig { returns(String) }
4666
- attr_accessor :to_phone_number
4920
+ sig do
4921
+ returns(
4922
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Provider::TaggedSymbol
4923
+ )
4924
+ end
4925
+ attr_accessor :provider
4667
4926
 
4668
4927
  sig { returns(T.nilable(String)) }
4669
- attr_accessor :twilio_message_sid
4928
+ attr_accessor :provider_message_id
4929
+
4930
+ sig { returns(String) }
4931
+ attr_accessor :to_phone_number
4670
4932
 
4671
4933
  sig do
4672
4934
  returns(
@@ -4680,8 +4942,10 @@ module Revox
4680
4942
  id: String,
4681
4943
  created_at: T.anything,
4682
4944
  message_body: String,
4945
+ provider:
4946
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Provider::OrSymbol,
4947
+ provider_message_id: T.nilable(String),
4683
4948
  to_phone_number: String,
4684
- twilio_message_sid: T.nilable(String),
4685
4949
  type:
4686
4950
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Type::OrSymbol
4687
4951
  ).returns(T.attached_class)
@@ -4691,8 +4955,9 @@ module Revox
4691
4955
  # When the SMS was sent.
4692
4956
  created_at:,
4693
4957
  message_body:,
4958
+ provider:,
4959
+ provider_message_id:,
4694
4960
  to_phone_number:,
4695
- twilio_message_sid:,
4696
4961
  type:
4697
4962
  )
4698
4963
  end
@@ -4703,8 +4968,10 @@ module Revox
4703
4968
  id: String,
4704
4969
  created_at: T.anything,
4705
4970
  message_body: String,
4971
+ provider:
4972
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Provider::TaggedSymbol,
4973
+ provider_message_id: T.nilable(String),
4706
4974
  to_phone_number: String,
4707
- twilio_message_sid: T.nilable(String),
4708
4975
  type:
4709
4976
  Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Type::TaggedSymbol
4710
4977
  }
@@ -4713,6 +4980,40 @@ module Revox
4713
4980
  def to_hash
4714
4981
  end
4715
4982
 
4983
+ module Provider
4984
+ extend Revox::Internal::Type::Enum
4985
+
4986
+ TaggedSymbol =
4987
+ T.type_alias do
4988
+ T.all(
4989
+ Symbol,
4990
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Provider
4991
+ )
4992
+ end
4993
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
4994
+
4995
+ TWILIO =
4996
+ T.let(
4997
+ :twilio,
4998
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Provider::TaggedSymbol
4999
+ )
5000
+ VONAGE =
5001
+ T.let(
5002
+ :vonage,
5003
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Provider::TaggedSymbol
5004
+ )
5005
+
5006
+ sig do
5007
+ override.returns(
5008
+ T::Array[
5009
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SMSLog::Provider::TaggedSymbol
5010
+ ]
5011
+ )
5012
+ end
5013
+ def self.values
5014
+ end
5015
+ end
5016
+
4716
5017
  module Type
4717
5018
  extend Revox::Internal::Type::Enum
4718
5019
 
@@ -4753,6 +5054,176 @@ module Revox
4753
5054
  end
4754
5055
  end
4755
5056
 
5057
+ class SpeechEvent < Revox::Internal::Type::BaseModel
5058
+ OrHash =
5059
+ T.type_alias do
5060
+ T.any(
5061
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent,
5062
+ Revox::Internal::AnyHash
5063
+ )
5064
+ end
5065
+
5066
+ sig { returns(String) }
5067
+ attr_accessor :id
5068
+
5069
+ # False when the segment was flagged as noise/blip rather than a meaningful turn.
5070
+ sig { returns(T::Boolean) }
5071
+ attr_accessor :is_real_turn
5072
+
5073
+ # Agent-only: despite the name, the whole prompt the LLM was given for this turn —
5074
+ # system instructions plus conversation history — as JSON.
5075
+ sig { returns(T.nilable(String)) }
5076
+ attr_accessor :llm_system_prompt
5077
+
5078
+ # Agent-only: LLM time-to-first-token for the reply, in ms.
5079
+ sig { returns(T.nilable(Float)) }
5080
+ attr_accessor :llm_ttft_ms
5081
+
5082
+ # Agent-only: the model that produced the reply — the winning leg when the LLM is
5083
+ # a race, which is also the model `llm_ttft_ms` describes.
5084
+ sig { returns(T.nilable(String)) }
5085
+ attr_accessor :llm_winner_model
5086
+
5087
+ # Who was speaking during this segment.
5088
+ sig do
5089
+ returns(
5090
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent::Speaker::TaggedSymbol
5091
+ )
5092
+ end
5093
+ attr_accessor :speaker
5094
+
5095
+ # Milliseconds since session start when speech began.
5096
+ sig { returns(Float) }
5097
+ attr_accessor :started_speaking_at_ms
5098
+
5099
+ # Milliseconds since session start when speech ended. Null when the session ended
5100
+ # before the turn closed.
5101
+ sig { returns(T.nilable(Float)) }
5102
+ attr_accessor :stopped_speaking_at_ms
5103
+
5104
+ # User-only: time from end-of-speech to final transcript, in ms.
5105
+ sig { returns(T.nilable(Float)) }
5106
+ attr_accessor :stt_transcription_delay_ms
5107
+
5108
+ # Recognized text for this segment, when available.
5109
+ sig { returns(T.nilable(String)) }
5110
+ attr_accessor :transcript
5111
+
5112
+ # Agent-only: TTS time-to-first-audio-byte for the reply, in ms.
5113
+ sig { returns(T.nilable(Float)) }
5114
+ attr_accessor :tts_ttfb_ms
5115
+
5116
+ # Agent-only: true when the agent's audio was interrupted (real or auto-resumed).
5117
+ # Null on user segments.
5118
+ sig { returns(T.nilable(T::Boolean)) }
5119
+ attr_accessor :was_cut
5120
+
5121
+ sig do
5122
+ params(
5123
+ id: String,
5124
+ is_real_turn: T::Boolean,
5125
+ llm_system_prompt: T.nilable(String),
5126
+ llm_ttft_ms: T.nilable(Float),
5127
+ llm_winner_model: T.nilable(String),
5128
+ speaker:
5129
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent::Speaker::OrSymbol,
5130
+ started_speaking_at_ms: Float,
5131
+ stopped_speaking_at_ms: T.nilable(Float),
5132
+ stt_transcription_delay_ms: T.nilable(Float),
5133
+ transcript: T.nilable(String),
5134
+ tts_ttfb_ms: T.nilable(Float),
5135
+ was_cut: T.nilable(T::Boolean)
5136
+ ).returns(T.attached_class)
5137
+ end
5138
+ def self.new(
5139
+ id:,
5140
+ # False when the segment was flagged as noise/blip rather than a meaningful turn.
5141
+ is_real_turn:,
5142
+ # Agent-only: despite the name, the whole prompt the LLM was given for this turn —
5143
+ # system instructions plus conversation history — as JSON.
5144
+ llm_system_prompt:,
5145
+ # Agent-only: LLM time-to-first-token for the reply, in ms.
5146
+ llm_ttft_ms:,
5147
+ # Agent-only: the model that produced the reply — the winning leg when the LLM is
5148
+ # a race, which is also the model `llm_ttft_ms` describes.
5149
+ llm_winner_model:,
5150
+ # Who was speaking during this segment.
5151
+ speaker:,
5152
+ # Milliseconds since session start when speech began.
5153
+ started_speaking_at_ms:,
5154
+ # Milliseconds since session start when speech ended. Null when the session ended
5155
+ # before the turn closed.
5156
+ stopped_speaking_at_ms:,
5157
+ # User-only: time from end-of-speech to final transcript, in ms.
5158
+ stt_transcription_delay_ms:,
5159
+ # Recognized text for this segment, when available.
5160
+ transcript:,
5161
+ # Agent-only: TTS time-to-first-audio-byte for the reply, in ms.
5162
+ tts_ttfb_ms:,
5163
+ # Agent-only: true when the agent's audio was interrupted (real or auto-resumed).
5164
+ # Null on user segments.
5165
+ was_cut:
5166
+ )
5167
+ end
5168
+
5169
+ sig do
5170
+ override.returns(
5171
+ {
5172
+ id: String,
5173
+ is_real_turn: T::Boolean,
5174
+ llm_system_prompt: T.nilable(String),
5175
+ llm_ttft_ms: T.nilable(Float),
5176
+ llm_winner_model: T.nilable(String),
5177
+ speaker:
5178
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent::Speaker::TaggedSymbol,
5179
+ started_speaking_at_ms: Float,
5180
+ stopped_speaking_at_ms: T.nilable(Float),
5181
+ stt_transcription_delay_ms: T.nilable(Float),
5182
+ transcript: T.nilable(String),
5183
+ tts_ttfb_ms: T.nilable(Float),
5184
+ was_cut: T.nilable(T::Boolean)
5185
+ }
5186
+ )
5187
+ end
5188
+ def to_hash
5189
+ end
5190
+
5191
+ # Who was speaking during this segment.
5192
+ module Speaker
5193
+ extend Revox::Internal::Type::Enum
5194
+
5195
+ TaggedSymbol =
5196
+ T.type_alias do
5197
+ T.all(
5198
+ Symbol,
5199
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent::Speaker
5200
+ )
5201
+ end
5202
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
5203
+
5204
+ USER =
5205
+ T.let(
5206
+ :user,
5207
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent::Speaker::TaggedSymbol
5208
+ )
5209
+ AGENT =
5210
+ T.let(
5211
+ :agent,
5212
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent::Speaker::TaggedSymbol
5213
+ )
5214
+
5215
+ sig do
5216
+ override.returns(
5217
+ T::Array[
5218
+ Revox::Models::CampaignGetRowsResponse::Row::Call::CallAttempt::SpeechEvent::Speaker::TaggedSymbol
5219
+ ]
5220
+ )
5221
+ end
5222
+ def self.values
5223
+ end
5224
+ end
5225
+ end
5226
+
4756
5227
  class Transcript < Revox::Internal::Type::BaseModel
4757
5228
  OrHash =
4758
5229
  T.type_alias do
@@ -5099,7 +5570,8 @@ module Revox
5099
5570
  sig { returns(String) }
5100
5571
  attr_accessor :calling_window_start_time
5101
5572
 
5102
- # Delay between retry attempts in seconds. Default: 7200 (2 hours).
5573
+ # Delay between retry attempts in seconds. 0 retries as soon as the calling window
5574
+ # allows. Default: 7200 (2 hours).
5103
5575
  sig { returns(Integer) }
5104
5576
  attr_accessor :retry_delay_seconds
5105
5577
 
@@ -5119,7 +5591,8 @@ module Revox
5119
5591
  # timezone_override if provided). Format: 'HH:mm' (24-hour) or 'H:mma' (12-hour).
5120
5592
  # Examples: '09:00', '10am'. Default: '10:00'.
5121
5593
  calling_window_start_time:,
5122
- # Delay between retry attempts in seconds. Default: 7200 (2 hours).
5594
+ # Delay between retry attempts in seconds. 0 retries as soon as the calling window
5595
+ # allows. Default: 7200 (2 hours).
5123
5596
  retry_delay_seconds:
5124
5597
  )
5125
5598
  end
@@ -5180,6 +5653,9 @@ module Revox
5180
5653
  sig { returns(T.nilable(String)) }
5181
5654
  attr_accessor :first_name
5182
5655
 
5656
+ sig { returns(T.nilable(String)) }
5657
+ attr_accessor :job_title
5658
+
5183
5659
  sig { returns(T.nilable(String)) }
5184
5660
  attr_accessor :last_name
5185
5661
 
@@ -5190,10 +5666,11 @@ module Revox
5190
5666
  company: T.nilable(String),
5191
5667
  email: T.nilable(String),
5192
5668
  first_name: T.nilable(String),
5669
+ job_title: T.nilable(String),
5193
5670
  last_name: T.nilable(String)
5194
5671
  ).returns(T.attached_class)
5195
5672
  end
5196
- def self.new(company:, email:, first_name:, last_name:)
5673
+ def self.new(company:, email:, first_name:, job_title:, last_name:)
5197
5674
  end
5198
5675
 
5199
5676
  sig do
@@ -5202,6 +5679,7 @@ module Revox
5202
5679
  company: T.nilable(String),
5203
5680
  email: T.nilable(String),
5204
5681
  first_name: T.nilable(String),
5682
+ job_title: T.nilable(String),
5205
5683
  last_name: T.nilable(String)
5206
5684
  }
5207
5685
  )
@@ -5276,6 +5754,37 @@ module Revox
5276
5754
  sig { returns(T.anything) }
5277
5755
  attr_accessor :ended_at
5278
5756
 
5757
+ # Whether the AI agent conducted the conversation on this attempt. False for a
5758
+ # silent speed-dial probe (whose agent only detects a human) and for attempts that
5759
+ # were never answered.
5760
+ sig { returns(T::Boolean) }
5761
+ attr_accessor :handled_by_ai
5762
+
5763
+ # Whether a human operator conducted (part of) this attempt — a jump-in takeover
5764
+ # or a speed-dial operator connection (both stamp human_takeover_at).
5765
+ sig { returns(T::Boolean) }
5766
+ attr_accessor :handled_by_human
5767
+
5768
+ # The team member responsible for following up on this call.
5769
+ sig do
5770
+ returns(
5771
+ T.nilable(
5772
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::HandledByUser
5773
+ )
5774
+ )
5775
+ end
5776
+ attr_reader :handled_by_user
5777
+
5778
+ sig do
5779
+ params(
5780
+ handled_by_user:
5781
+ T.nilable(
5782
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::HandledByUser::OrHash
5783
+ )
5784
+ ).void
5785
+ end
5786
+ attr_writer :handled_by_user
5787
+
5279
5788
  # The phone number that was called. Formatted in E.164 format. Example:
5280
5789
  # +1234567890
5281
5790
  sig { returns(String) }
@@ -5310,6 +5819,19 @@ module Revox
5310
5819
  sig { returns(T.nilable(T::Array[String])) }
5311
5820
  attr_accessor :assistants_used
5312
5821
 
5822
+ # Notification emails sent in connection with the call, ordered oldest first
5823
+ # (from/to addresses, subject, sent time).
5824
+ sig do
5825
+ returns(
5826
+ T.nilable(
5827
+ T::Array[
5828
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::EmailLog
5829
+ ]
5830
+ )
5831
+ )
5832
+ end
5833
+ attr_accessor :email_log
5834
+
5313
5835
  # Reason for ending the call when ended_by is 'agent'. E.g. 'tool_end_call',
5314
5836
  # 'voicemail', 'transfer', 'ivr_no_navigate'.
5315
5837
  sig do
@@ -5343,21 +5865,35 @@ module Revox
5343
5865
  )
5344
5866
  )
5345
5867
  end
5346
- attr_accessor :post_call_transcript
5868
+ attr_accessor :post_call_transcript
5869
+
5870
+ # Automatic SMS sent after the call (voicemail and after-call), ordered oldest
5871
+ # first. The in-call `send_sms` is excluded — it already appears in the transcript
5872
+ # as a tool call.
5873
+ sig do
5874
+ returns(
5875
+ T.nilable(
5876
+ T::Array[
5877
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog
5878
+ ]
5879
+ )
5880
+ )
5881
+ end
5882
+ attr_accessor :sms_log
5347
5883
 
5348
- # Automatic SMS sent after the call (voicemail and after-call), ordered oldest
5349
- # first. The in-call `send_sms` is excluded it already appears in the transcript
5350
- # as a tool call.
5884
+ # Per-turn speech segments (VAD-derived) with timing and pipeline latencies,
5885
+ # ordered by started_speaking_at_ms. Empty for calls recorded before this was
5886
+ # tracked or for realtime sessions that don't emit them.
5351
5887
  sig do
5352
5888
  returns(
5353
5889
  T.nilable(
5354
5890
  T::Array[
5355
- Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog
5891
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent
5356
5892
  ]
5357
5893
  )
5358
5894
  )
5359
5895
  end
5360
- attr_accessor :sms_log
5896
+ attr_accessor :speech_events
5361
5897
 
5362
5898
  # The data extracted from the call, using the structured output config from the
5363
5899
  # parent call object.
@@ -5387,6 +5923,12 @@ module Revox
5387
5923
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::DialError::OrSymbol
5388
5924
  ),
5389
5925
  ended_at: T.anything,
5926
+ handled_by_ai: T::Boolean,
5927
+ handled_by_human: T::Boolean,
5928
+ handled_by_user:
5929
+ T.nilable(
5930
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::HandledByUser::OrHash
5931
+ ),
5390
5932
  phone_number: String,
5391
5933
  recording_url: T.nilable(String),
5392
5934
  result:
@@ -5397,6 +5939,12 @@ module Revox
5397
5939
  status:
5398
5940
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::Status::OrSymbol,
5399
5941
  assistants_used: T.nilable(T::Array[String]),
5942
+ email_log:
5943
+ T.nilable(
5944
+ T::Array[
5945
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::EmailLog::OrHash
5946
+ ]
5947
+ ),
5400
5948
  end_reason:
5401
5949
  T.nilable(
5402
5950
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::EndReason::OrSymbol
@@ -5417,6 +5965,12 @@ module Revox
5417
5965
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::OrHash
5418
5966
  ]
5419
5967
  ),
5968
+ speech_events:
5969
+ T.nilable(
5970
+ T::Array[
5971
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent::OrHash
5972
+ ]
5973
+ ),
5420
5974
  structured_output: T.nilable(T::Hash[Symbol, T.anything]),
5421
5975
  transcript:
5422
5976
  T.nilable(
@@ -5435,6 +5989,15 @@ module Revox
5435
5989
  dial_error:,
5436
5990
  # The time the call ended.
5437
5991
  ended_at:,
5992
+ # Whether the AI agent conducted the conversation on this attempt. False for a
5993
+ # silent speed-dial probe (whose agent only detects a human) and for attempts that
5994
+ # were never answered.
5995
+ handled_by_ai:,
5996
+ # Whether a human operator conducted (part of) this attempt — a jump-in takeover
5997
+ # or a speed-dial operator connection (both stamp human_takeover_at).
5998
+ handled_by_human:,
5999
+ # The team member responsible for following up on this call.
6000
+ handled_by_user:,
5438
6001
  # The phone number that was called. Formatted in E.164 format. Example:
5439
6002
  # +1234567890
5440
6003
  phone_number:,
@@ -5447,6 +6010,9 @@ module Revox
5447
6010
  status:,
5448
6011
  # Assistant node ids entered during this attempt, in traversal order.
5449
6012
  assistants_used: nil,
6013
+ # Notification emails sent in connection with the call, ordered oldest first
6014
+ # (from/to addresses, subject, sent time).
6015
+ email_log: nil,
5450
6016
  # Reason for ending the call when ended_by is 'agent'. E.g. 'tool_end_call',
5451
6017
  # 'voicemail', 'transfer', 'ivr_no_navigate'.
5452
6018
  end_reason: nil,
@@ -5460,6 +6026,10 @@ module Revox
5460
6026
  # first. The in-call `send_sms` is excluded — it already appears in the transcript
5461
6027
  # as a tool call.
5462
6028
  sms_log: nil,
6029
+ # Per-turn speech segments (VAD-derived) with timing and pipeline latencies,
6030
+ # ordered by started_speaking_at_ms. Empty for calls recorded before this was
6031
+ # tracked or for realtime sessions that don't emit them.
6032
+ speech_events: nil,
5463
6033
  # The data extracted from the call, using the structured output config from the
5464
6034
  # parent call object.
5465
6035
  structured_output: nil,
@@ -5478,6 +6048,12 @@ module Revox
5478
6048
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::DialError::TaggedSymbol
5479
6049
  ),
5480
6050
  ended_at: T.anything,
6051
+ handled_by_ai: T::Boolean,
6052
+ handled_by_human: T::Boolean,
6053
+ handled_by_user:
6054
+ T.nilable(
6055
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::HandledByUser
6056
+ ),
5481
6057
  phone_number: String,
5482
6058
  recording_url: T.nilable(String),
5483
6059
  result:
@@ -5488,6 +6064,12 @@ module Revox
5488
6064
  status:
5489
6065
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::Status::TaggedSymbol,
5490
6066
  assistants_used: T.nilable(T::Array[String]),
6067
+ email_log:
6068
+ T.nilable(
6069
+ T::Array[
6070
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::EmailLog
6071
+ ]
6072
+ ),
5491
6073
  end_reason:
5492
6074
  T.nilable(
5493
6075
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::EndReason::TaggedSymbol
@@ -5508,6 +6090,12 @@ module Revox
5508
6090
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog
5509
6091
  ]
5510
6092
  ),
6093
+ speech_events:
6094
+ T.nilable(
6095
+ T::Array[
6096
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent
6097
+ ]
6098
+ ),
5511
6099
  structured_output: T.nilable(T::Hash[Symbol, T.anything]),
5512
6100
  transcript:
5513
6101
  T.nilable(
@@ -5586,6 +6174,60 @@ module Revox
5586
6174
  end
5587
6175
  end
5588
6176
 
6177
+ class HandledByUser < Revox::Internal::Type::BaseModel
6178
+ OrHash =
6179
+ T.type_alias do
6180
+ T.any(
6181
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::HandledByUser,
6182
+ Revox::Internal::AnyHash
6183
+ )
6184
+ end
6185
+
6186
+ # The database user id of the assignee.
6187
+ sig { returns(String) }
6188
+ attr_accessor :id
6189
+
6190
+ sig { returns(String) }
6191
+ attr_accessor :email
6192
+
6193
+ sig { returns(T.nilable(String)) }
6194
+ attr_accessor :first_name
6195
+
6196
+ sig { returns(T.nilable(String)) }
6197
+ attr_accessor :last_name
6198
+
6199
+ # The team member responsible for following up on this call.
6200
+ sig do
6201
+ params(
6202
+ id: String,
6203
+ email: String,
6204
+ first_name: T.nilable(String),
6205
+ last_name: T.nilable(String)
6206
+ ).returns(T.attached_class)
6207
+ end
6208
+ def self.new(
6209
+ # The database user id of the assignee.
6210
+ id:,
6211
+ email:,
6212
+ first_name:,
6213
+ last_name:
6214
+ )
6215
+ end
6216
+
6217
+ sig do
6218
+ override.returns(
6219
+ {
6220
+ id: String,
6221
+ email: String,
6222
+ first_name: T.nilable(String),
6223
+ last_name: T.nilable(String)
6224
+ }
6225
+ )
6226
+ end
6227
+ def to_hash
6228
+ end
6229
+ end
6230
+
5589
6231
  module Result
5590
6232
  extend Revox::Internal::Type::Enum
5591
6233
 
@@ -5685,6 +6327,71 @@ module Revox
5685
6327
  end
5686
6328
  end
5687
6329
 
6330
+ class EmailLog < Revox::Internal::Type::BaseModel
6331
+ OrHash =
6332
+ T.type_alias do
6333
+ T.any(
6334
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::EmailLog,
6335
+ Revox::Internal::AnyHash
6336
+ )
6337
+ end
6338
+
6339
+ sig { returns(String) }
6340
+ attr_accessor :id
6341
+
6342
+ # When the email was sent.
6343
+ sig { returns(T.anything) }
6344
+ attr_accessor :created_at
6345
+
6346
+ sig { returns(String) }
6347
+ attr_accessor :from_address
6348
+
6349
+ sig { returns(T.nilable(String)) }
6350
+ attr_accessor :resend_message_id
6351
+
6352
+ sig { returns(String) }
6353
+ attr_accessor :subject
6354
+
6355
+ sig { returns(T::Array[String]) }
6356
+ attr_accessor :to_emails
6357
+
6358
+ sig do
6359
+ params(
6360
+ id: String,
6361
+ created_at: T.anything,
6362
+ from_address: String,
6363
+ resend_message_id: T.nilable(String),
6364
+ subject: String,
6365
+ to_emails: T::Array[String]
6366
+ ).returns(T.attached_class)
6367
+ end
6368
+ def self.new(
6369
+ id:,
6370
+ # When the email was sent.
6371
+ created_at:,
6372
+ from_address:,
6373
+ resend_message_id:,
6374
+ subject:,
6375
+ to_emails:
6376
+ )
6377
+ end
6378
+
6379
+ sig do
6380
+ override.returns(
6381
+ {
6382
+ id: String,
6383
+ created_at: T.anything,
6384
+ from_address: String,
6385
+ resend_message_id: T.nilable(String),
6386
+ subject: String,
6387
+ to_emails: T::Array[String]
6388
+ }
6389
+ )
6390
+ end
6391
+ def to_hash
6392
+ end
6393
+ end
6394
+
5688
6395
  # Reason for ending the call when ended_by is 'agent'. E.g. 'tool_end_call',
5689
6396
  # 'voicemail', 'transfer', 'ivr_no_navigate'.
5690
6397
  module EndReason
@@ -6014,11 +6721,18 @@ module Revox
6014
6721
  sig { returns(String) }
6015
6722
  attr_accessor :message_body
6016
6723
 
6017
- sig { returns(String) }
6018
- attr_accessor :to_phone_number
6724
+ sig do
6725
+ returns(
6726
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Provider::TaggedSymbol
6727
+ )
6728
+ end
6729
+ attr_accessor :provider
6019
6730
 
6020
6731
  sig { returns(T.nilable(String)) }
6021
- attr_accessor :twilio_message_sid
6732
+ attr_accessor :provider_message_id
6733
+
6734
+ sig { returns(String) }
6735
+ attr_accessor :to_phone_number
6022
6736
 
6023
6737
  sig do
6024
6738
  returns(
@@ -6032,8 +6746,10 @@ module Revox
6032
6746
  id: String,
6033
6747
  created_at: T.anything,
6034
6748
  message_body: String,
6749
+ provider:
6750
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Provider::OrSymbol,
6751
+ provider_message_id: T.nilable(String),
6035
6752
  to_phone_number: String,
6036
- twilio_message_sid: T.nilable(String),
6037
6753
  type:
6038
6754
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Type::OrSymbol
6039
6755
  ).returns(T.attached_class)
@@ -6043,8 +6759,9 @@ module Revox
6043
6759
  # When the SMS was sent.
6044
6760
  created_at:,
6045
6761
  message_body:,
6762
+ provider:,
6763
+ provider_message_id:,
6046
6764
  to_phone_number:,
6047
- twilio_message_sid:,
6048
6765
  type:
6049
6766
  )
6050
6767
  end
@@ -6055,8 +6772,10 @@ module Revox
6055
6772
  id: String,
6056
6773
  created_at: T.anything,
6057
6774
  message_body: String,
6775
+ provider:
6776
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Provider::TaggedSymbol,
6777
+ provider_message_id: T.nilable(String),
6058
6778
  to_phone_number: String,
6059
- twilio_message_sid: T.nilable(String),
6060
6779
  type:
6061
6780
  Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Type::TaggedSymbol
6062
6781
  }
@@ -6065,6 +6784,40 @@ module Revox
6065
6784
  def to_hash
6066
6785
  end
6067
6786
 
6787
+ module Provider
6788
+ extend Revox::Internal::Type::Enum
6789
+
6790
+ TaggedSymbol =
6791
+ T.type_alias do
6792
+ T.all(
6793
+ Symbol,
6794
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Provider
6795
+ )
6796
+ end
6797
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
6798
+
6799
+ TWILIO =
6800
+ T.let(
6801
+ :twilio,
6802
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Provider::TaggedSymbol
6803
+ )
6804
+ VONAGE =
6805
+ T.let(
6806
+ :vonage,
6807
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Provider::TaggedSymbol
6808
+ )
6809
+
6810
+ sig do
6811
+ override.returns(
6812
+ T::Array[
6813
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SMSLog::Provider::TaggedSymbol
6814
+ ]
6815
+ )
6816
+ end
6817
+ def self.values
6818
+ end
6819
+ end
6820
+
6068
6821
  module Type
6069
6822
  extend Revox::Internal::Type::Enum
6070
6823
 
@@ -6105,6 +6858,176 @@ module Revox
6105
6858
  end
6106
6859
  end
6107
6860
 
6861
+ class SpeechEvent < Revox::Internal::Type::BaseModel
6862
+ OrHash =
6863
+ T.type_alias do
6864
+ T.any(
6865
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent,
6866
+ Revox::Internal::AnyHash
6867
+ )
6868
+ end
6869
+
6870
+ sig { returns(String) }
6871
+ attr_accessor :id
6872
+
6873
+ # False when the segment was flagged as noise/blip rather than a meaningful turn.
6874
+ sig { returns(T::Boolean) }
6875
+ attr_accessor :is_real_turn
6876
+
6877
+ # Agent-only: despite the name, the whole prompt the LLM was given for this turn —
6878
+ # system instructions plus conversation history — as JSON.
6879
+ sig { returns(T.nilable(String)) }
6880
+ attr_accessor :llm_system_prompt
6881
+
6882
+ # Agent-only: LLM time-to-first-token for the reply, in ms.
6883
+ sig { returns(T.nilable(Float)) }
6884
+ attr_accessor :llm_ttft_ms
6885
+
6886
+ # Agent-only: the model that produced the reply — the winning leg when the LLM is
6887
+ # a race, which is also the model `llm_ttft_ms` describes.
6888
+ sig { returns(T.nilable(String)) }
6889
+ attr_accessor :llm_winner_model
6890
+
6891
+ # Who was speaking during this segment.
6892
+ sig do
6893
+ returns(
6894
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent::Speaker::TaggedSymbol
6895
+ )
6896
+ end
6897
+ attr_accessor :speaker
6898
+
6899
+ # Milliseconds since session start when speech began.
6900
+ sig { returns(Float) }
6901
+ attr_accessor :started_speaking_at_ms
6902
+
6903
+ # Milliseconds since session start when speech ended. Null when the session ended
6904
+ # before the turn closed.
6905
+ sig { returns(T.nilable(Float)) }
6906
+ attr_accessor :stopped_speaking_at_ms
6907
+
6908
+ # User-only: time from end-of-speech to final transcript, in ms.
6909
+ sig { returns(T.nilable(Float)) }
6910
+ attr_accessor :stt_transcription_delay_ms
6911
+
6912
+ # Recognized text for this segment, when available.
6913
+ sig { returns(T.nilable(String)) }
6914
+ attr_accessor :transcript
6915
+
6916
+ # Agent-only: TTS time-to-first-audio-byte for the reply, in ms.
6917
+ sig { returns(T.nilable(Float)) }
6918
+ attr_accessor :tts_ttfb_ms
6919
+
6920
+ # Agent-only: true when the agent's audio was interrupted (real or auto-resumed).
6921
+ # Null on user segments.
6922
+ sig { returns(T.nilable(T::Boolean)) }
6923
+ attr_accessor :was_cut
6924
+
6925
+ sig do
6926
+ params(
6927
+ id: String,
6928
+ is_real_turn: T::Boolean,
6929
+ llm_system_prompt: T.nilable(String),
6930
+ llm_ttft_ms: T.nilable(Float),
6931
+ llm_winner_model: T.nilable(String),
6932
+ speaker:
6933
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent::Speaker::OrSymbol,
6934
+ started_speaking_at_ms: Float,
6935
+ stopped_speaking_at_ms: T.nilable(Float),
6936
+ stt_transcription_delay_ms: T.nilable(Float),
6937
+ transcript: T.nilable(String),
6938
+ tts_ttfb_ms: T.nilable(Float),
6939
+ was_cut: T.nilable(T::Boolean)
6940
+ ).returns(T.attached_class)
6941
+ end
6942
+ def self.new(
6943
+ id:,
6944
+ # False when the segment was flagged as noise/blip rather than a meaningful turn.
6945
+ is_real_turn:,
6946
+ # Agent-only: despite the name, the whole prompt the LLM was given for this turn —
6947
+ # system instructions plus conversation history — as JSON.
6948
+ llm_system_prompt:,
6949
+ # Agent-only: LLM time-to-first-token for the reply, in ms.
6950
+ llm_ttft_ms:,
6951
+ # Agent-only: the model that produced the reply — the winning leg when the LLM is
6952
+ # a race, which is also the model `llm_ttft_ms` describes.
6953
+ llm_winner_model:,
6954
+ # Who was speaking during this segment.
6955
+ speaker:,
6956
+ # Milliseconds since session start when speech began.
6957
+ started_speaking_at_ms:,
6958
+ # Milliseconds since session start when speech ended. Null when the session ended
6959
+ # before the turn closed.
6960
+ stopped_speaking_at_ms:,
6961
+ # User-only: time from end-of-speech to final transcript, in ms.
6962
+ stt_transcription_delay_ms:,
6963
+ # Recognized text for this segment, when available.
6964
+ transcript:,
6965
+ # Agent-only: TTS time-to-first-audio-byte for the reply, in ms.
6966
+ tts_ttfb_ms:,
6967
+ # Agent-only: true when the agent's audio was interrupted (real or auto-resumed).
6968
+ # Null on user segments.
6969
+ was_cut:
6970
+ )
6971
+ end
6972
+
6973
+ sig do
6974
+ override.returns(
6975
+ {
6976
+ id: String,
6977
+ is_real_turn: T::Boolean,
6978
+ llm_system_prompt: T.nilable(String),
6979
+ llm_ttft_ms: T.nilable(Float),
6980
+ llm_winner_model: T.nilable(String),
6981
+ speaker:
6982
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent::Speaker::TaggedSymbol,
6983
+ started_speaking_at_ms: Float,
6984
+ stopped_speaking_at_ms: T.nilable(Float),
6985
+ stt_transcription_delay_ms: T.nilable(Float),
6986
+ transcript: T.nilable(String),
6987
+ tts_ttfb_ms: T.nilable(Float),
6988
+ was_cut: T.nilable(T::Boolean)
6989
+ }
6990
+ )
6991
+ end
6992
+ def to_hash
6993
+ end
6994
+
6995
+ # Who was speaking during this segment.
6996
+ module Speaker
6997
+ extend Revox::Internal::Type::Enum
6998
+
6999
+ TaggedSymbol =
7000
+ T.type_alias do
7001
+ T.all(
7002
+ Symbol,
7003
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent::Speaker
7004
+ )
7005
+ end
7006
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
7007
+
7008
+ USER =
7009
+ T.let(
7010
+ :user,
7011
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent::Speaker::TaggedSymbol
7012
+ )
7013
+ AGENT =
7014
+ T.let(
7015
+ :agent,
7016
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent::Speaker::TaggedSymbol
7017
+ )
7018
+
7019
+ sig do
7020
+ override.returns(
7021
+ T::Array[
7022
+ Revox::Models::CampaignGetRowsResponse::Row::Call::LastCallAttempt::SpeechEvent::Speaker::TaggedSymbol
7023
+ ]
7024
+ )
7025
+ end
7026
+ def self.values
7027
+ end
7028
+ end
7029
+ end
7030
+
6108
7031
  class Transcript < Revox::Internal::Type::BaseModel
6109
7032
  OrHash =
6110
7033
  T.type_alias do
@@ -6615,6 +7538,11 @@ module Revox
6615
7538
  :post_processing,
6616
7539
  Revox::Models::CampaignGetRowsResponse::Row::Call::Status::TaggedSymbol
6617
7540
  )
7541
+ NOT_LAUNCHED =
7542
+ T.let(
7543
+ :not_launched,
7544
+ Revox::Models::CampaignGetRowsResponse::Row::Call::Status::TaggedSymbol
7545
+ )
6618
7546
  SCHEDULED =
6619
7547
  T.let(
6620
7548
  :scheduled,
@@ -6685,21 +7613,6 @@ module Revox
6685
7613
  :requested_callback_later,
6686
7614
  Revox::Models::CampaignGetRowsResponse::Row::Call::Outcome::TaggedSymbol
6687
7615
  )
6688
- REQUESTED_CALLBACK_NEW_NUMBER =
6689
- T.let(
6690
- :requested_callback_new_number,
6691
- Revox::Models::CampaignGetRowsResponse::Row::Call::Outcome::TaggedSymbol
6692
- )
6693
- DO_NOT_CONTACT =
6694
- T.let(
6695
- :do_not_contact,
6696
- Revox::Models::CampaignGetRowsResponse::Row::Call::Outcome::TaggedSymbol
6697
- )
6698
- AI_AVERSE =
6699
- T.let(
6700
- :ai_averse,
6701
- Revox::Models::CampaignGetRowsResponse::Row::Call::Outcome::TaggedSymbol
6702
- )
6703
7616
 
6704
7617
  sig do
6705
7618
  override.returns(