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,258 @@
1
+ # DataSphere Serverless Skill
2
+
3
+ The datasphere_serverless skill provides knowledge search capabilities using SignalWire DataSphere's RAG (Retrieval-Augmented Generation) stack with serverless execution via DataMap. This skill offers the same functionality as the standard datasphere skill but executes on SignalWire servers rather than your agent server.
4
+
5
+ ## Features
6
+
7
+ - **Serverless Execution**: Runs on SignalWire infrastructure via DataMap
8
+ - **SignalWire DataSphere Integration**: Vector-based knowledge search
9
+ - **Identical API**: Same parameters and functionality as the standard datasphere skill
10
+ - **Multi-language Support**: Synonym expansion and language-specific search
11
+ - **Tag-based Filtering**: Targeted searches using document tags
12
+ - **Custom No-results Messages**: Configurable response templates
13
+ - **Multiple Instance Support**: Search different knowledge bases with different configurations
14
+ - **No Webhook Infrastructure**: No need to expose HTTP endpoints
15
+
16
+ ## Requirements
17
+
18
+ - **Packages**: None (DataMap handles API calls serverlessly)
19
+ - **SignalWire Account**: DataSphere-enabled space with uploaded documents
20
+
21
+ ## Parameters
22
+
23
+ ### Required Parameters
24
+
25
+ - `space_name` (string): SignalWire space name
26
+ - `project_id` (string): SignalWire project ID
27
+ - `token` (string): SignalWire authentication token
28
+ - `document_id` (string): DataSphere document ID to search
29
+
30
+ ### Optional Parameters
31
+
32
+ - `count` (integer, default: 1): Number of search results to return
33
+ - `distance` (float, default: 3.0): Distance threshold for search matching (lower = more similar)
34
+ - `tags` (list): List of tags to filter search results
35
+ - `language` (string): Language code to limit search (e.g., "en", "es")
36
+ - `pos_to_expand` (list): Parts of speech for synonym expansion (e.g., ["NOUN", "VERB"])
37
+ - `max_synonyms` (integer): Maximum number of synonyms to use for each word
38
+ - `tool_name` (string, default: "search_knowledge"): Custom name for the search tool (enables multiple instances)
39
+ - `no_results_message` (string): Custom message when no results are found
40
+ - Default: "I couldn't find any relevant information for '{query}' in the knowledge base. Try rephrasing your question or asking about a different topic."
41
+ - Use `{query}` as placeholder for the search query
42
+
43
+ ### Advanced Parameters
44
+
45
+ - `swaig_fields` (dict): Additional SWAIG function configuration
46
+ - `secure` (boolean): Override security settings
47
+ - `fillers` (dict): Language-specific filler phrases during search
48
+ - Any other SWAIG function parameters
49
+
50
+ ## Tools Created
51
+
52
+ - **Default**: `search_knowledge` - Search the knowledge base for information
53
+ - **Custom**: Uses the `tool_name` parameter value
54
+
55
+ ## Usage Examples
56
+
57
+ ### Basic Usage
58
+
59
+ ```python
60
+ # Minimal configuration - same as standard datasphere skill
61
+ agent.add_skill("datasphere_serverless", {
62
+ "space_name": "my-space",
63
+ "project_id": "my-project-id",
64
+ "token": "my-token",
65
+ "document_id": "my-document-id"
66
+ })
67
+ ```
68
+
69
+ ### Advanced Configuration
70
+
71
+ ```python
72
+ # Comprehensive search with filtering - identical to standard skill
73
+ agent.add_skill("datasphere_serverless", {
74
+ "space_name": "my-space",
75
+ "project_id": "my-project-id",
76
+ "token": "my-token",
77
+ "document_id": "my-document-id",
78
+ "count": 3,
79
+ "distance": 5.0,
80
+ "tags": ["FAQ", "Support"],
81
+ "language": "en",
82
+ "pos_to_expand": ["NOUN", "VERB"],
83
+ "max_synonyms": 3,
84
+ "no_results_message": "I couldn't find information about '{query}' in our support documentation."
85
+ })
86
+ ```
87
+
88
+ ### Multiple Instances
89
+
90
+ ```python
91
+ # Product documentation search
92
+ agent.add_skill("datasphere_serverless", {
93
+ "space_name": "my-space",
94
+ "project_id": "my-project-id",
95
+ "token": "my-token",
96
+ "document_id": "product-docs-id",
97
+ "tool_name": "search_product_docs",
98
+ "tags": ["Products", "Features"],
99
+ "count": 2
100
+ })
101
+
102
+ # Support knowledge base search
103
+ agent.add_skill("datasphere_serverless", {
104
+ "space_name": "my-space",
105
+ "project_id": "my-project-id",
106
+ "token": "my-token",
107
+ "document_id": "support-kb-id",
108
+ "tool_name": "search_support",
109
+ "tags": ["Support", "Troubleshooting"],
110
+ "count": 3,
111
+ "distance": 4.0
112
+ })
113
+ ```
114
+
115
+ ## DataMap Implementation Details
116
+
117
+ This skill demonstrates advanced DataMap usage patterns:
118
+
119
+ ### 1. **Serverless API Integration**
120
+ - API calls execute on SignalWire servers, not your agent server
121
+ - No webhook endpoints required
122
+ - Built-in authentication and error handling
123
+
124
+ ### 2. **Dynamic Request Building**
125
+ ```python
126
+ webhook_body = {
127
+ "document_id": self.document_id,
128
+ "query_string": "${args.query}", # Dynamic from user input
129
+ "distance": self.distance, # Static from configuration
130
+ "count": self.count # Static from configuration
131
+ }
132
+
133
+ # Optional parameters added conditionally
134
+ if self.tags is not None:
135
+ webhook_body["tags"] = self.tags
136
+ ```
137
+
138
+ ### 3. **Response Processing with Foreach**
139
+ ```python
140
+ .foreach({
141
+ "input_key": "results", # API response key containing array
142
+ "output_key": "formatted_results", # Name for built string
143
+ "max": self.count, # Limit processing
144
+ "append": "=== RESULT ${this.index} ===\n${this.content}\n========\n\n"
145
+ })
146
+ ```
147
+
148
+ The `foreach` mechanism:
149
+ - Iterates over the `results` array from DataSphere API response
150
+ - For each result, expands `${this.content}` with the result's content field
151
+ - Builds a concatenated string stored as `formatted_results`
152
+ - Limits processing to `max` items
153
+
154
+ ### 4. **Variable Expansion in Output**
155
+ ```python
156
+ .output(SwaigFunctionResult('I found ${results.length} result(s) for "${args.query}":\n\n${formatted_results}'))
157
+ ```
158
+
159
+ References:
160
+ - `${results.length}`: Number of results from API
161
+ - `${args.query}`: User's search query
162
+ - `${formatted_results}`: String built by foreach
163
+
164
+ ### 5. **Error Handling**
165
+ ```python
166
+ .error_keys(['error', 'message'])
167
+ .fallback_output(SwaigFunctionResult(self.no_results_message.replace('{query}', '${args.query}')))
168
+ ```
169
+
170
+ ## Comparison: Standard vs Serverless
171
+
172
+ | Feature | Standard DataSphere | DataSphere Serverless |
173
+ |---------|-------------------|---------------------|
174
+ | **Execution** | Agent server | SignalWire servers |
175
+ | **Parameters** | Identical | Identical |
176
+ | **Functionality** | Full Python logic | DataMap templates |
177
+ | **Performance** | Agent server load | No agent server load |
178
+ | **Deployment** | Webhook infrastructure | No infrastructure needed |
179
+ | **Response Formatting** | Custom Python code | DataMap foreach/templates |
180
+ | **Error Handling** | Granular Python exceptions | DataMap error keys |
181
+ | **Use Case** | Complex custom logic | Standard API integration |
182
+
183
+ ## When to Use Serverless vs Standard
184
+
185
+ ### **Use DataSphere Serverless When:**
186
+ - You want simple deployment without webhook infrastructure
187
+ - Performance on agent server is a concern
188
+ - Standard response formatting is sufficient
189
+ - You prefer serverless execution model
190
+
191
+ ### **Use Standard DataSphere When:**
192
+ - You need complex custom response formatting
193
+ - You want granular error handling with different messages per error type
194
+ - You need runtime decision-making logic
195
+ - You want full control over the search process
196
+
197
+ ## Benefits of DataMap Implementation
198
+
199
+ 1. **Simplified Deployment**: No HTTP endpoints to expose or manage
200
+ 2. **Better Performance**: Executes on SignalWire infrastructure
201
+ 3. **Reduced Complexity**: Declarative configuration vs imperative code
202
+ 4. **Automatic Scaling**: SignalWire handles execution scaling
203
+ 5. **Built-in Reliability**: Server-side execution with built-in retry logic
204
+
205
+ ## How It Works
206
+
207
+ 1. **Configuration**: Skill parameters are validated and stored during setup
208
+ 2. **Tool Registration**: DataMap configuration is built with static values from setup
209
+ 3. **Execution**: When called, DataMap executes on SignalWire servers:
210
+ - Makes POST request to DataSphere API with user's query
211
+ - Processes response array using foreach mechanism
212
+ - Formats results using template expansion
213
+ - Returns formatted response to agent
214
+ 4. **Response**: Agent receives formatted results without any local processing
215
+
216
+ ## Multiple Instance Support
217
+
218
+ Like the standard datasphere skill, this supports multiple instances:
219
+
220
+ - Each instance creates a tool with a unique name (`tool_name` parameter)
221
+ - Different configurations per instance (different documents, tags, etc.)
222
+ - Instance tracking via `get_instance_key()` method
223
+ - Same agent can search multiple knowledge bases
224
+
225
+ ## Error Handling
226
+
227
+ - **API Errors**: Handled by `error_keys` configuration
228
+ - **No Results**: Uses `fallback_output` with custom message
229
+ - **Invalid Parameters**: Validated during skill setup
230
+ - **Timeout/Network**: Handled by SignalWire infrastructure
231
+
232
+ ## Troubleshooting
233
+
234
+ ### Common Issues
235
+
236
+ 1. **"Missing required parameters"**
237
+ - Ensure all required parameters are provided
238
+ - Check parameter names match exactly
239
+
240
+ 2. **"No results found"**
241
+ - Verify document_id exists and is accessible
242
+ - Check distance threshold isn't too restrictive
243
+ - Ensure tags match document tags if specified
244
+
245
+ 3. **"Authentication failed"**
246
+ - Verify project_id and token are correct
247
+ - Ensure token has DataSphere permissions
248
+
249
+ ### Debugging
250
+
251
+ Enable debug logging to see DataMap execution:
252
+
253
+ ```python
254
+ import logging
255
+ logging.basicConfig(level=logging.DEBUG)
256
+ ```
257
+
258
+ DataMap execution details are logged by the SignalWire server infrastructure.
@@ -1 +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
+
1
10
  """DataSphere Serverless Skill for SignalWire Agents using DataMap"""
@@ -26,6 +26,88 @@ class DataSphereServerlessSkill(SkillBase):
26
26
  # Enable multiple instances support
27
27
  SUPPORTS_MULTIPLE_INSTANCES = True
28
28
 
29
+ @classmethod
30
+ def get_parameter_schema(cls) -> Dict[str, Dict[str, Any]]:
31
+ """Get parameter schema for DataSphere Serverless skill"""
32
+ schema = super().get_parameter_schema()
33
+ schema.update({
34
+ "space_name": {
35
+ "type": "string",
36
+ "description": "SignalWire space name (e.g., 'mycompany' from mycompany.signalwire.com)",
37
+ "required": True
38
+ },
39
+ "project_id": {
40
+ "type": "string",
41
+ "description": "SignalWire project ID",
42
+ "required": True,
43
+ "env_var": "SIGNALWIRE_PROJECT_ID"
44
+ },
45
+ "token": {
46
+ "type": "string",
47
+ "description": "SignalWire API token",
48
+ "required": True,
49
+ "hidden": True,
50
+ "env_var": "SIGNALWIRE_TOKEN"
51
+ },
52
+ "document_id": {
53
+ "type": "string",
54
+ "description": "DataSphere document ID to search within",
55
+ "required": True
56
+ },
57
+ "count": {
58
+ "type": "integer",
59
+ "description": "Number of search results to return",
60
+ "default": 1,
61
+ "required": False,
62
+ "minimum": 1,
63
+ "maximum": 10
64
+ },
65
+ "distance": {
66
+ "type": "number",
67
+ "description": "Maximum distance threshold for results (lower is more relevant)",
68
+ "default": 3.0,
69
+ "required": False,
70
+ "minimum": 0.0,
71
+ "maximum": 10.0
72
+ },
73
+ "tags": {
74
+ "type": "array",
75
+ "description": "Tags to filter search results",
76
+ "required": False,
77
+ "items": {
78
+ "type": "string"
79
+ }
80
+ },
81
+ "language": {
82
+ "type": "string",
83
+ "description": "Language code for query expansion (e.g., 'en', 'es')",
84
+ "required": False
85
+ },
86
+ "pos_to_expand": {
87
+ "type": "array",
88
+ "description": "Parts of speech to expand with synonyms",
89
+ "required": False,
90
+ "items": {
91
+ "type": "string",
92
+ "enum": ["NOUN", "VERB", "ADJ", "ADV"]
93
+ }
94
+ },
95
+ "max_synonyms": {
96
+ "type": "integer",
97
+ "description": "Maximum number of synonyms to use for query expansion",
98
+ "required": False,
99
+ "minimum": 1,
100
+ "maximum": 10
101
+ },
102
+ "no_results_message": {
103
+ "type": "string",
104
+ "description": "Message to return when no results are found",
105
+ "default": "I couldn't find any relevant information for '{query}' in the knowledge base. Try rephrasing your question or asking about a different topic.",
106
+ "required": False
107
+ }
108
+ })
109
+ return schema
110
+
29
111
  def get_instance_key(self) -> str:
30
112
  """
31
113
  Get the key used to track this skill instance
@@ -83,7 +165,6 @@ class DataSphereServerlessSkill(SkillBase):
83
165
  webhook_params = {
84
166
  "document_id": self.document_id,
85
167
  "query_string": "${args.query}", # Only this is dynamic from user input
86
- "distance": self.distance,
87
168
  "count": self.count
88
169
  }
89
170
 
@@ -0,0 +1,132 @@
1
+ # DateTime Skill
2
+
3
+ The datetime skill provides current date and time information with timezone support. It allows agents to tell users the current time and date in any timezone around the world.
4
+
5
+ ## Features
6
+
7
+ - Current time retrieval with timezone support
8
+ - Current date retrieval with timezone support
9
+ - Automatic timezone conversion using pytz
10
+ - Human-readable time and date formatting
11
+ - UTC default with custom timezone options
12
+
13
+ ## Requirements
14
+
15
+ - **Packages**: `pytz`
16
+ - **No external APIs required**
17
+
18
+ ## Parameters
19
+
20
+ ### Optional Parameters
21
+
22
+ - `swaig_fields` (dict): Additional SWAIG function configuration
23
+ - `secure` (boolean): Override security settings for the time/date functions
24
+ - `fillers` (dict): Language-specific filler phrases while retrieving time/date
25
+ - Any other SWAIG function parameters
26
+
27
+ **Note**: This skill does not require any configuration parameters beyond the optional swaig_fields. It works out-of-the-box with no setup.
28
+
29
+ ## Tools Created
30
+
31
+ - `get_current_time` - Get the current time, optionally in a specific timezone
32
+ - `get_current_date` - Get the current date, optionally in a specific timezone
33
+
34
+ ## Usage Examples
35
+
36
+ ### Basic Usage
37
+
38
+ ```python
39
+ # No configuration needed - works immediately
40
+ agent.add_skill("datetime")
41
+ ```
42
+
43
+ ### With Custom Fillers
44
+
45
+ ```python
46
+ agent.add_skill("datetime", {
47
+ "swaig_fields": {
48
+ "fillers": {
49
+ "en-US": [
50
+ "Let me check the time...",
51
+ "Looking up the current date...",
52
+ "Getting the time for you..."
53
+ ],
54
+ "es-ES": [
55
+ "Déjame verificar la hora...",
56
+ "Consultando la fecha actual..."
57
+ ]
58
+ }
59
+ }
60
+ })
61
+ ```
62
+
63
+ ### Disabling Security (if needed)
64
+
65
+ ```python
66
+ agent.add_skill("datetime", {
67
+ "swaig_fields": {
68
+ "secure": False # Allow unauthenticated time/date requests
69
+ }
70
+ })
71
+ ```
72
+
73
+ ## How It Works
74
+
75
+ ### Time Function
76
+ - **Input**: Optional timezone parameter (e.g., "America/New_York", "Europe/London")
77
+ - **Default**: UTC timezone if no timezone specified
78
+ - **Output**: Time in 12-hour format with AM/PM and timezone abbreviation
79
+ - **Example**: "The current time is 02:30:45 PM EST"
80
+
81
+ ### Date Function
82
+ - **Input**: Optional timezone parameter for date calculation
83
+ - **Default**: UTC timezone if no timezone specified
84
+ - **Output**: Full date in readable format
85
+ - **Example**: "Today's date is Friday, December 15, 2023"
86
+
87
+ ### Timezone Support
88
+ - Uses the `pytz` library for accurate timezone handling
89
+ - Supports all standard timezone names (e.g., "America/New_York", "Asia/Tokyo")
90
+ - Handles daylight saving time automatically
91
+ - Falls back to UTC for invalid timezone names
92
+
93
+ ## Function Parameters
94
+
95
+ Both tools accept the same optional parameter:
96
+
97
+ - `timezone` (string, optional): Timezone name for the time/date
98
+ - Examples: "America/New_York", "Europe/London", "Asia/Tokyo", "UTC"
99
+ - Default: "UTC" if not specified
100
+ - Invalid timezones will cause an error message to be returned
101
+
102
+ ## Error Handling
103
+
104
+ - **Invalid Timezone**: Returns error message with the invalid timezone name
105
+ - **System Issues**: Returns friendly error message for any datetime calculation problems
106
+ - **Graceful Fallback**: Continues to work even if timezone data is corrupted
107
+
108
+ ## Common Timezone Examples
109
+
110
+ - **US Timezones**: "America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles"
111
+ - **European Timezones**: "Europe/London", "Europe/Paris", "Europe/Berlin", "Europe/Rome"
112
+ - **Asian Timezones**: "Asia/Tokyo", "Asia/Shanghai", "Asia/Kolkata", "Asia/Dubai"
113
+ - **Other Regions**: "Australia/Sydney", "Africa/Cairo", "America/Sao_Paulo"
114
+
115
+ ## Best Practices
116
+
117
+ 1. **Default Behavior**: The skill works immediately without configuration
118
+ 2. **User Queries**: Handle questions like "What time is it?", "What's today's date?", "What time is it in Tokyo?"
119
+ 3. **Timezone Validation**: The skill gracefully handles invalid timezone names
120
+ 4. **Localization**: Use fillers in different languages for multilingual agents
121
+ 5. **Performance**: Very fast since no external API calls are required
122
+
123
+ ## Agent Integration
124
+
125
+ When added to an agent, this skill automatically:
126
+
127
+ - Adds speech recognition hints for time/date related words
128
+ - Provides prompt guidance about time/date capabilities
129
+ - Enables the agent to respond to time and date questions
130
+ - Works with any timezone the user requests
131
+
132
+ The skill is designed to be maintenance-free and always available, making it ideal for customer service and general-purpose agents that need to provide time and date information.
@@ -1 +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
+
1
10
  """DateTime Skill for SignalWire Agents"""
@@ -30,7 +30,7 @@ class DateTimeSkill(SkillBase):
30
30
  def register_tools(self) -> None:
31
31
  """Register datetime tools with the agent"""
32
32
 
33
- self.agent.define_tool(
33
+ self.define_tool(
34
34
  name="get_current_time",
35
35
  description="Get the current time, optionally in a specific timezone",
36
36
  parameters={
@@ -39,11 +39,10 @@ class DateTimeSkill(SkillBase):
39
39
  "description": "Timezone name (e.g., 'America/New_York', 'Europe/London'). Defaults to UTC."
40
40
  }
41
41
  },
42
- handler=self._get_time_handler,
43
- **self.swaig_fields
42
+ handler=self._get_time_handler
44
43
  )
45
44
 
46
- self.agent.define_tool(
45
+ self.define_tool(
47
46
  name="get_current_date",
48
47
  description="Get the current date",
49
48
  parameters={
@@ -52,8 +51,7 @@ class DateTimeSkill(SkillBase):
52
51
  "description": "Timezone name for the date. Defaults to UTC."
53
52
  }
54
53
  },
55
- handler=self._get_date_handler,
56
- **self.swaig_fields
54
+ handler=self._get_date_handler
57
55
  )
58
56
 
59
57
  def _get_time_handler(self, args, raw_data):
@@ -110,4 +108,19 @@ class DateTimeSkill(SkillBase):
110
108
  "Both tools support different timezones"
111
109
  ]
112
110
  }
113
- ]
111
+ ]
112
+
113
+ @classmethod
114
+ def get_parameter_schema(cls) -> Dict[str, Dict[str, Any]]:
115
+ """
116
+ Get the parameter schema for the datetime skill
117
+
118
+ The datetime skill has no custom parameters - it inherits only
119
+ the base parameters from SkillBase.
120
+ """
121
+ # Get base schema from parent
122
+ schema = super().get_parameter_schema()
123
+
124
+ # No additional parameters for datetime skill
125
+
126
+ return schema