signalwire-agents 0.1.13__py3-none-any.whl → 1.0.17.dev4__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 (143) hide show
  1. signalwire_agents/__init__.py +99 -15
  2. signalwire_agents/agent_server.py +248 -60
  3. signalwire_agents/agents/bedrock.py +296 -0
  4. signalwire_agents/cli/__init__.py +9 -0
  5. signalwire_agents/cli/build_search.py +951 -41
  6. signalwire_agents/cli/config.py +80 -0
  7. signalwire_agents/cli/core/__init__.py +10 -0
  8. signalwire_agents/cli/core/agent_loader.py +470 -0
  9. signalwire_agents/cli/core/argparse_helpers.py +179 -0
  10. signalwire_agents/cli/core/dynamic_config.py +71 -0
  11. signalwire_agents/cli/core/service_loader.py +303 -0
  12. signalwire_agents/cli/dokku.py +2320 -0
  13. signalwire_agents/cli/execution/__init__.py +10 -0
  14. signalwire_agents/cli/execution/datamap_exec.py +446 -0
  15. signalwire_agents/cli/execution/webhook_exec.py +134 -0
  16. signalwire_agents/cli/init_project.py +2636 -0
  17. signalwire_agents/cli/output/__init__.py +10 -0
  18. signalwire_agents/cli/output/output_formatter.py +255 -0
  19. signalwire_agents/cli/output/swml_dump.py +186 -0
  20. signalwire_agents/cli/simulation/__init__.py +10 -0
  21. signalwire_agents/cli/simulation/data_generation.py +374 -0
  22. signalwire_agents/cli/simulation/data_overrides.py +200 -0
  23. signalwire_agents/cli/simulation/mock_env.py +282 -0
  24. signalwire_agents/cli/swaig_test_wrapper.py +52 -0
  25. signalwire_agents/cli/test_swaig.py +566 -2366
  26. signalwire_agents/cli/types.py +81 -0
  27. signalwire_agents/core/__init__.py +2 -2
  28. signalwire_agents/core/agent/__init__.py +12 -0
  29. signalwire_agents/core/agent/config/__init__.py +12 -0
  30. signalwire_agents/core/agent/deployment/__init__.py +9 -0
  31. signalwire_agents/core/agent/deployment/handlers/__init__.py +9 -0
  32. signalwire_agents/core/agent/prompt/__init__.py +14 -0
  33. signalwire_agents/core/agent/prompt/manager.py +306 -0
  34. signalwire_agents/core/agent/routing/__init__.py +9 -0
  35. signalwire_agents/core/agent/security/__init__.py +9 -0
  36. signalwire_agents/core/agent/swml/__init__.py +9 -0
  37. signalwire_agents/core/agent/tools/__init__.py +15 -0
  38. signalwire_agents/core/agent/tools/decorator.py +97 -0
  39. signalwire_agents/core/agent/tools/registry.py +210 -0
  40. signalwire_agents/core/agent_base.py +845 -2916
  41. signalwire_agents/core/auth_handler.py +233 -0
  42. signalwire_agents/core/config_loader.py +259 -0
  43. signalwire_agents/core/contexts.py +418 -0
  44. signalwire_agents/core/data_map.py +3 -15
  45. signalwire_agents/core/function_result.py +116 -44
  46. signalwire_agents/core/logging_config.py +162 -18
  47. signalwire_agents/core/mixins/__init__.py +28 -0
  48. signalwire_agents/core/mixins/ai_config_mixin.py +442 -0
  49. signalwire_agents/core/mixins/auth_mixin.py +280 -0
  50. signalwire_agents/core/mixins/prompt_mixin.py +358 -0
  51. signalwire_agents/core/mixins/serverless_mixin.py +460 -0
  52. signalwire_agents/core/mixins/skill_mixin.py +55 -0
  53. signalwire_agents/core/mixins/state_mixin.py +153 -0
  54. signalwire_agents/core/mixins/tool_mixin.py +230 -0
  55. signalwire_agents/core/mixins/web_mixin.py +1142 -0
  56. signalwire_agents/core/security_config.py +333 -0
  57. signalwire_agents/core/skill_base.py +84 -1
  58. signalwire_agents/core/skill_manager.py +62 -20
  59. signalwire_agents/core/swaig_function.py +18 -5
  60. signalwire_agents/core/swml_builder.py +207 -11
  61. signalwire_agents/core/swml_handler.py +27 -21
  62. signalwire_agents/core/swml_renderer.py +123 -312
  63. signalwire_agents/core/swml_service.py +171 -203
  64. signalwire_agents/mcp_gateway/__init__.py +29 -0
  65. signalwire_agents/mcp_gateway/gateway_service.py +564 -0
  66. signalwire_agents/mcp_gateway/mcp_manager.py +513 -0
  67. signalwire_agents/mcp_gateway/session_manager.py +218 -0
  68. signalwire_agents/prefabs/concierge.py +0 -3
  69. signalwire_agents/prefabs/faq_bot.py +0 -3
  70. signalwire_agents/prefabs/info_gatherer.py +0 -3
  71. signalwire_agents/prefabs/receptionist.py +0 -3
  72. signalwire_agents/prefabs/survey.py +0 -3
  73. signalwire_agents/schema.json +9218 -5489
  74. signalwire_agents/search/__init__.py +7 -1
  75. signalwire_agents/search/document_processor.py +490 -31
  76. signalwire_agents/search/index_builder.py +307 -37
  77. signalwire_agents/search/migration.py +418 -0
  78. signalwire_agents/search/models.py +30 -0
  79. signalwire_agents/search/pgvector_backend.py +748 -0
  80. signalwire_agents/search/query_processor.py +162 -31
  81. signalwire_agents/search/search_engine.py +916 -35
  82. signalwire_agents/search/search_service.py +376 -53
  83. signalwire_agents/skills/README.md +452 -0
  84. signalwire_agents/skills/__init__.py +14 -2
  85. signalwire_agents/skills/api_ninjas_trivia/README.md +215 -0
  86. signalwire_agents/skills/api_ninjas_trivia/__init__.py +12 -0
  87. signalwire_agents/skills/api_ninjas_trivia/skill.py +237 -0
  88. signalwire_agents/skills/datasphere/README.md +210 -0
  89. signalwire_agents/skills/datasphere/skill.py +84 -3
  90. signalwire_agents/skills/datasphere_serverless/README.md +258 -0
  91. signalwire_agents/skills/datasphere_serverless/__init__.py +9 -0
  92. signalwire_agents/skills/datasphere_serverless/skill.py +82 -1
  93. signalwire_agents/skills/datetime/README.md +132 -0
  94. signalwire_agents/skills/datetime/__init__.py +9 -0
  95. signalwire_agents/skills/datetime/skill.py +20 -7
  96. signalwire_agents/skills/joke/README.md +149 -0
  97. signalwire_agents/skills/joke/__init__.py +9 -0
  98. signalwire_agents/skills/joke/skill.py +21 -0
  99. signalwire_agents/skills/math/README.md +161 -0
  100. signalwire_agents/skills/math/__init__.py +9 -0
  101. signalwire_agents/skills/math/skill.py +18 -4
  102. signalwire_agents/skills/mcp_gateway/README.md +230 -0
  103. signalwire_agents/skills/mcp_gateway/__init__.py +10 -0
  104. signalwire_agents/skills/mcp_gateway/skill.py +421 -0
  105. signalwire_agents/skills/native_vector_search/README.md +210 -0
  106. signalwire_agents/skills/native_vector_search/__init__.py +9 -0
  107. signalwire_agents/skills/native_vector_search/skill.py +569 -101
  108. signalwire_agents/skills/play_background_file/README.md +218 -0
  109. signalwire_agents/skills/play_background_file/__init__.py +12 -0
  110. signalwire_agents/skills/play_background_file/skill.py +242 -0
  111. signalwire_agents/skills/registry.py +395 -40
  112. signalwire_agents/skills/spider/README.md +236 -0
  113. signalwire_agents/skills/spider/__init__.py +13 -0
  114. signalwire_agents/skills/spider/skill.py +598 -0
  115. signalwire_agents/skills/swml_transfer/README.md +395 -0
  116. signalwire_agents/skills/swml_transfer/__init__.py +10 -0
  117. signalwire_agents/skills/swml_transfer/skill.py +359 -0
  118. signalwire_agents/skills/weather_api/README.md +178 -0
  119. signalwire_agents/skills/weather_api/__init__.py +12 -0
  120. signalwire_agents/skills/weather_api/skill.py +191 -0
  121. signalwire_agents/skills/web_search/README.md +163 -0
  122. signalwire_agents/skills/web_search/__init__.py +9 -0
  123. signalwire_agents/skills/web_search/skill.py +586 -112
  124. signalwire_agents/skills/wikipedia_search/README.md +228 -0
  125. signalwire_agents/{core/state → skills/wikipedia_search}/__init__.py +5 -4
  126. signalwire_agents/skills/{wikipedia → wikipedia_search}/skill.py +33 -3
  127. signalwire_agents/web/__init__.py +17 -0
  128. signalwire_agents/web/web_service.py +559 -0
  129. signalwire_agents-1.0.17.dev4.data/data/share/man/man1/sw-agent-init.1 +400 -0
  130. signalwire_agents-1.0.17.dev4.data/data/share/man/man1/sw-search.1 +483 -0
  131. signalwire_agents-1.0.17.dev4.data/data/share/man/man1/swaig-test.1 +308 -0
  132. {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/METADATA +347 -215
  133. signalwire_agents-1.0.17.dev4.dist-info/RECORD +147 -0
  134. signalwire_agents-1.0.17.dev4.dist-info/entry_points.txt +6 -0
  135. signalwire_agents/core/state/file_state_manager.py +0 -219
  136. signalwire_agents/core/state/state_manager.py +0 -101
  137. signalwire_agents/skills/wikipedia/__init__.py +0 -9
  138. signalwire_agents-0.1.13.data/data/schema.json +0 -5611
  139. signalwire_agents-0.1.13.dist-info/RECORD +0 -67
  140. signalwire_agents-0.1.13.dist-info/entry_points.txt +0 -3
  141. {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/WHEEL +0 -0
  142. {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/licenses/LICENSE +0 -0
  143. {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,395 @@
1
+ # SWML Transfer Skill
2
+
3
+ Transfer calls between agents using SWML with pattern matching. This skill enables agents to transfer calls to other agents based on user input patterns, with full control over transfer messages and behaviors.
4
+
5
+ ## Description
6
+
7
+ The SWML Transfer skill provides a flexible way to implement call transfers between agents. It uses pattern matching to determine where to transfer calls based on user input, making it ideal for routing scenarios like transferring to sales, support, or other specialized agents.
8
+
9
+ ## Features
10
+
11
+ - **Pattern-based routing** - Use regex patterns to match user input
12
+ - **Multiple instances** - Load the skill multiple times with different configurations
13
+ - **Customizable messages** - Configure pre-transfer and post-transfer messages
14
+ - **Post-processing control** - Enable/disable post-processing per transfer
15
+ - **Dynamic URL support** - Transfer to any URL endpoint
16
+ - **Fallback handling** - Default behavior when no pattern matches
17
+ - **Automatic prompt sections** - Adds "Transferring" section listing all configured destinations
18
+ - **Required fields collection** - Collect any required data before transfer
19
+
20
+ ## Requirements
21
+
22
+ - No additional Python packages required
23
+ - No environment variables required
24
+
25
+ ## Configuration
26
+
27
+ ### Required Parameters
28
+
29
+ - `transfers`: Dictionary mapping regex patterns to transfer configurations
30
+
31
+ ### Optional Parameters
32
+
33
+ - `tool_name` (default: "transfer_call"): Name of the transfer function
34
+ - `description` (default: "Transfer call based on pattern matching"): Tool description
35
+ - `parameter_name` (default: "transfer_type"): Name of the parameter for the transfer function
36
+ - `parameter_description` (default: "The type of transfer to perform"): Parameter description
37
+ - `default_message` (default: "Please specify a valid transfer type."): Message when no pattern matches
38
+ - `default_post_process` (default: False): Post-processing flag for default case
39
+ - `required_fields` (default: {}): Object mapping field names to descriptions for data collection
40
+
41
+ ### Transfer Configuration
42
+
43
+ Each entry in the `transfers` dictionary should have:
44
+ - **Pattern (key)**: Regex pattern to match (e.g., "/sales/i" for case-insensitive)
45
+ - **Configuration (value)**: Dictionary with:
46
+ - **One of these required**:
47
+ - `url`: Transfer to SWML endpoint (uses swml_transfer action)
48
+ - `address`: Transfer to phone/SIP address (uses connect action)
49
+ - `message` (optional): Pre-transfer message
50
+ - `return_message` (optional): Post-transfer message (only used when `final` is False)
51
+ - `post_process` (optional): Boolean for post-processing (default: True)
52
+ - `final` (optional): Boolean for permanent transfer (default: True)
53
+ - `True`: Permanent transfer - call exits agent completely (default)
54
+ - `False`: Temporary transfer - control returns after transfer completes
55
+ - `from_addr` (optional): Caller ID override for connect action (only with `address`)
56
+
57
+ ## Usage
58
+
59
+ ### Basic Usage
60
+
61
+ ```python
62
+ from signalwire_agents import AgentBase
63
+
64
+ class MyAgent(AgentBase):
65
+ def __init__(self):
66
+ super().__init__(name="Routing Agent", route="/router")
67
+
68
+ # Add transfer capability
69
+ self.add_skill("swml_transfer", {
70
+ "tool_name": "transfer_to_department",
71
+ "transfers": {
72
+ "/sales/i": {
73
+ "url": "https://example.com/sales",
74
+ "message": "I'll connect you with our sales team.",
75
+ "return_message": "Thank you for speaking with sales."
76
+ },
77
+ "/support/i": {
78
+ "url": "https://example.com/support",
79
+ "message": "Let me transfer you to technical support.",
80
+ "return_message": "I hope support was able to help!"
81
+ }
82
+ }
83
+ })
84
+
85
+ agent = MyAgent()
86
+ agent.serve()
87
+ ```
88
+
89
+ ### Advanced Configuration
90
+
91
+ ```python
92
+ # Multiple transfer types with custom messages
93
+ self.add_skill("swml_transfer", {
94
+ "tool_name": "route_call",
95
+ "description": "Route calls to appropriate departments",
96
+ "parameter_name": "department",
97
+ "parameter_description": "Which department to transfer to",
98
+ "transfers": {
99
+ "/sales|billing|pricing/i": {
100
+ "url": "https://api.company.com/sales-agent",
101
+ "message": "I'll connect you with our sales team for pricing and billing questions.",
102
+ "return_message": "Thank you for contacting our sales department.",
103
+ "post_process": True,
104
+ "final": False # Temporary transfer - returns control
105
+ },
106
+ "/support|technical|help/i": {
107
+ "url": "https://api.company.com/support-agent",
108
+ "message": "Let me transfer you to our technical support team.",
109
+ "return_message": "I hope we were able to resolve your technical issue.",
110
+ "post_process": True,
111
+ "final": False # Temporary transfer - returns control
112
+ },
113
+ "/manager|supervisor/i": {
114
+ "url": "https://api.company.com/manager-agent",
115
+ "message": "I understand you'd like to speak with a manager. One moment please.",
116
+ "return_message": "Thank you for your patience.",
117
+ "post_process": False,
118
+ "final": False # Temporary transfer - returns control
119
+ },
120
+ "/disconnect|goodbye/i": {
121
+ "url": "https://api.company.com/closing-agent",
122
+ "message": "Thank you for calling. Goodbye!",
123
+ "post_process": True,
124
+ "final": True # Permanent transfer - exits this agent completely
125
+ }
126
+ },
127
+ "default_message": "I can transfer you to sales, support, or a manager. Which would you prefer?",
128
+ "default_post_process": False
129
+ })
130
+ ```
131
+
132
+ ### Permanent vs Temporary Transfers
133
+
134
+ ```python
135
+ # Permanent transfer example - call exits agent completely
136
+ self.add_skill("swml_transfer", {
137
+ "tool_name": "permanent_transfer",
138
+ "transfers": {
139
+ "/billing/i": {
140
+ "url": "https://example.com/billing-specialist",
141
+ "message": "I'll transfer you to our billing specialist. Goodbye!",
142
+ "final": True # Call won't return to this agent
143
+ }
144
+ }
145
+ })
146
+
147
+ # Temporary transfer example - call returns after transfer
148
+ self.add_skill("swml_transfer", {
149
+ "tool_name": "temporary_transfer",
150
+ "transfers": {
151
+ "/specialist/i": {
152
+ "url": "https://example.com/specialist",
153
+ "message": "Let me connect you with a specialist.",
154
+ "return_message": "Welcome back! Is there anything else I can help with?",
155
+ "final": False # Call returns to this agent after transfer
156
+ }
157
+ }
158
+ })
159
+ ```
160
+
161
+ ### Phone Number and SIP Address Transfers
162
+
163
+ ```python
164
+ # Transfer to phone numbers and SIP addresses using 'address'
165
+ self.add_skill("swml_transfer", {
166
+ "tool_name": "direct_transfer",
167
+ "transfers": {
168
+ "/emergency/i": {
169
+ "address": "+15551234567", # Phone number
170
+ "message": "Transferring you to our emergency line.",
171
+ "final": True
172
+ },
173
+ "/voicemail/i": {
174
+ "address": "sip:voicemail@company.com", # SIP address
175
+ "message": "Transferring to voicemail.",
176
+ "from_addr": "+15559876543", # Optional caller ID
177
+ "final": True
178
+ },
179
+ "/callback/i": {
180
+ "address": "+15551111111",
181
+ "message": "I'll connect you for a callback.",
182
+ "return_message": "The callback is complete. Anything else?",
183
+ "final": False # Temporary transfer
184
+ }
185
+ }
186
+ })
187
+ ```
188
+
189
+ ### Mixed Transfer Types
190
+
191
+ ```python
192
+ # Mix SWML endpoints and direct addresses in one skill
193
+ self.add_skill("swml_transfer", {
194
+ "tool_name": "transfer",
195
+ "transfers": {
196
+ # SWML agent transfers
197
+ "/sales|billing/i": {
198
+ "url": "https://api.company.com/sales-agent",
199
+ "message": "Transferring to our sales team.",
200
+ "final": False
201
+ },
202
+ "/support/i": {
203
+ "url": "https://api.company.com/support-agent",
204
+ "message": "Transferring to technical support.",
205
+ "final": False
206
+ },
207
+ # Direct phone transfers
208
+ "/operator/i": {
209
+ "address": "+18005551234",
210
+ "message": "Connecting you with an operator.",
211
+ "final": True
212
+ },
213
+ # SIP transfers
214
+ "/conference/i": {
215
+ "address": "sip:conference@company.com",
216
+ "message": "Joining you to the conference.",
217
+ "from_addr": "+15559876543",
218
+ "final": True
219
+ }
220
+ }
221
+ })
222
+ ```
223
+
224
+ ### Multiple Instances
225
+
226
+ You can load the skill multiple times for different transfer scenarios:
227
+
228
+ ```python
229
+ # General department transfers
230
+ self.add_skill("swml_transfer", {
231
+ "tool_name": "transfer_to_department",
232
+ "transfers": {
233
+ "/sales/i": {"url": "https://example.com/sales"},
234
+ "/support/i": {"url": "https://example.com/support"}
235
+ }
236
+ })
237
+
238
+ # Language-specific transfers
239
+ self.add_skill("swml_transfer", {
240
+ "tool_name": "transfer_to_language",
241
+ "parameter_name": "language",
242
+ "transfers": {
243
+ "/spanish|español/i": {
244
+ "url": "https://example.com/es-agent",
245
+ "message": "Le transferiré a un agente que habla español."
246
+ },
247
+ "/french|français/i": {
248
+ "url": "https://example.com/fr-agent",
249
+ "message": "Je vais vous transférer à un agent francophone."
250
+ }
251
+ }
252
+ })
253
+
254
+ # With required fields collection
255
+ self.add_skill("swml_transfer", {
256
+ "tool_name": "transfer_with_data",
257
+ "required_fields": {
258
+ "summary": "Summary of the conversation",
259
+ "customer_name": "Customer's full name",
260
+ "issue_type": "Type of issue (technical/billing/general)"
261
+ },
262
+ "transfers": {
263
+ "/sales/i": {
264
+ "url": "https://example.com/sales",
265
+ "message": "I'll transfer you to sales with your information."
266
+ },
267
+ "/support/i": {
268
+ "url": "https://example.com/support",
269
+ "message": "I'll transfer you to support with your information."
270
+ }
271
+ }
272
+ })
273
+ ```
274
+
275
+ ## Generated Functions
276
+
277
+ The skill generates a single SWAIG function with the configured name:
278
+
279
+ ### Function: `transfer_call` (or custom `tool_name`)
280
+
281
+ **Parameters:**
282
+ - `transfer_type` (or custom `parameter_name`): String parameter that will be matched against configured patterns
283
+ - Additional parameters defined in `required_fields` configuration
284
+
285
+ **Behavior:**
286
+ 1. Takes the input parameter value
287
+ 2. Matches it against configured regex patterns in order
288
+ 3. If `required_fields` are configured, saves all field values to `global_data.call_data`
289
+ 4. If a match is found, transfers to the corresponding URL with configured messages
290
+ 5. If no match is found, returns the default message (data still saved if provided)
291
+
292
+ ## Prompt Sections
293
+
294
+ The skill automatically adds prompt sections to help the AI understand available transfer destinations:
295
+
296
+ ### Transferring Section
297
+ Lists all configured transfer destinations extracted from the patterns. For example:
298
+ ```
299
+ ## Transferring
300
+ You can transfer calls using the transfer_to_department function with the following destinations:
301
+ - "sales" - transfers to https://example.com/sales
302
+ - "support" - transfers to https://example.com/support
303
+ ```
304
+
305
+ ### Transfer Instructions Section
306
+ Provides usage instructions for the transfer capability:
307
+ ```
308
+ ## Transfer Instructions
309
+ How to use the transfer capability:
310
+ - Use the transfer_to_department function when a transfer is needed
311
+ - Pass the destination type to the 'department' parameter
312
+ - The system will match patterns and handle the transfer automatically
313
+ - After transfer completes, you'll regain control of the conversation
314
+ ```
315
+
316
+ ## Example Conversations
317
+
318
+ ### Example 1: Department Transfer
319
+ ```
320
+ User: "I need help with my order"
321
+ Agent: "I can help you with that. Would you like to speak with sales or support?"
322
+ User: "I think I need support"
323
+ Agent: [Uses transfer_to_department("support")]
324
+ System: "Let me transfer you to our technical support team."
325
+ [Transfer occurs]
326
+ System: "I hope we were able to resolve your technical issue."
327
+ ```
328
+
329
+ ### Example 2: Multi-pattern Match
330
+ ```
331
+ User: "I want to talk to someone about pricing"
332
+ Agent: [Uses route_call("pricing")]
333
+ System: "I'll connect you with our sales team for pricing and billing questions."
334
+ [Transfer to sales agent]
335
+ ```
336
+
337
+ ### Example 3: No Match
338
+ ```
339
+ User: "Transfer me to the CEO"
340
+ Agent: [Uses transfer_to_department("CEO")]
341
+ System: "I can transfer you to sales, support, or a manager. Which would you prefer?"
342
+ ```
343
+
344
+ ### Example 4: Transfer with Required Fields
345
+ ```
346
+ User: "I need to speak with support about my PC that won't boot"
347
+ Agent: "I'll transfer you to support. Let me collect some information first."
348
+ Agent: [Uses transfer_with_data("support", "Customer experiencing boot failure with their PC. Initial troubleshooting not yet performed.", "John Smith", "technical")]
349
+ System: "I'll transfer you to support with your information."
350
+ [Transfer occurs with data saved to global_data.call_data]
351
+ Support Agent: [Can access the data via ${global_data.call_data.summary}, ${global_data.call_data.customer_name}, etc.]
352
+ ```
353
+
354
+ ## Troubleshooting
355
+
356
+ ### Transfer Not Working
357
+ - Verify the URL is accessible and returns valid SWML
358
+ - Check that the pattern syntax is correct (regex format)
359
+ - Enable debug logging to see pattern matching results
360
+
361
+ ### Pattern Not Matching
362
+ - Remember to use case-insensitive flag `/i` if needed
363
+ - Test patterns with online regex tools
364
+ - Use pipe `|` for multiple options: `/sales|billing/i`
365
+
366
+ ### Authentication Issues
367
+ - Ensure URLs include authentication if required
368
+ - Use `agent.get_full_url(include_auth=True)` for building URLs in dynamic configs
369
+
370
+ ## Best Practices
371
+
372
+ 1. **Use Clear Patterns**: Make patterns specific enough to avoid false matches
373
+ 2. **Provide Context**: Use descriptive messages so users know what's happening
374
+ 3. **Handle Failures**: Always include a sensible default message
375
+ 4. **Test Patterns**: Verify regex patterns match expected inputs
376
+ 5. **Group Related Transfers**: Use pipe `|` to group similar departments/options
377
+
378
+ ## Dynamic URL Configuration
379
+
380
+ For agents that need to build URLs dynamically (e.g., with proxy detection), implement the skill loading in a dynamic configuration callback:
381
+
382
+ ```python
383
+ def configure_transfers(self, query_params, body_params, headers, agent):
384
+ # Build URLs with proper proxy detection
385
+ base_url = self.get_full_url(include_auth=True).rstrip('/')
386
+
387
+ agent.add_skill("swml_transfer", {
388
+ "transfers": {
389
+ "/sales/i": {
390
+ "url": f"{base_url}/sales",
391
+ "message": "Transferring to sales..."
392
+ }
393
+ }
394
+ })
395
+ ```
@@ -0,0 +1,10 @@
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
+
10
+ """SWML Transfer Skill for SignalWire Agents"""