signalwire-agents 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl

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 (34) hide show
  1. signalwire_agents/__init__.py +10 -1
  2. signalwire_agents/agent_server.py +73 -44
  3. signalwire_agents/core/__init__.py +9 -0
  4. signalwire_agents/core/agent_base.py +125 -33
  5. signalwire_agents/core/function_result.py +31 -12
  6. signalwire_agents/core/pom_builder.py +9 -0
  7. signalwire_agents/core/security/__init__.py +9 -0
  8. signalwire_agents/core/security/session_manager.py +9 -0
  9. signalwire_agents/core/state/__init__.py +9 -0
  10. signalwire_agents/core/state/file_state_manager.py +9 -0
  11. signalwire_agents/core/state/state_manager.py +9 -0
  12. signalwire_agents/core/swaig_function.py +9 -0
  13. signalwire_agents/core/swml_builder.py +9 -0
  14. signalwire_agents/core/swml_handler.py +9 -0
  15. signalwire_agents/core/swml_renderer.py +9 -0
  16. signalwire_agents/core/swml_service.py +88 -40
  17. signalwire_agents/prefabs/__init__.py +12 -1
  18. signalwire_agents/prefabs/concierge.py +9 -18
  19. signalwire_agents/prefabs/faq_bot.py +9 -18
  20. signalwire_agents/prefabs/info_gatherer.py +193 -183
  21. signalwire_agents/prefabs/receptionist.py +294 -0
  22. signalwire_agents/prefabs/survey.py +9 -18
  23. signalwire_agents/utils/__init__.py +9 -0
  24. signalwire_agents/utils/pom_utils.py +9 -0
  25. signalwire_agents/utils/schema_utils.py +9 -0
  26. signalwire_agents/utils/token_generators.py +9 -0
  27. signalwire_agents/utils/validators.py +9 -0
  28. {signalwire_agents-0.1.0.dist-info → signalwire_agents-0.1.2.dist-info}/METADATA +75 -30
  29. signalwire_agents-0.1.2.dist-info/RECORD +34 -0
  30. {signalwire_agents-0.1.0.dist-info → signalwire_agents-0.1.2.dist-info}/WHEEL +1 -1
  31. signalwire_agents-0.1.2.dist-info/licenses/LICENSE +21 -0
  32. signalwire_agents-0.1.0.dist-info/RECORD +0 -32
  33. {signalwire_agents-0.1.0.data → signalwire_agents-0.1.2.data}/data/schema.json +0 -0
  34. {signalwire_agents-0.1.0.dist-info → signalwire_agents-0.1.2.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  SignalWire AI Agents SDK
3
12
  =======================
@@ -5,7 +14,7 @@ SignalWire AI Agents SDK
5
14
  A package for building AI agents using SignalWire's AI and SWML capabilities.
6
15
  """
7
16
 
8
- __version__ = "0.1.0"
17
+ __version__ = "0.1.2"
9
18
 
10
19
  # Import core classes for easier access
11
20
  from signalwire_agents.core.agent_base import AgentBase
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  AgentServer - Class for hosting multiple SignalWire AI Agents in a single server
3
12
  """
@@ -57,7 +66,7 @@ class AgentServer:
57
66
  self.app = FastAPI(
58
67
  title="SignalWire AI Agents",
59
68
  description="Hosted SignalWire AI Agents",
60
- version="0.1.0"
69
+ version="0.1.2"
61
70
  )
62
71
 
63
72
  # Keep track of registered agents
@@ -103,18 +112,25 @@ class AgentServer:
103
112
  self.logger.info(f"Registered agent '{agent.get_name()}' at route '{route}'")
104
113
 
105
114
  # If SIP routing is enabled and auto-mapping is on, register SIP usernames for this agent
106
- if hasattr(self, '_sip_auto_map') and self._sip_auto_map and self._sip_routing_enabled:
107
- self._auto_map_agent_sip_usernames(agent, route)
115
+ if self._sip_routing_enabled:
116
+ # Auto-map SIP usernames if enabled
117
+ if getattr(self, '_sip_auto_map', False):
118
+ self._auto_map_agent_sip_usernames(agent, route)
119
+
120
+ # Register the SIP routing callback with this agent if we have one
121
+ if hasattr(self, '_sip_routing_callback') and self._sip_routing_callback:
122
+ agent.register_routing_callback(self._sip_routing_callback, path=self._sip_route)
108
123
 
109
124
  def setup_sip_routing(self, route: str = "/sip", auto_map: bool = True) -> None:
110
125
  """
111
126
  Set up central SIP-based routing for the server
112
127
 
113
- This adds a special endpoint that can route SIP requests to the appropriate
114
- agent based on the SIP username in the request.
128
+ This configures all agents to handle SIP requests at the specified path,
129
+ using a coordinated routing system where each agent checks if it can
130
+ handle SIP requests for specific usernames.
115
131
 
116
132
  Args:
117
- route: The route for SIP requests
133
+ route: The path for SIP routing (default: "/sip")
118
134
  auto_map: Whether to automatically map SIP usernames to agent routes
119
135
  """
120
136
  if self._sip_routing_enabled:
@@ -136,48 +152,38 @@ class AgentServer:
136
152
  if auto_map:
137
153
  for agent_route, agent in self.agents.items():
138
154
  self._auto_map_agent_sip_usernames(agent, agent_route)
139
-
140
- # Register the SIP endpoint
141
- @self.app.post(f"{route}")
142
- @self.app.post(f"{route}/")
143
- async def handle_sip_request(request: Request):
144
- """Handle SIP requests and route to the appropriate agent"""
145
- self.logger.debug(f"Received request at SIP endpoint: {route}")
155
+
156
+ # Create a unified routing callback that checks all registered usernames
157
+ def server_sip_routing_callback(request: Request, body: Dict[str, Any]) -> Optional[str]:
158
+ """Unified SIP routing callback that checks all registered usernames"""
159
+ # Extract the SIP username
160
+ sip_username = SWMLService.extract_sip_username(body)
146
161
 
147
- try:
148
- # Extract the request body
149
- body = await request.json()
150
-
151
- # Extract the SIP username
152
- sip_username = SWMLService.extract_sip_username(body)
162
+ if sip_username:
163
+ self.logger.info(f"Extracted SIP username: {sip_username}")
153
164
 
154
- if sip_username:
155
- self.logger.info(f"Extracted SIP username: {sip_username}")
156
-
157
- # Look up the route for this username
158
- target_route = self._lookup_sip_route(sip_username)
159
-
160
- if target_route:
161
- self.logger.info(f"Routing SIP request to {target_route}")
162
-
163
- # Create a redirect response to the target route
164
- # Use 307 Temporary Redirect to preserve the POST method
165
- response = Response(status_code=307)
166
- response.headers["Location"] = target_route
167
- return response
168
- else:
169
- self.logger.warning(f"No route found for SIP username: {sip_username}")
165
+ # Look up the route for this username
166
+ target_route = self._lookup_sip_route(sip_username)
170
167
 
171
- # If we get here, either no SIP username was found or no matching route exists
172
- # Return a basic SWML response
173
- return {"version": "1.0.0", "sections": {"main": []}}
174
-
175
- except Exception as e:
176
- self.logger.error(f"Error processing SIP request: {str(e)}")
177
- return {"version": "1.0.0", "sections": {"main": []}}
168
+ if target_route:
169
+ self.logger.info(f"Routing SIP request to {target_route}")
170
+ return target_route
171
+ else:
172
+ self.logger.warning(f"No route found for SIP username: {sip_username}")
173
+
174
+ # No routing needed (will be handled by the current agent)
175
+ return None
176
+
177
+ # Save the callback for later use with new agents
178
+ self._sip_routing_callback = server_sip_routing_callback
179
+
180
+ # Register this callback with each agent
181
+ for agent in self.agents.values():
182
+ # Each agent gets the same routing callback but at their own path
183
+ agent.register_routing_callback(server_sip_routing_callback, path=route)
184
+
185
+ self.logger.info(f"SIP routing enabled at {route} on all agents")
178
186
 
179
- self.logger.info(f"SIP routing enabled at {route}")
180
-
181
187
  def register_sip_username(self, username: str, route: str) -> None:
182
188
  """
183
189
  Register a mapping from SIP username to agent route
@@ -334,3 +340,26 @@ class AgentServer:
334
340
  port=port,
335
341
  log_level=self.log_level
336
342
  )
343
+
344
+ def register_global_routing_callback(self, callback_fn: Callable[[Request, Dict[str, Any]], Optional[str]],
345
+ path: str) -> None:
346
+ """
347
+ Register a routing callback across all agents
348
+
349
+ This allows you to add unified routing logic to all agents at the same path.
350
+
351
+ Args:
352
+ callback_fn: The callback function to register
353
+ path: The path to register the callback at
354
+ """
355
+ # Normalize the path
356
+ if not path.startswith("/"):
357
+ path = f"/{path}"
358
+
359
+ path = path.rstrip("/")
360
+
361
+ # Register with all existing agents
362
+ for agent in self.agents.values():
363
+ agent.register_routing_callback(callback_fn, path=path)
364
+
365
+ self.logger.info(f"Registered global routing callback at {path} on all agents")
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  Core components for SignalWire AI Agents
3
12
  """
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  AgentBase - Core foundation class for all SignalWire AI Agents
3
12
  """
@@ -195,6 +204,10 @@ class AgentBase(SWMLService):
195
204
  self._session_manager = SessionManager(token_expiry_secs=token_expiry_secs)
196
205
  self._enable_state_tracking = enable_state_tracking
197
206
 
207
+ # URL override variables
208
+ self._web_hook_url_override = None
209
+ self._post_prompt_url_override = None
210
+
198
211
  # Register the tool decorator on this instance
199
212
  self.tool = self._tool_decorator
200
213
 
@@ -895,6 +908,10 @@ class AgentBase(SWMLService):
895
908
  # Get the default webhook URL with auth
896
909
  default_webhook_url = self._build_webhook_url("swaig", query_params)
897
910
 
911
+ # Use override if set
912
+ if hasattr(self, '_web_hook_url_override') and self._web_hook_url_override:
913
+ default_webhook_url = self._web_hook_url_override
914
+
898
915
  # Prepare SWAIG object (correct format)
899
916
  swaig_obj = {}
900
917
 
@@ -952,6 +969,10 @@ class AgentBase(SWMLService):
952
969
  post_prompt_url = None
953
970
  if post_prompt:
954
971
  post_prompt_url = self._build_webhook_url("post_prompt", {})
972
+
973
+ # Use override if set
974
+ if hasattr(self, '_post_prompt_url_override') and self._post_prompt_url_override:
975
+ post_prompt_url = self._post_prompt_url_override
955
976
 
956
977
  # Add answer verb with auto-answer enabled
957
978
  self.add_answer_verb()
@@ -1151,8 +1172,11 @@ class AgentBase(SWMLService):
1151
1172
 
1152
1173
  async def _handle_root_request(self, request: Request):
1153
1174
  """Handle GET/POST requests to the root endpoint"""
1175
+ # Check if this is a callback path request
1176
+ callback_path = getattr(request.state, "callback_path", None)
1177
+
1154
1178
  req_log = self.log.bind(
1155
- endpoint="root",
1179
+ endpoint="root" if not callback_path else f"callback:{callback_path}",
1156
1180
  method=request.method,
1157
1181
  path=request.url.path
1158
1182
  )
@@ -1202,6 +1226,25 @@ class AgentBase(SWMLService):
1202
1226
  req_log = req_log.bind(call_id=call_id)
1203
1227
  req_log.debug("call_id_identified")
1204
1228
 
1229
+ # Check if this is a callback path and we need to apply routing
1230
+ if callback_path and hasattr(self, '_routing_callbacks') and callback_path in self._routing_callbacks:
1231
+ callback_fn = self._routing_callbacks[callback_path]
1232
+
1233
+ if request.method == "POST" and body:
1234
+ req_log.debug("processing_routing_callback", path=callback_path)
1235
+ # Call the routing callback
1236
+ try:
1237
+ route = callback_fn(request, body)
1238
+ if route is not None:
1239
+ req_log.info("routing_request", route=route)
1240
+ # Return a redirect to the new route
1241
+ return Response(
1242
+ status_code=307, # 307 Temporary Redirect preserves the method and body
1243
+ headers={"Location": route}
1244
+ )
1245
+ except Exception as e:
1246
+ req_log.error("error_in_routing_callback", error=str(e), traceback=traceback.format_exc())
1247
+
1205
1248
  # Allow subclasses to inspect/modify the request
1206
1249
  modifications = None
1207
1250
  if body:
@@ -1669,28 +1712,34 @@ class AgentBase(SWMLService):
1669
1712
  async def handle_post_prompt_with_slash(request: Request):
1670
1713
  return await self._handle_post_prompt_request(request)
1671
1714
 
1672
- # Check if SIP routing is enabled for this agent
1673
- # (The agent will have _sip_usernames if enable_sip_routing was called)
1674
- if hasattr(self, '_sip_usernames') and self._sip_usernames:
1675
- self.log.info("registering_sip_endpoint", usernames=list(self._sip_usernames))
1676
-
1677
- # SIP endpoint - without trailing slash
1678
- @app.get("/sip")
1679
- @app.post("/sip")
1680
- async def handle_sip_no_slash(request: Request):
1681
- return await self._handle_root_request(request)
1715
+ # Register routes for all routing callbacks
1716
+ if hasattr(self, '_routing_callbacks') and self._routing_callbacks:
1717
+ for callback_path, callback_fn in self._routing_callbacks.items():
1718
+ # Skip the root path as it's already handled
1719
+ if callback_path == "/":
1720
+ continue
1682
1721
 
1683
- # SIP endpoint - with trailing slash
1684
- @app.get("/sip/")
1685
- @app.post("/sip/")
1686
- async def handle_sip_with_slash(request: Request):
1687
- return await self._handle_root_request(request)
1722
+ # Register the endpoint without trailing slash
1723
+ callback_route = callback_path
1724
+ self.log.info("registering_callback_route", path=callback_route)
1688
1725
 
1689
- # Log that SIP endpoint was added
1690
- self.log.info("sip_endpoint_registered", path="/sip")
1691
-
1692
- # Add SIP routes to the printed information
1693
- print(f"SIP endpoint available at: http://{self.host}:{self.port}/sip")
1726
+ @app.get(callback_route)
1727
+ @app.post(callback_route)
1728
+ async def handle_callback_no_slash(request: Request, path_param=callback_route):
1729
+ # Store the callback path in request state for _handle_root_request to use
1730
+ request.state.callback_path = path_param
1731
+ return await self._handle_root_request(request)
1732
+
1733
+ # Register the endpoint with trailing slash if it doesn't already have one
1734
+ if not callback_route.endswith('/'):
1735
+ slash_route = f"{callback_route}/"
1736
+
1737
+ @app.get(slash_route)
1738
+ @app.post(slash_route)
1739
+ async def handle_callback_with_slash(request: Request, path_param=callback_route):
1740
+ # Store the callback path in request state for _handle_root_request to use
1741
+ request.state.callback_path = path_param
1742
+ return await self._handle_root_request(request)
1694
1743
 
1695
1744
  # Log all registered routes
1696
1745
  routes = [f"{route.methods} {route.path}" for route in app.routes]
@@ -2042,16 +2091,24 @@ class AgentBase(SWMLService):
2042
2091
  print(f"URL: http://{host}:{port}{self.route}")
2043
2092
  print(f"Basic Auth: {username}:{password} (source: {source})")
2044
2093
 
2045
- # Check if SIP routing is enabled and print additional info
2094
+ # Check if SIP usernames are registered and print that info
2046
2095
  if hasattr(self, '_sip_usernames') and self._sip_usernames:
2047
- print(f"SIP endpoint: http://{host}:{port}/sip")
2048
- print(f"SIP usernames: {', '.join(self._sip_usernames)}")
2096
+ print(f"Registered SIP usernames: {', '.join(sorted(self._sip_usernames))}")
2097
+
2098
+ # Check if callback endpoints are registered and print them
2099
+ if hasattr(self, '_routing_callbacks') and self._routing_callbacks:
2100
+ for path in sorted(self._routing_callbacks.keys()):
2101
+ if hasattr(self, '_sip_usernames') and path == "/sip":
2102
+ print(f"SIP endpoint: http://{host}:{port}{path}")
2103
+ else:
2104
+ print(f"Callback endpoint: http://{host}:{port}{path}")
2049
2105
 
2050
2106
  # Configure Uvicorn for production
2051
2107
  uvicorn_log_config = uvicorn.config.LOGGING_CONFIG
2052
2108
  uvicorn_log_config["formatters"]["access"]["fmt"] = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
2053
2109
  uvicorn_log_config["formatters"]["default"]["fmt"] = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
2054
2110
 
2111
+ # Start the server
2055
2112
  try:
2056
2113
  # Run the server
2057
2114
  uvicorn.run(
@@ -2368,18 +2425,19 @@ class AgentBase(SWMLService):
2368
2425
  self._function_includes = valid_includes
2369
2426
  return self
2370
2427
 
2371
- def enable_sip_routing(self, auto_map: bool = True) -> 'AgentBase':
2428
+ def enable_sip_routing(self, auto_map: bool = True, path: str = "/sip") -> 'AgentBase':
2372
2429
  """
2373
2430
  Enable SIP-based routing for this agent
2374
2431
 
2375
2432
  This allows the agent to automatically route SIP requests based on SIP usernames.
2376
- When enabled, a global `/sip` endpoint is automatically created that will handle
2377
- SIP requests and deliver them to this agent.
2433
+ When enabled, an endpoint at the specified path is automatically created
2434
+ that will handle SIP requests and deliver them to this agent.
2378
2435
 
2379
2436
  Args:
2380
2437
  auto_map: Whether to automatically map common SIP usernames to this agent
2381
2438
  (based on the agent name and route path)
2382
-
2439
+ path: The path to register the SIP routing endpoint (default: "/sip")
2440
+
2383
2441
  Returns:
2384
2442
  Self for method chaining
2385
2443
  """
@@ -2391,11 +2449,19 @@ class AgentBase(SWMLService):
2391
2449
  if sip_username:
2392
2450
  self.log.info("sip_username_extracted", username=sip_username)
2393
2451
 
2394
- # This route is already being handled by the agent, no need to redirect
2395
- return None
2396
-
2397
- # Register the callback with the SWMLService
2398
- self.register_routing_callback(sip_routing_callback)
2452
+ # Check if this username is registered with this agent
2453
+ if hasattr(self, '_sip_usernames') and sip_username.lower() in self._sip_usernames:
2454
+ self.log.info("sip_username_matched", username=sip_username)
2455
+ # This route is already being handled by the agent, no need to redirect
2456
+ return None
2457
+ else:
2458
+ self.log.info("sip_username_not_matched", username=sip_username)
2459
+ # Not registered with this agent, let routing continue
2460
+
2461
+ return None
2462
+
2463
+ # Register the callback with the SWMLService, specifying the path
2464
+ self.register_routing_callback(sip_routing_callback, path=path)
2399
2465
 
2400
2466
  # Auto-map common usernames if requested
2401
2467
  if auto_map:
@@ -2447,3 +2513,29 @@ class AgentBase(SWMLService):
2447
2513
  self.register_sip_username(no_vowels)
2448
2514
 
2449
2515
  return self
2516
+
2517
+ def set_web_hook_url(self, url: str) -> 'AgentBase':
2518
+ """
2519
+ Override the default web_hook_url with a supplied URL string
2520
+
2521
+ Args:
2522
+ url: The URL to use for SWAIG function webhooks
2523
+
2524
+ Returns:
2525
+ Self for method chaining
2526
+ """
2527
+ self._web_hook_url_override = url
2528
+ return self
2529
+
2530
+ def set_post_prompt_url(self, url: str) -> 'AgentBase':
2531
+ """
2532
+ Override the default post_prompt_url with a supplied URL string
2533
+
2534
+ Args:
2535
+ url: The URL to use for post-prompt summary delivery
2536
+
2537
+ Returns:
2538
+ Self for method chaining
2539
+ """
2540
+ self._post_prompt_url_override = url
2541
+ return self
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  SwaigFunctionResult class for handling the response format of SWAIG function calls
3
12
  """
@@ -5,18 +14,6 @@ SwaigFunctionResult class for handling the response format of SWAIG function cal
5
14
  from typing import Dict, List, Any, Optional, Union
6
15
 
7
16
 
8
- class SwaigActionTypes:
9
- """Constants for standard SWAIG action types"""
10
- PLAY = "play"
11
- TRANSFER = "transfer"
12
- SEND_SMS = "send_sms"
13
- JOIN_ROOM = "join_room"
14
- RETURN = "return"
15
- HANG_UP = "hang_up"
16
- RECORD = "record"
17
- COLLECT = "collect"
18
-
19
-
20
17
  class SwaigFunctionResult:
21
18
  """
22
19
  Wrapper around SWAIG function responses that handles proper formatting
@@ -36,6 +33,15 @@ class SwaigFunctionResult:
36
33
  SwaigFunctionResult("I'll confirm that")
37
34
  .add_action("confirm", True)
38
35
  )
36
+
37
+ # With multiple actions
38
+ return (
39
+ SwaigFunctionResult("Processing your request")
40
+ .add_actions([
41
+ {"set_global_data": {"key": "value"}},
42
+ {"play": {"url": "music.mp3"}}
43
+ ])
44
+ )
39
45
  """
40
46
  def __init__(self, response: Optional[str] = None):
41
47
  """
@@ -74,6 +80,19 @@ class SwaigFunctionResult:
74
80
  self.action.append({name: data})
75
81
  return self
76
82
 
83
+ def add_actions(self, actions: List[Dict[str, Any]]) -> 'SwaigFunctionResult':
84
+ """
85
+ Add multiple structured actions to the response
86
+
87
+ Args:
88
+ actions: List of action objects to add to the response
89
+
90
+ Returns:
91
+ Self for method chaining
92
+ """
93
+ self.action.extend(actions)
94
+ return self
95
+
77
96
  def to_dict(self) -> Dict[str, Any]:
78
97
  """
79
98
  Convert to the JSON structure expected by SWAIG
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  PomBuilder for creating structured POM prompts for SignalWire AI Agents
3
12
  """
@@ -0,0 +1,9 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  Session manager for handling call sessions and security tokens
3
12
  """
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  State management for SignalWire AI Agents
3
12
  """
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  File-based implementation of the StateManager interface
3
12
  """
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  Abstract base class for state management
3
12
  """
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  SwaigFunction class for defining and managing SWAIG function interfaces
3
12
  """
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  SWML Builder - Fluent API for building SWML documents
3
12
 
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  SWML Verb Handlers - Interface and implementations for SWML verb handling
3
12
 
@@ -1,3 +1,12 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
1
10
  """
2
11
  SwmlRenderer for generating complete SWML documents for SignalWire AI Agents
3
12
  """