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
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) 2025 SignalWire
|
|
3
|
+
|
|
4
|
+
This file is part of the SignalWire AI Agents SDK.
|
|
5
|
+
|
|
6
|
+
Licensed under the MIT License.
|
|
7
|
+
See LICENSE file in the project root for full license information.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
API Ninjas Trivia Skill
|
|
12
|
+
|
|
13
|
+
A configurable skill for getting trivia questions from API Ninjas with customizable
|
|
14
|
+
categories and multiple tool instances.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from typing import Dict, Any, List
|
|
18
|
+
from signalwire_agents.core import SwaigFunctionResult
|
|
19
|
+
from signalwire_agents.core.skill_base import SkillBase
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ApiNinjasTriviaSkill(SkillBase):
|
|
23
|
+
"""
|
|
24
|
+
Skill for getting trivia questions from API Ninjas with configurable categories.
|
|
25
|
+
|
|
26
|
+
Supports multiple instances with different tool names and category combinations.
|
|
27
|
+
Uses DataMap for serverless execution with dynamic enum generation.
|
|
28
|
+
|
|
29
|
+
Configuration:
|
|
30
|
+
- tool_name: Custom name for the generated SWAIG function
|
|
31
|
+
- api_key: API Ninjas API key
|
|
32
|
+
- categories: Array of category strings to enable
|
|
33
|
+
|
|
34
|
+
Available categories:
|
|
35
|
+
- artliterature: Art and Literature
|
|
36
|
+
- language: Language
|
|
37
|
+
- sciencenature: Science and Nature
|
|
38
|
+
- general: General Knowledge
|
|
39
|
+
- fooddrink: Food and Drink
|
|
40
|
+
- peopleplaces: People and Places
|
|
41
|
+
- geography: Geography
|
|
42
|
+
- historyholidays: History and Holidays
|
|
43
|
+
- entertainment: Entertainment
|
|
44
|
+
- toysgames: Toys and Games
|
|
45
|
+
- music: Music
|
|
46
|
+
- mathematics: Mathematics
|
|
47
|
+
- religionmythology: Religion and Mythology
|
|
48
|
+
- sportsleisure: Sports and Leisure
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
agent.add_skill("api_ninjas_trivia", {
|
|
52
|
+
"tool_name": "get_science_trivia",
|
|
53
|
+
"api_key": "your_api_key",
|
|
54
|
+
"categories": ["sciencenature", "mathematics", "general"]
|
|
55
|
+
})
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
SKILL_NAME = "api_ninjas_trivia"
|
|
59
|
+
SKILL_DESCRIPTION = "Get trivia questions from API Ninjas"
|
|
60
|
+
SUPPORTS_MULTIPLE_INSTANCES = True
|
|
61
|
+
REQUIRED_ENV_VARS = [] # API key can be passed via params
|
|
62
|
+
|
|
63
|
+
# Valid API Ninjas trivia categories with human-readable descriptions
|
|
64
|
+
VALID_CATEGORIES = {
|
|
65
|
+
"artliterature": "Art and Literature",
|
|
66
|
+
"language": "Language",
|
|
67
|
+
"sciencenature": "Science and Nature",
|
|
68
|
+
"general": "General Knowledge",
|
|
69
|
+
"fooddrink": "Food and Drink",
|
|
70
|
+
"peopleplaces": "People and Places",
|
|
71
|
+
"geography": "Geography",
|
|
72
|
+
"historyholidays": "History and Holidays",
|
|
73
|
+
"entertainment": "Entertainment",
|
|
74
|
+
"toysgames": "Toys and Games",
|
|
75
|
+
"music": "Music",
|
|
76
|
+
"mathematics": "Mathematics",
|
|
77
|
+
"religionmythology": "Religion and Mythology",
|
|
78
|
+
"sportsleisure": "Sports and Leisure"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
def __init__(self, agent, params: Dict[str, Any] = None):
|
|
82
|
+
"""
|
|
83
|
+
Initialize the skill with configuration parameters.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
agent: The agent instance this skill belongs to
|
|
87
|
+
params: Configuration dictionary containing:
|
|
88
|
+
- tool_name: Custom tool name (default: "get_trivia")
|
|
89
|
+
- api_key: API Ninjas API key (required)
|
|
90
|
+
- categories: Array of category strings (default: all categories)
|
|
91
|
+
"""
|
|
92
|
+
super().__init__(agent, params)
|
|
93
|
+
|
|
94
|
+
# Extract configuration
|
|
95
|
+
self.tool_name = self.params.get('tool_name', 'get_trivia')
|
|
96
|
+
self.api_key = self.params.get('api_key')
|
|
97
|
+
self.categories = self.params.get('categories', list(self.VALID_CATEGORIES.keys()))
|
|
98
|
+
|
|
99
|
+
# Validate configuration
|
|
100
|
+
self._validate_config()
|
|
101
|
+
|
|
102
|
+
def _validate_config(self):
|
|
103
|
+
"""Validate the skill configuration."""
|
|
104
|
+
# Validate API key
|
|
105
|
+
if not self.api_key or not isinstance(self.api_key, str):
|
|
106
|
+
raise ValueError("api_key parameter is required and must be a non-empty string")
|
|
107
|
+
|
|
108
|
+
# Validate categories
|
|
109
|
+
if not isinstance(self.categories, list) or len(self.categories) == 0:
|
|
110
|
+
raise ValueError("categories parameter must be a non-empty list")
|
|
111
|
+
|
|
112
|
+
# Validate each category
|
|
113
|
+
for i, category in enumerate(self.categories):
|
|
114
|
+
if not isinstance(category, str):
|
|
115
|
+
raise ValueError(f"Category {i} must be a string")
|
|
116
|
+
if category not in self.VALID_CATEGORIES:
|
|
117
|
+
valid_cats = ', '.join(self.VALID_CATEGORIES.keys())
|
|
118
|
+
raise ValueError(f"Category '{category}' is not valid. Valid categories: {valid_cats}")
|
|
119
|
+
|
|
120
|
+
def setup(self) -> bool:
|
|
121
|
+
"""
|
|
122
|
+
Setup the skill - validates API key is available.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
True if setup successful
|
|
126
|
+
"""
|
|
127
|
+
# API key validation already done in _validate_config
|
|
128
|
+
return True
|
|
129
|
+
|
|
130
|
+
def register_tools(self) -> None:
|
|
131
|
+
"""Register SWAIG tools with the agent"""
|
|
132
|
+
tools = self.get_tools()
|
|
133
|
+
for tool in tools:
|
|
134
|
+
# Merge any swaig_fields from params into the tool
|
|
135
|
+
if self.swaig_fields:
|
|
136
|
+
tool.update(self.swaig_fields)
|
|
137
|
+
self.agent.register_swaig_function(tool)
|
|
138
|
+
|
|
139
|
+
def get_instance_key(self) -> str:
|
|
140
|
+
"""
|
|
141
|
+
Generate a unique instance key for this skill configuration.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Unique key combining skill name and tool name
|
|
145
|
+
"""
|
|
146
|
+
return f"{self.SKILL_NAME}_{self.tool_name}"
|
|
147
|
+
|
|
148
|
+
def get_tools(self) -> List[Dict[str, Any]]:
|
|
149
|
+
"""
|
|
150
|
+
Generate the SWAIG tool with DataMap webhook.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
List containing the generated tool configuration
|
|
154
|
+
"""
|
|
155
|
+
# Build enum values and descriptions
|
|
156
|
+
enum_values = []
|
|
157
|
+
descriptions = []
|
|
158
|
+
|
|
159
|
+
for category in self.categories:
|
|
160
|
+
enum_values.append(category)
|
|
161
|
+
descriptions.append(f"{category}: {self.VALID_CATEGORIES[category]}")
|
|
162
|
+
|
|
163
|
+
# Build parameter description
|
|
164
|
+
description = "Category for trivia question. Options: " + "; ".join(descriptions)
|
|
165
|
+
|
|
166
|
+
# Create the tool configuration with DataMap webhook
|
|
167
|
+
tool = {
|
|
168
|
+
"function": self.tool_name,
|
|
169
|
+
"description": f"Get trivia questions for {self.tool_name.replace('_', ' ')}",
|
|
170
|
+
"parameters": {
|
|
171
|
+
"type": "object",
|
|
172
|
+
"properties": {
|
|
173
|
+
"category": {
|
|
174
|
+
"type": "string",
|
|
175
|
+
"description": description,
|
|
176
|
+
"enum": enum_values
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"required": ["category"]
|
|
180
|
+
},
|
|
181
|
+
"data_map": {
|
|
182
|
+
"webhooks": [
|
|
183
|
+
{
|
|
184
|
+
"url": "https://api.api-ninjas.com/v1/trivia?category=%{args.category}",
|
|
185
|
+
"method": "GET",
|
|
186
|
+
"headers": {
|
|
187
|
+
"X-Api-Key": self.api_key
|
|
188
|
+
},
|
|
189
|
+
"output": SwaigFunctionResult(
|
|
190
|
+
"Category %{array[0].category} question: %{array[0].question} Answer: %{array[0].answer}, be sure to give the user time to answer before saying the answer."
|
|
191
|
+
).to_dict()
|
|
192
|
+
}
|
|
193
|
+
],
|
|
194
|
+
"error_keys": ["error"],
|
|
195
|
+
"output": SwaigFunctionResult(
|
|
196
|
+
"Sorry, I cannot get trivia questions right now. Please try again later."
|
|
197
|
+
).to_dict()
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return [tool]
|
|
202
|
+
|
|
203
|
+
@classmethod
|
|
204
|
+
def get_parameter_schema(cls) -> Dict[str, Dict[str, Any]]:
|
|
205
|
+
"""
|
|
206
|
+
Get the parameter schema for the API Ninjas Trivia skill.
|
|
207
|
+
|
|
208
|
+
Returns parameter definitions for GUI configuration.
|
|
209
|
+
"""
|
|
210
|
+
schema = super().get_parameter_schema()
|
|
211
|
+
|
|
212
|
+
# Build categories enum description
|
|
213
|
+
category_options = []
|
|
214
|
+
for key, desc in cls.VALID_CATEGORIES.items():
|
|
215
|
+
category_options.append(f"{key} ({desc})")
|
|
216
|
+
|
|
217
|
+
schema.update({
|
|
218
|
+
"api_key": {
|
|
219
|
+
"type": "string",
|
|
220
|
+
"description": "API Ninjas API key",
|
|
221
|
+
"required": True,
|
|
222
|
+
"hidden": True,
|
|
223
|
+
"env_var": "API_NINJAS_KEY"
|
|
224
|
+
},
|
|
225
|
+
"categories": {
|
|
226
|
+
"type": "array",
|
|
227
|
+
"description": "List of trivia categories to enable. Available: " + ", ".join(category_options),
|
|
228
|
+
"default": list(cls.VALID_CATEGORIES.keys()),
|
|
229
|
+
"required": False,
|
|
230
|
+
"items": {
|
|
231
|
+
"type": "string",
|
|
232
|
+
"enum": list(cls.VALID_CATEGORIES.keys())
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
return schema
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# DataSphere Skill
|
|
2
|
+
|
|
3
|
+
The datasphere skill provides knowledge search capabilities using SignalWire DataSphere's RAG (Retrieval-Augmented Generation) stack. It allows agents to search through uploaded documents and knowledge bases to find relevant information.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- SignalWire DataSphere integration for knowledge search
|
|
8
|
+
- Vector-based similarity search with configurable distance thresholds
|
|
9
|
+
- Multi-language support and synonym expansion
|
|
10
|
+
- Tag-based filtering for targeted searches
|
|
11
|
+
- Custom no-results messages with query placeholders
|
|
12
|
+
- **Multiple instance support** - search different knowledge bases with different configurations
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- **Packages**: `requests`
|
|
17
|
+
- **SignalWire Account**: DataSphere-enabled space with uploaded documents
|
|
18
|
+
|
|
19
|
+
## Parameters
|
|
20
|
+
|
|
21
|
+
### Required Parameters
|
|
22
|
+
|
|
23
|
+
- `space_name` (string): SignalWire space name
|
|
24
|
+
- `project_id` (string): SignalWire project ID
|
|
25
|
+
- `token` (string): SignalWire authentication token
|
|
26
|
+
- `document_id` (string): DataSphere document ID to search
|
|
27
|
+
|
|
28
|
+
### Optional Parameters
|
|
29
|
+
|
|
30
|
+
- `count` (integer, default: 1): Number of search results to return
|
|
31
|
+
- `distance` (float, default: 3.0): Distance threshold for search matching (lower = more similar)
|
|
32
|
+
- `tags` (list): List of tags to filter search results
|
|
33
|
+
- `language` (string): Language code to limit search (e.g., "en", "es")
|
|
34
|
+
- `pos_to_expand` (list): Parts of speech for synonym expansion (e.g., ["NOUN", "VERB"])
|
|
35
|
+
- `max_synonyms` (integer): Maximum number of synonyms to use for each word
|
|
36
|
+
- `tool_name` (string, default: "search_knowledge"): Custom name for the search tool (enables multiple instances)
|
|
37
|
+
- `no_results_message` (string): Custom message when no results are found
|
|
38
|
+
- Default: "I couldn't find any relevant information for '{query}' in the knowledge base. Try rephrasing your question or asking about a different topic."
|
|
39
|
+
- Use `{query}` as placeholder for the search query
|
|
40
|
+
|
|
41
|
+
### Advanced Parameters
|
|
42
|
+
|
|
43
|
+
- `swaig_fields` (dict): Additional SWAIG function configuration
|
|
44
|
+
- `secure` (boolean): Override security settings
|
|
45
|
+
- `fillers` (dict): Language-specific filler phrases during search
|
|
46
|
+
- Any other SWAIG function parameters
|
|
47
|
+
|
|
48
|
+
## Tools Created
|
|
49
|
+
|
|
50
|
+
- **Default**: `search_knowledge` - Search the knowledge base for information
|
|
51
|
+
- **Custom**: Uses the `tool_name` parameter value
|
|
52
|
+
|
|
53
|
+
## Usage Examples
|
|
54
|
+
|
|
55
|
+
### Basic Usage
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
# Minimal configuration
|
|
59
|
+
agent.add_skill("datasphere", {
|
|
60
|
+
"space_name": "my-space",
|
|
61
|
+
"project_id": "my-project-id",
|
|
62
|
+
"token": "my-token",
|
|
63
|
+
"document_id": "my-document-id"
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Advanced Configuration
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
# Comprehensive search with filtering
|
|
71
|
+
agent.add_skill("datasphere", {
|
|
72
|
+
"space_name": "my-space",
|
|
73
|
+
"project_id": "my-project-id",
|
|
74
|
+
"token": "my-token",
|
|
75
|
+
"document_id": "my-document-id",
|
|
76
|
+
"count": 3,
|
|
77
|
+
"distance": 5.0,
|
|
78
|
+
"tags": ["FAQ", "Support"],
|
|
79
|
+
"language": "en",
|
|
80
|
+
"pos_to_expand": ["NOUN", "VERB"],
|
|
81
|
+
"max_synonyms": 3,
|
|
82
|
+
"no_results_message": "I couldn't find information about '{query}' in our support documentation."
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Multiple Instances
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
# Product documentation search
|
|
90
|
+
agent.add_skill("datasphere", {
|
|
91
|
+
"space_name": "my-space",
|
|
92
|
+
"project_id": "my-project-id",
|
|
93
|
+
"token": "my-token",
|
|
94
|
+
"document_id": "product-docs-id",
|
|
95
|
+
"tool_name": "search_product_docs",
|
|
96
|
+
"tags": ["Products", "Features"],
|
|
97
|
+
"count": 2
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
# Support knowledge base search
|
|
101
|
+
agent.add_skill("datasphere", {
|
|
102
|
+
"space_name": "my-space",
|
|
103
|
+
"project_id": "my-project-id",
|
|
104
|
+
"token": "my-token",
|
|
105
|
+
"document_id": "support-kb-id",
|
|
106
|
+
"tool_name": "search_support",
|
|
107
|
+
"tags": ["Support", "Troubleshooting"],
|
|
108
|
+
"count": 3,
|
|
109
|
+
"distance": 4.0
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
# Policy and procedure search
|
|
113
|
+
agent.add_skill("datasphere", {
|
|
114
|
+
"space_name": "my-space",
|
|
115
|
+
"project_id": "my-project-id",
|
|
116
|
+
"token": "my-token",
|
|
117
|
+
"document_id": "policies-id",
|
|
118
|
+
"tool_name": "search_policies",
|
|
119
|
+
"tags": ["Policy", "Compliance"],
|
|
120
|
+
"count": 1,
|
|
121
|
+
"distance": 2.0
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### With Custom Fillers
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
agent.add_skill("datasphere", {
|
|
129
|
+
"space_name": "my-space",
|
|
130
|
+
"project_id": "my-project-id",
|
|
131
|
+
"token": "my-token",
|
|
132
|
+
"document_id": "my-document-id",
|
|
133
|
+
"swaig_fields": {
|
|
134
|
+
"fillers": {
|
|
135
|
+
"en-US": [
|
|
136
|
+
"Searching our knowledge base...",
|
|
137
|
+
"Looking through our documentation...",
|
|
138
|
+
"Checking our information database..."
|
|
139
|
+
],
|
|
140
|
+
"es-ES": [
|
|
141
|
+
"Buscando en nuestra base de conocimientos...",
|
|
142
|
+
"Revisando nuestra documentación..."
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## How It Works
|
|
150
|
+
|
|
151
|
+
1. **Vector Search**: Uses semantic similarity to find relevant content chunks
|
|
152
|
+
2. **Distance Filtering**: Only returns results within the specified distance threshold
|
|
153
|
+
3. **Tag Filtering**: Optionally filters results by document tags
|
|
154
|
+
4. **Language Processing**: Supports synonym expansion and language-specific search
|
|
155
|
+
5. **Format Results**: Presents found content with metadata and relevance scores
|
|
156
|
+
|
|
157
|
+
## Multiple Instance Support
|
|
158
|
+
|
|
159
|
+
The datasphere skill supports multiple instances, allowing you to:
|
|
160
|
+
|
|
161
|
+
- Search different knowledge bases/documents with one agent
|
|
162
|
+
- Use different search parameters per knowledge domain
|
|
163
|
+
- Create specialized search tools (`search_products`, `search_support`, etc.)
|
|
164
|
+
- Apply different tag filtering per instance
|
|
165
|
+
- Customize distance thresholds based on content type
|
|
166
|
+
|
|
167
|
+
Each instance is uniquely identified by its `search_engine_id` (derived from space/project/document) and `tool_name` combination.
|
|
168
|
+
|
|
169
|
+
## Parameters Explained
|
|
170
|
+
|
|
171
|
+
### Distance Threshold
|
|
172
|
+
- **Lower values** (1.0-2.0): Very strict matching, only highly similar content
|
|
173
|
+
- **Medium values** (3.0-4.0): Balanced matching, good for most use cases
|
|
174
|
+
- **Higher values** (5.0+): More permissive matching, broader results
|
|
175
|
+
|
|
176
|
+
### Count vs Distance
|
|
177
|
+
- Use higher `count` with lower `distance` for precise, multiple results
|
|
178
|
+
- Use lower `count` with higher `distance` for broader, fewer results
|
|
179
|
+
|
|
180
|
+
### Tags Usage
|
|
181
|
+
- Pre-tag your documents in DataSphere with categories
|
|
182
|
+
- Use tags to create domain-specific searches (e.g., ["FAQ"], ["Legal"], ["Technical"])
|
|
183
|
+
|
|
184
|
+
### Language Support
|
|
185
|
+
- Specify language codes for multilingual knowledge bases
|
|
186
|
+
- Helps improve search accuracy for non-English content
|
|
187
|
+
|
|
188
|
+
## Error Handling
|
|
189
|
+
|
|
190
|
+
- **No Results**: Returns custom `no_results_message` with query placeholder
|
|
191
|
+
- **API Issues**: Returns friendly error message for authentication/connectivity issues
|
|
192
|
+
- **Invalid Documents**: Gracefully handles missing or inaccessible documents
|
|
193
|
+
- **Timeout Protection**: Built-in 30-second timeout for API requests
|
|
194
|
+
|
|
195
|
+
## Best Practices
|
|
196
|
+
|
|
197
|
+
1. **Document Organization**: Use meaningful tags when uploading to DataSphere
|
|
198
|
+
2. **Distance Tuning**: Start with default 3.0, adjust based on result quality
|
|
199
|
+
3. **Multiple Instances**: Separate different knowledge domains for better results
|
|
200
|
+
4. **Language Consistency**: Specify language when dealing with multilingual content
|
|
201
|
+
5. **Result Count**: Balance between comprehensive answers (higher count) and response speed (lower count)
|
|
202
|
+
|
|
203
|
+
## Setting Up DataSphere
|
|
204
|
+
|
|
205
|
+
1. Access your SignalWire space
|
|
206
|
+
2. Enable DataSphere in your space settings
|
|
207
|
+
3. Upload documents through the DataSphere interface
|
|
208
|
+
4. Note the document IDs for use in skill configuration
|
|
209
|
+
5. Apply appropriate tags during document upload
|
|
210
|
+
6. Get your project ID and token from SignalWire console
|
|
@@ -26,6 +26,88 @@ class DataSphereSkill(SkillBase):
|
|
|
26
26
|
# Enable multiple instances support
|
|
27
27
|
SUPPORTS_MULTIPLE_INSTANCES = True
|
|
28
28
|
|
|
29
|
+
@classmethod
|
|
30
|
+
def get_parameter_schema(cls) -> Dict[str, Dict[str, Any]]:
|
|
31
|
+
"""Get parameter schema for DataSphere skill"""
|
|
32
|
+
schema = super().get_parameter_schema()
|
|
33
|
+
schema.update({
|
|
34
|
+
"space_name": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "SignalWire space name (e.g., 'mycompany' from mycompany.signalwire.com)",
|
|
37
|
+
"required": True
|
|
38
|
+
},
|
|
39
|
+
"project_id": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"description": "SignalWire project ID",
|
|
42
|
+
"required": True,
|
|
43
|
+
"env_var": "SIGNALWIRE_PROJECT_ID"
|
|
44
|
+
},
|
|
45
|
+
"token": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"description": "SignalWire API token",
|
|
48
|
+
"required": True,
|
|
49
|
+
"hidden": True,
|
|
50
|
+
"env_var": "SIGNALWIRE_TOKEN"
|
|
51
|
+
},
|
|
52
|
+
"document_id": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"description": "DataSphere document ID to search within",
|
|
55
|
+
"required": True
|
|
56
|
+
},
|
|
57
|
+
"count": {
|
|
58
|
+
"type": "integer",
|
|
59
|
+
"description": "Number of search results to return",
|
|
60
|
+
"default": 1,
|
|
61
|
+
"required": False,
|
|
62
|
+
"minimum": 1,
|
|
63
|
+
"maximum": 10
|
|
64
|
+
},
|
|
65
|
+
"distance": {
|
|
66
|
+
"type": "number",
|
|
67
|
+
"description": "Maximum distance threshold for results (lower is more relevant)",
|
|
68
|
+
"default": 3.0,
|
|
69
|
+
"required": False,
|
|
70
|
+
"minimum": 0.0,
|
|
71
|
+
"maximum": 10.0
|
|
72
|
+
},
|
|
73
|
+
"tags": {
|
|
74
|
+
"type": "array",
|
|
75
|
+
"description": "Tags to filter search results",
|
|
76
|
+
"required": False,
|
|
77
|
+
"items": {
|
|
78
|
+
"type": "string"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"language": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"description": "Language code for query expansion (e.g., 'en', 'es')",
|
|
84
|
+
"required": False
|
|
85
|
+
},
|
|
86
|
+
"pos_to_expand": {
|
|
87
|
+
"type": "array",
|
|
88
|
+
"description": "Parts of speech to expand with synonyms",
|
|
89
|
+
"required": False,
|
|
90
|
+
"items": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"enum": ["NOUN", "VERB", "ADJ", "ADV"]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"max_synonyms": {
|
|
96
|
+
"type": "integer",
|
|
97
|
+
"description": "Maximum number of synonyms to use for query expansion",
|
|
98
|
+
"required": False,
|
|
99
|
+
"minimum": 1,
|
|
100
|
+
"maximum": 10
|
|
101
|
+
},
|
|
102
|
+
"no_results_message": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"description": "Message to return when no results are found",
|
|
105
|
+
"default": "I couldn't find any relevant information for '{query}' in the knowledge base. Try rephrasing your question or asking about a different topic.",
|
|
106
|
+
"required": False
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
return schema
|
|
110
|
+
|
|
29
111
|
def get_instance_key(self) -> str:
|
|
30
112
|
"""
|
|
31
113
|
Get the key used to track this skill instance
|
|
@@ -77,7 +159,7 @@ class DataSphereSkill(SkillBase):
|
|
|
77
159
|
|
|
78
160
|
def register_tools(self) -> None:
|
|
79
161
|
"""Register knowledge search tool with the agent"""
|
|
80
|
-
self.
|
|
162
|
+
self.define_tool(
|
|
81
163
|
name=self.tool_name,
|
|
82
164
|
description="Search the knowledge base for information on any topic and return relevant results",
|
|
83
165
|
parameters={
|
|
@@ -86,8 +168,7 @@ class DataSphereSkill(SkillBase):
|
|
|
86
168
|
"description": "The search query - what information you're looking for in the knowledge base"
|
|
87
169
|
}
|
|
88
170
|
},
|
|
89
|
-
handler=self._search_knowledge_handler
|
|
90
|
-
**self.swaig_fields
|
|
171
|
+
handler=self._search_knowledge_handler
|
|
91
172
|
)
|
|
92
173
|
|
|
93
174
|
def _search_knowledge_handler(self, args, raw_data):
|