signalwire-agents 0.1.13__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 +99 -15
- signalwire_agents/agent_server.py +176 -23
- signalwire_agents/agents/bedrock.py +296 -0
- signalwire_agents/cli/__init__.py +9 -0
- signalwire_agents/cli/build_search.py +951 -41
- 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 +566 -2366
- 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 +825 -2916
- signalwire_agents/core/auth_handler.py +233 -0
- signalwire_agents/core/config_loader.py +259 -0
- signalwire_agents/core/contexts.py +418 -0
- signalwire_agents/core/data_map.py +3 -15
- signalwire_agents/core/function_result.py +116 -44
- signalwire_agents/core/logging_config.py +162 -18
- 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_config.py +333 -0
- signalwire_agents/core/skill_base.py +84 -1
- signalwire_agents/core/skill_manager.py +62 -20
- signalwire_agents/core/swaig_function.py +18 -5
- signalwire_agents/core/swml_builder.py +207 -11
- signalwire_agents/core/swml_handler.py +27 -21
- signalwire_agents/core/swml_renderer.py +123 -312
- signalwire_agents/core/swml_service.py +167 -200
- signalwire_agents/prefabs/concierge.py +0 -3
- signalwire_agents/prefabs/faq_bot.py +0 -3
- signalwire_agents/prefabs/info_gatherer.py +0 -3
- signalwire_agents/prefabs/receptionist.py +0 -3
- signalwire_agents/prefabs/survey.py +0 -3
- signalwire_agents/schema.json +9218 -5489
- signalwire_agents/search/__init__.py +7 -1
- signalwire_agents/search/document_processor.py +490 -31
- signalwire_agents/search/index_builder.py +307 -37
- 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 +162 -31
- signalwire_agents/search/search_engine.py +916 -35
- signalwire_agents/search/search_service.py +376 -53
- signalwire_agents/skills/README.md +452 -0
- signalwire_agents/skills/__init__.py +10 -1
- 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/skill.py +84 -3
- signalwire_agents/skills/datasphere_serverless/README.md +258 -0
- signalwire_agents/skills/datasphere_serverless/__init__.py +9 -0
- signalwire_agents/skills/datasphere_serverless/skill.py +82 -1
- signalwire_agents/skills/datetime/README.md +132 -0
- signalwire_agents/skills/datetime/__init__.py +9 -0
- signalwire_agents/skills/datetime/skill.py +20 -7
- signalwire_agents/skills/joke/README.md +149 -0
- signalwire_agents/skills/joke/__init__.py +9 -0
- signalwire_agents/skills/joke/skill.py +21 -0
- signalwire_agents/skills/math/README.md +161 -0
- signalwire_agents/skills/math/__init__.py +9 -0
- signalwire_agents/skills/math/skill.py +18 -4
- 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 +9 -0
- signalwire_agents/skills/native_vector_search/skill.py +569 -101
- 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 +395 -40
- 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 +9 -0
- signalwire_agents/skills/web_search/skill.py +586 -112
- signalwire_agents/skills/wikipedia_search/README.md +228 -0
- signalwire_agents/{core/state → skills/wikipedia_search}/__init__.py +5 -4
- signalwire_agents/skills/{wikipedia → wikipedia_search}/skill.py +33 -3
- 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-0.1.13.dist-info → signalwire_agents-1.0.7.dist-info}/METADATA +344 -215
- signalwire_agents-1.0.7.dist-info/RECORD +142 -0
- 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/skills/wikipedia/__init__.py +0 -9
- signalwire_agents-0.1.13.data/data/schema.json +0 -5611
- signalwire_agents-0.1.13.dist-info/RECORD +0 -67
- signalwire_agents-0.1.13.dist-info/entry_points.txt +0 -3
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.7.dist-info}/WHEEL +0 -0
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.7.dist-info}/licenses/LICENSE +0 -0
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-1.0.7.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: signalwire_agents
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.7
|
|
4
4
|
Summary: SignalWire AI Agents SDK
|
|
5
5
|
Author-email: SignalWire Team <info@signalwire.com>
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/signalwire/signalwire-agents
|
|
8
|
+
Keywords: signalwire,ai,agents,voice,telephony,swaig,swml
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
10
|
Classifier: Intended Audience :: Developers
|
|
9
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
12
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -16,16 +18,22 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
16
18
|
Requires-Python: >=3.7
|
|
17
19
|
Description-Content-Type: text/markdown
|
|
18
20
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: fastapi
|
|
20
|
-
Requires-Dist: pydantic
|
|
21
|
-
Requires-Dist: PyYAML
|
|
22
|
-
Requires-Dist: Requests
|
|
23
|
-
Requires-Dist: setuptools
|
|
24
|
-
Requires-Dist: signalwire_pom
|
|
25
|
-
Requires-Dist: structlog
|
|
26
|
-
Requires-Dist: uvicorn
|
|
27
|
-
Requires-Dist: beautifulsoup4
|
|
28
|
-
Requires-Dist: pytz
|
|
21
|
+
Requires-Dist: fastapi>=0.115.12
|
|
22
|
+
Requires-Dist: pydantic>=2.11.4
|
|
23
|
+
Requires-Dist: PyYAML>=6.0.2
|
|
24
|
+
Requires-Dist: Requests>=2.32.3
|
|
25
|
+
Requires-Dist: setuptools<81,>=66.1.1
|
|
26
|
+
Requires-Dist: signalwire_pom>=2.7.1
|
|
27
|
+
Requires-Dist: structlog>=25.3.0
|
|
28
|
+
Requires-Dist: uvicorn>=0.34.2
|
|
29
|
+
Requires-Dist: beautifulsoup4>=4.12.3
|
|
30
|
+
Requires-Dist: pytz>=2023.3
|
|
31
|
+
Requires-Dist: lxml>=4.9.0
|
|
32
|
+
Provides-Extra: search-queryonly
|
|
33
|
+
Requires-Dist: numpy>=1.24.0; extra == "search-queryonly"
|
|
34
|
+
Requires-Dist: scikit-learn>=1.3.0; extra == "search-queryonly"
|
|
35
|
+
Requires-Dist: sentence-transformers>=2.2.0; extra == "search-queryonly"
|
|
36
|
+
Requires-Dist: nltk>=3.8; extra == "search-queryonly"
|
|
29
37
|
Provides-Extra: search
|
|
30
38
|
Requires-Dist: sentence-transformers>=2.2.0; extra == "search"
|
|
31
39
|
Requires-Dist: scikit-learn>=1.3.0; extra == "search"
|
|
@@ -62,28 +70,162 @@ Requires-Dist: striprtf>=0.0.26; extra == "search-all"
|
|
|
62
70
|
Requires-Dist: openpyxl>=3.1.0; extra == "search-all"
|
|
63
71
|
Requires-Dist: python-pptx>=0.6.21; extra == "search-all"
|
|
64
72
|
Requires-Dist: python-magic>=0.4.27; extra == "search-all"
|
|
73
|
+
Requires-Dist: psycopg2-binary>=2.9.0; extra == "search-all"
|
|
74
|
+
Requires-Dist: pgvector>=0.2.0; extra == "search-all"
|
|
75
|
+
Provides-Extra: pgvector
|
|
76
|
+
Requires-Dist: psycopg2-binary>=2.9.0; extra == "pgvector"
|
|
77
|
+
Requires-Dist: pgvector>=0.2.0; extra == "pgvector"
|
|
78
|
+
Provides-Extra: all
|
|
79
|
+
Requires-Dist: sentence-transformers>=2.2.0; extra == "all"
|
|
80
|
+
Requires-Dist: scikit-learn>=1.3.0; extra == "all"
|
|
81
|
+
Requires-Dist: nltk>=3.8; extra == "all"
|
|
82
|
+
Requires-Dist: numpy>=1.24.0; extra == "all"
|
|
83
|
+
Requires-Dist: spacy>=3.6.0; extra == "all"
|
|
84
|
+
Requires-Dist: pdfplumber>=0.9.0; extra == "all"
|
|
85
|
+
Requires-Dist: python-docx>=0.8.11; extra == "all"
|
|
86
|
+
Requires-Dist: markdown>=3.4.0; extra == "all"
|
|
87
|
+
Requires-Dist: striprtf>=0.0.26; extra == "all"
|
|
88
|
+
Requires-Dist: openpyxl>=3.1.0; extra == "all"
|
|
89
|
+
Requires-Dist: python-pptx>=0.6.21; extra == "all"
|
|
90
|
+
Requires-Dist: python-magic>=0.4.27; extra == "all"
|
|
65
91
|
Dynamic: license-file
|
|
66
92
|
|
|
67
|
-
|
|
93
|
+
<!-- Header -->
|
|
94
|
+
<div align="center">
|
|
95
|
+
<a href="https://signalwire.com" target="_blank">
|
|
96
|
+
<img src="https://github.com/user-attachments/assets/0c8ed3b9-8c50-4dc6-9cc4-cc6cd137fd50" width="500" />
|
|
97
|
+
</a>
|
|
68
98
|
|
|
69
|
-
|
|
99
|
+
# Agents SDK
|
|
100
|
+
|
|
101
|
+
#### _A Python SDK for creating, hosting, and securing SignalWire AI agents as microservices with minimal boilerplate._
|
|
102
|
+
|
|
103
|
+
<br/>
|
|
104
|
+
|
|
105
|
+
<p align="center">
|
|
106
|
+
<a href="https://developer.signalwire.com/sdks/agents-sdk" target="_blank">📖 Documentation</a> <code>#</code>
|
|
107
|
+
<a href="https://github.com/signalwire/signalwire-docs/issues/new/choose" target="_blank">🐛 Report an issue</a> <code>#</code>
|
|
108
|
+
<a href="https://pypi.org/project/signalwire-agents/" target="_blank">🐍 PyPI</a>
|
|
109
|
+
</p>
|
|
110
|
+
|
|
111
|
+
<br/>
|
|
112
|
+
|
|
113
|
+
<!-- Badges -->
|
|
114
|
+
<div align="center">
|
|
115
|
+
<a href="https://discord.com/invite/F2WNYTNjuF" target="_blank"><img src="https://img.shields.io/badge/Discord%20Community-5865F2" alt="Discord" /></a>
|
|
116
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/MIT-License-blue" alt="MIT License" /></a>
|
|
117
|
+
<a href="https://github.com/signalwire" target="_blank"><img src="https://img.shields.io/badge/GitHub-%23121011.svg?logo=github&logoColor=white&" alt="GitHub" /></a>
|
|
118
|
+
<a href="https://github.com/signalwire/docs" target="_blank"><img src="https://img.shields.io/github/stars/signalwire/signalwire-agents" alt="GitHub Stars" /></a>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<br/>
|
|
122
|
+
|
|
123
|
+
<a href="https://signalwire.com/signup" target="_blank">
|
|
124
|
+
<img src="https://github.com/user-attachments/assets/c2510c86-ae03-42a9-be06-ab9bcea948e1" alt="Sign Up" height="65"/>
|
|
125
|
+
</a>
|
|
126
|
+
|
|
127
|
+
</div>
|
|
70
128
|
|
|
71
129
|
## Features
|
|
72
130
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- **
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- **
|
|
85
|
-
|
|
86
|
-
|
|
131
|
+
| | |
|
|
132
|
+
|-------------------------------|:-----------------------------------------------------------------------------:|
|
|
133
|
+
| 🤖 **Self-Contained Agents** | Each agent is both a web app and an AI persona |
|
|
134
|
+
| 📝 **Prompt Object Model** | Structured prompt composition using POM |
|
|
135
|
+
| ⚙️ **SWAIG Integration** | Easily define and handle AI tools/functions |
|
|
136
|
+
| 🔧 **Dynamic Configuration** | Configure agents per-request for multi-tenant apps and personalization |
|
|
137
|
+
| 🗺️ **Custom Routing** | Dynamic request handling for different paths and content |
|
|
138
|
+
| 📞 **SIP Integration** | Route SIP calls to agents based on SIP usernames |
|
|
139
|
+
| 🔒 **Security Built-In** | Session management, function-specific security tokens, and basic auth |
|
|
140
|
+
| 💾 **State Management** | Persistent conversation state with automatic tracking |
|
|
141
|
+
| 🏗️ **Prefab Archetypes** | Ready-to-use agent types for common scenarios |
|
|
142
|
+
| 🏢 **Multi-Agent Support** | Host multiple agents on a single server |
|
|
143
|
+
| � **Modular Skills System** | Add capabilities to agents with simple one-liner calls |
|
|
144
|
+
| 🔍 **Local Search System** | Offline document search with vector similarity and keyword search |
|
|
145
|
+
|
|
146
|
+
## Installation
|
|
147
|
+
|
|
148
|
+
### Basic Installation
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pip install signalwire-agents
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Optional Search Functionality
|
|
155
|
+
|
|
156
|
+
The SDK includes optional local search capabilities that can be installed separately to avoid adding large dependencies to the base installation:
|
|
157
|
+
|
|
158
|
+
#### Search Installation Options
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Query existing .swsearch files only (smallest footprint)
|
|
162
|
+
pip install signalwire-agents[search-queryonly]
|
|
163
|
+
|
|
164
|
+
# Basic search (vector search + keyword search + building indexes)
|
|
165
|
+
pip install signalwire-agents[search]
|
|
166
|
+
|
|
167
|
+
# Full search with document processing (PDF, DOCX, etc.)
|
|
168
|
+
pip install signalwire-agents[search-full]
|
|
169
|
+
|
|
170
|
+
# Advanced NLP features (includes spaCy)
|
|
171
|
+
pip install signalwire-agents[search-nlp]
|
|
172
|
+
|
|
173
|
+
# All search features
|
|
174
|
+
pip install signalwire-agents[search-all]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### What Each Option Includes
|
|
178
|
+
|
|
179
|
+
| Option | Size | Features |
|
|
180
|
+
|--------|------|----------|
|
|
181
|
+
| `search-queryonly` | ~400MB | Query existing .swsearch files only (no building/processing) |
|
|
182
|
+
| `search` | ~500MB | Vector embeddings, keyword search, basic text processing |
|
|
183
|
+
| `search-full` | ~600MB | + PDF, DOCX, Excel, PowerPoint, HTML, Markdown processing |
|
|
184
|
+
| `search-nlp` | ~600MB | + Advanced spaCy NLP features |
|
|
185
|
+
| `search-all` | ~700MB | All search features combined |
|
|
186
|
+
|
|
187
|
+
**When to use `search-queryonly`:**
|
|
188
|
+
- Production containers with pre-built `.swsearch` files
|
|
189
|
+
- Lambda/serverless deployments
|
|
190
|
+
- Agents that only need to query knowledge bases (not build them)
|
|
191
|
+
- Smaller deployment footprint requirements
|
|
192
|
+
|
|
193
|
+
#### Search Features
|
|
194
|
+
|
|
195
|
+
- **Local/Offline Search**: No external API dependencies
|
|
196
|
+
- **Hybrid Search**: Vector similarity + keyword search
|
|
197
|
+
- **Smart Document Processing**: Markdown, Python, PDF, DOCX, etc.
|
|
198
|
+
- **Multiple Languages**: English, Spanish, with extensible framework
|
|
199
|
+
- **CLI Tools**: Build search indexes from document directories
|
|
200
|
+
- **HTTP API**: Standalone or embedded search service
|
|
201
|
+
|
|
202
|
+
#### Usage Example
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
# Only available with search extras installed
|
|
206
|
+
from signalwire_agents.search import IndexBuilder, SearchEngine
|
|
207
|
+
|
|
208
|
+
# Build search index
|
|
209
|
+
builder = IndexBuilder()
|
|
210
|
+
builder.build_index(
|
|
211
|
+
source_dir="./docs",
|
|
212
|
+
output_file="knowledge.swsearch",
|
|
213
|
+
file_types=['md', 'txt', 'pdf']
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Search documents
|
|
217
|
+
engine = SearchEngine("knowledge.swsearch")
|
|
218
|
+
results = engine.search(
|
|
219
|
+
query_vector=embeddings,
|
|
220
|
+
enhanced_text="search query",
|
|
221
|
+
count=5
|
|
222
|
+
)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
<details>
|
|
226
|
+
<summary><h2>Documentation</h2></summary>
|
|
227
|
+
|
|
228
|
+
### Skills System
|
|
87
229
|
|
|
88
230
|
The SignalWire Agents SDK includes a powerful modular skills system that allows you to add complex capabilities to your agents with simple one-liner calls:
|
|
89
231
|
|
|
@@ -155,7 +297,7 @@ agent.add_skill("datasphere", {
|
|
|
155
297
|
agent.serve()
|
|
156
298
|
```
|
|
157
299
|
|
|
158
|
-
|
|
300
|
+
#### Available Built-in Skills
|
|
159
301
|
|
|
160
302
|
- **web_search**: Google Custom Search API integration with web scraping (supports multiple instances)
|
|
161
303
|
- **datetime**: Current date and time with timezone support
|
|
@@ -163,7 +305,7 @@ agent.serve()
|
|
|
163
305
|
- **datasphere**: SignalWire DataSphere knowledge search (supports multiple instances)
|
|
164
306
|
- **native_vector_search**: Offline document search with vector similarity and keyword search
|
|
165
307
|
|
|
166
|
-
|
|
308
|
+
#### Benefits
|
|
167
309
|
|
|
168
310
|
- **One-liner integration**: `agent.add_skill("skill_name")`
|
|
169
311
|
- **Configurable parameters**: `agent.add_skill("skill_name", {"param": "value"})`
|
|
@@ -171,13 +313,13 @@ agent.serve()
|
|
|
171
313
|
- **Dependency validation**: Clear error messages for missing requirements
|
|
172
314
|
- **Modular architecture**: Skills are self-contained and reusable
|
|
173
315
|
|
|
174
|
-
For detailed documentation, see [Skills System README](docs/
|
|
316
|
+
For detailed documentation, see [Skills System README](docs/skills_system.md).
|
|
175
317
|
|
|
176
|
-
|
|
318
|
+
### DataMap Tools
|
|
177
319
|
|
|
178
320
|
The SDK provides a DataMap system for creating SWAIG tools that integrate directly with REST APIs without requiring custom webhook endpoints. DataMap tools execute on the SignalWire server, making them simpler to deploy than traditional webhook-based tools.
|
|
179
321
|
|
|
180
|
-
|
|
322
|
+
#### Basic DataMap Usage
|
|
181
323
|
|
|
182
324
|
```python
|
|
183
325
|
from signalwire_agents import AgentBase
|
|
@@ -203,7 +345,7 @@ agent = APIAgent()
|
|
|
203
345
|
agent.serve()
|
|
204
346
|
```
|
|
205
347
|
|
|
206
|
-
|
|
348
|
+
#### Advanced DataMap Examples
|
|
207
349
|
|
|
208
350
|
```python
|
|
209
351
|
# POST API with authentication
|
|
@@ -234,7 +376,7 @@ docs_tool = (DataMap('get_latest_docs')
|
|
|
234
376
|
)
|
|
235
377
|
```
|
|
236
378
|
|
|
237
|
-
|
|
379
|
+
#### Helper Functions
|
|
238
380
|
|
|
239
381
|
For simpler use cases, use the convenience functions:
|
|
240
382
|
|
|
@@ -264,7 +406,7 @@ self.register_swaig_function(weather.to_swaig_function())
|
|
|
264
406
|
self.register_swaig_function(file_control.to_swaig_function())
|
|
265
407
|
```
|
|
266
408
|
|
|
267
|
-
|
|
409
|
+
#### Variable Expansion
|
|
268
410
|
|
|
269
411
|
DataMap tools support powerful variable expansion using `${variable}` syntax:
|
|
270
412
|
|
|
@@ -274,7 +416,7 @@ DataMap tools support powerful variable expansion using `${variable}` syntax:
|
|
|
274
416
|
- **Global data**: `${global_data.key}`
|
|
275
417
|
- **Metadata**: `${meta_data.call_id}`
|
|
276
418
|
|
|
277
|
-
|
|
419
|
+
#### Benefits of DataMap Tools
|
|
278
420
|
|
|
279
421
|
- **No webhook infrastructure**: Tools run on SignalWire servers
|
|
280
422
|
- **Simplified deployment**: No need to expose endpoints
|
|
@@ -285,20 +427,20 @@ DataMap tools support powerful variable expansion using `${variable}` syntax:
|
|
|
285
427
|
|
|
286
428
|
For detailed documentation, see [DataMap Guide](docs/datamap_guide.md).
|
|
287
429
|
|
|
288
|
-
|
|
430
|
+
### Contexts and Steps
|
|
289
431
|
|
|
290
|
-
The SignalWire Agents SDK provides a powerful
|
|
432
|
+
The SignalWire Agents SDK provides a powerful enhancement to traditional prompts through the **Contexts and Steps** system. This feature allows you to add structured, workflow-driven AI interactions on top of your base prompt, with explicit navigation control and step-by-step guidance.
|
|
291
433
|
|
|
292
|
-
|
|
434
|
+
#### Why Use Contexts and Steps?
|
|
293
435
|
|
|
294
436
|
- **Structured Workflows**: Define clear, step-by-step processes for complex interactions
|
|
295
437
|
- **Navigation Control**: Explicitly control which steps or contexts users can access
|
|
296
438
|
- **Completion Criteria**: Set specific criteria for step completion and progression
|
|
297
439
|
- **Function Restrictions**: Limit which AI tools are available in each step
|
|
298
440
|
- **Workflow Isolation**: Create separate contexts for different conversation flows
|
|
299
|
-
- **
|
|
441
|
+
- **Enhanced Base Prompts**: Adds structured workflows on top of your existing prompt foundation
|
|
300
442
|
|
|
301
|
-
|
|
443
|
+
#### Basic Usage
|
|
302
444
|
|
|
303
445
|
```python
|
|
304
446
|
from signalwire_agents import AgentBase
|
|
@@ -307,30 +449,34 @@ class WorkflowAgent(AgentBase):
|
|
|
307
449
|
def __init__(self):
|
|
308
450
|
super().__init__(name="Workflow Assistant", route="/workflow")
|
|
309
451
|
|
|
310
|
-
#
|
|
452
|
+
# Set base prompt (required even when using contexts)
|
|
453
|
+
self.prompt_add_section("Role", "You are a helpful workflow assistant.")
|
|
454
|
+
self.prompt_add_section("Instructions", "Guide users through structured processes step by step.")
|
|
455
|
+
|
|
456
|
+
# Define contexts and steps (adds structured workflow to base prompt)
|
|
311
457
|
contexts = self.define_contexts()
|
|
312
458
|
|
|
313
459
|
# Create a single context named "default" (required for single context)
|
|
314
|
-
context = contexts.
|
|
460
|
+
context = contexts.add_context("default")
|
|
315
461
|
|
|
316
462
|
# Add step-by-step workflow
|
|
317
|
-
context.
|
|
463
|
+
context.add_step("greeting") \
|
|
318
464
|
.set_text("Welcome! I'm here to help you complete your application. Let's start with your personal information.") \
|
|
319
465
|
.set_step_criteria("User has provided their name and confirmed they want to continue") \
|
|
320
466
|
.set_valid_steps(["personal_info"]) # Can only go to personal_info step
|
|
321
467
|
|
|
322
|
-
context.
|
|
468
|
+
context.add_step("personal_info") \
|
|
323
469
|
.add_section("Instructions", "Collect the user's personal information") \
|
|
324
470
|
.add_bullets(["Ask for full name", "Ask for email address", "Ask for phone number"]) \
|
|
325
471
|
.set_step_criteria("All personal information has been collected and confirmed") \
|
|
326
472
|
.set_valid_steps(["review", "personal_info"]) # Can stay or move to review
|
|
327
473
|
|
|
328
|
-
context.
|
|
474
|
+
context.add_step("review") \
|
|
329
475
|
.set_text("Let me review the information you've provided. Please confirm if everything is correct.") \
|
|
330
476
|
.set_step_criteria("User has confirmed or requested changes") \
|
|
331
477
|
.set_valid_steps(["personal_info", "complete"]) # Can go back or complete
|
|
332
478
|
|
|
333
|
-
context.
|
|
479
|
+
context.add_step("complete") \
|
|
334
480
|
.set_text("Thank you! Your application has been submitted successfully.") \
|
|
335
481
|
.set_step_criteria("Application processing is complete")
|
|
336
482
|
# No valid_steps = end of workflow
|
|
@@ -339,29 +485,34 @@ agent = WorkflowAgent()
|
|
|
339
485
|
agent.serve()
|
|
340
486
|
```
|
|
341
487
|
|
|
342
|
-
|
|
488
|
+
#### Advanced Features
|
|
343
489
|
|
|
344
490
|
```python
|
|
345
491
|
class MultiContextAgent(AgentBase):
|
|
346
492
|
def __init__(self):
|
|
347
493
|
super().__init__(name="Multi-Context Agent", route="/multi-context")
|
|
348
494
|
|
|
349
|
-
#
|
|
495
|
+
# Set base prompt (required)
|
|
496
|
+
self.prompt_add_section("Role", "You are a versatile AI assistant.")
|
|
497
|
+
self.prompt_add_section("Capabilities", "You can help with calculations and provide time information.")
|
|
498
|
+
|
|
499
|
+
# Add skills
|
|
350
500
|
self.add_skill("datetime")
|
|
351
501
|
self.add_skill("math")
|
|
352
502
|
|
|
503
|
+
# Define contexts for different service modes
|
|
353
504
|
contexts = self.define_contexts()
|
|
354
505
|
|
|
355
506
|
# Main conversation context
|
|
356
|
-
main_context = contexts.
|
|
357
|
-
main_context.
|
|
507
|
+
main_context = contexts.add_context("main")
|
|
508
|
+
main_context.add_step("welcome") \
|
|
358
509
|
.set_text("Welcome! I can help with calculations or provide date/time info. What would you like to do?") \
|
|
359
510
|
.set_step_criteria("User has chosen a service type") \
|
|
360
511
|
.set_valid_contexts(["calculator", "datetime_info"]) # Can switch contexts
|
|
361
512
|
|
|
362
513
|
# Calculator context with function restrictions
|
|
363
|
-
calc_context = contexts.
|
|
364
|
-
calc_context.
|
|
514
|
+
calc_context = contexts.add_context("calculator")
|
|
515
|
+
calc_context.add_step("math_mode") \
|
|
365
516
|
.add_section("Role", "You are a mathematical assistant") \
|
|
366
517
|
.add_section("Instructions", "Help users with calculations") \
|
|
367
518
|
.set_functions(["math"]) # Only math function available \
|
|
@@ -369,21 +520,21 @@ class MultiContextAgent(AgentBase):
|
|
|
369
520
|
.set_valid_contexts(["main"]) # Can return to main
|
|
370
521
|
|
|
371
522
|
# DateTime context
|
|
372
|
-
datetime_context = contexts.
|
|
373
|
-
datetime_context.
|
|
523
|
+
datetime_context = contexts.add_context("datetime_info")
|
|
524
|
+
datetime_context.add_step("time_mode") \
|
|
374
525
|
.set_text("I can provide current date and time information. What would you like to know?") \
|
|
375
526
|
.set_functions(["datetime"]) # Only datetime function available \
|
|
376
527
|
.set_step_criteria("Date/time information has been provided") \
|
|
377
528
|
.set_valid_contexts(["main"]) # Can return to main
|
|
378
529
|
```
|
|
379
530
|
|
|
380
|
-
|
|
531
|
+
#### Context and Step Methods
|
|
381
532
|
|
|
382
|
-
|
|
383
|
-
- `
|
|
533
|
+
##### Context Methods
|
|
534
|
+
- `add_step(name)`: Create a new step in this context
|
|
384
535
|
- `set_valid_contexts(contexts)`: Control which contexts can be accessed from this context
|
|
385
536
|
|
|
386
|
-
|
|
537
|
+
##### Step Methods
|
|
387
538
|
- `set_text(text)`: Set direct text prompt for the step
|
|
388
539
|
- `add_section(title, body)`: Add POM-style section (alternative to set_text)
|
|
389
540
|
- `add_bullets(bullets)`: Add bullet points to the current or last section
|
|
@@ -392,55 +543,59 @@ class MultiContextAgent(AgentBase):
|
|
|
392
543
|
- `set_valid_steps(steps)`: Control navigation to other steps in same context
|
|
393
544
|
- `set_valid_contexts(contexts)`: Control navigation to other contexts
|
|
394
545
|
|
|
395
|
-
|
|
546
|
+
#### Navigation Rules
|
|
396
547
|
|
|
397
548
|
- **Valid Steps**: If omitted, only "next" step is implied. If specified, only those steps are allowed.
|
|
398
549
|
- **Valid Contexts**: If omitted, user is trapped in current context. If specified, can navigate to those contexts.
|
|
399
550
|
- **Single Context**: Must be named "default" for single-context workflows.
|
|
400
551
|
- **Function Restrictions**: Use `set_functions(["function_name"])` or `set_functions("none")` to control AI tool access.
|
|
401
552
|
|
|
402
|
-
|
|
553
|
+
#### Complete Example: Customer Support Workflow
|
|
403
554
|
|
|
404
555
|
```python
|
|
405
556
|
class SupportAgent(AgentBase):
|
|
406
557
|
def __init__(self):
|
|
407
558
|
super().__init__(name="Customer Support", route="/support")
|
|
408
559
|
|
|
560
|
+
# Set base prompt (required)
|
|
561
|
+
self.prompt_add_section("Role", "You are a professional customer support representative.")
|
|
562
|
+
self.prompt_add_section("Goal", "Provide excellent customer service using structured workflows.")
|
|
563
|
+
|
|
409
564
|
# Add skills for enhanced capabilities
|
|
410
565
|
self.add_skill("datetime")
|
|
411
566
|
self.add_skill("web_search", {"api_key": "your-key", "search_engine_id": "your-id"})
|
|
412
567
|
|
|
568
|
+
# Define support workflow contexts
|
|
413
569
|
contexts = self.define_contexts()
|
|
414
570
|
|
|
415
571
|
# Triage context
|
|
416
|
-
triage = contexts.
|
|
417
|
-
triage.
|
|
418
|
-
.add_section("
|
|
419
|
-
.
|
|
420
|
-
.add_bullets(["Be empathetic and professional", "Ask clarifying questions", "Categorize the issue"]) \
|
|
572
|
+
triage = contexts.add_context("triage")
|
|
573
|
+
triage.add_step("initial_greeting") \
|
|
574
|
+
.add_section("Current Task", "Understand the customer's issue and route them appropriately") \
|
|
575
|
+
.add_bullets("Questions to Ask", ["What problem are you experiencing?", "How urgent is this issue?", "Have you tried any troubleshooting steps?"]) \
|
|
421
576
|
.set_step_criteria("Issue type has been identified") \
|
|
422
577
|
.set_valid_contexts(["technical_support", "billing_support", "general_inquiry"])
|
|
423
578
|
|
|
424
579
|
# Technical support context
|
|
425
|
-
tech = contexts.
|
|
426
|
-
tech.
|
|
427
|
-
.add_section("
|
|
428
|
-
.add_section("
|
|
580
|
+
tech = contexts.add_context("technical_support")
|
|
581
|
+
tech.add_step("technical_diagnosis") \
|
|
582
|
+
.add_section("Current Task", "Help diagnose and resolve technical issues") \
|
|
583
|
+
.add_section("Available Tools", "Use web search to find solutions and datetime to check service windows") \
|
|
429
584
|
.set_functions(["web_search", "datetime"]) # Can search for solutions and check times \
|
|
430
585
|
.set_step_criteria("Technical issue is resolved or escalated") \
|
|
431
586
|
.set_valid_contexts(["triage"]) # Can return to triage
|
|
432
587
|
|
|
433
588
|
# Billing support context
|
|
434
|
-
billing = contexts.
|
|
435
|
-
billing.
|
|
589
|
+
billing = contexts.add_context("billing_support")
|
|
590
|
+
billing.add_step("billing_assistance") \
|
|
436
591
|
.set_text("I'll help you with your billing inquiry. Please provide your account details.") \
|
|
437
592
|
.set_functions("none") # No external tools for sensitive billing info \
|
|
438
593
|
.set_step_criteria("Billing issue is addressed") \
|
|
439
594
|
.set_valid_contexts(["triage"])
|
|
440
595
|
|
|
441
596
|
# General inquiry context
|
|
442
|
-
general = contexts.
|
|
443
|
-
general.
|
|
597
|
+
general = contexts.add_context("general_inquiry")
|
|
598
|
+
general.add_step("general_help") \
|
|
444
599
|
.set_text("I'm here to help with general questions. What can I assist you with?") \
|
|
445
600
|
.set_functions(["web_search", "datetime"]) # Full access to search and time \
|
|
446
601
|
.set_step_criteria("Inquiry has been answered") \
|
|
@@ -450,7 +605,7 @@ agent = SupportAgent()
|
|
|
450
605
|
agent.serve()
|
|
451
606
|
```
|
|
452
607
|
|
|
453
|
-
|
|
608
|
+
#### Benefits
|
|
454
609
|
|
|
455
610
|
- **Clear Structure**: Explicit workflow definition makes agent behavior predictable
|
|
456
611
|
- **Enhanced Control**: Fine-grained control over function access and navigation
|
|
@@ -460,76 +615,7 @@ agent.serve()
|
|
|
460
615
|
|
|
461
616
|
For detailed documentation and advanced examples, see [Contexts and Steps Guide](docs/contexts_guide.md).
|
|
462
617
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
### Basic Installation
|
|
466
|
-
|
|
467
|
-
```bash
|
|
468
|
-
pip install signalwire-agents
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
### Optional Search Functionality
|
|
472
|
-
|
|
473
|
-
The SDK includes optional local search capabilities that can be installed separately to avoid adding large dependencies to the base installation:
|
|
474
|
-
|
|
475
|
-
#### Search Installation Options
|
|
476
|
-
|
|
477
|
-
```bash
|
|
478
|
-
# Basic search (vector search + keyword search)
|
|
479
|
-
pip install signalwire-agents[search]
|
|
480
|
-
|
|
481
|
-
# Full search with document processing (PDF, DOCX, etc.)
|
|
482
|
-
pip install signalwire-agents[search-full]
|
|
483
|
-
|
|
484
|
-
# Advanced NLP features (includes spaCy)
|
|
485
|
-
pip install signalwire-agents[search-nlp]
|
|
486
|
-
|
|
487
|
-
# All search features
|
|
488
|
-
pip install signalwire-agents[search-all]
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
#### What Each Option Includes
|
|
492
|
-
|
|
493
|
-
| Option | Size | Features |
|
|
494
|
-
|--------|------|----------|
|
|
495
|
-
| `search` | ~500MB | Vector embeddings, keyword search, basic text processing |
|
|
496
|
-
| `search-full` | ~600MB | + PDF, DOCX, Excel, PowerPoint, HTML, Markdown processing |
|
|
497
|
-
| `search-nlp` | ~600MB | + Advanced spaCy NLP features |
|
|
498
|
-
| `search-all` | ~700MB | All search features combined |
|
|
499
|
-
|
|
500
|
-
#### Search Features
|
|
501
|
-
|
|
502
|
-
- **Local/Offline Search**: No external API dependencies
|
|
503
|
-
- **Hybrid Search**: Vector similarity + keyword search
|
|
504
|
-
- **Smart Document Processing**: Markdown, Python, PDF, DOCX, etc.
|
|
505
|
-
- **Multiple Languages**: English, Spanish, with extensible framework
|
|
506
|
-
- **CLI Tools**: Build search indexes from document directories
|
|
507
|
-
- **HTTP API**: Standalone or embedded search service
|
|
508
|
-
|
|
509
|
-
#### Usage Example
|
|
510
|
-
|
|
511
|
-
```python
|
|
512
|
-
# Only available with search extras installed
|
|
513
|
-
from signalwire_agents.search import IndexBuilder, SearchEngine
|
|
514
|
-
|
|
515
|
-
# Build search index
|
|
516
|
-
builder = IndexBuilder()
|
|
517
|
-
builder.build_index(
|
|
518
|
-
source_dir="./docs",
|
|
519
|
-
output_file="knowledge.swsearch",
|
|
520
|
-
file_types=['md', 'txt', 'pdf']
|
|
521
|
-
)
|
|
522
|
-
|
|
523
|
-
# Search documents
|
|
524
|
-
engine = SearchEngine("knowledge.swsearch")
|
|
525
|
-
results = engine.search(
|
|
526
|
-
query_vector=embeddings,
|
|
527
|
-
enhanced_text="search query",
|
|
528
|
-
count=5
|
|
529
|
-
)
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
## Quick Start
|
|
618
|
+
### Quick Start
|
|
533
619
|
|
|
534
620
|
```python
|
|
535
621
|
from signalwire_agents import AgentBase
|
|
@@ -544,10 +630,7 @@ class SimpleAgent(AgentBase):
|
|
|
544
630
|
self.prompt_add_section("Goal", body="Help users with basic questions.")
|
|
545
631
|
self.prompt_add_section("Instructions", bullets=["Be concise and clear."])
|
|
546
632
|
|
|
547
|
-
#
|
|
548
|
-
# self.setPersonality("You are a helpful assistant.")
|
|
549
|
-
# self.setGoal("Help users with basic questions.")
|
|
550
|
-
# self.setInstructions(["Be concise and clear."])
|
|
633
|
+
# Note: Use prompt_add_section() for all prompt configuration
|
|
551
634
|
|
|
552
635
|
@AgentBase.tool(
|
|
553
636
|
name="get_time",
|
|
@@ -565,65 +648,59 @@ if __name__ == "__main__":
|
|
|
565
648
|
agent.serve(host="0.0.0.0", port=8000)
|
|
566
649
|
```
|
|
567
650
|
|
|
568
|
-
|
|
651
|
+
### Customizing LLM Parameters
|
|
652
|
+
|
|
653
|
+
The SDK allows you to customize LLM parameters for both the main prompt and post-prompt, giving you fine control over the AI's behavior:
|
|
569
654
|
|
|
570
655
|
```python
|
|
571
656
|
from signalwire_agents import AgentBase
|
|
572
|
-
from signalwire_agents.core.function_result import SwaigFunctionResult
|
|
573
|
-
from signalwire_agents.core.state import FileStateManager
|
|
574
657
|
|
|
575
|
-
class
|
|
658
|
+
class PreciseAgent(AgentBase):
|
|
576
659
|
def __init__(self):
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
660
|
+
super().__init__(name="precise", route="/precise")
|
|
661
|
+
|
|
662
|
+
# Configure the agent's personality
|
|
663
|
+
self.prompt_add_section("Role", "You are a precise technical assistant.")
|
|
664
|
+
self.prompt_add_section("Instructions", "Provide accurate, detailed information.")
|
|
665
|
+
|
|
666
|
+
# Set custom LLM parameters for the main prompt
|
|
667
|
+
# These parameters are passed to the server which validates them based on the model
|
|
668
|
+
self.set_prompt_llm_params(
|
|
669
|
+
temperature=0.3, # Low temperature for more consistent responses
|
|
670
|
+
top_p=0.9, # Slightly reduced for focused responses
|
|
671
|
+
barge_confidence=0.7, # Moderate interruption threshold
|
|
672
|
+
presence_penalty=0.1, # Slight penalty for repetition
|
|
673
|
+
frequency_penalty=0.2 # Encourage varied vocabulary
|
|
585
674
|
)
|
|
586
675
|
|
|
587
|
-
#
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
# Custom tool for accessing and updating state
|
|
591
|
-
@AgentBase.tool(
|
|
592
|
-
name="save_preference",
|
|
593
|
-
description="Save a user preference",
|
|
594
|
-
parameters={
|
|
595
|
-
"preference_name": {
|
|
596
|
-
"type": "string",
|
|
597
|
-
"description": "Name of the preference to save"
|
|
598
|
-
},
|
|
599
|
-
"preference_value": {
|
|
600
|
-
"type": "string",
|
|
601
|
-
"description": "Value of the preference"
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
)
|
|
605
|
-
def save_preference(self, args, raw_data):
|
|
606
|
-
# Get the call ID from the raw data
|
|
607
|
-
call_id = raw_data.get("call_id")
|
|
676
|
+
# Set post-prompt for summaries
|
|
677
|
+
self.set_post_prompt("Provide a concise summary of the key points discussed.")
|
|
608
678
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
# Save the updated state
|
|
619
|
-
self.update_state(call_id, state)
|
|
620
|
-
|
|
621
|
-
return SwaigFunctionResult("Preference saved successfully")
|
|
622
|
-
else:
|
|
623
|
-
return SwaigFunctionResult("Could not save preference: No call ID")
|
|
679
|
+
# Different parameters for post-prompt (summaries should be even more focused)
|
|
680
|
+
self.set_post_prompt_llm_params(
|
|
681
|
+
temperature=0.2, # Very low for consistent summaries
|
|
682
|
+
top_p=0.85 # More focused token selection
|
|
683
|
+
)
|
|
684
|
+
|
|
685
|
+
agent = PreciseAgent()
|
|
686
|
+
agent.serve()
|
|
624
687
|
```
|
|
625
688
|
|
|
626
|
-
|
|
689
|
+
#### Common LLM Parameters
|
|
690
|
+
|
|
691
|
+
The SDK accepts any parameters which are passed to the server for validation based on the model. Common parameters include:
|
|
692
|
+
|
|
693
|
+
- **temperature**: Controls randomness. Lower = more focused, higher = more creative
|
|
694
|
+
- **top_p**: Nucleus sampling. Lower = more focused on likely tokens
|
|
695
|
+
- **barge_confidence**: ASR confidence to interrupt. Higher = harder to interrupt (main prompt only)
|
|
696
|
+
- **presence_penalty**: Topic diversity. Positive = new topics
|
|
697
|
+
- **frequency_penalty**: Repetition control. Positive = varied vocabulary
|
|
698
|
+
|
|
699
|
+
Note: No defaults are sent unless explicitly set. The server handles validation and applies appropriate defaults based on the model.
|
|
700
|
+
|
|
701
|
+
For more details on LLM parameter tuning, see [LLM Parameters Guide](docs/llm_parameters.md).
|
|
702
|
+
|
|
703
|
+
### Using Prefab Agents
|
|
627
704
|
|
|
628
705
|
```python
|
|
629
706
|
from signalwire_agents.prefabs import InfoGathererAgent
|
|
@@ -648,16 +725,16 @@ Available prefabs include:
|
|
|
648
725
|
- `SurveyAgent`: Conducts structured surveys with questions and rating scales
|
|
649
726
|
- `ReceptionistAgent`: Greets callers and transfers them to appropriate departments
|
|
650
727
|
|
|
651
|
-
|
|
728
|
+
### Dynamic Agent Configuration
|
|
652
729
|
|
|
653
730
|
Configure agents dynamically based on request parameters for multi-tenant applications, A/B testing, and personalization.
|
|
654
731
|
|
|
655
|
-
|
|
732
|
+
#### Static vs Dynamic Configuration
|
|
656
733
|
|
|
657
734
|
- **Static**: Agent configured once at startup (traditional approach)
|
|
658
735
|
- **Dynamic**: Agent configured fresh for each request based on parameters
|
|
659
736
|
|
|
660
|
-
|
|
737
|
+
#### Basic Example
|
|
661
738
|
|
|
662
739
|
```python
|
|
663
740
|
from signalwire_agents import AgentBase
|
|
@@ -702,7 +779,7 @@ class DynamicAgent(AgentBase):
|
|
|
702
779
|
# curl "http://localhost:3000/dynamic?tier=standard&language=en"
|
|
703
780
|
```
|
|
704
781
|
|
|
705
|
-
|
|
782
|
+
#### Use Cases
|
|
706
783
|
|
|
707
784
|
- **Multi-tenant SaaS**: Different configurations per customer/organization
|
|
708
785
|
- **A/B Testing**: Test different agent behaviors with different user groups
|
|
@@ -710,13 +787,55 @@ class DynamicAgent(AgentBase):
|
|
|
710
787
|
- **Localization**: Language and cultural adaptation based on user location
|
|
711
788
|
- **Dynamic Pricing**: Adjust features and capabilities based on subscription tiers
|
|
712
789
|
|
|
713
|
-
|
|
790
|
+
#### Preserving Dynamic State in SWAIG Callbacks
|
|
791
|
+
|
|
792
|
+
When using dynamic configuration to add skills or tools based on request parameters, there's a challenge: SWAIG webhook callbacks are separate HTTP requests that won't have the original query parameters. The SDK provides `add_swaig_query_params()` to solve this:
|
|
793
|
+
|
|
794
|
+
```python
|
|
795
|
+
class DynamicAgent(AgentBase):
|
|
796
|
+
def __init__(self):
|
|
797
|
+
super().__init__(name="dynamic-agent", route="/agent")
|
|
798
|
+
self.set_dynamic_config_callback(self.configure_per_request)
|
|
799
|
+
|
|
800
|
+
def configure_per_request(self, query_params, body_params, headers, agent):
|
|
801
|
+
tier = query_params.get('tier', 'basic')
|
|
802
|
+
region = query_params.get('region', 'us-east')
|
|
803
|
+
|
|
804
|
+
if tier == 'premium':
|
|
805
|
+
# Add premium skills dynamically
|
|
806
|
+
agent.add_skill('advanced_search', {
|
|
807
|
+
'api_key': 'your-api-key',
|
|
808
|
+
'num_results': 5
|
|
809
|
+
})
|
|
810
|
+
|
|
811
|
+
# IMPORTANT: Preserve parameters for SWAIG callbacks
|
|
812
|
+
agent.add_swaig_query_params({
|
|
813
|
+
'tier': tier,
|
|
814
|
+
'region': region
|
|
815
|
+
})
|
|
816
|
+
|
|
817
|
+
# Now when SignalWire calls the SWAIG webhook, these params
|
|
818
|
+
# will be included, triggering the same dynamic configuration
|
|
819
|
+
|
|
820
|
+
# Initial request: GET /agent?tier=premium®ion=eu-west
|
|
821
|
+
# SWAIG callback: POST /swaig/?tier=premium®ion=eu-west
|
|
822
|
+
# Result: Premium skills are available in both requests!
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
**Key Points:**
|
|
826
|
+
|
|
827
|
+
- **Problem**: Dynamically added skills/tools won't exist during SWAIG callbacks without the original request parameters
|
|
828
|
+
- **Solution**: Use `add_swaig_query_params()` to include critical parameters in all SWAIG webhook URLs
|
|
829
|
+
- **Clear State**: Use `clear_swaig_query_params()` if needed to reset parameters between requests
|
|
830
|
+
- **Token Safety**: The SDK automatically renames security tokens from `token` to `__token` to avoid parameter collisions
|
|
831
|
+
|
|
832
|
+
This ensures that any dynamic configuration based on request parameters is consistently applied across the initial SWML request and all subsequent SWAIG function callbacks.
|
|
714
833
|
|
|
715
834
|
For detailed documentation and advanced examples, see the [Agent Guide](docs/agent_guide.md#dynamic-agent-configuration).
|
|
716
835
|
|
|
717
|
-
|
|
836
|
+
### Configuration
|
|
718
837
|
|
|
719
|
-
|
|
838
|
+
#### Environment Variables
|
|
720
839
|
|
|
721
840
|
The SDK supports the following environment variables:
|
|
722
841
|
|
|
@@ -733,14 +852,14 @@ When the auth environment variables are set, they will be used for all agents in
|
|
|
733
852
|
|
|
734
853
|
To enable HTTPS directly (without a reverse proxy), set `SWML_SSL_ENABLED` to "true", provide valid paths to your certificate and key files, and specify your domain name.
|
|
735
854
|
|
|
736
|
-
|
|
855
|
+
### Testing
|
|
737
856
|
|
|
738
857
|
The SDK includes powerful CLI tools for development and testing:
|
|
739
858
|
|
|
740
859
|
- **`swaig-test`**: Comprehensive local testing and serverless environment simulation
|
|
741
860
|
- **`sw-search`**: Build local search indexes from document directories and search within them
|
|
742
861
|
|
|
743
|
-
|
|
862
|
+
#### Local Testing with swaig-test
|
|
744
863
|
|
|
745
864
|
Test your agents locally without deployment:
|
|
746
865
|
|
|
@@ -757,12 +876,16 @@ swaig-test examples/my_agent.py --list-tools
|
|
|
757
876
|
# Test SWAIG functions with CLI syntax
|
|
758
877
|
swaig-test examples/my_agent.py --exec get_weather --location "New York"
|
|
759
878
|
|
|
879
|
+
# Multi-agent support
|
|
880
|
+
swaig-test examples/multi_agent.py --route /agent-path --list-tools
|
|
881
|
+
swaig-test examples/multi_agent.py --agent-class AgentName --exec function_name
|
|
882
|
+
|
|
760
883
|
# Generate and inspect SWML documents
|
|
761
884
|
swaig-test examples/my_agent.py --dump-swml
|
|
762
|
-
swaig-test examples/my_agent.py --dump-swml --
|
|
885
|
+
swaig-test examples/my_agent.py --dump-swml --raw | jq '.'
|
|
763
886
|
```
|
|
764
887
|
|
|
765
|
-
|
|
888
|
+
#### Serverless Environment Simulation
|
|
766
889
|
|
|
767
890
|
Test your agents in simulated serverless environments without deployment:
|
|
768
891
|
|
|
@@ -795,7 +918,7 @@ swaig-test examples/my_agent.py --simulate-serverless azure_function \
|
|
|
795
918
|
--exec my_function
|
|
796
919
|
```
|
|
797
920
|
|
|
798
|
-
|
|
921
|
+
#### Environment Management
|
|
799
922
|
|
|
800
923
|
Use environment files for consistent testing across platforms:
|
|
801
924
|
|
|
@@ -817,7 +940,7 @@ swaig-test examples/my_agent.py --simulate-serverless lambda \
|
|
|
817
940
|
--env-file production.env --env DEBUG=true --dump-swml
|
|
818
941
|
```
|
|
819
942
|
|
|
820
|
-
|
|
943
|
+
#### Cross-Platform Testing
|
|
821
944
|
|
|
822
945
|
Test the same agent across multiple serverless platforms:
|
|
823
946
|
|
|
@@ -834,7 +957,7 @@ swaig-test examples/my_agent.py --simulate-serverless lambda --dump-swml | grep
|
|
|
834
957
|
swaig-test examples/my_agent.py --simulate-serverless cgi --cgi-host example.com --dump-swml | grep web_hook_url
|
|
835
958
|
```
|
|
836
959
|
|
|
837
|
-
|
|
960
|
+
#### Key Benefits
|
|
838
961
|
|
|
839
962
|
- **No Deployment Required**: Test serverless behavior locally
|
|
840
963
|
- **Environment Simulation**: Complete platform-specific environment variable setup
|
|
@@ -845,7 +968,7 @@ swaig-test examples/my_agent.py --simulate-serverless cgi --cgi-host example.com
|
|
|
845
968
|
|
|
846
969
|
For detailed testing documentation, see the [CLI Testing Guide](docs/cli_testing_guide.md).
|
|
847
970
|
|
|
848
|
-
|
|
971
|
+
### Documentation
|
|
849
972
|
|
|
850
973
|
The package includes comprehensive documentation in the `docs/` directory:
|
|
851
974
|
|
|
@@ -858,6 +981,12 @@ The package includes comprehensive documentation in the `docs/` directory:
|
|
|
858
981
|
|
|
859
982
|
These documents provide in-depth explanations of the features, APIs, and usage patterns.
|
|
860
983
|
|
|
984
|
+
</details
|
|
985
|
+
|
|
986
|
+
### ***[Read the official docs.](https://developer.signalwire.com/sdks/agents-sdk)***
|
|
987
|
+
|
|
988
|
+
---
|
|
989
|
+
|
|
861
990
|
## License
|
|
862
991
|
|
|
863
992
|
MIT
|