signalwire-sdk 3.0.2.dev63__tar.gz → 3.0.2.dev65__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 (211) hide show
  1. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/PKG-INFO +1 -1
  2. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/pyproject.toml +35 -1
  3. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/__init__.py +15 -15
  4. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/agent_server.py +44 -54
  5. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/agents/bedrock.py +8 -8
  6. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/build_search.py +22 -19
  7. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/agent_loader.py +30 -27
  8. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/argparse_helpers.py +9 -16
  9. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/dynamic_config.py +2 -2
  10. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/service_loader.py +30 -34
  11. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/dokku.py +18 -15
  12. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/execution/datamap_exec.py +14 -16
  13. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/execution/webhook_exec.py +5 -5
  14. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/init_project.py +29 -32
  15. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/output/output_formatter.py +8 -17
  16. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/output/swml_dump.py +18 -19
  17. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/simulation/data_generation.py +14 -16
  18. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/simulation/data_overrides.py +9 -10
  19. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/simulation/mock_env.py +21 -20
  20. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/swaig_test_wrapper.py +3 -2
  21. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/test_swaig.py +12 -8
  22. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/types.py +15 -15
  23. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/prompt/manager.py +15 -15
  24. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/tools/registry.py +76 -74
  25. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/tools/type_inference.py +10 -12
  26. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent_base.py +105 -107
  27. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/auth_handler.py +8 -7
  28. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/config_loader.py +26 -27
  29. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/contexts.py +80 -81
  30. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/data_map.py +31 -35
  31. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/function_result.py +81 -90
  32. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/logging_config.py +6 -11
  33. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/ai_config_mixin.py +31 -30
  34. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/auth_mixin.py +6 -9
  35. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/mcp_server_mixin.py +5 -5
  36. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/prompt_mixin.py +60 -67
  37. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/serverless_mixin.py +79 -94
  38. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/skill_mixin.py +3 -3
  39. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/state_mixin.py +3 -8
  40. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/tool_mixin.py +14 -13
  41. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/web_mixin.py +34 -37
  42. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/pom_builder.py +11 -11
  43. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/session_manager.py +6 -9
  44. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/webhook_middleware.py +5 -4
  45. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/webhook_validator.py +17 -16
  46. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security_config.py +17 -17
  47. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/skill_base.py +15 -15
  48. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/skill_manager.py +17 -22
  49. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swaig_function.py +24 -28
  50. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swml_builder.py +31 -33
  51. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swml_handler.py +15 -15
  52. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swml_renderer.py +20 -20
  53. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swml_service.py +70 -73
  54. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/livewire/__init__.py +32 -30
  55. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/livewire/plugins.py +2 -2
  56. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/mcp_gateway/gateway_service.py +28 -27
  57. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/mcp_gateway/mcp_manager.py +39 -38
  58. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/mcp_gateway/session_manager.py +9 -9
  59. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/pom/pom.py +29 -38
  60. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/pom/pom_tool.py +13 -14
  61. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/concierge.py +15 -18
  62. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/faq_bot.py +8 -9
  63. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/info_gatherer.py +17 -18
  64. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/receptionist.py +4 -6
  65. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/survey.py +10 -9
  66. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/__init__.py +1 -1
  67. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/call.py +222 -208
  68. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/client.py +61 -39
  69. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/event.py +26 -26
  70. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/message.py +23 -8
  71. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/__init__.py +1 -1
  72. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/phone_numbers.py +4 -6
  73. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/__init__.py +11 -10
  74. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/document_processor.py +98 -105
  75. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/index_builder.py +40 -45
  76. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/migration.py +9 -9
  77. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/pgvector_backend.py +61 -54
  78. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/query_processor.py +16 -20
  79. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/search_engine.py +90 -94
  80. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/search_service.py +61 -63
  81. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/__init__.py +1 -1
  82. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/api_ninjas_trivia/skill.py +6 -6
  83. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/claude_skills/skill.py +20 -26
  84. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere/skill.py +10 -8
  85. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere_serverless/skill.py +11 -7
  86. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datetime/skill.py +9 -11
  87. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/google_maps/skill.py +11 -10
  88. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/info_gatherer/skill.py +7 -7
  89. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/joke/skill.py +9 -7
  90. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/math/skill.py +14 -16
  91. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/mcp_gateway/skill.py +34 -38
  92. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/native_vector_search/skill.py +44 -43
  93. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/play_background_file/skill.py +5 -5
  94. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/registry.py +18 -18
  95. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/spider/skill.py +29 -27
  96. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/swml_transfer/skill.py +13 -12
  97. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/weather_api/skill.py +5 -5
  98. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/skill.py +27 -34
  99. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/skill_improved.py +20 -23
  100. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/skill_original.py +19 -20
  101. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/wikipedia_search/skill.py +8 -9
  102. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/schema_utils.py +64 -61
  103. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/web/web_service.py +45 -49
  104. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/PKG-INFO +1 -1
  105. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/LICENSE +0 -0
  106. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/README.md +0 -0
  107. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/man/sw-agent-init.1 +0 -0
  108. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/man/sw-search.1 +0 -0
  109. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/man/swaig-test.1 +0 -0
  110. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/setup.cfg +0 -0
  111. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/setup.py +0 -0
  112. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/__init__.py +0 -0
  113. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/config.py +0 -0
  114. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/__init__.py +0 -0
  115. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/execution/__init__.py +0 -0
  116. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/output/__init__.py +0 -0
  117. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/simulation/__init__.py +0 -0
  118. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/__init__.py +1 -1
  119. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/_agent_host.py +0 -0
  120. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/__init__.py +0 -0
  121. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/config/__init__.py +0 -0
  122. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/deployment/__init__.py +0 -0
  123. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/deployment/handlers/__init__.py +0 -0
  124. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/prompt/__init__.py +0 -0
  125. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/routing/__init__.py +0 -0
  126. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/security/__init__.py +0 -0
  127. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/swml/__init__.py +0 -0
  128. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/tools/__init__.py +2 -2
  129. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/tools/decorator.py +0 -0
  130. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/__init__.py +5 -5
  131. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/_mixin_host.py +0 -0
  132. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/__init__.py +5 -5
  133. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/security_utils.py +0 -0
  134. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/mcp_gateway/__init__.py +4 -4
  135. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/pom/__init__.py +0 -0
  136. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/__init__.py +3 -3
  137. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/constants.py +0 -0
  138. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/_base.py +0 -0
  139. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/_pagination.py +0 -0
  140. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/call_handler.py +0 -0
  141. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/client.py +0 -0
  142. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/__init__.py +0 -0
  143. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/addresses.py +0 -0
  144. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/calling.py +0 -0
  145. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/chat.py +0 -0
  146. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/compat.py +0 -0
  147. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/datasphere.py +0 -0
  148. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/fabric.py +0 -0
  149. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/imported_numbers.py +0 -0
  150. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/logs.py +0 -0
  151. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/lookup.py +0 -0
  152. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/mfa.py +0 -0
  153. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/number_groups.py +0 -0
  154. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/project.py +0 -0
  155. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/pubsub.py +0 -0
  156. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/queues.py +0 -0
  157. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/recordings.py +0 -0
  158. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/registry.py +0 -0
  159. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/short_codes.py +0 -0
  160. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/sip_profile.py +0 -0
  161. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/verified_callers.py +0 -0
  162. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/video.py +0 -0
  163. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/schema.json +0 -0
  164. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/models.py +0 -0
  165. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/README.md +0 -0
  166. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/api_ninjas_trivia/README.md +0 -0
  167. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/api_ninjas_trivia/__init__.py +0 -0
  168. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/claude_skills/README.md +0 -0
  169. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/claude_skills/__init__.py +0 -0
  170. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere/README.md +0 -0
  171. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere/__init__.py +0 -0
  172. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere_serverless/README.md +0 -0
  173. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere_serverless/__init__.py +0 -0
  174. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datetime/README.md +0 -0
  175. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datetime/__init__.py +0 -0
  176. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/google_maps/__init__.py +0 -0
  177. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/info_gatherer/README.md +0 -0
  178. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/info_gatherer/__init__.py +0 -0
  179. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/joke/README.md +0 -0
  180. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/joke/__init__.py +0 -0
  181. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/math/README.md +0 -0
  182. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/math/__init__.py +0 -0
  183. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/mcp_gateway/README.md +0 -0
  184. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/mcp_gateway/__init__.py +0 -0
  185. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/native_vector_search/README.md +0 -0
  186. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/native_vector_search/__init__.py +0 -0
  187. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/play_background_file/README.md +0 -0
  188. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/play_background_file/__init__.py +0 -0
  189. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/spider/README.md +0 -0
  190. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/spider/__init__.py +0 -0
  191. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/swml_transfer/README.md +0 -0
  192. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/swml_transfer/__init__.py +0 -0
  193. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/weather_api/README.md +0 -0
  194. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/weather_api/__init__.py +0 -0
  195. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/README.md +0 -0
  196. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/__init__.py +0 -0
  197. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/wikipedia_search/README.md +0 -0
  198. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/wikipedia_search/__init__.py +0 -0
  199. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/__init__.py +0 -0
  200. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/pom_utils.py +0 -0
  201. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/token_generators.py +0 -0
  202. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/url_validator.py +0 -0
  203. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/validators.py +0 -0
  204. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/web/__init__.py +0 -0
  205. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/SOURCES.txt +0 -0
  206. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/dependency_links.txt +0 -0
  207. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/entry_points.txt +0 -0
  208. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/requires.txt +0 -0
  209. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/top_level.txt +0 -0
  210. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/tests/test_examples.py +0 -0
  211. {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/tests/test_mcp_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: signalwire-sdk
3
- Version: 3.0.2.dev63
3
+ Version: 3.0.2.dev65
4
4
  Summary: SignalWire 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-sdk"
7
- version = "3.0.2.dev63"
7
+ version = "3.0.2.dev65"
8
8
  description = "SignalWire SDK"
9
9
  authors = [
10
10
  {name = "SignalWire Team", email = "info@signalwire.com"}
@@ -166,6 +166,40 @@ signalwire = [
166
166
  target-version = "py310"
167
167
  line-length = 88
168
168
 
169
+ [tool.ruff.lint]
170
+ # E4/E7/E9 + F are the ruff defaults (E501 line-length intentionally excluded —
171
+ # formatting is owned by `ruff format`, not the linter). B = flake8-bugbear
172
+ # (likely-bug patterns), S = flake8-bandit (security smells).
173
+ select = ["E4", "E7", "E9", "F", "B", "S", "C4", "PERF", "SIM", "PTH", "RET", "RUF", "UP"]
174
+
175
+ [tool.ruff.lint.per-file-ignores]
176
+ # Tests are built on assert; bandit's S101 is noise there.
177
+ "tests/**" = ["S101"]
178
+ # sw-agent-dokku is a developer-run deploy CLI that shells out to git/ssh with
179
+ # fixed list-form arg vectors (shell=False, so no shell interpolation). The
180
+ # dynamic parts (app name, dokku host, config vars) are the operator's own CLI
181
+ # args for their own deployment — not untrusted server input. S603 (subprocess
182
+ # call) and S607 (partial executable path: git/ssh resolved via PATH, the normal
183
+ # idiom) are expected and safe across this file.
184
+ "signalwire/signalwire/cli/dokku.py" = ["S603", "S607"]
185
+
186
+ [tool.ruff.lint.flake8-bugbear]
187
+ # FastAPI's dependency-injection idiom puts Depends()/Query()/etc. in argument
188
+ # defaults on purpose; B008 (function-call-in-default) is a false positive for it.
189
+ # Both the bare (`from fastapi import Depends`) and qualified forms are listed
190
+ # because the code imports these names directly.
191
+ extend-immutable-calls = [
192
+ "Depends", "fastapi.Depends",
193
+ "Query", "fastapi.Query",
194
+ "Body", "fastapi.Body",
195
+ "Header", "fastapi.Header",
196
+ "Cookie", "fastapi.Cookie",
197
+ "Path", "fastapi.Path",
198
+ "Form", "fastapi.Form",
199
+ "File", "fastapi.File",
200
+ "Security", "fastapi.Security",
201
+ ]
202
+
169
203
  [tool.mypy]
170
204
  python_version = "3.10"
171
205
  files = ["signalwire/signalwire"]
@@ -17,7 +17,7 @@ from .core.logging_config import configure_logging
17
17
 
18
18
  configure_logging()
19
19
 
20
- __version__ = "3.0.2.dev63"
20
+ __version__ = "3.0.2.dev65"
21
21
 
22
22
  # Import core classes for easier access.
23
23
  # These imports are intentionally placed after configure_logging() so the SDK's
@@ -148,26 +148,26 @@ def RestClient(*args, **kwargs):
148
148
  __all__ = [
149
149
  "AgentBase",
150
150
  "AgentServer",
151
- "SWMLService",
152
- "SWMLBuilder",
153
- "FunctionResult",
154
- "SWAIGFunction",
155
- "DataMap",
156
- "create_simple_api_tool",
157
- "create_expression_tool",
158
- "ContextBuilder",
151
+ "BedrockAgent",
159
152
  "Context",
160
- "Step",
153
+ "ContextBuilder",
154
+ "DataMap",
155
+ "FunctionResult",
161
156
  "GatherInfo",
162
157
  "GatherQuestion",
163
- "create_simple_context",
164
- "SwaigFunctionResult",
158
+ "RestClient",
159
+ "SWAIGFunction",
160
+ "SWMLBuilder",
161
+ "SWMLService",
165
162
  "SchemaValidationError",
163
+ "Step",
164
+ "SwaigFunctionResult",
166
165
  "WebService",
166
+ "add_skill_directory",
167
+ "create_expression_tool",
168
+ "create_simple_api_tool",
169
+ "create_simple_context",
167
170
  "list_skills",
168
171
  "list_skills_with_params",
169
172
  "register_skill",
170
- "add_skill_directory",
171
- "BedrockAgent",
172
- "RestClient",
173
173
  ]
@@ -11,7 +11,9 @@ AgentServer - Class for hosting multiple SignalWire AI Agents in a single server
11
11
 
12
12
  import os
13
13
  import re
14
- from typing import Dict, Any, Optional, List, Tuple, Callable
14
+ from pathlib import Path
15
+ from typing import Any
16
+ from collections.abc import Callable
15
17
 
16
18
  try:
17
19
  from fastapi import FastAPI, Request, Response
@@ -19,11 +21,12 @@ try:
19
21
  except ImportError:
20
22
  raise ImportError(
21
23
  "fastapi and uvicorn are required. Install them with: pip install fastapi uvicorn"
22
- )
24
+ ) from None
23
25
 
24
26
  from signalwire.core.agent_base import AgentBase
25
27
  from signalwire.core.swml_service import SWMLService
26
28
  from signalwire.core.logging_config import get_logger
29
+ import contextlib
27
30
 
28
31
 
29
32
  class AgentServer:
@@ -41,7 +44,10 @@ class AgentServer:
41
44
  """
42
45
 
43
46
  def __init__(
44
- self, host: str = "0.0.0.0", port: int = 3000, log_level: str = "info"
47
+ self,
48
+ host: str = "0.0.0.0", # noqa: S104 # intended server default: listen on all interfaces (overridable)
49
+ port: int = 3000,
50
+ log_level: str = "info",
45
51
  ):
46
52
  """
47
53
  Initialize a new agent server
@@ -61,7 +67,7 @@ class AgentServer:
61
67
  self.app = FastAPI(
62
68
  title="SignalWire AI Agents",
63
69
  description="Hosted SignalWire AI Agents",
64
- version="3.0.2.dev63",
70
+ version="3.0.2.dev65",
65
71
  redirect_slashes=False,
66
72
  docs_url=None,
67
73
  redoc_url=None,
@@ -83,12 +89,12 @@ class AgentServer:
83
89
  return response
84
90
 
85
91
  # Keep track of registered agents
86
- self.agents: Dict[str, AgentBase] = {}
92
+ self.agents: dict[str, AgentBase] = {}
87
93
 
88
94
  # Keep track of SIP routing configuration
89
95
  self._sip_routing_enabled = False
90
- self._sip_route: Optional[str] = None
91
- self._sip_username_mapping: Dict[str, str] = {} # Maps SIP usernames to routes
96
+ self._sip_route: str | None = None
97
+ self._sip_username_mapping: dict[str, str] = {} # Maps SIP usernames to routes
92
98
 
93
99
  # Register health endpoints immediately so they're available
94
100
  # whether using server.run() or server.app with gunicorn
@@ -101,7 +107,7 @@ class AgentServer:
101
107
  async def _setup_catch_all():
102
108
  self._register_catch_all_handler()
103
109
 
104
- def register(self, agent: AgentBase, route: Optional[str] = None) -> None:
110
+ def register(self, agent: AgentBase, route: str | None = None) -> None:
105
111
  """
106
112
  Register an agent with the server
107
113
 
@@ -183,8 +189,8 @@ class AgentServer:
183
189
 
184
190
  # Create a unified routing callback that checks all registered usernames
185
191
  def server_sip_routing_callback(
186
- request: Request, body: Dict[str, Any]
187
- ) -> Optional[str]:
192
+ request: Request, body: dict[str, Any]
193
+ ) -> str | None:
188
194
  """Unified SIP routing callback that checks all registered usernames"""
189
195
  # Extract the SIP username
190
196
  sip_username = SWMLService.extract_sip_username(body)
@@ -198,10 +204,7 @@ class AgentServer:
198
204
  if target_route:
199
205
  self.logger.info(f"Routing SIP request to {target_route}")
200
206
  return target_route
201
- else:
202
- self.logger.warning(
203
- f"No route found for SIP username: {sip_username}"
204
- )
207
+ self.logger.warning(f"No route found for SIP username: {sip_username}")
205
208
 
206
209
  # No routing needed (will be handled by the current agent)
207
210
  return None
@@ -246,7 +249,7 @@ class AgentServer:
246
249
  self._sip_username_mapping[username.lower()] = route
247
250
  self.logger.info(f"Registered SIP username '{username}' to route '{route}'")
248
251
 
249
- def _lookup_sip_route(self, username: str) -> Optional[str]:
252
+ def _lookup_sip_route(self, username: str) -> str | None:
250
253
  """
251
254
  Look up the route for a SIP username
252
255
 
@@ -311,7 +314,7 @@ class AgentServer:
311
314
  self.logger.info("agent_unregistered", extra={"route": route})
312
315
  return True
313
316
 
314
- def get_agents(self) -> List[Tuple[str, AgentBase]]:
317
+ def get_agents(self) -> list[tuple[str, AgentBase]]:
315
318
  """
316
319
  Get all registered agents
317
320
 
@@ -320,7 +323,7 @@ class AgentServer:
320
323
  """
321
324
  return [(route, agent) for route, agent in self.agents.items()]
322
325
 
323
- def get_agent(self, route: str) -> Optional[AgentBase]:
326
+ def get_agent(self, route: str) -> AgentBase | None:
324
327
  """
325
328
  Get an agent by route
326
329
 
@@ -342,8 +345,8 @@ class AgentServer:
342
345
  self,
343
346
  event=None,
344
347
  context=None,
345
- host: Optional[str] = None,
346
- port: Optional[int] = None,
348
+ host: str | None = None,
349
+ port: int | None = None,
347
350
  ) -> Any:
348
351
  """
349
352
  Universal run method that automatically detects environment and handles accordingly
@@ -372,11 +375,10 @@ class AgentServer:
372
375
 
373
376
  if mode == "cgi":
374
377
  return self._handle_cgi_request()
375
- elif mode == "lambda":
378
+ if mode == "lambda":
376
379
  return self._handle_lambda_request(event, context)
377
- else:
378
- # Server mode - use existing logic
379
- return self._run_server(host, port)
380
+ # Server mode - use existing logic
381
+ return self._run_server(host, port)
380
382
 
381
383
  def _handle_cgi_request(self) -> str:
382
384
  """Handle CGI request using same routing logic as server"""
@@ -405,7 +407,7 @@ class AgentServer:
405
407
  swml, content_type="application/json"
406
408
  )
407
409
  except Exception as e:
408
- self.logger.error(f"Failed to generate SWML: {str(e)}")
410
+ self.logger.error(f"Failed to generate SWML: {e!s}")
409
411
  error_response = {"error": "Failed to generate SWML"}
410
412
  return self._format_cgi_response(
411
413
  error_response, status="500 Internal Server Error"
@@ -449,7 +451,7 @@ class AgentServer:
449
451
  )
450
452
 
451
453
  except Exception as e:
452
- self.logger.error(f"SWAIG function failed: {str(e)}")
454
+ self.logger.error(f"SWAIG function failed: {e!s}")
453
455
  error_response = {"error": "SWAIG function failed"}
454
456
  return self._format_cgi_response(
455
457
  error_response, status="500 Internal Server Error"
@@ -499,7 +501,7 @@ class AgentServer:
499
501
  )
500
502
 
501
503
  except Exception as e:
502
- self.logger.error(f"Function call failed: {str(e)}")
504
+ self.logger.error(f"Function call failed: {e!s}")
503
505
  error_response = {"error": "Function call failed"}
504
506
  return self._format_cgi_response(
505
507
  error_response, status="500 Internal Server Error"
@@ -544,7 +546,7 @@ class AgentServer:
544
546
  "body": json.dumps(swml) if isinstance(swml, dict) else swml,
545
547
  }
546
548
  except Exception as e:
547
- self.logger.error(f"Failed to generate SWML: {str(e)}")
549
+ self.logger.error(f"Failed to generate SWML: {e!s}")
548
550
  return {
549
551
  "statusCode": 500,
550
552
  "headers": {"Content-Type": "application/json"},
@@ -568,10 +570,8 @@ class AgentServer:
568
570
  # Get POST data from Lambda event body
569
571
  post_data = {}
570
572
  if event and "body" in event and event["body"]:
571
- try:
573
+ with contextlib.suppress(json.JSONDecodeError, ValueError):
572
574
  post_data = json.loads(event["body"])
573
- except (json.JSONDecodeError, ValueError):
574
- pass
575
575
 
576
576
  result = agent._execute_swaig_function(
577
577
  function_name, post_data, None, None
@@ -585,7 +585,7 @@ class AgentServer:
585
585
  }
586
586
 
587
587
  except Exception as e:
588
- self.logger.error(f"Function call failed: {str(e)}")
588
+ self.logger.error(f"Function call failed: {e!s}")
589
589
  return {
590
590
  "statusCode": 500,
591
591
  "headers": {"Content-Type": "application/json"},
@@ -607,10 +607,7 @@ class AgentServer:
607
607
  import sys
608
608
 
609
609
  # Format the body
610
- if isinstance(data, dict):
611
- body = json.dumps(data)
612
- else:
613
- body = str(data)
610
+ body = json.dumps(data) if isinstance(data, dict) else str(data)
614
611
 
615
612
  # Build CGI response with headers
616
613
  response_lines = [
@@ -648,9 +645,7 @@ class AgentServer:
648
645
  def readiness_check():
649
646
  return {"status": "ready", "agents": len(self.agents)}
650
647
 
651
- def _run_server(
652
- self, host: Optional[str] = None, port: Optional[int] = None
653
- ) -> None:
648
+ def _run_server(self, host: str | None = None, port: int | None = None) -> None:
654
649
  """Original server mode logic"""
655
650
  if not self.agents:
656
651
  self.logger.warning("Starting server with no registered agents")
@@ -668,10 +663,10 @@ class AgentServer:
668
663
 
669
664
  # Validate SSL configuration if enabled
670
665
  if ssl_enabled:
671
- if not ssl_cert_path or not os.path.exists(ssl_cert_path):
666
+ if not ssl_cert_path or not Path(ssl_cert_path).exists():
672
667
  self.logger.warning(f"SSL cert not found: {ssl_cert_path}")
673
668
  ssl_enabled = False
674
- elif not ssl_key_path or not os.path.exists(ssl_key_path):
669
+ elif not ssl_key_path or not Path(ssl_key_path).exists():
675
670
  self.logger.warning(f"SSL key not found: {ssl_key_path}")
676
671
  ssl_enabled = False
677
672
 
@@ -687,7 +682,7 @@ class AgentServer:
687
682
  display_host = f"{host}:{port}"
688
683
 
689
684
  self.logger.info(f"Starting server on {protocol}://{display_host}")
690
- for route, agent in self.agents.items():
685
+ for agent in self.agents.values():
691
686
  # include_source defaults False -> 2-tuple at runtime; index to
692
687
  # avoid the union-tuple unpack ambiguity mypy sees.
693
688
  creds = agent.get_basic_auth_credentials()
@@ -714,7 +709,7 @@ class AgentServer:
714
709
  uvicorn.run(self.app, host=host, port=port, log_level=self.log_level)
715
710
 
716
711
  def register_global_routing_callback(
717
- self, callback_fn: Callable[[Request, Dict[str, Any]], Optional[str]], path: str
712
+ self, callback_fn: Callable[[Request, dict[str, Any]], str | None], path: str
718
713
  ) -> None:
719
714
  """
720
715
  Register a routing callback across all agents
@@ -785,9 +780,7 @@ class AgentServer:
785
780
  f"Serving static files from '{directory}' at route '{route or '/'}'"
786
781
  )
787
782
 
788
- def _serve_static_file(
789
- self, file_path: str, route: str = "/"
790
- ) -> Optional[Response]:
783
+ def _serve_static_file(self, file_path: str, route: str = "/") -> Response | None:
791
784
  """
792
785
  Internal method to serve a static file.
793
786
 
@@ -860,7 +853,7 @@ class AgentServer:
860
853
  if full_path == route.lstrip("/"):
861
854
  # This is a request to an agent's root without trailing slash
862
855
  return await agent._handle_root_request(request)
863
- elif full_path.startswith(route.lstrip("/") + "/"):
856
+ if full_path.startswith(route.lstrip("/") + "/"):
864
857
  # This is a request to an agent's sub-path
865
858
  relative_path = full_path[len(route.lstrip("/")) :]
866
859
  relative_path = relative_path.lstrip("/")
@@ -872,21 +865,18 @@ class AgentServer:
872
865
  clean_path = relative_path.rstrip("/")
873
866
  if clean_path == "debug":
874
867
  return await agent._handle_debug_request(request)
875
- elif clean_path == "swaig":
868
+ if clean_path == "swaig":
876
869
  from fastapi import Response
877
870
 
878
871
  return await agent._handle_swaig_request(request, Response())
879
- elif clean_path == "post_prompt":
872
+ if clean_path == "post_prompt":
880
873
  return await agent._handle_post_prompt_request(request)
881
- elif clean_path == "check_for_input":
874
+ if clean_path == "check_for_input":
882
875
  return await agent._handle_check_for_input_request(request)
883
876
 
884
877
  # Check for custom routing callbacks
885
878
  if hasattr(agent, "_routing_callbacks"):
886
- for (
887
- callback_path,
888
- callback_fn,
889
- ) in agent._routing_callbacks.items():
879
+ for callback_path in agent._routing_callbacks:
890
880
  cb_path_clean = callback_path.strip("/")
891
881
  if clean_path == cb_path_clean:
892
882
  request.state.callback_path = callback_path
@@ -895,7 +885,7 @@ class AgentServer:
895
885
  # No matching agent - check for static files
896
886
  if hasattr(self, "_static_directories"):
897
887
  # Check each static directory route
898
- for static_route, static_dir in self._static_directories.items():
888
+ for static_route in self._static_directories:
899
889
  # For root static route, serve any unmatched path
900
890
  if static_route == "" or static_route == "/":
901
891
  response = self._serve_static_file(full_path, "")
@@ -14,7 +14,7 @@ with all SignalWire agent features like skills, POM, and SWAIG functions.
14
14
  """
15
15
 
16
16
  import json
17
- from typing import Dict, Any, Optional
17
+ from typing import Any
18
18
  from signalwire.core.agent_base import AgentBase
19
19
  from signalwire.core.logging_config import get_logger
20
20
 
@@ -41,7 +41,7 @@ class BedrockAgent(AgentBase):
41
41
  self,
42
42
  name: str = "bedrock_agent",
43
43
  route: str = "/bedrock",
44
- system_prompt: Optional[str] = None,
44
+ system_prompt: str | None = None,
45
45
  voice_id: str = "matthew",
46
46
  temperature: float = 0.7,
47
47
  top_p: float = 0.9,
@@ -77,7 +77,7 @@ class BedrockAgent(AgentBase):
77
77
  logger.info(f"BedrockAgent initialized: {name} on route {route}")
78
78
 
79
79
  def _render_swml(
80
- self, call_id: Optional[str] = None, modifications: Optional[dict] = None
80
+ self, call_id: str | None = None, modifications: dict | None = None
81
81
  ) -> str:
82
82
  """
83
83
  Render SWML document with amazon_bedrock verb
@@ -143,7 +143,7 @@ class BedrockAgent(AgentBase):
143
143
  # Convert back to JSON string
144
144
  return json.dumps(swml)
145
145
 
146
- def _add_voice_to_prompt(self, prompt_config: Dict[str, Any]) -> Dict[str, Any]:
146
+ def _add_voice_to_prompt(self, prompt_config: dict[str, Any]) -> dict[str, Any]:
147
147
  """
148
148
  Add voice configuration to the prompt object
149
149
 
@@ -176,7 +176,7 @@ class BedrockAgent(AgentBase):
176
176
 
177
177
  return filtered_config
178
178
 
179
- def _build_bedrock_params(self, base_params: Dict[str, Any]) -> Dict[str, Any]:
179
+ def _build_bedrock_params(self, base_params: dict[str, Any]) -> dict[str, Any]:
180
180
  """
181
181
  Build Bedrock-specific parameters
182
182
 
@@ -214,9 +214,9 @@ class BedrockAgent(AgentBase):
214
214
 
215
215
  def set_inference_params(
216
216
  self,
217
- temperature: Optional[float] = None,
218
- top_p: Optional[float] = None,
219
- max_tokens: Optional[int] = None,
217
+ temperature: float | None = None,
218
+ top_p: float | None = None,
219
+ max_tokens: int | None = None,
220
220
  ) -> None:
221
221
  """
222
222
  Update Bedrock inference parameters
@@ -11,7 +11,7 @@ import argparse
11
11
  import sys
12
12
  from pathlib import Path
13
13
  from datetime import datetime
14
- from typing import List, cast
14
+ from typing import cast
15
15
  from urllib.parse import urlparse, urlunparse
16
16
 
17
17
  from signalwire.search.models import MODEL_ALIASES, DEFAULT_MODEL, resolve_model_alias
@@ -27,7 +27,7 @@ def _mask_connection_string(conn_str):
27
27
  + (f":{parsed.port}" if parsed.port else "")
28
28
  )
29
29
  return urlunparse(masked)
30
- except Exception:
30
+ except Exception: # noqa: S110 # best-effort password masking for display; falls through to "****" on any parse failure
31
31
  pass
32
32
  return "****"
33
33
 
@@ -538,7 +538,7 @@ Examples:
538
538
  },
539
539
  }
540
540
 
541
- with open(json_path, "w", encoding="utf-8") as f:
541
+ with json_path.open("w", encoding="utf-8") as f:
542
542
  json.dump(chunk_data, f, indent=2, ensure_ascii=False)
543
543
 
544
544
  chunk_files_created.append(json_path)
@@ -548,7 +548,7 @@ Examples:
548
548
  # Accumulate all chunks for single file output
549
549
  all_chunks.extend(chunks)
550
550
 
551
- except Exception as e:
551
+ except Exception as e: # noqa: PERF203 # per-iteration error isolation: one failed file must not abort the batch
552
552
  print(f"Error processing {file_path}: {e}")
553
553
  if args.verbose:
554
554
  import traceback
@@ -567,7 +567,7 @@ Examples:
567
567
  },
568
568
  }
569
569
 
570
- with open(args.output, "w", encoding="utf-8") as f:
570
+ with Path(args.output).open("w", encoding="utf-8") as f:
571
571
  json.dump(output_data, f, indent=2, ensure_ascii=False)
572
572
 
573
573
  print(f"✓ Exported {len(all_chunks)} chunks to {args.output}")
@@ -577,7 +577,7 @@ Examples:
577
577
  )
578
578
  total_chunks = 0
579
579
  for chunk_file in chunk_files_created:
580
- with open(chunk_file) as fh:
580
+ with chunk_file.open() as fh:
581
581
  total_chunks += len(json.load(fh)["chunks"])
582
582
  print(f" Total chunks: {total_chunks}")
583
583
 
@@ -634,7 +634,11 @@ Examples:
634
634
  # Check if the index was actually created
635
635
  import os
636
636
 
637
- if os.path.exists(args.output):
637
+ # Rationale for PTH110 suppression below: tests patch global
638
+ # os.path.exists separately from pathlib.Path.exists to drive this
639
+ # post-build check; Path.exists() would pick up the unrelated Path
640
+ # mock and break the test seam.
641
+ if os.path.exists(args.output): # noqa: PTH110
638
642
  print(f"\n✓ Search index created successfully: {args.output}")
639
643
  else:
640
644
  print("\n✗ Search index creation failed - no files were processed")
@@ -771,10 +775,11 @@ def search_command():
771
775
  args.model = MODEL_ALIASES[args.model]
772
776
 
773
777
  # Validate keyword weight if provided
774
- if args.keyword_weight is not None:
775
- if args.keyword_weight < 0.0 or args.keyword_weight > 1.0:
776
- print("Error: --keyword-weight must be between 0.0 and 1.0")
777
- sys.exit(1)
778
+ if args.keyword_weight is not None and (
779
+ args.keyword_weight < 0.0 or args.keyword_weight > 1.0
780
+ ):
781
+ print("Error: --keyword-weight must be between 0.0 and 1.0")
782
+ sys.exit(1)
778
783
 
779
784
  # Validate backend configuration
780
785
  if args.backend == "pgvector" and not args.connection_string:
@@ -861,9 +866,7 @@ def search_command():
861
866
  print(" help - Show this help")
862
867
  print(" exit/quit/q - Exit shell")
863
868
  print(
864
- " count=N - Set result count (current: {})".format(
865
- args.count
866
- )
869
+ f" count=N - Set result count (current: {args.count})"
867
870
  )
868
871
  print(
869
872
  " tags=tag1,tag2 - Set tag filter (current: {})".format(
@@ -922,7 +925,7 @@ def search_command():
922
925
  # Perform search
923
926
  results = engine.search(
924
927
  query_vector=cast(
925
- List[float], enhanced.get("vector")
928
+ list[float], enhanced.get("vector")
926
929
  ), # vector is None for keyword-only search; search() tolerates it at runtime
927
930
  enhanced_text=enhanced.get("enhanced_text", query),
928
931
  count=args.count,
@@ -1007,7 +1010,7 @@ def search_command():
1007
1010
  # Perform search
1008
1011
  results = engine.search(
1009
1012
  query_vector=cast(
1010
- List[float], enhanced.get("vector")
1013
+ list[float], enhanced.get("vector")
1011
1014
  ), # vector is None for keyword-only search; search() tolerates it at runtime
1012
1015
  enhanced_text=enhanced.get("enhanced_text", args.query),
1013
1016
  count=args.count,
@@ -1540,17 +1543,17 @@ Examples:
1540
1543
  sys.argv.pop(1)
1541
1544
  validate_command()
1542
1545
  return
1543
- elif sys.argv[1] == "search":
1546
+ if sys.argv[1] == "search":
1544
1547
  # Remove 'search' from argv and call search_command
1545
1548
  sys.argv.pop(1)
1546
1549
  search_command()
1547
1550
  return
1548
- elif sys.argv[1] == "remote":
1551
+ if sys.argv[1] == "remote":
1549
1552
  # Remove 'remote' from argv and call remote_command
1550
1553
  sys.argv.pop(1)
1551
1554
  remote_command()
1552
1555
  return
1553
- elif sys.argv[1] == "migrate":
1556
+ if sys.argv[1] == "migrate":
1554
1557
  # Remove 'migrate' from argv and call migrate_command
1555
1558
  sys.argv.pop(1)
1556
1559
  migrate_command()