signalwire-agents 0.1.49__tar.gz → 0.1.51__tar.gz

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.
Files changed (144) hide show
  1. {signalwire_agents-0.1.49/signalwire_agents.egg-info → signalwire_agents-0.1.51}/PKG-INFO +1 -1
  2. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/pyproject.toml +1 -1
  3. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/__init__.py +1 -1
  4. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/ai_config_mixin.py +2 -2
  5. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/skill_base.py +20 -0
  6. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/schema.json +13 -9
  7. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datasphere/skill.py +2 -3
  8. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datetime/skill.py +4 -6
  9. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/math/skill.py +2 -3
  10. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/mcp_gateway/skill.py +2 -2
  11. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/native_vector_search/skill.py +35 -13
  12. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/spider/skill.py +6 -9
  13. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/web_search/skill.py +50 -30
  14. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/wikipedia_search/skill.py +2 -3
  15. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51/signalwire_agents.egg-info}/PKG-INFO +1 -1
  16. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/LICENSE +0 -0
  17. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/README.md +0 -0
  18. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/setup.cfg +0 -0
  19. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/setup.py +0 -0
  20. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/agent_server.py +0 -0
  21. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/agents/bedrock.py +0 -0
  22. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/__init__.py +0 -0
  23. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/build_search.py +0 -0
  24. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/config.py +0 -0
  25. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/core/__init__.py +0 -0
  26. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/core/agent_loader.py +0 -0
  27. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/core/argparse_helpers.py +0 -0
  28. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/core/dynamic_config.py +0 -0
  29. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/core/service_loader.py +0 -0
  30. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/execution/__init__.py +0 -0
  31. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/execution/datamap_exec.py +0 -0
  32. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/execution/webhook_exec.py +0 -0
  33. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/output/__init__.py +0 -0
  34. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/output/output_formatter.py +0 -0
  35. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/output/swml_dump.py +0 -0
  36. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/simulation/__init__.py +0 -0
  37. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/simulation/data_generation.py +0 -0
  38. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/simulation/data_overrides.py +0 -0
  39. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/simulation/mock_env.py +0 -0
  40. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/swaig_test_wrapper.py +0 -0
  41. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/test_swaig.py +0 -0
  42. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/cli/types.py +0 -0
  43. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/__init__.py +0 -0
  44. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/__init__.py +0 -0
  45. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/config/__init__.py +0 -0
  46. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/deployment/__init__.py +0 -0
  47. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/deployment/handlers/__init__.py +0 -0
  48. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/prompt/__init__.py +0 -0
  49. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/prompt/manager.py +0 -0
  50. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/routing/__init__.py +0 -0
  51. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/security/__init__.py +0 -0
  52. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/swml/__init__.py +0 -0
  53. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/tools/__init__.py +0 -0
  54. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/tools/decorator.py +0 -0
  55. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent/tools/registry.py +0 -0
  56. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/agent_base.py +0 -0
  57. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/auth_handler.py +0 -0
  58. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/config_loader.py +0 -0
  59. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/contexts.py +0 -0
  60. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/data_map.py +0 -0
  61. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/function_result.py +0 -0
  62. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/logging_config.py +0 -0
  63. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/__init__.py +0 -0
  64. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/auth_mixin.py +0 -0
  65. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/prompt_mixin.py +0 -0
  66. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/serverless_mixin.py +0 -0
  67. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/skill_mixin.py +0 -0
  68. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/state_mixin.py +0 -0
  69. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/tool_mixin.py +0 -0
  70. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/mixins/web_mixin.py +0 -0
  71. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/pom_builder.py +0 -0
  72. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/security/__init__.py +0 -0
  73. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/security/session_manager.py +0 -0
  74. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/security_config.py +0 -0
  75. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/skill_manager.py +0 -0
  76. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/swaig_function.py +0 -0
  77. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/swml_builder.py +0 -0
  78. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/swml_handler.py +0 -0
  79. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/swml_renderer.py +0 -0
  80. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/core/swml_service.py +0 -0
  81. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/prefabs/__init__.py +0 -0
  82. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/prefabs/concierge.py +0 -0
  83. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/prefabs/faq_bot.py +0 -0
  84. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/prefabs/info_gatherer.py +0 -0
  85. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/prefabs/receptionist.py +0 -0
  86. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/prefabs/survey.py +0 -0
  87. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/__init__.py +0 -0
  88. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/document_processor.py +0 -0
  89. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/index_builder.py +0 -0
  90. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/migration.py +0 -0
  91. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/models.py +0 -0
  92. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/pgvector_backend.py +0 -0
  93. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/query_processor.py +0 -0
  94. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/search_engine.py +0 -0
  95. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/search/search_service.py +0 -0
  96. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/README.md +0 -0
  97. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/__init__.py +0 -0
  98. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/api_ninjas_trivia/README.md +0 -0
  99. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/api_ninjas_trivia/__init__.py +0 -0
  100. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/api_ninjas_trivia/skill.py +0 -0
  101. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datasphere/README.md +0 -0
  102. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datasphere/__init__.py +0 -0
  103. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datasphere_serverless/README.md +0 -0
  104. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datasphere_serverless/__init__.py +0 -0
  105. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datasphere_serverless/skill.py +0 -0
  106. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datetime/README.md +0 -0
  107. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/datetime/__init__.py +0 -0
  108. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/joke/README.md +0 -0
  109. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/joke/__init__.py +0 -0
  110. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/joke/skill.py +0 -0
  111. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/math/README.md +0 -0
  112. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/math/__init__.py +0 -0
  113. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/mcp_gateway/README.md +0 -0
  114. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/mcp_gateway/__init__.py +0 -0
  115. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/native_vector_search/README.md +0 -0
  116. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/native_vector_search/__init__.py +0 -0
  117. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/play_background_file/README.md +0 -0
  118. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/play_background_file/__init__.py +0 -0
  119. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/play_background_file/skill.py +0 -0
  120. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/registry.py +0 -0
  121. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/spider/README.md +0 -0
  122. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/spider/__init__.py +0 -0
  123. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/swml_transfer/README.md +0 -0
  124. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/swml_transfer/__init__.py +0 -0
  125. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/swml_transfer/skill.py +0 -0
  126. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/weather_api/README.md +0 -0
  127. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/weather_api/__init__.py +0 -0
  128. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/weather_api/skill.py +0 -0
  129. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/web_search/README.md +0 -0
  130. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/web_search/__init__.py +0 -0
  131. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/wikipedia_search/README.md +0 -0
  132. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/skills/wikipedia_search/__init__.py +0 -0
  133. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/utils/__init__.py +0 -0
  134. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/utils/pom_utils.py +0 -0
  135. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/utils/schema_utils.py +0 -0
  136. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/utils/token_generators.py +0 -0
  137. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/utils/validators.py +0 -0
  138. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/web/__init__.py +0 -0
  139. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents/web/web_service.py +0 -0
  140. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents.egg-info/SOURCES.txt +0 -0
  141. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents.egg-info/dependency_links.txt +0 -0
  142. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents.egg-info/entry_points.txt +0 -0
  143. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents.egg-info/requires.txt +0 -0
  144. {signalwire_agents-0.1.49 → signalwire_agents-0.1.51}/signalwire_agents.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: signalwire_agents
3
- Version: 0.1.49
3
+ Version: 0.1.51
4
4
  Summary: SignalWire AI Agents SDK
5
5
  Author-email: SignalWire Team <info@signalwire.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "signalwire_agents"
7
- version = "0.1.49"
7
+ version = "0.1.51"
8
8
  description = "SignalWire AI Agents SDK"
9
9
  authors = [
10
10
  {name = "SignalWire Team", email = "info@signalwire.com"}
@@ -18,7 +18,7 @@ A package for building AI agents using SignalWire's AI and SWML capabilities.
18
18
  from .core.logging_config import configure_logging
19
19
  configure_logging()
20
20
 
21
- __version__ = "0.1.49"
21
+ __version__ = "0.1.51"
22
22
 
23
23
  # Import core classes for easier access
24
24
  from .core.agent_base import AgentBase
@@ -380,7 +380,7 @@ class AIConfigMixin:
380
380
  The server will validate and apply parameters based on the target model's capabilities.
381
381
 
382
382
  Common parameters include:
383
- model: The AI model to use (gpt-4o-mini, gpt-4.1-mini, gpt-4.1-nano, nova-micro, nova-lite)
383
+ model: The AI model to use (gpt-4o-mini, gpt-4.1-mini, gpt-4.1-nano, nova-micro, nova-lite, qwen3-235b-A22b-instruct)
384
384
  temperature: Randomness setting. Lower values make output more deterministic.
385
385
  top_p: Alternative to temperature. Controls nucleus sampling.
386
386
  barge_confidence: ASR confidence to interrupt. Higher values make it harder to interrupt.
@@ -415,7 +415,7 @@ class AIConfigMixin:
415
415
  The server will validate and apply parameters based on the target model's capabilities.
416
416
 
417
417
  Common parameters include:
418
- model: The AI model to use (gpt-4o-mini, gpt-4.1-mini, gpt-4.1-nano, nova-micro, nova-lite)
418
+ model: The AI model to use (gpt-4o-mini, gpt-4.1-mini, gpt-4.1-nano, nova-micro, nova-lite, qwen3-235b-A22b-instruct)
419
419
  temperature: Randomness setting. Lower values make output more deterministic.
420
420
  top_p: Alternative to temperature. Controls nucleus sampling.
421
421
  presence_penalty: Topic diversity. Positive values encourage new topics.
@@ -53,6 +53,26 @@ class SkillBase(ABC):
53
53
  """Register SWAIG tools with the agent"""
54
54
  pass
55
55
 
56
+ def define_tool(self, **kwargs) -> None:
57
+ """
58
+ Wrapper method that automatically includes swaig_fields when defining tools.
59
+
60
+ This method delegates to self.agent.define_tool() but automatically merges
61
+ any swaig_fields configured for this skill. Skills should use this method
62
+ instead of calling self.agent.define_tool() directly.
63
+
64
+ Args:
65
+ **kwargs: All arguments supported by agent.define_tool()
66
+ (name, description, parameters, handler, etc.)
67
+ """
68
+ # Merge swaig_fields with any explicitly passed fields
69
+ # Explicit fields take precedence over swaig_fields
70
+ merged_kwargs = dict(self.swaig_fields)
71
+ merged_kwargs.update(kwargs)
72
+
73
+ # Call the agent's define_tool with merged arguments
74
+ return self.agent.define_tool(**merged_kwargs)
75
+
56
76
 
57
77
 
58
78
  def get_hints(self) -> List[str]:
@@ -1933,9 +1933,13 @@
1933
1933
  {
1934
1934
  "type": "string",
1935
1935
  "const": "nova-lite"
1936
+ },
1937
+ {
1938
+ "type": "string",
1939
+ "const": "qwen3-235b-A22b-instruct"
1936
1940
  }
1937
1941
  ],
1938
- "description": "The model to use for the AI. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, and `nova-lite`."
1942
+ "description": "The model to use for the AI. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, `nova-lite`, and `qwen3-235b-A22b-instruct`."
1939
1943
  },
1940
1944
  "ai_volume": {
1941
1945
  "anyOf": [
@@ -4017,13 +4021,13 @@
4017
4021
  "anyOf": [
4018
4022
  {
4019
4023
  "type": "string",
4020
- "enum": ["gpt-4o-mini", "gpt-4.1-mini", "gpt-4.1-nano", "nova-micro", "nova-lite"]
4024
+ "enum": ["gpt-4o-mini", "gpt-4.1-mini", "gpt-4.1-nano", "nova-micro", "nova-lite", "qwen3-235b-A22b-instruct"]
4021
4025
  },
4022
4026
  {
4023
4027
  "$ref": "#/$defs/SWMLVar"
4024
4028
  }
4025
4029
  ],
4026
- "description": "The model to use for the post-prompt. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, and `nova-lite`."
4030
+ "description": "The model to use for the post-prompt. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, `nova-lite`, and `qwen3-235b-A22b-instruct`."
4027
4031
  },
4028
4032
  "text": {
4029
4033
  "type": "string",
@@ -4108,13 +4112,13 @@
4108
4112
  "anyOf": [
4109
4113
  {
4110
4114
  "type": "string",
4111
- "enum": ["gpt-4o-mini", "gpt-4.1-mini", "gpt-4.1-nano", "nova-micro", "nova-lite"]
4115
+ "enum": ["gpt-4o-mini", "gpt-4.1-mini", "gpt-4.1-nano", "nova-micro", "nova-lite", "qwen3-235b-A22b-instruct"]
4112
4116
  },
4113
4117
  {
4114
4118
  "$ref": "#/$defs/SWMLVar"
4115
4119
  }
4116
4120
  ],
4117
- "description": "The model to use for the post-prompt. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, and `nova-lite`."
4121
+ "description": "The model to use for the post-prompt. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, `nova-lite`, and `qwen3-235b-A22b-instruct`."
4118
4122
  },
4119
4123
  "pom": {
4120
4124
  "type": "array",
@@ -4202,13 +4206,13 @@
4202
4206
  "anyOf": [
4203
4207
  {
4204
4208
  "type": "string",
4205
- "enum": ["gpt-4o-mini", "gpt-4.1-mini", "gpt-4.1-nano", "nova-micro", "nova-lite"]
4209
+ "enum": ["gpt-4o-mini", "gpt-4.1-mini", "gpt-4.1-nano", "nova-micro", "nova-lite", "qwen3-235b-A22b-instruct"]
4206
4210
  },
4207
4211
  {
4208
4212
  "$ref": "#/$defs/SWMLVar"
4209
4213
  }
4210
4214
  ],
4211
- "description": "The model to use for the prompt. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, and `nova-lite`."
4215
+ "description": "The model to use for the prompt. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, `nova-lite`, and `qwen3-235b-A22b-instruct`."
4212
4216
  },
4213
4217
  "text": {
4214
4218
  "type": "string",
@@ -4297,13 +4301,13 @@
4297
4301
  "anyOf": [
4298
4302
  {
4299
4303
  "type": "string",
4300
- "enum": ["gpt-4o-mini", "gpt-4.1-mini", "gpt-4.1-nano", "nova-micro", "nova-lite"]
4304
+ "enum": ["gpt-4o-mini", "gpt-4.1-mini", "gpt-4.1-nano", "nova-micro", "nova-lite", "qwen3-235b-A22b-instruct"]
4301
4305
  },
4302
4306
  {
4303
4307
  "$ref": "#/$defs/SWMLVar"
4304
4308
  }
4305
4309
  ],
4306
- "description": "The model to use for the prompt. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, and `nova-lite`."
4310
+ "description": "The model to use for the prompt. Allowed values are `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-4.1-nano`, `nova-micro`, `nova-lite`, and `qwen3-235b-A22b-instruct`."
4307
4311
  },
4308
4312
  "pom": {
4309
4313
  "type": "array",
@@ -159,7 +159,7 @@ class DataSphereSkill(SkillBase):
159
159
 
160
160
  def register_tools(self) -> None:
161
161
  """Register knowledge search tool with the agent"""
162
- self.agent.define_tool(
162
+ self.define_tool(
163
163
  name=self.tool_name,
164
164
  description="Search the knowledge base for information on any topic and return relevant results",
165
165
  parameters={
@@ -168,8 +168,7 @@ class DataSphereSkill(SkillBase):
168
168
  "description": "The search query - what information you're looking for in the knowledge base"
169
169
  }
170
170
  },
171
- handler=self._search_knowledge_handler,
172
- **self.swaig_fields
171
+ handler=self._search_knowledge_handler
173
172
  )
174
173
 
175
174
  def _search_knowledge_handler(self, args, raw_data):
@@ -30,7 +30,7 @@ class DateTimeSkill(SkillBase):
30
30
  def register_tools(self) -> None:
31
31
  """Register datetime tools with the agent"""
32
32
 
33
- self.agent.define_tool(
33
+ self.define_tool(
34
34
  name="get_current_time",
35
35
  description="Get the current time, optionally in a specific timezone",
36
36
  parameters={
@@ -39,11 +39,10 @@ class DateTimeSkill(SkillBase):
39
39
  "description": "Timezone name (e.g., 'America/New_York', 'Europe/London'). Defaults to UTC."
40
40
  }
41
41
  },
42
- handler=self._get_time_handler,
43
- **self.swaig_fields
42
+ handler=self._get_time_handler
44
43
  )
45
44
 
46
- self.agent.define_tool(
45
+ self.define_tool(
47
46
  name="get_current_date",
48
47
  description="Get the current date",
49
48
  parameters={
@@ -52,8 +51,7 @@ class DateTimeSkill(SkillBase):
52
51
  "description": "Timezone name for the date. Defaults to UTC."
53
52
  }
54
53
  },
55
- handler=self._get_date_handler,
56
- **self.swaig_fields
54
+ handler=self._get_date_handler
57
55
  )
58
56
 
59
57
  def _get_time_handler(self, args, raw_data):
@@ -29,7 +29,7 @@ class MathSkill(SkillBase):
29
29
  def register_tools(self) -> None:
30
30
  """Register math tools with the agent"""
31
31
 
32
- self.agent.define_tool(
32
+ self.define_tool(
33
33
  name="calculate",
34
34
  description="Perform a mathematical calculation with basic operations (+, -, *, /, %, **)",
35
35
  parameters={
@@ -38,8 +38,7 @@ class MathSkill(SkillBase):
38
38
  "description": "Mathematical expression to evaluate (e.g., '2 + 3 * 4', '(10 + 5) / 3')"
39
39
  }
40
40
  },
41
- handler=self._calculate_handler,
42
- **self.swaig_fields
41
+ handler=self._calculate_handler
43
42
  )
44
43
 
45
44
  def _calculate_handler(self, args, raw_data):
@@ -215,7 +215,7 @@ class MCPGatewaySkill(SkillBase):
215
215
  self.logger.error(f"Failed to get tools for service '{service_name}': {e}")
216
216
 
217
217
  # Register the hangup hook for session cleanup
218
- self.agent.define_tool(
218
+ self.define_tool(
219
219
  name="_mcp_gateway_hangup",
220
220
  description="Internal cleanup function for MCP sessions",
221
221
  parameters={},
@@ -260,7 +260,7 @@ class MCPGatewaySkill(SkillBase):
260
260
  return self._call_mcp_tool(service_name, tool_name, args, raw_data)
261
261
 
262
262
  # Register the SWAIG function
263
- self.agent.define_tool(
263
+ self.define_tool(
264
264
  name=swaig_name,
265
265
  description=f"[{service_name}] {tool_def.get('description', tool_name)}",
266
266
  parameters=swaig_params,
@@ -136,6 +136,13 @@ class NativeVectorSearchSkill(SkillBase):
136
136
  "default": "",
137
137
  "required": False
138
138
  },
139
+ "max_content_length": {
140
+ "type": "integer",
141
+ "description": "Maximum total response size in characters (distributed across all results)",
142
+ "default": 32768,
143
+ "required": False,
144
+ "minimum": 1000
145
+ },
139
146
  "response_format_callback": {
140
147
  "type": "callable",
141
148
  "description": "Optional callback function to format/transform the response. Called with (response, agent, query, results, args). Must return a string.",
@@ -251,6 +258,7 @@ class NativeVectorSearchSkill(SkillBase):
251
258
  )
252
259
  self.response_prefix = self.params.get('response_prefix', '')
253
260
  self.response_postfix = self.params.get('response_postfix', '')
261
+ self.max_content_length = self.params.get('max_content_length', 32768)
254
262
  self.response_format_callback = self.params.get('response_format_callback')
255
263
  self.keyword_weight = self.params.get('keyword_weight')
256
264
  self.model_name = self.params.get('model_name', 'mini')
@@ -274,8 +282,8 @@ class NativeVectorSearchSkill(SkillBase):
274
282
  if parsed.path:
275
283
  self.remote_base_url += parsed.path
276
284
 
277
- # SWAIG fields for function fillers
278
- self.swaig_fields = self.params.get('swaig_fields', {})
285
+ # SWAIG fields are already extracted by SkillBase.__init__()
286
+ # No need to re-fetch from params - use self.swaig_fields inherited from parent
279
287
 
280
288
  # **EARLY REMOTE CHECK - Option 1**
281
289
  # If remote URL is configured, skip all heavy local imports and just validate remote connectivity
@@ -460,7 +468,7 @@ class NativeVectorSearchSkill(SkillBase):
460
468
  'Search the local knowledge base for information'
461
469
  )
462
470
 
463
- self.agent.define_tool(
471
+ self.define_tool(
464
472
  name=self.tool_name,
465
473
  description=description,
466
474
  parameters={
@@ -474,8 +482,7 @@ class NativeVectorSearchSkill(SkillBase):
474
482
  "default": self.count
475
483
  }
476
484
  },
477
- handler=self._search_handler,
478
- **self.swaig_fields
485
+ handler=self._search_handler
479
486
  )
480
487
 
481
488
  # Add our tool to the Knowledge Search section
@@ -601,21 +608,36 @@ class NativeVectorSearchSkill(SkillBase):
601
608
 
602
609
  return SwaigFunctionResult(no_results_msg)
603
610
 
604
- # Format results
611
+ # Format results with dynamic per-result truncation
605
612
  response_parts = []
606
-
613
+
607
614
  # Add response prefix if configured
608
615
  if self.response_prefix:
609
616
  response_parts.append(self.response_prefix)
610
-
617
+
611
618
  response_parts.append(f"Found {len(results)} relevant results for '{query}':\n")
612
-
619
+
620
+ # Calculate per-result content budget
621
+ # Estimate overhead per result: metadata (~200 chars) + formatting (~100 chars)
622
+ estimated_overhead_per_result = 300
623
+ # Account for prefix/postfix/header in total overhead
624
+ prefix_postfix_overhead = len(self.response_prefix) + len(self.response_postfix) + 100
625
+ total_overhead = (len(results) * estimated_overhead_per_result) + prefix_postfix_overhead
626
+ available_for_content = self.max_content_length - total_overhead
627
+
628
+ # Ensure minimum of 500 chars per result
629
+ per_result_limit = max(500, available_for_content // len(results)) if len(results) > 0 else 1000
630
+
613
631
  for i, result in enumerate(results, 1):
614
632
  filename = result['metadata']['filename']
615
633
  section = result['metadata'].get('section', '')
616
634
  score = result['score']
617
635
  content = result['content']
618
-
636
+
637
+ # Truncate content to per-result limit
638
+ if len(content) > per_result_limit:
639
+ content = content[:per_result_limit] + "..."
640
+
619
641
  # Get tags from either top level or metadata
620
642
  tags = result.get('tags', [])
621
643
  if not tags and 'metadata' in result['metadata'] and 'tags' in result['metadata']['metadata']:
@@ -624,16 +646,16 @@ class NativeVectorSearchSkill(SkillBase):
624
646
  elif not tags and 'tags' in result['metadata']:
625
647
  # Check in metadata directly
626
648
  tags = result['metadata']['tags']
627
-
649
+
628
650
  result_text = f"**Result {i}** (from {filename}"
629
651
  if section:
630
652
  result_text += f", section: {section}"
631
653
  if tags:
632
654
  result_text += f", tags: {', '.join(tags)}"
633
655
  result_text += f", relevance: {score:.2f})\n{content}\n"
634
-
656
+
635
657
  response_parts.append(result_text)
636
-
658
+
637
659
  # Add response postfix if configured
638
660
  if self.response_postfix:
639
661
  response_parts.append(self.response_postfix)
@@ -223,7 +223,7 @@ class SpiderSkill(SkillBase):
223
223
  tool_prefix = f"{tool_prefix}_"
224
224
 
225
225
  # Register scrape_url tool
226
- self.agent.define_tool(
226
+ self.define_tool(
227
227
  name=f"{tool_prefix}scrape_url",
228
228
  description="Extract text content from a single web page",
229
229
  parameters={
@@ -233,12 +233,11 @@ class SpiderSkill(SkillBase):
233
233
  }
234
234
  },
235
235
  required=["url"],
236
- handler=self._scrape_url_handler,
237
- **self.swaig_fields
236
+ handler=self._scrape_url_handler
238
237
  )
239
238
 
240
239
  # Register crawl_site tool
241
- self.agent.define_tool(
240
+ self.define_tool(
242
241
  name=f"{tool_prefix}crawl_site",
243
242
  description="Crawl multiple pages starting from a URL",
244
243
  parameters={
@@ -248,12 +247,11 @@ class SpiderSkill(SkillBase):
248
247
  }
249
248
  },
250
249
  required=["start_url"],
251
- handler=self._crawl_site_handler,
252
- **self.swaig_fields
250
+ handler=self._crawl_site_handler
253
251
  )
254
252
 
255
253
  # Register extract_structured_data tool
256
- self.agent.define_tool(
254
+ self.define_tool(
257
255
  name=f"{tool_prefix}extract_structured_data",
258
256
  description="Extract specific data from a web page using selectors",
259
257
  parameters={
@@ -263,8 +261,7 @@ class SpiderSkill(SkillBase):
263
261
  }
264
262
  },
265
263
  required=["url"],
266
- handler=self._extract_structured_handler,
267
- **self.swaig_fields
264
+ handler=self._extract_structured_handler
268
265
  )
269
266
 
270
267
  def _fetch_url(self, url: str) -> Optional[requests.Response]:
@@ -21,7 +21,7 @@ from signalwire_agents.core.function_result import SwaigFunctionResult
21
21
  class GoogleSearchScraper:
22
22
  """Google Search and Web Scraping functionality"""
23
23
 
24
- def __init__(self, api_key: str, search_engine_id: str, max_content_length: int = 2000):
24
+ def __init__(self, api_key: str, search_engine_id: str, max_content_length: int = 32768):
25
25
  self.api_key = api_key
26
26
  self.search_engine_id = search_engine_id
27
27
  self.max_content_length = max_content_length
@@ -62,63 +62,84 @@ class GoogleSearchScraper:
62
62
  except Exception as e:
63
63
  return []
64
64
 
65
- def extract_text_from_url(self, url: str, timeout: int = 10) -> str:
66
- """Scrape a URL and extract readable text content"""
65
+ def extract_text_from_url(self, url: str, content_limit: int = None, timeout: int = 10) -> str:
66
+ """Scrape a URL and extract readable text content
67
+
68
+ Args:
69
+ url: URL to scrape
70
+ content_limit: Maximum characters to return (uses self.max_content_length if not provided)
71
+ timeout: Request timeout in seconds
72
+ """
67
73
  try:
68
74
  response = self.session.get(url, timeout=timeout)
69
75
  response.raise_for_status()
70
-
76
+
71
77
  soup = BeautifulSoup(response.content, 'html.parser')
72
-
78
+
73
79
  # Remove unwanted elements
74
80
  for script in soup(["script", "style", "nav", "footer", "header", "aside"]):
75
81
  script.decompose()
76
-
82
+
77
83
  text = soup.get_text()
78
-
84
+
79
85
  # Clean up the text
80
86
  lines = (line.strip() for line in text.splitlines())
81
87
  chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
82
88
  text = ' '.join(chunk for chunk in chunks if chunk)
83
-
89
+
84
90
  # Limit text length
85
- if len(text) > self.max_content_length:
86
- text = text[:self.max_content_length] + "... [Content truncated]"
87
-
91
+ limit = content_limit if content_limit is not None else self.max_content_length
92
+ if len(text) > limit:
93
+ text = text[:limit]
94
+
88
95
  return text
89
-
96
+
90
97
  except Exception as e:
91
98
  return ""
92
99
 
93
100
  def search_and_scrape(self, query: str, num_results: int = 3, delay: float = 0.5) -> str:
94
- """Main function: search Google and scrape the resulting pages"""
101
+ """Main function: search Google and scrape the resulting pages
102
+
103
+ Dynamically calculates per-result content limit based on total max_content_length
104
+ and number of results to ensure total response stays within bounds.
105
+ """
95
106
  search_results = self.search_google(query, num_results)
96
-
107
+
97
108
  if not search_results:
98
109
  return f"No search results found for query: {query}"
99
-
110
+
111
+ # Calculate per-result content budget
112
+ # Reserve ~300 chars per result for overhead (titles, URLs, snippets, formatting)
113
+ estimated_overhead_per_result = 300
114
+ total_overhead = num_results * estimated_overhead_per_result
115
+ available_for_content = self.max_content_length - total_overhead
116
+
117
+ # Ensure we have at least 1000 chars per result
118
+ per_result_limit = max(1000, available_for_content // num_results)
119
+
100
120
  all_text = []
101
-
121
+
102
122
  for i, result in enumerate(search_results, 1):
103
123
  text_content = f"=== RESULT {i} ===\n"
104
124
  text_content += f"Title: {result['title']}\n"
105
125
  text_content += f"URL: {result['url']}\n"
106
126
  text_content += f"Snippet: {result['snippet']}\n"
107
127
  text_content += f"Content:\n"
108
-
109
- page_text = self.extract_text_from_url(result['url'])
110
-
128
+
129
+ # Pass the calculated per-result limit
130
+ page_text = self.extract_text_from_url(result['url'], content_limit=per_result_limit)
131
+
111
132
  if page_text:
112
133
  text_content += page_text
113
134
  else:
114
135
  text_content += "Failed to extract content from this page."
115
-
136
+
116
137
  text_content += f"\n{'='*50}\n\n"
117
138
  all_text.append(text_content)
118
-
139
+
119
140
  if i < len(search_results):
120
141
  time.sleep(delay)
121
-
142
+
122
143
  return '\n'.join(all_text)
123
144
 
124
145
 
@@ -163,7 +184,7 @@ class WebSearchSkill(SkillBase):
163
184
  # Set default parameters
164
185
  self.default_num_results = self.params.get('num_results', 1)
165
186
  self.default_delay = self.params.get('delay', 0)
166
- self.max_content_length = self.params.get('max_content_length', 2000)
187
+ self.max_content_length = self.params.get('max_content_length', 32768)
167
188
  self.no_results_message = self.params.get('no_results_message',
168
189
  "I couldn't find any results for '{query}'. "
169
190
  "This might be due to a very specific query or temporary issues. "
@@ -184,7 +205,7 @@ class WebSearchSkill(SkillBase):
184
205
 
185
206
  def register_tools(self) -> None:
186
207
  """Register web search tool with the agent"""
187
- self.agent.define_tool(
208
+ self.define_tool(
188
209
  name=self.tool_name,
189
210
  description="Search the web for information on any topic and return detailed results with content from multiple sources",
190
211
  parameters={
@@ -193,8 +214,7 @@ class WebSearchSkill(SkillBase):
193
214
  "description": "The search query - what you want to find information about"
194
215
  }
195
216
  },
196
- handler=self._web_search_handler,
197
- **self.swaig_fields
217
+ handler=self._web_search_handler
198
218
  )
199
219
 
200
220
  def _web_search_handler(self, args, raw_data):
@@ -308,10 +328,10 @@ class WebSearchSkill(SkillBase):
308
328
  },
309
329
  "max_content_length": {
310
330
  "type": "integer",
311
- "description": "Maximum content length per scraped page (characters)",
312
- "default": 2000,
331
+ "description": "Maximum total response size in characters (distributed across all results)",
332
+ "default": 32768,
313
333
  "required": False,
314
- "min": 100
334
+ "min": 1000
315
335
  },
316
336
  "no_results_message": {
317
337
  "type": "string",
@@ -321,4 +341,4 @@ class WebSearchSkill(SkillBase):
321
341
  }
322
342
  })
323
343
 
324
- return schema
344
+ return schema
@@ -84,7 +84,7 @@ class WikipediaSearchSkill(SkillBase):
84
84
  """
85
85
  Register the SWAIG tool for Wikipedia search.
86
86
  """
87
- self.agent.define_tool(
87
+ self.define_tool(
88
88
  name="search_wiki",
89
89
  description="Search Wikipedia for information about a topic and get article summaries",
90
90
  parameters={
@@ -93,8 +93,7 @@ class WikipediaSearchSkill(SkillBase):
93
93
  "description": "The search term or topic to look up on Wikipedia"
94
94
  }
95
95
  },
96
- handler=self._search_wiki_handler,
97
- **self.swaig_fields
96
+ handler=self._search_wiki_handler
98
97
  )
99
98
 
100
99
  def _search_wiki_handler(self, args, raw_data):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: signalwire_agents
3
- Version: 0.1.49
3
+ Version: 0.1.51
4
4
  Summary: SignalWire AI Agents SDK
5
5
  Author-email: SignalWire Team <info@signalwire.com>
6
6
  License: MIT