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.
- signalwire_agents/__init__.py +10 -1
- signalwire_agents/agent_server.py +73 -44
- signalwire_agents/core/__init__.py +9 -0
- signalwire_agents/core/agent_base.py +125 -33
- signalwire_agents/core/function_result.py +31 -12
- signalwire_agents/core/pom_builder.py +9 -0
- signalwire_agents/core/security/__init__.py +9 -0
- signalwire_agents/core/security/session_manager.py +9 -0
- signalwire_agents/core/state/__init__.py +9 -0
- signalwire_agents/core/state/file_state_manager.py +9 -0
- signalwire_agents/core/state/state_manager.py +9 -0
- signalwire_agents/core/swaig_function.py +9 -0
- signalwire_agents/core/swml_builder.py +9 -0
- signalwire_agents/core/swml_handler.py +9 -0
- signalwire_agents/core/swml_renderer.py +9 -0
- signalwire_agents/core/swml_service.py +88 -40
- signalwire_agents/prefabs/__init__.py +12 -1
- signalwire_agents/prefabs/concierge.py +9 -18
- signalwire_agents/prefabs/faq_bot.py +9 -18
- signalwire_agents/prefabs/info_gatherer.py +193 -183
- signalwire_agents/prefabs/receptionist.py +294 -0
- signalwire_agents/prefabs/survey.py +9 -18
- signalwire_agents/utils/__init__.py +9 -0
- signalwire_agents/utils/pom_utils.py +9 -0
- signalwire_agents/utils/schema_utils.py +9 -0
- signalwire_agents/utils/token_generators.py +9 -0
- signalwire_agents/utils/validators.py +9 -0
- {signalwire_agents-0.1.0.dist-info → signalwire_agents-0.1.2.dist-info}/METADATA +75 -30
- signalwire_agents-0.1.2.dist-info/RECORD +34 -0
- {signalwire_agents-0.1.0.dist-info → signalwire_agents-0.1.2.dist-info}/WHEEL +1 -1
- signalwire_agents-0.1.2.dist-info/licenses/LICENSE +21 -0
- signalwire_agents-0.1.0.dist-info/RECORD +0 -32
- {signalwire_agents-0.1.0.data → signalwire_agents-0.1.2.data}/data/schema.json +0 -0
- {signalwire_agents-0.1.0.dist-info → signalwire_agents-0.1.2.dist-info}/top_level.txt +0 -0
signalwire_agents/__init__.py
CHANGED
@@ -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.
|
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.
|
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
|
107
|
-
|
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
|
114
|
-
|
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
|
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
|
-
#
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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
|
-
|
148
|
-
|
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
|
-
|
155
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
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
|
-
#
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
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
|
-
|
1684
|
-
|
1685
|
-
|
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
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
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
|
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
|
2048
|
-
|
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,
|
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
|
-
#
|
2395
|
-
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
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
|
"""
|
@@ -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
|
"""
|