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.
@@ -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 discovering and managing skills"""
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
- self._discovered = False
27
+ # Remove _discovered flag since we're not doing discovery anymore
28
28
 
29
- def discover_skills(self) -> None:
30
- """Discover skills from the skills directory"""
31
- if self._discovered:
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
- # Get the skills directory path
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
- return
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.{skill_dir.name}.skill"
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 is not None):
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 {skill_dir}: {e}")
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
- self.discover_skills() # Ensure skills are discovered
86
- return self._skills.get(skill_name)
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 registered skills with metadata"""
90
- self.discover_skills()
91
- return [
92
- {
93
- "name": skill_class.SKILL_NAME,
94
- "description": skill_class.SKILL_DESCRIPTION,
95
- "version": skill_class.SKILL_VERSION,
96
- "required_packages": skill_class.REQUIRED_PACKAGES,
97
- "required_env_vars": skill_class.REQUIRED_ENV_VARS,
98
- "supports_multiple_instances": skill_class.SUPPORTS_MULTIPLE_INSTANCES
99
- }
100
- for skill_class in self._skills.values()
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: signalwire_agents
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  Summary: SignalWire AI Agents SDK
5
5
  Author-email: SignalWire Team <info@signalwire.com>
6
6
  Project-URL: Homepage, https://github.com/signalwire/signalwire-ai-agents
@@ -1,23 +1,23 @@
1
- signalwire_agents/__init__.py,sha256=IY7WpXHkFSNDItkEDkJpsfz3a4Bsw5aotPRtrHqJne4,2093
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=FXEgZEDn_2-7sJGQ07LYUxT9MGySUN-kpUbCCPBYxWk,15966
6
- signalwire_agents/cli/test_swaig.py,sha256=tBl2r-MqxKDiAVMfaDOntR9OMFE3I0ff51oGMlRQsl8,100237
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=uZoHeSivokoBL67CiseKur4L9JCq0Pzu-BDZ9hiNOYE,141686
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=ATO_Zo8Kc6Ts1wU39ewliF_dKAy6M91I9q-KiilsLyk,7507
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=6vAzkWYeycilX-5T1B039sf8s11BfRh6ASstt70wWsw,8074
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=3yhYfowgdKphjf2OLJYuaPsE6Paewe6rAO3e7F7NPic,49797
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=uqBvL8EGCou81ack7T49H0MNC7NkIRbciPtQecb1Jjo,31204
34
- signalwire_agents/search/index_builder.py,sha256=wAfDtK4YgnbHiG-syvEzbNGUHN92PMy1gMnhG_rXAUM,21143
35
- signalwire_agents/search/query_processor.py,sha256=1o8dEHVG52ci1e1PQxm5a0_1FV4zdqYBex_qcyJabRs,13926
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=xfxrQ0i-aTRomHiCsqelU4RlNlHPJFPgPu-UBDaBOqA,340
39
- signalwire_agents/skills/registry.py,sha256=UrFhZJdc_8Y9k9KCSRZtt7QemafDNtuvyuheAXShjuU,3821
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=jpXah7teIljgTfl2mW73VMlBwEKXS-s4Cws6XCS2JxU,14846
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.13.data/data/schema.json,sha256=M8Mn6pQda2P9jhbmkALrLr1wt-fRuhYRqdmEi9Rbhqk,178075
62
- signalwire_agents-0.1.13.dist-info/licenses/LICENSE,sha256=NYvAsB-rTcSvG9cqHt9EUHAWLiA9YzM4Qfz-mPdvDR0,1067
63
- signalwire_agents-0.1.13.dist-info/METADATA,sha256=wdck4xWPqwblSSKcHWW52H7HIGta1R9-8_H4IlRzo0k,34572
64
- signalwire_agents-0.1.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
65
- signalwire_agents-0.1.13.dist-info/entry_points.txt,sha256=7RBxC9wwFdsqP7g1F4JzsJ3AIHsjGtb3h0mxEGmANlI,151
66
- signalwire_agents-0.1.13.dist-info/top_level.txt,sha256=kDGS6ZYv84K9P5Kyg9_S8P_pbUXoHkso0On_DB5bbWc,18
67
- signalwire_agents-0.1.13.dist-info/RECORD,,
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,,
@@ -1,3 +1,3 @@
1
1
  [console_scripts]
2
- sw-search = signalwire_agents.cli.build_search:console_entry_point
2
+ sw-search = signalwire_agents.cli.sw_search_fast:main
3
3
  swaig-test = signalwire_agents.cli.test_swaig:console_entry_point