signalwire-agents 1.0.1__tar.gz → 1.0.3__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-1.0.1/signalwire_agents.egg-info → signalwire_agents-1.0.3}/PKG-INFO +1 -1
  2. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/pyproject.toml +1 -1
  3. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/__init__.py +1 -1
  4. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/agent_server.py +125 -12
  5. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/schema.json +165 -4
  6. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3/signalwire_agents.egg-info}/PKG-INFO +1 -1
  7. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/LICENSE +0 -0
  8. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/README.md +0 -0
  9. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/setup.cfg +0 -0
  10. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/setup.py +0 -0
  11. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/agents/bedrock.py +0 -0
  12. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/__init__.py +0 -0
  13. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/build_search.py +0 -0
  14. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/config.py +0 -0
  15. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/core/__init__.py +0 -0
  16. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/core/agent_loader.py +0 -0
  17. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/core/argparse_helpers.py +0 -0
  18. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/core/dynamic_config.py +0 -0
  19. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/core/service_loader.py +0 -0
  20. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/execution/__init__.py +0 -0
  21. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/execution/datamap_exec.py +0 -0
  22. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/execution/webhook_exec.py +0 -0
  23. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/output/__init__.py +0 -0
  24. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/output/output_formatter.py +0 -0
  25. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/output/swml_dump.py +0 -0
  26. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/simulation/__init__.py +0 -0
  27. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/simulation/data_generation.py +0 -0
  28. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/simulation/data_overrides.py +0 -0
  29. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/simulation/mock_env.py +0 -0
  30. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/swaig_test_wrapper.py +0 -0
  31. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/test_swaig.py +0 -0
  32. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/cli/types.py +0 -0
  33. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/__init__.py +0 -0
  34. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/__init__.py +0 -0
  35. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/config/__init__.py +0 -0
  36. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/deployment/__init__.py +0 -0
  37. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/deployment/handlers/__init__.py +0 -0
  38. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/prompt/__init__.py +0 -0
  39. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/prompt/manager.py +0 -0
  40. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/routing/__init__.py +0 -0
  41. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/security/__init__.py +0 -0
  42. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/swml/__init__.py +0 -0
  43. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/tools/__init__.py +0 -0
  44. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/tools/decorator.py +0 -0
  45. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent/tools/registry.py +0 -0
  46. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/agent_base.py +0 -0
  47. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/auth_handler.py +0 -0
  48. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/config_loader.py +0 -0
  49. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/contexts.py +0 -0
  50. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/data_map.py +0 -0
  51. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/function_result.py +0 -0
  52. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/logging_config.py +0 -0
  53. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/__init__.py +0 -0
  54. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/ai_config_mixin.py +0 -0
  55. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/auth_mixin.py +0 -0
  56. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/prompt_mixin.py +0 -0
  57. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/serverless_mixin.py +0 -0
  58. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/skill_mixin.py +0 -0
  59. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/state_mixin.py +0 -0
  60. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/tool_mixin.py +0 -0
  61. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/mixins/web_mixin.py +0 -0
  62. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/pom_builder.py +0 -0
  63. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/security/__init__.py +0 -0
  64. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/security/session_manager.py +0 -0
  65. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/security_config.py +0 -0
  66. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/skill_base.py +0 -0
  67. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/skill_manager.py +0 -0
  68. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/swaig_function.py +0 -0
  69. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/swml_builder.py +0 -0
  70. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/swml_handler.py +0 -0
  71. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/swml_renderer.py +0 -0
  72. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/core/swml_service.py +0 -0
  73. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/prefabs/__init__.py +0 -0
  74. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/prefabs/concierge.py +0 -0
  75. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/prefabs/faq_bot.py +0 -0
  76. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/prefabs/info_gatherer.py +0 -0
  77. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/prefabs/receptionist.py +0 -0
  78. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/prefabs/survey.py +0 -0
  79. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/__init__.py +0 -0
  80. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/document_processor.py +0 -0
  81. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/index_builder.py +0 -0
  82. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/migration.py +0 -0
  83. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/models.py +0 -0
  84. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/pgvector_backend.py +0 -0
  85. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/query_processor.py +0 -0
  86. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/search_engine.py +0 -0
  87. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/search/search_service.py +0 -0
  88. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/README.md +0 -0
  89. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/__init__.py +0 -0
  90. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/api_ninjas_trivia/README.md +0 -0
  91. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/api_ninjas_trivia/__init__.py +0 -0
  92. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/api_ninjas_trivia/skill.py +0 -0
  93. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datasphere/README.md +0 -0
  94. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datasphere/__init__.py +0 -0
  95. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datasphere/skill.py +0 -0
  96. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datasphere_serverless/README.md +0 -0
  97. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datasphere_serverless/__init__.py +0 -0
  98. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datasphere_serverless/skill.py +0 -0
  99. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datetime/README.md +0 -0
  100. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datetime/__init__.py +0 -0
  101. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/datetime/skill.py +0 -0
  102. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/joke/README.md +0 -0
  103. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/joke/__init__.py +0 -0
  104. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/joke/skill.py +0 -0
  105. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/math/README.md +0 -0
  106. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/math/__init__.py +0 -0
  107. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/math/skill.py +0 -0
  108. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/mcp_gateway/README.md +0 -0
  109. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/mcp_gateway/__init__.py +0 -0
  110. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/mcp_gateway/skill.py +0 -0
  111. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/native_vector_search/README.md +0 -0
  112. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/native_vector_search/__init__.py +0 -0
  113. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/native_vector_search/skill.py +0 -0
  114. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/play_background_file/README.md +0 -0
  115. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/play_background_file/__init__.py +0 -0
  116. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/play_background_file/skill.py +0 -0
  117. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/registry.py +0 -0
  118. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/spider/README.md +0 -0
  119. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/spider/__init__.py +0 -0
  120. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/spider/skill.py +0 -0
  121. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/swml_transfer/README.md +0 -0
  122. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/swml_transfer/__init__.py +0 -0
  123. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/swml_transfer/skill.py +0 -0
  124. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/weather_api/README.md +0 -0
  125. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/weather_api/__init__.py +0 -0
  126. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/weather_api/skill.py +0 -0
  127. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/web_search/README.md +0 -0
  128. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/web_search/__init__.py +0 -0
  129. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/web_search/skill.py +0 -0
  130. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/wikipedia_search/README.md +0 -0
  131. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/wikipedia_search/__init__.py +0 -0
  132. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/skills/wikipedia_search/skill.py +0 -0
  133. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/utils/__init__.py +0 -0
  134. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/utils/pom_utils.py +0 -0
  135. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/utils/schema_utils.py +0 -0
  136. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/utils/token_generators.py +0 -0
  137. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/utils/validators.py +0 -0
  138. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/web/__init__.py +0 -0
  139. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents/web/web_service.py +0 -0
  140. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents.egg-info/SOURCES.txt +0 -0
  141. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents.egg-info/dependency_links.txt +0 -0
  142. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents.egg-info/entry_points.txt +0 -0
  143. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/signalwire_agents.egg-info/requires.txt +0 -0
  144. {signalwire_agents-1.0.1 → signalwire_agents-1.0.3}/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: 1.0.1
3
+ Version: 1.0.3
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 = "1.0.1"
7
+ version = "1.0.3"
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__ = "1.0.1"
21
+ __version__ = "1.0.3"
22
22
 
23
23
  # Import core classes for easier access
24
24
  from .core.agent_base import AgentBase
@@ -549,11 +549,11 @@ class AgentServer:
549
549
  # This is a request to an agent's sub-path
550
550
  relative_path = full_path[len(route.lstrip("/")):]
551
551
  relative_path = relative_path.lstrip("/")
552
-
552
+
553
553
  # Route to appropriate handler based on path
554
554
  if not relative_path or relative_path == "/":
555
555
  return await agent._handle_root_request(request)
556
-
556
+
557
557
  clean_path = relative_path.rstrip("/")
558
558
  if clean_path == "debug":
559
559
  return await agent._handle_debug_request(request)
@@ -564,7 +564,7 @@ class AgentServer:
564
564
  return await agent._handle_post_prompt_request(request)
565
565
  elif clean_path == "check_for_input":
566
566
  return await agent._handle_check_for_input_request(request)
567
-
567
+
568
568
  # Check for custom routing callbacks
569
569
  if hasattr(agent, '_routing_callbacks'):
570
570
  for callback_path, callback_fn in agent._routing_callbacks.items():
@@ -572,9 +572,26 @@ class AgentServer:
572
572
  if clean_path == cb_path_clean:
573
573
  request.state.callback_path = callback_path
574
574
  return await agent._handle_root_request(request)
575
-
576
- # No matching agent found
577
- return {"error": "Not Found"}
575
+
576
+ # No matching agent - check for static files
577
+ if hasattr(self, '_static_directories'):
578
+ # Check each static directory route
579
+ for static_route, static_dir in self._static_directories.items():
580
+ # For root static route, serve any unmatched path
581
+ if static_route == "" or static_route == "/":
582
+ response = self._serve_static_file(full_path, "")
583
+ if response:
584
+ return response
585
+ # For prefixed static routes, check if path matches
586
+ elif full_path.startswith(static_route.lstrip("/") + "/") or full_path == static_route.lstrip("/"):
587
+ relative_path = full_path[len(static_route.lstrip("/")):].lstrip("/")
588
+ response = self._serve_static_file(relative_path, static_route)
589
+ if response:
590
+ return response
591
+
592
+ # No matching agent or static file found
593
+ from fastapi import HTTPException
594
+ raise HTTPException(status_code=404, detail="Not Found")
578
595
 
579
596
  # Set host and port
580
597
  host = host or self.host
@@ -634,13 +651,13 @@ class AgentServer:
634
651
  log_level=self.log_level
635
652
  )
636
653
 
637
- def register_global_routing_callback(self, callback_fn: Callable[[Request, Dict[str, Any]], Optional[str]],
654
+ def register_global_routing_callback(self, callback_fn: Callable[[Request, Dict[str, Any]], Optional[str]],
638
655
  path: str) -> None:
639
656
  """
640
657
  Register a routing callback across all agents
641
-
658
+
642
659
  This allows you to add unified routing logic to all agents at the same path.
643
-
660
+
644
661
  Args:
645
662
  callback_fn: The callback function to register
646
663
  path: The path to register the callback at
@@ -648,11 +665,107 @@ class AgentServer:
648
665
  # Normalize the path
649
666
  if not path.startswith("/"):
650
667
  path = f"/{path}"
651
-
668
+
652
669
  path = path.rstrip("/")
653
-
670
+
654
671
  # Register with all existing agents
655
672
  for agent in self.agents.values():
656
673
  agent.register_routing_callback(callback_fn, path=path)
657
-
674
+
658
675
  self.logger.info(f"Registered global routing callback at {path} on all agents")
676
+
677
+ def serve_static_files(self, directory: str, route: str = "/") -> None:
678
+ """
679
+ Serve static files from a directory.
680
+
681
+ This method properly integrates static file serving with agent routes,
682
+ ensuring that agent routes take priority over static files.
683
+
684
+ Unlike using StaticFiles.mount("/", ...) directly on self.app, this method
685
+ uses explicit route handlers that work correctly with agent routes.
686
+
687
+ Args:
688
+ directory: Path to the directory containing static files
689
+ route: URL path prefix for static files (default: "/" for root)
690
+
691
+ Example:
692
+ server = AgentServer()
693
+ server.register(SupportAgent(), "/support")
694
+ server.serve_static_files("./web") # Serves at /
695
+ # /support -> SupportAgent
696
+ # /index.html -> ./web/index.html
697
+ # / -> ./web/index.html
698
+ """
699
+ from pathlib import Path
700
+ from fastapi.responses import FileResponse
701
+ from fastapi import HTTPException
702
+
703
+ # Normalize directory path
704
+ static_dir = Path(directory).resolve()
705
+
706
+ if not static_dir.exists():
707
+ raise ValueError(f"Directory does not exist: {directory}")
708
+
709
+ if not static_dir.is_dir():
710
+ raise ValueError(f"Path is not a directory: {directory}")
711
+
712
+ # Normalize route
713
+ if not route.startswith("/"):
714
+ route = f"/{route}"
715
+ route = route.rstrip("/")
716
+
717
+ # Store static directory config for use by catch-all handler
718
+ if not hasattr(self, '_static_directories'):
719
+ self._static_directories = {}
720
+
721
+ self._static_directories[route] = static_dir
722
+
723
+ self.logger.info(f"Serving static files from '{directory}' at route '{route or '/'}'")
724
+
725
+ def _serve_static_file(self, file_path: str, route: str = "/") -> Optional[Response]:
726
+ """
727
+ Internal method to serve a static file.
728
+
729
+ Args:
730
+ file_path: The requested file path
731
+ route: The route prefix
732
+
733
+ Returns:
734
+ FileResponse if file exists, None otherwise
735
+ """
736
+ from pathlib import Path
737
+ from fastapi.responses import FileResponse
738
+
739
+ if not hasattr(self, '_static_directories'):
740
+ return None
741
+
742
+ static_dir = self._static_directories.get(route)
743
+ if not static_dir:
744
+ return None
745
+
746
+ # Default to index.html for empty path
747
+ if not file_path:
748
+ file_path = "index.html"
749
+
750
+ full_path = static_dir / file_path
751
+
752
+ # Security: prevent path traversal
753
+ try:
754
+ full_path = full_path.resolve()
755
+ if not str(full_path).startswith(str(static_dir)):
756
+ return None
757
+ except Exception:
758
+ return None
759
+
760
+ # Handle directory requests
761
+ if full_path.is_dir():
762
+ index_path = full_path / "index.html"
763
+ if index_path.exists():
764
+ full_path = index_path
765
+ else:
766
+ return None
767
+
768
+ if not full_path.exists():
769
+ return None
770
+
771
+ return FileResponse(full_path)
@@ -60,6 +60,9 @@
60
60
  {
61
61
  "$ref": "#/$defs/Denoise"
62
62
  },
63
+ {
64
+ "$ref": "#/$defs/EnterQueue"
65
+ },
63
66
  {
64
67
  "$ref": "#/$defs/Execute"
65
68
  },
@@ -303,6 +306,23 @@
303
306
  },
304
307
  "title": "Denoise object"
305
308
  },
309
+ "EnterQueue": {
310
+ "type": "object",
311
+ "properties": {
312
+ "enter_queue": {
313
+ "$ref": "#/$defs/EnterQueueObject",
314
+ "description": "Place the call in a queue.",
315
+ "title": "enter_queue"
316
+ }
317
+ },
318
+ "required": [
319
+ "enter_queue"
320
+ ],
321
+ "unevaluatedProperties": {
322
+ "not": {}
323
+ },
324
+ "title": "EnterQueue object"
325
+ },
306
326
  "Execute": {
307
327
  "type": "object",
308
328
  "properties": {
@@ -311,7 +331,7 @@
311
331
  "properties": {
312
332
  "dest": {
313
333
  "type": "string",
314
- "description": "Specifies what to execute. The value can be one of: \n<section_name> - section in the current document to execute.\nhttps://<URL>\" - URL pointing to the document to execute. Sends HTTP POST."
334
+ "description": "Specifies what to execute. The value can be one of:\n- `<section_name>` - section in the current document to execute\n- A URL (http or https) that returns a SWML document - Sends HTTP POST\n- An inline SWML document (as a JSON string)"
315
335
  },
316
336
  "params": {
317
337
  "type": "object",
@@ -1561,7 +1581,7 @@
1561
1581
  "properties": {
1562
1582
  "dest": {
1563
1583
  "type": "string",
1564
- "description": "Specifies where to transfer the call. The value can be one of:\n - `<section_name>` - section in the SWML document to jump to.\n - `https://<URL>` - URL pointing to the document to transfer to. Sends HTTP POST."
1584
+ "description": "Specifies where to transfer the call. The value can be one of:\n- `<section_name>` - section in the SWML document to jump to\n- A URL (http or https) that returns a SWML document - Sends HTTP POST\n- An inline SWML document (as a JSON string)"
1565
1585
  },
1566
1586
  "params": {
1567
1587
  "type": "object",
@@ -1642,7 +1662,7 @@
1642
1662
  "payment_connector_url": {
1643
1663
  "type": "string",
1644
1664
  "format": "uri",
1645
- "description": "The URL to make POST requests with all the gathered payment details.\nThis URL is used to process the final payment transaction and return the results through the response.\n\nVisit https://developer.signalwire.com//swml/methods/pay/payment_connector_url for more important information."
1665
+ "description": "The URL to make POST requests with all the gathered payment details.\nThis URL is used to process the final payment transaction and return the results through the response.\n\nVisit https://developer.signalwire.com/swml/methods/pay/payment_connector_url for more important information."
1646
1666
  },
1647
1667
  "charge_amount": {
1648
1668
  "type": "string",
@@ -2223,6 +2243,17 @@
2223
2243
  "format": "uri",
2224
2244
  "description": "http or https URL to deliver call status events"
2225
2245
  },
2246
+ "transfer_after_bridge": {
2247
+ "anyOf": [
2248
+ {
2249
+ "type": "string"
2250
+ },
2251
+ {
2252
+ "$ref": "#/$defs/SWMLVar"
2253
+ }
2254
+ ],
2255
+ "description": "SWML to execute after the bridge completes. This defines what should happen after the call is connected and the bridge ends.\nCan be either:\n- A URL (http or https) that returns a SWML document\n- An inline SWML document (as a JSON string)\n\n**Note:** This parameter is REQUIRED when connecting to a queue (when `to` starts with \"queue:\")"
2256
+ },
2226
2257
  "call_state_events": {
2227
2258
  "type": "array",
2228
2259
  "items": {
@@ -2235,7 +2266,7 @@
2235
2266
  },
2236
2267
  "to": {
2237
2268
  "type": "string",
2238
- "description": "The SIP URI or phone number to dial."
2269
+ "description": "Destination to dial. Can be:\n- Phone number in E.164 format (e.g., \"+15552345678\")\n- SIP URI (e.g., \"sip:alice@example.com\")\n- Call Fabric Resource address (e.g., \"/public/test_room\")\n- Queue (e.g., \"queue:support\")"
2239
2270
  }
2240
2271
  },
2241
2272
  "required": [
@@ -2398,6 +2429,17 @@
2398
2429
  "format": "uri",
2399
2430
  "description": "http or https URL to deliver call status events"
2400
2431
  },
2432
+ "transfer_after_bridge": {
2433
+ "anyOf": [
2434
+ {
2435
+ "type": "string"
2436
+ },
2437
+ {
2438
+ "$ref": "#/$defs/SWMLVar"
2439
+ }
2440
+ ],
2441
+ "description": "SWML to execute after the bridge completes. This defines what should happen after the call is connected and the bridge ends.\nCan be either:\n- A URL (http or https) that returns a SWML document\n- An inline SWML document (as a JSON string)\n\n**Note:** This parameter is REQUIRED when connecting to a queue (when `to` starts with \"queue:\")"
2442
+ },
2401
2443
  "call_state_events": {
2402
2444
  "type": "array",
2403
2445
  "items": {
@@ -2575,6 +2617,17 @@
2575
2617
  "format": "uri",
2576
2618
  "description": "http or https URL to deliver call status events"
2577
2619
  },
2620
+ "transfer_after_bridge": {
2621
+ "anyOf": [
2622
+ {
2623
+ "type": "string"
2624
+ },
2625
+ {
2626
+ "$ref": "#/$defs/SWMLVar"
2627
+ }
2628
+ ],
2629
+ "description": "SWML to execute after the bridge completes. This defines what should happen after the call is connected and the bridge ends.\nCan be either:\n- A URL (http or https) that returns a SWML document\n- An inline SWML document (as a JSON string)\n\n**Note:** This parameter is REQUIRED when connecting to a queue (when `to` starts with \"queue:\")"
2630
+ },
2578
2631
  "call_state_events": {
2579
2632
  "type": "array",
2580
2633
  "items": {
@@ -2753,6 +2806,17 @@
2753
2806
  "format": "uri",
2754
2807
  "description": "http or https URL to deliver call status events"
2755
2808
  },
2809
+ "transfer_after_bridge": {
2810
+ "anyOf": [
2811
+ {
2812
+ "type": "string"
2813
+ },
2814
+ {
2815
+ "$ref": "#/$defs/SWMLVar"
2816
+ }
2817
+ ],
2818
+ "description": "SWML to execute after the bridge completes. This defines what should happen after the call is connected and the bridge ends.\nCan be either:\n- A URL (http or https) that returns a SWML document\n- An inline SWML document (as a JSON string)\n\n**Note:** This parameter is REQUIRED when connecting to a queue (when `to` starts with \"queue:\")"
2819
+ },
2756
2820
  "call_state_events": {
2757
2821
  "type": "array",
2758
2822
  "items": {
@@ -2782,6 +2846,63 @@
2782
2846
  },
2783
2847
  "title": "ConnectDeviceSerialParallel object"
2784
2848
  },
2849
+ "EnterQueueObject": {
2850
+ "type": "object",
2851
+ "properties": {
2852
+ "queue_name": {
2853
+ "type": "string",
2854
+ "description": "Name of the queue to enter."
2855
+ },
2856
+ "transfer_after_bridge": {
2857
+ "anyOf": [
2858
+ {
2859
+ "type": "string"
2860
+ },
2861
+ {
2862
+ "$ref": "#/$defs/SWMLVar"
2863
+ }
2864
+ ],
2865
+ "description": "SWML to execute after the bridge completes. This defines what should happen after the call is connected to an agent and the bridge ends.\nCan be either:\n- A URL (http or https) that returns a SWML document\n- An inline SWML document (as a JSON string)"
2866
+ },
2867
+ "status_url": {
2868
+ "type": "string",
2869
+ "format": "uri",
2870
+ "description": "HTTP or HTTPS URL to deliver queue status events. Default not set"
2871
+ },
2872
+ "wait_url": {
2873
+ "anyOf": [
2874
+ {
2875
+ "type": "string",
2876
+ "format": "uri"
2877
+ },
2878
+ {
2879
+ "$ref": "#/$defs/SWMLVar"
2880
+ }
2881
+ ],
2882
+ "description": "URL for media to play while waiting in the queue. Default hold music will be played if not set"
2883
+ },
2884
+ "wait_time": {
2885
+ "anyOf": [
2886
+ {
2887
+ "type": "integer"
2888
+ },
2889
+ {
2890
+ "$ref": "#/$defs/SWMLVar"
2891
+ }
2892
+ ],
2893
+ "minimum": 1,
2894
+ "description": "Maximum time in seconds to wait in the queue before timeout. Default `3600`"
2895
+ }
2896
+ },
2897
+ "required": [
2898
+ "queue_name",
2899
+ "transfer_after_bridge"
2900
+ ],
2901
+ "unevaluatedProperties": {
2902
+ "not": {}
2903
+ },
2904
+ "title": "EnterQueueObject object"
2905
+ },
2785
2906
  "ExecuteSwitch": {
2786
2907
  "type": "object",
2787
2908
  "properties": {
@@ -8665,6 +8786,12 @@
8665
8786
  {
8666
8787
  "$ref": "#/$defs/SWMLAction"
8667
8788
  },
8789
+ {
8790
+ "$ref": "#/$defs/ChangeContextAction"
8791
+ },
8792
+ {
8793
+ "$ref": "#/$defs/ChangeStepAction"
8794
+ },
8668
8795
  {
8669
8796
  "$ref": "#/$defs/ContextSwitchAction"
8670
8797
  },
@@ -8860,6 +8987,40 @@
8860
8987
  },
8861
8988
  "title": "SWMLAction object"
8862
8989
  },
8990
+ "ChangeContextAction": {
8991
+ "type": "object",
8992
+ "properties": {
8993
+ "change_context": {
8994
+ "type": "string",
8995
+ "description": "The name of the context to switch to. The context must be defined in the AI's prompt.contexts configuration.",
8996
+ "title": "change_context"
8997
+ }
8998
+ },
8999
+ "required": [
9000
+ "change_context"
9001
+ ],
9002
+ "unevaluatedProperties": {
9003
+ "not": {}
9004
+ },
9005
+ "title": "ChangeContextAction object"
9006
+ },
9007
+ "ChangeStepAction": {
9008
+ "type": "object",
9009
+ "properties": {
9010
+ "change_step": {
9011
+ "type": "string",
9012
+ "description": "The name of the step to switch to. The step must be defined in the current context's steps array.",
9013
+ "title": "change_step"
9014
+ }
9015
+ },
9016
+ "required": [
9017
+ "change_step"
9018
+ ],
9019
+ "unevaluatedProperties": {
9020
+ "not": {}
9021
+ },
9022
+ "title": "ChangeStepAction object"
9023
+ },
8863
9024
  "ContextSwitchAction": {
8864
9025
  "type": "object",
8865
9026
  "properties": {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: signalwire_agents
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: SignalWire AI Agents SDK
5
5
  Author-email: SignalWire Team <info@signalwire.com>
6
6
  License: MIT