signalwire-agents 0.1.13__py3-none-any.whl → 0.1.14__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 +28 -11
- signalwire_agents/cli/build_search.py +174 -14
- signalwire_agents/cli/test_swaig.py +159 -114
- signalwire_agents/core/agent_base.py +7 -36
- signalwire_agents/core/logging_config.py +143 -14
- signalwire_agents/core/skill_manager.py +2 -2
- signalwire_agents/core/swml_service.py +5 -45
- signalwire_agents/search/document_processor.py +275 -14
- signalwire_agents/search/index_builder.py +45 -10
- signalwire_agents/search/query_processor.py +27 -12
- signalwire_agents/skills/__init__.py +1 -1
- signalwire_agents/skills/native_vector_search/skill.py +24 -6
- signalwire_agents/skills/registry.py +58 -42
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-0.1.14.dist-info}/METADATA +1 -1
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-0.1.14.dist-info}/RECORD +20 -20
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-0.1.14.dist-info}/entry_points.txt +1 -1
- {signalwire_agents-0.1.13.data → signalwire_agents-0.1.14.data}/data/schema.json +0 -0
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-0.1.14.dist-info}/WHEEL +0 -0
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-0.1.14.dist-info}/licenses/LICENSE +0 -0
- {signalwire_agents-0.1.13.dist-info → signalwire_agents-0.1.14.dist-info}/top_level.txt +0 -0
@@ -19,42 +19,30 @@ from signalwire_agents.core.skill_base import SkillBase
|
|
19
19
|
from signalwire_agents.core.logging_config import get_logger
|
20
20
|
|
21
21
|
class SkillRegistry:
|
22
|
-
"""Global registry for
|
22
|
+
"""Global registry for on-demand skill loading"""
|
23
23
|
|
24
24
|
def __init__(self):
|
25
25
|
self._skills: Dict[str, Type[SkillBase]] = {}
|
26
26
|
self.logger = get_logger("skill_registry")
|
27
|
-
|
27
|
+
# Remove _discovered flag since we're not doing discovery anymore
|
28
28
|
|
29
|
-
def
|
30
|
-
"""
|
31
|
-
if self.
|
32
|
-
return
|
29
|
+
def _load_skill_on_demand(self, skill_name: str) -> Optional[Type[SkillBase]]:
|
30
|
+
"""Load a skill on-demand by name"""
|
31
|
+
if skill_name in self._skills:
|
32
|
+
return self._skills[skill_name]
|
33
33
|
|
34
|
-
#
|
34
|
+
# Try to load the skill from its expected directory
|
35
35
|
skills_dir = Path(__file__).parent
|
36
|
-
|
37
|
-
# Scan for skill directories
|
38
|
-
for item in skills_dir.iterdir():
|
39
|
-
if item.is_dir() and not item.name.startswith('__'):
|
40
|
-
self._load_skill_from_directory(item)
|
41
|
-
|
42
|
-
self._discovered = True
|
43
|
-
|
44
|
-
# Check if we're in raw mode (used by swaig-test --raw) and suppress logging
|
45
|
-
is_raw_mode = "--raw" in sys.argv
|
46
|
-
if not is_raw_mode:
|
47
|
-
self.logger.info(f"Discovered {len(self._skills)} skills")
|
48
|
-
|
49
|
-
def _load_skill_from_directory(self, skill_dir: Path) -> None:
|
50
|
-
"""Load a skill from a directory"""
|
36
|
+
skill_dir = skills_dir / skill_name
|
51
37
|
skill_file = skill_dir / "skill.py"
|
38
|
+
|
52
39
|
if not skill_file.exists():
|
53
|
-
|
40
|
+
self.logger.debug(f"Skill '{skill_name}' not found at {skill_file}")
|
41
|
+
return None
|
54
42
|
|
55
43
|
try:
|
56
44
|
# Import the skill module
|
57
|
-
module_name = f"signalwire_agents.skills.{
|
45
|
+
module_name = f"signalwire_agents.skills.{skill_name}.skill"
|
58
46
|
spec = importlib.util.spec_from_file_location(module_name, skill_file)
|
59
47
|
module = importlib.util.module_from_spec(spec)
|
60
48
|
spec.loader.exec_module(module)
|
@@ -64,12 +52,27 @@ class SkillRegistry:
|
|
64
52
|
if (inspect.isclass(obj) and
|
65
53
|
issubclass(obj, SkillBase) and
|
66
54
|
obj != SkillBase and
|
67
|
-
obj.SKILL_NAME
|
55
|
+
obj.SKILL_NAME == skill_name): # Match exact skill name
|
68
56
|
|
69
57
|
self.register_skill(obj)
|
58
|
+
return obj
|
59
|
+
|
60
|
+
self.logger.warning(f"No skill class found with name '{skill_name}' in {skill_file}")
|
61
|
+
return None
|
70
62
|
|
71
63
|
except Exception as e:
|
72
|
-
self.logger.error(f"Failed to load skill from {
|
64
|
+
self.logger.error(f"Failed to load skill '{skill_name}' from {skill_file}: {e}")
|
65
|
+
return None
|
66
|
+
|
67
|
+
def discover_skills(self) -> None:
|
68
|
+
"""Deprecated: Skills are now loaded on-demand"""
|
69
|
+
# Keep this method for backwards compatibility but make it a no-op
|
70
|
+
pass
|
71
|
+
|
72
|
+
def _load_skill_from_directory(self, skill_dir: Path) -> None:
|
73
|
+
"""Deprecated: Skills are now loaded on-demand"""
|
74
|
+
# Keep this method for backwards compatibility but make it a no-op
|
75
|
+
pass
|
73
76
|
|
74
77
|
def register_skill(self, skill_class: Type[SkillBase]) -> None:
|
75
78
|
"""Register a skill class"""
|
@@ -81,24 +84,37 @@ class SkillRegistry:
|
|
81
84
|
self.logger.debug(f"Registered skill '{skill_class.SKILL_NAME}'")
|
82
85
|
|
83
86
|
def get_skill_class(self, skill_name: str) -> Optional[Type[SkillBase]]:
|
84
|
-
"""Get skill class by name"""
|
85
|
-
|
86
|
-
|
87
|
+
"""Get skill class by name, loading on-demand if needed"""
|
88
|
+
# First check if already loaded
|
89
|
+
if skill_name in self._skills:
|
90
|
+
return self._skills[skill_name]
|
91
|
+
|
92
|
+
# Try to load on-demand
|
93
|
+
return self._load_skill_on_demand(skill_name)
|
87
94
|
|
88
95
|
def list_skills(self) -> List[Dict[str, str]]:
|
89
|
-
"""List all
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
"
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
96
|
+
"""List all available skills by scanning directories (only when explicitly requested)"""
|
97
|
+
# Only scan when this method is explicitly called (e.g., for CLI tools)
|
98
|
+
skills_dir = Path(__file__).parent
|
99
|
+
available_skills = []
|
100
|
+
|
101
|
+
for item in skills_dir.iterdir():
|
102
|
+
if item.is_dir() and not item.name.startswith('__'):
|
103
|
+
skill_file = item / "skill.py"
|
104
|
+
if skill_file.exists():
|
105
|
+
# Try to load the skill to get its metadata
|
106
|
+
skill_class = self._load_skill_on_demand(item.name)
|
107
|
+
if skill_class:
|
108
|
+
available_skills.append({
|
109
|
+
"name": skill_class.SKILL_NAME,
|
110
|
+
"description": skill_class.SKILL_DESCRIPTION,
|
111
|
+
"version": skill_class.SKILL_VERSION,
|
112
|
+
"required_packages": skill_class.REQUIRED_PACKAGES,
|
113
|
+
"required_env_vars": skill_class.REQUIRED_ENV_VARS,
|
114
|
+
"supports_multiple_instances": skill_class.SUPPORTS_MULTIPLE_INSTANCES
|
115
|
+
})
|
116
|
+
|
117
|
+
return available_skills
|
102
118
|
|
103
119
|
# Global registry instance
|
104
120
|
skill_registry = SkillRegistry()
|
@@ -1,23 +1,23 @@
|
|
1
|
-
signalwire_agents/__init__.py,sha256=
|
1
|
+
signalwire_agents/__init__.py,sha256=VdzDfggQq5yncBmgKKO7HsQH2nolhgdHMlLChwu5kyg,2707
|
2
2
|
signalwire_agents/agent_server.py,sha256=3Or8rIMAqW750V-XitBUMgOpW9BAIXmKXoGq7LkejAA,24988
|
3
3
|
signalwire_agents/schema.json,sha256=M8Mn6pQda2P9jhbmkALrLr1wt-fRuhYRqdmEi9Rbhqk,178075
|
4
4
|
signalwire_agents/cli/__init__.py,sha256=Iy2BfWDWBEZoA1cyHTDsooBSVMx4vH5Ddhr3sEuFe8c,197
|
5
|
-
signalwire_agents/cli/build_search.py,sha256=
|
6
|
-
signalwire_agents/cli/test_swaig.py,sha256=
|
5
|
+
signalwire_agents/cli/build_search.py,sha256=PnGoIZVfIbSF21rb0m0_ceIL-8lJx59_qXrrl8l2yBE,22340
|
6
|
+
signalwire_agents/cli/test_swaig.py,sha256=CqfdBWE8_fiFnFWHbv9ouU1eUA_rGUUHwyOf_iUaZFU,101851
|
7
7
|
signalwire_agents/core/__init__.py,sha256=mVDLbpq1pg_WwiqsQR28NNZwJ6-VUXFIfg-vN7pk0ew,806
|
8
|
-
signalwire_agents/core/agent_base.py,sha256=
|
8
|
+
signalwire_agents/core/agent_base.py,sha256=F4ZxvFHK6FDs-jIaYSqua8QWvnoKA9wOeuomxnJO20g,140489
|
9
9
|
signalwire_agents/core/contexts.py,sha256=h7hra4xoiKAUdVyJhcKggl8X9EoqwTVWBmNMp-sEsuc,9598
|
10
10
|
signalwire_agents/core/data_map.py,sha256=U-HLEZQomWf-UI0-nLAE8g1oyRdE5bU_WxQpboI2YI4,17695
|
11
11
|
signalwire_agents/core/function_result.py,sha256=SP46vPAliEzwh3JeeSxmLD_f7_ixRxMBtpSl3t7jieU,45370
|
12
|
-
signalwire_agents/core/logging_config.py,sha256=
|
12
|
+
signalwire_agents/core/logging_config.py,sha256=A4huPkWicnpd7g7M4XYYKMALQqLSrhtIu21811nLV5c,12622
|
13
13
|
signalwire_agents/core/pom_builder.py,sha256=ywuiIfP8BeLBPo_G4X1teZlG6zTCMkW71CZnmyoDTAQ,6636
|
14
14
|
signalwire_agents/core/skill_base.py,sha256=lOpVTLhD9NjStF7Lxh6bAQUGa3DpNYV4agXJRakRuX0,4258
|
15
|
-
signalwire_agents/core/skill_manager.py,sha256=
|
15
|
+
signalwire_agents/core/skill_manager.py,sha256=XWq4MeDQ3kmM4Th8qI-Gx5klokDHNZ-K9cChJPW-zmQ,8113
|
16
16
|
signalwire_agents/core/swaig_function.py,sha256=3xJrrQVxCZX-DssLkdjaui_psTUzahkzAsQ1EyRVMFk,6837
|
17
17
|
signalwire_agents/core/swml_builder.py,sha256=Q1ikU9pedgjW888mjbqDFv-jMDvDZ-tZgfyMfu4qQN0,6719
|
18
18
|
signalwire_agents/core/swml_handler.py,sha256=C8NvMpNdFg9UiEzPwMmMXMn8X6w10IShKjBJ8VSITBk,8189
|
19
19
|
signalwire_agents/core/swml_renderer.py,sha256=u6HnbOC0NUnPpr6uz0FkXNEqcTF2OjWDui6gceD1Bhs,14773
|
20
|
-
signalwire_agents/core/swml_service.py,sha256=
|
20
|
+
signalwire_agents/core/swml_service.py,sha256=oLdVYRYDyucgBVDAuhiOWVTN6p21SvPvddkPIMMd5kw,48346
|
21
21
|
signalwire_agents/core/security/__init__.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_PumJ35Xds,191
|
22
22
|
signalwire_agents/core/security/session_manager.py,sha256=s5hXYcFnrsYFoyo-zcN7EJy-wInZQI_cWTBHX9MxHR4,9164
|
23
23
|
signalwire_agents/core/state/__init__.py,sha256=qpYIfQBApet6VQsy6diS3yu0lMxCBC6REOUk5l1McUw,379
|
@@ -30,13 +30,13 @@ signalwire_agents/prefabs/info_gatherer.py,sha256=dr9UUgNGX7MIKdCMth3jDVLf6OrHov
|
|
30
30
|
signalwire_agents/prefabs/receptionist.py,sha256=8EyQ6M0Egs3g7KKWukHFiO9UPoVUxT4MLkvyT3V8o64,10585
|
31
31
|
signalwire_agents/prefabs/survey.py,sha256=IIIQfgvMlfVNjEEEdWUn4lAJqVsCDlBsIAkOJ1ckyAE,14796
|
32
32
|
signalwire_agents/search/__init__.py,sha256=x7saU_MDbhoOIzcvCT1-gnqyH2rrMpzB4ZUqk-av-lI,3958
|
33
|
-
signalwire_agents/search/document_processor.py,sha256=
|
34
|
-
signalwire_agents/search/index_builder.py,sha256=
|
35
|
-
signalwire_agents/search/query_processor.py,sha256=
|
33
|
+
signalwire_agents/search/document_processor.py,sha256=J4OG640qbqGslbVevvD4J2cbTmFCZiGJ1bLX2yDayaE,43699
|
34
|
+
signalwire_agents/search/index_builder.py,sha256=OLITsAidBJ_tkTtl7JAMVF-v4lUxaAmLC5pdn0SdpAE,22816
|
35
|
+
signalwire_agents/search/query_processor.py,sha256=idQTGWO87I4IT5mrbGAuC3AvBiYNNj7Dx22KEv6YhV0,14668
|
36
36
|
signalwire_agents/search/search_engine.py,sha256=KFF33aPsBdwb2N1aTJmAA0xo3KPANoXjwV53uSxih9o,14798
|
37
37
|
signalwire_agents/search/search_service.py,sha256=Src_REgjkcddHBDCaLv2BMJnDSxcE4XV_1U8YStJOh8,8719
|
38
|
-
signalwire_agents/skills/__init__.py,sha256=
|
39
|
-
signalwire_agents/skills/registry.py,sha256=
|
38
|
+
signalwire_agents/skills/__init__.py,sha256=j0HambEKTkrFNP2vsaSmfrMJNDabq4EuvYJqRKZXfxU,342
|
39
|
+
signalwire_agents/skills/registry.py,sha256=lnr0XFOQ5YC_WgsAT6Id3RMAJ2-nf2ZCdqB7z_huLQI,4889
|
40
40
|
signalwire_agents/skills/datasphere/__init__.py,sha256=SJJlmeMSeezjINPgkuWN1XzDPN_Z3GzZ_StzO1BtxQs,257
|
41
41
|
signalwire_agents/skills/datasphere/skill.py,sha256=L6GrGwej3sKPcHljKBNf4it5g4DaGzR18KlQx65_XKg,9598
|
42
42
|
signalwire_agents/skills/datasphere_serverless/__init__.py,sha256=65hu8_0eqiczLSZ-aJgASpMQqTUjzTQUI1fC8GI7qTI,70
|
@@ -48,7 +48,7 @@ signalwire_agents/skills/joke/skill.py,sha256=AFaf6fMy0sxUPJHvcnf3CWMuPqpJP4ODsc
|
|
48
48
|
signalwire_agents/skills/math/__init__.py,sha256=lGAFWEmJH2fuwkuZUdDTY5dmucrIwtjfNT8bE2hOSP8,39
|
49
49
|
signalwire_agents/skills/math/skill.py,sha256=5sErd5x1rFHJg2GlmdJB3LvrmvTNOrZsA2jRnG67Zw8,3342
|
50
50
|
signalwire_agents/skills/native_vector_search/__init__.py,sha256=buvncVoH5u8MJA0SLlz1JQgIuyBTQW5aql-ydnc7Wh8,29
|
51
|
-
signalwire_agents/skills/native_vector_search/skill.py,sha256=
|
51
|
+
signalwire_agents/skills/native_vector_search/skill.py,sha256=da-3eM1NT7Tcju1GiQipxOrYhP7OIry68l2dLKpDV4I,15859
|
52
52
|
signalwire_agents/skills/web_search/__init__.py,sha256=wJlptYDExYw-nxZJVzlTLOgkKkDOLUUt1ZdoLt44ixs,45
|
53
53
|
signalwire_agents/skills/web_search/skill.py,sha256=GkfhG3Vz2HxOv91TvVuA4e_4b5cuswUpnJDLdaZW37k,10304
|
54
54
|
signalwire_agents/skills/wikipedia/__init__.py,sha256=8Db_aE0ly7QoXg7n2RDvCqKupkyR-UYlK9uFUnGNCE8,184
|
@@ -58,10 +58,10 @@ signalwire_agents/utils/pom_utils.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_Pu
|
|
58
58
|
signalwire_agents/utils/schema_utils.py,sha256=i4okv_O9bUApwT_jJf4Yoij3bLCrGrW3DC-vzSy2RuY,16392
|
59
59
|
signalwire_agents/utils/token_generators.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_PumJ35Xds,191
|
60
60
|
signalwire_agents/utils/validators.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_PumJ35Xds,191
|
61
|
-
signalwire_agents-0.1.
|
62
|
-
signalwire_agents-0.1.
|
63
|
-
signalwire_agents-0.1.
|
64
|
-
signalwire_agents-0.1.
|
65
|
-
signalwire_agents-0.1.
|
66
|
-
signalwire_agents-0.1.
|
67
|
-
signalwire_agents-0.1.
|
61
|
+
signalwire_agents-0.1.14.data/data/schema.json,sha256=M8Mn6pQda2P9jhbmkALrLr1wt-fRuhYRqdmEi9Rbhqk,178075
|
62
|
+
signalwire_agents-0.1.14.dist-info/licenses/LICENSE,sha256=NYvAsB-rTcSvG9cqHt9EUHAWLiA9YzM4Qfz-mPdvDR0,1067
|
63
|
+
signalwire_agents-0.1.14.dist-info/METADATA,sha256=_VCXeDp5iMOLmkdHJlognjxF5rLQV_rzp8mhiJpbADM,34572
|
64
|
+
signalwire_agents-0.1.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
65
|
+
signalwire_agents-0.1.14.dist-info/entry_points.txt,sha256=LRwltbVfaKUFMYmQoMxJGTT_-iQm0ftzXK0xPfD64Is,138
|
66
|
+
signalwire_agents-0.1.14.dist-info/top_level.txt,sha256=kDGS6ZYv84K9P5Kyg9_S8P_pbUXoHkso0On_DB5bbWc,18
|
67
|
+
signalwire_agents-0.1.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|