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.
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/PKG-INFO +1 -1
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/pyproject.toml +35 -1
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/__init__.py +15 -15
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/agent_server.py +44 -54
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/agents/bedrock.py +8 -8
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/build_search.py +22 -19
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/agent_loader.py +30 -27
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/argparse_helpers.py +9 -16
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/dynamic_config.py +2 -2
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/service_loader.py +30 -34
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/dokku.py +18 -15
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/execution/datamap_exec.py +14 -16
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/execution/webhook_exec.py +5 -5
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/init_project.py +29 -32
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/output/output_formatter.py +8 -17
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/output/swml_dump.py +18 -19
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/simulation/data_generation.py +14 -16
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/simulation/data_overrides.py +9 -10
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/simulation/mock_env.py +21 -20
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/swaig_test_wrapper.py +3 -2
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/test_swaig.py +12 -8
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/types.py +15 -15
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/prompt/manager.py +15 -15
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/tools/registry.py +76 -74
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/tools/type_inference.py +10 -12
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent_base.py +105 -107
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/auth_handler.py +8 -7
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/config_loader.py +26 -27
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/contexts.py +80 -81
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/data_map.py +31 -35
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/function_result.py +81 -90
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/logging_config.py +6 -11
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/ai_config_mixin.py +31 -30
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/auth_mixin.py +6 -9
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/mcp_server_mixin.py +5 -5
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/prompt_mixin.py +60 -67
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/serverless_mixin.py +79 -94
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/skill_mixin.py +3 -3
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/state_mixin.py +3 -8
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/tool_mixin.py +14 -13
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/web_mixin.py +34 -37
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/pom_builder.py +11 -11
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/session_manager.py +6 -9
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/webhook_middleware.py +5 -4
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/webhook_validator.py +17 -16
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security_config.py +17 -17
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/skill_base.py +15 -15
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/skill_manager.py +17 -22
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swaig_function.py +24 -28
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swml_builder.py +31 -33
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swml_handler.py +15 -15
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swml_renderer.py +20 -20
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/swml_service.py +70 -73
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/livewire/__init__.py +32 -30
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/livewire/plugins.py +2 -2
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/mcp_gateway/gateway_service.py +28 -27
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/mcp_gateway/mcp_manager.py +39 -38
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/mcp_gateway/session_manager.py +9 -9
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/pom/pom.py +29 -38
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/pom/pom_tool.py +13 -14
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/concierge.py +15 -18
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/faq_bot.py +8 -9
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/info_gatherer.py +17 -18
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/receptionist.py +4 -6
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/survey.py +10 -9
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/__init__.py +1 -1
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/call.py +222 -208
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/client.py +61 -39
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/event.py +26 -26
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/message.py +23 -8
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/__init__.py +1 -1
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/phone_numbers.py +4 -6
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/__init__.py +11 -10
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/document_processor.py +98 -105
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/index_builder.py +40 -45
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/migration.py +9 -9
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/pgvector_backend.py +61 -54
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/query_processor.py +16 -20
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/search_engine.py +90 -94
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/search_service.py +61 -63
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/__init__.py +1 -1
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/api_ninjas_trivia/skill.py +6 -6
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/claude_skills/skill.py +20 -26
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere/skill.py +10 -8
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere_serverless/skill.py +11 -7
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datetime/skill.py +9 -11
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/google_maps/skill.py +11 -10
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/info_gatherer/skill.py +7 -7
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/joke/skill.py +9 -7
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/math/skill.py +14 -16
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/mcp_gateway/skill.py +34 -38
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/native_vector_search/skill.py +44 -43
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/play_background_file/skill.py +5 -5
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/registry.py +18 -18
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/spider/skill.py +29 -27
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/swml_transfer/skill.py +13 -12
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/weather_api/skill.py +5 -5
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/skill.py +27 -34
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/skill_improved.py +20 -23
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/skill_original.py +19 -20
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/wikipedia_search/skill.py +8 -9
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/schema_utils.py +64 -61
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/web/web_service.py +45 -49
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/PKG-INFO +1 -1
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/LICENSE +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/man/sw-agent-init.1 +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/man/sw-search.1 +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/man/swaig-test.1 +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/setup.cfg +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/setup.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/config.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/core/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/execution/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/output/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/simulation/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/__init__.py +1 -1
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/_agent_host.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/config/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/deployment/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/deployment/handlers/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/prompt/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/routing/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/security/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/swml/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/tools/__init__.py +2 -2
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/agent/tools/decorator.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/__init__.py +5 -5
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/mixins/_mixin_host.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/__init__.py +5 -5
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/core/security/security_utils.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/mcp_gateway/__init__.py +4 -4
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/pom/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/prefabs/__init__.py +3 -3
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/relay/constants.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/_base.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/_pagination.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/call_handler.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/client.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/addresses.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/calling.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/chat.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/compat.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/datasphere.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/fabric.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/imported_numbers.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/logs.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/lookup.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/mfa.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/number_groups.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/project.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/pubsub.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/queues.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/recordings.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/registry.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/short_codes.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/sip_profile.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/verified_callers.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/rest/namespaces/video.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/schema.json +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/search/models.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/api_ninjas_trivia/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/api_ninjas_trivia/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/claude_skills/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/claude_skills/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere_serverless/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datasphere_serverless/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datetime/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/datetime/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/google_maps/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/info_gatherer/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/info_gatherer/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/joke/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/joke/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/math/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/math/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/mcp_gateway/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/mcp_gateway/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/native_vector_search/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/native_vector_search/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/play_background_file/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/play_background_file/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/spider/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/spider/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/swml_transfer/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/swml_transfer/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/weather_api/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/weather_api/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/web_search/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/wikipedia_search/README.md +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/skills/wikipedia_search/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/pom_utils.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/token_generators.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/url_validator.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/utils/validators.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/web/__init__.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/SOURCES.txt +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/dependency_links.txt +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/entry_points.txt +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/requires.txt +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire_sdk.egg-info/top_level.txt +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/tests/test_examples.py +0 -0
- {signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/tests/test_mcp_integration.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "signalwire-sdk"
|
|
7
|
-
version = "3.0.2.
|
|
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.
|
|
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
|
-
"
|
|
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
|
-
"
|
|
153
|
+
"ContextBuilder",
|
|
154
|
+
"DataMap",
|
|
155
|
+
"FunctionResult",
|
|
161
156
|
"GatherInfo",
|
|
162
157
|
"GatherQuestion",
|
|
163
|
-
"
|
|
164
|
-
"
|
|
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
|
]
|
{signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/agent_server.py
RENAMED
|
@@ -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
|
|
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,
|
|
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.
|
|
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:
|
|
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:
|
|
91
|
-
self._sip_username_mapping:
|
|
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:
|
|
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:
|
|
187
|
-
) ->
|
|
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
|
-
|
|
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) ->
|
|
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) ->
|
|
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) ->
|
|
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:
|
|
346
|
-
port:
|
|
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
|
-
|
|
378
|
+
if mode == "lambda":
|
|
376
379
|
return self._handle_lambda_request(event, context)
|
|
377
|
-
|
|
378
|
-
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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
|
-
|
|
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: {
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
868
|
+
if clean_path == "swaig":
|
|
876
869
|
from fastapi import Response
|
|
877
870
|
|
|
878
871
|
return await agent._handle_swaig_request(request, Response())
|
|
879
|
-
|
|
872
|
+
if clean_path == "post_prompt":
|
|
880
873
|
return await agent._handle_post_prompt_request(request)
|
|
881
|
-
|
|
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
|
|
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, "")
|
{signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/agents/bedrock.py
RENAMED
|
@@ -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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
218
|
-
top_p:
|
|
219
|
-
max_tokens:
|
|
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
|
{signalwire_sdk-3.0.2.dev63 → signalwire_sdk-3.0.2.dev65}/signalwire/signalwire/cli/build_search.py
RENAMED
|
@@ -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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
776
|
-
|
|
777
|
-
|
|
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: {})"
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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()
|