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,149 @@
1
+ # Joke Skill
2
+
3
+ Tell jokes using the API Ninjas joke API with DataMap integration.
4
+
5
+ ## Description
6
+
7
+ The Joke skill provides joke-telling capabilities to your SignalWire AI agents using the API Ninjas joke API. This skill demonstrates how to use DataMap for external API integration without requiring custom webhook endpoints.
8
+
9
+ ## Features
10
+
11
+ - **Random Jokes**: Get random jokes from API Ninjas
12
+ - **Dad Jokes**: Specifically request dad jokes
13
+ - **DataMap Integration**: Uses DataMap for serverless API execution
14
+ - **Configurable Tool Name**: Support for custom tool names
15
+ - **Required Parameter Validation**: Ensures joke type is specified
16
+
17
+ ## Requirements
18
+
19
+ - API Ninjas API key
20
+ - No additional Python packages required (DataMap handles API calls)
21
+
22
+ ## Configuration
23
+
24
+ ### Required Parameters
25
+
26
+ - `api_key`: Your API Ninjas API key
27
+
28
+ ### Optional Parameters
29
+
30
+ - `tool_name`: Custom name for the joke function (default: "get_joke")
31
+
32
+ ## Usage
33
+
34
+ ### Basic Usage
35
+
36
+ ```python
37
+ from signalwire_agents import AgentBase
38
+
39
+ class MyAgent(AgentBase):
40
+ def __init__(self):
41
+ super().__init__(name="Joke Agent", route="/jokes")
42
+
43
+ # Add joke skill
44
+ self.add_skill("joke", {
45
+ "api_key": "your-api-ninjas-api-key"
46
+ })
47
+
48
+ agent = MyAgent()
49
+ agent.serve()
50
+ ```
51
+
52
+ ### Advanced Usage
53
+
54
+ ```python
55
+ # Custom tool name
56
+ self.add_skill("joke", {
57
+ "api_key": "your-api-ninjas-api-key",
58
+ "tool_name": "tell_joke"
59
+ })
60
+ ```
61
+
62
+ ## Function Details
63
+
64
+ ### `get_joke(type: str)`
65
+
66
+ **Parameters:**
67
+ - `type` (required): Type of joke to get
68
+ - `"jokes"` - Regular jokes
69
+ - `"dadjokes"` - Dad jokes
70
+
71
+ **Returns:** A joke from the API Ninjas joke database
72
+
73
+ **Example Usage:**
74
+ - "Tell me a joke" (AI will choose the type)
75
+ - "Tell me a dad joke" (AI will use type="dadjokes")
76
+ - "Get me a regular joke" (AI will use type="jokes")
77
+
78
+ ## API Integration
79
+
80
+ This skill integrates with the API Ninjas Jokes API:
81
+ - **Endpoint**: `https://api.api-ninjas.com/v1/{type}`
82
+ - **Method**: GET
83
+ - **Authentication**: X-Api-Key header
84
+ - **Response**: JSON array with joke objects
85
+
86
+ ## Getting an API Key
87
+
88
+ 1. Visit [API Ninjas](https://api.api-ninjas.com/)
89
+ 2. Sign up for a free account
90
+ 3. Get your API key from the dashboard
91
+ 4. Use the key in your skill configuration
92
+
93
+ ## Error Handling
94
+
95
+ - Missing API key: Skill setup will fail with clear error message
96
+ - Invalid joke type: Parameter validation ensures only valid types are accepted
97
+ - API errors: Handled gracefully with user-friendly error messages
98
+
99
+ ## DataMap Implementation
100
+
101
+ This skill demonstrates DataMap usage with:
102
+
103
+ - **External API**: Calls API Ninjas joke endpoints
104
+ - **Dynamic URLs**: Uses `${args.type}` for different joke types
105
+ - **Header Authentication**: Includes API key in request headers
106
+ - **Response Processing**: Extracts joke from API response array
107
+ - **Error Handling**: Handles API errors gracefully
108
+
109
+ ## Troubleshooting
110
+
111
+ ### Common Issues
112
+
113
+ 1. **"Missing required parameters: ['api_key']"**
114
+ - Ensure you provide a valid API Ninjas API key
115
+
116
+ 2. **"No jokes returned"**
117
+ - Check your API key is valid
118
+ - Verify API Ninjas service is accessible
119
+ - Check API quota/rate limits
120
+
121
+ 3. **"Tool not found"**
122
+ - Ensure skill loaded successfully
123
+ - Check for any setup errors in logs
124
+
125
+ ### Debugging
126
+
127
+ Enable debug logging to see API requests:
128
+
129
+ ```python
130
+ import logging
131
+ logging.basicConfig(level=logging.DEBUG)
132
+ ```
133
+
134
+ ## API Reference
135
+
136
+ ### API Ninjas Endpoints
137
+
138
+ - `GET /v1/jokes` - Random jokes
139
+ - `GET /v1/dadjokes` - Dad jokes
140
+
141
+ ### Response Format
142
+
143
+ ```json
144
+ [
145
+ {
146
+ "joke": "Why don't scientists trust atoms? Because they make up everything!"
147
+ }
148
+ ]
149
+ ```
@@ -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
  """Joke Skill for SignalWire Agents using DataMap"""
@@ -23,6 +23,27 @@ class JokeSkill(SkillBase):
23
23
  REQUIRED_PACKAGES = [] # DataMap doesn't require local packages
24
24
  REQUIRED_ENV_VARS = [] # API key comes from parameters
25
25
 
26
+ @classmethod
27
+ def get_parameter_schema(cls) -> Dict[str, Dict[str, Any]]:
28
+ """Get parameter schema for joke skill"""
29
+ schema = super().get_parameter_schema()
30
+ schema.update({
31
+ "api_key": {
32
+ "type": "string",
33
+ "description": "API Ninjas API key for joke service",
34
+ "required": True,
35
+ "hidden": True,
36
+ "env_var": "API_NINJAS_KEY"
37
+ },
38
+ "tool_name": {
39
+ "type": "string",
40
+ "description": "Custom name for the joke tool",
41
+ "default": "get_joke",
42
+ "required": False
43
+ }
44
+ })
45
+ return schema
46
+
26
47
  def setup(self) -> bool:
27
48
  """Setup the joke skill"""
28
49
  # Validate required parameters
@@ -0,0 +1,161 @@
1
+ # Math Skill
2
+
3
+ The math skill provides safe mathematical calculation capabilities for agents. It allows users to perform basic arithmetic operations and complex mathematical expressions with security protections against code injection.
4
+
5
+ ## Features
6
+
7
+ - Safe mathematical expression evaluation
8
+ - Support for basic arithmetic operations
9
+ - Parentheses support for complex expressions
10
+ - Division by zero protection
11
+ - Security filtering to prevent code injection
12
+ - No external dependencies required
13
+
14
+ ## Requirements
15
+
16
+ - **Packages**: None (uses built-in Python functionality)
17
+ - **No external APIs required**
18
+
19
+ ## Parameters
20
+
21
+ ### Optional Parameters
22
+
23
+ - `swaig_fields` (dict): Additional SWAIG function configuration
24
+ - `secure` (boolean): Override security settings for the calculation function
25
+ - `fillers` (dict): Language-specific filler phrases while calculating
26
+ - Any other SWAIG function parameters
27
+
28
+ **Note**: This skill does not require any configuration parameters beyond the optional swaig_fields. It works out-of-the-box with no setup.
29
+
30
+ ## Tools Created
31
+
32
+ - `calculate` - Perform a mathematical calculation with basic operations
33
+
34
+ ## Usage Examples
35
+
36
+ ### Basic Usage
37
+
38
+ ```python
39
+ # No configuration needed - works immediately
40
+ agent.add_skill("math")
41
+ ```
42
+
43
+ ### With Custom Fillers
44
+
45
+ ```python
46
+ agent.add_skill("math", {
47
+ "swaig_fields": {
48
+ "fillers": {
49
+ "en-US": [
50
+ "Let me calculate that for you...",
51
+ "Crunching the numbers...",
52
+ "Computing the result...",
53
+ "Working out the math..."
54
+ ],
55
+ "es-ES": [
56
+ "Déjame calcular eso...",
57
+ "Procesando los números...",
58
+ "Calculando el resultado..."
59
+ ]
60
+ }
61
+ }
62
+ })
63
+ ```
64
+
65
+ ### Disabling Security (if needed)
66
+
67
+ ```python
68
+ agent.add_skill("math", {
69
+ "swaig_fields": {
70
+ "secure": False # Allow unauthenticated calculation requests
71
+ }
72
+ })
73
+ ```
74
+
75
+ ## How It Works
76
+
77
+ ### Calculation Function
78
+ - **Input**: Mathematical expression as a string
79
+ - **Processing**: Validates expression for safety, then evaluates it
80
+ - **Output**: Shows the original expression and the calculated result
81
+ - **Example**: "2 + 3 * 4 = 14"
82
+
83
+ ### Supported Operations
84
+
85
+ - **Addition**: `+` (e.g., "5 + 3")
86
+ - **Subtraction**: `-` (e.g., "10 - 7")
87
+ - **Multiplication**: `*` (e.g., "6 * 8")
88
+ - **Division**: `/` (e.g., "15 / 3")
89
+ - **Modulo**: `%` (e.g., "17 % 5")
90
+ - **Exponentiation**: `**` (e.g., "2 ** 3")
91
+ - **Parentheses**: `()` for grouping (e.g., "(2 + 3) * 4")
92
+
93
+ ### Expression Examples
94
+
95
+ - Simple: `"2 + 3"` → "2 + 3 = 5"
96
+ - Complex: `"(10 + 5) * 2 / 3"` → "(10 + 5) * 2 / 3 = 10.0"
97
+ - With decimals: `"3.14 * 2"` → "3.14 * 2 = 6.28"
98
+ - Powers: `"2 ** 8"` → "2 ** 8 = 256"
99
+ - Modulo: `"17 % 5"` → "17 % 5 = 2"
100
+
101
+ ## Function Parameters
102
+
103
+ The calculate tool accepts one parameter:
104
+
105
+ - `expression` (string, required): Mathematical expression to evaluate
106
+ - Must contain only numbers, operators, and parentheses
107
+ - Operators allowed: `+`, `-`, `*`, `/`, `%`, `**`, `(`, `)`
108
+ - Decimal numbers are supported
109
+ - Spaces are allowed and ignored
110
+
111
+ ## Security Features
112
+
113
+ ### Input Validation
114
+ - Only allows safe mathematical characters: numbers, operators, parentheses, spaces, decimal points
115
+ - Blocks any potentially dangerous code or function calls
116
+ - Uses regex pattern matching for character validation
117
+
118
+ ### Safe Evaluation
119
+ - Uses Python's `eval()` with restricted builtins (empty `__builtins__`)
120
+ - No access to system functions or imports
121
+ - Cannot execute arbitrary code
122
+
123
+ ### Error Handling
124
+ - **Division by Zero**: Returns friendly error message
125
+ - **Invalid Syntax**: Returns error for malformed expressions
126
+ - **Illegal Characters**: Rejects expressions with non-math characters
127
+ - **Empty Input**: Prompts user to provide an expression
128
+
129
+ ## Error Examples
130
+
131
+ - **Division by zero**: "Error: Division by zero is not allowed."
132
+ - **Invalid characters**: "Invalid expression. Only numbers and basic math operators are allowed."
133
+ - **Syntax error**: "Error calculating '2 + + 3': Invalid expression"
134
+ - **Empty input**: "Please provide a mathematical expression to calculate."
135
+
136
+ ## Common Use Cases
137
+
138
+ 1. **Basic Arithmetic**: "What's 15 + 27?"
139
+ 2. **Percentage Calculations**: "What's 15% of 200?" → "200 * 0.15"
140
+ 3. **Complex Expressions**: "Calculate (100 + 50) * 0.08"
141
+ 4. **Powers and Roots**: "What's 2 to the power of 10?"
142
+ 5. **Financial Calculations**: "If I have $500 and spend $125, how much is left?"
143
+
144
+ ## Best Practices
145
+
146
+ 1. **Default Behavior**: The skill works immediately without configuration
147
+ 2. **User Education**: Help users understand they can use parentheses for complex calculations
148
+ 3. **Expression Formatting**: The skill is forgiving with spaces and formatting
149
+ 4. **Error Recovery**: Provide helpful guidance when users make syntax errors
150
+ 5. **Security**: The skill is designed to be safe even with malicious input
151
+
152
+ ## Agent Integration
153
+
154
+ When added to an agent, this skill automatically:
155
+
156
+ - Adds speech recognition hints for math-related words
157
+ - Provides prompt guidance about calculation capabilities
158
+ - Enables the agent to respond to mathematical questions
159
+ - Shows both the original expression and result for transparency
160
+
161
+ The skill is designed to be completely self-contained and secure, making it safe for any agent to use for mathematical calculations.
@@ -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
  """Math Skill for SignalWire Agents"""
@@ -29,7 +29,7 @@ class MathSkill(SkillBase):
29
29
  def register_tools(self) -> None:
30
30
  """Register math tools with the agent"""
31
31
 
32
- self.agent.define_tool(
32
+ self.define_tool(
33
33
  name="calculate",
34
34
  description="Perform a mathematical calculation with basic operations (+, -, *, /, %, **)",
35
35
  parameters={
@@ -38,8 +38,7 @@ class MathSkill(SkillBase):
38
38
  "description": "Mathematical expression to evaluate (e.g., '2 + 3 * 4', '(10 + 5) / 3')"
39
39
  }
40
40
  },
41
- handler=self._calculate_handler,
42
- **self.swaig_fields
41
+ handler=self._calculate_handler
43
42
  )
44
43
 
45
44
  def _calculate_handler(self, args, raw_data):
@@ -88,4 +87,19 @@ class MathSkill(SkillBase):
88
87
  "Can handle parentheses for complex expressions"
89
88
  ]
90
89
  }
91
- ]
90
+ ]
91
+
92
+ @classmethod
93
+ def get_parameter_schema(cls) -> Dict[str, Dict[str, Any]]:
94
+ """
95
+ Get the parameter schema for the math skill
96
+
97
+ The math skill has no custom parameters - it inherits only
98
+ the base parameters from SkillBase.
99
+ """
100
+ # Get base schema from parent
101
+ schema = super().get_parameter_schema()
102
+
103
+ # No additional parameters for math skill
104
+
105
+ return schema
@@ -0,0 +1,230 @@
1
+ # MCP Gateway Skill
2
+
3
+ Bridge MCP (Model Context Protocol) servers with SignalWire SWAIG functions, allowing agents to seamlessly interact with MCP-based tools.
4
+
5
+ ## Description
6
+
7
+ The MCP Gateway skill connects SignalWire agents to MCP servers through a centralized gateway service. It dynamically discovers and registers MCP tools as SWAIG functions, maintaining session state throughout each call.
8
+
9
+ ## Features
10
+
11
+ - Dynamic tool discovery from MCP servers
12
+ - Session management tied to SignalWire call IDs
13
+ - Automatic cleanup on call hangup
14
+ - Support for multiple MCP services
15
+ - Selective tool loading
16
+ - HTTPS support with SSL verification
17
+ - Retry logic for resilient connections
18
+
19
+ ## Requirements
20
+
21
+ - Running MCP Gateway service
22
+ - Network access to gateway
23
+ - Gateway credentials (username/password)
24
+
25
+ ## Configuration
26
+
27
+ ### Required Parameters
28
+
29
+ Either Basic Auth credentials OR Bearer token:
30
+ - `gateway_url`: URL of the MCP gateway service (default: "http://localhost:8100")
31
+ - `auth_user` + `auth_password`: Basic auth credentials
32
+ - OR `auth_token`: Bearer token for authentication
33
+
34
+ ### Optional Parameters
35
+
36
+ - `services`: Array of services to load (default: all available)
37
+ - `name`: Service name
38
+ - `tools`: Array of tool names or "*" for all (default: all)
39
+ - `session_timeout`: Session timeout in seconds (default: 300)
40
+ - `tool_prefix`: Prefix for SWAIG function names (default: "mcp_")
41
+ - `retry_attempts`: Number of retry attempts (default: 3)
42
+ - `request_timeout`: HTTP request timeout in seconds (default: 30)
43
+ - `verify_ssl`: Verify SSL certificates (default: true)
44
+
45
+ ## Usage
46
+
47
+ ### Basic Usage (All Services)
48
+
49
+ ```python
50
+ from signalwire_agents import AgentBase
51
+
52
+ class MyAgent(AgentBase):
53
+ def __init__(self):
54
+ super().__init__(name="My Agent")
55
+
56
+ # Load all available MCP services
57
+ self.add_skill("mcp_gateway", {
58
+ "gateway_url": "http://localhost:8080",
59
+ "auth_user": "admin",
60
+ "auth_password": "changeme"
61
+ })
62
+
63
+ agent = MyAgent()
64
+ agent.run()
65
+ ```
66
+
67
+ ### Selective Service Loading
68
+
69
+ ```python
70
+ # Load specific services with specific tools
71
+ self.add_skill("mcp_gateway", {
72
+ "gateway_url": "https://gateway.example.com",
73
+ "auth_user": "admin",
74
+ "auth_password": "secret",
75
+ "services": [
76
+ {
77
+ "name": "todo",
78
+ "tools": ["add_todo", "list_todos"] # Only these tools
79
+ },
80
+ {
81
+ "name": "calculator",
82
+ "tools": "*" # All calculator tools
83
+ }
84
+ ],
85
+ "session_timeout": 600,
86
+ "tool_prefix": "ext_"
87
+ })
88
+ ```
89
+
90
+ ### HTTPS with Self-Signed Certificate
91
+
92
+ ```python
93
+ self.add_skill("mcp_gateway", {
94
+ "gateway_url": "https://localhost:8443",
95
+ "auth_user": "admin",
96
+ "auth_password": "secret",
97
+ "verify_ssl": False # For self-signed certificates
98
+ })
99
+ ```
100
+
101
+ ### Bearer Token Authentication
102
+
103
+ ```python
104
+ self.add_skill("mcp_gateway", {
105
+ "gateway_url": "https://gateway.example.com",
106
+ "auth_token": "your-bearer-token-here",
107
+ "services": [{
108
+ "name": "todo"
109
+ }]
110
+ })
111
+ ```
112
+
113
+ ## Generated Functions
114
+
115
+ The skill dynamically generates SWAIG functions based on discovered MCP tools. Function names follow the pattern:
116
+
117
+ `{tool_prefix}{service_name}_{tool_name}`
118
+
119
+ For example, with default settings:
120
+ - `mcp_todo_add_todo` - Add a todo item
121
+ - `mcp_todo_list_todos` - List todo items
122
+ - `mcp_calculator_add` - Calculator addition
123
+
124
+ ## Example Conversations
125
+
126
+ ### Using Todo Service
127
+
128
+ ```
129
+ User: "Add a task to buy milk"
130
+ Assistant: "I'll add that to your todo list."
131
+ [Calls mcp_todo_add_todo with text="buy milk"]
132
+ Assistant: "I've added 'buy milk' to your todo list."
133
+
134
+ User: "What's on my todo list?"
135
+ Assistant: "Let me check your todos."
136
+ [Calls mcp_todo_list_todos]
137
+ Assistant: "Here are your current todos:
138
+ ○ #1 [medium] buy milk"
139
+ ```
140
+
141
+ ### Multiple Services
142
+
143
+ ```
144
+ User: "Add 'finish report' to my todos and calculate 15% of 200"
145
+ Assistant: "I'll add that todo and do the calculation for you."
146
+ [Calls mcp_todo_add_todo with text="finish report"]
147
+ [Calls mcp_calculator_percent with value=200, percent=15]
148
+ Assistant: "I've added 'finish report' to your todos. 15% of 200 is 30."
149
+ ```
150
+
151
+ ## Session Management
152
+
153
+ - Each SignalWire call gets its own MCP session
154
+ - Sessions persist across multiple tool calls
155
+ - Automatic cleanup on call hangup
156
+ - Configurable timeout for inactive sessions
157
+
158
+ ### Custom Session ID
159
+
160
+ You can override the session ID by setting `mcp_call_id` in global_data:
161
+
162
+ ```python
163
+ # In your agent code
164
+ self.set_global_data({
165
+ "mcp_call_id": "custom-session-123"
166
+ })
167
+
168
+ # Or in a SWAIG function
169
+ result = SwaigFunctionResult("Session changed")
170
+ result.add_action("set_global_data", {"mcp_call_id": "new-session-456"})
171
+ ```
172
+
173
+ This is useful for:
174
+ - Managing multiple MCP sessions within a single call
175
+ - Sharing MCP sessions across different calls
176
+ - Custom session management strategies
177
+
178
+ ## Troubleshooting
179
+
180
+ ### Gateway Connection Failed
181
+
182
+ Check:
183
+ 1. Gateway service is running
184
+ 2. Correct URL and credentials
185
+ 3. Network connectivity
186
+ 4. Firewall rules
187
+
188
+ ### SSL Certificate Errors
189
+
190
+ For self-signed certificates:
191
+ ```python
192
+ "verify_ssl": False
193
+ ```
194
+
195
+ For custom CA certificates, ensure they're in the system trust store.
196
+
197
+ ### Tool Not Found
198
+
199
+ Verify:
200
+ 1. Service name is correct
201
+ 2. Tool name matches exactly
202
+ 3. Tool is included in service configuration
203
+ 4. MCP server is returning tools correctly
204
+
205
+ ### Session Timeouts
206
+
207
+ Increase timeout if needed:
208
+ ```python
209
+ "session_timeout": 600 # 10 minutes
210
+ ```
211
+
212
+ ## Gateway Setup
213
+
214
+ To run the MCP Gateway service:
215
+
216
+ ```bash
217
+ cd mcp_gateway
218
+ python3 gateway_service.py
219
+
220
+ # Or with custom config
221
+ python3 gateway_service.py -c myconfig.json
222
+ ```
223
+
224
+ ## Security Considerations
225
+
226
+ 1. Always use HTTPS in production
227
+ 2. Use strong authentication credentials
228
+ 3. Limit service access to required tools only
229
+ 4. Monitor gateway logs for suspicious activity
230
+ 5. Set appropriate session timeouts
@@ -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
+ """MCP Gateway Skill for SignalWire Agents"""