Deadmon commited on
Commit
64382cc
·
verified ·
1 Parent(s): f4f00e7

Update bot_registry.py

Browse files
Files changed (1) hide show
  1. bot_registry.py +22 -128
bot_registry.py CHANGED
@@ -1,137 +1,31 @@
1
- # bot_registry.py
2
- """Bot registry pattern for managing different bot types."""
3
-
4
- from typing import Any, Callable, Dict, List, Optional
5
-
6
- from bot_constants import DEFAULT_DIALIN_EXAMPLE
7
- from bot_runner_helpers import ensure_dialout_settings_array
8
- from fastapi import HTTPException
9
-
10
-
11
- class BotType:
12
- """Bot type configuration and handling."""
13
-
14
- def __init__(
15
- self,
16
- name: str,
17
- settings_creator: Callable[[Dict[str, Any]], Dict[str, Any]],
18
- required_settings: list = None,
19
- incompatible_with: list = None,
20
- auto_add_settings: dict = None,
21
- ):
22
- """Initialize a bot type.
23
-
24
- Args:
25
- name: Name of the bot type
26
- settings_creator: Function to create/update settings for this bot type
27
- required_settings: List of settings this bot type requires
28
- incompatible_with: List of bot types this one cannot be used with
29
- auto_add_settings: Settings to add if this bot is being run in test mode
30
- """
31
- self.name = name
32
- self.settings_creator = settings_creator
33
- self.required_settings = required_settings or []
34
- self.incompatible_with = incompatible_with or []
35
- self.auto_add_settings = auto_add_settings or {}
36
-
37
- def has_test_mode(self, body: Dict[str, Any]) -> bool:
38
- """Check if this bot type is configured for test mode."""
39
- return self.name in body and body[self.name].get("testInPrebuilt", False)
40
-
41
- def create_settings(self, body: Dict[str, Any]) -> Dict[str, Any]:
42
- """Create or update settings for this bot type."""
43
- body[self.name] = self.settings_creator(body)
44
- return body
45
-
46
- def prepare_for_test(self, body: Dict[str, Any]) -> Dict[str, Any]:
47
- """Add required settings for test mode if they don't exist."""
48
- for setting, default_value in self.auto_add_settings.items():
49
- if setting not in body:
50
- body[setting] = default_value
51
- return body
52
 
53
 
54
  class BotRegistry:
55
- """Registry for managing different bot types."""
56
-
57
  def __init__(self):
58
- self.bots = {}
59
- self.bot_validation_rules = []
60
-
61
- def register(self, bot_type: BotType):
62
- """Register a bot type."""
63
- self.bots[bot_type.name] = bot_type
64
- return self
65
-
66
- def get_bot(self, name: str) -> BotType:
67
- """Get a bot type by name."""
68
  return self.bots.get(name)
69
 
70
  def detect_bot_type(self, body: Dict[str, Any]) -> Optional[str]:
71
- """Detect which bot type to use based on configuration."""
72
- # First check for test mode bots
73
- for name, bot in self.bots.items():
74
- if bot.has_test_mode(body):
75
- return name
76
-
77
- # Then check for specific combinations of settings
78
- for name, bot in self.bots.items():
79
- if name in body and all(req in body for req in bot.required_settings):
80
- return name
81
-
82
- # Default for dialin settings
83
- if "dialin_settings" in body:
84
- return DEFAULT_DIALIN_EXAMPLE
85
-
86
  return None
87
 
88
- def validate_bot_combination(self, body: Dict[str, Any]) -> List[str]:
89
- """Validate that bot types in the configuration are compatible."""
90
- errors = []
91
- bot_types_in_config = [name for name in self.bots.keys() if name in body]
92
-
93
- # Check each bot type against its incompatible list
94
- for bot_name in bot_types_in_config:
95
- bot = self.bots[bot_name]
96
- for incompatible in bot.incompatible_with:
97
- if incompatible in body:
98
- errors.append(
99
- f"Cannot have both '{bot_name}' and '{incompatible}' in the same configuration"
100
- )
101
-
102
- return errors
103
-
104
- def setup_configuration(self, body: Dict[str, Any]) -> Dict[str, Any]:
105
- """Set up bot configuration based on detected bot type."""
106
- # Ensure dialout_settings is an array if present
107
- body = ensure_dialout_settings_array(body)
108
-
109
- # Detect which bot type to use
110
- bot_type_name = self.detect_bot_type(body)
111
- if not bot_type_name:
112
- raise HTTPException(
113
- status_code=400, detail="Configuration doesn't match any supported scenario"
114
- )
115
-
116
- # If we have a dialin scenario but no explicit bot type, add the default
117
- if "dialin_settings" in body and bot_type_name == DEFAULT_DIALIN_EXAMPLE:
118
- if bot_type_name not in body:
119
- body[bot_type_name] = {}
120
-
121
- # Get the bot type object
122
- bot_type = self.get_bot(bot_type_name)
123
-
124
- # Create/update settings for the bot type
125
- body = bot_type.create_settings(body)
126
-
127
- # If in test mode, add any required settings
128
- if bot_type.has_test_mode(body):
129
- body = bot_type.prepare_for_test(body)
130
-
131
- # Validate bot combinations
132
- errors = self.validate_bot_combination(body)
133
- if errors:
134
- error_message = "Invalid configuration: " + "; ".join(errors)
135
- raise HTTPException(status_code=400, detail=error_message)
136
-
137
- return body
 
1
+ from typing import Dict, Optional, Any
2
+ from bot_definitions import BotType, call_transfer, simple_dialin, simple_dialout, voicemail_detection
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
 
5
  class BotRegistry:
 
 
6
  def __init__(self):
7
+ self.bots: Dict[str, BotType] = {
8
+ "call_transfer": call_transfer,
9
+ "simple_dialin": simple_dialin,
10
+ "simple_dialout": simple_dialout,
11
+ "voicemail_detection": voicemail_detection,
12
+ }
13
+
14
+ def get_bot(self, name: str) -> Optional[BotType]:
 
 
15
  return self.bots.get(name)
16
 
17
  def detect_bot_type(self, body: Dict[str, Any]) -> Optional[str]:
18
+ for bot in self.bots.values():
19
+ if bot.config_key in body:
20
+ return bot.name
21
+ if all(key in body for key in ["From", "To", "callId", "callDomain"]):
22
+ return "call_transfer"
 
 
 
 
 
 
 
 
 
 
23
  return None
24
 
25
+ def setup_configuration(self, config: Dict[str, Any]) -> Dict[str, Any]:
26
+ body = {}
27
+ bot_name = config.get("bot_type")
28
+ bot = self.get_bot(bot_name)
29
+ if bot:
30
+ body[bot.config_key] = config.get("settings", {})
31
+ return body