signalwire-agents 1.0.12__tar.gz → 1.0.14__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 (154) hide show
  1. {signalwire_agents-1.0.12/signalwire_agents.egg-info → signalwire_agents-1.0.14}/PKG-INFO +1 -1
  2. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/pyproject.toml +2 -1
  3. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/__init__.py +1 -1
  4. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/agent_server.py +102 -64
  5. signalwire_agents-1.0.14/signalwire_agents/cli/dokku.py +2423 -0
  6. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14/signalwire_agents.egg-info}/PKG-INFO +1 -1
  7. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents.egg-info/SOURCES.txt +1 -0
  8. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents.egg-info/entry_points.txt +1 -0
  9. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/LICENSE +0 -0
  10. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/README.md +0 -0
  11. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/man/sw-agent-init.1 +0 -0
  12. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/man/sw-search.1 +0 -0
  13. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/man/swaig-test.1 +0 -0
  14. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/setup.cfg +0 -0
  15. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/setup.py +0 -0
  16. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/agents/bedrock.py +0 -0
  17. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/__init__.py +0 -0
  18. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/build_search.py +0 -0
  19. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/config.py +0 -0
  20. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/core/__init__.py +0 -0
  21. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/core/agent_loader.py +0 -0
  22. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/core/argparse_helpers.py +0 -0
  23. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/core/dynamic_config.py +0 -0
  24. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/core/service_loader.py +0 -0
  25. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/execution/__init__.py +0 -0
  26. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/execution/datamap_exec.py +0 -0
  27. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/execution/webhook_exec.py +0 -0
  28. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/init_project.py +0 -0
  29. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/output/__init__.py +0 -0
  30. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/output/output_formatter.py +0 -0
  31. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/output/swml_dump.py +0 -0
  32. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/simulation/__init__.py +0 -0
  33. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/simulation/data_generation.py +0 -0
  34. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/simulation/data_overrides.py +0 -0
  35. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/simulation/mock_env.py +0 -0
  36. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/swaig_test_wrapper.py +0 -0
  37. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/test_swaig.py +0 -0
  38. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/cli/types.py +0 -0
  39. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/__init__.py +0 -0
  40. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/__init__.py +0 -0
  41. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/config/__init__.py +0 -0
  42. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/deployment/__init__.py +0 -0
  43. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/deployment/handlers/__init__.py +0 -0
  44. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/prompt/__init__.py +0 -0
  45. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/prompt/manager.py +0 -0
  46. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/routing/__init__.py +0 -0
  47. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/security/__init__.py +0 -0
  48. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/swml/__init__.py +0 -0
  49. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/tools/__init__.py +0 -0
  50. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/tools/decorator.py +0 -0
  51. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent/tools/registry.py +0 -0
  52. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/agent_base.py +0 -0
  53. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/auth_handler.py +0 -0
  54. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/config_loader.py +0 -0
  55. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/contexts.py +0 -0
  56. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/data_map.py +0 -0
  57. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/function_result.py +0 -0
  58. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/logging_config.py +0 -0
  59. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/__init__.py +0 -0
  60. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/ai_config_mixin.py +0 -0
  61. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/auth_mixin.py +0 -0
  62. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/prompt_mixin.py +0 -0
  63. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/serverless_mixin.py +0 -0
  64. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/skill_mixin.py +0 -0
  65. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/state_mixin.py +0 -0
  66. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/tool_mixin.py +0 -0
  67. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/mixins/web_mixin.py +0 -0
  68. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/pom_builder.py +0 -0
  69. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/security/__init__.py +0 -0
  70. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/security/session_manager.py +0 -0
  71. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/security_config.py +0 -0
  72. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/skill_base.py +0 -0
  73. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/skill_manager.py +0 -0
  74. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/swaig_function.py +0 -0
  75. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/swml_builder.py +0 -0
  76. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/swml_handler.py +0 -0
  77. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/swml_renderer.py +0 -0
  78. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/core/swml_service.py +0 -0
  79. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/mcp_gateway/__init__.py +0 -0
  80. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/mcp_gateway/gateway_service.py +0 -0
  81. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/mcp_gateway/mcp_manager.py +0 -0
  82. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/mcp_gateway/session_manager.py +0 -0
  83. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/prefabs/__init__.py +0 -0
  84. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/prefabs/concierge.py +0 -0
  85. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/prefabs/faq_bot.py +0 -0
  86. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/prefabs/info_gatherer.py +0 -0
  87. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/prefabs/receptionist.py +0 -0
  88. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/prefabs/survey.py +0 -0
  89. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/schema.json +0 -0
  90. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/__init__.py +0 -0
  91. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/document_processor.py +0 -0
  92. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/index_builder.py +0 -0
  93. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/migration.py +0 -0
  94. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/models.py +0 -0
  95. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/pgvector_backend.py +0 -0
  96. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/query_processor.py +0 -0
  97. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/search_engine.py +0 -0
  98. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/search/search_service.py +0 -0
  99. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/README.md +0 -0
  100. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/__init__.py +0 -0
  101. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/api_ninjas_trivia/README.md +0 -0
  102. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/api_ninjas_trivia/__init__.py +0 -0
  103. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/api_ninjas_trivia/skill.py +0 -0
  104. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datasphere/README.md +0 -0
  105. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datasphere/__init__.py +0 -0
  106. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datasphere/skill.py +0 -0
  107. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datasphere_serverless/README.md +0 -0
  108. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datasphere_serverless/__init__.py +0 -0
  109. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datasphere_serverless/skill.py +0 -0
  110. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datetime/README.md +0 -0
  111. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datetime/__init__.py +0 -0
  112. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/datetime/skill.py +0 -0
  113. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/joke/README.md +0 -0
  114. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/joke/__init__.py +0 -0
  115. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/joke/skill.py +0 -0
  116. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/math/README.md +0 -0
  117. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/math/__init__.py +0 -0
  118. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/math/skill.py +0 -0
  119. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/mcp_gateway/README.md +0 -0
  120. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/mcp_gateway/__init__.py +0 -0
  121. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/mcp_gateway/skill.py +0 -0
  122. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/native_vector_search/README.md +0 -0
  123. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/native_vector_search/__init__.py +0 -0
  124. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/native_vector_search/skill.py +0 -0
  125. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/play_background_file/README.md +0 -0
  126. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/play_background_file/__init__.py +0 -0
  127. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/play_background_file/skill.py +0 -0
  128. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/registry.py +0 -0
  129. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/spider/README.md +0 -0
  130. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/spider/__init__.py +0 -0
  131. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/spider/skill.py +0 -0
  132. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/swml_transfer/README.md +0 -0
  133. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/swml_transfer/__init__.py +0 -0
  134. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/swml_transfer/skill.py +0 -0
  135. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/weather_api/README.md +0 -0
  136. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/weather_api/__init__.py +0 -0
  137. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/weather_api/skill.py +0 -0
  138. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/web_search/README.md +0 -0
  139. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/web_search/__init__.py +0 -0
  140. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/web_search/skill.py +0 -0
  141. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/wikipedia_search/README.md +0 -0
  142. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/wikipedia_search/__init__.py +0 -0
  143. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/skills/wikipedia_search/skill.py +0 -0
  144. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/utils/__init__.py +0 -0
  145. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/utils/pom_utils.py +0 -0
  146. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/utils/schema_utils.py +0 -0
  147. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/utils/token_generators.py +0 -0
  148. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/utils/validators.py +0 -0
  149. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/web/__init__.py +0 -0
  150. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents/web/web_service.py +0 -0
  151. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents.egg-info/dependency_links.txt +0 -0
  152. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents.egg-info/requires.txt +0 -0
  153. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/signalwire_agents.egg-info/top_level.txt +0 -0
  154. {signalwire_agents-1.0.12 → signalwire_agents-1.0.14}/tests/test_examples.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: signalwire_agents
3
- Version: 1.0.12
3
+ Version: 1.0.14
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.12"
7
+ version = "1.0.14"
8
8
  description = "SignalWire AI Agents SDK"
9
9
  authors = [
10
10
  {name = "SignalWire Team", email = "info@signalwire.com"}
@@ -136,6 +136,7 @@ Homepage = "https://github.com/signalwire/signalwire-agents"
136
136
  swaig-test = "signalwire_agents.cli.swaig_test_wrapper:main"
137
137
  sw-search = "signalwire_agents.cli.build_search:console_entry_point"
138
138
  sw-agent-init = "signalwire_agents.cli.init_project:main"
139
+ sw-agent-dokku = "signalwire_agents.cli.dokku:main"
139
140
  mcp-gateway = "signalwire_agents.mcp_gateway.gateway_service:main"
140
141
 
141
142
  [tool.setuptools]
@@ -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.12"
21
+ __version__ = "1.0.14"
22
22
 
23
23
  # Import core classes for easier access
24
24
  from .core.agent_base import AgentBase
@@ -67,11 +67,15 @@ class AgentServer:
67
67
 
68
68
  # Keep track of registered agents
69
69
  self.agents: Dict[str, AgentBase] = {}
70
-
70
+
71
71
  # Keep track of SIP routing configuration
72
72
  self._sip_routing_enabled = False
73
73
  self._sip_route = None
74
74
  self._sip_username_mapping: Dict[str, str] = {} # Maps SIP usernames to routes
75
+
76
+ # Register health endpoints immediately so they're available
77
+ # whether using server.run() or server.app with gunicorn
78
+ self._register_health_endpoints()
75
79
 
76
80
  def register(self, agent: AgentBase, route: Optional[str] = None) -> None:
77
81
  """
@@ -519,13 +523,13 @@ class AgentServer:
519
523
  sys.stdout.flush()
520
524
 
521
525
  return response
522
-
523
- def _run_server(self, host: Optional[str] = None, port: Optional[int] = None) -> None:
524
- """Original server mode logic"""
525
- if not self.agents:
526
- self.logger.warning("Starting server with no registered agents")
527
-
528
- # Add a health check endpoint
526
+
527
+ def _register_health_endpoints(self) -> None:
528
+ """Register health and readiness endpoints.
529
+
530
+ Called during __init__ so endpoints are available whether using
531
+ server.run() or accessing server.app directly with gunicorn.
532
+ """
529
533
  @self.app.get("/health")
530
534
  def health_check():
531
535
  return {
@@ -533,66 +537,22 @@ class AgentServer:
533
537
  "agents": len(self.agents),
534
538
  "routes": list(self.agents.keys())
535
539
  }
536
-
537
- # Add catch-all route handler to handle both trailing slash and non-trailing slash versions
538
- @self.app.get("/{full_path:path}")
539
- @self.app.post("/{full_path:path}")
540
- async def handle_all_routes(request: Request, full_path: str):
541
- """Handle requests that don't match registered routes (e.g. /matti instead of /matti/)"""
542
- # Check if this path maps to one of our registered agents
543
- for route, agent in self.agents.items():
544
- # Check for exact match with registered route
545
- if full_path == route.lstrip("/"):
546
- # This is a request to an agent's root without trailing slash
547
- return await agent._handle_root_request(request)
548
- elif full_path.startswith(route.lstrip("/") + "/"):
549
- # This is a request to an agent's sub-path
550
- relative_path = full_path[len(route.lstrip("/")):]
551
- relative_path = relative_path.lstrip("/")
552
540
 
553
- # Route to appropriate handler based on path
554
- if not relative_path or relative_path == "/":
555
- return await agent._handle_root_request(request)
556
-
557
- clean_path = relative_path.rstrip("/")
558
- if clean_path == "debug":
559
- return await agent._handle_debug_request(request)
560
- elif clean_path == "swaig":
561
- from fastapi import Response
562
- return await agent._handle_swaig_request(request, Response())
563
- elif clean_path == "post_prompt":
564
- return await agent._handle_post_prompt_request(request)
565
- elif clean_path == "check_for_input":
566
- return await agent._handle_check_for_input_request(request)
541
+ @self.app.get("/ready")
542
+ def readiness_check():
543
+ return {
544
+ "status": "ready",
545
+ "agents": len(self.agents)
546
+ }
567
547
 
568
- # Check for custom routing callbacks
569
- if hasattr(agent, '_routing_callbacks'):
570
- for callback_path, callback_fn in agent._routing_callbacks.items():
571
- cb_path_clean = callback_path.strip("/")
572
- if clean_path == cb_path_clean:
573
- request.state.callback_path = callback_path
574
- return await agent._handle_root_request(request)
548
+ def _run_server(self, host: Optional[str] = None, port: Optional[int] = None) -> None:
549
+ """Original server mode logic"""
550
+ if not self.agents:
551
+ self.logger.warning("Starting server with no registered agents")
575
552
 
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
553
+ # Register catch-all route handler (handles agent routing and static files)
554
+ self._register_catch_all_handler()
591
555
 
592
- # No matching agent or static file found
593
- from fastapi import HTTPException
594
- raise HTTPException(status_code=404, detail="Not Found")
595
-
596
556
  # Set host and port
597
557
  host = host or self.host
598
558
  port = port or self.port
@@ -722,6 +682,10 @@ class AgentServer:
722
682
 
723
683
  self.logger.info(f"Serving static files from '{directory}' at route '{route or '/'}'")
724
684
 
685
+ # Register catch-all handler immediately so it works with gunicorn
686
+ # (when using server.app directly instead of server.run())
687
+ self._register_catch_all_handler()
688
+
725
689
  def _serve_static_file(self, file_path: str, route: str = "/") -> Optional[Response]:
726
690
  """
727
691
  Internal method to serve a static file.
@@ -769,3 +733,77 @@ class AgentServer:
769
733
  return None
770
734
 
771
735
  return FileResponse(full_path)
736
+
737
+ def _register_catch_all_handler(self) -> None:
738
+ """
739
+ Register catch-all route handler for agent routing and static files.
740
+
741
+ This handler is needed for:
742
+ 1. Routing requests without trailing slashes to agents (e.g., /santa instead of /santa/)
743
+ 2. Serving static files from directories registered with serve_static_files()
744
+
745
+ The handler is registered once and works with both server.run() and
746
+ direct use of server.app with gunicorn/uvicorn.
747
+ """
748
+ # Only register once
749
+ if getattr(self, '_catch_all_registered', False):
750
+ return
751
+ self._catch_all_registered = True
752
+
753
+ @self.app.get("/{full_path:path}")
754
+ @self.app.post("/{full_path:path}")
755
+ async def handle_all_routes(request: Request, full_path: str):
756
+ """Handle requests that don't match registered routes (e.g. /matti instead of /matti/)"""
757
+ # Check if this path maps to one of our registered agents
758
+ for route, agent in self.agents.items():
759
+ # Check for exact match with registered route
760
+ if full_path == route.lstrip("/"):
761
+ # This is a request to an agent's root without trailing slash
762
+ return await agent._handle_root_request(request)
763
+ elif full_path.startswith(route.lstrip("/") + "/"):
764
+ # This is a request to an agent's sub-path
765
+ relative_path = full_path[len(route.lstrip("/")):]
766
+ relative_path = relative_path.lstrip("/")
767
+
768
+ # Route to appropriate handler based on path
769
+ if not relative_path or relative_path == "/":
770
+ return await agent._handle_root_request(request)
771
+
772
+ clean_path = relative_path.rstrip("/")
773
+ if clean_path == "debug":
774
+ return await agent._handle_debug_request(request)
775
+ elif clean_path == "swaig":
776
+ from fastapi import Response
777
+ return await agent._handle_swaig_request(request, Response())
778
+ elif clean_path == "post_prompt":
779
+ return await agent._handle_post_prompt_request(request)
780
+ elif clean_path == "check_for_input":
781
+ return await agent._handle_check_for_input_request(request)
782
+
783
+ # Check for custom routing callbacks
784
+ if hasattr(agent, '_routing_callbacks'):
785
+ for callback_path, callback_fn in agent._routing_callbacks.items():
786
+ cb_path_clean = callback_path.strip("/")
787
+ if clean_path == cb_path_clean:
788
+ request.state.callback_path = callback_path
789
+ return await agent._handle_root_request(request)
790
+
791
+ # No matching agent - check for static files
792
+ if hasattr(self, '_static_directories'):
793
+ # Check each static directory route
794
+ for static_route, static_dir in self._static_directories.items():
795
+ # For root static route, serve any unmatched path
796
+ if static_route == "" or static_route == "/":
797
+ response = self._serve_static_file(full_path, "")
798
+ if response:
799
+ return response
800
+ # For prefixed static routes, check if path matches
801
+ elif full_path.startswith(static_route.lstrip("/") + "/") or full_path == static_route.lstrip("/"):
802
+ relative_path = full_path[len(static_route.lstrip("/")):].lstrip("/")
803
+ response = self._serve_static_file(relative_path, static_route)
804
+ if response:
805
+ return response
806
+
807
+ # No matching agent or static file found
808
+ from fastapi import HTTPException
809
+ raise HTTPException(status_code=404, detail="Not Found")