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