signalwire-agents 0.1.6__py3-none-any.whl → 1.0.7__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 +130 -4
- signalwire_agents/agent_server.py +438 -32
- signalwire_agents/agents/bedrock.py +296 -0
- signalwire_agents/cli/__init__.py +18 -0
- signalwire_agents/cli/build_search.py +1367 -0
- signalwire_agents/cli/config.py +80 -0
- signalwire_agents/cli/core/__init__.py +10 -0
- signalwire_agents/cli/core/agent_loader.py +470 -0
- signalwire_agents/cli/core/argparse_helpers.py +179 -0
- signalwire_agents/cli/core/dynamic_config.py +71 -0
- signalwire_agents/cli/core/service_loader.py +303 -0
- signalwire_agents/cli/execution/__init__.py +10 -0
- signalwire_agents/cli/execution/datamap_exec.py +446 -0
- signalwire_agents/cli/execution/webhook_exec.py +134 -0
- signalwire_agents/cli/init_project.py +1225 -0
- signalwire_agents/cli/output/__init__.py +10 -0
- signalwire_agents/cli/output/output_formatter.py +255 -0
- signalwire_agents/cli/output/swml_dump.py +186 -0
- signalwire_agents/cli/simulation/__init__.py +10 -0
- signalwire_agents/cli/simulation/data_generation.py +374 -0
- signalwire_agents/cli/simulation/data_overrides.py +200 -0
- signalwire_agents/cli/simulation/mock_env.py +282 -0
- signalwire_agents/cli/swaig_test_wrapper.py +52 -0
- signalwire_agents/cli/test_swaig.py +809 -0
- signalwire_agents/cli/types.py +81 -0
- signalwire_agents/core/__init__.py +2 -2
- signalwire_agents/core/agent/__init__.py +12 -0
- signalwire_agents/core/agent/config/__init__.py +12 -0
- signalwire_agents/core/agent/deployment/__init__.py +9 -0
- signalwire_agents/core/agent/deployment/handlers/__init__.py +9 -0
- signalwire_agents/core/agent/prompt/__init__.py +14 -0
- signalwire_agents/core/agent/prompt/manager.py +306 -0
- signalwire_agents/core/agent/routing/__init__.py +9 -0
- signalwire_agents/core/agent/security/__init__.py +9 -0
- signalwire_agents/core/agent/swml/__init__.py +9 -0
- signalwire_agents/core/agent/tools/__init__.py +15 -0
- signalwire_agents/core/agent/tools/decorator.py +97 -0
- signalwire_agents/core/agent/tools/registry.py +210 -0
- signalwire_agents/core/agent_base.py +959 -2166
- signalwire_agents/core/auth_handler.py +233 -0
- signalwire_agents/core/config_loader.py +259 -0
- signalwire_agents/core/contexts.py +707 -0
- signalwire_agents/core/data_map.py +487 -0
- signalwire_agents/core/function_result.py +1150 -1
- signalwire_agents/core/logging_config.py +376 -0
- signalwire_agents/core/mixins/__init__.py +28 -0
- signalwire_agents/core/mixins/ai_config_mixin.py +442 -0
- signalwire_agents/core/mixins/auth_mixin.py +287 -0
- signalwire_agents/core/mixins/prompt_mixin.py +358 -0
- signalwire_agents/core/mixins/serverless_mixin.py +368 -0
- signalwire_agents/core/mixins/skill_mixin.py +55 -0
- signalwire_agents/core/mixins/state_mixin.py +153 -0
- signalwire_agents/core/mixins/tool_mixin.py +230 -0
- signalwire_agents/core/mixins/web_mixin.py +1134 -0
- signalwire_agents/core/security/session_manager.py +174 -86
- signalwire_agents/core/security_config.py +333 -0
- signalwire_agents/core/skill_base.py +200 -0
- signalwire_agents/core/skill_manager.py +244 -0
- signalwire_agents/core/swaig_function.py +33 -9
- signalwire_agents/core/swml_builder.py +212 -12
- signalwire_agents/core/swml_handler.py +43 -13
- signalwire_agents/core/swml_renderer.py +123 -297
- signalwire_agents/core/swml_service.py +277 -260
- signalwire_agents/prefabs/concierge.py +6 -2
- signalwire_agents/prefabs/info_gatherer.py +149 -33
- signalwire_agents/prefabs/receptionist.py +14 -22
- signalwire_agents/prefabs/survey.py +6 -2
- signalwire_agents/schema.json +9218 -5489
- signalwire_agents/search/__init__.py +137 -0
- signalwire_agents/search/document_processor.py +1223 -0
- signalwire_agents/search/index_builder.py +804 -0
- signalwire_agents/search/migration.py +418 -0
- signalwire_agents/search/models.py +30 -0
- signalwire_agents/search/pgvector_backend.py +752 -0
- signalwire_agents/search/query_processor.py +502 -0
- signalwire_agents/search/search_engine.py +1264 -0
- signalwire_agents/search/search_service.py +574 -0
- signalwire_agents/skills/README.md +452 -0
- signalwire_agents/skills/__init__.py +23 -0
- signalwire_agents/skills/api_ninjas_trivia/README.md +215 -0
- signalwire_agents/skills/api_ninjas_trivia/__init__.py +12 -0
- signalwire_agents/skills/api_ninjas_trivia/skill.py +237 -0
- signalwire_agents/skills/datasphere/README.md +210 -0
- signalwire_agents/skills/datasphere/__init__.py +12 -0
- signalwire_agents/skills/datasphere/skill.py +310 -0
- signalwire_agents/skills/datasphere_serverless/README.md +258 -0
- signalwire_agents/skills/datasphere_serverless/__init__.py +10 -0
- signalwire_agents/skills/datasphere_serverless/skill.py +237 -0
- signalwire_agents/skills/datetime/README.md +132 -0
- signalwire_agents/skills/datetime/__init__.py +10 -0
- signalwire_agents/skills/datetime/skill.py +126 -0
- signalwire_agents/skills/joke/README.md +149 -0
- signalwire_agents/skills/joke/__init__.py +10 -0
- signalwire_agents/skills/joke/skill.py +109 -0
- signalwire_agents/skills/math/README.md +161 -0
- signalwire_agents/skills/math/__init__.py +10 -0
- signalwire_agents/skills/math/skill.py +105 -0
- signalwire_agents/skills/mcp_gateway/README.md +230 -0
- signalwire_agents/skills/mcp_gateway/__init__.py +10 -0
- signalwire_agents/skills/mcp_gateway/skill.py +421 -0
- signalwire_agents/skills/native_vector_search/README.md +210 -0
- signalwire_agents/skills/native_vector_search/__init__.py +10 -0
- signalwire_agents/skills/native_vector_search/skill.py +820 -0
- signalwire_agents/skills/play_background_file/README.md +218 -0
- signalwire_agents/skills/play_background_file/__init__.py +12 -0
- signalwire_agents/skills/play_background_file/skill.py +242 -0
- signalwire_agents/skills/registry.py +459 -0
- signalwire_agents/skills/spider/README.md +236 -0
- signalwire_agents/skills/spider/__init__.py +13 -0
- signalwire_agents/skills/spider/skill.py +598 -0
- signalwire_agents/skills/swml_transfer/README.md +395 -0
- signalwire_agents/skills/swml_transfer/__init__.py +10 -0
- signalwire_agents/skills/swml_transfer/skill.py +359 -0
- signalwire_agents/skills/weather_api/README.md +178 -0
- signalwire_agents/skills/weather_api/__init__.py +12 -0
- signalwire_agents/skills/weather_api/skill.py +191 -0
- signalwire_agents/skills/web_search/README.md +163 -0
- signalwire_agents/skills/web_search/__init__.py +10 -0
- signalwire_agents/skills/web_search/skill.py +739 -0
- signalwire_agents/skills/wikipedia_search/README.md +228 -0
- signalwire_agents/{core/state → skills/wikipedia_search}/__init__.py +5 -4
- signalwire_agents/skills/wikipedia_search/skill.py +210 -0
- signalwire_agents/utils/__init__.py +14 -0
- signalwire_agents/utils/schema_utils.py +111 -44
- signalwire_agents/web/__init__.py +17 -0
- signalwire_agents/web/web_service.py +559 -0
- signalwire_agents-1.0.7.data/data/share/man/man1/sw-agent-init.1 +307 -0
- signalwire_agents-1.0.7.data/data/share/man/man1/sw-search.1 +483 -0
- signalwire_agents-1.0.7.data/data/share/man/man1/swaig-test.1 +308 -0
- signalwire_agents-1.0.7.dist-info/METADATA +992 -0
- signalwire_agents-1.0.7.dist-info/RECORD +142 -0
- {signalwire_agents-0.1.6.dist-info → signalwire_agents-1.0.7.dist-info}/WHEEL +1 -1
- signalwire_agents-1.0.7.dist-info/entry_points.txt +4 -0
- signalwire_agents/core/state/file_state_manager.py +0 -219
- signalwire_agents/core/state/state_manager.py +0 -101
- signalwire_agents-0.1.6.data/data/schema.json +0 -5611
- signalwire_agents-0.1.6.dist-info/METADATA +0 -199
- signalwire_agents-0.1.6.dist-info/RECORD +0 -34
- {signalwire_agents-0.1.6.dist-info → signalwire_agents-1.0.7.dist-info}/licenses/LICENSE +0 -0
- {signalwire_agents-0.1.6.dist-info → signalwire_agents-1.0.7.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,296 @@
|
|
|
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
|
+
"""
|
|
11
|
+
Bedrock Agent - Amazon Bedrock voice-to-voice integration
|
|
12
|
+
|
|
13
|
+
This module provides BedrockAgent, which extends AgentBase to support
|
|
14
|
+
Amazon Bedrock's voice-to-voice model while maintaining compatibility
|
|
15
|
+
with all SignalWire agent features like skills, POM, and SWAIG functions.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
from typing import Dict, List, Any, Optional, Union
|
|
20
|
+
from signalwire_agents.core.agent_base import AgentBase
|
|
21
|
+
from signalwire_agents.core.logging_config import get_logger
|
|
22
|
+
|
|
23
|
+
logger = get_logger("bedrock_agent")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class BedrockAgent(AgentBase):
|
|
27
|
+
"""
|
|
28
|
+
Agent implementation for Amazon Bedrock voice-to-voice model
|
|
29
|
+
|
|
30
|
+
This agent extends AgentBase to provide full compatibility with
|
|
31
|
+
SignalWire's agent ecosystem while using Amazon Bedrock as the
|
|
32
|
+
AI backend. It supports all standard agent features including:
|
|
33
|
+
- Prompt building with text and POM
|
|
34
|
+
- Skills and SWAIG functions
|
|
35
|
+
- Post-prompt functionality
|
|
36
|
+
- Dynamic configuration
|
|
37
|
+
|
|
38
|
+
The main difference from the standard agent is that it generates
|
|
39
|
+
SWML with the "amazon_bedrock" verb instead of "ai".
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
name: str = "bedrock_agent",
|
|
45
|
+
route: str = "/bedrock",
|
|
46
|
+
system_prompt: Optional[str] = None,
|
|
47
|
+
voice_id: str = "matthew",
|
|
48
|
+
temperature: float = 0.7,
|
|
49
|
+
top_p: float = 0.9,
|
|
50
|
+
max_tokens: int = 1024,
|
|
51
|
+
**kwargs
|
|
52
|
+
):
|
|
53
|
+
"""
|
|
54
|
+
Initialize BedrockAgent
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
name: Agent name
|
|
58
|
+
route: HTTP route for the agent
|
|
59
|
+
system_prompt: Initial system prompt (can be overridden with set_prompt)
|
|
60
|
+
voice_id: Bedrock voice ID (default: matthew)
|
|
61
|
+
temperature: Generation temperature (0-1)
|
|
62
|
+
top_p: Nucleus sampling parameter (0-1)
|
|
63
|
+
max_tokens: Maximum tokens to generate
|
|
64
|
+
**kwargs: Additional arguments passed to AgentBase
|
|
65
|
+
"""
|
|
66
|
+
# Store Bedrock-specific parameters first
|
|
67
|
+
self._voice_id = voice_id
|
|
68
|
+
self._temperature = temperature
|
|
69
|
+
self._top_p = top_p
|
|
70
|
+
self._max_tokens = max_tokens
|
|
71
|
+
|
|
72
|
+
# Initialize base class
|
|
73
|
+
super().__init__(name=name, route=route, **kwargs)
|
|
74
|
+
|
|
75
|
+
# Set initial prompt if provided (after super init)
|
|
76
|
+
if system_prompt:
|
|
77
|
+
self.set_prompt_text(system_prompt)
|
|
78
|
+
|
|
79
|
+
logger.info(f"BedrockAgent initialized: {name} on route {route}")
|
|
80
|
+
|
|
81
|
+
def _render_swml(self, call_id: str = None, modifications: Optional[dict] = None) -> str:
|
|
82
|
+
"""
|
|
83
|
+
Render SWML document with amazon_bedrock verb
|
|
84
|
+
|
|
85
|
+
This method overrides the base implementation to generate
|
|
86
|
+
SWML with the amazon_bedrock verb structure that matches
|
|
87
|
+
the ai verb structure for consistency.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
call_id: Optional call ID for session-specific tokens
|
|
91
|
+
modifications: Optional dict of modifications to apply
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
SWML document as JSON string with amazon_bedrock verb
|
|
95
|
+
"""
|
|
96
|
+
# Call parent to build the base SWML with ai verb
|
|
97
|
+
base_swml_json = super()._render_swml(call_id, modifications)
|
|
98
|
+
|
|
99
|
+
# Parse the JSON to modify it
|
|
100
|
+
swml = json.loads(base_swml_json)
|
|
101
|
+
|
|
102
|
+
# Find and transform the ai verb to amazon_bedrock
|
|
103
|
+
sections = swml.get("sections", {})
|
|
104
|
+
main_section = sections.get("main", [])
|
|
105
|
+
|
|
106
|
+
# Look for ai verb and transform it
|
|
107
|
+
for i, verb in enumerate(main_section):
|
|
108
|
+
if "ai" in verb:
|
|
109
|
+
ai_config = verb["ai"]
|
|
110
|
+
|
|
111
|
+
# Build amazon_bedrock verb with same structure
|
|
112
|
+
bedrock_verb = {
|
|
113
|
+
"amazon_bedrock": {
|
|
114
|
+
# Add voice configuration and inference params inside prompt
|
|
115
|
+
# Note: In Bedrock, voice and inference params are part of prompt config
|
|
116
|
+
"prompt": self._add_voice_to_prompt(ai_config.get("prompt", {})),
|
|
117
|
+
|
|
118
|
+
# Copy SWAIG if present
|
|
119
|
+
"SWAIG": ai_config.get("SWAIG", {}),
|
|
120
|
+
|
|
121
|
+
# Include params only if they were explicitly set via set_params()
|
|
122
|
+
# The C++ code ignores params for now (marked for future extensibility)
|
|
123
|
+
"params": ai_config.get("params", {}),
|
|
124
|
+
|
|
125
|
+
# Copy global_data if present
|
|
126
|
+
"global_data": ai_config.get("global_data", {}),
|
|
127
|
+
|
|
128
|
+
# Copy post_prompt if present
|
|
129
|
+
"post_prompt": ai_config.get("post_prompt"),
|
|
130
|
+
|
|
131
|
+
# Copy post_prompt_url if present
|
|
132
|
+
"post_prompt_url": ai_config.get("post_prompt_url")
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Remove None values
|
|
137
|
+
bedrock_config = bedrock_verb["amazon_bedrock"]
|
|
138
|
+
bedrock_verb["amazon_bedrock"] = {
|
|
139
|
+
k: v for k, v in bedrock_config.items()
|
|
140
|
+
if v is not None
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
# Replace ai verb with amazon_bedrock verb
|
|
144
|
+
main_section[i] = bedrock_verb
|
|
145
|
+
break
|
|
146
|
+
|
|
147
|
+
# Convert back to JSON string
|
|
148
|
+
return json.dumps(swml)
|
|
149
|
+
|
|
150
|
+
def _add_voice_to_prompt(self, prompt_config: Dict[str, Any]) -> Dict[str, Any]:
|
|
151
|
+
"""
|
|
152
|
+
Add voice configuration to the prompt object
|
|
153
|
+
|
|
154
|
+
In Bedrock, voice configuration is part of the prompt object,
|
|
155
|
+
not a separate field like in OpenAI.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
prompt_config: Current prompt configuration
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
Updated prompt configuration with voice
|
|
162
|
+
"""
|
|
163
|
+
# Create a clean copy, filtering out text-model-specific parameters
|
|
164
|
+
# that don't apply to Bedrock's voice-to-voice model
|
|
165
|
+
filtered_config = {}
|
|
166
|
+
|
|
167
|
+
# Copy over only the relevant fields
|
|
168
|
+
for key, value in prompt_config.items():
|
|
169
|
+
# Skip text-model-specific parameters
|
|
170
|
+
if key in ['barge_confidence', 'presence_penalty', 'frequency_penalty']:
|
|
171
|
+
continue
|
|
172
|
+
filtered_config[key] = value
|
|
173
|
+
|
|
174
|
+
# Add voice_id to the prompt configuration
|
|
175
|
+
filtered_config["voice_id"] = self._voice_id
|
|
176
|
+
|
|
177
|
+
# Add/override inference parameters (where C code expects them)
|
|
178
|
+
filtered_config["temperature"] = self._temperature
|
|
179
|
+
filtered_config["top_p"] = self._top_p
|
|
180
|
+
|
|
181
|
+
return filtered_config
|
|
182
|
+
|
|
183
|
+
def _build_bedrock_params(self, base_params: Dict[str, Any]) -> Dict[str, Any]:
|
|
184
|
+
"""
|
|
185
|
+
Build Bedrock-specific parameters
|
|
186
|
+
|
|
187
|
+
Merges base parameters with Bedrock-specific inference settings.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
base_params: Base parameters from AgentBase
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
Combined parameters for Bedrock
|
|
194
|
+
"""
|
|
195
|
+
# Start with base params
|
|
196
|
+
params = base_params.copy()
|
|
197
|
+
|
|
198
|
+
# Add Bedrock inference parameters
|
|
199
|
+
params.update({
|
|
200
|
+
"temperature": self._temperature,
|
|
201
|
+
"top_p": self._top_p,
|
|
202
|
+
"max_tokens": self._max_tokens
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
return params
|
|
206
|
+
|
|
207
|
+
def set_voice(self, voice_id: str) -> None:
|
|
208
|
+
"""
|
|
209
|
+
Set the Bedrock voice ID
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
voice_id: Bedrock voice identifier (e.g., 'matthew', 'joanna')
|
|
213
|
+
"""
|
|
214
|
+
self._voice_id = voice_id
|
|
215
|
+
logger.debug(f"Voice set to: {voice_id}")
|
|
216
|
+
|
|
217
|
+
def set_inference_params(
|
|
218
|
+
self,
|
|
219
|
+
temperature: Optional[float] = None,
|
|
220
|
+
top_p: Optional[float] = None,
|
|
221
|
+
max_tokens: Optional[int] = None
|
|
222
|
+
) -> None:
|
|
223
|
+
"""
|
|
224
|
+
Update Bedrock inference parameters
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
temperature: Generation temperature (0-1)
|
|
228
|
+
top_p: Nucleus sampling parameter (0-1)
|
|
229
|
+
max_tokens: Maximum tokens to generate
|
|
230
|
+
"""
|
|
231
|
+
if temperature is not None:
|
|
232
|
+
self._temperature = temperature
|
|
233
|
+
if top_p is not None:
|
|
234
|
+
self._top_p = top_p
|
|
235
|
+
if max_tokens is not None:
|
|
236
|
+
self._max_tokens = max_tokens
|
|
237
|
+
|
|
238
|
+
logger.debug(f"Inference params updated: temp={self._temperature}, "
|
|
239
|
+
f"top_p={self._top_p}, max_tokens={self._max_tokens}")
|
|
240
|
+
|
|
241
|
+
# Methods that may not be relevant to Bedrock
|
|
242
|
+
# These are overridden to provide appropriate behavior or warnings
|
|
243
|
+
|
|
244
|
+
def set_llm_model(self, model: str) -> None:
|
|
245
|
+
"""
|
|
246
|
+
Set LLM model - not applicable for Bedrock
|
|
247
|
+
|
|
248
|
+
Bedrock uses a fixed voice-to-voice model, so this method
|
|
249
|
+
logs a warning and does nothing.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
model: Model name (ignored)
|
|
253
|
+
"""
|
|
254
|
+
logger.warning(f"set_llm_model('{model}') called but Bedrock uses a fixed voice-to-voice model")
|
|
255
|
+
|
|
256
|
+
def set_llm_temperature(self, temperature: float) -> None:
|
|
257
|
+
"""
|
|
258
|
+
Set LLM temperature - redirects to set_inference_params
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
temperature: Temperature value
|
|
262
|
+
"""
|
|
263
|
+
self.set_inference_params(temperature=temperature)
|
|
264
|
+
|
|
265
|
+
def set_post_prompt_llm_params(self, **params) -> None:
|
|
266
|
+
"""
|
|
267
|
+
Set post-prompt LLM parameters - not applicable for Bedrock
|
|
268
|
+
|
|
269
|
+
Bedrock uses OpenAI for post-prompt summarization, but those
|
|
270
|
+
parameters are configured in the C code.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
**params: Ignored parameters
|
|
274
|
+
"""
|
|
275
|
+
logger.warning("set_post_prompt_llm_params() called but Bedrock post-prompt uses OpenAI configured in C code")
|
|
276
|
+
|
|
277
|
+
def set_prompt_llm_params(self, **params) -> None:
|
|
278
|
+
"""
|
|
279
|
+
Set prompt LLM parameters - use set_inference_params instead
|
|
280
|
+
|
|
281
|
+
For Bedrock, use set_inference_params() to configure temperature,
|
|
282
|
+
top_p, and max_tokens.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
**params: Parameters (ignored, use set_inference_params)
|
|
286
|
+
"""
|
|
287
|
+
logger.warning("set_prompt_llm_params() called - use set_inference_params() for Bedrock")
|
|
288
|
+
|
|
289
|
+
# Note: We don't override prompt methods like set_prompt_text, set_prompt_pom
|
|
290
|
+
# because those work fine - they just build the prompt structure that we
|
|
291
|
+
# transform in _render_swml()
|
|
292
|
+
|
|
293
|
+
def __repr__(self) -> str:
|
|
294
|
+
"""String representation of the agent"""
|
|
295
|
+
return (f"BedrockAgent(name='{self.name}', route='{self.route}', "
|
|
296
|
+
f"voice='{self._voice_id}')")
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
"""
|
|
11
|
+
SignalWire Agents CLI Tools
|
|
12
|
+
|
|
13
|
+
This package contains command-line tools for working with SignalWire AI Agents.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from .test_swaig import main as test_swaig_main
|
|
17
|
+
|
|
18
|
+
__all__ = ['test_swaig_main']
|